Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 
 

1203 lignes
33 KiB

  1. #include "plsr_platform.h"
  2. #include "plsr.h"
  3. #ifdef PLSR_HOST_TEST
  4. #include <string.h>
  5. static uint8_t PlsrHostPulseActive[4];
  6. static uint32_t PlsrHostFrequency[4];
  7. static uint32_t PlsrHostQueuedFrequency[4];
  8. static uint8_t PlsrHostUpdatePending[4];
  9. static uint8_t PlsrHostInputs[2];
  10. static uint8_t PlsrHostSelectedPulse;
  11. static uint8_t PlsrHostDirectionLevel;
  12. static uint8_t PlsrHostEmitPulseOnCriticalEntry;
  13. static uint8_t PlsrHostEmitPulseOnCriticalExit;
  14. static uint8_t PlsrHostLatchPulseOnCriticalEntry;
  15. static uint8_t PlsrHostCriticalEntriesToSkip;
  16. static uint8_t PlsrHostFailNextStart;
  17. static uint8_t PlsrHostFailNextFrequencyAtUpdate;
  18. static PLSR_PERSIST_PAYLOAD PlsrHostPersistentPayload;
  19. static uint8_t PlsrHostPersistentValid;
  20. static uint32_t PlsrHostSaveCount;
  21. static void PlsrHostLatchPulse(uint8_t pulseOutput)
  22. {
  23. if ((pulseOutput <= 3U)
  24. && (PlsrHostPulseActive[pulseOutput] != 0U))
  25. {
  26. PlsrHostFrequency[pulseOutput] =
  27. PlsrHostQueuedFrequency[pulseOutput];
  28. PlsrHostUpdatePending[pulseOutput] = 1U;
  29. }
  30. }
  31. static void PlsrHostServicePendingPulse(uint8_t pulseOutput)
  32. {
  33. if ((pulseOutput <= 3U)
  34. && (PlsrHostUpdatePending[pulseOutput] != 0U))
  35. {
  36. PlsrHostUpdatePending[pulseOutput] = 0U;
  37. PlsrPulseTimerIrq(pulseOutput);
  38. }
  39. }
  40. uint8_t PlsrPlatformInit(void)
  41. {
  42. (void)memset(PlsrHostPulseActive, 0, sizeof(PlsrHostPulseActive));
  43. (void)memset(PlsrHostFrequency, 0, sizeof(PlsrHostFrequency));
  44. (void)memset(PlsrHostQueuedFrequency, 0,
  45. sizeof(PlsrHostQueuedFrequency));
  46. (void)memset(PlsrHostUpdatePending, 0,
  47. sizeof(PlsrHostUpdatePending));
  48. PlsrHostSelectedPulse = 0U;
  49. PlsrHostDirectionLevel = 0U;
  50. PlsrHostEmitPulseOnCriticalEntry = 0U;
  51. PlsrHostEmitPulseOnCriticalExit = 0U;
  52. PlsrHostLatchPulseOnCriticalEntry = 0U;
  53. PlsrHostCriticalEntriesToSkip = 0U;
  54. PlsrHostFailNextStart = 0U;
  55. PlsrHostFailNextFrequencyAtUpdate = 0U;
  56. return 1U;
  57. }
  58. uint8_t PlsrPlatformPrepare(uint8_t pulseOutput,
  59. uint8_t directionOutput,
  60. uint8_t directionLevel)
  61. {
  62. uint8_t index;
  63. (void)directionOutput;
  64. if (PlsrHostFailNextStart != 0U)
  65. {
  66. PlsrHostFailNextStart = 0U;
  67. return 0U;
  68. }
  69. if ((pulseOutput > 3U) || (directionOutput > 3U))
  70. {
  71. return 0U;
  72. }
  73. for (index = 0U; index < 4U; index++)
  74. {
  75. PlsrHostPulseActive[index] = 0U;
  76. PlsrHostFrequency[index] = 0UL;
  77. PlsrHostQueuedFrequency[index] = 0UL;
  78. PlsrHostUpdatePending[index] = 0U;
  79. }
  80. PlsrHostSelectedPulse = pulseOutput;
  81. PlsrHostDirectionLevel = (directionLevel != 0U) ? 1U : 0U;
  82. return 1U;
  83. }
  84. uint8_t PlsrPlatformStartPulse(uint8_t pulseOutput,
  85. uint32_t firstFrequencyHz,
  86. uint32_t queuedFrequencyHz,
  87. uint32_t *actualFirstFrequencyHz,
  88. uint32_t *actualQueuedFrequencyHz)
  89. {
  90. if ((pulseOutput > 3U) || (firstFrequencyHz == 0UL)
  91. || (firstFrequencyHz > PLSR_FREQUENCY_MAX_HZ)
  92. || (queuedFrequencyHz == 0UL)
  93. || (queuedFrequencyHz > PLSR_FREQUENCY_MAX_HZ)
  94. || (actualFirstFrequencyHz == NULL)
  95. || (actualQueuedFrequencyHz == NULL))
  96. {
  97. return 0U;
  98. }
  99. PlsrHostPulseActive[pulseOutput] = 1U;
  100. PlsrHostFrequency[pulseOutput] = firstFrequencyHz;
  101. PlsrHostQueuedFrequency[pulseOutput] = queuedFrequencyHz;
  102. PlsrHostUpdatePending[pulseOutput] = 0U;
  103. PlsrHostSelectedPulse = pulseOutput;
  104. *actualFirstFrequencyHz = firstFrequencyHz;
  105. *actualQueuedFrequencyHz = queuedFrequencyHz;
  106. return 1U;
  107. }
  108. uint8_t PlsrPlatformQueueFrequency(uint8_t pulseOutput,
  109. uint32_t frequencyHz,
  110. uint32_t *actualFrequencyHz)
  111. {
  112. if (PlsrHostFailNextFrequencyAtUpdate != 0U)
  113. {
  114. PlsrHostFailNextFrequencyAtUpdate = 0U;
  115. return 0U;
  116. }
  117. if ((pulseOutput > 3U) || (frequencyHz == 0UL)
  118. || (frequencyHz > PLSR_FREQUENCY_MAX_HZ)
  119. || (actualFrequencyHz == NULL)
  120. || (PlsrHostPulseActive[pulseOutput] == 0U))
  121. {
  122. return 0U;
  123. }
  124. PlsrHostQueuedFrequency[pulseOutput] = frequencyHz;
  125. *actualFrequencyHz = frequencyHz;
  126. return 1U;
  127. }
  128. void PlsrPlatformDrainPendingPulse(uint8_t pulseOutput)
  129. {
  130. PlsrHostServicePendingPulse(pulseOutput);
  131. }
  132. uint32_t PlsrPlatformActiveFrequency(uint8_t pulseOutput)
  133. {
  134. return (pulseOutput <= 3U) ? PlsrHostFrequency[pulseOutput] : 0UL;
  135. }
  136. void PlsrPlatformStopPulse(uint8_t pulseOutput)
  137. {
  138. if (pulseOutput <= 3U)
  139. {
  140. PlsrHostPulseActive[pulseOutput] = 0U;
  141. PlsrHostFrequency[pulseOutput] = 0UL;
  142. PlsrHostQueuedFrequency[pulseOutput] = 0UL;
  143. PlsrHostUpdatePending[pulseOutput] = 0U;
  144. }
  145. }
  146. uint8_t PlsrPlatformReadInput(uint8_t inputSelection)
  147. {
  148. return (inputSelection <= 1U) ? PlsrHostInputs[inputSelection] : 0U;
  149. }
  150. uint8_t PlsrPlatformLoad(PLSR_PERSIST_PAYLOAD *payload)
  151. {
  152. if ((payload == NULL) || (PlsrHostPersistentValid == 0U))
  153. {
  154. return 0U;
  155. }
  156. *payload = PlsrHostPersistentPayload;
  157. return 1U;
  158. }
  159. uint8_t PlsrPlatformSave(const PLSR_PERSIST_PAYLOAD *payload)
  160. {
  161. if (payload == NULL)
  162. {
  163. return 0U;
  164. }
  165. PlsrHostPersistentPayload = *payload;
  166. PlsrHostPersistentValid = 1U;
  167. PlsrHostSaveCount++;
  168. return 1U;
  169. }
  170. void PlsrPlatformCheckpointConfig(const PLSR_CONFIG *config)
  171. {
  172. if (config != NULL)
  173. {
  174. PlsrHostPersistentPayload.config = *config;
  175. PlsrHostPersistentValid = 1U;
  176. }
  177. }
  178. void PlsrPlatformCheckpointPosition(int32_t position,
  179. uint8_t positionValid,
  180. uint8_t wasBusy)
  181. {
  182. PlsrHostPersistentPayload.position = position;
  183. PlsrHostPersistentPayload.positionValid = positionValid;
  184. PlsrHostPersistentPayload.wasBusy = wasBusy;
  185. PlsrHostPersistentPayload.reserved = 0U;
  186. }
  187. uint32_t PlsrPlatformEnterCritical(void)
  188. {
  189. if (PlsrHostEmitPulseOnCriticalEntry != 0U)
  190. {
  191. if (PlsrHostCriticalEntriesToSkip != 0U)
  192. {
  193. PlsrHostCriticalEntriesToSkip--;
  194. }
  195. else
  196. {
  197. PlsrHostEmitPulseOnCriticalEntry = 0U;
  198. PlsrHostLatchPulse(PlsrHostSelectedPulse);
  199. PlsrHostServicePendingPulse(PlsrHostSelectedPulse);
  200. }
  201. }
  202. if (PlsrHostLatchPulseOnCriticalEntry != 0U)
  203. {
  204. PlsrHostLatchPulseOnCriticalEntry = 0U;
  205. PlsrHostLatchPulse(PlsrHostSelectedPulse);
  206. }
  207. return 0UL;
  208. }
  209. void PlsrPlatformExitCritical(uint32_t state)
  210. {
  211. (void)state;
  212. if (PlsrHostEmitPulseOnCriticalExit != 0U)
  213. {
  214. PlsrHostEmitPulseOnCriticalExit = 0U;
  215. PlsrHostLatchPulse(PlsrHostSelectedPulse);
  216. }
  217. PlsrHostServicePendingPulse(PlsrHostSelectedPulse);
  218. }
  219. void PlsrTestSetInput(uint8_t inputSelection, uint8_t level)
  220. {
  221. if (inputSelection <= 1U)
  222. {
  223. PlsrHostInputs[inputSelection] = (level != 0U) ? 1U : 0U;
  224. }
  225. }
  226. void PlsrTestEmitPulses(uint32_t pulseCount)
  227. {
  228. while ((pulseCount != 0UL)
  229. && (PlsrHostPulseActive[PlsrHostSelectedPulse] != 0U))
  230. {
  231. PlsrHostLatchPulse(PlsrHostSelectedPulse);
  232. PlsrHostServicePendingPulse(PlsrHostSelectedPulse);
  233. pulseCount--;
  234. }
  235. }
  236. void PlsrTestEmitPulseOnCriticalEntry(void)
  237. {
  238. PlsrHostCriticalEntriesToSkip = 0U;
  239. PlsrHostEmitPulseOnCriticalEntry = 1U;
  240. }
  241. void PlsrTestEmitPulseAfterCriticalEntries(uint8_t entriesToSkip)
  242. {
  243. PlsrHostCriticalEntriesToSkip = entriesToSkip;
  244. PlsrHostEmitPulseOnCriticalEntry = 1U;
  245. }
  246. void PlsrTestEmitPulseOnCriticalExit(void)
  247. {
  248. PlsrHostEmitPulseOnCriticalExit = 1U;
  249. }
  250. void PlsrTestLatchPulseOnCriticalEntry(void)
  251. {
  252. PlsrHostLatchPulseOnCriticalEntry = 1U;
  253. }
  254. void PlsrTestServicePendingPulse(void)
  255. {
  256. PlsrHostServicePendingPulse(PlsrHostSelectedPulse);
  257. }
  258. void PlsrTestFailNextStart(void)
  259. {
  260. PlsrHostFailNextStart = 1U;
  261. }
  262. void PlsrTestFailNextFrequencyAtUpdate(void)
  263. {
  264. PlsrHostFailNextFrequencyAtUpdate = 1U;
  265. }
  266. uint8_t PlsrTestPulseIsActive(void)
  267. {
  268. return PlsrHostPulseActive[PlsrHostSelectedPulse];
  269. }
  270. uint32_t PlsrTestOutputFrequency(void)
  271. {
  272. return PlsrHostFrequency[PlsrHostSelectedPulse];
  273. }
  274. uint32_t PlsrTestQueuedFrequency(void)
  275. {
  276. return PlsrHostQueuedFrequency[PlsrHostSelectedPulse];
  277. }
  278. uint8_t PlsrTestDirectionLevel(void)
  279. {
  280. return PlsrHostDirectionLevel;
  281. }
  282. void PlsrTestClearPersistentStorage(void)
  283. {
  284. (void)memset(&PlsrHostPersistentPayload, 0,
  285. sizeof(PlsrHostPersistentPayload));
  286. (void)memset(PlsrHostInputs, 0, sizeof(PlsrHostInputs));
  287. PlsrHostPersistentValid = 0U;
  288. PlsrHostSaveCount = 0UL;
  289. }
  290. void PlsrTestResetSaveCount(void)
  291. {
  292. PlsrHostSaveCount = 0UL;
  293. }
  294. uint32_t PlsrTestSaveCount(void)
  295. {
  296. return PlsrHostSaveCount;
  297. }
  298. #else
  299. #include "stm32f4xx_hal.h"
  300. #include <stddef.h>
  301. #include <string.h>
  302. #define PLSR_ENABLE_IRQ_CYCLE_DIAG (0U)
  303. #define PLSR_FLASH_SLOT_A_ADDRESS (0x080C0000UL)
  304. #define PLSR_FLASH_SLOT_B_ADDRESS (0x080E0000UL)
  305. #define PLSR_FLASH_MAGIC (0x50534C52UL)
  306. #define PLSR_FLASH_VERSION (2U)
  307. #define PLSR_BACKUP_CONFIG_ADDRESS (BKPSRAM_BASE + 0x0100UL)
  308. #define PLSR_BACKUP_POSITION_ADDRESS (BKPSRAM_BASE + 0x0200UL)
  309. #define PLSR_BACKUP_CONFIG_MAGIC (0x50434647UL)
  310. #define PLSR_BACKUP_POSITION_MAGIC (0x50504F53UL)
  311. typedef struct
  312. {
  313. TIM_TypeDef *timer;
  314. GPIO_TypeDef *port;
  315. uint16_t pin;
  316. uint8_t pinIndex;
  317. uint8_t alternate;
  318. IRQn_Type irq;
  319. uint32_t timerClockHz;
  320. } PLSR_TIMER_MAP;
  321. typedef struct
  322. {
  323. GPIO_TypeDef *port;
  324. uint16_t pin;
  325. } PLSR_GPIO_MAP;
  326. typedef struct
  327. {
  328. uint32_t prescaler;
  329. uint32_t period;
  330. uint32_t compare;
  331. uint32_t actualFrequencyHz;
  332. } PLSR_TIMER_SETTING;
  333. typedef struct
  334. {
  335. uint32_t magic;
  336. uint16_t version;
  337. uint16_t payloadSize;
  338. uint32_t generation;
  339. PLSR_PERSIST_PAYLOAD payload;
  340. uint32_t crc32;
  341. } PLSR_FLASH_RECORD;
  342. typedef struct
  343. {
  344. uint32_t magic;
  345. PLSR_CONFIG config;
  346. uint32_t crc32;
  347. } PLSR_BACKUP_CONFIG_RECORD;
  348. typedef struct
  349. {
  350. uint32_t magic;
  351. uint32_t generation;
  352. int32_t position;
  353. uint8_t positionValid;
  354. uint8_t wasBusy;
  355. uint16_t reserved;
  356. uint32_t crc32;
  357. } PLSR_BACKUP_POSITION_RECORD;
  358. static const PLSR_TIMER_MAP PlsrTimerMap[4] =
  359. {
  360. {TIM10, GPIOF, GPIO_PIN_6, 6U, GPIO_AF3_TIM10,
  361. TIM1_UP_TIM10_IRQn, 168000000UL},
  362. {TIM13, GPIOF, GPIO_PIN_8, 8U, GPIO_AF9_TIM13,
  363. TIM8_UP_TIM13_IRQn, 84000000UL},
  364. {TIM11, GPIOF, GPIO_PIN_7, 7U, GPIO_AF3_TIM11,
  365. TIM1_TRG_COM_TIM11_IRQn, 168000000UL},
  366. {TIM14, GPIOF, GPIO_PIN_9, 9U, GPIO_AF9_TIM14,
  367. TIM8_TRG_COM_TIM14_IRQn, 84000000UL}
  368. };
  369. static const PLSR_GPIO_MAP PlsrDirectionMap[4] =
  370. {
  371. {GPIOH, GPIO_PIN_9},
  372. {GPIOH, GPIO_PIN_8},
  373. {GPIOH, GPIO_PIN_7},
  374. {GPIOH, GPIO_PIN_6}
  375. };
  376. static PLSR_FLASH_RECORD PlsrFlashRecordBuffer;
  377. static uint32_t PlsrBackupPositionGeneration;
  378. static uint32_t PlsrTimerActiveFrequencyHz[4];
  379. static uint32_t PlsrTimerQueuedFrequencyHz[4];
  380. static uint32_t PlsrTimerQueueGeneration[4];
  381. static void PlsrHandleTimerIrq(uint8_t pulseOutput);
  382. #if PLSR_ENABLE_IRQ_CYCLE_DIAG
  383. volatile uint32_t PlsrIrqCount[4];
  384. volatile uint32_t PlsrIrqLastCycles[4];
  385. volatile uint32_t PlsrIrqMaxCycles[4];
  386. #endif
  387. static uint32_t PlsrCrc32(const void *data, uint32_t length)
  388. {
  389. const uint8_t *bytes = (const uint8_t *)data;
  390. uint32_t crc = 0xFFFFFFFFUL;
  391. uint32_t index;
  392. uint8_t bit;
  393. for (index = 0UL; index < length; index++)
  394. {
  395. crc ^= bytes[index];
  396. for (bit = 0U; bit < 8U; bit++)
  397. {
  398. crc = ((crc & 1UL) != 0UL) ? ((crc >> 1U) ^ 0xEDB88320UL)
  399. : (crc >> 1U);
  400. }
  401. }
  402. return ~crc;
  403. }
  404. static uint8_t PlsrGenerationIsNewer(uint32_t first, uint32_t second)
  405. {
  406. return ((int32_t)(first - second) > 0) ? 1U : 0U;
  407. }
  408. static uint32_t PlsrFlashRecordCrc(const PLSR_FLASH_RECORD *record)
  409. {
  410. const uint8_t *start = (const uint8_t *)&record->version;
  411. uint32_t length = (uint32_t)(offsetof(PLSR_FLASH_RECORD, crc32)
  412. - offsetof(PLSR_FLASH_RECORD, version));
  413. return PlsrCrc32(start, length);
  414. }
  415. static uint8_t PlsrFlashRecordIsValid(const PLSR_FLASH_RECORD *record)
  416. {
  417. return ((record->magic == PLSR_FLASH_MAGIC)
  418. && (record->version == PLSR_FLASH_VERSION)
  419. && (record->payloadSize == sizeof(PLSR_PERSIST_PAYLOAD))
  420. && (record->crc32 == PlsrFlashRecordCrc(record))) ? 1U : 0U;
  421. }
  422. static uint8_t PlsrBackupConfigIsValid(
  423. const PLSR_BACKUP_CONFIG_RECORD *record)
  424. {
  425. return ((record->magic == PLSR_BACKUP_CONFIG_MAGIC)
  426. && (record->crc32
  427. == PlsrCrc32(&record->config, sizeof(record->config)))) ? 1U : 0U;
  428. }
  429. static uint8_t PlsrBackupPositionIsValid(
  430. const PLSR_BACKUP_POSITION_RECORD *record)
  431. {
  432. uint32_t crc = PlsrCrc32(&record->generation,
  433. sizeof(record->generation)
  434. + sizeof(record->position)
  435. + sizeof(record->positionValid)
  436. + sizeof(record->wasBusy)
  437. + sizeof(record->reserved));
  438. return ((record->magic == PLSR_BACKUP_POSITION_MAGIC)
  439. && (record->crc32 == crc)) ? 1U : 0U;
  440. }
  441. static const PLSR_BACKUP_POSITION_RECORD *PlsrNewestBackupPosition(void)
  442. {
  443. const PLSR_BACKUP_POSITION_RECORD *slots =
  444. (const PLSR_BACKUP_POSITION_RECORD *)PLSR_BACKUP_POSITION_ADDRESS;
  445. uint8_t validA = PlsrBackupPositionIsValid(&slots[0]);
  446. uint8_t validB = PlsrBackupPositionIsValid(&slots[1]);
  447. if ((validA == 0U) && (validB == 0U))
  448. {
  449. return NULL;
  450. }
  451. if (validA == 0U)
  452. {
  453. return &slots[1];
  454. }
  455. if (validB == 0U)
  456. {
  457. return &slots[0];
  458. }
  459. return (PlsrGenerationIsNewer(slots[1].generation,
  460. slots[0].generation) != 0U)
  461. ? &slots[1] : &slots[0];
  462. }
  463. static void PlsrTimerStop(TIM_TypeDef *timer)
  464. {
  465. timer->DIER &= ~TIM_DIER_UIE;
  466. timer->CR1 &= ~TIM_CR1_CEN;
  467. timer->CCER &= ~TIM_CCER_CC1E;
  468. timer->SR = ~TIM_SR_UIF;
  469. }
  470. static void PlsrTimerInitialize(TIM_TypeDef *timer)
  471. {
  472. timer->CR1 = TIM_CR1_ARPE | TIM_CR1_URS;
  473. timer->CR2 = 0UL;
  474. timer->SMCR = 0UL;
  475. timer->DIER = 0UL;
  476. timer->CCMR1 = TIM_CCMR1_OC1PE | (6UL << TIM_CCMR1_OC1M_Pos);
  477. timer->CCER = 0UL;
  478. timer->PSC = 0UL;
  479. timer->ARR = 999UL;
  480. timer->CCR1 = 500UL;
  481. timer->CNT = 0UL;
  482. timer->EGR = TIM_EGR_UG;
  483. timer->SR = 0UL;
  484. }
  485. static void PlsrPulsePinHoldIdle(uint8_t pulseOutput)
  486. {
  487. const PLSR_TIMER_MAP *map = &PlsrTimerMap[pulseOutput];
  488. GPIO_InitTypeDef gpio;
  489. HAL_GPIO_WritePin(map->port, map->pin, GPIO_PIN_SET);
  490. gpio.Pin = map->pin;
  491. gpio.Mode = GPIO_MODE_OUTPUT_PP;
  492. gpio.Pull = GPIO_NOPULL;
  493. gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  494. gpio.Alternate = 0U;
  495. HAL_GPIO_Init(map->port, &gpio);
  496. }
  497. static void PlsrPulsePinCaptureIdle(uint8_t pulseOutput)
  498. {
  499. const PLSR_TIMER_MAP *map = &PlsrTimerMap[pulseOutput];
  500. uint32_t shift = (uint32_t)map->pinIndex * 2UL;
  501. uint32_t mode = map->port->MODER;
  502. /* The update IRQ occurs while PWM is high; switch to GPIO high first. */
  503. map->port->BSRR = map->pin;
  504. mode &= ~(3UL << shift);
  505. mode |= 1UL << shift;
  506. map->port->MODER = mode;
  507. __DSB();
  508. }
  509. static void PlsrPulsePinRelease(uint8_t pulseOutput)
  510. {
  511. const PLSR_TIMER_MAP *map = &PlsrTimerMap[pulseOutput];
  512. GPIO_InitTypeDef gpio;
  513. gpio.Pin = map->pin;
  514. gpio.Mode = GPIO_MODE_AF_PP;
  515. gpio.Pull = GPIO_NOPULL;
  516. gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  517. gpio.Alternate = map->alternate;
  518. HAL_GPIO_Init(map->port, &gpio);
  519. __DSB();
  520. }
  521. static uint8_t PlsrTimerCalculate(uint8_t pulseOutput,
  522. uint32_t frequencyHz,
  523. PLSR_TIMER_SETTING *setting)
  524. {
  525. const PLSR_TIMER_MAP *map;
  526. uint32_t prescalerDivider;
  527. uint32_t denominator;
  528. uint32_t periodCounts;
  529. if ((pulseOutput > 3U) || (frequencyHz == 0UL)
  530. || (frequencyHz > PLSR_FREQUENCY_MAX_HZ)
  531. || (setting == NULL))
  532. {
  533. return 0U;
  534. }
  535. map = &PlsrTimerMap[pulseOutput];
  536. prescalerDivider = (((map->timerClockHz - 1UL) / frequencyHz) >> 16U)
  537. + 1UL;
  538. if (prescalerDivider > 65536UL)
  539. {
  540. return 0U;
  541. }
  542. denominator = prescalerDivider * frequencyHz;
  543. periodCounts = (map->timerClockHz + denominator / 2UL) / denominator;
  544. if (periodCounts < 2UL)
  545. {
  546. periodCounts = 2UL;
  547. }
  548. if (periodCounts > 65536UL)
  549. {
  550. periodCounts = 65536UL;
  551. }
  552. setting->prescaler = prescalerDivider - 1UL;
  553. setting->period = periodCounts - 1UL;
  554. setting->compare = periodCounts / 2UL;
  555. setting->actualFrequencyHz =
  556. map->timerClockHz / (prescalerDivider * periodCounts);
  557. return 1U;
  558. }
  559. static void PlsrTimerWriteSetting(TIM_TypeDef *timer,
  560. const PLSR_TIMER_SETTING *setting)
  561. {
  562. timer->PSC = setting->prescaler;
  563. timer->ARR = setting->period;
  564. timer->CCR1 = setting->compare;
  565. }
  566. uint8_t PlsrPlatformInit(void)
  567. {
  568. GPIO_InitTypeDef gpio;
  569. uint8_t index;
  570. const PLSR_BACKUP_POSITION_RECORD *positionRecord;
  571. __HAL_RCC_GPIOB_CLK_ENABLE();
  572. __HAL_RCC_GPIOF_CLK_ENABLE();
  573. __HAL_RCC_GPIOG_CLK_ENABLE();
  574. __HAL_RCC_GPIOH_CLK_ENABLE();
  575. __HAL_RCC_TIM10_CLK_ENABLE();
  576. __HAL_RCC_TIM11_CLK_ENABLE();
  577. __HAL_RCC_TIM13_CLK_ENABLE();
  578. __HAL_RCC_TIM14_CLK_ENABLE();
  579. __HAL_RCC_PWR_CLK_ENABLE();
  580. HAL_PWR_EnableBkUpAccess();
  581. __HAL_RCC_BKPSRAM_CLK_ENABLE();
  582. if (HAL_PWREx_EnableBkUpReg() != HAL_OK)
  583. {
  584. return 0U;
  585. }
  586. #if PLSR_ENABLE_IRQ_CYCLE_DIAG
  587. CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  588. DWT->CYCCNT = 0UL;
  589. DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
  590. (void)memset((void *)PlsrIrqCount, 0, sizeof(PlsrIrqCount));
  591. (void)memset((void *)PlsrIrqLastCycles, 0, sizeof(PlsrIrqLastCycles));
  592. (void)memset((void *)PlsrIrqMaxCycles, 0, sizeof(PlsrIrqMaxCycles));
  593. #endif
  594. HAL_GPIO_WritePin(GPIOH, GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8
  595. | GPIO_PIN_9, GPIO_PIN_SET);
  596. gpio.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9;
  597. gpio.Mode = GPIO_MODE_OUTPUT_PP;
  598. gpio.Pull = GPIO_NOPULL;
  599. gpio.Speed = GPIO_SPEED_FREQ_HIGH;
  600. gpio.Alternate = 0U;
  601. HAL_GPIO_Init(GPIOH, &gpio);
  602. gpio.Mode = GPIO_MODE_INPUT;
  603. gpio.Pull = GPIO_NOPULL;
  604. gpio.Speed = GPIO_SPEED_FREQ_LOW;
  605. gpio.Alternate = 0U;
  606. gpio.Pin = GPIO_PIN_5;
  607. HAL_GPIO_Init(GPIOB, &gpio);
  608. gpio.Pin = GPIO_PIN_12;
  609. HAL_GPIO_Init(GPIOG, &gpio);
  610. for (index = 0U; index < 4U; index++)
  611. {
  612. PlsrTimerActiveFrequencyHz[index] = 0UL;
  613. PlsrTimerQueuedFrequencyHz[index] = 0UL;
  614. PlsrTimerQueueGeneration[index] = 0UL;
  615. PlsrTimerInitialize(PlsrTimerMap[index].timer);
  616. PlsrPulsePinHoldIdle(index);
  617. HAL_NVIC_SetPriority(PlsrTimerMap[index].irq, 1U, 0U);
  618. HAL_NVIC_EnableIRQ(PlsrTimerMap[index].irq);
  619. }
  620. positionRecord = PlsrNewestBackupPosition();
  621. PlsrBackupPositionGeneration =
  622. (positionRecord == NULL) ? 0UL : positionRecord->generation;
  623. return 1U;
  624. }
  625. uint8_t PlsrPlatformPrepare(uint8_t pulseOutput,
  626. uint8_t directionOutput,
  627. uint8_t directionLevel)
  628. {
  629. uint8_t index;
  630. if ((pulseOutput > 3U) || (directionOutput > 3U))
  631. {
  632. return 0U;
  633. }
  634. for (index = 0U; index < 4U; index++)
  635. {
  636. PlsrPulsePinHoldIdle(index);
  637. PlsrTimerStop(PlsrTimerMap[index].timer);
  638. HAL_GPIO_WritePin(PlsrDirectionMap[index].port,
  639. PlsrDirectionMap[index].pin,
  640. GPIO_PIN_SET);
  641. }
  642. if (directionLevel != 0U)
  643. {
  644. HAL_GPIO_WritePin(PlsrDirectionMap[directionOutput].port,
  645. PlsrDirectionMap[directionOutput].pin,
  646. GPIO_PIN_RESET);
  647. }
  648. return 1U;
  649. }
  650. uint8_t PlsrPlatformStartPulse(uint8_t pulseOutput,
  651. uint32_t firstFrequencyHz,
  652. uint32_t queuedFrequencyHz,
  653. uint32_t *actualFirstFrequencyHz,
  654. uint32_t *actualQueuedFrequencyHz)
  655. {
  656. TIM_TypeDef *timer;
  657. PLSR_TIMER_SETTING firstSetting;
  658. PLSR_TIMER_SETTING queuedSetting;
  659. if ((actualFirstFrequencyHz == NULL)
  660. || (actualQueuedFrequencyHz == NULL)
  661. || (PlsrTimerCalculate(pulseOutput, firstFrequencyHz,
  662. &firstSetting) == 0U)
  663. || (PlsrTimerCalculate(pulseOutput, queuedFrequencyHz,
  664. &queuedSetting) == 0U))
  665. {
  666. return 0U;
  667. }
  668. timer = PlsrTimerMap[pulseOutput].timer;
  669. timer->DIER &= ~TIM_DIER_UIE;
  670. timer->CR1 &= ~TIM_CR1_CEN;
  671. timer->CCER &= ~TIM_CCER_CC1E;
  672. timer->CNT = 0UL;
  673. PlsrTimerWriteSetting(timer, &firstSetting);
  674. timer->EGR = TIM_EGR_UG;
  675. PlsrTimerWriteSetting(timer, &queuedSetting);
  676. timer->SR = 0UL;
  677. timer->CCER |= TIM_CCER_CC1E;
  678. __DSB();
  679. timer->DIER |= TIM_DIER_UIE;
  680. PlsrPulsePinRelease(pulseOutput);
  681. timer->CR1 |= TIM_CR1_CEN;
  682. PlsrTimerActiveFrequencyHz[pulseOutput] =
  683. firstSetting.actualFrequencyHz;
  684. PlsrTimerQueuedFrequencyHz[pulseOutput] =
  685. queuedSetting.actualFrequencyHz;
  686. PlsrTimerQueueGeneration[pulseOutput]++;
  687. *actualFirstFrequencyHz = firstSetting.actualFrequencyHz;
  688. *actualQueuedFrequencyHz = queuedSetting.actualFrequencyHz;
  689. return 1U;
  690. }
  691. uint8_t PlsrPlatformQueueFrequency(uint8_t pulseOutput,
  692. uint32_t frequencyHz,
  693. uint32_t *actualFrequencyHz)
  694. {
  695. TIM_TypeDef *timer;
  696. PLSR_TIMER_SETTING setting;
  697. uint32_t counterBefore;
  698. uint32_t counterAfter;
  699. uint32_t counterFinal;
  700. uint32_t criticalState;
  701. uint32_t generationBefore;
  702. uint32_t ownGeneration;
  703. uint8_t wrappedWhileUpdatesDisabled;
  704. if ((pulseOutput > 3U) || (actualFrequencyHz == NULL)
  705. || (PlsrTimerCalculate(pulseOutput, frequencyHz, &setting) == 0U))
  706. {
  707. return 0U;
  708. }
  709. timer = PlsrTimerMap[pulseOutput].timer;
  710. if ((timer->CR1 & TIM_CR1_CEN) == 0UL)
  711. {
  712. return 0U;
  713. }
  714. criticalState = PlsrPlatformEnterCritical();
  715. generationBefore = PlsrTimerQueueGeneration[pulseOutput];
  716. if ((timer->SR & TIM_SR_UIF) != 0UL)
  717. {
  718. PlsrHandleTimerIrq(pulseOutput);
  719. if (PlsrTimerQueueGeneration[pulseOutput] != generationBefore)
  720. {
  721. *actualFrequencyHz = PlsrTimerQueuedFrequencyHz[pulseOutput];
  722. PlsrPlatformExitCritical(criticalState);
  723. return 1U;
  724. }
  725. if ((timer->CR1 & TIM_CR1_CEN) == 0UL)
  726. {
  727. PlsrPlatformExitCritical(criticalState);
  728. return 0U;
  729. }
  730. }
  731. /* UDIS blocks shadow transfers while the three preload registers are
  732. replaced. The counter and PWM output continue without interruption. */
  733. counterBefore = timer->CNT;
  734. timer->CR1 |= TIM_CR1_UDIS;
  735. __DMB();
  736. if ((timer->SR & TIM_SR_UIF) != 0UL)
  737. {
  738. timer->CR1 &= ~TIM_CR1_UDIS;
  739. PlsrHandleTimerIrq(pulseOutput);
  740. if ((PlsrTimerQueueGeneration[pulseOutput] != generationBefore)
  741. || ((timer->CR1 & TIM_CR1_CEN) == 0UL))
  742. {
  743. uint8_t stillRunning =
  744. ((timer->CR1 & TIM_CR1_CEN) != 0UL) ? 1U : 0U;
  745. *actualFrequencyHz = PlsrTimerQueuedFrequencyHz[pulseOutput];
  746. PlsrPlatformExitCritical(criticalState);
  747. return stillRunning;
  748. }
  749. counterBefore = timer->CNT;
  750. timer->CR1 |= TIM_CR1_UDIS;
  751. __DMB();
  752. }
  753. PlsrTimerWriteSetting(timer, &setting);
  754. __DMB();
  755. PlsrTimerQueuedFrequencyHz[pulseOutput] = setting.actualFrequencyHz;
  756. PlsrTimerQueueGeneration[pulseOutput]++;
  757. ownGeneration = PlsrTimerQueueGeneration[pulseOutput];
  758. counterAfter = timer->CNT;
  759. timer->CR1 &= ~TIM_CR1_UDIS;
  760. __DMB();
  761. counterFinal = timer->CNT;
  762. /* With UDIS set an overflow does not set UIF. A wrapped counter proves
  763. that its real output edge occurred, so account for that edge once. */
  764. wrappedWhileUpdatesDisabled =
  765. ((counterAfter < counterBefore)
  766. || ((counterFinal < counterAfter)
  767. && ((timer->SR & TIM_SR_UIF) == 0UL))) ? 1U : 0U;
  768. if (wrappedWhileUpdatesDisabled != 0U)
  769. {
  770. PlsrPulseTimerIrq(pulseOutput);
  771. }
  772. else if ((timer->SR & TIM_SR_UIF) != 0UL)
  773. {
  774. PlsrHandleTimerIrq(pulseOutput);
  775. }
  776. *actualFrequencyHz =
  777. (PlsrTimerQueueGeneration[pulseOutput] == ownGeneration)
  778. ? setting.actualFrequencyHz
  779. : PlsrTimerQueuedFrequencyHz[pulseOutput];
  780. PlsrPlatformExitCritical(criticalState);
  781. return 1U;
  782. }
  783. void PlsrPlatformDrainPendingPulse(uint8_t pulseOutput)
  784. {
  785. if (pulseOutput <= 3U)
  786. {
  787. PlsrHandleTimerIrq(pulseOutput);
  788. }
  789. }
  790. uint32_t PlsrPlatformActiveFrequency(uint8_t pulseOutput)
  791. {
  792. return (pulseOutput <= 3U)
  793. ? PlsrTimerActiveFrequencyHz[pulseOutput] : 0UL;
  794. }
  795. void PlsrPlatformStopPulse(uint8_t pulseOutput)
  796. {
  797. if (pulseOutput <= 3U)
  798. {
  799. PlsrPulsePinCaptureIdle(pulseOutput);
  800. PlsrTimerStop(PlsrTimerMap[pulseOutput].timer);
  801. PlsrTimerActiveFrequencyHz[pulseOutput] = 0UL;
  802. PlsrTimerQueuedFrequencyHz[pulseOutput] = 0UL;
  803. PlsrTimerQueueGeneration[pulseOutput]++;
  804. }
  805. }
  806. uint8_t PlsrPlatformReadInput(uint8_t inputSelection)
  807. {
  808. if (inputSelection == 0U)
  809. {
  810. return (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5) == GPIO_PIN_SET) ? 1U : 0U;
  811. }
  812. if (inputSelection == 1U)
  813. {
  814. return (HAL_GPIO_ReadPin(GPIOG, GPIO_PIN_12) == GPIO_PIN_SET) ? 1U : 0U;
  815. }
  816. return 0U;
  817. }
  818. uint8_t PlsrPlatformLoad(PLSR_PERSIST_PAYLOAD *payload)
  819. {
  820. const PLSR_FLASH_RECORD *slotA =
  821. (const PLSR_FLASH_RECORD *)PLSR_FLASH_SLOT_A_ADDRESS;
  822. const PLSR_FLASH_RECORD *slotB =
  823. (const PLSR_FLASH_RECORD *)PLSR_FLASH_SLOT_B_ADDRESS;
  824. const PLSR_FLASH_RECORD *selected = NULL;
  825. const PLSR_BACKUP_CONFIG_RECORD *backupConfig =
  826. (const PLSR_BACKUP_CONFIG_RECORD *)PLSR_BACKUP_CONFIG_ADDRESS;
  827. const PLSR_BACKUP_POSITION_RECORD *backupPosition;
  828. uint8_t validA;
  829. uint8_t validB;
  830. uint8_t haveConfig = 0U;
  831. if (payload == NULL)
  832. {
  833. return 0U;
  834. }
  835. validA = PlsrFlashRecordIsValid(slotA);
  836. validB = PlsrFlashRecordIsValid(slotB);
  837. if ((validA != 0U) && (validB != 0U))
  838. {
  839. selected = (PlsrGenerationIsNewer(slotB->generation,
  840. slotA->generation) != 0U)
  841. ? slotB : slotA;
  842. }
  843. else if (validA != 0U)
  844. {
  845. selected = slotA;
  846. }
  847. else if (validB != 0U)
  848. {
  849. selected = slotB;
  850. }
  851. if (selected != NULL)
  852. {
  853. *payload = selected->payload;
  854. haveConfig = 1U;
  855. }
  856. else
  857. {
  858. (void)memset(payload, 0, sizeof(*payload));
  859. }
  860. if (PlsrBackupConfigIsValid(backupConfig) != 0U)
  861. {
  862. payload->config = backupConfig->config;
  863. haveConfig = 1U;
  864. }
  865. backupPosition = PlsrNewestBackupPosition();
  866. if (backupPosition != NULL)
  867. {
  868. payload->position = backupPosition->position;
  869. payload->positionValid = backupPosition->positionValid;
  870. payload->wasBusy = backupPosition->wasBusy;
  871. }
  872. return haveConfig;
  873. }
  874. uint8_t PlsrPlatformSave(const PLSR_PERSIST_PAYLOAD *payload)
  875. {
  876. const PLSR_FLASH_RECORD *slotA =
  877. (const PLSR_FLASH_RECORD *)PLSR_FLASH_SLOT_A_ADDRESS;
  878. const PLSR_FLASH_RECORD *slotB =
  879. (const PLSR_FLASH_RECORD *)PLSR_FLASH_SLOT_B_ADDRESS;
  880. uint8_t validA;
  881. uint8_t validB;
  882. uint32_t newestGeneration = 0UL;
  883. uint32_t targetAddress;
  884. uint32_t targetSector;
  885. uint32_t sectorError;
  886. uint32_t index;
  887. uint32_t wordCount;
  888. const uint32_t *words;
  889. FLASH_EraseInitTypeDef erase;
  890. HAL_StatusTypeDef status = HAL_OK;
  891. if (payload == NULL)
  892. {
  893. return 0U;
  894. }
  895. validA = PlsrFlashRecordIsValid(slotA);
  896. validB = PlsrFlashRecordIsValid(slotB);
  897. if ((validA != 0U) && (validB != 0U))
  898. {
  899. if (PlsrGenerationIsNewer(slotB->generation, slotA->generation) != 0U)
  900. {
  901. newestGeneration = slotB->generation;
  902. targetAddress = PLSR_FLASH_SLOT_A_ADDRESS;
  903. targetSector = FLASH_SECTOR_10;
  904. }
  905. else
  906. {
  907. newestGeneration = slotA->generation;
  908. targetAddress = PLSR_FLASH_SLOT_B_ADDRESS;
  909. targetSector = FLASH_SECTOR_11;
  910. }
  911. }
  912. else if (validA != 0U)
  913. {
  914. newestGeneration = slotA->generation;
  915. targetAddress = PLSR_FLASH_SLOT_B_ADDRESS;
  916. targetSector = FLASH_SECTOR_11;
  917. }
  918. else if (validB != 0U)
  919. {
  920. newestGeneration = slotB->generation;
  921. targetAddress = PLSR_FLASH_SLOT_A_ADDRESS;
  922. targetSector = FLASH_SECTOR_10;
  923. }
  924. else
  925. {
  926. targetAddress = PLSR_FLASH_SLOT_A_ADDRESS;
  927. targetSector = FLASH_SECTOR_10;
  928. }
  929. (void)memset(&PlsrFlashRecordBuffer, 0, sizeof(PlsrFlashRecordBuffer));
  930. PlsrFlashRecordBuffer.magic = PLSR_FLASH_MAGIC;
  931. PlsrFlashRecordBuffer.version = PLSR_FLASH_VERSION;
  932. PlsrFlashRecordBuffer.payloadSize = sizeof(PLSR_PERSIST_PAYLOAD);
  933. PlsrFlashRecordBuffer.generation = newestGeneration + 1UL;
  934. PlsrFlashRecordBuffer.payload = *payload;
  935. PlsrFlashRecordBuffer.crc32 = PlsrFlashRecordCrc(&PlsrFlashRecordBuffer);
  936. if (HAL_FLASH_Unlock() != HAL_OK)
  937. {
  938. return 0U;
  939. }
  940. __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR
  941. | FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR
  942. | FLASH_FLAG_PGSERR);
  943. erase.TypeErase = FLASH_TYPEERASE_SECTORS;
  944. erase.VoltageRange = FLASH_VOLTAGE_RANGE_3;
  945. erase.Sector = targetSector;
  946. erase.NbSectors = 1U;
  947. if (HAL_FLASHEx_Erase(&erase, &sectorError) != HAL_OK)
  948. {
  949. status = HAL_ERROR;
  950. }
  951. words = (const uint32_t *)&PlsrFlashRecordBuffer;
  952. wordCount = sizeof(PlsrFlashRecordBuffer) / sizeof(uint32_t);
  953. if (status == HAL_OK)
  954. {
  955. for (index = 1UL; index < wordCount; index++)
  956. {
  957. if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,
  958. targetAddress + index * 4UL,
  959. words[index]) != HAL_OK)
  960. {
  961. status = HAL_ERROR;
  962. break;
  963. }
  964. }
  965. }
  966. if ((status == HAL_OK)
  967. && (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, targetAddress,
  968. PLSR_FLASH_MAGIC) != HAL_OK))
  969. {
  970. status = HAL_ERROR;
  971. }
  972. if (HAL_FLASH_Lock() != HAL_OK)
  973. {
  974. status = HAL_ERROR;
  975. }
  976. if ((status == HAL_OK)
  977. && (PlsrFlashRecordIsValid(
  978. (const PLSR_FLASH_RECORD *)targetAddress) != 0U))
  979. {
  980. return 1U;
  981. }
  982. return 0U;
  983. }
  984. void PlsrPlatformCheckpointConfig(const PLSR_CONFIG *config)
  985. {
  986. PLSR_BACKUP_CONFIG_RECORD *record =
  987. (PLSR_BACKUP_CONFIG_RECORD *)PLSR_BACKUP_CONFIG_ADDRESS;
  988. if (config == NULL)
  989. {
  990. return;
  991. }
  992. record->magic = 0UL;
  993. record->config = *config;
  994. record->crc32 = PlsrCrc32(&record->config, sizeof(record->config));
  995. __DMB();
  996. record->magic = PLSR_BACKUP_CONFIG_MAGIC;
  997. __DMB();
  998. }
  999. void PlsrPlatformCheckpointPosition(int32_t position,
  1000. uint8_t positionValid,
  1001. uint8_t wasBusy)
  1002. {
  1003. PLSR_BACKUP_POSITION_RECORD *slots =
  1004. (PLSR_BACKUP_POSITION_RECORD *)PLSR_BACKUP_POSITION_ADDRESS;
  1005. PLSR_BACKUP_POSITION_RECORD *record;
  1006. PlsrBackupPositionGeneration++;
  1007. record = &slots[PlsrBackupPositionGeneration & 1UL];
  1008. record->magic = 0UL;
  1009. record->generation = PlsrBackupPositionGeneration;
  1010. record->position = position;
  1011. record->positionValid = (positionValid != 0U) ? 1U : 0U;
  1012. record->wasBusy = (wasBusy != 0U) ? 1U : 0U;
  1013. record->reserved = 0U;
  1014. record->crc32 = PlsrCrc32(&record->generation,
  1015. sizeof(record->generation)
  1016. + sizeof(record->position)
  1017. + sizeof(record->positionValid)
  1018. + sizeof(record->wasBusy)
  1019. + sizeof(record->reserved));
  1020. __DMB();
  1021. record->magic = PLSR_BACKUP_POSITION_MAGIC;
  1022. __DMB();
  1023. }
  1024. uint32_t PlsrPlatformEnterCritical(void)
  1025. {
  1026. uint32_t state = __get_PRIMASK();
  1027. __disable_irq();
  1028. __DMB();
  1029. return state;
  1030. }
  1031. void PlsrPlatformExitCritical(uint32_t state)
  1032. {
  1033. __DMB();
  1034. if (state == 0UL)
  1035. {
  1036. __enable_irq();
  1037. }
  1038. }
  1039. static void PlsrHandleTimerIrq(uint8_t pulseOutput)
  1040. {
  1041. TIM_TypeDef *timer = PlsrTimerMap[pulseOutput].timer;
  1042. #if PLSR_ENABLE_IRQ_CYCLE_DIAG
  1043. uint32_t startedAt;
  1044. uint32_t elapsedCycles;
  1045. #endif
  1046. if (((timer->SR & TIM_SR_UIF) != 0UL)
  1047. && ((timer->DIER & TIM_DIER_UIE) != 0UL))
  1048. {
  1049. #if PLSR_ENABLE_IRQ_CYCLE_DIAG
  1050. startedAt = DWT->CYCCNT;
  1051. #endif
  1052. timer->SR = ~TIM_SR_UIF;
  1053. PlsrTimerActiveFrequencyHz[pulseOutput] =
  1054. PlsrTimerQueuedFrequencyHz[pulseOutput];
  1055. PlsrPulseTimerIrq(pulseOutput);
  1056. #if PLSR_ENABLE_IRQ_CYCLE_DIAG
  1057. elapsedCycles = DWT->CYCCNT - startedAt;
  1058. PlsrIrqCount[pulseOutput]++;
  1059. PlsrIrqLastCycles[pulseOutput] = elapsedCycles;
  1060. if (elapsedCycles > PlsrIrqMaxCycles[pulseOutput])
  1061. {
  1062. PlsrIrqMaxCycles[pulseOutput] = elapsedCycles;
  1063. }
  1064. #endif
  1065. }
  1066. }
  1067. void TIM1_UP_TIM10_IRQHandler(void)
  1068. {
  1069. PlsrHandleTimerIrq(0U);
  1070. }
  1071. void TIM8_UP_TIM13_IRQHandler(void)
  1072. {
  1073. PlsrHandleTimerIrq(1U);
  1074. }
  1075. void TIM1_TRG_COM_TIM11_IRQHandler(void)
  1076. {
  1077. PlsrHandleTimerIrq(2U);
  1078. }
  1079. void TIM8_TRG_COM_TIM14_IRQHandler(void)
  1080. {
  1081. PlsrHandleTimerIrq(3U);
  1082. }
  1083. #endif /* PLSR_HOST_TEST */