sc2440_usb_hw.c
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:46k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. /**
  2. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. PARTICULAR PURPOSE.
  6. Copyright (c) 2001. Samsung Electronics, co. ltd  All rights reserved.
  7. Module Name:  
  8. Abstract:
  9.     S3C2440 USB function(ACTIVE SYNC) device driver (Chip Layer)
  10. rev:
  11. 2003.3.18 : EP3 is replaced by EP4 for DMA operation because DMA2(EP3) is used by audio. (purnnamu)
  12. 2003.3.17 : Every USBD interrupt is followed by the dummy interrupt 
  13.   because USBD sub-pending interrupt is cleared after clearing INTPND register.
  14.   So,USBD sub-pending bit is cleared before clearing INTPND register. (purnnamu)
  15.     2002.5.7 : Add to s3c2410_code (Seung-han, Lim)
  16.     2002.1.22 : First release/no error recovery (kwangyoon LEE, kwangyoon@samsung.com)
  17. Notes: 
  18. */
  19. #include <windows.h>
  20. #include <types.h>
  21. #include <ceddk.h>
  22. #include <memory.h>
  23. #include <serhw.h>
  24. #include <nkintr.h>
  25. #include "S2440.h"
  26. #include <SC2440_usb_hw.h>
  27. #include <SC2440_usb_ser.h>
  28. #undef ZONE_INIT
  29. #include <serdbg.h>
  30. #include <drv_glob.h> //:-)
  31. #include <2440usb.h>  //:-)
  32. #define USBDMSG  DEBUGMSG  //RETAILMSG
  33. PDRIVER_GLOBALS v_pDriverGlobals=NULL; //:-)
  34. volatile USBD_GLOBALS *usbdShMem=NULL;  //:-)
  35. volatile DMAreg *v_pDMAregs=NULL;  //:-)
  36. volatile INTreg *v_pINTregs=NULL;  //:-)
  37. ULONG realPhysicalAddr_UsbdRxBuf=0;
  38. ULONG totalRxCnt=0; //debug
  39. /*
  40. #if (USBD_GLOBALS_BUF_SIZE!=0x4000)
  41. STOP_COMPILE GEN_ERROR
  42. //drv_glob.h should be changed correctly
  43. #endif
  44. */
  45. // This driver defines a simple BULK FIFO device. It supports only one
  46. // interface with one alternate setting, as shown below.  
  47. //
  48. //  Endpoint    Setting 0
  49. //------------------------
  50. //  EP0         Control
  51. //  EP1 In      Bulk  
  52. //  EP3 Out     Bulk   
  53. // Steal the useless IR zone from MDD and use it as EP0 & USB specific stuff
  54.  
  55. #define ZONE_USB ZONE_IR
  56. // Define the configuration descriptor length
  57.  
  58. #define CFGLEN  32   
  59. #define iCONF   18
  60. #define TLEN    (CFGLEN + 18)
  61. // Define the configuration descriptor itself
  62. const BYTE uStd[TLEN]=  {
  63. 0x12, //  0 desc size                      
  64. DEVICE, //  1 desc type (DEVICE)             
  65. 0x00, //  2 USB release                    
  66. 0x01, //  3 => 1.00                        
  67. 0xff, //  4 class                          
  68. 0xff, //  5 subclass                       
  69. 0xff, //  6 protocol                       
  70. EP0_MAXP_SIZE, //  7 max pack size                  
  71. 0x47, //  8 vendor ID LSB (Samsung Semi)   
  72. 0x05, //  9 vendor ID MSB ( 0x1419 )       
  73. 0x20, // 10 product ID LSB                 
  74. 0x27, // 11 product ID MSB                 
  75. 0x00, // 12 device release LSB             
  76. 0x00, // 13 device release MSB             
  77. 0x00, // 14 manufacturer string desc index 
  78. 0x00, // 15 product string desc index      
  79. 0x00, // 16 serial num string desc index   
  80. 0x01, // 17 num of possible configurations 
  81. // Configuration Descriptor 
  82. 0x09, //  desc size                            
  83. CONFIGURATION, //  desc type (CONFIGURATION)            
  84. CFGLEN%256, //  total length of data returned LSB    
  85. CFGLEN/256, //  total length of data returned MSB    
  86. 0x01, //  num of interfaces                    
  87. 0x01, //  value to select config (1 for now)   
  88. 0x00, //  index of string desc ( 0 for now)    
  89. 0x80, //  bus powered                          
  90. 25, //  max power, 50mA for now    
  91. // Interface Decriptor 
  92. 0x09, //  desc size                            
  93. INTERFACE, //  desc type (INTERFACE)                
  94. 0x00, //  interface index.                     
  95. 0x00, //  value for alternate setting          
  96. 0x02, //  bNumEndpoints (number endpoints used, excluding EP0)
  97. 0xff,
  98. 0xff,
  99. 0xff,
  100. 0x00, //  string index,      
  101. // Endpoint descriptor (EP 1 Bulk IN) 
  102. 0x07, //  desc size                            
  103. ENDPOINT, //  desc type (ENDPOINT)                 
  104. 0x81, //  endpoint address: endpoint 1, IN    
  105. 0x02, //  endpoint attributes: Bulk       
  106. EP1_IN_MAXP_SIZE, //  max packet size LSB                  
  107. 0x00, //  max packet size MSB                  
  108. 0x00, //  polling interval (4ms/bit=time,500ms)  
  109. #if 0
  110. // Endpoint descriptor (EP 2 Interrupt IN) 
  111. 0x07, //  desc size                            
  112. ENDPOINT, //  desc type (ENDPOINT)                 
  113. 0x82, //  endpoint address: endpoint 2, IN     
  114. 0x03, //  endpoint attributes: Interrupt       
  115. EP2_IN_MAXP_SIZE, //  max packet size LSB                  
  116. 0x00, //  max packet size MSB                  
  117. 0xFA, //  polling interval (4ms/bit=time,100ms)  
  118. #endif
  119. // Endpoint descriptor (EP 4 Bulk OUT) 
  120. 0x07, //  desc size                            
  121. ENDPOINT, //  desc type (ENDPOINT)                 
  122. 0x04, //  endpoint address: endpoint 4, OUT    
  123. 0x02, //  endpoint attributes: Bulk            
  124. EP4_OUT_MAXP_SIZE, //  max packet size LSB                  
  125. 0x00, //  max packet size MSB                  
  126. 0x00 //  polling interval (4ms/bit=time,500ms)  
  127. #if 0
  128. // Endpoint descriptor (EP 4 Interrupt OUT) 
  129. 0x07, //  desc size                            
  130. ENDPOINT, //  desc type (ENDPOINT)                 
  131. 0x04, //  endpoint address: endpoint 4, OUT    
  132. 0x03, //  endpoint attributes: Interrupt            
  133. EP4_OUT_MAXP_SIZE, //  max packet size LSB                  
  134. 0x00, //  max packet size MSB                  
  135. 0x00 //  polling interval (4ms/bit=time,500ms)   // $$$$
  136. #endif
  137. };
  138. // Register writes need to be verified. This macro loops the write until
  139. // the effects are visible and records the number of retries.
  140. #define UDC_REG_WRITE(_struct,_ptr,_field,_val) IOW_REG_FIELD(_struct,_ptr,_field,_val)
  141. #define UDC_REG_BITSET(_struct,_ptr,_field,_val) { _struct xx;
  142.         *(unsigned int *)&xx = 0;
  143.       xx._field = _val;
  144.       IOW_REG_SET(_struct,_ptr,*(unsigned int*)&xx); }
  145. #define UDC_REG_WRITEX(_setptr,_setval) (_setptr) = _setval;
  146. // Variables for EP0 resend control. Keep track of last packet sent.
  147. static char *sendPacket;
  148. static int  sendPacketLength;
  149. static int  sendTotalLength;
  150. static char *savSendPacket;
  151. static int  savSendPacketLength;
  152. // EP1/EP3 packet size. For polling this can not be greater than 16
  153. static unsigned int maxPacketSize = EP1Len;  
  154. // Read the command from the endpoint 0 FIFO 
  155. void HW_USBClocks(PSER_INFO pHWHead);
  156. static
  157. int getCommand(PSER_INFO pHWHead, void *argP)
  158. {
  159. unsigned char *bufP = (unsigned char*)argP;
  160. int length     = pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low | pHWHead->pUSBCtrlAddr->OFCR2.out_cnt_high<<8;
  161. int i;
  162. memset(bufP, 0x55, 8);
  163. // All setup commands are 8 bytes in length
  164. if (length != 8) 
  165. {
  166. DEBUGMSG(1, (TEXT("UDC bad command length %dn"), length));
  167. return 1;
  168. }
  169. DEBUGMSG(1, (TEXT("[GETCOMMAND : ")));
  170. for (i=0; i < length; i++) 
  171. {
  172. bufP[i] = (BYTE)pHWHead->pUSBCtrlAddr->EP0F.fifo_data;
  173. DEBUGMSG(1, (TEXT("%2x "), bufP[i]));
  174. }
  175. DEBUGMSG(1, (TEXT("]rn")));
  176. return 0;
  177. }
  178. /*************************************************************************
  179. Command response with data packets
  180. *************************************************************************/
  181. static
  182. void sendData(PSER_INFO pHWHead, void *argP, int length, int totalLen)
  183. {
  184. unsigned char *bufP = (unsigned char*)argP;
  185. struct EP0ICSR1Bits EP0ICSR1;
  186. int i;
  187. // Endpoint0 mode
  188. pHWHead->pUSBCtrlAddr->INDEX.index = 0x0;
  189. DEBUGMSG(1, (TEXT("[UDC WILL SEND] %d bytesrn"), length));
  190. // Send the data back. The FIFO should be turned around for
  191. // us already. Just blast away ...
  192.   for (i=0; (i < length) && (i < EP0Len); i++) 
  193. {
  194. IOW_REG_FIELD(struct EP0FBits, 
  195. &pHWHead->pUSBCtrlAddr->EP0F, fifo_data, bufP[i]);
  196. }
  197. // Form the register update. Always set IN_PKT_RDY.
  198. EP0ICSR1 = pHWHead->pUSBCtrlAddr->EP0ICSR1;
  199. EP0ICSR1.ipr_ = 1;
  200. // We can complete on a packet which is full. We need to wait till
  201. // next time and generate a zero length packet, so only complete
  202. // if we're at the end and it is not the max packet size.
  203. if ((i == length) && (i != EP0Len)) 
  204. {
  205. savSendPacket       = sendPacket;
  206. savSendPacketLength = sendPacketLength;
  207. sendPacket          = NULL;
  208. sendPacketLength    = length - i;
  209. sendTotalLength     = totalLen - i;
  210. EP0ICSR1.de_ff = 1;
  211. }
  212. // Need to send another packet.
  213. else {
  214. sendPacket          = (char*)&bufP[i];
  215. sendPacketLength    = length - i;
  216. sendTotalLength     = totalLen - i;
  217. savSendPacket       = sendPacket;
  218. savSendPacketLength = sendPacketLength;
  219. DEBUGMSG(1, (TEXT("UDC WILL SEND %d more bytes laterrn"), 
  220. sendPacketLength));
  221. }
  222. /* Update the register
  223. */
  224. UDC_REG_WRITEX(*(volatile unsigned *)&pHWHead->pUSBCtrlAddr->EP0ICSR1, 
  225.   *(unsigned *)&EP0ICSR1);
  226. }
  227. /*************************************************************************
  228. Send command done
  229. *************************************************************************/
  230. static
  231. void sendCommandDone(PSER_INFO pHWHead)
  232. {
  233. BYTE index;
  234. // Endpoint0 mode
  235.     index = pHWHead->pUSBCtrlAddr->INDEX.index;
  236.     pHWHead->pUSBCtrlAddr->INDEX.index = 0x0;
  237.     // Set SERVICE_OUT_PKY_RDY bit
  238.     pHWHead->pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 0x1;
  239.     
  240.     pHWHead->pUSBCtrlAddr->INDEX.index = index;
  241. }
  242. /*************************************************************************
  243. Command response with no data packets
  244. *************************************************************************/
  245. static
  246. void sendDone(PSER_INFO pHWHead, int err)
  247. {
  248.     struct EP0ICSR1Bits EP0ICSR1;
  249.     BYTE index;
  250.     
  251.     EP0ICSR1 = pHWHead->pUSBCtrlAddr->EP0ICSR1;
  252.     EP0ICSR1.sopr_cdt   = 1;
  253.     EP0ICSR1.de_ff      = 1;
  254.     EP0ICSR1.sts_ur     = (BYTE)err;
  255.     // Endpoint 0 mode
  256.     index = pHWHead->pUSBCtrlAddr->INDEX.index;
  257.     pHWHead->pUSBCtrlAddr->INDEX.index = 0x0;
  258.     if (err) {
  259.         DEBUGMSG(ZONE_ERROR, (TEXT("SENT_STALL CLEARrn")));
  260.     }
  261.     UDC_REG_WRITEX( *(volatile DWORD *)&pHWHead->pUSBCtrlAddr->EP0ICSR1,
  262.                     *(DWORD *)&EP0ICSR1 );
  263.     pHWHead->pUSBCtrlAddr->INDEX.index = index;
  264. }
  265. /*************************************************************************
  266. Set the device address
  267. *************************************************************************/
  268. static
  269. void setAddress(PSER_INFO pHWHead, int addr)
  270. {
  271.     DEBUGMSG(ZONE_USB, (TEXT("[SET ADDRESS to %x]rn"), addr));
  272.     pHWHead->pUSBCtrlAddr->udcFAR.func_addr = (BYTE)addr;
  273.     pHWHead->pUSBCtrlAddr->udcFAR.addr_up = 1;
  274. }
  275. /*************************************************************************
  276. SC2440_USB_Init
  277. Initialize the UDC.
  278. *************************************************************************/
  279. extern
  280. void SC2440_USB_Init(PSER_INFO pHWHead)
  281. {
  282. BYTE index;
  283. int i;
  284.     EnterCriticalSection(&pHWHead->HwRegCritSec);
  285. USBDMSG(1, (TEXT("++SC2440_USB_Initrn")));
  286. //RETAILMSG(1, (TEXT("++SC2440_USB_Initrn")));
  287. //DebugBreak();;;
  288. pHWHead->dConfIdx    = 0;
  289. pHWHead->dSetting    = 0;
  290. pHWHead->dInterface  = 0;
  291. pHWHead->dAddress    = 0;
  292. pHWHead->ModemStatus = 0; // All lines low till we get connected.
  293. pHWHead->wSOFStableCnt = 0;
  294. _re_enable:
  295.     switch (pHWHead->State) {
  296.         case IDLE:
  297.             //RETAILMSG(1, (TEXT("IDLErn")));
  298.             //
  299.             // Enable the USB Clocks
  300.             //
  301. HW_USBClocks(pHWHead);
  302. break;
  303.         case OFF:
  304.             //RETAILMSG(1, (TEXT("OFFrn")));
  305.             //
  306.             // Disable the USB Clocks
  307.             //
  308. HW_USBClocks(pHWHead);
  309.             DEBUGMSG(ZONE_INIT, (TEXT("rUPLLCON: 0x%Xrn"), pHWHead->pCLKPWR->rUPLLCON));
  310.             goto _done;
  311.             break;
  312.         case SUSPEND:
  313.             // should never get here
  314.             //RETAILMSG(1, (TEXT("SUSPENDrn")));
  315. ASSERT(0);
  316.             goto _done;
  317.             break;
  318.         case RESUME:
  319.             // Suspend disconnects us from the USB.
  320.             // When we Resume we re-enumerate on the USB.
  321.             //RETAILMSG(1, (TEXT("RESUME => ")));
  322.         default:            
  323.             pHWHead->State = IDLE;
  324.             goto _re_enable;
  325.             break;
  326.     }
  327.     
  328.     //
  329.     // Initialize the USBD Controller
  330.     //
  331.     index = pHWHead->pUSBCtrlAddr->INDEX.index;
  332.     
  333.     // suspend mode disable
  334.     pHWHead->pUSBCtrlAddr->PMR.sus_en = 0x0;
  335.     ASSERT(pHWHead->pUSBCtrlAddr->PMR.sus_en == 0x0);
  336.     // setup endpoint 0
  337.     pHWHead->pUSBCtrlAddr->INDEX.index = 0;
  338.     ASSERT(pHWHead->pUSBCtrlAddr->INDEX.index == 0);
  339.     pHWHead->pUSBCtrlAddr->MAXP.maxp = 0x1;         // 8 BYTE
  340.     ASSERT(pHWHead->pUSBCtrlAddr->MAXP.maxp == 0x1);
  341.     pHWHead->pUSBCtrlAddr->EP0ICSR1.sopr_cdt = 1;   // OUT_PKT_RDY
  342.     //ASSERT(pHWHead->pUSBCtrlAddr->EP0ICSR1.sopr_cdt == 1); // W only
  343.     pHWHead->pUSBCtrlAddr->EP0ICSR1.sse_ = 1;       // SETUP_END
  344.     //ASSERT(pHWHead->pUSBCtrlAddr->EP0ICSR1.sse_ == 1); // W only
  345.     // setup endpoint 1
  346.     pHWHead->pUSBCtrlAddr->INDEX.index = 1;
  347.     ASSERT(pHWHead->pUSBCtrlAddr->INDEX.index == 1);
  348.         
  349.     pHWHead->pUSBCtrlAddr->MAXP.maxp = 0x8;     // 64 BYTE
  350.     ASSERT(pHWHead->pUSBCtrlAddr->MAXP.maxp == 0x8);
  351.     
  352.     pHWHead->pUSBCtrlAddr->ICSR2.mode_in = 1;   // IN
  353.     ASSERT(pHWHead->pUSBCtrlAddr->ICSR2.mode_in == 1);
  354.     
  355.     pHWHead->pUSBCtrlAddr->ICSR2.iso = 0;       // BULK
  356.     ASSERT(pHWHead->pUSBCtrlAddr->ICSR2.iso == 0);
  357.     // setup endpoint 4
  358.     pHWHead->pUSBCtrlAddr->INDEX.index = 4;
  359.     ASSERT(pHWHead->pUSBCtrlAddr->INDEX.index == 4);
  360.     
  361.     pHWHead->pUSBCtrlAddr->MAXP.maxp = 0x8;     // 64 BYTE
  362.     ASSERT(pHWHead->pUSBCtrlAddr->MAXP.maxp == 0x8);
  363.     
  364.     pHWHead->pUSBCtrlAddr->ICSR2.mode_in = 0;   // OUT
  365.     ASSERT(pHWHead->pUSBCtrlAddr->ICSR2.mode_in == 0);
  366.     
  367.     pHWHead->pUSBCtrlAddr->OCSR2.iso = 0;       // BULK
  368.     ASSERT(pHWHead->pUSBCtrlAddr->OCSR2.iso == 0);
  369.     // clear all EP interrupts
  370.     pHWHead->pUSBCtrlAddr->EIR.ep0_int = 0x1;
  371.     ASSERT(pHWHead->pUSBCtrlAddr->EIR.ep0_int == 0);
  372.     
  373.     pHWHead->pUSBCtrlAddr->EIR.ep1_int = 0x1;
  374.     ASSERT(pHWHead->pUSBCtrlAddr->EIR.ep1_int == 0);
  375.     
  376.     pHWHead->pUSBCtrlAddr->EIR.ep2_int = 0x1;
  377.     ASSERT(pHWHead->pUSBCtrlAddr->EIR.ep2_int == 0);
  378.     
  379.     pHWHead->pUSBCtrlAddr->EIR.ep3_int = 0x1;
  380.     ASSERT(pHWHead->pUSBCtrlAddr->EIR.ep3_int == 0);
  381.         
  382.     pHWHead->pUSBCtrlAddr->EIR.ep4_int = 0x1;
  383.     ASSERT(pHWHead->pUSBCtrlAddr->EIR.ep4_int == 0);
  384.     // clear reset int
  385.     pHWHead->pUSBCtrlAddr->UIR.reset_int = 0x1;
  386.     ASSERT(pHWHead->pUSBCtrlAddr->UIR.reset_int == 0x0);
  387.     // EP0, 1, & 4 Enabled, EP2, 3 Disabled
  388.     pHWHead->pUSBCtrlAddr->EIER.ep2_int_en = 0x0;
  389.     ASSERT(pHWHead->pUSBCtrlAddr->EIER.ep2_int_en == 0x0);
  390.     
  391.     pHWHead->pUSBCtrlAddr->EIER.ep3_int_en = 0x0;
  392.     ASSERT(pHWHead->pUSBCtrlAddr->EIER.ep3_int_en == 0x0);
  393.     pHWHead->pUSBCtrlAddr->EIER.ep0_int_en = 0x1;
  394.     ASSERT(pHWHead->pUSBCtrlAddr->EIER.ep0_int_en == 0x1);
  395.     
  396.     pHWHead->pUSBCtrlAddr->EIER.ep1_int_en = 0x1;
  397.     ASSERT(pHWHead->pUSBCtrlAddr->EIER.ep1_int_en == 0x1);
  398.     
  399.     pHWHead->pUSBCtrlAddr->EIER.ep4_int_en = 0x1;
  400.     ASSERT(pHWHead->pUSBCtrlAddr->EIER.ep4_int_en == 0x1);
  401.     // enable reset int 
  402.     pHWHead->pUSBCtrlAddr->UIER.reset_int_en = 0x1;
  403.     ASSERT(pHWHead->pUSBCtrlAddr->UIER.reset_int_en == 0x1);
  404. if(v_pDMAregs==NULL)
  405. {
  406. //RETAILMSG(1, (TEXT("ERROR: SC2440_usb_hw: v_pDMAregs=NULLrn")));
  407. while(1);
  408. }
  409. pHWHead->pUSBCtrlAddr->INDEX.index = 0x4;
  410. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DC=0x0; 
  411.     //may not be needed, not to operate DMA during initialization.
  412. UsbdInitDma3(0,0);
  413. usbdShMem->usbdRxRdPt=0;
  414. usbdShMem->usbdRxWrPt=0;
  415. usbdShMem->usbdRxCnt=0;
  416. usbdShMem->usbdEir=0;
  417.   usbdShMem->usbdUir=0;
  418. usbdShMem->usbdDma3Int=0; 
  419.     //rEP4_DMA_FIFO=0x40; //not needed for OUT operation.
  420. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DTL=USBD_GLOBALS_BUF_SIZE&0xff;
  421. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DTM=(USBD_GLOBALS_BUF_SIZE>>8)&0xff;
  422. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DTH=(USBD_GLOBALS_BUF_SIZE>>16)&0x0f;
  423. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->OCSR2=
  424. *(BYTE *)&pHWHead->pUSBCtrlAddr->OCSR2 | (BYTE)EPO_AUTO_CLR /*| EPO_OUT_DMA_INT_MASK*/;  
  425. //AUTO_CLR(OUT_PKT_READY is cleared automatically), interrupt_masking.
  426. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DU=0x01; //DMA transfer unit=1byte
  427. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DC=UDMA_OUT_DMA_RUN|UDMA_DMA_MODE_EN;
  428. //deamnd disable,out_dma_run=run,in_dma_run=stop,DMA mode enable
  429. //wait until DMA_CON is effective.
  430. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DC;
  431. for(i=0;i<10;i++);   
  432. v_pINTregs->rINTMSK&=~(BIT_DMA3);  //enable DMA3 interrupt
  433. pHWHead->pUSBCtrlAddr->INDEX.index = 0x0; //del me
  434. _done:
  435. LeaveCriticalSection(&pHWHead->HwRegCritSec);
  436.     
  437. USBDMSG(1, (TEXT("--SC2440_USB_Initrn")));
  438. //RETAILMSG(1, (TEXT("--SC2440_USB_Initrn")));
  439. }
  440. /*************************************************************************
  441. Process Endpoint 0 interrupt. We are called here on every EIR interrupt.
  442. We need to check the EP0 status and send the next packet, if any. We need
  443. to handle errors as follows:
  444. SE - This is set if we received a new command before we finished the last
  445. one. This happens when the host does not wish to read all reply data
  446. (it may only be interested in the first 8 bytes of a device descriptor
  447. to get the max packet size, for example). We will simply discard the
  448. next data to send and continue with the normal command handling. We
  449.   need to clear SE by asserting SSE before we continue.
  450.  
  451. SST - This is set when the UDC actually issues a stall. We just clear it
  452. and continue.
  453.  Normal setup is as follows:
  454.  OPR - This indicates a receive command packet is ready to be read. Commands
  455. are always 8 bytes in length and follow the form defined in chapter 9.
  456.  If OPR is not set and IPR is not set and SE is not set we must be here
  457.  because IPR transitioned from 1 -> 0. This means the last packet has been
  458.  sent (ACK'd). Send the next packet, if any.
  459.  We are emulating a serial line here. The state of the modem control lines
  460.  are sent in a command packet. Extract these and set the modem status bits
  461.  as for a normal serial line. This allows the upper levels to treat this
  462.  link just like a serial line with modem control (no flow control is
  463.  explicitly required and hence is not supported.
  464. **************************************************************************/
  465. void SC2440_USB_DoEndpoint0(PSER_INFO pHWHead, PDWORD pModemStatus)
  466. {
  467. BYTE dbuf[8];
  468. WORD len, totLen;
  469. PUCHAR p;
  470. unsigned int cnt=0;
  471. struct EP0ICSR1Bits EP0ICSR1=pHWHead->pUSBCtrlAddr->EP0ICSR1;
  472. // Endpoint 0 mode
  473. UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0x0); 
  474. DEBUGMSG(1, (TEXT("++SC2440_USB_DoEndpoint0rn")));
  475. //RETAILMSG(1, (TEXT("++SC2440_USB_DoEndpoint0rn")));
  476. /* If there is data to send and the transmitter is open go send
  477. * the next packet. But, do not continue to send if the host has
  478. * aborted the transfer or sent a new one. We'll clean up below.
  479. */
  480. if ((EP0ICSR1.se_sds == 0) && (EP0ICSR1.ipr_ == 0) && 
  481. (EP0ICSR1.opr_ipr == 0) && (sendPacket))
  482. {
  483. DEBUGMSG( 1, (TEXT("Send remaining data !!!rn")));
  484. sendData(pHWHead, sendPacket, sendPacketLength, sendTotalLength);
  485. }
  486. // If setup end, the host has aborted the last transfer. Kill any
  487. //remaining packets and continue;
  488. if (EP0ICSR1.se_sds) {
  489. sendPacketLength = 0;
  490. sendPacket = NULL;
  491. UDC_REG_BITSET(struct EP0ICSR1Bits, &pHWHead->pUSBCtrlAddr->EP0ICSR1, sse_, 1); 
  492. }
  493. // If stall ack, not sure what needs to be done here.
  494. if (EP0ICSR1.sts_ur) 
  495. {
  496. DEBUGMSG( 1, (TEXT("Stall ACK setrn")));
  497. UDC_REG_BITSET(struct EP0ICSR1Bits, &pHWHead->pUSBCtrlAddr->EP0ICSR1, sts_ur, 0);  // 0 -> clear
  498. }
  499. // If new command received ...
  500. DEBUGMSG(1, (TEXT("OUT_PKT_RDY = 0x%xrn"), EP0ICSR1.opr_ipr));
  501. // if (EP0ICSR1.opr_ipr) 
  502. if (EP0ICSR1.opr_ipr)
  503. {
  504. // New command with existing data. Not sure how this can happen but if
  505. // it does just clear the old data and continue.
  506. if (sendPacket)
  507.   sendPacket = NULL;
  508. cnt = pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low | pHWHead->pUSBCtrlAddr->OFCR2.out_cnt_high << 8; 
  509. DEBUGMSG(1,(TEXT("UDC received setup, EP0ICSR1 %x, len %dn"), 
  510. EP0ICSR1, cnt));
  511. // Read the command from the input FIFO
  512. if (getCommand(pHWHead, (void*)&pHWHead->dReq) != 0) 
  513. {
  514. sendDone(pHWHead,1);
  515. }
  516. DEBUGMSG(1, 
  517. (TEXT("bmRequest: %02x bRequest: %02x wValue: %04x wIndex: %04x wLength: %04xn"), 
  518. pHWHead->dReq.bmRequest,
  519. pHWHead->dReq.bRequest,
  520. pHWHead->dReq.wValue,
  521. pHWHead->dReq.wIndex,
  522. pHWHead->dReq.wLength));
  523. // Decode and execute the command. We support two sets of commands, vendor
  524. // specific (modem control) and chapter 9 standard commands.
  525. if (pHWHead->dReq.bmRequest & 0x60) // vendor or class command
  526. DEBUGMSG(1, (TEXT("Vendor/Class Command !!n")));
  527. if (SET_CONTROL_LINE_STATE == pHWHead->dReq.bRequest) 
  528. {
  529. // Host is notifying us of control line state.
  530. // wValue contains bitmask
  531. // 0 - DTR
  532. // 1 - RTS
  533. DEBUGMSG(1, (TEXT("SET_CONTROL_LINE_STATE %4.4Xrn"),
  534. pHWHead->dReq.wValue));
  535. if (pHWHead->dReq.wValue & 0x01)
  536. *pModemStatus |= (MS_DSR_ON|MS_RLSD_ON);  // DTR active, set DSR/RLSD
  537. else
  538. *pModemStatus &= ~(MS_DSR_ON|MS_RLSD_ON); // DTR clear, clr DSR/RLSD
  539.         
  540. if (pHWHead->dReq.wValue & 0x02) 
  541. *pModemStatus |= MS_CTS_ON;   // RTS active, set CTS
  542. else
  543. *pModemStatus &= ~MS_CTS_ON;   // RTS clear, clear CTS
  544. }
  545. else {
  546. // Unknown vendor/class request
  547. DEBUGMSG(1,(TEXT("Unknown vendor/class request %2.2Xrn"),
  548. pHWHead->dReq.bRequest));
  549. }
  550. // Command is complete
  551. sendDone(pHWHead,0);
  552. return;
  553. }
  554. // standard chapter 9 commands
  555. switch (pHWHead->dReq.bRequest) {
  556. case GET_STATUS:
  557. RETAILMSG(1, (TEXT("GET_STATUSrn")));
  558. dbuf[0] = 0;
  559. dbuf[1] = 0;
  560. // If this is a request to the endpoint return the stalled status.
  561. if (pHWHead->dReq.bmRequest == 0x82) {
  562. dbuf[0] = 0;
  563. switch (pHWHead->dReq.wIndex & 15) {
  564. // Control endpoint can't stall (we wouldn't get this message).
  565. case 0:
  566. break;
  567.   
  568. // OUT endpoint. Return send_stall.
  569. case 1:
  570. UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0x4); 
  571. if (pHWHead->pUSBCtrlAddr->OCSR1.send_stall)
  572. dbuf[0] = 1;
  573. break;
  574. // IN endpoint. Return send_stall.
  575. case 2:
  576. //case 3:
  577. case 4:
  578. UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0x1); 
  579. if (pHWHead->pUSBCtrlAddr->EP0ICSR1.se_sds)
  580. dbuf[0] = 1;
  581. break;
  582. }
  583. UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0);
  584. }
  585. // Clear the OPR bit and start the data phase
  586. sendCommandDone(pHWHead);
  587. // Send the reply data.
  588. sendData(pHWHead, dbuf, 2, 2);
  589. //RETAILMSG(1, (TEXT("GS[0x%X]rn"), pHWHead->dReq.wIndex & 0xFF));
  590. break;
  591. case CLEAR_FEATURE:
  592. DEBUGMSG(1, (TEXT("CLEAR_FEATURErn")));
  593. if (pHWHead->dReq.bmRequest == 0x02) { // Halt 
  594. switch (pHWHead->dReq.wIndex & 15) {
  595. // Control endpoint. Not suggested.
  596. case 0:
  597. break;
  598. // OUT endpoint. Set and clear sendstall to reset DATA0/DATA1.
  599. case 1:
  600. UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0x4); 
  601. UDC_REG_BITSET(struct OCSR1Bits,
  602. &pHWHead->pUSBCtrlAddr->OCSR1,send_stall,1); // STALL!!!
  603. UDC_REG_BITSET(struct OCSR1Bits,
  604. &pHWHead->pUSBCtrlAddr->OCSR1,send_stall,0);
  605. UDC_REG_BITSET(struct OCSR1Bits,
  606. &pHWHead->pUSBCtrlAddr->OCSR1,sent_stall,0); // CLEAR STALL
  607. break;
  608. // IN endpoint. Set and clear sendstall to reset DATA0/DATA1.
  609. case 2:
  610. //case 3:
  611. case 4:
  612. UDC_REG_WRITE(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0x1); 
  613. UDC_REG_BITSET(struct EP0ICSR1Bits,
  614. &pHWHead->pUSBCtrlAddr->EP0ICSR1,se_sds,1); // STALL!!!
  615. UDC_REG_BITSET(struct EP0ICSR1Bits,
  616. &pHWHead->pUSBCtrlAddr->EP0ICSR1,se_sds,0);
  617. UDC_REG_BITSET(struct EP0ICSR1Bits,
  618. &pHWHead->pUSBCtrlAddr->EP0ICSR1,sds_sts,0); // CLEAR STALL
  619. break;
  620. }
  621. UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0);
  622. }
  623. // Command is complete
  624. sendDone(pHWHead,0);
  625. //RETAILMSG(1, (TEXT("CF[0x%X]rn"), pHWHead->dReq.wIndex & 0xFF));
  626. break;
  627. case SET_FEATURE:
  628. DEBUGMSG(1, (TEXT("SET_FEATURE %drn"), pHWHead->dReq.bmRequest));
  629. if (pHWHead->dReq.bmRequest == 0x02) {
  630. switch (pHWHead->dReq.wIndex & 15) {
  631. // Control endpoint. Not suggested.
  632. case 0:
  633. break;
  634. /* OUT endpoint. Set sendstall to force stall condition
  635. */
  636. case 1:
  637. UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0x4); 
  638. UDC_REG_BITSET(struct OCSR1Bits,
  639. &pHWHead->pUSBCtrlAddr->OCSR1, send_stall, 1); // STALL
  640. break;
  641. /* IN endpoint. Set sendstall to force stall condition
  642. */
  643. case 2:
  644. //case 3:
  645. case 4:
  646. UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0x1); 
  647. UDC_REG_BITSET(struct EP0ICSR1Bits, 
  648. &pHWHead->pUSBCtrlAddr->EP0ICSR1, se_sds, 1); // STALL
  649. break;
  650. }
  651. UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0);
  652. }
  653. // Command is complete
  654. sendDone(pHWHead,0);
  655. //RETAILMSG(1, (TEXT("SF[0x%X]rn"), pHWHead->dReq.wIndex & 0xFF));
  656. break;
  657. case SET_ADDRESS:
  658. RETAILMSG(1, (TEXT("SET_ADDRESS - 0x%Xrn"), pHWHead->dReq.wValue));
  659. pHWHead->dAddress = (BYTE)pHWHead->dReq.wValue;
  660. // Note, this write needs to be started here but it will not read back
  661. // until the command completes. There is no retry mechanism.
  662. setAddress(pHWHead, pHWHead->dAddress);
  663. // Command is complete
  664. sendDone(pHWHead,0);
  665. break;
  666. case GET_DESCRIPTOR:
  667. switch ((BYTE)(pHWHead->dReq.wValue>>8)) {
  668. case DEVICE: // 0x01
  669. RETAILMSG(1, (TEXT("GET_DESCRIPTOR:DEVICE 0x%X, 0x%Xrn"), 
  670. uStd[0], pHWHead->dReq.wLength));
  671. //sendCommandDone(pHWHead);
  672. p = (PUCHAR)uStd;
  673. len = (BYTE)min(uStd[0],pHWHead->dReq.wLength);
  674. totLen = uStd[0];
  675. break;
  676. case CONFIGURATION: // 0x02
  677. RETAILMSG(1,(TEXT("GET_DESCRIPTOR:CONFIGURATIONrn")));
  678. //sendCommandDone(pHWHead);
  679. p = (PUCHAR)&uStd[iCONF];
  680. len = (BYTE)min(CFGLEN,pHWHead->dReq.wLength);
  681. totLen = CFGLEN;
  682. break;
  683. case STRING: // 0x03
  684. DEBUGMSG(1,(TEXT("GET_DESCRIPTOR:STRINGrn")));
  685. //sendCommandDone(pHWHead);
  686. p = NULL;
  687. len = 0;
  688. totLen = 0;
  689. break;
  690. default:
  691. DEBUGMSG(1,(TEXT("GET_DESCRIPTOR:Unknown %drn"),
  692. (pHWHead->dReq.wValue>>8) ));
  693. sendCommandDone(pHWHead);
  694. p = NULL;
  695. len = 0;
  696. totLen = 0;
  697. break;
  698. }
  699. // Clear the OPR bit and start the data phase
  700. sendCommandDone(pHWHead);
  701. // Send the reply data.
  702. sendData(pHWHead, p, len, totLen);
  703. DEBUGMSG(1,(TEXT("GET_DESCRIPTOR:EP0ICSR1 status value = 0x%xrn"), pHWHead->pUSBCtrlAddr->EP0ICSR1));
  704. break;
  705. case GET_CONFIG:
  706. RETAILMSG(1, (TEXT("GET_CONFIGrn")));
  707. // Clear the OPR bit and start the data phase
  708. sendCommandDone(pHWHead);
  709. // Send the reply data.
  710. sendData(pHWHead, &pHWHead->dConfIdx, 1, 1);
  711. break;
  712. case GET_INTERFACE:
  713. DEBUGMSG(1,(TEXT("GET_INTERFACErn")));
  714. // Clear the OPR bit and start the data phase
  715. sendCommandDone(pHWHead);
  716. // Send the reply data.
  717. sendData(pHWHead, &pHWHead->dInterface, 1, 1);
  718. break; 
  719. case SET_CONFIG:
  720. RETAILMSG(1,(TEXT("SET_CONFIG %drn"),
  721. pHWHead->dReq.wValue));
  722. pHWHead->dConfIdx = (BYTE)pHWHead->dReq.wValue;
  723. // Command done
  724. sendDone(pHWHead,0);
  725. break;
  726. case SET_DESCRIPTOR:
  727. RETAILMSG(1, (TEXT("SET_DESCRIPTORrn")));
  728. // Command done
  729. sendDone(pHWHead,0);
  730. break;
  731. case SET_INTERFACE:
  732. DEBUGMSG(1,(TEXT("SET_INTERFACE : %d,%drn"),
  733. pHWHead->dReq.wIndex,
  734. pHWHead->dReq.wValue));
  735. pHWHead->dInterface = (BYTE)pHWHead->dReq.wIndex;
  736. pHWHead->dSetting = (BYTE)pHWHead->dReq.wValue;
  737. // Command done
  738. sendDone(pHWHead,0);
  739. break;
  740. default:
  741. DEBUGMSG(1,(TEXT("Unhandled Command : %drn"),
  742. pHWHead->dReq.bRequest));
  743. // Command done
  744. sendDone(pHWHead,0);
  745. break;
  746. }
  747. }
  748. DEBUGMSG(1, (TEXT("--SC2440_USB_DoEndpoint0rn")));
  749. }
  750. /*************************************************************************
  751. SC2440_USB_GetInterruptType
  752. Determine the source of an interrupt and return flags to control 
  753. which function gets called to handle it. EP0 is handled as modem 
  754. interrupt, EP1 as TX, EP3 as RX and reset is handle as line 
  755. interrupt.
  756. *************************************************************************/
  757. INTERRUPT_TYPE SC2440_USB_GetInterruptType( PSER_INFO pHWHead) //:-)
  758. {
  759. INTERRUPT_TYPE interruptFlags = 0;
  760. //BYTE saveIndex;
  761.     pHWHead->wPrevSOF = pHWHead->wSOF;
  762.     pHWHead->wSOF = (pHWHead->pUSBCtrlAddr->FNR2.fr_n2 << 8) | pHWHead->pUSBCtrlAddr->FNR1.fr_n1; 
  763. DEBUGMSG(1, (TEXT("SOF: %u, wPrevSOF: %urn"), pHWHead->wSOF, pHWHead->wPrevSOF));
  764. //RETAILMSG(1, (TEXT("SOF: %u, wPrevSOF: %urn"), pHWHead->wSOF, pHWHead->wPrevSOF));
  765. //important notes
  766. // 1. INDEX register should be preserved here. //:-)
  767. // 2. 'else if' should not be used here. //:-) 
  768. if (usbdShMem->usbdEir& USBDEIR_EP1) // EP1(IN), ready to TX more data.
  769. {
  770. interruptFlags |= INTR_TX;
  771. }
  772.   if (usbdShMem->usbdEir& USBDEIR_EP4) // EP4(OUT), RX data ready
  773. {
  774. interruptFlags |= INTR_RX;
  775. }
  776. if (usbdShMem->usbdDma3Int) // DMA3 done interrupt
  777. {
  778. interruptFlags |= INTR_RX;
  779. USBDMSG(1, (TEXT("<D3Int>rn")));
  780. }
  781. if (usbdShMem->usbdUir& USBDUIR_RESET)// USB reset, so re-initialize our driver.
  782. {
  783. USBDMSG(1, (TEXT("RESET INTrn")));
  784. interruptFlags |= INTR_LINE; // We use INTR_LINE to handle USB Reset 
  785. usbdShMem->usbdUir&=~USBDUIR_RESET;
  786. }
  787. if (usbdShMem->usbdEir&USBDEIR_EP0) // EP0, Control endpoint
  788. {
  789. interruptFlags |= INTR_MODEM; // Use INTR_MODEM for EP0 interrupts
  790. // call SerModemIntr function  by shim 020503
  791. usbdShMem->usbdEir&=~USBDEIR_EP0;
  792. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=0x0;  
  793. //temp_kiw, should be repaired officially.
  794. USBDMSG(1, (TEXT("<EP0 Int>rn")));
  795. }
  796. return (interruptFlags);
  797. }
  798. /*************************************************************************
  799. SC2440_USB_LineIntHandler
  800. This handler is called for reset interrupts
  801. *************************************************************************/
  802. void SC2440_USB_LineIntHandler(PSER_INFO pHWHead)
  803. {
  804. DEBUGMSG(1, (TEXT("++SC2440_USB_LineIntHandlerrn")));
  805. SC2440_USB_Init(pHWHead);
  806. UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0);
  807. DEBUGMSG(1, (TEXT("--SC2440_USB_LineIntHandlerrn")));
  808. }
  809. /*************************************************************************
  810.   SC2440_USB_RxIntHandler
  811.  
  812.   Read characters up to the max packet length from the IN FIFO. Return the
  813.   number of characters read in the supplied argument. The function returns
  814.   a boolean indicating whether event characters are present.
  815. *************************************************************************/
  816. BOOL SC2440_USB_RxIntHandler(PSER_INFO pHWHead,
  817.      PUCHAR pRxBuffer,
  818.      ULONG *pBuffLen)
  819. {
  820. BOOL fRXFlag    = FALSE;
  821. UCHAR cEvtChar    = pHWHead->dcb.EvtChar;
  822. int buflen    = *pBuffLen;
  823. UCHAR cRxChar;
  824. ULONG usbdRxRdPt=0;
  825. ULONG usbdRxWrPt=0;
  826. ULONG usbdRxCnt;
  827. BYTE* usbdRxBuf;
  828. ULONG cnt,saveCnt;
  829. int   swRdCnt=0;
  830. BYTE saveIndex;
  831. DEBUGMSG(1, (TEXT("++SC2440_USB_RxIntHandlerrn")));
  832.     
  833. usbdRxRdPt=usbdShMem->usbdRxRdPt;
  834. usbdRxBuf=(BYTE*)usbdShMem->usbdRxBuf;
  835. *pBuffLen = 0;
  836.     
  837. // Endpoint 4 mode
  838. saveIndex=*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX;
  839. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=0x4;
  840. if (usbdShMem->usbdDma3Int)
  841. {
  842. //usbdRxWrPt=v_pDMAregs->rDCDST3 - realPhysicalAddr_UsbdRxBuf;
  843. USBDMSG(1,(TEXT("[RxPt:%d]"),usbdRxRdPt));
  844. if(usbdRxRdPt==0)
  845. {
  846. usbdShMem->usbdDma3Int=0;
  847. USBDMSG(1,(TEXT("[D:%d"),pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low));
  848. // cnt=swRdCnt=pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low | pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_high;
  849. swRdCnt=pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low | pHWHead->pUSBCtrlAddr->OFCR2.out_cnt_high;
  850. for(cnt=0; cnt < swRdCnt; cnt++)
  851. {
  852. usbdRxBuf[cnt]=(UCHAR)pHWHead->pUSBCtrlAddr->EP4F.fifo_data;
  853. }
  854. if((pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low | pHWHead->pUSBCtrlAddr->OFCR2.out_cnt_high)==0 && 
  855.    pHWHead->pUSBCtrlAddr->OCSR1.out_pkt_rdy==1)
  856. {
  857. USBDMSG(1, (TEXT(",OPR CLR,")));
  858. UDC_REG_BITSET(struct OCSR1Bits,&pHWHead->pUSBCtrlAddr->OCSR1, out_pkt_rdy, 0);
  859. }
  860. UsbdInitDma3(0,swRdCnt); 
  861. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DTL=(USBD_GLOBALS_BUF_SIZE-swRdCnt)&0xff;
  862. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DTM=((USBD_GLOBALS_BUF_SIZE-swRdCnt)>>8)&0xff;
  863. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DTH=((USBD_GLOBALS_BUF_SIZE-swRdCnt)>>16)&0x0f;
  864. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->EP4DC=UDMA_OUT_DMA_RUN|UDMA_DMA_MODE_EN;
  865. }
  866. }
  867. usbdRxWrPt=v_pDMAregs->rDCDST3 - realPhysicalAddr_UsbdRxBuf;
  868. if(usbdRxWrPt==USBD_GLOBALS_BUF_SIZE)
  869. {
  870. usbdRxWrPt=swRdCnt;
  871. //usbdRxWrPt=0;
  872. }
  873. if(usbdRxRdPt<=usbdRxWrPt)
  874. usbdRxCnt=usbdRxWrPt-usbdRxRdPt;
  875. else
  876. usbdRxCnt=USBD_GLOBALS_BUF_SIZE-usbdRxRdPt+usbdRxWrPt;
  877. if( buflen > usbdRxCnt)
  878. saveCnt=cnt=usbdRxCnt;
  879. else
  880. saveCnt=cnt=buflen;
  881. if (usbdRxCnt == 0) // No data to read
  882. USBDMSG(1, (TEXT("[R0]")));
  883. }  
  884. else
  885. {
  886. USBDMSG(1, (TEXT("<%d>"),cnt));
  887. while(cnt--) 
  888. {
  889. *pRxBuffer++ = cRxChar = (UCHAR)usbdRxBuf[usbdRxRdPt++];
  890. if(usbdRxRdPt==USBD_GLOBALS_BUF_SIZE)
  891. usbdRxRdPt=0;
  892. if( cRxChar == cEvtChar )
  893. fRXFlag = TRUE;
  894. }
  895. (*pBuffLen)=saveCnt;
  896. usbdRxCnt-=saveCnt;
  897. usbdShMem->usbdRxRdPt=usbdRxRdPt;
  898. usbdShMem->usbdEir&=~USBDEIR_EP4;
  899. }
  900.     //not be needed. Only for test
  901. if(pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low==0 ) 
  902. if(pHWHead->pUSBCtrlAddr->OCSR1.out_pkt_rdy==1)
  903. {
  904.     USBDMSG(1, (TEXT("__OPR__(NEVER EXECUTED)")));
  905. UDC_REG_BITSET(struct OCSR1Bits,&pHWHead->pUSBCtrlAddr->OCSR1, out_pkt_rdy, 0);
  906. }
  907. // If we didn't read the whole buffer we need to come back. Leave with
  908. // the interrupt still enabled so the MDD will recall.
  909. if (usbdRxCnt>0)
  910. {
  911. USBDMSG(1, (TEXT("[%d->MDD]"),usbdRxCnt));
  912. usbdShMem->usbdEir|=USBDEIR_EP4; 
  913. // MDD will recall RxIntHandler by chekcing SC2440_USB_GetInterruptType().
  914. // So, usbdShMem->usbdEir:USBDEIR_EP3 must not be cleared //:-) 
  915. //Sleep(100);
  916. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
  917. return fRXFlag;
  918. }
  919. usbdShMem->usbdEir&=~USBDEIR_EP4;
  920. DEBUGMSG(1, (TEXT("--SC2440_USB_RxIntHandlerrn")));
  921. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
  922. return fRXFlag;
  923. }
  924. /*************************************************************************
  925.   SC2440_USB_TxIntHandler
  926.  
  927.   Send the next packet to the USB. The first packet gets sent by directly
  928.   calling this function (via dispatch table) from the MDD. After the first
  929.   call the interrupt mechanism will keep things going.
  930.  
  931.   We return the actual number of bytes we've queued to the UDC. Note that
  932.   until the next interrupt we wont know if it has been transmitted. We'll
  933.   deal with the failure by saving the original packet and retransmitting if
  934.   we get an error. In that case we'll return 0 as the number of bytes sent
  935.   since no new bytes have been consumed from the caller's buffer.
  936.  
  937.   When the packet is accepted we return the number of bytes and grab the 
  938.   next packet (or portion thereof).
  939.  
  940. *************************************************************************/
  941. //:-)
  942. void SC2440_USB_TxIntHandler( PSER_INFO pHWHead,
  943.       PUCHAR pTxBuffer,
  944.       ULONG *pBuffLen ) 
  945. {
  946. unsigned int i;
  947. UCHAR ucLen;
  948. BYTE saveIndex;
  949. //DEBUGMSG(1, (TEXT("++SC2440_USB_TxIntHandlerrn")));
  950. //USBDMSG(1, (TEXT("<T:%d>"),*pBuffLen));
  951. usbdShMem->usbdEir&=~USBDEIR_EP1;
  952. // Endpoint 1 mode
  953. saveIndex=*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX;
  954. UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0x1);
  955.     //pHWHead->pUSBCtrlAddr->INDEX.index=0x1; //:-)
  956. pHWHead->CommErrors &= ~CE_TXFULL;
  957. // If nothing to send, just return after clearing interrupt.
  958. if (! *pBuffLen ) 
  959. {
  960. //DEBUGMSG (1, (TEXT("[TX:nothing to send]")));    
  961. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
  962. return;
  963. }
  964.            
  965. // Don't try to send more than EP1 can handle.
  966. if( *pBuffLen > EP1Len )
  967.      ucLen = EP1Len;
  968. else {
  969. // If we end exactly on a packet boundary, the host doesn't
  970. // realize there is no more data.  So if we exactly fill the final 
  971. // packet, truncate it so we can send a short packet next frame
  972. // indicating end of the transmission
  973. if( *pBuffLen == EP1Len ) 
  974. {
  975. //USBDMSG (1, (TEXT("Tx breaking packetrn")));            
  976. ucLen = EP1Len - 2;
  977. } else {
  978. ucLen = (UCHAR)*pBuffLen;
  979. }
  980. }
  981. if (!pHWHead->pUSBCtrlAddr->EP0ICSR1.opr_ipr)
  982. {
  983. // Write to the FIFO directly to send the bytes.
  984. for (i=0; i < ucLen; i++) 
  985. {
  986. IOW_REG_FIELD(struct EP1FBits, 
  987. &pHWHead->pUSBCtrlAddr->EP1F, fifo_data, *pTxBuffer++);
  988. }
  989. // Return number of bytes transmitted via pBuffLen.
  990. *pBuffLen = ucLen;
  991. UDC_REG_WRITE(struct EP0ICSR1Bits, &pHWHead->pUSBCtrlAddr->EP0ICSR1, opr_ipr, 1);
  992. } else {
  993. // Transmit already in progress.  Just return and wait for current
  994. // transmission to complete before sending more.
  995. //USBDMSG(0, (TEXT("Write Pend !!!rn")));
  996. *pBuffLen = 0; 
  997. }
  998. //DEBUGMSG(0, (TEXT("--SC2440_USB_TxIntHandlerrn")));
  999. *(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
  1000. }
  1001. BOOL
  1002. HW_PowerOff(
  1003.     PSER_INFO pHWHead 
  1004.     )
  1005. {
  1006. pHWHead->State = OFF;
  1007. // cache the interrupt regs
  1008. pHWHead->cIntStat_uir = *(BYTE *)&pHWHead->pUSBCtrlAddr->UIR;
  1009. pHWHead->cIntStat_eir = *(BYTE *)&pHWHead->pUSBCtrlAddr->EIR;
  1010.     
  1011. // disable the USB Clocks
  1012. EnterCriticalSection(&pHWHead->HwRegCritSec);
  1013. //DEBUGMSG(1, (TEXT("USB:HW_PowerOff()rn")));
  1014. //RETAILMSG(1, (TEXT("USB:HW_PowerOff()rn")));
  1015. HW_USBClocks(pHWHead);
  1016. LeaveCriticalSection(&pHWHead->HwRegCritSec);
  1017.     return TRUE;
  1018. }
  1019. BOOL 
  1020. HW_PowerOn(
  1021.     PSER_INFO pHWHead
  1022.     )
  1023. {
  1024. pHWHead->State = RESUME;
  1025. // enable the USB Clocks
  1026. EnterCriticalSection(&pHWHead->HwRegCritSec);
  1027. //DEBUGMSG(1, (TEXT("USB:HW_PowerOn()rn")));
  1028. //RETAILMSG(1, (TEXT("USB:HW_PowerOn()rn")));
  1029. HW_USBClocks(pHWHead);
  1030. LeaveCriticalSection(&pHWHead->HwRegCritSec);
  1031. SetInterruptEvent(pHWHead->pHWObj->dwIntID); 
  1032.     
  1033.     return TRUE;
  1034. }
  1035. VOID
  1036. HW_USBClocks(PSER_INFO pHWHead)
  1037. {
  1038. if ((pHWHead->State == IDLE) || (pHWHead->State == RESUME))
  1039. {
  1040. DEBUGMSG(1, (TEXT("HW_USBClocks::IDLErn")));
  1041.         //
  1042.         // Enable the USB Clocks
  1043.         //
  1044.         pHWHead->pCLKPWR->rCLKCON |= (1<<7);
  1045.         DEBUGMSG(ZONE_INIT, (TEXT("rCLKCON: 0x%Xrn"), pHWHead->pCLKPWR->rCLKCON));
  1046.         
  1047.         // Fin=12MHz, Fout=48MHz
  1048.         //pHWHead->pCLKPWR->rUPLLCON = 0x48032;   // ((0x48 << 12) + (0x3 << 4) + 0x2)
  1049.         //DEBUGMSG(ZONE_INIT, (TEXT("rUPLLCON: 0x%Xrn"), pHWHead->pCLKPWR->rUPLLCON));
  1050.         //
  1051.         // MISCCR: USBD Pads, Normal mode
  1052.         //
  1053.         pHWHead->pIrqCtrlAddr->rMISCCR &= ~((3 << 12) | (1 << 3));
  1054.         // TO DO :
  1055.         // Enable USB_PULLUP on GPIO PIN (tied to USB D+) & set high
  1056.         //
  1057.         //pHWHead->pIrqCtrlAddr->rGPBCON &= ~(3 << 18);    // clear GPE15
  1058.         //pHWHead->pIrqCtrlAddr->rGPBCON |=  (1 << 18);    // config as output
  1059.         //pHWHead->pIrqCtrlAddr->rGPBUP  &= ~(1 << 9);    // pullup disabled
  1060.         //pHWHead->pIrqCtrlAddr->rGPBDAT |=  (1 << 9);    // set high
  1061.         pHWHead->pIrqCtrlAddr->rGPGCON &= ~(3 << 24);    // clear GPE15
  1062.         pHWHead->pIrqCtrlAddr->rGPGCON |=  (1 << 24);    // config as output
  1063.         pHWHead->pIrqCtrlAddr->rGPGUP  &= ~(1 << 12);    // pullup disabled
  1064.         pHWHead->pIrqCtrlAddr->rGPGDAT |=  (1 << 12);    // set high
  1065.         DEBUGMSG(ZONE_INIT, (TEXT("rGPDCON: 0x%Xrn"), pHWHead->pIrqCtrlAddr->rGPDCON));
  1066.         DEBUGMSG(ZONE_INIT, (TEXT("rGPDUP: 0x%Xrn"),  pHWHead->pIrqCtrlAddr->rGPDUP));
  1067.         DEBUGMSG(ZONE_INIT, (TEXT("rGPDDAT: 0x%Xrn"), pHWHead->pIrqCtrlAddr->rGPDDAT));
  1068. }
  1069. else if (pHWHead->State == OFF) 
  1070. {
  1071. DEBUGMSG(1, (TEXT("HW_USBClocks::OFFrn")));
  1072.         //
  1073.         // Disable the USB Clocks
  1074.         //
  1075.         pHWHead->pCLKPWR->rCLKCON &= ~(1<<7);
  1076.         DEBUGMSG(ZONE_INIT, (TEXT("rCLKCON: 0x%Xrn"), pHWHead->pCLKPWR->rCLKCON));
  1077.         
  1078.         // Fin=12MHz, Fout=48MHz
  1079.         //pHWHead->pCLKPWR->rUPLLCON = 0;
  1080.         // MISCCR: USBD Pads, Suspend mode
  1081.         pHWHead->pIrqCtrlAddr->rMISCCR |= (3 << 12);
  1082.         // TO DO :
  1083.         // Disable USB_PULLUP to remove us from the bus
  1084.         
  1085.         //pHWHead->pIrqCtrlAddr->rGPBCON &= ~(3 << 18);    // clear GPE15
  1086.         //pHWHead->pIrqCtrlAddr->rGPBCON |=  (1 << 18);    // config as output
  1087.         //pHWHead->pIrqCtrlAddr->rGPBUP  |=  (1 << 9);    // pullup disabled
  1088.         //pHWHead->pIrqCtrlAddr->rGPBDAT &= ~(1 << 9);    // set low
  1089.         
  1090. pHWHead->pIrqCtrlAddr->rGPGCON &= ~(3 << 24);    // clear GPE15
  1091.         pHWHead->pIrqCtrlAddr->rGPGCON |=  (1 << 24);    // config as output
  1092.         pHWHead->pIrqCtrlAddr->rGPGUP  |=  (1 << 12);    // pullup disabled
  1093.         pHWHead->pIrqCtrlAddr->rGPGDAT &= ~(1 << 12);    // set low
  1094. DEBUGMSG(ZONE_INIT, (TEXT("rUPLLCON: 0x%Xrn"), pHWHead->pCLKPWR->rUPLLCON));
  1095. }
  1096. }
  1097. // :-)
  1098. /***************************************
  1099.   Added routines for USBD Rx:DMA Tx:ISR
  1100.  ***************************************/
  1101. BOOL InitUsbdDriverGlobals(void)
  1102. {
  1103. BOOL Ret;
  1104. int i;
  1105. if ( v_pDriverGlobals == NULL )
  1106. {
  1107. v_pDriverGlobals =(PDRIVER_GLOBALS)VirtualAlloc( 0,
  1108. DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
  1109. MEM_RESERVE,
  1110. PAGE_NOACCESS);
  1111. if ( v_pDriverGlobals == NULL )
  1112. {
  1113.     USBDMSG( 1, (TEXT( "InitUsbdDriverGlobals : VirtualAlloc failed!rn")) );
  1114. return ( FALSE );
  1115. }
  1116. Ret = VirtualCopy( (LPVOID)v_pDriverGlobals,
  1117.    (LPVOID)DRIVER_GLOBALS_PHYSICAL_MEMORY_START,
  1118.    DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
  1119.    PAGE_READWRITE | PAGE_NOCACHE
  1120.    );
  1121. if ( Ret == FALSE )
  1122. {
  1123. DEBUGMSG( ZONE_ERROR, (TEXT( "InitUsbdDriverGlobals: VirtualCopy failed!rn")) );
  1124. if ( v_pDriverGlobals )
  1125. {
  1126. VirtualFree( v_pDriverGlobals,
  1127.  DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE ,
  1128.  MEM_RELEASE
  1129. );
  1130. v_pDriverGlobals = NULL;
  1131. return ( FALSE );
  1132. }
  1133. }
  1134. usbdShMem=&(v_pDriverGlobals->usbd);
  1135.     for(i=0;i<USBD_GLOBALS_BUF_SIZE;i++)
  1136.     {
  1137.         usbdShMem->usbdRxBuf[i]=0x0;
  1138. //usbdShMem->usbdTxBuf[i]=0x0;
  1139.     }
  1140. usbdShMem->usbdRxRdPt=0;
  1141. usbdShMem->usbdRxWrPt=0;
  1142. usbdShMem->usbdRxCnt=0;
  1143. //usbdShMem->usbdTxRdPt=0;
  1144. //usbdShMem->usbdTxWrPt=0;
  1145. //usbdShMem->usbdTxCnt=0;
  1146. usbdShMem->usbdEir=0;
  1147.   usbdShMem->usbdUir=0;
  1148. usbdShMem->usbdDma3Int=0; 
  1149. //usbdShMem->usbdMddRxCnt=0;
  1150. USBDMSG( 1, (TEXT( "USBD:DRIVER_GLOBALS is initializedrn")) );
  1151. return( TRUE ); 
  1152. }
  1153. BOOL UsbdAllocateVm(void)
  1154. {
  1155. if(v_pDMAregs == NULL) 
  1156. {
  1157. v_pDMAregs = (volatile DMAreg *) 
  1158. VirtualAlloc(0,sizeof(DMAreg),MEM_RESERVE, PAGE_NOACCESS);
  1159. if(v_pDMAregs == NULL)
  1160. {
  1161. ERRORMSG(1,(TEXT("For DMAreg: VirtualAlloc failed!rn")));
  1162. return (FALSE);
  1163. }
  1164. else 
  1165. {
  1166. if(!VirtualCopy((PVOID)v_pDMAregs,(PVOID)(DMA_BASE),sizeof(DMAreg),
  1167. PAGE_READWRITE | PAGE_NOCACHE )) 
  1168. {
  1169. ERRORMSG(1,(TEXT("For pIOPregs: VirtualCopy failed!rn")));
  1170. UsbdDeallocateVm();
  1171. return (FALSE);
  1172. }
  1173. }
  1174. }
  1175. if(v_pINTregs == NULL)
  1176. {
  1177.      v_pINTregs = (volatile INTreg *) 
  1178.      VirtualAlloc(0,sizeof(INTreg),MEM_RESERVE, PAGE_NOACCESS);
  1179.     if(v_pINTregs == NULL)
  1180. {
  1181.     ERRORMSG(1,(TEXT("For INTreg: VirtualAlloc failed!rn")));
  1182. return (FALSE);
  1183.     }
  1184.      else 
  1185. {
  1186.      if(!VirtualCopy((PVOID)v_pINTregs,(PVOID)(INT_BASE),sizeof(INTreg),
  1187.         PAGE_READWRITE | PAGE_NOCACHE ))
  1188.     {
  1189. ERRORMSG(1,(TEXT("For INTreg: VirtualCopy failed!rn")));
  1190.      return (FALSE);
  1191.      }
  1192.     }
  1193. }
  1194. return TRUE;
  1195. }
  1196. void UsbdDeallocateVm(void)
  1197. {
  1198. if(v_pDMAregs)
  1199. {
  1200. VirtualFree((void*)v_pDMAregs, sizeof(DMAreg), MEM_RELEASE);
  1201. v_pDMAregs=NULL;
  1202. }
  1203. if(v_pINTregs)
  1204. {
  1205. VirtualFree((void*)v_pINTregs, sizeof(INTreg), MEM_RELEASE);
  1206. v_pINTregs=NULL;
  1207. }
  1208. }
  1209. void UsbdInitDma3(int bufIndex,int bufOffset)
  1210. {
  1211. //ULONG usbdRxRdPt,usbdRxWrPt;
  1212.    //If DMA3 is turned on, DMA3 should be turned off.
  1213. if((v_pDMAregs->rDMASKTRIG3&(1<<1))!=0)
  1214. {
  1215. v_pDMAregs->rDMASKTRIG3=(1<<2); //DMA3 stop
  1216. while(v_pDMAregs->rDMASKTRIG3&(1<<1)); //wait until DMA3 stop
  1217. usbdShMem->usbdRxRdPt=0;
  1218. USBDMSG( 1, (TEXT("[DMA3 is stopped]rn")));
  1219. }
  1220. v_pDMAregs->rDISRCC3 = (1<<1)|(1<<0);    //src=APB, srcAddr=fixed
  1221. v_pDMAregs->rDISRC3 = REAL_PHYSICAL_ADDR_EP4_FIFO; //srcAddr=EP4_FIFO 
  1222. v_pDMAregs->rDIDSTC3 = (0<<1)|(0<<0);    //dst=AHB(memory),increase,
  1223. #if (DRIVER_GLOBALS_PHYSICAL_MEMORY_START<0xA0000000 || DMA_BUFFER_BASE<0xA0000000) 
  1224. GENERATE_ERROR
  1225.     //The above two address should be non-cacheable area.
  1226. #endif  
  1227. realPhysicalAddr_UsbdRxBuf = 
  1228. (ULONG)&((DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START)->usbd.usbdRxBuf 
  1229. - DMA_BUFFER_BASE + DMA_PHYSICAL_BASE;
  1230. //USBDMSG( 1, (TEXT( "[USBD:RPA_URxBuf=%x]"),realPhysicalAddr_UsbdRxBuf) );
  1231. //Real physical address of usbdShMem->usbdRxBuf
  1232. if(bufIndex==0)
  1233. {
  1234.     v_pDMAregs->rDIDST3=realPhysicalAddr_UsbdRxBuf+0+bufOffset;
  1235. }
  1236. else
  1237. {
  1238. v_pDMAregs->rDIDST3=realPhysicalAddr_UsbdRxBuf+(USBD_GLOBALS_BUF_SIZE/2)+bufOffset;
  1239. }
  1240.     v_pDMAregs->rDCON3=(USBD_GLOBALS_BUF_SIZE-bufOffset)|(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(4<<24)|(1<<23)|(1<<22)|(0<<20); 
  1241. //handshake,requestor=APB,CURR_TC int enable,unit transfer,
  1242. //single service,src=USBD,H/W request,no_autoreload,byte,CURR_TC
  1243. v_pDMAregs->rDMASKTRIG3=(1<<1); //DMA 3 on
  1244.    
  1245. USBDMSG( 1, (TEXT( "[USBD:rDIDST3=%x,rDCDST3=%x]rn"),v_pDMAregs->rDIDST3,v_pDMAregs->rDCDST3) );
  1246. }