Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of USBDevice_STM32F103 by
USBHAL_STM32F1.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 #include "USBDevice.h" 00020 00021 #if defined(TARGET_STM32F1) | defined(TARGET_STM32F4) 00022 00023 #define USB_LP_IRQn USB_LP_CAN1_RX0_IRQn 00024 const uint8_t PCD_EP_TYPE_CTRL = EP_TYPE_CTRL; 00025 const uint8_t PCD_EP_TYPE_INTR = EP_TYPE_INTR; 00026 const uint8_t PCD_EP_TYPE_BULK = EP_TYPE_BULK; 00027 const uint8_t PCD_EP_TYPE_ISOC = EP_TYPE_ISOC; 00028 00029 static PCD_HandleTypeDef hpcd_USB_FS; 00030 static volatile int epComplete = 0; 00031 00032 USBHAL * USBHAL::instance; 00033 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {return 0;} 00034 00035 USBHAL::USBHAL(void) { 00036 hpcd_USB_FS.pData = this; 00037 hpcd_USB_FS.Instance = USB; 00038 hpcd_USB_FS.Init.dev_endpoints = 8; 00039 hpcd_USB_FS.Init.speed = PCD_SPEED_FULL; 00040 hpcd_USB_FS.Init.ep0_mps = DEP0CTL_MPS_8; 00041 hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED; 00042 hpcd_USB_FS.Init.Sof_enable = DISABLE; 00043 hpcd_USB_FS.Init.low_power_enable = DISABLE; 00044 hpcd_USB_FS.Init.battery_charging_enable = DISABLE; 00045 NVIC_SetVector(USB_LP_IRQn, (uint32_t)&_usbisr); 00046 HAL_PCD_Init(&hpcd_USB_FS); 00047 HAL_PCD_Start(&hpcd_USB_FS); 00048 } 00049 00050 void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd) { 00051 __USB_CLK_ENABLE(); 00052 HAL_NVIC_SetPriority(USB_LP_IRQn, 0, 0); 00053 HAL_NVIC_EnableIRQ(USB_LP_IRQn); 00054 } 00055 00056 void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd) { 00057 __USB_CLK_DISABLE(); // Peripheral clock disable 00058 HAL_NVIC_DisableIRQ(USB_LP_IRQn); // Peripheral interrupt Deinit 00059 } 00060 00061 USBHAL::~USBHAL(void) { 00062 HAL_PCD_DeInit(&hpcd_USB_FS); 00063 } 00064 00065 void USBHAL::connect(void) { 00066 HAL_PCD_DevConnect(&hpcd_USB_FS); 00067 } 00068 00069 void USBHAL::disconnect(void) { 00070 HAL_PCD_DevDisconnect(&hpcd_USB_FS); 00071 } 00072 00073 void USBHAL::configureDevice(void) { 00074 // Not needed 00075 } 00076 void USBHAL::unconfigureDevice(void) { 00077 // Not needed 00078 } 00079 00080 void USBHAL::setAddress(uint8_t address) { 00081 HAL_PCD_SetAddress(&hpcd_USB_FS, address); 00082 } 00083 00084 class PacketBufferAreaManager { 00085 public: 00086 PacketBufferAreaManager(int bufsize_):bufsize(bufsize_) { 00087 reset(); 00088 } 00089 void reset() { 00090 head = 0; 00091 tail = bufsize; 00092 } 00093 int allocBuf(int maxPacketSize) { 00094 head += 4; 00095 tail -= maxPacketSize; 00096 if (tail < head) { 00097 return 0; 00098 } 00099 return tail; 00100 } 00101 private: 00102 int head,tail; 00103 int bufsize; 00104 } PktBufArea(512); 00105 00106 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, uint32_t flags) { 00107 int pmaadress = PktBufArea.allocBuf(maxPacket); 00108 MBED_ASSERT(pmaadress != 0); 00109 if (pmaadress == 0) { 00110 return false; 00111 } 00112 PCD_HandleTypeDef *hpcd = &hpcd_USB_FS; 00113 uint8_t ep_type; 00114 switch(endpoint) { 00115 case EP0OUT: 00116 HAL_PCDEx_PMAConfig(hpcd, 0x00, PCD_SNG_BUF, pmaadress); 00117 HAL_PCD_EP_Open(hpcd, 0x00, maxPacket, PCD_EP_TYPE_CTRL); 00118 break; 00119 case EP0IN: 00120 HAL_PCDEx_PMAConfig(hpcd, 0x80, PCD_SNG_BUF, pmaadress); 00121 HAL_PCD_EP_Open(hpcd, 0x80, maxPacket, PCD_EP_TYPE_CTRL); 00122 break; 00123 case EPINT_OUT: 00124 HAL_PCDEx_PMAConfig(hpcd, 0x01, PCD_SNG_BUF, pmaadress); 00125 HAL_PCD_EP_Open(hpcd, 0x01, maxPacket, PCD_EP_TYPE_INTR); 00126 break; 00127 case EPINT_IN: 00128 HAL_PCDEx_PMAConfig(hpcd, 0x81, PCD_SNG_BUF, pmaadress); 00129 HAL_PCD_EP_Open(hpcd, 0x81, maxPacket, PCD_EP_TYPE_INTR); 00130 break; 00131 case EPBULK_OUT: 00132 HAL_PCDEx_PMAConfig(hpcd, 0x02, PCD_SNG_BUF, pmaadress); 00133 HAL_PCD_EP_Open(hpcd, 0x02, maxPacket, PCD_EP_TYPE_BULK); 00134 break; 00135 case EPBULK_IN: 00136 HAL_PCDEx_PMAConfig(hpcd, 0x82, PCD_SNG_BUF, pmaadress); 00137 HAL_PCD_EP_Open(hpcd, 0x82, maxPacket, PCD_EP_TYPE_BULK); 00138 break; 00139 case EP3OUT: 00140 HAL_PCDEx_PMAConfig(hpcd, 0x03, PCD_SNG_BUF, pmaadress); 00141 ep_type = (flags & ISOCHRONOUS) ? PCD_EP_TYPE_ISOC : PCD_EP_TYPE_BULK; 00142 HAL_PCD_EP_Open(hpcd, 0x03, maxPacket, ep_type); 00143 break; 00144 case EP3IN: 00145 HAL_PCDEx_PMAConfig(hpcd, 0x83, PCD_SNG_BUF, pmaadress); 00146 ep_type = (flags & ISOCHRONOUS) ? PCD_EP_TYPE_ISOC : PCD_EP_TYPE_BULK; 00147 HAL_PCD_EP_Open(hpcd, 0x83, maxPacket, ep_type); 00148 break; 00149 default: 00150 MBED_ASSERT(0); 00151 return false; 00152 } 00153 return true; 00154 } 00155 00156 // read setup packet 00157 void USBHAL::EP0setup(uint8_t *buffer) { 00158 memcpy(buffer, hpcd_USB_FS.Setup, 8); 00159 } 00160 00161 void USBHAL::EP0readStage(void) { 00162 } 00163 00164 void USBHAL::EP0read(void) { 00165 endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0); 00166 } 00167 00168 class rxTempBufferManager { 00169 uint8_t buf0[MAX_PACKET_SIZE_EP0]; 00170 uint8_t buf1[MAX_PACKET_SIZE_EP1]; 00171 uint8_t buf2[MAX_PACKET_SIZE_EP2]; 00172 uint8_t buf3[MAX_PACKET_SIZE_EP3_ISO]; 00173 public: 00174 uint8_t* ptr(uint8_t endpoint, int maxPacketSize) { 00175 switch(endpoint) { 00176 case EP0OUT: 00177 MBED_ASSERT(maxPacketSize <= MAX_PACKET_SIZE_EP0); 00178 break; 00179 case EP1OUT: 00180 MBED_ASSERT(maxPacketSize <= MAX_PACKET_SIZE_EP1); 00181 break; 00182 case EP2OUT: 00183 MBED_ASSERT(maxPacketSize <= MAX_PACKET_SIZE_EP2); 00184 break; 00185 case EP3OUT: 00186 MBED_ASSERT(maxPacketSize <= MAX_PACKET_SIZE_EP3_ISO); 00187 break; 00188 } 00189 return ptr(endpoint); 00190 } 00191 uint8_t* ptr(uint8_t endpoint) { 00192 switch(endpoint) { 00193 case EP0OUT: return buf0; 00194 case EP1OUT: return buf1; 00195 case EP2OUT: return buf2; 00196 case EP3OUT: return buf3; 00197 } 00198 MBED_ASSERT(0); 00199 return NULL; 00200 } 00201 } rxtmp; 00202 00203 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) { 00204 const uint8_t endpoint = EP0OUT; 00205 uint32_t length = HAL_PCD_EP_GetRxCount(&hpcd_USB_FS, endpoint>>1); 00206 memcpy(buffer, rxtmp.ptr(endpoint), length); 00207 return length; 00208 } 00209 00210 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) { 00211 endpointWrite(EP0IN, buffer, size); 00212 } 00213 00214 void USBHAL::EP0getWriteResult(void) { 00215 } 00216 00217 void USBHAL::EP0stall(void) { 00218 // If we stall the out endpoint here then we have problems transferring 00219 // and setup requests after the (stalled) get device qualifier requests. 00220 // TODO: Find out if this is correct behavior, or whether we are doing 00221 // something else wrong 00222 stallEndpoint(EP0IN); 00223 // stallEndpoint(EP0OUT); 00224 } 00225 00226 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) { 00227 HAL_PCD_EP_Receive(&hpcd_USB_FS, endpoint>>1, rxtmp.ptr(endpoint, maximumSize), maximumSize); 00228 epComplete &= ~(1 << endpoint); 00229 return EP_PENDING; 00230 } 00231 00232 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) { 00233 if (!(epComplete & (1 << endpoint))) { 00234 return EP_PENDING; 00235 } 00236 int len = HAL_PCD_EP_GetRxCount(&hpcd_USB_FS, endpoint>>1); 00237 memcpy(buffer, rxtmp.ptr(endpoint), len); 00238 *bytesRead = len; 00239 return EP_COMPLETED; 00240 } 00241 00242 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) { 00243 HAL_PCD_EP_Transmit(&hpcd_USB_FS, endpoint>>1, data, size); 00244 epComplete &= ~(1 << endpoint); 00245 return EP_PENDING; 00246 } 00247 00248 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) { 00249 if (epComplete & (1 << endpoint)) { 00250 epComplete &= ~(1 << endpoint); 00251 return EP_COMPLETED; 00252 } 00253 return EP_PENDING; 00254 } 00255 00256 void USBHAL::stallEndpoint(uint8_t endpoint) { 00257 PCD_HandleTypeDef *hpcd = &hpcd_USB_FS; 00258 switch(endpoint) { 00259 case EP0IN: 00260 HAL_PCD_EP_SetStall(hpcd, 0x80); 00261 break; 00262 case EP0OUT: 00263 HAL_PCD_EP_SetStall(hpcd, 0x00); 00264 break; 00265 default: 00266 break; 00267 } 00268 } 00269 00270 void USBHAL::unstallEndpoint(uint8_t endpoint) { 00271 } 00272 00273 bool USBHAL::getEndpointStallState(uint8_t endpoint) { 00274 return false; 00275 } 00276 00277 void USBHAL::remoteWakeup(void) {} 00278 00279 void USBHAL::_usbisr(void) { 00280 HAL_PCD_IRQHandler(&hpcd_USB_FS); 00281 } 00282 00283 void USBHAL::usbisr(void) {} 00284 00285 void USBHAL::SetupStageCallback() { 00286 EP0setupCallback(); 00287 } 00288 00289 void USBHAL::DataInStageCallback(uint8_t epnum) { 00290 switch(epnum) { 00291 case 0: // EP0IN 00292 EP0in(); 00293 break; 00294 case 1: 00295 epComplete |= (1<<EP1IN); 00296 if (EP1_IN_callback()) { 00297 epComplete &= ~(1<<EP1IN); 00298 } 00299 break; 00300 case 2: 00301 epComplete |= (1<<EP2IN); 00302 if (EP2_IN_callback()) { 00303 epComplete &= ~(1<<EP2IN); 00304 } 00305 break; 00306 case 3: 00307 epComplete |= (1<<EP3IN); 00308 if (EP3_IN_callback()) { 00309 epComplete &= ~(1<<EP3IN); 00310 } 00311 break; 00312 default: 00313 MBED_ASSERT(0); 00314 break; 00315 } 00316 } 00317 00318 void USBHAL::DataOutStageCallback(uint8_t epnum) { 00319 switch(epnum) { 00320 case 0: // EP0OUT 00321 if ((hpcd_USB_FS.Setup[0]&0x80) == 0x00) { // host to device ? 00322 EP0out(); 00323 } 00324 break; 00325 case 1: 00326 epComplete |= (1<<EP1OUT); 00327 if (EP1_OUT_callback()) { 00328 epComplete &= ~(1<<EP1OUT); 00329 } 00330 break; 00331 case 2: 00332 epComplete |= (1<<EP2OUT); 00333 if (EP2_OUT_callback()) { 00334 epComplete &= ~(1<<EP2OUT); 00335 } 00336 break; 00337 case 3: 00338 epComplete |= (1<<EP3OUT); 00339 if (EP3_OUT_callback()) { 00340 epComplete &= ~(1<<EP3OUT); 00341 } 00342 break; 00343 default: 00344 MBED_ASSERT(0); 00345 break; 00346 } 00347 } 00348 00349 void USBHAL::ResetCallback() { 00350 PktBufArea.reset(); 00351 realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0); 00352 realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0); 00353 } 00354 00355 void USBHAL::SOFCallback() { 00356 SOF(hpcd_USB_FS.Instance->FNR & USB_FNR_FN); 00357 } 00358 00359 void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) { 00360 reinterpret_cast<USBHAL*>(hpcd->pData)->SetupStageCallback(); 00361 } 00362 00363 void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { 00364 reinterpret_cast<USBHAL*>(hpcd->pData)->DataInStageCallback(epnum); 00365 } 00366 00367 void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) { 00368 reinterpret_cast<USBHAL*>(hpcd->pData)->DataOutStageCallback(epnum); 00369 } 00370 00371 void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) { 00372 reinterpret_cast<USBHAL*>(hpcd->pData)->ResetCallback(); 00373 } 00374 00375 void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) { 00376 reinterpret_cast<USBHAL*>(hpcd->pData)->SOFCallback(); 00377 } 00378 00379 void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) { 00380 if (hpcd->Init.low_power_enable) { 00381 SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk)); 00382 } 00383 } 00384 00385 #endif
Generated on Tue Jul 12 2022 21:49:58 by
1.7.2
