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.
|
||||
*
|
||||
* 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
|
||||
* nebude snášet velké rychlosti (nad 115200 Bd).
|
||||
* přímo v tomto čipu. Jinak je to asi nejlevnější řešení.
|
||||
*
|
||||
* @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 Usart usart;
|
||||
static Mirror top;
|
||||
static Middle mid;
|
||||
int main () {
|
||||
cdc.init();
|
||||
top += cdc;
|
||||
top -= usart;
|
||||
top -= mid += usart;
|
||||
cdc.attach(usart);
|
||||
for (;;) {
|
||||
/* Vše probíhá v přerušení */
|
||||
mid.pass();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ static void Handler (int) {
|
|||
int main (void) {
|
||||
loop = true;
|
||||
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 += usart;
|
||||
while (loop) {
|
||||
|
|
|
@ -14,7 +14,7 @@ UsartClass::UsartClass (const char * name, const int baudrate) : BaseLayer() {
|
|||
fd = ::open (id, O_RDWR);
|
||||
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;
|
||||
int attr = tcgetattr (fd, &LineFlags);
|
||||
|
@ -66,6 +66,7 @@ uint32_t UsartClass::Down (const char * data, uint32_t len) {
|
|||
while (remain) {
|
||||
const unsigned chunk = remain > maxchunk ? maxchunk : remain;
|
||||
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
|
||||
offset += writn;
|
||||
remain -= writn;
|
||||
|
|
Loading…
Reference in a new issue