mbed library sources
Dependents: frdm_kl05z_gpio_test
Fork of mbed-src by
Diff: targets/cmsis/TARGET_STM/TARGET_NUCLEO_F401RE/stm32f4xx_ll_usb.c
- Revision:
- 106:ced8cbb51063
- Parent:
- 87:085cde657901
- Child:
- 226:b062af740e40
--- a/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F401RE/stm32f4xx_ll_usb.c Mon Feb 24 10:30:08 2014 +0000 +++ b/targets/cmsis/TARGET_STM/TARGET_NUCLEO_F401RE/stm32f4xx_ll_usb.c Wed Feb 26 09:45:12 2014 +0000 @@ -2,8 +2,8 @@ ****************************************************************************** * @file stm32f4xx_ll_usb.c * @author MCD Application Team - * @version V1.0.0RC2 - * @date 04-February-2014 + * @version V1.0.0 + * @date 18-February-2014 * @brief USB Low Layer HAL module driver. * * This file provides firmware functions to manage the following @@ -112,10 +112,6 @@ { USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSD; } - else - { - USBx->GUSBCFG |= USB_OTG_GUSBCFG_ULPIEVBUSI; - } /* Reset after a PHY select */ USB_CoreReset(USBx); } @@ -124,26 +120,14 @@ /* Select FS Embedded PHY */ USBx->GUSBCFG |= USB_OTG_GUSBCFG_PHYSEL; - + /* Reset after a PHY select and set Host mode */ USB_CoreReset(USBx); /* Deactivate the power down*/ USBx->GCCFG = USB_OTG_GCCFG_PWRDWN; - - /*Activate VBUS Sensing A & B */ - USBx->GCCFG |= (USB_OTG_GCCFG_VBUSASEN | USB_OTG_GCCFG_VBUSBSEN); - - if (cfg.vbus_sensing_enable == ENABLE) - { - USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; - } } - if (cfg.Sof_enable == ENABLE) - { - USBx->GCCFG |= USB_OTG_GCCFG_SOFOUTEN; - } - + if(cfg.dma_enable == ENABLE) { USBx->GAHBCFG |= (USB_OTG_GAHBCFG_HBSTLEN_1 | USB_OTG_GAHBCFG_HBSTLEN_2); @@ -216,6 +200,15 @@ HAL_StatusTypeDef USB_DevInit (USB_OTG_GlobalTypeDef *USBx, USB_OTG_CfgTypeDef cfg) { uint32_t i = 0; + + /*Activate VBUS Sensing B */ + USBx->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; + + if (cfg.vbus_sensing_enable == 0) + { + USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; + } + /* Restart the Phy Clock */ USBx_PCGCCTL = 0; @@ -308,9 +301,14 @@ /* Enable interrupts matching to the Device mode ONLY */ USBx->GINTMSK |= (USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_USBRST |\ USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_IEPINT |\ - USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_SOFM |\ - USB_OTG_GINTMSK_IISOIXFRM| USB_OTG_GINTMSK_PXFRM_IISOOXFRM); + USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IISOIXFRM|\ + USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM); + if(cfg.Sof_enable) + { + USBx->GINTMSK |= USB_OTG_GINTMSK_SOFM; + } + if (cfg.vbus_sensing_enable == ENABLE) { USBx->GINTMSK |= (USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_OTGINT); @@ -338,10 +336,11 @@ { if (++count > 200000) { - break; + return HAL_TIMEOUT; } } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH) == USB_OTG_GRSTCTL_TXFFLSH); + return HAL_OK; } @@ -361,10 +360,11 @@ { if (++count > 200000) { - break; + return HAL_TIMEOUT; } } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_RXFFLSH) == USB_OTG_GRSTCTL_RXFFLSH); + return HAL_OK; } @@ -426,22 +426,24 @@ { if (ep->is_in == 1) { + USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))); + if (((USBx_INEP(ep->num)->DIEPCTL) & USB_OTG_DIEPCTL_USBAEP) == 0) { USBx_INEP(ep->num)->DIEPCTL |= ((ep->maxpacket & USB_OTG_DIEPCTL_MPSIZ ) | (ep->type << 18 ) |\ - ((ep->num + 1) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); + ((ep->num) << 22 ) | (USB_OTG_DIEPCTL_SD0PID_SEVNFRM) | (USB_OTG_DIEPCTL_USBAEP)); } - USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num))); + } else { + USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16); + if (((USBx_OUTEP(ep->num)->DOEPCTL) & USB_OTG_DOEPCTL_USBAEP) == 0) { USBx_OUTEP(ep->num)->DOEPCTL |= ((ep->maxpacket & USB_OTG_DOEPCTL_MPSIZ ) | (ep->type << 18 ) |\ - ((ep->num + 1) << 22 ) | (USB_OTG_DOEPCTL_USBAEP)); + (USB_OTG_DIEPCTL_SD0PID_SEVNFRM)| (USB_OTG_DOEPCTL_USBAEP)); } - - USBx_DEVICE->DAINTMSK |= USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16); } return HAL_OK; } @@ -499,13 +501,16 @@ /* Read DEPCTLn register */ if (ep->is_in == 1) { - USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP; USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)))); + USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_IEPM & ((1 << (ep->num)))); + USBx_INEP(ep->num)->DIEPCTL &= ~ USB_OTG_DIEPCTL_USBAEP; } else { - USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP; + USBx_DEVICE->DEACHMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16)); + USBx_DEVICE->DAINTMSK &= ~(USB_OTG_DAINTMSK_OEPM & ((1 << (ep->num)) << 16)); + USBx_OUTEP(ep->num)->DOEPCTL &= ~USB_OTG_DOEPCTL_USBAEP; } return HAL_OK; } @@ -1077,10 +1082,9 @@ /* Wait for AHB master IDLE state. */ do { - HAL_Delay(1); if (++count > 200000) { - return HAL_OK;; + return HAL_TIMEOUT; } } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0); @@ -1093,14 +1097,11 @@ { if (++count > 200000) { - break; + return HAL_TIMEOUT; } } while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST); - /* Wait for at least 3 PHY Clocks*/ - HAL_Delay(1); - return HAL_OK; } @@ -1120,9 +1121,13 @@ /* Restart the Phy Clock */ USBx_PCGCCTL = 0; + /* no VBUS sensing*/ + USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSASEN); + USBx->GCCFG &=~ (USB_OTG_GCCFG_VBUSBSEN); + USBx->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; + /* Disable the FS/LS support mode only */ - if(((cfg.speed == USB_OTG_SPEED_FULL) || - (cfg.speed == USB_OTG_SPEED_LOW))&& + if((cfg.speed == USB_OTG_SPEED_FULL)&& (USBx != USB_OTG_FS)) { USBx_HOST->HCFG |= USB_OTG_HCFG_FSLSS; @@ -1160,7 +1165,7 @@ /* set Rx FIFO size */ USBx->GRXFSIZ = (uint32_t )0x80; USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x60 << 16)& USB_OTG_NPTXFD) | 0x80); - USBx->HPTXFSIZ = (uint32_t )(((0x60 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0); + USBx->HPTXFSIZ = (uint32_t )(((0x40 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0xE0); } @@ -1169,7 +1174,7 @@ /* set Rx FIFO size */ USBx->GRXFSIZ = (uint32_t )0x200; USBx->DIEPTXF0_HNPTXFSIZ = (uint32_t )(((0x100 << 16)& USB_OTG_NPTXFD) | 0x200); - USBx->HPTXFSIZ = (uint32_t )(((0x100 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0x300); + USBx->HPTXFSIZ = (uint32_t )(((0xE0 << 16)& USB_OTG_HPTXFSIZ_PTXFD) | 0x300); } /* Enable the common interrupts */ @@ -1180,12 +1185,9 @@ /* Enable interrupts matching to the Host mode ONLY */ USBx->GINTMSK |= (USB_OTG_GINTMSK_PRTIM | USB_OTG_GINTMSK_HCIM |\ - USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_SOFM |\ - USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM | - USB_OTG_GINTSTS_DISCINT); + USB_OTG_GINTMSK_SOFM |USB_OTG_GINTSTS_DISCINT|\ + USB_OTG_GINTMSK_PXFRM_IISOOXFRM | USB_OTG_GINTMSK_WUIM); - - return HAL_OK; } @@ -1233,7 +1235,7 @@ USBx_HPRT0 = (USB_OTG_HPRT_PRST | hprt0); HAL_Delay (10); /* See Note #1 */ - USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0); + USBx_HPRT0 = ((~USB_OTG_HPRT_PRST) & hprt0); return HAL_OK; } @@ -1396,7 +1398,7 @@ ((ep_type << 18) & USB_OTG_HCCHAR_EPTYP)|\ (mps & USB_OTG_HCCHAR_MPSIZ)); - if (ep_type == HCCHAR_INTR) + if (ep_type == EP_TYPE_INTR) { USBx_HC(ch_num)->HCCHAR |= USB_OTG_HCCHAR_ODDFRM ; } @@ -1540,7 +1542,8 @@ */ HAL_StatusTypeDef USB_HC_Halt(USB_OTG_GlobalTypeDef *USBx , uint8_t hc_num) { - + uint32_t count = 0; + /* Check for space in the request queue to issue the halt. */ if (((USBx_HC(hc_num)->HCCHAR) & (HCCHAR_CTRL << 18)) || ((USBx_HC(hc_num)->HCCHAR) & (HCCHAR_BULK << 18))) { @@ -1548,11 +1551,21 @@ if ((USBx->HNPTXSTS & 0xFFFF) == 0) { - USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA; + USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA; + USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; + USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR; + do + { + if (++count > 1000) + { + break; + } + } + while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA); } else { - USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; + USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; } } else @@ -1561,7 +1574,17 @@ if ((USBx_HOST->HPTXSTS & 0xFFFF) == 0) { - USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA; + USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_CHENA; + USBx_HC(hc_num)->HCCHAR |= USB_OTG_HCCHAR_CHENA; + USBx_HC(hc_num)->HCCHAR &= ~USB_OTG_HCCHAR_EPDIR; + do + { + if (++count > 1000) + { + break; + } + } + while ((USBx_HC(hc_num)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA); } else { @@ -1601,18 +1624,47 @@ HAL_StatusTypeDef USB_StopHost(USB_OTG_GlobalTypeDef *USBx) { uint8_t i; + uint32_t count = 0; + uint32_t value; + USB_DisableGlobalInt(USBx); - /* Halt all the Host Channels */ - for (i = 0; i <= 15; i++) - { - USB_HC_Halt(USBx , i); - } - - /* Flush FIFO */ + /* Flush FIFO */ USB_FlushTxFifo(USBx, 0x10); USB_FlushRxFifo(USBx); + /* Flush out any leftover queued requests. */ + for (i = 0; i <= 15; i++) + { + + value = USBx_HC(i)->HCCHAR ; + value |= USB_OTG_HCCHAR_CHDIS; + value &= ~USB_OTG_HCCHAR_CHENA; + value &= ~USB_OTG_HCCHAR_EPDIR; + USBx_HC(i)->HCCHAR = value; + } + + /* Halt all channels to put them into a known state. */ + for (i = 0; i <= 15; i++) + { + + value = USBx_HC(i)->HCCHAR ; + + value |= USB_OTG_HCCHAR_CHDIS; + value |= USB_OTG_HCCHAR_CHENA; + value &= ~USB_OTG_HCCHAR_EPDIR; + + USBx_HC(i)->HCCHAR = value; + do + { + if (++count > 1000) + { + break; + } + } + while ((USBx_HC(i)->HCCHAR & USB_OTG_HCCHAR_CHENA) == USB_OTG_HCCHAR_CHENA); + } + /* Clear any pending Host interrups */ USBx_HOST->HAINT = 0xFFFFFFFF; USBx->GINTSTS = 0xFFFFFFFF;