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.
Dependents: F401RE-USBHostMIDI_RecieveExample
Fork of F401RE-USBHost by
Diff: USBHost/USBHALHost_F401RE.cpp
- Revision:
- 16:981c3104f6c0
- Parent:
- 14:b167f2b97cb7
- Child:
- 19: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
