usart rx timeout management

This commit is contained in:
Kizarm 2024-10-16 19:34:04 +02:00
parent 71e6023978
commit 95b08e26ae
3 changed files with 44 additions and 10 deletions

View file

@ -126,6 +126,7 @@ void SystemCoreClockUpdate (void) {
} }
static uint32_t p_us = 0u; static uint32_t p_us = 0u;
static bool timeout;
void delay_init () { void delay_init () {
p_us = SystemCoreClock / 8000000; p_us = SystemCoreClock / 8000000;
} }
@ -143,5 +144,24 @@ void delay_us (const unsigned dly) {
while((SysTick.SR & (1u << 0)) != (1u << 0)); while((SysTick.SR & (1u << 0)) != (1u << 0));
SysTick.CTLR.B.STE = RESET; 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;
}

View file

@ -86,6 +86,8 @@ extern "C" {
extern void SystemInit(void); extern void SystemInit(void);
extern void delay_init (); 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 #endif // SYSTEM_H

View file

@ -1,6 +1,9 @@
#include "cdc_class.h" #include "cdc_class.h"
#include "usart.h" #include "usart.h"
#include "mirror.h" #include "mirror.h"
static constexpr unsigned Timeout = 5000; // us
/** Převodník USB_CDC - USART /** Převodník USB_CDC - USART
* Datový formát je pevný - 8 bit, 1 stop bit, bez parity. * 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é. * 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 /* Vlastní odeslání paketu na USB_CDC
* */ * */
void pass () { void pass () {
/* Je to velmi zjednodušeno, odešle se 32 bytový paket, přímo. /* Je to dost zjednodušeno, odešle se 64 bytový paket,
* Pro test to stačí (testováno pro 1 MBd, full duplex), ale jinak by * nebo po 5 ms to co zůstalo v bufferu.
* zde musela být kontrola přetečení, odeslání, časování timeout atd.
* Nechci to zaplevelit nečitelnými hovadinami jako ten číňan.
* */ * */
if (index >= 32) { // 32 je vhodný kompromis mezi 1 a 64 if ((is_timeout() and index) or (index >= 64)) {
BaseLayer::Up (buffer, index); block(buffer, index);
index = 0;
} }
} }
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 cdc_class cdc;
static Usart usart; static Usart usart;
@ -57,6 +68,7 @@ int main () {
top += cdc; top += cdc;
top -= mid += usart; top -= mid += usart;
cdc.attach(usart); cdc.attach(usart);
set_timeout_us(Timeout);
for (;;) { for (;;) {
mid.pass(); mid.pass();
} }