Fork of https://developer.mbed.org/users/bscott/code/STM32_USBDevice/
Fork of STM32_USBDevice by
USBHAL_STM32L1.cpp
00001 /* Copyright (c) 2010-2015 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without 00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish, 00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 00007 * Software is furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #if defined(TARGET_STM32L1)||defined(TARGET_STM32F3)||defined(TARGET_STM32F1)||defined(TARGET_STM32F0) 00020 #include "pinmap.h" 00021 #include "USBDevice.h" 00022 00023 #if defined(TARGET_STM32F1) 00024 #define USB_LP_IRQn USB_LP_CAN1_RX0_IRQn 00025 const uint8_t PCD_EP_TYPE_CTRL = EP_TYPE_CTRL; 00026 const uint8_t PCD_EP_TYPE_INTR = EP_TYPE_INTR; 00027 const uint8_t PCD_EP_TYPE_BULK = EP_TYPE_BULK; 00028 const uint8_t PCD_EP_TYPE_ISOC = EP_TYPE_ISOC; 00029 00030 #elif defined(TARGET_STM32L1) 00031 void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state) { 00032 __SYSCFG_CLK_ENABLE(); // for SYSCFG_PMC_USB_PU 00033 if (state == 1) { 00034 __HAL_SYSCFG_USBPULLUP_ENABLE(); 00035 } else { 00036 __HAL_SYSCFG_USBPULLUP_DISABLE(); 00037 } 00038 } 00039 00040 #elif defined(TARGET_STM32L0)||defined(TARGET_STM32F0) 00041 #define USB_LP_IRQn USB_IRQn 00042 void HAL_PCDEx_SetConnectionState(PCD_HandleTypeDef *hpcd, uint8_t state) { 00043 if (state == 1) { 00044 SET_BIT(USB->BCDR, USB_BCDR_DPPU); // DP Pull-up 00045 } else { 00046 CLEAR_BIT(USB->BCDR, USB_BCDR_DPPU); 00047 } 00048 } 00049 00050 #elif defined(TARGET_STM32F3) 00051 // use remapped USB interrupts, so that CAN peripheral can also be used if needed 00052 //#define USB_LP_IRQn USB_LP_CAN_RX0_IRQn 00053 #endif 00054 00055 static PCD_HandleTypeDef hpcd_USB_FS; 00056 static volatile int epComplete = 0; 00057 00058 USBHAL * USBHAL::instance; 00059 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {return 0;} 00060 00061 USBHAL::USBHAL(void) : PktBufArea(512) { 00062 #if defined(TARGET_STM32F3) 00063 // Configure USB pins 00064 pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF14_USB)); 00065 pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF14_USB)); 00066 #endif 00067 hpcd_USB_FS.pData = this; 00068 hpcd_USB_FS.Instance = USB; 00069 hpcd_USB_FS.Init.dev_endpoints = 8; 00070 hpcd_USB_FS.Init.speed = PCD_SPEED_FULL; 00071 hpcd_USB_FS.Init.ep0_mps = DEP0CTL_MPS_8; 00072 hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED; 00073 hpcd_USB_FS.Init.Sof_enable = DISABLE; 00074 hpcd_USB_FS.Init.low_power_enable = DISABLE; 00075 hpcd_USB_FS.Init.battery_charging_enable = DISABLE; 00076 #if defined(TARGET_STM32F3) 00077 __HAL_RCC_SYSCFG_CLK_ENABLE(); 00078 __HAL_REMAPINTERRUPT_USB_ENABLE(); 00079 #endif 00080 NVIC_SetVector(USB_LP_IRQn, (uint32_t)&_usbisr); 00081 HAL_PCD_Init(&hpcd_USB_FS); 00082 HAL_PCD_Start(&hpcd_USB_FS); 00083 } 00084 00085 void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd) { 00086 __USB_CLK_ENABLE(); 00087 HAL_NVIC_SetPriority(USB_LP_IRQn, 0, 0); 00088 } 00089 00090 void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd) { 00091 HAL_NVIC_DisableIRQ(USB_LP_IRQn); // Peripheral interrupt Deinit 00092 __USB_CLK_DISABLE(); // Peripheral clock disable 00093 } 00094 00095 USBHAL::~USBHAL(void) { 00096 HAL_PCD_DeInit(&hpcd_USB_FS); 00097 } 00098 00099 void USBHAL::connect(void) { 00100 HAL_NVIC_EnableIRQ(USB_LP_IRQn); 00101 HAL_PCD_DevConnect(&hpcd_USB_FS); 00102 } 00103 00104 void USBHAL::disconnect(void) { 00105 HAL_PCD_DevDisconnect(&hpcd_USB_FS); 00106 HAL_NVIC_DisableIRQ(USB_LP_IRQn); 00107 } 00108 00109 void USBHAL::configureDevice(void) { 00110 // Not needed 00111 } 00112 void USBHAL::unconfigureDevice(void) { 00113 // Not needed 00114 } 00115 00116 void USBHAL::setAddress(uint8_t address) { 00117 HAL_PCD_SetAddress(&hpcd_USB_FS, address); 00118 } 00119 00120 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) { 00121 int pmaadress = PktBufArea.allocBuf(maxPacket); 00122 MBED_ASSERT(pmaadress != 0); 00123 if (pmaadress == 0) { 00124 return false; 00125 } 00126 PCD_HandleTypeDef *hpcd = &hpcd_USB_FS; 00127 uint8_t ep_type; 00128 switch(endpoint) { 00129 case EP0OUT: 00130 HAL_PCDEx_PMAConfig(hpcd, 0x00, PCD_SNG_BUF, pmaadress); 00131 HAL_PCD_EP_Open(hpcd, 0x00, maxPacket, PCD_EP_TYPE_CTRL); 00132 break; 00133 case EP0IN: 00134 HAL_PCDEx_PMAConfig(hpcd, 0x80, PCD_SNG_BUF, pmaadress); 00135 HAL_PCD_EP_Open(hpcd, 0x80, maxPacket, PCD_EP_TYPE_CTRL); 00136 break; 00137 case EPINT_OUT: 00138 HAL_PCDEx_PMAConfig(hpcd, 0x01, PCD_SNG_BUF, pmaadress); 00139 HAL_PCD_EP_Open(hpcd, 0x01, maxPacket, PCD_EP_TYPE_INTR); 00140 break; 00141 case EPINT_IN: 00142 HAL_PCDEx_PMAConfig(hpcd, 0x81, PCD_SNG_BUF, pmaadress); 00143 HAL_PCD_EP_Open(hpcd, 0x81, maxPacket, PCD_EP_TYPE_INTR); 00144 break; 00145 case EPBULK_OUT: 00146 HAL_PCDEx_PMAConfig(hpcd, 0x02, PCD_SNG_BUF, pmaadress); 00147 HAL_PCD_EP_Open(hpcd, 0x02, maxPacket, PCD_EP_TYPE_BULK); 00148 break; 00149 case EPBULK_IN: 00150 HAL_PCDEx_PMAConfig(hpcd, 0x82, PCD_SNG_BUF, pmaadress); 00151 HAL_PCD_EP_Open(hpcd, 0x82, maxPacket, PCD_EP_TYPE_BULK); 00152 break; 00153 case EP3OUT: 00154 HAL_PCDEx_PMAConfig(hpcd, 0x03, PCD_SNG_BUF, pmaadress); 00155 ep_type = (flags & ISOCHRONOUS) ? PCD_EP_TYPE_ISOC : PCD_EP_TYPE_BULK; 00156 HAL_PCD_EP_Open(hpcd, 0x03, maxPacket, ep_type); 00157 break; 00158 case EP3IN: 00159 HAL_PCDEx_PMAConfig(hpcd, 0x83, PCD_SNG_BUF, pmaadress); 00160 ep_type = (flags & ISOCHRONOUS) ? PCD_EP_TYPE_ISOC : PCD_EP_TYPE_BULK; 00161 HAL_PCD_EP_Open(hpcd, 0x83, maxPacket, ep_type); 00162 break; 00163 default: 00164 MBED_ASSERT(0); 00165 return false; 00166 } 00167 return true; 00168 } 00169 00170 // read setup packet 00171 void USBHAL::EP0setup(uint8_t *buffer) { 00172 memcpy(buffer, hpcd_USB_FS.Setup, 8); 00173 } 00174 00175 void USBHAL::EP0readStage(void) { 00176 } 00177 00178 void USBHAL::EP0read(void) { 00179 endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0); 00180 } 00181 00182 class rxTempBufferManager { 00183 uint8_t buf0[MAX_PACKET_SIZE_EP0]; 00184 uint8_t buf1[MAX_PACKET_SIZE_EP1]; 00185 uint8_t buf2[MAX_PACKET_SIZE_EP2]; 00186 uint8_t buf3[MAX_PACKET_SIZE_EP3_ISO]; 00187 public: 00188 uint8_t* ptr(uint8_t endpoint, int maxPacketSize) { 00189 switch(endpoint) { 00190 case EP0OUT: 00191 MBED_ASSERT(maxPacketSize <= MAX_PACKET_SIZE_EP0); 00192 break; 00193 case EP1OUT: 00194 MBED_ASSERT(maxPacketSize <= MAX_PACKET_SIZE_EP1); 00195 break; 00196 case EP2OUT: 00197 MBED_ASSERT(maxPacketSize <= MAX_PACKET_SIZE_EP2); 00198 break; 00199 case EP3OUT: 00200 MBED_ASSERT(maxPacketSize <= MAX_PACKET_SIZE_EP3_ISO); 00201 break; 00202 } 00203 return ptr(endpoint); 00204 } 00205 uint8_t* ptr(uint8_t endpoint) { 00206 switch(endpoint) { 00207 case EP0OUT: return buf0; 00208 case EP1OUT: return buf1; 00209 case EP2OUT: return buf2; 00210 case EP3OUT: return buf3; 00211 } 00212 MBED_ASSERT(0); 00213 return NULL; 00214 } 00215 } rxtmp; 00216 00217 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) { 00218 const uint8_t endpoint = EP0OUT; 00219 uint32_t length = HAL_PCD_EP_GetRxCount(&hpcd_USB_FS, endpoint>>1); 00220 memcpy(buffer, rxtmp.ptr(endpoint), length); 00221 return length; 00222 } 00223 00224 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) { 00225 endpointWrite(EP0IN, buffer, size); 00226 } 00227 00228 void USBHAL::EP0getWriteResult(void) { 00229 } 00230 00231 void USBHAL::EP0stall(void) { 00232 // If we stall the out endpoint here then we have problems transferring 00233 // and setup requests after the (stalled) get device qualifier requests. 00234 // TODO: Find out if this is correct behavior, or whether we are doing 00235 // something else wrong 00236 stallEndpoint(EP0IN); 00237 // stallEndpoint(EP0OUT); 00238 } 00239 00240 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) { 00241 core_util_critical_section_enter(); 00242 HAL_PCD_EP_Receive(&hpcd_USB_FS, endpoint>>1, rxtmp.ptr(endpoint, maximumSize), maximumSize); 00243 epComplete &= ~(1 << endpoint); 00244 core_util_critical_section_exit(); 00245 return EP_PENDING; 00246 } 00247 00248 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) { 00249 if (!(epComplete & (1 << endpoint))) { 00250 return EP_PENDING; 00251 } 00252 int len = HAL_PCD_EP_GetRxCount(&hpcd_USB_FS, endpoint>>1); 00253 memcpy(buffer, rxtmp.ptr(endpoint), len); 00254 *bytesRead = len; 00255 return EP_COMPLETED; 00256 } 00257 00258 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, const uint8_t *data, uint32_t size) { 00259 core_util_critical_section_enter(); 00260 HAL_PCD_EP_Transmit(&hpcd_USB_FS, endpoint>>1, const_cast<uint8_t*>(data), size); 00261 epComplete &= ~(1 << endpoint); 00262 core_util_critical_section_exit(); 00263 return EP_PENDING; 00264 } 00265 00266 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) { 00267 if (epComplete & (1 << endpoint)) { 00268 core_util_critical_section_enter(); 00269 epComplete &= ~(1 << endpoint); 00270 core_util_critical_section_exit(); 00271 return EP_COMPLETED; 00272 } 00273 return EP_PENDING; 00274 } 00275 00276 void USBHAL::stallEndpoint(uint8_t endpoint) { 00277 PCD_HandleTypeDef *hpcd = &hpcd_USB_FS; 00278 switch(endpoint) { 00279 case EP0IN: 00280 HAL_PCD_EP_SetStall(hpcd, 0x80); 00281 break; 00282 case EP0OUT: 00283 HAL_PCD_EP_SetStall(hpcd, 0x00); 00284 break; 00285 default: 00286 break; 00287 } 00288 } 00289 00290 void USBHAL::unstallEndpoint(uint8_t endpoint) { 00291 } 00292 00293 bool USBHAL::getEndpointStallState(uint8_t endpoint) { 00294 return false; 00295 } 00296 00297 void USBHAL::remoteWakeup(void) {} 00298 00299 void USBHAL::_usbisr(void) { 00300 HAL_PCD_IRQHandler(&hpcd_USB_FS); 00301 } 00302 00303 void USBHAL::usbisr(void) {} 00304 00305 void USBHAL::SetupStageCallback() { 00306 EP0setupCallback(); 00307 } 00308 00309 void USBHAL::DataInStageCallback(uint8_t epnum) { 00310 switch(epnum) { 00311 case 0: // EP0IN 00312 EP0in(); 00313 break; 00314 case 1: 00315 epComplete |= (1<<EP1IN); 00316 if (EP1_IN_callback()) { 00317 epComplete &= ~(1<<EP1IN); 00318 } 00319 break; 00320 case 2: 00321 epComplete |= (1<<EP2IN); 00322 if (EP2_IN_callback()) { 00323 epComplete &= ~(1<<EP2IN); 00324 } 00325 break; 00326 case 3: 00327 epComplete |= (1<<EP3IN); 00328 if (EP3_IN_callback()) { 00329 epComplete &= ~(1<<EP3IN); 00330 } 00331 break; 00332 default: 00333 MBED_ASSERT(0); 00334 break; 00335 } 00336 } 00337 00338 void USBHAL::DataOutStageCallback(uint8_t epnum) { 00339 switch(epnum) { 00340 case 0: // EP0OUT 00341 if ((hpcd_USB_FS.Setup[0]&0x80) == 0x00) { // host to device ? 00342 EP0out(); 00343 } 00344 break; 00345 case 1: 00346 epComplete |= (1<<EP1OUT); 00347 if (EP1_OUT_callback()) { 00348 epComplete &= ~(1<<EP1OUT); 00349 } 00350 break; 00351 case 2: 00352 epComplete |= (1<<EP2OUT); 00353 if (EP2_OUT_callback()) { 00354 epComplete &= ~(1<<EP2OUT); 00355 } 00356 break; 00357 case 3: 00358 epComplete |= (1<<EP3OUT); 00359 if (EP3_OUT_callback()) { 00360 epComplete &= ~(1<<EP3OUT); 00361 } 00362 break; 00363 default: 00364 MBED_ASSERT(0); 00365 break; 00366 } 00367 } 00368 00369 void USBHAL::ResetCallback() { 00370 PktBufArea.reset(); 00371 realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0); 00372 realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0); 00373 } 00374 00375 void USBHAL::SOFCallback() { 00376 SOF(hpcd_USB_FS.Instance->FNR & USB_FNR_FN); 00377 } 00378 00379 void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) { 00380 reinterpret_cast<USBHAL*>(hpcd->pData)->SetupStageCallback(); 00381 } 00382 00383 void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { 00384 reinterpret_cast<USBHAL*>(hpcd->pData)->DataInStageCallback(epnum); 00385 } 00386 00387 void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { 00388 reinterpret_cast<USBHAL*>(hpcd->pData)->DataOutStageCallback(epnum); 00389 } 00390 00391 void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) { 00392 reinterpret_cast<USBHAL*>(hpcd->pData)->ResetCallback(); 00393 } 00394 00395 void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) { 00396 reinterpret_cast<USBHAL*>(hpcd->pData)->SOFCallback(); 00397 } 00398 00399 void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) { 00400 if (hpcd->Init.low_power_enable) { 00401 SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); 00402 } 00403 } 00404 00405 #endif
Generated on Wed Jul 13 2022 00:18:45 by 1.7.2