1. Си / Говнокод #27516

    +4

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 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 {
    
    // ... и ещё сотня строк в том же духе ...

    Иногда в меня вселяется дух PHP...

    Запостил: bormand, 13 Июля 2021

    Комментарии (30) RSS

    • Тот самый момент, когда под рукой не оказалось USB UART зато была STM'ка.
      Ответить
    • // USBPRE=0 (USB=72MHz/1.5=48MHz)
      // PLLMUL=0111 (PLLOUT=8MHz*9=72MHz)
      // PLLXTPRE=0 (PLLIN=HSE=8MHz)
      // PLLSRC=1 (HSE)
      // PPRE2=000 (APB2=AHB=72MHz)
      // PPRE1=100 (APB1=AHB/2=36MHz)
      // HPRE=0000 (AHB=72MHz)
      // SW=0 (stay on HSI during PLL startup)
      out(RCC_BASE + RCC_CFGR, 0x001D0400);
      
      // PLLON=1
      out(RCC_BASE + RCC_CR, in(RCC_BASE + RCC_CR) | 0x01000000);
          
      // Wait for PLLRDY
      while ((in(RCC_BASE + RCC_CR) & 0x02000000) == 0);
      Константы? Не, ня слышала.
      Ответить
    • 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);
      ...



      Я бы такую хуйню в макрос завернул

      #define SHIT(x) \
        if ((in(USB_BASE + USB_EP0R) & (x)) != (x)) \
            out(USB_BASE + USB_EP0R, 0x0200 | (x) );
      Ответить
      • Да вообще в функцию, наверное. А то оно там дофига раз встречается.
        Ответить
      • По идее эти портянки копипасты вообще должны быть каким-нибудь usb_respond(ep, data, size). Но что вышло то вышло.
        Ответить
        • ужос. есть еще в мире кто так пишет. все нормальные люди пишут так usb() << data << usb::pos(10) << bla bla;
          Ответить
          • Это хуита одномерная, надо чтоб можно было направленные ациклические графы рисовать, типа
            (a) >> (b) >> (c)
             ^      ^
             ^      ^
            (d)    (e) >> (g)
             ^      ^
             ^      ^
            (f) > > *


            Или даже чтоб в 3D!
            Ответить
          • Если серьезно, ничего такого хорошего я не вижу в этой вот "<<" хрени в тех же крестах с их std::cout
            Ответить
            • Да, есть багор: можно спутать со сдвигом. Хоть скобки ставь повсюду, как в Лиспе.
              Ответить
            • хорошего там то, что можно определить этот оператор на объекте
              Ответить
              • Но писать его всегда приходится снаружи т.к. левый аргумент -- это стрим.
                Ответить
    • Оглянись вокруг посмотри назад
      Духи с тобою связаться хотят.....
      Ответить
      • Призрачный голос со стороны параши
        https://en.wikipedia.org/wiki/Hanako-san
        Ответить
    • ненавижу лесенки такие

      >usbRead(0x181) == 0x06
      могу простить
      а лесенки нет

      >USB_BASE + USB_EP0R
      тоже лучше вынести
      Ответить
      • > ненавижу лесенки такие

        Ты не поверишь... я тоже ;)

        Но говнопрототип на то и говнопрототип.
        Ответить
        • а твой IDE экстрактить не умеет?
          Ответить
          • Экстракт говна на вкус ничуть не лучше, чем оно само...
            Ответить
            • ну ты бы хотя бы разобрал лесенку

              На самом деле код довольно прямолинейный, и не выглядит таким уж адом (если знать предметную область конечно)
              Ответить
              • А смысл разбирать лесенку в коде, который написан на выброс?

                Я специально пишу прототипы в таком стиле, чтобы вообще не возникало желания их рефакторить.
                Ответить
                • интересный подход. и как, работает?
                  Ответить
                  • Вполне. Ну суть в том, что иначе я буду пытаться придумать красивую архитектуру и сделать конфетку. А для первого прототипа эта красота будет только мешать т.к. я ещё толком не понимаю предметную область.

                    Поэтому хуяк-хуяк и в продакшен. А потом можно красиво переписать с нуля.

                    Там, где ты всё уже знаешь и умеешь, смысла в такой методологии нету, наверное. Можно сразу чистовик ебашить.
                    Ответить
                • а, ну я тоже иногда пишу на коленке куски говнокода когда что-то изучаю (API например), но я их даже не коммичу обычно

                  Иногда полезно три раза с ноля одно и тоже написать: каждый следующий раз код будет чище, а ты лучше поймешь API

                  Но это только маленькие участочки кода конечно, не целые приложения
                  Ответить
              • > если знать предметную область конечно

                Если знать предметную область, то тут всё ещё хуже.

                Я деталей уже не помню, но вот эти ожидания флажков синхронные и могут застрять на несколько миллисекунд. Или вообще повиснуть если софт со стороны компа упал. И плату придётся ребутать.

                Т.е. говно тут от корней до самых кончиков.
                Ответить
                • Я не знаю где это запускается, и насколько валидно зависать на несколько миллисек

                  А как правильно? Через прерывания?
                  Ответить
                  • > через прерывания

                    По хорошему -- да. while (true) с поллингом флажков ещё и не особо энергосберегающий.
                    Ответить
                    • да, бизивейт такой малоприятный, и жрущий цпу
                      понял тебя

                      Есть кстати примеры бизивейта вполне обоснованные, например спинлоки в ядре или дрееевний софт на однозадачной ОС и ЦПУ без ACPI/APM

                      Есть даже алгоритмы синхронизации (Петерсона и Деккера вроде) на бизивейте
                      Ответить
                      • Не, ну в теории и в бизивейт можно въебать какой-нибудь wfi чтобы проц спал до следующего прерывания.
                        Ответить
                        • этим ты решишь проблему бесполезной траты питания, глобального потепления и таянья ледников

                          но ты не один на цпу, угу
                          Ответить
                          • В этом случае в общем-то один. Там ещё обработчик таймерного прерывания, но он более приоритетный и ему пофиг.
                            Ответить

    Добавить комментарий