ROM Comm / USBDevice_STM32F103

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 #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 }