Skip to content

File costas_core.h

FileList > costas > costas_core.h

Go to the source code of this file

Costas carrier-tracking loop (integer-NCO de-rotation + PI loop). More...

  • #include "clib_common.h"
  • #include "dp_state.h"
  • #include "jm_perf.h"
  • #include "lo/lo_core.h"
  • #include "loop_filter/loop_filter_core.h"
  • #include <math.h>

Classes

Type Name
struct costas_state_t
Costas loop state.

Public Functions

Type Name
void costas_configure (costas_state_t * state, double bn, double zeta)
costas_state_t * costas_create (double bn, double zeta, double init_norm_freq, size_t tsamps, double bn_fll)
Create a Costas instance.
void costas_destroy (costas_state_t * state)
Destroy a Costas instance and release all memory.
double costas_get_bn (const costas_state_t * state)
double costas_get_bn_fll (const costas_state_t * state)
double costas_get_last_error (const costas_state_t * state)
double costas_get_lock_metric (const costas_state_t * state)
double costas_get_norm_freq (const costas_state_t * state)
void costas_get_state (const costas_state_t * state, void * blob)
Serialize the full loop state into blob .
void costas_init (costas_state_t * s, double bn, double zeta, double init_norm_freq, size_t tsamps, double bn_fll)
Initialise a Costas loop in place (no allocation).
void costas_reset (costas_state_t * state)
Re-seed the loop to its create-time frequency/phase; keep config.
void costas_set_bn (costas_state_t * state, double val)
void costas_set_bn_fll (costas_state_t * state, double val)
void costas_set_norm_freq (costas_state_t * state, double val)
int costas_set_state (costas_state_t * state, const void * blob)
Restore state; DP_OK, or DP_ERR_INVALID if the envelope rejects.
size_t costas_state_bytes (const costas_state_t * state)
Serialized-state byte size.
size_t costas_steps (costas_state_t * state, const float complex * x, size_t x_len, float complex * out, size_t max_out)
size_t costas_steps_max_out (costas_state_t * state)
JM_FORCEINLINE JM_HOT void costas_update (costas_state_t * s, float complex P)
Per-symbol carrier update: discriminator -> loop filter -> steer NCO.
JM_FORCEINLINE JM_HOT float complex costas_wipeoff (costas_state_t * s, float complex x)
Per-sample carrier wipe-off: de-rotate x by the NCO, advance it.

Macros

Type Name
define COSTAS_EPS 1e-12f
define COSTAS_LOCK_ALPHA 0.1
define COSTAS_STATE_MAGIC [**DP\_FOURCC**](dp__state_8h.md#define-dp_fourcc)('C', 'S', 'T', 'S')
define COSTAS_STATE_VERSION 1u

Detailed Description

A continuous BPSK carrier-recovery loop: per sample it de-rotates the input with the integer-phase lo NCO (carrier wipe-off); every tsamps samples it dumps the coherent integrate-and-dump accumulator, runs a decision-directed Costas phase discriminator, filters the error through an embedded 2nd-order loop_filter_state_t, and steers the NCO frequency + phase. It tracks a small residual carrier offset (the bulk Doppler is removed upstream by FFT acquisition); the steering NCO is lo, so the phase is bounded and exactly reproducible (no double-accumulator drift).

The block API (costas_steps) is the Python face; the JM_FORCEINLINE costas_wipeoff()/costas_update() are the C composition API a despreader / tracking channel inlines into its own sample loop.

Lifecycle: costas_create -> [steps / configure / reset]* -> costas_destroy, or embed by value with costas_init().

Set bn_fll > 0 to enable FLL assist (a wide-pull-in frequency-lock loop aiding the PLL) for large or fast-moving residuals; bn_fll = 0 is a pure Costas PLL.

costas_state_t *c = costas_create(0.05, 0.707, 0.01, 64, 0.0);
float complex sym[16];
size_t k = costas_steps(c, rx, rx_len, sym, 16);  // one prompt per symbol
double f = c->nco.norm_freq;                       // tracked residual
costas_destroy(c);

Public Functions Documentation

function costas_configure

void costas_configure (
    costas_state_t * state,
    double bn,
    double zeta
) 

function costas_create

Create a Costas instance.

costas_state_t * costas_create (
    double bn,
    double zeta,
    double init_norm_freq,
    size_t tsamps,
    double bn_fll
) 

Parameters:

  • bn Loop noise bandwidth (default 0.05).
  • zeta Damping factor (default 0.707).
  • init_norm_freq Seed carrier frequency, cycles/sample (default 0.0).
  • tsamps Samples per symbol (default 64).
  • bn_fll FLL-assist bandwidth (default 0.0 = pure PLL).

Returns:

Heap-allocated state, or NULL on allocation failure.

Note:

Caller must call costas_destroy() when done.


function costas_destroy

Destroy a Costas instance and release all memory.

void costas_destroy (
    costas_state_t * state
) 

Parameters:

  • state May be NULL.

function costas_get_bn

double costas_get_bn (
    const costas_state_t * state
) 

function costas_get_bn_fll

double costas_get_bn_fll (
    const costas_state_t * state
) 

function costas_get_last_error

double costas_get_last_error (
    const costas_state_t * state
) 

function costas_get_lock_metric

double costas_get_lock_metric (
    const costas_state_t * state
) 

function costas_get_norm_freq

double costas_get_norm_freq (
    const costas_state_t * state
) 

function costas_get_state

Serialize the full loop state into blob .

void costas_get_state (
    const costas_state_t * state,
    void * blob
) 


function costas_init

Initialise a Costas loop in place (no allocation).

void costas_init (
    costas_state_t * s,
    double bn,
    double zeta,
    double init_norm_freq,
    size_t tsamps,
    double bn_fll
) 

The by-value counterpart to costas_create(): a tracking channel that embeds a costas_state_t initialises it here. Seeds the NCO at init_norm_freq and the loop integrator to the matching per-symbol frequency so de-rotation is correct from the first sample.

Parameters:

  • s State to initialise. Must be non-NULL.
  • bn Loop noise bandwidth, normalised to the symbol rate.
  • zeta Damping factor (0.707 = critically damped).
  • init_norm_freq Seed carrier frequency, cycles/sample.
  • tsamps Samples per symbol (the integrate-and-dump period).
  • bn_fll FLL-assist bandwidth (0 = pure PLL).

function costas_reset

Re-seed the loop to its create-time frequency/phase; keep config.

void costas_reset (
    costas_state_t * state
) 

Parameters:

  • state Must be non-NULL.

function costas_set_bn

void costas_set_bn (
    costas_state_t * state,
    double val
) 

function costas_set_bn_fll

void costas_set_bn_fll (
    costas_state_t * state,
    double val
) 

function costas_set_norm_freq

void costas_set_norm_freq (
    costas_state_t * state,
    double val
) 

function costas_set_state

Restore state; DP_OK, or DP_ERR_INVALID if the envelope rejects.

int costas_set_state (
    costas_state_t * state,
    const void * blob
) 


function costas_state_bytes

Serialized-state byte size.

size_t costas_state_bytes (
    const costas_state_t * state
) 


function costas_steps

size_t costas_steps (
    costas_state_t * state,
    const float complex * x,
    size_t x_len,
    float complex * out,
    size_t max_out
) 

function costas_steps_max_out

size_t costas_steps_max_out (
    costas_state_t * state
) 

function costas_update

Per-symbol carrier update: discriminator -> loop filter -> steer NCO.

JM_FORCEINLINE  JM_HOT void costas_update (
    costas_state_t * s,
    float complex P
) 

Runs the decision-directed BPSK Costas discriminator on the prompt P, filters it, and writes the new frequency (lo_set_norm_freq) plus a proportional phase nudge into the NCO. Updates the lock metric and last_error (the instantaneous loop stress). Inline for composition.

Parameters:

  • s Costas state. Must be non-NULL.
  • P The dumped integrate-and-dump prompt for this symbol.

function costas_wipeoff

Per-sample carrier wipe-off: de-rotate x by the NCO, advance it.

JM_FORCEINLINE  JM_HOT float complex costas_wipeoff (
    costas_state_t * s,
    float complex x
) 

x * conj(lo_step(nco)) — strips the (tracked) carrier ahead of the matched-filter integrate-and-dump. Inline, zero call overhead.

Parameters:

  • s Costas state. Must be non-NULL.
  • x One input sample.

Returns:

The de-rotated sample to feed the integrator.


Macro Definition Documentation

define COSTAS_EPS

#define COSTAS_EPS `1e-12f`

define COSTAS_LOCK_ALPHA

#define COSTAS_LOCK_ALPHA `0.1`

define COSTAS_STATE_MAGIC

#define COSTAS_STATE_MAGIC `DP_FOURCC ('C', 'S', 'T', 'S')`

define COSTAS_STATE_VERSION

#define COSTAS_STATE_VERSION `1u`


The documentation for this class was generated from the following file native/inc/costas/costas_core.h