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