usart rx timeout management
This commit is contained in:
parent
71e6023978
commit
95b08e26ae
3 changed files with 44 additions and 10 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue