blob: e5e581b153c4b2e36c0a50dcbd04e64d6a3ca5f1 [file] [log] [blame]
Brian Silvermanf91524f2017-09-23 13:15:55 -04001#include "motors/usb/usb.h"
2
3#include <string.h>
4
Brian Silverman4aa83042018-01-05 12:47:31 -08005#include <map>
6
Brian Silvermanf91524f2017-09-23 13:15:55 -04007#include "motors/util.h"
8
Stephan Pleinesf63bde82024-01-13 15:59:33 -08009namespace frc971::teensy {
Brian Silvermanf91524f2017-09-23 13:15:55 -040010namespace {
11
12// The mask of interrupts we care about.
13constexpr uint32_t usb_enabled_interrupts() {
14 // Deliberately not turning the sleep interrupt on here because we just
15 // want to ignore that anyways.
16 return USB_INTEN_TOKDNEEN | USB_INTEN_SOFTOKEN | USB_INTEN_ERROREN |
17 USB_INTEN_USBRSTEN;
18}
19
20// The names of all the standard setup requests which come in on endpoint 0.
21namespace standard_setup_requests {
22constexpr int kGetStatus = 0;
23constexpr int kClearFeature = 1;
24constexpr int kSetFeature = 3;
25constexpr int kSetAddress = 5;
26constexpr int kGetDescriptor = 6;
27constexpr int kSetDescriptor = 7;
28constexpr int kGetConfiguration = 8;
29constexpr int kSetConfiguration = 9;
30constexpr int kGetInterface = 10;
31constexpr int kSetInterface = 11;
32constexpr int kSynchFrame = 12;
33} // namespace standard_setup_requests
34
35// The names of the standard feature selectors.
36namespace standard_feature_selectors {
37constexpr int kDeviceRemoteWakeup = 1;
38constexpr int kEndpointHalt = 0;
39constexpr int kTestMode = 2;
40} // namespace standard_feature_selectors
41
42// The names of all the PIDs (Packet IDs) from the USB standard. Note that this
43// USB hardware doesn't expose most of them, especially in device mode.
44enum class UsbPid {
45 kOut = 0x1,
46 kIn = 0x9,
47 kSof = 0x5,
48 kSetup = 0xD,
49 kData0 = 0x3,
50 kData1 = 0xB,
51 kData2 = 0x7,
52 kMData = 0xF,
53 kAck = 0x2,
54 kNak = 0xA,
55 kStall = 0xE,
56 kNYet = 0x6,
57 kPre = 0xC,
58 kErr = 0xC,
59 kSplit = 0x8,
60 kPing = 0x4,
61 kReserved = 0x0,
62};
63
64// The device class for using IADs.
65constexpr uint8_t iad_device_class() { return 0xEF; }
66// The device subclass for using IADs.
67constexpr uint8_t iad_device_subclass() { return 0x02; }
68// The device protocol for using IADs.
69constexpr uint8_t iad_device_protocol() { return 0x01; }
70
Brian Silverman4aa83042018-01-05 12:47:31 -080071// The Microsoft "vendor code" we're going to use. It's pretty arbitrary (just
72// has to not be some other request we want to use).
73constexpr uint8_t microsoft_vendor_code() { return 0x67; }
74
Brian Silvermanf91524f2017-09-23 13:15:55 -040075// The total number of endpoints supported by this hardware.
76constexpr int number_endpoints() { return 16; }
77
Philipp Schrader790cb542023-07-05 21:06:52 -070078__attribute__((aligned(512)))
79BdtEntry usb0_buffer_descriptor_table[number_endpoints() * 2 /* rx/tx */ *
80 2 /* even/odd */];
Brian Silvermanf91524f2017-09-23 13:15:55 -040081
82// Returns the specified BDT entry.
83BdtEntry *MutableBdtEntry(int endpoint, Direction direction, EvenOdd odd) {
84 return &usb0_buffer_descriptor_table[static_cast<uint32_t>(endpoint << 2) |
85 static_cast<uint32_t>(direction) |
86 static_cast<uint32_t>(odd)];
87}
88
89// Returns the BDT entry corresponding to a USBx_STAT value.
90BdtEntry *MutableBdtEntryFromStat(uint8_t stat) {
91 return &usb0_buffer_descriptor_table[static_cast<uint32_t>(stat) >> 2];
92}
93
94// A pointer to the object we're going to ask to handle interrupts.
95UsbDevice *volatile global_usb0_device = nullptr;
96
97} // namespace
98
Brian Silverman19ea60f2018-01-03 21:43:15 -080099constexpr int UsbDevice::kEndpoint0MaxSize;
100
Brian Silvermanf91524f2017-09-23 13:15:55 -0400101UsbDevice::UsbDevice(int index, uint16_t vendor_id, uint16_t product_id)
102 : index_(index) {
103 // TODO(Brian): Pass index_ into all the register access macros. Also sort out
104 // how to deal with it for the interrupts.
105 assert(index == 0);
106
107 assert(global_usb0_device == nullptr);
108 global_usb0_device = this;
109
110 // Endpoint 0 isn't a normal endpoint, so it doesn't show up in here.
111 endpoint_mapping_.push_back(nullptr);
112
113 // Set up the "String Descriptor Zero, Specifying Languages Supported by the
114 // Device" (aka english_us_code() only).
115 strings_.emplace_back(4, '\0');
116 strings_.back()[0] = 4;
117 strings_.back()[1] = static_cast<uint8_t>(UsbDescriptorType::kString);
118 strings_.back()[2] = english_us_code() & 0xFF;
119 strings_.back()[3] = (english_us_code() >> 8) & 0xFF;
120
121 device_descriptor_ =
122 device_descriptor_list_.CreateDescriptor(18, UsbDescriptorType::kDevice);
Philipp Schrader790cb542023-07-05 21:06:52 -0700123 device_descriptor_->AddUint16(0x0200); // bcdUSB
124 device_descriptor_->AddByte(iad_device_class()); // bDeviceClass
Brian Silvermanf91524f2017-09-23 13:15:55 -0400125 device_descriptor_->AddByte(iad_device_subclass()); // bDeviceSubClass
126 device_descriptor_->AddByte(iad_device_protocol()); // bDeviceProtocol
Philipp Schrader790cb542023-07-05 21:06:52 -0700127 device_descriptor_->AddByte(kEndpoint0MaxSize); // bMaxPacketSize0
128 device_descriptor_->AddUint16(vendor_id); // idVendor
129 device_descriptor_->AddUint16(product_id); // idProduct
Brian Silverman4aa83042018-01-05 12:47:31 -0800130 // Increment this whenever you need Windows boxes to actually pay attention to
131 // changes.
Austin Schuh75c6af42018-03-09 21:16:07 -0800132 device_descriptor_->AddUint16(25); // bcdDevice
Brian Silvermanf91524f2017-09-23 13:15:55 -0400133 // We might overwrite these string descriptor indices later if we get strings
134 // to put there.
135 device_descriptor_->AddByte(0); // iManufacturer
136 device_descriptor_->AddByte(0); // iProduct
137 device_descriptor_->AddByte(0); // iSerialNumber
138 device_descriptor_->AddByte(1); // bNumConfigurations
139
140 config_descriptor_ = config_descriptor_list_.CreateDescriptor(
141 9, UsbDescriptorType::kConfiguration);
142}
143
144UsbDevice::~UsbDevice() {
145 NVIC_DISABLE_IRQ(IRQ_USBOTG);
146 dma_memory_barrier();
147 assert(global_usb0_device == this);
148 global_usb0_device = nullptr;
149}
150
151void UsbDevice::Initialize() {
152 assert(!is_set_up_);
153
154 for (UsbFunction *function : functions_) {
155 function->Initialize();
156 }
157
Brian Silverman4aa83042018-01-05 12:47:31 -0800158 {
159 const uint32_t length = 16 + 24 * functions_.size();
160 microsoft_extended_id_descriptor_.resize(length);
161 int index = 0;
162
163 // dwLength
164 microsoft_extended_id_descriptor_[index++] = length & 0xFF;
165 microsoft_extended_id_descriptor_[index++] = (length >> UINT32_C(8)) & 0xFF;
166 microsoft_extended_id_descriptor_[index++] =
167 (length >> UINT32_C(16)) & 0xFF;
168 microsoft_extended_id_descriptor_[index++] =
169 (length >> UINT32_C(24)) & 0xFF;
170
171 // bcdVersion
172 microsoft_extended_id_descriptor_[index++] = 0x00;
173 microsoft_extended_id_descriptor_[index++] = 0x01;
174
175 // wIndex
176 microsoft_extended_id_descriptor_[index++] =
177 microsoft_feature_descriptors::kExtendedCompatibilityId;
178 microsoft_extended_id_descriptor_[index++] = 0;
179
180 // bCount
181 microsoft_extended_id_descriptor_[index++] = functions_.size();
182
183 // Reserved
184 index += 7;
185
186 for (UsbFunction *function : functions_) {
187 // bFirstInterfaceNumber
188 microsoft_extended_id_descriptor_[index++] = function->first_interface_;
189
190 // Reserved
191 index++;
192
193 // compatibleID and subCompatibleID
194 microsoft_extended_id_descriptor_.replace(
195 index, 16, function->MicrosoftExtendedCompatibleId());
196 index += 16;
197
198 // Reserved
199 index += 6;
200 }
201
202 assert(index == length);
203 }
204
Brian Silvermanf91524f2017-09-23 13:15:55 -0400205 config_descriptor_->AddUint16(
206 config_descriptor_list_.CurrentSize()); // wTotalLength
207 config_descriptor_->AddByte(interface_mapping_.size()); // bNumInterfaces
208 config_descriptor_->AddByte(1); // bConfigurationValue
209 // Doesn't seem to be much point naming our one and only configuration.
210 config_descriptor_->AddByte(0); // iConfiguration
211 config_descriptor_->AddByte((1 << 7) /* Reserved */ |
212 (1 << 6) /* Self-powered */); // bmAttribute
Philipp Schrader790cb542023-07-05 21:06:52 -0700213 config_descriptor_->AddByte(2 /* 4mA */); // bMaxPower
Brian Silvermanf91524f2017-09-23 13:15:55 -0400214
215 device_descriptor_.reset();
216 config_descriptor_.reset();
217 device_descriptor_list_.CheckFinished();
218 config_descriptor_list_.CheckFinished();
219 is_set_up_ = true;
220
221 // Make sure all the buffer descriptors are clear.
222 for (int i = 0; i < number_endpoints(); ++i) {
223 for (Direction direction : {Direction::kTx, Direction::kRx}) {
224 for (EvenOdd odd : {EvenOdd::kOdd, EvenOdd::kEven}) {
225 MutableBdtEntry(i, direction, odd)->buffer_descriptor = 0;
226 MutableBdtEntry(i, direction, odd)->address = nullptr;
227 }
228 }
229 }
230 dma_memory_barrier();
231
232 // The other startup code handles getting the incoming 48MHz clock running.
233 SIM_SCGC4 |= SIM_SCGC4_USBOTG;
234 MPU_RGDAAC0 |= 0x03000000;
235
236 // Reset it.
237 USB0_USBTRC0 = USB_USBTRC_USBRESET;
238 // TRM says to wait "two USB clock cycles", so assume that's at 48MHz and then
239 // round up, being pessimistic in assuming each read from the peripheral is
240 // only a single core clock. This wildly overapproximates how long we need to
241 // wait, but whatever.
242 for (int i = 0; i < ((F_CPU / 48000000) + 1) * 2; ++i) {
243 while ((USB0_USBTRC0 & USB_USBTRC_USBRESET) != 0) {
244 }
245 }
246
247 USB0_BDTPAGE1 =
248 reinterpret_cast<uintptr_t>(&usb0_buffer_descriptor_table[0]) >> 8;
249 USB0_BDTPAGE2 =
250 reinterpret_cast<uintptr_t>(&usb0_buffer_descriptor_table[0]) >> 16;
251 USB0_BDTPAGE3 =
252 reinterpret_cast<uintptr_t>(&usb0_buffer_descriptor_table[0]) >> 24;
253
254 // The Quick Reference User Guide says to clear all the interrupts.
255 ClearInterrupts();
256 USB0_OTGISTAT = USB_OTGISTAT_ONEMSEC | USB_OTGISTAT_LINE_STATE_CHG;
257
258 // Now enable the module.
259 USB0_CTL = USB_CTL_USBENSOFEN;
260
261 // Un-suspend the transceiver and disable weak pulldowns.
262 USB0_USBCTRL = 0;
263 // And enable the D+ pullup which indicates we're a full-speed device.
264 USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG;
265
266 // Enable the reset interrupt (which is the first one we care about).
267 USB0_INTEN = USB_INTEN_USBRSTEN;
268
269 dma_memory_barrier();
270 NVIC_ENABLE_IRQ(IRQ_USBOTG);
271}
272
273void usb_isr(void) {
274 UsbDevice *const usb0_device = global_usb0_device;
275 if (usb0_device == nullptr) {
276 NVIC_DISABLE_IRQ(IRQ_USBOTG);
277 } else {
278 usb0_device->HandleInterrupt();
279 }
280}
281
282void UsbDevice::ClearInterrupts() {
283 USB0_ISTAT = USB_ISTAT_ATTACH | USB_ISTAT_RESUME | USB_ISTAT_SLEEP |
284 USB_ISTAT_TOKDNE | USB_ISTAT_SOFTOK | USB_ISTAT_ERROR |
285 USB_ISTAT_USBRST;
286 USB0_ERRSTAT = USB_ERRSTAT_BTSERR | USB_ERRSTAT_DMAERR | USB_ERRSTAT_BTOERR |
287 USB_ERRSTAT_DFN8 | USB_ERRSTAT_CRC16 | USB_ERRSTAT_CRC5EOF |
288 USB_ERRSTAT_PIDERR;
289}
290
291void UsbDevice::HandleInterrupt() {
292 while (true) {
293 const uint32_t status = USB0_ISTAT;
294 if ((status & usb_enabled_interrupts()) == 0) {
295 return;
296 }
297
298 // If we just got a start-of-frame token, then ask all the functions what to
299 // do.
300 if (status & USB_ISTAT_SOFTOK) {
301 // TODO(Brian): Actually ask the functions, maybe only if we're
302 // configured.
303 USB0_ISTAT = USB_ISTAT_SOFTOK;
304 }
305
306 // If we just finished processing a token.
307 if (status & USB_ISTAT_TOKDNE) {
308 const uint8_t stat = USB0_STAT;
Brian Silverman69f96c22017-11-01 02:54:02 -0400309 USB0_ISTAT = USB_ISTAT_TOKDNE;
Brian Silvermanf91524f2017-09-23 13:15:55 -0400310 const int endpoint = G_USB_STAT_ENDP(stat);
311
312 if (endpoint == 0) {
313 HandleEndpoint0Token(stat);
314 } else {
315 BdtEntry *const bdt_entry = MutableBdtEntryFromStat(stat);
316 const UsbPid pid = G_USB_BD_PID(bdt_entry->buffer_descriptor);
317 UsbFunction *const function = endpoint_mapping_[endpoint];
318 if (function == nullptr) {
319 // Should never happen, so stall if we do get here somehow.
320 StallEndpoint(endpoint);
321 } else {
322 switch (pid) {
323 case UsbPid::kOut:
324 function->HandleOutFinished(endpoint, bdt_entry);
325 break;
326
327 case UsbPid::kIn:
328 function->HandleInFinished(
329 endpoint, bdt_entry,
330 (stat & M_USB_STAT_ODD) ? EvenOdd::kOdd : EvenOdd::kEven);
331 break;
332
333 case UsbPid::kSetup:
334 default:
335 // Should never happen, so stall if we do get here somehow.
336 StallEndpoint(endpoint);
337 break;
338 }
339 }
340 }
Brian Silvermanf91524f2017-09-23 13:15:55 -0400341 }
342
343 if (status & USB_ISTAT_USBRST) {
344 // Use DATA0 for all endpoints.
345 USB0_CTL = USB_CTL_ODDRST;
346 endpoint0_tx_odd_ = EvenOdd::kEven;
347 endpoint0_tx_toggle_ = Data01::kData0;
348
349 for (UsbFunction *function : functions_) {
350 function->HandleReset();
351 }
352
353 MutableBdtEntry(0, Direction::kRx, EvenOdd::kEven)->buffer_descriptor =
354 M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
355 MutableBdtEntry(0, Direction::kRx, EvenOdd::kEven)->address =
356 &endpoint0_receive_buffer_[0][0];
357
358 MutableBdtEntry(0, Direction::kRx, EvenOdd::kOdd)->buffer_descriptor =
359 M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
360 MutableBdtEntry(0, Direction::kRx, EvenOdd::kOdd)->address =
361 &endpoint0_receive_buffer_[1][0];
362
363 MutableBdtEntry(0, Direction::kTx, EvenOdd::kEven)->buffer_descriptor = 0;
364 MutableBdtEntry(0, Direction::kTx, EvenOdd::kOdd)->buffer_descriptor = 0;
365
366 USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
367
368 ClearInterrupts();
369
370 // Set the address to 0 for enumeration.
371 USB0_ADDR = 0;
372 new_address_ = 0;
373
374 endpoint0_data_ = nullptr;
375 endpoint0_data_left_ = 0;
376
377 USB0_INTEN = usb_enabled_interrupts();
378 USB0_ERREN = USB_ERREN_BTSERREN | USB_ERREN_DMAERREN |
379 USB_ERREN_BTOERREN | USB_ERREN_DFN8EN | USB_ERREN_CRC16EN |
380 USB_ERREN_CRC5EOFEN | USB_ERREN_PIDERREN;
381
382 // Start the peripheral going.
383 dma_memory_barrier();
384 USB0_CTL = USB_CTL_USBENSOFEN;
385
386 continue;
387 }
388
389 // TODO(Brian): Handle errors more intelligently.
390 if (status & USB_ISTAT_ERROR) {
391 const uint8_t error = USB0_ERRSTAT;
392 USB0_ERRSTAT = error;
393 USB0_ISTAT = USB_ISTAT_ERROR;
394 }
395 }
396}
397
398void UsbDevice::HandleEndpoint0Token(const uint8_t stat) {
399 BdtEntry *const bdt_entry = MutableBdtEntryFromStat(stat);
400 const UsbPid pid = G_USB_BD_PID(bdt_entry->buffer_descriptor);
401 switch (pid) {
402 case UsbPid::kSetup:
403 // Unstall it if it was previously stalled.
404 USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK;
405
406 SetupPacket setup_packet;
407 memcpy(&setup_packet, bdt_entry->address, sizeof(setup_packet));
408
409 // Give the buffer back now.
410 dma_memory_barrier();
411 // Next IN and OUT packet for this endpoint (data stage/status stage)
412 // should both be DATA1.
Brian Silvermanf91524f2017-09-23 13:15:55 -0400413 MutableBdtEntryFromStat(stat ^ M_USB_STAT_ODD)->buffer_descriptor =
414 M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize) |
415 M_USB_BD_DATA1;
416 endpoint0_tx_toggle_ = Data01::kData1;
417
Brian Silverman69f96c22017-11-01 02:54:02 -0400418 // Give this buffer back. It should be DATA0 because it'll be the second
419 // received packet.
420 bdt_entry->buffer_descriptor =
421 M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
422
Brian Silvermanf91524f2017-09-23 13:15:55 -0400423 // TODO(Brian): Tell the functions a new setup packet is starting.
424 // CdcTty: next_endpoint0_out_ = NextEndpoint0Out::kNone;
425
426 // Forget about any pending transactions on this endpoint. There shouldn't
427 // be any, so if we think there are something's out of sync and we should
428 // just drop it. Important to do this before clearing TXD_SUSPEND in
429 // USBx_CTL. Standard says "If a Setup transaction is received by an
430 // endpoint before a previously initiated control transfer is completed,
431 // the device must abort the current transfer/operation".
432 endpoint0_data_ = nullptr;
433 endpoint0_data_left_ = 0;
434 MutableBdtEntry(0, Direction::kTx, EvenOdd::kEven)->buffer_descriptor = 0;
435 MutableBdtEntry(0, Direction::kTx, EvenOdd::kOdd)->buffer_descriptor = 0;
436
437 HandleEndpoint0SetupPacket(setup_packet);
438
439 break;
440
441 case UsbPid::kOut:
Philipp Schrader790cb542023-07-05 21:06:52 -0700442 for (UsbFunction *function : functions_) {
443 switch (function->HandleEndpoint0OutPacket(
444 bdt_entry->address, G_USB_BD_BC(bdt_entry->buffer_descriptor))) {
Brian Silvermanf91524f2017-09-23 13:15:55 -0400445 case SetupResponse::kIgnored:
446 break;
447 case SetupResponse::kHandled:
448 dma_memory_barrier();
449 bdt_entry->buffer_descriptor =
450 M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
451 return;
452 case SetupResponse::kStall:
453 bdt_entry->buffer_descriptor =
454 M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
455 StallEndpoint0();
456 return;
457 }
458 }
459 bdt_entry->buffer_descriptor =
460 M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
461 StallEndpoint0();
462 return;
463
464 case UsbPid::kIn:
465 // The functions are allowed to queue data in {endpoint0_data_,
466 // endpoint0_data_left_}, so this case deals with sending their data too.
467
468 // An IN transaction completed, so set up for the next one if appropriate.
469 if (!BufferEndpoint0TxPacket()) {
470 // After we're done, any further requests from the host should result in
471 // stalls (until the next setup token).
472 // TODO(Brian): Keep track of which direction it is and how much we've
473 // finished so we actually know when to stall it, both here and for
474 // kOut tokens.
Philipp Schrader790cb542023-07-05 21:06:52 -0700475 // StallEndpoint0();
Brian Silvermanf91524f2017-09-23 13:15:55 -0400476 }
477
478 // If we have a new address, there is nothing left in the setup request
479 // besides a single IN packet forming the status stage, so we know the
480 // changes must be done now.
481 if (new_address_ != 0) {
482 USB0_ADDR = new_address_;
483 new_address_ = 0;
484 }
485
486 break;
487
488 default:
489 // Should never happen, but give the buffer back anyways if necessary.
490 if (!(bdt_entry->buffer_descriptor & M_USB_BD_OWN)) {
491 bdt_entry->buffer_descriptor =
492 M_USB_BD_OWN | M_USB_BD_DTS | V_USB_BD_BC(kEndpoint0MaxSize);
493 }
494 break;
495 }
496
497 // Clear the TXD_SUSPEND flag.
498 dma_memory_barrier();
499 USB0_CTL = USB_CTL_USBENSOFEN;
500}
501
502void UsbDevice::HandleEndpoint0SetupPacket(const SetupPacket &setup_packet) {
503 const bool in = setup_packet.request_type & M_SETUP_REQUEST_TYPE_IN;
504 const uint8_t recipient =
505 G_SETUP_REQUEST_TYPE_RECIPIENT(setup_packet.request_type);
506 switch (G_SETUP_REQUEST_TYPE_TYPE(setup_packet.request_type)) {
507 case SetupRequestType::kStandard:
508 switch (setup_packet.request) {
509 case standard_setup_requests::kSetAddress:
510 if (in || recipient != standard_setup_recipients::kDevice ||
511 setup_packet.index != 0 || setup_packet.length != 0) {
512 break;
513 }
514 new_address_ = setup_packet.value;
515 SendEmptyEndpoint0Packet();
516 return;
517
518 case standard_setup_requests::kSetConfiguration:
519 if (in || recipient != standard_setup_recipients::kDevice ||
520 setup_packet.index != 0 || setup_packet.length != 0) {
521 break;
522 }
523 configuration_ = setup_packet.value;
524
525 // No need to mess with endpoint0_tx_toggle_ because we reset it with
526 // each setup packet anyways.
527
528 for (int endpoint = 0;
529 endpoint < static_cast<int>(endpoint_mapping_.size());
530 ++endpoint) {
531 if (endpoint_mapping_[endpoint]) {
532 endpoint_mapping_[endpoint]->HandleConfigured(endpoint);
533 }
534 }
535
536 SendEmptyEndpoint0Packet();
537 return;
538
539 case standard_setup_requests::kClearFeature:
540 if (in || setup_packet.length != 0) {
541 break;
542 }
543 if (recipient == standard_setup_recipients::kEndpoint &&
544 setup_packet.value == standard_feature_selectors::kEndpointHalt) {
545 const int endpoint =
546 G_SETUP_REQUEST_INDEX_ENDPOINT(setup_packet.index);
547 // Our endpoint 0 doesn't support the halt feature because that's
548 // weird and not recommended by the standard.
549 if (endpoint == 0) {
550 break;
551 }
552 if (endpoint >= number_endpoints()) {
553 break;
554 }
555 USB0_ENDPTn(endpoint) &= ~USB_ENDPT_EPSTALL;
556 if (endpoint_mapping_[endpoint] != nullptr) {
557 endpoint_mapping_[endpoint]->HandleConfigured(endpoint);
558 }
559 SendEmptyEndpoint0Packet();
560 return;
561 }
562 // We should never get kDeviceRemoteWakeup because we don't advertise
563 // support for it in our configuration descriptors.
564 // We should never get kTestMode because we're not high-speed.
565 break;
566
567 case standard_setup_requests::kSetFeature:
568 if (in || setup_packet.length != 0) {
569 break;
570 }
571 if (recipient == standard_setup_recipients::kEndpoint &&
572 setup_packet.value == standard_feature_selectors::kEndpointHalt) {
573 const int endpoint =
574 G_SETUP_REQUEST_INDEX_ENDPOINT(setup_packet.index);
575 // Our endpoint 0 doesn't support the halt feature because that's
576 // weird and not recommended by the standard.
577 if (endpoint == 0) {
578 break;
579 }
580 if (endpoint >= number_endpoints()) {
581 break;
582 }
583 StallEndpoint(endpoint);
584 // TODO(Brian): Tell the appropriate function it's now stalled.
585 SendEmptyEndpoint0Packet();
586 return;
587 }
588 // We should never get kDeviceRemoteWakeup because we don't advertise
589 // support for it in our configuration descriptors.
590 // We should never get kTestMode because we're not high-speed.
591 break;
592
593 case standard_setup_requests::kGetConfiguration:
594 if (!in || recipient != standard_setup_recipients::kDevice ||
595 setup_packet.index != 0 || setup_packet.length != 1) {
596 break;
597 }
598 endpoint0_transmit_buffer_[0] = configuration_;
599 QueueEndpoint0Data(endpoint0_transmit_buffer_, 1);
600 return;
601
602 case standard_setup_requests::kGetInterface:
603 if (!in || recipient != standard_setup_recipients::kInterface ||
604 setup_packet.value != 0 || setup_packet.length != 1) {
605 break;
606 }
607 // Standard says it's unspecified in the default state and must
608 // respond with an error in the address state, so just do an error for
609 // both of them.
610 if (configuration_ == 0) {
611 break;
612 }
613 // TODO(Brian): Ask the appropriate function what alternate setting
614 // the interface has, and stall if there isn't one.
615 endpoint0_transmit_buffer_[0] = 0;
616 QueueEndpoint0Data(endpoint0_transmit_buffer_, 1);
617 return;
618
619 case standard_setup_requests::kSetInterface:
620 if (in || recipient != standard_setup_recipients::kInterface ||
621 setup_packet.length != 0) {
622 break;
623 }
624 // Standard says it's unspecified in the default state and must
625 // respond with an error in the address state, so just do an error for
626 // both of them.
627 if (configuration_ == 0) {
628 break;
629 }
630
631 // TODO(Brian): Pass to the appropriate function instead.
632 if (setup_packet.value != 0) {
633 break;
634 }
635 SendEmptyEndpoint0Packet();
636 return;
637
638 case standard_setup_requests::kGetStatus:
639 if (!in || setup_packet.value != 0 || setup_packet.length != 2) {
640 break;
641 }
642 if (recipient == standard_setup_recipients::kDevice) {
643 if (setup_packet.index != 0) {
644 break;
645 }
646 // Say that we're currently self powered.
647 endpoint0_transmit_buffer_[0] = 1;
648 endpoint0_transmit_buffer_[1] = 0;
649 QueueEndpoint0Data(endpoint0_transmit_buffer_, 2);
650 return;
651 }
652 if ((recipient == standard_setup_recipients::kInterface &&
653 setup_packet.index == 0) ||
654 (recipient == standard_setup_recipients::kEndpoint &&
655 G_SETUP_REQUEST_INDEX_ENDPOINT(setup_packet.index) == 0)) {
656 endpoint0_transmit_buffer_[0] = 0;
657 endpoint0_transmit_buffer_[1] = 0;
658 QueueEndpoint0Data(endpoint0_transmit_buffer_, 2);
659 return;
660 }
661 // Standard says it's unspecified in the default state and must
662 // respond with an error in the address state, so just do an error
663 // for both of them.
664 if (configuration_ == 0) {
665 break;
666 }
667
668 if (recipient == standard_setup_recipients::kInterface) {
669 // TODO(Brian): Check if it's actually an interface we have?
670 endpoint0_transmit_buffer_[0] = 0;
671 endpoint0_transmit_buffer_[1] = 0;
672 QueueEndpoint0Data(endpoint0_transmit_buffer_, 2);
673 return;
674 }
675
676 if (recipient == standard_setup_recipients::kEndpoint) {
677 const int endpoint =
678 G_SETUP_REQUEST_INDEX_ENDPOINT(setup_packet.index);
679 // TODO(Brian): Check if it's actually an endpoint we have?
680 if (USB0_ENDPTn(endpoint) & USB_ENDPT_EPSTALL) {
681 endpoint0_transmit_buffer_[0] = 1;
682 } else {
683 endpoint0_transmit_buffer_[0] = 0;
684 }
685 endpoint0_transmit_buffer_[1] = 0;
686 QueueEndpoint0Data(endpoint0_transmit_buffer_, 2);
687 return;
688 }
689 break;
690
691 case standard_setup_requests::kSetDescriptor:
692 // Not implementing anything for this.
693 break;
694
695 case standard_setup_requests::kSynchFrame:
696 // We don't implement any classes which use this.
697 break;
698
699 case standard_setup_requests::kGetDescriptor:
Brian Silvermand930f282017-11-04 23:09:12 -0400700 if (!in) {
Brian Silvermanf91524f2017-09-23 13:15:55 -0400701 break;
702 }
Brian Silvermand930f282017-11-04 23:09:12 -0400703
Brian Silvermanf91524f2017-09-23 13:15:55 -0400704 const uint8_t descriptor_type_byte = (setup_packet.value >> 8) & 0xFF;
Brian Silvermand930f282017-11-04 23:09:12 -0400705 if (G_DESCRIPTOR_TYPE_TYPE(descriptor_type_byte) !=
706 standard_descriptor_type_types::kStandard) {
707 for (UsbFunction *function : functions_) {
708 switch (function->HandleGetDescriptor(setup_packet)) {
709 case SetupResponse::kIgnored:
710 continue;
711 case SetupResponse::kHandled:
712 return;
713 case SetupResponse::kStall:
714 break;
715 }
716 break;
717 }
718 break;
719 }
720
721 if (recipient != standard_setup_recipients::kDevice) {
722 break;
723 }
Brian Silvermanf91524f2017-09-23 13:15:55 -0400724 if (descriptor_type_byte < kUsbDescriptorTypeMin ||
725 descriptor_type_byte > kUsbDescriptorTypeMax) {
726 break;
727 }
728 const UsbDescriptorType descriptor_type =
729 static_cast<UsbDescriptorType>(descriptor_type_byte);
730 const uint8_t descriptor_index = setup_packet.value & 0xFF;
731 switch (descriptor_type) {
732 case UsbDescriptorType::kDevice:
733 if (setup_packet.index != 0 || descriptor_index != 0) {
734 break;
735 }
736 QueueEndpoint0Data(
737 device_descriptor_list_.data_.data(),
738 ::std::min<int>(setup_packet.length,
739 device_descriptor_list_.data_.size()));
740 return;
741
742 case UsbDescriptorType::kConfiguration:
743 if (setup_packet.index != 0 || descriptor_index != 0) {
744 break;
745 }
746 QueueEndpoint0Data(
747 config_descriptor_list_.data_.data(),
748 ::std::min<int>(setup_packet.length,
749 config_descriptor_list_.data_.size()));
750 return;
751
752 case UsbDescriptorType::kString:
Brian Silverman4aa83042018-01-05 12:47:31 -0800753 // Skip any other checks on the other fields. Who knows what
754 // Microsoft is going to set them to; not like they document it
755 // anywhere obvious...
756 if (descriptor_index == 0xEE && setup_packet.index == 0) {
Philipp Schrader790cb542023-07-05 21:06:52 -0700757 static uint8_t kMicrosoftOsStringDescriptor[] = {
758 0x12, // bLength
759 static_cast<uint8_t>(
760 UsbDescriptorType::kString), // bDescriptorType
761 0x4D,
762 0x00,
763 0x53,
764 0x00,
765 0x46,
766 0x00,
767 0x54,
768 0x00,
769 0x31,
770 0x00,
771 0x30,
772 0x00,
773 0x30,
774 0x00, // qwSignature
775 microsoft_vendor_code(), // bMS_VendorCode
776 0x00 // bPad
777 };
Brian Silverman4aa83042018-01-05 12:47:31 -0800778 QueueEndpoint0Data(
779 reinterpret_cast<char *>(kMicrosoftOsStringDescriptor),
780 ::std::min<int>(setup_packet.length,
781 sizeof(kMicrosoftOsStringDescriptor)));
782 return;
783 }
Brian Silvermand930f282017-11-04 23:09:12 -0400784 if (descriptor_index != 0 &&
785 setup_packet.index != english_us_code()) {
Brian Silvermanf91524f2017-09-23 13:15:55 -0400786 break;
787 }
788 if (descriptor_index >= strings_.size()) {
789 break;
790 }
791 QueueEndpoint0Data(
792 strings_[descriptor_index].data(),
793 ::std::min<int>(setup_packet.length,
794 strings_[descriptor_index].size()));
795 return;
796
797 default:
798 // TODO(Brian): Handle other types of descriptor too.
799 break;
800 }
801 }
802 break;
803
Brian Silverman4aa83042018-01-05 12:47:31 -0800804 case SetupRequestType::kVendor:
805 switch (setup_packet.request) {
806 case microsoft_vendor_code():
807 if (!in) {
808 break;
809 }
810
811 switch (recipient) {
812 case standard_setup_recipients::kDevice:
813 if (setup_packet.value != 0) {
814 // Ignoring weird things and descriptors larger than 64K for
815 // now.
816 break;
817 }
818 switch (setup_packet.index) {
819 case microsoft_feature_descriptors::kExtendedCompatibilityId:
820 QueueEndpoint0Data(
821 microsoft_extended_id_descriptor_.data(),
822 ::std::min<int>(
823 setup_packet.length,
824 microsoft_extended_id_descriptor_.size()));
825 return;
826 }
827 break;
828
829 case standard_setup_recipients::kInterface:
830 switch (setup_packet.index) {
831 case microsoft_feature_descriptors::kExtendedProperties:
832 const int interface = setup_packet.value & 0xFF;
833 const int page_number = (setup_packet.value >> 8) & 0xFF;
834
835 if (page_number != 0) {
836 // Ignoring weird things and descriptors larger than 64K for
837 // now.
838 break;
839 }
840
841 const UsbFunction *const function =
842 interface_mapping_[interface];
843 const ::std::string &descriptor =
844 function->microsoft_extended_property_descriptor_;
845 if (descriptor.empty() ||
846 interface != function->first_interface_) {
847 break;
848 }
849 QueueEndpoint0Data(
850 descriptor.data(),
851 ::std::min<int>(setup_packet.length, descriptor.size()));
852 return;
853 }
854 break;
855 }
856 break;
857 }
858 break;
859
Brian Silvermanf91524f2017-09-23 13:15:55 -0400860 default:
861 for (UsbFunction *function : functions_) {
862 switch (function->HandleEndpoint0SetupPacket(setup_packet)) {
863 case SetupResponse::kIgnored:
864 continue;
865 case SetupResponse::kHandled:
866 return;
867 case SetupResponse::kStall:
868 break;
869 }
870 break;
871 }
872 break;
873 }
874
875 StallEndpoint0();
876}
877
878// We're supposed to continue returning stalls until the next kSetup packet.
879// Code might continue putting stuff in the TX buffers, but the hardware won't
880// actually send it as long as the EPSTALL bit is set.
881void UsbDevice::StallEndpoint0() {
882 USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN |
883 USB_ENDPT_EPHSHK;
884}
885
886bool UsbDevice::BufferEndpoint0TxPacket() {
887 if (endpoint0_data_ == nullptr) {
888 return false;
889 }
890
891 const int to_transmit = ::std::min(endpoint0_data_left_, kEndpoint0MaxSize);
892 BdtEntry *const tx_bdt_entry =
893 MutableBdtEntry(0, Direction::kTx, endpoint0_tx_odd_);
894 // const_cast is safe because the hardware is only going to read from
895 // this, not write.
896 tx_bdt_entry->address =
897 const_cast<void *>(static_cast<const void *>(endpoint0_data_));
898 dma_memory_barrier();
899 tx_bdt_entry->buffer_descriptor =
900 V_USB_BD_BC(to_transmit) | static_cast<uint32_t>(endpoint0_tx_toggle_) |
901 M_USB_BD_OWN | M_USB_BD_DTS;
902
903 endpoint0_tx_odd_ = EvenOddInverse(endpoint0_tx_odd_);
904 endpoint0_tx_toggle_ = Data01Inverse(endpoint0_tx_toggle_);
905
906 endpoint0_data_ += to_transmit;
907 endpoint0_data_left_ -= to_transmit;
908 if (to_transmit < kEndpoint0MaxSize) {
909 endpoint0_data_ = nullptr;
910 }
911
912 return true;
913}
914
915void UsbDevice::SendEmptyEndpoint0Packet() {
916 // Really doesn't matter what we put here as long as it's not nullptr.
917 endpoint0_data_ = reinterpret_cast<char *>(this);
918 endpoint0_data_left_ = 0;
919 BufferEndpoint0TxPacket();
920}
921
922void UsbDevice::QueueEndpoint0Data(const char *data, int size) {
923 endpoint0_data_ = data;
924 endpoint0_data_left_ = size;
925 // There are 2 TX buffers, so fill them both up.
926 BufferEndpoint0TxPacket();
927 BufferEndpoint0TxPacket();
928}
929
930void UsbDevice::StallEndpoint(int endpoint) {
931 for (Direction direction : {Direction::kTx, Direction::kRx}) {
932 for (EvenOdd odd : {EvenOdd::kOdd, EvenOdd::kEven}) {
933 MutableBdtEntry(endpoint, direction, odd)->buffer_descriptor = 0;
934 dma_memory_barrier();
935 MutableBdtEntry(endpoint, direction, odd)->address = nullptr;
936 }
937 }
938 USB0_ENDPTn(endpoint) |= USB_ENDPT_EPSTALL;
939}
940
941void UsbDevice::ConfigureEndpointFor(int endpoint, bool rx, bool tx,
942 bool handshake) {
943 uint8_t control = 0;
944 if (rx) {
945 control |= USB_ENDPT_EPRXEN;
946 }
947 if (tx) {
948 control |= USB_ENDPT_EPTXEN;
949 }
950 if (handshake) {
951 control |= USB_ENDPT_EPHSHK;
952 }
953 USB0_ENDPTn(endpoint) = control;
954}
955
956int UsbFunction::AddEndpoint() {
957 const int r = device_->endpoint_mapping_.size();
958 assert(r < number_endpoints());
959 device_->endpoint_mapping_.push_back(this);
960 return r;
961}
962
963int UsbFunction::AddInterface() {
964 const int r = device_->interface_mapping_.size();
965 // bInterfaceNumber is only one byte.
966 assert(r < 255);
967 device_->interface_mapping_.push_back(this);
968 return r;
969}
970
Brian Silverman4aa83042018-01-05 12:47:31 -0800971void UsbFunction::CreateIadDescriptor(int first_interface, int interface_count,
972 int function_class, int function_subclass,
973 int function_protocol,
974 const ::std::string &function) {
975 first_interface_ = first_interface;
976 const auto iad_descriptor = CreateDescriptor(
977 iad_descriptor_length(), UsbDescriptorType::kInterfaceAssociation);
978 iad_descriptor->AddByte(first_interface); // bFirstInterface
979 iad_descriptor->AddByte(interface_count); // bInterfaceCount
980 iad_descriptor->AddByte(function_class); // bFunctionClass
981 iad_descriptor->AddByte(function_subclass); // bFunctionSubClass
982 iad_descriptor->AddByte(function_protocol); // bFunctionProtocol
983 iad_descriptor->AddByte(device()->AddString(function)); // iFunction
984}
985
986void UsbFunction::SetMicrosoftDeviceInterfaceGuids(const ::std::string &guids) {
987 ::std::map<::std::string, ::std::string> properties;
988 properties["DeviceInterfaceGUIDs"] = guids + ::std::string(1, '\0');
989 ::std::string *const descriptor = &microsoft_extended_property_descriptor_;
990
991 uint32_t length = 10;
992 for (auto &pair : properties) {
993 length += 14;
994 length += (pair.first.size() + 1) * 2;
995 length += (pair.second.size() + 1) * 2;
996 }
997 descriptor->resize(length);
998 int index = 0;
999
1000 // dwLength
1001 (*descriptor)[index++] = length & 0xFF;
1002 (*descriptor)[index++] = (length >> UINT32_C(8)) & 0xFF;
1003 (*descriptor)[index++] = (length >> UINT32_C(16)) & 0xFF;
1004 (*descriptor)[index++] = (length >> UINT32_C(24)) & 0xFF;
1005
1006 // bcdVersion
1007 (*descriptor)[index++] = 0x00;
1008 (*descriptor)[index++] = 0x01;
1009
1010 // wIndex
1011 (*descriptor)[index++] = microsoft_feature_descriptors::kExtendedProperties;
1012 (*descriptor)[index++] = 0;
1013
1014 // wCount
1015 (*descriptor)[index++] = properties.size() & 0xFF;
1016 (*descriptor)[index++] = (properties.size() >> 8) & 0xFF;
1017
1018 for (auto &pair : properties) {
1019 const uint32_t size = 14 + (pair.first.size() + pair.second.size() + 2) * 2;
1020 // dwSize
1021 (*descriptor)[index++] = size & 0xFF;
1022 (*descriptor)[index++] = (size >> UINT32_C(8)) & 0xFF;
1023 (*descriptor)[index++] = (size >> UINT32_C(16)) & 0xFF;
1024 (*descriptor)[index++] = (size >> UINT32_C(24)) & 0xFF;
1025
1026 // Need to get this from the map if we ever do others in the future.
1027 const uint32_t data_type = 7; // REG_MULTI_SZ
1028 // dwPropertyDataType
1029 (*descriptor)[index++] = data_type & 0xFF;
1030 (*descriptor)[index++] = (data_type >> UINT32_C(8)) & 0xFF;
1031 (*descriptor)[index++] = (data_type >> UINT32_C(16)) & 0xFF;
1032 (*descriptor)[index++] = (data_type >> UINT32_C(24)) & 0xFF;
1033
1034 // wPropertyNameLength
1035 (*descriptor)[index++] = ((pair.first.size() + 1) * 2) & 0xFF;
1036 (*descriptor)[index++] = (((pair.first.size() + 1) * 2) >> 8) & 0xFF;
1037
1038 // bPropertyName
1039 for (size_t i = 0; i < pair.first.size(); ++i) {
1040 (*descriptor)[index] = pair.first[i];
1041 index += 2;
1042 }
1043 index += 2;
1044
1045 // wPropertyDataLength
1046 (*descriptor)[index++] = ((pair.second.size() + 1) * 2) & 0xFF;
1047 (*descriptor)[index++] =
1048 (((pair.second.size() + 1) * 2) >> UINT8_C(8)) & 0xFF;
1049 (*descriptor)[index++] =
1050 (((pair.second.size() + 1) * 2) >> UINT8_C(16)) & 0xFF;
1051 (*descriptor)[index++] =
1052 (((pair.second.size() + 1) * 2) >> UINT8_C(24)) & 0xFF;
1053
1054 // bPropertyData
1055 for (size_t i = 0; i < pair.second.size(); ++i) {
1056 (*descriptor)[index] = pair.second[i];
1057 index += 2;
1058 }
1059 index += 2;
1060 }
1061
1062 assert(index == length);
1063}
1064
Brian Silvermanf91524f2017-09-23 13:15:55 -04001065void UsbDevice::SetBdtEntry(int endpoint, Direction direction, EvenOdd odd,
1066 BdtEntry bdt_entry) {
1067 *MutableBdtEntry(endpoint, direction, odd) = bdt_entry;
1068}
1069
Stephan Pleinesf63bde82024-01-13 15:59:33 -08001070} // namespace frc971::teensy