#include "usart.h"
#include "print.h"
#include "adcdma.h"
#include "oneway.h"
#include "fifo.h"
////////////////////////////////////////////////////////
/* Voltmetr měří na pinu PA2 napětí a vypisuje v mV.
 * Frekvence vzorkování je 1kHz, průměruje se to a
 * zobrazuje jednou za 120 ms (9600 Bd).   */
////////////////////////////////////////////////////////
class Meassure : public OneWay {
  FIFO<unsigned, 8u> fifo;
  unsigned           avg;
  public:
    explicit Meassure () noexcept : OneWay(), fifo(), avg(0u) {}
    unsigned int Send (uint16_t * const ptr, const unsigned int len) override;
    void out ();
};
////////////////////////////////////////////////////////
static Usart    serial (9600u);
static Print    cout   (DEC);
static AdcDma   adc;
static Meassure meas;
////////////////////////////////////////////////////////
int main () {
  cout += serial;
  adc.attach (meas);
  for (;;) {
    meas.out();
  }
  return 0;
}
////////////////////////////////////////////////////////
static constexpr unsigned BK = 3316u << 4;  // Mělo by to být přesně 3300.
unsigned int Meassure::Send(uint16_t * const ptr, const unsigned int len) {
  for (unsigned n=0; n<len; n++) {
    const unsigned mv = (BK * ptr [n]) >> 16;
    avg = (avg * 15 + mv) >> 4; // klouzavý průměr s postupným zapomínáním
  }
  fifo.Write (avg);
  return 0;
}
void Meassure::out() {
  unsigned t;
  if (fifo.Read (t)) {
    cout << t << " mV\r\n";
  }
}