]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/usb/imx/v2_0/src/usbs_imx.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / devs / usb / imx / v2_0 / src / usbs_imx.c
1 //==========================================================================
2 //
3 //      usbs_imx.c
4 //
5 //      Device driver for the i.MX51 or i.MX37 USB OTG port.
6 //
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.
13 //
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.
17 //
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
21 // for more details.
22 //
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.
26 //
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.
33 //
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.
36 //
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####
43 //
44 // Author(s):    fisherz
45 // Contributors: fisherz
46 // Date:         2008-10-16
47 //
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.
55 //
56 // [Note] DMA is not enabled for USB transfer
57 //####DESCRIPTIONEND####
58 //
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>
77 #endif
78 #include <cyg/io/usb/usb.h>
79 #include <cyg/io/usb/usbs.h>
80 #include <cyg/io/usb/usbs_imx.h>
81
82 #pragma O0      //this pragma is useful when Realview tool chain is used
83 #define VOLATILE volatile
84
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
89 #define EPIPE 304
90
91 /* Constants */
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
100
101 /* SDP Responses */
102 #define WRITE_COMPLETE  0x128A8A12
103
104 /* SDP States */
105 #define CONTINUE        0
106 #define DONE            1
107 #define COMPLETE        0x88
108
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);
125 #endif
126
127 /*      Bit3 - Mass Storage Information
128         Bit2 - Enumeration Information
129         Bit1 - Transaction Information
130         Bit0 - Basic Information
131 */
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
136
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
140 #if 1
141 #define USBDBGMSG(opt,fmt,args...) if(g_debug_switch&opt) diag_printf(fmt, ## args)
142 #else
143 #define USBDBGMSG(opt,fmt,args...)
144 #endif
145
146 #else
147 #define USBDBGMSG(opt,fmt,args...) //diag_printf(fmt, ## args)
148 #define D(fmt,args...) diag_printf(fmt, ## args)
149 #endif
150
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;
155
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;
160
161 //The below two flags is used to distinguish the received data is data or command
162 cyg_uint32 g_received_data_type;
163
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.
166 */
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;
169
170 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
171 extern cyg_sem_t usbs_msc_sem;                          //semaphore to schedule mass storage command handling thread
172 #endif
173
174 // ----------------------------------------------------------------------------
175 // Static pointers for USB buffer layout
176 /*=============================================================================
177                                       STATIC VARIABLES
178 //============================================================================*/
179
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.
185
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
190 #else
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);
197 #endif
198
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);
202 #endif
203 //
204 #endif  //defined(CYGHWR_IMX_USB_BUFFER_USE_IRAM)
205
206 VOLATILE usbs_imx_otg_hardware* usbs_imx_otg_base = (VOLATILE usbs_imx_otg_hardware* const) USB_BASE_ADDRESS;
207
208 static void usbs_imx_otg_config_utmi_clock(void);
209
210
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;
233
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;
238
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))
247
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)
252
253 // ----------------------------------------------------------------------------
254 // Set USB device address
255 #define USBS_DEVICE_SET_ADDRESS(addr) (usbs_imx_otg_base->devaddr = ((cyg_uint32)addr & 0x7F) << 25)
256 /*
257 #*************
258 #   OTG
259 #*************
260 */
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              */
267
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 */
274
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                                                                    */
279
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     */
284
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 ={
312         USB_DEV_DESC_LEN,
313     USB_DEV_DESC_TYPE,
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
330 };
331
332
333 /* USB Config Descriptor according to USB2.0 Specification */
334 static VOLATILE usb_conf_desc g_usb_config_desc = {
335         {
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
345         },
346                 /* USB Interface Descriptor according to USB2.0 Specification */
347         {//09
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,
357         #else
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,
361     #endif
362         USB_DEV_INF_DESC_STRING_INDEX
363         },
364                 /* USB Endpoint 1 Descriptors according to USB2.0 Specification, OUT */
365         {
366         {//18
367         USB_EP1_DESC_SIZE,
368     USB_EP1_DESC_TYPE,
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
374         },
375                 /* USB Endpoint 2 Descriptors according to USB2.0 Specification, IN */
376         {//25
377         USB_EP2_DESC_SIZE,
378     USB_EP2_DESC_TYPE,
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
384         }
385         }
386 };
387
388 /* USB String Descriptors 0, according to USB2.0 Specification */
389 static VOLATILE usb_str0_desc g_usb_otg_str0_desc ={
390     USB_STR0_DESC_SIZE,
391     USB_STR0_DESC_TYPE,
392     USB_LANGUAGE_ID_LB,
393     USB_LANGUAGE_ID_HB
394 };
395
396 /*
397  STRING DESCRIPTOR
398  See table 9-15 in USB2.0 spec (www.usb.org)
399  iManufacturer
400 */
401 static VOLATILE usb_str1_desc g_usb_otg_string_desc1 ={
402         USB_STR1_DESC_SIZE,             /* bLength */
403         USB_STR1_DESC_TYPE,                     /* bDescriptorType */
404         {
405         'F', 0x00,                                                      /* bString */
406         'r', 0x00,
407         'e', 0x00,
408         'e', 0x00,
409         's', 0x00,
410         'c', 0x00,
411         'a', 0x00,
412         'l', 0x00,
413         'e', 0x00,
414         ' ', 0x00,
415         'S', 0x00,
416         'e', 0x00,
417         'm', 0x00,
418         'i', 0x00,
419         'C', 0x00,
420         'o', 0x00,
421         'n', 0x00,
422         'd', 0x00,
423         'u', 0x00,
424         'c', 0x00,
425         't', 0x00,
426         'o', 0x00,
427         'r', 0x00,
428         ' ', 0x00,
429         'I', 0x00,
430         'n', 0x00,
431         'c', 0x00,
432         '.', 0x00
433         }
434 };
435 #if defined(CYGHWR_USB_DEVS_MX37_OTG)
436 /*iProduct*/
437 static VOLATILE usb_str2_desc g_usb_otg_string_desc2 = {
438         USB_STR2_DESC_SIZE_NS,          /* bLength */
439         USB_STR2_DESC_TYPE,                                             /* bDescriptorType */
440         {
441         'M', 0x00,                              /* bString */
442         'A', 0x00,
443         'R', 0x00,
444         'L', 0x00,
445         'E', 0x00,
446         'Y', 0x00,
447         ' ', 0x00,
448         'U', 0x00,
449         'S', 0x00,
450         'B', 0x00,
451         ' ', 0x00,
452         'O', 0x00,
453         'T', 0x00,
454         'G', 0x00,
455         ' ', 0x00
456         }
457 };
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 = {
461                 USB_SN_DESC_LEN,
462                 USB_SN_DESC_TYPE,
463                 {
464                 '2',0x00,
465                 '0',0x00,
466                 '0',0x00,
467                 '8',0x00,
468                 '1',0x00,
469                 '8',0x00,
470                 '9',0x00,
471                 '8',0x00,
472                 '5',0x00,
473                 '0',0x00,
474                 '3',0x00,
475                 '7',0x00
476           }
477 };
478 //#endif
479 #endif
480
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 */
485         {
486         'E', 0x00,                              /* bString */
487         'l', 0x00,
488         'v', 0x00,
489         'i', 0x00,
490         's', 0x00,
491         ' ', 0x00,
492         'U', 0x00,
493         'S', 0x00,
494         'B', 0x00,
495         ' ', 0x00,
496         'O', 0x00,
497         'T', 0x00,
498         'T', 0x00,
499         ' ', 0x00,
500         ' ', 0x00
501         }
502 };
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 = {
506                 USB_SN_DESC_LEN,
507                 USB_SN_DESC_TYPE,
508                 {
509                 '2',0x00,
510                 '0',0x00,
511                 '0',0x00,
512                 '8',0x00,
513                 '1',0x00,
514                 '8',0x00,
515                 '9',0x00,
516                 '8',0x00,
517                 '5',0x00,
518                 '0',0x00,
519                 '5',0x00,
520                 '1',0x00
521           }
522 };
523 //#endif
524 #endif
525
526 /* STRING DESCRIPTOR
527    See table 9-15 in USB2.0 spec (www.usb.org)
528    iSerialNumber */
529 static VOLATILE usb_str3_desc g_usb_otg_string_desc3 = {
530         USB_STR3_DESC_SIZE,                                     /* bLength */
531         USB_STR3_DESC_TYPE,                                     /* bDescriptorType */
532         {
533         'F', 0x00,                                                                      /* bString */
534         'r', 0x00,
535         'e', 0x00,
536         'e', 0x00,
537         's', 0x00,
538         'c', 0x00,
539         'a', 0x00,
540         'l', 0x00,
541         'e', 0x00,
542         ' ', 0x00,
543         'F', 0x00,
544         'l', 0x00,
545         'a', 0x00,
546         's', 0x00,
547         'h', 0x00
548         }
549 };
550
551
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.
560
561 // ----------------------------------------------------------------------------
562 // Endpoint 0 is always present, this module would not get compiled
563 // otherwise.
564 static void usbs_imx_otg_dev_ep0_start(usbs_control_endpoint*);
565 static void usbs_imx_otg_dev_poll(usbs_control_endpoint*);
566
567 typedef enum ep0_state {
568     EP0_STATE_IDLE      = 0,
569     EP0_STATE_IN        = 1,
570     EP0_STATE_OUT       = 2
571 } ep0_state;
572
573 typedef struct ep0_impl {
574     usbs_control_endpoint   common;                     //struct usbs_control_endpoint defined in usbs.h
575     ep0_state               ep_state;
576     int                     length;
577     int                     transmitted;
578 } ep0_impl;
579
580 static ep0_impl ep0 = {
581     common:
582     {
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,
600         buffer_size:            0,
601         fill_buffer_fn:         (void (*)(usbs_control_endpoint*)) 0,
602         fill_data:              (void*) 0,
603         fill_index:             0,
604         complete_fn:            (usbs_control_return (*)(usbs_control_endpoint*, int)) 0
605     },
606     ep_state:           EP0_STATE_IDLE,
607     length:             0,
608     transmitted:        0
609 };
610
611 extern usbs_control_endpoint usbs_imx_otg_ep0 __attribute__((alias ("ep0")));
612
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
617
618 typedef struct ep1_impl {
619     usbs_rx_endpoint    common;                 //struct usbs_rx_endpoint defined in usbs.h
620     int                 fetched;
621     cyg_bool            using_buf_a;
622 } ep1_impl;
623
624 static void ep1_start_rx(usbs_rx_endpoint*);
625 static void ep1_set_halted(usbs_rx_endpoint*, cyg_bool);
626
627 static ep1_impl ep1 = {
628     common: {
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,
634         buffer_size:        0,
635         halted:             0,
636     },
637     fetched:            0,
638     using_buf_a:        0
639 };
640
641 extern usbs_rx_endpoint usbs_imx_otg_ep1 __attribute__((alias ("ep1")));
642 //#endif
643
644 // Endpoint 2 is optional. If the application only involves control
645 // messages or only host->slave transfers then the endpoint 2 support
646 // can be disabled.
647 //#ifdef CYGPKG_DEVS_USB_MX37_EP2
648
649 typedef struct ep2_impl {
650     usbs_tx_endpoint        common;                     //struct usbs_tx_endpoint defined in usbs.h
651     int                     transmitted;
652     int                     pkt_size;
653 } ep2_impl;
654
655 static void ep2_start_tx(usbs_tx_endpoint*);
656 static void ep2_set_halted(usbs_tx_endpoint*, cyg_bool);
657
658 static ep2_impl ep2 = {
659     common: {
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,
665         buffer_size:        0,
666         halted:             0,
667     },
668     transmitted:        0,
669     pkt_size:           0
670 };
671
672 extern usbs_tx_endpoint usbs_imx_otg_ep2 __attribute__ ((alias ("ep2")));
673 //#endif
674
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);
685
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);
689
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);
694
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);
699
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)       |
711         |                                |
712          ------------------------       dQH1
713         |       EP0 OUT (64 bytes)       |
714         |                                |
715          ------------------------       dQH0
716 ARGUMENTS PASSED:
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
732
733 RETURN VALUE:   None
734 IMPORTANT NOTES:None
735 =============================================================================*/
736 static void
737 usbs_setup_queuehead(struct dqh_t* qhead)
738 {
739     volatile struct dqh_setup_t* dqh_word = (volatile struct dqh_setup_t*) qhead->dqh_base;
740
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));
743
744     /*Current dTD Pointer => for hw use, not modified by DCD software */
745     dqh_word->dqh_word1 = 0x0;
746
747     /*Next dTD Pointer */
748     dqh_word->dqh_word2 = (((qhead->next_link_ptr) & 0xFFFFFFE0) | qhead->terminate);
749
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));
752
753     /*Bit31:12 Buffer Pointer (Page 0) */
754     dqh_word->dqh_word4 = ((qhead->buffer_ptr0 & 0xFFFFF000) | (qhead->current_offset & 0xFFF));
755
756     /*Bit31:12 Buffer Pointer (Page 1) */
757     dqh_word->dqh_word5 = (qhead->buffer_ptr1 & 0xFFFFF000);
758
759     /*Bit31:12 Buffer Pointer (Page 2) */
760     dqh_word->dqh_word6 = (qhead->buffer_ptr2 & 0xFFFFF000);
761
762     /*Bit31:12 Buffer Pointer (Page 3) */
763     dqh_word->dqh_word7 = (qhead->buffer_ptr3 & 0xFFFFF000);
764
765     /*Bit31:12 Buffer Pointer (Page 4) */
766     dqh_word->dqh_word8 = (qhead->buffer_ptr4 & 0xFFFFF000);
767
768     /*Reserved */
769     dqh_word->dqh_word9 = 0;
770
771     /*Setup Buffer 0 */
772     dqh_word->dqh_word10 = 0;
773
774     /*Setup Buffer 1 */
775     dqh_word->dqh_word11 = 0;
776 }
777 /*=============================================================================
778 FUNCTION: usbs_setup_transdesc
779 DESCRIPTION: This function is used to setup the dTD
780 ARGUMENTS PASSED:
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
793 RETURN VALUE:   None
794 IMPORTANT NOTES:None
795 ==============================================================================*/
796 static void
797 usbs_setup_transdesc(struct dtd_t* td)
798 {
799     volatile struct dtd_setup_t* dtd_word = (volatile struct dtd_setup_t *) td->dtd_base;
800
801     /* Bit31:5 Next Link Pointer ; Bit0 terminate */
802     dtd_word->dtd_word0 = ((td->next_link_ptr & 0xFFFFFFE0) | td->terminate);
803
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));
806
807     /* Bit31:12 Buffer Pointer Page 0 ; Bit11:0 Current Offset */
808     dtd_word->dtd_word2 = ((td->buffer_ptr0 & 0xFFFFF000) | (td->current_offset & 0xFFF));
809
810     /* Bit31:12 Buffer Pointer Page 1 ; Bit10:0 Frame Number */
811     dtd_word->dtd_word3 = (td->buffer_ptr1 & 0xFFFFF000);
812
813     /* Bit31:12 Buffer Pointer Page 2 ; */
814     dtd_word->dtd_word4 = (td->buffer_ptr2 & 0xFFFFF000);
815
816     /* Bit31:12 Buffer Pointer Page 3 ; */
817     dtd_word->dtd_word5 = (td->buffer_ptr3 & 0xFFFFF000);
818
819     /* Bit31:12 Buffer Pointer Page 4 ; */
820     dtd_word->dtd_word6 = (td->buffer_ptr4 & 0xFFFFF000);
821
822 }
823
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)
833 {
834     cyg_uint32 buffer_addr = (cyg_uint32)NULL; //force type conversion for multiple NULL definitions
835
836     /* Check if buffer1 is free then mark it busy and return address */
837     if (g_bulkbuffer_map.buffer1_status == BUFFER_FREE )
838     {
839         buffer_addr = g_bulkbuffer_map.buffer1_address;
840                 g_bulkbuffer_map.buffer1_status = BUFFER_IN_USE;
841     }
842     /* Check if buffer2 is free then mark it busy and return address */
843     else if(g_bulkbuffer_map.buffer2_status == BUFFER_FREE)
844     {
845         buffer_addr = g_bulkbuffer_map.buffer2_address;
846                 g_bulkbuffer_map.buffer2_status = BUFFER_IN_USE;
847     }
848
849     return buffer_addr ;
850 }
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 .
855 RETURN VALUE:           None
856 IMPORTANT NOTES:        None
857
858 ==================================================================================================*/
859 void util_free_buffer(cyg_uint32 address)
860 {
861         if( address == g_bulkbuffer_map.buffer1_address )
862     {
863         g_bulkbuffer_map.buffer1_status = BUFFER_FREE;
864     }
865     else if ( address == g_bulkbuffer_map.buffer2_address )
866     {
867         g_bulkbuffer_map.buffer2_status = BUFFER_FREE;
868     }
869 }
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
875 enum {
876         BUFFER_FREED,
877         BUFFER_RELEASED,
878         BUFFER_ALLOCATED
879 };
880 RETURN VALUE:           None
881 IMPORTANT NOTES:        None
882
883 ==================================================================================================*/
884 void util_set_status_bulk_buffer(cyg_uint32 buffer_addr,int buffer_status)
885 {
886         if( buffer_addr == (cyg_uint32)g_bulkbuffer_a.buffer)
887     {
888         g_bulkbuffer_a.stat = buffer_status;
889     }
890     else if ( buffer_addr == (cyg_uint32)g_bulkbuffer_b.buffer )
891     {
892         g_bulkbuffer_b.stat = buffer_status;
893     }
894         else
895                 return;
896 }
897 /*=============================================================================
898 FUNCTION:       usbs_endpoint_stall
899 DESCRIPTION: This function Send/Receive the STALL HANDSHAKE to  USB Host
900 ARGUMENTS PASSED:
901         cyg_uint8 endpoint  -   Endpoint Number .
902         cyg_uint8 direction -   IN/OUT :  direction of EndPoint.
903 RETURN VALUE:   None
904 IMPORTANT NOTES:None
905 ==============================================================================*/
906 static void
907 usbs_endpoint_stall(cyg_uint8 endpoint , cyg_uint8 direction)
908 {
909     if( direction == OUT )
910     {
911         usbs_imx_otg_base->endptctrl[endpoint]|= STALL_RX;
912     }
913     else
914     {
915         usbs_imx_otg_base->endptctrl[endpoint] |= STALL_TX;
916     }
917
918         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - EP%d - %d stalled\n",endpoint,direction);
919 }
920
921 static void
922 usbs_endpoint_unstall(cyg_uint8 endpoint , cyg_uint8 direction)
923 {
924         if( direction == OUT )
925     {
926         usbs_imx_otg_base->endptctrl[endpoint]&= ~STALL_RX;
927     }
928     else
929     {
930         usbs_imx_otg_base->endptctrl[endpoint]&= ~STALL_TX;
931     }
932 }
933
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
939 RETURN VALUE:           None
940 IMPORTANT NOTES:
941 ===============================================================================*/
942 static void
943 usbs_status_phase(cyg_uint8 trans_type, cyg_uint8 direction)
944 {
945         usb_buffer_descriptor_t bd ;
946
947     /* Buffer pointer is not used for EP0 */
948     bd.buffer = (cyg_uint32 *) 0xFFFFFFFF;
949     bd.size = 0x0;
950
951     if(trans_type==CONTROL)
952     {
953         switch ( direction )
954         {
955                         case OUT :
956                         /*  Receive ZERO length Length Data */
957                         usbs_ep0_receive_data(&bd);
958                 break;
959                         case IN :
960                         /* Send ZERO length Length Data */
961                         usbs_ep0_send_data(&bd,0);
962                         break;
963         }
964     }
965     else if(trans_type==BULK)/*TODO*/
966     {
967         switch ( direction )
968         {
969                         case OUT :
970                         /* Send ZERO length Length Data */
971                         //usbs_ep2_send_data(EP2,&bd,FALSE);
972                 break;
973                         case IN :
974                         /*  Receive ZERO length Length Data */
975                         //usbs_ep1_receive_data(EP1,&bd);
976                         break;
977         }
978     }
979
980 }
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
987 RETURN VALUE:                   None
988 IMPORTANT NOTES:        None
989 ============================================================================*/
990 static void
991 usbs_handle_get_descriptor()
992 {
993         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get descriptor handler\n");
994         switch (g_usb_setup_data[WVALUE_HIGHBYTE])
995         {
996                 case DEVICE_DESC:       /* device descriptor*/
997                         usbs_handle_get_device_desc();  //Device will send the MPS to host
998                         break;
999                 case CONF_DESC:         /* configuration descriptor*/
1000                         usbs_handle_get_config_desc();  //Device will send the whole device descriptor to host
1001                 break;
1002                 case STRING_DESC:       /* string descriptor*/
1003                         usbs_handle_get_string_desc();
1004                 break;
1005                 case INTERFACE_DESC:
1006                 case ENDPOINT_DESC:
1007                 case DEVICE_QUALIFIER:
1008                 case OTHER_SPEED_CONF_DESC:
1009                 default:        /* Send STALL Handshake  */
1010                 usbs_endpoint_stall(EP0,IN);
1011                 break;
1012         }
1013
1014
1015 }
1016 /*=============================================================================
1017 FUNCTION:                       usbs_handle_get_device_desc
1018 DESCRIPTION:            This function Handle the GET DEVICE DESCRIPTOR request
1019 ARGUMENTS PASSED:       None
1020 RETURN VALUE:           None
1021 IMPORTANT NOTES:        None
1022 ==============================================================================*/
1023 static void
1024 usbs_handle_get_device_desc(void)
1025 {
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
1030
1031         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get device descriptor\n");
1032
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
1035
1036     /* Fill the buffer with the descriptor data */
1037     usbs_ep0in_fill_buffer(FILL_DEVICE_DESC,buffer_addrs);
1038
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);
1042
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 )
1046     {
1047         bd.size = MPS_8;
1048     }
1049     else
1050     {
1051         bd.size = USB_DEV_DESC_LEN;
1052     }
1053
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.
1057
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)
1060
1061
1062 }
1063 /*=============================================================================
1064 FUNCTION:               usbs_handle_get_config_desc
1065 DESCRIPTION:    This function Handle the GET CONFIGURATION DESCRIPTOR request
1066 ARGUMENTS PASSED:
1067 RETURN VALUE:   None
1068 IMPORTANT NOTES:None
1069 =============================================================================*/
1070 static void
1071 usbs_handle_get_config_desc(void)
1072 {
1073         usb_buffer_descriptor_t bd;
1074     cyg_uint32 buffer_addrs;
1075     cyg_uint16 desc_length_req = 0x0;
1076     cyg_uint16 desc_length = 0x0;
1077     int zlt = 0;
1078
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;
1082
1083         /* Fill the buffer with the descriptor data */
1084         usbs_ep0in_fill_buffer(FILL_CONF_DESC, buffer_addrs);
1085
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);
1092
1093
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)
1097     {
1098         bd.size = desc_length_req;
1099     }
1100     else
1101     {
1102         bd.size = desc_length;
1103
1104                 if ( bd.size > MPS_64)
1105                 {
1106                 zlt = 1;
1107                 }
1108     }
1109     usbs_ep0_send_data(&bd,zlt);
1110
1111     /* Status Phase -- OUT */
1112     usbs_status_phase(CONTROL,OUT);
1113
1114 }
1115 /*=============================================================================
1116 FUNCTION:                       usbs_handle_get_string_desc
1117 DESCRIPTION:            This function Handle the GET STRING DESCRIPTOR request
1118 ARGUMENTS PASSED:       None
1119 RETURN VALUE:           None
1120 IMPORTANT NOTES:        None
1121 ==============================================================================*/
1122 static void
1123 usbs_handle_get_string_desc(void)
1124 {
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;
1129     int zlt = 0;
1130
1131
1132     /* Get Buufer to fill the data to be received/transmitted.    */
1133     buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs;
1134
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);
1138
1139     switch (g_usb_setup_data[WVALUE_LOWBYTE])
1140     {
1141         case STR_DES0:
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 )
1146                 {
1147                         bd.size = desc_length_req;
1148                 }
1149                 else
1150                 {
1151                                 bd.size = g_usb_desc.str_desc0->length;
1152                 if (  bd.size > MPS_64)
1153                         {
1154                         zlt = 1;
1155                         }
1156                 }
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");
1162                 break;
1163
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 )
1169                     {
1170                     bd.size = desc_length_req;
1171                 }
1172                 else
1173                 {
1174                                 bd.size = g_usb_desc.str_desc1->length;
1175                 if (  bd.size > MPS_64)
1176                                 {
1177                         zlt = 1;
1178                         }
1179                 }
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");
1185             break;
1186
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 )
1193                     {
1194                     bd.size = desc_length_req;
1195                     }
1196                     else
1197                 {
1198                                 bd.size = length_of_desc;
1199                 if (  bd.size > MPS_64)
1200                     {
1201                             zlt = 1;
1202                         }
1203                     }
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");
1209                     break;
1210
1211         case STR_DES3:
1212                         /* send zero length data */
1213                         usbs_status_phase(CONTROL,IN);
1214                         /* Status Phase -- OUT */
1215             usbs_status_phase(CONTROL,OUT);
1216                         break;
1217
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 )
1224                     {
1225                     bd.size = desc_length_req;
1226                     }
1227                     else
1228                     {
1229                                 bd.size = g_usb_desc.sn_desc->length;
1230                 if (  bd.size > MPS_64)
1231                         {
1232                             zlt = 1;
1233                         }
1234                     }
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");
1240                     break;
1241                         #endif
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 )
1247                     {
1248                     bd.size = desc_length_req;
1249                     }
1250                     else
1251                     {
1252                                 bd.size = g_usb_desc.str_desc3->length;
1253                 if (  bd.size > MPS_64)
1254                         {
1255                             zlt = 1;
1256                         }
1257                     }
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");
1263                     break;
1264                 default:
1265                 /* Send STALL Handshake  */
1266                     usbs_endpoint_stall(EP0,IN);
1267                         //USBDBGMSG("+USBDBGMSG:EP0 IN stalled at get string desc\n");
1268                     break;
1269     }
1270
1271
1272 }
1273
1274 /*=============================================================================
1275 FUNCTION:               usbs_handle_set_address
1276 DESCRIPTION:    This function Handle the SET ADDRESS Request from USB Host
1277 ARGUMENTS PASSED:       None
1278 RETURN VALUE:           None
1279 IMPORTANT NOTES:
1280 ==============================================================================*/
1281 static void
1282 usbs_handle_set_address(void)
1283 {
1284                 cyg_uint16 device_addrs;
1285
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);
1289
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))
1295     {
1296         switch(g_usb_dev_state)
1297                 {
1298                 case USB_DEV_DEFAULT_STATE :
1299                                 /* Send Ack to Host */
1300                                 usbs_status_phase(CONTROL,IN);
1301                                 if (device_addrs != USB_DEFAULT_ADDR)
1302                                 {
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;
1307                                 }
1308                         break;
1309
1310                         case USB_DEV_ADDRESSED_STATE :
1311                                 /* Send Ack to Host */
1312                                 usbs_status_phase(CONTROL,IN);
1313                                 if ( device_addrs == USB_DEFAULT_ADDR )
1314                                 {
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;
1319                         }
1320                                 else
1321                                 {
1322                                         /* Set the Device Address */
1323                                         USBS_DEVICE_SET_ADDRESS(device_addrs);
1324                                 }
1325                                 break;
1326
1327             case USB_DEV_CONFIGURED_STATE :
1328                         if ( device_addrs == USB_DEFAULT_ADDR)
1329                                 {
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;
1336                                 }
1337                                 else
1338                                 {
1339                                         /* Send STALL Handshake  */
1340                                         usbs_endpoint_stall(EP0,IN);
1341                                 }
1342                         default :
1343                                 break;
1344                 }
1345     }
1346     else
1347     {
1348         /* Send STALL Handshake */
1349         usbs_endpoint_stall(EP0,IN);
1350     }
1351
1352
1353 }
1354 /*=============================================================================
1355 FUNCTION:                       usbs_handle_get_configuration
1356 DESCRIPTION:            This function Handle the GET CONFIGURATION request
1357 ARGUMENTS PASSED:       None
1358 RETURN VALUE:           None
1359 IMPORTANT NOTES:        None
1360 =============================================================================*/
1361 static void
1362 usbs_handle_get_configuration(void)
1363 {
1364         usb_buffer_descriptor_t bd;
1365         cyg_uint32 buffer_addrs;
1366     cyg_uint32* buffer_ptr;
1367
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))
1374     {
1375         switch(g_usb_dev_state)
1376                 {
1377                 case USB_DEV_DEFAULT_STATE :
1378                         /* Send STALL Handshake */
1379                         usbs_endpoint_stall(EP0,IN);
1380                                 break;
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;
1385                                 *buffer_ptr = 0x0;
1386
1387                                 bd.buffer = buffer_ptr;
1388                                 bd.size=LEN_OF_CONFIG_VALUE;
1389
1390                                 usbs_ep0_send_data(&bd,0);
1391
1392                                 /* Receive Ack from Host*/
1393                                 usbs_status_phase(CONTROL,OUT);
1394                                 break;
1395
1396                         case USB_DEV_CONFIGURED_STATE:
1397                                 buffer_addrs = g_bulkbuffer_map.ep0_buffer_addrs;
1398                 buffer_ptr = (cyg_uint32 *)buffer_addrs;
1399
1400                                 *buffer_ptr = (cyg_uint32 )g_usb_desc.config_desc->usb_config_desc.configuration_id;
1401
1402                                 bd.buffer = buffer_ptr;
1403                                 bd.size=LEN_OF_CONFIG_VALUE;
1404
1405                                 usbs_ep0_send_data(&bd,0);
1406
1407                                 /* Receive Ack from Host*/
1408                                 usbs_status_phase(CONTROL,OUT);
1409                                 break;
1410
1411                         default:
1412                         /* Send STALL Handshake */
1413                         usbs_endpoint_stall(EP0,IN);
1414                 }
1415
1416     }
1417
1418                 USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - get config handler\n");
1419 }
1420 /*=============================================================================
1421 FUNCTION:                       usbs_handle_set_configuration
1422 DESCRIPTION:            This function Handle the SET CONFIGURATION request
1423 ARGUMENTS PASSED:       None
1424 RETURN VALUE:           None
1425 IMPORTANT NOTES:        None
1426 =============================================================================*/
1427 static void
1428 usbs_handle_set_configuration(void)
1429 {
1430         usb_end_pt_info_t config_data ;
1431     cyg_uint8 i;
1432
1433     switch (g_usb_dev_state)
1434     {
1435                 case USB_DEV_ADDRESSED_STATE :
1436                         if (g_usb_setup_data[WVALUE_LOWBYTE] == USB_DEV_VALUE_OF_UNCONFIG)
1437                         {
1438                                 /* Send Ack to Host*/
1439                                 usbs_status_phase(CONTROL,IN);
1440                     }
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)
1443                     {
1444                                 /* Configure endpoints */
1445                                 for ( i = 0 ; i< g_number_of_endpoints ; i++)
1446                                 {
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;
1451
1452                                         usbs_imx_otg_dev_set_configuration(&config_data);
1453                                 }
1454
1455                                 /* Send Ack to Host*/
1456                                 usbs_status_phase(CONTROL,IN);
1457
1458                                 g_usb_dev_state = USB_DEV_CONFIGURED_STATE ;
1459                 }
1460                 else
1461                 {
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");
1465                 }
1466                         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set conf@ADDRESSED_STATE\n");
1467                         break;
1468                 case USB_DEV_CONFIGURED_STATE :
1469                 if(g_usb_setup_data[WVALUE_LOWBYTE] == USB_DEV_CONFIG_DESC_CONFIG_VALUE)
1470                 {
1471                                 /* Send Ack to Host*/
1472                                 usbs_status_phase(CONTROL,IN);
1473                 }
1474                 else if (g_usb_setup_data[WVALUE_LOWBYTE] == USB_DEV_VALUE_OF_UNCONFIG)
1475                 {
1476                                 /* Send Ack to Host*/
1477                                 usbs_status_phase(CONTROL,IN);
1478
1479                                 /* Change USB State to Addressed State  */
1480                                 g_usb_dev_state = USB_DEV_ADDRESSED_STATE;
1481                 }
1482                         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set conf@CONFIGURED_STATE\n");
1483                         break;
1484                 default :
1485                 /* Send STALL Handshake */
1486                 usbs_endpoint_stall(EP0,IN);
1487                         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set conf@incorrect state\n");
1488                 break;
1489     }
1490
1491         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: enum - set config handler\n");
1492 }
1493 /*=============================================================================
1494 FUNCTION:                       usbs_handle_msc_get_maxlun
1495 DESCRIPTION:            This function Handle the GET MAX LUN Mass Storage class
1496                                 specific request
1497 ARGUMENTS PASSED:       None
1498 RETURN VALUE:           None
1499 IMPORTANT NOTES:        None
1500 =============================================================================*/
1501 static void
1502 usbs_handle_msc_get_maxlun(void)
1503 {
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");
1510
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
1513
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);
1517
1518     /* If requested length of descriptor is zero*/
1519         if(desc_length==0)
1520         {
1521                 /* Fill the buffer with the descriptor data */
1522                 *(cyg_uint8 *)buffer_addrs = 0;//Max_Lun;
1523                 bd.size = 0;
1524         }
1525         else
1526         {
1527                 /* Fill the buffer with the descriptor data */
1528                 *(cyg_uint8 *)buffer_addrs = Max_Lun;
1529                 bd.size = desc_length;
1530         }
1531
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.
1535
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)
1538
1539
1540 }
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
1545 ARGUMENTS PASSED:
1546                                 cyg_uint8 type: type of descriptor
1547                                 cyg_uint32 buffer_addrs - buffer pointer to be filled
1548 RETURN VALUE:   None
1549 IMPORTANT NOTES:None
1550 =============================================================================*/
1551 static void
1552 usbs_ep0in_fill_buffer(cyg_uint8 type, cyg_uint32 buffer_addrs)
1553 {
1554     const cyg_uint8 *data=0;
1555     cyg_uint32 *buffer_page = (cyg_uint32*)buffer_addrs;
1556     int k = 0;
1557         //USBDBGMSG("+USBDBGMSG: enum - copy descriptor to buffer\n");
1558     switch (type)
1559     {
1560         case FILL_DEVICE_DESC:  /*5*32 bit */
1561                 data = (cyg_uint8 *)g_usb_desc.device_desc;
1562             break;
1563                 case FILL_CONF_DESC:            /*8*32 bit */
1564                     data = (cyg_uint8 *)g_usb_desc.config_desc;
1565                 break;
1566                 case FILL_STR_DES0:             /*1*32 bit */
1567                 data = (cyg_uint8 *)g_usb_desc.str_desc0;
1568                 break;
1569                 case FILL_STR_DES1:             /*7*32 bit */
1570                     data =(cyg_uint8 *)g_usb_desc.str_desc1;
1571                 break;
1572                 case FILL_STR_DES2:             /*7*32 bit */
1573                         data = (cyg_uint8 *)g_usb_desc.str_desc2;
1574                     break;
1575                 case FILL_STR_DES3:             /*6*32 bit */
1576                     data = (cyg_uint8 *)g_usb_desc.str_desc3;
1577                 break;
1578                 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
1579                 case FILL_SN_DESC:
1580                         data = (cyg_uint8 *)g_usb_desc.sn_desc;
1581                         break;
1582                 #endif
1583     }
1584
1585     for (k=0; k<(MPS_64/sizeof(cyg_uint32)); k++)
1586     {
1587         *buffer_page = data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24);
1588                                  //USBDBGMSG("+USBDBGMSG: desc[k] = 0x%x\n",(*buffer_page));
1589          buffer_page++;
1590                                  data += 4;
1591
1592     }
1593
1594
1595 }
1596
1597 /*=============================================================================
1598 FUNCTION:                       usbs_ep0_init_dqh
1599 DESCRIPTION:            This function is used to initialize the queue header of EP0
1600 ARGUMENTS PASSED:       NONE
1601 RETURN VALUE:           NONE
1602 IMPORTANT NOTES:        called by usbs_imx_otg_dev_ep0_init(),usbs_imx_otg_dev_handle_bus_reset()
1603 =============================================================================*/
1604 static void
1605 usbs_ep0_init_dqh(void)
1606 {
1607         struct dqh_t qhead;
1608         cyg_uint32 total_bytes;
1609         volatile cyg_uint32 * ep_q_hdr_base;
1610         cyg_int8 i;
1611
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++)
1616     {
1617         *ep_q_hdr_base++ = 0;
1618     }
1619
1620      /******************************************************************************
1621     / =================
1622     / dQH0 for EP0OUT
1623     / =================
1624     / Initialize device queue heads in system memory
1625     / 8 bytes for the 1st setup packet */
1626
1627     total_bytes                                 = 0x8;
1628     qhead.dqh_base                              = USBS_EP_GET_dQH(EP0,OUT);
1629     qhead.zlt                                   = ZLT_DISABLE;
1630     qhead.mps                                   = MPS_64;
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);
1645
1646     /* ==================
1647     END of dQH0 setup
1648     ====================*/
1649      /*=================
1650     dQH1 for EP0IN
1651     ================= */
1652
1653     total_bytes                 = 0x8;
1654     qhead.dqh_base              = USBS_EP_GET_dQH(EP0,IN);
1655     qhead.zlt                   = ZLT_DISABLE;
1656     qhead.mps                   = MPS_64;
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;
1669
1670     /* Set Device Queue Head */
1671     usbs_setup_queuehead(&qhead);
1672
1673     /* ==================
1674     /  END of dQH1 setup
1675     /  ================*/
1676 }
1677 /*=============================================================================
1678 FUNCTION:                       usbs_ep0_send_data
1679 DESCRIPTION:            This function Send Data to host through EP0-IN Pipe.
1680 ARGUMENTS PASSED:
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
1683 RETURN VALUE:
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 =============================================================================*/
1689 static usb_status_t
1690 usbs_ep0_send_data(usb_buffer_descriptor_t* bd,cyg_uint8 zlt)
1691 {
1692         struct dtd_t td;
1693     cyg_uint32 total_bytes ;
1694     cyg_uint32 dtd_address,dqh_address;
1695
1696     usb_status_t status = USB_FAILURE;
1697
1698         /* Get Device Transfer Descriptor of the requested endpoint */
1699         dtd_address = USBS_EP_GET_dTD(EP0,IN);
1700
1701         /* Get Device Queue head of the requested endpoint */
1702         dqh_address = USBS_EP_GET_dQH(EP0,IN);
1703
1704         /* Get Total Bytes to Be recieved */
1705         total_bytes = bd->size;
1706
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;
1712         td.ioc                          = IOC_SET;
1713         td.status                       = ACTIVE;
1714         td.buffer_ptr0          = g_bulkbuffer_map.ep0_buffer_addrs;
1715         td.current_offset       = (g_bulkbuffer_map.ep0_buffer_addrs & 0xFFF);
1716         td.buffer_ptr1          = 0;
1717         td.buffer_ptr2          = 0;
1718         td.buffer_ptr3          = 0;
1719         td.buffer_ptr4          = 0;
1720
1721         /* Set the transfer descriptor */
1722         usbs_setup_transdesc(&td);
1723
1724         /* Enable ZLT when data size is in multiple of Maximum Packet Size  */
1725         if(zlt)
1726         {
1727                 /* set ZLT enable */
1728                 (*(volatile cyg_uint32*)(dqh_address)) &= ~0x20000000;
1729         }
1730
1731         /* 1. write dQH next ptr and dQH terminate bit to 0  */
1732         *(volatile cyg_uint32*)(dqh_address+0x8)= (dtd_address);
1733
1734         /* 2. clear active & halt bit in dQH */
1735         *(volatile cyg_uint32*)(dqh_address+0xC) &= ~0xFF;
1736
1737         /* 3. prime endpoint by writing '1' in ENDPTPRIME */
1738         usbs_imx_otg_base->endptprime |= BIT16;
1739
1740         /* wait for complete set and clear */
1741         while (!(usbs_imx_otg_base->endptcomplete & EPIN_COMPLETE));
1742
1743         usbs_imx_otg_base->endptcomplete = EPIN_COMPLETE;
1744
1745         status = USB_SUCCESS;
1746
1747         return status;
1748 }
1749 /*=============================================================================
1750 FUNCTION: usbs_ep0_recevie_data
1751 DESCRIPTION:    This function Handle the Status Token (IN/OUT) from USB Host
1752 ARGUMENTS PASSED:
1753         usb_buffer_descriptor_t *bd : This is the pointer to the buffer descriptor.
1754 RETURN VALUE:
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)
1762 {
1763                 struct dtd_t td;
1764     usb_status_t status = USB_FAILURE;
1765     cyg_uint32 total_bytes;
1766     cyg_uint32 dtd_address;
1767     cyg_uint32 dqh_address;
1768
1769                 /* Get Device Device Queue Head of the requested endpoint */
1770     dqh_address = USBS_EP_GET_dQH(EP0, OUT);
1771
1772                 /* Get Device Transfer Descriptor of the requested endpoint */
1773     dtd_address = USBS_EP_GET_dTD(EP0, OUT);
1774
1775                 /* Get the total bytes to be received   */
1776                 total_bytes             = bd->size;
1777
1778                 td.dtd_base                     = dtd_address;
1779                 td.next_link_ptr        = dtd_address + 0x20;
1780                 td.terminate            = TERMINATE;
1781                 td.total_bytes          = total_bytes;
1782                 td.ioc                          = IOC_SET;
1783                 td.status                       = ACTIVE;
1784                 td.buffer_ptr0          = g_bulkbuffer_map.ep0_buffer_addrs;
1785                 td.current_offset       = (g_bulkbuffer_map.ep0_buffer_addrs & 0xFFF);
1786                 td.buffer_ptr1          = 0;
1787                 td.buffer_ptr2          = 0;
1788                 td.buffer_ptr3          = 0;
1789                 td.buffer_ptr4          = 0;
1790
1791         /* Set the Transfer Descriptor  */
1792         usbs_setup_transdesc(&td);
1793
1794         /* 1. write dQH next ptr and dQH terminate bit to 0 */
1795         *(volatile cyg_uint32*)(dqh_address+0x8)= dtd_address;
1796
1797         /* 2. clear active & halt bit in dQH */
1798         *(volatile cyg_uint32*)(dqh_address+0xC) &= ~0xFF;
1799
1800         /* 3. prime endpoint by writing '1' in ENDPTPRIME */
1801         usbs_imx_otg_base->endptprime |= (  EPOUT_PRIME << EP0 );
1802
1803         /* 4. Wait for the Complete Status */
1804         while (!((usbs_imx_otg_base->endptprime) & ( EPOUT_COMPLETE << EP0)));
1805
1806         /*clear the complete status */
1807         usbs_imx_otg_base->endptprime = (EPOUT_COMPLETE << EP0);
1808
1809         status = USB_SUCCESS;
1810
1811         return status;
1812 }
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
1822 // simple.
1823 // so far, ep0 DSR works only during enumeration here.
1824 =============================================================================*/
1825 static void
1826 usbs_imx_otg_dev_ep0_dsr(void)
1827 {
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;
1832         cyg_uint32 temp;
1833
1834         //USBDBGMSG("+USBDBGMSG: enter ep0 dsr.\n");
1835         /* 1. Receive Setup Data*/
1836         bd.buffer = (cyg_uint32 *)g_usb_setup_data;
1837         bd.size   = 0;
1838
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;
1842
1843         /* write '1' to clear corresponding bit in ENDPTSETUPSTAT */
1844         temp = usbs_imx_otg_base->endptsetupstat;
1845         usbs_imx_otg_base->endptsetupstat = temp;
1846
1847 //      if(usbs_imx_otg_base->endptsetupstat & BIT0)
1848 //              usbs_imx_otg_base->endptsetupstat = BIT0;
1849
1850         do{
1851             /* write '1' to Setup Tripwire (SUTW) in USBCMD register */
1852             usbs_imx_otg_base->usbcmd |= BIT13;
1853
1854             /* Copy the SetupBuffer into local software byte array */
1855             temp  = (dqh_word->dqh_word10);
1856
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;
1865
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));
1876
1877         /* Write '0' to clear SUTW in USBCMD register */
1878         usbs_imx_otg_base->usbcmd &= ~BIT13;
1879         status = USB_SUCCESS;
1880
1881         #if 0
1882         USBDBGMSG("+USBDBGMSG: setup packet:(LSB)");
1883         for(temp=0;temp<8;temp++)
1884         {
1885                 USBDBGMSG("%02X",g_usb_setup_data[temp]);
1886         }
1887         USBDBGMSG("(MSB)\n");
1888         #endif
1889
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])
1894         {
1895                 case USB_GET_DESCRIPTOR:
1896                         /* Handle the GET DESCRIPTOR Request */
1897                         usbs_handle_get_descriptor();
1898             break;
1899
1900                 case USB_SET_ADDRESS:
1901                         /* Handle the SET ADDRESS Request */
1902                         usbs_handle_set_address();
1903                         break;
1904
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))
1912                         {
1913                                 usbs_handle_set_configuration();
1914                         }
1915                         else
1916                         {
1917                                 /* Send STALL Handshake   */
1918                                 usbs_endpoint_stall(EP0,IN);
1919                                 //USBDBGMSG("+USBDBGMSG:EP0 IN stalled at set conf in ep0 dsr\n");
1920                 }
1921                 break;
1922
1923                 case USB_GET_CONFIGURATION:
1924                         /* GET CONFIGURATION request handler */
1925                         usbs_handle_get_configuration();
1926                         break;
1927                 case USB_MSC_GET_MAX_LUN:
1928                         usbs_handle_msc_get_maxlun();
1929                         break;
1930                 case USB_MSC_BOT_RESET:
1931
1932                 default:
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]);
1937                 break;
1938         }
1939
1940         USBDBGMSG(DEBUG_ENUM,"+USBDBGMSG: ep0 dsr\n");
1941 }
1942 /*=============================================================================
1943 // Endpoint 0 initialization.
1944 // Control Endpoint, bi-direction
1945 // This may get called during system start-up or following a reset
1946 // from the host.
1947 =============================================================================*/
1948 static void
1949 usbs_imx_otg_dev_ep0_init(void)
1950 {
1951         /*initialize Endpoint 0 Queue Header*/
1952         usbs_ep0_init_dqh();
1953
1954         {
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))
1958     {
1959                 #if !defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
1960            (*ep0.common.complete_fn)(&ep0.common, -EPIPE);
1961                 #endif
1962     }
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;
1972     ep0.length                  = 0;
1973     ep0.transmitted             = 0;
1974         }
1975 }
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
1986 // reset.
1987 =============================================================================*/
1988 static void
1989 usbs_imx_otg_dev_ep0_start(usbs_control_endpoint* endpoint)
1990 {
1991         cyg_uint32 temp;
1992
1993         CYG_ASSERT( endpoint == &ep0.common, "USB startup involves the wrong endpoint");
1994
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
1998
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);
2001
2002         /*set Run/Stop bit to Run Mode*/
2003         usbs_imx_otg_base->usbcmd |= BIT0;
2004
2005         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: mx37 ep0 start.\n");
2006 }
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 =============================================================================*/
2014 static void
2015 ep1_rx_complete(int result)
2016 {
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;
2023
2024         if (g_usb_dev_state != USB_DEV_CONFIGURED_STATE)
2025                 return; //EP1 only receives data when the USB device has been configured
2026
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
2030         }
2031
2032         /* Get Device Device Queue Head of the out endpoint */
2033         dqh_address = USBS_EP_GET_dQH(EP1,OUT);
2034
2035         /* Get Device Transfer Descriptor of the out endpoint */
2036         dtd_address = USBS_EP_GET_dTD(EP1,OUT);
2037
2038         /*clear the complete status */
2039         usbs_imx_otg_base->endptcomplete |= (EPOUT_COMPLETE << EP1);
2040
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");
2046                 return;
2047         }
2048
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);
2054         #if 0
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
2058         {
2059                 g_bulk_out_transdesc_buffer_offset = 0;
2060                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_start_rx - set offset to zero \n");
2061         }
2062
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;
2065         #endif
2066
2067         /* tell ep1 how many bytes data is received*/
2068         ep1.fetched     = received_data_length;
2069
2070         if(ep1.fetched)
2071         {
2072                 if(ep1.fetched == 31)
2073                         g_received_data_type = MASS_STORAGE_CBW_TYPE;
2074                 else
2075                         g_received_data_type = MASS_STORAGE_DATA_TYPE;
2076                 ep1.common.complete_data    = (void*)(ep1.common.buffer);
2077
2078                 #if 0
2079                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete: \n");
2080                 USBDBGMSG(DEBUG_TRANS,"----Dump Bulk-Out Recevied Data----\n");
2081                 for(i=0;i<32;i++)
2082                 {
2083                         USBDBGMSG(DEBUG_TRANS,"%02X ", *((cyg_uint8 *)(ep1.common.complete_data)+i));
2084                 }
2085                 USBDBGMSG(DEBUG_TRANS,"\n");
2086                 #endif
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
2091         }
2092
2093     #if 0
2094         if(ep1.fetched == 31)
2095         {
2096                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1_rx_complete - recevied data: \n");
2097                 for(i=0;i<32;i++)
2098                 {
2099                         USBDBGMSG(DEBUG_TRANS,"%02X ", *((cyg_uint8 *)(ep1.common.complete_data)+i));
2100                 }
2101                 USBDBGMSG(DEBUG_TRANS,"\n");
2102
2103                 for(i=0;i<32;i++)
2104                 {
2105                         USBDBGMSG(DEBUG_TRANS,"%02X ", *((cyg_uint8 *)received_buffer_addrs+i));
2106                 }
2107                 USBDBGMSG(DEBUG_TRANS,"\n");
2108         }
2109         #endif
2110
2111
2112 }
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 =============================================================================*/
2118 static void
2119 ep1_start_rx(usbs_rx_endpoint* endpoint)
2120 {
2121         struct dtd_t td;
2122         cyg_uint32 total_bytes;
2123         cyg_uint32 dtd_address;
2124         cyg_uint32 dqh_address;
2125     cyg_uint32 buffer_addrs_page0;
2126
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)
2131         {
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
2134         }
2135         #endif
2136         /* Get Device Device Queue Head of the out endpoint */
2137         dqh_address = USBS_EP_GET_dQH(EP1,OUT);
2138
2139         /* Get Device Transfer Descriptor of the out endpoint */
2140         dtd_address = USBS_EP_GET_dTD(EP1,OUT);
2141
2142         /* ==Prepare TD for next bulk out transfer== */
2143         /* get the dTD buffer pointer */
2144         buffer_addrs_page0 = (cyg_uint32)(endpoint->buffer);
2145
2146         /* Get the total bytes to be received   */
2147         total_bytes = endpoint->buffer_size;
2148
2149         /* OUT setup dTD */
2150         td.dtd_base             = dtd_address;
2151         td.next_link_ptr        = dtd_address + 0x20;
2152         td.terminate            = TERMINATE;
2153         td.total_bytes          = total_bytes;
2154         td.ioc                          = IOC_SET;
2155         td.status                       = ACTIVE;
2156         td.buffer_ptr0          = buffer_addrs_page0 ;
2157         td.current_offset       = ( buffer_addrs_page0 & 0xFFF ) + g_td_buffer_offset;
2158         td.buffer_ptr1          = 0;
2159         td.buffer_ptr2          = 0;
2160         td.buffer_ptr3          = 0;
2161         td.buffer_ptr4          = 0;
2162
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);
2170
2171         /* Set the Transfer Descriptor  */
2172         usbs_setup_transdesc(&td);
2173
2174         /* 1. write dQH next ptr and dQH terminate bit to 0 */
2175         *(volatile cyg_uint32 *)(dqh_address+0x8)= dtd_address;
2176
2177         /* 2. clear active & halt bit in dQH */
2178         *(volatile cyg_uint32 *)(dqh_address+0xC) &= ~0xFF;
2179
2180         /* 3. prime endpoint by writing '1' in ENDPTPRIME
2181                 prime bulk out endpoint after sending the CSW of last command
2182         */
2183         //usbs_imx_otg_base->endptprime |= ( EPOUT_PRIME << EP1 );
2184
2185 }
2186 /*=============================================================================
2187 // The exported interface to halt the EP1
2188 =============================================================================*/
2189 static void
2190 ep1_set_halted(usbs_rx_endpoint* endpoint, cyg_bool new_value)
2191 {
2192         if (ep1.common.halted == new_value) {
2193         return;
2194     }
2195     if (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;
2201     }
2202         else {
2203         // Take care of the hardware so that a new transfer is allowed.
2204         usbs_endpoint_unstall(EP1,OUT);
2205         ep1.common.halted = 0;
2206     }
2207
2208 }
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
2212 // bit is set.
2213 // [Note] EP1 DSR is only used to receive the command block wrapper from host
2214 // to USB mass storage device
2215 =============================================================================*/
2216
2217 static void
2218 usbs_imx_otg_dev_ep1_dsr(void)
2219 {
2220         int result = 0; //contains the actual recevied data length from bulk-out endpoint
2221         g_received_data_type = 0;//MASS_STORAGE_CBW_TYPE
2222
2223         if(ep1.common.buffer)//buffer of TD is not null, then receive
2224         {
2225                 ep1_rx_complete(result);
2226         }
2227         //USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1 dsr - result = %d\n",result);
2228         //recevie mass storage device CBW
2229
2230         if((ep1.fetched == 31)&&(g_received_data_type == MASS_STORAGE_CBW_TYPE))
2231         {
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);
2236                 #endif
2237                 ep1.fetched = 0;
2238         }
2239         else
2240                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep1 dsr - received %d byte\n",ep1.fetched);
2241
2242 }
2243
2244 /*=============================================================================
2245 // Endpoint 1 initialization.
2246 // Bulk-OUT Endpoint
2247 // This may get called during system start-up or following a reset
2248 // from the host.
2249 =============================================================================*/
2250 static void
2251 usbs_imx_otg_dev_ep1_init(void)
2252 {
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*/
2256
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);
2264 }
2265
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 =============================================================================*/
2273 static void
2274 ep2_tx_complete(int result)
2275 {
2276     void (*complete_fn)(void*, int)  = ep2.common.complete_fn;
2277     void* complete_data = ep2.common.complete_data;
2278
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;
2283
2284     if (NULL != complete_fn) {
2285         complete_fn(complete_data, result);
2286     }
2287 }
2288
2289 /*=============================================================================
2290 // The exported interface to start to transmit data to Host
2291 =============================================================================*/
2292 static void
2293 ep2_start_tx(usbs_tx_endpoint* endpoint)
2294 {
2295         int timeout = 400;
2296         struct dtd_t td;
2297     cyg_uint32 total_bytes ;
2298     cyg_uint32 dtd_address,dqh_address;
2299     cyg_uint32 buffer_addrs_page0;
2300     cyg_uint32 size = 0x0;
2301
2302         /* Get Device Transfer Descriptor of the requested endpoint */
2303         dtd_address = USBS_EP_GET_dTD(EP2,IN);
2304
2305         /* Get Device Queue head of the requested endpoint */
2306         dqh_address = USBS_EP_GET_dQH(EP2,IN);
2307
2308         /* allocate memory for data transfer */
2309         buffer_addrs_page0 = endpoint->buffer;
2310
2311         if(buffer_addrs_page0 == 0)
2312         {
2313                 USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep2_start_tx: NULL tx buffer \n");
2314                 return;
2315         }
2316
2317         total_bytes = (cyg_uint32)(endpoint->buffer_size);
2318         size = (total_bytes < BULK_TD_BUFFER_TOTAL_SIZE )?total_bytes:(BULK_TD_BUFFER_TOTAL_SIZE);
2319
2320         td.dtd_base             = dtd_address;
2321         td.next_link_ptr        = dtd_address + 0x20 ;
2322         td.terminate            = TERMINATE;
2323         td.total_bytes          = size;
2324         td.ioc                          = IOC_SET;
2325         td.status                       = ACTIVE;
2326         td.buffer_ptr0          = buffer_addrs_page0 ;
2327         td.current_offset       = (buffer_addrs_page0 & 0xFFF)+ g_td_buffer_offset;
2328         td.buffer_ptr1          = 0;
2329         td.buffer_ptr2          = 0;
2330         td.buffer_ptr3          = 0;
2331         td.buffer_ptr4          = 0;
2332
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);
2340
2341         /* Set the Transfer Descriptor  */
2342         usbs_setup_transdesc(&td);
2343
2344         /* 1. write dQH next ptr and dQH terminate bit to 0  */
2345         *(volatile cyg_uint32 *)(dqh_address+0x8)= (dtd_address);
2346
2347         /* 2. clear active & halt bit in dQH */
2348         *(volatile cyg_uint32 *)(dqh_address+0xC) &= ~0xFF;
2349
2350         /* 3. prime endpoint by writing '1' in ENDPTPRIME */
2351         usbs_imx_otg_base->endptprime = ( EPIN_PRIME << EP2 );
2352
2353         /* wait for complete set and clear */
2354         while (!((usbs_imx_otg_base->endptcomplete) & (EPIN_COMPLETE<<EP2)));
2355
2356         usbs_imx_otg_base->endptcomplete |= (EPIN_COMPLETE << EP2);
2357
2358         ep2.transmitted = size;
2359
2360         ep2_tx_complete(-EPIPE);
2361
2362         USBDBGMSG(DEBUG_TRANS,"+USBDBGMSG: ep2 tx done\n");// ep2.transmitted);
2363
2364 }
2365 /*=============================================================================
2366 // The exported interface to halt the EP2
2367 =============================================================================*/
2368 static void
2369 ep2_set_halted(usbs_tx_endpoint* endpoint, cyg_bool new_value)
2370 {
2371         if (ep2.common.halted == new_value) {
2372         return;
2373     }
2374     if (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;
2380     }
2381         else {
2382         // Take care of the hardware so that a new transfer is allowed.
2383         usbs_endpoint_unstall(EP2,IN);
2384         ep2.common.halted = 0;
2385     }
2386 }
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 =============================================================================*/
2391
2392 static void
2393 usbs_imx_otg_dev_ep2_dsr(void)
2394 {
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);
2398
2399
2400         if(ep2.common.buffer_size==0)
2401         {
2402                 ep2_tx_complete(-EPIPE);
2403                 ep2.transmitted = 0;    //clear the field to wait for the next transmit
2404         }
2405
2406 }
2407
2408 /*=============================================================================
2409 // Endpoint 2 initialization.
2410 // Bulk-IN Endpoint
2411 // This may be called during system start-up or following a reset
2412 // from the host.
2413 =============================================================================*/
2414 static void
2415 usbs_imx_otg_dev_ep2_init(void)
2416 {
2417         //at initialization, ep2.common.buffer is NULL. The buffer should be initialized
2418         //by upper layer caller.
2419
2420         // Endpoints should never be halted after a reset
2421     ep2.common.halted   = false;
2422
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);
2427 }
2428
2429 // ****************************************************************************
2430 // -----------------------MX37 USB Device Driver API Functions-----------------
2431 // ****************************************************************************
2432
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 =============================================================================*/
2440 static void
2441 usbs_imx_otg_dev_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
2442 {
2443     int status = 0;
2444     cyg_uint32 temp;
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();
2457
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)
2467     {
2468         int new_status = usbs_imx_otg_base->usbsts;
2469         if (0 == (new_status & IMX_USB_STS_RESET))
2470         {
2471                         usbs_imx_otg_dev_handle_bus_reset();
2472                         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: !!USB BUS RESET\n");
2473         }
2474
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);
2478                 #endif
2479     }
2480         else if(status & IMX_USB_STS_USBINT)
2481         {
2482
2483                 if(usbs_imx_otg_base->endptsetupstat & BIT0)
2484         {// if Setup Packet arrived
2485                 usbs_imx_otg_dev_ep0_dsr();
2486         }
2487
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
2491         }
2492
2493
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();
2497
2498         }
2499
2500                 else if((usbs_imx_otg_base->endptcomplete) & ( EPOUT_COMPLETE << EP0))
2501                 {
2502                         //usbs_imx_otg_dev_ep0_dsr();
2503                         usbs_imx_otg_base->endptcomplete = ( EPOUT_COMPLETE << EP0);
2504                 }
2505         else
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");
2510                 }
2511
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);
2515                 #endif
2516         }
2517     else
2518     {
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);
2522                 #endif
2523     }
2524
2525
2526 }
2527 /*=============================================================================
2528 // The DSR thread
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;
2537
2538
2539 static void
2540 usbs_imx_otg_dev_thread_fn(cyg_addrword_t param)
2541 {
2542         USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: usb driver thread\n");
2543         for (;;) {
2544         cyg_semaphore_wait(&usbs_imx_otg_dev_sem);
2545                 usbs_imx_otg_dev_dsr(IMX_IRQ_USB_DEV_SERVICE_REQUEST, 0, 0);
2546     }
2547     CYG_UNUSED_PARAM(cyg_addrword_t, param);
2548 }
2549
2550 static void
2551 usbs_imx_otg_dev_thread_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
2552 {
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);
2555
2556
2557     CYG_UNUSED_PARAM(cyg_vector_t, vector);
2558     CYG_UNUSED_PARAM(cyg_ucount32, count);
2559     CYG_UNUSED_PARAM(cyg_addrword_t, data);
2560 }
2561 #endif
2562 /*=============================================================================
2563 // The interrupt handler. This does as little as possible.
2564 =============================================================================*/
2565 static cyg_uint32
2566 usbs_imx_otg_dev_isr(cyg_vector_t vector, cyg_addrword_t data)
2567 {
2568         cyg_uint32 old_status_bits = g_isr_status_bits;
2569         cyg_uint32 status_bits;
2570
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" );
2573
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)
2583     {
2584
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);
2588     }
2589         else if(status_bits & IMX_USB_STS_USBINT)
2590         {
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);
2594         }
2595     else
2596     {
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");
2600         }
2601
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;
2605 }
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 =============================================================================*/
2611 static void
2612 usbs_imx_otg_dev_poll(usbs_control_endpoint* endpoint)
2613 {
2614         CYG_ASSERT( endpoint == &ep0.common, "USB poll involves the wrong endpoint");
2615
2616     if (g_isr_status_bits & IMX_USB_STS_RESET)
2617     {
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))
2622         {
2623             g_isr_status_bits = 0;
2624             usbs_imx_otg_dev_handle_bus_reset();
2625         }
2626     }
2627     else
2628     {
2629         g_isr_status_bits = usbs_imx_otg_base->usbsts;
2630         if (IMX_USB_STS_PTCHANGE & g_isr_status_bits)
2631         {
2632             //process Port Change Detect
2633             usbs_imx_otg_dev_handle_port_change();
2634         }
2635         else if (IMX_USB_STS_USBINT & g_isr_status_bits)
2636         {
2637             usbs_imx_otg_dev_dsr(IMX_IRQ_USB_DEV_SERVICE_REQUEST, 0, (cyg_addrword_t) 0);
2638         }
2639         else
2640         {
2641                 usbs_imx_otg_base->usbsts = g_isr_status_bits;  //clear the don't-care status
2642         }
2643     }
2644 }
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 =============================================================================*/
2651 static void
2652 usbs_imx_otg_dev_handle_bus_reset(void)
2653 {
2654         cyg_uint32 temp;
2655
2656         usbs_imx_otg_base->usbcmd &= ~BIT0; //detach device from bus temprorarily
2657         usbs_imx_otg_base->usbsts |= BIT6;      //clear reset bit in USBSTS
2658
2659         //temp = usbs_imx_otg_base->usbsts;
2660         //usbs_imx_otg_base->usbsts = temp;
2661
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;
2666
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;
2671
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;
2676
2677
2678         /*4. Initialize EP0 Queue Head again*/
2679         usbs_ep0_init_dqh();
2680
2681         usbs_imx_otg_base->endptlistaddr = g_bulkbuffer_map.ep_dqh_base_addrs;
2682
2683         usbs_imx_otg_base->usbcmd |= BIT0; //re-attach device to the bus
2684
2685         g_usb_dev_state = USB_DEV_DEFAULT_STATE;
2686
2687
2688 }
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 =============================================================================*/
2695 static void
2696 usbs_imx_otg_dev_handle_port_change(void)
2697 {
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
2704
2705 }
2706
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;
2714 RETURN VALUE:           None
2715 IMPORTANT NOTES:        None
2716 =============================================================================*/
2717 static void
2718 usbs_imx_otg_dev_set_configuration(usb_end_pt_info_t* config_data)
2719 {
2720     struct dtd_t td;
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;
2726
2727     struct dqh_t qhead;
2728
2729
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))
2737     {
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);
2741
2742                 if ( direction ==  OUT )
2743                 {
2744                 total_bytes = BULK_BUFFER_SIZE ;
2745
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;
2761
2762                 usbs_setup_queuehead(&qhead);
2763
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;
2768
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;
2775
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);
2781
2782
2783                 USBDBGMSG(DEBUG_BASIC,"+USBDBGMSG: set config - ep1 dtd buffer 0x%08X\n",buffer_addrs_page0);
2784
2785                 /* OUT setup dTD */
2786                 td.dtd_base                     = dtd_address;
2787                 td.next_link_ptr        = dtd_address + 0x20;
2788                 td.terminate            = TERMINATE;
2789                 td.total_bytes          = total_bytes;
2790                 td.ioc                          = IOC_SET;
2791                 td.status                       = ACTIVE;
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;
2798
2799                 /* Set the Transfer Descriptor  */
2800                 usbs_setup_transdesc(&td);
2801
2802                 /* 1. write dQH next ptr and dQH terminate bit to 0 */
2803                 *(volatile cyg_uint32*)(dqh_address+0x8)= dtd_address;
2804
2805                 /* 2. clear active & halt bit in dQH */
2806                 *(volatile cyg_uint32*)(dqh_address+0xC) &= ~0xFF;
2807
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;
2812
2813
2814             }
2815
2816                 else
2817                 {
2818                 total_bytes = 0x4 ;
2819
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;
2835
2836                 usbs_setup_queuehead(&qhead);
2837
2838                 /* Endpoint Configured for Input */
2839                 g_in_endpoint= endpt_num;
2840
2841                 /* Endpoint 2: MPS = 64, IN (Tx endpoint) */
2842                 usbs_imx_otg_base->endptctrl[endpt_num] = 0x00480008;
2843
2844                 /* Enable EP2 IN */
2845                 usbs_imx_otg_base->endptctrl[endpt_num] |= EPIN_ENABLE;
2846
2847                 /* 3. prime endpoint by writing '1' in ENDPTPRIME */
2848                 usbs_imx_otg_base->endptprime |= (EPIN_PRIME << g_in_endpoint);
2849
2850             }
2851     }
2852     else
2853     {
2854         /* TODO: error handling TBD */
2855     }
2856
2857 }
2858
2859 static void usbs_imx_otg_config_utmi_clock(void)
2860 {
2861         #if defined(CYGHWR_USB_DEVS_MX37_OTG)
2862         USB_MX37_SET_PHY_CLK_24MHZ();
2863         #endif
2864
2865         #if defined(CYGHWR_USB_DEVS_MX51_OTG)
2866         cyg_uint32 temp;
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;
2874         #endif
2875 }
2876
2877 /*=============================================================================
2878 // The USB OTG hardware relevant initialization.
2879 =============================================================================*/
2880 static void
2881 usbs_imx_otg_hardware_init(void)
2882 {
2883         cyg_uint32 temp;
2884         cyg_uint32 timeout = 0x1D0000;
2885         usb_plat_config_data_t config_data_ptr;
2886         cyg_uint8 i;
2887
2888         /*Enable USB Internal PHY Clock as 24MHz on-board Ocsillator*/
2889         usbs_imx_otg_config_utmi_clock();
2890
2891         {/*Setup USB Buffer Map*/
2892     config_data_ptr.buffer_address = (cyg_uint32)usb_buffer;
2893     config_data_ptr.buffer_size  = BUFFER_SIZE;
2894
2895     /* Base address of the buffer allocated to IP Layer */
2896     g_bulkbuffer_address_base =  config_data_ptr.buffer_address;
2897
2898     /* length of the buffer */
2899     g_bulkbuffer_length = config_data_ptr.buffer_size;
2900
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
2903
2904     /* Base of queue Head Pointer */
2905     g_bulkbuffer_map.ep_dqh_base_addrs = g_bulkbuffer_address_base;
2906
2907     /* Total size of qhead */
2908     temp = (SIZE_OF_QHD * (g_max_ep_supported * 2));    //total size of QH is 384byte
2909
2910     /* Base Address of dTDs */
2911     g_bulkbuffer_map.ep_dtd_base_addrs = (g_bulkbuffer_map.ep_dqh_base_addrs + temp);
2912
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
2915
2916     /* Base Address of EP0 Buffer */
2917     g_bulkbuffer_map.ep0_buffer_addrs = (g_bulkbuffer_map.ep_dtd_base_addrs + temp  );  //256byte
2918
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;
2924
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;
2928         }
2929
2930         {/*Set USB OTG at device only mode*/
2931                 usbs_imx_otg_base->usbmode = 0x2;                                       //set OTG as a device controller
2932                 temp = 0xA5A55A5A;
2933                 while (!(usbs_imx_otg_base->usbmode == 0x2))
2934                 {
2935                         if(temp != (usbs_imx_otg_base->usbmode))
2936                         {
2937                                 temp = (usbs_imx_otg_base->usbmode);
2938                                 USBDBGMSG(DEBUG_BASIC,"usbmode is 0x%08X\n",temp);
2939                         }
2940                         timeout--;
2941                         if(timeout==0) break;
2942                 }               //check that device controller was configured to device mode only
2943         }
2944
2945         {
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()
2951         }
2952
2953         {
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;
2960
2961                 usbs_imx_otg_base->portsc1 = temp;
2962         }
2963
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
2973
2974                 /* Get Number of Endpoints supported from Configuration Descriptor*/
2975                 g_number_of_endpoints = g_usb_desc.config_desc->usb_interface_desc.number_endpoints;
2976
2977                 /* Store the Endpoint specific information in local variable structure to this Layer */
2978                 for ( i = 0 ; i< g_number_of_endpoints ; i++)
2979                 {
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 ));
2985                 }
2986
2987                 g_usb_dev_state = USB_DEV_DEFAULT_STATE;
2988         }
2989 }
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 =============================================================================*/
2998 void
2999 usbs_imx_otg_device_init(void)  //works like usb port open when
3000 {
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;
3004
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);
3008         #endif
3009
3010         /*ping-pang buffer A*/
3011         g_bulkbuffer_a.buffer = bulk_buffer;
3012         g_bulkbuffer_a.stat   = BUFFER_FREED;
3013
3014         /*ping-pang buffer B*/
3015         g_bulkbuffer_b.buffer = bulk_buffer + BULK_TD_BUFFER_TOTAL_SIZE;
3016         g_bulkbuffer_b.stat   = BUFFER_FREED;
3017
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");
3026
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,
3031                       0,
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
3037         );
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
3041         // while yet.
3042         cyg_interrupt_create(IMX_IRQ_USB_DEV_SERVICE_REQUEST,
3043                              IMX_IRQ_USB_DEV_PRIORITY,        // priority
3044                              0,         // data
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");
3054         #endif
3055         ep0.common.start_fn(&(ep0.common));
3056
3057 }
3058
3059 void
3060 usbs_imx_otg_device_deinit(void) //works like usb port close
3061 {
3062         usbs_imx_otg_base->usbcmd &= (~BIT0);                           // Set Run/Stop bit to Stop Mode
3063         g_usb_dev_state = USB_DEV_DUMMY_STATE;
3064 }
3065
3066 #if defined(CYGHWR_IMX_USB_DOWNLOAD_SUPPORT)
3067
3068 static cyg_uint32 get_free_bulk_buffer(void)
3069 {
3070         cyg_uint32 buff_addr = 0;
3071         int i = 0;
3072         while(buff_addr == 0)
3073         {
3074                 if(g_bulkbuffer_a.stat == BUFFER_FREED)
3075                 {
3076                         buff_addr = (cyg_uint32)(g_bulkbuffer_a.buffer);
3077                         break;
3078                 }
3079                 else if(g_bulkbuffer_b.stat == BUFFER_FREED)
3080                 {
3081                         buff_addr = (cyg_uint32)(g_bulkbuffer_b.buffer);
3082                         break;
3083                 }
3084                 /*
3085                 else
3086                 {
3087                         i++;
3088                         if(i==0xD0000)
3089                         {
3090                                 diag_printf("no bulk buffer free\n");
3091                                 break;
3092                         }
3093
3094                 }
3095                 */
3096         }
3097         return buff_addr;
3098 }
3099
3100 cyg_bool set_status_bulk_buffer(cyg_uint32 buff_addr, int buff_stat)
3101 {
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;
3107         else
3108                 ret = false;
3109
3110         return ret;
3111 }
3112 static usb_status_t usb_bulk_receive_data(usb_buffer_descriptor_t * bd)
3113 {
3114         usb_status_t status;
3115         int res;
3116
3117         /* Check if Bus Reset Received */
3118     if((usbs_imx_otg_base->usbsts) & IMX_USB_STS_RESET)
3119     {
3120         /* Handle Bus Reset */
3121         usbs_imx_otg_dev_handle_bus_reset();
3122     }
3123     /* Check if Reset is already received and Setup Token Received */
3124     if((usbs_imx_otg_base->endptsetupstat) & BIT0)
3125     {
3126                 /* Handle Setup Token */
3127         usbs_imx_otg_dev_ep0_dsr();
3128     }
3129
3130         if((usbs_imx_otg_base->endptcomplete) & ( EPOUT_COMPLETE << EP1))
3131         {
3132                 ep1_rx_complete(res);
3133                 if(ep1.common.complete_data)
3134                 {
3135                         bd->bytes_transfered = ep1.fetched;
3136                         memcpy(bd->buffer,ep1.common.complete_data,ep1.fetched);
3137                         ep1.fetched = 0;
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;
3145                 }
3146
3147                 else
3148                         status = USB_FAILURE;
3149         }
3150         return status;
3151 }
3152
3153 static usb_status_t usb_bulk_transmit_data(usb_buffer_descriptor_t * bd)
3154 {
3155         //usb_state_t status;
3156
3157         while(bd->size)
3158         {
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));
3164
3165                 bd->size -= (ep2.common.buffer_size);
3166         }
3167
3168         return USB_SUCCESS;
3169 }
3170 static cyg_uint32 usb_rx_processing(cyg_uint8* read_ptr, usb_status_t* status, cyg_uint32 data_length)
3171 {
3172         cyg_uint32 bytes_received = 0;
3173     if ( (status != NULL) && (read_ptr != NULL) )
3174     {
3175         usb_status_t trans_status = USB_FAILURE;
3176
3177         usb_buffer_descriptor_t  buf_desc;
3178
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)
3183         {
3184             buf_desc.size = data_length;
3185             buf_desc.bytes_transfered = 0;
3186
3187             /* Receive data from USB */
3188             trans_status = (usb_status_t )usb_bulk_receive_data(&buf_desc);
3189             if(trans_status == USB_SUCCESS)
3190             {
3191                 data_length -= buf_desc.bytes_transfered;
3192                 bytes_received += buf_desc.bytes_transfered;
3193                 //(cyg_uint8*)
3194                                 (buf_desc.buffer) += buf_desc.bytes_transfered;
3195             }
3196             else
3197             {
3198                 *status = USB_FAILURE;
3199             }
3200
3201                         g_timeout_value++;
3202                         if(g_timeout_value%0x1000000==0) D("C");
3203                         if(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT) return 0;
3204         }
3205     }
3206
3207     return ( bytes_received );
3208 }
3209 static usb_status_t usb_tx_processing(cyg_uint8* write_ptr, cyg_uint32 data_len)
3210 {
3211     usb_status_t trans_status = USB_FAILURE;
3212
3213     /* Prepare the buffer descriptor for USB transfer */
3214     usb_buffer_descriptor_t  buf_desc;
3215
3216     /* Prepare transfer buffer descriptor*/
3217     buf_desc.buffer = (void *)write_ptr;
3218     buf_desc.size = data_len;
3219     buf_desc.bytes_transfered = 0;
3220
3221     /* Send data over USB */
3222     trans_status = usb_bulk_transmit_data(&buf_desc);
3223
3224         return trans_status;
3225 }
3226 static cyg_bool pl_get_command(void)
3227 {
3228         cyg_uint8 i = 0;
3229         usb_status_t status;
3230     cyg_uint32 bytes_recvd = 0;
3231     cyg_uint8 start_command = 0xFF;
3232
3233     while(start_command == 0xFF)
3234     {
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;
3241     }
3242         //D("+USBDBGMSG: start_command = 0x%02X\n",start_command);
3243     if(start_command == 0xF0)
3244     {
3245         //copy rest of the bytes
3246         for(i=1; i < SDP_CMD_MAX_LEN; i++)
3247         {
3248             sdp_command[i] = sdp_payload_data[i-1];
3249         }
3250     }
3251     else
3252     {
3253         //copy starting bytes
3254         for(i=0; i < (SDP_CMD_MAX_LEN - start_command) ; i++)
3255         {
3256             sdp_command[i] = sdp_payload_data[i + start_command];
3257         }
3258
3259         if(start_command != 0)
3260         {
3261             //receive rest of the bytes
3262             bytes_recvd = usb_rx_processing(sdp_payload_data, &status, start_command);
3263
3264             if(bytes_recvd == start_command)
3265             {
3266                 for(i=0; i <start_command; i++)
3267                 {
3268                     sdp_command[SDP_CMD_MAX_LEN - start_command + i] = sdp_payload_data[i];
3269                 }
3270             }
3271         }
3272     }
3273
3274     return true;
3275 }
3276 static cyg_uint8 pl_command_start(void)
3277 {
3278         cyg_uint8 i=0;
3279     static cyg_uint8 last_byte = 0;
3280
3281     if(last_byte != 0x0)
3282     {
3283         if(last_byte == sdp_payload_data[0])
3284         {
3285             sdp_command[0] = last_byte;
3286             last_byte = sdp_payload_data[SDP_CMD_MAX_LEN -1];
3287             return 0xF0;
3288         }
3289     }
3290
3291     for(i=0; i < SDP_CMD_MAX_LEN -1; i++)
3292     {
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))
3303          {
3304              return i;
3305          }
3306     }
3307
3308     //handle last byte
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 ||
3312        last_byte == 0x9))
3313     {
3314         last_byte = 0;
3315     }
3316
3317     return 0xFF;
3318 }
3319 static cyg_uint8 pl_handle_command(cyg_uint8 g_error_status)
3320 {
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;
3326         //int i;
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]));
3331
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);
3335     switch (Header)
3336     {
3337         case WRITE_FILE:
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;
3342                         //g_load_cycle ++;
3343                         usb_download_address += ByteCount;
3344                         usb_download_length +=ByteCount;
3345                         D(".");
3346                         if(ByteCount<BULK_TD_BUFFER_TOTAL_SIZE)
3347                         {
3348                                 status = COMPLETE;
3349                         }
3350             break;
3351         case ERROR_STATUS_HEADER:
3352             pl_command_ack(g_error_statusAck);
3353                         status = COMPLETE;
3354             break;
3355                 case READ_FILE:
3356         case WRITE_HEADER:
3357         case READ_HEADER:
3358         default:
3359             break;
3360     }
3361
3362     return status;
3363
3364 }
3365 static void pl_handle_write_file(cyg_uint32 address, cyg_uint32 total_bytes)
3366 {
3367         usb_status_t status;
3368     usb_rx_processing((cyg_uint8*)address, &status, total_bytes);
3369 }
3370
3371 static void pl_command_ack(cyg_uint32 ack)
3372 {
3373     usb_tx_processing((cyg_uint8*)&ack, SDP_CMD_ACK_LEN);
3374 }
3375
3376 void
3377 usbs_imx_otg_download(unsigned char * buffer, unsigned int length)
3378 {
3379         cyg_bool bytes_recvd = false;
3380         //D("+usbdownload: enter usbs_imx_otg_download\n");
3381         //D("+USBDBGMSG: re-enumerate USB device\n");
3382         /*enumeration*/
3383         /*TODO*/
3384         while(g_usb_dev_state!=USB_DEV_CONFIGURED_STATE)
3385         {
3386
3387                 /* Check if Bus Reset Received */
3388         if((usbs_imx_otg_base->usbsts) & IMX_USB_STS_RESET)
3389         {
3390             /* Handle Bus Reset */
3391                 usbs_imx_otg_dev_handle_bus_reset();
3392         }
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))
3395         {
3396                 /* Handle Setup Token */
3397                 usbs_imx_otg_dev_ep0_dsr();
3398         }
3399         }
3400
3401         if(g_usb_dev_state==USB_DEV_CONFIGURED_STATE)
3402         {
3403                 //D("+USBDBGMSG: enumeration done\n");
3404                 /*file download*/
3405                 D("USB file download start\n");
3406                 g_timeout_value = 0;
3407                 usb_download_length = 0;
3408                 //usb_download_address = 0;
3409                 //g_load_cycle = 0;
3410                 while(1)
3411                 {
3412
3413                         bytes_recvd = pl_get_command();
3414                 if(bytes_recvd == true)
3415                 {
3416                 g_usb_download_state = pl_handle_command(g_error_status);
3417                 }
3418
3419                         if((g_usb_download_state==COMPLETE)||(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT))
3420                                 break;
3421
3422                 }
3423                 diag_printf("\n");
3424                 if(g_timeout_value == USB_DOWNLOAD_TIMEOUT_LIMIT) //timeout value
3425                         D("USB download timeout to wait none file to download\n");
3426                 else
3427                 {
3428                         D("USB file download complete\n");
3429                         //D("+usbdownload: image base 0x%08X, length %d\n",usb_download_address,usb_download_length);
3430                 }
3431         }
3432 }
3433 #endif
3434
3435 //EOF