|
|
|
@@ -327,6 +327,10 @@ static volatile uint32_t PlsrSegmentElapsedMs; |
|
|
|
static volatile uint32_t PlsrWaitElapsedMs; |
|
|
|
static volatile uint8_t PlsrExtPreviousLevel; |
|
|
|
static volatile uint8_t PlsrExtEdgePending; |
|
|
|
static volatile uint8_t PlsrExtEdgePendingSegment; |
|
|
|
static volatile uint32_t PlsrExtEdgePendingEpoch; |
|
|
|
static volatile uint8_t PlsrExtCaptureSegment; |
|
|
|
static volatile uint32_t PlsrExtCaptureEpoch; |
|
|
|
static volatile uint8_t PlsrWaitSignalArmedMask; |
|
|
|
static volatile uint8_t PlsrWaitSignalPendingMask; |
|
|
|
static volatile uint8_t PlsrStopRequested; |
|
|
|
@@ -2608,7 +2612,8 @@ static void PlsrServiceTimedStartPreparation(void) |
|
|
|
|| (PlsrLastDirectionLevel != directionLevel)) ? 1U : 0U; |
|
|
|
coldStartBoundary = ((sourceWaitType == PLSR_WAIT_TIME) |
|
|
|
|| (sourceWaitType == PLSR_WAIT_SIGNAL) |
|
|
|
|| ((sourceWaitType == PLSR_ACT_TIME) |
|
|
|
|| (((sourceWaitType == PLSR_ACT_TIME) |
|
|
|
|| (sourceWaitType == PLSR_EXT_SIGNAL)) |
|
|
|
&& (sourceWaiting != 0U))) ? 1U : 0U; |
|
|
|
if ((coldStartBoundary == 0U) && (directionChanged == 0U)) |
|
|
|
{ |
|
|
|
@@ -3431,6 +3436,8 @@ static PLSR_PLATFORM_SERVICE_RESULT PlsrTryStartPreparedTimedSegment( |
|
|
|
|
|
|
|
PlsrSegmentEpoch++; |
|
|
|
PlsrCurrentSegment = segmentNumber; |
|
|
|
PlsrExtCaptureSegment = segmentNumber; |
|
|
|
PlsrExtCaptureEpoch = PlsrSegmentEpoch; |
|
|
|
PlsrSegmentClockStarted = 0U; |
|
|
|
PlsrSegmentElapsedMs = 0UL; |
|
|
|
PlsrWaitElapsedMs = 0UL; |
|
|
|
@@ -3449,7 +3456,6 @@ static PLSR_PLATFORM_SERVICE_RESULT PlsrTryStartPreparedTimedSegment( |
|
|
|
PlsrShortProfile.nextPeriod = 0U; |
|
|
|
PlsrDirectionDelayActive = 0U; |
|
|
|
PlsrDirectionDelayRemainingMs = 0U; |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
PlsrRemainingPulses = magnitude; |
|
|
|
PlsrCountPositive = positive; |
|
|
|
PlsrActTimedCutPlanned = PlsrTimedStart.nextActTimedCut; |
|
|
|
@@ -3697,8 +3703,12 @@ static uint8_t PlsrStartSegment(uint8_t segmentNumber, |
|
|
|
magnitude = (displacement < 0) ? (uint64_t)(-displacement) |
|
|
|
: (uint64_t)displacement; |
|
|
|
|
|
|
|
criticalState = PlsrPlatformEnterCritical(); |
|
|
|
PlsrSegmentEpoch++; |
|
|
|
PlsrCurrentSegment = segmentNumber; |
|
|
|
PlsrExtCaptureSegment = segmentNumber; |
|
|
|
PlsrExtCaptureEpoch = PlsrSegmentEpoch; |
|
|
|
PlsrPlatformExitCritical(criticalState); |
|
|
|
PlsrSegmentClockStarted = 0U; |
|
|
|
PlsrSegmentElapsedMs = 0UL; |
|
|
|
PlsrWaitElapsedMs = 0UL; |
|
|
|
@@ -3725,7 +3735,6 @@ static uint8_t PlsrStartSegment(uint8_t segmentNumber, |
|
|
|
} |
|
|
|
PlsrDirectionDelayActive = 0U; |
|
|
|
PlsrDirectionDelayRemainingMs = 0U; |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
PlsrExtPreviousLevel = |
|
|
|
PlsrPlatformReadInput((uint8_t)PlsrActiveConfig.extInput); |
|
|
|
|
|
|
|
@@ -3873,6 +3882,7 @@ static void PlsrFinishCompleted(void) |
|
|
|
PlsrSegmentClockStarted = 0U; |
|
|
|
PlsrDirectionDelayActive = 0U; |
|
|
|
PlsrDirectionDelayRemainingMs = 0U; |
|
|
|
PlsrExtCaptureSegment = 0U; |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
PlsrStopRequested = 0U; |
|
|
|
PlsrStopPulsesRemaining = 0U; |
|
|
|
@@ -3913,6 +3923,7 @@ static void PlsrFinishStopped(void) |
|
|
|
PlsrSegmentClockStarted = 0U; |
|
|
|
PlsrDirectionDelayActive = 0U; |
|
|
|
PlsrDirectionDelayRemainingMs = 0U; |
|
|
|
PlsrExtCaptureSegment = 0U; |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
PlsrStopRequested = 0U; |
|
|
|
PlsrStopPulsesRemaining = 0U; |
|
|
|
@@ -3953,6 +3964,7 @@ static void PlsrEnterError(PLSR_ERROR error) |
|
|
|
PlsrSegmentClockStarted = 0U; |
|
|
|
PlsrDirectionDelayActive = 0U; |
|
|
|
PlsrDirectionDelayRemainingMs = 0U; |
|
|
|
PlsrExtCaptureSegment = 0U; |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
PlsrStopRequested = 0U; |
|
|
|
PlsrStopPulsesRemaining = 0U; |
|
|
|
@@ -4508,6 +4520,9 @@ void PlsrExecCountedSegmentBoundaryIrq(uint8_t pulseOutput, |
|
|
|
{ |
|
|
|
PLSR_COUNTED_BOUNDARY_EVENT *event; |
|
|
|
uint8_t writeIndex; |
|
|
|
uint8_t previousExtSegment; |
|
|
|
uint8_t hardwareExtPending; |
|
|
|
uint32_t previousExtEpoch; |
|
|
|
|
|
|
|
if (pulseOutput != (uint8_t)PlsrActiveConfig.pulseOutput) |
|
|
|
{ |
|
|
|
@@ -4534,6 +4549,27 @@ void PlsrExecCountedSegmentBoundaryIrq(uint8_t pulseOutput, |
|
|
|
event->nextSegment = PlsrHandoffPlan.nextSegment; |
|
|
|
event->positive = PlsrHandoffPlan.positive; |
|
|
|
event->nextActTimedCut = PlsrHandoffPlan.nextActTimedCut; |
|
|
|
previousExtSegment = PlsrExtCaptureSegment; |
|
|
|
previousExtEpoch = PlsrExtCaptureEpoch; |
|
|
|
hardwareExtPending = PlsrPlatformTakeInputExtiPending( |
|
|
|
(uint8_t)PlsrActiveConfig.extInput); |
|
|
|
if (hardwareExtPending != 0U) |
|
|
|
{ |
|
|
|
/* The lower-priority EXTI ISR has not run yet. The natural boundary |
|
|
|
consumes this source-segment edge, so discard any matching software |
|
|
|
latch as well and do not let either reach the next segment. */ |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
} |
|
|
|
else if ((PlsrExtEdgePending != 0U) |
|
|
|
&& (PlsrExtEdgePendingSegment == previousExtSegment) |
|
|
|
&& (PlsrExtEdgePendingEpoch == previousExtEpoch)) |
|
|
|
{ |
|
|
|
/* The EXTI ISR already captured the source-segment edge. Natural |
|
|
|
completion satisfies EXT_OR_COMPLETE, preventing a double step. */ |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
} |
|
|
|
PlsrExtCaptureSegment = event->nextSegment; |
|
|
|
PlsrExtCaptureEpoch = previousExtEpoch + 1UL; |
|
|
|
#if defined(__ICCARM__) |
|
|
|
__DMB(); |
|
|
|
#endif |
|
|
|
@@ -4661,7 +4697,6 @@ static void PlsrExecServiceCountedBoundaryEvent(void) |
|
|
|
PlsrActiveConfig.segments[nextSegment - 1U].frequencyHz; |
|
|
|
} |
|
|
|
PlsrDeferredFrequencyPending = 0U; |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
PlsrExtPreviousLevel = |
|
|
|
PlsrPlatformReadInput((uint8_t)PlsrActiveConfig.extInput); |
|
|
|
PlsrCopyShortProfile(&PlsrShortProfile, |
|
|
|
@@ -4929,12 +4964,16 @@ static PLSR_PLATFORM_QUEUE_RESULT PlsrTryContinuousHandoff(void) |
|
|
|
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. */ |
|
|
|
/* EXTI only records an input edge. Motion state transitions and timer |
|
|
|
operations remain in the task context. WAIT uses an armed mask; EXT binds |
|
|
|
the edge to the active segment epoch so a stale edge cannot cut a later |
|
|
|
segment. */ |
|
|
|
void PlsrWaitInputExtiIrq(uint8_t inputSelection) |
|
|
|
{ |
|
|
|
uint8_t bit; |
|
|
|
uint8_t captureSegment; |
|
|
|
uint32_t captureEpoch; |
|
|
|
uint16_t waitType; |
|
|
|
|
|
|
|
if (inputSelection > 1U) |
|
|
|
{ |
|
|
|
@@ -4945,6 +4984,25 @@ void PlsrWaitInputExtiIrq(uint8_t inputSelection) |
|
|
|
{ |
|
|
|
PlsrWaitSignalPendingMask |= bit; |
|
|
|
} |
|
|
|
captureEpoch = PlsrExtCaptureEpoch; |
|
|
|
captureSegment = PlsrExtCaptureSegment; |
|
|
|
if ((PlsrActiveConfig.outputMode != PLSR_OUTPUT_PULSE_DIR) |
|
|
|
|| (inputSelection != (uint8_t)PlsrActiveConfig.extInput) |
|
|
|
|| (captureSegment == 0U) |
|
|
|
|| (captureSegment > PlsrActiveConfig.segmentCount)) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
waitType = PlsrActiveConfig.segments[captureSegment - 1U].waitType; |
|
|
|
if (((waitType == PLSR_EXT_SIGNAL) |
|
|
|
|| (waitType == PLSR_EXT_OR_COMPLETE)) |
|
|
|
&& (captureEpoch == PlsrExtCaptureEpoch) |
|
|
|
&& (captureSegment == PlsrExtCaptureSegment)) |
|
|
|
{ |
|
|
|
PlsrExtEdgePendingSegment = captureSegment; |
|
|
|
PlsrExtEdgePendingEpoch = captureEpoch; |
|
|
|
PlsrExtEdgePending = 1U; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void PlsrArmWaitSignal(uint8_t inputSelection) |
|
|
|
@@ -5009,8 +5067,10 @@ static void PlsrHandleBoundary(uint8_t extEdge) |
|
|
|
{ |
|
|
|
const PLSR_SEGMENT_CONFIG *segment; |
|
|
|
uint32_t criticalState; |
|
|
|
uint32_t currentEpoch; |
|
|
|
uint8_t wasCut = PlsrBoundaryWasCut; |
|
|
|
uint8_t preserveTimedStart; |
|
|
|
uint8_t currentSegment; |
|
|
|
|
|
|
|
PlsrPlatformStopPulse((uint8_t)PlsrActiveConfig.pulseOutput); |
|
|
|
PlsrBoundaryPending = 0U; |
|
|
|
@@ -5074,10 +5134,18 @@ static void PlsrHandleBoundary(uint8_t extEdge) |
|
|
|
segment = &PlsrActiveConfig.segments[PlsrCurrentSegment - 1U]; |
|
|
|
if (wasCut != 0U) |
|
|
|
{ |
|
|
|
PlsrTransitionToNext( |
|
|
|
uint8_t allowCarry = |
|
|
|
((segment->waitType == PLSR_ACT_TIME) |
|
|
|
|| (PlsrActiveConfig.sendMode == PLSR_SEND_SUBSEQUENT)) |
|
|
|
? 1U : 0U); |
|
|
|
? 1U : 0U; |
|
|
|
|
|
|
|
if ((PlsrActiveConfig.outputMode == PLSR_OUTPUT_PULSE_DIR) |
|
|
|
&& ((segment->waitType == PLSR_EXT_SIGNAL) |
|
|
|
|| (segment->waitType == PLSR_EXT_OR_COMPLETE))) |
|
|
|
{ |
|
|
|
allowCarry = 1U; |
|
|
|
} |
|
|
|
PlsrTransitionToNext(allowCarry); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
@@ -5117,6 +5185,17 @@ static void PlsrHandleBoundary(uint8_t extEdge) |
|
|
|
break; |
|
|
|
|
|
|
|
case PLSR_EXT_SIGNAL: |
|
|
|
criticalState = PlsrPlatformEnterCritical(); |
|
|
|
currentEpoch = PlsrSegmentEpoch; |
|
|
|
currentSegment = PlsrCurrentSegment; |
|
|
|
if ((PlsrExtEdgePending != 0U) |
|
|
|
&& (PlsrExtEdgePendingEpoch == currentEpoch) |
|
|
|
&& (PlsrExtEdgePendingSegment == currentSegment)) |
|
|
|
{ |
|
|
|
extEdge = 1U; |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
} |
|
|
|
PlsrPlatformExitCritical(criticalState); |
|
|
|
if (extEdge != 0U) |
|
|
|
{ |
|
|
|
PlsrTransitionToNext(0U); |
|
|
|
@@ -5353,6 +5432,10 @@ uint8_t PlsrInit(void) |
|
|
|
PlsrSegmentClockStarted = 0U; |
|
|
|
PlsrExtPreviousLevel = 0U; |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
PlsrExtEdgePendingSegment = 0U; |
|
|
|
PlsrExtEdgePendingEpoch = 0UL; |
|
|
|
PlsrExtCaptureSegment = 0U; |
|
|
|
PlsrExtCaptureEpoch = 0UL; |
|
|
|
PlsrWaitSignalArmedMask = 0U; |
|
|
|
PlsrWaitSignalPendingMask = 0U; |
|
|
|
PlsrStopRequested = 0U; |
|
|
|
@@ -5586,6 +5669,7 @@ static void PlsrExecuteClear(void) |
|
|
|
PlsrBoundaryWasCut = 0U; |
|
|
|
PlsrDirectionDelayActive = 0U; |
|
|
|
PlsrDirectionDelayRemainingMs = 0U; |
|
|
|
PlsrExtCaptureSegment = 0U; |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
PlsrShortProfile.active = 0U; |
|
|
|
PlsrProfileQueueReset(); |
|
|
|
@@ -5801,18 +5885,23 @@ void PlsrPoll1ms(void) |
|
|
|
|
|
|
|
criticalState = PlsrPlatformEnterCritical(); |
|
|
|
pollEpoch = PlsrSegmentEpoch; |
|
|
|
activeSegmentNumber = PlsrCurrentSegment; |
|
|
|
extLevel = PlsrPlatformReadInput((uint8_t)PlsrActiveConfig.extInput); |
|
|
|
extEdge = ((extLevel != 0U) && (PlsrExtPreviousLevel == 0U)) ? 1U : 0U; |
|
|
|
PlsrExtPreviousLevel = extLevel; |
|
|
|
if (PlsrExtEdgePending != 0U) |
|
|
|
{ |
|
|
|
extEdge = 1U; |
|
|
|
if ((PlsrExtEdgePendingEpoch == pollEpoch) |
|
|
|
&& (PlsrExtEdgePendingSegment == activeSegmentNumber)) |
|
|
|
{ |
|
|
|
extEdge = 1U; |
|
|
|
} |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
} |
|
|
|
PlsrPlatformExitCritical(criticalState); |
|
|
|
|
|
|
|
if (PlsrBoundaryPending != 0U) |
|
|
|
{ |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
PlsrHandleBoundary(extEdge); |
|
|
|
PlsrPollPersistenceDelay(); |
|
|
|
return; |
|
|
|
@@ -5832,9 +5921,18 @@ void PlsrPoll1ms(void) |
|
|
|
|
|
|
|
if (PlsrDirectionDelayActive != 0U) |
|
|
|
{ |
|
|
|
if (extEdge != 0U) |
|
|
|
{ |
|
|
|
PlsrExtEdgePending = 1U; |
|
|
|
activeSegmentNumber = PlsrCurrentSegment; |
|
|
|
if ((extEdge != 0U) |
|
|
|
&& (activeSegmentNumber != 0U) |
|
|
|
&& (activeSegmentNumber <= PlsrActiveConfig.segmentCount) |
|
|
|
&& ((PlsrActiveConfig.segments[activeSegmentNumber - 1U].waitType |
|
|
|
== PLSR_EXT_SIGNAL) |
|
|
|
|| (PlsrActiveConfig.segments[ |
|
|
|
activeSegmentNumber - 1U].waitType |
|
|
|
== PLSR_EXT_OR_COMPLETE))) |
|
|
|
{ |
|
|
|
PlsrRequestCut(pollEpoch); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (PlsrDirectionDelayRemainingMs != 0U) |
|
|
|
{ |
|
|
|
@@ -5868,7 +5966,6 @@ void PlsrPoll1ms(void) |
|
|
|
PlsrPlatformExitCritical(criticalState); |
|
|
|
return; |
|
|
|
} |
|
|
|
PlsrExtEdgePending = 0U; |
|
|
|
if (PlsrSegmentClockStarted != 0U) |
|
|
|
{ |
|
|
|
PlsrSegmentElapsedMs++; |
|
|
|
|