- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
while (1) {
uint16_t state = in(USB_BASE + USB_ISTR);
if (state & 0x8000) {
uint16_t epstat = in(USB_BASE + USB_EP0R);
if (epstat & 0x8000) {
// RX done
if (epstat & 0x0800) {
// setup
if ((usbRead(0x180) == 0x80) && (usbRead(0x181) == 0x06)) {
uint16_t maxlen = (usbRead(0x187) << 8) | usbRead(0x186);
if (usbRead(0x183) == 0x01) {
// send device descriptor
copyToUsb(0x0100, deviceDescriptor, sizeof(deviceDescriptor));
if (sizeof(deviceDescriptor) < maxlen)
maxlen = sizeof(deviceDescriptor);
out(USB_SRAM_BASE + 0x04, 0x9000 + maxlen); // TX count
// STAT_TX=11 (valid)
if ((in(USB_BASE + USB_EP0R) & 0x0010) != 0x0010)
out(USB_BASE + USB_EP0R, 0x0210);
if ((in(USB_BASE + USB_EP0R) & 0x0020) != 0x0020)
out(USB_BASE + USB_EP0R, 0x0220);
} else if (usbRead(0x183) == 0x02) {
// send config descriptor
copyToUsb(0x0100, configDescriptor, sizeof(configDescriptor));
if (sizeof(configDescriptor) < maxlen)
maxlen = sizeof(configDescriptor);
out(USB_SRAM_BASE + 0x04, 0x9000 + maxlen); // TX count
// STAT_TX=11 (valid)
if ((in(USB_BASE + USB_EP0R) & 0x0010) != 0x0010)
out(USB_BASE + USB_EP0R, 0x0210);
if ((in(USB_BASE + USB_EP0R) & 0x0020) != 0x0020)
out(USB_BASE + USB_EP0R, 0x0220);
} else {
// ... и ещё сотня строк в том же духе ...
Я бы такую хуйню в макрос завернул
Или даже чтоб в 3D!
https://ru.wikipedia.org/wiki/Befunge
Духи с тобою связаться хотят.....
https://en.wikipedia.org/wiki/Hanako-san
>usbRead(0x181) == 0x06
могу простить
а лесенки нет
>USB_BASE + USB_EP0R
тоже лучше вынести
Ты не поверишь... я тоже ;)
Но говнопрототип на то и говнопрототип.
На самом деле код довольно прямолинейный, и не выглядит таким уж адом (если знать предметную область конечно)
Я специально пишу прототипы в таком стиле, чтобы вообще не возникало желания их рефакторить.
Поэтому хуяк-хуяк и в продакшен. А потом можно красиво переписать с нуля.
Там, где ты всё уже знаешь и умеешь, смысла в такой методологии нету, наверное. Можно сразу чистовик ебашить.
Иногда полезно три раза с ноля одно и тоже написать: каждый следующий раз код будет чище, а ты лучше поймешь API
Но это только маленькие участочки кода конечно, не целые приложения
Если знать предметную область, то тут всё ещё хуже.
Я деталей уже не помню, но вот эти ожидания флажков синхронные и могут застрять на несколько миллисекунд. Или вообще повиснуть если софт со стороны компа упал. И плату придётся ребутать.
Т.е. говно тут от корней до самых кончиков.
А как правильно? Через прерывания?
По хорошему -- да. while (true) с поллингом флажков ещё и не особо энергосберегающий.
понял тебя
Есть кстати примеры бизивейта вполне обоснованные, например спинлоки в ядре или дрееевний софт на однозадачной ОС и ЦПУ без ACPI/APM
Есть даже алгоритмы синхронизации (Петерсона и Деккера вроде) на бизивейте
но ты не один на цпу, угу