RISC-V/V203/usb/adc/main.cpp
2024-10-19 14:58:36 +02:00

72 lines
2.3 KiB
C++

#include "cdc_class.h"
#include "adcdma.h"
#include "oneway.h"
/** Test ADC.
* Jednoduchý test ADC převodníku se vzorkovací frekvencí 1kHz.
* Data se čtou na PA2 a vypisují pomocí USB_CDC v hex formátu.
* Převodník je lehce přetaktovaný (18 MHz místo max.14), ale
* zřejmě to moc nevadí. Žádný závěr o kvalitě se z toho dělat
* nedá, šum může být způsoben vývojovou deskou, linearitu nemám
* jak měřit (resp. mě to nebaví).
* */
class Transport : public BaseLayer, public OneWay {
static constexpr const char * hexStr = "0123456789abcdef";
static constexpr const char * eol = "\r\n ";
static constexpr unsigned max = 128;
static_assert (max > 4u * HALF_LEN + 4u, "buffer len is too small");
GpioClass led; // indikace DMA
volatile bool toggle;
FIFO<char, max> ring;
char buffer [max];
public:
explicit Transport () noexcept : BaseLayer(), OneWay(),
led(GPIOA, 1), toggle(false), ring() {}
// Toto je voláno v přerušení DMA1_Channel1_IRQHandler od ADC.
unsigned int Send(uint16_t * const ptr, const unsigned int len) override {
led << toggle; // indikace
toggle = ! toggle;
for (unsigned n=0u; n<len; n++) { // pro test vypisuji v hexu
put_u16 (ptr [n]);
}
for (unsigned n=0u; n<2u; n++) ring.Write(eol [n]); // new line
return len;
}
void pass () {
unsigned n = 0u;
for (n=0u; n<max; n++) {
if (!ring.Read (buffer [n])) break;
}
if (n) block (n);
}
void put_u16 (const uint16_t p) {
uint16_t e = p; // max 0xFFF (12 bit)
const char c1 = hexStr [e & 0x0f]; e >>= 4;
const char c2 = hexStr [e & 0x0f]; e >>= 4;
const char c3 = hexStr [e & 0x0f];
ring.Write (c3);
ring.Write (c2);
ring.Write (c1);
ring.Write (eol [2]); // space
}
protected:
void block (const unsigned len) {
unsigned ofs = 0u, rem = len;
while (rem) {
const unsigned res = Down (buffer + ofs, rem);
rem -= res;
ofs += res;
}
}
};
static cdc_class cdc;
static AdcDma adc;
static Transport tra;
int main () {
cdc.init();
tra += cdc;
adc.attach(tra);
for (;;) {
tra.pass();
}
return 0;
}