blablabla
Dependencies: MAG3110 MMA8451Q SLCD- TSI USBDevice mbed
USBHAL_STM32F4.cpp
00001 /* Copyright (c) 2010-2011 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 #if defined(TARGET_STM32F4XX) 00020 00021 #include "USBHAL.h" 00022 #include "USBRegs_STM32.h" 00023 #include "pinmap.h" 00024 00025 USBHAL * USBHAL::instance; 00026 00027 static volatile int epComplete = 0; 00028 00029 static uint32_t bufferEnd = 0; 00030 static const uint32_t rxFifoSize = 512; 00031 static uint32_t rxFifoCount = 0; 00032 00033 static uint32_t setupBuffer[MAX_PACKET_SIZE_EP0 >> 2]; 00034 00035 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) { 00036 return 0; 00037 } 00038 00039 USBHAL::USBHAL(void) { 00040 NVIC_DisableIRQ(OTG_FS_IRQn); 00041 epCallback[0] = &USBHAL::EP1_OUT_callback; 00042 epCallback[1] = &USBHAL::EP1_IN_callback; 00043 epCallback[2] = &USBHAL::EP2_OUT_callback; 00044 epCallback[3] = &USBHAL::EP2_IN_callback; 00045 epCallback[4] = &USBHAL::EP3_OUT_callback; 00046 epCallback[5] = &USBHAL::EP3_IN_callback; 00047 00048 // Enable power and clocking 00049 RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; 00050 00051 pin_function(PA_8, STM_PIN_DATA(2, 10)); 00052 pin_function(PA_9, STM_PIN_DATA(0, 0)); 00053 pin_function(PA_10, STM_PIN_DATA(2, 10)); 00054 pin_function(PA_11, STM_PIN_DATA(2, 10)); 00055 pin_function(PA_12, STM_PIN_DATA(2, 10)); 00056 00057 // Set ID pin to open drain with pull-up resistor 00058 pin_mode(PA_10, OpenDrain); 00059 GPIOA->PUPDR &= ~(0x3 << 20); 00060 GPIOA->PUPDR |= 1 << 20; 00061 00062 // Set VBUS pin to open drain 00063 pin_mode(PA_9, OpenDrain); 00064 00065 RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN; 00066 00067 // Enable interrupts 00068 OTG_FS->GREGS.GAHBCFG |= (1 << 0); 00069 00070 // Turnaround time to maximum value - too small causes packet loss 00071 OTG_FS->GREGS.GUSBCFG |= (0xF << 10); 00072 00073 // Unmask global interrupts 00074 OTG_FS->GREGS.GINTMSK |= (1 << 3) | // SOF 00075 (1 << 4) | // RX FIFO not empty 00076 (1 << 12); // USB reset 00077 00078 OTG_FS->DREGS.DCFG |= (0x3 << 0) | // Full speed 00079 (1 << 2); // Non-zero-length status OUT handshake 00080 00081 OTG_FS->GREGS.GCCFG |= (1 << 19) | // Enable VBUS sensing 00082 (1 << 16); // Power Up 00083 00084 instance = this; 00085 NVIC_SetVector(OTG_FS_IRQn, (uint32_t)&_usbisr); 00086 NVIC_SetPriority(OTG_FS_IRQn, 1); 00087 } 00088 00089 USBHAL::~USBHAL(void) { 00090 } 00091 00092 void USBHAL::connect(void) { 00093 NVIC_EnableIRQ(OTG_FS_IRQn); 00094 } 00095 00096 void USBHAL::disconnect(void) { 00097 NVIC_DisableIRQ(OTG_FS_IRQn); 00098 } 00099 00100 void USBHAL::configureDevice(void) { 00101 // Not needed 00102 } 00103 00104 void USBHAL::unconfigureDevice(void) { 00105 // Not needed 00106 } 00107 00108 void USBHAL::setAddress(uint8_t address) { 00109 OTG_FS->DREGS.DCFG |= (address << 4); 00110 EP0write(0, 0); 00111 } 00112 00113 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket, 00114 uint32_t flags) { 00115 uint32_t epIndex = endpoint >> 1; 00116 00117 uint32_t type; 00118 switch (endpoint) { 00119 case EP0IN: 00120 case EP0OUT: 00121 type = 0; 00122 break; 00123 case EPISO_IN: 00124 case EPISO_OUT: 00125 type = 1; 00126 case EPBULK_IN: 00127 case EPBULK_OUT: 00128 type = 2; 00129 break; 00130 case EPINT_IN: 00131 case EPINT_OUT: 00132 type = 3; 00133 break; 00134 } 00135 00136 // Generic in or out EP controls 00137 uint32_t control = (maxPacket << 0) | // Packet size 00138 (1 << 15) | // Active endpoint 00139 (type << 18); // Endpoint type 00140 00141 if (endpoint & 0x1) { // In Endpoint 00142 // Set up the Tx FIFO 00143 if (endpoint == EP0IN) { 00144 OTG_FS->GREGS.DIEPTXF0_HNPTXFSIZ = ((maxPacket >> 2) << 16) | 00145 (bufferEnd << 0); 00146 } 00147 else { 00148 OTG_FS->GREGS.DIEPTXF[epIndex - 1] = ((maxPacket >> 2) << 16) | 00149 (bufferEnd << 0); 00150 } 00151 bufferEnd += maxPacket >> 2; 00152 00153 // Set the In EP specific control settings 00154 if (endpoint != EP0IN) { 00155 control |= (1 << 28); // SD0PID 00156 } 00157 00158 control |= (epIndex << 22) | // TxFIFO index 00159 (1 << 27); // SNAK 00160 OTG_FS->INEP_REGS[epIndex].DIEPCTL = control; 00161 00162 // Unmask the interrupt 00163 OTG_FS->DREGS.DAINTMSK |= (1 << epIndex); 00164 } 00165 else { // Out endpoint 00166 // Set the out EP specific control settings 00167 control |= (1 << 26); // CNAK 00168 OTG_FS->OUTEP_REGS[epIndex].DOEPCTL = control; 00169 00170 // Unmask the interrupt 00171 OTG_FS->DREGS.DAINTMSK |= (1 << (epIndex + 16)); 00172 } 00173 return true; 00174 } 00175 00176 // read setup packet 00177 void USBHAL::EP0setup(uint8_t *buffer) { 00178 memcpy(buffer, setupBuffer, MAX_PACKET_SIZE_EP0); 00179 } 00180 00181 void USBHAL::EP0readStage(void) { 00182 } 00183 00184 void USBHAL::EP0read(void) { 00185 } 00186 00187 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) { 00188 uint32_t* buffer32 = (uint32_t *) buffer; 00189 uint32_t length = rxFifoCount; 00190 for (uint32_t i = 0; i < length; i += 4) { 00191 buffer32[i >> 2] = OTG_FS->FIFO[0][0]; 00192 } 00193 00194 rxFifoCount = 0; 00195 return length; 00196 } 00197 00198 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) { 00199 endpointWrite(0, buffer, size); 00200 } 00201 00202 void USBHAL::EP0getWriteResult(void) { 00203 } 00204 00205 void USBHAL::EP0stall(void) { 00206 // If we stall the out endpoint here then we have problems transferring 00207 // and setup requests after the (stalled) get device qualifier requests. 00208 // TODO: Find out if this is correct behavior, or whether we are doing 00209 // something else wrong 00210 stallEndpoint(EP0IN); 00211 // stallEndpoint(EP0OUT); 00212 } 00213 00214 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) { 00215 uint32_t epIndex = endpoint >> 1; 00216 uint32_t size = (1 << 19) | // 1 packet 00217 (maximumSize << 0); // Packet size 00218 // if (endpoint == EP0OUT) { 00219 size |= (1 << 29); // 1 setup packet 00220 // } 00221 OTG_FS->OUTEP_REGS[epIndex].DOEPTSIZ = size; 00222 OTG_FS->OUTEP_REGS[epIndex].DOEPCTL |= (1 << 31) | // Enable endpoint 00223 (1 << 26); // Clear NAK 00224 00225 epComplete &= ~(1 << endpoint); 00226 return EP_PENDING; 00227 } 00228 00229 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) { 00230 if (!(epComplete & (1 << endpoint))) { 00231 return EP_PENDING; 00232 } 00233 00234 uint32_t* buffer32 = (uint32_t *) buffer; 00235 uint32_t length = rxFifoCount; 00236 for (uint32_t i = 0; i < length; i += 4) { 00237 buffer32[i >> 2] = OTG_FS->FIFO[endpoint >> 1][0]; 00238 } 00239 rxFifoCount = 0; 00240 *bytesRead = length; 00241 return EP_COMPLETED; 00242 } 00243 00244 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) { 00245 uint32_t epIndex = endpoint >> 1; 00246 OTG_FS->INEP_REGS[epIndex].DIEPTSIZ = (1 << 19) | // 1 packet 00247 (size << 0); // Size of packet 00248 OTG_FS->INEP_REGS[epIndex].DIEPCTL |= (1 << 31) | // Enable endpoint 00249 (1 << 26); // CNAK 00250 OTG_FS->DREGS.DIEPEMPMSK = (1 << epIndex); 00251 00252 while ((OTG_FS->INEP_REGS[epIndex].DTXFSTS & 0XFFFF) < ((size + 3) >> 2)); 00253 00254 for (uint32_t i=0; i<(size + 3) >> 2; i++, data+=4) { 00255 OTG_FS->FIFO[epIndex][0] = *(uint32_t *)data; 00256 } 00257 00258 epComplete &= ~(1 << endpoint); 00259 00260 return EP_PENDING; 00261 } 00262 00263 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) { 00264 if (epComplete & (1 << endpoint)) { 00265 epComplete &= ~(1 << endpoint); 00266 return EP_COMPLETED; 00267 } 00268 00269 return EP_PENDING; 00270 } 00271 00272 void USBHAL::stallEndpoint(uint8_t endpoint) { 00273 if (endpoint & 0x1) { // In EP 00274 OTG_FS->INEP_REGS[endpoint >> 1].DIEPCTL |= (1 << 30) | // Disable 00275 (1 << 21); // Stall 00276 } 00277 else { // Out EP 00278 OTG_FS->DREGS.DCTL |= (1 << 9); // Set global out NAK 00279 OTG_FS->OUTEP_REGS[endpoint >> 1].DOEPCTL |= (1 << 30) | // Disable 00280 (1 << 21); // Stall 00281 } 00282 } 00283 00284 void USBHAL::unstallEndpoint(uint8_t endpoint) { 00285 00286 } 00287 00288 bool USBHAL::getEndpointStallState(uint8_t endpoint) { 00289 return false; 00290 } 00291 00292 void USBHAL::remoteWakeup(void) { 00293 } 00294 00295 00296 void USBHAL::_usbisr(void) { 00297 instance->usbisr(); 00298 } 00299 00300 00301 void USBHAL::usbisr(void) { 00302 if (OTG_FS->GREGS.GINTSTS & (1 << 12)) { // USB Reset 00303 // Set SNAK bits 00304 OTG_FS->OUTEP_REGS[0].DOEPCTL |= (1 << 27); 00305 OTG_FS->OUTEP_REGS[1].DOEPCTL |= (1 << 27); 00306 OTG_FS->OUTEP_REGS[2].DOEPCTL |= (1 << 27); 00307 OTG_FS->OUTEP_REGS[3].DOEPCTL |= (1 << 27); 00308 00309 OTG_FS->DREGS.DIEPMSK = (1 << 0); 00310 00311 bufferEnd = 0; 00312 00313 // Set the receive FIFO size 00314 OTG_FS->GREGS.GRXFSIZ = rxFifoSize >> 2; 00315 bufferEnd += rxFifoSize >> 2; 00316 00317 // Create the endpoints, and wait for setup packets on out EP0 00318 realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0); 00319 realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0); 00320 endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0); 00321 00322 OTG_FS->GREGS.GINTSTS = (1 << 12); 00323 } 00324 00325 if (OTG_FS->GREGS.GINTSTS & (1 << 4)) { // RX FIFO not empty 00326 uint32_t status = OTG_FS->GREGS.GRXSTSP; 00327 00328 uint32_t endpoint = (status & 0xF) << 1; 00329 uint32_t length = (status >> 4) & 0x7FF; 00330 uint32_t type = (status >> 17) & 0xF; 00331 00332 rxFifoCount = length; 00333 00334 if (type == 0x6) { 00335 // Setup packet 00336 for (uint32_t i=0; i<length; i+=4) { 00337 setupBuffer[i >> 2] = OTG_FS->FIFO[0][i >> 2]; 00338 } 00339 rxFifoCount = 0; 00340 } 00341 00342 if (type == 0x4) { 00343 // Setup complete 00344 EP0setupCallback(); 00345 endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0); 00346 } 00347 00348 if (type == 0x2) { 00349 // Out packet 00350 if (endpoint == EP0OUT) { 00351 EP0out(); 00352 } 00353 else { 00354 epComplete |= (1 << endpoint); 00355 if ((instance->*(epCallback[endpoint - 2]))()) { 00356 epComplete &= (1 << endpoint); 00357 } 00358 } 00359 } 00360 00361 for (uint32_t i=0; i<rxFifoCount; i+=4) { 00362 (void) OTG_FS->FIFO[0][0]; 00363 } 00364 OTG_FS->GREGS.GINTSTS = (1 << 4); 00365 } 00366 00367 if (OTG_FS->GREGS.GINTSTS & (1 << 18)) { // In endpoint interrupt 00368 // Loop through the in endpoints 00369 for (uint32_t i=0; i<4; i++) { 00370 if (OTG_FS->DREGS.DAINT & (1 << i)) { // Interrupt is on endpoint 00371 00372 if (OTG_FS->INEP_REGS[i].DIEPINT & (1 << 7)) {// Tx FIFO empty 00373 // If the Tx FIFO is empty on EP0 we need to send a further 00374 // packet, so call EP0in() 00375 if (i == 0) { 00376 EP0in(); 00377 } 00378 // Clear the interrupt 00379 OTG_FS->INEP_REGS[i].DIEPINT = (1 << 7); 00380 // Stop firing Tx empty interrupts 00381 // Will get turned on again if another write is called 00382 OTG_FS->DREGS.DIEPEMPMSK &= ~(1 << i); 00383 } 00384 00385 // If the transfer is complete 00386 if (OTG_FS->INEP_REGS[i].DIEPINT & (1 << 0)) { // Tx Complete 00387 epComplete |= (1 << (1 + (i << 1))); 00388 OTG_FS->INEP_REGS[i].DIEPINT = (1 << 0); 00389 } 00390 } 00391 } 00392 OTG_FS->GREGS.GINTSTS = (1 << 18); 00393 } 00394 00395 if (OTG_FS->GREGS.GINTSTS & (1 << 3)) { // Start of frame 00396 SOF((OTG_FS->GREGS.GRXSTSR >> 17) & 0xF); 00397 OTG_FS->GREGS.GINTSTS = (1 << 3); 00398 } 00399 } 00400 00401 00402 #endif
Generated on Tue Jul 12 2022 16:20:44 by 1.7.2