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;
2024 if (g_usb_dev_state != USB_DEV_CONFIGURED_STATE)
2025 return; //EP1 only receives data when the USB device has been configured
2027 if (ep1.common.buffer == NULL) {
2028 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: NULL buffer \n");
2029 return; //there is not a buffer used to store the data from host
2032 /* Get Device Device Queue Head of the out endpoint */
2033 dqh_address = USBS_EP_GET_dQH(EP1,OUT);
2035 /* Get Device Transfer Descriptor of the out endpoint */
2036 dtd_address = USBS_EP_GET_dTD(EP1,OUT);
2038 /*clear the complete status */
2039 usbs_imx_otg_base->endptcomplete |= (EPOUT_COMPLETE << EP1);
2041 //received_buffer_addrs = (*((unsigned int *)dtd_address + 2)) & 0xFFFFF000;
2042 received_buffer_addrs = (cyg_uint32)ep1.common.buffer;
2043 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: received_buffer_addrs 0x%08X \n",received_buffer_addrs);
2044 if ( received_buffer_addrs == 0) {
2045 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: NULL rx buffer \n");
2049 /* calculate the received data length using number of bytes left in TD */
2050 temp = (cyg_uint32 *)dtd_address;
2051 temp++; //pointer to total bytes in dtd, second work in dTD
2052 received_data_length = (ep1.common.buffer_size - (((*temp) >> 16 )&0x7FFF)); //recevied data length <= BULK_TD_BUFFER_TOTAL_SIZE
2053 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: received length %d \n",received_data_length);
2055 /* Check if the received packet is SCSI WRITE, if yes, assign the TD buffer offset
2056 is zero, otherwise, one. This is a bug in MX37 USB OTG */
2057 if((received_data_length==31)&&(*(destination_ptr+0xF)==0x2A))//WRITE10 received
2059 g_bulk_out_transdesc_buffer_offset = 0;
2060 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_start_rx - set offset to zero \n");
2063 else if((g_bulk_out_sector_number_is_one == 1)&&(received_data_length!=31)) //last bulk out data sector
2064 g_bulk_out_transdesc_buffer_offset = 1;
2067 /* tell ep1 how many bytes data is received*/
2068 ep1.fetched = received_data_length;
2072 if(ep1.fetched == 31)
2073 g_received_data_type = MASS_STORAGE_CBW_TYPE;
2075 g_received_data_type = MASS_STORAGE_DATA_TYPE;
2076 ep1.common.complete_data = (void*)(ep1.common.buffer);
2079 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: \n");
2080 USBDBGMSG(DEBUG_TRANS,"----Dump Bulk-Out Recevied Data----\n");
2083 USBDBGMSG(DEBUG_TRANS,"%02X ", *((cyg_uint8 *)(ep1.common.complete_data)+i));
2085 USBDBGMSG(DEBUG_TRANS,"\n");
2087 //USB_IMX_SET_TD_OFFSET(g_td_buffer_offset, 0);
2088 ep1.common.buffer = (unsigned char*) 0;
2089 ep1.common.buffer_size = 0;
2090 ep1_start_rx((usbs_rx_endpoint *)(&(ep1.common))); //prevent to receive more CBW before processing done
2094 if(ep1.fetched == 31)
2096 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete - recevied data: \n");
2099 USBDBGMSG(DEBUG_TRANS,"%02X ", *((cyg_uint8 *)(ep1.common.complete_data)+i));
2101 USBDBGMSG(DEBUG_TRANS,"\n");
2105 USBDBGMSG(DEBUG_TRANS,"%02X ", *((cyg_uint8 *)received_buffer_addrs+i));
2107 USBDBGMSG(DEBUG_TRANS,"\n");
2113 /*=============================================================================
2114 // Start to receive data from host. This functionality is overloaded to cope with
2115 // waiting for stalls to complete.
2116 // The transfer descriptor is prepared
2117 =============================================================================*/
2119 ep1_start_rx(usbs_rx_endpoint* endpoint)
2122 cyg_uint32 total_bytes;
2123 cyg_uint32 dtd_address;
2124 cyg_uint32 dqh_address;
2125 cyg_uint32 buffer_addrs_page0;
2127 if(g_usb_dev_state != USB_DEV_CONFIGURED_STATE)
2128 return; //EP1 only receives data when the USB device has been configured
2129 #if 0 //don't check to prevent EP1 from receiving data before processing the previous.
2130 if(endpoint->buffer == NULL)
2132 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_start_rx: NULL buffer \n");
2133 return; //there is not a buffer used to store the data from host
2136 /* Get Device Device Queue Head of the out endpoint */
2137 dqh_address = USBS_EP_GET_dQH(EP1,OUT);
2139 /* Get Device Transfer Descriptor of the out endpoint */
2140 dtd_address = USBS_EP_GET_dTD(EP1,OUT);
2142 /* ==Prepare TD for next bulk out transfer== */
2143 /* get the dTD buffer pointer */
2144 buffer_addrs_page0 = (cyg_uint32)(endpoint->buffer);
2146 /* Get the total bytes to be received */
2147 total_bytes = endpoint->buffer_size;
2150 td.dtd_base = dtd_address;
2151 td.next_link_ptr = dtd_address + 0x20;
2152 td.terminate = TERMINATE;
2153 td.total_bytes = total_bytes;
2156 td.buffer_ptr0 = buffer_addrs_page0 ;
2157 td.current_offset = ( buffer_addrs_page0 & 0xFFF ) + g_td_buffer_offset;
2163 /* re-define the buffer page pointers based on the total_bytes*/
2164 if(total_bytes > BULK_TD_BUFFER_PAGE_SIZE)
2165 td.buffer_ptr1 = (td.buffer_ptr0 + BULK_TD_BUFFER_PAGE_SIZE);
2166 if(total_bytes > BULK_TD_BUFFER_PAGE_SIZE*2)
2167 td.buffer_ptr2 = (td.buffer_ptr1 + BULK_TD_BUFFER_PAGE_SIZE);
2168 if(total_bytes > BULK_TD_BUFFER_PAGE_SIZE*3)
2169 td.buffer_ptr3 = (td.buffer_ptr2 + BULK_TD_BUFFER_PAGE_SIZE);
2171 /* Set the Transfer Descriptor */
2172 usbs_setup_transdesc(&td);
2174 /* 1. write dQH next ptr and dQH terminate bit to 0 */
2175 *(volatile cyg_uint32 *)(dqh_address+0x8)= dtd_address;
2177 /* 2. clear active & halt bit in dQH */
2178 *(volatile cyg_uint32 *)(dqh_address+0xC) &= ~0xFF;
2180 /* 3. prime endpoint by writing '1' in ENDPTPRIME
2181 prime bulk out endpoint after sending the CSW of last command
2183 //usbs_imx_otg_base->endptprime |= ( EPOUT_PRIME << EP1 );
2186 /*=============================================================================
2187 // The exported interface to halt the EP1
2188 =============================================================================*/
2190 ep1_set_halted(usbs_rx_endpoint* endpoint, cyg_bool new_value)
2192 if (ep1.common.halted == new_value) {
2196 // The endpoint should be stalled. There is a potential race
2197 // condition here with the current transfer and DSR invocation.
2198 // Updating the stalled flag means that the DSR will do nothing.
2199 usbs_endpoint_stall(EP1,OUT);
2200 ep1.common.halted = 1;
2203 // Take care of the hardware so that a new transfer is allowed.
2204 usbs_endpoint_unstall(EP1,OUT);
2205 ep1.common.halted = 0;
2209 /*=============================================================================
2210 // The DSR is invoked following an interrupt. According to the docs an
2211 // endpoint 1 interrupt can only happen if the receive-packet-complete
2213 // [Note] EP1 DSR is only used to receive the command block wrapper from host
2214 // to USB mass storage device
2215 =============================================================================*/
2218 usbs_imx_otg_dev_ep1_dsr(void)
2220 int result = 0; //contains the actual recevied data length from bulk-out endpoint
2221 g_received_data_type = 0;//MASS_STORAGE_CBW_TYPE
2223 if(ep1.common.buffer)//buffer of TD is not null, then receive
2225 ep1_rx_complete(result);
2227 //USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1 dsr - result = %d\n",result);
2228 //recevie mass storage device CBW
2230 if((ep1.fetched == 31)&&(g_received_data_type == MASS_STORAGE_CBW_TYPE))
2232 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1 dsr - CBW received\n");
2233 //post the semaphore of MSC command handler thread
2234 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2235 cyg_semaphore_post(&usbs_msc_sem);
2240 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1 dsr - received %d byte\n",ep1.fetched);
2244 /*=============================================================================
2245 // Endpoint 1 initialization.
2246 // Bulk-OUT Endpoint
2247 // This may get called during system start-up or following a reset
2249 =============================================================================*/
2251 usbs_imx_otg_dev_ep1_init(void)
2253 //at present, ep1.common.buffer is NULL. The buffer should be initialized
2254 //by upper layer caller.
2255 /*buffer is assigned in MSC initialization*/
2257 // Endpoints should never be halted during a start-up.
2258 ep1.common.halted = 0; //false =0, true =1
2259 ep1.common.complete_fn = ep1_rx_complete;
2260 // If there has been a reset and there was a receive in progress,
2261 // abort it. This also takes care of sorting out the endpoint
2262 // fields ready for the next rx.
2263 ep1_rx_complete(-EPIPE);
2266 // ****************************************************************************
2267 // -----------------------Endpoint 2 Functions---------------------------------
2268 // ****************************************************************************
2269 /*=============================================================================
2270 // A utility routine for completing a transfer. This takes care of the
2271 // callback as well as resetting the buffer.
2272 =============================================================================*/
2274 ep2_tx_complete(int result)
2276 void (*complete_fn)(void*, int) = ep2.common.complete_fn;
2277 void* complete_data = ep2.common.complete_data;
2279 ep2.common.buffer = (unsigned char*) 0;
2280 ep2.common.buffer_size = 0;
2281 ep2.common.complete_fn = (void (*)(void*, int)) 0;
2282 ep2.common.complete_data = (void*) 0;
2284 if (NULL != complete_fn) {
2285 complete_fn(complete_data, result);
2289 /*=============================================================================
2290 // The exported interface to start to transmit data to Host
2291 =============================================================================*/
2293 ep2_start_tx(usbs_tx_endpoint* endpoint)
2297 cyg_uint32 total_bytes ;
2298 cyg_uint32 dtd_address,dqh_address;
2299 cyg_uint32 buffer_addrs_page0;
2300 cyg_uint32 size = 0x0;
2302 /* Get Device Transfer Descriptor of the requested endpoint */
2303 dtd_address = USBS_EP_GET_dTD(EP2,IN);
2305 /* Get Device Queue head of the requested endpoint */
2306 dqh_address = USBS_EP_GET_dQH(EP2,IN);
2308 /* allocate memory for data transfer */
2309 buffer_addrs_page0 = endpoint->buffer;
2311 if(buffer_addrs_page0 == 0)
2313 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep2_start_tx: NULL tx buffer \n");
2317 total_bytes = (cyg_uint32)(endpoint->buffer_size);
2318 size = (total_bytes < BULK_TD_BUFFER_TOTAL_SIZE )?total_bytes:(BULK_TD_BUFFER_TOTAL_SIZE);
2320 td.dtd_base = dtd_address;
2321 td.next_link_ptr = dtd_address + 0x20 ;
2322 td.terminate = TERMINATE;
2323 td.total_bytes = size;
2326 td.buffer_ptr0 = buffer_addrs_page0 ;
2327 td.current_offset = (buffer_addrs_page0 & 0xFFF)+ g_td_buffer_offset;
2333 /* re-define the buffer page pointers based on the total_bytes*/
2334 if(size > BULK_TD_BUFFER_PAGE_SIZE)
2335 td.buffer_ptr1 = (td.buffer_ptr0 + BULK_TD_BUFFER_PAGE_SIZE);
2336 if(size > BULK_TD_BUFFER_PAGE_SIZE*2)
2337 td.buffer_ptr2 = (td.buffer_ptr1 + BULK_TD_BUFFER_PAGE_SIZE);
2338 if(size > BULK_TD_BUFFER_PAGE_SIZE*3)
2339 td.buffer_ptr3 = (td.buffer_ptr2 + BULK_TD_BUFFER_PAGE_SIZE);
2341 /* Set the Transfer Descriptor */
2342 usbs_setup_transdesc(&td);
2344 /* 1. write dQH next ptr and dQH terminate bit to 0 */
2345 *(volatile cyg_uint32 *)(dqh_address+0x8)= (dtd_address);
2347 /* 2. clear active & halt bit in dQH */
2348 *(volatile cyg_uint32 *)(dqh_address+0xC) &= ~0xFF;
2350 /* 3. prime endpoint by writing '1' in ENDPTPRIME */
2351 usbs_imx_otg_base->endptprime = ( EPIN_PRIME << EP2 );
2353 /* wait for complete set and clear */
2354 while (!((usbs_imx_otg_base->endptcomplete) & (EPIN_COMPLETE<<EP2)));
2356 usbs_imx_otg_base->endptcomplete |= (EPIN_COMPLETE << EP2);
2358 ep2.transmitted = size;
2360 ep2_tx_complete(-EPIPE);
2362 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep2 tx done\n");// ep2.transmitted);
2365 /*=============================================================================
2366 // The exported interface to halt the EP2
2367 =============================================================================*/
2369 ep2_set_halted(usbs_tx_endpoint* endpoint, cyg_bool new_value)
2371 if (ep2.common.halted == new_value) {
2375 // The endpoint should be stalled. There is a potential race
2376 // condition here with the current transfer and DSR invocation.
2377 // Updating the stalled flag means that the DSR will do nothing.
2378 usbs_endpoint_stall(EP2,IN);
2379 ep2.common.halted = 1;
2382 // Take care of the hardware so that a new transfer is allowed.
2383 usbs_endpoint_unstall(EP2,IN);
2384 ep2.common.halted = 0;
2387 /*=============================================================================
2388 // The dsr will be invoked when the transmit-packet-complete bit is
2389 // set. Typically this happens when a packet has been completed
2390 =============================================================================*/
2393 usbs_imx_otg_dev_ep2_dsr(void)
2395 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep2 dsr\n");
2396 /* EP2 DSR will be called as soon as a transfer complete to clear status*/
2397 usbs_imx_otg_base->endptcomplete |= (EPIN_COMPLETE << EP2);
2400 if(ep2.common.buffer_size==0)
2402 ep2_tx_complete(-EPIPE);
2403 ep2.transmitted = 0; //clear the field to wait for the next transmit
2408 /*=============================================================================
2409 // Endpoint 2 initialization.
2411 // This may be called during system start-up or following a reset
2413 =============================================================================*/
2415 usbs_imx_otg_dev_ep2_init(void)
2417 //at initialization, ep2.common.buffer is NULL. The buffer should be initialized
2418 //by upper layer caller.
2420 // Endpoints should never be halted after a reset
2421 ep2.common.halted = false;
2423 // If there has been a reset and there was a receive in progress,
2424 // abort it. This also takes care of clearing the endpoint
2425 // structure fields.
2426 ep2_tx_complete(-EPIPE);
2429 // ****************************************************************************
2430 // -----------------------MX37 USB Device Driver API Functions-----------------
2431 // ****************************************************************************
2433 /*=============================================================================
2434 // The DSR. This can be invoked directly by poll(), or via the usual
2435 // interrupt subsystem. It acts as per the current value of
2436 // g_isr_status_bits. If another interrupt goes off while this
2437 // DSR is running, there will be another invocation of the DSR and
2438 // the status bits will be updated.
2439 =============================================================================*/
2441 usbs_imx_otg_dev_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
2445 CYG_ASSERT(MX51_IRQ_USB_SERVICE_REQUEST == vector, "USB DSR should only be invoked for USB interrupts" );
2446 CYG_ASSERT(0 == data, "The i.MX37 USB DSR needs no global data pointer");
2447 //USBDBGMSG("+USBDBGMSG: enter mx37 dsr\n");
2448 // There is no atomic swap support, so interrupts have to be
2449 // blocked. It might be possible to do this via the USBS_CONTROL
2450 // register, but at the risk of messing up the status register
2451 // if another interrupt comes in. Blocking interrupts at the
2452 // processor level is less intrusive on the USB code.
2453 //cyg_drv_isr_lock();
2454 status = g_isr_status_bits;
2455 g_isr_status_bits = 0;
2456 //cyg_drv_isr_unlock();
2458 // Reset is special, since it invalidates everything else.
2459 // If the reset is still ongoing then do not attempt any
2460 // further processing, there will just be another interrupt.
2461 // Otherwise handle_reset() does the hard work. Unmasking
2462 // the interrupt means that another interrupt will occur
2463 // immediately if reset is still asserted, i.e. no threads
2464 // will run, but there is no easy way of triggering action
2465 // at the end of reset.
2466 if (status & IMX_USB_STS_RESET)
2468 int new_status = usbs_imx_otg_base->usbsts;
2469 if (0 == (new_status & IMX_USB_STS_RESET))
2471 usbs_imx_otg_dev_handle_bus_reset();
2472 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: !!USB BUS RESET\n");
2475 // This unmask is likely to cause another interrupt immediately
2476 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2477 cyg_interrupt_unmask(MX51_IRQ_USB_SERVICE_REQUEST);
2480 else if(status & IMX_USB_STS_USBINT)
2483 if(usbs_imx_otg_base->endptsetupstat & BIT0)
2484 {// if Setup Packet arrived
2485 usbs_imx_otg_dev_ep0_dsr();
2488 else if((usbs_imx_otg_base->endptcomplete) & ( EPIN_COMPLETE << EP2))
2489 {// EP2 Queue Header buffer completes sending data
2490 //complete bit is cleared in ep2_start_tx
2494 else if((usbs_imx_otg_base->endptcomplete) & ( EPOUT_COMPLETE << EP1))
2495 {// EP1 Queue Header buffer get data
2496 usbs_imx_otg_dev_ep1_dsr();
2500 else if((usbs_imx_otg_base->endptcomplete) & ( EPOUT_COMPLETE << EP0))
2502 //usbs_imx_otg_dev_ep0_dsr();
2503 usbs_imx_otg_base->endptcomplete = ( EPOUT_COMPLETE << EP0);
2506 {//do nothing, only for constructure integrity
2507 temp = usbs_imx_otg_base->endptcomplete;
2508 usbs_imx_otg_base->endptcomplete = temp;
2509 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: usbsts int - unknown.\n");
2512 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2513 // This unmask is likely to cause another interrupt immediately
2514 cyg_interrupt_unmask(MX51_IRQ_USB_SERVICE_REQUEST);
2519 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2520 // This unmask is likely to cause another interrupt immediately
2521 cyg_interrupt_unmask(MX51_IRQ_USB_SERVICE_REQUEST);
2527 /*=============================================================================
2529 =============================================================================*/
2530 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
2531 #define CYGNUM_DEVS_USB_OTG_DEV_THREAD_STACK_SIZE 1024
2532 #define CYGNUM_DEVS_USB_OTG_DEV_THREAD_PRIORITY 29
2533 static unsigned char usbs_imx_otg_dev_thread_stack[CYGNUM_DEVS_USB_OTG_DEV_THREAD_STACK_SIZE];
2534 static cyg_thread usbs_imx_otg_dev_thread;
2535 static cyg_handle_t usbs_imx_otg_dev_thread_handle;
2536 static cyg_sem_t usbs_imx_otg_dev_sem;
2540 usbs_imx_otg_dev_thread_fn(cyg_addrword_t param)
2542 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: usb driver thread\n");
2544 cyg_semaphore_wait(&usbs_imx_otg_dev_sem);
2545 usbs_imx_otg_dev_dsr(IMX_IRQ_USB_DEV_SERVICE_REQUEST, 0, 0);
2547 CYG_UNUSED_PARAM(cyg_addrword_t, param);
2551 usbs_imx_otg_dev_thread_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
2553 CYG_ASSERT( 0 != isr_status_bits, "DSR's should only be scheduled when there is work to do");
2554 cyg_semaphore_post(&usbs_imx_otg_dev_sem);
2557 CYG_UNUSED_PARAM(cyg_vector_t, vector);
2558 CYG_UNUSED_PARAM(cyg_ucount32, count);
2559 CYG_UNUSED_PARAM(cyg_addrword_t, data);
2562 /*=============================================================================
2563 // The interrupt handler. This does as little as possible.
2564 =============================================================================*/
2566 usbs_imx_otg_dev_isr(cyg_vector_t vector, cyg_addrword_t data)
2568 cyg_uint32 old_status_bits = g_isr_status_bits;
2569 cyg_uint32 status_bits;
2571 CYG_ASSERT(IMX_IRQ_USB_DEV_SERVICE_REQUEST == vector, "USB ISR should only be invoked for USB interrupts" );
2572 CYG_ASSERT(0 == data, "The MX51 USB ISR needs no global data pointer" );
2574 //USBDBGMSG("+USBDBGMSG: enter mx51 isr\n");
2575 // Read the current status. Reset is special, it means that the
2576 // whole chip has been reset apart from the one bit in the status
2577 // register. Nothing should be done about this until the DSR sets
2578 // the endpoints back to a consistent state and re-enables
2579 // interrupts in the control register.
2580 status_bits = usbs_imx_otg_base->usbsts;
2581 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: usb intr 0x%08X\n",status_bits);
2582 if (status_bits & IMX_USB_STS_RESET)
2585 g_isr_status_bits |= IMX_USB_STS_RESET;
2586 usbs_imx_otg_base->usbsts |= IMX_USB_STS_RESET;
2587 cyg_interrupt_mask(IMX_IRQ_USB_DEV_SERVICE_REQUEST);
2589 else if(status_bits & IMX_USB_STS_USBINT)
2591 g_isr_status_bits |= IMX_USB_STS_USBINT;
2592 usbs_imx_otg_base->usbsts |= IMX_USB_STS_USBINT;
2593 cyg_interrupt_mask(IMX_IRQ_USB_DEV_SERVICE_REQUEST);
2597 usbs_imx_otg_base->usbsts = status_bits; //clear the status bit of USBSTS
2598 g_isr_status_bits &= ~status_bits;
2599 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: unknown usb intr\n");
2602 // Now keep the rest of the system happy.
2603 cyg_interrupt_acknowledge(vector); //reenable the USB interrupt
2604 return (old_status_bits != g_isr_status_bits) ? CYG_ISR_CALL_DSR : CYG_ISR_HANDLED;
2606 /*=============================================================================
2607 // Polling support. This acts mostly like the interrupt handler: it
2608 // sets the isr status bits and causes the dsr to run. Reset has to be
2609 // handled specially: polling does nothing as long as reset is asserted.
2610 =============================================================================*/
2612 usbs_imx_otg_dev_poll(usbs_control_endpoint* endpoint)
2614 CYG_ASSERT( endpoint == &ep0.common, "USB poll involves the wrong endpoint");
2616 if (g_isr_status_bits & IMX_USB_STS_RESET)
2618 // Reset was detected the last time poll() was invoked. If
2619 // reset is still active, do nothing. Once the reset has
2620 // completed things can continue.
2621 if (0 == (IMX_USB_STS_RESET & usbs_imx_otg_base->usbsts))
2623 g_isr_status_bits = 0;
2624 usbs_imx_otg_dev_handle_bus_reset();
2629 g_isr_status_bits = usbs_imx_otg_base->usbsts;
2630 if (IMX_USB_STS_PTCHANGE & g_isr_status_bits)
2632 //process Port Change Detect
2633 usbs_imx_otg_dev_handle_port_change();
2635 else if (IMX_USB_STS_USBINT & g_isr_status_bits)
2637 usbs_imx_otg_dev_dsr(IMX_IRQ_USB_DEV_SERVICE_REQUEST, 0, (cyg_addrword_t) 0);
2641 usbs_imx_otg_base->usbsts = g_isr_status_bits; //clear the don't-care status
2645 /*=============================================================================
2646 // Perform reset operations on all endpoints that have been
2647 // configured in. It is convenient to keep this in a separate
2648 // routine to allow for polling, where manipulating the
2649 // interrupt controller mask is a bad idea.
2650 =============================================================================*/
2652 usbs_imx_otg_dev_handle_bus_reset(void)
2656 usbs_imx_otg_base->usbcmd &= ~BIT0; //detach device from bus temprorarily
2657 usbs_imx_otg_base->usbsts |= BIT6; //clear reset bit in USBSTS
2659 //temp = usbs_imx_otg_base->usbsts;
2660 //usbs_imx_otg_base->usbsts = temp;
2662 /*1. Reading and writing back the ENDPTSETUPSTAT register
2663 clears the setup token semaphores */
2664 temp = usbs_imx_otg_base->endptsetupstat;
2665 usbs_imx_otg_base->endptsetupstat = temp;
2667 /*2. Reading and writing back the ENDPTCOMPLETE register
2668 clears the endpoint complete status bits */
2669 temp = usbs_imx_otg_base->endptcomplete;
2670 usbs_imx_otg_base->endptcomplete = temp;
2672 /*3. Cancel all primed status by waiting until all bits in ENDPTPRIME are 0
2673 and then write 0xFFFFFFFF to ENDPTFLUSH */
2674 while(usbs_imx_otg_base->endptprime);
2675 usbs_imx_otg_base->endptflush = 0xFFFFFFFF;
2678 /*4. Initialize EP0 Queue Head again*/
2679 usbs_ep0_init_dqh();
2681 usbs_imx_otg_base->endptlistaddr = g_bulkbuffer_map.ep_dqh_base_addrs;
2683 usbs_imx_otg_base->usbcmd |= BIT0; //re-attach device to the bus
2685 g_usb_dev_state = USB_DEV_DEFAULT_STATE;
2689 /*=============================================================================
2690 // Perform port change operations on all endpoints that have been
2691 // configured in. It is convenient to keep this in a separate
2692 // routine to allow for polling, where manipulating the
2693 // interrupt controller mask is a bad idea.
2694 =============================================================================*/
2696 usbs_imx_otg_dev_handle_port_change(void)
2698 /*Port Change happens when USB device enters/exits FS or HS mode
2699 When exiting from FS or HS due to Bus reset or DCSuspend, the notification
2700 mechanisms are Reset Received and DCSuspend.
2701 This function only processes the port change on entering FS or HS
2702 Don't enable Port Change Detect interrupt, it's no sense for operation.*/
2703 usbs_imx_otg_base->usbsts |= IMX_USB_STS_PTCHANGE; //clear Port change status
2707 // ****************************************************************************
2708 // ----------------------------------------------------------------------------
2709 // ****************************************************************************
2710 /*=============================================================================
2711 FUNCTION: usbs_imx_otg_dev_set_configuration
2712 DESCRIPTION: This function Handle the SET CONFIGRATION Request.
2713 ARGUMENTS PASSED: usb_end_pt_info_t* config_data;
2715 IMPORTANT NOTES: None
2716 =============================================================================*/
2718 usbs_imx_otg_dev_set_configuration(usb_end_pt_info_t* config_data)
2721 cyg_uint32 total_bytes = 0x0;
2722 cyg_uint32 buffer_addrs_page0 = 0;
2723 cyg_uint32 dqh_address = 0;
2724 cyg_uint32 dtd_address = 0;
2725 cyg_uint8 endpt_num,direction;
2730 /* get endpoint number to be configured and its direction */
2731 endpt_num= config_data->end_pt_no;
2732 direction= config_data->direction;
2733 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: set config - ep%d\n",endpt_num);
2734 /* Check if the endpoint number and direction is withing the permitted range or not */
2735 if (( endpt_num != EP0 ) && (endpt_num <= ( g_max_ep_supported - 1)) &&
2736 ( direction == OUT || direction == IN))
2738 /* get the device q head and deice TD */
2739 dqh_address = USBS_EP_GET_dQH(endpt_num,direction);
2740 dtd_address = USBS_EP_GET_dTD(endpt_num,direction);
2742 if ( direction == OUT )
2744 total_bytes = BULK_BUFFER_SIZE ;
2746 qhead.dqh_base = dqh_address;
2747 qhead.zlt = ZLT_DISABLE;
2748 qhead.mps = config_data->max_pkt_size;
2749 qhead.ios = IOS_SET;
2750 qhead.next_link_ptr = dtd_address ;
2751 qhead.terminate = TERMINATE;
2752 qhead.total_bytes = total_bytes;
2753 qhead.ioc = IOC_SET;
2754 qhead.status = NO_STATUS;
2755 qhead.buffer_ptr0 = 0;
2756 qhead.current_offset= 0;
2757 qhead.buffer_ptr1 = 0;
2758 qhead.buffer_ptr2 = 0;
2759 qhead.buffer_ptr3 = 0;
2760 qhead.buffer_ptr4 = 0;
2762 usbs_setup_queuehead(&qhead);
2764 /* Endpoint 1 : MPS = 64, OUT (Rx endpoint) */
2765 usbs_imx_otg_base->endptctrl[endpt_num] = 0x00080048;
2766 /* Enable EP1 OUT */
2767 usbs_imx_otg_base->endptctrl[endpt_num] |= EPOUT_ENABLE;
2769 /* allocate buffer for receiving data */
2770 /* free the usb buffer after re-enumeration*/
2771 //g_bulkbuffer_map.buffer1_status = BUFFER_FREE;
2772 //g_bulkbuffer_map.buffer2_status = BUFFER_FREE;
2773 g_bulkbuffer_a.stat = BUFFER_FREED;
2774 g_bulkbuffer_b.stat = BUFFER_FREED;
2776 //buffer_addrs_page0 = util_alloc_buffer();
2777 ep1.common.buffer = g_bulkbuffer_a.buffer;
2778 ep1.common.buffer_size = total_bytes;
2779 g_bulkbuffer_a.stat = BUFFER_ALLOCATED;
2780 buffer_addrs_page0 = (cyg_uint32)(ep1.common.buffer);
2783 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: set config - ep1 dtd buffer 0x%08X\n",buffer_addrs_page0);
2786 td.dtd_base = dtd_address;
2787 td.next_link_ptr = dtd_address + 0x20;
2788 td.terminate = TERMINATE;
2789 td.total_bytes = total_bytes;
2792 td.buffer_ptr0 = buffer_addrs_page0;
2793 td.current_offset = (buffer_addrs_page0 & 0xFFF) + g_td_buffer_offset;
2794 td.buffer_ptr1 = 0x0;
2795 td.buffer_ptr2 = 0x0;
2796 td.buffer_ptr3 = 0x0;
2797 td.buffer_ptr4 = 0x0;
2799 /* Set the Transfer Descriptor */
2800 usbs_setup_transdesc(&td);
2802 /* 1. write dQH next ptr and dQH terminate bit to 0 */
2803 *(volatile cyg_uint32*)(dqh_address+0x8)= dtd_address;
2805 /* 2. clear active & halt bit in dQH */
2806 *(volatile cyg_uint32*)(dqh_address+0xC) &= ~0xFF;
2808 /* 3. prime endpoint by writing '1' in ENDPTPRIME */
2809 usbs_imx_otg_base->endptprime |= ( EPOUT_PRIME << endpt_num );
2810 /* Endpoint Configured for output */
2811 g_out_endpoint= endpt_num;
2820 qhead.dqh_base = USBS_EP_GET_dQH(endpt_num,direction);
2821 qhead.zlt = ZLT_DISABLE;
2822 qhead.mps = config_data->max_pkt_size;
2823 qhead.ios = IOS_SET;
2824 qhead.next_link_ptr = USBS_EP_GET_dQH(endpt_num,direction);
2825 qhead.terminate = TERMINATE;
2826 qhead.total_bytes = total_bytes;
2827 qhead.ioc = IOC_SET;
2828 qhead.status = NO_STATUS;
2829 qhead.buffer_ptr0 = 0;
2830 qhead.current_offset= 0;
2831 qhead.buffer_ptr1 = 0;
2832 qhead.buffer_ptr2 = 0;
2833 qhead.buffer_ptr3 = 0;
2834 qhead.buffer_ptr4 = 0;
2836 usbs_setup_queuehead(&qhead);
2838 /* Endpoint Configured for Input */
2839 g_in_endpoint= endpt_num;
2841 /* Endpoint 2: MPS = 64, IN (Tx endpoint) */
2842 usbs_imx_otg_base->endptctrl[endpt_num] = 0x00480008;
2845 usbs_imx_otg_base->endptctrl[endpt_num] |= EPIN_ENABLE;
2847 /* 3. prime endpoint by writing '1' in ENDPTPRIME */
2848 usbs_imx_otg_base->endptprime |= (EPIN_PRIME << g_in_endpoint);
2854 /* TODO: error handling TBD */
2859 static void usbs_imx_otg_config_utmi_clock(void)
2861 #if defined(CYGHWR_USB_DEVS_MX37_OTG)
2862 USB_MX37_SET_PHY_CLK_24MHZ();
2865 #if defined(CYGHWR_USB_DEVS_MX51_OTG)
2867 /*Configure USB_PHYCLOCK_ROOT source as 24MHz OSC*/
2868 CCM_CSCMR1_REGVAL = CCM_CSCMR1_REGVAL & (~CSCMR1_USBOH3_PHY_CLK_SEL_VALUE); //configure USB CRM
2869 /*Configure plldivvalue of USB_PHY_CTRL_1_REG for 24 Mhz*/
2870 temp = *(volatile cyg_uint32 *)USB_PHY_CTRL_1_REG;
2871 temp &= ~USB_PHY_CTRL_PLLDIVVALUE_MASK;
2872 temp |= USB_PHY_CTRL_PLLDIVVALUE_24_MHZ;
2873 *(volatile cyg_uint32 *)USB_PHY_CTRL_1_REG = temp;
2877 /*=============================================================================
2878 // The USB OTG hardware relevant initialization.
2879 =============================================================================*/
2881 usbs_imx_otg_hardware_init(void)
2884 cyg_uint32 timeout = 0x1D0000;
2885 usb_plat_config_data_t config_data_ptr;
2888 /*Enable USB Internal PHY Clock as 24MHz on-board Ocsillator*/
2889 usbs_imx_otg_config_utmi_clock();
2891 {/*Setup USB Buffer Map*/
2892 config_data_ptr.buffer_address = (cyg_uint32)usb_buffer;
2893 config_data_ptr.buffer_size = BUFFER_SIZE;
2895 /* Base address of the buffer allocated to IP Layer */
2896 g_bulkbuffer_address_base = config_data_ptr.buffer_address;
2898 /* length of the buffer */
2899 g_bulkbuffer_length = config_data_ptr.buffer_size;
2901 /* Maximum Number of EPs to be confiured */
2902 g_max_ep_supported = (( g_bulkbuffer_length - TOTAL_DATA_BUFFER_SIZE)/(BUFFER_USED_PER_EP)); //=(2048-1088)/256~=3.75->3
2904 /* Base of queue Head Pointer */
2905 g_bulkbuffer_map.ep_dqh_base_addrs = g_bulkbuffer_address_base;
2907 /* Total size of qhead */
2908 temp = (SIZE_OF_QHD * (g_max_ep_supported * 2)); //total size of QH is 384byte
2910 /* Base Address of dTDs */
2911 g_bulkbuffer_map.ep_dtd_base_addrs = (g_bulkbuffer_map.ep_dqh_base_addrs + temp);
2913 /* Total size of transfer descriptor */
2914 temp = ((dTD_SIZE_EPIN * g_max_ep_supported) + (dTD_SIZE_EPOUT * g_max_ep_supported )); //total size of TD is 384 byte
2916 /* Base Address of EP0 Buffer */
2917 g_bulkbuffer_map.ep0_buffer_addrs = (g_bulkbuffer_map.ep_dtd_base_addrs + temp ); //256byte
2919 /*Bulk Buffer Areas, 512byte per buffer*/
2920 /*Actually, the dual 512 byte bulk buffers are not used, because two larger 16kB bulk buffers are used*/
2921 /* transfer buffer 1 */
2922 g_bulkbuffer_map.buffer1_address=(g_bulkbuffer_address_base + g_bulkbuffer_length -(BULK_BUFFER_SIZE*NUM_OF_BULK_BUFFER));
2923 g_bulkbuffer_map.buffer1_status = BUFFER_FREE;
2925 /* transfer buffer 2 */
2926 g_bulkbuffer_map.buffer2_address = g_bulkbuffer_map.buffer1_address + BULK_BUFFER_SIZE;
2927 g_bulkbuffer_map.buffer2_status = BUFFER_FREE;
2930 {/*Set USB OTG at device only mode*/
2931 usbs_imx_otg_base->usbmode = 0x2; //set OTG as a device controller
2933 while (!(usbs_imx_otg_base->usbmode == 0x2))
2935 if(temp != (usbs_imx_otg_base->usbmode))
2937 temp = (usbs_imx_otg_base->usbmode);
2938 USBDBGMSG(DEBUG_BASIC,"usbmode is 0x%08X\n",temp);
2941 if(timeout==0) break;
2942 } //check that device controller was configured to device mode only
2946 usbs_imx_otg_base->endptlistaddr = g_bulkbuffer_map.ep_dqh_base_addrs; // Configure ENDPOINTLISTADDR Pointer
2947 usbs_imx_otg_base->otgsc |= BIT3; // Set OTG termination, controls the pulldown on DM
2948 usbs_imx_otg_base->endptnak = 0x00010001; // Enable Endpoint NAK
2949 usbs_imx_otg_base->usbmode |= BIT3; // Disable Setup Lockout by writing '1' to SLOM in USBMODE
2950 //usbs_imx_otg_base->usbcmd |= BIT0; // Set Run/Stop bit to Run Mode, make USB run in usbs_imx_otg_dev_ep0_start()
2954 /* set it to be utmi interface */
2955 temp = usbs_imx_otg_base->portsc1;
2956 temp &= ~USB_OTG_TRANS_MASK;
2957 temp |= USB_OTG_TRANS_UTMI;
2958 temp &= ~USB_OTG_FS_ONLY; //enable high speed
2959 temp |= USB_OTG_TRANS_WIDTH;
2961 usbs_imx_otg_base->portsc1 = temp;
2964 {// The USB OTG transaction relevant initialization.
2965 /* Select the common descriptors , these descriptor are independent of speed and security mode */
2966 g_usb_desc.device_desc = &g_usb_device_desc ;
2967 g_usb_desc.config_desc = &g_usb_config_desc;
2968 g_usb_desc.sn_desc = &g_usb_serialnumber_desc;
2969 g_usb_desc.str_desc0 = &g_usb_otg_str0_desc; //language desc
2970 g_usb_desc.str_desc1 = &g_usb_otg_string_desc1; //Manufacturer desc
2971 g_usb_desc.str_desc2 = &g_usb_otg_string_desc2; //USB Name Desc
2972 g_usb_desc.str_desc3 = &g_usb_otg_string_desc3; //Device Name Desc
2974 /* Get Number of Endpoints supported from Configuration Descriptor*/
2975 g_number_of_endpoints = g_usb_desc.config_desc->usb_interface_desc.number_endpoints;
2977 /* Store the Endpoint specific information in local variable structure to this Layer */
2978 for ( i = 0 ; i< g_number_of_endpoints ; i++)
2980 g_end_pt_info[i].end_pt_no = ((g_usb_desc.config_desc->usb_endpoint_desc[i].endpoint) & ENDPT_NUMBER_MASK);
2981 g_end_pt_info[i].direction = (((g_usb_desc.config_desc->usb_endpoint_desc[i].endpoint) & ENDPT_DIR_MASK )>>ENDPT_DIR_SHIFT);
2982 g_end_pt_info[i].transfer_type = (g_usb_desc.config_desc->usb_endpoint_desc[i].attributes & ENDPT_TRNS_TYPE_MASK);
2983 g_end_pt_info[i].max_pkt_size = ((g_usb_desc.config_desc->usb_endpoint_desc[i].max_packet_lo) \
2984 | (( g_usb_desc.config_desc->usb_endpoint_desc[i].max_packet_hi ) << 8 ));
2987 g_usb_dev_state = USB_DEV_DEFAULT_STATE;
2990 // ****************************************************************************
2991 // ----------------------------------------------------------------------------
2992 // ****************************************************************************
2993 /*=============================================================================
2994 // Initialization i.MX37(Marley) USB OTG Hardware
2995 // This function is the only extern function of this device driver, and it
2996 // registers the driver ISR and DSRs to the kernel.
2997 =============================================================================*/
2999 usbs_imx_otg_device_init(void) //works like usb port open when
3001 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: USB Device Driver Start Initializing...\n");
3002 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: USB OTG REG BASE@0x%08X\n",USB_BASE_ADDRESS);
3003 g_usb_setup_data = ep0.common.control_buffer;
3005 g_td_buffer_offset = 0;
3006 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
3007 USB_IMX_SET_TD_OFFSET(g_td_buffer_offset,1);
3010 /*ping-pang buffer A*/
3011 g_bulkbuffer_a.buffer = bulk_buffer;
3012 g_bulkbuffer_a.stat = BUFFER_FREED;
3014 /*ping-pang buffer B*/
3015 g_bulkbuffer_b.buffer = bulk_buffer + BULK_TD_BUFFER_TOTAL_SIZE;
3016 g_bulkbuffer_b.stat = BUFFER_FREED;
3018 usbs_imx_otg_hardware_init();
3019 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: Usb Hardware Initialize Complete.\n");
3020 usbs_imx_otg_dev_ep0_init();
3021 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: Usb Ep0 Initialize Complete.\n");
3022 usbs_imx_otg_dev_ep1_init();
3023 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: Usb Ep1 Initialize Complete.\n");
3024 usbs_imx_otg_dev_ep2_init();
3025 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: Usb Ep2 Initialize Complete.\n");
3027 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
3028 cyg_semaphore_init(&usbs_imx_otg_dev_sem, 0);
3029 cyg_thread_create(CYGNUM_DEVS_USB_OTG_DEV_THREAD_PRIORITY,
3030 &usbs_imx_otg_dev_thread_fn,
3032 "i.MX37/51 USB Device",
3033 usbs_imx_otg_dev_thread_stack,
3034 CYGNUM_DEVS_USB_OTG_DEV_THREAD_STACK_SIZE,
3035 &usbs_imx_otg_dev_thread_handle,
3036 &usbs_imx_otg_dev_thread
3038 cyg_thread_resume(usbs_imx_otg_dev_thread_handle);
3039 // It is also possible and desirable to install the interrupt
3040 // handler here, even though there will be no interrupts for a
3042 cyg_interrupt_create(IMX_IRQ_USB_DEV_SERVICE_REQUEST,
3043 IMX_IRQ_USB_DEV_PRIORITY, // priority
3045 &usbs_imx_otg_dev_isr,
3046 &usbs_imx_otg_dev_thread_dsr,
3047 &g_usbs_dev_intr_handle,
3048 &g_usbs_dev_intr_data);
3049 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: cyg_interrupt_create@vector %d.\n",IMX_IRQ_USB_DEV_SERVICE_REQUEST);
3050 cyg_interrupt_attach(g_usbs_dev_intr_handle); //fill interrupt handler table for USB
3051 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: cyg_interrupt_attach.\n");
3052 cyg_interrupt_unmask(IMX_IRQ_USB_DEV_SERVICE_REQUEST); //enable USB interrrupt
3053 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: cyg_interrupt_unmask.\n");
3055 ep0.common.start_fn(&(ep0.common));
3060 usbs_imx_otg_device_deinit(void) //works like usb port close
3062 usbs_imx_otg_base->usbcmd &= (~BIT0); // Set Run/Stop bit to Stop Mode
3063 g_usb_dev_state = USB_DEV_DUMMY_STATE;
3066 #if defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
3068 static cyg_uint32 get_free_bulk_buffer(void)
3070 cyg_uint32 buff_addr = 0;
3072 while(buff_addr == 0)
3074 if(g_bulkbuffer_a.stat == BUFFER_FREED)
3076 buff_addr = (cyg_uint32)(g_bulkbuffer_a.buffer);
3079 else if(g_bulkbuffer_b.stat == BUFFER_FREED)
3081 buff_addr = (cyg_uint32)(g_bulkbuffer_b.buffer);
3090 diag_printf("no bulk buffer free\n");
3100 cyg_bool set_status_bulk_buffer(cyg_uint32 buff_addr, int buff_stat)
3102 cyg_bool ret = true;
3103 if(buff_addr == (cyg_uint32)(g_bulkbuffer_a.buffer))
3104 g_bulkbuffer_a.stat = buff_stat;
3105 else if (buff_addr == (cyg_uint32)(g_bulkbuffer_b.buffer))
3106 g_bulkbuffer_b.stat = buff_stat;
3112 static usb_status_t usb_bulk_receive_data(usb_buffer_descriptor_t * bd)
3114 usb_status_t status;
3117 /* Check if Bus Reset Received */
3118 if((usbs_imx_otg_base->usbsts) & IMX_USB_STS_RESET)
3120 /* Handle Bus Reset */
3121 usbs_imx_otg_dev_handle_bus_reset();
3123 /* Check if Reset is already received and Setup Token Received */
3124 if((usbs_imx_otg_base->endptsetupstat) & BIT0)
3126 /* Handle Setup Token */
3127 usbs_imx_otg_dev_ep0_dsr();
3130 if((usbs_imx_otg_base->endptcomplete) & ( EPOUT_COMPLETE << EP1))
3132 ep1_rx_complete(res);
3133 if(ep1.common.complete_data)
3135 bd->bytes_transfered = ep1.fetched;
3136 memcpy(bd->buffer,ep1.common.complete_data,ep1.fetched);
3138 //D("+USBDBGMSG:bd->bytes_transfered %d\n",bd->bytes_transfered);
3139 set_status_bulk_buffer((cyg_uint32)(ep1.common.complete_data), BUFFER_FREED);
3140 ep1.common.buffer = (unsigned char *)get_free_bulk_buffer();
3141 ep1.common.buffer_size = BULK_TD_BUFFER_TOTAL_SIZE;
3142 ep1_start_rx(&(ep1.common));
3143 usbs_imx_otg_base->endptprime |= ( EPOUT_PRIME << EP1 );//prime ep1 td
3144 status = USB_SUCCESS;
3148 status = USB_FAILURE;
3153 static usb_status_t usb_bulk_transmit_data(usb_buffer_descriptor_t * bd)
3155 //usb_state_t status;
3159 ep2.common.buffer = (unsigned char *)get_free_bulk_buffer();
3160 set_status_bulk_buffer((cyg_uint32)(ep2.common.buffer), BUFFER_ALLOCATED);
3161 ep2.common.buffer_size = (BULK_TD_BUFFER_TOTAL_SIZE<(bd->size))?BULK_TD_BUFFER_TOTAL_SIZE:(bd->size);
3162 memcpy((ep2.common.buffer),(bd->buffer),(ep2.common.buffer_size));
3163 ep2_start_tx(&(ep2.common));
3165 bd->size -= (ep2.common.buffer_size);
3170 static cyg_uint32 usb_rx_processing(cyg_uint8* read_ptr, usb_status_t* status, cyg_uint32 data_length)
3172 cyg_uint32 bytes_received = 0;
3173 if ( (status != NULL) && (read_ptr != NULL) )
3175 usb_status_t trans_status = USB_FAILURE;
3177 usb_buffer_descriptor_t buf_desc;
3179 /* Prepare the buffer descriptor for USB transfer */
3180 //(cyg_uint8*)(buf_desc.buffer) = read_ptr;
3181 buf_desc.buffer = (void *)read_ptr;
3182 while(data_length != 0)
3184 buf_desc.size = data_length;
3185 buf_desc.bytes_transfered = 0;
3187 /* Receive data from USB */
3188 trans_status = (usb_status_t )usb_bulk_receive_data(&buf_desc);
3189 if(trans_status == USB_SUCCESS)
3191 data_length -= buf_desc.bytes_transfered;
3192 bytes_received += buf_desc.bytes_transfered;
3194 (buf_desc.buffer) += buf_desc.bytes_transfered;
3198 *status = USB_FAILURE;
3202 if(g_timeout_value%0x1000000==0) D("C");
3203 if(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT) return 0;
3207 return ( bytes_received );
3209 static usb_status_t usb_tx_processing(cyg_uint8* write_ptr, cyg_uint32 data_len)
3211 usb_status_t trans_status = USB_FAILURE;
3213 /* Prepare the buffer descriptor for USB transfer */
3214 usb_buffer_descriptor_t buf_desc;
3216 /* Prepare transfer buffer descriptor*/
3217 buf_desc.buffer = (void *)write_ptr;
3218 buf_desc.size = data_len;
3219 buf_desc.bytes_transfered = 0;
3221 /* Send data over USB */
3222 trans_status = usb_bulk_transmit_data(&buf_desc);
3224 return trans_status;
3226 static cyg_bool pl_get_command(void)
3229 usb_status_t status;
3230 cyg_uint32 bytes_recvd = 0;
3231 cyg_uint8 start_command = 0xFF;
3233 while(start_command == 0xFF)
3235 //g_timeout_value++;
3236 //if(g_timeout_value%1000==0) D("C");
3237 //D("%d\n",g_timeout_value);
3238 bytes_recvd = usb_rx_processing(sdp_payload_data, &status, SDP_CMD_MAX_LEN);
3239 start_command = pl_command_start();
3240 if(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT) return false;
3242 //D("+USBDBGMSG: start_command = 0x%02X\n",start_command);
3243 if(start_command == 0xF0)
3245 //copy rest of the bytes
3246 for(i=1; i < SDP_CMD_MAX_LEN; i++)
3248 sdp_command[i] = sdp_payload_data[i-1];
3253 //copy starting bytes
3254 for(i=0; i < (SDP_CMD_MAX_LEN - start_command) ; i++)
3256 sdp_command[i] = sdp_payload_data[i + start_command];
3259 if(start_command != 0)
3261 //receive rest of the bytes
3262 bytes_recvd = usb_rx_processing(sdp_payload_data, &status, start_command);
3264 if(bytes_recvd == start_command)
3266 for(i=0; i <start_command; i++)
3268 sdp_command[SDP_CMD_MAX_LEN - start_command + i] = sdp_payload_data[i];
3276 static cyg_uint8 pl_command_start(void)
3279 static cyg_uint8 last_byte = 0;
3281 if(last_byte != 0x0)
3283 if(last_byte == sdp_payload_data[0])
3285 sdp_command[0] = last_byte;
3286 last_byte = sdp_payload_data[SDP_CMD_MAX_LEN -1];
3291 for(i=0; i < SDP_CMD_MAX_LEN -1; i++)
3293 if((sdp_payload_data[i] == 0x01) && (sdp_payload_data[i+1] == 0x01) ||
3294 (sdp_payload_data[i] == 0x02) && (sdp_payload_data[i+1] == 0x02) ||
3295 (sdp_payload_data[i] == 0x03) && (sdp_payload_data[i+1] == 0x03) ||
3296 (sdp_payload_data[i] == 0x04) && (sdp_payload_data[i+1] == 0x04) ||
3297 (sdp_payload_data[i] == 0x05) && (sdp_payload_data[i+1] == 0x05) ||
3298 (sdp_payload_data[i] == 0x06) && (sdp_payload_data[i+1] == 0x06) ||
3299 (sdp_payload_data[i] == 0x07) && (sdp_payload_data[i+1] == 0x07) ||
3300 (sdp_payload_data[i] == 0x08) && (sdp_payload_data[i+1] == 0x08) ||
3301 (sdp_payload_data[i] == 0x09) && (sdp_payload_data[i+1] == 0x09) ||
3302 (sdp_payload_data[i] == 0x0A) && (sdp_payload_data[i+1] == 0x0A))
3309 last_byte = sdp_payload_data[SDP_CMD_MAX_LEN -1];
3310 if(!(last_byte == 0x1 || last_byte == 0x2 || last_byte == 0x3 || last_byte == 0x4 ||
3311 last_byte == 0x5 || last_byte == 0x6 || last_byte == 0x7 || last_byte == 0x8 || last_byte == 0x8 ||
3319 static cyg_uint8 pl_handle_command(cyg_uint8 g_error_status)
3321 cyg_uint16 Header = 0;
3322 cyg_uint32 Address = 0;
3323 cyg_uint32 ByteCount = 0;
3324 cyg_uint32 g_error_statusAck = 0;
3325 cyg_uint8 status = 0;
3327 /* Command Packet Format: Header(2)+Address(4)+Format(1)+ByteCount(4)+Data(4)+Execute(1) */
3328 Header = ((sdp_command[0]<<8) | (sdp_command[1]));
3329 Address = ((sdp_command[2]<<24) | (sdp_command[3]<<16) | (sdp_command[4] << 8) | (sdp_command[5]));
3330 ByteCount = ((sdp_command[7]<<24) | (sdp_command[8]<<16) | (sdp_command[9] << 8) | (sdp_command[10]));
3332 /* Save g_error_status ack */
3333 g_error_statusAck = (cyg_uint32)((g_error_status<<24) | (g_error_status <<16) | (g_error_status<<8) | (g_error_status));
3334 //D("+USBDBGMSG: Command Header 0x%04X\n",Header);
3338 //D("+USBDBGMSG: usb download file to address 0x%08X, length %d\n",usb_download_address,ByteCount);
3339 pl_handle_write_file(usb_download_address, ByteCount);
3340 //pl_handle_write_file(Address, ByteCount);
3341 //if(g_load_cycle==0) usb_download_address=Address;
3343 usb_download_address += ByteCount;
3344 usb_download_length +=ByteCount;
3346 if(ByteCount<BULK_TD_BUFFER_TOTAL_SIZE)
3351 case ERROR_STATUS_HEADER:
3352 pl_command_ack(g_error_statusAck);
3365 static void pl_handle_write_file(cyg_uint32 address, cyg_uint32 total_bytes)
3367 usb_status_t status;
3368 usb_rx_processing((cyg_uint8*)address, &status, total_bytes);
3371 static void pl_command_ack(cyg_uint32 ack)
3373 usb_tx_processing((cyg_uint8*)&ack, SDP_CMD_ACK_LEN);
3377 usbs_imx_otg_download(unsigned char * buffer, unsigned int length)
3379 cyg_bool bytes_recvd = false;
3380 //D("+usbdownload: enter usbs_imx_otg_download\n");
3381 //D("+USBDBGMSG: re-enumerate USB device\n");
3384 while(g_usb_dev_state!=USB_DEV_CONFIGURED_STATE)
3387 /* Check if Bus Reset Received */
3388 if((usbs_imx_otg_base->usbsts) & IMX_USB_STS_RESET)
3390 /* Handle Bus Reset */
3391 usbs_imx_otg_dev_handle_bus_reset();
3393 /* Check if Reset is already received and Setup Token Received */
3394 if((g_usb_dev_state != USB_DEV_DUMMY_STATE) && (usbs_imx_otg_base->endptsetupstat & BIT0))
3396 /* Handle Setup Token */
3397 usbs_imx_otg_dev_ep0_dsr();
3401 if(g_usb_dev_state==USB_DEV_CONFIGURED_STATE)
3403 //D("+USBDBGMSG: enumeration done\n");
3405 D("USB file download start\n");
3406 g_timeout_value = 0;
3407 usb_download_length = 0;
3408 //usb_download_address = 0;
3413 bytes_recvd = pl_get_command();
3414 if(bytes_recvd == true)
3416 g_usb_download_state = pl_handle_command(g_error_status);
3419 if((g_usb_download_state==COMPLETE)||(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT))
3424 if(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT) //timeout value
3425 D("USB download timeout to wait none file to download\n");
3428 D("USB file download complete\n");
3429 //D("+usbdownload: image base 0x%08X, length %d\n",usb_download_address,usb_download_length);