|
- #ifndef PLSR_PLANNER_H
- #define PLSR_PLANNER_H
-
- #include "plsr_platform.h"
-
- #include <stdint.h>
-
- typedef enum
- {
- PLSR_BOUNDARY_STOP = 0,
- PLSR_BOUNDARY_NEXT_FRESH,
- PLSR_BOUNDARY_NEXT_CARRY,
- PLSR_BOUNDARY_WAIT_TIME,
- PLSR_BOUNDARY_WAIT_SIGNAL,
- PLSR_BOUNDARY_WAIT_EXT,
- PLSR_BOUNDARY_JUMP,
- PLSR_BOUNDARY_EXT_CUT
- } PLSR_BOUNDARY_ACTION;
-
- /* A block is self-contained: the planner must not read live Modbus state. */
- typedef struct
- {
- uint32_t entryHz; // 本块起点频率:启动速度,或上一段 carry 过来的速度
- uint32_t cruiseHz; // 本块目标巡航频率(段频率)
- uint32_t exitHz; // 本块终点频率:停止速度,或下一段 cruise(同向连续)
- uint32_t pulseBudget; // 本块要发的脉冲总数
- uint32_t referenceSpeedHz; // 默认速度,用来折算加减速时间 T∝|Δf|/f_ref
- uint16_t accelerationTimeMs; // 从 0 爬到默认速度所配的加速时间(ms)
- uint16_t decelerationTimeMs; // 从默认速度降到 0 所配的减速时间(ms)
- uint16_t curveMode; // 0 线性,1 S 曲线,2 正弦
- uint8_t pulseOutput; // 脉冲输出通道 0..3
- PLSR_BOUNDARY_ACTION boundary; // 块结束后怎么走:停 / 下一段重起 / carry / WAIT / 跳转 / EXT切断
- } PLSR_MOTION_BLOCK;
-
- typedef struct
- {
- PLSR_PLATFORM_TIMER_SETTING setting;
- uint32_t requestedFrequencyHz;//用于诊断的频率
- uint32_t repeatCount;//这一档连续多少个脉冲。斜坡多半 1;匀速可以是剩下的全部(例如 5000)
- } PLSR_STREAM_ITEM;
-
- typedef enum
- {
- PLSR_PLANNER_OK = 0,
- PLSR_PLANNER_CLIPPED,
- PLSR_PLANNER_DONE,
- PLSR_PLANNER_INVALID
- } PLSR_PLANNER_STATUS;
-
- typedef enum
- {
- PLSR_PLANNER_PHASE_ENTRY = 0,
- PLSR_PLANNER_PHASE_STEADY,
- PLSR_PLANNER_PHASE_EXIT,
- PLSR_PLANNER_PHASE_COMPLETE
- } PLSR_PLANNER_PHASE;
-
- typedef struct
- {
- uint32_t pulseCount;
- uint32_t actualFrequencyHz;
- PLSR_PLANNER_PHASE phase;
- uint8_t deadlineInProfile;
- } PLSR_PLANNER_TIME_PREDICTION;
-
- typedef struct
- {
- PLSR_MOTION_BLOCK block; // 本块输入:起/巡/终速度、预算、加减速时间、曲线、通道
- uint64_t phasePulses; // 起点相位,已实际输出的脉冲累计,冷启动为 0
- uint32_t startHz; // 实际起始频率(appliedHz,0 抬成 1)
- uint32_t peakHz; // 实际峰值,预算不足时低于 cruise
- uint32_t endHz; // 实际终点:停止速度、carry 或 clip 后可达值
- uint32_t entryPulses; // 加速段脉冲数
- uint32_t steadyPulses; // 匀速段脉冲数,三角轮廓为 0
- uint32_t exitPulses; // 减速段脉冲数
- uint32_t generatedPulses; // 已交给调用方的脉冲总数(按脉冲计,非项数)
- uint32_t rampRelativePulse; // 当前斜坡内已走脉冲序号,0 为斜坡第一项
- uint32_t rampPulseCount; // 当前斜坡总脉冲数
- uint32_t rampFromHz; // 当前斜坡起点频率
- uint32_t rampToHz; // 当前斜坡终点频率
- uint32_t rampDurationMs; // 当前斜坡折算持续时间(ms)
- uint32_t lastRampHz; // 上一斜坡脉冲量化后的实际频率,禁止加减速倒退
- uint64_t rampTotalAreaQ32; // 当前斜坡 x=0~1 的总面积(Q32)
- uint64_t rampAreaStepQ32; // 每个脉冲的面积整数商:totalArea / N
- uint64_t rampTargetAreaQ32; // 到当前脉冲结束必须达到的累计面积
- uint64_t rampBoundaryQ32; // 上一脉冲结束时的归一化时间边界 x
- uint64_t rampActualTimeQ32; // 已按量化后 actualHz 走过的归一化时间(闭环)
- uint64_t rampLastPhaseStepQ32; // 上一脉冲相位步长,供后续预测边界
- uint64_t rampFirstBoundaryQ32; // 第 1 个斜坡脉冲的精确边界(二分)
- uint64_t rampSecondBoundaryQ32; // 第 2 个斜坡脉冲的精确边界(二分),其后改预测
- uint32_t rampAreaRemainder; // totalArea % N,余数往各脉冲面积上摊
- uint32_t rampRemainderAccumulator; // 摊余数累加器,满 N 则目标面积 +1
- uint8_t rampKind; // 0 无斜坡/匀速,1 加速,2 减速
- uint8_t clipped; // 预算不足已裁峰/终点,结果仍可执行
- uint8_t active; // 是否还可 Generate,吐完或失败清 0
- } PLSR_PLANNER_CONTEXT;
-
- #if defined(PLSR_DEBUG_TIMING) && (PLSR_DEBUG_TIMING != 0) \
- && !defined(PLSR_HOST_TEST)
- typedef struct
- {
- volatile uint32_t callCount;
- volatile uint32_t lastCycles;
- volatile uint32_t totalCycles;
- volatile uint32_t minCycles;
- volatile uint32_t maxCycles;
- } PLSR_PLANNER_TIMING_SAMPLE;
-
- typedef struct
- {
- PLSR_PLANNER_TIMING_SAMPLE begin;
- PLSR_PLANNER_TIMING_SAMPLE generate;
- PLSR_PLANNER_TIMING_SAMPLE startRamp;
- PLSR_PLANNER_TIMING_SAMPLE rampTime;
- PLSR_PLANNER_TIMING_SAMPLE rampTotalArea;
- PLSR_PLANNER_TIMING_SAMPLE rampAreaSplit;
- PLSR_PLANNER_TIMING_SAMPLE rampFirstBoundary;
- PLSR_PLANNER_TIMING_SAMPLE rampSecondBoundary;
- PLSR_PLANNER_TIMING_SAMPLE rampPredictedBoundary;
- PLSR_PLANNER_TIMING_SAMPLE rampRequestedDivide;
- PLSR_PLANNER_TIMING_SAMPLE timerSetting;
- PLSR_PLANNER_TIMING_SAMPLE rampActualDivide;
- PLSR_PLANNER_TIMING_SAMPLE rampStep;
- } PLSR_PLANNER_TIMING;
-
- extern volatile PLSR_PLANNER_TIMING PlsrPlannerTiming;
- void PlsrPlannerTimingReset(void);
- #endif
-
- #if !defined(PLSR_HOST_TEST)
- /* Target-board throughput benchmark. One benchmark run exercises the exact
- runtime calling convention (Generate capacity == 1) for a 100000-pulse
- triangular profile in each curve mode. Q16 cycle values retain fractional
- cycles without using floating point in the target. */
- typedef struct
- {
- uint32_t curveMode;
- uint32_t beginStatus;
- uint32_t completed;
- uint32_t plannedPulses;
- uint32_t generateCalls;
- uint64_t totalCycles;
- uint32_t averageCyclesPerPulseQ16;
- uint32_t minimumBlockCyclesPerPulseQ16;
- uint32_t maximumBlockCyclesPerPulseQ16;
- uint32_t estimatedPulsesPerSecond;
- uint32_t passes100k;
- } PLSR_PLANNER_BENCHMARK_RESULT;
-
- extern volatile uint32_t PlsrPlannerBenchmarkRequest;
- extern volatile uint32_t PlsrPlannerBenchmarkRunning;
- extern volatile uint32_t PlsrPlannerBenchmarkRunCount;
- extern volatile uint32_t PlsrPlannerBenchmarkCoreClockHz;
- extern volatile PLSR_PLANNER_BENCHMARK_RESULT
- PlsrPlannerBenchmarkResults[3];
-
- void PlsrPlannerBenchmarkService(void);
- #endif
-
- PLSR_PLANNER_STATUS PlsrPlannerBegin(PLSR_PLANNER_CONTEXT *context,
- const PLSR_MOTION_BLOCK *block,
- uint32_t appliedHz,
- uint64_t phasePulses);
- uint16_t PlsrPlannerGenerate(PLSR_PLANNER_CONTEXT *context,
- PLSR_STREAM_ITEM *output,
- uint16_t capacity);
- uint8_t PlsrPlannerPredictTime(
- const PLSR_PLANNER_CONTEXT *context,
- uint32_t elapsedUs,
- PLSR_PLANNER_TIME_PREDICTION *prediction);
-
- #endif /* PLSR_PLANNER_H */
|