1 //==========================================================================
5 // Device driver for the i.MX51 or i.MX37 USB OTG port.
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is a part of Diagnosis Package based on eCos for Freescale i.MX
11 // Family microprocessor.
12 // Copyright (C) 2008 Freescale Semiconductor, Inc.
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
45 // Contributors: fisherz
48 // This code implements support for the on-chip USB OTG port on the Freescale i.MX
49 // family of processors. The code has been developed on the i.MX and
50 // may or may not work on other members of the i.MX family. There
51 // have problems with the USB support on certain revisions of the silicon,
52 // so the errata sheet appropriate to the specific processor being used
53 // should be consulted. There also appear to be problems which do not
54 // appear on any errata, which this code attempts to work around.
56 // [Note] DMA is not enabled for USB transfer
57 //####DESCRIPTIONEND####
59 //####REVISION HISTORY####
60 // Date Author Comments
61 // 22Jul08 Fisher ZHU(b18985) Created for i.MX37 eCos USB device driver
62 // 16Oct08 Fisher ZHU(b18985) Ported to i.MX51 USB OTG core
63 //==========================================================================
64 #include <string.h> //use memset() of C run-time library
65 #include <cyg/infra/cyg_type.h>
66 #include <cyg/infra/cyg_ass.h>
67 #include <cyg/infra/cyg_trac.h>
68 #include <cyg/infra/diag.h>
69 #include <pkgconf/hal_arm.h>
70 #include <pkgconf/devs_usb_imx_otg.h>
71 #include <cyg/hal/drv_api.h>
72 #include <cyg/hal/hal_arch.h>
73 #include <cyg/hal/hal_io.h>
74 #include <cyg/hal/hal_cache.h>
75 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
76 #include <cyg/error/codes.h>
78 #include <cyg/io/usb/usb.h>
79 #include <cyg/io/usb/usbs.h>
80 #include <cyg/io/usb/usbs_imx.h>
82 #pragma O0 //this pragma is useful when Realview tool chain is used
83 #define VOLATILE volatile
85 #if defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
86 //this error code is defined in error/include/codes.h
87 //but when the usb driver is used in redboot, the codes.h won't
88 //be included, so that this definition will solve the problem
92 #define SDP_CMD_MAX_LEN 0x10 /* 16 bytes */
93 #define SDP_CMD_ACK_LEN 0x4 /* 4 bytes */
94 /* Command Packet Format: Header(2)+Address(4)+Format(1)+ByteCount(4)+Data(4) */
95 #define READ_HEADER 0x0101 //Read the flag in an assigned address on the target board
96 #define WRITE_HEADER 0x0202
97 #define WRITE_FILE 0x0404 //Write a file in host PC to target board
98 #define READ_FILE 0x0A0A //Read a block of RAM to host PC and save in a file
99 #define ERROR_STATUS_HEADER 0x0505
102 #define WRITE_COMPLETE 0x128A8A12
107 #define COMPLETE 0x88
109 #define USB_DOWNLOAD_TIMEOUT_LIMIT 0x1D000000
110 cyg_uint32 usb_download_address;
111 cyg_uint32 usb_download_length;
112 static cyg_uint8 sdp_payload_data[SDP_CMD_MAX_LEN]; /* Used to send or receive Command/ACK */
113 static cyg_uint8 sdp_command[SDP_CMD_MAX_LEN]; /* Used to store Command */
114 static cyg_uint8 g_error_status;
115 static cyg_uint8 g_usb_download_state = CONTINUE;
116 static cyg_uint32 g_timeout_value = 0;
117 static cyg_uint32 g_load_cycle;
118 static cyg_bool pl_get_command(void);
119 static cyg_uint8 pl_command_start(void);
120 static cyg_uint8 pl_handle_command(cyg_uint8 g_error_status);
121 static void pl_command_ack(cyg_uint32 ack);
122 static void pl_handle_write_file(cyg_uint32 address, cyg_uint32 total_bytes);
123 static cyg_uint32 usb_rx_processing(cyg_uint8* read_ptr, usb_status_t* status, cyg_uint32 data_length);
124 static usb_status_t usb_tx_processing(cyg_uint8* write_ptr, cyg_uint32 data_len);
127 /* Bit3 - Mass Storage Information
128 Bit2 - Enumeration Information
129 Bit1 - Transaction Information
130 Bit0 - Basic Information
132 //#define DEBUG_TRANS 0x8 //also defined in usbs_msc.c
133 #define DEBUG_ENUM 0x4
134 #define DEBUG_TRANS 0x2
135 #define DEBUG_BASIC 0x1
137 //#define USBDBGMSG(str) if(g_debug_switch&0x1) diag_printf(str)
138 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
139 extern cyg_uint32 g_debug_switch; //the lowest 4-bit is used for USB debug
141 #define USBDBGMSG(opt,fmt,args...) if(g_debug_switch&opt) diag_printf(fmt, ## args)
143 #define USBDBGMSG(opt,fmt,args...)
147 #define USBDBGMSG(opt,fmt,args...) //diag_printf(fmt, ## args)
148 #define D(fmt,args...) diag_printf(fmt, ## args)
151 // ----------------------------------------------------------------------------
152 //volatile cyg_uint8 g_bulkbuffer[BULK_TD_BUFFER_TOTAL_SIZE*NUM_OF_BULK_BUFFER] __attribute__((aligned(0x1000)));
153 bulk_buffer_t g_bulkbuffer_a;
154 bulk_buffer_t g_bulkbuffer_b;
156 //This variable is used to workaround the 31-byte packet issue in i.MX37
157 //It is initialized as "0x1",
158 //When data read/write, it must initialize as '0x0'
159 cyg_uint32 g_td_buffer_offset = 0;
161 //The below two flags is used to distinguish the received data is data or command
162 cyg_uint32 g_received_data_type;
164 /* This is used to pause the EP2 In wait for complete, just a workaround for this issue
165 It is not sure to be a bug of IC or software, need to check later.
167 //cyg_uint8 g_tx_done=1; //to keep EP1 issue sempahore to scsi after the previous CBW processed
168 cyg_uint8 g_ep2_complete_bit_set = 0;
170 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
171 extern cyg_sem_t usbs_msc_sem; //semaphore to schedule mass storage command handling thread
174 // ----------------------------------------------------------------------------
175 // Static pointers for USB buffer layout
176 /*=============================================================================
178 //============================================================================*/
180 // Allocate 2k-byte buffer as USB QueueHeaderList region.
181 // Don't use #pragma arm section in GCC
182 // !!!!USB buffer should not be cached and buffered.
183 //#pragma arm section rwdata="usb_buffer_no_init", zidata="usb_buffer_no_init"
184 //2k aligned, this buffer must be uncacheable and unbufferable.
186 #if defined(CYGHWR_IMX_USB_BUFFER_USE_IRAM)
187 static volatile cyg_uint8 usb_buffer[BUFFER_SIZE] __attribute__((aligned(0x800)));
188 static volatile cyg_uint8 bulk_buffer[BULK_TD_BUFFER_TOTAL_SIZE*NUM_OF_BULK_BUFFER] __attribute__((aligned(0x1000)));
189 //#pragma arm section
191 /* iRAM is configured as uncacheable and unbufferable in MMU initialization
192 Reserve 0x800 bytes as USB buffer
193 Don't use 0x10001000~0x10001800 for other program. */
194 #if defined(CYGHWR_USB_DEVS_MX37_OTG)
195 static volatile cyg_uint8 * usb_buffer=(cyg_uint8 *)(0x10001000);
196 static volatile cyg_uint8 * bulk_buffer = (cyg_uint8 *)(0x10002000);
199 #if defined(CYGHWR_USB_DEVS_MX51_OTG)
200 static volatile cyg_uint8 * usb_buffer=(cyg_uint8 *)(0x1FFE9000);
201 static volatile cyg_uint8 * bulk_buffer = (cyg_uint8 *)(0x1FFEA000);
204 #endif //defined(CYGHWR_IMX_USB_BUFFER_USE_IRAM)
206 VOLATILE usbs_imx_otg_hardware* usbs_imx_otg_base = (VOLATILE usbs_imx_otg_hardware* const) USB_BASE_ADDRESS;
208 static void usbs_imx_otg_config_utmi_clock(void);
211 /* Base address of the buffer allocated to IP Layer */
212 static VOLATILE cyg_uint32 g_bulkbuffer_address_base;
213 /* length of the buffer */
214 static VOLATILE cyg_uint32 g_bulkbuffer_length;
215 /* Buffer information used for data transfer */
216 static VOLATILE buffer_map_t g_bulkbuffer_map;
217 /* Number of Endpoints configured in system */
218 static VOLATILE cyg_uint8 g_max_ep_supported;
219 /* State os USB Device */
220 static VOLATILE usb_state_t g_usb_dev_state = USB_DEV_DUMMY_STATE;
221 /* Length of setup data received */
222 static VOLATILE cyg_uint8 * g_usb_setup_data;
223 /* Array to keep information about the endpoints used */
224 static VOLATILE usb_end_pt_info_t g_end_pt_info[USB_DEV_INF_DESC_NUM_OF_EP];
225 /* Number of endpoints */
226 static VOLATILE cyg_uint8 g_number_of_endpoints;
227 /* USB Descriptors */
228 static VOLATILE usb_descriptor g_usb_desc;
229 /* Number of Endpoint configured as IN */
230 static VOLATILE cyg_uint8 g_in_endpoint;
231 /* Number of Endpoint configured as OUT*/
232 static VOLATILE cyg_uint8 g_out_endpoint;
234 /* Support for the interrupt handling code.*/
235 static cyg_interrupt g_usbs_dev_intr_data;
236 static cyg_handle_t g_usbs_dev_intr_handle;
237 static volatile int g_isr_status_bits = 0;
239 // ----------------------------------------------------------------------------
240 // get the base address of queue header for an endpointer
241 #define USBS_EP_GET_dQH(endptno,dir) (g_bulkbuffer_map.ep_dqh_base_addrs + (SIZE_OF_QHD * (endptno * 2 + dir)))
242 #define USBS_EP_GET_dTD(endptno,dir) (g_bulkbuffer_map.ep_dtd_base_addrs + (SIZE_OF_DTD0 + SIZE_OF_DTD1) * ( endptno * 2 + dir))
243 // ----------------------------------------------------------------------------
244 // USB interrupt enable/disable macros
245 #define USBS_IMX_OTG_INTR_MASK() (usbs_imx_otg_base->usbintrclr = 0xFFFFFFFF)//0|IMX_USB_INTR_DEV_RESET|IMX_USB_INTR_DEV_USBINT)
246 #define USBS_IMX_OTG_INTR_UNMASK(intr) (usbs_imx_otg_base->usbintr = 0|(intr))
248 // ----------------------------------------------------------------------------
249 // Check if the IOS bit of QueueHeader or the IOC bit of Transfer Descriptor are set
250 #define USBS_dQH_IOS_CHECK(ep_num,dir) (((*(cyg_uint32*)USBS_EP_GET_dQH(ep_num,dir))&0x8000)?1:0)
251 #define USBS_dTD_IOC_CHECK(ep_num,dir) (((*(cyg_uint32*)USBS_EP_GET_dTD(ep_num,dir))&0x8000)?1:0)
253 // ----------------------------------------------------------------------------
254 // Set USB device address
255 #define USBS_DEVICE_SET_ADDRESS(addr) (usbs_imx_otg_base->devaddr = ((cyg_uint32)addr & 0x7F) << 25)
261 #define USB_OTG_ID (&(usbs_imx_otg_base->id)) /* Identification Register */
262 #define USB_OTG_HWGENERAL (&(usbs_imx_otg_base->hwgeneral)) /* General Hardware Parameters */
263 #define USB_OTG_HWHOST (&(usbs_imx_otg_base->hwhost)) /* Host Hardware Parameters */
264 #define USB_OTG_HWDEVICE (&(usbs_imx_otg_base->hwdevice)) /* Device Hardware Parameters */
265 #define USB_OTG_HWTXBUF (&(usbs_imx_otg_base->hwtxbuf)) /* TX Buffer Hardware Parameters */
266 #define USB_OTG_HWRXBUF (&(usbs_imx_otg_base->hwrxbuf)) /* RX Buffer Hardware Parameters */
268 #define USB_OTG_CAPLENGTH (&(usbs_imx_otg_base->caplength)) /* Capability Register Length */
269 #define USB_OTG_HCIVERSION (&(usbs_imx_otg_base->hciversion)) /* Host Interface Version Number */
270 #define USB_OTG_HCSPARAMS (&(usbs_imx_otg_base->hcsparams)) /* Host Ctrl. Structural Parameters */
271 #define USB_OTG_HCCPARAMS (&(usbs_imx_otg_base->hccparams)) /* Host Ctrl. Capability Parameters */
272 #define USB_OTG_DCIVERSION (&(usbs_imx_otg_base->dciversion)) /* Dev. Interface Version Number */
273 #define USB_OTG_DCCPARAMS (&(usbs_imx_otg_base->dccparams)) /* Dev. Ctrl. Capability Parameters */
275 #define USB_OTG_USBCMD (&(usbs_imx_otg_base->usbcmd)) /* USB Command */
276 #define USB_OTG_USBSTS (&(usbs_imx_otg_base->usbsts)) /* USB Status */
277 #define USB_OTG_USBINTR (&(usbs_imx_otg_base->usbintr)) /* USB Interrupt Enable */
278 #define USB_OTG_FRINDEX (&(usbs_imx_otg_base->frindex)) /* USB Frame Index */
280 #define USB_OTG_DEVICEADDR (&(usbs_imx_otg_base->devaddr)) /* USB Device Address */
281 #define USB_OTG_PERIODICLISTBASE USB_OTG_DEVICEADDR /* Frame List Base Address */
282 #define USB_OTG_ENDPOINTLISTADDR (&(usbs_imx_otg_base->endptlistaddr)) /*Address of Endpt list in memory*/
283 #define USB_OTG_ASYNCLISTADDR USB_OTG_ENDPOINTLISTADDR /* Next Asynchronous List Address */
285 #define USB_OTG_BURSTSIZE (&(usbs_imx_otg_base->burstsize)) /* Programmable Burst Size */
286 #define USB_OTG_TXFILLTUNING (&(usbs_imx_otg_base->txfilltuning)) /* Host TX Pre-Buffer Packet Tuning */
287 #define USB_OTG_VIEWPORT (&(usbs_imx_otg_base->ulpiviewport)) /* ULPI Register */
288 #define USB_OTG_ENDPTNAK (&(usbs_imx_otg_base->endptnak)) /*Endpoint NAK */
289 #define USB_OTG_ENDPTNAKEN (&(usbs_imx_otg_base->endptnaken)) /*Endpoint NAK Enable */
290 #define USB_OTG_CONFIGFLAG (&(usbs_imx_otg_base->configflg)) /* Configured Flag Register */
291 #define USB_OTG_PORTSC1 (&(usbs_imx_otg_base->portsc1)) /* Port 0 Status/Control */
292 #define USB_OTG_OTGSC (&(usbs_imx_otg_base->otgsc)) /* OTG Status and Control */
293 #define USB_OTG_USBMODE (&(usbs_imx_otg_base->usbmode)) /* USB Device Mode */
294 #define USB_OTG_ENDPTSETUPSTAT (&(usbs_imx_otg_base->endptsetupstat)) /* Endpoint Setup Status */
295 #define USB_OTG_ENDPTPRIME (&(usbs_imx_otg_base->endptprime)) /* Endpoint Initialization */
296 #define USB_OTG_ENDPTFLUSH (&(usbs_imx_otg_base->endptflush)) /* Endpoint De-Initialize */
297 #define USB_OTG_ENDPTSTATUS (&(usbs_imx_otg_base->endptstatus))/* Endpoint Status */
298 #define USB_OTG_ENDPTCOMPLETE (&(usbs_imx_otg_base->endptcomplete)) /* Endpoint Complete */
299 #define USB_OTG_ENDPTCTRL0 (&(usbs_imx_otg_base->endptctrl[0])) /* Endpoint Control 0 */
300 #define USB_OTG_ENDPTCTRL1 (&(usbs_imx_otg_base->endptctrl[1])) /* Endpoint Control 1 */
301 #define USB_OTG_ENDPTCTRL2 (&(usbs_imx_otg_base->endptctrl[2])) /* Endpoint Control 2 */
302 #define USB_OTG_ENDPTCTRL3 (&(usbs_imx_otg_base->endptctrl[3])) /* Endpoint Control 3 */
303 #define USB_OTG_ENDPTCTRL4 (&(usbs_imx_otg_base->endptctrl[4])) /* Endpoint Control 4 */
304 #define USB_OTG_ENDPTCTRL5 (&(usbs_imx_otg_base->endptctrl[5])) /* Endpoint Control 5 */
305 #define USB_OTG_ENDPTCTRL6 (&(usbs_imx_otg_base->endptctrl[6])) /* Endpoint Control 6 */
306 #define USB_OTG_ENDPTCTRL7 (&(usbs_imx_otg_base->endptctrl[7])) /* Endpoint Control 7 */
307 // ****************************************************************************
308 // -----------------------USB Device Descriptors-------------------------------
309 // ****************************************************************************
310 /* USB Device Descriptor according to USB2.0 Specification */
311 static VOLATILE usb_device_descriptor g_usb_device_desc ={
314 USB_DEV_DESC_SPEC_LB,
315 USB_DEV_DESC_SPEC_HB,
316 USB_DEV_DESC_DEV_CLASS,
317 USB_DEV_DESC_DEV_SUBCLASS,
318 USB_DEV_DESC_DEV_PROTOCOL,
319 USB_DEV_DESC_EP0_MAXPACKETSIZE,
320 USB_DEV_DESC_VENDORID_LB,
321 USB_DEV_DESC_VENDORID_HB,
322 USB_DEV_DESC_PRODUCTID_LB,
323 USB_DEV_DESC_PRODUCTID_HB,
324 USB_DEV_DESC_DEV_RELEASE_NUM_LB,
325 USB_DEV_DESC_DEV_RELEASE_NUM_HB,
326 USB_DEV_DESC_DEV_STRING_IND_MANUFACTURE,
327 USB_DEV_DESC_DEV_STRING_IND_PRODUCT,
328 USB_DEV_DESC_DEV_STRING_IND_SERIAL_NUM,
329 USB_DEV_DESC_DEV_NUM_CONFIGURATIONS
333 /* USB Config Descriptor according to USB2.0 Specification */
334 static VOLATILE usb_conf_desc g_usb_config_desc = {
336 USB_DEV_CONFIG_DESC_LEN,
337 USB_DEV_CONFIG_DESC_TYPE,
338 USB_DEV_CONFIG_DESC_TTL_LEN_LB ,
339 USB_DEV_CONFIG_DESC_TTL_LEN_HB ,
340 USB_DEV_CONFIG_DESC_NUM_0F_INF,
341 USB_DEV_CONFIG_DESC_CONFIG_VALUE ,
342 USB_DEV_CONFIG_DESC_STRING_INDEX,
343 USB_DEV_CONFIG_DESC_ATTRIBUTES,
344 USB_DEV_CONFIG_DESC_MAX_POWER
346 /* USB Interface Descriptor according to USB2.0 Specification */
348 USB_DEV_INF_DESC_LEN,
349 USB_DEV_INF_DESC_TYPE,
350 USB_DEV_INF_DESC_INF_INDEX,
351 USB_DEV_INF_DESC_ALT_SETTING,
352 USB_DEV_INF_DESC_NUM_OF_EP, /* NOTE : This should not be more than 2 */
353 #if defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
354 USB_DEV_INF_DESC_INF_CLASS_VENDOR,
355 USB_DEV_INF_DESC_INF_SUBCLASS_NS_BLANK,
356 USB_DEV_INF_DESC_INF_PROTOCOL,
358 USB_DEV_INF_DESC_INF_CLASS_MSC,
359 USB_DEV_INF_DESC_INF_SUBCLASS_MSC_SCSI,
360 USB_DEV_INF_DESC_INF_PROTOCOL_MSC_BOT,
362 USB_DEV_INF_DESC_STRING_INDEX
364 /* USB Endpoint 1 Descriptors according to USB2.0 Specification, OUT */
369 USB_EP1_DESC_EP_ADDR,
370 USB_EP1_DESC_ATTRIBUTES,
371 USB_EP1_DESC_MAX_PACKET_SIZE_HS_LB,
372 USB_EP1_DESC_MAX_PACKET_SIZE_HS_HB,
373 USB_EP1_DESC_INTERVAL
375 /* USB Endpoint 2 Descriptors according to USB2.0 Specification, IN */
379 USB_EP2_DESC_EP_ADDR,
380 USB_EP2_DESC_ATTRIBUTES,
381 USB_EP2_DESC_MAX_PACKET_SIZE_HS_LB,
382 USB_EP2_DESC_MAX_PACKET_SIZE_HS_HB,
383 USB_EP2_DESC_INTERVAL
388 /* USB String Descriptors 0, according to USB2.0 Specification */
389 static VOLATILE usb_str0_desc g_usb_otg_str0_desc ={
398 See table 9-15 in USB2.0 spec (www.usb.org)
401 static VOLATILE usb_str1_desc g_usb_otg_string_desc1 ={
402 USB_STR1_DESC_SIZE, /* bLength */
403 USB_STR1_DESC_TYPE, /* bDescriptorType */
405 'F', 0x00, /* bString */
435 #if defined(CYGHWR_USB_DEVS_MX37_OTG)
437 static VOLATILE usb_str2_desc g_usb_otg_string_desc2 = {
438 USB_STR2_DESC_SIZE_NS, /* bLength */
439 USB_STR2_DESC_TYPE, /* bDescriptorType */
441 'M', 0x00, /* bString */
458 //#if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
459 /* USB Serial Number Descriptor which is mandatory to Mass Storage Device */
460 static VOLATILE usb_str4_desc g_usb_serialnumber_desc = {
481 #if defined(CYGHWR_USB_DEVS_MX51_OTG)
482 static VOLATILE usb_str2_desc g_usb_otg_string_desc2 = {
483 USB_STR2_DESC_SIZE_NS, /* bLength */
484 USB_STR2_DESC_TYPE, /* bDescriptorType */
486 'E', 0x00, /* bString */
503 //#if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
504 /* USB Serial Number Descriptor which is mandatory to Mass Storage Device */
505 static VOLATILE usb_str4_desc g_usb_serialnumber_desc = {
527 See table 9-15 in USB2.0 spec (www.usb.org)
529 static VOLATILE usb_str3_desc g_usb_otg_string_desc3 = {
530 USB_STR3_DESC_SIZE, /* bLength */
531 USB_STR3_DESC_TYPE, /* bDescriptorType */
533 'F', 0x00, /* bString */
552 // ****************************************************************************
553 // ----------------------------------------------------------------------------
554 // ****************************************************************************
555 // ----------------------------------------------------------------------------
556 // Static data. There is a data structure for each endpoint. The
557 // implementation is essentially a private class that inherits from
558 // common classes for control and data endpoints, but device drivers
559 // are supposed to be written in C so some ugliness is required.
561 // ----------------------------------------------------------------------------
562 // Endpoint 0 is always present, this module would not get compiled
564 static void usbs_imx_otg_dev_ep0_start(usbs_control_endpoint*);
565 static void usbs_imx_otg_dev_poll(usbs_control_endpoint*);
567 typedef enum ep0_state {
573 typedef struct ep0_impl {
574 usbs_control_endpoint common; //struct usbs_control_endpoint defined in usbs.h
580 static ep0_impl ep0 = {
583 state: USBS_STATE_POWERED, // The hardware does not distinguish between detached, attached and powered.
584 enumeration_data: (usbs_enumeration_data*) 0,
585 start_fn: &usbs_imx_otg_dev_ep0_start,
586 poll_fn: &usbs_imx_otg_dev_poll,
587 interrupt_vector: IMX_IRQ_USB_DEV_SERVICE_REQUEST,
588 control_buffer: { 0, 0, 0, 0, 0, 0, 0, 0 },
589 state_change_fn: (void (*)(usbs_control_endpoint*, void*, usbs_state_change, int)) 0,
590 state_change_data: (void*) 0,
591 standard_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
592 standard_control_data: (void*) 0,
593 class_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
594 class_control_data: (void*) 0,
595 vendor_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
596 vendor_control_data: (void*) 0,
597 reserved_control_fn: (usbs_control_return (*)(usbs_control_endpoint*, void*)) 0,
598 reserved_control_data: (void*) 0,
599 buffer: (unsigned char*) 0,
601 fill_buffer_fn: (void (*)(usbs_control_endpoint*)) 0,
602 fill_data: (void*) 0,
604 complete_fn: (usbs_control_return (*)(usbs_control_endpoint*, int)) 0
606 ep_state: EP0_STATE_IDLE,
611 extern usbs_control_endpoint usbs_imx_otg_ep0 __attribute__((alias ("ep0")));
613 // Endpoint 1 is optional. If the application only involves control
614 // messages or only slave->host transfers then the endpoint 1
615 // support can be disabled.
616 //#ifdef CYGPKG_DEVS_USB_MX37_EP1
618 typedef struct ep1_impl {
619 usbs_rx_endpoint common; //struct usbs_rx_endpoint defined in usbs.h
621 cyg_bool using_buf_a;
624 static void ep1_start_rx(usbs_rx_endpoint*);
625 static void ep1_set_halted(usbs_rx_endpoint*, cyg_bool);
627 static ep1_impl ep1 = {
629 start_rx_fn: &ep1_start_rx,
630 set_halted_fn: &ep1_set_halted,
631 complete_fn: (void (*)(void*, int)) 0,
632 complete_data: (void*) 0,
633 buffer: (unsigned char*) 0,
641 extern usbs_rx_endpoint usbs_imx_otg_ep1 __attribute__((alias ("ep1")));
644 // Endpoint 2 is optional. If the application only involves control
645 // messages or only host->slave transfers then the endpoint 2 support
647 //#ifdef CYGPKG_DEVS_USB_MX37_EP2
649 typedef struct ep2_impl {
650 usbs_tx_endpoint common; //struct usbs_tx_endpoint defined in usbs.h
655 static void ep2_start_tx(usbs_tx_endpoint*);
656 static void ep2_set_halted(usbs_tx_endpoint*, cyg_bool);
658 static ep2_impl ep2 = {
660 start_tx_fn: &ep2_start_tx,
661 set_halted_fn: &ep2_set_halted,
662 complete_fn: (void (*)(void*, int)) 0,
663 complete_data: (void*) 0,
664 buffer: (const unsigned char*) 0,
672 extern usbs_tx_endpoint usbs_imx_otg_ep2 __attribute__ ((alias ("ep2")));
675 // ****************************************************************************
676 // -----------------------Static Functions Initialization----------------------
677 // ****************************************************************************
678 static void usbs_handle_get_descriptor(void);
679 static void usbs_handle_set_configuration(void);
680 static void usbs_handle_get_device_desc(void);
681 static void usbs_handle_get_config_desc(void);
682 static void usbs_handle_get_string_desc(void);
683 static void usbs_handle_get_configuration(void);
684 static void usbs_handle_set_address(void);
686 static void usbs_ep0in_fill_buffer(cyg_uint8 type, cyg_uint32 buffer_addrs);
687 static usb_status_t usbs_ep0_send_data(usb_buffer_descriptor_t* bd,cyg_uint8 zlt);
688 static usb_status_t usbs_ep0_receive_data(usb_buffer_descriptor_t* bd);
690 static void usbs_setup_queuehead(struct dqh_t* qhead);
691 static void usbs_setup_transdesc(struct dtd_t* td);
692 static void usbs_endpoint_stall(cyg_uint8 endpoint , cyg_uint8 direction);
693 static void usbs_status_phase(cyg_uint8 trans_type, cyg_uint8 direction);
695 static void usbs_imx_otg_dev_set_configuration(usb_end_pt_info_t* config_data);
696 static void usbs_imx_otg_dev_handle_bus_reset(void);
697 static void usbs_imx_otg_dev_handle_port_change(void);
698 static void usbs_imx_otg_hardware_init(void);
700 cyg_uint32 util_alloc_buffer(void);
701 void util_free_buffer(cyg_uint32 address);
702 void util_set_status_bulk_buffer(cyg_uint32 buffer_addr,int buffer_status);
703 // ****************************************************************************
704 // -----------------------Static Functions ------------------------------------
705 // ****************************************************************************
706 /*=============================================================================
707 FUNCTION: usbs_setup_queuehead
708 DESCRIPTION: This function is used to setup the dQH
709 ------------------------
710 | EP0 IN (64 bytes) |
712 ------------------------ dQH1
713 | EP0 OUT (64 bytes) |
715 ------------------------ dQH0
717 cyg_uint32 dqh_base - Base Address of the dQH
718 cyg_uint8 zlt - zero lengh packet termination (enable - ZLT_ENABLE; disable - ZLT_DISABLE)
719 cyg_uint16 mps - Max packet length
720 cyg_uint8 ios - interrupt on Setup
721 cyg_uint32 next_link_ptr - Next Link Pointer,
722 cyg_uint8 terminate - terminate - TERMINATE; not terminate - NOT_TERMINATE
723 cyg_uint16 total_bytes - Total Bytes to be transfered in this dQH
724 cyg_uint8 ioc - interrupt on complete, set - IOC_SET, not set - IOC_NOTSET
725 cyg_uint8 status - status
726 cyg_uint32 buffer_ptr0 - Buffer Pointer page 0
727 cyg_uint16 current_offset - current offset
728 cyg_uint32 buffer_ptr1 - Buffer Pointer page 1
729 cyg_uint32 buffer_ptr2 - Buffer Pointer page 1
730 cyg_uint32 buffer_ptr3 - Buffer Pointer page 1
731 cyg_uint32 buffer_ptr4 - Buffer Pointer page 1
735 =============================================================================*/
737 usbs_setup_queuehead(struct dqh_t* qhead)
739 volatile struct dqh_setup_t* dqh_word = (volatile struct dqh_setup_t*) qhead->dqh_base;
741 /*Bit31:30 Mult; Bit29 zlt; Bit26:16 mps; Bit15 ios */
742 dqh_word->dqh_word0 = (((cyg_uint32)(qhead->zlt) << 29)|((cyg_uint32)(qhead->mps) <<16) | ((cyg_uint32)(qhead->ios) <<15));
744 /*Current dTD Pointer => for hw use, not modified by DCD software */
745 dqh_word->dqh_word1 = 0x0;
747 /*Next dTD Pointer */
748 dqh_word->dqh_word2 = (((qhead->next_link_ptr) & 0xFFFFFFE0) | qhead->terminate);
750 /*Bit30:16 total_bytes; Bit15 ioc; Bit11:10 MultO; Bit7:0 status */
751 dqh_word->dqh_word3 = ((((cyg_uint32)(qhead->total_bytes) & 0x7FFF) << 16) | ((cyg_uint32)(qhead->ioc) <<15) | (qhead->status));
753 /*Bit31:12 Buffer Pointer (Page 0) */
754 dqh_word->dqh_word4 = ((qhead->buffer_ptr0 & 0xFFFFF000) | (qhead->current_offset & 0xFFF));
756 /*Bit31:12 Buffer Pointer (Page 1) */
757 dqh_word->dqh_word5 = (qhead->buffer_ptr1 & 0xFFFFF000);
759 /*Bit31:12 Buffer Pointer (Page 2) */
760 dqh_word->dqh_word6 = (qhead->buffer_ptr2 & 0xFFFFF000);
762 /*Bit31:12 Buffer Pointer (Page 3) */
763 dqh_word->dqh_word7 = (qhead->buffer_ptr3 & 0xFFFFF000);
765 /*Bit31:12 Buffer Pointer (Page 4) */
766 dqh_word->dqh_word8 = (qhead->buffer_ptr4 & 0xFFFFF000);
769 dqh_word->dqh_word9 = 0;
772 dqh_word->dqh_word10 = 0;
775 dqh_word->dqh_word11 = 0;
777 /*=============================================================================
778 FUNCTION: usbs_setup_transdesc
779 DESCRIPTION: This function is used to setup the dTD
781 cyg_uint32 dtd_base - Base Address of the dTD
782 cyg_uint32 next_link_ptr - Next Link Pointer,
783 cyg_uint8 terminate - terminate - TERMINATE; not terminate - NOT_TERMINATE
784 cyg_uint16 total_bytes - Total Bytes to be transfered in this dQH
785 cyg_uint8 ioc - interrupt on complete, set - IOC_SET, not set - IOC_NOTSET
786 cyg_uint8 Status - Status
787 cyg_uint32 buffer_ptr0 - Buffer Pointer page 0
788 cyg_uint16 current_offset - current offset
789 cyg_uint32 buffer_ptr1 - Buffer Pointer page 1
790 cyg_uint32 buffer_ptr2 - Buffer Pointer page 1
791 cyg_uint32 buffer_ptr3 - Buffer Pointer page 1
792 cyg_uint32 buffer_ptr4 - Buffer Pointer page 1
795 ==============================================================================*/
797 usbs_setup_transdesc(struct dtd_t* td)
799 volatile struct dtd_setup_t* dtd_word = (volatile struct dtd_setup_t *) td->dtd_base;
801 /* Bit31:5 Next Link Pointer ; Bit0 terminate */
802 dtd_word->dtd_word0 = ((td->next_link_ptr & 0xFFFFFFE0) | td->terminate);
804 /* Bit30:16 total_bytes, Bit15 ioc, Bit7:0 status */
805 dtd_word->dtd_word1 = ((((cyg_uint32)td->total_bytes & 0x7FFF) << 16)| ((cyg_uint32)td->ioc <<15) | (td->status));
807 /* Bit31:12 Buffer Pointer Page 0 ; Bit11:0 Current Offset */
808 dtd_word->dtd_word2 = ((td->buffer_ptr0 & 0xFFFFF000) | (td->current_offset & 0xFFF));
810 /* Bit31:12 Buffer Pointer Page 1 ; Bit10:0 Frame Number */
811 dtd_word->dtd_word3 = (td->buffer_ptr1 & 0xFFFFF000);
813 /* Bit31:12 Buffer Pointer Page 2 ; */
814 dtd_word->dtd_word4 = (td->buffer_ptr2 & 0xFFFFF000);
816 /* Bit31:12 Buffer Pointer Page 3 ; */
817 dtd_word->dtd_word5 = (td->buffer_ptr3 & 0xFFFFF000);
819 /* Bit31:12 Buffer Pointer Page 4 ; */
820 dtd_word->dtd_word6 = (td->buffer_ptr4 & 0xFFFFF000);
824 /*==================================================================================================
825 FUNCTION: util_alloc_buffer
826 DESCRIPTION: This utility function allocate the free buffer available
827 ARGUMENTS PASSED: None
828 RETURN VALUE: cyg_uint32 address : address of the allocated buffer
829 IMPORTANT NOTES: If Buffer1 is FREE then return Buffer1 and mark this as Busy else check for buffer2 . If
830 none of the buffer is free then return NULL.
831 ==================================================================================================*/
832 cyg_uint32 util_alloc_buffer(void)
834 cyg_uint32 buffer_addr = (cyg_uint32)NULL; //force type conversion for multiple NULL definitions
836 /* Check if buffer1 is free then mark it busy and return address */
837 if (g_bulkbuffer_map.buffer1_status == BUFFER_FREE )
839 buffer_addr = g_bulkbuffer_map.buffer1_address;
840 g_bulkbuffer_map.buffer1_status = BUFFER_IN_USE;
842 /* Check if buffer2 is free then mark it busy and return address */
843 else if(g_bulkbuffer_map.buffer2_status == BUFFER_FREE)
845 buffer_addr = g_bulkbuffer_map.buffer2_address;
846 g_bulkbuffer_map.buffer2_status = BUFFER_IN_USE;
851 /*==================================================================================================
852 FUNCTION: util_free_buffer
853 DESCRIPTION: This function put the buffer in free state.
854 ARGUMENTS PASSED: cyg_uint32 address : address of the buffer .
856 IMPORTANT NOTES: None
858 ==================================================================================================*/
859 void util_free_buffer(cyg_uint32 address)
861 if( address == g_bulkbuffer_map.buffer1_address )
863 g_bulkbuffer_map.buffer1_status = BUFFER_FREE;
865 else if ( address == g_bulkbuffer_map.buffer2_address )
867 g_bulkbuffer_map.buffer2_status = BUFFER_FREE;
870 /*==================================================================================================
871 FUNCTION: util_set_bulk_buffer_stat
872 DESCRIPTION: This function change the bulk buffer status
873 ARGUMENTS PASSED: cyg_uint32 buffer_addr: buffer base address
874 int buffer_status: new buffer_status
881 IMPORTANT NOTES: None
883 ==================================================================================================*/
884 void util_set_status_bulk_buffer(cyg_uint32 buffer_addr,int buffer_status)
886 if( buffer_addr == (cyg_uint32)g_bulkbuffer_a.buffer)
888 g_bulkbuffer_a.stat = buffer_status;
890 else if ( buffer_addr == (cyg_uint32)g_bulkbuffer_b.buffer )
892 g_bulkbuffer_b.stat = buffer_status;
897 /*=============================================================================
898 FUNCTION: usbs_endpoint_stall
899 DESCRIPTION: This function Send/Receive the STALL HANDSHAKE to USB Host
901 cyg_uint8 endpoint - Endpoint Number .
902 cyg_uint8 direction - IN/OUT : direction of EndPoint.
905 ==============================================================================*/
907 usbs_endpoint_stall(cyg_uint8 endpoint , cyg_uint8 direction)
909 if( direction == OUT )
911 usbs_imx_otg_base->endptctrl[endpoint]|= STALL_RX;
915 usbs_imx_otg_base->endptctrl[endpoint] |= STALL_TX;
918 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - EP%d - %d stalled\n",endpoint,direction);
922 usbs_endpoint_unstall(cyg_uint8 endpoint , cyg_uint8 direction)
924 if( direction == OUT )
926 usbs_imx_otg_base->endptctrl[endpoint]&= ~STALL_RX;
930 usbs_imx_otg_base->endptctrl[endpoint]&= ~STALL_TX;
934 /*=============================================================================
935 FUNCTION: usbs_status_phase
936 DESCRIPTION: This function Send/Receive the Status to/from Host.
937 ARGUMENTS PASSED: cyg_uint8 direction OUT Receive Status Command From Host
938 IN Send Status Command to Host
941 ===============================================================================*/
943 usbs_status_phase(cyg_uint8 trans_type, cyg_uint8 direction)
945 usb_buffer_descriptor_t bd ;
947 /* Buffer pointer is not used for EP0 */
948 bd.buffer = (cyg_uint32 *) 0xFFFFFFFF;
951 if(trans_type==CONTROL)
956 /* Receive ZERO length Length Data */
957 usbs_ep0_receive_data(&bd);
960 /* Send ZERO length Length Data */
961 usbs_ep0_send_data(&bd,0);
965 else if(trans_type==BULK)/*TODO*/
970 /* Send ZERO length Length Data */
971 //usbs_ep2_send_data(EP2,&bd,FALSE);
974 /* Receive ZERO length Length Data */
975 //usbs_ep1_receive_data(EP1,&bd);
981 // ---------------------------------------------------------------------------
982 // The following static functions are for USB device enumeration processing
983 /*============================================================================
984 FUNCTION: usbs_handle_get_descriptor
985 DESCRIPTION: This function Handle the GET DESCRIPTOR request
986 ARGUMENTS PASSED: None
988 IMPORTANT NOTES: None
989 ============================================================================*/
991 usbs_handle_get_descriptor()
993 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get descriptor handler\n");
994 switch (g_usb_setup_data[WVALUE_HIGHBYTE])
996 case DEVICE_DESC: /* device descriptor*/
997 usbs_handle_get_device_desc(); //Device will send the MPS to host
999 case CONF_DESC: /* configuration descriptor*/
1000 usbs_handle_get_config_desc(); //Device will send the whole device descriptor to host
1002 case STRING_DESC: /* string descriptor*/
1003 usbs_handle_get_string_desc();
1005 case INTERFACE_DESC:
1007 case DEVICE_QUALIFIER:
1008 case OTHER_SPEED_CONF_DESC:
1009 default: /* Send STALL Handshake */
1010 usbs_endpoint_stall(EP0,IN);
1016 /*=============================================================================
1017 FUNCTION: usbs_handle_get_device_desc
1018 DESCRIPTION: This function Handle the GET DEVICE DESCRIPTOR request
1019 ARGUMENTS PASSED: None
1021 IMPORTANT NOTES: None
1022 ==============================================================================*/
1024 usbs_handle_get_device_desc(void)
1026 usb_buffer_descriptor_t bd ;
1027 cyg_uint32 buffer_addrs;
1028 cyg_uint16 desc_length = 0x0;
1029 cyg_uint8 zlt = 0;//0 means false
1031 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get device descriptor\n");
1033 /* get the buffer address for data transfer over EP0 */
1034 buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs; //256bytes before the two Bulk buffers
1036 /* Fill the buffer with the descriptor data */
1037 usbs_ep0in_fill_buffer(FILL_DEVICE_DESC,buffer_addrs);
1039 /* Get the length of descriptor requested */
1040 desc_length = g_usb_setup_data[WLENGTH_LOWBYTE];
1041 desc_length |= ( g_usb_setup_data[WLENGTH_HIGHBYTE] <<0x8);
1043 /* If requested length of descriptor is lesser than actual length of descriptor then send
1044 * requested length of descroptor only else send the actual length of descriptor*/
1045 if( g_usb_dev_state == USB_DEV_DEFAULT_STATE )
1051 bd.size = USB_DEV_DESC_LEN;
1054 /* Send descriptor - Data Phase*/
1055 usbs_ep0_send_data(&bd,zlt); //zlt is false=>not zero length packet
1056 //send dev descriptor to host.
1058 /* Status Phase -- OUT */
1059 usbs_status_phase(CONTROL,OUT); //Get Zero-length data packet from Host, Device sends status: ACK(success), NAK(busy), or STALL(failed)
1063 /*=============================================================================
1064 FUNCTION: usbs_handle_get_config_desc
1065 DESCRIPTION: This function Handle the GET CONFIGURATION DESCRIPTOR request
1068 IMPORTANT NOTES:None
1069 =============================================================================*/
1071 usbs_handle_get_config_desc(void)
1073 usb_buffer_descriptor_t bd;
1074 cyg_uint32 buffer_addrs;
1075 cyg_uint16 desc_length_req = 0x0;
1076 cyg_uint16 desc_length = 0x0;
1079 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get config descriptor\n");
1080 /* get the buffer address for data transfer over EP0 */
1081 buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs;
1083 /* Fill the buffer with the descriptor data */
1084 usbs_ep0in_fill_buffer(FILL_CONF_DESC, buffer_addrs);
1086 /* total length of descriptor */
1087 desc_length = ((g_usb_desc.config_desc->usb_config_desc.total_length_lo) \
1088 | ( g_usb_desc.config_desc->usb_config_desc.total_length_hi << 0x8 ));
1089 /* Get the length of descriptor requested */
1090 desc_length_req = g_usb_setup_data[WLENGTH_LOWBYTE];
1091 desc_length_req |= ( g_usb_setup_data[WLENGTH_HIGHBYTE] <<0x8);
1094 /* If requested length of descriptor is lesser than actual length of descriotor then send
1095 * requested length of descroptor only else send the actual length of descriptor*/
1096 if(desc_length_req <= desc_length)
1098 bd.size = desc_length_req;
1102 bd.size = desc_length;
1104 if ( bd.size > MPS_64)
1109 usbs_ep0_send_data(&bd,zlt);
1111 /* Status Phase -- OUT */
1112 usbs_status_phase(CONTROL,OUT);
1115 /*=============================================================================
1116 FUNCTION: usbs_handle_get_string_desc
1117 DESCRIPTION: This function Handle the GET STRING DESCRIPTOR request
1118 ARGUMENTS PASSED: None
1120 IMPORTANT NOTES: None
1121 ==============================================================================*/
1123 usbs_handle_get_string_desc(void)
1125 usb_buffer_descriptor_t bd;
1126 cyg_uint32 buffer_addrs;
1127 cyg_uint16 desc_length_req = 0x0;
1128 cyg_uint16 length_of_desc = 0x0;
1132 /* Get Buufer to fill the data to be received/transmitted. */
1133 buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs;
1135 /* Get the length of descriptor requested */
1136 desc_length_req = g_usb_setup_data[WLENGTH_LOWBYTE];
1137 desc_length_req |= ( g_usb_setup_data[WLENGTH_HIGHBYTE] <<0x8);
1139 switch (g_usb_setup_data[WVALUE_LOWBYTE])
1142 usbs_ep0in_fill_buffer(FILL_STR_DES0,buffer_addrs);
1143 /* If requested length of descriptor is lesser than actual length of descriotor then send
1144 * requested length of descroptor only else send the actual length of descriptor*/
1145 if(desc_length_req <= g_usb_desc.str_desc0->length )
1147 bd.size = desc_length_req;
1151 bd.size = g_usb_desc.str_desc0->length;
1152 if ( bd.size > MPS_64)
1157 /* Data Phase -- IN */
1158 usbs_ep0_send_data(&bd,zlt);
1159 /* Status Phase -- OUT */
1160 usbs_status_phase(CONTROL,OUT);
1161 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get string descriptor 0\n");
1164 case STR_DES1: /*iManufacturer */
1165 usbs_ep0in_fill_buffer(FILL_STR_DES1,buffer_addrs);
1166 /* If requested length of descriptor is lesser than actual length of descriotor then send
1167 * requested length of descroptor only else send the actual length of descriptor*/
1168 if(desc_length_req <= g_usb_desc.str_desc1->length )
1170 bd.size = desc_length_req;
1174 bd.size = g_usb_desc.str_desc1->length;
1175 if ( bd.size > MPS_64)
1180 /* Data Phase -- IN */
1181 usbs_ep0_send_data(&bd,zlt);
1182 /* Status Phase -- OUT */
1183 usbs_status_phase(CONTROL,OUT);
1184 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get string descriptor 1\n");
1187 case STR_DES2: /*iProduct */
1188 usbs_ep0in_fill_buffer(FILL_STR_DES2,buffer_addrs );
1189 length_of_desc = g_usb_desc.str_desc2->length;
1190 /* If requested length of descriptor is lesser than actual length of descriotor then send
1191 * requested length of descroptor only else send the actual length of descriptor*/
1192 if(desc_length_req <= length_of_desc )
1194 bd.size = desc_length_req;
1198 bd.size = length_of_desc;
1199 if ( bd.size > MPS_64)
1204 /* Data Phase -- IN */
1205 usbs_ep0_send_data(&bd,zlt);
1206 /* Status Phase -- OUT */
1207 usbs_status_phase(CONTROL,OUT);
1208 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get string descriptor 2\n");
1212 /* send zero length data */
1213 usbs_status_phase(CONTROL,IN);
1214 /* Status Phase -- OUT */
1215 usbs_status_phase(CONTROL,OUT);
1218 case STR_DES5: /*iSerialNumber */
1219 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
1220 usbs_ep0in_fill_buffer(FILL_SN_DESC,buffer_addrs );
1221 /* If requested length of descriptor is lesser than actual length of descriotor then send
1222 * requested length of descroptor only else send the actual length of descriptor*/
1223 if(desc_length_req <= g_usb_desc.sn_desc->length )
1225 bd.size = desc_length_req;
1229 bd.size = g_usb_desc.sn_desc->length;
1230 if ( bd.size > MPS_64)
1235 /* Data Phase -- IN */
1236 usbs_ep0_send_data(&bd,zlt);
1237 /* Status Phase -- OUT */
1238 usbs_status_phase(CONTROL,OUT);
1239 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get string descriptor - SN\n");
1242 case STR_DES4: /*iSerialNumber */
1243 usbs_ep0in_fill_buffer(FILL_STR_DES3,buffer_addrs );
1244 /* If requested length of descriptor is lesser than actual length of descriotor then send
1245 * requested length of descroptor only else send the actual length of descriptor*/
1246 if(desc_length_req <= g_usb_desc.str_desc3->length )
1248 bd.size = desc_length_req;
1252 bd.size = g_usb_desc.str_desc3->length;
1253 if ( bd.size > MPS_64)
1258 /* Data Phase -- IN */
1259 usbs_ep0_send_data(&bd,zlt);
1260 /* Status Phase -- OUT */
1261 usbs_status_phase(CONTROL,OUT);
1262 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get string descriptor 3\n");
1265 /* Send STALL Handshake */
1266 usbs_endpoint_stall(EP0,IN);
1267 //USBDBGMSG("+USBDBGMSG:EP0 IN stalled at get string desc\n");
1274 /*=============================================================================
1275 FUNCTION: usbs_handle_set_address
1276 DESCRIPTION: This function Handle the SET ADDRESS Request from USB Host
1277 ARGUMENTS PASSED: None
1280 ==============================================================================*/
1282 usbs_handle_set_address(void)
1284 cyg_uint16 device_addrs;
1286 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set address handler\n");
1287 /* Get the Device Address to be SET from the Setup Data */
1288 device_addrs = g_usb_setup_data[WVALUE_LOWBYTE] + (g_usb_setup_data[WVALUE_HIGHBYTE]<<8);
1290 if ((g_usb_setup_data[WINDEX_LOWBYTE] == 0) &&
1291 (g_usb_setup_data[WINDEX_HIGHBYTE] == 0) &&
1292 (g_usb_setup_data[WLENGTH_LOWBYTE] == 0) &&
1293 (g_usb_setup_data[WLENGTH_HIGHBYTE] == 0) &&
1294 (device_addrs <= USB_MAX_DEVICE_ADDR))
1296 switch(g_usb_dev_state)
1298 case USB_DEV_DEFAULT_STATE :
1299 /* Send Ack to Host */
1300 usbs_status_phase(CONTROL,IN);
1301 if (device_addrs != USB_DEFAULT_ADDR)
1303 /* Set the Device Address */
1304 USBS_DEVICE_SET_ADDRESS(device_addrs);
1305 /* Change state to ADDRESSED STATE */
1306 g_usb_dev_state = USB_DEV_ADDRESSED_STATE;
1310 case USB_DEV_ADDRESSED_STATE :
1311 /* Send Ack to Host */
1312 usbs_status_phase(CONTROL,IN);
1313 if ( device_addrs == USB_DEFAULT_ADDR )
1315 /* Set the Device Address */
1316 USBS_DEVICE_SET_ADDRESS(USB_DEFAULT_ADDR);
1317 /* Change state to ADDRESSED STATE */
1318 g_usb_dev_state = USB_DEV_DEFAULT_STATE;
1322 /* Set the Device Address */
1323 USBS_DEVICE_SET_ADDRESS(device_addrs);
1327 case USB_DEV_CONFIGURED_STATE :
1328 if ( device_addrs == USB_DEFAULT_ADDR)
1330 /* Send Ack to Host */
1331 usbs_status_phase(CONTROL,IN);
1332 /* Set the Device Address */
1333 USBS_DEVICE_SET_ADDRESS(device_addrs);
1334 /* Change state to ADDRESSED STATE */
1335 g_usb_dev_state = USB_DEV_DEFAULT_STATE;
1339 /* Send STALL Handshake */
1340 usbs_endpoint_stall(EP0,IN);
1348 /* Send STALL Handshake */
1349 usbs_endpoint_stall(EP0,IN);
1354 /*=============================================================================
1355 FUNCTION: usbs_handle_get_configuration
1356 DESCRIPTION: This function Handle the GET CONFIGURATION request
1357 ARGUMENTS PASSED: None
1359 IMPORTANT NOTES: None
1360 =============================================================================*/
1362 usbs_handle_get_configuration(void)
1364 usb_buffer_descriptor_t bd;
1365 cyg_uint32 buffer_addrs;
1366 cyg_uint32* buffer_ptr;
1368 if((g_usb_setup_data[WINDEX_LOWBYTE] == 0) &&
1369 (g_usb_setup_data[WINDEX_HIGHBYTE] == 0) &&
1370 (g_usb_setup_data[WVALUE_LOWBYTE] == 0) &&
1371 (g_usb_setup_data[WVALUE_HIGHBYTE] == 0) &&
1372 (g_usb_setup_data[WLENGTH_LOWBYTE] == LEN_OF_CONFIG_VALUE) &&
1373 (g_usb_setup_data[WLENGTH_HIGHBYTE] == 0))
1375 switch(g_usb_dev_state)
1377 case USB_DEV_DEFAULT_STATE :
1378 /* Send STALL Handshake */
1379 usbs_endpoint_stall(EP0,IN);
1381 case USB_DEV_ADDRESSED_STATE:
1382 /* If the Device is in Address state then return 0x0 : See USB2.0 Spec */
1383 buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs;
1384 buffer_ptr = (cyg_uint32 *)buffer_addrs;
1387 bd.buffer = buffer_ptr;
1388 bd.size=LEN_OF_CONFIG_VALUE;
1390 usbs_ep0_send_data(&bd,0);
1392 /* Receive Ack from Host*/
1393 usbs_status_phase(CONTROL,OUT);
1396 case USB_DEV_CONFIGURED_STATE:
1397 buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs;
1398 buffer_ptr = (cyg_uint32 *)buffer_addrs;
1400 *buffer_ptr = (cyg_uint32 )g_usb_desc.config_desc->usb_config_desc.configuration_id;
1402 bd.buffer = buffer_ptr;
1403 bd.size=LEN_OF_CONFIG_VALUE;
1405 usbs_ep0_send_data(&bd,0);
1407 /* Receive Ack from Host*/
1408 usbs_status_phase(CONTROL,OUT);
1412 /* Send STALL Handshake */
1413 usbs_endpoint_stall(EP0,IN);
1418 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get config handler\n");
1420 /*=============================================================================
1421 FUNCTION: usbs_handle_set_configuration
1422 DESCRIPTION: This function Handle the SET CONFIGURATION request
1423 ARGUMENTS PASSED: None
1425 IMPORTANT NOTES: None
1426 =============================================================================*/
1428 usbs_handle_set_configuration(void)
1430 usb_end_pt_info_t config_data ;
1433 switch (g_usb_dev_state)
1435 case USB_DEV_ADDRESSED_STATE :
1436 if (g_usb_setup_data[WVALUE_LOWBYTE] == USB_DEV_VALUE_OF_UNCONFIG)
1438 /* Send Ack to Host*/
1439 usbs_status_phase(CONTROL,IN);
1441 /* Check if the configuration value received request is same as in Config descriptor */
1442 else if(g_usb_setup_data[WVALUE_LOWBYTE] == g_usb_desc.config_desc->usb_config_desc.configuration_id)
1444 /* Configure endpoints */
1445 for ( i = 0 ; i< g_number_of_endpoints ; i++)
1447 config_data.end_pt_no = g_end_pt_info[i].end_pt_no;
1448 config_data.direction = g_end_pt_info[i].direction;
1449 config_data.transfer_type = g_end_pt_info[i].transfer_type;
1450 config_data.max_pkt_size = g_end_pt_info[i].max_pkt_size;
1452 usbs_imx_otg_dev_set_configuration(&config_data);
1455 /* Send Ack to Host*/
1456 usbs_status_phase(CONTROL,IN);
1458 g_usb_dev_state = USB_DEV_CONFIGURED_STATE ;
1462 /* Invalid configuration value. Send STALL Handshake */
1463 usbs_endpoint_stall(EP0,IN);
1464 //USBDBGMSG("+USBDBGMSG:EP0 IN stalled at set conf in addr state\n");
1466 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set conf@ADDRESSED_STATE\n");
1468 case USB_DEV_CONFIGURED_STATE :
1469 if(g_usb_setup_data[WVALUE_LOWBYTE] == USB_DEV_CONFIG_DESC_CONFIG_VALUE)
1471 /* Send Ack to Host*/
1472 usbs_status_phase(CONTROL,IN);
1474 else if (g_usb_setup_data[WVALUE_LOWBYTE] == USB_DEV_VALUE_OF_UNCONFIG)
1476 /* Send Ack to Host*/
1477 usbs_status_phase(CONTROL,IN);
1479 /* Change USB State to Addressed State */
1480 g_usb_dev_state = USB_DEV_ADDRESSED_STATE;
1482 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set conf@CONFIGURED_STATE\n");
1485 /* Send STALL Handshake */
1486 usbs_endpoint_stall(EP0,IN);
1487 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set conf@incorrect state\n");
1491 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set config handler\n");
1493 /*=============================================================================
1494 FUNCTION: usbs_handle_msc_get_maxlun
1495 DESCRIPTION: This function Handle the GET MAX LUN Mass Storage class
1497 ARGUMENTS PASSED: None
1499 IMPORTANT NOTES: None
1500 =============================================================================*/
1502 usbs_handle_msc_get_maxlun(void)
1504 usb_buffer_descriptor_t bd ;
1505 cyg_uint32 buffer_addrs;
1506 cyg_uint16 desc_length = 0x0;
1507 cyg_uint8 zlt = 0;//0 means false
1508 cyg_uint8 Max_Lun=0;
1509 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: MASS - Get MAX LUN\n");
1511 /* get the buffer address for data transfer over EP0 */
1512 buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs; //256bytes before the two Bulk buffers
1514 /* Get the length of descriptor requested */
1515 desc_length = g_usb_setup_data[WLENGTH_LOWBYTE];
1516 desc_length |= ( g_usb_setup_data[WLENGTH_HIGHBYTE] <<0x8);
1518 /* If requested length of descriptor is zero*/
1521 /* Fill the buffer with the descriptor data */
1522 *(cyg_uint8 *)buffer_addrs = 0;//Max_Lun;
1527 /* Fill the buffer with the descriptor data */
1528 *(cyg_uint8 *)buffer_addrs = Max_Lun;
1529 bd.size = desc_length;
1532 /* Send descriptor - Data Phase*/
1533 usbs_ep0_send_data(&bd,zlt); //zlt is false=>not zero length packet
1534 //send dev descriptor to host.
1536 /* Status Phase -- OUT */
1537 usbs_status_phase(CONTROL,OUT); //Get Zero-length data packet from Host, Device sends status: ACK(success), NAK(busy), or STALL(failed)
1541 /*=============================================================================
1542 FUNCTION: usbs_ep0in_fill_buffer
1543 DESCRIPTION: This function is used to fill the corresponding
1544 response for the data phase of SETUP Transfer
1546 cyg_uint8 type: type of descriptor
1547 cyg_uint32 buffer_addrs - buffer pointer to be filled
1549 IMPORTANT NOTES:None
1550 =============================================================================*/
1552 usbs_ep0in_fill_buffer(cyg_uint8 type, cyg_uint32 buffer_addrs)
1554 const cyg_uint8 *data=0;
1555 cyg_uint32 *buffer_page = (cyg_uint32*)buffer_addrs;
1557 //USBDBGMSG("+USBDBGMSG: enum - copy descriptor to buffer\n");
1560 case FILL_DEVICE_DESC: /*5*32 bit */
1561 data = (cyg_uint8 *)g_usb_desc.device_desc;
1563 case FILL_CONF_DESC: /*8*32 bit */
1564 data = (cyg_uint8 *)g_usb_desc.config_desc;
1566 case FILL_STR_DES0: /*1*32 bit */
1567 data = (cyg_uint8 *)g_usb_desc.str_desc0;
1569 case FILL_STR_DES1: /*7*32 bit */
1570 data =(cyg_uint8 *)g_usb_desc.str_desc1;
1572 case FILL_STR_DES2: /*7*32 bit */
1573 data = (cyg_uint8 *)g_usb_desc.str_desc2;
1575 case FILL_STR_DES3: /*6*32 bit */
1576 data = (cyg_uint8 *)g_usb_desc.str_desc3;
1578 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
1580 data = (cyg_uint8 *)g_usb_desc.sn_desc;
1585 for (k=0; k<(MPS_64/sizeof(cyg_uint32)); k++)
1587 *buffer_page = data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24);
1588 //USBDBGMSG("+USBDBGMSG: desc[k] = 0x%x\n",(*buffer_page));
1597 /*=============================================================================
1598 FUNCTION: usbs_ep0_init_dqh
1599 DESCRIPTION: This function is used to initialize the queue header of EP0
1600 ARGUMENTS PASSED: NONE
1602 IMPORTANT NOTES: called by usbs_imx_otg_dev_ep0_init(),usbs_imx_otg_dev_handle_bus_reset()
1603 =============================================================================*/
1605 usbs_ep0_init_dqh(void)
1608 cyg_uint32 total_bytes;
1609 volatile cyg_uint32 * ep_q_hdr_base;
1612 //clear queue header
1613 ep_q_hdr_base = ((volatile cyg_uint32 *)g_bulkbuffer_map.ep_dqh_base_addrs);
1614 /* Clear the dQH Memory */
1615 for ( i = 0; i < (SIZE_OF_QHD*g_max_ep_supported*2)/sizeof(cyg_uint32) ; i++)
1617 *ep_q_hdr_base++ = 0;
1620 /******************************************************************************
1624 / Initialize device queue heads in system memory
1625 / 8 bytes for the 1st setup packet */
1628 qhead.dqh_base = USBS_EP_GET_dQH(EP0,OUT);
1629 qhead.zlt = ZLT_DISABLE;
1631 qhead.ios = IOS_SET;
1632 qhead.next_link_ptr = USBS_EP_GET_dTD(EP0,OUT);
1633 qhead.terminate = NOT_TERMINATE;
1634 qhead.total_bytes = total_bytes;
1635 qhead.ioc = IOC_SET;
1636 qhead.status = NO_STATUS;
1637 qhead.buffer_ptr0 = 0;
1638 qhead.current_offset= 0;
1639 qhead.buffer_ptr1 = 0;
1640 qhead.buffer_ptr2 = 0;
1641 qhead.buffer_ptr3 = 0;
1642 qhead.buffer_ptr4 = 0;
1643 /* Set Device Queue Head */
1644 usbs_setup_queuehead(&qhead);
1646 /* ==================
1648 ====================*/
1651 ================= */
1654 qhead.dqh_base = USBS_EP_GET_dQH(EP0,IN);
1655 qhead.zlt = ZLT_DISABLE;
1657 qhead.ios = IOS_SET;
1658 qhead.next_link_ptr = USBS_EP_GET_dTD(EP0,IN);
1659 qhead.terminate = TERMINATE;
1660 qhead.total_bytes = total_bytes;
1661 qhead.ioc = IOC_SET;
1662 qhead.status = NO_STATUS;
1663 qhead.buffer_ptr0 = g_bulkbuffer_map.ep0_buffer_addrs;
1664 qhead.current_offset= (g_bulkbuffer_map.ep0_buffer_addrs & 0xFFF);
1665 qhead.buffer_ptr1 = 0;
1666 qhead.buffer_ptr2 = 0;
1667 qhead.buffer_ptr3 = 0;
1668 qhead.buffer_ptr4 = 0;
1670 /* Set Device Queue Head */
1671 usbs_setup_queuehead(&qhead);
1673 /* ==================
1675 / ================*/
1677 /*=============================================================================
1678 FUNCTION: usbs_ep0_send_data
1679 DESCRIPTION: This function Send Data to host through EP0-IN Pipe.
1681 usb_buffer_descriptor_t *bd : This is the pointer to the buffer descriptor.
1682 cyg_uint8 zlt : Flag to decide if Zero Length Packet to be sent
1684 USB_SUCCESS - The buffer was successfully processed by the USB device and
1685 data sent to the Host.
1686 USB_FAILURE - Some failure occurred in transmitting the data.
1687 IMPORTANT NOTES: None
1688 =============================================================================*/
1690 usbs_ep0_send_data(usb_buffer_descriptor_t* bd,cyg_uint8 zlt)
1693 cyg_uint32 total_bytes ;
1694 cyg_uint32 dtd_address,dqh_address;
1696 usb_status_t status = USB_FAILURE;
1698 /* Get Device Transfer Descriptor of the requested endpoint */
1699 dtd_address = USBS_EP_GET_dTD(EP0,IN);
1701 /* Get Device Queue head of the requested endpoint */
1702 dqh_address = USBS_EP_GET_dQH(EP0,IN);
1704 /* Get Total Bytes to Be recieved */
1705 total_bytes = bd->size;
1707 /* Setup Transfer Descriptor for EP0 IN*/
1708 td.dtd_base = dtd_address;
1709 td.next_link_ptr = 0;
1710 td.terminate = TERMINATE;
1711 td.total_bytes = total_bytes;
1714 td.buffer_ptr0 = g_bulkbuffer_map.ep0_buffer_addrs;
1715 td.current_offset = (g_bulkbuffer_map.ep0_buffer_addrs & 0xFFF);
1721 /* Set the transfer descriptor */
1722 usbs_setup_transdesc(&td);
1724 /* Enable ZLT when data size is in multiple of Maximum Packet Size */
1727 /* set ZLT enable */
1728 (*(volatile cyg_uint32*)(dqh_address)) &= ~0x20000000;
1731 /* 1. write dQH next ptr and dQH terminate bit to 0 */
1732 *(volatile cyg_uint32*)(dqh_address+0x8)= (dtd_address);
1734 /* 2. clear active & halt bit in dQH */
1735 *(volatile cyg_uint32*)(dqh_address+0xC) &= ~0xFF;
1737 /* 3. prime endpoint by writing '1' in ENDPTPRIME */
1738 usbs_imx_otg_base->endptprime |= BIT16;
1740 /* wait for complete set and clear */
1741 while (!(usbs_imx_otg_base->endptcomplete & EPIN_COMPLETE));
1743 usbs_imx_otg_base->endptcomplete = EPIN_COMPLETE;
1745 status = USB_SUCCESS;
1749 /*=============================================================================
1750 FUNCTION: usbs_ep0_recevie_data
1751 DESCRIPTION: This function Handle the Status Token (IN/OUT) from USB Host
1753 usb_buffer_descriptor_t *bd : This is the pointer to the buffer descriptor.
1755 USB_SUCCESS - : The buffer was successfully processed by the USB device and
1756 data is received from the host.
1757 USB_FAILURE - : Some failure occurred in receiving the data.
1758 USB_INVALID - : If the endpoint is invalid.
1759 IMPORTANT NOTES:None
1760 =============================================================================*/
1761 static usb_status_t usbs_ep0_receive_data(usb_buffer_descriptor_t* bd)
1764 usb_status_t status = USB_FAILURE;
1765 cyg_uint32 total_bytes;
1766 cyg_uint32 dtd_address;
1767 cyg_uint32 dqh_address;
1769 /* Get Device Device Queue Head of the requested endpoint */
1770 dqh_address = USBS_EP_GET_dQH(EP0, OUT);
1772 /* Get Device Transfer Descriptor of the requested endpoint */
1773 dtd_address = USBS_EP_GET_dTD(EP0, OUT);
1775 /* Get the total bytes to be received */
1776 total_bytes = bd->size;
1778 td.dtd_base = dtd_address;
1779 td.next_link_ptr = dtd_address + 0x20;
1780 td.terminate = TERMINATE;
1781 td.total_bytes = total_bytes;
1784 td.buffer_ptr0 = g_bulkbuffer_map.ep0_buffer_addrs;
1785 td.current_offset = (g_bulkbuffer_map.ep0_buffer_addrs & 0xFFF);
1791 /* Set the Transfer Descriptor */
1792 usbs_setup_transdesc(&td);
1794 /* 1. write dQH next ptr and dQH terminate bit to 0 */
1795 *(volatile cyg_uint32*)(dqh_address+0x8)= dtd_address;
1797 /* 2. clear active & halt bit in dQH */
1798 *(volatile cyg_uint32*)(dqh_address+0xC) &= ~0xFF;
1800 /* 3. prime endpoint by writing '1' in ENDPTPRIME */
1801 usbs_imx_otg_base->endptprime |= ( EPOUT_PRIME << EP0 );
1803 /* 4. Wait for the Complete Status */
1804 while (!((usbs_imx_otg_base->endptprime) & ( EPOUT_COMPLETE << EP0)));
1806 /*clear the complete status */
1807 usbs_imx_otg_base->endptprime = (EPOUT_COMPLETE << EP0);
1809 status = USB_SUCCESS;
1813 // ****************************************************************************
1814 // -----------------------Endpoint 0 Functions---------------------------------
1815 // ****************************************************************************
1816 /*=============================================================================
1817 // This is where all the hard work happens. It is a very large routine
1818 // for a DSR, but in practice nearly all of it is nested if's and very
1819 // little code actually gets executed. Note that there may be
1820 // invocations of callback functions and the driver has no control
1821 // over how much time those will take, but those callbacks should be
1823 // so far, ep0 DSR works only during enumeration here.
1824 =============================================================================*/
1826 usbs_imx_otg_dev_ep0_dsr(void)
1828 usb_buffer_descriptor_t bd ;
1829 usb_status_t status = USB_FAILURE;
1830 volatile struct dqh_setup_t * dqh_word ;
1831 cyg_uint32 dqh_address;
1834 //USBDBGMSG("+USBDBGMSG: enter ep0 dsr.\n");
1835 /* 1. Receive Setup Data*/
1836 bd.buffer = (cyg_uint32 *)g_usb_setup_data;
1839 /* Get the Device Queue Head Address for EP0 OUT */
1840 dqh_address = USBS_EP_GET_dQH(EP0,OUT);
1841 dqh_word = (volatile struct dqh_setup_t*)dqh_address;
1843 /* write '1' to clear corresponding bit in ENDPTSETUPSTAT */
1844 temp = usbs_imx_otg_base->endptsetupstat;
1845 usbs_imx_otg_base->endptsetupstat = temp;
1847 // if(usbs_imx_otg_base->endptsetupstat & BIT0)
1848 // usbs_imx_otg_base->endptsetupstat = BIT0;
1851 /* write '1' to Setup Tripwire (SUTW) in USBCMD register */
1852 usbs_imx_otg_base->usbcmd |= BIT13;
1854 /* Copy the SetupBuffer into local software byte array */
1855 temp = (dqh_word->dqh_word10);
1857 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )(temp & 0x000000FF);
1858 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1859 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )((temp & 0x0000FF00)>>8);
1860 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1861 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )((temp & 0x00FF0000)>>16);
1862 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1863 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )((temp & 0xFF000000)>>24);
1864 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1866 temp = (dqh_word->dqh_word11);
1867 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )(temp & 0x000000FF);
1868 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1869 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )((temp & 0x0000FF00)>>8);
1870 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1871 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )((temp & 0x00FF0000)>>16);
1872 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1873 *((cyg_uint8 *)(bd.buffer)) = (cyg_uint8 )((temp & 0xFF000000)>>24);
1874 (bd.buffer) =(cyg_uint8 *)(bd.buffer) + 1;
1875 }while (!(usbs_imx_otg_base->usbcmd & BIT13));
1877 /* Write '0' to clear SUTW in USBCMD register */
1878 usbs_imx_otg_base->usbcmd &= ~BIT13;
1879 status = USB_SUCCESS;
1882 USBDBGMSG("+USBDBGMSG: setup packet:(LSB)");
1883 for(temp=0;temp<8;temp++)
1885 USBDBGMSG("%02X",g_usb_setup_data[temp]);
1887 USBDBGMSG("(MSB)\n");
1890 /* 2. Process Setup Data*/
1891 /* switch construct to handle different request*/
1892 /* Parser the Setup Request Type */
1893 switch (g_usb_setup_data[BREQUEST])
1895 case USB_GET_DESCRIPTOR:
1896 /* Handle the GET DESCRIPTOR Request */
1897 usbs_handle_get_descriptor();
1900 case USB_SET_ADDRESS:
1901 /* Handle the SET ADDRESS Request */
1902 usbs_handle_set_address();
1905 case USB_SET_CONFIGURATION:
1906 /* Handle the SET CONFIGURATION Request */
1907 if ((g_usb_setup_data[WINDEX_LOWBYTE] == 0) &&
1908 (g_usb_setup_data[WINDEX_HIGHBYTE] == 0)&&
1909 (g_usb_setup_data[WLENGTH_LOWBYTE] == 0)&&
1910 (g_usb_setup_data[WLENGTH_HIGHBYTE] == 0)&&
1911 (g_usb_setup_data[WVALUE_HIGHBYTE] == 0))
1913 usbs_handle_set_configuration();
1917 /* Send STALL Handshake */
1918 usbs_endpoint_stall(EP0,IN);
1919 //USBDBGMSG("+USBDBGMSG:EP0 IN stalled at set conf in ep0 dsr\n");
1923 case USB_GET_CONFIGURATION:
1924 /* GET CONFIGURATION request handler */
1925 usbs_handle_get_configuration();
1927 case USB_MSC_GET_MAX_LUN:
1928 usbs_handle_msc_get_maxlun();
1930 case USB_MSC_BOT_RESET:
1933 /* Send STALL Handshake */
1934 usbs_endpoint_stall(EP0,IN);
1935 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG:EP0 IN stalled in ep0 dsr\n");
1936 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG:Setup Request Type 0x%02x,0x%02X\n",g_usb_setup_data[BMREQUESTTYPE],g_usb_setup_data[BREQUEST]);
1940 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: ep0 dsr\n");
1942 /*=============================================================================
1943 // Endpoint 0 initialization.
1944 // Control Endpoint, bi-direction
1945 // This may get called during system start-up or following a reset
1947 =============================================================================*/
1949 usbs_imx_otg_dev_ep0_init(void)
1951 /*initialize Endpoint 0 Queue Header*/
1952 usbs_ep0_init_dqh();
1955 /*fill the structure for ep0*/
1956 if ((EP0_STATE_IDLE != ep0.ep_state) &&
1957 ((usbs_control_return (*)(usbs_control_endpoint*, int)) 0 != ep0.common.complete_fn))
1959 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
1960 (*ep0.common.complete_fn)(&ep0.common, -EPIPE);
1963 ep0.common.state = USBS_STATE_POWERED;
1964 memset(ep0.common.control_buffer, 0, 8);
1965 ep0.common.buffer = (unsigned char*) 0;
1966 ep0.common.buffer_size = 0;
1967 ep0.common.fill_buffer_fn = (void (*)(usbs_control_endpoint*)) 0;
1968 ep0.common.fill_data = (void*) 0;
1969 ep0.common.fill_index = 0;
1970 ep0.common.complete_fn = (usbs_control_return (*)(usbs_control_endpoint*, int)) 0;
1971 ep0.ep_state = EP0_STATE_IDLE;
1973 ep0.transmitted = 0;
1976 // ----------------------------------------------------------------------------
1977 /*=============================================================================
1978 // The start function is called by higher-level code when things have
1979 // been set up, i.e. the enumeration data is available, appropriate
1980 // handlers have been installed for the different types of control
1981 // messages, and communication with the host is allowed to start. The
1982 // next event that should happen is a reset operation from the host,
1983 // so all other interrupts should be blocked. However it is likely
1984 // that the hardware will detect a suspend state before the reset
1985 // arrives, and hence the reset will act as a resume as well as a
1987 =============================================================================*/
1989 usbs_imx_otg_dev_ep0_start(usbs_control_endpoint* endpoint)
1993 CYG_ASSERT( endpoint == &ep0.common, "USB startup involves the wrong endpoint");
1995 /*clear all interrupt status bits*/
1996 temp = usbs_imx_otg_base->usbsts;
1997 usbs_imx_otg_base->usbsts = temp; //clear all the previous interrupts
1999 /*enable all the sub-interrupt sources for USB device*/
2000 USBS_IMX_OTG_INTR_UNMASK(IMX_USB_INTR_DEV_PCE|IMX_USB_INTR_DEV_RESET|IMX_USB_INTR_DEV_USBINT);
2002 /*set Run/Stop bit to Run Mode*/
2003 usbs_imx_otg_base->usbcmd |= BIT0;
2005 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: mx37 ep0 start.\n");
2007 // ****************************************************************************
2008 // -----------------------Endpoint 1 Functions---------------------------------
2009 // ****************************************************************************
2010 /*=============================================================================
2011 // Complete a transfer. This takes care of invoking the completion
2012 // callback and resetting the buffer.
2013 =============================================================================*/
2015 ep1_rx_complete(int result)
2017 //cyg_uint32 total_bytes;
2018 cyg_uint32 dtd_address;
2019 cyg_uint32 dqh_address;
2020 cyg_uint32 received_buffer_addrs = 0x0;
2021 cyg_uint32 received_data_length = 0x0;
2022 cyg_uint32* temp = 0x0;
2026 if(g_usb_dev_state != USB_DEV_CONFIGURED_STATE)
2027 return; //EP1 only receives data when the USB device has been configured
2029 if(ep1.common.buffer == NULL)
2031 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: NULL buffer \n");
2032 return; //there is not a buffer used to store the data from host
2035 /* Get Device Device Queue Head of the out endpoint */
2036 dqh_address = USBS_EP_GET_dQH(EP1,OUT);
2038 /* Get Device Transfer Descriptor of the out endpoint */
2039 dtd_address = USBS_EP_GET_dTD(EP1,OUT);
2041 /*clear the complete status */
2042 usbs_imx_otg_base->endptcomplete |= (EPOUT_COMPLETE << EP1);
2044 //received_buffer_addrs = (*((unsigned int *)dtd_address + 2)) & 0xFFFFF000;
2045 received_buffer_addrs = (cyg_uint32)ep1.common.buffer;
2046 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: received_buffer_addrs 0x%08X \n",received_buffer_addrs);
2047 if( received_buffer_addrs == 0)
2049 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: NULL rx buffer \n");
2053 /* calculate the received data length using number of bytes left in TD */
2054 temp = (cyg_uint32 *)dtd_address;
2055 temp++; //pointer to total bytes in dtd, second work in dTD
2056 received_data_length = (ep1.common.buffer_size - (((*temp) >> 16 )&0x7FFF)); //recevied data length <= BULK_TD_BUFFER_TOTAL_SIZE
2057 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: received length %d \n",received_data_length);
2059 /* Check if the received packet is SCSI WRITE, if yes, assign the TD buffer offset
2060 is zero, otherwise, one. This is a bug in MX37 USB OTG */
2061 if((received_data_length==31)&&(*(destination_ptr+0xF)==0x2A))//WRITE10 received
2063 g_bulk_out_transdesc_buffer_offset = 0;
2064 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_start_rx - set offset to zero \n");
2067 else if((g_bulk_out_sector_number_is_one == 1)&&(received_data_length!=31)) //last bulk out data sector
2068 g_bulk_out_transdesc_buffer_offset = 1;
2071 /* tell ep1 how many bytes data is received*/
2072 ep1.fetched = received_data_length;
2076 if(ep1.fetched == 31)
2077 g_received_data_type = MASS_STORAGE_CBW_TYPE;
2079 g_received_data_type = MASS_STORAGE_DATA_TYPE;
2080 ep1.common.complete_data = (void*)(ep1.common.buffer);
2083 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: \n");
2084 USBDBGMSG(DEBUG_TRANS,"----Dump Bulk-Out Recevied Data----\n");
2087 USBDBGMSG(DEBUG_TRANS,"%02X ", *((cyg_uint8 *)(ep1.common.complete_data)+i));
2089 USBDBGMSG(DEBUG_TRANS,"\n");
2091 //USB_IMX_SET_TD_OFFSET(g_td_buffer_offset, 0);
2092 ep1.common.buffer = (unsigned char*) 0;
2093 ep1.common.buffer_size = 0;
2094 ep1_start_rx((usbs_rx_endpoint *)(&(ep1.common))); //prevent to receive more CBW before processing done
2098 if(ep1.fetched == 31)
2100 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete - recevied data: \n");
2103 USBDBGMSG(DEBUG_TRANS,"%02X ", *((cyg_uint8 *)(ep1.common.complete_data)+i));
2105 USBDBGMSG(DEBUG_TRANS,"\n");
2109 USBDBGMSG(DEBUG_TRANS,"%02X ", *((cyg_uint8 *)received_buffer_addrs+i));
2111 USBDBGMSG(DEBUG_TRANS,"\n");
2117 /*=============================================================================
2118 // Start to receive data from host. This functionality is overloaded to cope with
2119 // waiting for stalls to complete.
2120 // The transfer descriptor is prepared
2121 =============================================================================*/
2123 ep1_start_rx(usbs_rx_endpoint* endpoint)
2126 cyg_uint32 total_bytes;
2127 cyg_uint32 dtd_address;
2128 cyg_uint32 dqh_address;
2129 cyg_uint32 buffer_addrs_page0;
2131 if(g_usb_dev_state != USB_DEV_CONFIGURED_STATE)
2132 return; //EP1 only receives data when the USB device has been configured
2133 #if 0 //don't check to prevent EP1 from receiving data before processing the previous.
2134 if(endpoint->buffer == NULL)
2136 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_start_rx: NULL buffer \n");
2137 return; //there is not a buffer used to store the data from host
2140 /* Get Device Device Queue Head of the out endpoint */
2141 dqh_address = USBS_EP_GET_dQH(EP1,OUT);
2143 /* Get Device Transfer Descriptor of the out endpoint */
2144 dtd_address = USBS_EP_GET_dTD(EP1,OUT);
2146 /* ==Prepare TD for next bulk out transfer== */
2147 /* get the dTD buffer pointer */
2148 buffer_addrs_page0 = (cyg_uint32)(endpoint->buffer);
2150 /* Get the total bytes to be received */
2151 total_bytes = endpoint->buffer_size;
2154 td.dtd_base = dtd_address;
2155 td.next_link_ptr = dtd_address + 0x20;
2156 td.terminate = TERMINATE;
2157 td.total_bytes = total_bytes;
2160 td.buffer_ptr0 = buffer_addrs_page0 ;
2161 td.current_offset = ( buffer_addrs_page0 & 0xFFF ) + g_td_buffer_offset;
2167 /* re-define the buffer page pointers based on the total_bytes*/
2168 if(total_bytes > BULK_TD_BUFFER_PAGE_SIZE)
2169 td.buffer_ptr1 = (td.buffer_ptr0 + BULK_TD_BUFFER_PAGE_SIZE);
2170 if(total_bytes > BULK_TD_BUFFER_PAGE_SIZE*2)
2171 td.buffer_ptr2 = (td.buffer_ptr1 + BULK_TD_BUFFER_PAGE_SIZE);
2172 if(total_bytes > BULK_TD_BUFFER_PAGE_SIZE*3)
2173 td.buffer_ptr3 = (td.buffer_ptr2 + BULK_TD_BUFFER_PAGE_SIZE);
2175 /* Set the Transfer Descriptor */
2176 usbs_setup_transdesc(&td);
2178 /* 1. write dQH next ptr and dQH terminate bit to 0 */
2179 *(volatile cyg_uint32 *)(dqh_address+0x8)= dtd_address;
2181 /* 2. clear active & halt bit in dQH */
2182 *(volatile cyg_uint32 *)(dqh_address+0xC) &= ~0xFF;
2184 /* 3. prime endpoint by writing '1' in ENDPTPRIME
2185 prime bulk out endpoint after sending the CSW of last command
2187 //usbs_imx_otg_base->endptprime |= ( EPOUT_PRIME << EP1 );
2190 /*=============================================================================
2191 // The exported interface to halt the EP1
2192 =============================================================================*/
2194 ep1_set_halted(usbs_rx_endpoint* endpoint, cyg_bool new_value)
2196 if (ep1.common.halted == new_value) {
2200 // The endpoint should be stalled. There is a potential race
2201 // condition here with the current transfer and DSR invocation.
2202 // Updating the stalled flag means that the DSR will do nothing.
2203 usbs_endpoint_stall(EP1,OUT);
2204 ep1.common.halted = 1;
2207 // Take care of the hardware so that a new transfer is allowed.
2208 usbs_endpoint_unstall(EP1,OUT);
2209 ep1.common.halted = 0;
2213 /*=============================================================================
2214 // The DSR is invoked following an interrupt. According to the docs an
2215 // endpoint 1 interrupt can only happen if the receive-packet-complete
2217 // [Note] EP1 DSR is only used to receive the command block wrapper from host
2218 // to USB mass storage device
2219 =============================================================================*/
2222 usbs_imx_otg_dev_ep1_dsr(void)
2224 int result = 0; //contains the actual recevied data length from bulk-out endpoint
2225 g_received_data_type = 0;//MASS_STORAGE_CBW_TYPE
2227 if(ep1.common.buffer)//buffer of TD is not null, then receive
2229 ep1_rx_complete(result);
2231 //USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1 dsr - result = %d\n",result);
2232 //recevie mass storage device CBW
2234 if((ep1.fetched == 31)&&(g_received_data_type == MASS_STORAGE_CBW_TYPE))
2236 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1 dsr - CBW received\n");
2237 //post the semaphore of MSC command handler thread
2238 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2239 cyg_semaphore_post(&usbs_msc_sem);
2244 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1 dsr - received %d byte\n",ep1.fetched);
2248 /*=============================================================================
2249 // Endpoint 1 initialization.
2250 // Bulk-OUT Endpoint
2251 // This may get called during system start-up or following a reset
2253 =============================================================================*/
2255 usbs_imx_otg_dev_ep1_init(void)
2257 //at present, ep1.common.buffer is NULL. The buffer should be initialized
2258 //by upper layer caller.
2259 /*buffer is assigned in MSC initialization*/
2261 // Endpoints should never be halted during a start-up.
2262 ep1.common.halted = 0; //false =0, true =1
2263 ep1.common.complete_fn = ep1_rx_complete;
2264 // If there has been a reset and there was a receive in progress,
2265 // abort it. This also takes care of sorting out the endpoint
2266 // fields ready for the next rx.
2267 ep1_rx_complete(-EPIPE);
2270 // ****************************************************************************
2271 // -----------------------Endpoint 2 Functions---------------------------------
2272 // ****************************************************************************
2273 /*=============================================================================
2274 // A utility routine for completing a transfer. This takes care of the
2275 // callback as well as resetting the buffer.
2276 =============================================================================*/
2278 ep2_tx_complete(int result)
2280 void (*complete_fn)(void*, int) = ep2.common.complete_fn;
2281 void* complete_data = ep2.common.complete_data;
2283 ep2.common.buffer = (unsigned char*) 0;
2284 ep2.common.buffer_size = 0;
2285 ep2.common.complete_fn = (void (*)(void*, int)) 0;
2286 ep2.common.complete_data = (void*) 0;
2288 if ((void (*)(void*, int))0 != complete_fn) {
2289 (*complete_fn)(complete_data, result);
2293 /*=============================================================================
2294 // The exported interface to start to transmit data to Host
2295 =============================================================================*/
2297 ep2_start_tx(usbs_tx_endpoint* endpoint)
2301 cyg_uint32 total_bytes ;
2302 cyg_uint32 dtd_address,dqh_address;
2303 cyg_uint32 buffer_addrs_page0;
2304 cyg_uint32 size = 0x0;
2306 /* Get Device Transfer Descriptor of the requested endpoint */
2307 dtd_address = USBS_EP_GET_dTD(EP2,IN);
2309 /* Get Device Queue head of the requested endpoint */
2310 dqh_address = USBS_EP_GET_dQH(EP2,IN);
2312 /* allocate memory for data transfer */
2313 buffer_addrs_page0 = endpoint->buffer;
2315 if(buffer_addrs_page0 == 0)
2317 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep2_start_tx: NULL tx buffer \n");
2321 total_bytes = (cyg_uint32)(endpoint->buffer_size);
2322 size = (total_bytes < BULK_TD_BUFFER_TOTAL_SIZE )?total_bytes:(BULK_TD_BUFFER_TOTAL_SIZE);
2324 td.dtd_base = dtd_address;
2325 td.next_link_ptr = dtd_address + 0x20 ;
2326 td.terminate = TERMINATE;
2327 td.total_bytes = size;
2330 td.buffer_ptr0 = buffer_addrs_page0 ;
2331 td.current_offset = (buffer_addrs_page0 & 0xFFF)+ g_td_buffer_offset;
2337 /* re-define the buffer page pointers based on the total_bytes*/
2338 if(size > BULK_TD_BUFFER_PAGE_SIZE)
2339 td.buffer_ptr1 = (td.buffer_ptr0 + BULK_TD_BUFFER_PAGE_SIZE);
2340 if(size > BULK_TD_BUFFER_PAGE_SIZE*2)
2341 td.buffer_ptr2 = (td.buffer_ptr1 + BULK_TD_BUFFER_PAGE_SIZE);
2342 if(size > BULK_TD_BUFFER_PAGE_SIZE*3)
2343 td.buffer_ptr3 = (td.buffer_ptr2 + BULK_TD_BUFFER_PAGE_SIZE);
2345 /* Set the Transfer Descriptor */
2346 usbs_setup_transdesc(&td);
2348 /* 1. write dQH next ptr and dQH terminate bit to 0 */
2349 *(volatile cyg_uint32 *)(dqh_address+0x8)= (dtd_address);
2351 /* 2. clear active & halt bit in dQH */
2352 *(volatile cyg_uint32 *)(dqh_address+0xC) &= ~0xFF;
2354 /* 3. prime endpoint by writing '1' in ENDPTPRIME */
2355 usbs_imx_otg_base->endptprime = ( EPIN_PRIME << EP2 );
2357 /* wait for complete set and clear */
2358 while (!((usbs_imx_otg_base->endptcomplete) & (EPIN_COMPLETE<<EP2)));
2360 usbs_imx_otg_base->endptcomplete |= (EPIN_COMPLETE << EP2);
2362 ep2.transmitted = size;
2364 ep2_tx_complete(-EPIPE);
2366 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep2 tx done\n");// ep2.transmitted);
2369 /*=============================================================================
2370 // The exported interface to halt the EP2
2371 =============================================================================*/
2373 ep2_set_halted(usbs_tx_endpoint* endpoint, cyg_bool new_value)
2375 if (ep2.common.halted == new_value) {
2379 // The endpoint should be stalled. There is a potential race
2380 // condition here with the current transfer and DSR invocation.
2381 // Updating the stalled flag means that the DSR will do nothing.
2382 usbs_endpoint_stall(EP2,IN);
2383 ep2.common.halted = 1;
2386 // Take care of the hardware so that a new transfer is allowed.
2387 usbs_endpoint_unstall(EP2,IN);
2388 ep2.common.halted = 0;
2391 /*=============================================================================
2392 // The dsr will be invoked when the transmit-packet-complete bit is
2393 // set. Typically this happens when a packet has been completed
2394 =============================================================================*/
2397 usbs_imx_otg_dev_ep2_dsr(void)
2399 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep2 dsr\n");
2400 /* EP2 DSR will be called as soon as a transfer complete to clear status*/
2401 usbs_imx_otg_base->endptcomplete |= (EPIN_COMPLETE << EP2);
2404 if(ep2.common.buffer_size==0)
2406 ep2_tx_complete(-EPIPE);
2407 ep2.transmitted = 0; //clear the field to wait for the next transmit
2412 /*=============================================================================
2413 // Endpoint 2 initialization.
2415 // This may be called during system start-up or following a reset
2417 =============================================================================*/
2419 usbs_imx_otg_dev_ep2_init(void)
2421 //at initialization, ep2.common.buffer is NULL. The buffer should be initialized
2422 //by upper layer caller.
2424 // Endpoints should never be halted after a reset
2425 ep2.common.halted = false;
2427 // If there has been a reset and there was a receive in progress,
2428 // abort it. This also takes care of clearing the endpoint
2429 // structure fields.
2430 ep2_tx_complete(-EPIPE);
2433 // ****************************************************************************
2434 // -----------------------MX37 USB Device Driver API Functions-----------------
2435 // ****************************************************************************
2437 /*=============================================================================
2438 // The DSR. This can be invoked directly by poll(), or via the usual
2439 // interrupt subsystem. It acts as per the current value of
2440 // g_isr_status_bits. If another interrupt goes off while this
2441 // DSR is running, there will be another invocation of the DSR and
2442 // the status bits will be updated.
2443 =============================================================================*/
2445 usbs_imx_otg_dev_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
2449 CYG_ASSERT(MX51_IRQ_USB_SERVICE_REQUEST == vector, "USB DSR should only be invoked for USB interrupts" );
2450 CYG_ASSERT(0 == data, "The i.MX37 USB DSR needs no global data pointer");
2451 //USBDBGMSG("+USBDBGMSG: enter mx37 dsr\n");
2452 // There is no atomic swap support, so interrupts have to be
2453 // blocked. It might be possible to do this via the USBS_CONTROL
2454 // register, but at the risk of messing up the status register
2455 // if another interrupt comes in. Blocking interrupts at the
2456 // processor level is less intrusive on the USB code.
2457 //cyg_drv_isr_lock();
2458 status = g_isr_status_bits;
2459 g_isr_status_bits = 0;
2460 //cyg_drv_isr_unlock();
2462 // Reset is special, since it invalidates everything else.
2463 // If the reset is still ongoing then do not attempt any
2464 // further processing, there will just be another interrupt.
2465 // Otherwise handle_reset() does the hard work. Unmasking
2466 // the interrupt means that another interrupt will occur
2467 // immediately if reset is still asserted, i.e. no threads
2468 // will run, but there is no easy way of triggering action
2469 // at the end of reset.
2470 if (status & IMX_USB_STS_RESET)
2472 int new_status = usbs_imx_otg_base->usbsts;
2473 if (0 == (new_status & IMX_USB_STS_RESET))
2475 usbs_imx_otg_dev_handle_bus_reset();
2476 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: !!USB BUS RESET\n");
2479 // This unmask is likely to cause another interrupt immediately
2480 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2481 cyg_interrupt_unmask(MX51_IRQ_USB_SERVICE_REQUEST);
2484 else if(status & IMX_USB_STS_USBINT)
2487 if(usbs_imx_otg_base->endptsetupstat & BIT0)
2488 {// if Setup Packet arrived
2489 usbs_imx_otg_dev_ep0_dsr();
2492 else if((usbs_imx_otg_base->endptcomplete) & ( EPIN_COMPLETE << EP2))
2493 {// EP2 Queue Header buffer completes sending data
2494 //complete bit is cleared in ep2_start_tx
2498 else if((usbs_imx_otg_base->endptcomplete) & ( EPOUT_COMPLETE << EP1))
2499 {// EP1 Queue Header buffer get data
2500 usbs_imx_otg_dev_ep1_dsr();
2504 else if((usbs_imx_otg_base->endptcomplete) & ( EPOUT_COMPLETE << EP0))
2506 //usbs_imx_otg_dev_ep0_dsr();
2507 usbs_imx_otg_base->endptcomplete = ( EPOUT_COMPLETE << EP0);
2510 {//do nothing, only for constructure integrity
2511 temp = usbs_imx_otg_base->endptcomplete;
2512 usbs_imx_otg_base->endptcomplete = temp;
2513 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: usbsts int - unknown.\n");
2516 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2517 // This unmask is likely to cause another interrupt immediately
2518 cyg_interrupt_unmask(MX51_IRQ_USB_SERVICE_REQUEST);
2523 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2524 // This unmask is likely to cause another interrupt immediately
2525 cyg_interrupt_unmask(MX51_IRQ_USB_SERVICE_REQUEST);
2531 /*=============================================================================
2533 =============================================================================*/
2534 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2535 #define CYGNUM_DEVS_USB_OTG_DEV_THREAD_STACK_SIZE 1024
2536 #define CYGNUM_DEVS_USB_OTG_DEV_THREAD_PRIORITY 29
2537 static unsigned char usbs_imx_otg_dev_thread_stack[CYGNUM_DEVS_USB_OTG_DEV_THREAD_STACK_SIZE];
2538 static cyg_thread usbs_imx_otg_dev_thread;
2539 static cyg_handle_t usbs_imx_otg_dev_thread_handle;
2540 static cyg_sem_t usbs_imx_otg_dev_sem;
2544 usbs_imx_otg_dev_thread_fn(cyg_addrword_t param)
2546 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: usb driver thread\n");
2548 cyg_semaphore_wait(&usbs_imx_otg_dev_sem);
2549 usbs_imx_otg_dev_dsr(IMX_IRQ_USB_DEV_SERVICE_REQUEST, 0, 0);
2551 CYG_UNUSED_PARAM(cyg_addrword_t, param);
2555 usbs_imx_otg_dev_thread_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
2557 CYG_ASSERT( 0 != isr_status_bits, "DSR's should only be scheduled when there is work to do");
2558 cyg_semaphore_post(&usbs_imx_otg_dev_sem);
2561 CYG_UNUSED_PARAM(cyg_vector_t, vector);
2562 CYG_UNUSED_PARAM(cyg_ucount32, count);
2563 CYG_UNUSED_PARAM(cyg_addrword_t, data);
2566 /*=============================================================================
2567 // The interrupt handler. This does as little as possible.
2568 =============================================================================*/
2570 usbs_imx_otg_dev_isr(cyg_vector_t vector, cyg_addrword_t data)
2572 cyg_uint32 old_status_bits = g_isr_status_bits;
2573 cyg_uint32 status_bits;
2575 CYG_ASSERT(IMX_IRQ_USB_DEV_SERVICE_REQUEST == vector, "USB ISR should only be invoked for USB interrupts" );
2576 CYG_ASSERT(0 == data, "The MX51 USB ISR needs no global data pointer" );
2578 //USBDBGMSG("+USBDBGMSG: enter mx51 isr\n");
2579 // Read the current status. Reset is special, it means that the
2580 // whole chip has been reset apart from the one bit in the status
2581 // register. Nothing should be done about this until the DSR sets
2582 // the endpoints back to a consistent state and re-enables
2583 // interrupts in the control register.
2584 status_bits = usbs_imx_otg_base->usbsts;
2585 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: usb intr 0x%08X\n",status_bits);
2586 if (status_bits & IMX_USB_STS_RESET)
2589 g_isr_status_bits |= IMX_USB_STS_RESET;
2590 usbs_imx_otg_base->usbsts |= IMX_USB_STS_RESET;
2591 cyg_interrupt_mask(IMX_IRQ_USB_DEV_SERVICE_REQUEST);
2593 else if(status_bits & IMX_USB_STS_USBINT)
2595 g_isr_status_bits |= IMX_USB_STS_USBINT;
2596 usbs_imx_otg_base->usbsts |= IMX_USB_STS_USBINT;
2597 cyg_interrupt_mask(IMX_IRQ_USB_DEV_SERVICE_REQUEST);
2601 usbs_imx_otg_base->usbsts = status_bits; //clear the status bit of USBSTS
2602 g_isr_status_bits &= ~status_bits;
2603 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: unknown usb intr\n");
2606 // Now keep the rest of the system happy.
2607 cyg_interrupt_acknowledge(vector); //reenable the USB interrupt
2608 return (old_status_bits != g_isr_status_bits) ? CYG_ISR_CALL_DSR : CYG_ISR_HANDLED;
2610 /*=============================================================================
2611 // Polling support. This acts mostly like the interrupt handler: it
2612 // sets the isr status bits and causes the dsr to run. Reset has to be
2613 // handled specially: polling does nothing as long as reset is asserted.
2614 =============================================================================*/
2616 usbs_imx_otg_dev_poll(usbs_control_endpoint* endpoint)
2618 CYG_ASSERT( endpoint == &ep0.common, "USB poll involves the wrong endpoint");
2620 if (g_isr_status_bits & IMX_USB_STS_RESET)
2622 // Reset was detected the last time poll() was invoked. If
2623 // reset is still active, do nothing. Once the reset has
2624 // completed things can continue.
2625 if (0 == (IMX_USB_STS_RESET & usbs_imx_otg_base->usbsts))
2627 g_isr_status_bits = 0;
2628 usbs_imx_otg_dev_handle_bus_reset();
2633 g_isr_status_bits = usbs_imx_otg_base->usbsts;
2634 if (IMX_USB_STS_PTCHANGE & g_isr_status_bits)
2636 //process Port Change Detect
2637 usbs_imx_otg_dev_handle_port_change();
2639 else if (IMX_USB_STS_USBINT & g_isr_status_bits)
2641 usbs_imx_otg_dev_dsr(IMX_IRQ_USB_DEV_SERVICE_REQUEST, 0, (cyg_addrword_t) 0);
2645 usbs_imx_otg_base->usbsts = g_isr_status_bits; //clear the don't-care status
2649 /*=============================================================================
2650 // Perform reset operations on all endpoints that have been
2651 // configured in. It is convenient to keep this in a separate
2652 // routine to allow for polling, where manipulating the
2653 // interrupt controller mask is a bad idea.
2654 =============================================================================*/
2656 usbs_imx_otg_dev_handle_bus_reset(void)
2660 usbs_imx_otg_base->usbcmd &= ~BIT0; //detach device from bus temprorarily
2661 usbs_imx_otg_base->usbsts |= BIT6; //clear reset bit in USBSTS
2663 //temp = usbs_imx_otg_base->usbsts;
2664 //usbs_imx_otg_base->usbsts = temp;
2666 /*1. Reading and writing back the ENDPTSETUPSTAT register
2667 clears the setup token semaphores */
2668 temp = usbs_imx_otg_base->endptsetupstat;
2669 usbs_imx_otg_base->endptsetupstat = temp;
2671 /*2. Reading and writing back the ENDPTCOMPLETE register
2672 clears the endpoint complete status bits */
2673 temp = usbs_imx_otg_base->endptcomplete;
2674 usbs_imx_otg_base->endptcomplete = temp;
2676 /*3. Cancel all primed status by waiting until all bits in ENDPTPRIME are 0
2677 and then write 0xFFFFFFFF to ENDPTFLUSH */
2678 while(usbs_imx_otg_base->endptprime);
2679 usbs_imx_otg_base->endptflush = 0xFFFFFFFF;
2682 /*4. Initialize EP0 Queue Head again*/
2683 usbs_ep0_init_dqh();
2685 usbs_imx_otg_base->endptlistaddr = g_bulkbuffer_map.ep_dqh_base_addrs;
2687 usbs_imx_otg_base->usbcmd |= BIT0; //re-attach device to the bus
2689 g_usb_dev_state = USB_DEV_DEFAULT_STATE;
2693 /*=============================================================================
2694 // Perform port change operations on all endpoints that have been
2695 // configured in. It is convenient to keep this in a separate
2696 // routine to allow for polling, where manipulating the
2697 // interrupt controller mask is a bad idea.
2698 =============================================================================*/
2700 usbs_imx_otg_dev_handle_port_change(void)
2702 /*Port Change happens when USB device enters/exits FS or HS mode
2703 When exiting from FS or HS due to Bus reset or DCSuspend, the notification
2704 mechanisms are Reset Received and DCSuspend.
2705 This function only processes the port change on entering FS or HS
2706 Don't enable Port Change Detect interrupt, it's no sense for operation.*/
2707 usbs_imx_otg_base->usbsts |= IMX_USB_STS_PTCHANGE; //clear Port change status
2711 // ****************************************************************************
2712 // ----------------------------------------------------------------------------
2713 // ****************************************************************************
2714 /*=============================================================================
2715 FUNCTION: usbs_imx_otg_dev_set_configuration
2716 DESCRIPTION: This function Handle the SET CONFIGRATION Request.
2717 ARGUMENTS PASSED: usb_end_pt_info_t* config_data;
2719 IMPORTANT NOTES: None
2720 =============================================================================*/
2722 usbs_imx_otg_dev_set_configuration(usb_end_pt_info_t* config_data)
2725 cyg_uint32 total_bytes = 0x0;
2726 cyg_uint32 buffer_addrs_page0 = 0;
2727 cyg_uint32 dqh_address = 0;
2728 cyg_uint32 dtd_address = 0;
2729 cyg_uint8 endpt_num,direction;
2734 /* get endpoint number to be configured and its direction */
2735 endpt_num= config_data->end_pt_no;
2736 direction= config_data->direction;
2737 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: set config - ep%d\n",endpt_num);
2738 /* Check if the endpoint number and direction is withing the permitted range or not */
2739 if (( endpt_num != EP0 ) && (endpt_num <= ( g_max_ep_supported - 1)) &&
2740 ( direction == OUT || direction == IN))
2742 /* get the device q head and deice TD */
2743 dqh_address = USBS_EP_GET_dQH(endpt_num,direction);
2744 dtd_address = USBS_EP_GET_dTD(endpt_num,direction);
2746 if ( direction == OUT )
2748 total_bytes = BULK_BUFFER_SIZE ;
2750 qhead.dqh_base = dqh_address;
2751 qhead.zlt = ZLT_DISABLE;
2752 qhead.mps = config_data->max_pkt_size;
2753 qhead.ios = IOS_SET;
2754 qhead.next_link_ptr = dtd_address ;
2755 qhead.terminate = TERMINATE;
2756 qhead.total_bytes = total_bytes;
2757 qhead.ioc = IOC_SET;
2758 qhead.status = NO_STATUS;
2759 qhead.buffer_ptr0 = 0;
2760 qhead.current_offset= 0;
2761 qhead.buffer_ptr1 = 0;
2762 qhead.buffer_ptr2 = 0;
2763 qhead.buffer_ptr3 = 0;
2764 qhead.buffer_ptr4 = 0;
2766 usbs_setup_queuehead(&qhead);
2768 /* Endpoint 1 : MPS = 64, OUT (Rx endpoint) */
2769 usbs_imx_otg_base->endptctrl[endpt_num] = 0x00080048;
2770 /* Enable EP1 OUT */
2771 usbs_imx_otg_base->endptctrl[endpt_num] |= EPOUT_ENABLE;
2773 /* allocate buffer for receiving data */
2774 /* free the usb buffer after re-enumeration*/
2775 //g_bulkbuffer_map.buffer1_status = BUFFER_FREE;
2776 //g_bulkbuffer_map.buffer2_status = BUFFER_FREE;
2777 g_bulkbuffer_a.stat = BUFFER_FREED;
2778 g_bulkbuffer_b.stat = BUFFER_FREED;
2780 //buffer_addrs_page0 = util_alloc_buffer();
2781 ep1.common.buffer = g_bulkbuffer_a.buffer;
2782 ep1.common.buffer_size = total_bytes;
2783 g_bulkbuffer_a.stat = BUFFER_ALLOCATED;
2784 buffer_addrs_page0 = (cyg_uint32)(ep1.common.buffer);
2787 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: set config - ep1 dtd buffer 0x%08X\n",buffer_addrs_page0);
2790 td.dtd_base = dtd_address;
2791 td.next_link_ptr = dtd_address + 0x20;
2792 td.terminate = TERMINATE;
2793 td.total_bytes = total_bytes;
2796 td.buffer_ptr0 = buffer_addrs_page0;
2797 td.current_offset = (buffer_addrs_page0 & 0xFFF) + g_td_buffer_offset;
2798 td.buffer_ptr1 = 0x0;
2799 td.buffer_ptr2 = 0x0;
2800 td.buffer_ptr3 = 0x0;
2801 td.buffer_ptr4 = 0x0;
2803 /* Set the Transfer Descriptor */
2804 usbs_setup_transdesc(&td);
2806 /* 1. write dQH next ptr and dQH terminate bit to 0 */
2807 *(volatile cyg_uint32*)(dqh_address+0x8)= dtd_address;
2809 /* 2. clear active & halt bit in dQH */
2810 *(volatile cyg_uint32*)(dqh_address+0xC) &= ~0xFF;
2812 /* 3. prime endpoint by writing '1' in ENDPTPRIME */
2813 usbs_imx_otg_base->endptprime |= ( EPOUT_PRIME << endpt_num );
2814 /* Endpoint Configured for output */
2815 g_out_endpoint= endpt_num;
2824 qhead.dqh_base = USBS_EP_GET_dQH(endpt_num,direction);
2825 qhead.zlt = ZLT_DISABLE;
2826 qhead.mps = config_data->max_pkt_size;
2827 qhead.ios = IOS_SET;
2828 qhead.next_link_ptr = USBS_EP_GET_dQH(endpt_num,direction);
2829 qhead.terminate = TERMINATE;
2830 qhead.total_bytes = total_bytes;
2831 qhead.ioc = IOC_SET;
2832 qhead.status = NO_STATUS;
2833 qhead.buffer_ptr0 = 0;
2834 qhead.current_offset= 0;
2835 qhead.buffer_ptr1 = 0;
2836 qhead.buffer_ptr2 = 0;
2837 qhead.buffer_ptr3 = 0;
2838 qhead.buffer_ptr4 = 0;
2840 usbs_setup_queuehead(&qhead);
2842 /* Endpoint Configured for Input */
2843 g_in_endpoint= endpt_num;
2845 /* Endpoint 2: MPS = 64, IN (Tx endpoint) */
2846 usbs_imx_otg_base->endptctrl[endpt_num] = 0x00480008;
2849 usbs_imx_otg_base->endptctrl[endpt_num] |= EPIN_ENABLE;
2851 /* 3. prime endpoint by writing '1' in ENDPTPRIME */
2852 usbs_imx_otg_base->endptprime |= (EPIN_PRIME << g_in_endpoint);
2858 /* TODO: error handling TBD */
2863 static void usbs_imx_otg_config_utmi_clock(void)
2865 #if defined(CYGHWR_USB_DEVS_MX37_OTG)
2866 USB_MX37_SET_PHY_CLK_24MHZ();
2869 #if defined(CYGHWR_USB_DEVS_MX51_OTG)
2871 /*Configure USB_PHYCLOCK_ROOT source as 24MHz OSC*/
2872 CCM_CSCMR1_REGVAL = CCM_CSCMR1_REGVAL & (~CSCMR1_USBOH3_PHY_CLK_SEL_VALUE); //configure USB CRM
2873 /*Configure plldivvalue of USB_PHY_CTRL_1_REG for 24 Mhz*/
2874 temp = *(volatile cyg_uint32 *)USB_PHY_CTRL_1_REG;
2875 temp &= ~USB_PHY_CTRL_PLLDIVVALUE_MASK;
2876 temp |= USB_PHY_CTRL_PLLDIVVALUE_24_MHZ;
2877 *(volatile cyg_uint32 *)USB_PHY_CTRL_1_REG = temp;
2881 /*=============================================================================
2882 // The USB OTG hardware relevant initialization.
2883 =============================================================================*/
2885 usbs_imx_otg_hardware_init(void)
2888 cyg_uint32 timeout = 0x1D0000;
2889 usb_plat_config_data_t config_data_ptr;
2892 /*Enable USB Internal PHY Clock as 24MHz on-board Ocsillator*/
2893 usbs_imx_otg_config_utmi_clock();
2895 {/*Setup USB Buffer Map*/
2896 config_data_ptr.buffer_address = (cyg_uint32)usb_buffer;
2897 config_data_ptr.buffer_size = BUFFER_SIZE;
2899 /* Base address of the buffer allocated to IP Layer */
2900 g_bulkbuffer_address_base = config_data_ptr.buffer_address;
2902 /* length of the buffer */
2903 g_bulkbuffer_length = config_data_ptr.buffer_size;
2905 /* Maximum Number of EPs to be confiured */
2906 g_max_ep_supported = (( g_bulkbuffer_length - TOTAL_DATA_BUFFER_SIZE)/(BUFFER_USED_PER_EP)); //=(2048-1088)/256~=3.75->3
2908 /* Base of queue Head Pointer */
2909 g_bulkbuffer_map.ep_dqh_base_addrs = g_bulkbuffer_address_base;
2911 /* Total size of qhead */
2912 temp = (SIZE_OF_QHD * (g_max_ep_supported * 2)); //total size of QH is 384byte
2914 /* Base Address of dTDs */
2915 g_bulkbuffer_map.ep_dtd_base_addrs = (g_bulkbuffer_map.ep_dqh_base_addrs + temp);
2917 /* Total size of transfer descriptor */
2918 temp = ((dTD_SIZE_EPIN * g_max_ep_supported) + (dTD_SIZE_EPOUT * g_max_ep_supported )); //total size of TD is 384 byte
2920 /* Base Address of EP0 Buffer */
2921 g_bulkbuffer_map.ep0_buffer_addrs = (g_bulkbuffer_map.ep_dtd_base_addrs + temp ); //256byte
2923 /*Bulk Buffer Areas, 512byte per buffer*/
2924 /*Actually, the dual 512 byte bulk buffers are not used, because two larger 16kB bulk buffers are used*/
2925 /* transfer buffer 1 */
2926 g_bulkbuffer_map.buffer1_address=(g_bulkbuffer_address_base + g_bulkbuffer_length -(BULK_BUFFER_SIZE*NUM_OF_BULK_BUFFER));
2927 g_bulkbuffer_map.buffer1_status = BUFFER_FREE;
2929 /* transfer buffer 2 */
2930 g_bulkbuffer_map.buffer2_address = g_bulkbuffer_map.buffer1_address + BULK_BUFFER_SIZE;
2931 g_bulkbuffer_map.buffer2_status = BUFFER_FREE;
2934 {/*Set USB OTG at device only mode*/
2935 usbs_imx_otg_base->usbmode = 0x2; //set OTG as a device controller
2937 while (!(usbs_imx_otg_base->usbmode == 0x2))
2939 if(temp != (usbs_imx_otg_base->usbmode))
2941 temp = (usbs_imx_otg_base->usbmode);
2942 USBDBGMSG(DEBUG_BASIC,"usbmode is 0x%08X\n",temp);
2945 if(timeout==0) break;
2946 } //check that device controller was configured to device mode only
2950 usbs_imx_otg_base->endptlistaddr = g_bulkbuffer_map.ep_dqh_base_addrs; // Configure ENDPOINTLISTADDR Pointer
2951 usbs_imx_otg_base->otgsc |= BIT3; // Set OTG termination, controls the pulldown on DM
2952 usbs_imx_otg_base->endptnak = 0x00010001; // Enable Endpoint NAK
2953 usbs_imx_otg_base->usbmode |= BIT3; // Disable Setup Lockout by writing '1' to SLOM in USBMODE
2954 //usbs_imx_otg_base->usbcmd |= BIT0; // Set Run/Stop bit to Run Mode, make USB run in usbs_imx_otg_dev_ep0_start()
2958 /* set it to be utmi interface */
2959 temp = usbs_imx_otg_base->portsc1;
2960 temp &= ~USB_OTG_TRANS_MASK;
2961 temp |= USB_OTG_TRANS_UTMI;
2962 temp &= ~USB_OTG_FS_ONLY; //enable high speed
2963 temp |= USB_OTG_TRANS_WIDTH;
2965 usbs_imx_otg_base->portsc1 = temp;
2968 {// The USB OTG transaction relevant initialization.
2969 /* Select the common descriptors , these descriptor are independent of speed and security mode */
2970 g_usb_desc.device_desc = &g_usb_device_desc ;
2971 g_usb_desc.config_desc = &g_usb_config_desc;
2972 g_usb_desc.sn_desc = &g_usb_serialnumber_desc;
2973 g_usb_desc.str_desc0 = &g_usb_otg_str0_desc; //language desc
2974 g_usb_desc.str_desc1 = &g_usb_otg_string_desc1; //Manufacturer desc
2975 g_usb_desc.str_desc2 = &g_usb_otg_string_desc2; //USB Name Desc
2976 g_usb_desc.str_desc3 = &g_usb_otg_string_desc3; //Device Name Desc
2978 /* Get Number of Endpoints supported from Configuration Descriptor*/
2979 g_number_of_endpoints = g_usb_desc.config_desc->usb_interface_desc.number_endpoints;
2981 /* Store the Endpoint specific information in local variable structure to this Layer */
2982 for ( i = 0 ; i< g_number_of_endpoints ; i++)
2984 g_end_pt_info[i].end_pt_no = ((g_usb_desc.config_desc->usb_endpoint_desc[i].endpoint) & ENDPT_NUMBER_MASK);
2985 g_end_pt_info[i].direction = (((g_usb_desc.config_desc->usb_endpoint_desc[i].endpoint) & ENDPT_DIR_MASK )>>ENDPT_DIR_SHIFT);
2986 g_end_pt_info[i].transfer_type = (g_usb_desc.config_desc->usb_endpoint_desc[i].attributes & ENDPT_TRNS_TYPE_MASK);
2987 g_end_pt_info[i].max_pkt_size = ((g_usb_desc.config_desc->usb_endpoint_desc[i].max_packet_lo) \
2988 | (( g_usb_desc.config_desc->usb_endpoint_desc[i].max_packet_hi ) << 8 ));
2991 g_usb_dev_state = USB_DEV_DEFAULT_STATE;
2994 // ****************************************************************************
2995 // ----------------------------------------------------------------------------
2996 // ****************************************************************************
2997 /*=============================================================================
2998 // Initialization i.MX37(Marley) USB OTG Hardware
2999 // This function is the only extern function of this device driver, and it
3000 // registers the driver ISR and DSRs to the kernel.
3001 =============================================================================*/
3003 usbs_imx_otg_device_init(void) //works like usb port open when
3005 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: USB Device Driver Start Initializing...\n");
3006 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: USB OTG REG BASE@0x%08X\n",USB_BASE_ADDRESS);
3007 g_usb_setup_data = ep0.common.control_buffer;
3009 g_td_buffer_offset = 0;
3010 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
3011 USB_IMX_SET_TD_OFFSET(g_td_buffer_offset,1);
3014 /*ping-pang buffer A*/
3015 g_bulkbuffer_a.buffer = bulk_buffer;
3016 g_bulkbuffer_a.stat = BUFFER_FREED;
3018 /*ping-pang buffer B*/
3019 g_bulkbuffer_b.buffer = bulk_buffer + BULK_TD_BUFFER_TOTAL_SIZE;
3020 g_bulkbuffer_b.stat = BUFFER_FREED;
3022 usbs_imx_otg_hardware_init();
3023 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: Usb Hardware Initialize Complete.\n");
3024 usbs_imx_otg_dev_ep0_init();
3025 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: Usb Ep0 Initialize Complete.\n");
3026 usbs_imx_otg_dev_ep1_init();
3027 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: Usb Ep1 Initialize Complete.\n");
3028 usbs_imx_otg_dev_ep2_init();
3029 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: Usb Ep2 Initialize Complete.\n");
3031 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
3032 cyg_semaphore_init(&usbs_imx_otg_dev_sem, 0);
3033 cyg_thread_create(CYGNUM_DEVS_USB_OTG_DEV_THREAD_PRIORITY,
3034 &usbs_imx_otg_dev_thread_fn,
3036 "i.MX37/51 USB Device",
3037 usbs_imx_otg_dev_thread_stack,
3038 CYGNUM_DEVS_USB_OTG_DEV_THREAD_STACK_SIZE,
3039 &usbs_imx_otg_dev_thread_handle,
3040 &usbs_imx_otg_dev_thread
3042 cyg_thread_resume(usbs_imx_otg_dev_thread_handle);
3043 // It is also possible and desirable to install the interrupt
3044 // handler here, even though there will be no interrupts for a
3046 cyg_interrupt_create(IMX_IRQ_USB_DEV_SERVICE_REQUEST,
3047 IMX_IRQ_USB_DEV_PRIORITY, // priority
3049 &usbs_imx_otg_dev_isr,
3050 &usbs_imx_otg_dev_thread_dsr,
3051 &g_usbs_dev_intr_handle,
3052 &g_usbs_dev_intr_data);
3053 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: cyg_interrupt_create@vector %d.\n",IMX_IRQ_USB_DEV_SERVICE_REQUEST);
3054 cyg_interrupt_attach(g_usbs_dev_intr_handle); //fill interrupt handler table for USB
3055 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: cyg_interrupt_attach.\n");
3056 cyg_interrupt_unmask(IMX_IRQ_USB_DEV_SERVICE_REQUEST); //enable USB interrrupt
3057 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: cyg_interrupt_unmask.\n");
3059 ep0.common.start_fn(&(ep0.common));
3064 usbs_imx_otg_device_deinit(void) //works like usb port close
3066 usbs_imx_otg_base->usbcmd &= (~BIT0); // Set Run/Stop bit to Stop Mode
3067 g_usb_dev_state = USB_DEV_DUMMY_STATE;
3070 #if defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
3072 static cyg_uint32 get_free_bulk_buffer(void)
3074 cyg_uint32 buff_addr = 0;
3076 while(buff_addr == 0)
3078 if(g_bulkbuffer_a.stat == BUFFER_FREED)
3080 buff_addr = (cyg_uint32)(g_bulkbuffer_a.buffer);
3083 else if(g_bulkbuffer_b.stat == BUFFER_FREED)
3085 buff_addr = (cyg_uint32)(g_bulkbuffer_b.buffer);
3094 diag_printf("no bulk buffer free\n");
3104 cyg_bool set_status_bulk_buffer(cyg_uint32 buff_addr, int buff_stat)
3106 cyg_bool ret = true;
3107 if(buff_addr == (cyg_uint32)(g_bulkbuffer_a.buffer))
3108 g_bulkbuffer_a.stat = buff_stat;
3109 else if (buff_addr == (cyg_uint32)(g_bulkbuffer_b.buffer))
3110 g_bulkbuffer_b.stat = buff_stat;
3116 static usb_status_t usb_bulk_receive_data(usb_buffer_descriptor_t * bd)
3118 usb_status_t status;
3121 /* Check if Bus Reset Received */
3122 if((usbs_imx_otg_base->usbsts) & IMX_USB_STS_RESET)
3124 /* Handle Bus Reset */
3125 usbs_imx_otg_dev_handle_bus_reset();
3127 /* Check if Reset is already received and Setup Token Received */
3128 if((usbs_imx_otg_base->endptsetupstat) & BIT0)
3130 /* Handle Setup Token */
3131 usbs_imx_otg_dev_ep0_dsr();
3134 if((usbs_imx_otg_base->endptcomplete) & ( EPOUT_COMPLETE << EP1))
3136 ep1_rx_complete(res);
3137 if(ep1.common.complete_data)
3139 bd->bytes_transfered = ep1.fetched;
3140 memcpy(bd->buffer,ep1.common.complete_data,ep1.fetched);
3142 //D("+USBDBGMSG:bd->bytes_transfered %d\n",bd->bytes_transfered);
3143 set_status_bulk_buffer((cyg_uint32)(ep1.common.complete_data), BUFFER_FREED);
3144 ep1.common.buffer = (unsigned char *)get_free_bulk_buffer();
3145 ep1.common.buffer_size = BULK_TD_BUFFER_TOTAL_SIZE;
3146 ep1_start_rx(&(ep1.common));
3147 usbs_imx_otg_base->endptprime |= ( EPOUT_PRIME << EP1 );//prime ep1 td
3148 status = USB_SUCCESS;
3152 status = USB_FAILURE;
3157 static usb_status_t usb_bulk_transmit_data(usb_buffer_descriptor_t * bd)
3159 //usb_state_t status;
3163 ep2.common.buffer = (unsigned char *)get_free_bulk_buffer();
3164 set_status_bulk_buffer((cyg_uint32)(ep2.common.buffer), BUFFER_ALLOCATED);
3165 ep2.common.buffer_size = (BULK_TD_BUFFER_TOTAL_SIZE<(bd->size))?BULK_TD_BUFFER_TOTAL_SIZE:(bd->size);
3166 memcpy((ep2.common.buffer),(bd->buffer),(ep2.common.buffer_size));
3167 ep2_start_tx(&(ep2.common));
3169 bd->size -= (ep2.common.buffer_size);
3174 static cyg_uint32 usb_rx_processing(cyg_uint8* read_ptr, usb_status_t* status, cyg_uint32 data_length)
3176 cyg_uint32 bytes_received = 0;
3177 if ( (status != NULL) && (read_ptr != NULL) )
3179 usb_status_t trans_status = USB_FAILURE;
3181 usb_buffer_descriptor_t buf_desc;
3183 /* Prepare the buffer descriptor for USB transfer */
3184 //(cyg_uint8*)(buf_desc.buffer) = read_ptr;
3185 buf_desc.buffer = (void *)read_ptr;
3186 while(data_length != 0)
3188 buf_desc.size = data_length;
3189 buf_desc.bytes_transfered = 0;
3191 /* Receive data from USB */
3192 trans_status = (usb_status_t )usb_bulk_receive_data(&buf_desc);
3193 if(trans_status == USB_SUCCESS)
3195 data_length -= buf_desc.bytes_transfered;
3196 bytes_received += buf_desc.bytes_transfered;
3198 (buf_desc.buffer) += buf_desc.bytes_transfered;
3202 *status = USB_FAILURE;
3206 if(g_timeout_value%0x1000000==0) D("C");
3207 if(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT) return 0;
3211 return ( bytes_received );
3213 static usb_status_t usb_tx_processing(cyg_uint8* write_ptr, cyg_uint32 data_len)
3215 usb_status_t trans_status = USB_FAILURE;
3217 /* Prepare the buffer descriptor for USB transfer */
3218 usb_buffer_descriptor_t buf_desc;
3220 /* Prepare transfer buffer descriptor*/
3221 buf_desc.buffer = (void *)write_ptr;
3222 buf_desc.size = data_len;
3223 buf_desc.bytes_transfered = 0;
3225 /* Send data over USB */
3226 trans_status = usb_bulk_transmit_data(&buf_desc);
3228 return trans_status;
3230 static cyg_bool pl_get_command(void)
3233 usb_status_t status;
3234 cyg_uint32 bytes_recvd = 0;
3235 cyg_uint8 start_command = 0xFF;
3237 while(start_command == 0xFF)
3239 //g_timeout_value++;
3240 //if(g_timeout_value%1000==0) D("C");
3241 //D("%d\n",g_timeout_value);
3242 bytes_recvd = usb_rx_processing(sdp_payload_data, &status, SDP_CMD_MAX_LEN);
3243 start_command = pl_command_start();
3244 if(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT) return false;
3246 //D("+USBDBGMSG: start_command = 0x%02X\n",start_command);
3247 if(start_command == 0xF0)
3249 //copy rest of the bytes
3250 for(i=1; i < SDP_CMD_MAX_LEN; i++)
3252 sdp_command[i] = sdp_payload_data[i-1];
3257 //copy starting bytes
3258 for(i=0; i < (SDP_CMD_MAX_LEN - start_command) ; i++)
3260 sdp_command[i] = sdp_payload_data[i + start_command];
3263 if(start_command != 0)
3265 //receive rest of the bytes
3266 bytes_recvd = usb_rx_processing(sdp_payload_data, &status, start_command);
3268 if(bytes_recvd == start_command)
3270 for(i=0; i <start_command; i++)
3272 sdp_command[SDP_CMD_MAX_LEN - start_command + i] = sdp_payload_data[i];
3280 static cyg_uint8 pl_command_start(void)
3283 static cyg_uint8 last_byte = 0;
3285 if(last_byte != 0x0)
3287 if(last_byte == sdp_payload_data[0])
3289 sdp_command[0] = last_byte;
3290 last_byte = sdp_payload_data[SDP_CMD_MAX_LEN -1];
3295 for(i=0; i < SDP_CMD_MAX_LEN -1; i++)
3297 if((sdp_payload_data[i] == 0x01) && (sdp_payload_data[i+1] == 0x01) ||
3298 (sdp_payload_data[i] == 0x02) && (sdp_payload_data[i+1] == 0x02) ||
3299 (sdp_payload_data[i] == 0x03) && (sdp_payload_data[i+1] == 0x03) ||
3300 (sdp_payload_data[i] == 0x04) && (sdp_payload_data[i+1] == 0x04) ||
3301 (sdp_payload_data[i] == 0x05) && (sdp_payload_data[i+1] == 0x05) ||
3302 (sdp_payload_data[i] == 0x06) && (sdp_payload_data[i+1] == 0x06) ||
3303 (sdp_payload_data[i] == 0x07) && (sdp_payload_data[i+1] == 0x07) ||
3304 (sdp_payload_data[i] == 0x08) && (sdp_payload_data[i+1] == 0x08) ||
3305 (sdp_payload_data[i] == 0x09) && (sdp_payload_data[i+1] == 0x09) ||
3306 (sdp_payload_data[i] == 0x0A) && (sdp_payload_data[i+1] == 0x0A))
3313 last_byte = sdp_payload_data[SDP_CMD_MAX_LEN -1];
3314 if(!(last_byte == 0x1 || last_byte == 0x2 || last_byte == 0x3 || last_byte == 0x4 ||
3315 last_byte == 0x5 || last_byte == 0x6 || last_byte == 0x7 || last_byte == 0x8 || last_byte == 0x8 ||
3323 static cyg_uint8 pl_handle_command(cyg_uint8 g_error_status)
3325 cyg_uint16 Header = 0;
3326 cyg_uint32 Address = 0;
3327 cyg_uint32 ByteCount = 0;
3328 cyg_uint32 g_error_statusAck = 0;
3329 cyg_uint8 status = 0;
3331 /* Command Packet Format: Header(2)+Address(4)+Format(1)+ByteCount(4)+Data(4)+Execute(1) */
3332 Header = ((sdp_command[0]<<8) | (sdp_command[1]));
3333 Address = ((sdp_command[2]<<24) | (sdp_command[3]<<16) | (sdp_command[4] << 8) | (sdp_command[5]));
3334 ByteCount = ((sdp_command[7]<<24) | (sdp_command[8]<<16) | (sdp_command[9] << 8) | (sdp_command[10]));
3336 /* Save g_error_status ack */
3337 g_error_statusAck = (cyg_uint32)((g_error_status<<24) | (g_error_status <<16) | (g_error_status<<8) | (g_error_status));
3338 //D("+USBDBGMSG: Command Header 0x%04X\n",Header);
3342 //D("+USBDBGMSG: usb download file to address 0x%08X, length %d\n",usb_download_address,ByteCount);
3343 pl_handle_write_file(usb_download_address, ByteCount);
3344 //pl_handle_write_file(Address, ByteCount);
3345 //if(g_load_cycle==0) usb_download_address=Address;
3347 usb_download_address += ByteCount;
3348 usb_download_length +=ByteCount;
3350 if(ByteCount<BULK_TD_BUFFER_TOTAL_SIZE)
3355 case ERROR_STATUS_HEADER:
3356 pl_command_ack(g_error_statusAck);
3369 static void pl_handle_write_file(cyg_uint32 address, cyg_uint32 total_bytes)
3371 usb_status_t status;
3372 usb_rx_processing((cyg_uint8*)address, &status, total_bytes);
3375 static void pl_command_ack(cyg_uint32 ack)
3377 usb_tx_processing((cyg_uint8*)&ack, SDP_CMD_ACK_LEN);
3381 usbs_imx_otg_download(unsigned char * buffer, unsigned int length)
3383 cyg_bool bytes_recvd = false;
3384 //D("+usbdownload: enter usbs_imx_otg_download\n");
3385 //D("+USBDBGMSG: re-enumerate USB device\n");
3388 while(g_usb_dev_state!=USB_DEV_CONFIGURED_STATE)
3391 /* Check if Bus Reset Received */
3392 if((usbs_imx_otg_base->usbsts) & IMX_USB_STS_RESET)
3394 /* Handle Bus Reset */
3395 usbs_imx_otg_dev_handle_bus_reset();
3397 /* Check if Reset is already received and Setup Token Received */
3398 if((g_usb_dev_state != USB_DEV_DUMMY_STATE) && (usbs_imx_otg_base->endptsetupstat & BIT0))
3400 /* Handle Setup Token */
3401 usbs_imx_otg_dev_ep0_dsr();
3405 if(g_usb_dev_state==USB_DEV_CONFIGURED_STATE)
3407 //D("+USBDBGMSG: enumeration done\n");
3409 D("USB file download start\n");
3410 g_timeout_value = 0;
3411 usb_download_length = 0;
3412 //usb_download_address = 0;
3417 bytes_recvd = pl_get_command();
3418 if(bytes_recvd == true)
3420 g_usb_download_state = pl_handle_command(g_error_status);
3423 if((g_usb_download_state==COMPLETE)||(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT))
3428 if(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT) //timeout value
3429 D("USB download timeout to wait none file to download\n");
3432 D("USB file download complete\n");
3433 //D("+usbdownload: image base 0x%08X, length %d\n",usb_download_address,usb_download_length);