diff --git a/V203/usb/ch32v203/system.cpp b/V203/usb/ch32v203/system.cpp index 0806171..d94ffbe 100644 --- a/V203/usb/ch32v203/system.cpp +++ b/V203/usb/ch32v203/system.cpp @@ -126,6 +126,7 @@ void SystemCoreClockUpdate (void) { } static uint32_t p_us = 0u; +static bool timeout; void delay_init () { p_us = SystemCoreClock / 8000000; } @@ -143,5 +144,24 @@ void delay_us (const unsigned dly) { while((SysTick.SR & (1u << 0)) != (1u << 0)); SysTick.CTLR.B.STE = RESET; } - - +void set_timeout_us (const uint32_t time) { + SysTick.CTLR.B.STE = RESET; + timeout = false; + const uint32_t i = (uint32_t) time * p_us; + SysTick.SR &= ~(1 << 0); + SysTick.CMPLR = i; + SysTick.CTLR.modify([](SysTick_Type::CTLR_DEF & r) -> uint32_t { + r.B.MODE = SET; + r.B.INIT = SET; + return r.R; + }); + SysTick.CTLR.B.STE = SET; +} +bool is_timeout () { + if (SysTick.SR & (1u << 0)) { + SysTick.CTLR.B.STE = RESET; + timeout = true; + } else { + } + return timeout; +} diff --git a/V203/usb/ch32v203/system.h b/V203/usb/ch32v203/system.h index fe6c6ce..9a57c76 100644 --- a/V203/usb/ch32v203/system.h +++ b/V203/usb/ch32v203/system.h @@ -85,7 +85,9 @@ extern "C" { extern void SystemCoreClockUpdate (void); extern void SystemInit(void); extern void delay_init (); - extern void delay_us (const unsigned dly); + extern void delay_us (const unsigned dly); + extern void set_timeout_us (const uint32_t time); + extern bool is_timeout (); }; #endif // SYSTEM_H diff --git a/V203/usb/usart/main.cpp b/V203/usb/usart/main.cpp index 59d7cfb..f940f1d 100644 --- a/V203/usb/usart/main.cpp +++ b/V203/usb/usart/main.cpp @@ -1,6 +1,9 @@ #include "cdc_class.h" #include "usart.h" #include "mirror.h" + +static constexpr unsigned Timeout = 5000; // us + /** Převodník USB_CDC - USART * Datový formát je pevný - 8 bit, 1 stop bit, bez parity. * Změnu po USB by šlo dost jednoduše dodělat, ale nepovažoval jsem to za nutné. @@ -37,16 +40,24 @@ public: /* Vlastní odeslání paketu na USB_CDC * */ void pass () { - /* Je to velmi zjednodušeno, odešle se 32 bytový paket, přímo. - * Pro test to stačí (testováno pro 1 MBd, full duplex), ale jinak by - * zde musela být kontrola přetečení, odeslání, časování timeout atd. - * Nechci to zaplevelit nečitelnými hovadinami jako ten číňan. + /* Je to dost zjednodušeno, odešle se 64 bytový paket, + * nebo po 5 ms to co zůstalo v bufferu. * */ - if (index >= 32) { // 32 je vhodný kompromis mezi 1 a 64 - BaseLayer::Up (buffer, index); - index = 0; + if ((is_timeout() and index) or (index >= 64)) { + block(buffer, index); } } + protected: + void block (const char * data, const uint32_t len) { + unsigned ofs = 0, rem = len; + while (rem) { + const unsigned n = BaseLayer::Up(data + ofs, rem); + rem -= n; + ofs += n; + } + index = 0; + set_timeout_us(Timeout); + } }; static cdc_class cdc; static Usart usart; @@ -57,6 +68,7 @@ int main () { top += cdc; top -= mid += usart; cdc.attach(usart); + set_timeout_us(Timeout); for (;;) { mid.pass(); }