61 lines
1.7 KiB
C
61 lines
1.7 KiB
C
/* SPDX-License-Identifier: GPL-2.0 OR MIT */
|
||
/*
|
||
* Affine maps from master TSF to each radio TSF: t_radio ≈ α·t_master + β.
|
||
* One master among N radios → (N−1) fitted maps + identity for the master.
|
||
*/
|
||
|
||
#ifndef TSF_AFFINE_H
|
||
#define TSF_AFFINE_H
|
||
|
||
#include <stdbool.h>
|
||
#include <stddef.h>
|
||
#include <stdint.h>
|
||
|
||
#define TSF_AFFINE_MAX_RADIOS 32
|
||
|
||
struct tsf_affine_map {
|
||
double alpha;
|
||
double beta;
|
||
uint64_t anchor_master;
|
||
uint64_t anchor_radio;
|
||
int have_anchor;
|
||
/* Window of (dm, dr) with dm = master - anchor_master, dr = radio - anchor_radio */
|
||
int64_t *dm;
|
||
int64_t *dr;
|
||
size_t win_cap;
|
||
size_t win_count;
|
||
size_t win_pos; /* next write index */
|
||
};
|
||
|
||
struct tsf_affine_pool {
|
||
unsigned int n_radios;
|
||
unsigned int master_idx;
|
||
struct tsf_affine_map maps[TSF_AFFINE_MAX_RADIOS];
|
||
};
|
||
|
||
int tsf_affine_pool_init(struct tsf_affine_pool *p, unsigned int n_radios,
|
||
unsigned int master_idx, size_t window_cap);
|
||
|
||
void tsf_affine_pool_fini(struct tsf_affine_pool *p);
|
||
|
||
/* Push one simultaneous pair (same physical instant). Ignored for master_idx. */
|
||
void tsf_affine_pool_sample(struct tsf_affine_pool *p, unsigned int radio_idx,
|
||
uint64_t master_tsf, uint64_t radio_tsf);
|
||
|
||
/*
|
||
* Given master TSF, fill out_radio[i] for all i.
|
||
* Master index: out_radio[master_idx] == master_tsf exactly.
|
||
*/
|
||
void tsf_affine_pool_master_to_all(const struct tsf_affine_pool *p,
|
||
uint64_t master_tsf,
|
||
uint64_t out_radio[TSF_AFFINE_MAX_RADIOS]);
|
||
|
||
/* Single radio; returns false if radio_idx invalid or map not yet usable. */
|
||
bool tsf_affine_pool_master_to_radio(const struct tsf_affine_pool *p,
|
||
unsigned int radio_idx, uint64_t master_tsf,
|
||
uint64_t *out_radio_tsf);
|
||
|
||
bool tsf_affine_map_ready(const struct tsf_affine_map *m);
|
||
|
||
#endif
|