mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
104 lines
2.1 KiB
C++
104 lines
2.1 KiB
C++
#include "globals.h"
|
|
#include "fluxmap.h"
|
|
#include "decoders/fluxmapreader.h"
|
|
#include "decoders/fluxdecoder.h"
|
|
#include "lib/decoders/decoders.pb.h"
|
|
|
|
FluxDecoder::FluxDecoder(FluxmapReader* fmr, nanoseconds_t bitcell,
|
|
const DecoderProto& config):
|
|
_fmr(fmr),
|
|
_pll_phase(config.pll_phase()),
|
|
_pll_adjust(config.pll_adjust()),
|
|
_flux_scale(config.flux_scale()),
|
|
_clock(bitcell),
|
|
_clock_centre(bitcell),
|
|
_clock_min(bitcell * (1.0 - _pll_adjust)),
|
|
_clock_max(bitcell * (1.0 + _pll_adjust)),
|
|
_flux(0),
|
|
_leading_zeroes(fmr->tell().zeroes)
|
|
{}
|
|
|
|
|
|
bool FluxDecoder::readBit()
|
|
{
|
|
if (_leading_zeroes > 0)
|
|
{
|
|
_leading_zeroes--;
|
|
return false;
|
|
}
|
|
else if (_leading_zeroes == 0)
|
|
{
|
|
_leading_zeroes--;
|
|
return true;
|
|
}
|
|
|
|
while (!_fmr->eof() && (_flux < (_clock/2)))
|
|
{
|
|
_flux += nextFlux() * _flux_scale;;
|
|
_clocked_zeroes = 0;
|
|
}
|
|
|
|
_flux -= _clock;
|
|
if (_flux >= (_clock/2))
|
|
{
|
|
_clocked_zeroes++;
|
|
_goodbits++;
|
|
return false;
|
|
}
|
|
|
|
/* PLL adjustment: change the clock frequency according to the phase
|
|
* mismatch */
|
|
if (_clocked_zeroes <= 3)
|
|
{
|
|
/* In sync: adjust base clock */
|
|
|
|
_clock += _flux * _pll_adjust;
|
|
}
|
|
else
|
|
{
|
|
/* Out of sync: adjust the base clock back towards the centre */
|
|
|
|
_clock += (_clock_centre - _clock) * _pll_adjust;
|
|
|
|
/* We require 256 good bits before reporting another sync loss event. */
|
|
|
|
if (_goodbits >= 256)
|
|
_sync_lost = true;
|
|
_goodbits = 0;
|
|
}
|
|
|
|
/* Clamp the clock's adjustment range. */
|
|
|
|
_clock = std::min(std::max(_clock_min, _clock), _clock_max);
|
|
|
|
_goodbits++;
|
|
return true;
|
|
}
|
|
|
|
std::vector<bool> FluxDecoder::readBits(unsigned count)
|
|
{
|
|
std::vector<bool> result;
|
|
while (!_fmr->eof() && count--)
|
|
{
|
|
bool b = readBit();
|
|
result.push_back(b);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
std::vector<bool> FluxDecoder::readBits(const Fluxmap::Position& until)
|
|
{
|
|
std::vector<bool> result;
|
|
while (!_fmr->eof() && (_fmr->tell().bytes < until.bytes))
|
|
{
|
|
bool b = readBit();
|
|
result.push_back(b);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
nanoseconds_t FluxDecoder::nextFlux()
|
|
{
|
|
return _fmr->readInterval(_clock_centre) * NS_PER_TICK;
|
|
}
|