Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of F401RE-USBHost by
Diff: USBHost/USBHALHost_F401RE.cpp
- Revision:
- 16:981c3104f6c0
- Parent:
- 14:b167f2b97cb7
- Child:
- 18:61554f238584
--- a/USBHost/USBHALHost_F401RE.cpp Fri Jun 13 01:52:44 2014 +0000 +++ b/USBHost/USBHALHost_F401RE.cpp Mon Jun 23 20:30:04 2014 +0900 @@ -1,6 +1,7 @@ // Simple USBHost for Nucleo F401RE #if defined(TARGET_NUCLEO_F401RE) #include "USBHALHost_F401RE.h" +#include <algorithm> template <bool>struct CtAssert; template <>struct CtAssert<true> {}; @@ -9,6 +10,7 @@ #ifdef _USB_DBG extern RawSerial pc; +//RawSerial pc(USBTX,USBRX); #include "mydebug.h" #define USB_DBG(...) do{pc.printf("[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);pc.printf(__VA_ARGS__);pc.puts("\n");} while(0); #define USB_DBG_HEX(A,B) debug_hex<RawSerial>(pc,A,B) @@ -41,15 +43,13 @@ #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0); __IO bool attach_done = false; -__IO bool token_done = false; -__IO HCD_URBStateTypeDef g_urb_state = URB_IDLE; void delay_ms(uint32_t t) { HAL_Delay(t); } -// from usbh_conf.c +// usbh_conf.c extern HCD_HandleTypeDef hhcd_USB_OTG_FS; void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd) @@ -79,7 +79,7 @@ } } -// from stm32f4xx_it.c +// stm32f4xx_it.c extern "C" { void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd) { @@ -87,33 +87,8 @@ attach_done = true; } -void HAL_HCD_Disconnect_Callback(HCD_HandleTypeDef *hhcd) -{ - USB_TRACE(); -} - -void HAL_HCD_HC_NotifyURBChange_Callback(HCD_HandleTypeDef *hhcd, uint8_t chnum, HCD_URBStateTypeDef urb_state) -{ - USB_TRACE1(chnum); - USB_TRACE1(urb_state); - g_urb_state = urb_state; - token_done = true; -} - } // extern "C" -const int CH_CTL_IN = 0; -const int CH_CTL_OUT = 1; -const int CH_INT_IN = 2; -const int CH_INT_OUT = 3; -const int CH_BLK_IN = 4; -const int CH_BLK_OUT = 5; -const int CH_ISO_IN = 6; -const int DIR_IN = 1; -const int DIR_OUT = 0; - - - USBHALHost* USBHALHost::instHost; USBHALHost::USBHALHost() { @@ -156,19 +131,19 @@ } int USBHALHost::token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength) { + const uint8_t ep_addr = 0x00; + HC hc; USBDeviceConnected* dev = ep->getDevice(); - - HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_CTL_OUT, 0x00, + hc.Init(ep_addr, dev->getAddress(), dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, EP_TYPE_CTRL, ep->getSize()); setup->wLength = wLength; + hc.SubmitRequest((uint8_t*)setup, 8, true); // PID_SETUP + while(hc.GetURBState() == URB_IDLE); - HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_CTL_OUT, DIR_OUT, EP_TYPE_CTRL, 0, (uint8_t*)setup, 8, 0); - while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT) == URB_IDLE); - - switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT)) { + switch(hc.GetURBState()) { case URB_DONE: LastStatus = ACK; break; @@ -177,36 +152,7 @@ break; } ep->setData01(DATA1); - return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_CTL_OUT); -} - -HAL_StatusTypeDef HAL_HCD_HC_SubmitRequest2(HCD_HandleTypeDef *hhcd, - uint8_t ch_num, - uint8_t direction , - uint8_t ep_type, - uint8_t token, - uint8_t* pbuff, - uint16_t length, - uint8_t do_ping) -{ - HCD_HCTypeDef* hc = &(hhcd->hc[ch_num]); - hc->ep_is_in = direction; - hc->ep_type = ep_type; - - if (hc->toggle_in == 0) { - hc->data_pid = HC_PID_DATA0; - } else { - hc->data_pid = HC_PID_DATA1; - } - - hc->xfer_buff = pbuff; - hc->xfer_len = length; - hc->urb_state = URB_IDLE; - hc->xfer_count = 0 ; - hc->ch_num = ch_num; - hc->state = HC_IDLE; - - return USB_HC_StartXfer(hhcd->Instance, hc, hhcd->Init.dma_enable); + return 8; } int USBHALHost::token_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { @@ -222,17 +168,20 @@ } int USBHALHost::token_ctl_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { + const uint8_t ep_addr = 0x80; + HC hc; USBDeviceConnected* dev = ep->getDevice(); - HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_CTL_IN, 0x80, + hc.Init(ep_addr, dev->getAddress(), dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, EP_TYPE_CTRL, ep->getSize()); - hhcd_USB_OTG_FS.hc[CH_CTL_IN].toggle_in = (ep->getData01() == DATA0) ? 0 : 1; + + hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1); - HAL_HCD_HC_SubmitRequest2(&hhcd_USB_OTG_FS, CH_CTL_IN, DIR_IN, EP_TYPE_CTRL, 1, data, size, 0); - while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_IN) == URB_IDLE); + hc.SubmitRequest(data, size); + while(hc.GetURBState() == URB_IDLE); - switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_IN)) { + switch(hc.GetURBState()) { case URB_DONE: LastStatus = ACK; break; @@ -241,27 +190,29 @@ return -1; } ep->toggleData01(); - return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_CTL_IN); + return hc.GetXferCount(); } int USBHALHost::token_int_in(USBEndpoint* ep, uint8_t* data, int size) { + HC hc; USBDeviceConnected* dev = ep->getDevice(); - HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_INT_IN, + hc.Init( ep->getAddress(), dev->getAddress(), dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, EP_TYPE_INTR, ep->getSize()); - hhcd_USB_OTG_FS.hc[CH_INT_IN].toggle_in = (ep->getData01() == DATA0) ? 0 : 1; + + hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1); - HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_INT_IN, DIR_IN, EP_TYPE_INTR, 1, data, size, 0); - while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_INT_IN) == URB_IDLE); - switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_INT_IN)) { + hc.SubmitRequest(data, size); + while(hc.GetURBState() == URB_IDLE); + switch(hc.GetURBState()) { case URB_DONE: - switch(HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, CH_INT_IN)) { + switch(hc.GetState()) { case HC_XFRC: LastStatus = ep->getData01(); ep->toggleData01(); - return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_INT_IN); + return hc.GetXferCount(); case HC_NAK: LastStatus = NAK; return -1; @@ -273,26 +224,28 @@ } int USBHALHost::token_blk_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit) { + HC hc; USBDeviceConnected* dev = ep->getDevice(); + hc.Init( + ep->getAddress(), + dev->getAddress(), + HCD_SPEED_FULL, + EP_TYPE_BULK, ep->getSize()); + + hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1); + int retry = 0; do { - HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_BLK_IN, - ep->getAddress(), - dev->getAddress(), - HCD_SPEED_FULL, - EP_TYPE_BULK, ep->getSize()); - hhcd_USB_OTG_FS.hc[CH_BLK_IN].toggle_in = (ep->getData01() == DATA0) ? 0 : 1; + hc.SubmitRequest(data, size); + while(hc.GetURBState() == URB_IDLE); - HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_BLK_IN, DIR_IN, EP_TYPE_BULK, 1, data, size, 0); - while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_IN) == URB_IDLE); - - switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_IN)) { + switch(hc.GetURBState()) { case URB_DONE: - switch(HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, CH_BLK_IN)) { + switch(hc.GetState()) { case HC_XFRC: LastStatus = ep->getData01(); ep->toggleData01(); - return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_BLK_IN); + return hc.GetXferCount(); case HC_NAK: LastStatus = NAK; if (retryLimit > 0) { @@ -328,18 +281,21 @@ } int USBHALHost::token_ctl_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) { + const uint8_t ep_addr = 0x00; + HC hc; USBDeviceConnected* dev = ep->getDevice(); - HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_CTL_OUT, 0x00, - dev->getAddress(), - dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, - EP_TYPE_CTRL, ep->getSize()); - hhcd_USB_OTG_FS.hc[CH_CTL_OUT].toggle_out = (ep->getData01() == DATA0) ? 0 : 1; + hc.Init(ep_addr, + dev->getAddress(), + dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, + EP_TYPE_CTRL, ep->getSize()); + + hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1); do { - HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_CTL_OUT, DIR_OUT, EP_TYPE_CTRL, 1, (uint8_t*)data, size, 0); - while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT) == URB_IDLE); + hc.SubmitRequest((uint8_t*)data, size); + while(hc.GetURBState() == URB_IDLE); - switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_CTL_OUT)) { + switch(hc.GetURBState()) { case URB_DONE: LastStatus = ACK; ep->toggleData01(); @@ -354,19 +310,19 @@ } int USBHALHost::token_int_out(USBEndpoint* ep, const uint8_t* data, int size) { + HC hc; USBDeviceConnected* dev = ep->getDevice(); - HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_INT_OUT, + hc.Init( ep->getAddress(), dev->getAddress(), dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL, EP_TYPE_INTR, ep->getSize()); - hhcd_USB_OTG_FS.hc[CH_INT_OUT].toggle_out = (ep->getData01() == DATA0) ? 0 : 1; + + hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1); - token_done = false; - HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_INT_OUT, DIR_OUT, EP_TYPE_INTR, 1, (uint8_t*)data, size, 0); - while(!token_done); - - if (HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_INT_OUT) != URB_DONE) { + hc.SubmitRequest((uint8_t*)data, size); + while(hc.GetURBState() == URB_IDLE); + if (hc.GetURBState() != URB_DONE) { return -1; } ep->toggleData01(); @@ -374,20 +330,22 @@ } int USBHALHost::token_blk_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit) { + HC hc; USBDeviceConnected* dev = ep->getDevice(); + hc.Init( + ep->getAddress(), dev->getAddress(), + HCD_SPEED_FULL, EP_TYPE_BULK, ep->getSize()); + + hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1); + int retry = 0; do { - HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_BLK_OUT, - ep->getAddress(), dev->getAddress(), - HCD_SPEED_FULL, EP_TYPE_BULK, ep->getSize()); - hhcd_USB_OTG_FS.hc[CH_BLK_OUT].toggle_out = (ep->getData01() == DATA0) ? 0 : 1; + hc.SubmitRequest((uint8_t*)data, size); + while(hc.GetURBState() == URB_IDLE); - HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_BLK_OUT, DIR_OUT, EP_TYPE_BULK, 1, (uint8_t*)data, size, 0); - while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_OUT) == URB_IDLE); - - switch(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_BLK_OUT)) { + switch(hc.GetURBState()) { case URB_DONE: - switch(HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, CH_BLK_OUT)) { + switch(hc.GetState()) { case HC_XFRC: // ACK LastStatus = ep->getData01(); ep->toggleData01(); @@ -409,17 +367,158 @@ } int USBHALHost::token_iso_in(USBEndpoint* ep, uint8_t* data, int size) { - static bool init = false; - if (!init) { - init = true; + HC* hc = ep->getHALData<HC*>(); + if (hc == NULL) { + hc = new HC; + ep->setHALData<HC*>(hc); USBDeviceConnected* dev = ep->getDevice(); - HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, CH_ISO_IN, + hc->Init( ep->getAddress(), dev->getAddress(), HCD_SPEED_FULL, EP_TYPE_ISOC, ep->getSize()); } - HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, CH_ISO_IN, DIR_IN, EP_TYPE_ISOC, 1, data, size, 0); - while(HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, CH_ISO_IN) == URB_IDLE); - return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, CH_ISO_IN); + hc->SubmitRequest(data, size); + while(hc->GetURBState() == URB_IDLE); + return hc->GetXferCount(); +} + +int USBHALHost::multi_token_in(USBEndpoint* ep, uint8_t* data, size_t total, bool block) { + if (total == 0) { + return token_in(ep); + } + int retryLimit = block ? 10 : 0; + int read_len = 0; + for(int n = 0; read_len < total; n++) { + int size = std::min((int)total-read_len, ep->getSize()); + int result = token_in(ep, data+read_len, size, retryLimit); + if (result < 0) { + if (block) { + return -1; + } + if (LastStatus == NAK) { + if (n == 0) { + return -1; + } + break; + } + return result; + } + read_len += result; + if (result < ep->getSize()) { + break; + } + } + return read_len; +} + +int USBHALHost::multi_token_out(USBEndpoint* ep, const uint8_t* data, size_t total, bool block) { + if (total == 0) { + return token_out(ep); + } + int write_len = 0; + for(int n = 0; write_len < total; n++) { + int size = std::min((int)total-write_len, ep->getSize()); + int result = token_out(ep, data+write_len, size); + if (result < 0) { + if (LastStatus == NAK) { + if (n == 0) { + return -1; + } + break; + } + USB_DBG("token_out result=%d %02x", result, LastStatus); + return result; + } + write_len += result; + if (result < ep->getSize()) { + break; + } + } + return write_len; +} + +uint8_t HC::slot = 0x00; + +HC::HC() { + uint8_t mask = 0x01; + for(int i = 1; i < 8; i++, mask <<= 1) { + if (!(slot & mask)) { + slot |= mask; + _ch = i; + return; + } + } + _ch = 0; // ERROR!!! +} + +HC::HC(int ch) { + _ch = ch; + slot |= (1<<_ch); +} + +HC::~HC() { + slot &= ~(1<<_ch); +} + +HAL_StatusTypeDef HC::Init(uint8_t epnum, uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps) { + _ep_addr = epnum; + _ep_type = ep_type; + return HAL_HCD_HC_Init(&hhcd_USB_OTG_FS, _ch, + epnum, dev_address, speed, ep_type, mps); +} + +HAL_StatusTypeDef HC::SubmitRequest(uint8_t* pbuff, uint16_t length, bool setup) { + uint8_t direction = (_ep_addr & 0x80) ? DIR_IN : DIR_OUT; + if (_ep_type == EP_TYPE_CTRL) { + HCD_HCTypeDef* hc = &hhcd_USB_OTG_FS.hc[_ch]; + if (setup) { + hc->data_pid = HC_PID_SETUP; + hc->toggle_out = 0; + } else { + if (direction == DIR_IN) { + if (hc->toggle_in == 0) { + hc->data_pid = HC_PID_DATA0; + } else { + hc->data_pid = HC_PID_DATA1; + } + } else { // OUT + if (hc->toggle_out == 0) { + hc->data_pid = HC_PID_DATA0; + } else { + hc->data_pid = HC_PID_DATA1; + } + } + } + hc->xfer_buff = pbuff; + hc->xfer_len = length; + hc->urb_state = URB_IDLE; + hc->xfer_count = 0; + hc->ch_num = _ch; + hc->state = HC_IDLE; + + return USB_HC_StartXfer(hhcd_USB_OTG_FS.Instance, hc, 0); + } + return HAL_HCD_HC_SubmitRequest(&hhcd_USB_OTG_FS, _ch, + direction, _ep_type, 0, pbuff, length, 0); +} + +HCD_URBStateTypeDef HC::GetURBState() { + return HAL_HCD_HC_GetURBState(&hhcd_USB_OTG_FS, _ch); +} + +HCD_HCStateTypeDef HC::GetState() { + return HAL_HCD_HC_GetState(&hhcd_USB_OTG_FS, _ch); +} + +uint32_t HC::GetXferCount() { + return HAL_HCD_HC_GetXferCount(&hhcd_USB_OTG_FS, _ch); +} + +void HC::SetToggle(uint8_t toggle) { + if (_ep_addr & 0x80) { // IN + hhcd_USB_OTG_FS.hc[_ch].toggle_in = toggle; + } else { // OUT + hhcd_USB_OTG_FS.hc[_ch].toggle_out = toggle; + } } #endif