|
- #include "plsr_platform.h"
- #include "plsr.h"
-
- static uint8_t PlsrFlashNeedsStartupRecovery(
- uint8_t haveValidRecord,
- uint8_t sectorAHasProgrammedSlot,
- uint32_t sectorAFirstErasedAddress,
- uint8_t sectorBHasProgrammedSlot,
- uint32_t sectorBFirstErasedAddress)
- {
- return ((haveValidRecord == 0U)
- && (sectorAHasProgrammedSlot != 0U)
- && (sectorBHasProgrammedSlot != 0U)
- && (sectorAFirstErasedAddress == 0UL)
- && (sectorBFirstErasedAddress == 0UL)) ? 1U : 0U;
- }
-
- #ifdef PLSR_HOST_TEST
-
- #include <string.h>
-
- static uint8_t PlsrHostPulseActive[4];
- static uint32_t PlsrHostFrequency[4];
- static uint32_t PlsrHostQueuedFrequency[4];
- static PLSR_PLATFORM_TIMER_SETTING PlsrHostActiveSetting[4];
- static PLSR_PLATFORM_TIMER_SETTING PlsrHostQueuedSetting[4];
- static uint8_t PlsrHostUpdatePending[4];
- static uint8_t PlsrHostOutputMode[4];
- static uint8_t PlsrHostDirectionPositive[4];
- static uint8_t PlsrHostAbQuarter[4];
- static uint8_t PlsrHostAbPhase[4];
- static uint32_t PlsrHostAbTransitions[4];
- static uint8_t PlsrHostAbStopPending[4];
- static uint8_t PlsrHostAbFastGated[4];
- static uint32_t PlsrHostAbFastGateCount;
- static uint32_t PlsrHostAbCleanupCount;
- static uint64_t PlsrHostObservedPulses[4];
- static uint8_t PlsrHostInputs[2];
- static uint8_t PlsrHostSelectedPulse;
- static uint8_t PlsrHostDirectionLevel;
- static uint8_t PlsrHostDirectionPinLevel[4];
- static uint32_t PlsrHostDirectionWriteCount[4];
- static uint32_t PlsrHostDirectionTransitionCount[4];
- static uint8_t PlsrHostEmitPulseOnCriticalEntry;
- static uint8_t PlsrHostEmitPulseOnCriticalExit;
- static uint8_t PlsrHostLatchPulseOnCriticalEntry;
- static uint8_t PlsrHostCriticalEntriesToSkip;
- static uint8_t PlsrHostLatchAbFinalQuarterOnStopArm;
- static uint8_t PlsrHostCompleteAbCycleOnQueueCommit;
- static uint32_t PlsrHostCriticalDepth;
- static uint8_t PlsrHostFailNextStart;
- static uint8_t PlsrHostStaleNextFrequencyAtUpdate;
- static uint8_t PlsrHostFailNextFrequencyAtUpdate;
- static uint8_t PlsrHostFailNextStopRequest;
- static uint8_t PlsrHostFinalArmJobPending;
- static uint8_t PlsrHostFinalArmJobOwner;
- static uint8_t PlsrHostDeferFinalArmJob;
- static int32_t PlsrHostCountOffset;
- static int32_t PlsrHostFrequencyOffsetHz;
- static uint8_t PlsrHostCurveMismatchPending;
- static uint16_t PlsrHostDiagnosticFault;
- static PLSR_PERSIST_PAYLOAD PlsrHostPersistentPayload;
- static uint8_t PlsrHostPersistentValid;
- static uint32_t PlsrHostSaveCount;
- static uint8_t PlsrHostFiniteEnabled;
- static uint8_t PlsrHostFiniteActive[4];
- static uint8_t PlsrHostFiniteComplete[4];
- static uint8_t PlsrHostFiniteFrequencyPending[4];
- static uint32_t PlsrHostFiniteTarget[4];
- static uint32_t PlsrHostFiniteEmitted[4];
- static PLSR_PLATFORM_FINITE_STEP *PlsrHostFiniteSteps[4];
- static uint16_t PlsrHostFiniteStepCount[4];
- static uint16_t PlsrHostFiniteStepIndex[4];
- static uint16_t PlsrHostFiniteBoundaryReadIndex[4];
- static uint16_t PlsrHostFiniteCompletedStepCount[4];
-
- static void PlsrHostServiceFinalArmJob(void);
-
- static uint32_t PlsrHostOffsetFrequency(uint32_t frequencyHz)
- {
- int64_t adjusted = (int64_t)frequencyHz
- + (int64_t)PlsrHostFrequencyOffsetHz;
-
- if (adjusted < 1)
- {
- adjusted = 1;
- }
- if (adjusted > (int64_t)PLSR_FREQUENCY_MAX_HZ)
- {
- adjusted = (int64_t)PLSR_FREQUENCY_MAX_HZ;
- }
- return (uint32_t)adjusted;
- }
-
- static void PlsrHostLatchPulse(uint8_t pulseOutput)
- {
- if ((pulseOutput <= 3U)
- && (PlsrHostPulseActive[pulseOutput] != 0U))
- {
- if (PlsrHostCurveMismatchPending != 0U)
- {
- PlsrHostCurveMismatchPending = 0U;
- PlsrHostDiagnosticFault = 3U;
- }
- else if ((PlsrHostOutputMode[pulseOutput] != PLSR_OUTPUT_AB)
- || (PlsrHostAbStopPending[pulseOutput] == 0U))
- {
- PlsrHostFrequency[pulseOutput] =
- PlsrHostQueuedFrequency[pulseOutput];
- PlsrHostActiveSetting[pulseOutput] =
- PlsrHostQueuedSetting[pulseOutput];
- }
- PlsrHostObservedPulses[pulseOutput]++;
- PlsrHostUpdatePending[pulseOutput] = 1U;
- }
- }
-
- static void PlsrHostServicePendingPulse(uint8_t pulseOutput)
- {
- if ((pulseOutput <= 3U)
- && (PlsrHostUpdatePending[pulseOutput] != 0U))
- {
- PlsrHostUpdatePending[pulseOutput] = 0U;
- if ((PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- && (PlsrHostAbStopPending[pulseOutput] != 0U)
- && (PlsrHostAbFastGated[pulseOutput] == 0U))
- {
- PlsrHostAbFastGated[pulseOutput] = 1U;
- PlsrHostPulseActive[pulseOutput] = 0U;
- PlsrHostAbFastGateCount++;
- }
- PlsrPulseTimerIrq(pulseOutput);
- }
- if (PlsrHostDeferFinalArmJob == 0U)
- {
- PlsrHostServiceFinalArmJob();
- }
- }
-
- static void PlsrHostServiceFinalArmJob(void)
- {
- uint8_t owner;
-
- if (PlsrHostFinalArmJobPending == 0U)
- {
- return;
- }
- owner = PlsrHostFinalArmJobOwner;
- PlsrHostFinalArmJobPending = 0U;
- PlsrHostFinalArmJobOwner = 0xFFU;
- PlsrFinalArmJobIrq(owner);
- }
-
- static uint8_t PlsrHostAdvanceAbQuarter(uint8_t pulseOutput)
- {
- static const uint8_t positivePhase[4] = {0U, 2U, 3U, 1U};
- static const uint8_t negativePhase[4] = {0U, 1U, 3U, 2U};
-
- if ((pulseOutput > 3U)
- || (PlsrHostPulseActive[pulseOutput] == 0U)
- || (PlsrHostOutputMode[pulseOutput] != PLSR_OUTPUT_AB))
- {
- return 0U;
- }
- PlsrHostAbQuarter[pulseOutput] =
- (uint8_t)((PlsrHostAbQuarter[pulseOutput] + 1U) & 3U);
- PlsrHostAbPhase[pulseOutput] =
- (PlsrHostDirectionPositive[pulseOutput] != 0U)
- ? positivePhase[PlsrHostAbQuarter[pulseOutput]]
- : negativePhase[PlsrHostAbQuarter[pulseOutput]];
- PlsrHostAbTransitions[pulseOutput]++;
- if (PlsrHostAbQuarter[pulseOutput] != 0U)
- {
- return 0U;
- }
- PlsrHostLatchPulse(pulseOutput);
- return 1U;
- }
-
- uint8_t PlsrPlatformInit(void)
- {
- uint8_t index;
-
- (void)memset(PlsrHostPulseActive, 0, sizeof(PlsrHostPulseActive));
- (void)memset(PlsrHostFrequency, 0, sizeof(PlsrHostFrequency));
- (void)memset(PlsrHostQueuedFrequency, 0,
- sizeof(PlsrHostQueuedFrequency));
- (void)memset(PlsrHostActiveSetting, 0,
- sizeof(PlsrHostActiveSetting));
- (void)memset(PlsrHostQueuedSetting, 0,
- sizeof(PlsrHostQueuedSetting));
- (void)memset(PlsrHostUpdatePending, 0,
- sizeof(PlsrHostUpdatePending));
- (void)memset(PlsrHostOutputMode, 0, sizeof(PlsrHostOutputMode));
- (void)memset(PlsrHostDirectionPositive, 0,
- sizeof(PlsrHostDirectionPositive));
- (void)memset(PlsrHostAbQuarter, 0, sizeof(PlsrHostAbQuarter));
- (void)memset(PlsrHostAbPhase, 0, sizeof(PlsrHostAbPhase));
- (void)memset(PlsrHostAbTransitions, 0,
- sizeof(PlsrHostAbTransitions));
- (void)memset(PlsrHostAbStopPending, 0,
- sizeof(PlsrHostAbStopPending));
- (void)memset(PlsrHostAbFastGated, 0,
- sizeof(PlsrHostAbFastGated));
- PlsrHostAbFastGateCount = 0UL;
- PlsrHostAbCleanupCount = 0UL;
- (void)memset(PlsrHostObservedPulses, 0,
- sizeof(PlsrHostObservedPulses));
- PlsrHostSelectedPulse = 0U;
- PlsrHostDirectionLevel = 0U;
- for (index = 0U; index < 4U; index++)
- {
- PlsrHostDirectionPinLevel[index] = 1U;
- PlsrHostDirectionWriteCount[index] = 0UL;
- PlsrHostDirectionTransitionCount[index] = 0UL;
- }
- PlsrHostEmitPulseOnCriticalEntry = 0U;
- PlsrHostEmitPulseOnCriticalExit = 0U;
- PlsrHostLatchPulseOnCriticalEntry = 0U;
- PlsrHostCriticalEntriesToSkip = 0U;
- PlsrHostLatchAbFinalQuarterOnStopArm = 0U;
- PlsrHostCompleteAbCycleOnQueueCommit = 0U;
- PlsrHostCriticalDepth = 0UL;
- PlsrHostFailNextStart = 0U;
- PlsrHostStaleNextFrequencyAtUpdate = 0U;
- PlsrHostFailNextFrequencyAtUpdate = 0U;
- PlsrHostFailNextStopRequest = 0U;
- PlsrHostFinalArmJobPending = 0U;
- PlsrHostFinalArmJobOwner = 0xFFU;
- PlsrHostDeferFinalArmJob = 0U;
- PlsrHostCountOffset = 0L;
- PlsrHostFrequencyOffsetHz = 0L;
- PlsrHostCurveMismatchPending = 0U;
- PlsrHostDiagnosticFault = 0U;
- PlsrHostFiniteEnabled = 0U;
- (void)memset(PlsrHostFiniteActive, 0, sizeof(PlsrHostFiniteActive));
- (void)memset(PlsrHostFiniteComplete, 0,
- sizeof(PlsrHostFiniteComplete));
- (void)memset(PlsrHostFiniteFrequencyPending, 0,
- sizeof(PlsrHostFiniteFrequencyPending));
- (void)memset(PlsrHostFiniteTarget, 0, sizeof(PlsrHostFiniteTarget));
- (void)memset(PlsrHostFiniteEmitted, 0, sizeof(PlsrHostFiniteEmitted));
- (void)memset(PlsrHostFiniteSteps, 0, sizeof(PlsrHostFiniteSteps));
- (void)memset(PlsrHostFiniteStepCount, 0,
- sizeof(PlsrHostFiniteStepCount));
- (void)memset(PlsrHostFiniteStepIndex, 0,
- sizeof(PlsrHostFiniteStepIndex));
- (void)memset(PlsrHostFiniteBoundaryReadIndex, 0,
- sizeof(PlsrHostFiniteBoundaryReadIndex));
- (void)memset(PlsrHostFiniteCompletedStepCount, 0,
- sizeof(PlsrHostFiniteCompletedStepCount));
- return 1U;
- }
-
- uint8_t PlsrPlatformPrepare(uint8_t pulseOutput,
- uint8_t directionOutput,
- uint8_t directionLevel,
- uint8_t outputMode,
- uint8_t directionPositive)
- {
- uint8_t index;
- uint8_t pinLevel;
-
- if (PlsrHostFailNextStart != 0U)
- {
- PlsrHostFailNextStart = 0U;
- return 0U;
- }
- if ((pulseOutput > 3U) || (directionOutput > 3U)
- || (outputMode > PLSR_OUTPUT_AB)
- || ((outputMode == PLSR_OUTPUT_AB)
- && ((pulseOutput & 1U) != 0U))
- || (PlsrHostAbStopPending[0] != 0U)
- || (PlsrHostAbStopPending[2] != 0U))
- {
- return 0U;
- }
- for (index = 0U; index < 4U; index++)
- {
- PlsrHostPulseActive[index] = 0U;
- PlsrHostFrequency[index] = 0UL;
- PlsrHostQueuedFrequency[index] = 0UL;
- PlsrHostUpdatePending[index] = 0U;
- pinLevel = ((outputMode == PLSR_OUTPUT_PULSE_DIR)
- && (index == directionOutput)
- && (directionLevel != 0U)) ? 0U : 1U;
- PlsrHostDirectionWriteCount[index]++;
- if (PlsrHostDirectionPinLevel[index] != pinLevel)
- {
- PlsrHostDirectionTransitionCount[index]++;
- }
- PlsrHostDirectionPinLevel[index] = pinLevel;
- }
- PlsrHostSelectedPulse = pulseOutput;
- PlsrHostDirectionLevel = (directionLevel != 0U) ? 1U : 0U;
- PlsrHostOutputMode[pulseOutput] = outputMode;
- PlsrHostDirectionPositive[pulseOutput] =
- (directionPositive != 0U) ? 1U : 0U;
- PlsrHostAbQuarter[pulseOutput] = 0U;
- PlsrHostAbPhase[pulseOutput] = 0U;
- PlsrHostAbFastGated[pulseOutput] = 0U;
- return 1U;
- }
-
- uint8_t PlsrPlatformStartPulse(uint8_t pulseOutput,
- uint32_t firstFrequencyHz,
- uint32_t queuedFrequencyHz,
- uint32_t *actualFirstFrequencyHz,
- uint32_t *actualQueuedFrequencyHz)
- {
- PLSR_PLATFORM_TIMER_SETTING firstSetting;
- PLSR_PLATFORM_TIMER_SETTING queuedSetting;
-
- if ((pulseOutput > 3U)
- || (PlsrPlatformBuildTimerSetting(
- pulseOutput, PlsrHostOutputMode[pulseOutput],
- firstFrequencyHz, &firstSetting) == 0U)
- || (PlsrPlatformBuildTimerSetting(
- pulseOutput, PlsrHostOutputMode[pulseOutput],
- queuedFrequencyHz, &queuedSetting) == 0U))
- {
- return 0U;
- }
- return PlsrPlatformStartPrepared(pulseOutput, &firstSetting,
- &queuedSetting,
- actualFirstFrequencyHz,
- actualQueuedFrequencyHz);
- }
-
- uint8_t PlsrPlatformBuildTimerSetting(
- uint8_t pulseOutput,
- uint8_t outputMode,
- uint32_t requestedFrequencyHz,
- PLSR_PLATFORM_TIMER_SETTING *setting)
- {
- if ((pulseOutput > 3U) || (outputMode > PLSR_OUTPUT_AB)
- || ((outputMode == PLSR_OUTPUT_AB)
- && ((pulseOutput & 1U) != 0U))
- || (requestedFrequencyHz == 0UL)
- || (requestedFrequencyHz > PLSR_FREQUENCY_MAX_HZ)
- || (setting == NULL))
- {
- return 0U;
- }
- setting->actualFrequencyHz = requestedFrequencyHz;
- setting->prescaler = (outputMode == PLSR_OUTPUT_AB) ? 1U : 0U;
- setting->pairPrescaler = 0U;
- setting->period = (outputMode == PLSR_OUTPUT_AB) ? 3U : 1U;
- setting->compare = (outputMode == PLSR_OUTPUT_AB) ? 2U : 1U;
- return 1U;
- }
-
- uint8_t PlsrPlatformStartPrepared(
- uint8_t pulseOutput,
- const PLSR_PLATFORM_TIMER_SETTING *firstSetting,
- const PLSR_PLATFORM_TIMER_SETTING *queuedSetting,
- uint32_t *actualFirstFrequencyHz,
- uint32_t *actualQueuedFrequencyHz)
- {
- if ((pulseOutput > 3U) || (firstSetting == NULL)
- || (queuedSetting == NULL) || (actualFirstFrequencyHz == NULL)
- || (actualQueuedFrequencyHz == NULL)
- || (firstSetting->actualFrequencyHz == 0UL)
- || (firstSetting->actualFrequencyHz > PLSR_FREQUENCY_MAX_HZ)
- || (queuedSetting->actualFrequencyHz == 0UL)
- || (queuedSetting->actualFrequencyHz > PLSR_FREQUENCY_MAX_HZ)
- || (PlsrHostAbStopPending[pulseOutput] != 0U)
- || (PlsrHostAbFastGated[pulseOutput] != 0U))
- {
- return 0U;
- }
- PlsrHostPulseActive[pulseOutput] = 1U;
- PlsrHostFrequency[pulseOutput] = firstSetting->actualFrequencyHz;
- PlsrHostQueuedFrequency[pulseOutput] = queuedSetting->actualFrequencyHz;
- PlsrHostActiveSetting[pulseOutput] = *firstSetting;
- PlsrHostQueuedSetting[pulseOutput] = *queuedSetting;
- PlsrHostUpdatePending[pulseOutput] = 0U;
- PlsrHostSelectedPulse = pulseOutput;
- *actualFirstFrequencyHz = firstSetting->actualFrequencyHz;
- *actualQueuedFrequencyHz = queuedSetting->actualFrequencyHz;
- return 1U;
- }
-
- uint8_t PlsrPlatformSupportsFinitePulseTrain(void)
- {
- return PlsrHostFiniteEnabled;
- }
-
- uint8_t PlsrPlatformStartFinitePrepared(
- uint8_t pulseOutput,
- const PLSR_PLATFORM_TIMER_SETTING *setting,
- uint32_t pulseCount,
- uint32_t *actualFrequencyHz)
- {
- if ((PlsrHostFiniteEnabled == 0U) || (pulseOutput > 3U)
- || (setting == NULL) || (pulseCount == 0UL)
- || (actualFrequencyHz == NULL)
- || (PlsrHostOutputMode[pulseOutput] != PLSR_OUTPUT_PULSE_DIR))
- {
- return 0U;
- }
- PlsrHostPulseActive[pulseOutput] = 1U;
- PlsrHostFiniteActive[pulseOutput] = 1U;
- PlsrHostFiniteComplete[pulseOutput] = 0U;
- PlsrHostFiniteFrequencyPending[pulseOutput] = 0U;
- PlsrHostFiniteTarget[pulseOutput] = pulseCount;
- PlsrHostFiniteEmitted[pulseOutput] = 0UL;
- PlsrHostFiniteStepCount[pulseOutput] = 0U;
- PlsrHostFiniteStepIndex[pulseOutput] = 0U;
- PlsrHostFiniteBoundaryReadIndex[pulseOutput] = 0U;
- PlsrHostFiniteCompletedStepCount[pulseOutput] = 0U;
- PlsrHostFrequency[pulseOutput] = setting->actualFrequencyHz;
- PlsrHostQueuedFrequency[pulseOutput] = setting->actualFrequencyHz;
- PlsrHostActiveSetting[pulseOutput] = *setting;
- PlsrHostQueuedSetting[pulseOutput] = *setting;
- PlsrHostSelectedPulse = pulseOutput;
- *actualFrequencyHz = setting->actualFrequencyHz;
- return 1U;
- }
-
- uint8_t PlsrPlatformStartFiniteSequencePrepared(
- uint8_t pulseOutput,
- PLSR_PLATFORM_FINITE_STEP *steps,
- uint16_t stepCount,
- uint32_t *actualFrequencyHz)
- {
- if ((steps == NULL) || (stepCount == 0U)
- || (stepCount > PLSR_PLATFORM_FINITE_STEP_MAX)
- || (PlsrPlatformStartFinitePrepared(
- pulseOutput, &steps[0].setting, steps[0].pulseCount,
- actualFrequencyHz) == 0U))
- {
- return 0U;
- }
- PlsrHostFiniteSteps[pulseOutput] = steps;
- PlsrHostFiniteStepCount[pulseOutput] = stepCount;
- PlsrHostFiniteStepIndex[pulseOutput] = 0U;
- PlsrHostFiniteBoundaryReadIndex[pulseOutput] = 0U;
- PlsrHostFiniteCompletedStepCount[pulseOutput] = 0U;
- return 1U;
- }
-
-
- PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformUpdateFinitePrepared(
- uint8_t pulseOutput,
- const PLSR_PLATFORM_TIMER_SETTING *setting,
- uint32_t *actualFrequencyHz)
- {
- if (PlsrHostFailNextFrequencyAtUpdate != 0U)
- {
- PlsrHostFailNextFrequencyAtUpdate = 0U;
- return PLSR_PLATFORM_QUEUE_FAILED;
- }
- if ((pulseOutput > 3U) || (setting == NULL)
- || (actualFrequencyHz == NULL)
- || (PlsrHostFiniteActive[pulseOutput] == 0U))
- {
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- if (PlsrHostStaleNextFrequencyAtUpdate != 0U)
- {
- PlsrHostStaleNextFrequencyAtUpdate = 0U;
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- if (PlsrHostFiniteFrequencyPending[pulseOutput] != 0U)
- {
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- PlsrHostQueuedSetting[pulseOutput] = *setting;
- PlsrHostQueuedFrequency[pulseOutput] = setting->actualFrequencyHz;
- PlsrHostFiniteFrequencyPending[pulseOutput] = 1U;
- *actualFrequencyHz = setting->actualFrequencyHz;
- return PLSR_PLATFORM_QUEUE_APPLIED;
- }
-
- uint8_t PlsrPlatformRetargetFiniteStop(uint8_t pulseOutput,
- uint32_t drainPulses)
- {
- uint32_t completed;
-
- if ((pulseOutput > 3U) || (drainPulses == 0UL)
- || (PlsrHostFiniteActive[pulseOutput] == 0U))
- {
- return 0U;
- }
- completed = PlsrHostFiniteEmitted[pulseOutput];
- if (PlsrHostFiniteStepCount[pulseOutput] != 0U)
- {
- completed += PlsrHostFiniteSteps[pulseOutput][
- PlsrHostFiniteStepIndex[pulseOutput]].segmentPulseOffset;
- }
- PlsrHostFiniteTarget[pulseOutput] = completed + drainPulses;
- PlsrHostFiniteEmitted[pulseOutput] = completed;
- PlsrHostFiniteStepCount[pulseOutput] = 0U;
- PlsrHostFiniteStepIndex[pulseOutput] = 0U;
- PlsrHostFiniteBoundaryReadIndex[pulseOutput] = 0U;
- PlsrHostFiniteCompletedStepCount[pulseOutput] = 0U;
- return 1U;
- }
-
- uint8_t PlsrPlatformFiniteRetargetReady(uint8_t pulseOutput,
- uint32_t *activeFrequencyHz)
- {
- if ((pulseOutput > 3U) || (activeFrequencyHz == NULL)
- || (PlsrHostFiniteActive[pulseOutput] == 0U))
- {
- return 0U;
- }
- *activeFrequencyHz = PlsrHostFrequency[pulseOutput];
- return (PlsrHostFiniteStepCount[pulseOutput] == 0U) ? 1U : 0U;
- }
-
- uint8_t PlsrPlatformFiniteProgress(uint8_t pulseOutput,
- uint32_t *completedPulses)
- {
- if ((pulseOutput > 3U) || (completedPulses == NULL)
- || ((PlsrHostFiniteActive[pulseOutput] == 0U)
- && (PlsrHostFiniteComplete[pulseOutput] == 0U)))
- {
- return 0U;
- }
- if (PlsrHostFiniteStepCount[pulseOutput] != 0U)
- {
- const PLSR_PLATFORM_FINITE_STEP *step =
- &PlsrHostFiniteSteps[pulseOutput][
- PlsrHostFiniteStepIndex[pulseOutput]];
-
- *completedPulses = step->segmentPulseOffset
- + PlsrHostFiniteEmitted[pulseOutput];
- }
- else
- {
- *completedPulses = PlsrHostFiniteEmitted[pulseOutput];
- }
- return 1U;
- }
-
- uint8_t PlsrPlatformTakeFiniteCompletion(uint8_t pulseOutput,
- uint32_t *completedPulses)
- {
- if ((pulseOutput > 3U) || (completedPulses == NULL)
- || (PlsrHostFiniteComplete[pulseOutput] == 0U))
- {
- return 0U;
- }
- PlsrHostFiniteComplete[pulseOutput] = 0U;
- if (PlsrHostFiniteStepCount[pulseOutput] != 0U)
- {
- const PLSR_PLATFORM_FINITE_STEP *step =
- &PlsrHostFiniteSteps[pulseOutput][
- PlsrHostFiniteStepCount[pulseOutput] - 1U];
-
- *completedPulses = step->segmentPulseOffset + step->pulseCount;
- }
- else
- {
- *completedPulses = PlsrHostFiniteTarget[pulseOutput];
- }
- return 1U;
- }
-
- uint8_t PlsrPlatformTakeFiniteBoundary(uint8_t pulseOutput,
- uint8_t *segmentNumber,
- uint32_t *completedPulses,
- uint8_t *sequenceContinues,
- uint32_t *activeFrequencyHz)
- {
- if ((pulseOutput > 3U) || (segmentNumber == NULL)
- || (completedPulses == NULL) || (sequenceContinues == NULL)
- || (activeFrequencyHz == NULL))
- {
- return 0U;
- }
- while (PlsrHostFiniteBoundaryReadIndex[pulseOutput]
- < PlsrHostFiniteCompletedStepCount[pulseOutput])
- {
- uint16_t index = PlsrHostFiniteBoundaryReadIndex[pulseOutput]++;
- const PLSR_PLATFORM_FINITE_STEP *step =
- &PlsrHostFiniteSteps[pulseOutput][index];
-
- if (step->completesSegment != 0U)
- {
- *segmentNumber = step->segmentNumber;
- *completedPulses = step->segmentPulseOffset + step->pulseCount;
- *sequenceContinues =
- (index + 1U < PlsrHostFiniteStepCount[pulseOutput]) ? 1U : 0U;
- *activeFrequencyHz = (*sequenceContinues != 0U)
- ? PlsrHostFiniteSteps[pulseOutput][index + 1U]
- .setting.actualFrequencyHz
- : step->setting.actualFrequencyHz;
- return 1U;
- }
- }
- return 0U;
- }
-
- PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformLoadPreparedFromIrq(
- uint8_t pulseOutput,
- const PLSR_PLATFORM_TIMER_SETTING *setting,
- uint32_t *actualFrequencyHz)
- {
- if (PlsrHostFailNextFrequencyAtUpdate != 0U)
- {
- PlsrHostFailNextFrequencyAtUpdate = 0U;
- return PLSR_PLATFORM_QUEUE_FAILED;
- }
- if ((pulseOutput > 3U) || (setting == NULL)
- || (actualFrequencyHz == NULL)
- || (setting->actualFrequencyHz == 0UL)
- || (setting->actualFrequencyHz > PLSR_FREQUENCY_MAX_HZ))
- {
- return PLSR_PLATFORM_QUEUE_FAILED;
- }
- if (PlsrHostStaleNextFrequencyAtUpdate != 0U)
- {
- PlsrHostStaleNextFrequencyAtUpdate = 0U;
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- if ((PlsrHostCompleteAbCycleOnQueueCommit != 0U)
- && (PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB))
- {
- PlsrHostCompleteAbCycleOnQueueCommit = 0U;
- PlsrTestEmitAbQuarters(4UL);
- }
- if ((PlsrHostPulseActive[pulseOutput] == 0U)
- || (PlsrHostAbStopPending[pulseOutput] != 0U)
- || (PlsrHostAbFastGated[pulseOutput] != 0U))
- {
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- PlsrHostQueuedSetting[pulseOutput] = *setting;
- PlsrHostQueuedFrequency[pulseOutput] = setting->actualFrequencyHz;
- *actualFrequencyHz = setting->actualFrequencyHz;
- return PLSR_PLATFORM_QUEUE_APPLIED;
- }
-
- void PlsrPlatformGateFromIrq(uint8_t pulseOutput)
- {
- if ((pulseOutput <= 3U)
- && (PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- && (PlsrHostAbFastGated[pulseOutput] != 0U))
- {
- return;
- }
- PlsrPlatformStopPulse(pulseOutput);
- }
-
- PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformQueueFrequency(
- uint8_t pulseOutput,
- uint32_t frequencyHz,
- uint32_t *actualFrequencyHz)
- {
- uint32_t criticalState;
- PLSR_PLATFORM_TIMER_SETTING setting;
-
- if (PlsrHostFailNextFrequencyAtUpdate != 0U)
- {
- PlsrHostFailNextFrequencyAtUpdate = 0U;
- return PLSR_PLATFORM_QUEUE_FAILED;
- }
- if ((pulseOutput > 3U)
- || (PlsrPlatformBuildTimerSetting(
- pulseOutput, PlsrHostOutputMode[pulseOutput], frequencyHz,
- &setting) == 0U)
- || (actualFrequencyHz == NULL)
- || (PlsrHostPulseActive[pulseOutput] == 0U)
- || (PlsrHostAbStopPending[pulseOutput] != 0U)
- || (PlsrHostAbFastGated[pulseOutput] != 0U))
- {
- return PLSR_PLATFORM_QUEUE_FAILED;
- }
- if (PlsrHostStaleNextFrequencyAtUpdate != 0U)
- {
- PlsrHostStaleNextFrequencyAtUpdate = 0U;
- return PLSR_PLATFORM_QUEUE_STALE;
- }
-
- if ((PlsrHostCompleteAbCycleOnQueueCommit != 0U)
- && (PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB))
- {
- PlsrHostCompleteAbCycleOnQueueCommit = 0U;
- PlsrTestEmitAbQuarters(4UL);
- }
-
- criticalState = PlsrPlatformEnterCritical();
- if ((PlsrHostPulseActive[pulseOutput] == 0U)
- || (PlsrHostAbStopPending[pulseOutput] != 0U)
- || (PlsrHostAbFastGated[pulseOutput] != 0U))
- {
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- PlsrHostQueuedFrequency[pulseOutput] = setting.actualFrequencyHz;
- PlsrHostQueuedSetting[pulseOutput] = setting;
- *actualFrequencyHz = setting.actualFrequencyHz;
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_QUEUE_APPLIED;
- }
-
- void PlsrPlatformDrainPendingPulse(uint8_t pulseOutput)
- {
- PlsrHostServicePendingPulse(pulseOutput);
- }
-
- uint32_t PlsrPlatformActiveFrequency(uint8_t pulseOutput)
- {
- if (pulseOutput > 3U)
- {
- return 0UL;
- }
- return (PlsrHostFrequencyOffsetHz != 0L)
- ? PlsrHostOffsetFrequency(PlsrHostFrequency[pulseOutput])
- : PlsrHostFrequency[pulseOutput];
- }
-
- uint8_t PlsrPlatformExpectedFrequency(uint8_t pulseOutput,
- uint8_t outputMode,
- uint32_t requestedFrequencyHz,
- uint32_t *actualFrequencyHz)
- {
- PLSR_PLATFORM_TIMER_SETTING setting;
-
- if (PlsrPlatformBuildTimerSetting(pulseOutput, outputMode,
- requestedFrequencyHz,
- &setting) == 0U)
- {
- return 0U;
- }
- *actualFrequencyHz = setting.actualFrequencyHz;
- return 1U;
- }
-
- uint64_t PlsrPlatformObservedPulses(uint8_t pulseOutput)
- {
- int64_t observed;
-
- if (pulseOutput > 3U)
- {
- return 0UL;
- }
- observed = (int64_t)PlsrHostObservedPulses[pulseOutput]
- + (int64_t)PlsrHostCountOffset;
- return (observed > 0) ? (uint64_t)observed : 0UL;
- }
-
- uint16_t PlsrPlatformDiagnosticFault(void)
- {
- uint16_t fault = PlsrHostDiagnosticFault;
-
- PlsrHostDiagnosticFault = 0U;
- return fault;
- }
-
- PLSR_PLATFORM_STOP_RESULT PlsrPlatformRequestStopLocked(
- uint8_t pulseOutput,
- uint8_t requireZeroBoundary)
- {
- if (pulseOutput > 3U)
- {
- return PLSR_PLATFORM_STOP_FORCED_FAULT;
- }
- if (PlsrHostFailNextStopRequest != 0U)
- {
- PlsrHostFailNextStopRequest = 0U;
- PlsrPlatformStopPulse(pulseOutput);
- return PLSR_PLATFORM_STOP_FORCED_FAULT;
- }
- if ((requireZeroBoundary != 0U)
- && (PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- && (PlsrHostPulseActive[pulseOutput] != 0U)
- && (PlsrHostAbFastGated[pulseOutput] == 0U))
- {
- if (PlsrHostLatchAbFinalQuarterOnStopArm != 0U)
- {
- PlsrHostLatchAbFinalQuarterOnStopArm = 0U;
- (void)PlsrHostAdvanceAbQuarter(pulseOutput);
- }
- PlsrHostQueuedFrequency[pulseOutput] =
- PlsrHostFrequency[pulseOutput];
- PlsrHostAbStopPending[pulseOutput] = 1U;
- return PLSR_PLATFORM_STOP_PENDING;
- }
- PlsrPlatformStopPulse(pulseOutput);
- return PLSR_PLATFORM_STOP_COMPLETE;
- }
-
- uint8_t PlsrPlatformQueueFinalArmFromIrq(uint8_t pulseOutput)
- {
- if ((pulseOutput > 2U) || ((pulseOutput & 1U) != 0U)
- || (PlsrHostOutputMode[pulseOutput] != PLSR_OUTPUT_AB)
- || (PlsrHostPulseActive[pulseOutput] == 0U)
- || (PlsrHostAbFastGated[pulseOutput] != 0U))
- {
- return 0U;
- }
- PlsrHostFinalArmJobOwner = pulseOutput;
- PlsrHostFinalArmJobPending = 1U;
- return 1U;
- }
-
- void PlsrPlatformStopPulse(uint8_t pulseOutput)
- {
- if (pulseOutput <= 3U)
- {
- if ((PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- && ((PlsrHostAbStopPending[pulseOutput] != 0U)
- || (PlsrHostAbFastGated[pulseOutput] != 0U)))
- {
- PlsrHostAbCleanupCount++;
- }
- PlsrHostPulseActive[pulseOutput] = 0U;
- PlsrHostFiniteActive[pulseOutput] = 0U;
- PlsrHostFiniteComplete[pulseOutput] = 0U;
- PlsrHostFrequency[pulseOutput] = 0UL;
- PlsrHostQueuedFrequency[pulseOutput] = 0UL;
- PlsrHostUpdatePending[pulseOutput] = 0U;
- PlsrHostAbQuarter[pulseOutput] = 0U;
- PlsrHostAbPhase[pulseOutput] = 0U;
- PlsrHostAbStopPending[pulseOutput] = 0U;
- PlsrHostAbFastGated[pulseOutput] = 0U;
- PlsrHostFrequencyOffsetHz = 0L;
- if (PlsrHostFinalArmJobOwner == pulseOutput)
- {
- PlsrHostFinalArmJobPending = 0U;
- PlsrHostFinalArmJobOwner = 0xFFU;
- }
- }
- }
-
- uint8_t PlsrPlatformReadInput(uint8_t inputSelection)
- {
- return (inputSelection <= 1U) ? PlsrHostInputs[inputSelection] : 0U;
- }
-
- uint8_t PlsrPlatformLoad(PLSR_PERSIST_PAYLOAD *payload)
- {
- if ((payload == NULL) || (PlsrHostPersistentValid == 0U))
- {
- return 0U;
- }
- *payload = PlsrHostPersistentPayload;
- return 1U;
- }
-
- void PlsrPlatformForceSafeOutputsFromFault(void)
- {
- uint8_t index;
-
- for (index = 0U; index < 4U; index++)
- {
- PlsrPlatformStopPulse(index);
- }
- }
-
- PLSR_PLATFORM_SERVICE_RESULT PlsrPlatformServicePersistence(void)
- {
- return PLSR_PLATFORM_SERVICE_READY;
- }
-
- uint8_t PlsrPlatformSave(const PLSR_PERSIST_PAYLOAD *payload)
- {
- if (payload == NULL)
- {
- return 0U;
- }
- PlsrHostPersistentPayload = *payload;
- PlsrHostPersistentValid = 1U;
- PlsrHostSaveCount++;
- return 1U;
- }
-
- void PlsrPlatformCheckpointConfig(const PLSR_CONFIG *config)
- {
- if (config != NULL)
- {
- PlsrHostPersistentPayload.config = *config;
- PlsrHostPersistentValid = 1U;
- }
- }
-
- void PlsrPlatformCheckpointPosition(int32_t position,
- uint8_t positionValid,
- uint8_t wasBusy)
- {
- PlsrHostPersistentPayload.position = position;
- PlsrHostPersistentPayload.positionValid = positionValid;
- PlsrHostPersistentPayload.wasBusy = wasBusy;
- PlsrHostPersistentPayload.reserved = 0U;
- }
-
- uint32_t PlsrPlatformEnterCritical(void)
- {
- uint32_t previousDepth = PlsrHostCriticalDepth;
-
- if (PlsrHostEmitPulseOnCriticalEntry != 0U)
- {
- if (PlsrHostCriticalEntriesToSkip != 0U)
- {
- PlsrHostCriticalEntriesToSkip--;
- }
- else
- {
- PlsrHostEmitPulseOnCriticalEntry = 0U;
- PlsrHostLatchPulse(PlsrHostSelectedPulse);
- if (previousDepth == 0UL)
- {
- PlsrHostServicePendingPulse(PlsrHostSelectedPulse);
- }
- }
- }
- if (PlsrHostLatchPulseOnCriticalEntry != 0U)
- {
- PlsrHostLatchPulseOnCriticalEntry = 0U;
- PlsrHostLatchPulse(PlsrHostSelectedPulse);
- }
- PlsrHostCriticalDepth++;
- return previousDepth;
- }
-
- void PlsrPlatformExitCritical(uint32_t state)
- {
- (void)state;
- if (PlsrHostCriticalDepth != 0UL)
- {
- PlsrHostCriticalDepth--;
- }
- if (PlsrHostCriticalDepth != 0UL)
- {
- return;
- }
- if (PlsrHostEmitPulseOnCriticalExit != 0U)
- {
- PlsrHostEmitPulseOnCriticalExit = 0U;
- PlsrHostLatchPulse(PlsrHostSelectedPulse);
- }
- PlsrHostServicePendingPulse(PlsrHostSelectedPulse);
- }
-
- void PlsrTestSetInput(uint8_t inputSelection, uint8_t level)
- {
- if (inputSelection <= 1U)
- {
- PlsrHostInputs[inputSelection] = (level != 0U) ? 1U : 0U;
- }
- }
-
- void PlsrTestEmitPulses(uint32_t pulseCount)
- {
- if (PlsrHostFiniteActive[PlsrHostSelectedPulse] != 0U)
- {
- uint8_t pulseOutput = PlsrHostSelectedPulse;
- while ((pulseCount != 0UL)
- && (PlsrHostFiniteActive[pulseOutput] != 0U))
- {
- uint32_t available = PlsrHostFiniteTarget[pulseOutput]
- - PlsrHostFiniteEmitted[pulseOutput];
- uint32_t emitted = (pulseCount < available)
- ? pulseCount : available;
-
- if ((emitted != 0UL)
- && (PlsrHostFiniteFrequencyPending[pulseOutput] != 0U))
- {
- PlsrHostActiveSetting[pulseOutput] =
- PlsrHostQueuedSetting[pulseOutput];
- PlsrHostFrequency[pulseOutput] =
- PlsrHostQueuedFrequency[pulseOutput];
- PlsrHostFiniteFrequencyPending[pulseOutput] = 0U;
- }
- PlsrHostFiniteEmitted[pulseOutput] += emitted;
- PlsrHostObservedPulses[pulseOutput] += emitted;
- pulseCount -= emitted;
- if (PlsrHostFiniteEmitted[pulseOutput]
- == PlsrHostFiniteTarget[pulseOutput])
- {
- uint16_t index = PlsrHostFiniteStepIndex[pulseOutput];
- uint8_t hasNext = (index + 1U
- < PlsrHostFiniteStepCount[pulseOutput])
- ? 1U : 0U;
-
- if (PlsrHostFiniteStepCount[pulseOutput] != 0U)
- {
- PlsrHostFiniteCompletedStepCount[pulseOutput] =
- (uint16_t)(index + 1U);
- }
- if (hasNext != 0U)
- {
- const PLSR_PLATFORM_FINITE_STEP *next =
- &PlsrHostFiniteSteps[pulseOutput][index + 1U];
-
- PlsrHostFiniteStepIndex[pulseOutput]++;
- PlsrHostFiniteTarget[pulseOutput] = next->pulseCount;
- PlsrHostFiniteEmitted[pulseOutput] = 0UL;
- PlsrHostFrequency[pulseOutput] =
- next->setting.actualFrequencyHz;
- PlsrHostQueuedFrequency[pulseOutput] =
- next->setting.actualFrequencyHz;
- PlsrHostActiveSetting[pulseOutput] = next->setting;
- PlsrHostQueuedSetting[pulseOutput] = next->setting;
- PlsrHostFiniteFrequencyPending[pulseOutput] = 0U;
- }
- else
- {
- PlsrHostFiniteActive[pulseOutput] = 0U;
- PlsrHostFiniteComplete[pulseOutput] = 1U;
- PlsrHostPulseActive[pulseOutput] = 0U;
- PlsrHostFiniteFrequencyPending[pulseOutput] = 0U;
- PlsrHostFrequency[pulseOutput] = 0UL;
- PlsrHostQueuedFrequency[pulseOutput] = 0UL;
- }
- }
- }
- return;
- }
- if (PlsrHostOutputMode[PlsrHostSelectedPulse] == PLSR_OUTPUT_AB)
- {
- while ((pulseCount != 0UL)
- && (PlsrHostPulseActive[PlsrHostSelectedPulse] != 0U))
- {
- PlsrTestEmitAbQuarters(4UL);
- pulseCount--;
- }
- return;
- }
- while ((pulseCount != 0UL)
- && (PlsrHostPulseActive[PlsrHostSelectedPulse] != 0U))
- {
- PlsrHostLatchPulse(PlsrHostSelectedPulse);
- PlsrHostServicePendingPulse(PlsrHostSelectedPulse);
- pulseCount--;
- }
- }
-
- void PlsrTestEnableFinitePulseTrain(uint8_t enable)
- {
- PlsrHostFiniteEnabled = (enable != 0U) ? 1U : 0U;
- }
-
- void PlsrTestCompleteFinitePulseTrain(void)
- {
- uint8_t pulseOutput = PlsrHostSelectedPulse;
-
- if ((PlsrHostFiniteActive[pulseOutput] != 0U)
- && (PlsrHostPulseActive[pulseOutput] != 0U))
- {
- uint32_t remaining = PlsrHostFiniteTarget[pulseOutput]
- - PlsrHostFiniteEmitted[pulseOutput];
-
- PlsrHostFiniteEmitted[pulseOutput] += remaining;
- PlsrHostObservedPulses[pulseOutput] += remaining;
- PlsrHostFiniteActive[pulseOutput] = 0U;
- PlsrHostFiniteComplete[pulseOutput] = 1U;
- PlsrHostPulseActive[pulseOutput] = 0U;
- PlsrHostFrequency[pulseOutput] = 0UL;
- PlsrHostQueuedFrequency[pulseOutput] = 0UL;
- }
- }
-
- uint8_t PlsrTestFinitePulseTrainActive(void)
- {
- return PlsrHostFiniteActive[PlsrHostSelectedPulse];
- }
-
- void PlsrTestEmitPulseOnCriticalEntry(void)
- {
- PlsrHostCriticalEntriesToSkip = 0U;
- PlsrHostEmitPulseOnCriticalEntry = 1U;
- }
-
- void PlsrTestEmitPulseAfterCriticalEntries(uint8_t entriesToSkip)
- {
- PlsrHostCriticalEntriesToSkip = entriesToSkip;
- PlsrHostEmitPulseOnCriticalEntry = 1U;
- }
-
- void PlsrTestEmitPulseOnCriticalExit(void)
- {
- PlsrHostEmitPulseOnCriticalExit = 1U;
- }
-
- void PlsrTestLatchPulseOnCriticalEntry(void)
- {
- PlsrHostLatchPulseOnCriticalEntry = 1U;
- }
-
- void PlsrTestLatchAbFinalQuarterOnNextStopArm(void)
- {
- PlsrHostLatchAbFinalQuarterOnStopArm = 1U;
- }
-
- void PlsrTestCompleteAbCycleOnNextQueueCommit(void)
- {
- PlsrHostCompleteAbCycleOnQueueCommit = 1U;
- }
-
- void PlsrTestServicePendingPulse(void)
- {
- PlsrHostServicePendingPulse(PlsrHostSelectedPulse);
- }
-
- void PlsrTestFailNextStart(void)
- {
- PlsrHostFailNextStart = 1U;
- }
-
- void PlsrTestServiceFinalArmJob(void)
- {
- PlsrHostServiceFinalArmJob();
- }
-
- void PlsrTestDeferFinalArmJob(uint8_t defer)
- {
- PlsrHostDeferFinalArmJob = (defer != 0U) ? 1U : 0U;
- if (PlsrHostDeferFinalArmJob == 0U)
- {
- PlsrHostServiceFinalArmJob();
- }
- }
-
- void PlsrTestStaleNextFrequencyAtUpdate(void)
- {
- PlsrHostStaleNextFrequencyAtUpdate = 1U;
- }
-
- void PlsrTestFailNextFrequencyAtUpdate(void)
- {
- PlsrHostFailNextFrequencyAtUpdate = 1U;
- }
-
- void PlsrTestFailNextStopRequest(void)
- {
- PlsrHostFailNextStopRequest = 1U;
- }
-
- void PlsrTestEmitAbQuarters(uint32_t quarterCount)
- {
- uint8_t pulseOutput = PlsrHostSelectedPulse;
-
- while ((quarterCount != 0UL)
- && (PlsrHostPulseActive[pulseOutput] != 0U)
- && (PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB))
- {
- if (PlsrHostAdvanceAbQuarter(pulseOutput) != 0U)
- {
- PlsrHostServicePendingPulse(pulseOutput);
- }
- quarterCount--;
- }
- }
-
- uint8_t PlsrTestPulseIsActive(void)
- {
- return PlsrHostPulseActive[PlsrHostSelectedPulse];
- }
-
- uint32_t PlsrTestOutputFrequency(void)
- {
- return PlsrHostFrequency[PlsrHostSelectedPulse];
- }
-
- uint32_t PlsrTestQueuedFrequency(void)
- {
- return PlsrHostQueuedFrequency[PlsrHostSelectedPulse];
- }
-
- uint8_t PlsrTestDirectionLevel(void)
- {
- return PlsrHostDirectionLevel;
- }
-
- uint8_t PlsrTestDirectionPinLevel(uint8_t directionOutput)
- {
- return (directionOutput < 4U)
- ? PlsrHostDirectionPinLevel[directionOutput] : 0U;
- }
-
- uint32_t PlsrTestDirectionWriteCount(uint8_t directionOutput)
- {
- return (directionOutput < 4U)
- ? PlsrHostDirectionWriteCount[directionOutput] : 0UL;
- }
-
- uint32_t PlsrTestDirectionTransitionCount(uint8_t directionOutput)
- {
- return (directionOutput < 4U)
- ? PlsrHostDirectionTransitionCount[directionOutput] : 0UL;
- }
-
- uint8_t PlsrTestAbPhase(void)
- {
- return PlsrHostAbPhase[PlsrHostSelectedPulse];
- }
-
- uint32_t PlsrTestAbTransitionCount(void)
- {
- return PlsrHostAbTransitions[PlsrHostSelectedPulse];
- }
-
- uint32_t PlsrTestAbFastGateCount(void)
- {
- return PlsrHostAbFastGateCount;
- }
-
- uint32_t PlsrTestAbCleanupCount(void)
- {
- return PlsrHostAbCleanupCount;
- }
-
- void PlsrTestInjectCountOffset(int32_t offset)
- {
- PlsrHostCountOffset = offset;
- }
-
- void PlsrTestInjectActiveFrequencyOffset(int32_t offsetHz)
- {
- PlsrHostFrequencyOffsetHz = offsetHz;
- PlsrHostDiagnosticFault = 2U;
- }
-
- void PlsrTestInjectCurveMismatch(void)
- {
- PlsrHostCurveMismatchPending = 1U;
- }
-
- void PlsrTestClearPersistentStorage(void)
- {
- (void)memset(&PlsrHostPersistentPayload, 0,
- sizeof(PlsrHostPersistentPayload));
- (void)memset(PlsrHostInputs, 0, sizeof(PlsrHostInputs));
- PlsrHostPersistentValid = 0U;
- PlsrHostSaveCount = 0UL;
- PlsrHostCountOffset = 0L;
- PlsrHostFrequencyOffsetHz = 0L;
- PlsrHostCurveMismatchPending = 0U;
- PlsrHostDiagnosticFault = 0U;
- }
-
- void PlsrTestResetSaveCount(void)
- {
- PlsrHostSaveCount = 0UL;
- }
-
- uint32_t PlsrTestSaveCount(void)
- {
- return PlsrHostSaveCount;
- }
-
- uint8_t PlsrTestFlashNeedsStartupRecovery(
- uint8_t haveValidRecord,
- uint8_t sectorAHasProgrammedSlot,
- uint32_t sectorAFirstErasedAddress,
- uint8_t sectorBHasProgrammedSlot,
- uint32_t sectorBFirstErasedAddress)
- {
- return PlsrFlashNeedsStartupRecovery(
- haveValidRecord,
- sectorAHasProgrammedSlot,
- sectorAFirstErasedAddress,
- sectorBHasProgrammedSlot,
- sectorBFirstErasedAddress);
- }
-
- #else
-
- #include "stm32f4xx_hal.h"
- #include <stddef.h>
- #include <string.h>
-
- #ifndef PLSR_DEBUG_TIMING
- #define PLSR_DEBUG_TIMING (0U)
- #endif
-
- #define PLSR_FLASH_SLOT_A_ADDRESS (0x080C0000UL)
- #define PLSR_FLASH_SLOT_B_ADDRESS (0x080E0000UL)
- #define PLSR_FLASH_SECTOR_SIZE (0x00020000UL)
- #define PLSR_FLASH_MAGIC (0x50534C52UL)
- #define PLSR_FLASH_VERSION_V2 (2U)
- #define PLSR_FLASH_VERSION (3U)
- #define PLSR_BACKUP_CONFIG_ADDRESS (BKPSRAM_BASE + 0x0100UL)
- #define PLSR_BACKUP_POSITION_ADDRESS (BKPSRAM_BASE + 0x0200UL)
- #define PLSR_BACKUP_CONFIG_MAGIC (0x50434647UL)
- #define PLSR_BACKUP_POSITION_MAGIC (0x50504F53UL)
- #define PLSR_CONFIG_V2_SIZE (offsetof(PLSR_CONFIG, outputMode))
- #define PLSR_COUNTER_COUNT (2U)
- #define PLSR_COUNTER_NONE (0xFFU)
- #define PLSR_COUNTER_BLOCK_PULSES (65536UL)
- #define PLSR_PLATFORM_FAULT_FREQUENCY (2U)
- #define PLSR_PLATFORM_FAULT_CURVE (3U)
- #define PLSR_TIMER_OC1_MODE_MASK (7UL << TIM_CCMR1_OC1M_Pos)
- #define PLSR_TIMER_PWM1_MODE (6UL << TIM_CCMR1_OC1M_Pos)
- #define PLSR_STRUCTURE_VERIFY_INTERVAL (64U)
- #define PLSR_FREQUENCY_VERIFY_NONE (0U)
- #define PLSR_FREQUENCY_VERIFY_NOW (1U)
- #define PLSR_FREQUENCY_VERIFY_AB_AUX_IRQ (2U)
- #define PLSR_QUEUE_WRITE_GUARD_COUNTS (64UL)
- #define PLSR_FINITE_WRITE_GUARD_COUNTS (128UL)
- #define PLSR_FLASH_ERASE_NONE (0U)
- #define PLSR_FLASH_ERASE_SECTOR_A (1U)
- #define PLSR_FLASH_ERASE_SECTOR_B (2U)
- #define PLSR_FLASH_ERASE_FAILED (3U)
-
- typedef struct
- {
- TIM_TypeDef *timer;
- GPIO_TypeDef *port;
- uint16_t pin;
- uint8_t pinIndex;
- uint8_t alternate;
- IRQn_Type irq;
- uint32_t timerClockHz;
- } PLSR_TIMER_MAP;
-
- typedef struct
- {
- GPIO_TypeDef *port;
- uint16_t pin;
- } PLSR_GPIO_MAP;
-
- typedef struct
- {
- uint32_t prescaler;
- uint32_t period;
- uint32_t compare;
- uint32_t actualFrequencyHz;
- } PLSR_TIMER_SETTING;
-
- typedef struct
- {
- uint32_t basePrescaler;
- uint32_t pairPrescaler;
- uint32_t period;
- uint32_t compare;
- uint32_t actualFrequencyHz;
- } PLSR_AB_SETTING;
-
- typedef struct
- {
- uint32_t cr1;
- uint32_t ccmr1;
- uint32_t ccer;
- uint32_t psc;
- uint32_t arr;
- uint32_t ccr1;
- } PLSR_TIMER_SNAPSHOT;
-
- typedef struct
- {
- uint32_t magic;
- uint16_t version;
- uint16_t payloadSize;
- uint32_t generation;
- } PLSR_FLASH_HEADER;
-
- typedef struct
- {
- uint8_t config[PLSR_CONFIG_V2_SIZE];
- int32_t position;
- uint8_t positionValid;
- uint8_t wasBusy;
- uint16_t reserved;
- } PLSR_PERSIST_PAYLOAD_V2;
-
- typedef struct
- {
- uint32_t magic;
- uint16_t version;
- uint16_t payloadSize;
- uint32_t generation;
- PLSR_PERSIST_PAYLOAD payload;
- uint32_t crc32;
- } PLSR_FLASH_RECORD;
-
- typedef struct
- {
- uint32_t magic;
- uint16_t version;
- uint16_t payloadSize;
- uint32_t generation;
- PLSR_PERSIST_PAYLOAD_V2 payload;
- uint32_t crc32;
- } PLSR_FLASH_RECORD_V2;
-
- #define PLSR_FLASH_RECORD_STRIDE \
- ((uint32_t)sizeof(PLSR_FLASH_RECORD))
- #define PLSR_FLASH_SLOT_COUNT \
- (PLSR_FLASH_SECTOR_SIZE / PLSR_FLASH_RECORD_STRIDE)
-
- typedef char PLSR_FLASH_RECORD_SIZE_MUST_BE_228[
- (sizeof(PLSR_FLASH_RECORD) == 228U) ? 1 : -1];
-
- typedef struct
- {
- const PLSR_FLASH_HEADER *newest;
- uint32_t firstErasedAddress;
- uint8_t newestVersion;
- uint8_t hasProgrammedSlot;
- } PLSR_FLASH_SECTOR_SCAN;
-
- typedef struct
- {
- uint32_t magic;
- PLSR_CONFIG config;
- uint32_t crc32;
- } PLSR_BACKUP_CONFIG_RECORD;
-
- typedef struct
- {
- uint32_t magic;
- uint8_t config[PLSR_CONFIG_V2_SIZE];
- uint32_t crc32;
- } PLSR_BACKUP_CONFIG_RECORD_V2;
-
- typedef struct
- {
- uint32_t magic;
- uint32_t generation;
- int32_t position;
- uint8_t positionValid;
- uint8_t wasBusy;
- uint16_t reserved;
- uint32_t crc32;
- } PLSR_BACKUP_POSITION_RECORD;
-
- static const PLSR_TIMER_MAP PlsrTimerMap[4] =
- {
- {TIM10, GPIOF, GPIO_PIN_6, 6U, GPIO_AF3_TIM10,
- TIM1_UP_TIM10_IRQn, 168000000UL},
- {TIM13, GPIOF, GPIO_PIN_8, 8U, GPIO_AF9_TIM13,
- TIM8_UP_TIM13_IRQn, 84000000UL},
- {TIM11, GPIOF, GPIO_PIN_7, 7U, GPIO_AF3_TIM11,
- TIM1_TRG_COM_TIM11_IRQn, 168000000UL},
- {TIM14, GPIOF, GPIO_PIN_9, 9U, GPIO_AF9_TIM14,
- TIM8_TRG_COM_TIM14_IRQn, 84000000UL}
- };
-
- static const PLSR_GPIO_MAP PlsrDirectionMap[4] =
- {
- {GPIOH, GPIO_PIN_9},
- {GPIOH, GPIO_PIN_8},
- {GPIOH, GPIO_PIN_7},
- {GPIOH, GPIO_PIN_6}
- };
-
- static PLSR_FLASH_RECORD PlsrFlashRecordBuffer;
- static uint32_t PlsrFlashNewestAddress;
- static uint32_t PlsrFlashNewestGeneration;
- static uint32_t PlsrFlashNextErasedAddress[2];
- static uint8_t PlsrFlashJournalInitialized;
- static uint8_t PlsrFlashReserveEraseState;
- static uint32_t PlsrBackupPositionGeneration;
- static uint32_t PlsrTimerActiveFrequencyHz[4];
- static uint32_t PlsrTimerQueuedFrequencyHz[4];
- static PLSR_PLATFORM_TIMER_SETTING PlsrTimerActiveSetting[4];
- static PLSR_PLATFORM_TIMER_SETTING PlsrTimerQueuedSetting[4];
- static uint32_t PlsrTimerQueueGeneration[4];
- static uint8_t PlsrTimerOutputMode[4];
- static uint8_t PlsrTimerDirectionPositive[4];
- static uint8_t PlsrTimerRunning[4];
- static uint8_t PlsrFrequencyVerifyPending[4];
- static uint8_t PlsrFrequencyVerifyPulseCount[4];
- static volatile uint8_t PlsrDeferredPulsePending[4];
- static volatile uint8_t PlsrAbVerifyOwner[4];
- static volatile uint8_t PlsrAbFinalArmJobOwner[4];
- static uint8_t PlsrTimerIrqActive[4];
- static PLSR_AB_SETTING PlsrAbActiveSetting[4];
- static PLSR_AB_SETTING PlsrAbPendingSetting[4];
- static uint8_t PlsrAbFrequencyPending[4];
- static uint8_t PlsrAbLagAxis[4];
- static uint8_t PlsrAbStructureVerified[4];
- static uint8_t PlsrAbCounterSourceAxis[4];
- static uint32_t PlsrAbCounterBoundary[4];
- static volatile uint8_t PlsrAbStopPending[4];
- static volatile uint8_t PlsrAbFastGated[4];
- static TIM_TypeDef * const PlsrCounters[PLSR_COUNTER_COUNT] =
- {
- TIM9, TIM12
- };
- static uint8_t PlsrCounterOwner[PLSR_COUNTER_COUNT];
- static volatile uint64_t PlsrCounterOverflowPulses[PLSR_COUNTER_COUNT];
- static uint8_t PlsrCounterIndexByOutput[4];
- static uint64_t PlsrObservedPulseBase[4];
- static uint64_t PlsrObservedPulsePublished[4];
- static volatile uint8_t PlsrFiniteActive[4];
- static volatile uint8_t PlsrFiniteCompletionPending[4];
- static volatile uint8_t PlsrFiniteFrequencyPending[4];
- static volatile uint8_t PlsrFiniteRetargetPending[4];
- static volatile uint8_t PlsrFiniteTailStopPending[4];
- static uint32_t PlsrFiniteRetargetDrainPulses[4];
- static uint32_t PlsrFiniteTargetPulses[4];
- static uint32_t PlsrFiniteRemainingPulses[4];
- static uint8_t PlsrFiniteCounterPreload[4];
- static PLSR_PLATFORM_FINITE_STEP *PlsrFiniteSteps[4];
- static volatile uint16_t PlsrFiniteStepCount[4];
- static volatile uint16_t PlsrFiniteStepIndex[4];
- static volatile uint16_t PlsrFiniteBoundaryReadIndex[4];
- static volatile uint16_t PlsrFiniteCompletedStepCount[4];
- static volatile uint16_t PlsrPlatformFaultPending;
-
- static void PlsrHandleTimerIrq(uint8_t pulseOutput);
- static void PlsrCounterSuspend(uint8_t pulseOutput);
- static void PlsrAbFastGate(uint8_t pulseOutput);
- static void PlsrFiniteCounterIrq(uint8_t pulseOutput,
- TIM_TypeDef *counter);
- static void PlsrFinitePrepareNextStepIrq(uint8_t pulseOutput,
- TIM_TypeDef *counter);
- static void PlsrFiniteArmNextStepPrepare(uint8_t pulseOutput,
- TIM_TypeDef *counter,
- uint32_t blockPulses);
- static void PlsrFiniteRetargetAtFallingEdge(uint8_t pulseOutput);
- static void PlsrFiniteStopAtFallingEdge(uint8_t pulseOutput);
-
- static uint8_t PlsrFinalArmJobOutput(uint8_t pulseOutput)
- {
- return (pulseOutput == 0U) ? 2U : 0U;
- }
-
- #if PLSR_DEBUG_TIMING
- volatile uint32_t PlsrIrqCount[4];
- volatile uint32_t PlsrIrqLastCycles[4];
- volatile uint32_t PlsrIrqMaxCycles[4];
- volatile uint32_t PlsrFinalArmQueueCount[4];
- volatile uint32_t PlsrFinalArmJobLastCycles[4];
- volatile uint32_t PlsrFinalArmJobMaxCycles[4];
- volatile uint32_t PlsrFinalArmQueueToStopLastCycles[4];
- volatile uint32_t PlsrFinalArmQueueToStopMaxCycles[4];
- volatile uint32_t PlsrFiniteBlockIrqCount[4];
- volatile uint32_t PlsrFiniteBlockIrqMaxCycles[4];
- volatile uint32_t PlsrFiniteFinalIrqLastCycles[4];
- volatile uint32_t PlsrFiniteFinalIrqMaxCycles[4];
- volatile uint32_t PlsrAbReloadCounterBefore[4];
- volatile uint32_t PlsrAbReloadCounterArmed[4];
- volatile uint32_t PlsrAbReloadCounterStarted[4];
- volatile uint32_t PlsrAbReloadCount[4];
- static volatile uint32_t PlsrFinalArmQueuedAt[4];
- static volatile uint8_t PlsrFinalArmQueueTimingPending[4];
- #endif
-
- static uint32_t PlsrCrc32(const void *data, uint32_t length)
- {
- const uint8_t *bytes = (const uint8_t *)data;
- uint32_t crc = 0xFFFFFFFFUL;
- uint32_t index;
- uint8_t bit;
-
- for (index = 0UL; index < length; index++)
- {
- crc ^= bytes[index];
- for (bit = 0U; bit < 8U; bit++)
- {
- crc = ((crc & 1UL) != 0UL) ? ((crc >> 1U) ^ 0xEDB88320UL)
- : (crc >> 1U);
- }
- }
- return ~crc;
- }
-
- static uint8_t PlsrGenerationIsNewer(uint32_t first, uint32_t second)
- {
- return ((int32_t)(first - second) > 0) ? 1U : 0U;
- }
-
- static uint32_t PlsrFlashRecordCrc(const void *record,
- uint32_t payloadSize)
- {
- const PLSR_FLASH_HEADER *header = (const PLSR_FLASH_HEADER *)record;
- const uint8_t *start = (const uint8_t *)&header->version;
- uint32_t length = (uint32_t)(sizeof(header->version)
- + sizeof(header->payloadSize)
- + sizeof(header->generation))
- + payloadSize;
- return PlsrCrc32(start, length);
- }
-
- static uint8_t PlsrFlashRecordVersion(const void *address)
- {
- const PLSR_FLASH_HEADER *header = (const PLSR_FLASH_HEADER *)address;
-
- if (header->magic != PLSR_FLASH_MAGIC)
- {
- return 0U;
- }
- if ((header->version == PLSR_FLASH_VERSION)
- && (header->payloadSize == sizeof(PLSR_PERSIST_PAYLOAD)))
- {
- const PLSR_FLASH_RECORD *record =
- (const PLSR_FLASH_RECORD *)address;
-
- return (record->crc32
- == PlsrFlashRecordCrc(record, sizeof(record->payload)))
- ? PLSR_FLASH_VERSION : 0U;
- }
- if ((header->version == PLSR_FLASH_VERSION_V2)
- && (header->payloadSize == sizeof(PLSR_PERSIST_PAYLOAD_V2)))
- {
- const PLSR_FLASH_RECORD_V2 *record =
- (const PLSR_FLASH_RECORD_V2 *)address;
-
- return (record->crc32
- == PlsrFlashRecordCrc(record, sizeof(record->payload)))
- ? PLSR_FLASH_VERSION_V2 : 0U;
- }
- return 0U;
- }
-
- static uint8_t PlsrFlashSlotIsErased(uint32_t address)
- {
- const uint32_t *words = (const uint32_t *)address;
- uint32_t index;
-
- for (index = 0UL;
- index < (PLSR_FLASH_RECORD_STRIDE / sizeof(uint32_t));
- index++)
- {
- if (words[index] != 0xFFFFFFFFUL)
- {
- return 0U;
- }
- }
- return 1U;
- }
-
- static uint8_t PlsrFlashSectorIsErased(uint32_t address)
- {
- const uint32_t *words = (const uint32_t *)address;
- uint32_t index;
-
- for (index = 0UL;
- index < (PLSR_FLASH_SECTOR_SIZE / sizeof(uint32_t)); index++)
- {
- if (words[index] != 0xFFFFFFFFUL)
- {
- return 0U;
- }
- }
- return 1U;
- }
-
- static void PlsrFlashScanSector(uint32_t sectorAddress,
- PLSR_FLASH_SECTOR_SCAN *scan)
- {
- uint32_t index;
-
- (void)memset(scan, 0, sizeof(*scan));
- for (index = 0UL; index < PLSR_FLASH_SLOT_COUNT; index++)
- {
- uint32_t slotAddress = sectorAddress
- + index * PLSR_FLASH_RECORD_STRIDE;
- const PLSR_FLASH_HEADER *header =
- (const PLSR_FLASH_HEADER *)slotAddress;
- uint8_t version = PlsrFlashRecordVersion(header);
- uint8_t erased = PlsrFlashSlotIsErased(slotAddress);
-
- if ((version != 0U)
- && ((scan->newest == NULL)
- || (PlsrGenerationIsNewer(header->generation,
- scan->newest->generation) != 0U)))
- {
- scan->newest = header;
- scan->newestVersion = version;
- }
- if ((scan->firstErasedAddress == 0UL) && (erased != 0U))
- {
- scan->firstErasedAddress = slotAddress;
- }
- if (erased == 0U)
- {
- scan->hasProgrammedSlot = 1U;
- }
- }
- for (index = PLSR_FLASH_SLOT_COUNT * PLSR_FLASH_RECORD_STRIDE;
- index < PLSR_FLASH_SECTOR_SIZE; index += sizeof(uint32_t))
- {
- if (*(const uint32_t *)(sectorAddress + index) != 0xFFFFFFFFUL)
- {
- scan->hasProgrammedSlot = 1U;
- }
- }
- }
-
- static const PLSR_FLASH_HEADER *PlsrFlashSelectNewest(
- const PLSR_FLASH_SECTOR_SCAN *scanA,
- const PLSR_FLASH_SECTOR_SCAN *scanB,
- uint8_t *version,
- uint32_t *sectorAddress)
- {
- const PLSR_FLASH_SECTOR_SCAN *selectedScan;
-
- if (scanA->newest == NULL)
- {
- selectedScan = (scanB->newest != NULL) ? scanB : NULL;
- }
- else if ((scanB->newest != NULL)
- && (PlsrGenerationIsNewer(scanB->newest->generation,
- scanA->newest->generation) != 0U))
- {
- selectedScan = scanB;
- }
- else
- {
- selectedScan = scanA;
- }
-
- if (selectedScan == NULL)
- {
- *version = 0U;
- *sectorAddress = 0UL;
- return NULL;
- }
- *version = selectedScan->newestVersion;
- *sectorAddress = (selectedScan == scanA)
- ? PLSR_FLASH_SLOT_A_ADDRESS
- : PLSR_FLASH_SLOT_B_ADDRESS;
- return selectedScan->newest;
- }
-
- static const PLSR_FLASH_HEADER *PlsrFlashInitializeJournal(
- PLSR_FLASH_SECTOR_SCAN *scanA,
- PLSR_FLASH_SECTOR_SCAN *scanB,
- uint8_t *version,
- uint32_t *sectorAddress)
- {
- const PLSR_FLASH_HEADER *newest;
-
- PlsrFlashScanSector(PLSR_FLASH_SLOT_A_ADDRESS, scanA);
- PlsrFlashScanSector(PLSR_FLASH_SLOT_B_ADDRESS, scanB);
- newest = PlsrFlashSelectNewest(scanA, scanB, version, sectorAddress);
- PlsrFlashNextErasedAddress[0] = scanA->firstErasedAddress;
- PlsrFlashNextErasedAddress[1] = scanB->firstErasedAddress;
- PlsrFlashNewestAddress = (uint32_t)newest;
- PlsrFlashNewestGeneration = (newest != NULL)
- ? newest->generation : 0UL;
- PlsrFlashJournalInitialized = 1U;
- return newest;
- }
-
- static uint8_t PlsrFlashSectorIndex(uint32_t address)
- {
- return (address >= PLSR_FLASH_SLOT_B_ADDRESS) ? 1U : 0U;
- }
-
- static uint8_t PlsrFlashAddressIsJournalSlot(uint8_t sectorIndex,
- uint32_t address)
- {
- uint32_t sectorAddress = (sectorIndex == 0U)
- ? PLSR_FLASH_SLOT_A_ADDRESS
- : PLSR_FLASH_SLOT_B_ADDRESS;
- uint32_t offset;
-
- if ((address < sectorAddress)
- || (address >= sectorAddress + PLSR_FLASH_SECTOR_SIZE))
- {
- return 0U;
- }
- offset = address - sectorAddress;
- return ((offset % PLSR_FLASH_RECORD_STRIDE) == 0UL)
- && ((offset / PLSR_FLASH_RECORD_STRIDE)
- < PLSR_FLASH_SLOT_COUNT) ? 1U : 0U;
- }
-
- static uint32_t PlsrFlashFindErasedAfter(uint8_t sectorIndex,
- uint32_t address)
- {
- uint32_t sectorAddress = (sectorIndex == 0U)
- ? PLSR_FLASH_SLOT_A_ADDRESS
- : PLSR_FLASH_SLOT_B_ADDRESS;
- uint32_t firstIndex = ((address - sectorAddress)
- / PLSR_FLASH_RECORD_STRIDE) + 1UL;
- uint32_t index;
-
- for (index = firstIndex; index < PLSR_FLASH_SLOT_COUNT; index++)
- {
- uint32_t slotAddress = sectorAddress
- + index * PLSR_FLASH_RECORD_STRIDE;
-
- if (PlsrFlashSlotIsErased(slotAddress) != 0U)
- {
- return slotAddress;
- }
- }
- return 0UL;
- }
-
- static uint8_t PlsrFlashEraseReserve(uint8_t sectorIndex)
- {
- FLASH_EraseInitTypeDef erase;
- uint32_t sectorError;
- HAL_StatusTypeDef status;
-
- if (HAL_FLASH_Unlock() != HAL_OK)
- {
- (void)HAL_FLASH_Lock();
- return 0U;
- }
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR
- | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR
- | FLASH_FLAG_PGSERR);
- erase.TypeErase = FLASH_TYPEERASE_SECTORS;
- erase.VoltageRange = FLASH_VOLTAGE_RANGE_3;
- erase.Sector = (sectorIndex == 0U) ? FLASH_SECTOR_10 : FLASH_SECTOR_11;
- erase.NbSectors = 1U;
- status = HAL_FLASHEx_Erase(&erase, §orError);
- if ((status == HAL_OK)
- && (PlsrFlashSectorIsErased((sectorIndex == 0U)
- ? PLSR_FLASH_SLOT_A_ADDRESS
- : PLSR_FLASH_SLOT_B_ADDRESS) == 0U))
- {
- status = HAL_ERROR;
- }
- if (HAL_FLASH_Lock() != HAL_OK)
- {
- (void)HAL_FLASH_Lock();
- status = HAL_ERROR;
- }
- return (status == HAL_OK) ? 1U : 0U;
- }
-
- static uint8_t PlsrBackupConfigVersion(const void *address)
- {
- const PLSR_BACKUP_CONFIG_RECORD *record =
- (const PLSR_BACKUP_CONFIG_RECORD *)address;
-
- if (record->magic != PLSR_BACKUP_CONFIG_MAGIC)
- {
- return 0U;
- }
- if (record->crc32 == PlsrCrc32(&record->config, sizeof(record->config)))
- {
- return PLSR_FLASH_VERSION;
- }
- {
- const PLSR_BACKUP_CONFIG_RECORD_V2 *oldRecord =
- (const PLSR_BACKUP_CONFIG_RECORD_V2 *)address;
-
- return (oldRecord->crc32
- == PlsrCrc32(oldRecord->config, sizeof(oldRecord->config)))
- ? PLSR_FLASH_VERSION_V2 : 0U;
- }
- }
-
- static void PlsrLoadV2Payload(PLSR_PERSIST_PAYLOAD *destination,
- const PLSR_PERSIST_PAYLOAD_V2 *source)
- {
- (void)memset(destination, 0, sizeof(*destination));
- (void)memcpy(&destination->config, source->config,
- sizeof(source->config));
- destination->config.outputMode = PLSR_OUTPUT_PULSE_DIR;
- destination->position = source->position;
- destination->positionValid = source->positionValid;
- destination->wasBusy = source->wasBusy;
- }
-
- static uint8_t PlsrBackupPositionIsValid(
- const PLSR_BACKUP_POSITION_RECORD *record)
- {
- uint32_t crc = PlsrCrc32(&record->generation,
- sizeof(record->generation)
- + sizeof(record->position)
- + sizeof(record->positionValid)
- + sizeof(record->wasBusy)
- + sizeof(record->reserved));
- return ((record->magic == PLSR_BACKUP_POSITION_MAGIC)
- && (record->crc32 == crc)) ? 1U : 0U;
- }
-
- static const PLSR_BACKUP_POSITION_RECORD *PlsrNewestBackupPosition(void)
- {
- const PLSR_BACKUP_POSITION_RECORD *slots =
- (const PLSR_BACKUP_POSITION_RECORD *)PLSR_BACKUP_POSITION_ADDRESS;
- uint8_t validA = PlsrBackupPositionIsValid(&slots[0]);
- uint8_t validB = PlsrBackupPositionIsValid(&slots[1]);
-
- if ((validA == 0U) && (validB == 0U))
- {
- return NULL;
- }
- if (validA == 0U)
- {
- return &slots[1];
- }
- if (validB == 0U)
- {
- return &slots[0];
- }
- return (PlsrGenerationIsNewer(slots[1].generation,
- slots[0].generation) != 0U)
- ? &slots[1] : &slots[0];
- }
-
- static void PlsrTimerStop(TIM_TypeDef *timer)
- {
- timer->DIER &= ~(TIM_DIER_UIE | TIM_DIER_CC1IE);
- timer->CR1 &= ~TIM_CR1_CEN;
- timer->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
- timer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
- }
-
- static void PlsrTimerInitialize(TIM_TypeDef *timer)
- {
- timer->CR1 = TIM_CR1_ARPE | TIM_CR1_URS;
- timer->CR2 = 0UL;
- timer->SMCR = 0UL;
- timer->DIER = 0UL;
- timer->CCMR1 = TIM_CCMR1_OC1PE | (6UL << TIM_CCMR1_OC1M_Pos);
- timer->CCER = 0UL;
- timer->PSC = 0UL;
- timer->ARR = 999UL;
- timer->CCR1 = 500UL;
- timer->CNT = 0UL;
- timer->EGR = TIM_EGR_UG;
- timer->SR = 0UL;
- }
-
- static void PlsrPulsePinHoldIdle(uint8_t pulseOutput)
- {
- const PLSR_TIMER_MAP *map = &PlsrTimerMap[pulseOutput];
- GPIO_InitTypeDef gpio;
-
- HAL_GPIO_WritePin(map->port, map->pin, GPIO_PIN_SET);
- gpio.Pin = map->pin;
- gpio.Mode = GPIO_MODE_OUTPUT_PP;
- gpio.Pull = GPIO_NOPULL;
- gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- gpio.Alternate = 0U;
- HAL_GPIO_Init(map->port, &gpio);
- }
-
- static void PlsrPulsePinCaptureIdle(uint8_t pulseOutput)
- {
- const PLSR_TIMER_MAP *map = &PlsrTimerMap[pulseOutput];
- uint32_t shift = (uint32_t)map->pinIndex * 2UL;
- uint32_t mode = map->port->MODER;
-
- /* The update IRQ occurs while PWM is high; switch to GPIO high first. */
- map->port->BSRR = map->pin;
- mode &= ~(3UL << shift);
- mode |= 1UL << shift;
- map->port->MODER = mode;
- __DSB();
- }
-
- static void PlsrPulsePinRelease(uint8_t pulseOutput)
- {
- const PLSR_TIMER_MAP *map = &PlsrTimerMap[pulseOutput];
- GPIO_InitTypeDef gpio;
-
- gpio.Pin = map->pin;
- gpio.Mode = GPIO_MODE_AF_PP;
- gpio.Pull = GPIO_NOPULL;
- gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- gpio.Alternate = map->alternate;
- HAL_GPIO_Init(map->port, &gpio);
- __DSB();
- }
-
- static uint8_t PlsrTimerCalculate(uint8_t pulseOutput,
- uint32_t frequencyHz,
- PLSR_TIMER_SETTING *setting)
- {
- const PLSR_TIMER_MAP *map;
- uint32_t prescalerDivider;
- uint32_t denominator;
- uint32_t periodCounts;
-
- if ((pulseOutput > 3U) || (frequencyHz == 0UL)
- || (frequencyHz > PLSR_FREQUENCY_MAX_HZ)
- || (setting == NULL))
- {
- return 0U;
- }
-
- map = &PlsrTimerMap[pulseOutput];
- prescalerDivider = (((map->timerClockHz - 1UL) / frequencyHz) >> 16U)
- + 1UL;
- if (prescalerDivider > 65536UL)
- {
- return 0U;
- }
- denominator = prescalerDivider * frequencyHz;
- periodCounts = (map->timerClockHz + denominator / 2UL) / denominator;
- if (periodCounts < 2UL)
- {
- periodCounts = 2UL;
- }
- if (periodCounts > 65536UL)
- {
- periodCounts = 65536UL;
- }
-
- setting->prescaler = prescalerDivider - 1UL;
- setting->period = periodCounts - 1UL;
- setting->compare = periodCounts / 2UL;
- denominator = prescalerDivider * periodCounts;
- setting->actualFrequencyHz =
- (map->timerClockHz + denominator / 2UL) / denominator;
- return 1U;
- }
-
- static void PlsrTimerWriteSetting(TIM_TypeDef *timer,
- const PLSR_TIMER_SETTING *setting)
- {
- timer->PSC = setting->prescaler;
- timer->ARR = setting->period;
- timer->CCR1 = setting->compare;
- }
-
- static void PlsrTimerSnapshot(TIM_TypeDef *timer,
- PLSR_TIMER_SNAPSHOT *snapshot)
- {
- snapshot->cr1 = timer->CR1;
- snapshot->ccmr1 = timer->CCMR1;
- snapshot->ccer = timer->CCER;
- snapshot->psc = timer->PSC;
- snapshot->arr = timer->ARR;
- snapshot->ccr1 = timer->CCR1;
- }
-
- static uint8_t PlsrAbCalculate(uint8_t pulseOutput,
- uint32_t frequencyHz,
- PLSR_AB_SETTING *setting)
- {
- const PLSR_TIMER_MAP *baseMap;
- const PLSR_TIMER_MAP *pairMap;
- uint64_t ratio;
- uint64_t pairDivider;
- uint64_t baseDivider;
- uint64_t periodCounts;
-
- if (((pulseOutput != 0U) && (pulseOutput != 2U))
- || (frequencyHz == 0UL)
- || (frequencyHz > PLSR_FREQUENCY_MAX_HZ)
- || (setting == NULL))
- {
- return 0U;
- }
- baseMap = &PlsrTimerMap[pulseOutput];
- pairMap = &PlsrTimerMap[pulseOutput + 1U];
- if ((pairMap->timerClockHz == 0UL)
- || ((baseMap->timerClockHz % pairMap->timerClockHz) != 0UL))
- {
- return 0U;
- }
- ratio = baseMap->timerClockHz / pairMap->timerClockHz;
- pairDivider = ((uint64_t)pairMap->timerClockHz
- + (uint64_t)frequencyHz * 65536UL - 1UL)
- / ((uint64_t)frequencyHz * 65536UL);
- if (pairDivider == 0UL)
- {
- pairDivider = 1UL;
- }
- baseDivider = pairDivider * ratio;
- if ((pairDivider > 65536UL) || (baseDivider > 65536UL))
- {
- return 0U;
- }
- periodCounts = ((uint64_t)pairMap->timerClockHz
- + ((uint64_t)frequencyHz * pairDivider) / 2UL)
- / ((uint64_t)frequencyHz * pairDivider);
- if ((periodCounts < 4UL) || (periodCounts > 65536UL))
- {
- return 0U;
- }
- setting->basePrescaler = (uint32_t)(baseDivider - 1UL);
- setting->pairPrescaler = (uint32_t)(pairDivider - 1UL);
- setting->period = (uint32_t)(periodCounts - 1UL);
- setting->compare = (uint32_t)(periodCounts / 2UL);
- setting->actualFrequencyHz =
- (uint32_t)(((uint64_t)pairMap->timerClockHz
- + (pairDivider * periodCounts) / 2UL)
- / (pairDivider * periodCounts));
- return 1U;
- }
-
- static void PlsrAbHoldPairIdle(uint8_t pulseOutput)
- {
- uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
- GPIO_TypeDef *port = PlsrTimerMap[pulseOutput].port;
- uint32_t firstShift = (uint32_t)PlsrTimerMap[pulseOutput].pinIndex * 2UL;
- uint32_t secondShift = (uint32_t)PlsrTimerMap[pairOutput].pinIndex * 2UL;
- uint32_t mode = port->MODER;
-
- port->BSRR = (uint32_t)PlsrTimerMap[pulseOutput].pin
- | (uint32_t)PlsrTimerMap[pairOutput].pin;
- mode &= ~((3UL << firstShift) | (3UL << secondShift));
- mode |= (1UL << firstShift) | (1UL << secondShift);
- port->MODER = mode;
- __DSB();
- }
-
- static void PlsrAbReleasePair(uint8_t pulseOutput)
- {
- uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
- GPIO_TypeDef *port = PlsrTimerMap[pulseOutput].port;
- uint32_t firstAfrIndex =
- (uint32_t)PlsrTimerMap[pulseOutput].pinIndex >> 3U;
- uint32_t secondAfrIndex =
- (uint32_t)PlsrTimerMap[pairOutput].pinIndex >> 3U;
- uint32_t firstAfrShift =
- ((uint32_t)PlsrTimerMap[pulseOutput].pinIndex & 7UL) * 4UL;
- uint32_t secondAfrShift =
- ((uint32_t)PlsrTimerMap[pairOutput].pinIndex & 7UL) * 4UL;
- uint32_t firstShift = (uint32_t)PlsrTimerMap[pulseOutput].pinIndex * 2UL;
- uint32_t secondShift = (uint32_t)PlsrTimerMap[pairOutput].pinIndex * 2UL;
- uint32_t alternate;
- uint32_t mode = port->MODER;
-
- alternate = port->AFR[firstAfrIndex];
- alternate &= ~(0xFUL << firstAfrShift);
- alternate |= (uint32_t)PlsrTimerMap[pulseOutput].alternate
- << firstAfrShift;
- port->AFR[firstAfrIndex] = alternate;
- alternate = port->AFR[secondAfrIndex];
- alternate &= ~(0xFUL << secondAfrShift);
- alternate |= (uint32_t)PlsrTimerMap[pairOutput].alternate
- << secondAfrShift;
- port->AFR[secondAfrIndex] = alternate;
- mode &= ~((3UL << firstShift) | (3UL << secondShift));
- mode |= (2UL << firstShift) | (2UL << secondShift);
- port->MODER = mode;
- __DSB();
- }
-
- static uint8_t PlsrAbStructureIsRunnable(
- uint8_t pulseOutput,
- const PLSR_TIMER_SNAPSHOT *base,
- const PLSR_TIMER_SNAPSHOT *pair)
- {
- uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
- uint8_t lagOutput = PlsrAbLagAxis[pulseOutput];
-
- return ((((base->cr1 & TIM_CR1_CEN) != 0UL)
- && ((pair->cr1 & TIM_CR1_CEN) != 0UL)
- && ((base->ccer & TIM_CCER_CC1E) != 0UL)
- && ((pair->ccer & TIM_CCER_CC1E) != 0UL)
- && ((base->ccer & TIM_CCER_CC1P) != 0UL)
- && ((pair->ccer & TIM_CCER_CC1P) != 0UL)
- && ((base->ccmr1 & PLSR_TIMER_OC1_MODE_MASK)
- == PLSR_TIMER_PWM1_MODE)
- && ((pair->ccmr1 & PLSR_TIMER_OC1_MODE_MASK)
- == PLSR_TIMER_PWM1_MODE)
- && (base->arr == pair->arr)
- && (base->ccr1 == pair->ccr1)
- && (base->ccr1 == ((base->arr + 1UL) / 2UL))
- && ((base->psc + 1UL) == 2UL * (pair->psc + 1UL))
- && ((lagOutput == pulseOutput) || (lagOutput == pairOutput)))
- ? 1U : 0U);
- }
-
- static uint8_t PlsrAbTimersAreRunnable(uint8_t pulseOutput,
- TIM_TypeDef *baseTimer,
- TIM_TypeDef *pairTimer)
- {
- uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
- uint8_t lagOutput = PlsrAbLagAxis[pulseOutput];
- uint32_t baseCr1 = baseTimer->CR1;
- uint32_t pairCr1 = pairTimer->CR1;
- uint32_t baseCcer = baseTimer->CCER;
- uint32_t pairCcer = pairTimer->CCER;
- uint32_t baseCcmr1 = baseTimer->CCMR1;
- uint32_t pairCcmr1 = pairTimer->CCMR1;
- uint32_t basePsc = baseTimer->PSC;
- uint32_t pairPsc = pairTimer->PSC;
- uint32_t baseCcr1 = baseTimer->CCR1;
- uint32_t pairCcr1 = pairTimer->CCR1;
- uint32_t baseArr = baseTimer->ARR;
- uint32_t pairArr = pairTimer->ARR;
-
- return (((((baseCr1 & TIM_CR1_CEN) != 0UL)
- && ((pairCr1 & TIM_CR1_CEN) != 0UL)
- && ((baseCcer & (TIM_CCER_CC1E | TIM_CCER_CC1P))
- == (TIM_CCER_CC1E | TIM_CCER_CC1P))
- && ((pairCcer & (TIM_CCER_CC1E | TIM_CCER_CC1P))
- == (TIM_CCER_CC1E | TIM_CCER_CC1P))
- && ((baseCcmr1 & PLSR_TIMER_OC1_MODE_MASK)
- == PLSR_TIMER_PWM1_MODE)
- && ((pairCcmr1 & PLSR_TIMER_OC1_MODE_MASK)
- == PLSR_TIMER_PWM1_MODE)
- && (baseArr == pairArr)
- && (baseCcr1 == pairCcr1)
- && (baseCcr1 == ((baseArr + 1UL) / 2UL))
- && ((basePsc + 1UL) == 2UL * (pairPsc + 1UL))
- && ((lagOutput == pulseOutput)
- || (lagOutput == pairOutput))) ? 1U : 0U));
- }
-
- static uint8_t PlsrAbStopBoundaryIsReachable(
- uint8_t pulseOutput,
- TIM_TypeDef *baseTimer,
- TIM_TypeDef *pairTimer)
- {
- uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
- uint8_t lagOutput = PlsrAbLagAxis[pulseOutput];
- uint32_t baseCr1 = baseTimer->CR1;
- uint32_t pairCr1 = pairTimer->CR1;
- uint32_t baseCcer = baseTimer->CCER;
- uint32_t pairCcer = pairTimer->CCER;
- uint32_t baseCcr1 = baseTimer->CCR1;
- uint32_t pairCcr1 = pairTimer->CCR1;
- uint32_t baseArr = baseTimer->ARR;
- uint32_t pairArr = pairTimer->ARR;
-
- return (((((baseCr1 & TIM_CR1_CEN) != 0UL)
- && ((pairCr1 & TIM_CR1_CEN) != 0UL)
- && ((baseCcer & TIM_CCER_CC1E) != 0UL)
- && ((pairCcer & TIM_CCER_CC1E) != 0UL)
- && (baseCcr1 <= baseArr)
- && (pairCcr1 <= pairArr)
- && ((lagOutput == pulseOutput)
- || (lagOutput == pairOutput))) ? 1U : 0U));
- }
-
- static void PlsrAbFastGate(uint8_t pulseOutput)
- {
- uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
- TIM_TypeDef *baseTimer = PlsrTimerMap[pulseOutput].timer;
- TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
-
- PlsrAbStructureVerified[pulseOutput] = 0U;
- baseTimer->CR1 &= ~TIM_CR1_CEN;
- pairTimer->CR1 &= ~TIM_CR1_CEN;
- PlsrCounterSuspend(pulseOutput);
- __DMB();
- }
-
- #if defined(__ICCARM__)
- #pragma inline=never
- #endif
- static void PlsrAbEnableTimerPair(TIM_TypeDef *firstTimer,
- uint32_t firstCr1,
- TIM_TypeDef *secondTimer,
- uint32_t secondCr1)
- {
- firstTimer->CR1 = firstCr1;
- secondTimer->CR1 = secondCr1;
- }
-
- static uint8_t PlsrAbCanFastGateAtZero(uint8_t pulseOutput)
- {
- uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
- TIM_TypeDef *baseTimer = PlsrTimerMap[pulseOutput].timer;
- TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
- uint32_t baseCr1 = baseTimer->CR1;
- uint32_t pairCr1 = pairTimer->CR1;
- uint32_t baseCcer = baseTimer->CCER;
- uint32_t pairCcer = pairTimer->CCER;
- uint32_t baseCcr = baseTimer->CCR1;
- uint32_t pairCcr = pairTimer->CCR1;
- uint32_t baseCnt = baseTimer->CNT;
- uint32_t pairCnt = pairTimer->CNT;
-
- return ((((baseCr1 & TIM_CR1_CEN) != 0UL)
- && ((pairCr1 & TIM_CR1_CEN) != 0UL)
- && ((baseCcer & TIM_CCER_CC1E) != 0UL)
- && ((pairCcer & TIM_CCER_CC1E) != 0UL)
- && (baseCnt >= baseCcr)
- && (pairCnt >= pairCcr)) ? 1U : 0U);
- }
-
- static uint8_t PlsrCounterIndex(uint8_t pulseOutput, uint8_t outputMode)
- {
- return (outputMode == PLSR_OUTPUT_AB)
- ? (uint8_t)(pulseOutput >> 1U)
- : (uint8_t)(pulseOutput & 1U);
- }
-
- static uint64_t PlsrCounterCurrentRaw(uint8_t pulseOutput)
- {
- uint8_t index = PlsrCounterIndexByOutput[pulseOutput];
- TIM_TypeDef *counter;
- uint64_t overflowBefore;
- uint64_t overflowAfter;
- uint32_t statusBefore;
- uint32_t statusAfter;
- uint32_t count;
-
- if (index >= PLSR_COUNTER_COUNT)
- {
- return 0UL;
- }
- counter = PlsrCounters[index];
- for (;;)
- {
- overflowBefore = PlsrCounterOverflowPulses[index];
- statusBefore = counter->SR & TIM_SR_UIF;
- count = (uint16_t)counter->CNT;
- statusAfter = counter->SR & TIM_SR_UIF;
- overflowAfter = PlsrCounterOverflowPulses[index];
- if ((overflowBefore == overflowAfter)
- && (statusBefore == statusAfter))
- {
- if (statusAfter != 0UL)
- {
- overflowAfter += PLSR_COUNTER_BLOCK_PULSES;
- }
- return overflowAfter + count;
- }
- }
- }
-
- static uint64_t PlsrCounterSnapshot(uint8_t pulseOutput)
- {
- uint64_t current = PlsrCounterCurrentRaw(pulseOutput);
- uint64_t observed;
-
- if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- && (current > 0UL))
- {
- uint8_t sourceAxis = PlsrAbCounterSourceAxis[pulseOutput];
- uint8_t attempt;
-
- for (attempt = 0U; attempt < 2U; attempt++)
- {
- uint64_t verified;
-
- current = PlsrCounterCurrentRaw(pulseOutput);
- if (sourceAxis <= 3U)
- {
- uint32_t sourceCount = PlsrTimerMap[sourceAxis].timer->CNT;
-
- verified = PlsrCounterCurrentRaw(pulseOutput);
- if (current == verified)
- {
- if ((sourceCount
- < PlsrAbCounterBoundary[pulseOutput])
- && (current > 0UL))
- {
- current--;
- }
- break;
- }
- current = verified;
- }
- }
- }
- observed = PlsrObservedPulseBase[pulseOutput] + current;
- if (observed < PlsrObservedPulsePublished[pulseOutput])
- {
- observed = PlsrObservedPulsePublished[pulseOutput];
- }
- else
- {
- PlsrObservedPulsePublished[pulseOutput] = observed;
- }
- return observed;
- }
-
- static uint64_t PlsrCounterSnapshotStopped(uint8_t pulseOutput)
- {
- uint8_t index = PlsrCounterIndexByOutput[pulseOutput];
- TIM_TypeDef *counter = PlsrCounters[index];
- uint64_t current = PlsrCounterOverflowPulses[index];
- uint64_t observed;
-
- current += (uint16_t)counter->CNT;
- if ((counter->SR & TIM_SR_UIF) != 0UL)
- {
- current += PLSR_COUNTER_BLOCK_PULSES;
- }
- if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- && (current > 0UL))
- {
- uint8_t sourceAxis = PlsrAbCounterSourceAxis[pulseOutput];
-
- if ((sourceAxis <= 3U)
- && (PlsrTimerMap[sourceAxis].timer->CNT
- < PlsrAbCounterBoundary[pulseOutput]))
- {
- current--;
- }
- }
- observed = PlsrObservedPulseBase[pulseOutput] + current;
- if (observed < PlsrObservedPulsePublished[pulseOutput])
- {
- observed = PlsrObservedPulsePublished[pulseOutput];
- }
- else
- {
- PlsrObservedPulsePublished[pulseOutput] = observed;
- }
- return observed;
- }
-
- static void PlsrCounterStop(uint8_t pulseOutput)
- {
- uint8_t index = PlsrCounterIndexByOutput[pulseOutput];
-
- if (index < PLSR_COUNTER_COUNT)
- {
- TIM_TypeDef *counter = PlsrCounters[index];
-
- if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- && (PlsrAbFastGated[pulseOutput] != 0U))
- {
- PlsrObservedPulseBase[pulseOutput] =
- PlsrCounterSnapshotStopped(pulseOutput);
- }
- else
- {
- PlsrCounterSuspend(pulseOutput);
- PlsrObservedPulseBase[pulseOutput] =
- PlsrCounterSnapshot(pulseOutput);
- }
- PlsrObservedPulsePublished[pulseOutput] =
- PlsrObservedPulseBase[pulseOutput];
-
- counter->CR1 = 0UL;
- counter->DIER = 0UL;
- counter->SMCR = 0UL;
- counter->SR = 0UL;
- if (PlsrCounterOwner[index] == pulseOutput)
- {
- PlsrCounterOwner[index] = PLSR_COUNTER_NONE;
- }
- }
- PlsrCounterIndexByOutput[pulseOutput] = PLSR_COUNTER_NONE;
- }
-
- static uint8_t PlsrCounterConfigure(uint8_t pulseOutput, uint8_t outputMode)
- {
- uint8_t index = PlsrCounterIndex(pulseOutput, outputMode);
- TIM_TypeDef *counter = PlsrCounters[index];
- uint32_t triggerSelection = ((pulseOutput & 2U) == 0U)
- ? TIM_SMCR_TS_1
- : (TIM_SMCR_TS_1 | TIM_SMCR_TS_0);
-
- PlsrCounterStop(pulseOutput);
- if ((PlsrCounterOwner[index] != PLSR_COUNTER_NONE)
- && (PlsrCounterOwner[index] != pulseOutput))
- {
- return 0U;
- }
- PlsrCounterOwner[index] = pulseOutput;
- PlsrCounterIndexByOutput[pulseOutput] = index;
- PlsrCounterOverflowPulses[index] = 0UL;
- counter->CR1 = 0UL;
- counter->DIER = 0UL;
- counter->SMCR = 0UL;
- counter->PSC = 0UL;
- counter->ARR = 0xFFFFUL;
- counter->CNT = 0UL;
- counter->EGR = TIM_EGR_UG;
- counter->SR = 0UL;
- /* RM0090 table 101 routes TIM10/11/13/14 OC directly to ITR2/3. */
- counter->SMCR = triggerSelection;
- counter->DIER = TIM_DIER_UIE;
- return 1U;
- }
-
- static void PlsrCounterBegin(uint8_t pulseOutput)
- {
- uint8_t index = PlsrCounterIndexByOutput[pulseOutput];
-
- if (index < PLSR_COUNTER_COUNT)
- {
- TIM_TypeDef *counter = PlsrCounters[index];
-
- counter->SMCR |= TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0;
- counter->CR1 |= TIM_CR1_CEN;
- }
- }
-
- static void PlsrCounterSuspend(uint8_t pulseOutput)
- {
- uint8_t index = PlsrCounterIndexByOutput[pulseOutput];
-
- if (index < PLSR_COUNTER_COUNT)
- {
- PlsrCounters[index]->CR1 &= ~TIM_CR1_CEN;
- PlsrCounters[index]->SMCR &=
- ~(TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0);
- }
- }
-
- static void PlsrAbLoadAndStart(uint8_t pulseOutput,
- const PLSR_AB_SETTING *setting)
- {
- uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
- uint8_t leadOutput =
- (PlsrTimerDirectionPositive[pulseOutput] != 0U)
- ? pulseOutput : pairOutput;
- uint8_t lagOutput = (leadOutput == pulseOutput)
- ? pairOutput : pulseOutput;
- TIM_TypeDef *baseTimer = PlsrTimerMap[pulseOutput].timer;
- TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
- TIM_TypeDef *counterSourceTimer;
- TIM_TypeDef *otherTimer;
- uint32_t periodCounts = setting->period + 1UL;
- uint32_t leadStart = (periodCounts * 3UL) / 4UL + 1UL;
- uint32_t lagStart = periodCounts / 2UL + 1UL;
- uint32_t counterSourceCr1;
- uint32_t otherCr1;
- #if PLSR_DEBUG_TIMING
- uint8_t debugCounterIndex = PlsrCounterIndexByOutput[pulseOutput];
- uint8_t debugReload = PlsrTimerRunning[pulseOutput];
-
- if ((debugReload != 0U) && (debugCounterIndex < PLSR_COUNTER_COUNT))
- {
- PlsrAbReloadCounterBefore[pulseOutput] =
- (uint16_t)PlsrCounters[debugCounterIndex]->CNT;
- PlsrAbReloadCount[pulseOutput]++;
- }
- #endif
-
- if (leadStart >= periodCounts)
- {
- leadStart = periodCounts - 1UL;
- }
- if (lagStart >= periodCounts)
- {
- lagStart = periodCounts - 1UL;
- }
- PlsrAbStructureVerified[pulseOutput] = 0U;
- PlsrAbLagAxis[pulseOutput] = lagOutput;
- PlsrAbCounterSourceAxis[pulseOutput] =
- (pulseOutput == 0U) ? pulseOutput : pairOutput;
- PlsrAbCounterBoundary[pulseOutput] =
- (PlsrAbCounterSourceAxis[pulseOutput] == leadOutput)
- ? (leadStart - 1UL) : (periodCounts / 2UL);
-
- PlsrCounterSuspend(pulseOutput);
- baseTimer->CR1 &= ~TIM_CR1_CEN;
- pairTimer->CR1 &= ~TIM_CR1_CEN;
- PlsrAbHoldPairIdle(pulseOutput);
- baseTimer->CCER &= ~TIM_CCER_CC1E;
- pairTimer->CCER &= ~TIM_CCER_CC1E;
- baseTimer->DIER = 0UL;
- pairTimer->DIER = 0UL;
- baseTimer->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE;
- pairTimer->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE;
- baseTimer->PSC = setting->basePrescaler;
- pairTimer->PSC = setting->pairPrescaler;
- baseTimer->ARR = setting->period;
- pairTimer->ARR = setting->period;
- baseTimer->CCR1 = setting->compare;
- pairTimer->CCR1 = setting->compare;
- baseTimer->CR1 = TIM_CR1_ARPE | TIM_CR1_URS;
- pairTimer->CR1 = TIM_CR1_ARPE | TIM_CR1_URS;
- baseTimer->EGR = TIM_EGR_UG;
- pairTimer->EGR = TIM_EGR_UG;
- baseTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
- pairTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
- PlsrTimerMap[leadOutput].timer->CNT = leadStart;
- PlsrTimerMap[lagOutput].timer->CNT = lagStart;
- baseTimer->CCER = (baseTimer->CCER
- & ~(TIM_CCER_CC1P | TIM_CCER_CC1E))
- | TIM_CCER_CC1P | TIM_CCER_CC1E;
- pairTimer->CCER = (pairTimer->CCER
- & ~(TIM_CCER_CC1P | TIM_CCER_CC1E))
- | TIM_CCER_CC1P | TIM_CCER_CC1E;
- PlsrAbReleasePair(pulseOutput);
- baseTimer->CCMR1 = TIM_CCMR1_OC1PE
- | (6UL << TIM_CCMR1_OC1M_Pos);
- pairTimer->CCMR1 = TIM_CCMR1_OC1PE
- | (6UL << TIM_CCMR1_OC1M_Pos);
- PlsrCounterBegin(pulseOutput);
- #if PLSR_DEBUG_TIMING
- if ((debugReload != 0U) && (debugCounterIndex < PLSR_COUNTER_COUNT))
- {
- PlsrAbReloadCounterArmed[pulseOutput] =
- (uint16_t)PlsrCounters[debugCounterIndex]->CNT;
- }
- #endif
- counterSourceTimer =
- PlsrTimerMap[PlsrAbCounterSourceAxis[pulseOutput]].timer;
- otherTimer =
- PlsrTimerMap[(PlsrAbCounterSourceAxis[pulseOutput] == pulseOutput)
- ? pairOutput : pulseOutput].timer;
- counterSourceCr1 = counterSourceTimer->CR1 | TIM_CR1_CEN;
- otherCr1 = otherTimer->CR1 | TIM_CR1_CEN;
- PlsrAbEnableTimerPair(counterSourceTimer, counterSourceCr1,
- otherTimer, otherCr1);
- #if PLSR_DEBUG_TIMING
- if ((debugReload != 0U) && (debugCounterIndex < PLSR_COUNTER_COUNT))
- {
- __DSB();
- PlsrAbReloadCounterStarted[pulseOutput] =
- (uint16_t)PlsrCounters[debugCounterIndex]->CNT;
- }
- #endif
- baseTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
- pairTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
- PlsrTimerMap[lagOutput].timer->DIER |= TIM_DIER_CC1IE;
- __DMB();
- }
-
- static void PlsrAbScheduleFrequencyVerify(uint8_t pulseOutput)
- {
- uint8_t verifyOutput =
- (PlsrAbLagAxis[pulseOutput] == pulseOutput)
- ? (uint8_t)(pulseOutput + 1U) : pulseOutput;
- TIM_TypeDef *verifyTimer = PlsrTimerMap[verifyOutput].timer;
-
- PlsrFrequencyVerifyPending[pulseOutput] =
- PLSR_FREQUENCY_VERIFY_AB_AUX_IRQ;
- PlsrAbVerifyOwner[verifyOutput] = pulseOutput;
- verifyTimer->SR = ~TIM_SR_UIF;
- verifyTimer->DIER |= TIM_DIER_UIE;
- if (PlsrDeferredPulsePending[pulseOutput] != 0U)
- {
- verifyTimer->SR = ~TIM_SR_CC1IF;
- verifyTimer->DIER |= TIM_DIER_CC1IE;
- }
- __DMB();
- }
-
- static uint32_t PlsrFrequencyFromSnapshot(
- uint8_t pulseOutput,
- const PLSR_TIMER_SNAPSHOT *snapshot)
- {
- uint64_t divider = ((uint64_t)snapshot->psc + 1UL)
- * ((uint64_t)snapshot->arr + 1UL);
-
- if (divider == 0UL)
- {
- return 0UL;
- }
- return (uint32_t)(((uint64_t)PlsrTimerMap[pulseOutput].timerClockHz
- + divider / 2UL)
- / divider);
- }
-
- static uint32_t PlsrVerifyActiveFrequency(uint8_t pulseOutput)
- {
- TIM_TypeDef *baseTimer = PlsrTimerMap[pulseOutput].timer;
- PLSR_TIMER_SNAPSHOT baseSnapshot;
- uint32_t activeFrequency = PlsrTimerActiveFrequencyHz[pulseOutput];
-
- PlsrTimerSnapshot(baseTimer, &baseSnapshot);
-
- if (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- {
- uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
- TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
- PLSR_TIMER_SNAPSHOT pairSnapshot;
- uint8_t structureValid;
-
- PlsrTimerSnapshot(pairTimer, &pairSnapshot);
- structureValid = PlsrAbStructureIsRunnable(
- pulseOutput, &baseSnapshot, &pairSnapshot);
- PlsrAbStructureVerified[pulseOutput] = structureValid;
-
- if (structureValid == 0U)
- {
- PlsrPlatformFaultPending = PLSR_PLATFORM_FAULT_CURVE;
- }
- if ((baseSnapshot.psc
- != PlsrAbActiveSetting[pulseOutput].basePrescaler)
- || (pairSnapshot.psc
- != PlsrAbActiveSetting[pulseOutput].pairPrescaler)
- || (baseSnapshot.arr
- != PlsrAbActiveSetting[pulseOutput].period)
- || (pairSnapshot.arr
- != PlsrAbActiveSetting[pulseOutput].period)
- || (baseSnapshot.ccr1
- != PlsrAbActiveSetting[pulseOutput].compare)
- || (pairSnapshot.ccr1
- != PlsrAbActiveSetting[pulseOutput].compare))
- {
- activeFrequency = PlsrFrequencyFromSnapshot(pairOutput,
- &pairSnapshot);
- if (PlsrPlatformFaultPending != PLSR_PLATFORM_FAULT_CURVE)
- {
- PlsrPlatformFaultPending = PLSR_PLATFORM_FAULT_FREQUENCY;
- }
- }
- }
- else
- {
- uint8_t structureValid =
- ((((baseSnapshot.cr1 & TIM_CR1_CEN) != 0UL)
- && ((baseSnapshot.ccer & TIM_CCER_CC1E) != 0UL)
- && ((baseSnapshot.ccer & TIM_CCER_CC1P) == 0UL)
- && ((baseSnapshot.ccmr1 & PLSR_TIMER_OC1_MODE_MASK)
- == PLSR_TIMER_PWM1_MODE)
- && (baseSnapshot.ccr1
- == ((baseSnapshot.arr + 1UL) / 2UL)))
- ? 1U : 0U);
-
- if (structureValid == 0U)
- {
- PlsrPlatformFaultPending = PLSR_PLATFORM_FAULT_CURVE;
- }
- if ((baseSnapshot.psc
- != PlsrTimerQueuedSetting[pulseOutput].prescaler)
- || (baseSnapshot.arr
- != PlsrTimerQueuedSetting[pulseOutput].period)
- || (baseSnapshot.ccr1
- != PlsrTimerQueuedSetting[pulseOutput].compare))
- {
- activeFrequency = PlsrFrequencyFromSnapshot(pulseOutput,
- &baseSnapshot);
- if (PlsrPlatformFaultPending != PLSR_PLATFORM_FAULT_CURVE)
- {
- PlsrPlatformFaultPending = PLSR_PLATFORM_FAULT_FREQUENCY;
- }
- }
- }
- if (activeFrequency == 0UL)
- {
- PlsrPlatformFaultPending = PLSR_PLATFORM_FAULT_FREQUENCY;
- }
- return activeFrequency;
- }
-
- uint8_t PlsrPlatformInit(void)
- {
- GPIO_InitTypeDef gpio;
- uint8_t index;
- const PLSR_BACKUP_POSITION_RECORD *positionRecord;
-
- PlsrFlashReserveEraseState = PLSR_FLASH_ERASE_NONE;
- __HAL_RCC_GPIOB_CLK_ENABLE();
- __HAL_RCC_GPIOF_CLK_ENABLE();
- __HAL_RCC_GPIOG_CLK_ENABLE();
- __HAL_RCC_GPIOH_CLK_ENABLE();
- __HAL_RCC_TIM10_CLK_ENABLE();
- __HAL_RCC_TIM11_CLK_ENABLE();
- __HAL_RCC_TIM13_CLK_ENABLE();
- __HAL_RCC_TIM14_CLK_ENABLE();
- __HAL_RCC_TIM9_CLK_ENABLE();
- __HAL_RCC_TIM12_CLK_ENABLE();
- __HAL_RCC_PWR_CLK_ENABLE();
- HAL_PWR_EnableBkUpAccess();
- __HAL_RCC_BKPSRAM_CLK_ENABLE();
- if (HAL_PWREx_EnableBkUpReg() != HAL_OK)
- {
- return 0U;
- }
-
- #if PLSR_DEBUG_TIMING
- CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
- DWT->CYCCNT = 0UL;
- DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
- (void)memset((void *)PlsrIrqCount, 0, sizeof(PlsrIrqCount));
- (void)memset((void *)PlsrIrqLastCycles, 0, sizeof(PlsrIrqLastCycles));
- (void)memset((void *)PlsrIrqMaxCycles, 0, sizeof(PlsrIrqMaxCycles));
- (void)memset((void *)PlsrFinalArmQueueCount, 0,
- sizeof(PlsrFinalArmQueueCount));
- (void)memset((void *)PlsrFinalArmJobLastCycles, 0,
- sizeof(PlsrFinalArmJobLastCycles));
- (void)memset((void *)PlsrFinalArmJobMaxCycles, 0,
- sizeof(PlsrFinalArmJobMaxCycles));
- (void)memset((void *)PlsrFinalArmQueueToStopLastCycles, 0,
- sizeof(PlsrFinalArmQueueToStopLastCycles));
- (void)memset((void *)PlsrFinalArmQueueToStopMaxCycles, 0,
- sizeof(PlsrFinalArmQueueToStopMaxCycles));
- (void)memset((void *)PlsrFinalArmQueuedAt, 0,
- sizeof(PlsrFinalArmQueuedAt));
- (void)memset((void *)PlsrFinalArmQueueTimingPending, 0,
- sizeof(PlsrFinalArmQueueTimingPending));
- #endif
-
- HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8
- | GPIO_PIN_9, GPIO_PIN_SET);
- gpio.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9;
- gpio.Mode = GPIO_MODE_OUTPUT_PP;
- gpio.Pull = GPIO_NOPULL;
- gpio.Speed = GPIO_SPEED_FREQ_HIGH;
- gpio.Alternate = 0U;
- HAL_GPIO_Init(GPIOH, &gpio);
-
- gpio.Mode = GPIO_MODE_INPUT;
- gpio.Pull = GPIO_NOPULL;
- gpio.Speed = GPIO_SPEED_FREQ_LOW;
- gpio.Alternate = 0U;
- gpio.Pin = GPIO_PIN_5;
- HAL_GPIO_Init(GPIOB, &gpio);
- gpio.Pin = GPIO_PIN_12;
- HAL_GPIO_Init(GPIOG, &gpio);
-
- for (index = 0U; index < 4U; index++)
- {
- PlsrTimerActiveFrequencyHz[index] = 0UL;
- PlsrTimerQueuedFrequencyHz[index] = 0UL;
- (void)memset(&PlsrTimerActiveSetting[index], 0,
- sizeof(PlsrTimerActiveSetting[index]));
- (void)memset(&PlsrTimerQueuedSetting[index], 0,
- sizeof(PlsrTimerQueuedSetting[index]));
- PlsrTimerQueueGeneration[index] = 0UL;
- PlsrTimerOutputMode[index] = PLSR_OUTPUT_PULSE_DIR;
- PlsrTimerDirectionPositive[index] = 1U;
- PlsrTimerRunning[index] = 0U;
- PlsrFrequencyVerifyPending[index] = 0U;
- PlsrFrequencyVerifyPulseCount[index] = 0U;
- PlsrDeferredPulsePending[index] = 0U;
- PlsrAbVerifyOwner[index] = PLSR_COUNTER_NONE;
- PlsrAbFinalArmJobOwner[index] = PLSR_COUNTER_NONE;
- PlsrTimerIrqActive[index] = 0U;
- PlsrAbFrequencyPending[index] = 0U;
- PlsrAbLagAxis[index] = PLSR_COUNTER_NONE;
- PlsrAbStructureVerified[index] = 0U;
- PlsrAbCounterSourceAxis[index] = PLSR_COUNTER_NONE;
- PlsrAbCounterBoundary[index] = 0UL;
- PlsrAbStopPending[index] = 0U;
- PlsrAbFastGated[index] = 0U;
- PlsrCounterIndexByOutput[index] = PLSR_COUNTER_NONE;
- PlsrObservedPulseBase[index] = 0UL;
- PlsrObservedPulsePublished[index] = 0UL;
- PlsrFiniteActive[index] = 0U;
- PlsrFiniteCompletionPending[index] = 0U;
- PlsrFiniteFrequencyPending[index] = 0U;
- PlsrFiniteRetargetPending[index] = 0U;
- PlsrFiniteTailStopPending[index] = 0U;
- PlsrFiniteRetargetDrainPulses[index] = 0UL;
- PlsrFiniteTargetPulses[index] = 0UL;
- PlsrFiniteRemainingPulses[index] = 0UL;
- PlsrFiniteCounterPreload[index] = 0U;
- PlsrFiniteStepCount[index] = 0U;
- PlsrFiniteStepIndex[index] = 0U;
- PlsrFiniteBoundaryReadIndex[index] = 0U;
- PlsrFiniteCompletedStepCount[index] = 0U;
- PlsrTimerInitialize(PlsrTimerMap[index].timer);
- PlsrPulsePinHoldIdle(index);
- HAL_NVIC_SetPriority(PlsrTimerMap[index].irq, 0U, 0U);
- HAL_NVIC_EnableIRQ(PlsrTimerMap[index].irq);
- }
- for (index = 0U; index < PLSR_COUNTER_COUNT; index++)
- {
- PlsrCounterOwner[index] = PLSR_COUNTER_NONE;
- PlsrCounterOverflowPulses[index] = 0UL;
- PlsrCounters[index]->CR1 = 0UL;
- PlsrCounters[index]->DIER = 0UL;
- PlsrCounters[index]->SMCR = 0UL;
- PlsrCounters[index]->SR = 0UL;
- }
- PlsrPlatformFaultPending = 0U;
- HAL_NVIC_SetPriority(TIM1_BRK_TIM9_IRQn, 0U, 0U);
- HAL_NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn);
- HAL_NVIC_SetPriority(TIM8_BRK_TIM12_IRQn, 0U, 0U);
- HAL_NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn);
-
- positionRecord = PlsrNewestBackupPosition();
- PlsrBackupPositionGeneration =
- (positionRecord == NULL) ? 0UL : positionRecord->generation;
- return 1U;
- }
-
- uint8_t PlsrPlatformPrepare(uint8_t pulseOutput,
- uint8_t directionOutput,
- uint8_t directionLevel,
- uint8_t outputMode,
- uint8_t directionPositive)
- {
- uint8_t index;
-
- if ((pulseOutput > 3U) || (directionOutput > 3U)
- || (outputMode > PLSR_OUTPUT_AB)
- || ((outputMode == PLSR_OUTPUT_AB)
- && (pulseOutput != 0U) && (pulseOutput != 2U)))
- {
- return 0U;
- }
- if ((PlsrAbStopPending[0] != 0U) || (PlsrAbStopPending[2] != 0U))
- {
- return 0U;
- }
- for (index = 0U; index < 4U; index++)
- {
- PlsrAbFinalArmJobOwner[index] = PLSR_COUNTER_NONE;
- NVIC_ClearPendingIRQ(PlsrTimerMap[index].irq);
- PlsrCounterStop(index);
- PlsrPulsePinHoldIdle(index);
- PlsrTimerStop(PlsrTimerMap[index].timer);
- HAL_GPIO_WritePin(PlsrDirectionMap[index].port,
- PlsrDirectionMap[index].pin,
- ((outputMode == PLSR_OUTPUT_PULSE_DIR)
- && (index == directionOutput)
- && (directionLevel != 0U))
- ? GPIO_PIN_RESET : GPIO_PIN_SET);
- PlsrTimerRunning[index] = 0U;
- PlsrFrequencyVerifyPending[index] = 0U;
- PlsrFrequencyVerifyPulseCount[index] = 0U;
- PlsrDeferredPulsePending[index] = 0U;
- PlsrAbVerifyOwner[index] = PLSR_COUNTER_NONE;
- PlsrAbFrequencyPending[index] = 0U;
- PlsrAbStructureVerified[index] = 0U;
- PlsrAbFastGated[index] = 0U;
- }
- PlsrTimerOutputMode[pulseOutput] = outputMode;
- PlsrTimerDirectionPositive[pulseOutput] =
- (directionPositive != 0U) ? 1U : 0U;
- PlsrPlatformFaultPending = 0U;
- return 1U;
- }
-
- uint8_t PlsrPlatformStartPulse(uint8_t pulseOutput,
- uint32_t firstFrequencyHz,
- uint32_t queuedFrequencyHz,
- uint32_t *actualFirstFrequencyHz,
- uint32_t *actualQueuedFrequencyHz)
- {
- PLSR_PLATFORM_TIMER_SETTING firstSetting;
- PLSR_PLATFORM_TIMER_SETTING queuedSetting;
-
- if ((pulseOutput > 3U)
- || (PlsrPlatformBuildTimerSetting(
- pulseOutput, PlsrTimerOutputMode[pulseOutput],
- firstFrequencyHz, &firstSetting) == 0U)
- || (PlsrPlatformBuildTimerSetting(
- pulseOutput, PlsrTimerOutputMode[pulseOutput],
- queuedFrequencyHz, &queuedSetting) == 0U))
- {
- return 0U;
- }
- return PlsrPlatformStartPrepared(pulseOutput, &firstSetting,
- &queuedSetting,
- actualFirstFrequencyHz,
- actualQueuedFrequencyHz);
- }
-
- static uint8_t PlsrPreparedSettingIsValid(
- uint8_t pulseOutput,
- uint8_t outputMode,
- const PLSR_PLATFORM_TIMER_SETTING *setting)
- {
- uint32_t periodCounts;
-
- if ((pulseOutput > 3U) || (setting == NULL)
- || (setting->actualFrequencyHz == 0UL)
- || (setting->actualFrequencyHz > PLSR_FREQUENCY_MAX_HZ))
- {
- return 0U;
- }
- periodCounts = (uint32_t)setting->period + 1UL;
- if (setting->compare != (uint16_t)(periodCounts / 2UL))
- {
- return 0U;
- }
- if (outputMode == PLSR_OUTPUT_PULSE_DIR)
- {
- return ((periodCounts >= 2UL)
- && (setting->pairPrescaler == 0U)) ? 1U : 0U;
- }
- if ((outputMode != PLSR_OUTPUT_AB) || ((pulseOutput & 1U) != 0U)
- || (periodCounts < 4UL))
- {
- return 0U;
- }
- return ((((uint32_t)setting->prescaler + 1UL)
- == 2UL * ((uint32_t)setting->pairPrescaler + 1UL))
- ? 1U : 0U);
- }
-
- static void PlsrPlatformToTimerSetting(
- const PLSR_PLATFORM_TIMER_SETTING *source,
- PLSR_TIMER_SETTING *destination)
- {
- destination->prescaler = source->prescaler;
- destination->period = source->period;
- destination->compare = source->compare;
- destination->actualFrequencyHz = source->actualFrequencyHz;
- }
-
- static void PlsrPlatformToAbSetting(
- const PLSR_PLATFORM_TIMER_SETTING *source,
- PLSR_AB_SETTING *destination)
- {
- destination->basePrescaler = source->prescaler;
- destination->pairPrescaler = source->pairPrescaler;
- destination->period = source->period;
- destination->compare = source->compare;
- destination->actualFrequencyHz = source->actualFrequencyHz;
- }
-
- static uint8_t PlsrPlatformSettingsDiffer(
- const PLSR_PLATFORM_TIMER_SETTING *first,
- const PLSR_PLATFORM_TIMER_SETTING *second)
- {
- return (((first->actualFrequencyHz != second->actualFrequencyHz)
- || (first->prescaler != second->prescaler)
- || (first->pairPrescaler != second->pairPrescaler)
- || (first->period != second->period)
- || (first->compare != second->compare)) ? 1U : 0U);
- }
-
- uint8_t PlsrPlatformBuildTimerSetting(
- uint8_t pulseOutput,
- uint8_t outputMode,
- uint32_t requestedFrequencyHz,
- PLSR_PLATFORM_TIMER_SETTING *setting)
- {
- PLSR_TIMER_SETTING timerSetting;
- PLSR_AB_SETTING abSetting;
-
- if (setting == NULL)
- {
- return 0U;
- }
- if (outputMode == PLSR_OUTPUT_AB)
- {
- if (PlsrAbCalculate(pulseOutput, requestedFrequencyHz,
- &abSetting) == 0U)
- {
- return 0U;
- }
- setting->actualFrequencyHz = abSetting.actualFrequencyHz;
- setting->prescaler = (uint16_t)abSetting.basePrescaler;
- setting->pairPrescaler = (uint16_t)abSetting.pairPrescaler;
- setting->period = (uint16_t)abSetting.period;
- setting->compare = (uint16_t)abSetting.compare;
- return 1U;
- }
- if ((outputMode != PLSR_OUTPUT_PULSE_DIR)
- || (PlsrTimerCalculate(pulseOutput, requestedFrequencyHz,
- &timerSetting) == 0U))
- {
- return 0U;
- }
- setting->actualFrequencyHz = timerSetting.actualFrequencyHz;
- setting->prescaler = (uint16_t)timerSetting.prescaler;
- setting->pairPrescaler = 0U;
- setting->period = (uint16_t)timerSetting.period;
- setting->compare = (uint16_t)timerSetting.compare;
- return 1U;
- }
-
- uint8_t PlsrPlatformStartPrepared(
- uint8_t pulseOutput,
- const PLSR_PLATFORM_TIMER_SETTING *firstSetting,
- const PLSR_PLATFORM_TIMER_SETTING *queuedSetting,
- uint32_t *actualFirstFrequencyHz,
- uint32_t *actualQueuedFrequencyHz)
- {
- uint8_t outputMode;
-
- if ((pulseOutput > 3U) || (actualFirstFrequencyHz == NULL)
- || (actualQueuedFrequencyHz == NULL))
- {
- return 0U;
- }
- outputMode = PlsrTimerOutputMode[pulseOutput];
- if ((PlsrPreparedSettingIsValid(pulseOutput, outputMode,
- firstSetting) == 0U)
- || (PlsrPreparedSettingIsValid(pulseOutput, outputMode,
- queuedSetting) == 0U))
- {
- return 0U;
- }
- if (outputMode == PLSR_OUTPUT_AB)
- {
- PLSR_AB_SETTING firstAbSetting;
- PLSR_AB_SETTING queuedAbSetting;
-
- if ((PlsrAbStopPending[pulseOutput] != 0U)
- || (PlsrAbFastGated[pulseOutput] != 0U)
- || (PlsrCounterConfigure(pulseOutput, PLSR_OUTPUT_AB) == 0U))
- {
- return 0U;
- }
- PlsrPlatformToAbSetting(firstSetting, &firstAbSetting);
- PlsrPlatformToAbSetting(queuedSetting, &queuedAbSetting);
- PlsrAbLoadAndStart(pulseOutput, &firstAbSetting);
- PlsrAbActiveSetting[pulseOutput] = firstAbSetting;
- PlsrAbPendingSetting[pulseOutput] = queuedAbSetting;
- PlsrAbFrequencyPending[pulseOutput] =
- ((firstSetting->prescaler != queuedSetting->prescaler)
- || (firstSetting->pairPrescaler
- != queuedSetting->pairPrescaler)
- || (firstSetting->period != queuedSetting->period)) ? 1U : 0U;
- }
- else
- {
- TIM_TypeDef *timer = PlsrTimerMap[pulseOutput].timer;
- PLSR_TIMER_SETTING firstTimerSetting;
- PLSR_TIMER_SETTING queuedTimerSetting;
-
- if (PlsrCounterConfigure(pulseOutput,
- PLSR_OUTPUT_PULSE_DIR) == 0U)
- {
- return 0U;
- }
- PlsrPlatformToTimerSetting(firstSetting, &firstTimerSetting);
- PlsrPlatformToTimerSetting(queuedSetting, &queuedTimerSetting);
- timer->DIER &= ~TIM_DIER_UIE;
- timer->CR1 &= ~TIM_CR1_CEN;
- timer->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
- timer->CNT = 0UL;
- PlsrTimerWriteSetting(timer, &firstTimerSetting);
- timer->EGR = TIM_EGR_UG;
- PlsrTimerWriteSetting(timer, &queuedTimerSetting);
- timer->CNT = firstTimerSetting.compare;
- timer->SR = 0UL;
- timer->CCER = (timer->CCER
- & ~(TIM_CCER_CC1E | TIM_CCER_CC1P))
- | TIM_CCER_CC1E;
- __DSB();
- timer->DIER |= TIM_DIER_UIE;
- PlsrPulsePinRelease(pulseOutput);
- PlsrCounterBegin(pulseOutput);
- timer->CR1 |= TIM_CR1_CEN;
- }
- PlsrTimerActiveSetting[pulseOutput] = *firstSetting;
- PlsrTimerQueuedSetting[pulseOutput] = *queuedSetting;
- PlsrTimerActiveFrequencyHz[pulseOutput] =
- firstSetting->actualFrequencyHz;
- PlsrTimerQueuedFrequencyHz[pulseOutput] =
- queuedSetting->actualFrequencyHz;
- PlsrTimerQueueGeneration[pulseOutput]++;
- PlsrTimerRunning[pulseOutput] = 1U;
- if (outputMode == PLSR_OUTPUT_AB)
- {
- PlsrAbScheduleFrequencyVerify(pulseOutput);
- }
- else
- {
- PlsrFrequencyVerifyPending[pulseOutput] =
- PLSR_FREQUENCY_VERIFY_NOW;
- }
- PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
- *actualFirstFrequencyHz = firstSetting->actualFrequencyHz;
- *actualQueuedFrequencyHz = queuedSetting->actualFrequencyHz;
- return 1U;
- }
-
- uint8_t PlsrPlatformSupportsFinitePulseTrain(void)
- {
- return 1U;
- }
-
- uint8_t PlsrPlatformStartFinitePrepared(
- uint8_t pulseOutput,
- const PLSR_PLATFORM_TIMER_SETTING *setting,
- uint32_t pulseCount,
- uint32_t *actualFrequencyHz)
- {
- TIM_TypeDef *timer;
- TIM_TypeDef *counter;
- PLSR_TIMER_SETTING timerSetting;
- uint32_t firstBlock;
- uint8_t counterIndex;
-
- if ((pulseOutput > 3U) || (setting == NULL)
- || (pulseCount == 0UL) || (actualFrequencyHz == NULL)
- || (PlsrTimerOutputMode[pulseOutput] != PLSR_OUTPUT_PULSE_DIR)
- || (PlsrPreparedSettingIsValid(pulseOutput,
- PLSR_OUTPUT_PULSE_DIR,
- setting) == 0U)
- || (PlsrCounterConfigure(pulseOutput,
- PLSR_OUTPUT_PULSE_DIR) == 0U))
- {
- return 0U;
- }
-
- timer = PlsrTimerMap[pulseOutput].timer;
- counterIndex = PlsrCounterIndexByOutput[pulseOutput];
- counter = PlsrCounters[counterIndex];
- firstBlock = (pulseCount > PLSR_COUNTER_BLOCK_PULSES)
- ? PLSR_COUNTER_BLOCK_PULSES : pulseCount;
- PlsrPlatformToTimerSetting(setting, &timerSetting);
-
- counter->CR1 &= ~TIM_CR1_CEN;
- counter->SMCR &= ~(TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0);
- counter->ARR = (firstBlock == 1UL) ? 1UL : (firstBlock - 1UL);
- counter->CNT = 0UL;
- counter->EGR = TIM_EGR_UG;
- PlsrFiniteCounterPreload[pulseOutput] =
- (firstBlock == 1UL) ? 1U : 0U;
- counter->CNT = PlsrFiniteCounterPreload[pulseOutput];
- counter->SR = 0UL;
- counter->DIER = TIM_DIER_UIE;
-
- timer->DIER = 0UL;
- timer->CR1 &= ~TIM_CR1_CEN;
- timer->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
- timer->CNT = 0UL;
- PlsrTimerWriteSetting(timer, &timerSetting);
- timer->EGR = TIM_EGR_UG;
- /*
- * The board's high-speed output stage is active low. Keep OC1 high
- * while the pin changes from GPIO idle to the timer alternate function,
- * then let the first terminal pulse start at CCR1. Starting at CCR1
- * would expose an uncounted terminal pulse before the first OC rising
- * edge reaches TIM9/TIM12.
- */
- timer->CNT = 0UL;
- timer->SR = 0UL;
- timer->CCER = (timer->CCER
- & ~(TIM_CCER_CC1E | TIM_CCER_CC1P))
- | TIM_CCER_CC1E;
- PlsrFiniteTargetPulses[pulseOutput] = pulseCount;
- PlsrFiniteRemainingPulses[pulseOutput] = pulseCount;
- PlsrFiniteCompletionPending[pulseOutput] = 0U;
- PlsrFiniteFrequencyPending[pulseOutput] = 0U;
- PlsrFiniteActive[pulseOutput] = 1U;
- PlsrFiniteStepCount[pulseOutput] = 0U;
- PlsrFiniteStepIndex[pulseOutput] = 0U;
- PlsrFiniteBoundaryReadIndex[pulseOutput] = 0U;
- PlsrFiniteCompletedStepCount[pulseOutput] = 0U;
- PlsrTimerActiveSetting[pulseOutput] = *setting;
- PlsrTimerQueuedSetting[pulseOutput] = *setting;
- PlsrTimerActiveFrequencyHz[pulseOutput] = setting->actualFrequencyHz;
- PlsrTimerQueuedFrequencyHz[pulseOutput] = setting->actualFrequencyHz;
- PlsrTimerRunning[pulseOutput] = 1U;
- *actualFrequencyHz = setting->actualFrequencyHz;
-
- __DSB();
- PlsrPulsePinRelease(pulseOutput);
- PlsrCounterBegin(pulseOutput);
- timer->CR1 |= TIM_CR1_CEN;
- return 1U;
- }
-
- uint8_t PlsrPlatformStartFiniteSequencePrepared(
- uint8_t pulseOutput,
- PLSR_PLATFORM_FINITE_STEP *steps,
- uint16_t stepCount,
- uint32_t *actualFrequencyHz)
- {
- TIM_TypeDef *counter;
- uint16_t index;
-
- if ((steps == NULL) || (stepCount == 0U)
- || (stepCount > PLSR_PLATFORM_FINITE_STEP_MAX))
- {
- return 0U;
- }
- for (index = 0U; index < stepCount; index++)
- {
- if ((steps[index].pulseCount == 0UL)
- || (steps[index].segmentNumber == 0U)
- || (PlsrPreparedSettingIsValid(
- pulseOutput, PLSR_OUTPUT_PULSE_DIR,
- &steps[index].setting) == 0U))
- {
- return 0U;
- }
- }
- if (PlsrPlatformStartFinitePrepared(
- pulseOutput, &steps[0].setting, steps[0].pulseCount,
- actualFrequencyHz) == 0U)
- {
- return 0U;
- }
- PlsrFiniteSteps[pulseOutput] = steps;
- PlsrFiniteStepCount[pulseOutput] = stepCount;
- PlsrFiniteStepIndex[pulseOutput] = 0U;
- PlsrFiniteBoundaryReadIndex[pulseOutput] = 0U;
- PlsrFiniteCompletedStepCount[pulseOutput] = 0U;
- if (stepCount > 1U)
- {
- counter = PlsrCounters[PlsrCounterIndexByOutput[pulseOutput]];
- PlsrFiniteArmNextStepPrepare(
- pulseOutput, counter,
- (steps[0].pulseCount > PLSR_COUNTER_BLOCK_PULSES)
- ? PLSR_COUNTER_BLOCK_PULSES : steps[0].pulseCount);
- }
- return 1U;
- }
-
- PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformUpdateFinitePrepared(
- uint8_t pulseOutput,
- const PLSR_PLATFORM_TIMER_SETTING *setting,
- uint32_t *actualFrequencyHz)
- {
- TIM_TypeDef *timer;
- uint32_t activePeriod;
- uint32_t counter;
- uint32_t criticalState;
-
- if ((pulseOutput > 3U) || (setting == NULL)
- || (actualFrequencyHz == NULL)
- || (PlsrFiniteActive[pulseOutput] == 0U)
- || (PlsrPreparedSettingIsValid(pulseOutput,
- PLSR_OUTPUT_PULSE_DIR,
- setting) == 0U))
- {
- return PLSR_PLATFORM_QUEUE_STALE;
- }
-
- timer = PlsrTimerMap[pulseOutput].timer;
- criticalState = PlsrPlatformEnterCritical();
- if ((PlsrFiniteActive[pulseOutput] == 0U)
- || ((timer->CR1 & TIM_CR1_CEN) == 0UL))
- {
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- if (PlsrFiniteFrequencyPending[pulseOutput] != 0U)
- {
- if ((timer->SR & TIM_SR_UIF) == 0UL)
- {
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_QUEUE_STALE;
- }
-
- /* The update IRQ normally commits this preload. Also consume a
- latched update here so a delayed/shared IRQ cannot stall a ramp. */
- timer->SR = ~TIM_SR_UIF;
- timer->DIER &= ~TIM_DIER_UIE;
- PlsrTimerActiveFrequencyHz[pulseOutput] =
- PlsrTimerQueuedFrequencyHz[pulseOutput];
- PlsrTimerActiveSetting[pulseOutput] =
- PlsrTimerQueuedSetting[pulseOutput];
- PlsrFiniteFrequencyPending[pulseOutput] = 0U;
- }
- activePeriod = PlsrTimerActiveSetting[pulseOutput].period;
- counter = timer->CNT;
- if ((counter > activePeriod)
- || ((activePeriod - counter) < PLSR_FINITE_WRITE_GUARD_COUNTS))
- {
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_QUEUE_STALE;
- }
-
- timer->PSC = setting->prescaler;
- timer->ARR = setting->period;
- timer->CCR1 = setting->compare;
- __DMB();
- PlsrTimerQueuedSetting[pulseOutput] = *setting;
- PlsrTimerQueuedFrequencyHz[pulseOutput] = setting->actualFrequencyHz;
- PlsrTimerQueueGeneration[pulseOutput]++;
- PlsrFiniteFrequencyPending[pulseOutput] = 1U;
- timer->SR = ~TIM_SR_UIF;
- timer->DIER |= TIM_DIER_UIE;
- *actualFrequencyHz = setting->actualFrequencyHz;
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_QUEUE_APPLIED;
- }
-
- uint8_t PlsrPlatformRetargetFiniteStop(uint8_t pulseOutput,
- uint32_t drainPulses)
- {
- TIM_TypeDef *timer;
-
- if ((pulseOutput > 3U) || (drainPulses == 0UL)
- || (PlsrFiniteActive[pulseOutput] == 0U)
- || (PlsrCounterIndexByOutput[pulseOutput] >= PLSR_COUNTER_COUNT)
- || (PlsrFiniteRetargetPending[pulseOutput] != 0U)
- || (PlsrFiniteTailStopPending[pulseOutput] != 0U))
- {
- return 0U;
- }
- timer = PlsrTimerMap[pulseOutput].timer;
- PlsrFiniteRetargetDrainPulses[pulseOutput] = drainPulses;
- PlsrFiniteRetargetPending[pulseOutput] = 1U;
- timer->SR = ~TIM_SR_CC1IF;
- timer->DIER |= TIM_DIER_CC1IE;
- __DMB();
- return 1U;
- }
-
- uint8_t PlsrPlatformFiniteRetargetReady(uint8_t pulseOutput,
- uint32_t *activeFrequencyHz)
- {
- uint32_t criticalState;
- uint8_t ready;
-
- if ((pulseOutput > 3U) || (activeFrequencyHz == NULL))
- {
- return 0U;
- }
- criticalState = PlsrPlatformEnterCritical();
- ready = ((PlsrFiniteActive[pulseOutput] != 0U)
- && (PlsrFiniteRetargetPending[pulseOutput] == 0U)
- && (PlsrFiniteStepCount[pulseOutput] == 0U)) ? 1U : 0U;
- *activeFrequencyHz = PlsrTimerActiveFrequencyHz[pulseOutput];
- PlsrPlatformExitCritical(criticalState);
- return ready;
- }
-
- uint8_t PlsrPlatformFiniteProgress(uint8_t pulseOutput,
- uint32_t *completedPulses)
- {
- uint8_t counterIndex;
- TIM_TypeDef *counter;
- uint32_t criticalState;
- uint32_t completed;
-
- if ((pulseOutput > 3U) || (completedPulses == NULL)
- || ((PlsrFiniteActive[pulseOutput] == 0U)
- && (PlsrFiniteCompletionPending[pulseOutput] == 0U)))
- {
- return 0U;
- }
-
- criticalState = PlsrPlatformEnterCritical();
- counterIndex = PlsrCounterIndexByOutput[pulseOutput];
- if (PlsrFiniteCompletionPending[pulseOutput] != 0U)
- {
- completed = PlsrFiniteTargetPulses[pulseOutput];
- }
- else if (counterIndex < PLSR_COUNTER_COUNT)
- {
- counter = PlsrCounters[counterIndex];
- uint32_t blockCount = (uint16_t)counter->CNT;
-
- if (blockCount >= PlsrFiniteCounterPreload[pulseOutput])
- {
- blockCount -= PlsrFiniteCounterPreload[pulseOutput];
- }
- completed = PlsrFiniteTargetPulses[pulseOutput]
- - PlsrFiniteRemainingPulses[pulseOutput]
- + blockCount;
- if (completed > PlsrFiniteTargetPulses[pulseOutput])
- {
- completed = PlsrFiniteTargetPulses[pulseOutput];
- }
- }
- else
- {
- PlsrPlatformExitCritical(criticalState);
- return 0U;
- }
- if (PlsrFiniteStepCount[pulseOutput] != 0U)
- {
- completed += PlsrFiniteSteps[pulseOutput][
- PlsrFiniteStepIndex[pulseOutput]].segmentPulseOffset;
- }
- *completedPulses = completed;
- PlsrPlatformExitCritical(criticalState);
- return 1U;
- }
-
- uint8_t PlsrPlatformTakeFiniteCompletion(uint8_t pulseOutput,
- uint32_t *completedPulses)
- {
- uint8_t counterIndex;
- TIM_TypeDef *counter;
-
- if ((pulseOutput > 3U) || (completedPulses == NULL)
- || (PlsrFiniteCompletionPending[pulseOutput] == 0U))
- {
- return 0U;
- }
-
- counterIndex = PlsrCounterIndexByOutput[pulseOutput];
- if (PlsrFiniteStepCount[pulseOutput] != 0U)
- {
- const PLSR_PLATFORM_FINITE_STEP *step =
- &PlsrFiniteSteps[pulseOutput][
- PlsrFiniteStepCount[pulseOutput] - 1U];
-
- *completedPulses = step->segmentPulseOffset + step->pulseCount;
- }
- else
- {
- *completedPulses = PlsrFiniteTargetPulses[pulseOutput];
- }
- if (PlsrFiniteStepCount[pulseOutput] == 0U)
- {
- PlsrObservedPulseBase[pulseOutput] += *completedPulses;
- }
- PlsrObservedPulsePublished[pulseOutput] =
- PlsrObservedPulseBase[pulseOutput];
- PlsrFiniteCompletionPending[pulseOutput] = 0U;
- PlsrFiniteFrequencyPending[pulseOutput] = 0U;
- PlsrFiniteTargetPulses[pulseOutput] = 0UL;
- PlsrFiniteRemainingPulses[pulseOutput] = 0UL;
- PlsrFiniteCounterPreload[pulseOutput] = 0U;
- PlsrFiniteStepCount[pulseOutput] = 0U;
- PlsrFiniteStepIndex[pulseOutput] = 0U;
- PlsrTimerActiveFrequencyHz[pulseOutput] = 0UL;
- PlsrTimerQueuedFrequencyHz[pulseOutput] = 0UL;
- PlsrTimerRunning[pulseOutput] = 0U;
-
- if (counterIndex < PLSR_COUNTER_COUNT)
- {
- counter = PlsrCounters[counterIndex];
- counter->CR1 = 0UL;
- counter->DIER = 0UL;
- counter->SMCR = 0UL;
- counter->SR = 0UL;
- PlsrCounterOverflowPulses[counterIndex] = 0UL;
- PlsrCounterOwner[counterIndex] = PLSR_COUNTER_NONE;
- }
- PlsrCounterIndexByOutput[pulseOutput] = PLSR_COUNTER_NONE;
- return 1U;
- }
-
- uint8_t PlsrPlatformTakeFiniteBoundary(uint8_t pulseOutput,
- uint8_t *segmentNumber,
- uint32_t *completedPulses,
- uint8_t *sequenceContinues,
- uint32_t *activeFrequencyHz)
- {
- uint32_t criticalState;
- uint16_t readIndex;
- uint16_t completedCount;
-
- if ((pulseOutput > 3U) || (segmentNumber == NULL)
- || (completedPulses == NULL) || (sequenceContinues == NULL)
- || (activeFrequencyHz == NULL))
- {
- return 0U;
- }
- criticalState = PlsrPlatformEnterCritical();
- readIndex = PlsrFiniteBoundaryReadIndex[pulseOutput];
- completedCount = PlsrFiniteCompletedStepCount[pulseOutput];
- while (readIndex < completedCount)
- {
- uint16_t index = readIndex++;
- const PLSR_PLATFORM_FINITE_STEP *step =
- &PlsrFiniteSteps[pulseOutput][index];
-
- PlsrFiniteBoundaryReadIndex[pulseOutput] = readIndex;
- if (step->completesSegment != 0U)
- {
- *segmentNumber = step->segmentNumber;
- *completedPulses = step->segmentPulseOffset + step->pulseCount;
- *sequenceContinues =
- (index + 1U < PlsrFiniteStepCount[pulseOutput]) ? 1U : 0U;
- *activeFrequencyHz = (*sequenceContinues != 0U)
- ? PlsrFiniteSteps[pulseOutput][index + 1U]
- .setting.actualFrequencyHz
- : step->setting.actualFrequencyHz;
- PlsrPlatformExitCritical(criticalState);
- return 1U;
- }
- }
- PlsrPlatformExitCritical(criticalState);
- return 0U;
- }
-
- PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformLoadPreparedFromIrq(
- uint8_t pulseOutput,
- const PLSR_PLATFORM_TIMER_SETTING *setting,
- uint32_t *actualFrequencyHz)
- {
- uint8_t outputMode;
-
- if ((pulseOutput > 3U) || (actualFrequencyHz == NULL))
- {
- return PLSR_PLATFORM_QUEUE_FAILED;
- }
- outputMode = PlsrTimerOutputMode[pulseOutput];
- if (PlsrPreparedSettingIsValid(pulseOutput, outputMode,
- setting) == 0U)
- {
- return PLSR_PLATFORM_QUEUE_FAILED;
- }
- if ((PlsrTimerRunning[pulseOutput] == 0U)
- || (PlsrAbStopPending[pulseOutput] != 0U)
- || (PlsrAbFastGated[pulseOutput] != 0U))
- {
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- if (outputMode == PLSR_OUTPUT_AB)
- {
- PLSR_AB_SETTING pending;
-
- PlsrPlatformToAbSetting(setting, &pending);
- PlsrAbPendingSetting[pulseOutput] = pending;
- PlsrAbFrequencyPending[pulseOutput] =
- ((setting->prescaler
- != PlsrAbActiveSetting[pulseOutput].basePrescaler)
- || (setting->pairPrescaler
- != PlsrAbActiveSetting[pulseOutput].pairPrescaler)
- || (setting->period
- != PlsrAbActiveSetting[pulseOutput].period)) ? 1U : 0U;
- }
- else
- {
- TIM_TypeDef *timer = PlsrTimerMap[pulseOutput].timer;
-
- if ((timer->CR1 & TIM_CR1_CEN) == 0UL)
- {
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- timer->PSC = setting->prescaler;
- timer->ARR = setting->period;
- timer->CCR1 = setting->compare;
- __DMB();
- }
- PlsrTimerQueuedSetting[pulseOutput] = *setting;
- PlsrTimerQueuedFrequencyHz[pulseOutput] = setting->actualFrequencyHz;
- PlsrTimerQueueGeneration[pulseOutput]++;
- *actualFrequencyHz = setting->actualFrequencyHz;
- return PLSR_PLATFORM_QUEUE_APPLIED;
- }
-
- void PlsrPlatformGateFromIrq(uint8_t pulseOutput)
- {
- if ((pulseOutput <= 3U)
- && (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- && (PlsrAbFastGated[pulseOutput] != 0U))
- {
- return;
- }
- PlsrPlatformStopPulse(pulseOutput);
- }
-
- PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformQueueFrequency(
- uint8_t pulseOutput,
- uint32_t frequencyHz,
- uint32_t *actualFrequencyHz)
- {
- TIM_TypeDef *timer;
- PLSR_PLATFORM_TIMER_SETTING setting;
- uint32_t activePeriod;
- uint32_t counter;
- uint32_t criticalState;
- uint32_t ownGeneration;
- uint8_t updatePending;
-
- if ((pulseOutput > 3U) || (actualFrequencyHz == NULL)
- || (PlsrPlatformBuildTimerSetting(
- pulseOutput, PlsrTimerOutputMode[pulseOutput], frequencyHz,
- &setting) == 0U))
- {
- return PLSR_PLATFORM_QUEUE_FAILED;
- }
- if (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- {
- PLSR_AB_SETTING pending;
- uint32_t criticalState;
-
- if ((PlsrTimerRunning[pulseOutput] == 0U)
- || (PlsrAbStopPending[pulseOutput] != 0U)
- || (PlsrAbFastGated[pulseOutput] != 0U))
- {
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- criticalState = PlsrPlatformEnterCritical();
- if ((PlsrTimerRunning[pulseOutput] == 0U)
- || (PlsrAbStopPending[pulseOutput] != 0U)
- || (PlsrAbFastGated[pulseOutput] != 0U))
- {
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- PlsrPlatformToAbSetting(&setting, &pending);
- PlsrAbPendingSetting[pulseOutput] = pending;
- PlsrAbFrequencyPending[pulseOutput] =
- ((pending.basePrescaler
- != PlsrAbActiveSetting[pulseOutput].basePrescaler)
- || (pending.pairPrescaler
- != PlsrAbActiveSetting[pulseOutput].pairPrescaler)
- || (pending.period
- != PlsrAbActiveSetting[pulseOutput].period)) ? 1U : 0U;
- PlsrTimerQueuedSetting[pulseOutput] = setting;
- PlsrTimerQueuedFrequencyHz[pulseOutput] = setting.actualFrequencyHz;
- PlsrTimerQueueGeneration[pulseOutput]++;
- *actualFrequencyHz = setting.actualFrequencyHz;
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_QUEUE_APPLIED;
- }
-
- timer = PlsrTimerMap[pulseOutput].timer;
- if ((timer->CR1 & TIM_CR1_CEN) == 0UL)
- {
- return PLSR_PLATFORM_QUEUE_STALE;
- }
-
- criticalState = PlsrPlatformEnterCritical();
- if ((timer->SR & TIM_SR_UIF) != 0UL)
- {
- *actualFrequencyHz = PlsrTimerQueuedFrequencyHz[pulseOutput];
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- activePeriod = PlsrTimerActiveSetting[pulseOutput].period;
- counter = timer->CNT;
- if ((counter > activePeriod)
- || ((activePeriod - counter) < PLSR_QUEUE_WRITE_GUARD_COUNTS))
- {
- *actualFrequencyHz = PlsrTimerQueuedFrequencyHz[pulseOutput];
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_QUEUE_STALE;
- }
-
- /* Preserve real update events and their TRGO pulse while replacing the
- three preload registers. The near-wrap guard bounds the write window. */
- timer->PSC = setting.prescaler;
- timer->ARR = setting.period;
- timer->CCR1 = setting.compare;
- __DMB();
- updatePending = ((timer->SR & TIM_SR_UIF) != 0UL) ? 1U : 0U;
- PlsrTimerQueuedFrequencyHz[pulseOutput] = setting.actualFrequencyHz;
- PlsrTimerQueuedSetting[pulseOutput] = setting;
- PlsrTimerQueueGeneration[pulseOutput]++;
- ownGeneration = PlsrTimerQueueGeneration[pulseOutput];
- if (updatePending != 0U)
- {
- *actualFrequencyHz = PlsrTimerQueuedFrequencyHz[pulseOutput];
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- *actualFrequencyHz =
- (PlsrTimerQueueGeneration[pulseOutput] == ownGeneration)
- ? setting.actualFrequencyHz
- : PlsrTimerQueuedFrequencyHz[pulseOutput];
- if (PlsrTimerQueueGeneration[pulseOutput] != ownGeneration)
- {
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_QUEUE_STALE;
- }
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_QUEUE_APPLIED;
- }
-
- void PlsrPlatformDrainPendingPulse(uint8_t pulseOutput)
- {
- if (pulseOutput <= 3U)
- {
- if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- && (PlsrDeferredPulsePending[pulseOutput] != 0U))
- {
- uint8_t verifyOutput =
- (PlsrAbLagAxis[pulseOutput] == pulseOutput)
- ? (uint8_t)(pulseOutput + 1U) : pulseOutput;
- TIM_TypeDef *verifyTimer = PlsrTimerMap[verifyOutput].timer;
-
- verifyTimer->DIER &= ~(TIM_DIER_UIE | TIM_DIER_CC1IE);
- verifyTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
- PlsrAbVerifyOwner[verifyOutput] = PLSR_COUNTER_NONE;
- if (PlsrFrequencyVerifyPending[pulseOutput]
- == PLSR_FREQUENCY_VERIFY_AB_AUX_IRQ)
- {
- PlsrFrequencyVerifyPending[pulseOutput] =
- PLSR_FREQUENCY_VERIFY_NONE;
- PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
- (void)PlsrVerifyActiveFrequency(pulseOutput);
- }
- PlsrDeferredPulsePending[pulseOutput] = 0U;
- PlsrPulseTimerIrq(pulseOutput);
- return;
- }
- PlsrHandleTimerIrq(pulseOutput);
- }
- }
-
- uint32_t PlsrPlatformActiveFrequency(uint8_t pulseOutput)
- {
- if (pulseOutput > 3U)
- {
- return 0UL;
- }
- if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- && (PlsrAbFastGated[pulseOutput] != 0U))
- {
- PlsrFrequencyVerifyPending[pulseOutput] =
- PLSR_FREQUENCY_VERIFY_NONE;
- PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
- return PlsrTimerActiveFrequencyHz[pulseOutput];
- }
- if (PlsrFrequencyVerifyPending[pulseOutput]
- == PLSR_FREQUENCY_VERIFY_AB_AUX_IRQ)
- {
- return PlsrTimerActiveFrequencyHz[pulseOutput];
- }
- if (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- {
- PlsrFrequencyVerifyPulseCount[pulseOutput]++;
- if (PlsrFrequencyVerifyPulseCount[pulseOutput]
- >= PLSR_STRUCTURE_VERIFY_INTERVAL)
- {
- PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
- PlsrAbScheduleFrequencyVerify(pulseOutput);
- }
- return PlsrTimerActiveFrequencyHz[pulseOutput];
- }
- if (PlsrFrequencyVerifyPending[pulseOutput]
- == PLSR_FREQUENCY_VERIFY_NOW)
- {
- PlsrFrequencyVerifyPending[pulseOutput] =
- PLSR_FREQUENCY_VERIFY_NONE;
- PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
- return PlsrVerifyActiveFrequency(pulseOutput);
- }
- PlsrFrequencyVerifyPulseCount[pulseOutput]++;
- if (PlsrFrequencyVerifyPulseCount[pulseOutput]
- >= PLSR_STRUCTURE_VERIFY_INTERVAL)
- {
- PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
- return PlsrVerifyActiveFrequency(pulseOutput);
- }
- return PlsrTimerActiveFrequencyHz[pulseOutput];
- }
-
- uint8_t PlsrPlatformExpectedFrequency(uint8_t pulseOutput,
- uint8_t outputMode,
- uint32_t requestedFrequencyHz,
- uint32_t *actualFrequencyHz)
- {
- PLSR_PLATFORM_TIMER_SETTING setting;
-
- if (actualFrequencyHz == NULL)
- {
- return 0U;
- }
- if (PlsrPlatformBuildTimerSetting(pulseOutput, outputMode,
- requestedFrequencyHz,
- &setting) == 0U)
- {
- return 0U;
- }
- *actualFrequencyHz = setting.actualFrequencyHz;
- return 1U;
- }
-
- uint64_t PlsrPlatformObservedPulses(uint8_t pulseOutput)
- {
- uint32_t criticalState;
- uint64_t observed;
-
- if (pulseOutput > 3U)
- {
- return 0UL;
- }
- criticalState = PlsrPlatformEnterCritical();
- if (PlsrCounterIndexByOutput[pulseOutput] < PLSR_COUNTER_COUNT)
- {
- observed = ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- && (PlsrAbFastGated[pulseOutput] != 0U))
- ? PlsrCounterSnapshotStopped(pulseOutput)
- : PlsrCounterSnapshot(pulseOutput);
- }
- else
- {
- observed = PlsrObservedPulseBase[pulseOutput];
- }
- PlsrPlatformExitCritical(criticalState);
- return observed;
- }
-
- uint16_t PlsrPlatformDiagnosticFault(void)
- {
- uint16_t fault = PlsrPlatformFaultPending;
-
- PlsrPlatformFaultPending = 0U;
- return fault;
- }
-
- PLSR_PLATFORM_STOP_RESULT PlsrPlatformRequestStopLocked(
- uint8_t pulseOutput,
- uint8_t requireZeroBoundary)
- {
- if (pulseOutput > 3U)
- {
- return PLSR_PLATFORM_STOP_FORCED_FAULT;
- }
- if ((requireZeroBoundary != 0U)
- && (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- && (PlsrTimerRunning[pulseOutput] != 0U)
- && (PlsrAbFastGated[pulseOutput] == 0U))
- {
- uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
- uint8_t lagOutput = PlsrAbLagAxis[pulseOutput];
- uint32_t activeFrequencyHz;
- TIM_TypeDef *baseTimer = PlsrTimerMap[pulseOutput].timer;
- TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
- uint8_t structureRunnable =
- ((PlsrAbStructureVerified[pulseOutput] != 0U)
- && (PlsrFrequencyVerifyPending[pulseOutput]
- == PLSR_FREQUENCY_VERIFY_NONE))
- ? PlsrAbStopBoundaryIsReachable(pulseOutput, baseTimer,
- pairTimer)
- : PlsrAbTimersAreRunnable(pulseOutput, baseTimer,
- pairTimer);
-
- if (structureRunnable == 0U)
- {
- PlsrCounterSuspend(pulseOutput);
- PlsrAbHoldPairIdle(pulseOutput);
- baseTimer->CR1 &= ~TIM_CR1_CEN;
- pairTimer->CR1 &= ~TIM_CR1_CEN;
- __DMB();
- PlsrPlatformStopPulse(pulseOutput);
- return PLSR_PLATFORM_STOP_FORCED_FAULT;
- }
- if (PlsrAbStopPending[pulseOutput] != 0U)
- {
- return PLSR_PLATFORM_STOP_PENDING;
- }
-
- PlsrAbFrequencyPending[pulseOutput] = 0U;
- baseTimer->DIER &= ~TIM_DIER_UIE;
- pairTimer->DIER &= ~TIM_DIER_UIE;
- PlsrFrequencyVerifyPending[pulseOutput] =
- PLSR_FREQUENCY_VERIFY_NONE;
- PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
- PlsrAbVerifyOwner[pulseOutput] = PLSR_COUNTER_NONE;
- PlsrAbVerifyOwner[pairOutput] = PLSR_COUNTER_NONE;
- activeFrequencyHz = PlsrTimerActiveFrequencyHz[pulseOutput];
- PlsrTimerQueuedFrequencyHz[pulseOutput] = activeFrequencyHz;
- PlsrTimerQueueGeneration[pulseOutput]++;
- PlsrAbStopPending[pulseOutput] = 1U;
- #if PLSR_DEBUG_TIMING
- if (PlsrFinalArmQueueTimingPending[pulseOutput] != 0U)
- {
- uint32_t queuedAt = PlsrFinalArmQueuedAt[pulseOutput];
- uint32_t stoppedAt = DWT->CYCCNT;
- uint32_t latency = stoppedAt - queuedAt;
-
- PlsrFinalArmQueueTimingPending[pulseOutput] = 0U;
- PlsrFinalArmQueueToStopLastCycles[pulseOutput] = latency;
- if (latency > PlsrFinalArmQueueToStopMaxCycles[pulseOutput])
- {
- PlsrFinalArmQueueToStopMaxCycles[pulseOutput] = latency;
- }
- }
- #endif
- if (lagOutput == pulseOutput)
- {
- pairTimer->SR = ~TIM_SR_CC1IF;
- }
- else
- {
- baseTimer->SR = ~TIM_SR_CC1IF;
- }
- baseTimer->DIER |= TIM_DIER_CC1IE;
- pairTimer->DIER |= TIM_DIER_CC1IE;
- __DMB();
- return PLSR_PLATFORM_STOP_PENDING;
- }
- PlsrPlatformStopPulse(pulseOutput);
- return PLSR_PLATFORM_STOP_COMPLETE;
- }
-
- uint8_t PlsrPlatformQueueFinalArmFromIrq(uint8_t pulseOutput)
- {
- uint8_t jobOutput;
-
- if ((pulseOutput > 2U) || ((pulseOutput & 1U) != 0U)
- || (PlsrTimerOutputMode[pulseOutput] != PLSR_OUTPUT_AB)
- || (PlsrTimerRunning[pulseOutput] == 0U)
- || (PlsrAbFastGated[pulseOutput] != 0U))
- {
- return 0U;
- }
- jobOutput = PlsrFinalArmJobOutput(pulseOutput);
- if (PlsrAbFinalArmJobOwner[jobOutput] != PLSR_COUNTER_NONE)
- {
- return 0U;
- }
- PlsrAbFinalArmJobOwner[jobOutput] = pulseOutput;
- #if PLSR_DEBUG_TIMING
- PlsrFinalArmQueuedAt[pulseOutput] = DWT->CYCCNT;
- PlsrFinalArmQueueTimingPending[pulseOutput] = 1U;
- PlsrFinalArmQueueCount[pulseOutput]++;
- #endif
- __DMB();
- NVIC_SetPendingIRQ(PlsrTimerMap[jobOutput].irq);
- return 1U;
- }
-
- void PlsrPlatformStopPulse(uint8_t pulseOutput)
- {
- if (pulseOutput <= 3U)
- {
- PlsrFiniteActive[pulseOutput] = 0U;
- PlsrFiniteCompletionPending[pulseOutput] = 0U;
- PlsrFiniteFrequencyPending[pulseOutput] = 0U;
- PlsrFiniteRetargetPending[pulseOutput] = 0U;
- PlsrFiniteTailStopPending[pulseOutput] = 0U;
- PlsrFiniteRetargetDrainPulses[pulseOutput] = 0UL;
- PlsrFiniteTargetPulses[pulseOutput] = 0UL;
- PlsrFiniteRemainingPulses[pulseOutput] = 0UL;
- if (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- {
- uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
- uint8_t jobOutput = PlsrFinalArmJobOutput(pulseOutput);
- TIM_TypeDef *baseTimer = PlsrTimerMap[pulseOutput].timer;
- TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
-
- PlsrAbStructureVerified[pulseOutput] = 0U;
- PlsrAbFinalArmJobOwner[jobOutput] = PLSR_COUNTER_NONE;
- #if PLSR_DEBUG_TIMING
- PlsrFinalArmQueueTimingPending[pulseOutput] = 0U;
- #endif
- NVIC_ClearPendingIRQ(PlsrTimerMap[jobOutput].irq);
- if (PlsrAbFastGated[pulseOutput] != 0U)
- {
- PlsrAbHoldPairIdle(pulseOutput);
- baseTimer->DIER = 0UL;
- pairTimer->DIER = 0UL;
- baseTimer->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
- pairTimer->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
- baseTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
- pairTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
- }
- else
- {
- PlsrCounterSuspend(pulseOutput);
- PlsrAbHoldPairIdle(pulseOutput);
- PlsrTimerStop(baseTimer);
- PlsrTimerStop(pairTimer);
- }
- }
- else
- {
- PlsrPulsePinCaptureIdle(pulseOutput);
- PlsrTimerStop(PlsrTimerMap[pulseOutput].timer);
- }
- PlsrCounterStop(pulseOutput);
- PlsrTimerActiveFrequencyHz[pulseOutput] = 0UL;
- PlsrTimerQueuedFrequencyHz[pulseOutput] = 0UL;
- PlsrTimerQueueGeneration[pulseOutput]++;
- PlsrTimerRunning[pulseOutput] = 0U;
- PlsrFrequencyVerifyPending[pulseOutput] = 0U;
- PlsrDeferredPulsePending[pulseOutput] = 0U;
- PlsrAbVerifyOwner[pulseOutput] = PLSR_COUNTER_NONE;
- if (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
- {
- PlsrAbVerifyOwner[pulseOutput + 1U] = PLSR_COUNTER_NONE;
- }
- PlsrAbFrequencyPending[pulseOutput] = 0U;
- PlsrAbStopPending[pulseOutput] = 0U;
- PlsrAbFastGated[pulseOutput] = 0U;
- }
- }
-
- void PlsrPlatformForceSafeOutputsFromFault(void)
- {
- uint32_t mode;
- const uint32_t outputPins = GPIO_PIN_6 | GPIO_PIN_7
- | GPIO_PIN_8 | GPIO_PIN_9;
- const uint32_t outputModeMask = (3UL << (6U * 2U))
- | (3UL << (7U * 2U))
- | (3UL << (8U * 2U))
- | (3UL << (9U * 2U));
-
- __disable_irq();
-
- TIM10->DIER = 0UL;
- TIM10->CR1 &= ~TIM_CR1_CEN;
- TIM10->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
- TIM10->SR = 0UL;
- TIM11->DIER = 0UL;
- TIM11->CR1 &= ~TIM_CR1_CEN;
- TIM11->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
- TIM11->SR = 0UL;
- TIM13->DIER = 0UL;
- TIM13->CR1 &= ~TIM_CR1_CEN;
- TIM13->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
- TIM13->SR = 0UL;
- TIM14->DIER = 0UL;
- TIM14->CR1 &= ~TIM_CR1_CEN;
- TIM14->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
- TIM14->SR = 0UL;
-
- TIM9->DIER = 0UL;
- TIM9->CR1 &= ~TIM_CR1_CEN;
- TIM9->SMCR = 0UL;
- TIM9->SR = 0UL;
- TIM12->DIER = 0UL;
- TIM12->CR1 &= ~TIM_CR1_CEN;
- TIM12->SMCR = 0UL;
- TIM12->SR = 0UL;
-
- RCC->AHB1ENR |= RCC_AHB1ENR_GPIOFEN | RCC_AHB1ENR_GPIOHEN;
- __DSB();
- GPIOF->BSRR = outputPins;
- GPIOH->BSRR = outputPins;
- GPIOF->OTYPER &= ~outputPins;
- GPIOH->OTYPER &= ~outputPins;
- GPIOF->PUPDR &= ~outputModeMask;
- GPIOH->PUPDR &= ~outputModeMask;
- mode = GPIOF->MODER;
- mode &= ~outputModeMask;
- mode |= (1UL << (6U * 2U)) | (1UL << (7U * 2U))
- | (1UL << (8U * 2U)) | (1UL << (9U * 2U));
- GPIOF->MODER = mode;
- mode = GPIOH->MODER;
- mode &= ~outputModeMask;
- mode |= (1UL << (6U * 2U)) | (1UL << (7U * 2U))
- | (1UL << (8U * 2U)) | (1UL << (9U * 2U));
- GPIOH->MODER = mode;
- __DSB();
- }
-
- uint8_t PlsrPlatformReadInput(uint8_t inputSelection)
- {
- if (inputSelection == 0U)
- {
- return (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) == GPIO_PIN_SET) ? 1U : 0U;
- }
- if (inputSelection == 1U)
- {
- return (HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_12) == GPIO_PIN_SET) ? 1U : 0U;
- }
- return 0U;
- }
-
- uint8_t PlsrPlatformLoad(PLSR_PERSIST_PAYLOAD *payload)
- {
- PLSR_FLASH_SECTOR_SCAN scanA;
- PLSR_FLASH_SECTOR_SCAN scanB;
- const PLSR_FLASH_HEADER *selected = NULL;
- const void *backupConfig = (const void *)PLSR_BACKUP_CONFIG_ADDRESS;
- const PLSR_BACKUP_POSITION_RECORD *backupPosition;
- uint8_t selectedVersion = 0U;
- uint8_t backupVersion;
- uint8_t haveConfig = 0U;
- uint32_t selectedSectorAddress;
-
- if (payload == NULL)
- {
- return 0U;
- }
-
- selected = PlsrFlashInitializeJournal(&scanA, &scanB, &selectedVersion,
- &selectedSectorAddress);
-
- if (selected != NULL)
- {
- if (selectedVersion == PLSR_FLASH_VERSION)
- {
- *payload = ((const PLSR_FLASH_RECORD *)selected)->payload;
- }
- else
- {
- PlsrLoadV2Payload(
- payload,
- &((const PLSR_FLASH_RECORD_V2 *)selected)->payload);
- }
- haveConfig = 1U;
- }
- else
- {
- (void)memset(payload, 0, sizeof(*payload));
- }
-
- backupVersion = PlsrBackupConfigVersion(backupConfig);
- if (backupVersion == PLSR_FLASH_VERSION)
- {
- payload->config =
- ((const PLSR_BACKUP_CONFIG_RECORD *)backupConfig)->config;
- haveConfig = 1U;
- }
- else if (backupVersion == PLSR_FLASH_VERSION_V2)
- {
- const PLSR_BACKUP_CONFIG_RECORD_V2 *oldConfig =
- (const PLSR_BACKUP_CONFIG_RECORD_V2 *)backupConfig;
-
- (void)memcpy(&payload->config, oldConfig->config,
- sizeof(oldConfig->config));
- payload->config.outputMode = PLSR_OUTPUT_PULSE_DIR;
- haveConfig = 1U;
- }
- backupPosition = PlsrNewestBackupPosition();
- if (backupPosition != NULL)
- {
- payload->position = backupPosition->position;
- payload->positionValid = backupPosition->positionValid;
- payload->wasBusy = backupPosition->wasBusy;
- }
-
- if (selected != NULL)
- {
- uint8_t reserveIndex =
- (selectedSectorAddress == PLSR_FLASH_SLOT_A_ADDRESS) ? 1U : 0U;
- const PLSR_FLASH_SECTOR_SCAN *reserveScan =
- (reserveIndex == 0U) ? &scanA : &scanB;
-
- if (reserveScan->hasProgrammedSlot != 0U)
- {
- PlsrFlashReserveEraseState = (uint8_t)(reserveIndex + 1U);
- }
- }
- else if (PlsrFlashNeedsStartupRecovery(
- 0U,
- scanA.hasProgrammedSlot,
- scanA.firstErasedAddress,
- scanB.hasProgrammedSlot,
- scanB.firstErasedAddress) != 0U)
- {
- PlsrFlashReserveEraseState = PLSR_FLASH_ERASE_SECTOR_A;
- }
- return haveConfig;
- }
-
- PLSR_PLATFORM_SERVICE_RESULT PlsrPlatformServicePersistence(void)
- {
- uint32_t criticalState;
- uint8_t eraseState;
- uint8_t sectorIndex;
- uint8_t index;
-
- criticalState = PlsrPlatformEnterCritical();
- eraseState = PlsrFlashReserveEraseState;
- if (eraseState == PLSR_FLASH_ERASE_FAILED)
- {
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_SERVICE_FAILED;
- }
- if (eraseState == PLSR_FLASH_ERASE_NONE)
- {
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_SERVICE_READY;
- }
- if ((eraseState < PLSR_FLASH_ERASE_SECTOR_A)
- || (eraseState > PLSR_FLASH_ERASE_SECTOR_B))
- {
- PlsrFlashReserveEraseState = PLSR_FLASH_ERASE_FAILED;
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_SERVICE_FAILED;
- }
- for (index = 0U; index < 4U; index++)
- {
- if ((PlsrTimerRunning[index] != 0U)
- || (PlsrTimerIrqActive[index] != 0U))
- {
- PlsrPlatformExitCritical(criticalState);
- return PLSR_PLATFORM_SERVICE_DEFERRED;
- }
- }
- sectorIndex = (uint8_t)(eraseState - PLSR_FLASH_ERASE_SECTOR_A);
- PlsrPlatformExitCritical(criticalState);
-
- if (PlsrFlashEraseReserve(sectorIndex) == 0U)
- {
- PlsrFlashReserveEraseState = PLSR_FLASH_ERASE_FAILED;
- return PLSR_PLATFORM_SERVICE_FAILED;
- }
-
- PlsrFlashNextErasedAddress[sectorIndex] =
- (sectorIndex == 0U) ? PLSR_FLASH_SLOT_A_ADDRESS
- : PLSR_FLASH_SLOT_B_ADDRESS;
- PlsrFlashReserveEraseState = PLSR_FLASH_ERASE_NONE;
- return PLSR_PLATFORM_SERVICE_READY;
- }
-
- uint8_t PlsrPlatformSave(const PLSR_PERSIST_PAYLOAD *payload)
- {
- PLSR_FLASH_SECTOR_SCAN scanA;
- PLSR_FLASH_SECTOR_SCAN scanB;
- uint8_t newestVersion;
- uint32_t newestSectorAddress;
- uint8_t targetIndex;
- uint32_t targetAddress;
- uint32_t index;
- uint32_t wordCount;
- const uint32_t *words;
- HAL_StatusTypeDef status = HAL_OK;
-
- if (payload == NULL)
- {
- return 0U;
- }
-
- if (PlsrFlashJournalInitialized == 0U)
- {
- (void)PlsrFlashInitializeJournal(&scanA, &scanB, &newestVersion,
- &newestSectorAddress);
- (void)newestVersion;
- (void)newestSectorAddress;
- }
-
- if (PlsrFlashNewestAddress != 0UL)
- {
- targetIndex = PlsrFlashSectorIndex(PlsrFlashNewestAddress);
- if (PlsrFlashNextErasedAddress[targetIndex] == 0UL)
- {
- targetIndex ^= 1U;
- }
- }
- else if (PlsrFlashNextErasedAddress[0] != 0UL)
- {
- targetIndex = 0U;
- }
- else
- {
- targetIndex = 1U;
- }
-
- targetAddress = PlsrFlashNextErasedAddress[targetIndex];
- if ((targetAddress != 0UL)
- && ((PlsrFlashAddressIsJournalSlot(targetIndex, targetAddress) == 0U)
- || (PlsrFlashSlotIsErased(targetAddress) == 0U)))
- {
- targetAddress = 0UL;
- PlsrFlashNextErasedAddress[targetIndex] = 0UL;
- }
- if (targetAddress == 0UL)
- {
- uint8_t newestIndex = (PlsrFlashNewestAddress != 0UL)
- ? PlsrFlashSectorIndex(
- PlsrFlashNewestAddress)
- : 0xFFU;
- uint8_t alternateIndex = targetIndex ^ 1U;
-
- if ((targetIndex == newestIndex)
- || (PlsrFlashNextErasedAddress[alternateIndex] != 0UL))
- {
- targetIndex = alternateIndex;
- targetAddress = PlsrFlashNextErasedAddress[targetIndex];
- if ((targetAddress != 0UL)
- && ((PlsrFlashAddressIsJournalSlot(targetIndex,
- targetAddress) == 0U)
- || (PlsrFlashSlotIsErased(targetAddress) == 0U)))
- {
- targetAddress = 0UL;
- PlsrFlashNextErasedAddress[targetIndex] = 0UL;
- }
- }
- if (targetAddress == 0UL)
- {
- return 0U;
- }
- }
-
- PlsrFlashNextErasedAddress[targetIndex] =
- PlsrFlashFindErasedAfter(targetIndex, targetAddress);
-
- (void)memset(&PlsrFlashRecordBuffer, 0, sizeof(PlsrFlashRecordBuffer));
- PlsrFlashRecordBuffer.magic = PLSR_FLASH_MAGIC;
- PlsrFlashRecordBuffer.version = PLSR_FLASH_VERSION;
- PlsrFlashRecordBuffer.payloadSize = sizeof(PLSR_PERSIST_PAYLOAD);
- PlsrFlashRecordBuffer.generation = PlsrFlashNewestGeneration + 1UL;
- PlsrFlashRecordBuffer.payload = *payload;
- PlsrFlashRecordBuffer.crc32 =
- PlsrFlashRecordCrc(&PlsrFlashRecordBuffer,
- sizeof(PlsrFlashRecordBuffer.payload));
-
- if (HAL_FLASH_Unlock() != HAL_OK)
- {
- (void)HAL_FLASH_Lock();
- return 0U;
- }
- __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR
- | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR
- | FLASH_FLAG_PGSERR);
- words = (const uint32_t *)&PlsrFlashRecordBuffer;
- wordCount = sizeof(PlsrFlashRecordBuffer) / sizeof(uint32_t);
- if (status == HAL_OK)
- {
- for (index = 1UL; index < wordCount; index++)
- {
- if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,
- targetAddress + index * 4UL,
- words[index]) != HAL_OK)
- {
- status = HAL_ERROR;
- break;
- }
- }
- }
- if ((status == HAL_OK)
- && (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, targetAddress,
- PLSR_FLASH_MAGIC) != HAL_OK))
- {
- status = HAL_ERROR;
- }
- if (HAL_FLASH_Lock() != HAL_OK)
- {
- (void)HAL_FLASH_Lock();
- status = HAL_ERROR;
- }
-
- if (PlsrFlashRecordVersion((const void *)targetAddress)
- == PLSR_FLASH_VERSION)
- {
- PlsrFlashNewestAddress = targetAddress;
- PlsrFlashNewestGeneration = PlsrFlashRecordBuffer.generation;
- return (status == HAL_OK) ? 1U : 0U;
- }
- return 0U;
- }
-
- void PlsrPlatformCheckpointConfig(const PLSR_CONFIG *config)
- {
- PLSR_BACKUP_CONFIG_RECORD *record =
- (PLSR_BACKUP_CONFIG_RECORD *)PLSR_BACKUP_CONFIG_ADDRESS;
-
- if (config == NULL)
- {
- return;
- }
- record->magic = 0UL;
- record->config = *config;
- record->crc32 = PlsrCrc32(&record->config, sizeof(record->config));
- __DMB();
- record->magic = PLSR_BACKUP_CONFIG_MAGIC;
- __DMB();
- }
-
- void PlsrPlatformCheckpointPosition(int32_t position,
- uint8_t positionValid,
- uint8_t wasBusy)
- {
- PLSR_BACKUP_POSITION_RECORD *slots =
- (PLSR_BACKUP_POSITION_RECORD *)PLSR_BACKUP_POSITION_ADDRESS;
- PLSR_BACKUP_POSITION_RECORD *record;
-
- PlsrBackupPositionGeneration++;
- record = &slots[PlsrBackupPositionGeneration & 1UL];
- record->magic = 0UL;
- record->generation = PlsrBackupPositionGeneration;
- record->position = position;
- record->positionValid = (positionValid != 0U) ? 1U : 0U;
- record->wasBusy = (wasBusy != 0U) ? 1U : 0U;
- record->reserved = 0U;
- record->crc32 = PlsrCrc32(&record->generation,
- sizeof(record->generation)
- + sizeof(record->position)
- + sizeof(record->positionValid)
- + sizeof(record->wasBusy)
- + sizeof(record->reserved));
- __DMB();
- record->magic = PLSR_BACKUP_POSITION_MAGIC;
- __DMB();
- }
-
- uint32_t PlsrPlatformEnterCritical(void)
- {
- uint32_t state = __get_PRIMASK();
- __disable_irq();
- __DMB();
- return state;
- }
-
- void PlsrPlatformExitCritical(uint32_t state)
- {
- __DMB();
- if (state == 0UL)
- {
- __enable_irq();
- }
- }
-
- static void PlsrHandleTimerIrq(uint8_t pulseOutput)
- {
- TIM_TypeDef *timer;
- #if PLSR_DEBUG_TIMING
- uint32_t startedAt;
- uint32_t elapsedCycles;
- uint8_t timingOutput = pulseOutput;
-
- startedAt = DWT->CYCCNT;
- #endif
- timer = PlsrTimerMap[pulseOutput].timer;
-
- if (PlsrTimerIrqActive[pulseOutput] != 0U)
- {
- #if PLSR_DEBUG_TIMING
- goto irq_record;
- #else
- return;
- #endif
- }
- PlsrTimerIrqActive[pulseOutput] = 1U;
-
- if (((timer->SR & TIM_SR_CC1IF) != 0UL)
- && ((timer->DIER & TIM_DIER_CC1IE) != 0UL))
- {
- uint8_t owner = ((pulseOutput & 2U) == 0U) ? 0U : 2U;
-
- if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_PULSE_DIR)
- && (PlsrFiniteRetargetPending[pulseOutput] != 0U))
- {
- timer->SR = ~TIM_SR_CC1IF;
- PlsrFiniteRetargetAtFallingEdge(pulseOutput);
- goto irq_done;
- }
- if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_PULSE_DIR)
- && (PlsrFiniteTailStopPending[pulseOutput] != 0U))
- {
- timer->SR = ~TIM_SR_CC1IF;
- PlsrFiniteStopAtFallingEdge(pulseOutput);
- goto irq_done;
- }
- #if PLSR_DEBUG_TIMING
- timingOutput = owner;
- #endif
- timer->SR = ~TIM_SR_CC1IF;
- if ((owner <= 2U)
- && (PlsrTimerRunning[owner] != 0U)
- && (PlsrTimerOutputMode[owner] == PLSR_OUTPUT_AB))
- {
- uint8_t pairOutput = (uint8_t)(owner + 1U);
- TIM_TypeDef *baseTimer = PlsrTimerMap[owner].timer;
- TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
- PLSR_AB_SETTING pending;
-
- if (PlsrAbStopPending[owner] != 0U)
- {
- if (PlsrAbCanFastGateAtZero(owner) == 0U)
- {
- goto irq_done;
- }
- baseTimer->DIER &= ~(TIM_DIER_CC1IE | TIM_DIER_UIE);
- pairTimer->DIER &= ~(TIM_DIER_CC1IE | TIM_DIER_UIE);
- baseTimer->SR = ~TIM_SR_CC1IF;
- pairTimer->SR = ~TIM_SR_CC1IF;
- PlsrFrequencyVerifyPending[owner] =
- PLSR_FREQUENCY_VERIFY_NONE;
- PlsrAbVerifyOwner[owner] = PLSR_COUNTER_NONE;
- PlsrAbVerifyOwner[pairOutput] = PLSR_COUNTER_NONE;
- PlsrAbFastGate(owner);
- PlsrAbFastGated[owner] = 1U;
- PlsrDeferredPulsePending[owner] = 0U;
- PlsrPulseTimerIrq(owner);
- goto irq_done;
- }
- if (pulseOutput != PlsrAbLagAxis[owner])
- {
- if (PlsrDeferredPulsePending[owner] != 0U)
- {
- PlsrDeferredPulsePending[owner] = 0U;
- timer->DIER &= ~TIM_DIER_CC1IE;
- PlsrPulseTimerIrq(owner);
- }
- goto irq_done;
- }
- if (PlsrDeferredPulsePending[owner] != 0U)
- {
- goto irq_done;
- }
- if (PlsrAbFrequencyPending[owner] != 0U)
- {
- pending = PlsrAbPendingSetting[owner];
- PlsrAbFrequencyPending[owner] = 0U;
- PlsrAbLoadAndStart(owner, &pending);
- PlsrAbActiveSetting[owner] = pending;
- PlsrTimerActiveSetting[owner] =
- PlsrTimerQueuedSetting[owner];
- PlsrTimerActiveFrequencyHz[owner] =
- pending.actualFrequencyHz;
- PlsrDeferredPulsePending[owner] = 1U;
- PlsrAbScheduleFrequencyVerify(owner);
- goto irq_done;
- }
- PlsrPulseTimerIrq(owner);
- }
- goto irq_done;
- }
-
- if (((timer->SR & TIM_SR_UIF) != 0UL)
- && ((timer->DIER & TIM_DIER_UIE) != 0UL))
- {
- timer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
- if ((PlsrFiniteActive[pulseOutput] != 0U)
- && (PlsrFiniteFrequencyPending[pulseOutput] != 0U))
- {
- PlsrTimerActiveFrequencyHz[pulseOutput] =
- PlsrTimerQueuedFrequencyHz[pulseOutput];
- PlsrTimerActiveSetting[pulseOutput] =
- PlsrTimerQueuedSetting[pulseOutput];
- PlsrFiniteFrequencyPending[pulseOutput] = 0U;
- timer->DIER &= ~TIM_DIER_UIE;
- goto irq_done;
- }
- if (PlsrPlatformSettingsDiffer(
- &PlsrTimerActiveSetting[pulseOutput],
- &PlsrTimerQueuedSetting[pulseOutput]) != 0U)
- {
- PlsrFrequencyVerifyPending[pulseOutput] = 1U;
- PlsrTimerActiveFrequencyHz[pulseOutput] =
- PlsrTimerQueuedFrequencyHz[pulseOutput];
- PlsrTimerActiveSetting[pulseOutput] =
- PlsrTimerQueuedSetting[pulseOutput];
- }
- PlsrPulseTimerIrq(pulseOutput);
- }
- irq_done:
- PlsrTimerIrqActive[pulseOutput] = 0U;
- #if PLSR_DEBUG_TIMING
- irq_record:
- elapsedCycles = DWT->CYCCNT - startedAt;
- PlsrIrqCount[timingOutput]++;
- PlsrIrqLastCycles[timingOutput] = elapsedCycles;
- if (elapsedCycles > PlsrIrqMaxCycles[timingOutput])
- {
- PlsrIrqMaxCycles[timingOutput] = elapsedCycles;
- }
- #endif
- }
-
- static uint8_t PlsrHandleScheduledAbVerify(uint8_t pulseOutput)
- {
- uint8_t verifyOwner = PlsrAbVerifyOwner[pulseOutput];
- TIM_TypeDef *timer;
- #if PLSR_DEBUG_TIMING
- uint32_t startedAt;
- uint32_t elapsedCycles;
- #endif
-
- if (verifyOwner > 2U)
- {
- return 0U;
- }
- timer = PlsrTimerMap[pulseOutput].timer;
- if (((timer->SR & TIM_SR_UIF) == 0UL)
- || ((timer->DIER & TIM_DIER_UIE) == 0UL))
- {
- return 0U;
- }
- #if PLSR_DEBUG_TIMING
- startedAt = DWT->CYCCNT;
- #endif
- timer->SR = ~TIM_SR_UIF;
- timer->DIER &= ~TIM_DIER_UIE;
- PlsrAbVerifyOwner[pulseOutput] = PLSR_COUNTER_NONE;
- if (PlsrFrequencyVerifyPending[verifyOwner]
- == PLSR_FREQUENCY_VERIFY_AB_AUX_IRQ)
- {
- PlsrFrequencyVerifyPending[verifyOwner] =
- PLSR_FREQUENCY_VERIFY_NONE;
- PlsrFrequencyVerifyPulseCount[verifyOwner] = 0U;
- (void)PlsrVerifyActiveFrequency(verifyOwner);
- }
- #if PLSR_DEBUG_TIMING
- elapsedCycles = DWT->CYCCNT - startedAt;
- PlsrIrqCount[verifyOwner]++;
- PlsrIrqLastCycles[verifyOwner] = elapsedCycles;
- if (elapsedCycles > PlsrIrqMaxCycles[verifyOwner])
- {
- PlsrIrqMaxCycles[verifyOwner] = elapsedCycles;
- }
- #endif
- return 1U;
- }
-
- static uint8_t PlsrFinalStopIrqIsPending(uint8_t pulseOutput)
- {
- uint8_t owner = ((pulseOutput & 2U) == 0U) ? 0U : 2U;
- TIM_TypeDef *timer = PlsrTimerMap[pulseOutput].timer;
-
- return ((PlsrAbStopPending[owner] != 0U)
- && ((timer->SR & TIM_SR_CC1IF) != 0UL)
- && ((timer->DIER & TIM_DIER_CC1IE) != 0UL)) ? 1U : 0U;
- }
-
- static uint8_t PlsrHandleFinalArmJob(uint8_t pulseOutput)
- {
- uint8_t owner = PlsrAbFinalArmJobOwner[pulseOutput];
- #if PLSR_DEBUG_TIMING
- uint32_t startedAt;
- uint32_t elapsedCycles;
- #endif
-
- if (owner > 2U)
- {
- return 0U;
- }
- PlsrAbFinalArmJobOwner[pulseOutput] = PLSR_COUNTER_NONE;
- #if PLSR_DEBUG_TIMING
- startedAt = DWT->CYCCNT;
- #endif
- PlsrFinalArmJobIrq(owner);
- #if PLSR_DEBUG_TIMING
- elapsedCycles = DWT->CYCCNT - startedAt;
- PlsrFinalArmJobLastCycles[owner] = elapsedCycles;
- if (elapsedCycles > PlsrFinalArmJobMaxCycles[owner])
- {
- PlsrFinalArmJobMaxCycles[owner] = elapsedCycles;
- }
- #endif
- return 1U;
- }
-
- static void PlsrDispatchTimerIrq(uint8_t pulseOutput)
- {
- if (PlsrFinalStopIrqIsPending(pulseOutput) != 0U)
- {
- PlsrHandleTimerIrq(pulseOutput);
- return;
- }
- if (PlsrHandleFinalArmJob(pulseOutput) != 0U)
- {
- return;
- }
- if (PlsrHandleScheduledAbVerify(pulseOutput) == 0U)
- {
- PlsrHandleTimerIrq(pulseOutput);
- }
- }
-
- void TIM1_UP_TIM10_IRQHandler(void)
- {
- PlsrDispatchTimerIrq(0U);
- }
-
- void TIM8_UP_TIM13_IRQHandler(void)
- {
- PlsrDispatchTimerIrq(1U);
- }
-
- void TIM1_TRG_COM_TIM11_IRQHandler(void)
- {
- PlsrDispatchTimerIrq(2U);
- }
-
- void TIM8_TRG_COM_TIM14_IRQHandler(void)
- {
- PlsrDispatchTimerIrq(3U);
- }
-
- static void PlsrHandleCounterIrq(uint8_t counterIndex)
- {
- TIM_TypeDef *counter;
- #if PLSR_DEBUG_TIMING
- uint32_t startedAt = DWT->CYCCNT;
- #endif
-
- if (counterIndex >= PLSR_COUNTER_COUNT)
- {
- return;
- }
- counter = PlsrCounters[counterIndex];
- if (((counter->SR & TIM_SR_CC1IF) != 0UL)
- && ((counter->DIER & TIM_DIER_CC1IE) != 0UL))
- {
- uint8_t owner = PlsrCounterOwner[counterIndex];
-
- counter->SR = ~TIM_SR_CC1IF;
- if ((owner <= 3U) && (PlsrFiniteActive[owner] != 0U))
- {
- PlsrFinitePrepareNextStepIrq(owner, counter);
- }
- }
- if (((counter->SR & TIM_SR_UIF) != 0UL)
- && ((counter->DIER & TIM_DIER_UIE) != 0UL))
- {
- uint8_t owner = PlsrCounterOwner[counterIndex];
-
- counter->SR = ~TIM_SR_UIF;
- if ((owner <= 3U) && (PlsrFiniteActive[owner] != 0U))
- {
- PlsrFiniteCounterIrq(owner, counter);
- #if PLSR_DEBUG_TIMING
- {
- uint32_t elapsedCycles = DWT->CYCCNT - startedAt;
-
- if (PlsrFiniteCompletionPending[owner] != 0U)
- {
- PlsrFiniteFinalIrqLastCycles[owner] = elapsedCycles;
- if (elapsedCycles > PlsrFiniteFinalIrqMaxCycles[owner])
- {
- PlsrFiniteFinalIrqMaxCycles[owner] = elapsedCycles;
- }
- }
- else
- {
- PlsrFiniteBlockIrqCount[owner]++;
- if (elapsedCycles > PlsrFiniteBlockIrqMaxCycles[owner])
- {
- PlsrFiniteBlockIrqMaxCycles[owner] = elapsedCycles;
- }
- }
- }
- #endif
- }
- else
- {
- PlsrCounterOverflowPulses[counterIndex] +=
- PLSR_COUNTER_BLOCK_PULSES;
- }
- }
- }
-
- static void PlsrFiniteArmNextStepPrepare(uint8_t pulseOutput,
- TIM_TypeDef *counter,
- uint32_t blockPulses)
- {
- uint16_t nextIndex =
- (uint16_t)(PlsrFiniteStepIndex[pulseOutput] + 1U);
-
- counter->DIER &= ~TIM_DIER_CC1IE;
- counter->SR = ~TIM_SR_CC1IF;
- if ((nextIndex >= PlsrFiniteStepCount[pulseOutput])
- || (PlsrFiniteRemainingPulses[pulseOutput] > blockPulses))
- {
- return;
- }
- if (blockPulses > 1UL)
- {
- counter->CCR1 = blockPulses - 1UL;
- counter->DIER |= TIM_DIER_CC1IE;
- }
- else
- {
- PlsrFinitePrepareNextStepIrq(pulseOutput, counter);
- }
- }
-
- static void PlsrFinitePrepareNextStepIrq(uint8_t pulseOutput,
- TIM_TypeDef *counter)
- {
- uint16_t nextIndex =
- (uint16_t)(PlsrFiniteStepIndex[pulseOutput] + 1U);
- TIM_TypeDef *timer;
- const PLSR_PLATFORM_TIMER_SETTING *next;
-
- counter->DIER &= ~TIM_DIER_CC1IE;
- if (nextIndex >= PlsrFiniteStepCount[pulseOutput])
- {
- return;
- }
- timer = PlsrTimerMap[pulseOutput].timer;
- next = &PlsrFiniteSteps[pulseOutput][nextIndex].setting;
- timer->PSC = next->prescaler;
- timer->ARR = next->period;
- timer->CCR1 = next->compare;
- PlsrTimerQueuedSetting[pulseOutput] = *next;
- PlsrTimerQueuedFrequencyHz[pulseOutput] = next->actualFrequencyHz;
- }
-
- static void PlsrFiniteCounterIrq(uint8_t pulseOutput,
- TIM_TypeDef *counter)
- {
- uint32_t completedBlock =
- (PlsrFiniteRemainingPulses[pulseOutput]
- > PLSR_COUNTER_BLOCK_PULSES)
- ? PLSR_COUNTER_BLOCK_PULSES
- : PlsrFiniteRemainingPulses[pulseOutput];
-
- PlsrFiniteRemainingPulses[pulseOutput] -= completedBlock;
- if (PlsrFiniteRemainingPulses[pulseOutput] != 0UL)
- {
- uint32_t nextBlock =
- (PlsrFiniteRemainingPulses[pulseOutput]
- > PLSR_COUNTER_BLOCK_PULSES)
- ? PLSR_COUNTER_BLOCK_PULSES
- : PlsrFiniteRemainingPulses[pulseOutput];
-
- PlsrCounterOverflowPulses[PlsrCounterIndexByOutput[pulseOutput]] +=
- completedBlock;
- counter->ARR = (nextBlock == 1UL) ? 1UL : (nextBlock - 1UL);
- PlsrFiniteCounterPreload[pulseOutput] =
- (nextBlock == 1UL) ? 1U : 0U;
- counter->CNT = PlsrFiniteCounterPreload[pulseOutput];
- PlsrFiniteArmNextStepPrepare(pulseOutput, counter, nextBlock);
- return;
- }
-
- if (PlsrFiniteStepCount[pulseOutput] != 0U)
- {
- uint16_t completedIndex = PlsrFiniteStepIndex[pulseOutput];
- uint16_t nextIndex = (uint16_t)(completedIndex + 1U);
- uint8_t hasNext = (nextIndex
- < PlsrFiniteStepCount[pulseOutput]) ? 1U : 0U;
-
- PlsrObservedPulseBase[pulseOutput] +=
- PlsrFiniteTargetPulses[pulseOutput];
- PlsrObservedPulsePublished[pulseOutput] =
- PlsrObservedPulseBase[pulseOutput];
- PlsrFiniteCompletedStepCount[pulseOutput] =
- (uint16_t)(completedIndex + 1U);
-
- if (hasNext != 0U)
- {
- const PLSR_PLATFORM_FINITE_STEP *next =
- &PlsrFiniteSteps[pulseOutput][nextIndex];
- uint32_t firstBlock =
- (next->pulseCount > PLSR_COUNTER_BLOCK_PULSES)
- ? PLSR_COUNTER_BLOCK_PULSES : next->pulseCount;
- PlsrFiniteStepIndex[pulseOutput] = nextIndex;
- PlsrFiniteTargetPulses[pulseOutput] = next->pulseCount;
- PlsrFiniteRemainingPulses[pulseOutput] = next->pulseCount;
- PlsrCounterOverflowPulses[
- PlsrCounterIndexByOutput[pulseOutput]] = 0UL;
- counter->ARR = (firstBlock == 1UL)
- ? 1UL : (firstBlock - 1UL);
- PlsrFiniteCounterPreload[pulseOutput] =
- (firstBlock == 1UL) ? 1U : 0U;
- counter->CNT = PlsrFiniteCounterPreload[pulseOutput];
- PlsrTimerActiveSetting[pulseOutput] = next->setting;
- PlsrTimerActiveFrequencyHz[pulseOutput] =
- next->setting.actualFrequencyHz;
- PlsrTimerQueuedSetting[pulseOutput] = next->setting;
- PlsrTimerQueuedFrequencyHz[pulseOutput] =
- next->setting.actualFrequencyHz;
- PlsrFiniteArmNextStepPrepare(pulseOutput, counter, firstBlock);
- return;
- }
- }
-
- counter->DIER = 0UL;
- counter->CR1 &= ~TIM_CR1_CEN;
- counter->SMCR &= ~(TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0);
-
- /*
- * An OC rising edge is the terminal pulse's falling edge because the
- * output stage is active low. The target-count update IRQ therefore is
- * already the safe idle boundary: stop here before CCR1 can start an
- * extra terminal pulse.
- */
- PlsrFiniteStopAtFallingEdge(pulseOutput);
- }
-
- static void PlsrFiniteRetargetAtFallingEdge(uint8_t pulseOutput)
- {
- uint8_t counterIndex = PlsrCounterIndexByOutput[pulseOutput];
- TIM_TypeDef *counter = PlsrCounters[counterIndex];
- TIM_TypeDef *timer = PlsrTimerMap[pulseOutput].timer;
- uint32_t drainPulses = PlsrFiniteRetargetDrainPulses[pulseOutput];
- uint32_t blockCount;
- uint32_t completed;
-
- PlsrFiniteRetargetPending[pulseOutput] = 0U;
- PlsrFiniteRetargetDrainPulses[pulseOutput] = 0UL;
- timer->DIER &= ~TIM_DIER_CC1IE;
- PlsrCounterSuspend(pulseOutput);
- blockCount = (uint16_t)counter->CNT;
- if (blockCount >= PlsrFiniteCounterPreload[pulseOutput])
- {
- blockCount -= PlsrFiniteCounterPreload[pulseOutput];
- }
- completed = PlsrFiniteTargetPulses[pulseOutput]
- - PlsrFiniteRemainingPulses[pulseOutput] + blockCount;
- if (PlsrFiniteStepCount[pulseOutput] != 0U)
- {
- completed += PlsrFiniteSteps[pulseOutput][
- PlsrFiniteStepIndex[pulseOutput]].segmentPulseOffset;
- }
- if (completed > PlsrFiniteTargetPulses[pulseOutput])
- {
- completed = PlsrFiniteTargetPulses[pulseOutput];
- }
- PlsrFiniteTargetPulses[pulseOutput] = completed + drainPulses;
- PlsrFiniteRemainingPulses[pulseOutput] = drainPulses;
- PlsrFiniteStepCount[pulseOutput] = 0U;
- PlsrFiniteStepIndex[pulseOutput] = 0U;
- PlsrFiniteBoundaryReadIndex[pulseOutput] = 0U;
- PlsrFiniteCompletedStepCount[pulseOutput] = 0U;
- counter->ARR = (drainPulses == 1UL) ? 1UL : (drainPulses - 1UL);
- PlsrFiniteCounterPreload[pulseOutput] =
- (drainPulses == 1UL) ? 1U : 0U;
- counter->CNT = 0UL;
- counter->EGR = TIM_EGR_UG;
- counter->CNT = PlsrFiniteCounterPreload[pulseOutput];
- counter->SR = 0UL;
- counter->DIER = TIM_DIER_UIE;
- PlsrCounterBegin(pulseOutput);
- }
-
- static void PlsrFiniteStopAtFallingEdge(uint8_t pulseOutput)
- {
- TIM_TypeDef *timer = PlsrTimerMap[pulseOutput].timer;
-
- /* OC1 and GPIO idle are both high here; hand off without a pin glitch. */
- PlsrPulsePinCaptureIdle(pulseOutput);
- timer->DIER = 0UL;
- timer->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
- timer->CR1 &= ~TIM_CR1_CEN;
- timer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
- PlsrFiniteTailStopPending[pulseOutput] = 0U;
- PlsrFiniteActive[pulseOutput] = 0U;
- PlsrFiniteCompletionPending[pulseOutput] = 1U;
- PlsrFiniteFrequencyPending[pulseOutput] = 0U;
- PlsrFiniteCounterPreload[pulseOutput] = 0U;
- __DSB();
- }
-
- void TIM1_BRK_TIM9_IRQHandler(void)
- {
- PlsrHandleCounterIrq(0U);
- }
-
- void TIM8_BRK_TIM12_IRQHandler(void)
- {
- PlsrHandleCounterIrq(1U);
- }
-
- #endif /* PLSR_HOST_TEST */
|