Simple USBHost library for STM32F746NG Discovery board. Only either the Fastspeed or the Highspeed port can be used( not both together)

Dependents:   DISCO-F746NG_USB_Host

Fork of KL46Z-USBHost by Norimasa Okamoto

Committer:
DieterGraef
Date:
Mon Jun 13 17:21:07 2016 +0000
Revision:
24:5396b6a93262
Child:
25:7d6d9fc471bf
USB Host for STM32F746 DISCO Board. At the moment you can only use either the High Speed Port or the Fast Speed Port.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
DieterGraef 24:5396b6a93262 1 #if defined(TARGET_DISCO_F746NG)
DieterGraef 24:5396b6a93262 2 #include "mbed.h"
DieterGraef 24:5396b6a93262 3 #include "stm32f7xx_hal.h"
DieterGraef 24:5396b6a93262 4 #include "USBHALHost.h"
DieterGraef 24:5396b6a93262 5 #include <algorithm>
DieterGraef 24:5396b6a93262 6 #include "USB_Helper.h"
DieterGraef 24:5396b6a93262 7 #ifdef _USB_DBG
DieterGraef 24:5396b6a93262 8 //extern RawSerial pc;
DieterGraef 24:5396b6a93262 9 //RawSerial pc(USBTX,USBRX);
DieterGraef 24:5396b6a93262 10 #include "mydebug.h"
DieterGraef 24:5396b6a93262 11 #define USB_DBG(...) do{printf("[%s@%d] ",__PRETTY_FUNCTION__,__LINE__);printf(__VA_ARGS__);printf("\n");} while(0);
DieterGraef 24:5396b6a93262 12 #define USB_DBG_HEX(A,B) debug_hex<RawSerial>(pc,A,B)
DieterGraef 24:5396b6a93262 13
DieterGraef 24:5396b6a93262 14 #else
DieterGraef 24:5396b6a93262 15 #define USB_DBG(...) while(0)
DieterGraef 24:5396b6a93262 16 #define USB_DBG_HEX(A,B) while(0)
DieterGraef 24:5396b6a93262 17 #endif
DieterGraef 24:5396b6a93262 18
DieterGraef 24:5396b6a93262 19 #undef USB_TEST_ASSERT
DieterGraef 24:5396b6a93262 20 void usb_test_assert_internal(const char *expr, const char *file, int line);
DieterGraef 24:5396b6a93262 21 #define USB_TEST_ASSERT(EXPR) while(!(EXPR)){usb_test_assert_internal(#EXPR,__FILE__,__LINE__);}
DieterGraef 24:5396b6a93262 22
DieterGraef 24:5396b6a93262 23 #define USB_TRACE1(A) while(0)
DieterGraef 24:5396b6a93262 24
DieterGraef 24:5396b6a93262 25 #define USB_INFO(...) do{fprintf(stderr,__VA_ARGS__);fprintf(stderr,"\n");}while(0);
DieterGraef 24:5396b6a93262 26
DieterGraef 24:5396b6a93262 27 __IO bool attach_done = false;
DieterGraef 24:5396b6a93262 28
DieterGraef 24:5396b6a93262 29 void delay_ms(uint32_t t)
DieterGraef 24:5396b6a93262 30 {
DieterGraef 24:5396b6a93262 31 wait_ms(t);
DieterGraef 24:5396b6a93262 32 }
DieterGraef 24:5396b6a93262 33
DieterGraef 24:5396b6a93262 34 // usbh_conf.c
DieterGraef 24:5396b6a93262 35
DieterGraef 24:5396b6a93262 36 //__attribute__((section(".dmatransfer")));
DieterGraef 24:5396b6a93262 37
DieterGraef 24:5396b6a93262 38
DieterGraef 24:5396b6a93262 39 void HAL_HCD_MspInit(HCD_HandleTypeDef* hhcd)
DieterGraef 24:5396b6a93262 40 {
DieterGraef 24:5396b6a93262 41 GPIO_InitTypeDef GPIO_InitStruct;
DieterGraef 24:5396b6a93262 42 if(hhcd->Instance==USB_OTG_FS)
DieterGraef 24:5396b6a93262 43 {
DieterGraef 24:5396b6a93262 44 /* Configure USB FS GPIOs */
DieterGraef 24:5396b6a93262 45 __HAL_RCC_GPIOA_CLK_ENABLE();
DieterGraef 24:5396b6a93262 46 __HAL_RCC_GPIOD_CLK_ENABLE();
DieterGraef 24:5396b6a93262 47 GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12);
DieterGraef 24:5396b6a93262 48 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
DieterGraef 24:5396b6a93262 49 GPIO_InitStruct.Pull = GPIO_NOPULL;
DieterGraef 24:5396b6a93262 50 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
DieterGraef 24:5396b6a93262 51 GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
DieterGraef 24:5396b6a93262 52 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
DieterGraef 24:5396b6a93262 53
DieterGraef 24:5396b6a93262 54 GPIO_InitStruct.Pin = GPIO_PIN_10;
DieterGraef 24:5396b6a93262 55 GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
DieterGraef 24:5396b6a93262 56 GPIO_InitStruct.Pull = GPIO_PULLUP;
DieterGraef 24:5396b6a93262 57 GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
DieterGraef 24:5396b6a93262 58 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
DieterGraef 24:5396b6a93262 59
DieterGraef 24:5396b6a93262 60 /* Configure POWER_SWITCH IO pin */
DieterGraef 24:5396b6a93262 61 GPIO_InitStruct.Pin = GPIO_PIN_5;
DieterGraef 24:5396b6a93262 62 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
DieterGraef 24:5396b6a93262 63 GPIO_InitStruct.Pull = GPIO_NOPULL;
DieterGraef 24:5396b6a93262 64 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
DieterGraef 24:5396b6a93262 65
DieterGraef 24:5396b6a93262 66 /* Enable USB FS Clocks */
DieterGraef 24:5396b6a93262 67 __HAL_RCC_USB_OTG_FS_CLK_ENABLE();
DieterGraef 24:5396b6a93262 68 }
DieterGraef 24:5396b6a93262 69 if(hhcd->Instance==USB_OTG_HS)
DieterGraef 24:5396b6a93262 70 {
DieterGraef 24:5396b6a93262 71 /* Peripheral clock enable */
DieterGraef 24:5396b6a93262 72 __HAL_RCC_GPIOA_CLK_ENABLE();
DieterGraef 24:5396b6a93262 73 __HAL_RCC_GPIOB_CLK_ENABLE();
DieterGraef 24:5396b6a93262 74 __HAL_RCC_GPIOC_CLK_ENABLE();
DieterGraef 24:5396b6a93262 75 __HAL_RCC_GPIOH_CLK_ENABLE();
DieterGraef 24:5396b6a93262 76 /* CLK */
DieterGraef 24:5396b6a93262 77 GPIO_InitStruct.Pin = GPIO_PIN_5;
DieterGraef 24:5396b6a93262 78 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
DieterGraef 24:5396b6a93262 79 GPIO_InitStruct.Pull = GPIO_NOPULL;
DieterGraef 24:5396b6a93262 80 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
DieterGraef 24:5396b6a93262 81 GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
DieterGraef 24:5396b6a93262 82 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
DieterGraef 24:5396b6a93262 83
DieterGraef 24:5396b6a93262 84 /* D0 */
DieterGraef 24:5396b6a93262 85 GPIO_InitStruct.Pin = GPIO_PIN_3;
DieterGraef 24:5396b6a93262 86 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
DieterGraef 24:5396b6a93262 87 GPIO_InitStruct.Pull = GPIO_NOPULL;
DieterGraef 24:5396b6a93262 88 GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
DieterGraef 24:5396b6a93262 89 GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
DieterGraef 24:5396b6a93262 90 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
DieterGraef 24:5396b6a93262 91
DieterGraef 24:5396b6a93262 92 /* D1 D2 D3 D4 D5 D6 D7 */
DieterGraef 24:5396b6a93262 93 GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_5 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
DieterGraef 24:5396b6a93262 94 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
DieterGraef 24:5396b6a93262 95 GPIO_InitStruct.Pull = GPIO_NOPULL;
DieterGraef 24:5396b6a93262 96 GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
DieterGraef 24:5396b6a93262 97 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
DieterGraef 24:5396b6a93262 98
DieterGraef 24:5396b6a93262 99 /* STP */
DieterGraef 24:5396b6a93262 100 GPIO_InitStruct.Pin = GPIO_PIN_0;
DieterGraef 24:5396b6a93262 101 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
DieterGraef 24:5396b6a93262 102 GPIO_InitStruct.Pull = GPIO_NOPULL;
DieterGraef 24:5396b6a93262 103 GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
DieterGraef 24:5396b6a93262 104 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
DieterGraef 24:5396b6a93262 105
DieterGraef 24:5396b6a93262 106 /* NXT */
DieterGraef 24:5396b6a93262 107 GPIO_InitStruct.Pin = GPIO_PIN_4;
DieterGraef 24:5396b6a93262 108 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
DieterGraef 24:5396b6a93262 109 GPIO_InitStruct.Pull = GPIO_NOPULL;
DieterGraef 24:5396b6a93262 110 GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
DieterGraef 24:5396b6a93262 111 HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
DieterGraef 24:5396b6a93262 112
DieterGraef 24:5396b6a93262 113 /* DIR */
DieterGraef 24:5396b6a93262 114 GPIO_InitStruct.Pin = GPIO_PIN_2;
DieterGraef 24:5396b6a93262 115 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
DieterGraef 24:5396b6a93262 116 GPIO_InitStruct.Pull = GPIO_NOPULL;
DieterGraef 24:5396b6a93262 117 GPIO_InitStruct.Alternate = GPIO_AF10_OTG_HS;
DieterGraef 24:5396b6a93262 118 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
DieterGraef 24:5396b6a93262 119
DieterGraef 24:5396b6a93262 120 __HAL_RCC_USB_OTG_HS_ULPI_CLK_ENABLE();
DieterGraef 24:5396b6a93262 121
DieterGraef 24:5396b6a93262 122 /* Enable USB HS Clocks */
DieterGraef 24:5396b6a93262 123 __HAL_RCC_USB_OTG_HS_CLK_ENABLE();
DieterGraef 24:5396b6a93262 124 }
DieterGraef 24:5396b6a93262 125 }
DieterGraef 24:5396b6a93262 126
DieterGraef 24:5396b6a93262 127 // stm32f4xx_it.c
DieterGraef 24:5396b6a93262 128 extern "C" {
DieterGraef 24:5396b6a93262 129 void HAL_HCD_Connect_Callback(HCD_HandleTypeDef *hhcd)
DieterGraef 24:5396b6a93262 130 {
DieterGraef 24:5396b6a93262 131 //USB_TRACE1(hhcd);
DieterGraef 24:5396b6a93262 132 attach_done = true;
DieterGraef 24:5396b6a93262 133 }
DieterGraef 24:5396b6a93262 134
DieterGraef 24:5396b6a93262 135 } // extern "C"
DieterGraef 24:5396b6a93262 136
DieterGraef 24:5396b6a93262 137 USBHALHost* USBHALHost::instHost;
DieterGraef 24:5396b6a93262 138
DieterGraef 24:5396b6a93262 139 USBHALHost::USBHALHost(int InterfaceNumber)
DieterGraef 24:5396b6a93262 140 {
DieterGraef 24:5396b6a93262 141 IF_N=InterfaceNumber;
DieterGraef 24:5396b6a93262 142 hhcd=&hhcd_USB;
DieterGraef 24:5396b6a93262 143 instHost = this;
DieterGraef 24:5396b6a93262 144 }
DieterGraef 24:5396b6a93262 145
DieterGraef 24:5396b6a93262 146 void USBHALHost::init()
DieterGraef 24:5396b6a93262 147 {
DieterGraef 24:5396b6a93262 148 if(IF_N==USB_FastSpeed)
DieterGraef 24:5396b6a93262 149 {
DieterGraef 24:5396b6a93262 150 hhcd_USB.Instance = USB_OTG_FS;
DieterGraef 24:5396b6a93262 151 hhcd_USB.Init.Host_channels = 11;
DieterGraef 24:5396b6a93262 152 hhcd_USB.Init.dma_enable = 0;
DieterGraef 24:5396b6a93262 153 hhcd_USB.Init.low_power_enable = 0;
DieterGraef 24:5396b6a93262 154 hhcd_USB.Init.phy_itface = HCD_PHY_EMBEDDED;
DieterGraef 24:5396b6a93262 155 hhcd_USB.Init.Sof_enable = 1;
DieterGraef 24:5396b6a93262 156 hhcd_USB.Init.speed = HCD_SPEED_FULL;
DieterGraef 24:5396b6a93262 157 hhcd_USB.Init.vbus_sensing_enable = 0;
DieterGraef 24:5396b6a93262 158 hhcd_USB.Init.lpm_enable = 0;
DieterGraef 24:5396b6a93262 159
DieterGraef 24:5396b6a93262 160 HAL_HCD_Init(&hhcd_USB);
DieterGraef 24:5396b6a93262 161 /* Peripheral interrupt init*/
DieterGraef 24:5396b6a93262 162 /* Sets the priority grouping field */
DieterGraef 24:5396b6a93262 163 NVIC_SetVector(OTG_FS_IRQn, (uint32_t)&_usbisr);
DieterGraef 24:5396b6a93262 164 HAL_NVIC_SetPriority(OTG_FS_IRQn, 6, 0);
DieterGraef 24:5396b6a93262 165 HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
DieterGraef 24:5396b6a93262 166
DieterGraef 24:5396b6a93262 167 HAL_HCD_Start(&hhcd_USB);
DieterGraef 24:5396b6a93262 168
DieterGraef 24:5396b6a93262 169 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_RESET);
DieterGraef 24:5396b6a93262 170
DieterGraef 24:5396b6a93262 171 bool lowSpeed = wait_attach();
DieterGraef 24:5396b6a93262 172 delay_ms(200);
DieterGraef 24:5396b6a93262 173 HAL_HCD_ResetPort(&hhcd_USB);
DieterGraef 24:5396b6a93262 174 delay_ms(100); // Wait for 100 ms after Reset
DieterGraef 24:5396b6a93262 175 addDevice(NULL, 0, lowSpeed);
DieterGraef 24:5396b6a93262 176 }
DieterGraef 24:5396b6a93262 177 if(IF_N==USB_HighSpeed)
DieterGraef 24:5396b6a93262 178 {
DieterGraef 24:5396b6a93262 179 hhcd_USB.Instance = USB_OTG_HS;
DieterGraef 24:5396b6a93262 180 hhcd_USB.Init.Host_channels = 8;
DieterGraef 24:5396b6a93262 181 hhcd_USB.Init.dma_enable = 1;
DieterGraef 24:5396b6a93262 182 hhcd_USB.Init.low_power_enable = 0;
DieterGraef 24:5396b6a93262 183 hhcd_USB.Init.phy_itface = HCD_PHY_ULPI;
DieterGraef 24:5396b6a93262 184 hhcd_USB.Init.Sof_enable = 1;
DieterGraef 24:5396b6a93262 185 hhcd_USB.Init.speed = HCD_SPEED_HIGH;
DieterGraef 24:5396b6a93262 186 hhcd_USB.Init.vbus_sensing_enable = 0;
DieterGraef 24:5396b6a93262 187 hhcd_USB.Init.use_external_vbus = 1;
DieterGraef 24:5396b6a93262 188 hhcd_USB.Init.lpm_enable = 0;
DieterGraef 24:5396b6a93262 189
DieterGraef 24:5396b6a93262 190 HAL_HCD_Init(&hhcd_USB);
DieterGraef 24:5396b6a93262 191 NVIC_SetVector(OTG_HS_IRQn, (uint32_t)&_usbisr);
DieterGraef 24:5396b6a93262 192 HAL_NVIC_SetPriority(OTG_HS_IRQn, 6, 0);
DieterGraef 24:5396b6a93262 193 HAL_NVIC_EnableIRQ(OTG_HS_IRQn);
DieterGraef 24:5396b6a93262 194
DieterGraef 24:5396b6a93262 195 HAL_HCD_Start(&hhcd_USB);
DieterGraef 24:5396b6a93262 196
DieterGraef 24:5396b6a93262 197 bool lowSpeed = wait_attach();
DieterGraef 24:5396b6a93262 198 delay_ms(200);
DieterGraef 24:5396b6a93262 199 HAL_HCD_ResetPort(&hhcd_USB);
DieterGraef 24:5396b6a93262 200 delay_ms(100); // Wait for 100 ms after Reset
DieterGraef 24:5396b6a93262 201 addDevice(NULL, 0, lowSpeed);
DieterGraef 24:5396b6a93262 202 }
DieterGraef 24:5396b6a93262 203 }
DieterGraef 24:5396b6a93262 204
DieterGraef 24:5396b6a93262 205 bool USBHALHost::wait_attach()
DieterGraef 24:5396b6a93262 206 {
DieterGraef 24:5396b6a93262 207 Timer t;
DieterGraef 24:5396b6a93262 208 t.reset();
DieterGraef 24:5396b6a93262 209 t.start();
DieterGraef 24:5396b6a93262 210 while(!attach_done)
DieterGraef 24:5396b6a93262 211 {
DieterGraef 24:5396b6a93262 212 if (t.read_ms() > 5*1000)
DieterGraef 24:5396b6a93262 213 {
DieterGraef 24:5396b6a93262 214 t.reset();
DieterGraef 24:5396b6a93262 215 USB_INFO("Please attach USB device.");
DieterGraef 24:5396b6a93262 216 }
DieterGraef 24:5396b6a93262 217 }
DieterGraef 24:5396b6a93262 218 wait_ms(100);
DieterGraef 24:5396b6a93262 219 return HAL_HCD_GetCurrentSpeed(&hhcd_USB) == USB_OTG_SPEED_LOW;
DieterGraef 24:5396b6a93262 220 }
DieterGraef 24:5396b6a93262 221
DieterGraef 24:5396b6a93262 222
DieterGraef 24:5396b6a93262 223
DieterGraef 24:5396b6a93262 224 int USBHALHost::token_setup(USBEndpoint* ep, SETUP_PACKET* setup, uint16_t wLength)
DieterGraef 24:5396b6a93262 225 {
DieterGraef 24:5396b6a93262 226 const uint8_t ep_addr = 0x00;
DieterGraef 24:5396b6a93262 227 HC hc(&hhcd_USB);
DieterGraef 24:5396b6a93262 228 HCD_URBStateTypeDef st;
DieterGraef 24:5396b6a93262 229 USBDeviceConnected* dev = ep->getDevice();
DieterGraef 24:5396b6a93262 230 if(IF_N==USB_FastSpeed)
DieterGraef 24:5396b6a93262 231 {
DieterGraef 24:5396b6a93262 232 hc.Init(IF_N, ep_addr,
DieterGraef 24:5396b6a93262 233 dev->getAddress(),
DieterGraef 24:5396b6a93262 234 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
DieterGraef 24:5396b6a93262 235 EP_TYPE_CTRL, ep->getSize());
DieterGraef 24:5396b6a93262 236 }
DieterGraef 24:5396b6a93262 237 else
DieterGraef 24:5396b6a93262 238 {
DieterGraef 24:5396b6a93262 239 hc.Init(IF_N,ep_addr,
DieterGraef 24:5396b6a93262 240 dev->getAddress(),
DieterGraef 24:5396b6a93262 241 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_HIGH ,
DieterGraef 24:5396b6a93262 242 EP_TYPE_CTRL, ep->getSize());
DieterGraef 24:5396b6a93262 243 }
DieterGraef 24:5396b6a93262 244
DieterGraef 24:5396b6a93262 245 setup->wLength = wLength;
DieterGraef 24:5396b6a93262 246 st=hc.GetURBState();
DieterGraef 24:5396b6a93262 247 hc.SubmitRequest(IF_N,(uint8_t*)setup, 8, true); // PID_SETUP
DieterGraef 24:5396b6a93262 248 while(hc.GetURBState() == URB_IDLE);
DieterGraef 24:5396b6a93262 249
DieterGraef 24:5396b6a93262 250 switch(hc.GetURBState())
DieterGraef 24:5396b6a93262 251 {
DieterGraef 24:5396b6a93262 252 case URB_DONE:
DieterGraef 24:5396b6a93262 253 LastStatus = ACK;
DieterGraef 24:5396b6a93262 254 break;
DieterGraef 24:5396b6a93262 255 default:
DieterGraef 24:5396b6a93262 256 LastStatus = 0xff;
DieterGraef 24:5396b6a93262 257 break;
DieterGraef 24:5396b6a93262 258 }
DieterGraef 24:5396b6a93262 259 ep->setData01(DATA1);
DieterGraef 24:5396b6a93262 260 return 8;
DieterGraef 24:5396b6a93262 261 }
DieterGraef 24:5396b6a93262 262
DieterGraef 24:5396b6a93262 263 int USBHALHost::token_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit)
DieterGraef 24:5396b6a93262 264 {
DieterGraef 24:5396b6a93262 265 SCB_InvalidateDCache_by_Addr((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 266 switch(ep->getType())
DieterGraef 24:5396b6a93262 267 {
DieterGraef 24:5396b6a93262 268 case CONTROL_ENDPOINT:
DieterGraef 24:5396b6a93262 269 return token_ctl_in(ep, data, size, retryLimit);
DieterGraef 24:5396b6a93262 270 case INTERRUPT_ENDPOINT:
DieterGraef 24:5396b6a93262 271 return token_int_in(ep, data, size);
DieterGraef 24:5396b6a93262 272 case BULK_ENDPOINT:
DieterGraef 24:5396b6a93262 273 return token_blk_in(ep, data, size, retryLimit);
DieterGraef 24:5396b6a93262 274 }
DieterGraef 24:5396b6a93262 275 return -1;
DieterGraef 24:5396b6a93262 276 }
DieterGraef 24:5396b6a93262 277
DieterGraef 24:5396b6a93262 278 int USBHALHost::token_ctl_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit)
DieterGraef 24:5396b6a93262 279 {
DieterGraef 24:5396b6a93262 280 const uint8_t ep_addr = 0x80;
DieterGraef 24:5396b6a93262 281 HC hc(&hhcd_USB);
DieterGraef 24:5396b6a93262 282 HCD_URBStateTypeDef st;
DieterGraef 24:5396b6a93262 283 USBDeviceConnected* dev = ep->getDevice();
DieterGraef 24:5396b6a93262 284 if(IF_N==USB_FastSpeed)
DieterGraef 24:5396b6a93262 285 {
DieterGraef 24:5396b6a93262 286 hc.Init(IF_N,ep_addr,
DieterGraef 24:5396b6a93262 287 dev->getAddress(),
DieterGraef 24:5396b6a93262 288 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
DieterGraef 24:5396b6a93262 289 EP_TYPE_CTRL, ep->getSize());
DieterGraef 24:5396b6a93262 290 }
DieterGraef 24:5396b6a93262 291 else
DieterGraef 24:5396b6a93262 292 {
DieterGraef 24:5396b6a93262 293 hc.Init(IF_N,ep_addr,
DieterGraef 24:5396b6a93262 294 dev->getAddress(),
DieterGraef 24:5396b6a93262 295 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_HIGH ,
DieterGraef 24:5396b6a93262 296 EP_TYPE_CTRL, ep->getSize());
DieterGraef 24:5396b6a93262 297 }
DieterGraef 24:5396b6a93262 298
DieterGraef 24:5396b6a93262 299 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1);
DieterGraef 24:5396b6a93262 300 st=hc.GetURBState();
DieterGraef 24:5396b6a93262 301 SCB_InvalidateDCache_by_Addr((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 302 wait_ms(1);
DieterGraef 24:5396b6a93262 303 hc.SubmitRequest(IF_N,data, size);
DieterGraef 24:5396b6a93262 304 while(hc.GetURBState() == URB_IDLE);
DieterGraef 24:5396b6a93262 305 CPU_CACHE_Flush((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 306 st=hc.GetURBState();
DieterGraef 24:5396b6a93262 307 switch(hc.GetURBState())
DieterGraef 24:5396b6a93262 308 {
DieterGraef 24:5396b6a93262 309 case URB_DONE:
DieterGraef 24:5396b6a93262 310 LastStatus = ACK;
DieterGraef 24:5396b6a93262 311 break;
DieterGraef 24:5396b6a93262 312 default:
DieterGraef 24:5396b6a93262 313 LastStatus = 0xff;
DieterGraef 24:5396b6a93262 314 return -1;
DieterGraef 24:5396b6a93262 315 }
DieterGraef 24:5396b6a93262 316 ep->toggleData01();
DieterGraef 24:5396b6a93262 317 return hc.GetXferCount();
DieterGraef 24:5396b6a93262 318 }
DieterGraef 24:5396b6a93262 319
DieterGraef 24:5396b6a93262 320 int USBHALHost::token_int_in(USBEndpoint* ep, uint8_t* data, int size)
DieterGraef 24:5396b6a93262 321 {
DieterGraef 24:5396b6a93262 322 HC hc(&hhcd_USB);
DieterGraef 24:5396b6a93262 323 HCD_URBStateTypeDef st;
DieterGraef 24:5396b6a93262 324 USBDeviceConnected* dev = ep->getDevice();
DieterGraef 24:5396b6a93262 325 if(IF_N==USB_FastSpeed)
DieterGraef 24:5396b6a93262 326 {
DieterGraef 24:5396b6a93262 327 hc.Init(IF_N,ep->getAddress(),
DieterGraef 24:5396b6a93262 328 dev->getAddress(),
DieterGraef 24:5396b6a93262 329 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
DieterGraef 24:5396b6a93262 330 EP_TYPE_INTR, ep->getSize());
DieterGraef 24:5396b6a93262 331 }
DieterGraef 24:5396b6a93262 332 else
DieterGraef 24:5396b6a93262 333 {
DieterGraef 24:5396b6a93262 334 hc.Init(IF_N,ep->getAddress(),
DieterGraef 24:5396b6a93262 335 dev->getAddress(),
DieterGraef 24:5396b6a93262 336 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_HIGH ,
DieterGraef 24:5396b6a93262 337 EP_TYPE_INTR, ep->getSize());
DieterGraef 24:5396b6a93262 338 }
DieterGraef 24:5396b6a93262 339
DieterGraef 24:5396b6a93262 340 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1);
DieterGraef 24:5396b6a93262 341 st=hc.GetURBState();
DieterGraef 24:5396b6a93262 342 SCB_InvalidateDCache_by_Addr((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 343 hc.SubmitRequest(IF_N,data, size);
DieterGraef 24:5396b6a93262 344 while(hc.GetURBState() == URB_IDLE);
DieterGraef 24:5396b6a93262 345 CPU_CACHE_Flush((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 346 switch(hc.GetURBState())
DieterGraef 24:5396b6a93262 347 {
DieterGraef 24:5396b6a93262 348 case URB_DONE:
DieterGraef 24:5396b6a93262 349 switch(hc.GetState())
DieterGraef 24:5396b6a93262 350 {
DieterGraef 24:5396b6a93262 351 case HC_XFRC:
DieterGraef 24:5396b6a93262 352 LastStatus = ep->getData01();
DieterGraef 24:5396b6a93262 353 ep->toggleData01();
DieterGraef 24:5396b6a93262 354 return hc.GetXferCount();
DieterGraef 24:5396b6a93262 355 case HC_NAK:
DieterGraef 24:5396b6a93262 356 LastStatus = NAK;
DieterGraef 24:5396b6a93262 357 return -1;
DieterGraef 24:5396b6a93262 358 }
DieterGraef 24:5396b6a93262 359 break;
DieterGraef 24:5396b6a93262 360 }
DieterGraef 24:5396b6a93262 361 LastStatus = STALL;
DieterGraef 24:5396b6a93262 362 return -1;
DieterGraef 24:5396b6a93262 363 }
DieterGraef 24:5396b6a93262 364
DieterGraef 24:5396b6a93262 365 int USBHALHost::token_blk_in(USBEndpoint* ep, uint8_t* data, int size, int retryLimit)
DieterGraef 24:5396b6a93262 366 {
DieterGraef 24:5396b6a93262 367 HC hc(&hhcd_USB);
DieterGraef 24:5396b6a93262 368 HCD_URBStateTypeDef st;
DieterGraef 24:5396b6a93262 369 USBDeviceConnected* dev = ep->getDevice();
DieterGraef 24:5396b6a93262 370 if(IF_N==USB_FastSpeed)
DieterGraef 24:5396b6a93262 371 {
DieterGraef 24:5396b6a93262 372 hc.Init(IF_N,
DieterGraef 24:5396b6a93262 373 ep->getAddress(),
DieterGraef 24:5396b6a93262 374 dev->getAddress(),
DieterGraef 24:5396b6a93262 375 HCD_SPEED_FULL,
DieterGraef 24:5396b6a93262 376 EP_TYPE_BULK, ep->getSize());
DieterGraef 24:5396b6a93262 377 }
DieterGraef 24:5396b6a93262 378 else
DieterGraef 24:5396b6a93262 379 {
DieterGraef 24:5396b6a93262 380 hc.Init(IF_N,
DieterGraef 24:5396b6a93262 381 ep->getAddress(),
DieterGraef 24:5396b6a93262 382 dev->getAddress(),
DieterGraef 24:5396b6a93262 383 HCD_SPEED_HIGH,
DieterGraef 24:5396b6a93262 384 EP_TYPE_BULK, ep->getSize());
DieterGraef 24:5396b6a93262 385 }
DieterGraef 24:5396b6a93262 386
DieterGraef 24:5396b6a93262 387 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1);
DieterGraef 24:5396b6a93262 388
DieterGraef 24:5396b6a93262 389 int retry = 0;
DieterGraef 24:5396b6a93262 390 do
DieterGraef 24:5396b6a93262 391 {
DieterGraef 24:5396b6a93262 392 st=hc.GetURBState();
DieterGraef 24:5396b6a93262 393 SCB_InvalidateDCache_by_Addr((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 394 hc.SubmitRequest(IF_N,data, size);
DieterGraef 24:5396b6a93262 395 while(hc.GetURBState() == URB_IDLE);
DieterGraef 24:5396b6a93262 396 CPU_CACHE_Flush((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 397 st=hc.GetURBState();
DieterGraef 24:5396b6a93262 398 switch(st)
DieterGraef 24:5396b6a93262 399 {
DieterGraef 24:5396b6a93262 400 case URB_DONE:
DieterGraef 24:5396b6a93262 401 switch(hc.GetState())
DieterGraef 24:5396b6a93262 402 {
DieterGraef 24:5396b6a93262 403 case HC_XFRC:
DieterGraef 24:5396b6a93262 404 LastStatus = ep->getData01();
DieterGraef 24:5396b6a93262 405 ep->toggleData01();
DieterGraef 24:5396b6a93262 406 return hc.GetXferCount();
DieterGraef 24:5396b6a93262 407 case HC_NAK:
DieterGraef 24:5396b6a93262 408 LastStatus = NAK;
DieterGraef 24:5396b6a93262 409 if (retryLimit > 0)
DieterGraef 24:5396b6a93262 410 {
DieterGraef 24:5396b6a93262 411 delay_ms(1 + 10 * retry);
DieterGraef 24:5396b6a93262 412 }
DieterGraef 24:5396b6a93262 413 break;
DieterGraef 24:5396b6a93262 414 default:
DieterGraef 24:5396b6a93262 415 break;
DieterGraef 24:5396b6a93262 416 }
DieterGraef 24:5396b6a93262 417 break;
DieterGraef 24:5396b6a93262 418 case URB_STALL:
DieterGraef 24:5396b6a93262 419 LastStatus = STALL;
DieterGraef 24:5396b6a93262 420 return -1;
DieterGraef 24:5396b6a93262 421 default:
DieterGraef 24:5396b6a93262 422 LastStatus = STALL;
DieterGraef 24:5396b6a93262 423 delay_ms(500 + 100 * retry);
DieterGraef 24:5396b6a93262 424 break;
DieterGraef 24:5396b6a93262 425 }
DieterGraef 24:5396b6a93262 426 }
DieterGraef 24:5396b6a93262 427 while(retry++ < retryLimit);
DieterGraef 24:5396b6a93262 428 return -1;
DieterGraef 24:5396b6a93262 429 }
DieterGraef 24:5396b6a93262 430
DieterGraef 24:5396b6a93262 431 int USBHALHost::token_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit)
DieterGraef 24:5396b6a93262 432 {
DieterGraef 24:5396b6a93262 433 CPU_CACHE_Flush((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 434 SCB_InvalidateDCache_by_Addr((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 435 switch(ep->getType())
DieterGraef 24:5396b6a93262 436 {
DieterGraef 24:5396b6a93262 437 case CONTROL_ENDPOINT:
DieterGraef 24:5396b6a93262 438 return token_ctl_out(ep, data, size, retryLimit);
DieterGraef 24:5396b6a93262 439 case INTERRUPT_ENDPOINT:
DieterGraef 24:5396b6a93262 440 return token_int_out(ep, data, size);
DieterGraef 24:5396b6a93262 441 case BULK_ENDPOINT:
DieterGraef 24:5396b6a93262 442 return token_blk_out(ep, data, size, retryLimit);
DieterGraef 24:5396b6a93262 443 }
DieterGraef 24:5396b6a93262 444 return -1;
DieterGraef 24:5396b6a93262 445 }
DieterGraef 24:5396b6a93262 446
DieterGraef 24:5396b6a93262 447 int USBHALHost::token_ctl_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit)
DieterGraef 24:5396b6a93262 448 {
DieterGraef 24:5396b6a93262 449 const uint8_t ep_addr = 0x00;
DieterGraef 24:5396b6a93262 450 HC hc(&hhcd_USB);
DieterGraef 24:5396b6a93262 451 HCD_URBStateTypeDef st;
DieterGraef 24:5396b6a93262 452 USBDeviceConnected* dev = ep->getDevice();
DieterGraef 24:5396b6a93262 453 if(IF_N==USB_FastSpeed)
DieterGraef 24:5396b6a93262 454 {
DieterGraef 24:5396b6a93262 455 hc.Init(IF_N,ep_addr,
DieterGraef 24:5396b6a93262 456 dev->getAddress(),
DieterGraef 24:5396b6a93262 457 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
DieterGraef 24:5396b6a93262 458 EP_TYPE_CTRL, ep->getSize());
DieterGraef 24:5396b6a93262 459 }
DieterGraef 24:5396b6a93262 460 else
DieterGraef 24:5396b6a93262 461 {
DieterGraef 24:5396b6a93262 462 hc.Init(IF_N,ep_addr,
DieterGraef 24:5396b6a93262 463 dev->getAddress(),
DieterGraef 24:5396b6a93262 464 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_HIGH ,
DieterGraef 24:5396b6a93262 465 EP_TYPE_CTRL, ep->getSize());
DieterGraef 24:5396b6a93262 466 }
DieterGraef 24:5396b6a93262 467
DieterGraef 24:5396b6a93262 468 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1);
DieterGraef 24:5396b6a93262 469
DieterGraef 24:5396b6a93262 470 do
DieterGraef 24:5396b6a93262 471 {
DieterGraef 24:5396b6a93262 472 st=hc.GetURBState();
DieterGraef 24:5396b6a93262 473 CPU_CACHE_Flush((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 474 wait_ms(1);
DieterGraef 24:5396b6a93262 475 hc.SubmitRequest(IF_N,(uint8_t*)data, size);
DieterGraef 24:5396b6a93262 476 while(hc.GetURBState() == URB_IDLE);
DieterGraef 24:5396b6a93262 477 SCB_InvalidateDCache_by_Addr((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 478 switch(hc.GetURBState())
DieterGraef 24:5396b6a93262 479 {
DieterGraef 24:5396b6a93262 480 case URB_DONE:
DieterGraef 24:5396b6a93262 481 LastStatus = ACK;
DieterGraef 24:5396b6a93262 482 ep->toggleData01();
DieterGraef 24:5396b6a93262 483 return size;
DieterGraef 24:5396b6a93262 484
DieterGraef 24:5396b6a93262 485 default:
DieterGraef 24:5396b6a93262 486 break;
DieterGraef 24:5396b6a93262 487 }
DieterGraef 24:5396b6a93262 488 delay_ms(1);
DieterGraef 24:5396b6a93262 489 }
DieterGraef 24:5396b6a93262 490 while(retryLimit-- > 0);
DieterGraef 24:5396b6a93262 491 return -1;
DieterGraef 24:5396b6a93262 492 }
DieterGraef 24:5396b6a93262 493
DieterGraef 24:5396b6a93262 494 int USBHALHost::token_int_out(USBEndpoint* ep, const uint8_t* data, int size)
DieterGraef 24:5396b6a93262 495 {
DieterGraef 24:5396b6a93262 496 HC hc(&hhcd_USB);
DieterGraef 24:5396b6a93262 497 HCD_URBStateTypeDef st;
DieterGraef 24:5396b6a93262 498 USBDeviceConnected* dev = ep->getDevice();
DieterGraef 24:5396b6a93262 499 if(IF_N==USB_FastSpeed)
DieterGraef 24:5396b6a93262 500 {
DieterGraef 24:5396b6a93262 501 hc.Init(IF_N,
DieterGraef 24:5396b6a93262 502 ep->getAddress(),
DieterGraef 24:5396b6a93262 503 dev->getAddress(),
DieterGraef 24:5396b6a93262 504 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_FULL,
DieterGraef 24:5396b6a93262 505 EP_TYPE_INTR, ep->getSize());
DieterGraef 24:5396b6a93262 506 }
DieterGraef 24:5396b6a93262 507 else
DieterGraef 24:5396b6a93262 508 {
DieterGraef 24:5396b6a93262 509 hc.Init(IF_N,
DieterGraef 24:5396b6a93262 510 ep->getAddress(),
DieterGraef 24:5396b6a93262 511 dev->getAddress(),
DieterGraef 24:5396b6a93262 512 dev->getSpeed() ? HCD_SPEED_LOW : HCD_SPEED_HIGH ,
DieterGraef 24:5396b6a93262 513 EP_TYPE_INTR, ep->getSize());
DieterGraef 24:5396b6a93262 514 }
DieterGraef 24:5396b6a93262 515
DieterGraef 24:5396b6a93262 516 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1);
DieterGraef 24:5396b6a93262 517 st=hc.GetURBState();
DieterGraef 24:5396b6a93262 518 CPU_CACHE_Flush((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 519 hc.SubmitRequest(IF_N,(uint8_t*)data, size);
DieterGraef 24:5396b6a93262 520 while(hc.GetURBState() == URB_IDLE);
DieterGraef 24:5396b6a93262 521 SCB_InvalidateDCache_by_Addr((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 522 if (hc.GetURBState() != URB_DONE)
DieterGraef 24:5396b6a93262 523 {
DieterGraef 24:5396b6a93262 524 return -1;
DieterGraef 24:5396b6a93262 525 }
DieterGraef 24:5396b6a93262 526 ep->toggleData01();
DieterGraef 24:5396b6a93262 527 return size;
DieterGraef 24:5396b6a93262 528 }
DieterGraef 24:5396b6a93262 529
DieterGraef 24:5396b6a93262 530 int USBHALHost::token_blk_out(USBEndpoint* ep, const uint8_t* data, int size, int retryLimit)
DieterGraef 24:5396b6a93262 531 {
DieterGraef 24:5396b6a93262 532 HC hc(&hhcd_USB);
DieterGraef 24:5396b6a93262 533 HCD_URBStateTypeDef st;
DieterGraef 24:5396b6a93262 534 USBDeviceConnected* dev = ep->getDevice();
DieterGraef 24:5396b6a93262 535 if(IF_N==USB_FastSpeed)
DieterGraef 24:5396b6a93262 536 {
DieterGraef 24:5396b6a93262 537
DieterGraef 24:5396b6a93262 538
DieterGraef 24:5396b6a93262 539 hc.Init(IF_N,
DieterGraef 24:5396b6a93262 540 ep->getAddress(), dev->getAddress(),
DieterGraef 24:5396b6a93262 541 HCD_SPEED_FULL, EP_TYPE_BULK, ep->getSize());
DieterGraef 24:5396b6a93262 542 }
DieterGraef 24:5396b6a93262 543 else
DieterGraef 24:5396b6a93262 544 {
DieterGraef 24:5396b6a93262 545 hc.Init(IF_N,
DieterGraef 24:5396b6a93262 546 ep->getAddress(), dev->getAddress(),
DieterGraef 24:5396b6a93262 547 HCD_SPEED_HIGH, EP_TYPE_BULK, ep->getSize());
DieterGraef 24:5396b6a93262 548 }
DieterGraef 24:5396b6a93262 549 hc.SetToggle((ep->getData01() == DATA0) ? 0 : 1);
DieterGraef 24:5396b6a93262 550
DieterGraef 24:5396b6a93262 551 int retry = 0;
DieterGraef 24:5396b6a93262 552 do
DieterGraef 24:5396b6a93262 553 {
DieterGraef 24:5396b6a93262 554 st=hc.GetURBState();
DieterGraef 24:5396b6a93262 555 CPU_CACHE_Flush((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 556 hc.SubmitRequest(IF_N,(uint8_t*)data, size);
DieterGraef 24:5396b6a93262 557 while(hc.GetURBState() == URB_IDLE);
DieterGraef 24:5396b6a93262 558 SCB_InvalidateDCache_by_Addr((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 559 switch(hc.GetURBState())
DieterGraef 24:5396b6a93262 560 {
DieterGraef 24:5396b6a93262 561 case URB_DONE:
DieterGraef 24:5396b6a93262 562 switch(hc.GetState())
DieterGraef 24:5396b6a93262 563 {
DieterGraef 24:5396b6a93262 564 case HC_XFRC: // ACK
DieterGraef 24:5396b6a93262 565 LastStatus = ep->getData01();
DieterGraef 24:5396b6a93262 566 ep->toggleData01();
DieterGraef 24:5396b6a93262 567 return size;
DieterGraef 24:5396b6a93262 568 default:
DieterGraef 24:5396b6a93262 569 break;
DieterGraef 24:5396b6a93262 570 }
DieterGraef 24:5396b6a93262 571 break;
DieterGraef 24:5396b6a93262 572 case URB_NOTREADY: // HC_NAK
DieterGraef 24:5396b6a93262 573 LastStatus = NAK;
DieterGraef 24:5396b6a93262 574 delay_ms(100 * retry);
DieterGraef 24:5396b6a93262 575 break;
DieterGraef 24:5396b6a93262 576 default:
DieterGraef 24:5396b6a93262 577 LastStatus = STALL;
DieterGraef 24:5396b6a93262 578 return -1;
DieterGraef 24:5396b6a93262 579 }
DieterGraef 24:5396b6a93262 580 }
DieterGraef 24:5396b6a93262 581 while(retry++ < retryLimit);
DieterGraef 24:5396b6a93262 582 return -1;
DieterGraef 24:5396b6a93262 583 }
DieterGraef 24:5396b6a93262 584
DieterGraef 24:5396b6a93262 585 int USBHALHost::token_iso_in(USBEndpoint* ep, uint8_t* data, int size)
DieterGraef 24:5396b6a93262 586 {
DieterGraef 24:5396b6a93262 587 HCD_URBStateTypeDef st;
DieterGraef 24:5396b6a93262 588 HC* hc = ep->getHALData<HC*>();
DieterGraef 24:5396b6a93262 589 if (hc == NULL)
DieterGraef 24:5396b6a93262 590 {
DieterGraef 24:5396b6a93262 591 hc = new HC(&hhcd_USB);
DieterGraef 24:5396b6a93262 592 ep->setHALData<HC*>(hc);
DieterGraef 24:5396b6a93262 593 USBDeviceConnected* dev = ep->getDevice();
DieterGraef 24:5396b6a93262 594 if(IF_N==USB_FastSpeed)
DieterGraef 24:5396b6a93262 595 {
DieterGraef 24:5396b6a93262 596
DieterGraef 24:5396b6a93262 597
DieterGraef 24:5396b6a93262 598 hc->Init(IF_N,
DieterGraef 24:5396b6a93262 599 ep->getAddress(), dev->getAddress(),
DieterGraef 24:5396b6a93262 600 HCD_SPEED_FULL, EP_TYPE_ISOC, ep->getSize());
DieterGraef 24:5396b6a93262 601 }
DieterGraef 24:5396b6a93262 602 else
DieterGraef 24:5396b6a93262 603 {
DieterGraef 24:5396b6a93262 604 hc->Init(IF_N,
DieterGraef 24:5396b6a93262 605 ep->getAddress(), dev->getAddress(),
DieterGraef 24:5396b6a93262 606 HCD_SPEED_HIGH, EP_TYPE_ISOC, ep->getSize());
DieterGraef 24:5396b6a93262 607 }
DieterGraef 24:5396b6a93262 608 }
DieterGraef 24:5396b6a93262 609 st=hc->GetURBState();
DieterGraef 24:5396b6a93262 610 SCB_InvalidateDCache_by_Addr((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 611 hc->SubmitRequest(IF_N,data, size);
DieterGraef 24:5396b6a93262 612 while(hc->GetURBState() == URB_IDLE);
DieterGraef 24:5396b6a93262 613 CPU_CACHE_Flush((uint32_t *)data,size);
DieterGraef 24:5396b6a93262 614 return hc->GetXferCount();
DieterGraef 24:5396b6a93262 615 }
DieterGraef 24:5396b6a93262 616
DieterGraef 24:5396b6a93262 617 int USBHALHost::multi_token_in(USBEndpoint* ep, uint8_t* data, size_t total, bool block)
DieterGraef 24:5396b6a93262 618 {
DieterGraef 24:5396b6a93262 619 if (total == 0)
DieterGraef 24:5396b6a93262 620 {
DieterGraef 24:5396b6a93262 621 return token_in(ep);
DieterGraef 24:5396b6a93262 622 }
DieterGraef 24:5396b6a93262 623 int retryLimit = block ? 10 : 0;
DieterGraef 24:5396b6a93262 624 int read_len = 0;
DieterGraef 24:5396b6a93262 625 for(int n = 0; read_len < total; n++)
DieterGraef 24:5396b6a93262 626 {
DieterGraef 24:5396b6a93262 627 int size = std::min((int)total-read_len, ep->getSize());
DieterGraef 24:5396b6a93262 628 int result = token_in(ep, data+read_len, size, retryLimit);
DieterGraef 24:5396b6a93262 629 if (result < 0)
DieterGraef 24:5396b6a93262 630 {
DieterGraef 24:5396b6a93262 631 if (block)
DieterGraef 24:5396b6a93262 632 {
DieterGraef 24:5396b6a93262 633 return -1;
DieterGraef 24:5396b6a93262 634 }
DieterGraef 24:5396b6a93262 635 if (LastStatus == NAK)
DieterGraef 24:5396b6a93262 636 {
DieterGraef 24:5396b6a93262 637 if (n == 0)
DieterGraef 24:5396b6a93262 638 {
DieterGraef 24:5396b6a93262 639 return -1;
DieterGraef 24:5396b6a93262 640 }
DieterGraef 24:5396b6a93262 641 break;
DieterGraef 24:5396b6a93262 642 }
DieterGraef 24:5396b6a93262 643 return result;
DieterGraef 24:5396b6a93262 644 }
DieterGraef 24:5396b6a93262 645 read_len += result;
DieterGraef 24:5396b6a93262 646 if (result < ep->getSize())
DieterGraef 24:5396b6a93262 647 {
DieterGraef 24:5396b6a93262 648 break;
DieterGraef 24:5396b6a93262 649 }
DieterGraef 24:5396b6a93262 650 }
DieterGraef 24:5396b6a93262 651 return read_len;
DieterGraef 24:5396b6a93262 652 }
DieterGraef 24:5396b6a93262 653
DieterGraef 24:5396b6a93262 654 int USBHALHost::multi_token_out(USBEndpoint* ep, const uint8_t* data, size_t total)
DieterGraef 24:5396b6a93262 655 {
DieterGraef 24:5396b6a93262 656 if (total == 0)
DieterGraef 24:5396b6a93262 657 {
DieterGraef 24:5396b6a93262 658 return token_out(ep);
DieterGraef 24:5396b6a93262 659 }
DieterGraef 24:5396b6a93262 660 int write_len = 0;
DieterGraef 24:5396b6a93262 661 for(int n = 0; write_len < total; n++)
DieterGraef 24:5396b6a93262 662 {
DieterGraef 24:5396b6a93262 663 int size = std::min((int)total-write_len, ep->getSize());
DieterGraef 24:5396b6a93262 664 int result = token_out(ep, data+write_len, size);
DieterGraef 24:5396b6a93262 665 if (result < 0)
DieterGraef 24:5396b6a93262 666 {
DieterGraef 24:5396b6a93262 667 if (LastStatus == NAK)
DieterGraef 24:5396b6a93262 668 {
DieterGraef 24:5396b6a93262 669 if (n == 0)
DieterGraef 24:5396b6a93262 670 {
DieterGraef 24:5396b6a93262 671 return -1;
DieterGraef 24:5396b6a93262 672 }
DieterGraef 24:5396b6a93262 673 break;
DieterGraef 24:5396b6a93262 674 }
DieterGraef 24:5396b6a93262 675 USB_DBG("token_out result=%d %02x", result, LastStatus);
DieterGraef 24:5396b6a93262 676 return result;
DieterGraef 24:5396b6a93262 677 }
DieterGraef 24:5396b6a93262 678 write_len += result;
DieterGraef 24:5396b6a93262 679 if (result < ep->getSize())
DieterGraef 24:5396b6a93262 680 {
DieterGraef 24:5396b6a93262 681 break;
DieterGraef 24:5396b6a93262 682 }
DieterGraef 24:5396b6a93262 683 }
DieterGraef 24:5396b6a93262 684 return write_len;
DieterGraef 24:5396b6a93262 685 }
DieterGraef 24:5396b6a93262 686 void USBHALHost::multi_token_inNB(USBEndpoint* ep, uint8_t* data, int size)
DieterGraef 24:5396b6a93262 687 {
DieterGraef 24:5396b6a93262 688 //USB_TRACE1(size);
DieterGraef 24:5396b6a93262 689 //USB_TEST_ASSERT(ep->getState() != USB_TYPE_PROCESSING);
DieterGraef 24:5396b6a93262 690 ep->setBuffer(data, size);
DieterGraef 24:5396b6a93262 691 ep->setState(USB_TYPE_PROCESSING);
DieterGraef 24:5396b6a93262 692 }
DieterGraef 24:5396b6a93262 693
DieterGraef 24:5396b6a93262 694 USB_TYPE USBHALHost::multi_token_inNB_result(USBEndpoint* ep)
DieterGraef 24:5396b6a93262 695 {
DieterGraef 24:5396b6a93262 696 //USB_TEST_ASSERT(ep->getState() == USB_TYPE_PROCESSING);
DieterGraef 24:5396b6a93262 697 uint8_t* buf = ep->getBufStart();
DieterGraef 24:5396b6a93262 698 int size = ep->getBufSize();
DieterGraef 24:5396b6a93262 699 int result = multi_token_in(ep, buf, size, false);
DieterGraef 24:5396b6a93262 700 //USB_TRACE1(result);
DieterGraef 24:5396b6a93262 701 if (result < 0)
DieterGraef 24:5396b6a93262 702 {
DieterGraef 24:5396b6a93262 703 return USB_TYPE_PROCESSING;
DieterGraef 24:5396b6a93262 704 }
DieterGraef 24:5396b6a93262 705 ep->setLengthTransferred(result);
DieterGraef 24:5396b6a93262 706 ep->setState(USB_TYPE_IDLE);
DieterGraef 24:5396b6a93262 707 return USB_TYPE_OK;
DieterGraef 24:5396b6a93262 708
DieterGraef 24:5396b6a93262 709 }
DieterGraef 24:5396b6a93262 710
DieterGraef 24:5396b6a93262 711 void USBHALHost::setToggle(USBEndpoint* ep, uint8_t toggle)
DieterGraef 24:5396b6a93262 712 {
DieterGraef 24:5396b6a93262 713 //USB_TEST_ASSERT(toggle == 1);
DieterGraef 24:5396b6a93262 714 ep->setData01(toggle == 0 ? DATA0 : DATA1);
DieterGraef 24:5396b6a93262 715 }
DieterGraef 24:5396b6a93262 716
DieterGraef 24:5396b6a93262 717 int USBHALHost::epint_setup(USBEndpoint* ep)
DieterGraef 24:5396b6a93262 718 {
DieterGraef 24:5396b6a93262 719 return 1;
DieterGraef 24:5396b6a93262 720 }
DieterGraef 24:5396b6a93262 721
DieterGraef 24:5396b6a93262 722 void USBHALHost::_usbisr(void)
DieterGraef 24:5396b6a93262 723 {
DieterGraef 24:5396b6a93262 724 instHost->usbisr();
DieterGraef 24:5396b6a93262 725 }
DieterGraef 24:5396b6a93262 726
DieterGraef 24:5396b6a93262 727
DieterGraef 24:5396b6a93262 728 void USBHALHost::usbisr(void)
DieterGraef 24:5396b6a93262 729 {
DieterGraef 24:5396b6a93262 730 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
DieterGraef 24:5396b6a93262 731 uint32_t i = 0 , interrupt = 0;
DieterGraef 24:5396b6a93262 732
DieterGraef 24:5396b6a93262 733 /* ensure that we are in device mode */
DieterGraef 24:5396b6a93262 734 if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST)
DieterGraef 24:5396b6a93262 735 {
DieterGraef 24:5396b6a93262 736 /* avoid spurious interrupt */
DieterGraef 24:5396b6a93262 737 if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd))
DieterGraef 24:5396b6a93262 738 {
DieterGraef 24:5396b6a93262 739 return;
DieterGraef 24:5396b6a93262 740 }
DieterGraef 24:5396b6a93262 741
DieterGraef 24:5396b6a93262 742 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT))
DieterGraef 24:5396b6a93262 743 {
DieterGraef 24:5396b6a93262 744 /* incorrect mode, acknowledge the interrupt */
DieterGraef 24:5396b6a93262 745 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT);
DieterGraef 24:5396b6a93262 746 }
DieterGraef 24:5396b6a93262 747
DieterGraef 24:5396b6a93262 748 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR))
DieterGraef 24:5396b6a93262 749 {
DieterGraef 24:5396b6a93262 750 /* incorrect mode, acknowledge the interrupt */
DieterGraef 24:5396b6a93262 751 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR);
DieterGraef 24:5396b6a93262 752 }
DieterGraef 24:5396b6a93262 753
DieterGraef 24:5396b6a93262 754 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE))
DieterGraef 24:5396b6a93262 755 {
DieterGraef 24:5396b6a93262 756 /* incorrect mode, acknowledge the interrupt */
DieterGraef 24:5396b6a93262 757 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE);
DieterGraef 24:5396b6a93262 758 }
DieterGraef 24:5396b6a93262 759
DieterGraef 24:5396b6a93262 760 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS))
DieterGraef 24:5396b6a93262 761 {
DieterGraef 24:5396b6a93262 762 /* incorrect mode, acknowledge the interrupt */
DieterGraef 24:5396b6a93262 763 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS);
DieterGraef 24:5396b6a93262 764 }
DieterGraef 24:5396b6a93262 765
DieterGraef 24:5396b6a93262 766 /* Handle Host Disconnect Interrupts */
DieterGraef 24:5396b6a93262 767 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT))
DieterGraef 24:5396b6a93262 768 {
DieterGraef 24:5396b6a93262 769
DieterGraef 24:5396b6a93262 770 /* Cleanup HPRT */
DieterGraef 24:5396b6a93262 771 USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
DieterGraef 24:5396b6a93262 772 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
DieterGraef 24:5396b6a93262 773
DieterGraef 24:5396b6a93262 774 /* Handle Host Port Interrupts */
DieterGraef 24:5396b6a93262 775 HAL_HCD_Disconnect_Callback(hhcd);
DieterGraef 24:5396b6a93262 776 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
DieterGraef 24:5396b6a93262 777 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT);
DieterGraef 24:5396b6a93262 778 }
DieterGraef 24:5396b6a93262 779
DieterGraef 24:5396b6a93262 780 /* Handle Host Port Interrupts */
DieterGraef 24:5396b6a93262 781 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT))
DieterGraef 24:5396b6a93262 782 {
DieterGraef 24:5396b6a93262 783 //
DieterGraef 24:5396b6a93262 784 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
DieterGraef 24:5396b6a93262 785 __IO uint32_t hprt0, hprt0_dup;
DieterGraef 24:5396b6a93262 786
DieterGraef 24:5396b6a93262 787 /* Handle Host Port Interrupts */
DieterGraef 24:5396b6a93262 788 hprt0 = USBx_HPRT0;
DieterGraef 24:5396b6a93262 789 hprt0_dup = USBx_HPRT0;
DieterGraef 24:5396b6a93262 790
DieterGraef 24:5396b6a93262 791 hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
DieterGraef 24:5396b6a93262 792 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
DieterGraef 24:5396b6a93262 793
DieterGraef 24:5396b6a93262 794 /* Check wether Port Connect Detected */
DieterGraef 24:5396b6a93262 795 if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET)
DieterGraef 24:5396b6a93262 796 {
DieterGraef 24:5396b6a93262 797 if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS)
DieterGraef 24:5396b6a93262 798 {
DieterGraef 24:5396b6a93262 799 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
DieterGraef 24:5396b6a93262 800 HAL_HCD_Connect_Callback(hhcd);
DieterGraef 24:5396b6a93262 801 }
DieterGraef 24:5396b6a93262 802 hprt0_dup |= USB_OTG_HPRT_PCDET;
DieterGraef 24:5396b6a93262 803
DieterGraef 24:5396b6a93262 804 }
DieterGraef 24:5396b6a93262 805
DieterGraef 24:5396b6a93262 806 /* Check whether Port Enable Changed */
DieterGraef 24:5396b6a93262 807 if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG)
DieterGraef 24:5396b6a93262 808 {
DieterGraef 24:5396b6a93262 809 hprt0_dup |= USB_OTG_HPRT_PENCHNG;
DieterGraef 24:5396b6a93262 810
DieterGraef 24:5396b6a93262 811 if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA)
DieterGraef 24:5396b6a93262 812 {
DieterGraef 24:5396b6a93262 813 if(hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY)
DieterGraef 24:5396b6a93262 814 {
DieterGraef 24:5396b6a93262 815 if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17))
DieterGraef 24:5396b6a93262 816 {
DieterGraef 24:5396b6a93262 817 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ );
DieterGraef 24:5396b6a93262 818 }
DieterGraef 24:5396b6a93262 819 else
DieterGraef 24:5396b6a93262 820 {
DieterGraef 24:5396b6a93262 821 USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ );
DieterGraef 24:5396b6a93262 822 }
DieterGraef 24:5396b6a93262 823 }
DieterGraef 24:5396b6a93262 824 else
DieterGraef 24:5396b6a93262 825 {
DieterGraef 24:5396b6a93262 826 if(hhcd->Init.speed == HCD_SPEED_FULL)
DieterGraef 24:5396b6a93262 827 {
DieterGraef 24:5396b6a93262 828 USBx_HOST->HFIR = (uint32_t)60000;
DieterGraef 24:5396b6a93262 829 }
DieterGraef 24:5396b6a93262 830 }
DieterGraef 24:5396b6a93262 831 HAL_HCD_Connect_Callback(hhcd);
DieterGraef 24:5396b6a93262 832
DieterGraef 24:5396b6a93262 833 if(hhcd->Init.speed == HCD_SPEED_HIGH)
DieterGraef 24:5396b6a93262 834 {
DieterGraef 24:5396b6a93262 835 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
DieterGraef 24:5396b6a93262 836 }
DieterGraef 24:5396b6a93262 837 }
DieterGraef 24:5396b6a93262 838 else
DieterGraef 24:5396b6a93262 839 {
DieterGraef 24:5396b6a93262 840 /* Cleanup HPRT */
DieterGraef 24:5396b6a93262 841 USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\
DieterGraef 24:5396b6a93262 842 USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG );
DieterGraef 24:5396b6a93262 843
DieterGraef 24:5396b6a93262 844 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT);
DieterGraef 24:5396b6a93262 845 }
DieterGraef 24:5396b6a93262 846 }
DieterGraef 24:5396b6a93262 847
DieterGraef 24:5396b6a93262 848 /* Check For an overcurrent */
DieterGraef 24:5396b6a93262 849 if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG)
DieterGraef 24:5396b6a93262 850 {
DieterGraef 24:5396b6a93262 851 hprt0_dup |= USB_OTG_HPRT_POCCHNG;
DieterGraef 24:5396b6a93262 852 }
DieterGraef 24:5396b6a93262 853
DieterGraef 24:5396b6a93262 854 /* Clear Port Interrupts */
DieterGraef 24:5396b6a93262 855 USBx_HPRT0 = hprt0_dup;
DieterGraef 24:5396b6a93262 856 }
DieterGraef 24:5396b6a93262 857
DieterGraef 24:5396b6a93262 858
DieterGraef 24:5396b6a93262 859 //
DieterGraef 24:5396b6a93262 860
DieterGraef 24:5396b6a93262 861
DieterGraef 24:5396b6a93262 862 /* Handle Host SOF Interrupts */
DieterGraef 24:5396b6a93262 863 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF))
DieterGraef 24:5396b6a93262 864 {
DieterGraef 24:5396b6a93262 865 HAL_HCD_SOF_Callback(hhcd);
DieterGraef 24:5396b6a93262 866 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF);
DieterGraef 24:5396b6a93262 867 }
DieterGraef 24:5396b6a93262 868
DieterGraef 24:5396b6a93262 869 /* Handle Host channel Interrupts */
DieterGraef 24:5396b6a93262 870 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT))
DieterGraef 24:5396b6a93262 871 {
DieterGraef 24:5396b6a93262 872
DieterGraef 24:5396b6a93262 873 interrupt = USB_HC_ReadInterrupt(hhcd->Instance);
DieterGraef 24:5396b6a93262 874 for (i = 0; i < hhcd->Init.Host_channels ; i++)
DieterGraef 24:5396b6a93262 875 {
DieterGraef 24:5396b6a93262 876 if (interrupt & (1 << i))
DieterGraef 24:5396b6a93262 877 {
DieterGraef 24:5396b6a93262 878 if ((USBx_HC(i)->HCCHAR) & USB_OTG_HCCHAR_EPDIR)
DieterGraef 24:5396b6a93262 879 {
DieterGraef 24:5396b6a93262 880 //
DieterGraef 24:5396b6a93262 881 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
DieterGraef 24:5396b6a93262 882 uint8_t chnum = i;
DieterGraef 24:5396b6a93262 883 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
DieterGraef 24:5396b6a93262 884 {
DieterGraef 24:5396b6a93262 885 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
DieterGraef 24:5396b6a93262 886 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 887 }
DieterGraef 24:5396b6a93262 888 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
DieterGraef 24:5396b6a93262 889 {
DieterGraef 24:5396b6a93262 890 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
DieterGraef 24:5396b6a93262 891 }
DieterGraef 24:5396b6a93262 892
DieterGraef 24:5396b6a93262 893 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
DieterGraef 24:5396b6a93262 894 {
DieterGraef 24:5396b6a93262 895 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 896 hhcd->hc[chnum].state = HC_STALL;
DieterGraef 24:5396b6a93262 897 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
DieterGraef 24:5396b6a93262 898 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
DieterGraef 24:5396b6a93262 899 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 900 }
DieterGraef 24:5396b6a93262 901 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
DieterGraef 24:5396b6a93262 902 {
DieterGraef 24:5396b6a93262 903 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 904 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 905 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
DieterGraef 24:5396b6a93262 906 hhcd->hc[chnum].state = HC_DATATGLERR;
DieterGraef 24:5396b6a93262 907 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
DieterGraef 24:5396b6a93262 908 }
DieterGraef 24:5396b6a93262 909
DieterGraef 24:5396b6a93262 910 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
DieterGraef 24:5396b6a93262 911 {
DieterGraef 24:5396b6a93262 912 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 913 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 914 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
DieterGraef 24:5396b6a93262 915 }
DieterGraef 24:5396b6a93262 916
DieterGraef 24:5396b6a93262 917 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
DieterGraef 24:5396b6a93262 918 {
DieterGraef 24:5396b6a93262 919
DieterGraef 24:5396b6a93262 920 if (hhcd->Init.dma_enable)
DieterGraef 24:5396b6a93262 921 {
DieterGraef 24:5396b6a93262 922 hhcd->hc[chnum].xfer_count = hhcd->hc[chnum].xfer_len - \
DieterGraef 24:5396b6a93262 923 (USBx_HC(chnum)->HCTSIZ & USB_OTG_HCTSIZ_XFRSIZ);
DieterGraef 24:5396b6a93262 924 }
DieterGraef 24:5396b6a93262 925
DieterGraef 24:5396b6a93262 926 hhcd->hc[chnum].state = HC_XFRC;
DieterGraef 24:5396b6a93262 927 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
DieterGraef 24:5396b6a93262 928
DieterGraef 24:5396b6a93262 929
DieterGraef 24:5396b6a93262 930 if ((hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)||
DieterGraef 24:5396b6a93262 931 (hhcd->hc[chnum].ep_type == EP_TYPE_BULK))
DieterGraef 24:5396b6a93262 932 {
DieterGraef 24:5396b6a93262 933 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 934 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 935 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
DieterGraef 24:5396b6a93262 936
DieterGraef 24:5396b6a93262 937 }
DieterGraef 24:5396b6a93262 938 else if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
DieterGraef 24:5396b6a93262 939 {
DieterGraef 24:5396b6a93262 940 USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
DieterGraef 24:5396b6a93262 941 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 942 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 943 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
DieterGraef 24:5396b6a93262 944 }
DieterGraef 24:5396b6a93262 945 else if(hhcd->hc[chnum].ep_type == EP_TYPE_ISOC)
DieterGraef 24:5396b6a93262 946 {
DieterGraef 24:5396b6a93262 947 USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM;
DieterGraef 24:5396b6a93262 948 hhcd->hc[chnum].urb_state = URB_DONE;
DieterGraef 24:5396b6a93262 949 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
DieterGraef 24:5396b6a93262 950 }
DieterGraef 24:5396b6a93262 951 hhcd->hc[chnum].toggle_in ^= 1;
DieterGraef 24:5396b6a93262 952
DieterGraef 24:5396b6a93262 953 }
DieterGraef 24:5396b6a93262 954 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
DieterGraef 24:5396b6a93262 955 {
DieterGraef 24:5396b6a93262 956 __HAL_HCD_MASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 957
DieterGraef 24:5396b6a93262 958 if(hhcd->hc[chnum].state == HC_XFRC)
DieterGraef 24:5396b6a93262 959 {
DieterGraef 24:5396b6a93262 960 hhcd->hc[chnum].urb_state = URB_DONE;
DieterGraef 24:5396b6a93262 961 }
DieterGraef 24:5396b6a93262 962
DieterGraef 24:5396b6a93262 963 else if (hhcd->hc[chnum].state == HC_NAK)
DieterGraef 24:5396b6a93262 964 {
DieterGraef 24:5396b6a93262 965 hhcd->hc[chnum].urb_state = URB_DONE;
DieterGraef 24:5396b6a93262 966 }
DieterGraef 24:5396b6a93262 967
DieterGraef 24:5396b6a93262 968 else if (hhcd->hc[chnum].state == HC_STALL)
DieterGraef 24:5396b6a93262 969 {
DieterGraef 24:5396b6a93262 970 hhcd->hc[chnum].urb_state = URB_STALL;
DieterGraef 24:5396b6a93262 971 }
DieterGraef 24:5396b6a93262 972
DieterGraef 24:5396b6a93262 973 else if (hhcd->hc[chnum].state == HC_XACTERR)
DieterGraef 24:5396b6a93262 974 {
DieterGraef 24:5396b6a93262 975 hhcd->hc[chnum].urb_state = URB_NOTREADY;
DieterGraef 24:5396b6a93262 976 }
DieterGraef 24:5396b6a93262 977
DieterGraef 24:5396b6a93262 978 else if (hhcd->hc[chnum].state == HC_DATATGLERR)
DieterGraef 24:5396b6a93262 979 {
DieterGraef 24:5396b6a93262 980 hhcd->hc[chnum].urb_state = URB_ERROR;
DieterGraef 24:5396b6a93262 981 }
DieterGraef 24:5396b6a93262 982
DieterGraef 24:5396b6a93262 983 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
DieterGraef 24:5396b6a93262 984 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
DieterGraef 24:5396b6a93262 985 }
DieterGraef 24:5396b6a93262 986
DieterGraef 24:5396b6a93262 987 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
DieterGraef 24:5396b6a93262 988 {
DieterGraef 24:5396b6a93262 989 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 990 hhcd->hc[chnum].state = HC_XACTERR;
DieterGraef 24:5396b6a93262 991 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 992 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
DieterGraef 24:5396b6a93262 993 }
DieterGraef 24:5396b6a93262 994 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
DieterGraef 24:5396b6a93262 995 {
DieterGraef 24:5396b6a93262 996 if(hhcd->hc[chnum].ep_type == EP_TYPE_INTR)
DieterGraef 24:5396b6a93262 997 {
DieterGraef 24:5396b6a93262 998 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 999 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 1000 }
DieterGraef 24:5396b6a93262 1001 else if (hhcd->hc[chnum].ep_type == EP_TYPE_CTRL)
DieterGraef 24:5396b6a93262 1002 {
DieterGraef 24:5396b6a93262 1003 /* re-activate the channel */
DieterGraef 24:5396b6a93262 1004 USBx_HC(chnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHDIS;
DieterGraef 24:5396b6a93262 1005 USBx_HC(chnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
DieterGraef 24:5396b6a93262 1006
DieterGraef 24:5396b6a93262 1007 }
DieterGraef 24:5396b6a93262 1008
DieterGraef 24:5396b6a93262 1009 else if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)
DieterGraef 24:5396b6a93262 1010 {
DieterGraef 24:5396b6a93262 1011 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 1012 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 1013 }
DieterGraef 24:5396b6a93262 1014
DieterGraef 24:5396b6a93262 1015 hhcd->hc[chnum].state = HC_NAK;
DieterGraef 24:5396b6a93262 1016 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
DieterGraef 24:5396b6a93262 1017 }
DieterGraef 24:5396b6a93262 1018 //
DieterGraef 24:5396b6a93262 1019 }
DieterGraef 24:5396b6a93262 1020 else
DieterGraef 24:5396b6a93262 1021 {
DieterGraef 24:5396b6a93262 1022 //
DieterGraef 24:5396b6a93262 1023 uint8_t chnum=i;
DieterGraef 24:5396b6a93262 1024 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
DieterGraef 24:5396b6a93262 1025
DieterGraef 24:5396b6a93262 1026 if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_AHBERR)
DieterGraef 24:5396b6a93262 1027 {
DieterGraef 24:5396b6a93262 1028 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_AHBERR);
DieterGraef 24:5396b6a93262 1029 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 1030 }
DieterGraef 24:5396b6a93262 1031 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_ACK)
DieterGraef 24:5396b6a93262 1032 {
DieterGraef 24:5396b6a93262 1033 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_ACK);
DieterGraef 24:5396b6a93262 1034
DieterGraef 24:5396b6a93262 1035 if( hhcd->hc[chnum].do_ping == 1)
DieterGraef 24:5396b6a93262 1036 {
DieterGraef 24:5396b6a93262 1037 hhcd->hc[chnum].state = HC_NYET;
DieterGraef 24:5396b6a93262 1038 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 1039 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 1040 hhcd->hc[chnum].urb_state = URB_NOTREADY;
DieterGraef 24:5396b6a93262 1041 }
DieterGraef 24:5396b6a93262 1042 }
DieterGraef 24:5396b6a93262 1043
DieterGraef 24:5396b6a93262 1044 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NYET)
DieterGraef 24:5396b6a93262 1045 {
DieterGraef 24:5396b6a93262 1046 hhcd->hc[chnum].state = HC_NYET;
DieterGraef 24:5396b6a93262 1047 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 1048 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 1049 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NYET);
DieterGraef 24:5396b6a93262 1050
DieterGraef 24:5396b6a93262 1051 }
DieterGraef 24:5396b6a93262 1052
DieterGraef 24:5396b6a93262 1053 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_FRMOR)
DieterGraef 24:5396b6a93262 1054 {
DieterGraef 24:5396b6a93262 1055 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 1056 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 1057 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_FRMOR);
DieterGraef 24:5396b6a93262 1058 }
DieterGraef 24:5396b6a93262 1059
DieterGraef 24:5396b6a93262 1060 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_XFRC)
DieterGraef 24:5396b6a93262 1061 {
DieterGraef 24:5396b6a93262 1062 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 1063 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 1064 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_XFRC);
DieterGraef 24:5396b6a93262 1065 hhcd->hc[chnum].state = HC_XFRC;
DieterGraef 24:5396b6a93262 1066
DieterGraef 24:5396b6a93262 1067 }
DieterGraef 24:5396b6a93262 1068
DieterGraef 24:5396b6a93262 1069 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_STALL)
DieterGraef 24:5396b6a93262 1070 {
DieterGraef 24:5396b6a93262 1071 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_STALL);
DieterGraef 24:5396b6a93262 1072 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 1073 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 1074 hhcd->hc[chnum].state = HC_STALL;
DieterGraef 24:5396b6a93262 1075 }
DieterGraef 24:5396b6a93262 1076
DieterGraef 24:5396b6a93262 1077 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_NAK)
DieterGraef 24:5396b6a93262 1078 {
DieterGraef 24:5396b6a93262 1079 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 1080 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 1081 hhcd->hc[chnum].state = HC_NAK;
DieterGraef 24:5396b6a93262 1082 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
DieterGraef 24:5396b6a93262 1083 }
DieterGraef 24:5396b6a93262 1084
DieterGraef 24:5396b6a93262 1085 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_TXERR)
DieterGraef 24:5396b6a93262 1086 {
DieterGraef 24:5396b6a93262 1087 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 1088 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 1089 hhcd->hc[chnum].state = HC_XACTERR;
DieterGraef 24:5396b6a93262 1090 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_TXERR);
DieterGraef 24:5396b6a93262 1091 }
DieterGraef 24:5396b6a93262 1092
DieterGraef 24:5396b6a93262 1093 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_DTERR)
DieterGraef 24:5396b6a93262 1094 {
DieterGraef 24:5396b6a93262 1095 __HAL_HCD_UNMASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 1096 USB_HC_Halt(hhcd->Instance, chnum);
DieterGraef 24:5396b6a93262 1097 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_NAK);
DieterGraef 24:5396b6a93262 1098 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_DTERR);
DieterGraef 24:5396b6a93262 1099 hhcd->hc[chnum].state = HC_DATATGLERR;
DieterGraef 24:5396b6a93262 1100 }
DieterGraef 24:5396b6a93262 1101
DieterGraef 24:5396b6a93262 1102
DieterGraef 24:5396b6a93262 1103 else if ((USBx_HC(chnum)->HCINT) & USB_OTG_HCINT_CHH)
DieterGraef 24:5396b6a93262 1104 {
DieterGraef 24:5396b6a93262 1105 __HAL_HCD_MASK_HALT_HC_INT(chnum);
DieterGraef 24:5396b6a93262 1106
DieterGraef 24:5396b6a93262 1107 if(hhcd->hc[chnum].state == HC_XFRC)
DieterGraef 24:5396b6a93262 1108 {
DieterGraef 24:5396b6a93262 1109 hhcd->hc[chnum].urb_state = URB_DONE;
DieterGraef 24:5396b6a93262 1110 if (hhcd->hc[chnum].ep_type == EP_TYPE_BULK)
DieterGraef 24:5396b6a93262 1111 {
DieterGraef 24:5396b6a93262 1112 hhcd->hc[chnum].toggle_out ^= 1;
DieterGraef 24:5396b6a93262 1113 }
DieterGraef 24:5396b6a93262 1114 }
DieterGraef 24:5396b6a93262 1115 else if (hhcd->hc[chnum].state == HC_NAK)
DieterGraef 24:5396b6a93262 1116 {
DieterGraef 24:5396b6a93262 1117 hhcd->hc[chnum].urb_state = URB_NOTREADY;
DieterGraef 24:5396b6a93262 1118 }
DieterGraef 24:5396b6a93262 1119
DieterGraef 24:5396b6a93262 1120 else if (hhcd->hc[chnum].state == HC_NYET)
DieterGraef 24:5396b6a93262 1121 {
DieterGraef 24:5396b6a93262 1122 hhcd->hc[chnum].urb_state = URB_NOTREADY;
DieterGraef 24:5396b6a93262 1123 hhcd->hc[chnum].do_ping = 0;
DieterGraef 24:5396b6a93262 1124 }
DieterGraef 24:5396b6a93262 1125
DieterGraef 24:5396b6a93262 1126 else if (hhcd->hc[chnum].state == HC_STALL)
DieterGraef 24:5396b6a93262 1127 {
DieterGraef 24:5396b6a93262 1128 hhcd->hc[chnum].urb_state = URB_STALL;
DieterGraef 24:5396b6a93262 1129 }
DieterGraef 24:5396b6a93262 1130
DieterGraef 24:5396b6a93262 1131 else if(hhcd->hc[chnum].state == HC_XACTERR)
DieterGraef 24:5396b6a93262 1132 {
DieterGraef 24:5396b6a93262 1133 hhcd->hc[chnum].urb_state = URB_NOTREADY;
DieterGraef 24:5396b6a93262 1134 }
DieterGraef 24:5396b6a93262 1135
DieterGraef 24:5396b6a93262 1136 else if (hhcd->hc[chnum].state == HC_DATATGLERR)
DieterGraef 24:5396b6a93262 1137 {
DieterGraef 24:5396b6a93262 1138 hhcd->hc[chnum].urb_state = URB_ERROR;
DieterGraef 24:5396b6a93262 1139 }
DieterGraef 24:5396b6a93262 1140
DieterGraef 24:5396b6a93262 1141 __HAL_HCD_CLEAR_HC_INT(chnum, USB_OTG_HCINT_CHH);
DieterGraef 24:5396b6a93262 1142 HAL_HCD_HC_NotifyURBChange_Callback(hhcd, chnum, hhcd->hc[chnum].urb_state);
DieterGraef 24:5396b6a93262 1143 }
DieterGraef 24:5396b6a93262 1144 //
DieterGraef 24:5396b6a93262 1145 }
DieterGraef 24:5396b6a93262 1146 }
DieterGraef 24:5396b6a93262 1147 }
DieterGraef 24:5396b6a93262 1148
DieterGraef 24:5396b6a93262 1149 __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT);
DieterGraef 24:5396b6a93262 1150 }
DieterGraef 24:5396b6a93262 1151
DieterGraef 24:5396b6a93262 1152 /* Handle Rx Queue Level Interrupts */
DieterGraef 24:5396b6a93262 1153 if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL))
DieterGraef 24:5396b6a93262 1154 {
DieterGraef 24:5396b6a93262 1155 USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
DieterGraef 24:5396b6a93262 1156
DieterGraef 24:5396b6a93262 1157 //
DieterGraef 24:5396b6a93262 1158 USB_OTG_GlobalTypeDef *USBx = hhcd->Instance;
DieterGraef 24:5396b6a93262 1159 uint8_t channelnum =0;
DieterGraef 24:5396b6a93262 1160 uint32_t pktsts;
DieterGraef 24:5396b6a93262 1161 uint32_t pktcnt;
DieterGraef 24:5396b6a93262 1162 uint32_t temp = 0;
DieterGraef 24:5396b6a93262 1163
DieterGraef 24:5396b6a93262 1164 temp = hhcd->Instance->GRXSTSP ;
DieterGraef 24:5396b6a93262 1165 channelnum = temp & USB_OTG_GRXSTSP_EPNUM;
DieterGraef 24:5396b6a93262 1166 pktsts = (temp & USB_OTG_GRXSTSP_PKTSTS) >> 17;
DieterGraef 24:5396b6a93262 1167 pktcnt = (temp & USB_OTG_GRXSTSP_BCNT) >> 4;
DieterGraef 24:5396b6a93262 1168
DieterGraef 24:5396b6a93262 1169 switch (pktsts)
DieterGraef 24:5396b6a93262 1170 {
DieterGraef 24:5396b6a93262 1171 case GRXSTS_PKTSTS_IN:
DieterGraef 24:5396b6a93262 1172 /* Read the data into the host buffer. */
DieterGraef 24:5396b6a93262 1173 if ((pktcnt > 0) && (hhcd->hc[channelnum].xfer_buff != (void *)0))
DieterGraef 24:5396b6a93262 1174 {
DieterGraef 24:5396b6a93262 1175
DieterGraef 24:5396b6a93262 1176 USB_ReadPacket(hhcd->Instance, hhcd->hc[channelnum].xfer_buff, pktcnt);
DieterGraef 24:5396b6a93262 1177
DieterGraef 24:5396b6a93262 1178 /*manage multiple Xfer */
DieterGraef 24:5396b6a93262 1179 hhcd->hc[channelnum].xfer_buff += pktcnt;
DieterGraef 24:5396b6a93262 1180 hhcd->hc[channelnum].xfer_count += pktcnt;
DieterGraef 24:5396b6a93262 1181
DieterGraef 24:5396b6a93262 1182 if((USBx_HC(channelnum)->HCTSIZ & USB_OTG_HCTSIZ_PKTCNT) > 0)
DieterGraef 24:5396b6a93262 1183 {
DieterGraef 24:5396b6a93262 1184 /* re-activate the channel when more packets are expected */
DieterGraef 24:5396b6a93262 1185 USBx_HC(channelnum)->HCCHAR &= ~USB_OTG_HCCHAR_CHDIS;
DieterGraef 24:5396b6a93262 1186 USBx_HC(channelnum)->HCCHAR |= USB_OTG_HCCHAR_CHENA;
DieterGraef 24:5396b6a93262 1187 hhcd->hc[channelnum].toggle_in ^= 1;
DieterGraef 24:5396b6a93262 1188 }
DieterGraef 24:5396b6a93262 1189 }
DieterGraef 24:5396b6a93262 1190 break;
DieterGraef 24:5396b6a93262 1191
DieterGraef 24:5396b6a93262 1192 case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
DieterGraef 24:5396b6a93262 1193 break;
DieterGraef 24:5396b6a93262 1194 case GRXSTS_PKTSTS_IN_XFER_COMP:
DieterGraef 24:5396b6a93262 1195 case GRXSTS_PKTSTS_CH_HALTED:
DieterGraef 24:5396b6a93262 1196 default:
DieterGraef 24:5396b6a93262 1197 break;
DieterGraef 24:5396b6a93262 1198 }
DieterGraef 24:5396b6a93262 1199 //
DieterGraef 24:5396b6a93262 1200
DieterGraef 24:5396b6a93262 1201 USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL);
DieterGraef 24:5396b6a93262 1202 }
DieterGraef 24:5396b6a93262 1203 }
DieterGraef 24:5396b6a93262 1204 }
DieterGraef 24:5396b6a93262 1205
DieterGraef 24:5396b6a93262 1206
DieterGraef 24:5396b6a93262 1207
DieterGraef 24:5396b6a93262 1208 uint8_t HC::slot = 0x00;
DieterGraef 24:5396b6a93262 1209
DieterGraef 24:5396b6a93262 1210 HC::HC(HCD_HandleTypeDef* hhcd_USB)
DieterGraef 24:5396b6a93262 1211 {
DieterGraef 24:5396b6a93262 1212 static const int start = 1;
DieterGraef 24:5396b6a93262 1213 uint8_t mask = (1<<start);
DieterGraef 24:5396b6a93262 1214 hc_USB=hhcd_USB;
DieterGraef 24:5396b6a93262 1215 for(int i = start; i < 8; i++, mask <<= 1)
DieterGraef 24:5396b6a93262 1216 {
DieterGraef 24:5396b6a93262 1217 if (!(slot & mask))
DieterGraef 24:5396b6a93262 1218 {
DieterGraef 24:5396b6a93262 1219 slot |= mask;
DieterGraef 24:5396b6a93262 1220 _ch = i;
DieterGraef 24:5396b6a93262 1221 return;
DieterGraef 24:5396b6a93262 1222 }
DieterGraef 24:5396b6a93262 1223 }
DieterGraef 24:5396b6a93262 1224 _ch = 0; // ERROR!!!
DieterGraef 24:5396b6a93262 1225 }
DieterGraef 24:5396b6a93262 1226
DieterGraef 24:5396b6a93262 1227 HC::HC(HCD_HandleTypeDef* hhcd_USB,int ch)
DieterGraef 24:5396b6a93262 1228 {
DieterGraef 24:5396b6a93262 1229 hc_USB=hhcd_USB;
DieterGraef 24:5396b6a93262 1230 _ch = ch;
DieterGraef 24:5396b6a93262 1231 slot |= (1<<_ch);
DieterGraef 24:5396b6a93262 1232 }
DieterGraef 24:5396b6a93262 1233
DieterGraef 24:5396b6a93262 1234 HC::~HC()
DieterGraef 24:5396b6a93262 1235 {
DieterGraef 24:5396b6a93262 1236 slot &= ~(1<<_ch);
DieterGraef 24:5396b6a93262 1237 }
DieterGraef 24:5396b6a93262 1238
DieterGraef 24:5396b6a93262 1239 HAL_StatusTypeDef HC::Init(int IF_N, uint8_t epnum, uint8_t dev_address, uint8_t speed, uint8_t ep_type, uint16_t mps)
DieterGraef 24:5396b6a93262 1240 {
DieterGraef 24:5396b6a93262 1241 _ep_addr = epnum;
DieterGraef 24:5396b6a93262 1242 _ep_type = ep_type;
DieterGraef 24:5396b6a93262 1243 if(IF_N!=USB_FastSpeed)
DieterGraef 24:5396b6a93262 1244 {
DieterGraef 24:5396b6a93262 1245 while(HAL_HCD_GetState(hc_USB)!=HAL_HCD_STATE_READY);
DieterGraef 24:5396b6a93262 1246 }
DieterGraef 24:5396b6a93262 1247 return HAL_HCD_HC_Init(hc_USB, _ch,
DieterGraef 24:5396b6a93262 1248 epnum, dev_address, speed, ep_type, mps);
DieterGraef 24:5396b6a93262 1249 }
DieterGraef 24:5396b6a93262 1250
DieterGraef 24:5396b6a93262 1251 HAL_StatusTypeDef HC::SubmitRequest(int IF_N,uint8_t* pbuff, uint16_t length, bool setup)
DieterGraef 24:5396b6a93262 1252 {
DieterGraef 24:5396b6a93262 1253 uint32_t tick;
DieterGraef 24:5396b6a93262 1254 tick=HAL_GetTick();
DieterGraef 24:5396b6a93262 1255 while(HAL_GetTick()==tick);
DieterGraef 24:5396b6a93262 1256 if(IF_N!=USB_FastSpeed)
DieterGraef 24:5396b6a93262 1257 {
DieterGraef 24:5396b6a93262 1258 while((hc_USB->Instance->GRXSTSR&0x1E0000)==0x40000);
DieterGraef 24:5396b6a93262 1259 while(((hc_USB->Instance->HNPTXSTS& 0xFFFF)*((hc_USB->Instance->HNPTXSTS& 0x000F0000)>>16))<length);
DieterGraef 24:5396b6a93262 1260 }
DieterGraef 24:5396b6a93262 1261 uint8_t direction = (_ep_addr & 0x80) ? DIR_IN : DIR_OUT;
DieterGraef 24:5396b6a93262 1262 if (_ep_type == EP_TYPE_CTRL)
DieterGraef 24:5396b6a93262 1263 {
DieterGraef 24:5396b6a93262 1264 HCD_HCTypeDef* hc = &hc_USB->hc[_ch];
DieterGraef 24:5396b6a93262 1265 if (setup)
DieterGraef 24:5396b6a93262 1266 {
DieterGraef 24:5396b6a93262 1267 hc->data_pid = HC_PID_SETUP;
DieterGraef 24:5396b6a93262 1268 hc->toggle_out = 0;
DieterGraef 24:5396b6a93262 1269 }
DieterGraef 24:5396b6a93262 1270 else
DieterGraef 24:5396b6a93262 1271 {
DieterGraef 24:5396b6a93262 1272 if (direction == DIR_IN)
DieterGraef 24:5396b6a93262 1273 {
DieterGraef 24:5396b6a93262 1274 if (hc->toggle_in == 0)
DieterGraef 24:5396b6a93262 1275 {
DieterGraef 24:5396b6a93262 1276 hc->data_pid = HC_PID_DATA0;
DieterGraef 24:5396b6a93262 1277 }
DieterGraef 24:5396b6a93262 1278 else
DieterGraef 24:5396b6a93262 1279 {
DieterGraef 24:5396b6a93262 1280 hc->data_pid = HC_PID_DATA1;
DieterGraef 24:5396b6a93262 1281 }
DieterGraef 24:5396b6a93262 1282 }
DieterGraef 24:5396b6a93262 1283 else // OUT
DieterGraef 24:5396b6a93262 1284 {
DieterGraef 24:5396b6a93262 1285 if (hc->toggle_out == 0)
DieterGraef 24:5396b6a93262 1286 {
DieterGraef 24:5396b6a93262 1287 hc->data_pid = HC_PID_DATA0;
DieterGraef 24:5396b6a93262 1288 }
DieterGraef 24:5396b6a93262 1289 else
DieterGraef 24:5396b6a93262 1290 {
DieterGraef 24:5396b6a93262 1291 hc->data_pid = HC_PID_DATA1;
DieterGraef 24:5396b6a93262 1292 }
DieterGraef 24:5396b6a93262 1293 }
DieterGraef 24:5396b6a93262 1294 }
DieterGraef 24:5396b6a93262 1295 hc->xfer_buff = pbuff;
DieterGraef 24:5396b6a93262 1296 hc->xfer_len = length;
DieterGraef 24:5396b6a93262 1297 hc->urb_state = URB_IDLE;
DieterGraef 24:5396b6a93262 1298 hc->xfer_count = 0;
DieterGraef 24:5396b6a93262 1299 hc->ch_num = _ch;
DieterGraef 24:5396b6a93262 1300 hc->state = HC_IDLE;
DieterGraef 24:5396b6a93262 1301 if(IF_N==USB_FastSpeed)
DieterGraef 24:5396b6a93262 1302 {
DieterGraef 24:5396b6a93262 1303 return USB_HC_StartXfer(hc_USB->Instance, hc, 0);
DieterGraef 24:5396b6a93262 1304 }
DieterGraef 24:5396b6a93262 1305 else
DieterGraef 24:5396b6a93262 1306 {
DieterGraef 24:5396b6a93262 1307 return USB_HC_StartXfer(hc_USB->Instance, hc, 1);
DieterGraef 24:5396b6a93262 1308 }
DieterGraef 24:5396b6a93262 1309 }
DieterGraef 24:5396b6a93262 1310 return HAL_HCD_HC_SubmitRequest(hc_USB, _ch,
DieterGraef 24:5396b6a93262 1311 direction, _ep_type, 0, pbuff, length, 0);
DieterGraef 24:5396b6a93262 1312 }
DieterGraef 24:5396b6a93262 1313
DieterGraef 24:5396b6a93262 1314 HCD_URBStateTypeDef HC::GetURBState()
DieterGraef 24:5396b6a93262 1315 {
DieterGraef 24:5396b6a93262 1316 return HAL_HCD_HC_GetURBState(hc_USB, _ch);
DieterGraef 24:5396b6a93262 1317 }
DieterGraef 24:5396b6a93262 1318
DieterGraef 24:5396b6a93262 1319
DieterGraef 24:5396b6a93262 1320
DieterGraef 24:5396b6a93262 1321 HCD_HCStateTypeDef HC::GetState()
DieterGraef 24:5396b6a93262 1322 {
DieterGraef 24:5396b6a93262 1323 return HAL_HCD_HC_GetState(hc_USB, _ch);
DieterGraef 24:5396b6a93262 1324 }
DieterGraef 24:5396b6a93262 1325
DieterGraef 24:5396b6a93262 1326 uint32_t HC::GetXferCount()
DieterGraef 24:5396b6a93262 1327 {
DieterGraef 24:5396b6a93262 1328 return HAL_HCD_HC_GetXferCount(hc_USB, _ch);
DieterGraef 24:5396b6a93262 1329 }
DieterGraef 24:5396b6a93262 1330
DieterGraef 24:5396b6a93262 1331 void HC::SetToggle(uint8_t toggle)
DieterGraef 24:5396b6a93262 1332 {
DieterGraef 24:5396b6a93262 1333 if (_ep_addr & 0x80) // IN
DieterGraef 24:5396b6a93262 1334 {
DieterGraef 24:5396b6a93262 1335 hc_USB->hc[_ch].toggle_in = toggle;
DieterGraef 24:5396b6a93262 1336 }
DieterGraef 24:5396b6a93262 1337 else // OUT
DieterGraef 24:5396b6a93262 1338 {
DieterGraef 24:5396b6a93262 1339 hc_USB->hc[_ch].toggle_out = toggle;
DieterGraef 24:5396b6a93262 1340 }
DieterGraef 24:5396b6a93262 1341 }
DieterGraef 24:5396b6a93262 1342
DieterGraef 24:5396b6a93262 1343 #endif
DieterGraef 24:5396b6a93262 1344
DieterGraef 24:5396b6a93262 1345