Add shared waveform processing, generation and firmware image support

This commit is contained in:
2026-09-27 01:45:08 +03:00
parent 2ad29e7ffd
commit cc22c803d1
36 changed files with 2591 additions and 61 deletions

View File

@@ -0,0 +1,24 @@
#ifndef SET_FIRMWARE_IMAGE_H
#define SET_FIRMWARE_IMAGE_H
#include "pcan_abi.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Caller-owned workspace; the parser never allocates memory or accesses files. */
typedef struct { uint32_t address; uint8_t value; } firmware_hex_cell_t;
enum { FW_HEX_OK, FW_HEX_FORMAT, FW_HEX_CHECKSUM, FW_HEX_RECORD,
FW_HEX_EOF, FW_HEX_OVERLAP, FW_HEX_RANGE, FW_HEX_CAPACITY,
FW_HEX_PREFIX, FW_HEX_DIGITS, FW_HEX_LENGTH };
/* Strict HEX: reject any overlap and any non-whitespace after EOF. On failure
* count is zero. Cells are sorted by address only on successful completion. */
PCAN_ABI_API int firmware_hex_parse(const char *text, size_t length,
firmware_hex_cell_t *cells, size_t capacity, size_t max_records,
size_t *count, size_t *error_line);
/* Return one contiguous segment starting at offset in a successfully parsed
* workspace; the caller uses its address and copies its values into its model. */
PCAN_ABI_API size_t firmware_hex_segment_size(const firmware_hex_cell_t *cells,
size_t count, size_t offset);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,24 @@
/** @file set_signal.h Portable interpolation and DAC waveform preparation. */
#ifndef SET_SIGNAL_H
#define SET_SIGNAL_H
#include "pcan_abi.h"
#ifdef __cplusplus
extern "C" {
#endif
enum { SET_SIGNAL_POLYNOMIAL, SET_SIGNAL_LINEAR, SET_SIGNAL_PCHIP, SET_SIGNAL_SPLINE };
/* Caller-owned workspace: at least 14*count+128 doubles. No heap or globals.
* Inputs may be unsorted; duplicate times are averaged. No extrapolation.
* meta[0..2] = original count, unique count, RMSE at original measurements.
* endpoint=1 includes the last time; 0 samples a cyclic period [first,last).
* Return: 0 success, 1 bounds, 2 nonfinite/degenerate data, 3 rank deficient. */
PCAN_ABI_API int set_signal_reconstruct(const double *x, const double *y, size_t count,
int method, unsigned degree, size_t output_count, int endpoint,
double *out_x, double *out_y, double *meta, double *work, size_t work_count);
/* Reject out-of-range voltages, never silently clip. vref must be positive.
* All input is validated before any output is written. */
PCAN_ABI_API int set_signal_dac12(const double *volts, size_t count, double vref,
uint16_t *codes);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,59 @@
/** @file set_wavegen.h Transactional table upload and cyclic DAC playback. */
#ifndef SET_WAVEGEN_H
#define SET_WAVEGEN_H
#include "pcan_abi.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SET_WAVE_MAX 4096u
#define SET_WAVE_MAX_RATE 1000000u
#define SET_WAVE_BLOCK_MAX 120u
#define SET_WAVE_BASE 0x1300u
#define SET_WAVE_DATA 0xA000u
typedef struct {
void *context;
/* Return 0 on success. Samples remain owned by state until stop returns.
* start must arrange periodic output, typically DAC + timer + DMA.
* stop must quiesce DMA before returning and set output to zero. */
int (*start)(void *, const uint16_t *, size_t, uint32_t);
void (*stop)(void *);
} set_wave_port;
typedef struct {
uint16_t *samples;
size_t capacity;
uint16_t count, received, ready, running, rate_high;
uint32_t rate;
set_wave_port port;
} set_wave_state;
void set_wave_init(set_wave_state *, uint16_t *, size_t, const set_wave_port *);
/* Atomic sample-block transfer. values=NULL builds a read; otherwise a write.
* At most 120 words: request <=249 bytes, response <=245 bytes. */
PCAN_ABI_API size_t set_wave_block_request(unsigned device,unsigned index,
const uint16_t *values,size_t count,uint8_t *out,size_t capacity);
PCAN_ABI_API int set_wave_block_response(const uint8_t *request,size_t request_size,
const uint8_t *reply,size_t reply_size,uint16_t *words,size_t capacity);
size_t set_wave_block_rtu(set_wave_state *,unsigned device,const uint8_t *,size_t,
uint8_t *,size_t);
/* Relative register callbacks for set_regmap; status=8 words, samples=4096.
* These are the same state/validation used by the legacy RTU wrapper. */
PCAN_ABI_API unsigned set_wave_read(void *,uint16_t,uint16_t,uint16_t *);
PCAN_ABI_API unsigned set_wave_write(void *,uint16_t,uint16_t);
PCAN_ABI_API unsigned set_wave_samples_read(void *,uint16_t,uint16_t,uint16_t *);
PCAN_ABI_API unsigned set_wave_samples_write(void *,uint16_t,uint16_t);
/* Caller serializes calls in the main loop. Returns complete reply size,
* 0 for unrelated/invalid frames. CRC verified before all state changes. */
size_t set_wave_rtu(set_wave_state *, unsigned device, const uint8_t *, size_t,
uint8_t *, size_t);
/* Thin host transport ABI. Operations: 0=status, 1=stop, 2=sample rate,
* 3=begin upload(count), 4=sample(index,value), 5=commit, 6=start.
* 7=read a sample(index) for verification. Return 8 or 0. */
PCAN_ABI_API size_t set_wave_request(unsigned device,unsigned operation,unsigned index,
unsigned value,uint8_t *out,size_t capacity);
/* Return 0=need more bytes, positive=word count, negative=invalid/exception.
* Validates exact echo/read shape, CRC, address and signature on status. */
PCAN_ABI_API int set_wave_response(const uint8_t *request,const uint8_t *reply,
size_t size,uint16_t *words,size_t capacity);
#ifdef __cplusplus
}
#endif
#endif