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