#ifndef PLSR_JOB_H #define PLSR_JOB_H #include "plsr_position.h" #include "plsr_types.h" #include #ifdef __cplusplus extern "C" { #endif #define PLSR_MAX_SEGMENTS (100U) #define PLSR_OUTPUT_MODE_FROM_SFD (0xFFU) #define PLSR_FREQUENCY_MIN_HZ (1UL) #define PLSR_FREQUENCY_MAX_HZ (100000UL) typedef enum { PLSR_DEVICE_D = 0, PLSR_DEVICE_HD, PLSR_DEVICE_FD, PLSR_DEVICE_X, PLSR_DEVICE_M, PLSR_DEVICE_HM } PLSR_DEVICE_TYPE; typedef uint8_t (*PLSR_VALIDATE_WORDS_FN)(void *context, PLSR_DEVICE_TYPE device, uint32_t firstAddress, uint32_t wordCount); typedef uint8_t (*PLSR_READ_WORD_FN)(void *context, PLSR_DEVICE_TYPE device, uint32_t address, uint16_t *value); typedef uint8_t (*PLSR_READ_DWORD_FN)(void *context, PLSR_DEVICE_TYPE device, uint32_t address, int32_t *value); typedef uint8_t (*PLSR_READ_BIT_FN)(void *context, PLSR_DEVICE_TYPE device, uint32_t address, uint8_t *value); typedef struct { void *context; PLSR_VALIDATE_WORDS_FN validateWords; PLSR_READ_WORD_FN readWord; /* Optional atomic low-word/high-word snapshot. A 0.1ms live-frequency * source should provide this callback to prevent torn 32-bit reads. */ PLSR_READ_DWORD_FN readDword; PLSR_READ_BIT_FN readBit; } PLSR_DATA_SOURCE; typedef struct { PLSR_DEVICE_TYPE device; uint32_t address; } PLSR_DATA_REF; typedef enum { PLSR_OPERAND_CONSTANT = 0, PLSR_OPERAND_DATA } PLSR_OPERAND_TYPE; typedef struct { PLSR_OPERAND_TYPE type; PLSR_DATA_REF data; int32_t constant; } PLSR_VALUE_OPERAND; typedef struct { uint32_t sequence; /* The source context must remain valid while the queued/running job exists. */ PLSR_DATA_SOURCE source; PLSR_DATA_REF s0; PLSR_DATA_REF s1; PLSR_VALUE_OPERAND s2; uint8_t dAxis; uint8_t outputModeOverride; } PLSR_CALL; typedef enum { PLSR_WAIT_PULSE_COMPLETE = 0, PLSR_WAIT_TIME, PLSR_WAIT_SIGNAL, PLSR_WAIT_ACT_TIME, PLSR_WAIT_EXT, PLSR_WAIT_EXT_OR_COMPLETE } PLSR_WAIT_CONDITION; typedef enum { PLSR_VALUE_CONSTANT = 0, PLSR_VALUE_D, PLSR_VALUE_HD, PLSR_VALUE_FD, PLSR_VALUE_X, PLSR_VALUE_M, PLSR_VALUE_HM } PLSR_VALUE_SOURCE; #define PLSR_SEGMENT_FLAG_ZERO_PULSE (1U << 0U) #define PLSR_SEGMENT_FLAG_DEFAULT_SPEED (1U << 1U) #define PLSR_SEGMENT_FLAG_SPEED_CLAMPED (1U << 2U) #define PLSR_SEGMENT_FLAG_SELF_LOOP (1U << 3U) typedef struct { uint32_t targetFrequency; int32_t pulseOrTarget; int32_t waitValueOrAddress; int32_t jumpValueOrAddress; uint8_t waitCondition; uint8_t waitSource; uint8_t jumpSource; uint8_t flags; } PLSR_SEGMENT_SNAPSHOT; typedef struct { uint32_t defaultSpeed; uint32_t maximumSpeed; uint32_t startSpeed; uint32_t stopSpeed; uint32_t zrnHighSpeed; uint32_t zrnCrawlSpeed; uint16_t accelerationMs; uint16_t decelerationMs; uint16_t gapAccelerationMs; uint16_t directionDelayMs; uint8_t curveMode; uint8_t follow; uint8_t feedforwardPercent; uint8_t refreshCode; } PLSR_S2_SNAPSHOT; typedef struct { int64_t positiveSoftLimitPulses; int64_t negativeSoftLimitPulses; uint8_t softLimitEnabled; uint8_t positiveInputPoint; uint8_t negativeInputPoint; uint8_t positiveInputActiveLow; uint8_t negativeInputActiveLow; } PLSR_LIMIT_SNAPSHOT; typedef struct { PLSR_DATA_SOURCE source; PLSR_DATA_REF s0; PLSR_DATA_REF s1; PLSR_S2_SNAPSHOT s2; PLSR_EQUIVALENT_CONFIG equivalent; PLSR_LIMIT_SNAPSHOT limits; PLSR_SEGMENT_SNAPSHOT segments[PLSR_MAX_SEGMENTS]; uint16_t positiveBacklashPulses; uint16_t negativeBacklashPulses; uint32_t inputDefaultSpeed; uint32_t inputMaximumSpeed; uint32_t timerClockHz; uint32_t pairedTimerClockHz; uint16_t segmentCount; uint16_t startSegment; uint8_t dAxis; uint8_t s2Set; uint8_t positioningMode; uint8_t outputMode; uint8_t directionPoint; uint8_t directionNegativeLogic; uint8_t initialDirectionPositive; uint8_t speedClamped; uint8_t hasSelfLoop; } PLSR_JOB_SNAPSHOT; typedef enum { PLSR_PARSE_BLOCK_NONE = 0, PLSR_PARSE_BLOCK_S0, PLSR_PARSE_BLOCK_S1, PLSR_PARSE_BLOCK_S2, PLSR_PARSE_BLOCK_OUTPUT, PLSR_PARSE_BLOCK_POSITION } PLSR_PARSE_BLOCK; typedef struct { PLSR_RESULT result; PLSR_PARSE_BLOCK block; uint32_t address; int32_t value; uint16_t segment; } PLSR_PARSE_DETAIL; typedef struct { int64_t logicalPosition; uint8_t positionValid; } PLSR_PARSE_CONTEXT; PLSR_RESULT PlsrBuildJobSnapshot(const PLSR_CALL *call, const PLSR_PARSE_CONTEXT *context, PLSR_JOB_SNAPSHOT *snapshot, PLSR_PARSE_DETAIL *detail); PLSR_RESULT PlsrResolveLiveFrequency(const PLSR_JOB_SNAPSHOT *snapshot, uint16_t segment, uint32_t *frequency, uint8_t *clamped); PLSR_RESULT PlsrReadLiveFrequencyRaw(const PLSR_JOB_SNAPSHOT *snapshot, uint16_t segment, int32_t *rawFrequency); PLSR_RESULT PlsrCalculateTimerDivider(uint32_t timerClockHz, uint32_t frequencyHz, uint16_t *psc, uint16_t *arr); #ifdef __cplusplus } #endif #endif /* PLSR_JOB_H */