test cdc-usart

This commit is contained in:
Kizarm 2024-10-16 15:46:34 +02:00
parent 07c30fffc8
commit 71e6023978
3 changed files with 46 additions and 6 deletions

View file

@ -7,19 +7,58 @@
* Baudová rychlost se po USB změnit na libovolnou hodnotu. * Baudová rychlost se po USB změnit na libovolnou hodnotu.
* *
* Výhoda tohoto řešení je, že nad USARTem může běžet nějaký protokol * Výhoda tohoto řešení je, že nad USARTem může běžet nějaký protokol
* přímo v tomto čipu. Jinak je to asi nejlevnější řešení. Zřejmě to * přímo v tomto čipu. Jinak je to asi nejlevnější řešení.
* nebude snášet velké rychlosti (nad 115200 Bd). *
* @class Middle
* Zkracuje obsluhu přerušení od USART1 čí podstatně zlepší činnost
* v plném duplexu. Je možné z řetězce vyhodit. Je to také ukázka
* jak přidat funkci (třeba vlastní protokol) do řetězce.
* */ * */
class Middle : public BaseLayer {
static constexpr unsigned max = 128;
volatile unsigned index;
char buffer [max];
public:
explicit Middle () noexcept : BaseLayer(), index(0u) {}
/* Up() v původním řetězci volalo fakticky Down() v cdc_class.
* Vzhledem k tomu, že len je zde 1 a USB musí vyvolat odeslání
* paketu, zdržuje to a přerušení zde může být ignorováno.
* Tohle ho významně zkrátí, ale zase musí být v hlavní smyčce
* odeslání dat pomocí metody pass().
* */
uint32_t Up(const char * data, const uint32_t len) override {
for (unsigned n=0; n<len; n++) buffer [index++] = data [n];
return len;
}
// Down je průchozí, bylo by možné toto zcela vypustit.
uint32_t Down(const char * data, const uint32_t len) override {
return BaseLayer::Down(data, len);
}
/* 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.
* */
if (index >= 32) { // 32 je vhodný kompromis mezi 1 a 64
BaseLayer::Up (buffer, index);
index = 0;
}
}
};
static cdc_class cdc; static cdc_class cdc;
static Usart usart; static Usart usart;
static Mirror top; static Mirror top;
static Middle mid;
int main () { int main () {
cdc.init(); cdc.init();
top += cdc; top += cdc;
top -= usart; top -= mid += usart;
cdc.attach(usart); cdc.attach(usart);
for (;;) { for (;;) {
/* Vše probíhá v přerušení */ mid.pass();
} }
return 0; return 0;
} }

View file

@ -35,7 +35,7 @@ static void Handler (int) {
int main (void) { int main (void) {
loop = true; loop = true;
signal (SIGINT, Handler); signal (SIGINT, Handler);
UsartClass usart ("/dev/serial/by-id/usb-Kizarm_Labs._USB__=__USART_0002-if00", 9600); UsartClass usart ("/dev/serial/by-id/usb-Kizarm_Labs._USB__=__USART_0002-if00", 1'000'000);
Top top; Top top;
top += usart; top += usart;
while (loop) { while (loop) {

View file

@ -14,7 +14,7 @@ UsartClass::UsartClass (const char * name, const int baudrate) : BaseLayer() {
fd = ::open (id, O_RDWR); fd = ::open (id, O_RDWR);
if (fd < 0) return; if (fd < 0) return;
timeout = 12'000'000 / baudrate; // cca pro 1 byte timeout = 20'000'000 / baudrate; // cca 2 násobek pro 1 byte
struct termios LineFlags; struct termios LineFlags;
int attr = tcgetattr (fd, &LineFlags); int attr = tcgetattr (fd, &LineFlags);
@ -66,6 +66,7 @@ uint32_t UsartClass::Down (const char * data, uint32_t len) {
while (remain) { while (remain) {
const unsigned chunk = remain > maxchunk ? maxchunk : remain; const unsigned chunk = remain > maxchunk ? maxchunk : remain;
const unsigned writn = ::write (fd, data + offset, chunk); const unsigned writn = ::write (fd, data + offset, chunk);
// Počkat je nejjednodušší prevence zahlcení USB (USART má omezenou rychlost)
usleep (timeout * writn); // závisí na baud rate usleep (timeout * writn); // závisí na baud rate
offset += writn; offset += writn;
remain -= writn; remain -= writn;