This fork re-enables FRDM boards and adds WebUSB CDC functionality

Fork of USBDevice_STM32F103 by Devan Lai

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USBHAL_STM32F1.cpp Source File

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