No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.
 
 
 
 
 
 

5311 líneas
173 KiB

  1. #include "plsr_platform.h"
  2. #include "plsr.h"
  3. static uint8_t PlsrFlashNeedsStartupRecovery(
  4. uint8_t haveValidRecord,
  5. uint8_t sectorAHasProgrammedSlot,
  6. uint32_t sectorAFirstErasedAddress,
  7. uint8_t sectorBHasProgrammedSlot,
  8. uint32_t sectorBFirstErasedAddress)
  9. {
  10. return ((haveValidRecord == 0U)
  11. && (sectorAHasProgrammedSlot != 0U)
  12. && (sectorBHasProgrammedSlot != 0U)
  13. && (sectorAFirstErasedAddress == 0UL)
  14. && (sectorBFirstErasedAddress == 0UL)) ? 1U : 0U;
  15. }
  16. #ifdef PLSR_HOST_TEST
  17. #include <string.h>
  18. static uint8_t PlsrHostPulseActive[4];
  19. static uint32_t PlsrHostFrequency[4];
  20. static uint32_t PlsrHostQueuedFrequency[4];
  21. static PLSR_PLATFORM_TIMER_SETTING PlsrHostActiveSetting[4];
  22. static PLSR_PLATFORM_TIMER_SETTING PlsrHostQueuedSetting[4];
  23. static uint8_t PlsrHostUpdatePending[4];
  24. static uint8_t PlsrHostOutputMode[4];
  25. static uint8_t PlsrHostDirectionPositive[4];
  26. static uint8_t PlsrHostAbQuarter[4];
  27. static uint8_t PlsrHostAbPhase[4];
  28. static uint32_t PlsrHostAbTransitions[4];
  29. static uint8_t PlsrHostAbStopPending[4];
  30. static uint8_t PlsrHostAbFastGated[4];
  31. static uint32_t PlsrHostAbFastGateCount;
  32. static uint32_t PlsrHostAbCleanupCount;
  33. static uint64_t PlsrHostObservedPulses[4];
  34. static uint8_t PlsrHostInputs[2];
  35. static uint8_t PlsrHostSelectedPulse;
  36. static uint8_t PlsrHostDirectionLevel;
  37. static uint8_t PlsrHostDirectionPinLevel[4];
  38. static uint32_t PlsrHostDirectionWriteCount[4];
  39. static uint32_t PlsrHostDirectionTransitionCount[4];
  40. static uint8_t PlsrHostEmitPulseOnCriticalEntry;
  41. static uint8_t PlsrHostEmitPulseOnCriticalExit;
  42. static uint8_t PlsrHostLatchPulseOnCriticalEntry;
  43. static uint8_t PlsrHostCriticalEntriesToSkip;
  44. static uint8_t PlsrHostLatchAbFinalQuarterOnStopArm;
  45. static uint8_t PlsrHostCompleteAbCycleOnQueueCommit;
  46. static uint32_t PlsrHostCriticalDepth;
  47. static uint8_t PlsrHostFailNextStart;
  48. static uint8_t PlsrHostStaleNextFrequencyAtUpdate;
  49. static uint8_t PlsrHostFailNextFrequencyAtUpdate;
  50. static uint8_t PlsrHostFailNextStopRequest;
  51. static uint8_t PlsrHostFinalArmJobPending;
  52. static uint8_t PlsrHostFinalArmJobOwner;
  53. static uint8_t PlsrHostDeferFinalArmJob;
  54. static int32_t PlsrHostCountOffset;
  55. static int32_t PlsrHostFrequencyOffsetHz;
  56. static uint8_t PlsrHostCurveMismatchPending;
  57. static uint16_t PlsrHostDiagnosticFault;
  58. static PLSR_PERSIST_PAYLOAD PlsrHostPersistentPayload;
  59. static uint8_t PlsrHostPersistentValid;
  60. static uint32_t PlsrHostSaveCount;
  61. static uint8_t PlsrHostFiniteEnabled;
  62. static uint8_t PlsrHostFiniteActive[4];
  63. static uint8_t PlsrHostFiniteComplete[4];
  64. static uint8_t PlsrHostFiniteFrequencyPending[4];
  65. static uint8_t PlsrHostCountedStreamActive[4];
  66. static uint32_t PlsrHostFiniteTarget[4];
  67. static uint32_t PlsrHostFiniteEmitted[4];
  68. static PLSR_PLATFORM_FINITE_STEP *PlsrHostFiniteSteps[4];
  69. static uint16_t PlsrHostFiniteStepCount[4];
  70. static uint16_t PlsrHostFiniteStepIndex[4];
  71. static uint16_t PlsrHostFiniteBoundaryReadIndex[4];
  72. static uint16_t PlsrHostFiniteCompletedStepCount[4];
  73. static void PlsrHostServiceFinalArmJob(void);
  74. static uint32_t PlsrHostOffsetFrequency(uint32_t frequencyHz)
  75. {
  76. int64_t adjusted = (int64_t)frequencyHz
  77. + (int64_t)PlsrHostFrequencyOffsetHz;
  78. if (adjusted < 1)
  79. {
  80. adjusted = 1;
  81. }
  82. if (adjusted > (int64_t)PLSR_FREQUENCY_MAX_HZ)
  83. {
  84. adjusted = (int64_t)PLSR_FREQUENCY_MAX_HZ;
  85. }
  86. return (uint32_t)adjusted;
  87. }
  88. static void PlsrHostLatchPulse(uint8_t pulseOutput)
  89. {
  90. if ((pulseOutput <= 3U)
  91. && (PlsrHostPulseActive[pulseOutput] != 0U))
  92. {
  93. if (PlsrHostCurveMismatchPending != 0U)
  94. {
  95. PlsrHostCurveMismatchPending = 0U;
  96. PlsrHostDiagnosticFault = 3U;
  97. }
  98. else if ((PlsrHostOutputMode[pulseOutput] != PLSR_OUTPUT_AB)
  99. || (PlsrHostAbStopPending[pulseOutput] == 0U))
  100. {
  101. PlsrHostFrequency[pulseOutput] =
  102. PlsrHostQueuedFrequency[pulseOutput];
  103. PlsrHostActiveSetting[pulseOutput] =
  104. PlsrHostQueuedSetting[pulseOutput];
  105. }
  106. PlsrHostObservedPulses[pulseOutput]++;
  107. PlsrHostUpdatePending[pulseOutput] = 1U;
  108. }
  109. }
  110. static void PlsrHostServicePendingPulse(uint8_t pulseOutput)
  111. {
  112. if ((pulseOutput <= 3U)
  113. && (PlsrHostUpdatePending[pulseOutput] != 0U))
  114. {
  115. PlsrHostUpdatePending[pulseOutput] = 0U;
  116. if ((PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  117. && (PlsrHostAbStopPending[pulseOutput] != 0U)
  118. && (PlsrHostAbFastGated[pulseOutput] == 0U))
  119. {
  120. PlsrHostAbFastGated[pulseOutput] = 1U;
  121. PlsrHostPulseActive[pulseOutput] = 0U;
  122. PlsrHostAbFastGateCount++;
  123. }
  124. PlsrPulseTimerIrq(pulseOutput);
  125. }
  126. if (PlsrHostDeferFinalArmJob == 0U)
  127. {
  128. PlsrHostServiceFinalArmJob();
  129. }
  130. }
  131. static void PlsrHostServiceFinalArmJob(void)
  132. {
  133. uint8_t owner;
  134. if (PlsrHostFinalArmJobPending == 0U)
  135. {
  136. return;
  137. }
  138. owner = PlsrHostFinalArmJobOwner;
  139. PlsrHostFinalArmJobPending = 0U;
  140. PlsrHostFinalArmJobOwner = 0xFFU;
  141. PlsrFinalArmJobIrq(owner);
  142. }
  143. static uint8_t PlsrHostAdvanceAbQuarter(uint8_t pulseOutput)
  144. {
  145. static const uint8_t positivePhase[4] = {0U, 2U, 3U, 1U};
  146. static const uint8_t negativePhase[4] = {0U, 1U, 3U, 2U};
  147. if ((pulseOutput > 3U)
  148. || (PlsrHostPulseActive[pulseOutput] == 0U)
  149. || (PlsrHostOutputMode[pulseOutput] != PLSR_OUTPUT_AB))
  150. {
  151. return 0U;
  152. }
  153. PlsrHostAbQuarter[pulseOutput] =
  154. (uint8_t)((PlsrHostAbQuarter[pulseOutput] + 1U) & 3U);
  155. PlsrHostAbPhase[pulseOutput] =
  156. (PlsrHostDirectionPositive[pulseOutput] != 0U)
  157. ? positivePhase[PlsrHostAbQuarter[pulseOutput]]
  158. : negativePhase[PlsrHostAbQuarter[pulseOutput]];
  159. PlsrHostAbTransitions[pulseOutput]++;
  160. if (PlsrHostAbQuarter[pulseOutput] != 0U)
  161. {
  162. return 0U;
  163. }
  164. PlsrHostLatchPulse(pulseOutput);
  165. return 1U;
  166. }
  167. uint8_t PlsrPlatformInit(void)
  168. {
  169. uint8_t index;
  170. (void)memset(PlsrHostPulseActive, 0, sizeof(PlsrHostPulseActive));
  171. (void)memset(PlsrHostFrequency, 0, sizeof(PlsrHostFrequency));
  172. (void)memset(PlsrHostQueuedFrequency, 0,
  173. sizeof(PlsrHostQueuedFrequency));
  174. (void)memset(PlsrHostActiveSetting, 0,
  175. sizeof(PlsrHostActiveSetting));
  176. (void)memset(PlsrHostQueuedSetting, 0,
  177. sizeof(PlsrHostQueuedSetting));
  178. (void)memset(PlsrHostUpdatePending, 0,
  179. sizeof(PlsrHostUpdatePending));
  180. (void)memset(PlsrHostOutputMode, 0, sizeof(PlsrHostOutputMode));
  181. (void)memset(PlsrHostDirectionPositive, 0,
  182. sizeof(PlsrHostDirectionPositive));
  183. (void)memset(PlsrHostAbQuarter, 0, sizeof(PlsrHostAbQuarter));
  184. (void)memset(PlsrHostAbPhase, 0, sizeof(PlsrHostAbPhase));
  185. (void)memset(PlsrHostAbTransitions, 0,
  186. sizeof(PlsrHostAbTransitions));
  187. (void)memset(PlsrHostAbStopPending, 0,
  188. sizeof(PlsrHostAbStopPending));
  189. (void)memset(PlsrHostAbFastGated, 0,
  190. sizeof(PlsrHostAbFastGated));
  191. PlsrHostAbFastGateCount = 0UL;
  192. PlsrHostAbCleanupCount = 0UL;
  193. (void)memset(PlsrHostObservedPulses, 0,
  194. sizeof(PlsrHostObservedPulses));
  195. PlsrHostSelectedPulse = 0U;
  196. PlsrHostDirectionLevel = 0U;
  197. for (index = 0U; index < 4U; index++)
  198. {
  199. PlsrHostDirectionPinLevel[index] = 1U;
  200. PlsrHostDirectionWriteCount[index] = 0UL;
  201. PlsrHostDirectionTransitionCount[index] = 0UL;
  202. }
  203. PlsrHostEmitPulseOnCriticalEntry = 0U;
  204. PlsrHostEmitPulseOnCriticalExit = 0U;
  205. PlsrHostLatchPulseOnCriticalEntry = 0U;
  206. PlsrHostCriticalEntriesToSkip = 0U;
  207. PlsrHostLatchAbFinalQuarterOnStopArm = 0U;
  208. PlsrHostCompleteAbCycleOnQueueCommit = 0U;
  209. PlsrHostCriticalDepth = 0UL;
  210. PlsrHostFailNextStart = 0U;
  211. PlsrHostStaleNextFrequencyAtUpdate = 0U;
  212. PlsrHostFailNextFrequencyAtUpdate = 0U;
  213. PlsrHostFailNextStopRequest = 0U;
  214. PlsrHostFinalArmJobPending = 0U;
  215. PlsrHostFinalArmJobOwner = 0xFFU;
  216. PlsrHostDeferFinalArmJob = 0U;
  217. PlsrHostCountOffset = 0L;
  218. PlsrHostFrequencyOffsetHz = 0L;
  219. PlsrHostCurveMismatchPending = 0U;
  220. PlsrHostDiagnosticFault = 0U;
  221. PlsrHostFiniteEnabled = 0U;
  222. (void)memset(PlsrHostFiniteActive, 0, sizeof(PlsrHostFiniteActive));
  223. (void)memset(PlsrHostFiniteComplete, 0,
  224. sizeof(PlsrHostFiniteComplete));
  225. (void)memset(PlsrHostFiniteFrequencyPending, 0,
  226. sizeof(PlsrHostFiniteFrequencyPending));
  227. (void)memset(PlsrHostFiniteTarget, 0, sizeof(PlsrHostFiniteTarget));
  228. (void)memset(PlsrHostFiniteEmitted, 0, sizeof(PlsrHostFiniteEmitted));
  229. (void)memset(PlsrHostFiniteSteps, 0, sizeof(PlsrHostFiniteSteps));
  230. (void)memset(PlsrHostFiniteStepCount, 0,
  231. sizeof(PlsrHostFiniteStepCount));
  232. (void)memset(PlsrHostFiniteStepIndex, 0,
  233. sizeof(PlsrHostFiniteStepIndex));
  234. (void)memset(PlsrHostFiniteBoundaryReadIndex, 0,
  235. sizeof(PlsrHostFiniteBoundaryReadIndex));
  236. (void)memset(PlsrHostFiniteCompletedStepCount, 0,
  237. sizeof(PlsrHostFiniteCompletedStepCount));
  238. return 1U;
  239. }
  240. uint8_t PlsrPlatformPrepare(uint8_t pulseOutput,
  241. uint8_t directionOutput,
  242. uint8_t directionLevel,
  243. uint8_t outputMode,
  244. uint8_t directionPositive)
  245. {
  246. uint8_t index;
  247. uint8_t pinLevel;
  248. if (PlsrHostFailNextStart != 0U)
  249. {
  250. PlsrHostFailNextStart = 0U;
  251. return 0U;
  252. }
  253. if ((pulseOutput > 3U) || (directionOutput > 3U)
  254. || (outputMode > PLSR_OUTPUT_AB)
  255. || ((outputMode == PLSR_OUTPUT_AB)
  256. && ((pulseOutput & 1U) != 0U))
  257. || (PlsrHostAbStopPending[0] != 0U)
  258. || (PlsrHostAbStopPending[2] != 0U))
  259. {
  260. return 0U;
  261. }
  262. for (index = 0U; index < 4U; index++)
  263. {
  264. PlsrHostPulseActive[index] = 0U;
  265. PlsrHostFrequency[index] = 0UL;
  266. PlsrHostQueuedFrequency[index] = 0UL;
  267. PlsrHostUpdatePending[index] = 0U;
  268. pinLevel = ((outputMode == PLSR_OUTPUT_PULSE_DIR)
  269. && (index == directionOutput)
  270. && (directionLevel != 0U)) ? 0U : 1U;
  271. PlsrHostDirectionWriteCount[index]++;
  272. if (PlsrHostDirectionPinLevel[index] != pinLevel)
  273. {
  274. PlsrHostDirectionTransitionCount[index]++;
  275. }
  276. PlsrHostDirectionPinLevel[index] = pinLevel;
  277. }
  278. PlsrHostSelectedPulse = pulseOutput;
  279. PlsrHostDirectionLevel = (directionLevel != 0U) ? 1U : 0U;
  280. PlsrHostOutputMode[pulseOutput] = outputMode;
  281. PlsrHostDirectionPositive[pulseOutput] =
  282. (directionPositive != 0U) ? 1U : 0U;
  283. PlsrHostAbQuarter[pulseOutput] = 0U;
  284. PlsrHostAbPhase[pulseOutput] = 0U;
  285. PlsrHostAbFastGated[pulseOutput] = 0U;
  286. return 1U;
  287. }
  288. uint8_t PlsrPlatformStartPulse(uint8_t pulseOutput,
  289. uint32_t firstFrequencyHz,
  290. uint32_t queuedFrequencyHz,
  291. uint32_t *actualFirstFrequencyHz,
  292. uint32_t *actualQueuedFrequencyHz)
  293. {
  294. PLSR_PLATFORM_TIMER_SETTING firstSetting;
  295. PLSR_PLATFORM_TIMER_SETTING queuedSetting;
  296. if ((pulseOutput > 3U)
  297. || (PlsrPlatformBuildTimerSetting(
  298. pulseOutput, PlsrHostOutputMode[pulseOutput],
  299. firstFrequencyHz, &firstSetting) == 0U)
  300. || (PlsrPlatformBuildTimerSetting(
  301. pulseOutput, PlsrHostOutputMode[pulseOutput],
  302. queuedFrequencyHz, &queuedSetting) == 0U))
  303. {
  304. return 0U;
  305. }
  306. return PlsrPlatformStartPrepared(pulseOutput, &firstSetting,
  307. &queuedSetting,
  308. actualFirstFrequencyHz,
  309. actualQueuedFrequencyHz);
  310. }
  311. uint8_t PlsrPlatformBuildTimerSetting(
  312. uint8_t pulseOutput,
  313. uint8_t outputMode,
  314. uint32_t requestedFrequencyHz,
  315. PLSR_PLATFORM_TIMER_SETTING *setting)
  316. {
  317. if ((pulseOutput > 3U) || (outputMode > PLSR_OUTPUT_AB)
  318. || ((outputMode == PLSR_OUTPUT_AB)
  319. && ((pulseOutput & 1U) != 0U))
  320. || (requestedFrequencyHz == 0UL)
  321. || (requestedFrequencyHz > PLSR_FREQUENCY_MAX_HZ)
  322. || (setting == NULL))
  323. {
  324. return 0U;
  325. }
  326. setting->actualFrequencyHz = requestedFrequencyHz;
  327. setting->prescaler = (outputMode == PLSR_OUTPUT_AB) ? 1U : 0U;
  328. setting->pairPrescaler = 0U;
  329. setting->period = (outputMode == PLSR_OUTPUT_AB) ? 3U : 1U;
  330. setting->compare = (outputMode == PLSR_OUTPUT_AB) ? 2U : 1U;
  331. return 1U;
  332. }
  333. uint8_t PlsrPlatformStartPrepared(
  334. uint8_t pulseOutput,
  335. const PLSR_PLATFORM_TIMER_SETTING *firstSetting,
  336. const PLSR_PLATFORM_TIMER_SETTING *queuedSetting,
  337. uint32_t *actualFirstFrequencyHz,
  338. uint32_t *actualQueuedFrequencyHz)
  339. {
  340. if ((pulseOutput > 3U) || (firstSetting == NULL)
  341. || (queuedSetting == NULL) || (actualFirstFrequencyHz == NULL)
  342. || (actualQueuedFrequencyHz == NULL)
  343. || (firstSetting->actualFrequencyHz == 0UL)
  344. || (firstSetting->actualFrequencyHz > PLSR_FREQUENCY_MAX_HZ)
  345. || (queuedSetting->actualFrequencyHz == 0UL)
  346. || (queuedSetting->actualFrequencyHz > PLSR_FREQUENCY_MAX_HZ)
  347. || (PlsrHostAbStopPending[pulseOutput] != 0U)
  348. || (PlsrHostAbFastGated[pulseOutput] != 0U))
  349. {
  350. return 0U;
  351. }
  352. PlsrHostPulseActive[pulseOutput] = 1U;
  353. PlsrHostFrequency[pulseOutput] = firstSetting->actualFrequencyHz;
  354. PlsrHostQueuedFrequency[pulseOutput] = queuedSetting->actualFrequencyHz;
  355. PlsrHostActiveSetting[pulseOutput] = *firstSetting;
  356. PlsrHostQueuedSetting[pulseOutput] = *queuedSetting;
  357. PlsrHostUpdatePending[pulseOutput] = 0U;
  358. PlsrHostSelectedPulse = pulseOutput;
  359. *actualFirstFrequencyHz = firstSetting->actualFrequencyHz;
  360. *actualQueuedFrequencyHz = queuedSetting->actualFrequencyHz;
  361. return 1U;
  362. }
  363. uint8_t PlsrPlatformSupportsFinitePulseTrain(void)
  364. {
  365. return PlsrHostFiniteEnabled;
  366. }
  367. uint8_t PlsrPlatformStartFinitePrepared(
  368. uint8_t pulseOutput,
  369. const PLSR_PLATFORM_TIMER_SETTING *setting,
  370. uint32_t pulseCount,
  371. uint32_t *actualFrequencyHz)
  372. {
  373. if ((PlsrHostFiniteEnabled == 0U) || (pulseOutput > 3U)
  374. || (setting == NULL) || (pulseCount == 0UL)
  375. || (actualFrequencyHz == NULL)
  376. || (PlsrHostOutputMode[pulseOutput] != PLSR_OUTPUT_PULSE_DIR))
  377. {
  378. return 0U;
  379. }
  380. PlsrHostPulseActive[pulseOutput] = 1U;
  381. PlsrHostFiniteActive[pulseOutput] = 1U;
  382. PlsrHostFiniteComplete[pulseOutput] = 0U;
  383. PlsrHostFiniteFrequencyPending[pulseOutput] = 0U;
  384. PlsrHostCountedStreamActive[pulseOutput] = 0U;
  385. PlsrHostFiniteTarget[pulseOutput] = pulseCount;
  386. PlsrHostFiniteEmitted[pulseOutput] = 0UL;
  387. PlsrHostFiniteStepCount[pulseOutput] = 0U;
  388. PlsrHostFiniteStepIndex[pulseOutput] = 0U;
  389. PlsrHostFiniteBoundaryReadIndex[pulseOutput] = 0U;
  390. PlsrHostFiniteCompletedStepCount[pulseOutput] = 0U;
  391. PlsrHostFrequency[pulseOutput] = setting->actualFrequencyHz;
  392. PlsrHostQueuedFrequency[pulseOutput] = setting->actualFrequencyHz;
  393. PlsrHostActiveSetting[pulseOutput] = *setting;
  394. PlsrHostQueuedSetting[pulseOutput] = *setting;
  395. PlsrHostSelectedPulse = pulseOutput;
  396. *actualFrequencyHz = setting->actualFrequencyHz;
  397. return 1U;
  398. }
  399. uint8_t PlsrPlatformStartCountedStreamPrepared(
  400. uint8_t pulseOutput,
  401. const PLSR_PLATFORM_TIMER_SETTING *setting,
  402. uint32_t pulseCount,
  403. uint32_t *actualFrequencyHz)
  404. {
  405. if (PlsrPlatformStartFinitePrepared(pulseOutput, setting, pulseCount,
  406. actualFrequencyHz) == 0U)
  407. {
  408. return 0U;
  409. }
  410. PlsrHostCountedStreamActive[pulseOutput] = 1U;
  411. return 1U;
  412. }
  413. uint8_t PlsrPlatformStartFiniteSequencePrepared(
  414. uint8_t pulseOutput,
  415. PLSR_PLATFORM_FINITE_STEP *steps,
  416. uint16_t stepCount,
  417. uint32_t *actualFrequencyHz)
  418. {
  419. if ((steps == NULL) || (stepCount == 0U)
  420. || (stepCount > PLSR_PLATFORM_FINITE_STEP_MAX)
  421. || (PlsrPlatformStartFinitePrepared(
  422. pulseOutput, &steps[0].setting, steps[0].pulseCount,
  423. actualFrequencyHz) == 0U))
  424. {
  425. return 0U;
  426. }
  427. PlsrHostFiniteSteps[pulseOutput] = steps;
  428. PlsrHostFiniteStepCount[pulseOutput] = stepCount;
  429. PlsrHostFiniteStepIndex[pulseOutput] = 0U;
  430. PlsrHostFiniteBoundaryReadIndex[pulseOutput] = 0U;
  431. PlsrHostFiniteCompletedStepCount[pulseOutput] = 0U;
  432. return 1U;
  433. }
  434. PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformUpdateFinitePrepared(
  435. uint8_t pulseOutput,
  436. const PLSR_PLATFORM_TIMER_SETTING *setting,
  437. uint32_t *actualFrequencyHz)
  438. {
  439. if (PlsrHostFailNextFrequencyAtUpdate != 0U)
  440. {
  441. PlsrHostFailNextFrequencyAtUpdate = 0U;
  442. return PLSR_PLATFORM_QUEUE_FAILED;
  443. }
  444. if ((pulseOutput > 3U) || (setting == NULL)
  445. || (actualFrequencyHz == NULL)
  446. || (PlsrHostFiniteActive[pulseOutput] == 0U))
  447. {
  448. return PLSR_PLATFORM_QUEUE_STALE;
  449. }
  450. if (PlsrHostStaleNextFrequencyAtUpdate != 0U)
  451. {
  452. PlsrHostStaleNextFrequencyAtUpdate = 0U;
  453. return PLSR_PLATFORM_QUEUE_STALE;
  454. }
  455. if (PlsrHostFiniteFrequencyPending[pulseOutput] != 0U)
  456. {
  457. return PLSR_PLATFORM_QUEUE_STALE;
  458. }
  459. PlsrHostQueuedSetting[pulseOutput] = *setting;
  460. PlsrHostQueuedFrequency[pulseOutput] = setting->actualFrequencyHz;
  461. PlsrHostFiniteFrequencyPending[pulseOutput] = 1U;
  462. *actualFrequencyHz = setting->actualFrequencyHz;
  463. return PLSR_PLATFORM_QUEUE_APPLIED;
  464. }
  465. uint8_t PlsrPlatformRetargetFiniteStop(uint8_t pulseOutput,
  466. uint32_t drainPulses)
  467. {
  468. uint32_t completed;
  469. if ((pulseOutput > 3U) || (drainPulses == 0UL)
  470. || (PlsrHostFiniteActive[pulseOutput] == 0U))
  471. {
  472. return 0U;
  473. }
  474. completed = PlsrHostFiniteEmitted[pulseOutput];
  475. if (PlsrHostFiniteStepCount[pulseOutput] != 0U)
  476. {
  477. completed += PlsrHostFiniteSteps[pulseOutput][
  478. PlsrHostFiniteStepIndex[pulseOutput]].segmentPulseOffset;
  479. }
  480. PlsrHostFiniteTarget[pulseOutput] = completed + drainPulses;
  481. PlsrHostFiniteEmitted[pulseOutput] = completed;
  482. PlsrHostFiniteStepCount[pulseOutput] = 0U;
  483. PlsrHostFiniteStepIndex[pulseOutput] = 0U;
  484. PlsrHostFiniteBoundaryReadIndex[pulseOutput] = 0U;
  485. PlsrHostFiniteCompletedStepCount[pulseOutput] = 0U;
  486. return 1U;
  487. }
  488. uint8_t PlsrPlatformRequestFiniteCut(uint8_t pulseOutput)
  489. {
  490. if ((pulseOutput > 3U)
  491. || (PlsrHostFiniteActive[pulseOutput] == 0U)
  492. || (PlsrHostCountedStreamActive[pulseOutput] == 0U))
  493. {
  494. return 0U;
  495. }
  496. /* The host model has no half-pulse phase. Complete the cut at the
  497. current emitted boundary and publish the normal finite-completion
  498. event expected by the counted executor. */
  499. PlsrHostFiniteTarget[pulseOutput] =
  500. PlsrHostFiniteEmitted[pulseOutput];
  501. PlsrHostFiniteStepCount[pulseOutput] = 0U;
  502. PlsrHostFiniteStepIndex[pulseOutput] = 0U;
  503. PlsrHostFiniteBoundaryReadIndex[pulseOutput] = 0U;
  504. PlsrHostFiniteCompletedStepCount[pulseOutput] = 0U;
  505. PlsrHostFiniteActive[pulseOutput] = 0U;
  506. PlsrHostFiniteComplete[pulseOutput] = 1U;
  507. return 1U;
  508. }
  509. uint8_t PlsrPlatformFiniteRetargetReady(uint8_t pulseOutput,
  510. uint32_t *activeFrequencyHz)
  511. {
  512. if ((pulseOutput > 3U) || (activeFrequencyHz == NULL)
  513. || (PlsrHostFiniteActive[pulseOutput] == 0U))
  514. {
  515. return 0U;
  516. }
  517. *activeFrequencyHz = PlsrHostFrequency[pulseOutput];
  518. return (PlsrHostFiniteStepCount[pulseOutput] == 0U) ? 1U : 0U;
  519. }
  520. uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput,
  521. uint32_t *committedPulses,
  522. uint32_t *tailFrequencyHz,
  523. uint8_t *startsNextSegment)
  524. {
  525. uint32_t remaining;
  526. if ((pulseOutput > 3U) || (committedPulses == NULL)
  527. || (tailFrequencyHz == NULL) || (startsNextSegment == NULL)
  528. || (PlsrHostFiniteActive[pulseOutput] == 0U))
  529. {
  530. return 0U;
  531. }
  532. remaining = PlsrHostFiniteTarget[pulseOutput]
  533. - PlsrHostFiniteEmitted[pulseOutput];
  534. *committedPulses = remaining;
  535. *tailFrequencyHz = PlsrHostQueuedFrequency[pulseOutput];
  536. *startsNextSegment = 0U;
  537. return 1U;
  538. }
  539. uint8_t PlsrPlatformFiniteProgress(uint8_t pulseOutput,
  540. uint32_t *completedPulses)
  541. {
  542. if ((pulseOutput > 3U) || (completedPulses == NULL)
  543. || ((PlsrHostFiniteActive[pulseOutput] == 0U)
  544. && (PlsrHostFiniteComplete[pulseOutput] == 0U)))
  545. {
  546. return 0U;
  547. }
  548. if (PlsrHostFiniteStepCount[pulseOutput] != 0U)
  549. {
  550. const PLSR_PLATFORM_FINITE_STEP *step =
  551. &PlsrHostFiniteSteps[pulseOutput][
  552. PlsrHostFiniteStepIndex[pulseOutput]];
  553. *completedPulses = step->segmentPulseOffset
  554. + PlsrHostFiniteEmitted[pulseOutput];
  555. }
  556. else
  557. {
  558. *completedPulses = PlsrHostFiniteEmitted[pulseOutput];
  559. }
  560. return 1U;
  561. }
  562. uint8_t PlsrPlatformTakeFiniteCompletion(uint8_t pulseOutput,
  563. uint32_t *completedPulses)
  564. {
  565. if ((pulseOutput > 3U) || (completedPulses == NULL)
  566. || (PlsrHostFiniteComplete[pulseOutput] == 0U))
  567. {
  568. return 0U;
  569. }
  570. PlsrHostFiniteComplete[pulseOutput] = 0U;
  571. if (PlsrHostFiniteStepCount[pulseOutput] != 0U)
  572. {
  573. const PLSR_PLATFORM_FINITE_STEP *step =
  574. &PlsrHostFiniteSteps[pulseOutput][
  575. PlsrHostFiniteStepCount[pulseOutput] - 1U];
  576. *completedPulses = step->segmentPulseOffset + step->pulseCount;
  577. }
  578. else
  579. {
  580. *completedPulses = PlsrHostFiniteTarget[pulseOutput];
  581. }
  582. return 1U;
  583. }
  584. uint8_t PlsrPlatformTakeFiniteBoundary(uint8_t pulseOutput,
  585. uint8_t *segmentNumber,
  586. uint32_t *completedPulses,
  587. uint8_t *sequenceContinues,
  588. uint32_t *activeFrequencyHz)
  589. {
  590. if ((pulseOutput > 3U) || (segmentNumber == NULL)
  591. || (completedPulses == NULL) || (sequenceContinues == NULL)
  592. || (activeFrequencyHz == NULL))
  593. {
  594. return 0U;
  595. }
  596. while (PlsrHostFiniteBoundaryReadIndex[pulseOutput]
  597. < PlsrHostFiniteCompletedStepCount[pulseOutput])
  598. {
  599. uint16_t index = PlsrHostFiniteBoundaryReadIndex[pulseOutput]++;
  600. const PLSR_PLATFORM_FINITE_STEP *step =
  601. &PlsrHostFiniteSteps[pulseOutput][index];
  602. if (step->completesSegment != 0U)
  603. {
  604. *segmentNumber = step->segmentNumber;
  605. *completedPulses = step->segmentPulseOffset + step->pulseCount;
  606. *sequenceContinues =
  607. (index + 1U < PlsrHostFiniteStepCount[pulseOutput]) ? 1U : 0U;
  608. *activeFrequencyHz = (*sequenceContinues != 0U)
  609. ? PlsrHostFiniteSteps[pulseOutput][index + 1U]
  610. .setting.actualFrequencyHz
  611. : step->setting.actualFrequencyHz;
  612. return 1U;
  613. }
  614. }
  615. return 0U;
  616. }
  617. PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformLoadPreparedFromIrq(
  618. uint8_t pulseOutput,
  619. const PLSR_PLATFORM_TIMER_SETTING *setting,
  620. uint32_t *actualFrequencyHz)
  621. {
  622. if (PlsrHostFailNextFrequencyAtUpdate != 0U)
  623. {
  624. PlsrHostFailNextFrequencyAtUpdate = 0U;
  625. return PLSR_PLATFORM_QUEUE_FAILED;
  626. }
  627. if ((pulseOutput > 3U) || (setting == NULL)
  628. || (actualFrequencyHz == NULL)
  629. || (setting->actualFrequencyHz == 0UL)
  630. || (setting->actualFrequencyHz > PLSR_FREQUENCY_MAX_HZ))
  631. {
  632. return PLSR_PLATFORM_QUEUE_FAILED;
  633. }
  634. if (PlsrHostStaleNextFrequencyAtUpdate != 0U)
  635. {
  636. PlsrHostStaleNextFrequencyAtUpdate = 0U;
  637. return PLSR_PLATFORM_QUEUE_STALE;
  638. }
  639. if ((PlsrHostCompleteAbCycleOnQueueCommit != 0U)
  640. && (PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB))
  641. {
  642. PlsrHostCompleteAbCycleOnQueueCommit = 0U;
  643. PlsrTestEmitAbQuarters(4UL);
  644. }
  645. if ((PlsrHostPulseActive[pulseOutput] == 0U)
  646. || (PlsrHostAbStopPending[pulseOutput] != 0U)
  647. || (PlsrHostAbFastGated[pulseOutput] != 0U))
  648. {
  649. return PLSR_PLATFORM_QUEUE_STALE;
  650. }
  651. PlsrHostQueuedSetting[pulseOutput] = *setting;
  652. PlsrHostQueuedFrequency[pulseOutput] = setting->actualFrequencyHz;
  653. *actualFrequencyHz = setting->actualFrequencyHz;
  654. return PLSR_PLATFORM_QUEUE_APPLIED;
  655. }
  656. void PlsrPlatformGateFromIrq(uint8_t pulseOutput)
  657. {
  658. if ((pulseOutput <= 3U)
  659. && (PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  660. && (PlsrHostAbFastGated[pulseOutput] != 0U))
  661. {
  662. return;
  663. }
  664. PlsrPlatformStopPulse(pulseOutput);
  665. }
  666. PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformQueueFrequency(
  667. uint8_t pulseOutput,
  668. uint32_t frequencyHz,
  669. uint32_t *actualFrequencyHz)
  670. {
  671. uint32_t criticalState;
  672. PLSR_PLATFORM_TIMER_SETTING setting;
  673. if (PlsrHostFailNextFrequencyAtUpdate != 0U)
  674. {
  675. PlsrHostFailNextFrequencyAtUpdate = 0U;
  676. return PLSR_PLATFORM_QUEUE_FAILED;
  677. }
  678. if ((pulseOutput > 3U)
  679. || (PlsrPlatformBuildTimerSetting(
  680. pulseOutput, PlsrHostOutputMode[pulseOutput], frequencyHz,
  681. &setting) == 0U)
  682. || (actualFrequencyHz == NULL)
  683. || (PlsrHostPulseActive[pulseOutput] == 0U)
  684. || (PlsrHostAbStopPending[pulseOutput] != 0U)
  685. || (PlsrHostAbFastGated[pulseOutput] != 0U))
  686. {
  687. return PLSR_PLATFORM_QUEUE_FAILED;
  688. }
  689. if (PlsrHostStaleNextFrequencyAtUpdate != 0U)
  690. {
  691. PlsrHostStaleNextFrequencyAtUpdate = 0U;
  692. return PLSR_PLATFORM_QUEUE_STALE;
  693. }
  694. if ((PlsrHostCompleteAbCycleOnQueueCommit != 0U)
  695. && (PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB))
  696. {
  697. PlsrHostCompleteAbCycleOnQueueCommit = 0U;
  698. PlsrTestEmitAbQuarters(4UL);
  699. }
  700. criticalState = PlsrPlatformEnterCritical();
  701. if ((PlsrHostPulseActive[pulseOutput] == 0U)
  702. || (PlsrHostAbStopPending[pulseOutput] != 0U)
  703. || (PlsrHostAbFastGated[pulseOutput] != 0U))
  704. {
  705. PlsrPlatformExitCritical(criticalState);
  706. return PLSR_PLATFORM_QUEUE_STALE;
  707. }
  708. PlsrHostQueuedFrequency[pulseOutput] = setting.actualFrequencyHz;
  709. PlsrHostQueuedSetting[pulseOutput] = setting;
  710. *actualFrequencyHz = setting.actualFrequencyHz;
  711. PlsrPlatformExitCritical(criticalState);
  712. return PLSR_PLATFORM_QUEUE_APPLIED;
  713. }
  714. void PlsrPlatformDrainPendingPulse(uint8_t pulseOutput)
  715. {
  716. PlsrHostServicePendingPulse(pulseOutput);
  717. }
  718. uint32_t PlsrPlatformActiveFrequency(uint8_t pulseOutput)
  719. {
  720. if (pulseOutput > 3U)
  721. {
  722. return 0UL;
  723. }
  724. return (PlsrHostFrequencyOffsetHz != 0L)
  725. ? PlsrHostOffsetFrequency(PlsrHostFrequency[pulseOutput])
  726. : PlsrHostFrequency[pulseOutput];
  727. }
  728. uint8_t PlsrPlatformExpectedFrequency(uint8_t pulseOutput,
  729. uint8_t outputMode,
  730. uint32_t requestedFrequencyHz,
  731. uint32_t *actualFrequencyHz)
  732. {
  733. PLSR_PLATFORM_TIMER_SETTING setting;
  734. if (PlsrPlatformBuildTimerSetting(pulseOutput, outputMode,
  735. requestedFrequencyHz,
  736. &setting) == 0U)
  737. {
  738. return 0U;
  739. }
  740. *actualFrequencyHz = setting.actualFrequencyHz;
  741. return 1U;
  742. }
  743. uint64_t PlsrPlatformObservedPulses(uint8_t pulseOutput)
  744. {
  745. int64_t observed;
  746. if (pulseOutput > 3U)
  747. {
  748. return 0UL;
  749. }
  750. observed = (int64_t)PlsrHostObservedPulses[pulseOutput]
  751. + (int64_t)PlsrHostCountOffset;
  752. return (observed > 0) ? (uint64_t)observed : 0UL;
  753. }
  754. uint16_t PlsrPlatformDiagnosticFault(void)
  755. {
  756. uint16_t fault = PlsrHostDiagnosticFault;
  757. PlsrHostDiagnosticFault = 0U;
  758. return fault;
  759. }
  760. PLSR_PLATFORM_STOP_RESULT PlsrPlatformRequestStopLocked(
  761. uint8_t pulseOutput,
  762. uint8_t requireZeroBoundary)
  763. {
  764. if (pulseOutput > 3U)
  765. {
  766. return PLSR_PLATFORM_STOP_FORCED_FAULT;
  767. }
  768. if (PlsrHostFailNextStopRequest != 0U)
  769. {
  770. PlsrHostFailNextStopRequest = 0U;
  771. PlsrPlatformStopPulse(pulseOutput);
  772. return PLSR_PLATFORM_STOP_FORCED_FAULT;
  773. }
  774. if ((requireZeroBoundary != 0U)
  775. && (PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  776. && (PlsrHostPulseActive[pulseOutput] != 0U)
  777. && (PlsrHostAbFastGated[pulseOutput] == 0U))
  778. {
  779. if (PlsrHostLatchAbFinalQuarterOnStopArm != 0U)
  780. {
  781. PlsrHostLatchAbFinalQuarterOnStopArm = 0U;
  782. (void)PlsrHostAdvanceAbQuarter(pulseOutput);
  783. }
  784. PlsrHostQueuedFrequency[pulseOutput] =
  785. PlsrHostFrequency[pulseOutput];
  786. PlsrHostAbStopPending[pulseOutput] = 1U;
  787. return PLSR_PLATFORM_STOP_PENDING;
  788. }
  789. PlsrPlatformStopPulse(pulseOutput);
  790. return PLSR_PLATFORM_STOP_COMPLETE;
  791. }
  792. uint8_t PlsrPlatformQueueFinalArmFromIrq(uint8_t pulseOutput)
  793. {
  794. if ((pulseOutput > 2U) || ((pulseOutput & 1U) != 0U)
  795. || (PlsrHostOutputMode[pulseOutput] != PLSR_OUTPUT_AB)
  796. || (PlsrHostPulseActive[pulseOutput] == 0U)
  797. || (PlsrHostAbFastGated[pulseOutput] != 0U))
  798. {
  799. return 0U;
  800. }
  801. PlsrHostFinalArmJobOwner = pulseOutput;
  802. PlsrHostFinalArmJobPending = 1U;
  803. return 1U;
  804. }
  805. void PlsrPlatformStopPulse(uint8_t pulseOutput)
  806. {
  807. if (pulseOutput <= 3U)
  808. {
  809. if ((PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  810. && ((PlsrHostAbStopPending[pulseOutput] != 0U)
  811. || (PlsrHostAbFastGated[pulseOutput] != 0U)))
  812. {
  813. PlsrHostAbCleanupCount++;
  814. }
  815. PlsrHostPulseActive[pulseOutput] = 0U;
  816. PlsrHostFiniteActive[pulseOutput] = 0U;
  817. PlsrHostFiniteComplete[pulseOutput] = 0U;
  818. PlsrHostFrequency[pulseOutput] = 0UL;
  819. PlsrHostQueuedFrequency[pulseOutput] = 0UL;
  820. PlsrHostUpdatePending[pulseOutput] = 0U;
  821. PlsrHostAbQuarter[pulseOutput] = 0U;
  822. PlsrHostAbPhase[pulseOutput] = 0U;
  823. PlsrHostAbStopPending[pulseOutput] = 0U;
  824. PlsrHostAbFastGated[pulseOutput] = 0U;
  825. PlsrHostFrequencyOffsetHz = 0L;
  826. if (PlsrHostFinalArmJobOwner == pulseOutput)
  827. {
  828. PlsrHostFinalArmJobPending = 0U;
  829. PlsrHostFinalArmJobOwner = 0xFFU;
  830. }
  831. }
  832. }
  833. uint8_t PlsrPlatformReadInput(uint8_t inputSelection)
  834. {
  835. return (inputSelection <= 1U) ? PlsrHostInputs[inputSelection] : 0U;
  836. }
  837. uint8_t PlsrPlatformLoad(PLSR_PERSIST_PAYLOAD *payload)
  838. {
  839. if ((payload == NULL) || (PlsrHostPersistentValid == 0U))
  840. {
  841. return 0U;
  842. }
  843. *payload = PlsrHostPersistentPayload;
  844. return 1U;
  845. }
  846. void PlsrPlatformForceSafeOutputsFromFault(void)
  847. {
  848. uint8_t index;
  849. for (index = 0U; index < 4U; index++)
  850. {
  851. PlsrPlatformStopPulse(index);
  852. }
  853. }
  854. PLSR_PLATFORM_SERVICE_RESULT PlsrPlatformServicePersistence(void)
  855. {
  856. return PLSR_PLATFORM_SERVICE_READY;
  857. }
  858. uint8_t PlsrPlatformSave(const PLSR_PERSIST_PAYLOAD *payload)
  859. {
  860. if (payload == NULL)
  861. {
  862. return 0U;
  863. }
  864. PlsrHostPersistentPayload = *payload;
  865. PlsrHostPersistentValid = 1U;
  866. PlsrHostSaveCount++;
  867. return 1U;
  868. }
  869. void PlsrPlatformCheckpointConfig(const PLSR_CONFIG *config)
  870. {
  871. if (config != NULL)
  872. {
  873. PlsrHostPersistentPayload.config = *config;
  874. PlsrHostPersistentValid = 1U;
  875. }
  876. }
  877. void PlsrPlatformCheckpointPosition(int32_t position,
  878. uint8_t positionValid,
  879. uint8_t wasBusy)
  880. {
  881. PlsrHostPersistentPayload.position = position;
  882. PlsrHostPersistentPayload.positionValid = positionValid;
  883. PlsrHostPersistentPayload.wasBusy = wasBusy;
  884. PlsrHostPersistentPayload.reserved = 0U;
  885. }
  886. uint32_t PlsrPlatformEnterCritical(void)
  887. {
  888. uint32_t previousDepth = PlsrHostCriticalDepth;
  889. if (PlsrHostEmitPulseOnCriticalEntry != 0U)
  890. {
  891. if (PlsrHostCriticalEntriesToSkip != 0U)
  892. {
  893. PlsrHostCriticalEntriesToSkip--;
  894. }
  895. else
  896. {
  897. PlsrHostEmitPulseOnCriticalEntry = 0U;
  898. PlsrHostLatchPulse(PlsrHostSelectedPulse);
  899. if (previousDepth == 0UL)
  900. {
  901. PlsrHostServicePendingPulse(PlsrHostSelectedPulse);
  902. }
  903. }
  904. }
  905. if (PlsrHostLatchPulseOnCriticalEntry != 0U)
  906. {
  907. PlsrHostLatchPulseOnCriticalEntry = 0U;
  908. PlsrHostLatchPulse(PlsrHostSelectedPulse);
  909. }
  910. PlsrHostCriticalDepth++;
  911. return previousDepth;
  912. }
  913. void PlsrPlatformExitCritical(uint32_t state)
  914. {
  915. (void)state;
  916. if (PlsrHostCriticalDepth != 0UL)
  917. {
  918. PlsrHostCriticalDepth--;
  919. }
  920. if (PlsrHostCriticalDepth != 0UL)
  921. {
  922. return;
  923. }
  924. if (PlsrHostEmitPulseOnCriticalExit != 0U)
  925. {
  926. PlsrHostEmitPulseOnCriticalExit = 0U;
  927. PlsrHostLatchPulse(PlsrHostSelectedPulse);
  928. }
  929. PlsrHostServicePendingPulse(PlsrHostSelectedPulse);
  930. }
  931. void PlsrTestSetInput(uint8_t inputSelection, uint8_t level)
  932. {
  933. if (inputSelection <= 1U)
  934. {
  935. PlsrHostInputs[inputSelection] = (level != 0U) ? 1U : 0U;
  936. }
  937. }
  938. void PlsrTestEmitPulses(uint32_t pulseCount)
  939. {
  940. if (PlsrHostFiniteActive[PlsrHostSelectedPulse] != 0U)
  941. {
  942. uint8_t pulseOutput = PlsrHostSelectedPulse;
  943. while ((pulseCount != 0UL)
  944. && (PlsrHostFiniteActive[pulseOutput] != 0U))
  945. {
  946. uint32_t available = PlsrHostFiniteTarget[pulseOutput]
  947. - PlsrHostFiniteEmitted[pulseOutput];
  948. uint32_t emitted = (pulseCount < available)
  949. ? pulseCount : available;
  950. if ((emitted != 0UL)
  951. && (PlsrHostFiniteFrequencyPending[pulseOutput] != 0U))
  952. {
  953. PlsrHostActiveSetting[pulseOutput] =
  954. PlsrHostQueuedSetting[pulseOutput];
  955. PlsrHostFrequency[pulseOutput] =
  956. PlsrHostQueuedFrequency[pulseOutput];
  957. PlsrHostFiniteFrequencyPending[pulseOutput] = 0U;
  958. }
  959. PlsrHostFiniteEmitted[pulseOutput] += emitted;
  960. PlsrHostObservedPulses[pulseOutput] += emitted;
  961. pulseCount -= emitted;
  962. if (PlsrHostFiniteEmitted[pulseOutput]
  963. == PlsrHostFiniteTarget[pulseOutput])
  964. {
  965. uint16_t index = PlsrHostFiniteStepIndex[pulseOutput];
  966. uint8_t hasNext = (index + 1U
  967. < PlsrHostFiniteStepCount[pulseOutput])
  968. ? 1U : 0U;
  969. if (PlsrHostFiniteStepCount[pulseOutput] != 0U)
  970. {
  971. PlsrHostFiniteCompletedStepCount[pulseOutput] =
  972. (uint16_t)(index + 1U);
  973. }
  974. if (hasNext != 0U)
  975. {
  976. const PLSR_PLATFORM_FINITE_STEP *next =
  977. &PlsrHostFiniteSteps[pulseOutput][index + 1U];
  978. PlsrHostFiniteStepIndex[pulseOutput]++;
  979. PlsrHostFiniteTarget[pulseOutput] = next->pulseCount;
  980. PlsrHostFiniteEmitted[pulseOutput] = 0UL;
  981. PlsrHostFrequency[pulseOutput] =
  982. next->setting.actualFrequencyHz;
  983. PlsrHostQueuedFrequency[pulseOutput] =
  984. next->setting.actualFrequencyHz;
  985. PlsrHostActiveSetting[pulseOutput] = next->setting;
  986. PlsrHostQueuedSetting[pulseOutput] = next->setting;
  987. PlsrHostFiniteFrequencyPending[pulseOutput] = 0U;
  988. }
  989. else
  990. {
  991. PlsrHostFiniteActive[pulseOutput] = 0U;
  992. PlsrHostFiniteComplete[pulseOutput] = 1U;
  993. PlsrHostPulseActive[pulseOutput] = 0U;
  994. PlsrHostFiniteFrequencyPending[pulseOutput] = 0U;
  995. PlsrHostFrequency[pulseOutput] = 0UL;
  996. PlsrHostQueuedFrequency[pulseOutput] = 0UL;
  997. }
  998. }
  999. }
  1000. return;
  1001. }
  1002. if (PlsrHostOutputMode[PlsrHostSelectedPulse] == PLSR_OUTPUT_AB)
  1003. {
  1004. while ((pulseCount != 0UL)
  1005. && (PlsrHostPulseActive[PlsrHostSelectedPulse] != 0U))
  1006. {
  1007. PlsrTestEmitAbQuarters(4UL);
  1008. pulseCount--;
  1009. }
  1010. return;
  1011. }
  1012. while ((pulseCount != 0UL)
  1013. && (PlsrHostPulseActive[PlsrHostSelectedPulse] != 0U))
  1014. {
  1015. PlsrHostLatchPulse(PlsrHostSelectedPulse);
  1016. PlsrHostServicePendingPulse(PlsrHostSelectedPulse);
  1017. pulseCount--;
  1018. }
  1019. }
  1020. void PlsrTestEnableFinitePulseTrain(uint8_t enable)
  1021. {
  1022. PlsrHostFiniteEnabled = (enable != 0U) ? 1U : 0U;
  1023. }
  1024. void PlsrTestCompleteFinitePulseTrain(void)
  1025. {
  1026. uint8_t pulseOutput = PlsrHostSelectedPulse;
  1027. if ((PlsrHostFiniteActive[pulseOutput] != 0U)
  1028. && (PlsrHostPulseActive[pulseOutput] != 0U))
  1029. {
  1030. uint32_t remaining = PlsrHostFiniteTarget[pulseOutput]
  1031. - PlsrHostFiniteEmitted[pulseOutput];
  1032. PlsrHostFiniteEmitted[pulseOutput] += remaining;
  1033. PlsrHostObservedPulses[pulseOutput] += remaining;
  1034. PlsrHostFiniteActive[pulseOutput] = 0U;
  1035. PlsrHostFiniteComplete[pulseOutput] = 1U;
  1036. PlsrHostPulseActive[pulseOutput] = 0U;
  1037. PlsrHostFrequency[pulseOutput] = 0UL;
  1038. PlsrHostQueuedFrequency[pulseOutput] = 0UL;
  1039. }
  1040. }
  1041. uint8_t PlsrTestFinitePulseTrainActive(void)
  1042. {
  1043. return PlsrHostFiniteActive[PlsrHostSelectedPulse];
  1044. }
  1045. void PlsrTestEmitPulseOnCriticalEntry(void)
  1046. {
  1047. PlsrHostCriticalEntriesToSkip = 0U;
  1048. PlsrHostEmitPulseOnCriticalEntry = 1U;
  1049. }
  1050. void PlsrTestEmitPulseAfterCriticalEntries(uint8_t entriesToSkip)
  1051. {
  1052. PlsrHostCriticalEntriesToSkip = entriesToSkip;
  1053. PlsrHostEmitPulseOnCriticalEntry = 1U;
  1054. }
  1055. void PlsrTestEmitPulseOnCriticalExit(void)
  1056. {
  1057. PlsrHostEmitPulseOnCriticalExit = 1U;
  1058. }
  1059. void PlsrTestLatchPulseOnCriticalEntry(void)
  1060. {
  1061. PlsrHostLatchPulseOnCriticalEntry = 1U;
  1062. }
  1063. void PlsrTestLatchAbFinalQuarterOnNextStopArm(void)
  1064. {
  1065. PlsrHostLatchAbFinalQuarterOnStopArm = 1U;
  1066. }
  1067. void PlsrTestCompleteAbCycleOnNextQueueCommit(void)
  1068. {
  1069. PlsrHostCompleteAbCycleOnQueueCommit = 1U;
  1070. }
  1071. void PlsrTestServicePendingPulse(void)
  1072. {
  1073. PlsrHostServicePendingPulse(PlsrHostSelectedPulse);
  1074. }
  1075. void PlsrTestFailNextStart(void)
  1076. {
  1077. PlsrHostFailNextStart = 1U;
  1078. }
  1079. void PlsrTestServiceFinalArmJob(void)
  1080. {
  1081. PlsrHostServiceFinalArmJob();
  1082. }
  1083. void PlsrTestDeferFinalArmJob(uint8_t defer)
  1084. {
  1085. PlsrHostDeferFinalArmJob = (defer != 0U) ? 1U : 0U;
  1086. if (PlsrHostDeferFinalArmJob == 0U)
  1087. {
  1088. PlsrHostServiceFinalArmJob();
  1089. }
  1090. }
  1091. void PlsrTestStaleNextFrequencyAtUpdate(void)
  1092. {
  1093. PlsrHostStaleNextFrequencyAtUpdate = 1U;
  1094. }
  1095. void PlsrTestFailNextFrequencyAtUpdate(void)
  1096. {
  1097. PlsrHostFailNextFrequencyAtUpdate = 1U;
  1098. }
  1099. void PlsrTestFailNextStopRequest(void)
  1100. {
  1101. PlsrHostFailNextStopRequest = 1U;
  1102. }
  1103. void PlsrTestEmitAbQuarters(uint32_t quarterCount)
  1104. {
  1105. uint8_t pulseOutput = PlsrHostSelectedPulse;
  1106. while ((quarterCount != 0UL)
  1107. && (PlsrHostPulseActive[pulseOutput] != 0U)
  1108. && (PlsrHostOutputMode[pulseOutput] == PLSR_OUTPUT_AB))
  1109. {
  1110. if (PlsrHostAdvanceAbQuarter(pulseOutput) != 0U)
  1111. {
  1112. PlsrHostServicePendingPulse(pulseOutput);
  1113. }
  1114. quarterCount--;
  1115. }
  1116. }
  1117. uint8_t PlsrTestPulseIsActive(void)
  1118. {
  1119. return PlsrHostPulseActive[PlsrHostSelectedPulse];
  1120. }
  1121. uint32_t PlsrTestOutputFrequency(void)
  1122. {
  1123. return PlsrHostFrequency[PlsrHostSelectedPulse];
  1124. }
  1125. uint32_t PlsrTestQueuedFrequency(void)
  1126. {
  1127. return PlsrHostQueuedFrequency[PlsrHostSelectedPulse];
  1128. }
  1129. uint8_t PlsrTestDirectionLevel(void)
  1130. {
  1131. return PlsrHostDirectionLevel;
  1132. }
  1133. uint8_t PlsrTestDirectionPinLevel(uint8_t directionOutput)
  1134. {
  1135. return (directionOutput < 4U)
  1136. ? PlsrHostDirectionPinLevel[directionOutput] : 0U;
  1137. }
  1138. uint32_t PlsrTestDirectionWriteCount(uint8_t directionOutput)
  1139. {
  1140. return (directionOutput < 4U)
  1141. ? PlsrHostDirectionWriteCount[directionOutput] : 0UL;
  1142. }
  1143. uint32_t PlsrTestDirectionTransitionCount(uint8_t directionOutput)
  1144. {
  1145. return (directionOutput < 4U)
  1146. ? PlsrHostDirectionTransitionCount[directionOutput] : 0UL;
  1147. }
  1148. uint8_t PlsrTestAbPhase(void)
  1149. {
  1150. return PlsrHostAbPhase[PlsrHostSelectedPulse];
  1151. }
  1152. uint32_t PlsrTestAbTransitionCount(void)
  1153. {
  1154. return PlsrHostAbTransitions[PlsrHostSelectedPulse];
  1155. }
  1156. uint32_t PlsrTestAbFastGateCount(void)
  1157. {
  1158. return PlsrHostAbFastGateCount;
  1159. }
  1160. uint32_t PlsrTestAbCleanupCount(void)
  1161. {
  1162. return PlsrHostAbCleanupCount;
  1163. }
  1164. void PlsrTestInjectCountOffset(int32_t offset)
  1165. {
  1166. PlsrHostCountOffset = offset;
  1167. }
  1168. void PlsrTestInjectActiveFrequencyOffset(int32_t offsetHz)
  1169. {
  1170. PlsrHostFrequencyOffsetHz = offsetHz;
  1171. PlsrHostDiagnosticFault = 2U;
  1172. }
  1173. void PlsrTestInjectCurveMismatch(void)
  1174. {
  1175. PlsrHostCurveMismatchPending = 1U;
  1176. }
  1177. void PlsrTestClearPersistentStorage(void)
  1178. {
  1179. (void)memset(&PlsrHostPersistentPayload, 0,
  1180. sizeof(PlsrHostPersistentPayload));
  1181. (void)memset(PlsrHostInputs, 0, sizeof(PlsrHostInputs));
  1182. PlsrHostPersistentValid = 0U;
  1183. PlsrHostSaveCount = 0UL;
  1184. PlsrHostCountOffset = 0L;
  1185. PlsrHostFrequencyOffsetHz = 0L;
  1186. PlsrHostCurveMismatchPending = 0U;
  1187. PlsrHostDiagnosticFault = 0U;
  1188. }
  1189. void PlsrTestResetSaveCount(void)
  1190. {
  1191. PlsrHostSaveCount = 0UL;
  1192. }
  1193. uint32_t PlsrTestSaveCount(void)
  1194. {
  1195. return PlsrHostSaveCount;
  1196. }
  1197. uint8_t PlsrTestFlashNeedsStartupRecovery(
  1198. uint8_t haveValidRecord,
  1199. uint8_t sectorAHasProgrammedSlot,
  1200. uint32_t sectorAFirstErasedAddress,
  1201. uint8_t sectorBHasProgrammedSlot,
  1202. uint32_t sectorBFirstErasedAddress)
  1203. {
  1204. return PlsrFlashNeedsStartupRecovery(
  1205. haveValidRecord,
  1206. sectorAHasProgrammedSlot,
  1207. sectorAFirstErasedAddress,
  1208. sectorBHasProgrammedSlot,
  1209. sectorBFirstErasedAddress);
  1210. }
  1211. #else
  1212. #include "stm32f4xx_hal.h"
  1213. #include <stddef.h>
  1214. #include <string.h>
  1215. #ifndef PLSR_DEBUG_TIMING
  1216. #define PLSR_DEBUG_TIMING (0U)
  1217. #endif
  1218. #define PLSR_FLASH_SLOT_A_ADDRESS (0x080C0000UL)
  1219. #define PLSR_FLASH_SLOT_B_ADDRESS (0x080E0000UL)
  1220. #define PLSR_FLASH_SECTOR_SIZE (0x00020000UL)
  1221. #define PLSR_FLASH_MAGIC (0x50534C52UL)
  1222. #define PLSR_FLASH_VERSION_V2 (2U)
  1223. #define PLSR_FLASH_VERSION (3U)
  1224. #define PLSR_BACKUP_CONFIG_ADDRESS (BKPSRAM_BASE + 0x0100UL)
  1225. #define PLSR_BACKUP_POSITION_ADDRESS (BKPSRAM_BASE + 0x0200UL)
  1226. #define PLSR_BACKUP_CONFIG_MAGIC (0x50434647UL)
  1227. #define PLSR_BACKUP_POSITION_MAGIC (0x50504F53UL)
  1228. #define PLSR_CONFIG_V2_SIZE (offsetof(PLSR_CONFIG, outputMode))
  1229. #define PLSR_COUNTER_COUNT (2U)
  1230. #define PLSR_COUNTER_NONE (0xFFU)
  1231. #define PLSR_COUNTER_BLOCK_PULSES (65536UL)
  1232. #define PLSR_PLATFORM_FAULT_FREQUENCY (2U)
  1233. #define PLSR_PLATFORM_FAULT_CURVE (3U)
  1234. #define PLSR_TIMER_OC1_MODE_MASK (7UL << TIM_CCMR1_OC1M_Pos)
  1235. #define PLSR_TIMER_PWM1_MODE (6UL << TIM_CCMR1_OC1M_Pos)
  1236. #define PLSR_STRUCTURE_VERIFY_INTERVAL (64U)
  1237. #define PLSR_FREQUENCY_VERIFY_NONE (0U)
  1238. #define PLSR_FREQUENCY_VERIFY_NOW (1U)
  1239. #define PLSR_FREQUENCY_VERIFY_AB_AUX_IRQ (2U)
  1240. #define PLSR_QUEUE_WRITE_GUARD_COUNTS (64UL)
  1241. #define PLSR_FINITE_WRITE_GUARD_COUNTS (128UL)
  1242. #define PLSR_FLASH_ERASE_NONE (0U)
  1243. #define PLSR_FLASH_ERASE_SECTOR_A (1U)
  1244. #define PLSR_FLASH_ERASE_SECTOR_B (2U)
  1245. #define PLSR_FLASH_ERASE_FAILED (3U)
  1246. typedef struct
  1247. {
  1248. TIM_TypeDef *timer;
  1249. GPIO_TypeDef *port;
  1250. uint16_t pin;
  1251. uint8_t pinIndex;
  1252. uint8_t alternate;
  1253. IRQn_Type irq;
  1254. uint32_t timerClockHz;
  1255. } PLSR_TIMER_MAP;
  1256. typedef struct
  1257. {
  1258. GPIO_TypeDef *port;
  1259. uint16_t pin;
  1260. } PLSR_GPIO_MAP;
  1261. typedef struct
  1262. {
  1263. uint32_t prescaler;
  1264. uint32_t period;
  1265. uint32_t compare;
  1266. uint32_t actualFrequencyHz;
  1267. } PLSR_TIMER_SETTING;
  1268. typedef struct
  1269. {
  1270. uint32_t basePrescaler;
  1271. uint32_t pairPrescaler;
  1272. uint32_t period;
  1273. uint32_t compare;
  1274. uint32_t actualFrequencyHz;
  1275. } PLSR_AB_SETTING;
  1276. typedef struct
  1277. {
  1278. uint32_t cr1;
  1279. uint32_t ccmr1;
  1280. uint32_t ccer;
  1281. uint32_t psc;
  1282. uint32_t arr;
  1283. uint32_t ccr1;
  1284. } PLSR_TIMER_SNAPSHOT;
  1285. typedef struct
  1286. {
  1287. uint32_t magic;
  1288. uint16_t version;
  1289. uint16_t payloadSize;
  1290. uint32_t generation;
  1291. } PLSR_FLASH_HEADER;
  1292. typedef struct
  1293. {
  1294. uint8_t config[PLSR_CONFIG_V2_SIZE];
  1295. int32_t position;
  1296. uint8_t positionValid;
  1297. uint8_t wasBusy;
  1298. uint16_t reserved;
  1299. } PLSR_PERSIST_PAYLOAD_V2;
  1300. typedef struct
  1301. {
  1302. uint32_t magic;
  1303. uint16_t version;
  1304. uint16_t payloadSize;
  1305. uint32_t generation;
  1306. PLSR_PERSIST_PAYLOAD payload;
  1307. uint32_t crc32;
  1308. } PLSR_FLASH_RECORD;
  1309. typedef struct
  1310. {
  1311. uint32_t magic;
  1312. uint16_t version;
  1313. uint16_t payloadSize;
  1314. uint32_t generation;
  1315. PLSR_PERSIST_PAYLOAD_V2 payload;
  1316. uint32_t crc32;
  1317. } PLSR_FLASH_RECORD_V2;
  1318. #define PLSR_FLASH_RECORD_STRIDE \
  1319. ((uint32_t)sizeof(PLSR_FLASH_RECORD))
  1320. #define PLSR_FLASH_SLOT_COUNT \
  1321. (PLSR_FLASH_SECTOR_SIZE / PLSR_FLASH_RECORD_STRIDE)
  1322. typedef char PLSR_FLASH_RECORD_SIZE_MUST_BE_228[
  1323. (sizeof(PLSR_FLASH_RECORD) == 228U) ? 1 : -1];
  1324. typedef struct
  1325. {
  1326. const PLSR_FLASH_HEADER *newest;
  1327. uint32_t firstErasedAddress;
  1328. uint8_t newestVersion;
  1329. uint8_t hasProgrammedSlot;
  1330. } PLSR_FLASH_SECTOR_SCAN;
  1331. typedef struct
  1332. {
  1333. uint32_t magic;
  1334. PLSR_CONFIG config;
  1335. uint32_t crc32;
  1336. } PLSR_BACKUP_CONFIG_RECORD;
  1337. typedef struct
  1338. {
  1339. uint32_t magic;
  1340. uint8_t config[PLSR_CONFIG_V2_SIZE];
  1341. uint32_t crc32;
  1342. } PLSR_BACKUP_CONFIG_RECORD_V2;
  1343. typedef struct
  1344. {
  1345. uint32_t magic;
  1346. uint32_t generation;
  1347. int32_t position;
  1348. uint8_t positionValid;
  1349. uint8_t wasBusy;
  1350. uint16_t reserved;
  1351. uint32_t crc32;
  1352. } PLSR_BACKUP_POSITION_RECORD;
  1353. static const PLSR_TIMER_MAP PlsrTimerMap[4] =
  1354. {
  1355. {TIM10, GPIOF, GPIO_PIN_6, 6U, GPIO_AF3_TIM10,
  1356. TIM1_UP_TIM10_IRQn, 168000000UL},
  1357. {TIM13, GPIOF, GPIO_PIN_8, 8U, GPIO_AF9_TIM13,
  1358. TIM8_UP_TIM13_IRQn, 84000000UL},
  1359. {TIM11, GPIOF, GPIO_PIN_7, 7U, GPIO_AF3_TIM11,
  1360. TIM1_TRG_COM_TIM11_IRQn, 168000000UL},
  1361. {TIM14, GPIOF, GPIO_PIN_9, 9U, GPIO_AF9_TIM14,
  1362. TIM8_TRG_COM_TIM14_IRQn, 84000000UL}
  1363. };
  1364. static const PLSR_GPIO_MAP PlsrDirectionMap[4] =
  1365. {
  1366. {GPIOH, GPIO_PIN_9},
  1367. {GPIOH, GPIO_PIN_8},
  1368. {GPIOH, GPIO_PIN_7},
  1369. {GPIOH, GPIO_PIN_6}
  1370. };
  1371. static PLSR_FLASH_RECORD PlsrFlashRecordBuffer;
  1372. static uint32_t PlsrFlashNewestAddress;
  1373. static uint32_t PlsrFlashNewestGeneration;
  1374. static uint32_t PlsrFlashNextErasedAddress[2];
  1375. static uint8_t PlsrFlashJournalInitialized;
  1376. static uint8_t PlsrFlashReserveEraseState;
  1377. static uint32_t PlsrBackupPositionGeneration;
  1378. static uint32_t PlsrTimerActiveFrequencyHz[4];
  1379. static uint32_t PlsrTimerQueuedFrequencyHz[4];
  1380. static PLSR_PLATFORM_TIMER_SETTING PlsrTimerActiveSetting[4];
  1381. static PLSR_PLATFORM_TIMER_SETTING PlsrTimerQueuedSetting[4];
  1382. static uint32_t PlsrTimerQueueGeneration[4];
  1383. static uint8_t PlsrTimerOutputMode[4];
  1384. static uint8_t PlsrTimerDirectionPositive[4];
  1385. static uint8_t PlsrTimerRunning[4];
  1386. static uint8_t PlsrFrequencyVerifyPending[4];
  1387. static uint8_t PlsrFrequencyVerifyPulseCount[4];
  1388. static volatile uint8_t PlsrDeferredPulsePending[4];
  1389. static volatile uint8_t PlsrAbVerifyOwner[4];
  1390. static volatile uint8_t PlsrAbFinalArmJobOwner[4];
  1391. static uint8_t PlsrTimerIrqActive[4];
  1392. static PLSR_AB_SETTING PlsrAbActiveSetting[4];
  1393. static PLSR_AB_SETTING PlsrAbPendingSetting[4];
  1394. static uint8_t PlsrAbFrequencyPending[4];
  1395. static uint8_t PlsrAbLagAxis[4];
  1396. static uint8_t PlsrAbStructureVerified[4];
  1397. static uint8_t PlsrAbCounterSourceAxis[4];
  1398. static uint32_t PlsrAbCounterBoundary[4];
  1399. static volatile uint8_t PlsrAbStopPending[4];
  1400. static volatile uint8_t PlsrAbFastGated[4];
  1401. static TIM_TypeDef * const PlsrCounters[PLSR_COUNTER_COUNT] =
  1402. {
  1403. TIM9, TIM12
  1404. };
  1405. static uint8_t PlsrCounterOwner[PLSR_COUNTER_COUNT];
  1406. static volatile uint64_t PlsrCounterOverflowPulses[PLSR_COUNTER_COUNT];
  1407. static uint8_t PlsrCounterIndexByOutput[4];
  1408. static uint64_t PlsrObservedPulseBase[4];
  1409. static uint64_t PlsrObservedPulsePublished[4];
  1410. static volatile uint8_t PlsrFiniteActive[4];
  1411. static volatile uint8_t PlsrFiniteCompletionPending[4];
  1412. static volatile uint8_t PlsrFiniteFrequencyPending[4];
  1413. static volatile uint8_t PlsrFiniteRetargetPending[4];
  1414. static volatile uint8_t PlsrFiniteTailStopPending[4];
  1415. static uint32_t PlsrFiniteRetargetDrainPulses[4];
  1416. static uint32_t PlsrFiniteTargetPulses[4];
  1417. static uint32_t PlsrFiniteRemainingPulses[4];
  1418. static uint8_t PlsrFiniteCounterPreload[4];
  1419. static volatile uint8_t PlsrFiniteStreamActive[4];
  1420. static volatile uint8_t PlsrFiniteStreamNextValid[4];
  1421. static volatile uint8_t PlsrFiniteStreamNextStartsSegment[4];
  1422. static volatile uint8_t PlsrFiniteStreamSourceDone[4];
  1423. static volatile uint8_t PlsrFiniteStreamSourceFault[4];
  1424. static uint32_t PlsrFiniteStreamNextPulses[4];
  1425. static PLSR_PLATFORM_TIMER_SETTING PlsrFiniteStreamNextSetting[4];
  1426. static PLSR_PLATFORM_FINITE_STEP *PlsrFiniteSteps[4];
  1427. static volatile uint16_t PlsrFiniteStepCount[4];
  1428. static volatile uint16_t PlsrFiniteStepIndex[4];
  1429. static volatile uint16_t PlsrFiniteBoundaryReadIndex[4];
  1430. static volatile uint16_t PlsrFiniteCompletedStepCount[4];
  1431. static volatile uint16_t PlsrPlatformFaultPending;
  1432. static void PlsrHandleTimerIrq(uint8_t pulseOutput);
  1433. static void PlsrCounterSuspend(uint8_t pulseOutput);
  1434. static void PlsrAbFastGate(uint8_t pulseOutput);
  1435. static void PlsrFiniteCounterIrq(uint8_t pulseOutput,
  1436. TIM_TypeDef *counter);
  1437. static void PlsrFinitePrepareNextStepIrq(uint8_t pulseOutput,
  1438. TIM_TypeDef *counter);
  1439. static void PlsrFiniteArmNextStepPrepare(uint8_t pulseOutput,
  1440. TIM_TypeDef *counter,
  1441. uint32_t blockPulses);
  1442. static void PlsrFiniteRetargetAtFallingEdge(uint8_t pulseOutput);
  1443. static void PlsrFiniteCutAtFallingEdge(uint8_t pulseOutput);
  1444. static void PlsrFiniteStopAtFallingEdge(uint8_t pulseOutput);
  1445. static uint8_t PlsrFinalArmJobOutput(uint8_t pulseOutput)
  1446. {
  1447. return (pulseOutput == 0U) ? 2U : 0U;
  1448. }
  1449. #if PLSR_DEBUG_TIMING
  1450. volatile uint32_t PlsrIrqCount[4];
  1451. volatile uint32_t PlsrIrqLastCycles[4];
  1452. volatile uint32_t PlsrIrqMaxCycles[4];
  1453. volatile uint32_t PlsrFinalArmQueueCount[4];
  1454. volatile uint32_t PlsrFinalArmJobLastCycles[4];
  1455. volatile uint32_t PlsrFinalArmJobMaxCycles[4];
  1456. volatile uint32_t PlsrFinalArmQueueToStopLastCycles[4];
  1457. volatile uint32_t PlsrFinalArmQueueToStopMaxCycles[4];
  1458. volatile uint32_t PlsrFiniteBlockIrqCount[4];
  1459. volatile uint32_t PlsrFiniteBlockIrqMaxCycles[4];
  1460. volatile uint32_t PlsrFiniteFinalIrqLastCycles[4];
  1461. volatile uint32_t PlsrFiniteFinalIrqMaxCycles[4];
  1462. volatile uint32_t PlsrAbReloadCounterBefore[4];
  1463. volatile uint32_t PlsrAbReloadCounterArmed[4];
  1464. volatile uint32_t PlsrAbReloadCounterStarted[4];
  1465. volatile uint32_t PlsrAbReloadCount[4];
  1466. static volatile uint32_t PlsrFinalArmQueuedAt[4];
  1467. static volatile uint8_t PlsrFinalArmQueueTimingPending[4];
  1468. #endif
  1469. static uint32_t PlsrCrc32(const void *data, uint32_t length)
  1470. {
  1471. const uint8_t *bytes = (const uint8_t *)data;
  1472. uint32_t crc = 0xFFFFFFFFUL;
  1473. uint32_t index;
  1474. uint8_t bit;
  1475. for (index = 0UL; index < length; index++)
  1476. {
  1477. crc ^= bytes[index];
  1478. for (bit = 0U; bit < 8U; bit++)
  1479. {
  1480. crc = ((crc & 1UL) != 0UL) ? ((crc >> 1U) ^ 0xEDB88320UL)
  1481. : (crc >> 1U);
  1482. }
  1483. }
  1484. return ~crc;
  1485. }
  1486. static uint8_t PlsrGenerationIsNewer(uint32_t first, uint32_t second)
  1487. {
  1488. return ((int32_t)(first - second) > 0) ? 1U : 0U;
  1489. }
  1490. static uint32_t PlsrFlashRecordCrc(const void *record,
  1491. uint32_t payloadSize)
  1492. {
  1493. const PLSR_FLASH_HEADER *header = (const PLSR_FLASH_HEADER *)record;
  1494. const uint8_t *start = (const uint8_t *)&header->version;
  1495. uint32_t length = (uint32_t)(sizeof(header->version)
  1496. + sizeof(header->payloadSize)
  1497. + sizeof(header->generation))
  1498. + payloadSize;
  1499. return PlsrCrc32(start, length);
  1500. }
  1501. static uint8_t PlsrFlashRecordVersion(const void *address)
  1502. {
  1503. const PLSR_FLASH_HEADER *header = (const PLSR_FLASH_HEADER *)address;
  1504. if (header->magic != PLSR_FLASH_MAGIC)
  1505. {
  1506. return 0U;
  1507. }
  1508. if ((header->version == PLSR_FLASH_VERSION)
  1509. && (header->payloadSize == sizeof(PLSR_PERSIST_PAYLOAD)))
  1510. {
  1511. const PLSR_FLASH_RECORD *record =
  1512. (const PLSR_FLASH_RECORD *)address;
  1513. return (record->crc32
  1514. == PlsrFlashRecordCrc(record, sizeof(record->payload)))
  1515. ? PLSR_FLASH_VERSION : 0U;
  1516. }
  1517. if ((header->version == PLSR_FLASH_VERSION_V2)
  1518. && (header->payloadSize == sizeof(PLSR_PERSIST_PAYLOAD_V2)))
  1519. {
  1520. const PLSR_FLASH_RECORD_V2 *record =
  1521. (const PLSR_FLASH_RECORD_V2 *)address;
  1522. return (record->crc32
  1523. == PlsrFlashRecordCrc(record, sizeof(record->payload)))
  1524. ? PLSR_FLASH_VERSION_V2 : 0U;
  1525. }
  1526. return 0U;
  1527. }
  1528. static uint8_t PlsrFlashSlotIsErased(uint32_t address)
  1529. {
  1530. const uint32_t *words = (const uint32_t *)address;
  1531. uint32_t index;
  1532. for (index = 0UL;
  1533. index < (PLSR_FLASH_RECORD_STRIDE / sizeof(uint32_t));
  1534. index++)
  1535. {
  1536. if (words[index] != 0xFFFFFFFFUL)
  1537. {
  1538. return 0U;
  1539. }
  1540. }
  1541. return 1U;
  1542. }
  1543. static uint8_t PlsrFlashSectorIsErased(uint32_t address)
  1544. {
  1545. const uint32_t *words = (const uint32_t *)address;
  1546. uint32_t index;
  1547. for (index = 0UL;
  1548. index < (PLSR_FLASH_SECTOR_SIZE / sizeof(uint32_t)); index++)
  1549. {
  1550. if (words[index] != 0xFFFFFFFFUL)
  1551. {
  1552. return 0U;
  1553. }
  1554. }
  1555. return 1U;
  1556. }
  1557. static void PlsrFlashScanSector(uint32_t sectorAddress,
  1558. PLSR_FLASH_SECTOR_SCAN *scan)
  1559. {
  1560. uint32_t index;
  1561. (void)memset(scan, 0, sizeof(*scan));
  1562. for (index = 0UL; index < PLSR_FLASH_SLOT_COUNT; index++)
  1563. {
  1564. uint32_t slotAddress = sectorAddress
  1565. + index * PLSR_FLASH_RECORD_STRIDE;
  1566. const PLSR_FLASH_HEADER *header =
  1567. (const PLSR_FLASH_HEADER *)slotAddress;
  1568. uint8_t version = PlsrFlashRecordVersion(header);
  1569. uint8_t erased = PlsrFlashSlotIsErased(slotAddress);
  1570. if ((version != 0U)
  1571. && ((scan->newest == NULL)
  1572. || (PlsrGenerationIsNewer(header->generation,
  1573. scan->newest->generation) != 0U)))
  1574. {
  1575. scan->newest = header;
  1576. scan->newestVersion = version;
  1577. }
  1578. if ((scan->firstErasedAddress == 0UL) && (erased != 0U))
  1579. {
  1580. scan->firstErasedAddress = slotAddress;
  1581. }
  1582. if (erased == 0U)
  1583. {
  1584. scan->hasProgrammedSlot = 1U;
  1585. }
  1586. }
  1587. for (index = PLSR_FLASH_SLOT_COUNT * PLSR_FLASH_RECORD_STRIDE;
  1588. index < PLSR_FLASH_SECTOR_SIZE; index += sizeof(uint32_t))
  1589. {
  1590. if (*(const uint32_t *)(sectorAddress + index) != 0xFFFFFFFFUL)
  1591. {
  1592. scan->hasProgrammedSlot = 1U;
  1593. }
  1594. }
  1595. }
  1596. static const PLSR_FLASH_HEADER *PlsrFlashSelectNewest(
  1597. const PLSR_FLASH_SECTOR_SCAN *scanA,
  1598. const PLSR_FLASH_SECTOR_SCAN *scanB,
  1599. uint8_t *version,
  1600. uint32_t *sectorAddress)
  1601. {
  1602. const PLSR_FLASH_SECTOR_SCAN *selectedScan;
  1603. if (scanA->newest == NULL)
  1604. {
  1605. selectedScan = (scanB->newest != NULL) ? scanB : NULL;
  1606. }
  1607. else if ((scanB->newest != NULL)
  1608. && (PlsrGenerationIsNewer(scanB->newest->generation,
  1609. scanA->newest->generation) != 0U))
  1610. {
  1611. selectedScan = scanB;
  1612. }
  1613. else
  1614. {
  1615. selectedScan = scanA;
  1616. }
  1617. if (selectedScan == NULL)
  1618. {
  1619. *version = 0U;
  1620. *sectorAddress = 0UL;
  1621. return NULL;
  1622. }
  1623. *version = selectedScan->newestVersion;
  1624. *sectorAddress = (selectedScan == scanA)
  1625. ? PLSR_FLASH_SLOT_A_ADDRESS
  1626. : PLSR_FLASH_SLOT_B_ADDRESS;
  1627. return selectedScan->newest;
  1628. }
  1629. static const PLSR_FLASH_HEADER *PlsrFlashInitializeJournal(
  1630. PLSR_FLASH_SECTOR_SCAN *scanA,
  1631. PLSR_FLASH_SECTOR_SCAN *scanB,
  1632. uint8_t *version,
  1633. uint32_t *sectorAddress)
  1634. {
  1635. const PLSR_FLASH_HEADER *newest;
  1636. PlsrFlashScanSector(PLSR_FLASH_SLOT_A_ADDRESS, scanA);
  1637. PlsrFlashScanSector(PLSR_FLASH_SLOT_B_ADDRESS, scanB);
  1638. newest = PlsrFlashSelectNewest(scanA, scanB, version, sectorAddress);
  1639. PlsrFlashNextErasedAddress[0] = scanA->firstErasedAddress;
  1640. PlsrFlashNextErasedAddress[1] = scanB->firstErasedAddress;
  1641. PlsrFlashNewestAddress = (uint32_t)newest;
  1642. PlsrFlashNewestGeneration = (newest != NULL)
  1643. ? newest->generation : 0UL;
  1644. PlsrFlashJournalInitialized = 1U;
  1645. return newest;
  1646. }
  1647. static uint8_t PlsrFlashSectorIndex(uint32_t address)
  1648. {
  1649. return (address >= PLSR_FLASH_SLOT_B_ADDRESS) ? 1U : 0U;
  1650. }
  1651. static uint8_t PlsrFlashAddressIsJournalSlot(uint8_t sectorIndex,
  1652. uint32_t address)
  1653. {
  1654. uint32_t sectorAddress = (sectorIndex == 0U)
  1655. ? PLSR_FLASH_SLOT_A_ADDRESS
  1656. : PLSR_FLASH_SLOT_B_ADDRESS;
  1657. uint32_t offset;
  1658. if ((address < sectorAddress)
  1659. || (address >= sectorAddress + PLSR_FLASH_SECTOR_SIZE))
  1660. {
  1661. return 0U;
  1662. }
  1663. offset = address - sectorAddress;
  1664. return ((offset % PLSR_FLASH_RECORD_STRIDE) == 0UL)
  1665. && ((offset / PLSR_FLASH_RECORD_STRIDE)
  1666. < PLSR_FLASH_SLOT_COUNT) ? 1U : 0U;
  1667. }
  1668. static uint32_t PlsrFlashFindErasedAfter(uint8_t sectorIndex,
  1669. uint32_t address)
  1670. {
  1671. uint32_t sectorAddress = (sectorIndex == 0U)
  1672. ? PLSR_FLASH_SLOT_A_ADDRESS
  1673. : PLSR_FLASH_SLOT_B_ADDRESS;
  1674. uint32_t firstIndex = ((address - sectorAddress)
  1675. / PLSR_FLASH_RECORD_STRIDE) + 1UL;
  1676. uint32_t index;
  1677. for (index = firstIndex; index < PLSR_FLASH_SLOT_COUNT; index++)
  1678. {
  1679. uint32_t slotAddress = sectorAddress
  1680. + index * PLSR_FLASH_RECORD_STRIDE;
  1681. if (PlsrFlashSlotIsErased(slotAddress) != 0U)
  1682. {
  1683. return slotAddress;
  1684. }
  1685. }
  1686. return 0UL;
  1687. }
  1688. static uint8_t PlsrFlashEraseReserve(uint8_t sectorIndex)
  1689. {
  1690. FLASH_EraseInitTypeDef erase;
  1691. uint32_t sectorError;
  1692. HAL_StatusTypeDef status;
  1693. if (HAL_FLASH_Unlock() != HAL_OK)
  1694. {
  1695. (void)HAL_FLASH_Lock();
  1696. return 0U;
  1697. }
  1698. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR
  1699. | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR
  1700. | FLASH_FLAG_PGSERR);
  1701. erase.TypeErase = FLASH_TYPEERASE_SECTORS;
  1702. erase.VoltageRange = FLASH_VOLTAGE_RANGE_3;
  1703. erase.Sector = (sectorIndex == 0U) ? FLASH_SECTOR_10 : FLASH_SECTOR_11;
  1704. erase.NbSectors = 1U;
  1705. status = HAL_FLASHEx_Erase(&erase, &sectorError);
  1706. if ((status == HAL_OK)
  1707. && (PlsrFlashSectorIsErased((sectorIndex == 0U)
  1708. ? PLSR_FLASH_SLOT_A_ADDRESS
  1709. : PLSR_FLASH_SLOT_B_ADDRESS) == 0U))
  1710. {
  1711. status = HAL_ERROR;
  1712. }
  1713. if (HAL_FLASH_Lock() != HAL_OK)
  1714. {
  1715. (void)HAL_FLASH_Lock();
  1716. status = HAL_ERROR;
  1717. }
  1718. return (status == HAL_OK) ? 1U : 0U;
  1719. }
  1720. static uint8_t PlsrBackupConfigVersion(const void *address)
  1721. {
  1722. const PLSR_BACKUP_CONFIG_RECORD *record =
  1723. (const PLSR_BACKUP_CONFIG_RECORD *)address;
  1724. if (record->magic != PLSR_BACKUP_CONFIG_MAGIC)
  1725. {
  1726. return 0U;
  1727. }
  1728. if (record->crc32 == PlsrCrc32(&record->config, sizeof(record->config)))
  1729. {
  1730. return PLSR_FLASH_VERSION;
  1731. }
  1732. {
  1733. const PLSR_BACKUP_CONFIG_RECORD_V2 *oldRecord =
  1734. (const PLSR_BACKUP_CONFIG_RECORD_V2 *)address;
  1735. return (oldRecord->crc32
  1736. == PlsrCrc32(oldRecord->config, sizeof(oldRecord->config)))
  1737. ? PLSR_FLASH_VERSION_V2 : 0U;
  1738. }
  1739. }
  1740. static void PlsrLoadV2Payload(PLSR_PERSIST_PAYLOAD *destination,
  1741. const PLSR_PERSIST_PAYLOAD_V2 *source)
  1742. {
  1743. (void)memset(destination, 0, sizeof(*destination));
  1744. (void)memcpy(&destination->config, source->config,
  1745. sizeof(source->config));
  1746. destination->config.outputMode = PLSR_OUTPUT_PULSE_DIR;
  1747. destination->position = source->position;
  1748. destination->positionValid = source->positionValid;
  1749. destination->wasBusy = source->wasBusy;
  1750. }
  1751. static uint8_t PlsrBackupPositionIsValid(
  1752. const PLSR_BACKUP_POSITION_RECORD *record)
  1753. {
  1754. uint32_t crc = PlsrCrc32(&record->generation,
  1755. sizeof(record->generation)
  1756. + sizeof(record->position)
  1757. + sizeof(record->positionValid)
  1758. + sizeof(record->wasBusy)
  1759. + sizeof(record->reserved));
  1760. return ((record->magic == PLSR_BACKUP_POSITION_MAGIC)
  1761. && (record->crc32 == crc)) ? 1U : 0U;
  1762. }
  1763. static const PLSR_BACKUP_POSITION_RECORD *PlsrNewestBackupPosition(void)
  1764. {
  1765. const PLSR_BACKUP_POSITION_RECORD *slots =
  1766. (const PLSR_BACKUP_POSITION_RECORD *)PLSR_BACKUP_POSITION_ADDRESS;
  1767. uint8_t validA = PlsrBackupPositionIsValid(&slots[0]);
  1768. uint8_t validB = PlsrBackupPositionIsValid(&slots[1]);
  1769. if ((validA == 0U) && (validB == 0U))
  1770. {
  1771. return NULL;
  1772. }
  1773. if (validA == 0U)
  1774. {
  1775. return &slots[1];
  1776. }
  1777. if (validB == 0U)
  1778. {
  1779. return &slots[0];
  1780. }
  1781. return (PlsrGenerationIsNewer(slots[1].generation,
  1782. slots[0].generation) != 0U)
  1783. ? &slots[1] : &slots[0];
  1784. }
  1785. static void PlsrTimerStop(TIM_TypeDef *timer)
  1786. {
  1787. timer->DIER &= ~(TIM_DIER_UIE | TIM_DIER_CC1IE);
  1788. timer->CR1 &= ~TIM_CR1_CEN;
  1789. timer->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
  1790. timer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
  1791. }
  1792. static void PlsrTimerInitialize(TIM_TypeDef *timer)
  1793. {
  1794. timer->CR1 = TIM_CR1_ARPE | TIM_CR1_URS;
  1795. timer->CR2 = 0UL;
  1796. timer->SMCR = 0UL;
  1797. timer->DIER = 0UL;
  1798. timer->CCMR1 = TIM_CCMR1_OC1PE | (6UL << TIM_CCMR1_OC1M_Pos);
  1799. timer->CCER = 0UL;
  1800. timer->PSC = 0UL;
  1801. timer->ARR = 999UL;
  1802. timer->CCR1 = 500UL;
  1803. timer->CNT = 0UL;
  1804. timer->EGR = TIM_EGR_UG;
  1805. timer->SR = 0UL;
  1806. }
  1807. static void PlsrPulsePinHoldIdle(uint8_t pulseOutput)
  1808. {
  1809. const PLSR_TIMER_MAP *map = &PlsrTimerMap[pulseOutput];
  1810. GPIO_InitTypeDef gpio;
  1811. HAL_GPIO_WritePin(map->port, map->pin, GPIO_PIN_SET);
  1812. gpio.Pin = map->pin;
  1813. gpio.Mode = GPIO_MODE_OUTPUT_PP;
  1814. gpio.Pull = GPIO_NOPULL;
  1815. gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  1816. gpio.Alternate = 0U;
  1817. HAL_GPIO_Init(map->port, &gpio);
  1818. }
  1819. static void PlsrPulsePinCaptureIdle(uint8_t pulseOutput)
  1820. {
  1821. const PLSR_TIMER_MAP *map = &PlsrTimerMap[pulseOutput];
  1822. uint32_t shift = (uint32_t)map->pinIndex * 2UL;
  1823. uint32_t mode = map->port->MODER;
  1824. /* The update IRQ occurs while PWM is high; switch to GPIO high first. */
  1825. map->port->BSRR = map->pin;
  1826. mode &= ~(3UL << shift);
  1827. mode |= 1UL << shift;
  1828. map->port->MODER = mode;
  1829. __DSB();
  1830. }
  1831. static void PlsrPulsePinRelease(uint8_t pulseOutput)
  1832. {
  1833. const PLSR_TIMER_MAP *map = &PlsrTimerMap[pulseOutput];
  1834. GPIO_InitTypeDef gpio;
  1835. gpio.Pin = map->pin;
  1836. gpio.Mode = GPIO_MODE_AF_PP;
  1837. gpio.Pull = GPIO_NOPULL;
  1838. gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  1839. gpio.Alternate = map->alternate;
  1840. HAL_GPIO_Init(map->port, &gpio);
  1841. __DSB();
  1842. }
  1843. static uint8_t PlsrTimerCalculate(uint8_t pulseOutput,
  1844. uint32_t frequencyHz,
  1845. PLSR_TIMER_SETTING *setting)
  1846. {
  1847. const PLSR_TIMER_MAP *map;
  1848. uint32_t prescalerDivider;
  1849. uint32_t denominator;
  1850. uint32_t periodCounts;
  1851. if ((pulseOutput > 3U) || (frequencyHz == 0UL)
  1852. || (frequencyHz > PLSR_FREQUENCY_MAX_HZ)
  1853. || (setting == NULL))
  1854. {
  1855. return 0U;
  1856. }
  1857. map = &PlsrTimerMap[pulseOutput];
  1858. prescalerDivider = (((map->timerClockHz - 1UL) / frequencyHz) >> 16U)
  1859. + 1UL;
  1860. if (prescalerDivider > 65536UL)
  1861. {
  1862. return 0U;
  1863. }
  1864. denominator = prescalerDivider * frequencyHz;
  1865. periodCounts = (map->timerClockHz + denominator / 2UL) / denominator;
  1866. if (periodCounts < 2UL)
  1867. {
  1868. periodCounts = 2UL;
  1869. }
  1870. if (periodCounts > 65536UL)
  1871. {
  1872. periodCounts = 65536UL;
  1873. }
  1874. setting->prescaler = prescalerDivider - 1UL;
  1875. setting->period = periodCounts - 1UL;
  1876. setting->compare = periodCounts / 2UL;
  1877. denominator = prescalerDivider * periodCounts;
  1878. setting->actualFrequencyHz =
  1879. (map->timerClockHz + denominator / 2UL) / denominator;
  1880. return 1U;
  1881. }
  1882. static void PlsrTimerWriteSetting(TIM_TypeDef *timer,
  1883. const PLSR_TIMER_SETTING *setting)
  1884. {
  1885. timer->PSC = setting->prescaler;
  1886. timer->ARR = setting->period;
  1887. timer->CCR1 = setting->compare;
  1888. }
  1889. static void PlsrTimerSnapshot(TIM_TypeDef *timer,
  1890. PLSR_TIMER_SNAPSHOT *snapshot)
  1891. {
  1892. snapshot->cr1 = timer->CR1;
  1893. snapshot->ccmr1 = timer->CCMR1;
  1894. snapshot->ccer = timer->CCER;
  1895. snapshot->psc = timer->PSC;
  1896. snapshot->arr = timer->ARR;
  1897. snapshot->ccr1 = timer->CCR1;
  1898. }
  1899. static uint8_t PlsrAbCalculate(uint8_t pulseOutput,
  1900. uint32_t frequencyHz,
  1901. PLSR_AB_SETTING *setting)
  1902. {
  1903. const PLSR_TIMER_MAP *baseMap;
  1904. const PLSR_TIMER_MAP *pairMap;
  1905. uint64_t ratio;
  1906. uint64_t pairDivider;
  1907. uint64_t baseDivider;
  1908. uint64_t periodCounts;
  1909. if (((pulseOutput != 0U) && (pulseOutput != 2U))
  1910. || (frequencyHz == 0UL)
  1911. || (frequencyHz > PLSR_FREQUENCY_MAX_HZ)
  1912. || (setting == NULL))
  1913. {
  1914. return 0U;
  1915. }
  1916. baseMap = &PlsrTimerMap[pulseOutput];
  1917. pairMap = &PlsrTimerMap[pulseOutput + 1U];
  1918. if ((pairMap->timerClockHz == 0UL)
  1919. || ((baseMap->timerClockHz % pairMap->timerClockHz) != 0UL))
  1920. {
  1921. return 0U;
  1922. }
  1923. ratio = baseMap->timerClockHz / pairMap->timerClockHz;
  1924. pairDivider = ((uint64_t)pairMap->timerClockHz
  1925. + (uint64_t)frequencyHz * 65536UL - 1UL)
  1926. / ((uint64_t)frequencyHz * 65536UL);
  1927. if (pairDivider == 0UL)
  1928. {
  1929. pairDivider = 1UL;
  1930. }
  1931. baseDivider = pairDivider * ratio;
  1932. if ((pairDivider > 65536UL) || (baseDivider > 65536UL))
  1933. {
  1934. return 0U;
  1935. }
  1936. periodCounts = ((uint64_t)pairMap->timerClockHz
  1937. + ((uint64_t)frequencyHz * pairDivider) / 2UL)
  1938. / ((uint64_t)frequencyHz * pairDivider);
  1939. if ((periodCounts < 4UL) || (periodCounts > 65536UL))
  1940. {
  1941. return 0U;
  1942. }
  1943. setting->basePrescaler = (uint32_t)(baseDivider - 1UL);
  1944. setting->pairPrescaler = (uint32_t)(pairDivider - 1UL);
  1945. setting->period = (uint32_t)(periodCounts - 1UL);
  1946. setting->compare = (uint32_t)(periodCounts / 2UL);
  1947. setting->actualFrequencyHz =
  1948. (uint32_t)(((uint64_t)pairMap->timerClockHz
  1949. + (pairDivider * periodCounts) / 2UL)
  1950. / (pairDivider * periodCounts));
  1951. return 1U;
  1952. }
  1953. static void PlsrAbHoldPairIdle(uint8_t pulseOutput)
  1954. {
  1955. uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
  1956. GPIO_TypeDef *port = PlsrTimerMap[pulseOutput].port;
  1957. uint32_t firstShift = (uint32_t)PlsrTimerMap[pulseOutput].pinIndex * 2UL;
  1958. uint32_t secondShift = (uint32_t)PlsrTimerMap[pairOutput].pinIndex * 2UL;
  1959. uint32_t mode = port->MODER;
  1960. port->BSRR = (uint32_t)PlsrTimerMap[pulseOutput].pin
  1961. | (uint32_t)PlsrTimerMap[pairOutput].pin;
  1962. mode &= ~((3UL << firstShift) | (3UL << secondShift));
  1963. mode |= (1UL << firstShift) | (1UL << secondShift);
  1964. port->MODER = mode;
  1965. __DSB();
  1966. }
  1967. static void PlsrAbReleasePair(uint8_t pulseOutput)
  1968. {
  1969. uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
  1970. GPIO_TypeDef *port = PlsrTimerMap[pulseOutput].port;
  1971. uint32_t firstAfrIndex =
  1972. (uint32_t)PlsrTimerMap[pulseOutput].pinIndex >> 3U;
  1973. uint32_t secondAfrIndex =
  1974. (uint32_t)PlsrTimerMap[pairOutput].pinIndex >> 3U;
  1975. uint32_t firstAfrShift =
  1976. ((uint32_t)PlsrTimerMap[pulseOutput].pinIndex & 7UL) * 4UL;
  1977. uint32_t secondAfrShift =
  1978. ((uint32_t)PlsrTimerMap[pairOutput].pinIndex & 7UL) * 4UL;
  1979. uint32_t firstShift = (uint32_t)PlsrTimerMap[pulseOutput].pinIndex * 2UL;
  1980. uint32_t secondShift = (uint32_t)PlsrTimerMap[pairOutput].pinIndex * 2UL;
  1981. uint32_t alternate;
  1982. uint32_t mode = port->MODER;
  1983. alternate = port->AFR[firstAfrIndex];
  1984. alternate &= ~(0xFUL << firstAfrShift);
  1985. alternate |= (uint32_t)PlsrTimerMap[pulseOutput].alternate
  1986. << firstAfrShift;
  1987. port->AFR[firstAfrIndex] = alternate;
  1988. alternate = port->AFR[secondAfrIndex];
  1989. alternate &= ~(0xFUL << secondAfrShift);
  1990. alternate |= (uint32_t)PlsrTimerMap[pairOutput].alternate
  1991. << secondAfrShift;
  1992. port->AFR[secondAfrIndex] = alternate;
  1993. mode &= ~((3UL << firstShift) | (3UL << secondShift));
  1994. mode |= (2UL << firstShift) | (2UL << secondShift);
  1995. port->MODER = mode;
  1996. __DSB();
  1997. }
  1998. static uint8_t PlsrAbStructureIsRunnable(
  1999. uint8_t pulseOutput,
  2000. const PLSR_TIMER_SNAPSHOT *base,
  2001. const PLSR_TIMER_SNAPSHOT *pair)
  2002. {
  2003. uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
  2004. uint8_t lagOutput = PlsrAbLagAxis[pulseOutput];
  2005. return ((((base->cr1 & TIM_CR1_CEN) != 0UL)
  2006. && ((pair->cr1 & TIM_CR1_CEN) != 0UL)
  2007. && ((base->ccer & TIM_CCER_CC1E) != 0UL)
  2008. && ((pair->ccer & TIM_CCER_CC1E) != 0UL)
  2009. && ((base->ccer & TIM_CCER_CC1P) != 0UL)
  2010. && ((pair->ccer & TIM_CCER_CC1P) != 0UL)
  2011. && ((base->ccmr1 & PLSR_TIMER_OC1_MODE_MASK)
  2012. == PLSR_TIMER_PWM1_MODE)
  2013. && ((pair->ccmr1 & PLSR_TIMER_OC1_MODE_MASK)
  2014. == PLSR_TIMER_PWM1_MODE)
  2015. && (base->arr == pair->arr)
  2016. && (base->ccr1 == pair->ccr1)
  2017. && (base->ccr1 == ((base->arr + 1UL) / 2UL))
  2018. && ((base->psc + 1UL) == 2UL * (pair->psc + 1UL))
  2019. && ((lagOutput == pulseOutput) || (lagOutput == pairOutput)))
  2020. ? 1U : 0U);
  2021. }
  2022. static uint8_t PlsrAbTimersAreRunnable(uint8_t pulseOutput,
  2023. TIM_TypeDef *baseTimer,
  2024. TIM_TypeDef *pairTimer)
  2025. {
  2026. uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
  2027. uint8_t lagOutput = PlsrAbLagAxis[pulseOutput];
  2028. uint32_t baseCr1 = baseTimer->CR1;
  2029. uint32_t pairCr1 = pairTimer->CR1;
  2030. uint32_t baseCcer = baseTimer->CCER;
  2031. uint32_t pairCcer = pairTimer->CCER;
  2032. uint32_t baseCcmr1 = baseTimer->CCMR1;
  2033. uint32_t pairCcmr1 = pairTimer->CCMR1;
  2034. uint32_t basePsc = baseTimer->PSC;
  2035. uint32_t pairPsc = pairTimer->PSC;
  2036. uint32_t baseCcr1 = baseTimer->CCR1;
  2037. uint32_t pairCcr1 = pairTimer->CCR1;
  2038. uint32_t baseArr = baseTimer->ARR;
  2039. uint32_t pairArr = pairTimer->ARR;
  2040. return (((((baseCr1 & TIM_CR1_CEN) != 0UL)
  2041. && ((pairCr1 & TIM_CR1_CEN) != 0UL)
  2042. && ((baseCcer & (TIM_CCER_CC1E | TIM_CCER_CC1P))
  2043. == (TIM_CCER_CC1E | TIM_CCER_CC1P))
  2044. && ((pairCcer & (TIM_CCER_CC1E | TIM_CCER_CC1P))
  2045. == (TIM_CCER_CC1E | TIM_CCER_CC1P))
  2046. && ((baseCcmr1 & PLSR_TIMER_OC1_MODE_MASK)
  2047. == PLSR_TIMER_PWM1_MODE)
  2048. && ((pairCcmr1 & PLSR_TIMER_OC1_MODE_MASK)
  2049. == PLSR_TIMER_PWM1_MODE)
  2050. && (baseArr == pairArr)
  2051. && (baseCcr1 == pairCcr1)
  2052. && (baseCcr1 == ((baseArr + 1UL) / 2UL))
  2053. && ((basePsc + 1UL) == 2UL * (pairPsc + 1UL))
  2054. && ((lagOutput == pulseOutput)
  2055. || (lagOutput == pairOutput))) ? 1U : 0U));
  2056. }
  2057. static uint8_t PlsrAbStopBoundaryIsReachable(
  2058. uint8_t pulseOutput,
  2059. TIM_TypeDef *baseTimer,
  2060. TIM_TypeDef *pairTimer)
  2061. {
  2062. uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
  2063. uint8_t lagOutput = PlsrAbLagAxis[pulseOutput];
  2064. uint32_t baseCr1 = baseTimer->CR1;
  2065. uint32_t pairCr1 = pairTimer->CR1;
  2066. uint32_t baseCcer = baseTimer->CCER;
  2067. uint32_t pairCcer = pairTimer->CCER;
  2068. uint32_t baseCcr1 = baseTimer->CCR1;
  2069. uint32_t pairCcr1 = pairTimer->CCR1;
  2070. uint32_t baseArr = baseTimer->ARR;
  2071. uint32_t pairArr = pairTimer->ARR;
  2072. return (((((baseCr1 & TIM_CR1_CEN) != 0UL)
  2073. && ((pairCr1 & TIM_CR1_CEN) != 0UL)
  2074. && ((baseCcer & TIM_CCER_CC1E) != 0UL)
  2075. && ((pairCcer & TIM_CCER_CC1E) != 0UL)
  2076. && (baseCcr1 <= baseArr)
  2077. && (pairCcr1 <= pairArr)
  2078. && ((lagOutput == pulseOutput)
  2079. || (lagOutput == pairOutput))) ? 1U : 0U));
  2080. }
  2081. static void PlsrAbFastGate(uint8_t pulseOutput)
  2082. {
  2083. uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
  2084. TIM_TypeDef *baseTimer = PlsrTimerMap[pulseOutput].timer;
  2085. TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
  2086. PlsrAbStructureVerified[pulseOutput] = 0U;
  2087. baseTimer->CR1 &= ~TIM_CR1_CEN;
  2088. pairTimer->CR1 &= ~TIM_CR1_CEN;
  2089. PlsrCounterSuspend(pulseOutput);
  2090. __DMB();
  2091. }
  2092. #if defined(__ICCARM__)
  2093. #pragma inline=never
  2094. #endif
  2095. static void PlsrAbEnableTimerPair(TIM_TypeDef *firstTimer,
  2096. uint32_t firstCr1,
  2097. TIM_TypeDef *secondTimer,
  2098. uint32_t secondCr1)
  2099. {
  2100. firstTimer->CR1 = firstCr1;
  2101. secondTimer->CR1 = secondCr1;
  2102. }
  2103. static uint8_t PlsrAbCanFastGateAtZero(uint8_t pulseOutput)
  2104. {
  2105. uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
  2106. TIM_TypeDef *baseTimer = PlsrTimerMap[pulseOutput].timer;
  2107. TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
  2108. uint32_t baseCr1 = baseTimer->CR1;
  2109. uint32_t pairCr1 = pairTimer->CR1;
  2110. uint32_t baseCcer = baseTimer->CCER;
  2111. uint32_t pairCcer = pairTimer->CCER;
  2112. uint32_t baseCcr = baseTimer->CCR1;
  2113. uint32_t pairCcr = pairTimer->CCR1;
  2114. uint32_t baseCnt = baseTimer->CNT;
  2115. uint32_t pairCnt = pairTimer->CNT;
  2116. return ((((baseCr1 & TIM_CR1_CEN) != 0UL)
  2117. && ((pairCr1 & TIM_CR1_CEN) != 0UL)
  2118. && ((baseCcer & TIM_CCER_CC1E) != 0UL)
  2119. && ((pairCcer & TIM_CCER_CC1E) != 0UL)
  2120. && (baseCnt >= baseCcr)
  2121. && (pairCnt >= pairCcr)) ? 1U : 0U);
  2122. }
  2123. static uint8_t PlsrCounterIndex(uint8_t pulseOutput, uint8_t outputMode)
  2124. {
  2125. return (outputMode == PLSR_OUTPUT_AB)
  2126. ? (uint8_t)(pulseOutput >> 1U)
  2127. : (uint8_t)(pulseOutput & 1U);
  2128. }
  2129. static uint64_t PlsrCounterCurrentRaw(uint8_t pulseOutput)
  2130. {
  2131. uint8_t index = PlsrCounterIndexByOutput[pulseOutput];
  2132. TIM_TypeDef *counter;
  2133. uint64_t overflowBefore;
  2134. uint64_t overflowAfter;
  2135. uint32_t statusBefore;
  2136. uint32_t statusAfter;
  2137. uint32_t count;
  2138. if (index >= PLSR_COUNTER_COUNT)
  2139. {
  2140. return 0UL;
  2141. }
  2142. counter = PlsrCounters[index];
  2143. for (;;)
  2144. {
  2145. overflowBefore = PlsrCounterOverflowPulses[index];
  2146. statusBefore = counter->SR & TIM_SR_UIF;
  2147. count = (uint16_t)counter->CNT;
  2148. statusAfter = counter->SR & TIM_SR_UIF;
  2149. overflowAfter = PlsrCounterOverflowPulses[index];
  2150. if ((overflowBefore == overflowAfter)
  2151. && (statusBefore == statusAfter))
  2152. {
  2153. if (statusAfter != 0UL)
  2154. {
  2155. overflowAfter += PLSR_COUNTER_BLOCK_PULSES;
  2156. }
  2157. return overflowAfter + count;
  2158. }
  2159. }
  2160. }
  2161. static uint64_t PlsrCounterSnapshot(uint8_t pulseOutput)
  2162. {
  2163. uint64_t current = PlsrCounterCurrentRaw(pulseOutput);
  2164. uint64_t observed;
  2165. if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  2166. && (current > 0UL))
  2167. {
  2168. uint8_t sourceAxis = PlsrAbCounterSourceAxis[pulseOutput];
  2169. uint8_t attempt;
  2170. for (attempt = 0U; attempt < 2U; attempt++)
  2171. {
  2172. uint64_t verified;
  2173. current = PlsrCounterCurrentRaw(pulseOutput);
  2174. if (sourceAxis <= 3U)
  2175. {
  2176. uint32_t sourceCount = PlsrTimerMap[sourceAxis].timer->CNT;
  2177. verified = PlsrCounterCurrentRaw(pulseOutput);
  2178. if (current == verified)
  2179. {
  2180. if ((sourceCount
  2181. < PlsrAbCounterBoundary[pulseOutput])
  2182. && (current > 0UL))
  2183. {
  2184. current--;
  2185. }
  2186. break;
  2187. }
  2188. current = verified;
  2189. }
  2190. }
  2191. }
  2192. observed = PlsrObservedPulseBase[pulseOutput] + current;
  2193. if (observed < PlsrObservedPulsePublished[pulseOutput])
  2194. {
  2195. observed = PlsrObservedPulsePublished[pulseOutput];
  2196. }
  2197. else
  2198. {
  2199. PlsrObservedPulsePublished[pulseOutput] = observed;
  2200. }
  2201. return observed;
  2202. }
  2203. static uint64_t PlsrCounterSnapshotStopped(uint8_t pulseOutput)
  2204. {
  2205. uint8_t index = PlsrCounterIndexByOutput[pulseOutput];
  2206. TIM_TypeDef *counter = PlsrCounters[index];
  2207. uint64_t current = PlsrCounterOverflowPulses[index];
  2208. uint64_t observed;
  2209. current += (uint16_t)counter->CNT;
  2210. if ((counter->SR & TIM_SR_UIF) != 0UL)
  2211. {
  2212. current += PLSR_COUNTER_BLOCK_PULSES;
  2213. }
  2214. if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  2215. && (current > 0UL))
  2216. {
  2217. uint8_t sourceAxis = PlsrAbCounterSourceAxis[pulseOutput];
  2218. if ((sourceAxis <= 3U)
  2219. && (PlsrTimerMap[sourceAxis].timer->CNT
  2220. < PlsrAbCounterBoundary[pulseOutput]))
  2221. {
  2222. current--;
  2223. }
  2224. }
  2225. observed = PlsrObservedPulseBase[pulseOutput] + current;
  2226. if (observed < PlsrObservedPulsePublished[pulseOutput])
  2227. {
  2228. observed = PlsrObservedPulsePublished[pulseOutput];
  2229. }
  2230. else
  2231. {
  2232. PlsrObservedPulsePublished[pulseOutput] = observed;
  2233. }
  2234. return observed;
  2235. }
  2236. static void PlsrCounterStop(uint8_t pulseOutput)
  2237. {
  2238. uint8_t index = PlsrCounterIndexByOutput[pulseOutput];
  2239. if (index < PLSR_COUNTER_COUNT)
  2240. {
  2241. TIM_TypeDef *counter = PlsrCounters[index];
  2242. if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  2243. && (PlsrAbFastGated[pulseOutput] != 0U))
  2244. {
  2245. PlsrObservedPulseBase[pulseOutput] =
  2246. PlsrCounterSnapshotStopped(pulseOutput);
  2247. }
  2248. else
  2249. {
  2250. PlsrCounterSuspend(pulseOutput);
  2251. PlsrObservedPulseBase[pulseOutput] =
  2252. PlsrCounterSnapshot(pulseOutput);
  2253. }
  2254. PlsrObservedPulsePublished[pulseOutput] =
  2255. PlsrObservedPulseBase[pulseOutput];
  2256. counter->CR1 = 0UL;
  2257. counter->DIER = 0UL;
  2258. counter->SMCR = 0UL;
  2259. counter->SR = 0UL;
  2260. if (PlsrCounterOwner[index] == pulseOutput)
  2261. {
  2262. PlsrCounterOwner[index] = PLSR_COUNTER_NONE;
  2263. }
  2264. }
  2265. PlsrCounterIndexByOutput[pulseOutput] = PLSR_COUNTER_NONE;
  2266. }
  2267. static uint8_t PlsrCounterConfigure(uint8_t pulseOutput, uint8_t outputMode)
  2268. {
  2269. uint8_t index = PlsrCounterIndex(pulseOutput, outputMode);
  2270. TIM_TypeDef *counter = PlsrCounters[index];
  2271. uint32_t triggerSelection = ((pulseOutput & 2U) == 0U)
  2272. ? TIM_SMCR_TS_1
  2273. : (TIM_SMCR_TS_1 | TIM_SMCR_TS_0);
  2274. PlsrCounterStop(pulseOutput);
  2275. if ((PlsrCounterOwner[index] != PLSR_COUNTER_NONE)
  2276. && (PlsrCounterOwner[index] != pulseOutput))
  2277. {
  2278. return 0U;
  2279. }
  2280. PlsrCounterOwner[index] = pulseOutput;
  2281. PlsrCounterIndexByOutput[pulseOutput] = index;
  2282. PlsrCounterOverflowPulses[index] = 0UL;
  2283. counter->CR1 = 0UL;
  2284. counter->DIER = 0UL;
  2285. counter->SMCR = 0UL;
  2286. counter->PSC = 0UL;
  2287. counter->ARR = 0xFFFFUL;
  2288. counter->CNT = 0UL;
  2289. counter->EGR = TIM_EGR_UG;
  2290. counter->SR = 0UL;
  2291. /* RM0090 table 101 routes TIM10/11/13/14 OC directly to ITR2/3. */
  2292. counter->SMCR = triggerSelection;
  2293. counter->DIER = TIM_DIER_UIE;
  2294. return 1U;
  2295. }
  2296. static void PlsrCounterBegin(uint8_t pulseOutput)
  2297. {
  2298. uint8_t index = PlsrCounterIndexByOutput[pulseOutput];
  2299. if (index < PLSR_COUNTER_COUNT)
  2300. {
  2301. TIM_TypeDef *counter = PlsrCounters[index];
  2302. counter->SMCR |= TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0;
  2303. counter->CR1 |= TIM_CR1_CEN;
  2304. }
  2305. }
  2306. static void PlsrCounterSuspend(uint8_t pulseOutput)
  2307. {
  2308. uint8_t index = PlsrCounterIndexByOutput[pulseOutput];
  2309. if (index < PLSR_COUNTER_COUNT)
  2310. {
  2311. PlsrCounters[index]->CR1 &= ~TIM_CR1_CEN;
  2312. PlsrCounters[index]->SMCR &=
  2313. ~(TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0);
  2314. }
  2315. }
  2316. static void PlsrAbLoadAndStart(uint8_t pulseOutput,
  2317. const PLSR_AB_SETTING *setting)
  2318. {
  2319. uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
  2320. uint8_t leadOutput =
  2321. (PlsrTimerDirectionPositive[pulseOutput] != 0U)
  2322. ? pulseOutput : pairOutput;
  2323. uint8_t lagOutput = (leadOutput == pulseOutput)
  2324. ? pairOutput : pulseOutput;
  2325. TIM_TypeDef *baseTimer = PlsrTimerMap[pulseOutput].timer;
  2326. TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
  2327. TIM_TypeDef *counterSourceTimer;
  2328. TIM_TypeDef *otherTimer;
  2329. uint32_t periodCounts = setting->period + 1UL;
  2330. uint32_t leadStart = (periodCounts * 3UL) / 4UL + 1UL;
  2331. uint32_t lagStart = periodCounts / 2UL + 1UL;
  2332. uint32_t counterSourceCr1;
  2333. uint32_t otherCr1;
  2334. #if PLSR_DEBUG_TIMING
  2335. uint8_t debugCounterIndex = PlsrCounterIndexByOutput[pulseOutput];
  2336. uint8_t debugReload = PlsrTimerRunning[pulseOutput];
  2337. if ((debugReload != 0U) && (debugCounterIndex < PLSR_COUNTER_COUNT))
  2338. {
  2339. PlsrAbReloadCounterBefore[pulseOutput] =
  2340. (uint16_t)PlsrCounters[debugCounterIndex]->CNT;
  2341. PlsrAbReloadCount[pulseOutput]++;
  2342. }
  2343. #endif
  2344. if (leadStart >= periodCounts)
  2345. {
  2346. leadStart = periodCounts - 1UL;
  2347. }
  2348. if (lagStart >= periodCounts)
  2349. {
  2350. lagStart = periodCounts - 1UL;
  2351. }
  2352. PlsrAbStructureVerified[pulseOutput] = 0U;
  2353. PlsrAbLagAxis[pulseOutput] = lagOutput;
  2354. PlsrAbCounterSourceAxis[pulseOutput] =
  2355. (pulseOutput == 0U) ? pulseOutput : pairOutput;
  2356. PlsrAbCounterBoundary[pulseOutput] =
  2357. (PlsrAbCounterSourceAxis[pulseOutput] == leadOutput)
  2358. ? (leadStart - 1UL) : (periodCounts / 2UL);
  2359. PlsrCounterSuspend(pulseOutput);
  2360. baseTimer->CR1 &= ~TIM_CR1_CEN;
  2361. pairTimer->CR1 &= ~TIM_CR1_CEN;
  2362. PlsrAbHoldPairIdle(pulseOutput);
  2363. baseTimer->CCER &= ~TIM_CCER_CC1E;
  2364. pairTimer->CCER &= ~TIM_CCER_CC1E;
  2365. baseTimer->DIER = 0UL;
  2366. pairTimer->DIER = 0UL;
  2367. baseTimer->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE;
  2368. pairTimer->CCMR1 = TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE;
  2369. baseTimer->PSC = setting->basePrescaler;
  2370. pairTimer->PSC = setting->pairPrescaler;
  2371. baseTimer->ARR = setting->period;
  2372. pairTimer->ARR = setting->period;
  2373. baseTimer->CCR1 = setting->compare;
  2374. pairTimer->CCR1 = setting->compare;
  2375. baseTimer->CR1 = TIM_CR1_ARPE | TIM_CR1_URS;
  2376. pairTimer->CR1 = TIM_CR1_ARPE | TIM_CR1_URS;
  2377. baseTimer->EGR = TIM_EGR_UG;
  2378. pairTimer->EGR = TIM_EGR_UG;
  2379. baseTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
  2380. pairTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
  2381. PlsrTimerMap[leadOutput].timer->CNT = leadStart;
  2382. PlsrTimerMap[lagOutput].timer->CNT = lagStart;
  2383. baseTimer->CCER = (baseTimer->CCER
  2384. & ~(TIM_CCER_CC1P | TIM_CCER_CC1E))
  2385. | TIM_CCER_CC1P | TIM_CCER_CC1E;
  2386. pairTimer->CCER = (pairTimer->CCER
  2387. & ~(TIM_CCER_CC1P | TIM_CCER_CC1E))
  2388. | TIM_CCER_CC1P | TIM_CCER_CC1E;
  2389. PlsrAbReleasePair(pulseOutput);
  2390. baseTimer->CCMR1 = TIM_CCMR1_OC1PE
  2391. | (6UL << TIM_CCMR1_OC1M_Pos);
  2392. pairTimer->CCMR1 = TIM_CCMR1_OC1PE
  2393. | (6UL << TIM_CCMR1_OC1M_Pos);
  2394. PlsrCounterBegin(pulseOutput);
  2395. #if PLSR_DEBUG_TIMING
  2396. if ((debugReload != 0U) && (debugCounterIndex < PLSR_COUNTER_COUNT))
  2397. {
  2398. PlsrAbReloadCounterArmed[pulseOutput] =
  2399. (uint16_t)PlsrCounters[debugCounterIndex]->CNT;
  2400. }
  2401. #endif
  2402. counterSourceTimer =
  2403. PlsrTimerMap[PlsrAbCounterSourceAxis[pulseOutput]].timer;
  2404. otherTimer =
  2405. PlsrTimerMap[(PlsrAbCounterSourceAxis[pulseOutput] == pulseOutput)
  2406. ? pairOutput : pulseOutput].timer;
  2407. counterSourceCr1 = counterSourceTimer->CR1 | TIM_CR1_CEN;
  2408. otherCr1 = otherTimer->CR1 | TIM_CR1_CEN;
  2409. PlsrAbEnableTimerPair(counterSourceTimer, counterSourceCr1,
  2410. otherTimer, otherCr1);
  2411. #if PLSR_DEBUG_TIMING
  2412. if ((debugReload != 0U) && (debugCounterIndex < PLSR_COUNTER_COUNT))
  2413. {
  2414. __DSB();
  2415. PlsrAbReloadCounterStarted[pulseOutput] =
  2416. (uint16_t)PlsrCounters[debugCounterIndex]->CNT;
  2417. }
  2418. #endif
  2419. baseTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
  2420. pairTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
  2421. PlsrTimerMap[lagOutput].timer->DIER |= TIM_DIER_CC1IE;
  2422. __DMB();
  2423. }
  2424. static void PlsrAbScheduleFrequencyVerify(uint8_t pulseOutput)
  2425. {
  2426. uint8_t verifyOutput =
  2427. (PlsrAbLagAxis[pulseOutput] == pulseOutput)
  2428. ? (uint8_t)(pulseOutput + 1U) : pulseOutput;
  2429. TIM_TypeDef *verifyTimer = PlsrTimerMap[verifyOutput].timer;
  2430. PlsrFrequencyVerifyPending[pulseOutput] =
  2431. PLSR_FREQUENCY_VERIFY_AB_AUX_IRQ;
  2432. PlsrAbVerifyOwner[verifyOutput] = pulseOutput;
  2433. verifyTimer->SR = ~TIM_SR_UIF;
  2434. verifyTimer->DIER |= TIM_DIER_UIE;
  2435. if (PlsrDeferredPulsePending[pulseOutput] != 0U)
  2436. {
  2437. verifyTimer->SR = ~TIM_SR_CC1IF;
  2438. verifyTimer->DIER |= TIM_DIER_CC1IE;
  2439. }
  2440. __DMB();
  2441. }
  2442. static uint32_t PlsrFrequencyFromSnapshot(
  2443. uint8_t pulseOutput,
  2444. const PLSR_TIMER_SNAPSHOT *snapshot)
  2445. {
  2446. uint64_t divider = ((uint64_t)snapshot->psc + 1UL)
  2447. * ((uint64_t)snapshot->arr + 1UL);
  2448. if (divider == 0UL)
  2449. {
  2450. return 0UL;
  2451. }
  2452. return (uint32_t)(((uint64_t)PlsrTimerMap[pulseOutput].timerClockHz
  2453. + divider / 2UL)
  2454. / divider);
  2455. }
  2456. static uint32_t PlsrVerifyActiveFrequency(uint8_t pulseOutput)
  2457. {
  2458. TIM_TypeDef *baseTimer = PlsrTimerMap[pulseOutput].timer;
  2459. PLSR_TIMER_SNAPSHOT baseSnapshot;
  2460. uint32_t activeFrequency = PlsrTimerActiveFrequencyHz[pulseOutput];
  2461. PlsrTimerSnapshot(baseTimer, &baseSnapshot);
  2462. if (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  2463. {
  2464. uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
  2465. TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
  2466. PLSR_TIMER_SNAPSHOT pairSnapshot;
  2467. uint8_t structureValid;
  2468. PlsrTimerSnapshot(pairTimer, &pairSnapshot);
  2469. structureValid = PlsrAbStructureIsRunnable(
  2470. pulseOutput, &baseSnapshot, &pairSnapshot);
  2471. PlsrAbStructureVerified[pulseOutput] = structureValid;
  2472. if (structureValid == 0U)
  2473. {
  2474. PlsrPlatformFaultPending = PLSR_PLATFORM_FAULT_CURVE;
  2475. }
  2476. if ((baseSnapshot.psc
  2477. != PlsrAbActiveSetting[pulseOutput].basePrescaler)
  2478. || (pairSnapshot.psc
  2479. != PlsrAbActiveSetting[pulseOutput].pairPrescaler)
  2480. || (baseSnapshot.arr
  2481. != PlsrAbActiveSetting[pulseOutput].period)
  2482. || (pairSnapshot.arr
  2483. != PlsrAbActiveSetting[pulseOutput].period)
  2484. || (baseSnapshot.ccr1
  2485. != PlsrAbActiveSetting[pulseOutput].compare)
  2486. || (pairSnapshot.ccr1
  2487. != PlsrAbActiveSetting[pulseOutput].compare))
  2488. {
  2489. activeFrequency = PlsrFrequencyFromSnapshot(pairOutput,
  2490. &pairSnapshot);
  2491. if (PlsrPlatformFaultPending != PLSR_PLATFORM_FAULT_CURVE)
  2492. {
  2493. PlsrPlatformFaultPending = PLSR_PLATFORM_FAULT_FREQUENCY;
  2494. }
  2495. }
  2496. }
  2497. else
  2498. {
  2499. uint8_t structureValid =
  2500. ((((baseSnapshot.cr1 & TIM_CR1_CEN) != 0UL)
  2501. && ((baseSnapshot.ccer & TIM_CCER_CC1E) != 0UL)
  2502. && ((baseSnapshot.ccer & TIM_CCER_CC1P) == 0UL)
  2503. && ((baseSnapshot.ccmr1 & PLSR_TIMER_OC1_MODE_MASK)
  2504. == PLSR_TIMER_PWM1_MODE)
  2505. && (baseSnapshot.ccr1
  2506. == ((baseSnapshot.arr + 1UL) / 2UL)))
  2507. ? 1U : 0U);
  2508. if (structureValid == 0U)
  2509. {
  2510. PlsrPlatformFaultPending = PLSR_PLATFORM_FAULT_CURVE;
  2511. }
  2512. if ((baseSnapshot.psc
  2513. != PlsrTimerQueuedSetting[pulseOutput].prescaler)
  2514. || (baseSnapshot.arr
  2515. != PlsrTimerQueuedSetting[pulseOutput].period)
  2516. || (baseSnapshot.ccr1
  2517. != PlsrTimerQueuedSetting[pulseOutput].compare))
  2518. {
  2519. activeFrequency = PlsrFrequencyFromSnapshot(pulseOutput,
  2520. &baseSnapshot);
  2521. if (PlsrPlatformFaultPending != PLSR_PLATFORM_FAULT_CURVE)
  2522. {
  2523. PlsrPlatformFaultPending = PLSR_PLATFORM_FAULT_FREQUENCY;
  2524. }
  2525. }
  2526. }
  2527. if (activeFrequency == 0UL)
  2528. {
  2529. PlsrPlatformFaultPending = PLSR_PLATFORM_FAULT_FREQUENCY;
  2530. }
  2531. return activeFrequency;
  2532. }
  2533. uint8_t PlsrPlatformInit(void)
  2534. {
  2535. GPIO_InitTypeDef gpio;
  2536. uint8_t index;
  2537. const PLSR_BACKUP_POSITION_RECORD *positionRecord;
  2538. PlsrFlashReserveEraseState = PLSR_FLASH_ERASE_NONE;
  2539. __HAL_RCC_GPIOB_CLK_ENABLE();
  2540. __HAL_RCC_GPIOF_CLK_ENABLE();
  2541. __HAL_RCC_GPIOG_CLK_ENABLE();
  2542. __HAL_RCC_GPIOH_CLK_ENABLE();
  2543. __HAL_RCC_SYSCFG_CLK_ENABLE();
  2544. __HAL_RCC_TIM10_CLK_ENABLE();
  2545. __HAL_RCC_TIM11_CLK_ENABLE();
  2546. __HAL_RCC_TIM13_CLK_ENABLE();
  2547. __HAL_RCC_TIM14_CLK_ENABLE();
  2548. __HAL_RCC_TIM9_CLK_ENABLE();
  2549. __HAL_RCC_TIM12_CLK_ENABLE();
  2550. __HAL_RCC_PWR_CLK_ENABLE();
  2551. HAL_PWR_EnableBkUpAccess();
  2552. __HAL_RCC_BKPSRAM_CLK_ENABLE();
  2553. if (HAL_PWREx_EnableBkUpReg() != HAL_OK)
  2554. {
  2555. return 0U;
  2556. }
  2557. #if PLSR_DEBUG_TIMING
  2558. CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  2559. DWT->CYCCNT = 0UL;
  2560. DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
  2561. (void)memset((void *)PlsrIrqCount, 0, sizeof(PlsrIrqCount));
  2562. (void)memset((void *)PlsrIrqLastCycles, 0, sizeof(PlsrIrqLastCycles));
  2563. (void)memset((void *)PlsrIrqMaxCycles, 0, sizeof(PlsrIrqMaxCycles));
  2564. (void)memset((void *)PlsrFinalArmQueueCount, 0,
  2565. sizeof(PlsrFinalArmQueueCount));
  2566. (void)memset((void *)PlsrFinalArmJobLastCycles, 0,
  2567. sizeof(PlsrFinalArmJobLastCycles));
  2568. (void)memset((void *)PlsrFinalArmJobMaxCycles, 0,
  2569. sizeof(PlsrFinalArmJobMaxCycles));
  2570. (void)memset((void *)PlsrFinalArmQueueToStopLastCycles, 0,
  2571. sizeof(PlsrFinalArmQueueToStopLastCycles));
  2572. (void)memset((void *)PlsrFinalArmQueueToStopMaxCycles, 0,
  2573. sizeof(PlsrFinalArmQueueToStopMaxCycles));
  2574. (void)memset((void *)PlsrFinalArmQueuedAt, 0,
  2575. sizeof(PlsrFinalArmQueuedAt));
  2576. (void)memset((void *)PlsrFinalArmQueueTimingPending, 0,
  2577. sizeof(PlsrFinalArmQueueTimingPending));
  2578. #endif
  2579. HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8
  2580. | GPIO_PIN_9, GPIO_PIN_SET);
  2581. gpio.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9;
  2582. gpio.Mode = GPIO_MODE_OUTPUT_PP;
  2583. gpio.Pull = GPIO_NOPULL;
  2584. gpio.Speed = GPIO_SPEED_FREQ_HIGH;
  2585. gpio.Alternate = 0U;
  2586. HAL_GPIO_Init(GPIOH, &gpio);
  2587. gpio.Mode = GPIO_MODE_IT_RISING;
  2588. gpio.Pull = GPIO_NOPULL;
  2589. gpio.Speed = GPIO_SPEED_FREQ_LOW;
  2590. gpio.Alternate = 0U;
  2591. gpio.Pin = GPIO_PIN_5;
  2592. HAL_GPIO_Init(GPIOB, &gpio);
  2593. gpio.Pin = GPIO_PIN_12;
  2594. HAL_GPIO_Init(GPIOG, &gpio);
  2595. __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_5 | GPIO_PIN_12);
  2596. HAL_NVIC_SetPriority(EXTI9_5_IRQn, 2U, 0U);
  2597. HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
  2598. HAL_NVIC_SetPriority(EXTI15_10_IRQn, 2U, 0U);
  2599. HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
  2600. for (index = 0U; index < 4U; index++)
  2601. {
  2602. PlsrTimerActiveFrequencyHz[index] = 0UL;
  2603. PlsrTimerQueuedFrequencyHz[index] = 0UL;
  2604. (void)memset(&PlsrTimerActiveSetting[index], 0,
  2605. sizeof(PlsrTimerActiveSetting[index]));
  2606. (void)memset(&PlsrTimerQueuedSetting[index], 0,
  2607. sizeof(PlsrTimerQueuedSetting[index]));
  2608. PlsrTimerQueueGeneration[index] = 0UL;
  2609. PlsrTimerOutputMode[index] = PLSR_OUTPUT_PULSE_DIR;
  2610. PlsrTimerDirectionPositive[index] = 1U;
  2611. PlsrTimerRunning[index] = 0U;
  2612. PlsrFrequencyVerifyPending[index] = 0U;
  2613. PlsrFrequencyVerifyPulseCount[index] = 0U;
  2614. PlsrDeferredPulsePending[index] = 0U;
  2615. PlsrAbVerifyOwner[index] = PLSR_COUNTER_NONE;
  2616. PlsrAbFinalArmJobOwner[index] = PLSR_COUNTER_NONE;
  2617. PlsrTimerIrqActive[index] = 0U;
  2618. PlsrAbFrequencyPending[index] = 0U;
  2619. PlsrAbLagAxis[index] = PLSR_COUNTER_NONE;
  2620. PlsrAbStructureVerified[index] = 0U;
  2621. PlsrAbCounterSourceAxis[index] = PLSR_COUNTER_NONE;
  2622. PlsrAbCounterBoundary[index] = 0UL;
  2623. PlsrAbStopPending[index] = 0U;
  2624. PlsrAbFastGated[index] = 0U;
  2625. PlsrCounterIndexByOutput[index] = PLSR_COUNTER_NONE;
  2626. PlsrObservedPulseBase[index] = 0UL;
  2627. PlsrObservedPulsePublished[index] = 0UL;
  2628. PlsrFiniteActive[index] = 0U;
  2629. PlsrFiniteCompletionPending[index] = 0U;
  2630. PlsrFiniteFrequencyPending[index] = 0U;
  2631. PlsrFiniteRetargetPending[index] = 0U;
  2632. PlsrFiniteTailStopPending[index] = 0U;
  2633. PlsrFiniteRetargetDrainPulses[index] = 0UL;
  2634. PlsrFiniteTargetPulses[index] = 0UL;
  2635. PlsrFiniteRemainingPulses[index] = 0UL;
  2636. PlsrFiniteCounterPreload[index] = 0U;
  2637. PlsrFiniteStepCount[index] = 0U;
  2638. PlsrFiniteStepIndex[index] = 0U;
  2639. PlsrFiniteBoundaryReadIndex[index] = 0U;
  2640. PlsrFiniteCompletedStepCount[index] = 0U;
  2641. PlsrTimerInitialize(PlsrTimerMap[index].timer);
  2642. PlsrPulsePinHoldIdle(index);
  2643. HAL_NVIC_SetPriority(PlsrTimerMap[index].irq, 0U, 0U);
  2644. HAL_NVIC_EnableIRQ(PlsrTimerMap[index].irq);
  2645. }
  2646. for (index = 0U; index < PLSR_COUNTER_COUNT; index++)
  2647. {
  2648. PlsrCounterOwner[index] = PLSR_COUNTER_NONE;
  2649. PlsrCounterOverflowPulses[index] = 0UL;
  2650. PlsrCounters[index]->CR1 = 0UL;
  2651. PlsrCounters[index]->DIER = 0UL;
  2652. PlsrCounters[index]->SMCR = 0UL;
  2653. PlsrCounters[index]->SR = 0UL;
  2654. }
  2655. PlsrPlatformFaultPending = 0U;
  2656. HAL_NVIC_SetPriority(TIM1_BRK_TIM9_IRQn, 0U, 0U);
  2657. HAL_NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn);
  2658. HAL_NVIC_SetPriority(TIM8_BRK_TIM12_IRQn, 0U, 0U);
  2659. HAL_NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn);
  2660. positionRecord = PlsrNewestBackupPosition();
  2661. PlsrBackupPositionGeneration =
  2662. (positionRecord == NULL) ? 0UL : positionRecord->generation;
  2663. return 1U;
  2664. }
  2665. uint8_t PlsrPlatformPrepare(uint8_t pulseOutput,
  2666. uint8_t directionOutput,
  2667. uint8_t directionLevel,
  2668. uint8_t outputMode,
  2669. uint8_t directionPositive)
  2670. {
  2671. uint8_t index;
  2672. if ((pulseOutput > 3U) || (directionOutput > 3U)
  2673. || (outputMode > PLSR_OUTPUT_AB)
  2674. || ((outputMode == PLSR_OUTPUT_AB)
  2675. && (pulseOutput != 0U) && (pulseOutput != 2U)))
  2676. {
  2677. return 0U;
  2678. }
  2679. if ((PlsrAbStopPending[0] != 0U) || (PlsrAbStopPending[2] != 0U))
  2680. {
  2681. return 0U;
  2682. }
  2683. for (index = 0U; index < 4U; index++)
  2684. {
  2685. PlsrAbFinalArmJobOwner[index] = PLSR_COUNTER_NONE;
  2686. NVIC_ClearPendingIRQ(PlsrTimerMap[index].irq);
  2687. PlsrCounterStop(index);
  2688. PlsrPulsePinHoldIdle(index);
  2689. PlsrTimerStop(PlsrTimerMap[index].timer);
  2690. HAL_GPIO_WritePin(PlsrDirectionMap[index].port,
  2691. PlsrDirectionMap[index].pin,
  2692. ((outputMode == PLSR_OUTPUT_PULSE_DIR)
  2693. && (index == directionOutput)
  2694. && (directionLevel != 0U))
  2695. ? GPIO_PIN_RESET : GPIO_PIN_SET);
  2696. PlsrTimerRunning[index] = 0U;
  2697. PlsrFrequencyVerifyPending[index] = 0U;
  2698. PlsrFrequencyVerifyPulseCount[index] = 0U;
  2699. PlsrDeferredPulsePending[index] = 0U;
  2700. PlsrAbVerifyOwner[index] = PLSR_COUNTER_NONE;
  2701. PlsrAbFrequencyPending[index] = 0U;
  2702. PlsrAbStructureVerified[index] = 0U;
  2703. PlsrAbFastGated[index] = 0U;
  2704. }
  2705. PlsrTimerOutputMode[pulseOutput] = outputMode;
  2706. PlsrTimerDirectionPositive[pulseOutput] =
  2707. (directionPositive != 0U) ? 1U : 0U;
  2708. PlsrPlatformFaultPending = 0U;
  2709. return 1U;
  2710. }
  2711. uint8_t PlsrPlatformStartPulse(uint8_t pulseOutput,
  2712. uint32_t firstFrequencyHz,
  2713. uint32_t queuedFrequencyHz,
  2714. uint32_t *actualFirstFrequencyHz,
  2715. uint32_t *actualQueuedFrequencyHz)
  2716. {
  2717. PLSR_PLATFORM_TIMER_SETTING firstSetting;
  2718. PLSR_PLATFORM_TIMER_SETTING queuedSetting;
  2719. if ((pulseOutput > 3U)
  2720. || (PlsrPlatformBuildTimerSetting(
  2721. pulseOutput, PlsrTimerOutputMode[pulseOutput],
  2722. firstFrequencyHz, &firstSetting) == 0U)
  2723. || (PlsrPlatformBuildTimerSetting(
  2724. pulseOutput, PlsrTimerOutputMode[pulseOutput],
  2725. queuedFrequencyHz, &queuedSetting) == 0U))
  2726. {
  2727. return 0U;
  2728. }
  2729. return PlsrPlatformStartPrepared(pulseOutput, &firstSetting,
  2730. &queuedSetting,
  2731. actualFirstFrequencyHz,
  2732. actualQueuedFrequencyHz);
  2733. }
  2734. static uint8_t PlsrPreparedSettingIsValid(
  2735. uint8_t pulseOutput,
  2736. uint8_t outputMode,
  2737. const PLSR_PLATFORM_TIMER_SETTING *setting)
  2738. {
  2739. uint32_t periodCounts;
  2740. if ((pulseOutput > 3U) || (setting == NULL)
  2741. || (setting->actualFrequencyHz == 0UL)
  2742. || (setting->actualFrequencyHz > PLSR_FREQUENCY_MAX_HZ))
  2743. {
  2744. return 0U;
  2745. }
  2746. periodCounts = (uint32_t)setting->period + 1UL;
  2747. if (setting->compare != (uint16_t)(periodCounts / 2UL))
  2748. {
  2749. return 0U;
  2750. }
  2751. if (outputMode == PLSR_OUTPUT_PULSE_DIR)
  2752. {
  2753. return ((periodCounts >= 2UL)
  2754. && (setting->pairPrescaler == 0U)) ? 1U : 0U;
  2755. }
  2756. if ((outputMode != PLSR_OUTPUT_AB) || ((pulseOutput & 1U) != 0U)
  2757. || (periodCounts < 4UL))
  2758. {
  2759. return 0U;
  2760. }
  2761. return ((((uint32_t)setting->prescaler + 1UL)
  2762. == 2UL * ((uint32_t)setting->pairPrescaler + 1UL))
  2763. ? 1U : 0U);
  2764. }
  2765. static void PlsrPlatformToTimerSetting(
  2766. const PLSR_PLATFORM_TIMER_SETTING *source,
  2767. PLSR_TIMER_SETTING *destination)
  2768. {
  2769. destination->prescaler = source->prescaler;
  2770. destination->period = source->period;
  2771. destination->compare = source->compare;
  2772. destination->actualFrequencyHz = source->actualFrequencyHz;
  2773. }
  2774. static void PlsrPlatformToAbSetting(
  2775. const PLSR_PLATFORM_TIMER_SETTING *source,
  2776. PLSR_AB_SETTING *destination)
  2777. {
  2778. destination->basePrescaler = source->prescaler;
  2779. destination->pairPrescaler = source->pairPrescaler;
  2780. destination->period = source->period;
  2781. destination->compare = source->compare;
  2782. destination->actualFrequencyHz = source->actualFrequencyHz;
  2783. }
  2784. static uint8_t PlsrPlatformSettingsDiffer(
  2785. const PLSR_PLATFORM_TIMER_SETTING *first,
  2786. const PLSR_PLATFORM_TIMER_SETTING *second)
  2787. {
  2788. return (((first->actualFrequencyHz != second->actualFrequencyHz)
  2789. || (first->prescaler != second->prescaler)
  2790. || (first->pairPrescaler != second->pairPrescaler)
  2791. || (first->period != second->period)
  2792. || (first->compare != second->compare)) ? 1U : 0U);
  2793. }
  2794. uint8_t PlsrPlatformBuildTimerSetting(
  2795. uint8_t pulseOutput,
  2796. uint8_t outputMode,
  2797. uint32_t requestedFrequencyHz,
  2798. PLSR_PLATFORM_TIMER_SETTING *setting)
  2799. {
  2800. PLSR_TIMER_SETTING timerSetting;
  2801. PLSR_AB_SETTING abSetting;
  2802. if (setting == NULL)
  2803. {
  2804. return 0U;
  2805. }
  2806. if (outputMode == PLSR_OUTPUT_AB)
  2807. {
  2808. if (PlsrAbCalculate(pulseOutput, requestedFrequencyHz,
  2809. &abSetting) == 0U)
  2810. {
  2811. return 0U;
  2812. }
  2813. setting->actualFrequencyHz = abSetting.actualFrequencyHz;
  2814. setting->prescaler = (uint16_t)abSetting.basePrescaler;
  2815. setting->pairPrescaler = (uint16_t)abSetting.pairPrescaler;
  2816. setting->period = (uint16_t)abSetting.period;
  2817. setting->compare = (uint16_t)abSetting.compare;
  2818. return 1U;
  2819. }
  2820. if ((outputMode != PLSR_OUTPUT_PULSE_DIR)
  2821. || (PlsrTimerCalculate(pulseOutput, requestedFrequencyHz,
  2822. &timerSetting) == 0U))
  2823. {
  2824. return 0U;
  2825. }
  2826. setting->actualFrequencyHz = timerSetting.actualFrequencyHz;
  2827. setting->prescaler = (uint16_t)timerSetting.prescaler;
  2828. setting->pairPrescaler = 0U;
  2829. setting->period = (uint16_t)timerSetting.period;
  2830. setting->compare = (uint16_t)timerSetting.compare;
  2831. return 1U;
  2832. }
  2833. uint8_t PlsrPlatformStartPrepared(
  2834. uint8_t pulseOutput,
  2835. const PLSR_PLATFORM_TIMER_SETTING *firstSetting,
  2836. const PLSR_PLATFORM_TIMER_SETTING *queuedSetting,
  2837. uint32_t *actualFirstFrequencyHz,
  2838. uint32_t *actualQueuedFrequencyHz)
  2839. {
  2840. uint8_t outputMode;
  2841. if ((pulseOutput > 3U) || (actualFirstFrequencyHz == NULL)
  2842. || (actualQueuedFrequencyHz == NULL))
  2843. {
  2844. return 0U;
  2845. }
  2846. outputMode = PlsrTimerOutputMode[pulseOutput];
  2847. if ((PlsrPreparedSettingIsValid(pulseOutput, outputMode,
  2848. firstSetting) == 0U)
  2849. || (PlsrPreparedSettingIsValid(pulseOutput, outputMode,
  2850. queuedSetting) == 0U))
  2851. {
  2852. return 0U;
  2853. }
  2854. if (outputMode == PLSR_OUTPUT_AB)
  2855. {
  2856. PLSR_AB_SETTING firstAbSetting;
  2857. PLSR_AB_SETTING queuedAbSetting;
  2858. if ((PlsrAbStopPending[pulseOutput] != 0U)
  2859. || (PlsrAbFastGated[pulseOutput] != 0U)
  2860. || (PlsrCounterConfigure(pulseOutput, PLSR_OUTPUT_AB) == 0U))
  2861. {
  2862. return 0U;
  2863. }
  2864. PlsrPlatformToAbSetting(firstSetting, &firstAbSetting);
  2865. PlsrPlatformToAbSetting(queuedSetting, &queuedAbSetting);
  2866. PlsrAbLoadAndStart(pulseOutput, &firstAbSetting);
  2867. PlsrAbActiveSetting[pulseOutput] = firstAbSetting;
  2868. PlsrAbPendingSetting[pulseOutput] = queuedAbSetting;
  2869. PlsrAbFrequencyPending[pulseOutput] =
  2870. ((firstSetting->prescaler != queuedSetting->prescaler)
  2871. || (firstSetting->pairPrescaler
  2872. != queuedSetting->pairPrescaler)
  2873. || (firstSetting->period != queuedSetting->period)) ? 1U : 0U;
  2874. }
  2875. else
  2876. {
  2877. TIM_TypeDef *timer = PlsrTimerMap[pulseOutput].timer;
  2878. PLSR_TIMER_SETTING firstTimerSetting;
  2879. PLSR_TIMER_SETTING queuedTimerSetting;
  2880. if (PlsrCounterConfigure(pulseOutput,
  2881. PLSR_OUTPUT_PULSE_DIR) == 0U)
  2882. {
  2883. return 0U;
  2884. }
  2885. PlsrPlatformToTimerSetting(firstSetting, &firstTimerSetting);
  2886. PlsrPlatformToTimerSetting(queuedSetting, &queuedTimerSetting);
  2887. timer->DIER &= ~TIM_DIER_UIE;
  2888. timer->CR1 &= ~TIM_CR1_CEN;
  2889. timer->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
  2890. timer->CNT = 0UL;
  2891. PlsrTimerWriteSetting(timer, &firstTimerSetting);
  2892. timer->EGR = TIM_EGR_UG;
  2893. PlsrTimerWriteSetting(timer, &queuedTimerSetting);
  2894. timer->CNT = firstTimerSetting.compare;
  2895. timer->SR = 0UL;
  2896. timer->CCER = (timer->CCER
  2897. & ~(TIM_CCER_CC1E | TIM_CCER_CC1P))
  2898. | TIM_CCER_CC1E;
  2899. __DSB();
  2900. timer->DIER |= TIM_DIER_UIE;
  2901. PlsrPulsePinRelease(pulseOutput);
  2902. PlsrCounterBegin(pulseOutput);
  2903. timer->CR1 |= TIM_CR1_CEN;
  2904. }
  2905. PlsrTimerActiveSetting[pulseOutput] = *firstSetting;
  2906. PlsrTimerQueuedSetting[pulseOutput] = *queuedSetting;
  2907. PlsrTimerActiveFrequencyHz[pulseOutput] =
  2908. firstSetting->actualFrequencyHz;
  2909. PlsrTimerQueuedFrequencyHz[pulseOutput] =
  2910. queuedSetting->actualFrequencyHz;
  2911. PlsrTimerQueueGeneration[pulseOutput]++;
  2912. PlsrTimerRunning[pulseOutput] = 1U;
  2913. if (outputMode == PLSR_OUTPUT_AB)
  2914. {
  2915. PlsrAbScheduleFrequencyVerify(pulseOutput);
  2916. }
  2917. else
  2918. {
  2919. PlsrFrequencyVerifyPending[pulseOutput] =
  2920. PLSR_FREQUENCY_VERIFY_NOW;
  2921. }
  2922. PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
  2923. *actualFirstFrequencyHz = firstSetting->actualFrequencyHz;
  2924. *actualQueuedFrequencyHz = queuedSetting->actualFrequencyHz;
  2925. return 1U;
  2926. }
  2927. uint8_t PlsrPlatformSupportsFinitePulseTrain(void)
  2928. {
  2929. return 1U;
  2930. }
  2931. uint8_t PlsrPlatformStartFinitePrepared(
  2932. uint8_t pulseOutput,
  2933. const PLSR_PLATFORM_TIMER_SETTING *setting,
  2934. uint32_t pulseCount,
  2935. uint32_t *actualFrequencyHz)
  2936. {
  2937. TIM_TypeDef *timer;
  2938. TIM_TypeDef *counter;
  2939. PLSR_TIMER_SETTING timerSetting;
  2940. uint32_t firstBlock;
  2941. uint8_t counterIndex;
  2942. if ((pulseOutput > 3U) || (setting == NULL)
  2943. || (pulseCount == 0UL) || (actualFrequencyHz == NULL)
  2944. || (PlsrTimerOutputMode[pulseOutput] != PLSR_OUTPUT_PULSE_DIR)
  2945. || (PlsrPreparedSettingIsValid(pulseOutput,
  2946. PLSR_OUTPUT_PULSE_DIR,
  2947. setting) == 0U)
  2948. || (PlsrCounterConfigure(pulseOutput,
  2949. PLSR_OUTPUT_PULSE_DIR) == 0U))
  2950. {
  2951. return 0U;
  2952. }
  2953. timer = PlsrTimerMap[pulseOutput].timer;
  2954. counterIndex = PlsrCounterIndexByOutput[pulseOutput];
  2955. counter = PlsrCounters[counterIndex];
  2956. firstBlock = (pulseCount > PLSR_COUNTER_BLOCK_PULSES)
  2957. ? PLSR_COUNTER_BLOCK_PULSES : pulseCount;
  2958. PlsrPlatformToTimerSetting(setting, &timerSetting);
  2959. counter->CR1 &= ~TIM_CR1_CEN;
  2960. counter->SMCR &= ~(TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0);
  2961. counter->ARR = (firstBlock == 1UL) ? 1UL : (firstBlock - 1UL);
  2962. counter->CNT = 0UL;
  2963. counter->EGR = TIM_EGR_UG;
  2964. PlsrFiniteCounterPreload[pulseOutput] =
  2965. (firstBlock == 1UL) ? 1U : 0U;
  2966. counter->CNT = PlsrFiniteCounterPreload[pulseOutput];
  2967. counter->SR = 0UL;
  2968. counter->DIER = TIM_DIER_UIE;
  2969. timer->DIER = 0UL;
  2970. timer->CR1 &= ~TIM_CR1_CEN;
  2971. timer->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
  2972. timer->CNT = 0UL;
  2973. PlsrTimerWriteSetting(timer, &timerSetting);
  2974. timer->EGR = TIM_EGR_UG;
  2975. /*
  2976. * The board's high-speed output stage is active low. Keep OC1 high
  2977. * while the pin changes from GPIO idle to the timer alternate function,
  2978. * then let the first terminal pulse start at CCR1. Starting at CCR1
  2979. * would expose an uncounted terminal pulse before the first OC rising
  2980. * edge reaches TIM9/TIM12.
  2981. */
  2982. timer->CNT = 0UL;
  2983. timer->SR = 0UL;
  2984. timer->CCER = (timer->CCER
  2985. & ~(TIM_CCER_CC1E | TIM_CCER_CC1P))
  2986. | TIM_CCER_CC1E;
  2987. PlsrFiniteTargetPulses[pulseOutput] = pulseCount;
  2988. PlsrFiniteRemainingPulses[pulseOutput] = pulseCount;
  2989. PlsrFiniteCompletionPending[pulseOutput] = 0U;
  2990. PlsrFiniteFrequencyPending[pulseOutput] = 0U;
  2991. PlsrFiniteStreamActive[pulseOutput] = 0U;
  2992. PlsrFiniteStreamNextValid[pulseOutput] = 0U;
  2993. PlsrFiniteStreamSourceDone[pulseOutput] = 0U;
  2994. PlsrFiniteStreamSourceFault[pulseOutput] = 0U;
  2995. PlsrFiniteActive[pulseOutput] = 1U;
  2996. PlsrFiniteStepCount[pulseOutput] = 0U;
  2997. PlsrFiniteStepIndex[pulseOutput] = 0U;
  2998. PlsrFiniteBoundaryReadIndex[pulseOutput] = 0U;
  2999. PlsrFiniteCompletedStepCount[pulseOutput] = 0U;
  3000. PlsrTimerActiveSetting[pulseOutput] = *setting;
  3001. PlsrTimerQueuedSetting[pulseOutput] = *setting;
  3002. PlsrTimerActiveFrequencyHz[pulseOutput] = setting->actualFrequencyHz;
  3003. PlsrTimerQueuedFrequencyHz[pulseOutput] = setting->actualFrequencyHz;
  3004. PlsrTimerRunning[pulseOutput] = 1U;
  3005. *actualFrequencyHz = setting->actualFrequencyHz;
  3006. __DSB();
  3007. PlsrPulsePinRelease(pulseOutput);
  3008. PlsrCounterBegin(pulseOutput);
  3009. timer->CR1 |= TIM_CR1_CEN;
  3010. return 1U;
  3011. }
  3012. uint8_t PlsrPlatformStartCountedStreamPrepared(
  3013. uint8_t pulseOutput,
  3014. const PLSR_PLATFORM_TIMER_SETTING *setting,
  3015. uint32_t pulseCount,
  3016. uint32_t *actualFrequencyHz)
  3017. {
  3018. TIM_TypeDef *counter;
  3019. uint32_t firstBlock;
  3020. if (PlsrPlatformStartFinitePrepared(pulseOutput, setting, pulseCount,
  3021. actualFrequencyHz) == 0U)
  3022. {
  3023. return 0U;
  3024. }
  3025. PlsrFiniteStreamActive[pulseOutput] = 1U;
  3026. PlsrFiniteStreamNextValid[pulseOutput] = 0U;
  3027. PlsrFiniteStreamNextStartsSegment[pulseOutput] = 0U;
  3028. PlsrFiniteStreamSourceDone[pulseOutput] = 0U;
  3029. PlsrFiniteStreamSourceFault[pulseOutput] = 0U;
  3030. firstBlock = (pulseCount > PLSR_COUNTER_BLOCK_PULSES)
  3031. ? PLSR_COUNTER_BLOCK_PULSES : pulseCount;
  3032. counter = PlsrCounters[PlsrCounterIndexByOutput[pulseOutput]];
  3033. PlsrFiniteArmNextStepPrepare(pulseOutput, counter, firstBlock);
  3034. return 1U;
  3035. }
  3036. uint8_t PlsrPlatformStartFiniteSequencePrepared(
  3037. uint8_t pulseOutput,
  3038. PLSR_PLATFORM_FINITE_STEP *steps,
  3039. uint16_t stepCount,
  3040. uint32_t *actualFrequencyHz)
  3041. {
  3042. TIM_TypeDef *counter;
  3043. uint16_t index;
  3044. if ((steps == NULL) || (stepCount == 0U)
  3045. || (stepCount > PLSR_PLATFORM_FINITE_STEP_MAX))
  3046. {
  3047. return 0U;
  3048. }
  3049. for (index = 0U; index < stepCount; index++)
  3050. {
  3051. if ((steps[index].pulseCount == 0UL)
  3052. || (steps[index].segmentNumber == 0U)
  3053. || (PlsrPreparedSettingIsValid(
  3054. pulseOutput, PLSR_OUTPUT_PULSE_DIR,
  3055. &steps[index].setting) == 0U))
  3056. {
  3057. return 0U;
  3058. }
  3059. }
  3060. if (PlsrPlatformStartFinitePrepared(
  3061. pulseOutput, &steps[0].setting, steps[0].pulseCount,
  3062. actualFrequencyHz) == 0U)
  3063. {
  3064. return 0U;
  3065. }
  3066. PlsrFiniteSteps[pulseOutput] = steps;
  3067. PlsrFiniteStepCount[pulseOutput] = stepCount;
  3068. PlsrFiniteStepIndex[pulseOutput] = 0U;
  3069. PlsrFiniteBoundaryReadIndex[pulseOutput] = 0U;
  3070. PlsrFiniteCompletedStepCount[pulseOutput] = 0U;
  3071. if (stepCount > 1U)
  3072. {
  3073. counter = PlsrCounters[PlsrCounterIndexByOutput[pulseOutput]];
  3074. PlsrFiniteArmNextStepPrepare(
  3075. pulseOutput, counter,
  3076. (steps[0].pulseCount > PLSR_COUNTER_BLOCK_PULSES)
  3077. ? PLSR_COUNTER_BLOCK_PULSES : steps[0].pulseCount);
  3078. }
  3079. return 1U;
  3080. }
  3081. PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformUpdateFinitePrepared(
  3082. uint8_t pulseOutput,
  3083. const PLSR_PLATFORM_TIMER_SETTING *setting,
  3084. uint32_t *actualFrequencyHz)
  3085. {
  3086. TIM_TypeDef *timer;
  3087. uint32_t activePeriod;
  3088. uint32_t counter;
  3089. uint32_t criticalState;
  3090. if ((pulseOutput > 3U) || (setting == NULL)
  3091. || (actualFrequencyHz == NULL)
  3092. || (PlsrFiniteActive[pulseOutput] == 0U)
  3093. || (PlsrPreparedSettingIsValid(pulseOutput,
  3094. PLSR_OUTPUT_PULSE_DIR,
  3095. setting) == 0U))
  3096. {
  3097. return PLSR_PLATFORM_QUEUE_STALE;
  3098. }
  3099. timer = PlsrTimerMap[pulseOutput].timer;
  3100. criticalState = PlsrPlatformEnterCritical();
  3101. if ((PlsrFiniteActive[pulseOutput] == 0U)
  3102. || ((timer->CR1 & TIM_CR1_CEN) == 0UL))
  3103. {
  3104. PlsrPlatformExitCritical(criticalState);
  3105. return PLSR_PLATFORM_QUEUE_STALE;
  3106. }
  3107. if (PlsrFiniteFrequencyPending[pulseOutput] != 0U)
  3108. {
  3109. if ((timer->SR & TIM_SR_UIF) == 0UL)
  3110. {
  3111. PlsrPlatformExitCritical(criticalState);
  3112. return PLSR_PLATFORM_QUEUE_STALE;
  3113. }
  3114. /* The update IRQ normally commits this preload. Also consume a
  3115. latched update here so a delayed/shared IRQ cannot stall a ramp. */
  3116. timer->SR = ~TIM_SR_UIF;
  3117. timer->DIER &= ~TIM_DIER_UIE;
  3118. PlsrTimerActiveFrequencyHz[pulseOutput] =
  3119. PlsrTimerQueuedFrequencyHz[pulseOutput];
  3120. PlsrTimerActiveSetting[pulseOutput] =
  3121. PlsrTimerQueuedSetting[pulseOutput];
  3122. PlsrFiniteFrequencyPending[pulseOutput] = 0U;
  3123. }
  3124. activePeriod = PlsrTimerActiveSetting[pulseOutput].period;
  3125. counter = timer->CNT;
  3126. if ((counter > activePeriod)
  3127. || ((activePeriod - counter) < PLSR_FINITE_WRITE_GUARD_COUNTS))
  3128. {
  3129. PlsrPlatformExitCritical(criticalState);
  3130. return PLSR_PLATFORM_QUEUE_STALE;
  3131. }
  3132. timer->PSC = setting->prescaler;
  3133. timer->ARR = setting->period;
  3134. timer->CCR1 = setting->compare;
  3135. __DMB();
  3136. PlsrTimerQueuedSetting[pulseOutput] = *setting;
  3137. PlsrTimerQueuedFrequencyHz[pulseOutput] = setting->actualFrequencyHz;
  3138. PlsrTimerQueueGeneration[pulseOutput]++;
  3139. PlsrFiniteFrequencyPending[pulseOutput] = 1U;
  3140. timer->SR = ~TIM_SR_UIF;
  3141. timer->DIER |= TIM_DIER_UIE;
  3142. *actualFrequencyHz = setting->actualFrequencyHz;
  3143. PlsrPlatformExitCritical(criticalState);
  3144. return PLSR_PLATFORM_QUEUE_APPLIED;
  3145. }
  3146. uint8_t PlsrPlatformRetargetFiniteStop(uint8_t pulseOutput,
  3147. uint32_t drainPulses)
  3148. {
  3149. TIM_TypeDef *timer;
  3150. if ((pulseOutput > 3U) || (drainPulses == 0UL)
  3151. || (PlsrFiniteActive[pulseOutput] == 0U)
  3152. || (PlsrCounterIndexByOutput[pulseOutput] >= PLSR_COUNTER_COUNT)
  3153. || (PlsrFiniteRetargetPending[pulseOutput] != 0U)
  3154. || (PlsrFiniteTailStopPending[pulseOutput] != 0U))
  3155. {
  3156. return 0U;
  3157. }
  3158. timer = PlsrTimerMap[pulseOutput].timer;
  3159. PlsrFiniteRetargetDrainPulses[pulseOutput] = drainPulses;
  3160. PlsrFiniteRetargetPending[pulseOutput] = 1U;
  3161. timer->SR = ~TIM_SR_CC1IF;
  3162. timer->DIER |= TIM_DIER_CC1IE;
  3163. __DMB();
  3164. return 1U;
  3165. }
  3166. uint8_t PlsrPlatformRequestFiniteCut(uint8_t pulseOutput)
  3167. {
  3168. TIM_TypeDef *timer;
  3169. uint32_t criticalState;
  3170. if (pulseOutput > 3U)
  3171. {
  3172. return 0U;
  3173. }
  3174. criticalState = PlsrPlatformEnterCritical();
  3175. if ((PlsrFiniteActive[pulseOutput] == 0U)
  3176. || (PlsrFiniteStreamActive[pulseOutput] == 0U)
  3177. || (PlsrCounterIndexByOutput[pulseOutput] >= PLSR_COUNTER_COUNT)
  3178. || (PlsrFiniteRetargetPending[pulseOutput] != 0U))
  3179. {
  3180. PlsrPlatformExitCritical(criticalState);
  3181. return 0U;
  3182. }
  3183. if (PlsrFiniteTailStopPending[pulseOutput] != 0U)
  3184. {
  3185. PlsrPlatformExitCritical(criticalState);
  3186. return 1U;
  3187. }
  3188. /* Do not allow a run already staged by the producer to cross the cut.
  3189. CC1 reaches the physical pulse's falling edge, where the output is
  3190. idle and can be stopped without shortening the high or low width. */
  3191. PlsrFiniteStreamNextValid[pulseOutput] = 0U;
  3192. PlsrFiniteStreamNextStartsSegment[pulseOutput] = 0U;
  3193. PlsrFiniteStreamSourceDone[pulseOutput] = 1U;
  3194. PlsrFiniteStreamSourceFault[pulseOutput] = 0U;
  3195. PlsrFiniteTailStopPending[pulseOutput] = 1U;
  3196. timer = PlsrTimerMap[pulseOutput].timer;
  3197. timer->SR = ~TIM_SR_CC1IF;
  3198. timer->DIER |= TIM_DIER_CC1IE;
  3199. __DMB();
  3200. PlsrPlatformExitCritical(criticalState);
  3201. return 1U;
  3202. }
  3203. uint8_t PlsrPlatformFiniteRetargetReady(uint8_t pulseOutput,
  3204. uint32_t *activeFrequencyHz)
  3205. {
  3206. uint32_t criticalState;
  3207. uint8_t ready;
  3208. if ((pulseOutput > 3U) || (activeFrequencyHz == NULL))
  3209. {
  3210. return 0U;
  3211. }
  3212. criticalState = PlsrPlatformEnterCritical();
  3213. ready = ((PlsrFiniteActive[pulseOutput] != 0U)
  3214. && (PlsrFiniteRetargetPending[pulseOutput] == 0U)
  3215. && (PlsrFiniteStepCount[pulseOutput] == 0U)) ? 1U : 0U;
  3216. *activeFrequencyHz = PlsrTimerActiveFrequencyHz[pulseOutput];
  3217. PlsrPlatformExitCritical(criticalState);
  3218. return ready;
  3219. }
  3220. uint8_t PlsrPlatformFinitePipelineSnapshot(uint8_t pulseOutput,
  3221. uint32_t *committedPulses,
  3222. uint32_t *tailFrequencyHz,
  3223. uint8_t *startsNextSegment)
  3224. {
  3225. TIM_TypeDef *counter;
  3226. uint32_t criticalState;
  3227. uint32_t blockCount;
  3228. uint32_t remaining;
  3229. if ((pulseOutput > 3U) || (committedPulses == NULL)
  3230. || (tailFrequencyHz == NULL) || (startsNextSegment == NULL))
  3231. {
  3232. return 0U;
  3233. }
  3234. criticalState = PlsrPlatformEnterCritical();
  3235. if ((PlsrFiniteActive[pulseOutput] == 0U)
  3236. || (PlsrFiniteStreamActive[pulseOutput] == 0U)
  3237. || (PlsrCounterIndexByOutput[pulseOutput] >= PLSR_COUNTER_COUNT))
  3238. {
  3239. PlsrPlatformExitCritical(criticalState);
  3240. return 0U;
  3241. }
  3242. counter = PlsrCounters[PlsrCounterIndexByOutput[pulseOutput]];
  3243. blockCount = (uint16_t)counter->CNT;
  3244. if (blockCount >= PlsrFiniteCounterPreload[pulseOutput])
  3245. {
  3246. blockCount -= PlsrFiniteCounterPreload[pulseOutput];
  3247. }
  3248. else
  3249. {
  3250. blockCount = 0UL;
  3251. }
  3252. remaining = PlsrFiniteRemainingPulses[pulseOutput];
  3253. if (blockCount > remaining)
  3254. {
  3255. blockCount = remaining;
  3256. }
  3257. remaining -= blockCount;
  3258. *tailFrequencyHz = PlsrTimerActiveFrequencyHz[pulseOutput];
  3259. *startsNextSegment = 0U;
  3260. if (PlsrFiniteStreamNextValid[pulseOutput] != 0U)
  3261. {
  3262. uint32_t nextPulses = PlsrFiniteStreamNextPulses[pulseOutput];
  3263. remaining = (nextPulses > (0xFFFFFFFFUL - remaining))
  3264. ? 0xFFFFFFFFUL : remaining + nextPulses;
  3265. *tailFrequencyHz =
  3266. PlsrFiniteStreamNextSetting[pulseOutput].actualFrequencyHz;
  3267. *startsNextSegment =
  3268. PlsrFiniteStreamNextStartsSegment[pulseOutput];
  3269. }
  3270. *committedPulses = remaining;
  3271. PlsrPlatformExitCritical(criticalState);
  3272. return 1U;
  3273. }
  3274. uint8_t PlsrPlatformFiniteProgress(uint8_t pulseOutput,
  3275. uint32_t *completedPulses)
  3276. {
  3277. uint8_t counterIndex;
  3278. TIM_TypeDef *counter;
  3279. uint32_t criticalState;
  3280. uint32_t completed;
  3281. if ((pulseOutput > 3U) || (completedPulses == NULL)
  3282. || ((PlsrFiniteActive[pulseOutput] == 0U)
  3283. && (PlsrFiniteCompletionPending[pulseOutput] == 0U)))
  3284. {
  3285. return 0U;
  3286. }
  3287. criticalState = PlsrPlatformEnterCritical();
  3288. counterIndex = PlsrCounterIndexByOutput[pulseOutput];
  3289. if (PlsrFiniteCompletionPending[pulseOutput] != 0U)
  3290. {
  3291. completed = PlsrFiniteTargetPulses[pulseOutput];
  3292. }
  3293. else if (counterIndex < PLSR_COUNTER_COUNT)
  3294. {
  3295. counter = PlsrCounters[counterIndex];
  3296. uint32_t blockCount = (uint16_t)counter->CNT;
  3297. if (blockCount >= PlsrFiniteCounterPreload[pulseOutput])
  3298. {
  3299. blockCount -= PlsrFiniteCounterPreload[pulseOutput];
  3300. }
  3301. completed = PlsrFiniteTargetPulses[pulseOutput]
  3302. - PlsrFiniteRemainingPulses[pulseOutput]
  3303. + blockCount;
  3304. if (completed > PlsrFiniteTargetPulses[pulseOutput])
  3305. {
  3306. completed = PlsrFiniteTargetPulses[pulseOutput];
  3307. }
  3308. }
  3309. else
  3310. {
  3311. PlsrPlatformExitCritical(criticalState);
  3312. return 0U;
  3313. }
  3314. if (PlsrFiniteStepCount[pulseOutput] != 0U)
  3315. {
  3316. completed += PlsrFiniteSteps[pulseOutput][
  3317. PlsrFiniteStepIndex[pulseOutput]].segmentPulseOffset;
  3318. }
  3319. *completedPulses = completed;
  3320. PlsrPlatformExitCritical(criticalState);
  3321. return 1U;
  3322. }
  3323. uint8_t PlsrPlatformTakeFiniteCompletion(uint8_t pulseOutput,
  3324. uint32_t *completedPulses)
  3325. {
  3326. uint8_t counterIndex;
  3327. TIM_TypeDef *counter;
  3328. if ((pulseOutput > 3U) || (completedPulses == NULL)
  3329. || (PlsrFiniteCompletionPending[pulseOutput] == 0U))
  3330. {
  3331. return 0U;
  3332. }
  3333. counterIndex = PlsrCounterIndexByOutput[pulseOutput];
  3334. if (PlsrFiniteStepCount[pulseOutput] != 0U)
  3335. {
  3336. const PLSR_PLATFORM_FINITE_STEP *step =
  3337. &PlsrFiniteSteps[pulseOutput][
  3338. PlsrFiniteStepCount[pulseOutput] - 1U];
  3339. *completedPulses = step->segmentPulseOffset + step->pulseCount;
  3340. }
  3341. else
  3342. {
  3343. *completedPulses = PlsrFiniteTargetPulses[pulseOutput];
  3344. }
  3345. if ((PlsrFiniteStepCount[pulseOutput] == 0U)
  3346. && (PlsrFiniteStreamActive[pulseOutput] == 0U))
  3347. {
  3348. PlsrObservedPulseBase[pulseOutput] += *completedPulses;
  3349. }
  3350. PlsrObservedPulsePublished[pulseOutput] =
  3351. PlsrObservedPulseBase[pulseOutput];
  3352. PlsrFiniteCompletionPending[pulseOutput] = 0U;
  3353. PlsrFiniteFrequencyPending[pulseOutput] = 0U;
  3354. PlsrFiniteTargetPulses[pulseOutput] = 0UL;
  3355. PlsrFiniteRemainingPulses[pulseOutput] = 0UL;
  3356. PlsrFiniteCounterPreload[pulseOutput] = 0U;
  3357. PlsrFiniteStepCount[pulseOutput] = 0U;
  3358. PlsrFiniteStepIndex[pulseOutput] = 0U;
  3359. PlsrFiniteStreamActive[pulseOutput] = 0U;
  3360. PlsrFiniteStreamNextValid[pulseOutput] = 0U;
  3361. PlsrFiniteStreamNextStartsSegment[pulseOutput] = 0U;
  3362. PlsrFiniteStreamSourceDone[pulseOutput] = 0U;
  3363. PlsrFiniteStreamSourceFault[pulseOutput] = 0U;
  3364. PlsrTimerActiveFrequencyHz[pulseOutput] = 0UL;
  3365. PlsrTimerQueuedFrequencyHz[pulseOutput] = 0UL;
  3366. PlsrTimerRunning[pulseOutput] = 0U;
  3367. if (counterIndex < PLSR_COUNTER_COUNT)
  3368. {
  3369. counter = PlsrCounters[counterIndex];
  3370. counter->CR1 = 0UL;
  3371. counter->DIER = 0UL;
  3372. counter->SMCR = 0UL;
  3373. counter->SR = 0UL;
  3374. PlsrCounterOverflowPulses[counterIndex] = 0UL;
  3375. PlsrCounterOwner[counterIndex] = PLSR_COUNTER_NONE;
  3376. }
  3377. PlsrCounterIndexByOutput[pulseOutput] = PLSR_COUNTER_NONE;
  3378. return 1U;
  3379. }
  3380. uint8_t PlsrPlatformTakeFiniteBoundary(uint8_t pulseOutput,
  3381. uint8_t *segmentNumber,
  3382. uint32_t *completedPulses,
  3383. uint8_t *sequenceContinues,
  3384. uint32_t *activeFrequencyHz)
  3385. {
  3386. uint32_t criticalState;
  3387. uint16_t readIndex;
  3388. uint16_t completedCount;
  3389. if ((pulseOutput > 3U) || (segmentNumber == NULL)
  3390. || (completedPulses == NULL) || (sequenceContinues == NULL)
  3391. || (activeFrequencyHz == NULL))
  3392. {
  3393. return 0U;
  3394. }
  3395. criticalState = PlsrPlatformEnterCritical();
  3396. readIndex = PlsrFiniteBoundaryReadIndex[pulseOutput];
  3397. completedCount = PlsrFiniteCompletedStepCount[pulseOutput];
  3398. while (readIndex < completedCount)
  3399. {
  3400. uint16_t index = readIndex++;
  3401. const PLSR_PLATFORM_FINITE_STEP *step =
  3402. &PlsrFiniteSteps[pulseOutput][index];
  3403. PlsrFiniteBoundaryReadIndex[pulseOutput] = readIndex;
  3404. if (step->completesSegment != 0U)
  3405. {
  3406. *segmentNumber = step->segmentNumber;
  3407. *completedPulses = step->segmentPulseOffset + step->pulseCount;
  3408. *sequenceContinues =
  3409. (index + 1U < PlsrFiniteStepCount[pulseOutput]) ? 1U : 0U;
  3410. *activeFrequencyHz = (*sequenceContinues != 0U)
  3411. ? PlsrFiniteSteps[pulseOutput][index + 1U]
  3412. .setting.actualFrequencyHz
  3413. : step->setting.actualFrequencyHz;
  3414. PlsrPlatformExitCritical(criticalState);
  3415. return 1U;
  3416. }
  3417. }
  3418. PlsrPlatformExitCritical(criticalState);
  3419. return 0U;
  3420. }
  3421. PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformLoadPreparedFromIrq(
  3422. uint8_t pulseOutput,
  3423. const PLSR_PLATFORM_TIMER_SETTING *setting,
  3424. uint32_t *actualFrequencyHz)
  3425. {
  3426. uint8_t outputMode;
  3427. if ((pulseOutput > 3U) || (actualFrequencyHz == NULL))
  3428. {
  3429. return PLSR_PLATFORM_QUEUE_FAILED;
  3430. }
  3431. outputMode = PlsrTimerOutputMode[pulseOutput];
  3432. if (PlsrPreparedSettingIsValid(pulseOutput, outputMode,
  3433. setting) == 0U)
  3434. {
  3435. return PLSR_PLATFORM_QUEUE_FAILED;
  3436. }
  3437. if ((PlsrTimerRunning[pulseOutput] == 0U)
  3438. || (PlsrAbStopPending[pulseOutput] != 0U)
  3439. || (PlsrAbFastGated[pulseOutput] != 0U))
  3440. {
  3441. return PLSR_PLATFORM_QUEUE_STALE;
  3442. }
  3443. if (outputMode == PLSR_OUTPUT_AB)
  3444. {
  3445. PLSR_AB_SETTING pending;
  3446. PlsrPlatformToAbSetting(setting, &pending);
  3447. PlsrAbPendingSetting[pulseOutput] = pending;
  3448. PlsrAbFrequencyPending[pulseOutput] =
  3449. ((setting->prescaler
  3450. != PlsrAbActiveSetting[pulseOutput].basePrescaler)
  3451. || (setting->pairPrescaler
  3452. != PlsrAbActiveSetting[pulseOutput].pairPrescaler)
  3453. || (setting->period
  3454. != PlsrAbActiveSetting[pulseOutput].period)) ? 1U : 0U;
  3455. }
  3456. else
  3457. {
  3458. TIM_TypeDef *timer = PlsrTimerMap[pulseOutput].timer;
  3459. if ((timer->CR1 & TIM_CR1_CEN) == 0UL)
  3460. {
  3461. return PLSR_PLATFORM_QUEUE_STALE;
  3462. }
  3463. timer->PSC = setting->prescaler;
  3464. timer->ARR = setting->period;
  3465. timer->CCR1 = setting->compare;
  3466. __DMB();
  3467. }
  3468. PlsrTimerQueuedSetting[pulseOutput] = *setting;
  3469. PlsrTimerQueuedFrequencyHz[pulseOutput] = setting->actualFrequencyHz;
  3470. PlsrTimerQueueGeneration[pulseOutput]++;
  3471. *actualFrequencyHz = setting->actualFrequencyHz;
  3472. return PLSR_PLATFORM_QUEUE_APPLIED;
  3473. }
  3474. void PlsrPlatformGateFromIrq(uint8_t pulseOutput)
  3475. {
  3476. if ((pulseOutput <= 3U)
  3477. && (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  3478. && (PlsrAbFastGated[pulseOutput] != 0U))
  3479. {
  3480. return;
  3481. }
  3482. PlsrPlatformStopPulse(pulseOutput);
  3483. }
  3484. PLSR_PLATFORM_QUEUE_RESULT PlsrPlatformQueueFrequency(
  3485. uint8_t pulseOutput,
  3486. uint32_t frequencyHz,
  3487. uint32_t *actualFrequencyHz)
  3488. {
  3489. TIM_TypeDef *timer;
  3490. PLSR_PLATFORM_TIMER_SETTING setting;
  3491. uint32_t activePeriod;
  3492. uint32_t counter;
  3493. uint32_t criticalState;
  3494. uint32_t ownGeneration;
  3495. uint8_t updatePending;
  3496. if ((pulseOutput > 3U) || (actualFrequencyHz == NULL)
  3497. || (PlsrPlatformBuildTimerSetting(
  3498. pulseOutput, PlsrTimerOutputMode[pulseOutput], frequencyHz,
  3499. &setting) == 0U))
  3500. {
  3501. return PLSR_PLATFORM_QUEUE_FAILED;
  3502. }
  3503. if (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  3504. {
  3505. PLSR_AB_SETTING pending;
  3506. uint32_t criticalState;
  3507. if ((PlsrTimerRunning[pulseOutput] == 0U)
  3508. || (PlsrAbStopPending[pulseOutput] != 0U)
  3509. || (PlsrAbFastGated[pulseOutput] != 0U))
  3510. {
  3511. return PLSR_PLATFORM_QUEUE_STALE;
  3512. }
  3513. criticalState = PlsrPlatformEnterCritical();
  3514. if ((PlsrTimerRunning[pulseOutput] == 0U)
  3515. || (PlsrAbStopPending[pulseOutput] != 0U)
  3516. || (PlsrAbFastGated[pulseOutput] != 0U))
  3517. {
  3518. PlsrPlatformExitCritical(criticalState);
  3519. return PLSR_PLATFORM_QUEUE_STALE;
  3520. }
  3521. PlsrPlatformToAbSetting(&setting, &pending);
  3522. PlsrAbPendingSetting[pulseOutput] = pending;
  3523. PlsrAbFrequencyPending[pulseOutput] =
  3524. ((pending.basePrescaler
  3525. != PlsrAbActiveSetting[pulseOutput].basePrescaler)
  3526. || (pending.pairPrescaler
  3527. != PlsrAbActiveSetting[pulseOutput].pairPrescaler)
  3528. || (pending.period
  3529. != PlsrAbActiveSetting[pulseOutput].period)) ? 1U : 0U;
  3530. PlsrTimerQueuedSetting[pulseOutput] = setting;
  3531. PlsrTimerQueuedFrequencyHz[pulseOutput] = setting.actualFrequencyHz;
  3532. PlsrTimerQueueGeneration[pulseOutput]++;
  3533. *actualFrequencyHz = setting.actualFrequencyHz;
  3534. PlsrPlatformExitCritical(criticalState);
  3535. return PLSR_PLATFORM_QUEUE_APPLIED;
  3536. }
  3537. timer = PlsrTimerMap[pulseOutput].timer;
  3538. if ((timer->CR1 & TIM_CR1_CEN) == 0UL)
  3539. {
  3540. return PLSR_PLATFORM_QUEUE_STALE;
  3541. }
  3542. criticalState = PlsrPlatformEnterCritical();
  3543. if ((timer->SR & TIM_SR_UIF) != 0UL)
  3544. {
  3545. *actualFrequencyHz = PlsrTimerQueuedFrequencyHz[pulseOutput];
  3546. PlsrPlatformExitCritical(criticalState);
  3547. return PLSR_PLATFORM_QUEUE_STALE;
  3548. }
  3549. activePeriod = PlsrTimerActiveSetting[pulseOutput].period;
  3550. counter = timer->CNT;
  3551. if ((counter > activePeriod)
  3552. || ((activePeriod - counter) < PLSR_QUEUE_WRITE_GUARD_COUNTS))
  3553. {
  3554. *actualFrequencyHz = PlsrTimerQueuedFrequencyHz[pulseOutput];
  3555. PlsrPlatformExitCritical(criticalState);
  3556. return PLSR_PLATFORM_QUEUE_STALE;
  3557. }
  3558. /* Preserve real update events and their TRGO pulse while replacing the
  3559. three preload registers. The near-wrap guard bounds the write window. */
  3560. timer->PSC = setting.prescaler;
  3561. timer->ARR = setting.period;
  3562. timer->CCR1 = setting.compare;
  3563. __DMB();
  3564. updatePending = ((timer->SR & TIM_SR_UIF) != 0UL) ? 1U : 0U;
  3565. PlsrTimerQueuedFrequencyHz[pulseOutput] = setting.actualFrequencyHz;
  3566. PlsrTimerQueuedSetting[pulseOutput] = setting;
  3567. PlsrTimerQueueGeneration[pulseOutput]++;
  3568. ownGeneration = PlsrTimerQueueGeneration[pulseOutput];
  3569. if (updatePending != 0U)
  3570. {
  3571. *actualFrequencyHz = PlsrTimerQueuedFrequencyHz[pulseOutput];
  3572. PlsrPlatformExitCritical(criticalState);
  3573. return PLSR_PLATFORM_QUEUE_STALE;
  3574. }
  3575. *actualFrequencyHz =
  3576. (PlsrTimerQueueGeneration[pulseOutput] == ownGeneration)
  3577. ? setting.actualFrequencyHz
  3578. : PlsrTimerQueuedFrequencyHz[pulseOutput];
  3579. if (PlsrTimerQueueGeneration[pulseOutput] != ownGeneration)
  3580. {
  3581. PlsrPlatformExitCritical(criticalState);
  3582. return PLSR_PLATFORM_QUEUE_STALE;
  3583. }
  3584. PlsrPlatformExitCritical(criticalState);
  3585. return PLSR_PLATFORM_QUEUE_APPLIED;
  3586. }
  3587. void PlsrPlatformDrainPendingPulse(uint8_t pulseOutput)
  3588. {
  3589. if (pulseOutput <= 3U)
  3590. {
  3591. if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  3592. && (PlsrDeferredPulsePending[pulseOutput] != 0U))
  3593. {
  3594. uint8_t verifyOutput =
  3595. (PlsrAbLagAxis[pulseOutput] == pulseOutput)
  3596. ? (uint8_t)(pulseOutput + 1U) : pulseOutput;
  3597. TIM_TypeDef *verifyTimer = PlsrTimerMap[verifyOutput].timer;
  3598. verifyTimer->DIER &= ~(TIM_DIER_UIE | TIM_DIER_CC1IE);
  3599. verifyTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
  3600. PlsrAbVerifyOwner[verifyOutput] = PLSR_COUNTER_NONE;
  3601. if (PlsrFrequencyVerifyPending[pulseOutput]
  3602. == PLSR_FREQUENCY_VERIFY_AB_AUX_IRQ)
  3603. {
  3604. PlsrFrequencyVerifyPending[pulseOutput] =
  3605. PLSR_FREQUENCY_VERIFY_NONE;
  3606. PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
  3607. (void)PlsrVerifyActiveFrequency(pulseOutput);
  3608. }
  3609. PlsrDeferredPulsePending[pulseOutput] = 0U;
  3610. PlsrPulseTimerIrq(pulseOutput);
  3611. return;
  3612. }
  3613. PlsrHandleTimerIrq(pulseOutput);
  3614. }
  3615. }
  3616. uint32_t PlsrPlatformActiveFrequency(uint8_t pulseOutput)
  3617. {
  3618. if (pulseOutput > 3U)
  3619. {
  3620. return 0UL;
  3621. }
  3622. if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  3623. && (PlsrAbFastGated[pulseOutput] != 0U))
  3624. {
  3625. PlsrFrequencyVerifyPending[pulseOutput] =
  3626. PLSR_FREQUENCY_VERIFY_NONE;
  3627. PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
  3628. return PlsrTimerActiveFrequencyHz[pulseOutput];
  3629. }
  3630. if (PlsrFrequencyVerifyPending[pulseOutput]
  3631. == PLSR_FREQUENCY_VERIFY_AB_AUX_IRQ)
  3632. {
  3633. return PlsrTimerActiveFrequencyHz[pulseOutput];
  3634. }
  3635. if (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  3636. {
  3637. PlsrFrequencyVerifyPulseCount[pulseOutput]++;
  3638. if (PlsrFrequencyVerifyPulseCount[pulseOutput]
  3639. >= PLSR_STRUCTURE_VERIFY_INTERVAL)
  3640. {
  3641. PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
  3642. PlsrAbScheduleFrequencyVerify(pulseOutput);
  3643. }
  3644. return PlsrTimerActiveFrequencyHz[pulseOutput];
  3645. }
  3646. if (PlsrFrequencyVerifyPending[pulseOutput]
  3647. == PLSR_FREQUENCY_VERIFY_NOW)
  3648. {
  3649. PlsrFrequencyVerifyPending[pulseOutput] =
  3650. PLSR_FREQUENCY_VERIFY_NONE;
  3651. PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
  3652. return PlsrVerifyActiveFrequency(pulseOutput);
  3653. }
  3654. PlsrFrequencyVerifyPulseCount[pulseOutput]++;
  3655. if (PlsrFrequencyVerifyPulseCount[pulseOutput]
  3656. >= PLSR_STRUCTURE_VERIFY_INTERVAL)
  3657. {
  3658. PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
  3659. return PlsrVerifyActiveFrequency(pulseOutput);
  3660. }
  3661. return PlsrTimerActiveFrequencyHz[pulseOutput];
  3662. }
  3663. uint8_t PlsrPlatformExpectedFrequency(uint8_t pulseOutput,
  3664. uint8_t outputMode,
  3665. uint32_t requestedFrequencyHz,
  3666. uint32_t *actualFrequencyHz)
  3667. {
  3668. PLSR_PLATFORM_TIMER_SETTING setting;
  3669. if (actualFrequencyHz == NULL)
  3670. {
  3671. return 0U;
  3672. }
  3673. if (PlsrPlatformBuildTimerSetting(pulseOutput, outputMode,
  3674. requestedFrequencyHz,
  3675. &setting) == 0U)
  3676. {
  3677. return 0U;
  3678. }
  3679. *actualFrequencyHz = setting.actualFrequencyHz;
  3680. return 1U;
  3681. }
  3682. uint64_t PlsrPlatformObservedPulses(uint8_t pulseOutput)
  3683. {
  3684. uint32_t criticalState;
  3685. uint64_t observed;
  3686. if (pulseOutput > 3U)
  3687. {
  3688. return 0UL;
  3689. }
  3690. criticalState = PlsrPlatformEnterCritical();
  3691. if (PlsrCounterIndexByOutput[pulseOutput] < PLSR_COUNTER_COUNT)
  3692. {
  3693. observed = ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  3694. && (PlsrAbFastGated[pulseOutput] != 0U))
  3695. ? PlsrCounterSnapshotStopped(pulseOutput)
  3696. : PlsrCounterSnapshot(pulseOutput);
  3697. }
  3698. else
  3699. {
  3700. observed = PlsrObservedPulseBase[pulseOutput];
  3701. }
  3702. PlsrPlatformExitCritical(criticalState);
  3703. return observed;
  3704. }
  3705. uint16_t PlsrPlatformDiagnosticFault(void)
  3706. {
  3707. uint16_t fault = PlsrPlatformFaultPending;
  3708. PlsrPlatformFaultPending = 0U;
  3709. return fault;
  3710. }
  3711. PLSR_PLATFORM_STOP_RESULT PlsrPlatformRequestStopLocked(
  3712. uint8_t pulseOutput,
  3713. uint8_t requireZeroBoundary)
  3714. {
  3715. if (pulseOutput > 3U)
  3716. {
  3717. return PLSR_PLATFORM_STOP_FORCED_FAULT;
  3718. }
  3719. if ((requireZeroBoundary != 0U)
  3720. && (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  3721. && (PlsrTimerRunning[pulseOutput] != 0U)
  3722. && (PlsrAbFastGated[pulseOutput] == 0U))
  3723. {
  3724. uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
  3725. uint8_t lagOutput = PlsrAbLagAxis[pulseOutput];
  3726. uint32_t activeFrequencyHz;
  3727. TIM_TypeDef *baseTimer = PlsrTimerMap[pulseOutput].timer;
  3728. TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
  3729. uint8_t structureRunnable =
  3730. ((PlsrAbStructureVerified[pulseOutput] != 0U)
  3731. && (PlsrFrequencyVerifyPending[pulseOutput]
  3732. == PLSR_FREQUENCY_VERIFY_NONE))
  3733. ? PlsrAbStopBoundaryIsReachable(pulseOutput, baseTimer,
  3734. pairTimer)
  3735. : PlsrAbTimersAreRunnable(pulseOutput, baseTimer,
  3736. pairTimer);
  3737. if (structureRunnable == 0U)
  3738. {
  3739. PlsrCounterSuspend(pulseOutput);
  3740. PlsrAbHoldPairIdle(pulseOutput);
  3741. baseTimer->CR1 &= ~TIM_CR1_CEN;
  3742. pairTimer->CR1 &= ~TIM_CR1_CEN;
  3743. __DMB();
  3744. PlsrPlatformStopPulse(pulseOutput);
  3745. return PLSR_PLATFORM_STOP_FORCED_FAULT;
  3746. }
  3747. if (PlsrAbStopPending[pulseOutput] != 0U)
  3748. {
  3749. return PLSR_PLATFORM_STOP_PENDING;
  3750. }
  3751. PlsrAbFrequencyPending[pulseOutput] = 0U;
  3752. baseTimer->DIER &= ~TIM_DIER_UIE;
  3753. pairTimer->DIER &= ~TIM_DIER_UIE;
  3754. PlsrFrequencyVerifyPending[pulseOutput] =
  3755. PLSR_FREQUENCY_VERIFY_NONE;
  3756. PlsrFrequencyVerifyPulseCount[pulseOutput] = 0U;
  3757. PlsrAbVerifyOwner[pulseOutput] = PLSR_COUNTER_NONE;
  3758. PlsrAbVerifyOwner[pairOutput] = PLSR_COUNTER_NONE;
  3759. activeFrequencyHz = PlsrTimerActiveFrequencyHz[pulseOutput];
  3760. PlsrTimerQueuedFrequencyHz[pulseOutput] = activeFrequencyHz;
  3761. PlsrTimerQueueGeneration[pulseOutput]++;
  3762. PlsrAbStopPending[pulseOutput] = 1U;
  3763. #if PLSR_DEBUG_TIMING
  3764. if (PlsrFinalArmQueueTimingPending[pulseOutput] != 0U)
  3765. {
  3766. uint32_t queuedAt = PlsrFinalArmQueuedAt[pulseOutput];
  3767. uint32_t stoppedAt = DWT->CYCCNT;
  3768. uint32_t latency = stoppedAt - queuedAt;
  3769. PlsrFinalArmQueueTimingPending[pulseOutput] = 0U;
  3770. PlsrFinalArmQueueToStopLastCycles[pulseOutput] = latency;
  3771. if (latency > PlsrFinalArmQueueToStopMaxCycles[pulseOutput])
  3772. {
  3773. PlsrFinalArmQueueToStopMaxCycles[pulseOutput] = latency;
  3774. }
  3775. }
  3776. #endif
  3777. if (lagOutput == pulseOutput)
  3778. {
  3779. pairTimer->SR = ~TIM_SR_CC1IF;
  3780. }
  3781. else
  3782. {
  3783. baseTimer->SR = ~TIM_SR_CC1IF;
  3784. }
  3785. baseTimer->DIER |= TIM_DIER_CC1IE;
  3786. pairTimer->DIER |= TIM_DIER_CC1IE;
  3787. __DMB();
  3788. return PLSR_PLATFORM_STOP_PENDING;
  3789. }
  3790. PlsrPlatformStopPulse(pulseOutput);
  3791. return PLSR_PLATFORM_STOP_COMPLETE;
  3792. }
  3793. uint8_t PlsrPlatformQueueFinalArmFromIrq(uint8_t pulseOutput)
  3794. {
  3795. uint8_t jobOutput;
  3796. if ((pulseOutput > 2U) || ((pulseOutput & 1U) != 0U)
  3797. || (PlsrTimerOutputMode[pulseOutput] != PLSR_OUTPUT_AB)
  3798. || (PlsrTimerRunning[pulseOutput] == 0U)
  3799. || (PlsrAbFastGated[pulseOutput] != 0U))
  3800. {
  3801. return 0U;
  3802. }
  3803. jobOutput = PlsrFinalArmJobOutput(pulseOutput);
  3804. if (PlsrAbFinalArmJobOwner[jobOutput] != PLSR_COUNTER_NONE)
  3805. {
  3806. return 0U;
  3807. }
  3808. PlsrAbFinalArmJobOwner[jobOutput] = pulseOutput;
  3809. #if PLSR_DEBUG_TIMING
  3810. PlsrFinalArmQueuedAt[pulseOutput] = DWT->CYCCNT;
  3811. PlsrFinalArmQueueTimingPending[pulseOutput] = 1U;
  3812. PlsrFinalArmQueueCount[pulseOutput]++;
  3813. #endif
  3814. __DMB();
  3815. NVIC_SetPendingIRQ(PlsrTimerMap[jobOutput].irq);
  3816. return 1U;
  3817. }
  3818. void PlsrPlatformStopPulse(uint8_t pulseOutput)
  3819. {
  3820. if (pulseOutput <= 3U)
  3821. {
  3822. PlsrFiniteActive[pulseOutput] = 0U;
  3823. PlsrFiniteCompletionPending[pulseOutput] = 0U;
  3824. PlsrFiniteFrequencyPending[pulseOutput] = 0U;
  3825. PlsrFiniteRetargetPending[pulseOutput] = 0U;
  3826. PlsrFiniteTailStopPending[pulseOutput] = 0U;
  3827. PlsrFiniteRetargetDrainPulses[pulseOutput] = 0UL;
  3828. PlsrFiniteTargetPulses[pulseOutput] = 0UL;
  3829. PlsrFiniteRemainingPulses[pulseOutput] = 0UL;
  3830. PlsrFiniteStreamActive[pulseOutput] = 0U;
  3831. PlsrFiniteStreamNextValid[pulseOutput] = 0U;
  3832. PlsrFiniteStreamNextStartsSegment[pulseOutput] = 0U;
  3833. PlsrFiniteStreamSourceDone[pulseOutput] = 0U;
  3834. PlsrFiniteStreamSourceFault[pulseOutput] = 0U;
  3835. if (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  3836. {
  3837. uint8_t pairOutput = (uint8_t)(pulseOutput + 1U);
  3838. uint8_t jobOutput = PlsrFinalArmJobOutput(pulseOutput);
  3839. TIM_TypeDef *baseTimer = PlsrTimerMap[pulseOutput].timer;
  3840. TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
  3841. PlsrAbStructureVerified[pulseOutput] = 0U;
  3842. PlsrAbFinalArmJobOwner[jobOutput] = PLSR_COUNTER_NONE;
  3843. #if PLSR_DEBUG_TIMING
  3844. PlsrFinalArmQueueTimingPending[pulseOutput] = 0U;
  3845. #endif
  3846. NVIC_ClearPendingIRQ(PlsrTimerMap[jobOutput].irq);
  3847. if (PlsrAbFastGated[pulseOutput] != 0U)
  3848. {
  3849. PlsrAbHoldPairIdle(pulseOutput);
  3850. baseTimer->DIER = 0UL;
  3851. pairTimer->DIER = 0UL;
  3852. baseTimer->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
  3853. pairTimer->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
  3854. baseTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
  3855. pairTimer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
  3856. }
  3857. else
  3858. {
  3859. PlsrCounterSuspend(pulseOutput);
  3860. PlsrAbHoldPairIdle(pulseOutput);
  3861. PlsrTimerStop(baseTimer);
  3862. PlsrTimerStop(pairTimer);
  3863. }
  3864. }
  3865. else
  3866. {
  3867. PlsrPulsePinCaptureIdle(pulseOutput);
  3868. PlsrTimerStop(PlsrTimerMap[pulseOutput].timer);
  3869. }
  3870. PlsrCounterStop(pulseOutput);
  3871. PlsrTimerActiveFrequencyHz[pulseOutput] = 0UL;
  3872. PlsrTimerQueuedFrequencyHz[pulseOutput] = 0UL;
  3873. PlsrTimerQueueGeneration[pulseOutput]++;
  3874. PlsrTimerRunning[pulseOutput] = 0U;
  3875. PlsrFrequencyVerifyPending[pulseOutput] = 0U;
  3876. PlsrDeferredPulsePending[pulseOutput] = 0U;
  3877. PlsrAbVerifyOwner[pulseOutput] = PLSR_COUNTER_NONE;
  3878. if (PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_AB)
  3879. {
  3880. PlsrAbVerifyOwner[pulseOutput + 1U] = PLSR_COUNTER_NONE;
  3881. }
  3882. PlsrAbFrequencyPending[pulseOutput] = 0U;
  3883. PlsrAbStopPending[pulseOutput] = 0U;
  3884. PlsrAbFastGated[pulseOutput] = 0U;
  3885. }
  3886. }
  3887. void PlsrPlatformForceSafeOutputsFromFault(void)
  3888. {
  3889. uint32_t mode;
  3890. const uint32_t outputPins = GPIO_PIN_6 | GPIO_PIN_7
  3891. | GPIO_PIN_8 | GPIO_PIN_9;
  3892. const uint32_t outputModeMask = (3UL << (6U * 2U))
  3893. | (3UL << (7U * 2U))
  3894. | (3UL << (8U * 2U))
  3895. | (3UL << (9U * 2U));
  3896. __disable_irq();
  3897. TIM10->DIER = 0UL;
  3898. TIM10->CR1 &= ~TIM_CR1_CEN;
  3899. TIM10->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
  3900. TIM10->SR = 0UL;
  3901. TIM11->DIER = 0UL;
  3902. TIM11->CR1 &= ~TIM_CR1_CEN;
  3903. TIM11->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
  3904. TIM11->SR = 0UL;
  3905. TIM13->DIER = 0UL;
  3906. TIM13->CR1 &= ~TIM_CR1_CEN;
  3907. TIM13->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
  3908. TIM13->SR = 0UL;
  3909. TIM14->DIER = 0UL;
  3910. TIM14->CR1 &= ~TIM_CR1_CEN;
  3911. TIM14->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
  3912. TIM14->SR = 0UL;
  3913. TIM9->DIER = 0UL;
  3914. TIM9->CR1 &= ~TIM_CR1_CEN;
  3915. TIM9->SMCR = 0UL;
  3916. TIM9->SR = 0UL;
  3917. TIM12->DIER = 0UL;
  3918. TIM12->CR1 &= ~TIM_CR1_CEN;
  3919. TIM12->SMCR = 0UL;
  3920. TIM12->SR = 0UL;
  3921. RCC->AHB1ENR |= RCC_AHB1ENR_GPIOFEN | RCC_AHB1ENR_GPIOHEN;
  3922. __DSB();
  3923. GPIOF->BSRR = outputPins;
  3924. GPIOH->BSRR = outputPins;
  3925. GPIOF->OTYPER &= ~outputPins;
  3926. GPIOH->OTYPER &= ~outputPins;
  3927. GPIOF->PUPDR &= ~outputModeMask;
  3928. GPIOH->PUPDR &= ~outputModeMask;
  3929. mode = GPIOF->MODER;
  3930. mode &= ~outputModeMask;
  3931. mode |= (1UL << (6U * 2U)) | (1UL << (7U * 2U))
  3932. | (1UL << (8U * 2U)) | (1UL << (9U * 2U));
  3933. GPIOF->MODER = mode;
  3934. mode = GPIOH->MODER;
  3935. mode &= ~outputModeMask;
  3936. mode |= (1UL << (6U * 2U)) | (1UL << (7U * 2U))
  3937. | (1UL << (8U * 2U)) | (1UL << (9U * 2U));
  3938. GPIOH->MODER = mode;
  3939. __DSB();
  3940. }
  3941. uint8_t PlsrPlatformReadInput(uint8_t inputSelection)
  3942. {
  3943. if (inputSelection == 0U)
  3944. {
  3945. return (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) == GPIO_PIN_SET) ? 1U : 0U;
  3946. }
  3947. if (inputSelection == 1U)
  3948. {
  3949. return (HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_12) == GPIO_PIN_SET) ? 1U : 0U;
  3950. }
  3951. return 0U;
  3952. }
  3953. uint8_t PlsrPlatformLoad(PLSR_PERSIST_PAYLOAD *payload)
  3954. {
  3955. PLSR_FLASH_SECTOR_SCAN scanA;
  3956. PLSR_FLASH_SECTOR_SCAN scanB;
  3957. const PLSR_FLASH_HEADER *selected = NULL;
  3958. const void *backupConfig = (const void *)PLSR_BACKUP_CONFIG_ADDRESS;
  3959. const PLSR_BACKUP_POSITION_RECORD *backupPosition;
  3960. uint8_t selectedVersion = 0U;
  3961. uint8_t backupVersion;
  3962. uint8_t haveConfig = 0U;
  3963. uint32_t selectedSectorAddress;
  3964. if (payload == NULL)
  3965. {
  3966. return 0U;
  3967. }
  3968. selected = PlsrFlashInitializeJournal(&scanA, &scanB, &selectedVersion,
  3969. &selectedSectorAddress);
  3970. if (selected != NULL)
  3971. {
  3972. if (selectedVersion == PLSR_FLASH_VERSION)
  3973. {
  3974. *payload = ((const PLSR_FLASH_RECORD *)selected)->payload;
  3975. }
  3976. else
  3977. {
  3978. PlsrLoadV2Payload(
  3979. payload,
  3980. &((const PLSR_FLASH_RECORD_V2 *)selected)->payload);
  3981. }
  3982. haveConfig = 1U;
  3983. }
  3984. else
  3985. {
  3986. (void)memset(payload, 0, sizeof(*payload));
  3987. }
  3988. backupVersion = PlsrBackupConfigVersion(backupConfig);
  3989. if (backupVersion == PLSR_FLASH_VERSION)
  3990. {
  3991. payload->config =
  3992. ((const PLSR_BACKUP_CONFIG_RECORD *)backupConfig)->config;
  3993. haveConfig = 1U;
  3994. }
  3995. else if (backupVersion == PLSR_FLASH_VERSION_V2)
  3996. {
  3997. const PLSR_BACKUP_CONFIG_RECORD_V2 *oldConfig =
  3998. (const PLSR_BACKUP_CONFIG_RECORD_V2 *)backupConfig;
  3999. (void)memcpy(&payload->config, oldConfig->config,
  4000. sizeof(oldConfig->config));
  4001. payload->config.outputMode = PLSR_OUTPUT_PULSE_DIR;
  4002. haveConfig = 1U;
  4003. }
  4004. backupPosition = PlsrNewestBackupPosition();
  4005. if (backupPosition != NULL)
  4006. {
  4007. payload->position = backupPosition->position;
  4008. payload->positionValid = backupPosition->positionValid;
  4009. payload->wasBusy = backupPosition->wasBusy;
  4010. }
  4011. if (selected != NULL)
  4012. {
  4013. uint8_t reserveIndex =
  4014. (selectedSectorAddress == PLSR_FLASH_SLOT_A_ADDRESS) ? 1U : 0U;
  4015. const PLSR_FLASH_SECTOR_SCAN *reserveScan =
  4016. (reserveIndex == 0U) ? &scanA : &scanB;
  4017. if (reserveScan->hasProgrammedSlot != 0U)
  4018. {
  4019. PlsrFlashReserveEraseState = (uint8_t)(reserveIndex + 1U);
  4020. }
  4021. }
  4022. else if (PlsrFlashNeedsStartupRecovery(
  4023. 0U,
  4024. scanA.hasProgrammedSlot,
  4025. scanA.firstErasedAddress,
  4026. scanB.hasProgrammedSlot,
  4027. scanB.firstErasedAddress) != 0U)
  4028. {
  4029. PlsrFlashReserveEraseState = PLSR_FLASH_ERASE_SECTOR_A;
  4030. }
  4031. return haveConfig;
  4032. }
  4033. PLSR_PLATFORM_SERVICE_RESULT PlsrPlatformServicePersistence(void)
  4034. {
  4035. uint32_t criticalState;
  4036. uint8_t eraseState;
  4037. uint8_t sectorIndex;
  4038. uint8_t index;
  4039. criticalState = PlsrPlatformEnterCritical();
  4040. eraseState = PlsrFlashReserveEraseState;
  4041. if (eraseState == PLSR_FLASH_ERASE_FAILED)
  4042. {
  4043. PlsrPlatformExitCritical(criticalState);
  4044. return PLSR_PLATFORM_SERVICE_FAILED;
  4045. }
  4046. if (eraseState == PLSR_FLASH_ERASE_NONE)
  4047. {
  4048. PlsrPlatformExitCritical(criticalState);
  4049. return PLSR_PLATFORM_SERVICE_READY;
  4050. }
  4051. if ((eraseState < PLSR_FLASH_ERASE_SECTOR_A)
  4052. || (eraseState > PLSR_FLASH_ERASE_SECTOR_B))
  4053. {
  4054. PlsrFlashReserveEraseState = PLSR_FLASH_ERASE_FAILED;
  4055. PlsrPlatformExitCritical(criticalState);
  4056. return PLSR_PLATFORM_SERVICE_FAILED;
  4057. }
  4058. for (index = 0U; index < 4U; index++)
  4059. {
  4060. if ((PlsrTimerRunning[index] != 0U)
  4061. || (PlsrTimerIrqActive[index] != 0U))
  4062. {
  4063. PlsrPlatformExitCritical(criticalState);
  4064. return PLSR_PLATFORM_SERVICE_DEFERRED;
  4065. }
  4066. }
  4067. sectorIndex = (uint8_t)(eraseState - PLSR_FLASH_ERASE_SECTOR_A);
  4068. PlsrPlatformExitCritical(criticalState);
  4069. if (PlsrFlashEraseReserve(sectorIndex) == 0U)
  4070. {
  4071. PlsrFlashReserveEraseState = PLSR_FLASH_ERASE_FAILED;
  4072. return PLSR_PLATFORM_SERVICE_FAILED;
  4073. }
  4074. PlsrFlashNextErasedAddress[sectorIndex] =
  4075. (sectorIndex == 0U) ? PLSR_FLASH_SLOT_A_ADDRESS
  4076. : PLSR_FLASH_SLOT_B_ADDRESS;
  4077. PlsrFlashReserveEraseState = PLSR_FLASH_ERASE_NONE;
  4078. return PLSR_PLATFORM_SERVICE_READY;
  4079. }
  4080. uint8_t PlsrPlatformSave(const PLSR_PERSIST_PAYLOAD *payload)
  4081. {
  4082. PLSR_FLASH_SECTOR_SCAN scanA;
  4083. PLSR_FLASH_SECTOR_SCAN scanB;
  4084. uint8_t newestVersion;
  4085. uint32_t newestSectorAddress;
  4086. uint8_t targetIndex;
  4087. uint32_t targetAddress;
  4088. uint32_t index;
  4089. uint32_t wordCount;
  4090. const uint32_t *words;
  4091. HAL_StatusTypeDef status = HAL_OK;
  4092. if (payload == NULL)
  4093. {
  4094. return 0U;
  4095. }
  4096. if (PlsrFlashJournalInitialized == 0U)
  4097. {
  4098. (void)PlsrFlashInitializeJournal(&scanA, &scanB, &newestVersion,
  4099. &newestSectorAddress);
  4100. (void)newestVersion;
  4101. (void)newestSectorAddress;
  4102. }
  4103. if (PlsrFlashNewestAddress != 0UL)
  4104. {
  4105. targetIndex = PlsrFlashSectorIndex(PlsrFlashNewestAddress);
  4106. if (PlsrFlashNextErasedAddress[targetIndex] == 0UL)
  4107. {
  4108. targetIndex ^= 1U;
  4109. }
  4110. }
  4111. else if (PlsrFlashNextErasedAddress[0] != 0UL)
  4112. {
  4113. targetIndex = 0U;
  4114. }
  4115. else
  4116. {
  4117. targetIndex = 1U;
  4118. }
  4119. targetAddress = PlsrFlashNextErasedAddress[targetIndex];
  4120. if ((targetAddress != 0UL)
  4121. && ((PlsrFlashAddressIsJournalSlot(targetIndex, targetAddress) == 0U)
  4122. || (PlsrFlashSlotIsErased(targetAddress) == 0U)))
  4123. {
  4124. targetAddress = 0UL;
  4125. PlsrFlashNextErasedAddress[targetIndex] = 0UL;
  4126. }
  4127. if (targetAddress == 0UL)
  4128. {
  4129. uint8_t newestIndex = (PlsrFlashNewestAddress != 0UL)
  4130. ? PlsrFlashSectorIndex(
  4131. PlsrFlashNewestAddress)
  4132. : 0xFFU;
  4133. uint8_t alternateIndex = targetIndex ^ 1U;
  4134. if ((targetIndex == newestIndex)
  4135. || (PlsrFlashNextErasedAddress[alternateIndex] != 0UL))
  4136. {
  4137. targetIndex = alternateIndex;
  4138. targetAddress = PlsrFlashNextErasedAddress[targetIndex];
  4139. if ((targetAddress != 0UL)
  4140. && ((PlsrFlashAddressIsJournalSlot(targetIndex,
  4141. targetAddress) == 0U)
  4142. || (PlsrFlashSlotIsErased(targetAddress) == 0U)))
  4143. {
  4144. targetAddress = 0UL;
  4145. PlsrFlashNextErasedAddress[targetIndex] = 0UL;
  4146. }
  4147. }
  4148. if (targetAddress == 0UL)
  4149. {
  4150. return 0U;
  4151. }
  4152. }
  4153. PlsrFlashNextErasedAddress[targetIndex] =
  4154. PlsrFlashFindErasedAfter(targetIndex, targetAddress);
  4155. (void)memset(&PlsrFlashRecordBuffer, 0, sizeof(PlsrFlashRecordBuffer));
  4156. PlsrFlashRecordBuffer.magic = PLSR_FLASH_MAGIC;
  4157. PlsrFlashRecordBuffer.version = PLSR_FLASH_VERSION;
  4158. PlsrFlashRecordBuffer.payloadSize = sizeof(PLSR_PERSIST_PAYLOAD);
  4159. PlsrFlashRecordBuffer.generation = PlsrFlashNewestGeneration + 1UL;
  4160. PlsrFlashRecordBuffer.payload = *payload;
  4161. PlsrFlashRecordBuffer.crc32 =
  4162. PlsrFlashRecordCrc(&PlsrFlashRecordBuffer,
  4163. sizeof(PlsrFlashRecordBuffer.payload));
  4164. if (HAL_FLASH_Unlock() != HAL_OK)
  4165. {
  4166. (void)HAL_FLASH_Lock();
  4167. return 0U;
  4168. }
  4169. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR
  4170. | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR
  4171. | FLASH_FLAG_PGSERR);
  4172. words = (const uint32_t *)&PlsrFlashRecordBuffer;
  4173. wordCount = sizeof(PlsrFlashRecordBuffer) / sizeof(uint32_t);
  4174. if (status == HAL_OK)
  4175. {
  4176. for (index = 1UL; index < wordCount; index++)
  4177. {
  4178. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,
  4179. targetAddress + index * 4UL,
  4180. words[index]) != HAL_OK)
  4181. {
  4182. status = HAL_ERROR;
  4183. break;
  4184. }
  4185. }
  4186. }
  4187. if ((status == HAL_OK)
  4188. && (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, targetAddress,
  4189. PLSR_FLASH_MAGIC) != HAL_OK))
  4190. {
  4191. status = HAL_ERROR;
  4192. }
  4193. if (HAL_FLASH_Lock() != HAL_OK)
  4194. {
  4195. (void)HAL_FLASH_Lock();
  4196. status = HAL_ERROR;
  4197. }
  4198. if (PlsrFlashRecordVersion((const void *)targetAddress)
  4199. == PLSR_FLASH_VERSION)
  4200. {
  4201. PlsrFlashNewestAddress = targetAddress;
  4202. PlsrFlashNewestGeneration = PlsrFlashRecordBuffer.generation;
  4203. return (status == HAL_OK) ? 1U : 0U;
  4204. }
  4205. return 0U;
  4206. }
  4207. void PlsrPlatformCheckpointConfig(const PLSR_CONFIG *config)
  4208. {
  4209. PLSR_BACKUP_CONFIG_RECORD *record =
  4210. (PLSR_BACKUP_CONFIG_RECORD *)PLSR_BACKUP_CONFIG_ADDRESS;
  4211. if (config == NULL)
  4212. {
  4213. return;
  4214. }
  4215. record->magic = 0UL;
  4216. record->config = *config;
  4217. record->crc32 = PlsrCrc32(&record->config, sizeof(record->config));
  4218. __DMB();
  4219. record->magic = PLSR_BACKUP_CONFIG_MAGIC;
  4220. __DMB();
  4221. }
  4222. void PlsrPlatformCheckpointPosition(int32_t position,
  4223. uint8_t positionValid,
  4224. uint8_t wasBusy)
  4225. {
  4226. PLSR_BACKUP_POSITION_RECORD *slots =
  4227. (PLSR_BACKUP_POSITION_RECORD *)PLSR_BACKUP_POSITION_ADDRESS;
  4228. PLSR_BACKUP_POSITION_RECORD *record;
  4229. PlsrBackupPositionGeneration++;
  4230. record = &slots[PlsrBackupPositionGeneration & 1UL];
  4231. record->magic = 0UL;
  4232. record->generation = PlsrBackupPositionGeneration;
  4233. record->position = position;
  4234. record->positionValid = (positionValid != 0U) ? 1U : 0U;
  4235. record->wasBusy = (wasBusy != 0U) ? 1U : 0U;
  4236. record->reserved = 0U;
  4237. record->crc32 = PlsrCrc32(&record->generation,
  4238. sizeof(record->generation)
  4239. + sizeof(record->position)
  4240. + sizeof(record->positionValid)
  4241. + sizeof(record->wasBusy)
  4242. + sizeof(record->reserved));
  4243. __DMB();
  4244. record->magic = PLSR_BACKUP_POSITION_MAGIC;
  4245. __DMB();
  4246. }
  4247. uint32_t PlsrPlatformEnterCritical(void)
  4248. {
  4249. uint32_t state = __get_PRIMASK();
  4250. __disable_irq();
  4251. __DMB();
  4252. return state;
  4253. }
  4254. void PlsrPlatformExitCritical(uint32_t state)
  4255. {
  4256. __DMB();
  4257. if (state == 0UL)
  4258. {
  4259. __enable_irq();
  4260. }
  4261. }
  4262. static void PlsrHandleTimerIrq(uint8_t pulseOutput)
  4263. {
  4264. TIM_TypeDef *timer;
  4265. #if PLSR_DEBUG_TIMING
  4266. uint32_t startedAt;
  4267. uint32_t elapsedCycles;
  4268. uint8_t timingOutput = pulseOutput;
  4269. startedAt = DWT->CYCCNT;
  4270. #endif
  4271. timer = PlsrTimerMap[pulseOutput].timer;
  4272. if (PlsrTimerIrqActive[pulseOutput] != 0U)
  4273. {
  4274. #if PLSR_DEBUG_TIMING
  4275. goto irq_record;
  4276. #else
  4277. return;
  4278. #endif
  4279. }
  4280. PlsrTimerIrqActive[pulseOutput] = 1U;
  4281. if (((timer->SR & TIM_SR_CC1IF) != 0UL)
  4282. && ((timer->DIER & TIM_DIER_CC1IE) != 0UL))
  4283. {
  4284. uint8_t owner = ((pulseOutput & 2U) == 0U) ? 0U : 2U;
  4285. if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_PULSE_DIR)
  4286. && (PlsrFiniteRetargetPending[pulseOutput] != 0U))
  4287. {
  4288. timer->SR = ~TIM_SR_CC1IF;
  4289. PlsrFiniteRetargetAtFallingEdge(pulseOutput);
  4290. goto irq_done;
  4291. }
  4292. if ((PlsrTimerOutputMode[pulseOutput] == PLSR_OUTPUT_PULSE_DIR)
  4293. && (PlsrFiniteTailStopPending[pulseOutput] != 0U))
  4294. {
  4295. timer->SR = ~TIM_SR_CC1IF;
  4296. PlsrFiniteCutAtFallingEdge(pulseOutput);
  4297. goto irq_done;
  4298. }
  4299. #if PLSR_DEBUG_TIMING
  4300. timingOutput = owner;
  4301. #endif
  4302. timer->SR = ~TIM_SR_CC1IF;
  4303. if ((owner <= 2U)
  4304. && (PlsrTimerRunning[owner] != 0U)
  4305. && (PlsrTimerOutputMode[owner] == PLSR_OUTPUT_AB))
  4306. {
  4307. uint8_t pairOutput = (uint8_t)(owner + 1U);
  4308. TIM_TypeDef *baseTimer = PlsrTimerMap[owner].timer;
  4309. TIM_TypeDef *pairTimer = PlsrTimerMap[pairOutput].timer;
  4310. PLSR_AB_SETTING pending;
  4311. if (PlsrAbStopPending[owner] != 0U)
  4312. {
  4313. if (PlsrAbCanFastGateAtZero(owner) == 0U)
  4314. {
  4315. goto irq_done;
  4316. }
  4317. baseTimer->DIER &= ~(TIM_DIER_CC1IE | TIM_DIER_UIE);
  4318. pairTimer->DIER &= ~(TIM_DIER_CC1IE | TIM_DIER_UIE);
  4319. baseTimer->SR = ~TIM_SR_CC1IF;
  4320. pairTimer->SR = ~TIM_SR_CC1IF;
  4321. PlsrFrequencyVerifyPending[owner] =
  4322. PLSR_FREQUENCY_VERIFY_NONE;
  4323. PlsrAbVerifyOwner[owner] = PLSR_COUNTER_NONE;
  4324. PlsrAbVerifyOwner[pairOutput] = PLSR_COUNTER_NONE;
  4325. PlsrAbFastGate(owner);
  4326. PlsrAbFastGated[owner] = 1U;
  4327. PlsrDeferredPulsePending[owner] = 0U;
  4328. PlsrPulseTimerIrq(owner);
  4329. goto irq_done;
  4330. }
  4331. if (pulseOutput != PlsrAbLagAxis[owner])
  4332. {
  4333. if (PlsrDeferredPulsePending[owner] != 0U)
  4334. {
  4335. PlsrDeferredPulsePending[owner] = 0U;
  4336. timer->DIER &= ~TIM_DIER_CC1IE;
  4337. PlsrPulseTimerIrq(owner);
  4338. }
  4339. goto irq_done;
  4340. }
  4341. if (PlsrDeferredPulsePending[owner] != 0U)
  4342. {
  4343. goto irq_done;
  4344. }
  4345. if (PlsrAbFrequencyPending[owner] != 0U)
  4346. {
  4347. pending = PlsrAbPendingSetting[owner];
  4348. PlsrAbFrequencyPending[owner] = 0U;
  4349. PlsrAbLoadAndStart(owner, &pending);
  4350. PlsrAbActiveSetting[owner] = pending;
  4351. PlsrTimerActiveSetting[owner] =
  4352. PlsrTimerQueuedSetting[owner];
  4353. PlsrTimerActiveFrequencyHz[owner] =
  4354. pending.actualFrequencyHz;
  4355. PlsrDeferredPulsePending[owner] = 1U;
  4356. PlsrAbScheduleFrequencyVerify(owner);
  4357. goto irq_done;
  4358. }
  4359. PlsrPulseTimerIrq(owner);
  4360. }
  4361. goto irq_done;
  4362. }
  4363. if (((timer->SR & TIM_SR_UIF) != 0UL)
  4364. && ((timer->DIER & TIM_DIER_UIE) != 0UL))
  4365. {
  4366. timer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
  4367. if ((PlsrFiniteActive[pulseOutput] != 0U)
  4368. && (PlsrFiniteFrequencyPending[pulseOutput] != 0U))
  4369. {
  4370. PlsrTimerActiveFrequencyHz[pulseOutput] =
  4371. PlsrTimerQueuedFrequencyHz[pulseOutput];
  4372. PlsrTimerActiveSetting[pulseOutput] =
  4373. PlsrTimerQueuedSetting[pulseOutput];
  4374. PlsrFiniteFrequencyPending[pulseOutput] = 0U;
  4375. timer->DIER &= ~TIM_DIER_UIE;
  4376. goto irq_done;
  4377. }
  4378. if (PlsrPlatformSettingsDiffer(
  4379. &PlsrTimerActiveSetting[pulseOutput],
  4380. &PlsrTimerQueuedSetting[pulseOutput]) != 0U)
  4381. {
  4382. PlsrFrequencyVerifyPending[pulseOutput] = 1U;
  4383. PlsrTimerActiveFrequencyHz[pulseOutput] =
  4384. PlsrTimerQueuedFrequencyHz[pulseOutput];
  4385. PlsrTimerActiveSetting[pulseOutput] =
  4386. PlsrTimerQueuedSetting[pulseOutput];
  4387. }
  4388. PlsrPulseTimerIrq(pulseOutput);
  4389. }
  4390. irq_done:
  4391. PlsrTimerIrqActive[pulseOutput] = 0U;
  4392. #if PLSR_DEBUG_TIMING
  4393. irq_record:
  4394. elapsedCycles = DWT->CYCCNT - startedAt;
  4395. PlsrIrqCount[timingOutput]++;
  4396. PlsrIrqLastCycles[timingOutput] = elapsedCycles;
  4397. if (elapsedCycles > PlsrIrqMaxCycles[timingOutput])
  4398. {
  4399. PlsrIrqMaxCycles[timingOutput] = elapsedCycles;
  4400. }
  4401. #endif
  4402. }
  4403. static uint8_t PlsrHandleScheduledAbVerify(uint8_t pulseOutput)
  4404. {
  4405. uint8_t verifyOwner = PlsrAbVerifyOwner[pulseOutput];
  4406. TIM_TypeDef *timer;
  4407. #if PLSR_DEBUG_TIMING
  4408. uint32_t startedAt;
  4409. uint32_t elapsedCycles;
  4410. #endif
  4411. if (verifyOwner > 2U)
  4412. {
  4413. return 0U;
  4414. }
  4415. timer = PlsrTimerMap[pulseOutput].timer;
  4416. if (((timer->SR & TIM_SR_UIF) == 0UL)
  4417. || ((timer->DIER & TIM_DIER_UIE) == 0UL))
  4418. {
  4419. return 0U;
  4420. }
  4421. #if PLSR_DEBUG_TIMING
  4422. startedAt = DWT->CYCCNT;
  4423. #endif
  4424. timer->SR = ~TIM_SR_UIF;
  4425. timer->DIER &= ~TIM_DIER_UIE;
  4426. PlsrAbVerifyOwner[pulseOutput] = PLSR_COUNTER_NONE;
  4427. if (PlsrFrequencyVerifyPending[verifyOwner]
  4428. == PLSR_FREQUENCY_VERIFY_AB_AUX_IRQ)
  4429. {
  4430. PlsrFrequencyVerifyPending[verifyOwner] =
  4431. PLSR_FREQUENCY_VERIFY_NONE;
  4432. PlsrFrequencyVerifyPulseCount[verifyOwner] = 0U;
  4433. (void)PlsrVerifyActiveFrequency(verifyOwner);
  4434. }
  4435. #if PLSR_DEBUG_TIMING
  4436. elapsedCycles = DWT->CYCCNT - startedAt;
  4437. PlsrIrqCount[verifyOwner]++;
  4438. PlsrIrqLastCycles[verifyOwner] = elapsedCycles;
  4439. if (elapsedCycles > PlsrIrqMaxCycles[verifyOwner])
  4440. {
  4441. PlsrIrqMaxCycles[verifyOwner] = elapsedCycles;
  4442. }
  4443. #endif
  4444. return 1U;
  4445. }
  4446. static uint8_t PlsrFinalStopIrqIsPending(uint8_t pulseOutput)
  4447. {
  4448. uint8_t owner = ((pulseOutput & 2U) == 0U) ? 0U : 2U;
  4449. TIM_TypeDef *timer = PlsrTimerMap[pulseOutput].timer;
  4450. return ((PlsrAbStopPending[owner] != 0U)
  4451. && ((timer->SR & TIM_SR_CC1IF) != 0UL)
  4452. && ((timer->DIER & TIM_DIER_CC1IE) != 0UL)) ? 1U : 0U;
  4453. }
  4454. static uint8_t PlsrHandleFinalArmJob(uint8_t pulseOutput)
  4455. {
  4456. uint8_t owner = PlsrAbFinalArmJobOwner[pulseOutput];
  4457. #if PLSR_DEBUG_TIMING
  4458. uint32_t startedAt;
  4459. uint32_t elapsedCycles;
  4460. #endif
  4461. if (owner > 2U)
  4462. {
  4463. return 0U;
  4464. }
  4465. PlsrAbFinalArmJobOwner[pulseOutput] = PLSR_COUNTER_NONE;
  4466. #if PLSR_DEBUG_TIMING
  4467. startedAt = DWT->CYCCNT;
  4468. #endif
  4469. PlsrFinalArmJobIrq(owner);
  4470. #if PLSR_DEBUG_TIMING
  4471. elapsedCycles = DWT->CYCCNT - startedAt;
  4472. PlsrFinalArmJobLastCycles[owner] = elapsedCycles;
  4473. if (elapsedCycles > PlsrFinalArmJobMaxCycles[owner])
  4474. {
  4475. PlsrFinalArmJobMaxCycles[owner] = elapsedCycles;
  4476. }
  4477. #endif
  4478. return 1U;
  4479. }
  4480. static void PlsrDispatchTimerIrq(uint8_t pulseOutput)
  4481. {
  4482. if (PlsrFinalStopIrqIsPending(pulseOutput) != 0U)
  4483. {
  4484. PlsrHandleTimerIrq(pulseOutput);
  4485. return;
  4486. }
  4487. if (PlsrHandleFinalArmJob(pulseOutput) != 0U)
  4488. {
  4489. return;
  4490. }
  4491. if (PlsrHandleScheduledAbVerify(pulseOutput) == 0U)
  4492. {
  4493. PlsrHandleTimerIrq(pulseOutput);
  4494. }
  4495. }
  4496. void TIM1_UP_TIM10_IRQHandler(void)
  4497. {
  4498. PlsrDispatchTimerIrq(0U);
  4499. }
  4500. void TIM8_UP_TIM13_IRQHandler(void)
  4501. {
  4502. PlsrDispatchTimerIrq(1U);
  4503. }
  4504. void TIM1_TRG_COM_TIM11_IRQHandler(void)
  4505. {
  4506. PlsrDispatchTimerIrq(2U);
  4507. }
  4508. void TIM8_TRG_COM_TIM14_IRQHandler(void)
  4509. {
  4510. PlsrDispatchTimerIrq(3U);
  4511. }
  4512. void EXTI9_5_IRQHandler(void)
  4513. {
  4514. if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_5) != RESET)
  4515. {
  4516. __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_5);
  4517. PlsrWaitInputExtiIrq(0U);
  4518. }
  4519. }
  4520. void EXTI15_10_IRQHandler(void)
  4521. {
  4522. if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_12) != RESET)
  4523. {
  4524. __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_12);
  4525. PlsrWaitInputExtiIrq(1U);
  4526. }
  4527. }
  4528. static void PlsrHandleCounterIrq(uint8_t counterIndex)
  4529. {
  4530. TIM_TypeDef *counter;
  4531. #if PLSR_DEBUG_TIMING
  4532. uint32_t startedAt = DWT->CYCCNT;
  4533. #endif
  4534. if (counterIndex >= PLSR_COUNTER_COUNT)
  4535. {
  4536. return;
  4537. }
  4538. counter = PlsrCounters[counterIndex];
  4539. if (((counter->SR & TIM_SR_CC1IF) != 0UL)
  4540. && ((counter->DIER & TIM_DIER_CC1IE) != 0UL))
  4541. {
  4542. uint8_t owner = PlsrCounterOwner[counterIndex];
  4543. counter->SR = ~TIM_SR_CC1IF;
  4544. if ((owner <= 3U) && (PlsrFiniteActive[owner] != 0U))
  4545. {
  4546. PlsrFinitePrepareNextStepIrq(owner, counter);
  4547. }
  4548. }
  4549. if (((counter->SR & TIM_SR_UIF) != 0UL)
  4550. && ((counter->DIER & TIM_DIER_UIE) != 0UL))
  4551. {
  4552. uint8_t owner = PlsrCounterOwner[counterIndex];
  4553. counter->SR = ~TIM_SR_UIF;
  4554. if ((owner <= 3U) && (PlsrFiniteActive[owner] != 0U))
  4555. {
  4556. PlsrFiniteCounterIrq(owner, counter);
  4557. #if PLSR_DEBUG_TIMING
  4558. {
  4559. uint32_t elapsedCycles = DWT->CYCCNT - startedAt;
  4560. if (PlsrFiniteCompletionPending[owner] != 0U)
  4561. {
  4562. PlsrFiniteFinalIrqLastCycles[owner] = elapsedCycles;
  4563. if (elapsedCycles > PlsrFiniteFinalIrqMaxCycles[owner])
  4564. {
  4565. PlsrFiniteFinalIrqMaxCycles[owner] = elapsedCycles;
  4566. }
  4567. }
  4568. else
  4569. {
  4570. PlsrFiniteBlockIrqCount[owner]++;
  4571. if (elapsedCycles > PlsrFiniteBlockIrqMaxCycles[owner])
  4572. {
  4573. PlsrFiniteBlockIrqMaxCycles[owner] = elapsedCycles;
  4574. }
  4575. }
  4576. }
  4577. #endif
  4578. }
  4579. else
  4580. {
  4581. PlsrCounterOverflowPulses[counterIndex] +=
  4582. PLSR_COUNTER_BLOCK_PULSES;
  4583. }
  4584. }
  4585. }
  4586. static void PlsrFiniteArmNextStepPrepare(uint8_t pulseOutput,
  4587. TIM_TypeDef *counter,
  4588. uint32_t blockPulses)
  4589. {
  4590. uint16_t nextIndex =
  4591. (uint16_t)(PlsrFiniteStepIndex[pulseOutput] + 1U);
  4592. counter->DIER &= ~TIM_DIER_CC1IE;
  4593. counter->SR = ~TIM_SR_CC1IF;
  4594. if (PlsrFiniteRemainingPulses[pulseOutput] > blockPulses)
  4595. {
  4596. return;
  4597. }
  4598. if ((PlsrFiniteStreamActive[pulseOutput] == 0U)
  4599. && (nextIndex >= PlsrFiniteStepCount[pulseOutput]))
  4600. {
  4601. return;
  4602. }
  4603. if (blockPulses > 1UL)
  4604. {
  4605. counter->CCR1 = blockPulses - 1UL;
  4606. counter->DIER |= TIM_DIER_CC1IE;
  4607. }
  4608. else
  4609. {
  4610. PlsrFinitePrepareNextStepIrq(pulseOutput, counter);
  4611. }
  4612. }
  4613. static void PlsrFinitePrepareNextStepIrq(uint8_t pulseOutput,
  4614. TIM_TypeDef *counter)
  4615. {
  4616. uint16_t nextIndex =
  4617. (uint16_t)(PlsrFiniteStepIndex[pulseOutput] + 1U);
  4618. TIM_TypeDef *timer;
  4619. const PLSR_PLATFORM_TIMER_SETTING *next;
  4620. counter->DIER &= ~TIM_DIER_CC1IE;
  4621. if (PlsrFiniteStreamActive[pulseOutput] != 0U)
  4622. {
  4623. PLSR_PLATFORM_TIMER_SETTING streamSetting;
  4624. uint32_t streamPulses = 0UL;
  4625. uint8_t startsNextSegment = 0U;
  4626. uint8_t takeResult;
  4627. if ((PlsrFiniteStreamNextValid[pulseOutput] != 0U)
  4628. || (PlsrFiniteStreamSourceDone[pulseOutput] != 0U)
  4629. || (PlsrFiniteStreamSourceFault[pulseOutput] != 0U))
  4630. {
  4631. return;
  4632. }
  4633. takeResult = PlsrExecTakeCountedRunIrq(
  4634. pulseOutput, &streamSetting, &streamPulses,
  4635. &startsNextSegment);
  4636. if (takeResult == PLSR_EXEC_RUN_DONE)
  4637. {
  4638. PlsrFiniteStreamSourceDone[pulseOutput] = 1U;
  4639. return;
  4640. }
  4641. if ((takeResult != PLSR_EXEC_RUN_READY)
  4642. || (streamPulses == 0UL)
  4643. || (PlsrPreparedSettingIsValid(
  4644. pulseOutput, PLSR_OUTPUT_PULSE_DIR,
  4645. &streamSetting) == 0U))
  4646. {
  4647. PlsrFiniteStreamSourceFault[pulseOutput] = 1U;
  4648. PlsrExecCountedStreamFaultIrq(pulseOutput);
  4649. return;
  4650. }
  4651. timer = PlsrTimerMap[pulseOutput].timer;
  4652. timer->PSC = streamSetting.prescaler;
  4653. timer->ARR = streamSetting.period;
  4654. timer->CCR1 = streamSetting.compare;
  4655. PlsrTimerQueuedSetting[pulseOutput] = streamSetting;
  4656. PlsrTimerQueuedFrequencyHz[pulseOutput] =
  4657. streamSetting.actualFrequencyHz;
  4658. PlsrFiniteStreamNextSetting[pulseOutput] = streamSetting;
  4659. PlsrFiniteStreamNextPulses[pulseOutput] = streamPulses;
  4660. PlsrFiniteStreamNextStartsSegment[pulseOutput] =
  4661. startsNextSegment;
  4662. PlsrFiniteStreamNextValid[pulseOutput] = 1U;
  4663. return;
  4664. }
  4665. if (nextIndex >= PlsrFiniteStepCount[pulseOutput])
  4666. {
  4667. return;
  4668. }
  4669. timer = PlsrTimerMap[pulseOutput].timer;
  4670. next = &PlsrFiniteSteps[pulseOutput][nextIndex].setting;
  4671. timer->PSC = next->prescaler;
  4672. timer->ARR = next->period;
  4673. timer->CCR1 = next->compare;
  4674. PlsrTimerQueuedSetting[pulseOutput] = *next;
  4675. PlsrTimerQueuedFrequencyHz[pulseOutput] = next->actualFrequencyHz;
  4676. }
  4677. static void PlsrFiniteCounterIrq(uint8_t pulseOutput,
  4678. TIM_TypeDef *counter)
  4679. {
  4680. uint32_t completedBlock =
  4681. (PlsrFiniteRemainingPulses[pulseOutput]
  4682. > PLSR_COUNTER_BLOCK_PULSES)
  4683. ? PLSR_COUNTER_BLOCK_PULSES
  4684. : PlsrFiniteRemainingPulses[pulseOutput];
  4685. PlsrFiniteRemainingPulses[pulseOutput] -= completedBlock;
  4686. if (PlsrFiniteRemainingPulses[pulseOutput] != 0UL)
  4687. {
  4688. uint32_t nextBlock =
  4689. (PlsrFiniteRemainingPulses[pulseOutput]
  4690. > PLSR_COUNTER_BLOCK_PULSES)
  4691. ? PLSR_COUNTER_BLOCK_PULSES
  4692. : PlsrFiniteRemainingPulses[pulseOutput];
  4693. PlsrCounterOverflowPulses[PlsrCounterIndexByOutput[pulseOutput]] +=
  4694. completedBlock;
  4695. counter->ARR = (nextBlock == 1UL) ? 1UL : (nextBlock - 1UL);
  4696. PlsrFiniteCounterPreload[pulseOutput] =
  4697. (nextBlock == 1UL) ? 1U : 0U;
  4698. counter->CNT = PlsrFiniteCounterPreload[pulseOutput];
  4699. PlsrFiniteArmNextStepPrepare(pulseOutput, counter, nextBlock);
  4700. return;
  4701. }
  4702. if (PlsrFiniteStreamActive[pulseOutput] != 0U)
  4703. {
  4704. PlsrObservedPulseBase[pulseOutput] +=
  4705. PlsrFiniteTargetPulses[pulseOutput];
  4706. PlsrObservedPulsePublished[pulseOutput] =
  4707. PlsrObservedPulseBase[pulseOutput];
  4708. if (PlsrFiniteStreamNextValid[pulseOutput] != 0U)
  4709. {
  4710. uint32_t nextPulses =
  4711. PlsrFiniteStreamNextPulses[pulseOutput];
  4712. uint32_t firstBlock =
  4713. (nextPulses > PLSR_COUNTER_BLOCK_PULSES)
  4714. ? PLSR_COUNTER_BLOCK_PULSES : nextPulses;
  4715. if (PlsrFiniteStreamNextStartsSegment[pulseOutput] != 0U)
  4716. {
  4717. /* 段边界回调只传"到当前 run 完成为止的累计计数"(IRQ 内
  4718. 已累加完成的 base),执行器只置事件,不做簿记。 */
  4719. PlsrExecCountedSegmentBoundaryIrq(
  4720. pulseOutput, PlsrObservedPulseBase[pulseOutput]);
  4721. }
  4722. PlsrFiniteTargetPulses[pulseOutput] = nextPulses;
  4723. PlsrFiniteRemainingPulses[pulseOutput] = nextPulses;
  4724. PlsrCounterOverflowPulses[
  4725. PlsrCounterIndexByOutput[pulseOutput]] = 0UL;
  4726. counter->ARR = (firstBlock == 1UL)
  4727. ? 1UL : (firstBlock - 1UL);
  4728. PlsrFiniteCounterPreload[pulseOutput] =
  4729. (firstBlock == 1UL) ? 1U : 0U;
  4730. counter->CNT = PlsrFiniteCounterPreload[pulseOutput];
  4731. PlsrTimerActiveSetting[pulseOutput] =
  4732. PlsrFiniteStreamNextSetting[pulseOutput];
  4733. PlsrTimerActiveFrequencyHz[pulseOutput] =
  4734. PlsrFiniteStreamNextSetting[pulseOutput].actualFrequencyHz;
  4735. PlsrFiniteStreamNextValid[pulseOutput] = 0U;
  4736. PlsrFiniteStreamNextStartsSegment[pulseOutput] = 0U;
  4737. PlsrFiniteArmNextStepPrepare(pulseOutput, counter, firstBlock);
  4738. return;
  4739. }
  4740. }
  4741. else if (PlsrFiniteStepCount[pulseOutput] != 0U)
  4742. {
  4743. uint16_t completedIndex = PlsrFiniteStepIndex[pulseOutput];
  4744. uint16_t nextIndex = (uint16_t)(completedIndex + 1U);
  4745. uint8_t hasNext = (nextIndex
  4746. < PlsrFiniteStepCount[pulseOutput]) ? 1U : 0U;
  4747. PlsrObservedPulseBase[pulseOutput] +=
  4748. PlsrFiniteTargetPulses[pulseOutput];
  4749. PlsrObservedPulsePublished[pulseOutput] =
  4750. PlsrObservedPulseBase[pulseOutput];
  4751. PlsrFiniteCompletedStepCount[pulseOutput] =
  4752. (uint16_t)(completedIndex + 1U);
  4753. if (hasNext != 0U)
  4754. {
  4755. const PLSR_PLATFORM_FINITE_STEP *next =
  4756. &PlsrFiniteSteps[pulseOutput][nextIndex];
  4757. uint32_t firstBlock =
  4758. (next->pulseCount > PLSR_COUNTER_BLOCK_PULSES)
  4759. ? PLSR_COUNTER_BLOCK_PULSES : next->pulseCount;
  4760. PlsrFiniteStepIndex[pulseOutput] = nextIndex;
  4761. PlsrFiniteTargetPulses[pulseOutput] = next->pulseCount;
  4762. PlsrFiniteRemainingPulses[pulseOutput] = next->pulseCount;
  4763. PlsrCounterOverflowPulses[
  4764. PlsrCounterIndexByOutput[pulseOutput]] = 0UL;
  4765. counter->ARR = (firstBlock == 1UL)
  4766. ? 1UL : (firstBlock - 1UL);
  4767. PlsrFiniteCounterPreload[pulseOutput] =
  4768. (firstBlock == 1UL) ? 1U : 0U;
  4769. counter->CNT = PlsrFiniteCounterPreload[pulseOutput];
  4770. PlsrTimerActiveSetting[pulseOutput] = next->setting;
  4771. PlsrTimerActiveFrequencyHz[pulseOutput] =
  4772. next->setting.actualFrequencyHz;
  4773. PlsrTimerQueuedSetting[pulseOutput] = next->setting;
  4774. PlsrTimerQueuedFrequencyHz[pulseOutput] =
  4775. next->setting.actualFrequencyHz;
  4776. PlsrFiniteArmNextStepPrepare(pulseOutput, counter, firstBlock);
  4777. return;
  4778. }
  4779. }
  4780. counter->DIER = 0UL;
  4781. counter->CR1 &= ~TIM_CR1_CEN;
  4782. counter->SMCR &= ~(TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1 | TIM_SMCR_SMS_0);
  4783. /*
  4784. * An OC rising edge is the terminal pulse's falling edge because the
  4785. * output stage is active low. The target-count update IRQ therefore is
  4786. * already the safe idle boundary: stop here before CCR1 can start an
  4787. * extra terminal pulse.
  4788. */
  4789. PlsrFiniteStopAtFallingEdge(pulseOutput);
  4790. }
  4791. static void PlsrFiniteRetargetAtFallingEdge(uint8_t pulseOutput)
  4792. {
  4793. uint8_t counterIndex = PlsrCounterIndexByOutput[pulseOutput];
  4794. TIM_TypeDef *counter = PlsrCounters[counterIndex];
  4795. TIM_TypeDef *timer = PlsrTimerMap[pulseOutput].timer;
  4796. uint32_t drainPulses = PlsrFiniteRetargetDrainPulses[pulseOutput];
  4797. uint32_t blockCount;
  4798. uint32_t completed;
  4799. PlsrFiniteRetargetPending[pulseOutput] = 0U;
  4800. PlsrFiniteRetargetDrainPulses[pulseOutput] = 0UL;
  4801. timer->DIER &= ~TIM_DIER_CC1IE;
  4802. PlsrCounterSuspend(pulseOutput);
  4803. blockCount = (uint16_t)counter->CNT;
  4804. if (blockCount >= PlsrFiniteCounterPreload[pulseOutput])
  4805. {
  4806. blockCount -= PlsrFiniteCounterPreload[pulseOutput];
  4807. }
  4808. completed = PlsrFiniteTargetPulses[pulseOutput]
  4809. - PlsrFiniteRemainingPulses[pulseOutput] + blockCount;
  4810. if (PlsrFiniteStepCount[pulseOutput] != 0U)
  4811. {
  4812. completed += PlsrFiniteSteps[pulseOutput][
  4813. PlsrFiniteStepIndex[pulseOutput]].segmentPulseOffset;
  4814. }
  4815. if (completed > PlsrFiniteTargetPulses[pulseOutput])
  4816. {
  4817. completed = PlsrFiniteTargetPulses[pulseOutput];
  4818. }
  4819. PlsrFiniteTargetPulses[pulseOutput] = completed + drainPulses;
  4820. PlsrFiniteRemainingPulses[pulseOutput] = drainPulses;
  4821. PlsrFiniteStepCount[pulseOutput] = 0U;
  4822. PlsrFiniteStepIndex[pulseOutput] = 0U;
  4823. PlsrFiniteBoundaryReadIndex[pulseOutput] = 0U;
  4824. PlsrFiniteCompletedStepCount[pulseOutput] = 0U;
  4825. counter->ARR = (drainPulses == 1UL) ? 1UL : (drainPulses - 1UL);
  4826. PlsrFiniteCounterPreload[pulseOutput] =
  4827. (drainPulses == 1UL) ? 1U : 0U;
  4828. counter->CNT = 0UL;
  4829. counter->EGR = TIM_EGR_UG;
  4830. counter->CNT = PlsrFiniteCounterPreload[pulseOutput];
  4831. counter->SR = 0UL;
  4832. counter->DIER = TIM_DIER_UIE;
  4833. PlsrCounterBegin(pulseOutput);
  4834. }
  4835. static void PlsrFiniteCutAtFallingEdge(uint8_t pulseOutput)
  4836. {
  4837. uint8_t counterIndex = PlsrCounterIndexByOutput[pulseOutput];
  4838. TIM_TypeDef *counter = PlsrCounters[counterIndex];
  4839. uint32_t blockCount;
  4840. uint32_t completed;
  4841. /* Freeze the external counter at the same falling edge that makes the
  4842. pulse output idle, then convert the partial current run into the
  4843. terminal run consumed by PlsrPlatformTakeFiniteCompletion(). */
  4844. PlsrCounterSuspend(pulseOutput);
  4845. blockCount = (uint16_t)counter->CNT;
  4846. if (blockCount >= PlsrFiniteCounterPreload[pulseOutput])
  4847. {
  4848. blockCount -= PlsrFiniteCounterPreload[pulseOutput];
  4849. }
  4850. else
  4851. {
  4852. blockCount = 0UL;
  4853. }
  4854. completed = PlsrFiniteTargetPulses[pulseOutput]
  4855. - PlsrFiniteRemainingPulses[pulseOutput] + blockCount;
  4856. if (completed > PlsrFiniteTargetPulses[pulseOutput])
  4857. {
  4858. completed = PlsrFiniteTargetPulses[pulseOutput];
  4859. }
  4860. PlsrObservedPulseBase[pulseOutput] += completed;
  4861. PlsrObservedPulsePublished[pulseOutput] =
  4862. PlsrObservedPulseBase[pulseOutput];
  4863. PlsrFiniteTargetPulses[pulseOutput] = completed;
  4864. PlsrFiniteRemainingPulses[pulseOutput] = 0UL;
  4865. PlsrFiniteStepCount[pulseOutput] = 0U;
  4866. PlsrFiniteStepIndex[pulseOutput] = 0U;
  4867. PlsrFiniteBoundaryReadIndex[pulseOutput] = 0U;
  4868. PlsrFiniteCompletedStepCount[pulseOutput] = 0U;
  4869. PlsrFiniteStreamNextValid[pulseOutput] = 0U;
  4870. PlsrFiniteStreamNextStartsSegment[pulseOutput] = 0U;
  4871. PlsrCounterOverflowPulses[counterIndex] = 0UL;
  4872. counter->CNT = 0UL;
  4873. counter->SR = 0UL;
  4874. PlsrFiniteStopAtFallingEdge(pulseOutput);
  4875. }
  4876. static void PlsrFiniteStopAtFallingEdge(uint8_t pulseOutput)
  4877. {
  4878. TIM_TypeDef *timer = PlsrTimerMap[pulseOutput].timer;
  4879. /* OC1 and GPIO idle are both high here; hand off without a pin glitch. */
  4880. PlsrPulsePinCaptureIdle(pulseOutput);
  4881. timer->DIER = 0UL;
  4882. timer->CCER &= ~(TIM_CCER_CC1E | TIM_CCER_CC1P);
  4883. timer->CR1 &= ~TIM_CR1_CEN;
  4884. timer->SR = ~(TIM_SR_UIF | TIM_SR_CC1IF);
  4885. PlsrFiniteTailStopPending[pulseOutput] = 0U;
  4886. PlsrFiniteActive[pulseOutput] = 0U;
  4887. PlsrFiniteCompletionPending[pulseOutput] = 1U;
  4888. PlsrFiniteFrequencyPending[pulseOutput] = 0U;
  4889. PlsrFiniteCounterPreload[pulseOutput] = 0U;
  4890. __DSB();
  4891. }
  4892. void TIM1_BRK_TIM9_IRQHandler(void)
  4893. {
  4894. PlsrHandleCounterIrq(0U);
  4895. }
  4896. void TIM8_BRK_TIM12_IRQHandler(void)
  4897. {
  4898. PlsrHandleCounterIrq(1U);
  4899. }
  4900. #endif /* PLSR_HOST_TEST */