diff --git a/EWARM/Modbus.ewp b/EWARM/Modbus.ewp
index cdde10f..9d543a5 100644
--- a/EWARM/Modbus.ewp
+++ b/EWARM/Modbus.ewp
@@ -1263,22 +1263,16 @@
- PLSR
-
- $PROJ_DIR$\..\PLSR\Inc\plsr.h
-
-
- $PROJ_DIR$\..\PLSR\Src\plsr_internal.h
-
-
- $PROJ_DIR$\..\PLSR\Src\plsr_platform.h
-
+ Modbus
- $PROJ_DIR$\..\PLSR\Src\plsr_planner.h
+ $PROJ_DIR$\..\Modbus\Src\modbus_rtu_slave.c
- $PROJ_DIR$\..\PLSR\Src\plsr_planner.c
+ $PROJ_DIR$\..\Modbus\Inc\modbus_rtu_slave.h
+
+
+ PLSR
$PROJ_DIR$\..\PLSR\Src\plsr.c
@@ -1289,6 +1283,248 @@
35
0
1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $PROJ_DIR$\..\PLSR\Inc\plsr.h
+
+
+ $PROJ_DIR$\..\PLSR\Src\plsr_internal.h
+
+
+ $PROJ_DIR$\..\PLSR\Src\plsr_planner.c
+
+
+ $PROJ_DIR$\..\PLSR\Src\plsr_planner.h
+
+
+ $PROJ_DIR$\..\PLSR\Src\plsr_platform.h
+
$PROJ_DIR$\..\PLSR\Src\plsr_platform_f407.c
@@ -1321,6 +1572,248 @@
35
0
1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- Modbus
-
- $PROJ_DIR$\..\Modbus\Src\modbus_rtu_slave.c
-
-
- $PROJ_DIR$\..\Modbus\Inc\modbus_rtu_slave.h
-
-
diff --git a/PLSR/Src/plsr.c b/PLSR/Src/plsr.c
index 00ffa36..6307ab1 100644
--- a/PLSR/Src/plsr.c
+++ b/PLSR/Src/plsr.c
@@ -443,6 +443,9 @@ static uint8_t PlsrLimitProfileToActTimeUs(
uint8_t *timedCutPlanned);
static void PlsrProfileRecordPlannerStatus(
const PLSR_SHORT_PROFILE *profile);
+static uint8_t PlsrApplyCountedProgressSnapshot(
+ uint64_t observed,
+ uint64_t *appliedPulses);
static PLSR_PLATFORM_SERVICE_RESULT PlsrReplanPulseDir(
uint32_t targetHz,
uint32_t totalPulses,
@@ -2115,6 +2118,9 @@ static PLSR_PLATFORM_SERVICE_RESULT PlsrReplanPulseDir(
PLSR_SHORT_PROFILE replacement;
PLSR_SHORT_PROFILE candidate;
PLSR_PROFILE_ENTRY entry;
+ uint64_t observedPulses;
+ uint64_t observedDelta = 0ULL;
+ uint64_t appliedPulses = 0ULL;
uint64_t committedTimeUs;
uint64_t prefixTimeUs = 0ULL;
uint64_t prefixTimeLimitUs = PLSR_REPLAN_PREFIX_TIME_US;
@@ -2187,7 +2193,8 @@ static PLSR_PLATFORM_SERVICE_RESULT PlsrReplanPulseDir(
}
if (PlsrPlatformFinitePipelineSnapshot(
(uint8_t)PlsrActiveConfig.pulseOutput,
- &committedPulses, &committedTimeUs, &tailFrequencyHz,
+ &observedPulses, &committedPulses, &committedTimeUs,
+ &tailFrequencyHz,
&pipelineStartsNextSegment) == 0U)
{
PlsrPlatformExitCritical(criticalState);
@@ -2198,6 +2205,34 @@ static PLSR_PLATFORM_SERVICE_RESULT PlsrReplanPulseDir(
PlsrPlatformExitCritical(criticalState);
return PLSR_PLATFORM_SERVICE_DEFERRED;
}
+ if (forceTerminalExit == 0U)
+ {
+ /* Reconcile the logical budget to the exact counter sample used to
+ calculate the committed hardware tail. A later independent count
+ read would reopen the same several-pulse replan race. */
+ if (observedPulses < PlsrCountedObservedPublished)
+ {
+ PlsrPlatformExitCritical(criticalState);
+ return PLSR_PLATFORM_SERVICE_FAILED;
+ }
+ observedDelta = observedPulses - PlsrCountedObservedPublished;
+ if ((observedDelta > totalPulses)
+ || (observedDelta > PlsrRemainingPulses)
+ || (observedDelta > PlsrCommandRemainingPulses))
+ {
+ PlsrPlatformExitCritical(criticalState);
+ return PLSR_PLATFORM_SERVICE_FAILED;
+ }
+ totalPulses -= (uint32_t)observedDelta;
+ if ((totalPulses < committedPulses)
+ || (PlsrApplyCountedProgressSnapshot(
+ observedPulses, &appliedPulses) == 0U)
+ || (appliedPulses != observedDelta))
+ {
+ PlsrPlatformExitCritical(criticalState);
+ return PLSR_PLATFORM_SERVICE_FAILED;
+ }
+ }
/* The replacement stream owns the inactive bank from this point. */
PlsrInvalidateTimedStartLocked();
PlsrPlatformExitCritical(criticalState);
@@ -4504,15 +4539,14 @@ static uint8_t PlsrStageCountedHandoff(void)
return 1U;
}
-static uint8_t PlsrSyncCountedProgress(void)
+static uint8_t PlsrApplyCountedProgressSnapshot(
+ uint64_t observed,
+ uint64_t *appliedPulses)
{
- uint64_t observed;
uint64_t delta;
uint64_t remaining;
int64_t nextPosition;
- observed = PlsrPlatformObservedPulses(
- (uint8_t)PlsrActiveConfig.pulseOutput);
if (observed < PlsrCountedObservedPublished)
{
return 0U;
@@ -4520,6 +4554,10 @@ static uint8_t PlsrSyncCountedProgress(void)
delta = observed - PlsrCountedObservedPublished;
if (delta == 0ULL)
{
+ if (appliedPulses != NULL)
+ {
+ *appliedPulses = 0ULL;
+ }
return 1U;
}
remaining = PlsrRemainingPulses;
@@ -4561,9 +4599,21 @@ static uint8_t PlsrSyncCountedProgress(void)
}
PlsrCountedObservedPublished = observed;
PlsrPositionCheckpointDirty = 1U;
+ if (appliedPulses != NULL)
+ {
+ *appliedPulses = delta;
+ }
return 1U;
}
+static uint8_t PlsrSyncCountedProgress(void)
+{
+ uint64_t observed = PlsrPlatformObservedPulses(
+ (uint8_t)PlsrActiveConfig.pulseOutput);
+
+ return PlsrApplyCountedProgressSnapshot(observed, NULL);
+}
+
uint8_t PlsrExecTakeCountedRunIrq(
uint8_t pulseOutput,
PLSR_PLATFORM_TIMER_SETTING *setting,
diff --git a/PLSR/Src/plsr_platform.h b/PLSR/Src/plsr_platform.h
index 84b1d77..e346815 100644
--- a/PLSR/Src/plsr_platform.h
+++ b/PLSR/Src/plsr_platform.h
@@ -93,6 +93,7 @@ uint8_t PlsrPlatformRequestFiniteCut(uint8_t pulseOutput);
uint8_t PlsrPlatformFiniteRetargetReady(uint8_t pulseOutput,
uint32_t *activeFrequencyHz);
uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput,
+ uint64_t *observedPulses,
uint32_t *committedPulses,
uint64_t *committedTimeUs,
uint32_t *tailFrequencyHz,
diff --git a/PLSR/Src/plsr_platform_f407.c b/PLSR/Src/plsr_platform_f407.c
index e3d515a..bf3bab1 100644
--- a/PLSR/Src/plsr_platform_f407.c
+++ b/PLSR/Src/plsr_platform_f407.c
@@ -551,6 +551,7 @@ uint8_t PlsrPlatformFiniteRetargetReady(uint8_t pulseOutput,
}
uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput,
+ uint64_t *observedPulses,
uint32_t *committedPulses,
uint64_t *committedTimeUs,
uint32_t *tailFrequencyHz,
@@ -559,7 +560,8 @@ uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput,
uint32_t remaining;
uint32_t frequencyHz;
- if ((pulseOutput > 3U) || (committedPulses == NULL)
+ if ((pulseOutput > 3U) || (observedPulses == NULL)
+ || (committedPulses == NULL)
|| (committedTimeUs == NULL) || (tailFrequencyHz == NULL)
|| (startsNextSegment == NULL)
|| (PlsrHostFiniteActive[pulseOutput] == 0U))
@@ -573,6 +575,7 @@ uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput,
{
return 0U;
}
+ *observedPulses = PlsrHostObservedPulses[pulseOutput];
*committedPulses = remaining;
*committedTimeUs = ((uint64_t)remaining * 1000000ULL
+ frequencyHz - 1UL) / frequencyHz;
@@ -3613,6 +3616,7 @@ uint8_t PlsrPlatformFiniteRetargetReady(uint8_t pulseOutput,
}
uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput,
+ uint64_t *observedPulses,
uint32_t *committedPulses,
uint64_t *committedTimeUs,
uint32_t *tailFrequencyHz,
@@ -3623,8 +3627,10 @@ uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput,
uint32_t frequencyHz;
uint32_t remaining;
uint64_t timeUs;
+ uint64_t observed;
- if ((pulseOutput > 3U) || (committedPulses == NULL)
+ if ((pulseOutput > 3U) || (observedPulses == NULL)
+ || (committedPulses == NULL)
|| (committedTimeUs == NULL) || (tailFrequencyHz == NULL)
|| (startsNextSegment == NULL))
{
@@ -3644,6 +3650,15 @@ uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput,
{
completed = remaining;
}
+ observed = PlsrObservedPulseBase[pulseOutput] + completed;
+ if (observed < PlsrObservedPulsePublished[pulseOutput])
+ {
+ observed = PlsrObservedPulsePublished[pulseOutput];
+ }
+ else
+ {
+ PlsrObservedPulsePublished[pulseOutput] = observed;
+ }
remaining -= completed;
frequencyHz = PlsrTimerActiveFrequencyHz[pulseOutput];
if (frequencyHz == 0UL)
@@ -3674,6 +3689,7 @@ uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput,
*startsNextSegment =
PlsrFiniteStreamNextStartsSegment[pulseOutput];
}
+ *observedPulses = observed;
*committedPulses = remaining;
*committedTimeUs = timeUs;
PlsrPlatformExitCritical(criticalState);