<!– SPDX-FileCopyrightText: 2026 Ahmed Imamovic SPDX-FileCopyrightText: 2026 Tarik Hamedovic SPDX-License-Identifier: CC-BY-SA-4.0 –>

C / RTL API Reference

This section exposes the firmware and RTL comments generated by Doxygen and Breathe. The current firmware API is implemented directly in 2.soc/2.sw/uberclock.c with generated LiteX CSR accessor functions from the board build directory.

Firmware Runtime

UART-driven bare-metal firmware for the uberClock LiteX SoC.

This file contains the current firmware runtime used by the VexRiscV CPU. It registers UART console commands, writes LiteX-generated CSRs, services the ce_down event from the DSP datapath, moves samples through the low-rate FIFOs, runs KISS FFT analysis, starts DDR/S2MM captures, and implements the track3 and trackq frequency-tracking workflows.

The application directory is generated by demo.py, so this top-level source in 2.soc/2.sw is the copy that should be documented and edited.

Defines

SIG3_ENABLE_DEFAULT
SIG3_CHANNELS
SIG3_TONES
TRACKQ_CHANNELS
TRACKQ_CH1_DELTA_HZ
TRACKQ_CH2_DELTA_HZ
TRACKQ_CH3_DELTA_HZ
TRACKQ_CH1_START_HZ
TRACKQ_CH2_START_HZ
TRACKQ_CH3_START_HZ
DSP_SWQ_LEN
FFT_MAX_N
FFT_CFG_MAX_BYTES
TRACK3_RF_FS_HZ
TRACK3_DEFAULT_STEP_HZ
TRACK3_DEFAULT_MAX_STEPS
TRACK3_DEFAULT_N
TRACK3_DEFAULT_SETTLE
TRACK3_DEFAULT_CENTER_HZ
TRACK3_DEFAULT_DELTA_HZ
TRACK3_DEFAULT_BAND_BINS
TRACKQ_INTERVAL_TICKS
TRACKQ_CORR_SHIFT
TRACKQ_MAX_STEP_HZ
TRACKQ_ERR_ALPHA_NUM
TRACKQ_ERR_ALPHA_DEN
TRACKQ_KP_NUM
TRACKQ_KP_DEN
TRACKQ_MIN_CONF_PCT
TRACKQ_WEAK_DEADBAND_PCT
TRACKQ_WEAK_GAIN_DEN
TRACKQ_WEAK_MAX_ERR_MHZ
TRACKQ_SERVICE_STRIDE
TRACK3_FIFO_WAIT_POLLS
TRACK3_SIDE_MIN_PCT
TRACK3_SIDE_MAX_PCT
TRACK3_SIDE_BALANCE_PCT
UBD3_MAGIC
UBD3_BOARD_IP
UBD3_PAYLOAD_MAX
UBD3_SERVICE_EVERY
UBD3_PACE_WAIT_MS
UBD3_PROGRESS_EVERY

Enums

enum fsm_states

Values:

enumerator IDLE
enumerator S1
enumerator S2

Functions

static inline unsigned parse_u(const char *s, unsigned max, const char *what)

Parse an unsigned console argument with an inclusive upper bound.

static inline int parse_s(const char *s, int minv, int maxv, const char *what)

Parse a signed console argument with inclusive bounds.

static void write_upsampler_inputs_all_x(int16_t v)

Write one signed X sample into every CPU-driven upsampler input CSR.

The current console commands treat CPU injection as a five-channel frame. Hardware variants may expose individual channel CSRs or a replicated scalar path; this helper is the single place that fans out the requested X value.

static void write_upsampler_inputs_all_y(int16_t v)

Write one signed Y sample into every CPU-driven upsampler input CSR.

static void ups_fifo_write_frame(const iq5_frame_t *frame)

Push a five-channel IQ frame into the upsampler injection FIFO.

The frame is presented through CSR storage registers and committed with the main_ups_fifo_push strobe. Samples are stored as 16-bit signed values.

static void ups_fifo_write_replicated(int16_t x, int16_t y)

Push the same IQ sample into all five logical upsampler channels.

static void ds_fifo_read_frame(iq5_frame_t *frame)

Pop one downsampled IQ frame from the DSP-to-CPU FIFO.

The pop strobe latches the FIFO output into the generated CSR status fields. Callers must check main_ds_fifo_flags before using this helper.

static void cmd_fft32_ds_y(char *args)

Console command: run a fixed 32-point real FFT over DS FIFO Y samples.

static uint32_t sig3_phase_inc(uint32_t f_hz, uint32_t fs_hz)

Convert a signal-generator frequency to a 32-bit DDS phase increment.

static void sig3_update_increments(void)

Recompute all software three-tone DDS phase increments.

static void sig3_set_channel_freqs(unsigned channel, uint32_t f1_hz, uint32_t f2_hz, uint32_t f3_hz)

Set the three software tone frequencies for one logical channel.

static void sig3_set_channel_symmetric(unsigned channel, uint32_t center_hz, uint32_t delta_hz)
static void sig3_enable_channel(unsigned channel)
static inline int16_t sig3_sin_u32(uint32_t ph)
static void sig3_start(void)

Enable the software three-tone generator and prime its increments.

static void sig3_stop(void)

Disable the software three-tone generator and push a zero sample.

static inline int16_t sig3_clamp_s16(int32_t x)
static int sig3_step(iq5_frame_t *frame)

Advance all enabled three-tone DDS channels by one sample.

Returns:

Non-zero when at least one channel is enabled and frame was filled.

static int sig3_push_update_now(void)
static void sig3_push_zero_now(void)
static void sig3_push_one(void)

Generate and enqueue one software signal-generator frame if enabled.

static void cmd_sig3_amp(char *a)
static void cmd_sig3_freqs(char *args)
static void cmd_sig3_enable_ch(char *a)
static void cmd_sig3_disable_ch(char *a)
static void cmd_sig3_start(char *a)
static void cmd_sig3_stop(char *a)
static inline void ub_cache_sync(void)

Flush CPU/L2 caches before or after DMA-visible DDR accesses.

static unsigned dsp_pump_step(unsigned max_in, unsigned max_out)

Move a bounded number of samples between software queues and FIFOs.

This non-blocking pump lets the firmware exercise the DSP loop without monopolizing the UART console.

static inline void uc_commit(void)

Commit pending CSR settings to the UC-domain snapshot FIFO.

static uint32_t trackq_default_delta_hz(unsigned channel)
static inline int is_pow2_u(unsigned x)
static uint32_t uc_phase_inc_from_hz(uint32_t f_hz, uint32_t fs_hz)

Convert an RF/sample frequency to the 26-bit hardware phase format.

static uint32_t uc_phase_inc_to_hz(uint32_t phase_inc, uint32_t fs_hz)

Convert a 26-bit hardware phase increment back to Hz.

static int64_t uc_phase_inc_to_mhz(uint32_t phase_inc, uint32_t fs_hz)
static int64_t sig3_phase_inc_to_mhz(uint32_t phase_inc, uint32_t fs_hz)
static int64_t trackq_center_tone_hz_milli(unsigned channel)
static uint32_t phase_down_read(unsigned channel)
static void phase_down_write(unsigned channel, uint32_t phase_inc)
static uint64_t fft_bin_power(unsigned k)

Return squared magnitude for FFT bin k from the global FFT output.

static uint64_t fft_band_power(unsigned k, unsigned bins)
static void service_one_ce_event(void)

Service one low-rate ce_down event from the DSP datapath.

This is the runtime hook that keeps software signal generation, magnitude polling, and event re-arming aligned to the downsampled DSP cadence.

static void track3_service_background(void)
static void track3_service_background_budget(unsigned budget)
static void track3_wait_ticks(uint32_t wait_ticks)
static unsigned ds_fifo_flush_all(unsigned max_samples)

Drain up to max_samples entries from the downsample FIFO.

static int track3_wait_ds_fifo(const char *phase, unsigned sample_idx, unsigned total)
static int capture_ds_fft_channel(unsigned channel, unsigned n, unsigned settle)

Capture n downsampled X samples for one logical channel into FFT input.

static int capture_ds_track_multi(unsigned n, unsigned settle)

Capture synchronized samples for the three-channel tracking loop.

static uint64_t fft_bin_power_at(unsigned k)
static uint64_t fft_band_power_at(unsigned k, unsigned half_bins, unsigned n)
static inline void trackq_service_background_sample(unsigned sample_idx)
static uint64_t track_power_at_hz(uint32_t f_hz, unsigned n)

Estimate FFT-bin power at a requested frequency using live FFT output.

static uint64_t track_power_at_hz_samples(const int16_t *samples, uint32_t f_hz, unsigned n)

Run an FFT over a sample buffer and return power near f_hz.

static uint64_t track_band_power_at_hz(uint32_t f_hz, unsigned n)
static uint64_t track_band_power_at_hz_samples(const int16_t *samples, uint32_t f_hz, unsigned n)
static int track3_triplet_match(uint64_t left_pwr, uint64_t center_pwr, uint64_t right_pwr)
static int32_t trackq_clamp_step_hz(int32_t correction_hz)
static int32_t trackq_clamp_weak_step_hz(int32_t correction_hz)
static int trackq_vertex_confident(uint64_t left_pwr, uint64_t center_pwr, uint64_t right_pwr)
static int32_t trackq_side_error_mhz(uint64_t left_pwr, uint64_t right_pwr, uint32_t delta_hz)
static void trackq_step(void)

Run one non-blocking iteration of the quadratic three-point tracker.

When enabled by trackq_start, this function captures probe samples, compares left/center/right tone power, and adjusts downconversion phase increments with bounded correction steps.

static void cmd_track3(char *args)
static void cmd_trackq_start(char *args)
static void cmd_trackq_probe(char *args)
static void cmd_trackq_stop(char *args)
static void cmd_fft64_peak(char *args)
static void ce_down_isr(void)

Interrupt handler for the DSP downsample event source.

The ISR keeps work minimal: it acknowledges the event and increments a software counter consumed by uberclock_poll.

static void uc_help(char *args)

Console command: print all registered uberClock commands.

static void cmd_phase_nco(char *a)
static void cmd_phase_cpu1(char *a)
static void cmd_phase_cpu2(char *a)
static void cmd_phase_cpu3(char *a)
static void cmd_phase_cpu4(char *a)
static void cmd_phase_cpu5(char *a)
static void cmd_nco_mag(char *a)
static void cmd_phase_down_ref(char *a)
static void cmd_mag_cpu1(char *a)
static void cmd_mag_cpu2(char *a)
static void cmd_mag_cpu3(char *a)
static void cmd_mag_cpu4(char *a)
static void cmd_mag_cpu5(char *a)
static void cmd_lowspeed_dbg_select(char *a)
static void cmd_highspeed_dbg_select(char *a)
static void cmd_phase_dn(char *a, int ch)
static void cmd_phase_down_1(char *a)
static void cmd_phase_down_2(char *a)
static void cmd_phase_down_3(char *a)
static void cmd_phase_down_4(char *a)
static void cmd_phase_down_5(char *a)
static void cmd_output_sel_ch1(char *a)
static void cmd_output_sel_ch2(char *a)
static void cmd_input_select(char *a)
static void cmd_ups_in_mux(char *a)
static void cmd_gain(char *a, int idx)
static void cmd_gain1(char *a)
static void cmd_gain2(char *a)
static void cmd_gain3(char *a)
static void cmd_gain4(char *a)
static void cmd_gain5(char *a)
static void cmd_final_shift(char *a)
static void cmd_cap_enable(char *a)
static void cmd_upsampler_x(char *a)
static void cmd_upsampler_y(char *a)
static void cap_start_cmd(char *a)
static void cap_status_cmd(char *a)
static void cap_dump_cmd(char *a)
static inline void dsp_process(int16_t in_x, int16_t in_y, int16_t *out_x, int16_t *out_y)
static void fifo_clear_flags(void)

Clear sticky overflow/underflow flags on DSP-side software FIFOs.

static void cmd_dsp_test(char *args)
static void cmd_ds_pop(char *a)
static void cmd_ds_status(char *a)
static void cmd_ups_push(char *args)
static void cmd_ups_status(char *a)
static void cmd_dsp_run(char *a)
static void cmd_fft_fs(char *a)
static void run_fft_ds(char *args, int peak_only)

Capture DS FIFO IQ samples and run a configurable KISS FFT.

Parameters:
  • args – Console argument string containing optional FFT length.

  • peak_only – Print only the strongest bin when non-zero.

static void cmd_fft_ds(char *args)
static void cmd_fft_ds_peak(char *args)
static void cmd_cap_arm_pulse(char *a)
static void cmd_cap_done(char *a)
static void cmd_cap_rd(char *args)
static void cmd_phase_print(char *a)
static void cmd_magnitude(char *a)
static inline uint8_t ub_size_to_code(const char *s)

Convert a byte-count token into the S2MM transfer-size encoding.

static void ub_help(char *args)
static void cmd_ub_info(char *a)
static void cmd_ub_mode(char *a)
static void cmd_ub_setmode(char *a)
static void ub_dma_start(uint64_t addr, uint32_t beats, uint8_t size_code)

Program and start an UberDDR3 S2MM DMA transfer.

static void cmd_ub_start(char *args)
static void cmd_ub_ramp2(char *args)
static void cmd_ub_cap(char *args)
static void cmd_ub_wait(char *a)
static void cmd_ub_hexdump(char *a)
static void cmd_cap_beats(char *a)
static inline void u32le_store(uint8_t *p, uint32_t v)

Store a 32-bit word in little-endian byte order for UDP payloads.

static int parse_ipv4(const char *s, uint32_t *out_ip)

Parse dotted-decimal IPv4 text into the LiteEth integer format.

static void cmd_ub_send(char *args)
void uberclock_register_cmds(void)

Register all uberClock console commands with the UART console.

void fsm_init(void)

Initialize the experimental magnitude-search state machine.

void tran(void)

Advance the experimental magnitude-search state machine by one step.

void uberclock_init(void)

Initialize CSRs, software generators, FIFOs, interrupts, and defaults.

This function is called once from the firmware entry point after the console is ready. It establishes the default downconversion frequencies, routing, gains, capture mode, and event interrupt state used by the UART workflows.

void uberclock_poll(void)

Run the non-blocking firmware background work.

The main loop calls this repeatedly after console_poll. It services the quadratic tracker and drains queued ce_down events recorded by the ISR.

Variables

static volatile int sig3_enable = 0
static uint8_t sig3_channel_enable[SIG3_CHANNELS] = {1u, 1u, 1u, 0u, 0u}
static uint32_t sig3_phase[SIG3_CHANNELS][SIG3_TONES]
static uint32_t sig3_inc[SIG3_CHANNELS][SIG3_TONES]
static uint32_t sig3_freq_hz[SIG3_CHANNELS][SIG3_TONES] = {{990u, 1000u, 1010u}, {970u, 1000u, 1030u}, {970u, 1000u, 1030u}, {990u, 1000u, 1010u}, {990u, 1000u, 1010u},}
static int16_t sig3_amp[SIG3_CHANNELS] = {3000, 10000, 10000, 3000, 3000}
static const int16_t sine_q64[64] = {0, 804, 1608, 2410, 3212, 4011, 4808, 5602, 6393, 7179, 7962, 8739, 9512, 10278, 11039, 11793, 12539, 13279, 14010, 14732, 15446, 16151, 16846, 17530, 18204, 18868, 19519, 20159, 20787, 21403, 22005, 22594, 23170, 23731, 24279, 24811, 25329, 25831, 26318, 26789, 27244, 27683, 28105, 28510, 28898, 29269, 29622, 29957, 30274, 30572, 30852, 31113, 31356, 31579, 31783, 31968, 32133, 32279, 32405, 32512, 32598, 32665, 32713, 32740}
static volatile uint32_t ce_event = 0
static int16_t mag
static int32_t phase
static volatile int dsp_pump_enable = 0
static volatile uint32_t dsp_work_tokens = 0
static int16_t dsp_swq_x[DSP_SWQ_LEN]
static int16_t dsp_swq_y[DSP_SWQ_LEN]
static unsigned dsp_swq_r = 0
static unsigned dsp_swq_w = 0
static unsigned dsp_swq_count = 0
static kiss_fft_cpx fft_in[FFT_MAX_N]
static kiss_fft_cpx fft_out[FFT_MAX_N]
static uint8_t fft_cfg_mem[FFT_CFG_MAX_BYTES]
static uint32_t fft_fs_hz = 10000u
static volatile uint32_t ce_ticks = 0
static int16_t track_samples[TRACKQ_CHANNELS][FFT_MAX_N]
static struct trackq_state trackq[TRACKQ_CHANNELS] = {{0, 0u, TRACK3_DEFAULT_N, TRACK3_DEFAULT_SETTLE, TRACK3_DEFAULT_CENTER_HZ, TRACKQ_CH1_DELTA_HZ, 0u, 0, 0}, {0, 1u, TRACK3_DEFAULT_N, TRACK3_DEFAULT_SETTLE, TRACK3_DEFAULT_CENTER_HZ, TRACKQ_CH2_DELTA_HZ, 0u, 0, 0}, {0, 2u, TRACK3_DEFAULT_N, TRACK3_DEFAULT_SETTLE, TRACK3_DEFAULT_CENTER_HZ, TRACKQ_CH3_DELTA_HZ, 0u, 0, 0},}
static uint32_t trackq_log_iteration = 0u
static const struct cmd_entry uc_tbl[]
char curr_state
uint32_t fsm_counter
uint32_t max_mag
uint32_t current_phase_inc
uint32_t max_mag_phase_inc
uint32_t shooting_phase_inc
int8_t sgn = 1
struct iq5_frame_t

Public Members

int16_t x[5]
int16_t y[5]
struct trackq_state

Public Members

int enabled
unsigned channel
unsigned n
unsigned settle
uint32_t center_hz
uint32_t delta_hz
uint32_t next_tick
int32_t filt_error_mhz
int32_t step_accum_mhz
struct ubd3_hdr

Public Members

uint32_t magic
uint32_t seq
uint32_t offset
uint32_t total

SoC-Side DSP RTL