Initial import
git-svn-id: http://moon:8086/svn/software/trunk/libsrc/radio@1 b431acfa-c32f-4a4a-93f1-934dc6c82436
This commit is contained in:
Executable
+224
@@ -0,0 +1,224 @@
|
||||
// --------------------------------------------------------------
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "synchronization.h"
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Clock generator
|
||||
// --------------------------------------------------------------
|
||||
void ClockInit(clock_t *pObj, uint32_t divide)
|
||||
{
|
||||
if (divide == 0)
|
||||
divide = 1;
|
||||
|
||||
pObj->reload = divide;
|
||||
pObj->count = (int32_t)divide;
|
||||
}
|
||||
|
||||
uint32_t ClockIsTick(clock_t *pObj, uint32_t do_advance)
|
||||
{
|
||||
uint32_t isTick;
|
||||
|
||||
isTick = pObj->count == 0;
|
||||
|
||||
if (do_advance)
|
||||
{
|
||||
if (isTick)
|
||||
{
|
||||
pObj->count = pObj->reload;
|
||||
}
|
||||
pObj->count--;
|
||||
}
|
||||
return isTick;
|
||||
}
|
||||
|
||||
void ClockAdvance(clock_t *pObj)
|
||||
{
|
||||
if (pObj->count == 0)
|
||||
{
|
||||
pObj->count = pObj->reload;
|
||||
}
|
||||
pObj->count--;
|
||||
}
|
||||
|
||||
void ClockSetPhase(clock_t *pObj, int32_t phase)
|
||||
{
|
||||
pObj->count = pObj->count - phase;
|
||||
if (pObj->count <= 0)
|
||||
{
|
||||
pObj->count += pObj->reload;
|
||||
}
|
||||
else if (pObj->count > (int32_t)pObj->reload)
|
||||
{
|
||||
pObj->count -= pObj->reload;
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Second-order Loop Filter
|
||||
// --------------------------------------------------------------
|
||||
void LeadLagInit(lead_lag_filter_t *pObj, radio_float_t state)
|
||||
{
|
||||
pObj->lag_state = LEAD_LAG_SCALING*state;
|
||||
};
|
||||
|
||||
void LeadLagSetCoeff(lead_lag_coeff_t *pCoeff, radio_float_t lead, radio_float_t lag)
|
||||
{
|
||||
pCoeff->lead = lead;
|
||||
pCoeff->lag = lag;
|
||||
}
|
||||
|
||||
radio_float_t LeadLagProcess(lead_lag_filter_t *pObj, lead_lag_coeff_t *pCoeff, radio_float_t x)
|
||||
{
|
||||
pObj->lag_state += LEAD_LAG_SCALING*pCoeff->lag * x;
|
||||
|
||||
return pObj->lag_state/LEAD_LAG_SCALING + pCoeff->lead * x;
|
||||
}
|
||||
|
||||
radio_float_t LeadLagGetState(lead_lag_filter_t *pObj)
|
||||
{
|
||||
return pObj->lag_state/LEAD_LAG_SCALING;
|
||||
}
|
||||
|
||||
void LeadLagSetState(lead_lag_filter_t *pObj, radio_float_t state)
|
||||
{
|
||||
pObj->lag_state = LEAD_LAG_SCALING*state;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Gardner Timing Error Detector
|
||||
// --------------------------------------------------------------
|
||||
void STRGardnerInit(str_t *pObj)
|
||||
{
|
||||
memset(pObj->d, 0, sizeof(pObj->d));
|
||||
}
|
||||
|
||||
radio_float_t STRGardnerProcess(str_t *pObj, cpx_t x)
|
||||
{
|
||||
radio_float_t Vd;
|
||||
cpx_t t, *pD;
|
||||
|
||||
pD = pObj->d;
|
||||
|
||||
t.real = (pD[1].real - x.real) * pD[0].real;
|
||||
t.imag = (pD[1].imag - x.imag) * pD[0].imag;
|
||||
Vd = (t.real + t.imag);
|
||||
|
||||
// Adjust delay line
|
||||
pD[1] = pD[0];
|
||||
pD[0] = x;
|
||||
|
||||
return Vd;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
// Simple Phase detector for QPSK
|
||||
// --------------------------------------------------------------
|
||||
radio_float_t PhaseErrQPSK(cpx_t x)
|
||||
{
|
||||
radio_float_t perr;
|
||||
perr = x.imag*dsign(x.real) - x.real*dsign(x.imag);
|
||||
|
||||
return perr;
|
||||
}
|
||||
|
||||
radio_float_t PhaseErr(cpx_t x, radio_float_t pstep, radio_float_t poffset)
|
||||
{
|
||||
radio_float_t perr, phi, m;
|
||||
|
||||
phi = (radio_float_t)CpxPhiS(x) + poffset;
|
||||
|
||||
m = dmod(phi/(radio_float_t)PI,(radio_float_t)2.0/pstep);
|
||||
perr = (radio_float_t)1.0/pstep - m;
|
||||
|
||||
return (radio_float_t)(PI*perr);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
void PfdInit(pfd_t *pObj)
|
||||
{
|
||||
pObj->state_up = 0;
|
||||
pObj->state_down = 0;
|
||||
}
|
||||
|
||||
radio_float_t PfdProcess(pfd_t *pObj, radio_float_t x, radio_float_t k)
|
||||
{
|
||||
radio_float_t result;
|
||||
|
||||
result = 0;
|
||||
if (x < 0)
|
||||
{
|
||||
if (pObj->state_down == 0)
|
||||
{
|
||||
pObj->state_up = 0;
|
||||
pObj->state_down = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = -k;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pObj->state_up == 0)
|
||||
{
|
||||
pObj->state_down = 0;
|
||||
pObj->state_up = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = k;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------
|
||||
void TimingCorrectorInit(timing_corrector_t *pObj, radio_float_t wrap_alpha)
|
||||
{
|
||||
pObj->mu = 0;
|
||||
pObj->mu_filtered = 0;
|
||||
pObj->wrap_alpha = wrap_alpha;
|
||||
pObj->wrap_beta = (radio_float_t)1.0 - wrap_alpha;
|
||||
memset(pObj->skip, 0, sizeof(pObj->skip));
|
||||
memset(pObj->stuff, 0, sizeof(pObj->stuff));
|
||||
}
|
||||
|
||||
radio_float_t TimingCorrectorProcess(timing_corrector_t *pObj, radio_float_t dMu)
|
||||
{
|
||||
pObj->mu += dMu;
|
||||
pObj->skip[1] = pObj->skip[0];
|
||||
pObj->stuff[1] = pObj->stuff[0];
|
||||
pObj->skip[0] = 0;
|
||||
pObj->stuff[0] = 0;
|
||||
pObj->mu_filtered = pObj->wrap_beta*pObj->mu_filtered + pObj->wrap_alpha*pObj->mu;
|
||||
|
||||
if (pObj->mu_filtered < 0)
|
||||
{
|
||||
pObj->mu += (radio_float_t)1.0;
|
||||
pObj->stuff[0] = 1;
|
||||
}
|
||||
else if (pObj->mu_filtered >= (radio_float_t)1.0)
|
||||
{
|
||||
pObj->mu -= (radio_float_t)1.0;
|
||||
pObj->skip[0] = 1;
|
||||
}
|
||||
|
||||
return pObj->mu;
|
||||
}
|
||||
|
||||
radio_float_t TimingCorrectorGetMu(timing_corrector_t *pObj)
|
||||
{
|
||||
return pObj->mu;
|
||||
}
|
||||
|
||||
uint32_t TimingCorrectorIsSkip(timing_corrector_t *pObj)
|
||||
{
|
||||
return pObj->skip[0];
|
||||
}
|
||||
|
||||
uint32_t TimingCorrectorIsStuff(timing_corrector_t *pObj)
|
||||
{
|
||||
return pObj->stuff[0];
|
||||
}
|
||||
Reference in New Issue
Block a user