USB device stack

Dependents:   USBMSD_step1 USBMSD_step1_5 picossd_step1_2cs

Committer:
Kojto
Date:
Thu Jul 27 12:14:04 2017 +0100
Revision:
71:53949e6131f6
Update libraries

Fixes the previous commmit, as some devices were not copied. USBDevice contains
now targets directory with all targets implementations

Who changed what in which revision?

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