|
20 | 20 |
|
21 | 21 | #include "USBHost/dbg.h"
|
22 | 22 | #include "USBHost/USBEndpoint.h"
|
| 23 | +#include "USBHost/USBDeviceConnected.h" |
| 24 | + |
23 | 25 | extern uint32_t HAL_HCD_HC_GetMaxPacket(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
|
24 | 26 | extern uint32_t HAL_HCD_HC_GetType(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
|
25 | 27 | extern void HAL_HCD_DisableInt(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
|
26 | 28 | extern void HAL_HCD_EnableInt(HCD_HandleTypeDef *hhcd, uint8_t chn_num);
|
27 | 29 |
|
28 |
| - |
29 |
| - |
| 30 | +#if defined(TARGET_PORTENTA_H7) |
| 31 | +#define USBx_BASE USB2_OTG_FS_PERIPH_BASE |
| 32 | +#elif defined(TARGET_GIGA) |
| 33 | +#define USBx_BASE USB1_OTG_HS_PERIPH_BASE |
| 34 | +#else |
| 35 | +#define USBx_BASE USB1_OTG_HS_PERIPH_BASE |
| 36 | +#endif |
30 | 37 |
|
31 | 38 | void USBEndpoint::init(HCED *hced_, ENDPOINT_TYPE type_, ENDPOINT_DIRECTION dir_, uint32_t size, uint8_t ep_number, HCTD *td_list_[2])
|
32 | 39 | {
|
@@ -107,21 +114,45 @@ void USBEndpoint::setState(USB_TYPE st)
|
107 | 114 | if ((*addr) && (type != INTERRUPT_ENDPOINT)) {
|
108 | 115 | this->ep_queue.put((uint8_t *)1);
|
109 | 116 | }
|
110 |
| - HAL_HCD_HC_Halt((HCD_HandleTypeDef *)hced->hhcd, hced->ch_num); |
| 117 | + // Flush posted requests |
| 118 | + USBx_HC(hced->ch_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS; |
| 119 | + // Disable the channel |
| 120 | + USBx_HC(hced->ch_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS | USB_OTG_HCCHAR_CHENA; |
| 121 | + // Notice the lack of error handling here - after testing a lot of |
| 122 | + // combinations, it seems that the USB host controller doesn't work fully |
| 123 | + // according to the reference manual in this aspect, which might also |
| 124 | + // be the reason for lacking error handling in the ST USB LL - instead, |
| 125 | + // we use a 50 us delay to wait for the channel to disable |
| 126 | + wait_us(50); |
| 127 | + |
111 | 128 | HAL_HCD_DisableInt((HCD_HandleTypeDef *)hced->hhcd, hced->ch_num);
|
112 | 129 | *addr = 0;
|
113 | 130 |
|
114 | 131 | }
|
115 | 132 | if (st == USB_TYPE_ERROR) {
|
116 |
| - HAL_HCD_HC_Halt((HCD_HandleTypeDef *)hced->hhcd, hced->ch_num); |
117 |
| - HAL_HCD_DisableInt((HCD_HandleTypeDef *)hced->hhcd, hced->ch_num); |
| 133 | + // Flush posted requests |
| 134 | + USBx_HC(hced->ch_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS; |
| 135 | + // Disable the channel |
| 136 | + USBx_HC(hced->ch_num)->HCCHAR |= USB_OTG_HCCHAR_CHDIS | USB_OTG_HCCHAR_CHENA; |
| 137 | + // Notice the lack of error handling here - after testing a lot of |
| 138 | + // combinations, it seems that the USB host controller doesn't work fully |
| 139 | + // according to the reference manual in this aspect, which might also |
| 140 | + // be the reason for lacking error handling in the ST USB LL - instead, |
| 141 | + // we use a 50 us delay to wait for the channel to disable |
| 142 | + wait_us(50); |
118 | 143 |
|
119 |
| - } |
120 |
| - if (st == USB_TYPE_ERROR) { |
| 144 | + HAL_HCD_DisableInt((HCD_HandleTypeDef *)hced->hhcd, hced->ch_num); |
121 | 145 | uint8_t hcd_speed = HCD_SPEED_FULL;
|
122 | 146 | /* small speed device with hub not supported
|
123 | 147 | if (this->speed) hcd_speed = HCD_SPEED_LOW;*/
|
124 |
| - HAL_HCD_HC_Init((HCD_HandleTypeDef *)hced->hhcd, hced->ch_num, address, 0, hcd_speed, type, size); |
| 148 | + |
| 149 | + // Notice that dev->getAddress() must be used instead of device_address, because the latter will contain |
| 150 | + // incorrect values in certain cases |
| 151 | + HAL_HCD_HC_Init((HCD_HandleTypeDef *)hced->hhcd, hced->ch_num, address, dev->getAddress(), hcd_speed, type, size); |
| 152 | + // HAL_HCD_HC_Init() doesn't fully enable the channel after disable above, so we do it here --> |
| 153 | + USBx_HC(hced->ch_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHDIS; |
| 154 | + USBx_HC(hced->ch_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; |
| 155 | + // <-- |
125 | 156 | }
|
126 | 157 | }
|
127 | 158 |
|
@@ -150,7 +181,7 @@ USB_TYPE USBEndpoint::queueTransfer()
|
150 | 181 | state = USB_TYPE_PROCESSING;
|
151 | 182 | /* one request */
|
152 | 183 | td_current->nextTD = (hcTd *)0;
|
153 |
| -#if defined(MAX_NYET_RETRY) |
| 184 | +#if defined(MAX_NOTREADY_RETRY) |
154 | 185 | td_current->retry = 0;
|
155 | 186 | #endif
|
156 | 187 | td_current->setup = setup;
|
|
0 commit comments