#ifndef PLSR_PLANNER_H #define PLSR_PLANNER_H #include "plsr_platform.h" #include 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; uint32_t cruiseHz; uint32_t exitHz; uint32_t pulseBudget; uint32_t referenceSpeedHz; uint16_t accelerationTimeMs; uint16_t decelerationTimeMs; uint16_t curveMode; uint8_t pulseOutput; PLSR_BOUNDARY_ACTION boundary; } PLSR_MOTION_BLOCK; typedef struct { PLSR_PLATFORM_TIMER_SETTING setting; uint32_t requestedFrequencyHz; uint32_t repeatCount; } 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; uint32_t startHz; uint32_t peakHz; uint32_t endHz; uint32_t entryPulses; uint32_t steadyPulses; uint32_t exitPulses; uint32_t generatedPulses; uint32_t rampRelativePulse; uint32_t rampPulseCount; uint32_t rampFromHz; uint32_t rampToHz; uint32_t rampDurationMs; uint32_t lastRampHz; uint64_t rampTotalAreaQ32; uint64_t rampAreaStepQ32; uint64_t rampTargetAreaQ32; uint64_t rampBoundaryQ32; uint64_t rampActualTimeQ32; uint64_t rampLastPhaseStepQ32; uint64_t rampFirstBoundaryQ32; uint64_t rampSecondBoundaryQ32; uint32_t rampAreaRemainder; uint32_t rampRemainderAccumulator; uint8_t rampKind; uint8_t clipped; uint8_t active; } PLSR_PLANNER_CONTEXT; 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 */