USB device stack with Nucleo F401RE support. NOTE: the default clock config needs to be changed to in order for USB to work.

Fork of USBDevice by Tomas Cerskus

Slightly modified original USBDevice library to support F401RE.

On F401RE the data pins of your USB connector should be attached to PA12 (D+) and PA11(D-). It is also required to connect the +5V USB line to PA9.

F401RE requires 48MHz clock for USB. Therefore in order for this to work you will need to change the default clock settings:

Clock settings for USB

#include "stm32f4xx_hal.h"

RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = 16;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 16;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
    error("RTC error: LSI clock initialization failed."); 
}

NOTE: Changing the clock frequency might affect the behavior of other libraries. I only tested the Serial library.

UPDATE: Clock settings should not to be changed anymore! Looks like the newer mbed library has the required clock enabled.

Committer:
tolaipner
Date:
Sun Mar 30 07:30:18 2014 +0000
Revision:
24:4ed3e25c3edc
Parent:
22:a4b9c279b437
Added Nucleo F401RE support

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 16:4f6df64750bd 1 /* Copyright (c) 2010-2011 mbed.org, MIT License
mbed_official 16:4f6df64750bd 2 *
mbed_official 16:4f6df64750bd 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
mbed_official 16:4f6df64750bd 4 * and associated documentation files (the "Software"), to deal in the Software without
mbed_official 16:4f6df64750bd 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
mbed_official 16:4f6df64750bd 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
mbed_official 16:4f6df64750bd 7 * Software is furnished to do so, subject to the following conditions:
mbed_official 16:4f6df64750bd 8 *
mbed_official 16:4f6df64750bd 9 * The above copyright notice and this permission notice shall be included in all copies or
mbed_official 16:4f6df64750bd 10 * substantial portions of the Software.
mbed_official 16:4f6df64750bd 11 *
mbed_official 16:4f6df64750bd 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
mbed_official 16:4f6df64750bd 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
mbed_official 16:4f6df64750bd 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
mbed_official 16:4f6df64750bd 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
mbed_official 16:4f6df64750bd 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
mbed_official 16:4f6df64750bd 17 */
mbed_official 16:4f6df64750bd 18
tolaipner 22:a4b9c279b437 19 #if defined(TARGET_STM32F4XX) or defined(TARGET_NUCLEO_F401RE)
mbed_official 16:4f6df64750bd 20
mbed_official 16:4f6df64750bd 21 #include "USBHAL.h"
mbed_official 16:4f6df64750bd 22 #include "USBRegs_STM32.h"
mbed_official 16:4f6df64750bd 23 #include "pinmap.h"
tolaipner 22:a4b9c279b437 24 #include "stm32f4xx_hal.h"
tolaipner 22:a4b9c279b437 25
tolaipner 22:a4b9c279b437 26
mbed_official 16:4f6df64750bd 27
mbed_official 16:4f6df64750bd 28 USBHAL * USBHAL::instance;
mbed_official 16:4f6df64750bd 29
mbed_official 16:4f6df64750bd 30 static volatile int epComplete = 0;
mbed_official 16:4f6df64750bd 31
mbed_official 16:4f6df64750bd 32 static uint32_t bufferEnd = 0;
mbed_official 16:4f6df64750bd 33 static const uint32_t rxFifoSize = 512;
mbed_official 16:4f6df64750bd 34 static uint32_t rxFifoCount = 0;
mbed_official 16:4f6df64750bd 35
mbed_official 16:4f6df64750bd 36 static uint32_t setupBuffer[MAX_PACKET_SIZE_EP0 >> 2];
mbed_official 16:4f6df64750bd 37
mbed_official 16:4f6df64750bd 38 uint32_t USBHAL::endpointReadcore(uint8_t endpoint, uint8_t *buffer) {
mbed_official 16:4f6df64750bd 39 return 0;
mbed_official 16:4f6df64750bd 40 }
mbed_official 16:4f6df64750bd 41
mbed_official 16:4f6df64750bd 42 USBHAL::USBHAL(void) {
mbed_official 16:4f6df64750bd 43 NVIC_DisableIRQ(OTG_FS_IRQn);
mbed_official 16:4f6df64750bd 44 epCallback[0] = &USBHAL::EP1_OUT_callback;
mbed_official 16:4f6df64750bd 45 epCallback[1] = &USBHAL::EP1_IN_callback;
mbed_official 16:4f6df64750bd 46 epCallback[2] = &USBHAL::EP2_OUT_callback;
mbed_official 16:4f6df64750bd 47 epCallback[3] = &USBHAL::EP2_IN_callback;
mbed_official 16:4f6df64750bd 48 epCallback[4] = &USBHAL::EP3_OUT_callback;
mbed_official 16:4f6df64750bd 49 epCallback[5] = &USBHAL::EP3_IN_callback;
mbed_official 16:4f6df64750bd 50
mbed_official 16:4f6df64750bd 51 // Enable power and clocking
mbed_official 16:4f6df64750bd 52 RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
mbed_official 16:4f6df64750bd 53
tolaipner 22:a4b9c279b437 54 #if defined(TARGET_NUCLEO_F401RE)
tolaipner 22:a4b9c279b437 55 pin_function(PA_9, STM_PIN_DATA(STM_MODE_INPUT, GPIO_NOPULL, 0xFF));
tolaipner 22:a4b9c279b437 56 pin_function(PA_10, STM_PIN_DATA(STM_MODE_AF_OD, GPIO_PULLUP, GPIO_AF10_OTG_FS));
tolaipner 22:a4b9c279b437 57 pin_function(PA_11, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
tolaipner 22:a4b9c279b437 58 pin_function(PA_12, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, GPIO_AF10_OTG_FS));
tolaipner 22:a4b9c279b437 59 #elif
mbed_official 16:4f6df64750bd 60 pin_function(PA_8, STM_PIN_DATA(2, 10));
mbed_official 16:4f6df64750bd 61 pin_function(PA_9, STM_PIN_DATA(0, 0));
mbed_official 16:4f6df64750bd 62 pin_function(PA_10, STM_PIN_DATA(2, 10));
mbed_official 16:4f6df64750bd 63 pin_function(PA_11, STM_PIN_DATA(2, 10));
mbed_official 16:4f6df64750bd 64 pin_function(PA_12, STM_PIN_DATA(2, 10));
tolaipner 24:4ed3e25c3edc 65
tolaipner 24:4ed3e25c3edc 66 // Set ID pin to open drain with pull-up resistor
tolaipner 24:4ed3e25c3edc 67 pin_mode(PA_10, OpenDrain);
tolaipner 24:4ed3e25c3edc 68 GPIOA->PUPDR &= ~(0x3 << 20);
tolaipner 24:4ed3e25c3edc 69 GPIOA->PUPDR |= 1 << 20;
tolaipner 24:4ed3e25c3edc 70
tolaipner 24:4ed3e25c3edc 71 // Set VBUS pin to open drain
tolaipner 24:4ed3e25c3edc 72 pin_mode(PA_9, OpenDrain);
tolaipner 22:a4b9c279b437 73 #endif
mbed_official 16:4f6df64750bd 74
mbed_official 16:4f6df64750bd 75 RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN;
mbed_official 16:4f6df64750bd 76
mbed_official 16:4f6df64750bd 77 // Enable interrupts
mbed_official 16:4f6df64750bd 78 OTG_FS->GREGS.GAHBCFG |= (1 << 0);
mbed_official 16:4f6df64750bd 79
mbed_official 16:4f6df64750bd 80 // Turnaround time to maximum value - too small causes packet loss
mbed_official 16:4f6df64750bd 81 OTG_FS->GREGS.GUSBCFG |= (0xF << 10);
mbed_official 16:4f6df64750bd 82
mbed_official 16:4f6df64750bd 83 // Unmask global interrupts
mbed_official 16:4f6df64750bd 84 OTG_FS->GREGS.GINTMSK |= (1 << 3) | // SOF
mbed_official 16:4f6df64750bd 85 (1 << 4) | // RX FIFO not empty
mbed_official 16:4f6df64750bd 86 (1 << 12); // USB reset
mbed_official 16:4f6df64750bd 87
mbed_official 16:4f6df64750bd 88 OTG_FS->DREGS.DCFG |= (0x3 << 0) | // Full speed
mbed_official 16:4f6df64750bd 89 (1 << 2); // Non-zero-length status OUT handshake
mbed_official 16:4f6df64750bd 90
mbed_official 16:4f6df64750bd 91 OTG_FS->GREGS.GCCFG |= (1 << 19) | // Enable VBUS sensing
mbed_official 16:4f6df64750bd 92 (1 << 16); // Power Up
mbed_official 16:4f6df64750bd 93
mbed_official 16:4f6df64750bd 94 instance = this;
mbed_official 16:4f6df64750bd 95 NVIC_SetVector(OTG_FS_IRQn, (uint32_t)&_usbisr);
mbed_official 16:4f6df64750bd 96 NVIC_SetPriority(OTG_FS_IRQn, 1);
mbed_official 16:4f6df64750bd 97 }
mbed_official 16:4f6df64750bd 98
mbed_official 16:4f6df64750bd 99 USBHAL::~USBHAL(void) {
mbed_official 16:4f6df64750bd 100 }
mbed_official 16:4f6df64750bd 101
mbed_official 16:4f6df64750bd 102 void USBHAL::connect(void) {
mbed_official 16:4f6df64750bd 103 NVIC_EnableIRQ(OTG_FS_IRQn);
mbed_official 16:4f6df64750bd 104 }
mbed_official 16:4f6df64750bd 105
mbed_official 16:4f6df64750bd 106 void USBHAL::disconnect(void) {
mbed_official 16:4f6df64750bd 107 NVIC_DisableIRQ(OTG_FS_IRQn);
mbed_official 16:4f6df64750bd 108 }
mbed_official 16:4f6df64750bd 109
mbed_official 16:4f6df64750bd 110 void USBHAL::configureDevice(void) {
mbed_official 16:4f6df64750bd 111 // Not needed
mbed_official 16:4f6df64750bd 112 }
mbed_official 16:4f6df64750bd 113
mbed_official 16:4f6df64750bd 114 void USBHAL::unconfigureDevice(void) {
mbed_official 16:4f6df64750bd 115 // Not needed
mbed_official 16:4f6df64750bd 116 }
mbed_official 16:4f6df64750bd 117
mbed_official 16:4f6df64750bd 118 void USBHAL::setAddress(uint8_t address) {
mbed_official 16:4f6df64750bd 119 OTG_FS->DREGS.DCFG |= (address << 4);
mbed_official 16:4f6df64750bd 120 EP0write(0, 0);
mbed_official 16:4f6df64750bd 121 }
mbed_official 16:4f6df64750bd 122
mbed_official 16:4f6df64750bd 123 bool USBHAL::realiseEndpoint(uint8_t endpoint, uint32_t maxPacket,
mbed_official 16:4f6df64750bd 124 uint32_t flags) {
mbed_official 16:4f6df64750bd 125 uint32_t epIndex = endpoint >> 1;
mbed_official 16:4f6df64750bd 126
mbed_official 16:4f6df64750bd 127 uint32_t type;
mbed_official 16:4f6df64750bd 128 switch (endpoint) {
mbed_official 16:4f6df64750bd 129 case EP0IN:
mbed_official 16:4f6df64750bd 130 case EP0OUT:
mbed_official 16:4f6df64750bd 131 type = 0;
mbed_official 16:4f6df64750bd 132 break;
mbed_official 16:4f6df64750bd 133 case EPISO_IN:
mbed_official 16:4f6df64750bd 134 case EPISO_OUT:
mbed_official 16:4f6df64750bd 135 type = 1;
mbed_official 16:4f6df64750bd 136 case EPBULK_IN:
mbed_official 16:4f6df64750bd 137 case EPBULK_OUT:
mbed_official 16:4f6df64750bd 138 type = 2;
mbed_official 16:4f6df64750bd 139 break;
mbed_official 16:4f6df64750bd 140 case EPINT_IN:
mbed_official 16:4f6df64750bd 141 case EPINT_OUT:
mbed_official 16:4f6df64750bd 142 type = 3;
mbed_official 16:4f6df64750bd 143 break;
mbed_official 16:4f6df64750bd 144 }
mbed_official 16:4f6df64750bd 145
mbed_official 16:4f6df64750bd 146 // Generic in or out EP controls
mbed_official 16:4f6df64750bd 147 uint32_t control = (maxPacket << 0) | // Packet size
mbed_official 16:4f6df64750bd 148 (1 << 15) | // Active endpoint
mbed_official 16:4f6df64750bd 149 (type << 18); // Endpoint type
mbed_official 16:4f6df64750bd 150
mbed_official 16:4f6df64750bd 151 if (endpoint & 0x1) { // In Endpoint
mbed_official 16:4f6df64750bd 152 // Set up the Tx FIFO
mbed_official 16:4f6df64750bd 153 if (endpoint == EP0IN) {
mbed_official 16:4f6df64750bd 154 OTG_FS->GREGS.DIEPTXF0_HNPTXFSIZ = ((maxPacket >> 2) << 16) |
mbed_official 16:4f6df64750bd 155 (bufferEnd << 0);
mbed_official 16:4f6df64750bd 156 }
mbed_official 16:4f6df64750bd 157 else {
mbed_official 16:4f6df64750bd 158 OTG_FS->GREGS.DIEPTXF[epIndex - 1] = ((maxPacket >> 2) << 16) |
mbed_official 16:4f6df64750bd 159 (bufferEnd << 0);
mbed_official 16:4f6df64750bd 160 }
mbed_official 16:4f6df64750bd 161 bufferEnd += maxPacket >> 2;
mbed_official 16:4f6df64750bd 162
mbed_official 16:4f6df64750bd 163 // Set the In EP specific control settings
mbed_official 16:4f6df64750bd 164 if (endpoint != EP0IN) {
mbed_official 16:4f6df64750bd 165 control |= (1 << 28); // SD0PID
mbed_official 16:4f6df64750bd 166 }
mbed_official 16:4f6df64750bd 167
mbed_official 16:4f6df64750bd 168 control |= (epIndex << 22) | // TxFIFO index
mbed_official 16:4f6df64750bd 169 (1 << 27); // SNAK
mbed_official 16:4f6df64750bd 170 OTG_FS->INEP_REGS[epIndex].DIEPCTL = control;
mbed_official 16:4f6df64750bd 171
mbed_official 16:4f6df64750bd 172 // Unmask the interrupt
mbed_official 16:4f6df64750bd 173 OTG_FS->DREGS.DAINTMSK |= (1 << epIndex);
mbed_official 16:4f6df64750bd 174 }
mbed_official 16:4f6df64750bd 175 else { // Out endpoint
mbed_official 16:4f6df64750bd 176 // Set the out EP specific control settings
mbed_official 16:4f6df64750bd 177 control |= (1 << 26); // CNAK
mbed_official 16:4f6df64750bd 178 OTG_FS->OUTEP_REGS[epIndex].DOEPCTL = control;
mbed_official 16:4f6df64750bd 179
mbed_official 16:4f6df64750bd 180 // Unmask the interrupt
mbed_official 16:4f6df64750bd 181 OTG_FS->DREGS.DAINTMSK |= (1 << (epIndex + 16));
mbed_official 16:4f6df64750bd 182 }
mbed_official 16:4f6df64750bd 183 return true;
mbed_official 16:4f6df64750bd 184 }
mbed_official 16:4f6df64750bd 185
mbed_official 16:4f6df64750bd 186 // read setup packet
mbed_official 16:4f6df64750bd 187 void USBHAL::EP0setup(uint8_t *buffer) {
mbed_official 16:4f6df64750bd 188 memcpy(buffer, setupBuffer, MAX_PACKET_SIZE_EP0);
mbed_official 16:4f6df64750bd 189 }
mbed_official 16:4f6df64750bd 190
mbed_official 16:4f6df64750bd 191 void USBHAL::EP0readStage(void) {
mbed_official 16:4f6df64750bd 192 }
mbed_official 16:4f6df64750bd 193
mbed_official 16:4f6df64750bd 194 void USBHAL::EP0read(void) {
mbed_official 16:4f6df64750bd 195 }
mbed_official 16:4f6df64750bd 196
mbed_official 16:4f6df64750bd 197 uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
mbed_official 16:4f6df64750bd 198 uint32_t* buffer32 = (uint32_t *) buffer;
mbed_official 16:4f6df64750bd 199 uint32_t length = rxFifoCount;
mbed_official 16:4f6df64750bd 200 for (uint32_t i = 0; i < length; i += 4) {
mbed_official 16:4f6df64750bd 201 buffer32[i >> 2] = OTG_FS->FIFO[0][0];
mbed_official 16:4f6df64750bd 202 }
mbed_official 16:4f6df64750bd 203
mbed_official 16:4f6df64750bd 204 rxFifoCount = 0;
mbed_official 16:4f6df64750bd 205 return length;
mbed_official 16:4f6df64750bd 206 }
mbed_official 16:4f6df64750bd 207
mbed_official 16:4f6df64750bd 208 void USBHAL::EP0write(uint8_t *buffer, uint32_t size) {
mbed_official 16:4f6df64750bd 209 endpointWrite(0, buffer, size);
mbed_official 16:4f6df64750bd 210 }
mbed_official 16:4f6df64750bd 211
mbed_official 16:4f6df64750bd 212 void USBHAL::EP0getWriteResult(void) {
mbed_official 16:4f6df64750bd 213 }
mbed_official 16:4f6df64750bd 214
mbed_official 16:4f6df64750bd 215 void USBHAL::EP0stall(void) {
mbed_official 16:4f6df64750bd 216 // If we stall the out endpoint here then we have problems transferring
mbed_official 16:4f6df64750bd 217 // and setup requests after the (stalled) get device qualifier requests.
mbed_official 16:4f6df64750bd 218 // TODO: Find out if this is correct behavior, or whether we are doing
mbed_official 16:4f6df64750bd 219 // something else wrong
mbed_official 16:4f6df64750bd 220 stallEndpoint(EP0IN);
mbed_official 16:4f6df64750bd 221 // stallEndpoint(EP0OUT);
mbed_official 16:4f6df64750bd 222 }
mbed_official 16:4f6df64750bd 223
mbed_official 16:4f6df64750bd 224 EP_STATUS USBHAL::endpointRead(uint8_t endpoint, uint32_t maximumSize) {
mbed_official 16:4f6df64750bd 225 uint32_t epIndex = endpoint >> 1;
mbed_official 16:4f6df64750bd 226 uint32_t size = (1 << 19) | // 1 packet
mbed_official 16:4f6df64750bd 227 (maximumSize << 0); // Packet size
mbed_official 16:4f6df64750bd 228 // if (endpoint == EP0OUT) {
mbed_official 16:4f6df64750bd 229 size |= (1 << 29); // 1 setup packet
mbed_official 16:4f6df64750bd 230 // }
mbed_official 16:4f6df64750bd 231 OTG_FS->OUTEP_REGS[epIndex].DOEPTSIZ = size;
mbed_official 16:4f6df64750bd 232 OTG_FS->OUTEP_REGS[epIndex].DOEPCTL |= (1 << 31) | // Enable endpoint
mbed_official 16:4f6df64750bd 233 (1 << 26); // Clear NAK
mbed_official 16:4f6df64750bd 234
mbed_official 16:4f6df64750bd 235 epComplete &= ~(1 << endpoint);
mbed_official 16:4f6df64750bd 236 return EP_PENDING;
mbed_official 16:4f6df64750bd 237 }
mbed_official 16:4f6df64750bd 238
mbed_official 16:4f6df64750bd 239 EP_STATUS USBHAL::endpointReadResult(uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) {
mbed_official 16:4f6df64750bd 240 if (!(epComplete & (1 << endpoint))) {
mbed_official 16:4f6df64750bd 241 return EP_PENDING;
mbed_official 16:4f6df64750bd 242 }
mbed_official 16:4f6df64750bd 243
mbed_official 16:4f6df64750bd 244 uint32_t* buffer32 = (uint32_t *) buffer;
mbed_official 16:4f6df64750bd 245 uint32_t length = rxFifoCount;
mbed_official 16:4f6df64750bd 246 for (uint32_t i = 0; i < length; i += 4) {
mbed_official 16:4f6df64750bd 247 buffer32[i >> 2] = OTG_FS->FIFO[endpoint >> 1][0];
mbed_official 16:4f6df64750bd 248 }
mbed_official 16:4f6df64750bd 249 rxFifoCount = 0;
mbed_official 16:4f6df64750bd 250 *bytesRead = length;
mbed_official 16:4f6df64750bd 251 return EP_COMPLETED;
mbed_official 16:4f6df64750bd 252 }
mbed_official 16:4f6df64750bd 253
mbed_official 16:4f6df64750bd 254 EP_STATUS USBHAL::endpointWrite(uint8_t endpoint, uint8_t *data, uint32_t size) {
mbed_official 16:4f6df64750bd 255 uint32_t epIndex = endpoint >> 1;
mbed_official 16:4f6df64750bd 256 OTG_FS->INEP_REGS[epIndex].DIEPTSIZ = (1 << 19) | // 1 packet
mbed_official 16:4f6df64750bd 257 (size << 0); // Size of packet
mbed_official 16:4f6df64750bd 258 OTG_FS->INEP_REGS[epIndex].DIEPCTL |= (1 << 31) | // Enable endpoint
mbed_official 16:4f6df64750bd 259 (1 << 26); // CNAK
mbed_official 16:4f6df64750bd 260 OTG_FS->DREGS.DIEPEMPMSK = (1 << epIndex);
mbed_official 16:4f6df64750bd 261
mbed_official 16:4f6df64750bd 262 while ((OTG_FS->INEP_REGS[epIndex].DTXFSTS & 0XFFFF) < ((size + 3) >> 2));
mbed_official 16:4f6df64750bd 263
mbed_official 16:4f6df64750bd 264 for (uint32_t i=0; i<(size + 3) >> 2; i++, data+=4) {
mbed_official 16:4f6df64750bd 265 OTG_FS->FIFO[epIndex][0] = *(uint32_t *)data;
mbed_official 16:4f6df64750bd 266 }
mbed_official 16:4f6df64750bd 267
mbed_official 16:4f6df64750bd 268 epComplete &= ~(1 << endpoint);
mbed_official 16:4f6df64750bd 269
mbed_official 16:4f6df64750bd 270 return EP_PENDING;
mbed_official 16:4f6df64750bd 271 }
mbed_official 16:4f6df64750bd 272
mbed_official 16:4f6df64750bd 273 EP_STATUS USBHAL::endpointWriteResult(uint8_t endpoint) {
mbed_official 16:4f6df64750bd 274 if (epComplete & (1 << endpoint)) {
mbed_official 16:4f6df64750bd 275 epComplete &= ~(1 << endpoint);
mbed_official 16:4f6df64750bd 276 return EP_COMPLETED;
mbed_official 16:4f6df64750bd 277 }
mbed_official 16:4f6df64750bd 278
mbed_official 16:4f6df64750bd 279 return EP_PENDING;
mbed_official 16:4f6df64750bd 280 }
mbed_official 16:4f6df64750bd 281
mbed_official 16:4f6df64750bd 282 void USBHAL::stallEndpoint(uint8_t endpoint) {
mbed_official 16:4f6df64750bd 283 if (endpoint & 0x1) { // In EP
mbed_official 16:4f6df64750bd 284 OTG_FS->INEP_REGS[endpoint >> 1].DIEPCTL |= (1 << 30) | // Disable
mbed_official 16:4f6df64750bd 285 (1 << 21); // Stall
mbed_official 16:4f6df64750bd 286 }
mbed_official 16:4f6df64750bd 287 else { // Out EP
mbed_official 16:4f6df64750bd 288 OTG_FS->DREGS.DCTL |= (1 << 9); // Set global out NAK
mbed_official 16:4f6df64750bd 289 OTG_FS->OUTEP_REGS[endpoint >> 1].DOEPCTL |= (1 << 30) | // Disable
mbed_official 16:4f6df64750bd 290 (1 << 21); // Stall
mbed_official 16:4f6df64750bd 291 }
mbed_official 16:4f6df64750bd 292 }
mbed_official 16:4f6df64750bd 293
mbed_official 16:4f6df64750bd 294 void USBHAL::unstallEndpoint(uint8_t endpoint) {
mbed_official 16:4f6df64750bd 295
mbed_official 16:4f6df64750bd 296 }
mbed_official 16:4f6df64750bd 297
mbed_official 16:4f6df64750bd 298 bool USBHAL::getEndpointStallState(uint8_t endpoint) {
mbed_official 16:4f6df64750bd 299 return false;
mbed_official 16:4f6df64750bd 300 }
mbed_official 16:4f6df64750bd 301
mbed_official 16:4f6df64750bd 302 void USBHAL::remoteWakeup(void) {
mbed_official 16:4f6df64750bd 303 }
mbed_official 16:4f6df64750bd 304
mbed_official 16:4f6df64750bd 305
mbed_official 16:4f6df64750bd 306 void USBHAL::_usbisr(void) {
mbed_official 16:4f6df64750bd 307 instance->usbisr();
mbed_official 16:4f6df64750bd 308 }
mbed_official 16:4f6df64750bd 309
mbed_official 16:4f6df64750bd 310
mbed_official 16:4f6df64750bd 311 void USBHAL::usbisr(void) {
mbed_official 16:4f6df64750bd 312 if (OTG_FS->GREGS.GINTSTS & (1 << 12)) { // USB Reset
mbed_official 16:4f6df64750bd 313 // Set SNAK bits
mbed_official 16:4f6df64750bd 314 OTG_FS->OUTEP_REGS[0].DOEPCTL |= (1 << 27);
mbed_official 16:4f6df64750bd 315 OTG_FS->OUTEP_REGS[1].DOEPCTL |= (1 << 27);
mbed_official 16:4f6df64750bd 316 OTG_FS->OUTEP_REGS[2].DOEPCTL |= (1 << 27);
mbed_official 16:4f6df64750bd 317 OTG_FS->OUTEP_REGS[3].DOEPCTL |= (1 << 27);
mbed_official 16:4f6df64750bd 318
mbed_official 16:4f6df64750bd 319 OTG_FS->DREGS.DIEPMSK = (1 << 0);
mbed_official 16:4f6df64750bd 320
mbed_official 16:4f6df64750bd 321 bufferEnd = 0;
mbed_official 16:4f6df64750bd 322
mbed_official 16:4f6df64750bd 323 // Set the receive FIFO size
mbed_official 16:4f6df64750bd 324 OTG_FS->GREGS.GRXFSIZ = rxFifoSize >> 2;
mbed_official 16:4f6df64750bd 325 bufferEnd += rxFifoSize >> 2;
mbed_official 16:4f6df64750bd 326
mbed_official 16:4f6df64750bd 327 // Create the endpoints, and wait for setup packets on out EP0
mbed_official 16:4f6df64750bd 328 realiseEndpoint(EP0IN, MAX_PACKET_SIZE_EP0, 0);
mbed_official 16:4f6df64750bd 329 realiseEndpoint(EP0OUT, MAX_PACKET_SIZE_EP0, 0);
mbed_official 16:4f6df64750bd 330 endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0);
mbed_official 16:4f6df64750bd 331
mbed_official 16:4f6df64750bd 332 OTG_FS->GREGS.GINTSTS = (1 << 12);
mbed_official 16:4f6df64750bd 333 }
mbed_official 16:4f6df64750bd 334
mbed_official 16:4f6df64750bd 335 if (OTG_FS->GREGS.GINTSTS & (1 << 4)) { // RX FIFO not empty
mbed_official 16:4f6df64750bd 336 uint32_t status = OTG_FS->GREGS.GRXSTSP;
mbed_official 16:4f6df64750bd 337
mbed_official 16:4f6df64750bd 338 uint32_t endpoint = (status & 0xF) << 1;
mbed_official 16:4f6df64750bd 339 uint32_t length = (status >> 4) & 0x7FF;
mbed_official 16:4f6df64750bd 340 uint32_t type = (status >> 17) & 0xF;
mbed_official 16:4f6df64750bd 341
mbed_official 16:4f6df64750bd 342 rxFifoCount = length;
mbed_official 16:4f6df64750bd 343
mbed_official 16:4f6df64750bd 344 if (type == 0x6) {
mbed_official 16:4f6df64750bd 345 // Setup packet
mbed_official 16:4f6df64750bd 346 for (uint32_t i=0; i<length; i+=4) {
mbed_official 16:4f6df64750bd 347 setupBuffer[i >> 2] = OTG_FS->FIFO[0][i >> 2];
mbed_official 16:4f6df64750bd 348 }
mbed_official 16:4f6df64750bd 349 rxFifoCount = 0;
mbed_official 16:4f6df64750bd 350 }
mbed_official 16:4f6df64750bd 351
mbed_official 16:4f6df64750bd 352 if (type == 0x4) {
mbed_official 16:4f6df64750bd 353 // Setup complete
mbed_official 16:4f6df64750bd 354 EP0setupCallback();
mbed_official 16:4f6df64750bd 355 endpointRead(EP0OUT, MAX_PACKET_SIZE_EP0);
mbed_official 16:4f6df64750bd 356 }
mbed_official 16:4f6df64750bd 357
mbed_official 16:4f6df64750bd 358 if (type == 0x2) {
mbed_official 16:4f6df64750bd 359 // Out packet
mbed_official 16:4f6df64750bd 360 if (endpoint == EP0OUT) {
mbed_official 16:4f6df64750bd 361 EP0out();
mbed_official 16:4f6df64750bd 362 }
mbed_official 16:4f6df64750bd 363 else {
mbed_official 16:4f6df64750bd 364 epComplete |= (1 << endpoint);
mbed_official 16:4f6df64750bd 365 if ((instance->*(epCallback[endpoint - 2]))()) {
mbed_official 16:4f6df64750bd 366 epComplete &= (1 << endpoint);
mbed_official 16:4f6df64750bd 367 }
mbed_official 16:4f6df64750bd 368 }
mbed_official 16:4f6df64750bd 369 }
mbed_official 16:4f6df64750bd 370
mbed_official 16:4f6df64750bd 371 for (uint32_t i=0; i<rxFifoCount; i+=4) {
mbed_official 16:4f6df64750bd 372 (void) OTG_FS->FIFO[0][0];
mbed_official 16:4f6df64750bd 373 }
mbed_official 16:4f6df64750bd 374 OTG_FS->GREGS.GINTSTS = (1 << 4);
mbed_official 16:4f6df64750bd 375 }
mbed_official 16:4f6df64750bd 376
mbed_official 16:4f6df64750bd 377 if (OTG_FS->GREGS.GINTSTS & (1 << 18)) { // In endpoint interrupt
mbed_official 16:4f6df64750bd 378 // Loop through the in endpoints
mbed_official 16:4f6df64750bd 379 for (uint32_t i=0; i<4; i++) {
mbed_official 16:4f6df64750bd 380 if (OTG_FS->DREGS.DAINT & (1 << i)) { // Interrupt is on endpoint
mbed_official 16:4f6df64750bd 381
mbed_official 16:4f6df64750bd 382 if (OTG_FS->INEP_REGS[i].DIEPINT & (1 << 7)) {// Tx FIFO empty
mbed_official 16:4f6df64750bd 383 // If the Tx FIFO is empty on EP0 we need to send a further
mbed_official 16:4f6df64750bd 384 // packet, so call EP0in()
mbed_official 16:4f6df64750bd 385 if (i == 0) {
mbed_official 16:4f6df64750bd 386 EP0in();
mbed_official 16:4f6df64750bd 387 }
mbed_official 16:4f6df64750bd 388 // Clear the interrupt
mbed_official 16:4f6df64750bd 389 OTG_FS->INEP_REGS[i].DIEPINT = (1 << 7);
mbed_official 16:4f6df64750bd 390 // Stop firing Tx empty interrupts
mbed_official 16:4f6df64750bd 391 // Will get turned on again if another write is called
mbed_official 16:4f6df64750bd 392 OTG_FS->DREGS.DIEPEMPMSK &= ~(1 << i);
mbed_official 16:4f6df64750bd 393 }
mbed_official 16:4f6df64750bd 394
mbed_official 16:4f6df64750bd 395 // If the transfer is complete
mbed_official 16:4f6df64750bd 396 if (OTG_FS->INEP_REGS[i].DIEPINT & (1 << 0)) { // Tx Complete
mbed_official 16:4f6df64750bd 397 epComplete |= (1 << (1 + (i << 1)));
mbed_official 16:4f6df64750bd 398 OTG_FS->INEP_REGS[i].DIEPINT = (1 << 0);
mbed_official 16:4f6df64750bd 399 }
mbed_official 16:4f6df64750bd 400 }
mbed_official 16:4f6df64750bd 401 }
mbed_official 16:4f6df64750bd 402 OTG_FS->GREGS.GINTSTS = (1 << 18);
mbed_official 16:4f6df64750bd 403 }
mbed_official 16:4f6df64750bd 404
mbed_official 16:4f6df64750bd 405 if (OTG_FS->GREGS.GINTSTS & (1 << 3)) { // Start of frame
mbed_official 16:4f6df64750bd 406 SOF((OTG_FS->GREGS.GRXSTSR >> 17) & 0xF);
mbed_official 16:4f6df64750bd 407 OTG_FS->GREGS.GINTSTS = (1 << 3);
mbed_official 16:4f6df64750bd 408 }
mbed_official 16:4f6df64750bd 409 }
mbed_official 16:4f6df64750bd 410
mbed_official 16:4f6df64750bd 411
mbed_official 16:4f6df64750bd 412 #endif