test cdc-usart
This commit is contained in:
parent
07c30fffc8
commit
71e6023978
3 changed files with 46 additions and 6 deletions
|
@ -7,19 +7,58 @@
|
||||||
* Baudová rychlost se dá po USB změnit na libovolnou hodnotu.
|
* Baudová rychlost se dá 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 čímž podstatně zlepší činnost
|
||||||
|
* v plném duplexu. Je možné jí 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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue