/
bortsov
/
ch32v203-BatteryDisplay
Обзор
Документация
Войти
/
bortsov
/
ch32v203-BatteryDisplay
Код
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
source/UsbImplementation.cpp
121 строка
3 KB
Vitaliy Bortsov
feat: switch microshell to USB virtual com port
22 мар 2026, 21:05
22 мар 2026, 21:05
3f570b4
Код
Авторство
О чём код?
#include "UsbInterface.h" #include "tusb.h" #include "bsp/board_api.h" #include "bsp/CH32V203F6P6_rcc.h" class UsbImplementation : public CommunicationBase { public: UsbImplementation() { auto rcc{getRccBase()}; // rcc->CFGR0 = rcc->CFGR0 & ~(0b11UL << 22); /* reset USBPRE bits; it is reset by defaults, so doesn't need to do something */ /* this bits should be configured before enabling USBD clocks */ switch (rcc::getPllFrequency_Hz()) { case 48'000'000UL : /*rcc->CFGR0 = rcc->CFGR0 | (0b00UL << 22);*/ break; /* it is the defaults */ case 96'000'000UL : rcc->CFGR0 = rcc->CFGR0 | (0b01UL << 22); break; case 144'000'000UL : rcc->CFGR0 = rcc->CFGR0 | (0b10UL << 22); break; default : while (true) {} /* halt here: can't use USBD with invalid PLL clocks */ } rcc::enableClock(PeripheralId::USBD); rcc::reset(PeripheralId::USBD); // init device stack on configured roothub port constexpr tusb_rhport_init_t dev_init {.role = TUSB_ROLE_DEVICE, .speed = TUSB_SPEED_AUTO}; tusb_init(BOARD_TUD_RHPORT, &dev_init); } virtual bool isNewChar() override {return tud_cdc_available() > 0;} virtual void putChar(const char ch) override { putArray(&ch, 1); } virtual void putArray(const char* str, const unsigned int len) override { unsigned int sent{}; while (tud_cdc_connected() && sent < len) { const uint32_t cntAvailable {tud_cdc_write_available()}; if (cntAvailable > 0UL) { unsigned int chunk {(len - sent) < cntAvailable ? (len - sent) : cntAvailable}; sent += tud_cdc_write(str + sent, chunk); sync(); } else { process(); } } } virtual char getChar() override { char ch{}; tud_cdc_read(&ch, 1); return ch; } virtual void process() override { tud_task(); } virtual void sync() override { tud_cdc_write_flush(); } virtual ~UsbImplementation() = default; // Get board unique ID for USB serial number. Return number of bytes. Note max_len is typically 16 static size_t board_get_unique_id(uint8_t id[], [[maybe_unused]] size_t max_len) { volatile uint32_t* ch32_uuid = ((volatile uint32_t*) 0x1FFFF7E8UL); uint32_t* serial_32 = (uint32_t*) (uintptr_t) id; serial_32[0] = ch32_uuid[0]; serial_32[1] = ch32_uuid[1]; serial_32[2] = ch32_uuid[2]; return 12; } private: static constexpr uint32_t BAUDRATE_{9'600UL}; static constexpr enum Usart ID_ {Usart::USART2}; }; std::unique_ptr<CommunicationBase> usb::create() { return std::make_unique<UsbImplementation>(); } size_t board_usb_get_serial(uint16_t desc_str1[], size_t max_chars) { uint8_t uid[16] TU_ATTR_ALIGNED(4); size_t uid_len; // TODO work with make, but not working with esp32s3 cmake uid_len = UsbImplementation::board_get_unique_id(uid, sizeof(uid)); if ( uid_len > max_chars / 2u ) { uid_len = max_chars / 2u; } for ( size_t i = 0; i < uid_len; i++ ) { for ( size_t j = 0; j < 2; j++ ) { const unsigned char nibble_to_hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; const uint8_t nibble = (uint8_t) ((uid[i] >> (j * 4u)) & 0xfu); desc_str1[i * 2 + (1 - j)] = nibble_to_hex[nibble]; // UTF-16-LE } } return 2 * uid_len; }