@@ -110,10 +110,59 @@ void USBHAL::setAddress(uint8_t address) {
110
110
EP0write (0 , 0 );
111
111
}
112
112
113
- bool USBHAL::realiseEndpoint (uint8_t endpoint, uint32_t maxPacket, uint32_t flags) {
113
+ bool USBHAL::realiseEndpoint (uint8_t endpoint, uint32_t maxPacket,
114
+ uint32_t flags) {
115
+ uint32_t epIndex = endpoint >> 1 ;
116
+
117
+ uint32_t type;
118
+ switch (endpoint) {
119
+ case EP0IN:
120
+ case EP0OUT:
121
+ type = 0 ;
122
+ break ;
123
+ case EPISO_IN:
124
+ case EPISO_OUT:
125
+ type = 1 ;
126
+ case EPBULK_IN:
127
+ case EPBULK_OUT:
128
+ type = 2 ;
129
+ break ;
130
+ case EPINT_IN:
131
+ case EPINT_OUT:
132
+ type = 3 ;
133
+ break ;
134
+ }
135
+
136
+ // Generic in or out EP controls
137
+ uint32_t control = (maxPacket << 0 ) | // Packet size
138
+ (1 << 15 ) | // Active endpoint
139
+ (type << 18 ); // Endpoint type
140
+
114
141
if (endpoint & 0x1 ) { // In Endpoint
142
+ // Set up the Tx FIFO
143
+ OTG_FS->GREGS .DIEPTXF [epIndex - 1 ] = ((maxPacket >> 2 ) << 16 ) |
144
+ (bufferEnd << 0 );
145
+ bufferEnd += maxPacket >> 2 ;
146
+
147
+ // Set the In EP specific control settings
148
+ if (endpoint != EP0IN) {
149
+ control |= (1 << 28 ); // SD0PID
150
+ }
151
+
152
+ control |= (epIndex << 22 ) | // TxFIFO index
153
+ (1 << 27 ); // SNAK
154
+ OTG_FS->INEP_REGS [epIndex].DIEPCTL = control;
155
+
156
+ // Unmask the interrupt
157
+ OTG_FS->DREGS .DAINTMSK |= (1 << epIndex);
115
158
}
116
- else {
159
+ else { // Out endpoint
160
+ // Set the out EP specific control settings
161
+ control |= (1 << 26 ); // CNAK
162
+ OTG_FS->OUTEP_REGS [epIndex].DOEPCTL = control;
163
+
164
+ // Unmask the interrupt
165
+ OTG_FS->DREGS .DAINTMSK |= (1 << (epIndex + 16 ));
117
166
}
118
167
return true ;
119
168
}
@@ -141,16 +190,7 @@ uint32_t USBHAL::EP0getReadResult(uint8_t *buffer) {
141
190
}
142
191
143
192
void USBHAL::EP0write (uint8_t *buffer, uint32_t size) {
144
- OTG_FS->INEP_REGS [0 ].DIEPTSIZ = (1 << 19 ) | // 1 packet
145
- (size << 0 ); // Size of packet
146
- OTG_FS->INEP_REGS [0 ].DIEPCTL |= (1 << 31 ) | // Enable endpoint
147
- (1 << 26 ); // CNAK
148
-
149
- while ((OTG_FS->INEP_REGS [0 ].DTXFSTS & 0XFFFF ) < ((size + 3 ) >> 2 ));
150
-
151
- for (uint32_t i=0 ; i<(size + 3 ) >> 2 ; i++, buffer+=4 ) {
152
- OTG_FS->FIFO [0 ][0 ] = *(uint32_t *)buffer;
153
- }
193
+ endpointWrite (0 , buffer, size);
154
194
}
155
195
156
196
void USBHAL::EP0getWriteResult (void ) {
@@ -162,19 +202,58 @@ void USBHAL::EP0stall(void) {
162
202
}
163
203
164
204
EP_STATUS USBHAL::endpointRead (uint8_t endpoint, uint32_t maximumSize) {
205
+ uint32_t epIndex = endpoint >> 1 ;
206
+ OTG_FS->OUTEP_REGS [epIndex].DOEPTSIZ = (1 << 29 ) | // 1 packet per frame
207
+ (1 << 19 ) | // 1 packet
208
+ (maximumSize << 0 ); // Packet size
209
+ OTG_FS->OUTEP_REGS [epIndex].DOEPCTL |= (1 << 31 ) | // Enable endpoint
210
+ (1 << 26 ); // Clear NAK
211
+
212
+ epComplete &= ~(1 << endpoint);
165
213
return EP_PENDING;
166
214
}
167
215
168
216
EP_STATUS USBHAL::endpointReadResult (uint8_t endpoint, uint8_t * buffer, uint32_t *bytesRead) {
217
+ if (!(epComplete & (1 << endpoint))) {
218
+ return EP_PENDING;
219
+ }
220
+
221
+ uint32_t * buffer32 = (uint32_t *) buffer;
222
+ uint32_t length = rxFifoCount;
223
+ for (uint32_t i = 0 ; i < length; i += 4 ) {
224
+ buffer32[i >> 2 ] = OTG_FS->FIFO [endpoint >> 1 ][0 ];
225
+ }
226
+ rxFifoCount = 0 ;
227
+ *bytesRead = length;
169
228
return EP_COMPLETED;
170
229
}
171
230
172
231
EP_STATUS USBHAL::endpointWrite (uint8_t endpoint, uint8_t *data, uint32_t size) {
173
- return EP_COMPLETED;
232
+ uint32_t epIndex = endpoint >> 1 ;
233
+ OTG_FS->INEP_REGS [epIndex].DIEPTSIZ = (1 << 19 ) | // 1 packet
234
+ (size << 0 ); // Size of packet
235
+ OTG_FS->INEP_REGS [epIndex].DIEPCTL |= (1 << 31 ) | // Enable endpoint
236
+ (1 << 26 ); // CNAK
237
+ OTG_FS->DREGS .DIEPEMPMSK = (1 << epIndex);
238
+
239
+ while ((OTG_FS->INEP_REGS [epIndex].DTXFSTS & 0XFFFF ) < ((size + 3 ) >> 2 ));
240
+
241
+ for (uint32_t i=0 ; i<(size + 3 ) >> 2 ; i++, data+=4 ) {
242
+ OTG_FS->FIFO [epIndex][0 ] = *(uint32_t *)data;
243
+ }
244
+
245
+ epComplete &= ~(1 << endpoint);
246
+
247
+ return EP_PENDING;
174
248
}
175
249
176
250
EP_STATUS USBHAL::endpointWriteResult (uint8_t endpoint) {
177
- return EP_COMPLETED;
251
+ if (epComplete & (1 << endpoint)) {
252
+ epComplete &= ~(1 << endpoint);
253
+ return EP_COMPLETED;
254
+ }
255
+
256
+ return EP_PENDING;
178
257
}
179
258
180
259
void USBHAL::stallEndpoint (uint8_t endpoint) {
@@ -218,8 +297,7 @@ void USBHAL::usbisr(void) {
218
297
(1 << 16 ); // Out 0 EP Mask
219
298
OTG_FS->DREGS .DOEPMSK = (1 << 0 ) | // Transfer complete
220
299
(1 << 3 ); // Setup phase done
221
-
222
- OTG_FS->DREGS .DIEPEMPMSK = (1 << 0 );
300
+ OTG_FS->DREGS .DIEPMSK |= (1 << 0 );
223
301
224
302
bufferEnd = 0 ;
225
303
@@ -231,18 +309,18 @@ void USBHAL::usbisr(void) {
231
309
bufferEnd += (MAX_PACKET_SIZE_EP0 >> 2 );
232
310
OTG_FS->OUTEP_REGS [0 ].DOEPTSIZ |= (0x3 << 29 ); // 3 setup packets
233
311
234
- OTG_FS->GREGS .GINTSTS | = (1 << 12 );
312
+ OTG_FS->GREGS .GINTSTS = (1 << 12 );
235
313
}
236
314
237
315
if (OTG_FS->GREGS .GINTSTS & (1 << 13 )) { // Enumeration done
238
316
OTG_FS->INEP_REGS [0 ].DIEPCTL &= ~(0x3 << 0 ); // 64 byte packet size
239
- OTG_FS->GREGS .GINTSTS | = (1 << 13 );
317
+ OTG_FS->GREGS .GINTSTS = (1 << 13 );
240
318
}
241
319
242
320
if (OTG_FS->GREGS .GINTSTS & (1 << 4 )) { // RX FIFO not empty
243
321
uint32_t status = OTG_FS->GREGS .GRXSTSP ;
244
322
245
- uint32_t endpoint = status & 0xF ;
323
+ uint32_t endpoint = ( status & 0xF ) << 1 ;
246
324
uint32_t length = (status >> 4 ) & 0x7FF ;
247
325
uint32_t type = (status >> 17 ) & 0xF ;
248
326
@@ -263,18 +341,76 @@ void USBHAL::usbisr(void) {
263
341
(1 << 26 ); // CNAK
264
342
}
265
343
344
+ if (type == 0x2 ) {
345
+ // Out packet
346
+ if (endpoint == 0 ) {
347
+ EP0out ();
348
+ }
349
+ else {
350
+ epComplete |= (1 << endpoint);
351
+ if ((instance->*(epCallback[endpoint - 2 ]))()) {
352
+ epComplete &= (1 << endpoint);
353
+ }
354
+ }
355
+ }
356
+
266
357
for (uint32_t i=0 ; i<rxFifoCount; i+=4 ) {
267
358
(void ) OTG_FS->FIFO [0 ][0 ];
268
- }
359
+ }
360
+ OTG_FS->GREGS .GINTSTS = (1 << 4 );
269
361
}
270
362
271
363
if (OTG_FS->GREGS .GINTSTS & (1 << 18 )) { // In endpoint interrupt
272
- if (OTG_FS->DREGS .DAINT & (1 << 0 )) { // In EP 0
273
- if (OTG_FS->INEP_REGS [0 ].DIEPINT & (1 << 7 )) {
274
- EP0in ();
364
+ // Loop through the in endpoints
365
+ for (uint32_t i=0 ; i<4 ; i++) {
366
+ if (OTG_FS->DREGS .DAINT & (1 << i)) { // Interrupt is on endpoint
367
+
368
+ // If the Tx FIFO is empty on EP0 we need to send a further
369
+ // packet, so call EP0in()
370
+ if (OTG_FS->INEP_REGS [i].DIEPINT & (1 << 7 )) {// Tx FIFO empty
371
+ // If the Tx FIFO is empty on EP0 we need to send a further
372
+ // packet, so call EP0in()
373
+ if (i == 0 ) {
374
+ EP0in ();
375
+ }
376
+ // Clear the interrupt
377
+ OTG_FS->INEP_REGS [i].DIEPINT = (1 << 7 );
378
+ // Stop firing Tx empty interrupts
379
+ // Will get turned on again if another write is called
380
+ OTG_FS->DREGS .DIEPEMPMSK &= ~(1 << i);
381
+ }
382
+
383
+ // If the transfer is complete
384
+ if (OTG_FS->INEP_REGS [i].DIEPINT & (1 << 0 )) { // Tx Complete
385
+ epComplete |= (1 << (1 + (i << 1 )));
386
+ OTG_FS->INEP_REGS [i].DIEPINT = (1 << 0 );
387
+ }
275
388
}
276
389
}
390
+ OTG_FS->GREGS .GINTSTS = (1 << 18 );
277
391
}
392
+
393
+ if (OTG_FS->GREGS .GINTSTS & (1 << 3 )) { // Start of frame
394
+ SOF ((OTG_FS->GREGS .GRXSTSR >> 17 ) & 0xF );
395
+ OTG_FS->GREGS .GINTSTS = (1 << 3 );
396
+ }
397
+
398
+ if (OTG_FS->GREGS .GINTSTS & (1 << 1 )) {
399
+ OTG_FS->GREGS .GINTSTS = (1 << 1 );
400
+ }
401
+
402
+ if (OTG_FS->GREGS .GINTSTS & (1 << 2 )) {
403
+ OTG_FS->GREGS .GINTSTS = (1 << 2 );
404
+ }
405
+
406
+ if (OTG_FS->GREGS .GINTSTS & (1 << 10 )) {
407
+ OTG_FS->GREGS .GINTSTS = (1 << 10 );
408
+ }
409
+
410
+ if (OTG_FS->GREGS .GINTSTS & (1 << 11 )) {
411
+ OTG_FS->GREGS .GINTSTS = (1 << 11 );
412
+ }
413
+
278
414
}
279
415
280
416
0 commit comments