Skip to content

Commit 6ff51cb

Browse files
committed
Fix USB host split transactions
1 parent e4b04bf commit 6ff51cb

File tree

6 files changed

+95
-1
lines changed

6 files changed

+95
-1
lines changed

libraries/USBHOST/examples/Shell/Shell.ino

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3232
SOFTWARE.
3333
*/
34+
35+
#include "USBHOST.h"
36+
3437
extern "C" {
3538
#include "teeny_usb.h"
3639
#include "class/host/tusbh.h"
@@ -44,6 +47,8 @@ extern "C" {
4447
#include "class/host/usb_key_code.h"
4548
}
4649

50+
#include "mbed.h"
51+
4752
#define TEENYUSB_LOGO \
4853
" _______ _ _ _____ ____ \n" \
4954
"|__ __| | | | |/ ____| _ \\ \n" \

libraries/USBHOST/src/board_config.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
//#define OTG_FS_EMBEDDED_PHY
4646

4747
/* Enable DMA for High speed phy */
48-
//#define OTG_HS_ENABLE_DMA
48+
#define OTG_HS_ENABLE_DMA
4949

5050
/* Support for other speed config and device qualifier descriptor */
5151
#define SUPPORT_OTHER_SPEED
@@ -98,6 +98,9 @@ do {} while(0U)
9898
#define HOST_PORT_POWER_ON_FS() \
9999
do{}while(0)
100100

101+
//#define RTOS_INTERRUPT_ENTER core_util_critical_section_enter
102+
//#define RTOS_INTERRUPT_LEAVE core_util_critical_section_exit
103+
101104
// init the stdio hardware
102105
void stdio_init(void);
103106
// stdin recv char handler

libraries/USBHOST/src/class/host/tusbh.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ const char* channelState(channel_state_t state)
9595
SSS( TUSB_CS_XFER_ONGOING )
9696
SSS( TUSB_CS_XFER_CANCEL )
9797
SSS( TUSB_CS_UNKNOWN_ERROR )
98+
SSS( TUSB_CS_TRANSFER_CSPLIT )
9899
}
99100
return "Unknown Channel State";
100101
#undef SSS
@@ -151,6 +152,44 @@ void tusbh_close_pipe(tusbh_device_t* dev, int pipe_num)
151152
tusb_pipe_close(&pipe);
152153
}
153154

155+
#if 1
156+
static channel_state_t tusbh_pipe_xfer_and_wait(tusbh_device_t* dev, int pipe_num, uint8_t is_data, void* data, uint16_t len, uint32_t timeout)
157+
{
158+
void* bak = dev->host->hc[pipe_num].user_data;
159+
dev->host->hc[pipe_num].user_data = &dev->xfer_evt;
160+
161+
channel_state_t r = TUSB_CS_UNKNOWN_ERROR;
162+
163+
uint16_t remain = len;
164+
uint8_t* p = (uint8_t*)data;
165+
int res = 0;
166+
167+
dev->host->hc[pipe_num].toggle_in = 1;
168+
channel_state_t s;
169+
170+
do{
171+
tusb_host_xfer_data(dev->host, pipe_num, is_data, p, remain);
172+
tusbh_evt_wait(dev->xfer_evt.event, timeout);
173+
tusb_hc_data_t* hc = &dev->host->hc[pipe_num];
174+
s = (channel_state_t)hc->state;
175+
if (s != TUSB_CS_TRANSFER_CSPLIT) {
176+
if(s != TUSB_CS_TRANSFER_COMPLETE){
177+
res = -(int)s;
178+
goto error;
179+
}
180+
remain -= hc->count;
181+
p += hc->count;
182+
}
183+
}while((remain && len) || (s == TUSB_CS_TRANSFER_CSPLIT));
184+
res = p - ((uint8_t*)data);
185+
error:
186+
dev->host->hc[pipe_num].user_data = bak;
187+
r = (channel_state_t)dev->host->hc[pipe_num].state;
188+
return r;
189+
}
190+
191+
#else
192+
154193
static channel_state_t tusbh_pipe_xfer_and_wait(tusbh_device_t* dev, int pipe_num, uint8_t is_data, void* data, uint16_t len, uint32_t timeout)
155194
{
156195
void* bak = dev->host->hc[pipe_num].user_data;
@@ -170,6 +209,7 @@ static channel_state_t tusbh_pipe_xfer_and_wait(tusbh_device_t* dev, int pipe_nu
170209

171210
return r;
172211
}
212+
#endif
173213

174214
int tusbh_ep_xfer(tusbh_ep_info_t* ep, void* data, uint16_t len, uint32_t timeout)
175215
{

libraries/USBHOST/src/stm32_otg_init.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,8 @@ static void tusb_otg_core_init(tusb_core_t* core)
428428
// only HS core has DMA feature
429429
USBx->GAHBCFG |= USB_OTG_GAHBCFG_HBSTLEN_2;
430430
USBx->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
431+
SCB_CleanInvalidateDCache();
432+
SCB_DisableDCache();
431433
}
432434
#endif
433435
}

libraries/USBHOST/src/teeny_usb.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ typedef enum {
285285
TUSB_CS_XFER_ONGOING, /**< Channel data transfer is on going */
286286
TUSB_CS_XFER_CANCEL, /**< Channel data transfer is canceled */
287287
TUSB_CS_UNKNOWN_ERROR, /**< Channel Unknown error */
288+
TUSB_CS_TRANSFER_CSPLIT, /**< Request complete split */
288289
}channel_state_t;
289290

290291
/** Enums for ID line state

libraries/USBHOST/src/teeny_usb_stm32_otg_host.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,15 @@ static void tusb_otg_in_channel_handler(tusb_host_t* host, uint8_t ch_num)
446446
}
447447
}
448448
}
449+
else if (HC->HCSPLT & USB_OTG_HCSPLT_SPLITEN)
450+
{
451+
if (!(HC->HCSPLT & USB_OTG_HCSPLT_COMPLSPLT)) {
452+
HC->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
453+
454+
hc->state = TUSB_CS_TRANSFER_CSPLIT;
455+
hc->xfer_done = 1;
456+
}
457+
}
449458
else
450459
{
451460
/* ... */
@@ -675,6 +684,14 @@ static void tusb_otg_out_channel_handler(tusb_host_t* host, uint8_t ch_num)
675684
{
676685
hc->xfer_done = 1;
677686
}
687+
else if (HC->HCSPLT & USB_OTG_HCSPLT_SPLITEN)
688+
{
689+
if (!(HC->HCSPLT & USB_OTG_HCSPLT_COMPLSPLT)) {
690+
HC->HCSPLT |= USB_OTG_HCSPLT_COMPLSPLT;
691+
hc->state = TUSB_CS_TRANSFER_CSPLIT;
692+
hc->xfer_done = 1;
693+
}
694+
}
678695
else
679696
{
680697
/* ... */
@@ -990,6 +1007,11 @@ uint32_t tusb_otg_host_submit(tusb_host_t* host, uint8_t hc_num)
9901007
hc->toggle_out = 1;
9911008
data_pid = HC_PID_DATA1;
9921009
}
1010+
} else {
1011+
if (is_in && is_dma && (len>=mps)){
1012+
// control in
1013+
data_pid = hc->toggle_in ? HC_PID_DATA1 : HC_PID_DATA0;
1014+
}
9931015
}
9941016
}else{
9951017
// otherwise setup packet
@@ -1056,6 +1078,11 @@ uint32_t tusb_otg_host_xfer_data(tusb_host_t* host, uint8_t hc_num, uint8_t is_d
10561078
hc->ch_buf = data;
10571079
hc->size = len;
10581080
hc->count = 0;
1081+
1082+
if (hc->state != TUSB_CS_TRANSFER_CSPLIT) {
1083+
HC->HCSPLT = 0;
1084+
}
1085+
10591086
hc->state = TUSB_CS_INIT;
10601087
hc->do_ping = 0;
10611088
hc->is_data = is_data;
@@ -1076,6 +1103,22 @@ uint32_t tusb_otg_host_xfer_data(tusb_host_t* host, uint8_t hc_num, uint8_t is_d
10761103
}
10771104
#endif
10781105
}
1106+
1107+
if (hc->speed != PORT_SPEED_HIGH) {
1108+
// SPLIT enable
1109+
uint32_t tmpreg = USB_OTG_HCSPLT_SPLITEN;
1110+
tmpreg |= USB_OTG_HCSPLT_XACTPOS_0;
1111+
tmpreg |= USB_OTG_HCSPLT_XACTPOS_1;
1112+
/* Hub device address */
1113+
tmpreg |= USB_OTG_HCSPLT_HUBADDR_0;
1114+
/* Port number */
1115+
//tmpreg |= USB_OTG_HCSPLT_PRTADDR_0; // port1 -> USB_OTG_HCSPLT_PRTADDR_0
1116+
tmpreg |= USB_OTG_HCSPLT_PRTADDR_1; // port2 -> USB_OTG_HCSPLT_PRTADDR_1
1117+
//tmpreg |= USB_OTG_HCSPLT_PRTADDR_2; // port4 -> USB_OTG_HCSPLT_PRTADDR_2
1118+
HC->HCSPLT |= tmpreg;
1119+
__HAL_HCD_UNMASK_HALT_HC_INT(hc_num);
1120+
}
1121+
10791122
tusb_otg_host_submit(host, hc_num);
10801123
return 0;
10811124
}

0 commit comments

Comments
 (0)