Usb read

Dependencies:   FATFileSystem

Fork of F401RE-USBHost by Norimasa Okamoto

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHALHost_F401RE.cpp Source File

USBHALHost_F401RE.cpp

00001 // Simple USBHost for Nucleo F401RE
00002 #if defined(TARGET_NUCLEO_F401RE)
00003 #include "USBHALHost_F401RE.h"
00004 
00005 template <bool>struct CtAssert;
00006 template <>struct CtAssert<true> {};
00007 #define CTASSERT(A) CtAssert<A>();
00008 
00009 
00010 #ifdef _USB_DBG
00011 extern RawSerial pc;
00012 #include "mydebug.h"
00013 #define USB_DBG(...) do{pc.printf("[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);pc.printf(__VA_ARGS__);pc.puts("\n");} while(0);
00014 #define USB_DBG_HEX(A,B) debug_hex<RawSerial>(pc,A,B)
00015 
00016 #else
00017 #define USB_DBG(...) while(0)
00018 #define USB_DBG_HEX(A,B) while(0)
00019 #endif
00020 
00021 #ifdef _USB_TEST
00022 #define USB_TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);};
00023 #define USB_TEST_ASSERT_FALSE(A) USB_TEST_ASSERT(!(A))
00024 #else
00025 #define USB_TEST_ASSERT(A) while(0)
00026 #define USB_TEST_ASSERT_FALSE(A) while(0)
00027 #endif
00028 
00029 #ifdef _USB_TRACE
00030 #define USB_TRACE() while(0)
00031 #define USB_TRACE1(A) while(0)
00032 #define USB_TRACE_VIEW() while(0)
00033 #define USB_TRACE_CLEAR() while(0)
00034 #else
00035 #define USB_TRACE() while(0)
00036 #define USB_TRACE1(A) while(0)
00037 #define USB_TRACE_VIEW() while(0)
00038 #define USB_TRACE_CLEAR() while(0)
00039 #endif
00040 
00041 #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0);
00042 
00043 __IO bool attach_done = false;
00044 __IO bool token_done = false;
00045 __IO HCD_URBStateTypeDef g_urb_state = URB_IDLE;
00046 
00047 void delay_ms(uint32_t t)
00048 {
00049     HAL_Delay(t);
00050 }
00051 
00052 // from usbh_conf.c
00053 extern HCD_HandleTypeDef hhcd_USB_OTG_FS;
00054 
00055 void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd)
00056 {
00057   GPIO_InitTypeDef GPIO_InitStruct;
00058   if(hhcd->Instance==USB_OTG_FS)
00059   {
00060     /* Peripheral clock enable */
00061     __USB_OTG_FS_CLK_ENABLE();
00062   
00063     /**USB_OTG_FS GPIO Configuration    
00064     PA11     ------> USB_OTG_FS_DM
00065     PA12     ------> USB_OTG_FS_DP 
00066     */
00067     GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
00068     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
00069     GPIO_InitStruct.Pull = GPIO_NOPULL;
00070     GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
00071     GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
00072     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
00073 
00074     /* Peripheral interrupt init*/
00075     /* Sets the priority grouping field */
00076     HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);
00077     HAL_NVIC_SetPriority(OTG_FS_IRQn, 0, 0);
00078     HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
00079   }
00080 }
00081 
00082 // from stm32f4xx_it.c
00083 extern "C" {
00084 void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
00085 {
00086     USB_TRACE();
00087     attach_done = true;
00088 }
00089 
00090 void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd)
00091 {
00092     USB_TRACE();
00093 }
00094 
00095 void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state)
00096 {
00097     USB_TRACE1(chnum);
00098     USB_TRACE1(urb_state);
00099     g_urb_state = urb_state;
00100     token_done = true;
00101 }
00102 
00103 } // extern "C"
00104 
00105 const int CH_CTL_IN  = 0;
00106 const int CH_CTL_OUT = 1;
00107 const int CH_INT_IN  = 2;
00108 const int CH_INT_OUT = 3;
00109 const int CH_BLK_IN  = 4;
00110 const int CH_BLK_OUT = 5;
00111 const int CH_ISO_IN  = 6;
00112 const int DIR_IN  = 1;
00113 const int DIR_OUT = 0;
00114 
00115 
00116 
00117 USBHALHost* USBHALHost::instHost;
00118 
00119 USBHALHost::USBHALHost() {
00120     instHost = this;
00121 }
00122 
00123 void USBHALHost::init() {
00124     hhcd_USB_OTG_FS.Instance = USB_OTG_FS;
00125     hhcd_USB_OTG_FS.Init.Host_channels = 8;
00126     hhcd_USB_OTG_FS.Init.speed = HCD_SPEED_FULL;
00127     hhcd_USB_OTG_FS.Init.dma_enable = DISABLE;
00128     hhcd_USB_OTG_FS.Init.phy_itface = HCD_PHY_EMBEDDED;
00129     hhcd_USB_OTG_FS.Init.Sof_enable = DISABLE;
00130     hhcd_USB_OTG_FS.Init.low_power_enable = ENABLE;
00131     hhcd_USB_OTG_FS.Init.vbus_sensing_enable = DISABLE;
00132     hhcd_USB_OTG_FS.Init.use_external_vbus = DISABLE;
00133 
00134     HAL_HCD_Init(&hhcd_USB_OTG_FS);
00135     HAL_HCD_Start(&hhcd_USB_OTG_FS);
00136 
00137     bool lowSpeed = wait_attach();
00138     delay_ms(200);
00139     HAL_HCD_ResetPort(&hhcd_USB_OTG_FS);
00140     delay_ms(100); // Wait for 100 ms after Reset
00141     addDevice(NULL, 0, lowSpeed);
00142 }
00143 
00144 bool USBHALHost::wait_attach() {
00145     Timer t;
00146     t.reset();
00147     t.start();
00148     while(!attach_done) {
00149         if (t.read_ms() > 5*1000) {
00150             t.reset();
00151             USB_INFO("Please attach USB device.");
00152         }
00153     }
00154     wait_ms(100);
00155     return HAL_HCD_GetCurrentSpeed(&hhcd_USB_OTG_FS) == USB_OTG_SPEED_LOW;
00156 }
00157 
00158 int USBHALHost::token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength) {
00159     USBDeviceConnected* dev = ep->getDevice();
00160 
00161     HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_CTL_OUT, 0x00, 
00162         dev->getAddress(),
00163         dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
00164         EP_TYPE_CTRL, ep->getSize());
00165 
00166     setup->wLength = wLength;
00167 
00168     HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_CTL_OUT, DIR_OUT, EP_TYPE_CTRL, 0, (uint8_t*)setup, 8, 0);
00169     while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT) == URB_IDLE);
00170 
00171     switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT)) {
00172         case URB_DONE:
00173             LastStatus = ACK;
00174             break;
00175         default:
00176             LastStatus = 0xff;
00177             break;
00178     }
00179     ep->setData01(DATA1);
00180     return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_CTL_OUT);
00181 }
00182 
00183 HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest2(HCD_HandleTypeDef *hhcd,
00184                                             uint8_t ch_num, 
00185                                             uint8_t direction ,
00186                                             uint8_t ep_type,  
00187                                             uint8_t token, 
00188                                             uint8_t* pbuff, 
00189                                             uint16_t length,
00190                                             uint8_t do_ping) 
00191 {
00192     HCD_HCTypeDef* hc = &(hhcd->hc[ch_num]);
00193     hc->ep_is_in = direction;
00194     hc->ep_type  = ep_type; 
00195 
00196     if (hc->toggle_in == 0) {
00197         hc->data_pid = HC_PID_DATA0;
00198     } else {
00199         hc->data_pid = HC_PID_DATA1;
00200    }
00201 
00202   hc->xfer_buff = pbuff;
00203   hc->xfer_len  = length;
00204   hc->urb_state = URB_IDLE;
00205   hc->xfer_count = 0 ;
00206   hc->ch_num = ch_num;
00207   hc->state = HC_IDLE;
00208 
00209   return USB_HC_StartXfer(hhcd->Instance, hc, hhcd->Init.dma_enable);
00210 }
00211 
00212 int USBHALHost::token_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) {
00213     switch(ep->getType()) {
00214         case CONTROL_ENDPOINT:
00215             return token_ctl_in(ep, data, size, retryLimit);
00216         case INTERRUPT_ENDPOINT:
00217             return token_int_in(ep, data, size);
00218         case BULK_ENDPOINT:
00219             return token_blk_in(ep, data, size, retryLimit);
00220     }
00221     return -1;
00222 }
00223 
00224 int USBHALHost::token_ctl_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) {
00225     USBDeviceConnected* dev = ep->getDevice();
00226     HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_CTL_IN, 0x80, 
00227         dev->getAddress(),
00228         dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
00229         EP_TYPE_CTRL, ep->getSize());
00230     hhcd_USB_OTG_FS.hc[CH_CTL_IN].toggle_in = (ep->getData01() == DATA0) ? 0 : 1;
00231 
00232     HAL_HCD_HC_SubmitRequest2(&hhcd_USB_OTG_FS, CH_CTL_IN, DIR_IN, EP_TYPE_CTRL, 1, data, size, 0);
00233     while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_IN) == URB_IDLE);
00234 
00235     switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_IN)) {
00236         case URB_DONE:
00237             LastStatus = ACK;
00238             break;
00239         default:
00240             LastStatus = 0xff;
00241             return -1;
00242     }
00243     ep->toggleData01();
00244     return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_CTL_IN);
00245 }
00246 
00247 int USBHALHost::token_int_in(USBEndpoint* ep, uint8_t* data, int size) {
00248     USBDeviceConnected* dev = ep->getDevice();
00249     HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_INT_IN,
00250         ep->getAddress(),
00251         dev->getAddress(),
00252         dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
00253         EP_TYPE_INTR, ep->getSize());
00254     hhcd_USB_OTG_FS.hc[CH_INT_IN].toggle_in = (ep->getData01() == DATA0) ? 0 : 1;
00255 
00256     HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_INT_IN, DIR_IN, EP_TYPE_INTR, 1, data, size, 0);
00257     while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_INT_IN) == URB_IDLE);
00258     switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_INT_IN)) {
00259         case URB_DONE:
00260             switch(HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, CH_INT_IN)) {
00261                 case HC_XFRC:
00262                     LastStatus = ep->getData01();
00263                     ep->toggleData01();
00264                     return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_INT_IN);
00265                 case HC_NAK:
00266                     LastStatus = NAK;
00267                     return -1;
00268             }
00269             break;
00270     }
00271     LastStatus = STALL;
00272     return -1;
00273 }
00274 
00275 int USBHALHost::token_blk_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) {
00276     USBDeviceConnected* dev = ep->getDevice();
00277     int retry = 0;
00278     do {
00279         HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_BLK_IN,
00280             ep->getAddress(),
00281             dev->getAddress(),
00282             HCD_SPEED_FULL,
00283             EP_TYPE_BULK, ep->getSize());
00284         hhcd_USB_OTG_FS.hc[CH_BLK_IN].toggle_in = (ep->getData01() == DATA0) ? 0 : 1;
00285 
00286         HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_BLK_IN, DIR_IN, EP_TYPE_BULK, 1, data, size, 0);
00287         while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_IN) == URB_IDLE);
00288 
00289         switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_IN)) {
00290             case URB_DONE:
00291                 switch(HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, CH_BLK_IN)) {
00292                     case HC_XFRC:
00293                         LastStatus = ep->getData01();
00294                         ep->toggleData01();
00295                         return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_BLK_IN);
00296                     case HC_NAK:
00297                         LastStatus = NAK;
00298                         if (retryLimit > 0) {
00299                             delay_ms(1 + 10 * retry);
00300                         }
00301                         break;
00302                     default:
00303                         break;
00304                 }
00305                 break;
00306             case URB_STALL:
00307                 LastStatus = STALL;
00308                 return -1;
00309             default:
00310                 LastStatus = STALL;
00311                 delay_ms(500 + 100 * retry);
00312                 break;
00313         }
00314     }while(retry++ < retryLimit);
00315     return -1;
00316 }
00317 
00318 int USBHALHost::token_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) {
00319     switch(ep->getType()) {
00320         case CONTROL_ENDPOINT:
00321             return token_ctl_out(ep, data, size, retryLimit);
00322         case INTERRUPT_ENDPOINT:
00323             return token_int_out(ep, data, size);
00324         case BULK_ENDPOINT:
00325             return token_blk_out(ep, data, size, retryLimit);
00326     }
00327     return -1;
00328 }
00329 
00330 int USBHALHost::token_ctl_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) {
00331     USBDeviceConnected* dev = ep->getDevice();
00332         HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_CTL_OUT, 0x00, 
00333             dev->getAddress(),
00334             dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
00335             EP_TYPE_CTRL, ep->getSize());
00336             hhcd_USB_OTG_FS.hc[CH_CTL_OUT].toggle_out = (ep->getData01() == DATA0) ? 0 : 1;
00337 
00338     do {
00339         HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_CTL_OUT, DIR_OUT, EP_TYPE_CTRL, 1, (uint8_t*)data, size, 0);
00340         while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT) == URB_IDLE);
00341 
00342         switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT)) {
00343             case URB_DONE:
00344                 LastStatus = ACK;
00345                 ep->toggleData01();
00346                 return size;
00347 
00348             default:
00349                 break;
00350         }
00351         delay_ms(1);
00352     }while(retryLimit-- > 0); 
00353     return -1;
00354 }
00355 
00356 int USBHALHost::token_int_out(USBEndpoint* ep, const uint8_t* data, int size) {
00357     USBDeviceConnected* dev = ep->getDevice();
00358     HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_INT_OUT,
00359         ep->getAddress(),
00360         dev->getAddress(),
00361         dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
00362         EP_TYPE_INTR, ep->getSize());
00363     hhcd_USB_OTG_FS.hc[CH_INT_OUT].toggle_out = (ep->getData01() == DATA0) ? 0 : 1;
00364 
00365     token_done = false;
00366     HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_INT_OUT, DIR_OUT, EP_TYPE_INTR, 1, (uint8_t*)data, size, 0);
00367     while(!token_done);
00368 
00369     if (HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_INT_OUT) != URB_DONE) {
00370         return -1;
00371     }
00372     ep->toggleData01();
00373     return size;
00374 }
00375 
00376 int USBHALHost::token_blk_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) {
00377     USBDeviceConnected* dev = ep->getDevice();
00378     int retry = 0;
00379     do {
00380         HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_BLK_OUT,
00381             ep->getAddress(), dev->getAddress(),
00382             HCD_SPEED_FULL, EP_TYPE_BULK, ep->getSize());
00383         hhcd_USB_OTG_FS.hc[CH_BLK_OUT].toggle_out = (ep->getData01() == DATA0) ? 0 : 1;
00384 
00385         HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_BLK_OUT, DIR_OUT, EP_TYPE_BULK, 1, (uint8_t*)data, size, 0);
00386         while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_OUT) == URB_IDLE);
00387 
00388         switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_OUT)) {
00389             case URB_DONE:
00390                 switch(HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, CH_BLK_OUT)) {
00391                     case HC_XFRC: // ACK
00392                         LastStatus = ep->getData01();
00393                         ep->toggleData01();
00394                         return size;
00395                     default:
00396                         break;
00397                 }
00398                 break;
00399             case URB_NOTREADY: // HC_NAK
00400                 LastStatus = NAK;
00401                 delay_ms(100 * retry);
00402                 break;
00403             default:
00404                 LastStatus = STALL;
00405                 return -1;
00406         }
00407     } while(retry++ < retryLimit);
00408     return -1;
00409 }
00410 
00411 int USBHALHost::token_iso_in(USBEndpoint* ep, uint8_t* data, int size) {
00412     static bool init = false;
00413     if (!init) {
00414         init = true;
00415         USBDeviceConnected* dev = ep->getDevice();
00416         HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_ISO_IN,
00417             ep->getAddress(), dev->getAddress(),
00418             HCD_SPEED_FULL, EP_TYPE_ISOC, ep->getSize());
00419     }
00420     HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_ISO_IN, DIR_IN, EP_TYPE_ISOC, 1, data, size, 0);
00421     while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_ISO_IN) == URB_IDLE);
00422     return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_ISO_IN);
00423 }
00424 
00425 #endif
00426 
00427