Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

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