Usb read
Dependencies: FATFileSystem
Fork of F401RE-USBHost by
USBHALHost_KL46Z.cpp
00001 // Simple USBHost for FRDM-KL46Z 00002 #if defined(TARGET_KL46Z)||defined(TARGET_KL25Z) 00003 #include "USBHALHost_KL46Z.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 #define USB_DBG(...) do{fprintf(stderr,"[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");} while(0); 00012 #define USB_DBG_HEX(A,B) debug_hex(A,B) 00013 void debug_hex(uint8_t* buf, int size); 00014 #else 00015 #define USB_DBG(...) while(0) 00016 #define USB_DBG_HEX(A,B) while(0) 00017 #endif 00018 00019 #ifdef _USB_TEST 00020 #define USB_TEST_ASSERT(A) while(!(A)){fprintf(stderr,"\n\n%s@%d %s ASSERT!\n\n",__PRETTY_FUNCTION__,__LINE__,#A);exit(1);}; 00021 #define USB_TEST_ASSERT_FALSE(A) USB_TEST_ASSERT(!(A)) 00022 #else 00023 #define USB_TEST_ASSERT(A) while(0) 00024 #define USB_TEST_ASSERT_FALSE(A) while(0) 00025 #endif 00026 00027 #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0); 00028 00029 #define BD_OWN_MASK (1<<7) 00030 #define BD_DATA01_MASK (1<<6) 00031 #define BD_KEEP_MASK (1<<5) 00032 #define BD_NINC_MASK (1<<4) 00033 #define BD_DTS_MASK (1<<3) 00034 #define BD_STALL_MASK (1<<2) 00035 00036 #define TX 1 00037 #define RX 0 00038 00039 #define EP0_BDT_IDX(dir, odd) (((2 * dir) + (1 * odd))) 00040 00041 #define SETUP_TOKEN 0x0D 00042 #define IN_TOKEN 0x09 00043 #define OUT_TOKEN 0x01 00044 00045 // for each endpt: 8 bytes 00046 struct BDT { 00047 uint8_t info; // BD[0:7] 00048 uint8_t dummy; // RSVD: BD[8:15] 00049 uint16_t byte_count; // BD[16:32] 00050 uint32_t address; // Addr 00051 void setBuffer(uint8_t* buf, int size) { 00052 address = (uint32_t)buf; 00053 byte_count = size; 00054 } 00055 uint8_t getStatus() { 00056 return (info>>2)&0x0f; 00057 } 00058 }; 00059 00060 __attribute__((__aligned__(512))) BDT bdt[64]; 00061 00062 USBHALHost* USBHALHost::instHost; 00063 00064 USBHALHost::USBHALHost() { 00065 instHost = this; 00066 report.clear(); 00067 } 00068 00069 void USBHALHost::init() { 00070 // Disable IRQ 00071 NVIC_DisableIRQ(USB0_IRQn); 00072 00073 // choose usb src as PLL 00074 SIM->SOPT2 |= (SIM_SOPT2_USBSRC_MASK | SIM_SOPT2_PLLFLLSEL_MASK); 00075 00076 // enable OTG clock 00077 SIM->SCGC4 |= SIM_SCGC4_USBOTG_MASK; 00078 00079 // USB Module Configuration 00080 // Reset USB Module 00081 USB0->USBTRC0 |= USB_USBTRC0_USBRESET_MASK; 00082 while(USB0->USBTRC0 & USB_USBTRC0_USBRESET_MASK); 00083 00084 // Clear interrupt flag 00085 USB0->ISTAT = 0xff; 00086 00087 // Set BDT Base Register 00088 USB0->BDTPAGE1=(uint8_t)((uint32_t)bdt>>8); 00089 USB0->BDTPAGE2=(uint8_t)((uint32_t)bdt>>16); 00090 USB0->BDTPAGE3=(uint8_t)((uint32_t)bdt>>24); 00091 00092 // Set SOF threshold 00093 USB0->SOFTHLD = USB_SOFTHLD_CNT(1); 00094 00095 // pulldown D+ and D- 00096 USB0->USBCTRL = USB_USBCTRL_PDE_MASK; 00097 00098 USB0->USBTRC0 |= 0x40; 00099 00100 // Host mode 00101 USB0->CTL |= USB_CTL_HOSTMODEEN_MASK; 00102 // Desable SOF packet generation 00103 USB0->CTL &= ~USB_CTL_USBENSOFEN_MASK; 00104 00105 NVIC_SetVector(USB0_IRQn, (uint32_t)_usbisr); 00106 NVIC_EnableIRQ(USB0_IRQn); 00107 00108 bool lowSpeed = wait_attach(); 00109 00110 for(int retry = 2; retry > 0; retry--) { 00111 // Enable RESET 00112 USB0->CTL |= USB_CTL_RESET_MASK; 00113 wait_ms(500); 00114 USB0->CTL &= ~USB_CTL_RESET_MASK; 00115 00116 // Enable SOF 00117 USB0->CTL |= USB_CTL_USBENSOFEN_MASK; 00118 wait_ms(100); 00119 00120 // token transfer initialize 00121 token_transfer_init(); 00122 00123 USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK| 00124 USB_INTEN_ERROREN_MASK; 00125 USB0->ERREN |= USB_ERREN_PIDERREN_MASK| 00126 USB_ERREN_CRC5EOFEN_MASK| 00127 USB_ERREN_CRC16EN_MASK| 00128 USB_ERREN_DFN8EN_MASK| 00129 USB_ERREN_BTOERREN_MASK| 00130 USB_ERREN_DMAERREN_MASK| 00131 USB_ERREN_BTSERREN_MASK; 00132 00133 if (addDevice(NULL, 0, lowSpeed)) { 00134 break; 00135 } 00136 USB_DBG("retry=%d", retry); 00137 USB_TEST_ASSERT(retry > 1); 00138 } 00139 } 00140 00141 bool USBHALHost::wait_attach() { 00142 attach_done = false; 00143 USB0->INTEN = USB_INTEN_ATTACHEN_MASK; 00144 Timer t; 00145 t.reset(); 00146 t.start(); 00147 while(!attach_done) { 00148 if (t.read_ms() > 5*1000) { 00149 t.reset(); 00150 USB_INFO("Please attach USB device."); 00151 } 00152 } 00153 wait_ms(100); 00154 USB_TEST_ASSERT_FALSE(USB0->CTL & USB_CTL_SE0_MASK); 00155 root_lowSpeed = (USB0->CTL & USB_CTL_JSTATE_MASK) ? false : true; 00156 return root_lowSpeed; 00157 } 00158 00159 void USBHALHost::setAddr(int _addr, bool _lowSpeed) { 00160 USB0->ADDR = (_lowSpeed ? USB_ADDR_LSEN_MASK : 0x00) | USB_ADDR_ADDR(_addr); 00161 } 00162 00163 void USBHALHost::setEndpoint() { 00164 USB0->ENDPOINT[0].ENDPT = (root_lowSpeed ? USB_ENDPT_HOSTWOHUB_MASK : 0x00)| 00165 USB_ENDPT_RETRYDIS_MASK| 00166 USB_ENDPT_EPCTLDIS_MASK| 00167 USB_ENDPT_EPRXEN_MASK| 00168 USB_ENDPT_EPTXEN_MASK| 00169 USB_ENDPT_EPHSHK_MASK; 00170 } 00171 00172 void USBHALHost::token_transfer_init() { 00173 tx_ptr = ODD; 00174 rx_ptr = ODD; 00175 } 00176 00177 int USBHALHost::token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength) { 00178 USBDeviceConnected* dev = ep->getDevice(); 00179 for(int retry = 0;; retry++) { 00180 token_ready(); 00181 USB0->ENDPOINT[0].ENDPT = (root_lowSpeed ? USB_ENDPT_HOSTWOHUB_MASK : 0x00) | 00182 USB_ENDPT_RETRYDIS_MASK| 00183 USB_ENDPT_EPRXEN_MASK| 00184 USB_ENDPT_EPTXEN_MASK| 00185 USB_ENDPT_EPHSHK_MASK; 00186 CTASSERT(sizeof(SETUP_PACKET) == 8); 00187 setup->wLength = wLength; 00188 int idx = EP0_BDT_IDX(TX, tx_ptr); 00189 bdt[idx].setBuffer((uint8_t*)setup, sizeof(SETUP_PACKET)); 00190 bdt[idx].info = BD_OWN_MASK | 00191 BD_DTS_MASK; // always data0 00192 token_done = false; 00193 USB0->TOKEN = USB_TOKEN_TOKENPID(SETUP_TOKEN)| 00194 USB_TOKEN_TOKENENDPT(ep->getAddress() & 0x7f); 00195 while(!token_done); 00196 LastStatus = bdt[idx].getStatus(); 00197 if (LastStatus == ACK) { 00198 if (retry > 0) { 00199 USB_DBG("retry=%d %02x", retry, prev_LastStatus); 00200 } 00201 break; 00202 } else if (LastStatus == STALL) { 00203 report.stall++; 00204 return STALL; 00205 } 00206 if (retry > 10) { 00207 USB_DBG("retry=%d", retry); 00208 break; 00209 } 00210 prev_LastStatus = LastStatus; 00211 wait_ms(100 * retry); 00212 } 00213 ep->setData01(DATA1); // next toggle 00214 return LastStatus; 00215 } 00216 00217 int USBHALHost::token_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { 00218 for(int retry = 0;; retry++) { 00219 token_ready(); 00220 int idx = EP0_BDT_IDX(RX, rx_ptr); 00221 bdt[idx].setBuffer(data, size); 00222 bdt[idx].info = BD_OWN_MASK| 00223 BD_DTS_MASK| 00224 (ep->getData01() == DATA1 ? BD_DATA01_MASK : 0); 00225 token_done = false; 00226 USB0->TOKEN = USB_TOKEN_TOKENPID(IN_TOKEN)| 00227 USB_TOKEN_TOKENENDPT(ep->getAddress()&0x7f); 00228 while(!token_done); 00229 LastStatus = bdt[idx].getStatus(); 00230 int len = bdt[idx].byte_count; 00231 if (LastStatus == DATA0 || LastStatus == DATA1) { 00232 USB_TEST_ASSERT(ep->getData01() == LastStatus); 00233 ep->setData01(LastStatus == DATA0 ? DATA1 : DATA0); 00234 if (retry > 0) { 00235 //USB_DBG("len=%d retry=%d %02x", len, retry, prev_LastStatus); 00236 } 00237 return len; 00238 } else if (LastStatus == STALL) { 00239 report.stall++; 00240 return -1; 00241 } else if (LastStatus == NAK) { 00242 report.nak++; 00243 if (retry >= retryLimit) { 00244 if (retryLimit > 0) { 00245 USB_DBG("retry=%d retryLimit=%d", retry, retryLimit); 00246 } 00247 return -1; 00248 } 00249 wait_ms(100 * retry); 00250 } else if (LastStatus == Bus_Timeout) { 00251 if (retry >= retryLimit) { 00252 if (retryLimit > 0) { 00253 USB_DBG("Bus_Timeout retry=%d retryLimit=%d", retry, retryLimit); 00254 } 00255 return -1; 00256 } 00257 wait_ms(500 + 100 * retry); 00258 } else { 00259 return -1; 00260 } 00261 prev_LastStatus = LastStatus; 00262 } 00263 } 00264 00265 int USBHALHost::token_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) { 00266 for(int retry = 0;; retry++) { 00267 token_ready(); 00268 int idx = EP0_BDT_IDX(TX, tx_ptr); 00269 bdt[idx].setBuffer((uint8_t*)data, size); 00270 bdt[idx].info = BD_OWN_MASK| 00271 BD_DTS_MASK| 00272 (ep->getData01() == DATA1 ? BD_DATA01_MASK : 0); 00273 token_done = false; 00274 USB0->TOKEN = USB_TOKEN_TOKENPID(OUT_TOKEN)| 00275 USB_TOKEN_TOKENENDPT(ep->getAddress()&0x7f); 00276 while(!token_done); 00277 LastStatus = bdt[idx].getStatus(); 00278 int len = bdt[idx].byte_count; 00279 //USB_DBG("len=%d %02x", len, LastStatus); 00280 if (LastStatus == ACK) { 00281 ep->toggleData01(); 00282 if (retry > 0) { 00283 USB_DBG("len=%d retry=%d %02x", len, retry, prev_LastStatus); 00284 } 00285 return len; 00286 } else if (LastStatus == STALL) { 00287 report.stall++; 00288 return -1; 00289 } else if (LastStatus == NAK) { 00290 report.nak++; 00291 if (retry > retryLimit) { 00292 USB_DBG("retry=%d retryLimit=%d", retry, retryLimit); 00293 return -1; 00294 } 00295 wait_ms(100 * retry); 00296 } else { 00297 return -1; 00298 } 00299 prev_LastStatus = LastStatus; 00300 } 00301 } 00302 00303 int USBHALHost::token_iso_in(USBEndpoint* ep, uint8_t* data, int size) { 00304 while(USB0->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK); // TOKEN_BUSY ? 00305 USB0->ISTAT |= USB_ISTAT_SOFTOK_MASK; // Clear SOF 00306 while (!(USB0->ISTAT & USB_ISTAT_SOFTOK_MASK)); 00307 USB0->SOFTHLD = 0; // this is needed as without this you can get errors 00308 USB0->ISTAT |= USB_ISTAT_SOFTOK_MASK; // clear SOF 00309 00310 USB0->ENDPOINT[0].ENDPT = USB_ENDPT_EPCTLDIS_MASK| 00311 USB_ENDPT_RETRYDIS_MASK| 00312 USB_ENDPT_EPRXEN_MASK| 00313 USB_ENDPT_EPTXEN_MASK; 00314 int idx = EP0_BDT_IDX(RX, rx_ptr); 00315 bdt[idx].setBuffer(data, size); 00316 bdt[idx].info = BD_OWN_MASK| 00317 BD_DTS_MASK; // always DATA0 00318 token_done = false; 00319 USB0->TOKEN = USB_TOKEN_TOKENPID(IN_TOKEN)| 00320 USB_TOKEN_TOKENENDPT(ep->getAddress()&0x7f); 00321 while(!token_done); 00322 LastStatus = bdt[idx].getStatus(); 00323 int len = bdt[idx].byte_count; 00324 if (LastStatus == DATA0) { 00325 return len; 00326 } 00327 return -1; 00328 } 00329 00330 void USBHALHost::token_ready() { 00331 while(USB0->CTL & USB_CTL_TXSUSPENDTOKENBUSY_MASK) { // TOKEN_BUSY ? 00332 wait_ms(1); 00333 } 00334 USB0->ISTAT |= USB_ISTAT_SOFTOK_MASK; // Clear SOF 00335 while (!(USB0->ISTAT & USB_ISTAT_SOFTOK_MASK)); 00336 USB0->SOFTHLD = 0; // this is needed as without this you can get errors 00337 USB0->ISTAT |= USB_ISTAT_SOFTOK_MASK; // clear SOF 00338 } 00339 00340 void USBHALHost::_usbisr(void) { 00341 if (instHost) { 00342 instHost->UsbIrqhandler(); 00343 } 00344 } 00345 00346 void USBHALHost::UsbIrqhandler() { 00347 if (USB0->ISTAT & USB_ISTAT_TOKDNE_MASK) { 00348 uint8_t stat = USB0->STAT; 00349 ODD_EVEN next_ptr = (stat & USB_STAT_ODD_MASK) ? ODD : EVEN; 00350 if (stat & USB_STAT_TX_MASK) { 00351 tx_ptr = next_ptr; 00352 } else { 00353 rx_ptr = next_ptr; 00354 } 00355 USB0->ISTAT = USB_ISTAT_TOKDNE_MASK; 00356 token_done = true; 00357 } 00358 if (USB0->ISTAT & USB_ISTAT_ATTACH_MASK) { 00359 USB0->INTEN &= ~USB_INTEN_ATTACHEN_MASK; 00360 USB0->ISTAT = USB_ISTAT_ATTACH_MASK; 00361 attach_done = true; 00362 } 00363 if (USB0->ISTAT & USB_ISTAT_ERROR_MASK) { 00364 uint8_t errstat = USB0->ERRSTAT; 00365 if (errstat & USB_ERRSTAT_PIDERR_MASK) { 00366 report.errstat_piderr++; 00367 } 00368 if (errstat & USB_ERRSTAT_CRC5EOF_MASK) { 00369 report.errstat_crc5eof++; 00370 } 00371 if (errstat & USB_ERRSTAT_CRC16_MASK) { 00372 report.errstat_crc16++; 00373 } 00374 if (errstat & USB_ERRSTAT_DFN8_MASK) { 00375 report.errstat_dfn8++; 00376 } 00377 if (errstat & USB_ERRSTAT_BTOERR_MASK) { 00378 report.errstat_btoerr++; 00379 } 00380 if (errstat & USB_ERRSTAT_DMAERR_MASK) { 00381 report.errstat_dmaerr++; 00382 } 00383 if (errstat & USB_ERRSTAT_BTSERR_MASK) { 00384 report.errstat_btoerr++; 00385 } 00386 USB0->ERRSTAT = errstat; 00387 USB0->ISTAT = USB_ISTAT_ERROR_MASK; 00388 } 00389 } 00390 00391 void Report::clear() { 00392 errstat_piderr = 0; 00393 errstat_crc5eof = 0; 00394 errstat_crc16 = 0; 00395 errstat_dfn8 = 0; 00396 errstat_btoerr = 0; 00397 errstat_dmaerr = 0; 00398 errstat_bsterr = 0; 00399 // 00400 nak = 0; 00401 } 00402 00403 void Report::print_errstat() { 00404 printf("ERRSTAT PID: %d, CRC5EOF: %d, CRC16: %d, DFN8: %d, BTO: %d, DMA: %d, BST: %d\n", 00405 errstat_piderr, errstat_crc5eof, 00406 errstat_crc16, errstat_dfn8, 00407 errstat_btoerr, errstat_dmaerr, errstat_bsterr); 00408 } 00409 00410 void debug_hex(uint8_t* buf, int size) { 00411 int n = 0; 00412 for(int i = 0; i < size; i++) { 00413 fprintf(stderr, "%02x ", buf[i]); 00414 if (++n >= 16) { 00415 fprintf(stderr, "\n"); 00416 n = 0; 00417 } 00418 } 00419 if (n > 0) { 00420 fprintf(stderr, "\n"); 00421 } 00422 } 00423 00424 #endif 00425 00426
Generated on Tue Jul 12 2022 19:09:12 by 1.7.2