This fork re-enables FRDM boards and adds WebUSB CDC functionality
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