38 lines
1.6 KiB
C++
38 lines
1.6 KiB
C++
#include "pwmclass.h"
|
|
#include "GsmDecoder.h"
|
|
|
|
static const unsigned int DataLenght = 2529384u;
|
|
extern "C" void * memcpy(void * dest, const void * src, size_t n);
|
|
|
|
GsmDecoder::GsmDecoder(GpioClass & io) noexcept : OneWay<uint16_t>(),
|
|
led(io), flash(), gsm(), count(0u), pass(false) {
|
|
}
|
|
static constexpr int INPUT_BIT_RANGE = 16;
|
|
static constexpr unsigned SIGMA_MASK = (1u << (INPUT_BIT_RANGE + 0)) - 1u;
|
|
static constexpr unsigned SIGNED_OFFEST = (1u << (INPUT_BIT_RANGE - 1));
|
|
// Předpokládá se na vstupu signed int o šířce INPUT_BIT_RANGE
|
|
// přičemž 0 na vstupu odpovídá MAXPWM / 2 na výstupu. Vypadá to divně, ale funguje.
|
|
static unsigned pwm_sd (const int input) {
|
|
static unsigned sigma = 0; // podstatné je, že proměnná je statická
|
|
const unsigned sample = (input + SIGNED_OFFEST) * MAXPWM;
|
|
sigma &= SIGMA_MASK; // v podstatě se odečte hodnota PWM
|
|
sigma += sample; // integrace prostým součtem
|
|
return sigma >> INPUT_BIT_RANGE;
|
|
}
|
|
unsigned GsmDecoder::Send(uint16_t * dptr, const unsigned len) {
|
|
led << pass;
|
|
pass = ! pass;
|
|
const unsigned step = sizeof(gsm_frame);
|
|
static gsm_frame e;
|
|
flash.ReadBlock(count, e, step);
|
|
count += step;
|
|
gsm.decode (e, tmp_buf);
|
|
if (count >= DataLenght) count = 0u;
|
|
for (unsigned n=0u, k=0u; k<len; n++) {
|
|
const int16_t s = tmp_buf[n];
|
|
dptr [k++] = pwm_sd (s); // vyzkoušená metoda jak vylepšit PWM
|
|
dptr [k++] = pwm_sd (s); // pokud máme frekvenci PWM větší
|
|
dptr [k++] = pwm_sd (s); // než vzorkovací frekvence signálu ft = n * fs, n = 3
|
|
}
|
|
return 0;
|
|
}
|