|
|
@@ -143,10 +143,10 @@ typedef struct |
|
|
volatile uint8_t generatorComplete; |
|
|
volatile uint8_t generatorComplete; |
|
|
} PLSR_PROFILE_QUEUE; |
|
|
} PLSR_PROFILE_QUEUE; |
|
|
|
|
|
|
|
|
/* A WAIT_TIME boundary is a cold start, but its planner work is predictable |
|
|
|
|
|
while the source segment is still running. Build that next stream in the |
|
|
|
|
|
inactive queue bank and publish it only after the startup horizon is ready. |
|
|
|
|
|
The boundary path then contains no planner loop. */ |
|
|
|
|
|
|
|
|
/* WAIT_TIME and WAIT_SIGNAL boundaries are cold starts, but their planner |
|
|
|
|
|
work is predictable while the source segment is still running or waiting. |
|
|
|
|
|
Build that next stream in the inactive queue bank and publish it only after |
|
|
|
|
|
the startup horizon is ready. The release path then has no planner loop. */ |
|
|
typedef struct |
|
|
typedef struct |
|
|
{ |
|
|
{ |
|
|
PLSR_PROFILE_ENTRY firstRun; |
|
|
PLSR_PROFILE_ENTRY firstRun; |
|
|
@@ -313,6 +313,8 @@ static volatile uint32_t PlsrSegmentElapsedMs; |
|
|
static volatile uint32_t PlsrWaitElapsedMs; |
|
|
static volatile uint32_t PlsrWaitElapsedMs; |
|
|
static volatile uint8_t PlsrExtPreviousLevel; |
|
|
static volatile uint8_t PlsrExtPreviousLevel; |
|
|
static volatile uint8_t PlsrExtEdgePending; |
|
|
static volatile uint8_t PlsrExtEdgePending; |
|
|
|
|
|
static volatile uint8_t PlsrWaitSignalArmedMask; |
|
|
|
|
|
static volatile uint8_t PlsrWaitSignalPendingMask; |
|
|
static volatile uint8_t PlsrStopRequested; |
|
|
static volatile uint8_t PlsrStopRequested; |
|
|
static volatile uint8_t PlsrStopPulsesRemaining; |
|
|
static volatile uint8_t PlsrStopPulsesRemaining; |
|
|
static volatile uint8_t PlsrAbStopArmed; |
|
|
static volatile uint8_t PlsrAbStopArmed; |
|
|
@@ -379,6 +381,9 @@ static void PlsrEnterErrorIfEpoch(PLSR_ERROR error, |
|
|
static void PlsrMarkPersistenceDirty(uint16_t delayMs); |
|
|
static void PlsrMarkPersistenceDirty(uint16_t delayMs); |
|
|
static void PlsrCheckpointPosition(uint8_t wasBusy); |
|
|
static void PlsrCheckpointPosition(uint8_t wasBusy); |
|
|
static void PlsrPollPositionCheckpoint(void); |
|
|
static void PlsrPollPositionCheckpoint(void); |
|
|
|
|
|
static void PlsrArmWaitSignal(uint8_t inputSelection); |
|
|
|
|
|
static void PlsrDisarmWaitSignal(void); |
|
|
|
|
|
static uint8_t PlsrWaitSignalDetected(uint8_t inputSelection); |
|
|
static PLSR_PLATFORM_QUEUE_RESULT PlsrTryContinuousHandoff(void); |
|
|
static PLSR_PLATFORM_QUEUE_RESULT PlsrTryContinuousHandoff(void); |
|
|
static uint8_t PlsrPrepareShortProfile(PLSR_SHORT_PROFILE *profile, |
|
|
static uint8_t PlsrPrepareShortProfile(PLSR_SHORT_PROFILE *profile, |
|
|
uint8_t segmentNumber, |
|
|
uint8_t segmentNumber, |
|
|
@@ -2360,8 +2365,10 @@ static void PlsrServiceTimedStartPreparation(void) |
|
|
sourceSegment = PlsrCurrentSegment; |
|
|
sourceSegment = PlsrCurrentSegment; |
|
|
if ((sourceSegment == 0U) |
|
|
if ((sourceSegment == 0U) |
|
|
|| (sourceSegment > PlsrActiveConfig.segmentCount) |
|
|
|| (sourceSegment > PlsrActiveConfig.segmentCount) |
|
|
|| (PlsrActiveConfig.segments[sourceSegment - 1U].waitType |
|
|
|
|
|
!= PLSR_WAIT_TIME)) |
|
|
|
|
|
|
|
|
|| ((PlsrActiveConfig.segments[sourceSegment - 1U].waitType |
|
|
|
|
|
!= PLSR_WAIT_TIME) |
|
|
|
|
|
&& (PlsrActiveConfig.segments[sourceSegment - 1U].waitType |
|
|
|
|
|
!= PLSR_WAIT_SIGNAL))) |
|
|
{ |
|
|
{ |
|
|
PlsrInvalidateTimedStartLocked(); |
|
|
PlsrInvalidateTimedStartLocked(); |
|
|
PlsrPlatformExitCritical(criticalState); |
|
|
PlsrPlatformExitCritical(criticalState); |
|
|
@@ -3293,6 +3300,7 @@ static uint8_t PlsrStartSegment(uint8_t segmentNumber, |
|
|
{ |
|
|
{ |
|
|
return 0U; |
|
|
return 0U; |
|
|
} |
|
|
} |
|
|
|
|
|
PlsrDisarmWaitSignal(); |
|
|
|
|
|
|
|
|
criticalState = PlsrPlatformEnterCritical(); |
|
|
criticalState = PlsrPlatformEnterCritical(); |
|
|
position = PlsrPosition; |
|
|
position = PlsrPosition; |
|
|
@@ -3445,6 +3453,7 @@ static void PlsrPollPositionCheckpoint(void) |
|
|
|
|
|
|
|
|
static void PlsrFinishCompleted(void) |
|
|
static void PlsrFinishCompleted(void) |
|
|
{ |
|
|
{ |
|
|
|
|
|
PlsrDisarmWaitSignal(); |
|
|
PlsrPlatformStopPulse((uint8_t)PlsrActiveConfig.pulseOutput); |
|
|
PlsrPlatformStopPulse((uint8_t)PlsrActiveConfig.pulseOutput); |
|
|
PlsrRemainingPulses = 0UL; |
|
|
PlsrRemainingPulses = 0UL; |
|
|
PlsrPulseActive = 0U; |
|
|
PlsrPulseActive = 0U; |
|
|
@@ -3482,6 +3491,7 @@ static void PlsrFinishCompleted(void) |
|
|
|
|
|
|
|
|
static void PlsrFinishStopped(void) |
|
|
static void PlsrFinishStopped(void) |
|
|
{ |
|
|
{ |
|
|
|
|
|
PlsrDisarmWaitSignal(); |
|
|
PlsrDiagnosticFinishSegment(0U); |
|
|
PlsrDiagnosticFinishSegment(0U); |
|
|
PlsrPlatformStopPulse((uint8_t)PlsrActiveConfig.pulseOutput); |
|
|
PlsrPlatformStopPulse((uint8_t)PlsrActiveConfig.pulseOutput); |
|
|
PlsrRemainingPulses = 0UL; |
|
|
PlsrRemainingPulses = 0UL; |
|
|
@@ -3520,6 +3530,7 @@ static void PlsrFinishStopped(void) |
|
|
|
|
|
|
|
|
static void PlsrEnterError(PLSR_ERROR error) |
|
|
static void PlsrEnterError(PLSR_ERROR error) |
|
|
{ |
|
|
{ |
|
|
|
|
|
PlsrDisarmWaitSignal(); |
|
|
PlsrDiagnosticFinishSegment(0U); |
|
|
PlsrDiagnosticFinishSegment(0U); |
|
|
PlsrPlatformStopPulse((uint8_t)PlsrActiveConfig.pulseOutput); |
|
|
PlsrPlatformStopPulse((uint8_t)PlsrActiveConfig.pulseOutput); |
|
|
PlsrRemainingPulses = 0UL; |
|
|
PlsrRemainingPulses = 0UL; |
|
|
@@ -4461,6 +4472,82 @@ static PLSR_PLATFORM_QUEUE_RESULT PlsrTryContinuousHandoff(void) |
|
|
return PLSR_PLATFORM_QUEUE_APPLIED; |
|
|
return PLSR_PLATFORM_QUEUE_APPLIED; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* EXTI only records a WAIT edge. Motion state transitions and timer startup |
|
|
|
|
|
remain in the task context. The armed mask prevents an edge from an idle |
|
|
|
|
|
or unrelated input from releasing a later segment. */ |
|
|
|
|
|
void PlsrWaitInputExtiIrq(uint8_t inputSelection) |
|
|
|
|
|
{ |
|
|
|
|
|
uint8_t bit; |
|
|
|
|
|
|
|
|
|
|
|
if (inputSelection > 1U) |
|
|
|
|
|
{ |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
bit = (uint8_t)(1U << inputSelection); |
|
|
|
|
|
if ((PlsrWaitSignalArmedMask & bit) != 0U) |
|
|
|
|
|
{ |
|
|
|
|
|
PlsrWaitSignalPendingMask |= bit; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void PlsrArmWaitSignal(uint8_t inputSelection) |
|
|
|
|
|
{ |
|
|
|
|
|
uint32_t criticalState; |
|
|
|
|
|
uint8_t bit; |
|
|
|
|
|
|
|
|
|
|
|
if (inputSelection > 1U) |
|
|
|
|
|
{ |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
bit = (uint8_t)(1U << inputSelection); |
|
|
|
|
|
criticalState = PlsrPlatformEnterCritical(); |
|
|
|
|
|
PlsrWaitSignalPendingMask = 0U; |
|
|
|
|
|
PlsrWaitSignalArmedMask = bit; |
|
|
|
|
|
PlsrPlatformExitCritical(criticalState); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void PlsrDisarmWaitSignal(void) |
|
|
|
|
|
{ |
|
|
|
|
|
uint32_t criticalState = PlsrPlatformEnterCritical(); |
|
|
|
|
|
|
|
|
|
|
|
PlsrWaitSignalArmedMask = 0U; |
|
|
|
|
|
PlsrWaitSignalPendingMask = 0U; |
|
|
|
|
|
PlsrPlatformExitCritical(criticalState); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static uint8_t PlsrWaitSignalDetected(uint8_t inputSelection) |
|
|
|
|
|
{ |
|
|
|
|
|
uint32_t criticalState; |
|
|
|
|
|
uint8_t bit; |
|
|
|
|
|
|
|
|
|
|
|
if (inputSelection > 1U) |
|
|
|
|
|
{ |
|
|
|
|
|
return 0U; |
|
|
|
|
|
} |
|
|
|
|
|
bit = (uint8_t)(1U << inputSelection); |
|
|
|
|
|
criticalState = PlsrPlatformEnterCritical(); |
|
|
|
|
|
if ((PlsrWaitSignalPendingMask & bit) != 0U) |
|
|
|
|
|
{ |
|
|
|
|
|
PlsrWaitSignalPendingMask &= (uint8_t)~bit; |
|
|
|
|
|
PlsrWaitSignalArmedMask &= (uint8_t)~bit; |
|
|
|
|
|
PlsrPlatformExitCritical(criticalState); |
|
|
|
|
|
return 1U; |
|
|
|
|
|
} |
|
|
|
|
|
PlsrPlatformExitCritical(criticalState); |
|
|
|
|
|
|
|
|
|
|
|
/* Preserve the original level semantics: a signal already high when the |
|
|
|
|
|
segment enters WAIT must release it even though no new EXTI edge occurs. */ |
|
|
|
|
|
if (PlsrPlatformReadInput(inputSelection) != 0U) |
|
|
|
|
|
{ |
|
|
|
|
|
criticalState = PlsrPlatformEnterCritical(); |
|
|
|
|
|
PlsrWaitSignalPendingMask &= (uint8_t)~bit; |
|
|
|
|
|
PlsrWaitSignalArmedMask &= (uint8_t)~bit; |
|
|
|
|
|
PlsrPlatformExitCritical(criticalState); |
|
|
|
|
|
return 1U; |
|
|
|
|
|
} |
|
|
|
|
|
return 0U; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
static void PlsrHandleBoundary(uint8_t extEdge) |
|
|
static void PlsrHandleBoundary(uint8_t extEdge) |
|
|
{ |
|
|
{ |
|
|
const PLSR_SEGMENT_CONFIG *segment; |
|
|
const PLSR_SEGMENT_CONFIG *segment; |
|
|
@@ -4550,14 +4637,13 @@ static void PlsrHandleBoundary(uint8_t extEdge) |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case PLSR_WAIT_SIGNAL: |
|
|
case PLSR_WAIT_SIGNAL: |
|
|
if (PlsrPlatformReadInput((uint8_t)PlsrActiveConfig.waitInput) != 0U) |
|
|
|
|
|
|
|
|
PlsrRunStatus = PLSR_STATUS_WAITING; |
|
|
|
|
|
PlsrArmWaitSignal((uint8_t)PlsrActiveConfig.waitInput); |
|
|
|
|
|
if (PlsrWaitSignalDetected( |
|
|
|
|
|
(uint8_t)PlsrActiveConfig.waitInput) != 0U) |
|
|
{ |
|
|
{ |
|
|
PlsrTransitionToNext(0U); |
|
|
PlsrTransitionToNext(0U); |
|
|
} |
|
|
} |
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
PlsrRunStatus = PLSR_STATUS_WAITING; |
|
|
|
|
|
} |
|
|
|
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case PLSR_ACT_TIME: |
|
|
case PLSR_ACT_TIME: |
|
|
@@ -4634,7 +4720,8 @@ static void PlsrPollWaiting(uint8_t extEdge) |
|
|
} |
|
|
} |
|
|
break; |
|
|
break; |
|
|
case PLSR_WAIT_SIGNAL: |
|
|
case PLSR_WAIT_SIGNAL: |
|
|
if (PlsrPlatformReadInput((uint8_t)PlsrActiveConfig.waitInput) != 0U) |
|
|
|
|
|
|
|
|
if (PlsrWaitSignalDetected( |
|
|
|
|
|
(uint8_t)PlsrActiveConfig.waitInput) != 0U) |
|
|
{ |
|
|
{ |
|
|
PlsrTransitionToNext(0U); |
|
|
PlsrTransitionToNext(0U); |
|
|
} |
|
|
} |
|
|
@@ -4786,6 +4873,8 @@ uint8_t PlsrInit(void) |
|
|
PlsrSegmentClockStarted = 0U; |
|
|
PlsrSegmentClockStarted = 0U; |
|
|
PlsrExtPreviousLevel = 0U; |
|
|
PlsrExtPreviousLevel = 0U; |
|
|
PlsrExtEdgePending = 0U; |
|
|
PlsrExtEdgePending = 0U; |
|
|
|
|
|
PlsrWaitSignalArmedMask = 0U; |
|
|
|
|
|
PlsrWaitSignalPendingMask = 0U; |
|
|
PlsrStopRequested = 0U; |
|
|
PlsrStopRequested = 0U; |
|
|
PlsrStopPulsesRemaining = 0U; |
|
|
PlsrStopPulsesRemaining = 0U; |
|
|
PlsrAbStopArmed = 0U; |
|
|
PlsrAbStopArmed = 0U; |
|
|
@@ -4995,6 +5084,7 @@ static void PlsrExecuteClear(void) |
|
|
{ |
|
|
{ |
|
|
uint32_t criticalState; |
|
|
uint32_t criticalState; |
|
|
|
|
|
|
|
|
|
|
|
PlsrDisarmWaitSignal(); |
|
|
criticalState = PlsrPlatformEnterCritical(); |
|
|
criticalState = PlsrPlatformEnterCritical(); |
|
|
PlsrPosition = 0L; |
|
|
PlsrPosition = 0L; |
|
|
PlsrPositionValid = 1U; |
|
|
PlsrPositionValid = 1U; |
|
|
|