refactoring usb
This commit is contained in:
parent
34e58e1b2b
commit
b345a72511
21 changed files with 162 additions and 2 deletions
|
@ -4,7 +4,7 @@ TOOL ?= gcc
|
||||||
|
|
||||||
PRJ = example
|
PRJ = example
|
||||||
|
|
||||||
VPATH = . ./$(TARGET)
|
VPATH = . ./$(TARGET) ./common
|
||||||
BLD = ./build/
|
BLD = ./build/
|
||||||
DFLAGS = -d
|
DFLAGS = -d
|
||||||
LFLAGS = -g
|
LFLAGS = -g
|
||||||
|
@ -12,7 +12,7 @@ LDLIBS =
|
||||||
BFLAGS = --strip-unneeded
|
BFLAGS = --strip-unneeded
|
||||||
|
|
||||||
CFLAGS = -MMD -Wall -Wno-parentheses -ggdb -fno-exceptions -ffunction-sections -fdata-sections
|
CFLAGS = -MMD -Wall -Wno-parentheses -ggdb -fno-exceptions -ffunction-sections -fdata-sections
|
||||||
CFLAGS+= -I. -I./$(TARGET)
|
CFLAGS+= -I. -I./$(TARGET) -I./common
|
||||||
DEL = rm -f
|
DEL = rm -f
|
||||||
|
|
||||||
# zdrojaky
|
# zdrojaky
|
||||||
|
|
1
V203/usb/cdc/ch32v203
Symbolic link
1
V203/usb/cdc/ch32v203
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../ch32v203/
|
1
V203/usb/cdc/common
Symbolic link
1
V203/usb/cdc/common
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../common/
|
85
V203/usb/common/print.cpp
Normal file
85
V203/usb/common/print.cpp
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
|
#define sleep()
|
||||||
|
|
||||||
|
static const char * hexStr = "0123456789ABCDEF";
|
||||||
|
static const uint16_t numLen[] = {1, 32, 1, 11, 8, 0};
|
||||||
|
|
||||||
|
Print::Print (PrintBases b) : BaseLayer () {
|
||||||
|
base = b;
|
||||||
|
}
|
||||||
|
// Výstup blokujeme podle toho, co se vrací ze spodní vrstvy
|
||||||
|
uint32_t Print::BlockDown (const char * buf, uint32_t len) {
|
||||||
|
uint32_t n, ofs = 0, req = len;
|
||||||
|
for (;;) {
|
||||||
|
// spodní vrstva může vrátit i nulu, pokud je FIFO plné
|
||||||
|
n = BaseLayer::Down (buf + ofs, req);
|
||||||
|
ofs += n; // Posuneme ukazatel
|
||||||
|
req -= n; // Zmenšíme další požadavek
|
||||||
|
if (!req) break;
|
||||||
|
sleep(); // A klidně můžeme spát
|
||||||
|
}
|
||||||
|
return ofs;
|
||||||
|
}
|
||||||
|
|
||||||
|
Print& Print::operator<< (const char * str) {
|
||||||
|
uint32_t i = 0;
|
||||||
|
while (str[i++]); // strlen
|
||||||
|
BlockDown (str, --i);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Print& Print::operator<< (const int num) {
|
||||||
|
uint32_t i = BUFLEN;
|
||||||
|
|
||||||
|
if (base == DEC) {
|
||||||
|
unsigned int u;
|
||||||
|
if (num < 0) u = -num;
|
||||||
|
else u = num;
|
||||||
|
do {
|
||||||
|
// Knihovní div() je nevhodné - dělí 2x.
|
||||||
|
// Přímočaré a funkční řešení
|
||||||
|
uint32_t rem;
|
||||||
|
rem = u % (unsigned) DEC; // 1.dělení
|
||||||
|
u = u / (unsigned) DEC; // 2.dělení
|
||||||
|
buf [--i] = hexStr [rem];
|
||||||
|
} while (u);
|
||||||
|
if (num < 0) buf [--i] = '-';
|
||||||
|
} else {
|
||||||
|
uint32_t m = (1U << (uint32_t) base) - 1U;
|
||||||
|
uint32_t l = (uint32_t) numLen [(int) base];
|
||||||
|
uint32_t u = (uint32_t) num;
|
||||||
|
for (unsigned n=0; n<l; n++) {
|
||||||
|
buf [--i] = hexStr [u & m];
|
||||||
|
u >>= (unsigned) base;
|
||||||
|
}
|
||||||
|
if (base == BIN) buf [--i] = 'b';
|
||||||
|
if (base == HEX) buf [--i] = 'x';
|
||||||
|
buf [--i] = '0';
|
||||||
|
}
|
||||||
|
BlockDown (buf+i, BUFLEN-i);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Print& Print::operator<< (const PrintBases num) {
|
||||||
|
base = num;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
void Print::out (const void * p, uint32_t l) {
|
||||||
|
const unsigned char* q = (const unsigned char*) p;
|
||||||
|
unsigned char uc;
|
||||||
|
uint32_t k, n = 0;
|
||||||
|
for (uint32_t i=0; i<l; i++) {
|
||||||
|
uc = q[i];
|
||||||
|
buf[n++] = '<';
|
||||||
|
k = uc >> 4;
|
||||||
|
buf[n++] = hexStr [k];
|
||||||
|
k = uc & 0x0f;
|
||||||
|
buf[n++] = hexStr [k];
|
||||||
|
buf[n++] = '>';
|
||||||
|
}
|
||||||
|
buf[n++] = '\r';
|
||||||
|
buf[n++] = '\n';
|
||||||
|
BlockDown (buf, n);
|
||||||
|
}
|
||||||
|
|
73
V203/usb/common/print.h
Normal file
73
V203/usb/common/print.h
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#ifndef PRINT_H
|
||||||
|
#define PRINT_H
|
||||||
|
|
||||||
|
#include "baselayer.h"
|
||||||
|
|
||||||
|
#define EOL "\r\n"
|
||||||
|
#define BUFLEN 64
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* @brief Něco jako ostream.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// Základy pro zobrazení čísla.
|
||||||
|
enum PrintBases {
|
||||||
|
BIN=1, OCT=3, DEC=10, HEX=4
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Print
|
||||||
|
* @brief Třída pro výpisy do Down().
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* V main pak přibude jen definice instance této třídy
|
||||||
|
* @code
|
||||||
|
static Print print;
|
||||||
|
* @endcode
|
||||||
|
* a ukázka, jak se s tím pracuje:
|
||||||
|
* @snippet main.cpp Main print example
|
||||||
|
* Nic na tom není - operátor << má přetížení pro string, číslo a volbu formátu čísla (enum PrintBases).
|
||||||
|
* Výstup je pak do bufferu a aby nám to "neutíkalo", tedy aby se vypsalo vše,
|
||||||
|
* zavedeme blokování, vycházející z toho, že spodní třída vrátí jen počet bytů,
|
||||||
|
* které skutečně odeslala. Při čekání spí, takže nepoužívat v přerušení.
|
||||||
|
* @snippet src/print.cpp Block example
|
||||||
|
* Toto blokování pak není použito ve vrchních třídách stacku,
|
||||||
|
* blokovaná metoda je BlockDown(). Pokud bychom použili přímo Down(), blokování by pak
|
||||||
|
* používaly všechny vrstvy nad tím. A protože mohou Down() používat v přerušení, byl by problém.
|
||||||
|
*
|
||||||
|
* Metody pro výpisy jsou sice dost zjednodušené, ale zase to nezabere
|
||||||
|
* moc místa - pro ladění se to použít dá. Délka vypisovaného stringu není omezena
|
||||||
|
* délkou použitého buferu.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Print : public BaseLayer {
|
||||||
|
public:
|
||||||
|
/// Konstruktor @param b Default decimální výpisy.
|
||||||
|
Print (PrintBases b = DEC);
|
||||||
|
/// Blokování výstupu
|
||||||
|
/// @param buf Ukazatel na data
|
||||||
|
/// @param len Délka přenášených dat
|
||||||
|
/// @return Počet přenesených bytů (rovno len)
|
||||||
|
uint32_t BlockDown (const char * buf, uint32_t len);
|
||||||
|
/// Výstup řetězce bytů
|
||||||
|
/// @param str Ukazatel na řetězec
|
||||||
|
/// @return Odkaz na tuto třídu kvůli řetězení.
|
||||||
|
Print & operator << (const char * str);
|
||||||
|
/// Výstup celého čísla podle base
|
||||||
|
/// @param num Číslo
|
||||||
|
/// @return Odkaz na tuto třídu kvůli řetězení.
|
||||||
|
Print & operator << (const int num);
|
||||||
|
/// Změna základu pro výstup čísla
|
||||||
|
/// @param num enum PrintBases
|
||||||
|
/// @return Odkaz na tuto třídu kvůli řetězení.
|
||||||
|
Print & operator << (const PrintBases num);
|
||||||
|
void out (const void* p, uint32_t l);
|
||||||
|
private:
|
||||||
|
PrintBases base; //!< Základ pro výstup čísla.
|
||||||
|
char buf[BUFLEN]; //!< Buffer pro výstup čísla.
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PRINT_H
|
Loading…
Add table
Reference in a new issue