Добавить общие графики, декодер KONOR и порт STM32 bxCAN

This commit is contained in:
2026-09-04 12:22:17 +03:00
parent af82687e42
commit e163d9ba55
51 changed files with 5040 additions and 15 deletions

View File

@@ -10,7 +10,7 @@
* Транспорт ProtoCAN (MsgType = 0b0011) кладёт в MsgBody адрес первого
* регистра, а в данные - до 4 регистров подряд, младшим байтом вперёд.
* Это ровно то, что делает PROTOCAN_SEND_GENERAL_ADDRESS_SPACE()
* в SETCAN/Src/protocan.c, поэтому обмен совместим с существующими
* в ports/stm32-bxcan/protocan.c, поэтому обмен совместим с существующими
* устройствами.
*
* Запрос на чтение кодируется кадром GAS с DLC = 0: в исходном коде

View File

@@ -2,7 +2,7 @@
* @file pcan_id.h
* @brief Упаковка и разбор 29-битного идентификатора ProtoCAN.
*
* Раскладка (соответствует ProtoCanId_t из SETCAN/Inc/protocan.h):
* Раскладка (ProtoCanId_t из ports/stm32-bxcan/protocan.h, бывший SETCAN):
*
* биты 28 Priority
* 27 Route

View File

@@ -0,0 +1,35 @@
/** @file set_plot.h
* @brief Toolkit-independent plot interaction math shared by JNI and ctypes.
* Coordinates are doubles in the caller's units. No allocation or global state.
*/
#ifndef SET_PLOT_H
#define SET_PLOT_H
#include "pcan_abi.h"
#ifdef __cplusplus
extern "C" {
#endif
enum set_plot_operation {
SET_PLOT_TRANSFORM = 0, /* x,y,w,h, zoomX,zoomY, panX,panY, focusX,focusY -> x,y,w,h */
SET_PLOT_AXIS = 1, /* deltaX,deltaY,slop -> 0=none, 1=X, 2=Y */
SET_PLOT_FRACTION = 2, /* value,low,high,inverted -> fraction (not clamped) */
SET_PLOT_VALUE = 3, /* fraction,low,high,inverted -> value (not clamped) */
SET_PLOT_DRAG = 4, /* initial,deltaPixels,length,low,high,inverted -> clamped value */
SET_PLOT_TICK_STEP = 5, /* range,lengthPixels -> nice step */
SET_PLOT_DELTA = 6 /* A,B,multiplier -> (B-A)*multiplier */
};
/** Version of this plot ABI, independently of the transport ABI. */
PCAN_ABI_API uint32_t set_plot_abi_version(void);
/** Evaluates one operation. Returns output count, or 0 for invalid arguments.
* TRANSFORM rejects malformed viewports; invalid gesture values return the
* unchanged viewport. Zoom is restricted to 1..128, with focus anchoring.
* Screen fractions increase downwards; set inverted=1 for the Y value axis.
*/
PCAN_ABI_API size_t set_plot_eval(uint32_t operation, const double *input,
size_t count, double *output, size_t capacity);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,34 @@
/** Shared host-side FFT for Android/JNI and desktop/ctypes; no GUI dependencies. */
#ifndef SET_SPECTRUM_H
#define SET_SPECTRUM_H
#include "pcan_abi.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SET_SPECTRUM_MAX 16384U
enum { SET_WINDOW_RECT, SET_WINDOW_HANN, SET_WINDOW_HAMMING, SET_WINDOW_BLACKMAN, SET_WINDOW_FLATTOP };
enum { SET_FILTER_NONE, SET_FILTER_LOW_PASS, SET_FILTER_HIGH_PASS, SET_FILTER_BAND_PASS, SET_FILTER_NOTCH };
enum { SET_SPECTRUM_OK, SET_SPECTRUM_SHORT, SET_SPECTRUM_INVALID, SET_SPECTRUM_TIMING,
SET_SPECTRUM_CUTOFF, SET_SPECTRUM_MEMORY };
/** Analyze the last power-of-two block (16 <= N <= max_size).
* times are seconds, strictly increasing; values must be finite. Fs is measured
* from timestamps, never taken from the requested acquisition rate. Interval
* deviations >50% of the mean are rejected; smaller jitter is linearly resampled.
* Filter: second-order Butterworth LP/HP, their cascade for band pass, notch Q=30.
* low_hz: HP/band lower cutoff or notch center; high_hz: LP/band upper cutoff.
* Each block starts the causal filters at steady state for its first sample.
* Processing order: resample, optional mean removal, filter, periodic window, FFT.
* Output: one-sided PEAK amplitude, normalized by window sum, DC/Nyquist not doubled.
* Caller supplies max_size/2+1 amplitudes; meta = {N, Fs, max relative jitter}.
* Inputs are immutable. Scratch memory is bounded by 2*N doubles, allocated here.
*/
PCAN_ABI_API int set_spectrum_analyze(const double *times, const double *values, size_t count,
size_t max_size, int window, int filter, double low_hz, double high_hz, int remove_mean,
double *amplitudes, size_t capacity, double *meta);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,54 @@
/** @file set_trends.h
* @brief Shared GUI trend decoding and GUI v1 GAS subscription payloads.
* No transport, rendering, allocation or global state. JNI/ctypes call the
* same exported functions; flags use the existing AA55 bridge ABI.
*/
#ifndef SET_TRENDS_H
#define SET_TRENDS_H
#include "pcan_abi.h"
#ifdef __cplusplus
extern "C" {
#endif
#define SET_TREND_CAN_GAS 1U
#define SET_TREND_CAN_RAW 2U
#define SET_TREND_NO_VALUE INT32_MIN
#define SET_TREND_WATCH_MAX 64U
/** Convert one wire word, without implementation-defined signed casts. */
PCAN_ABI_API int32_t set_trend_word_value(uint16_t word, uint8_t is_signed);
/** Return a decoded value or SET_TREND_NO_VALUE for a nonmatching/invalid frame.
* GAS requires Route=FROM_DEVICE, exact DeviceType/DeviceID, and an even DLC.
* TX echoes, RTR and error frames are always ignored. RAW offset is in bytes.
*/
PCAN_ABI_API int32_t set_trend_can_value(
uint8_t source, uint32_t address, uint8_t device_type, uint8_t device,
uint8_t byte_offset, uint8_t extended, uint8_t is_signed,
uint32_t can_id, uint8_t flags, const uint8_t *data, size_t size);
/** Encode period:u16 + count:u16 + addresses[count]:u16, little-endian.
* A zero period/count is an unsubscribe. Returns 0 on invalid arguments.
*/
PCAN_ABI_API size_t set_trend_watch_request(
uint16_t period_ms, const uint16_t *addresses, size_t count,
uint8_t *output, size_t capacity);
/** Accept only an exact acknowledgement of the entire ordered subscription.
* The device may omit unknown addresses. Partial acceptance must NOT be used:
* its acknowledgement has no address list, so index-to-address mapping is lost.
*/
PCAN_ABI_API int set_trend_watch_ack(
const uint8_t *payload, size_t size, uint16_t period_ms, size_t count);
/** Decode timestamp:u32 + count:u16 + words. Returns count, or -1 on error.
* Timestamp is device-local; GUI plot clocks should use their own monotonic time.
*/
PCAN_ABI_API int set_trend_watch_values(
const uint8_t *payload, size_t size, uint16_t *words, size_t capacity);
#ifdef __cplusplus
}
#endif
#endif