您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 
 
 

1965 行
66 KiB

  1. #include "plsr.h"
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #define PLSR_WAIT_TIME (0U)
  5. #define PLSR_WAIT_SIGNAL (1U)
  6. #define PLSR_ACT_TIME (2U)
  7. #define PLSR_EXT_SIGNAL (3U)
  8. #define PLSR_EXT_OR_COMPLETE (4U)
  9. #define PLSR_SEND_COMPLETE (0U)
  10. #define PLSR_SEND_SUBSEQUENT (1U)
  11. #define PLSR_POSITION_RELATIVE (0U)
  12. #define PLSR_POSITION_ABSOLUTE (1U)
  13. #define PLSR_COMMAND_START (0x0001U)
  14. #define PLSR_COMMAND_STOP (0x0002U)
  15. #define PLSR_COMMAND_CLEAR (0x0004U)
  16. #define PLSR_ERROR_COUNT (5U)
  17. static const char *CurrentTest;
  18. static unsigned int AssertionCount;
  19. static unsigned int FailureCount;
  20. static void ExpectUnsigned(unsigned long expected,
  21. unsigned long actual,
  22. const char *expression,
  23. int line)
  24. {
  25. AssertionCount++;
  26. if (expected != actual)
  27. {
  28. FailureCount++;
  29. (void)printf("FAIL %s:%d: %s expected %lu, got %lu\n",
  30. CurrentTest, line, expression, expected, actual);
  31. }
  32. }
  33. static void ExpectSigned(long expected,
  34. long actual,
  35. const char *expression,
  36. int line)
  37. {
  38. AssertionCount++;
  39. if (expected != actual)
  40. {
  41. FailureCount++;
  42. (void)printf("FAIL %s:%d: %s expected %ld, got %ld\n",
  43. CurrentTest, line, expression, expected, actual);
  44. }
  45. }
  46. static void ExpectTrue(int condition, const char *expression, int line)
  47. {
  48. AssertionCount++;
  49. if (!condition)
  50. {
  51. FailureCount++;
  52. (void)printf("FAIL %s:%d: expected true: %s\n",
  53. CurrentTest, line, expression);
  54. }
  55. }
  56. #define EXPECT_U(expected, actual) \
  57. ExpectUnsigned((unsigned long)(expected), \
  58. (unsigned long)(actual), #actual, __LINE__)
  59. #define EXPECT_I(expected, actual) \
  60. ExpectSigned((long)(expected), (long)(actual), #actual, __LINE__)
  61. #define EXPECT_TRUE(expression) ExpectTrue((expression), #expression, __LINE__)
  62. static uint16_t LowWord(uint32_t value)
  63. {
  64. return (uint16_t)(value & 0xFFFFUL);
  65. }
  66. static uint16_t HighWord(uint32_t value)
  67. {
  68. return (uint16_t)(value >> 16U);
  69. }
  70. static void TestU64ByU32Division(void)
  71. {
  72. static const uint64_t dividends[] =
  73. {
  74. 0ULL, 1ULL, 0xFFFFFFFFULL, 0x100000000ULL,
  75. 0x100000001ULL, 0xFFFFFFFFFFFFFFFFULL,
  76. 0x8000000000000000ULL, 0x7FFFFFFFFFFFFFFFULL
  77. };
  78. static const uint32_t divisors[] =
  79. {
  80. 1UL, 2UL, 3UL, 0xFFFFUL, 0x10000UL, 100000UL,
  81. 0x7FFFFFFFUL, 0x80000000UL, 0xFFFFFFFFUL
  82. };
  83. uint32_t state = 0xA5C39E17UL;
  84. uint64_t dividend;
  85. uint64_t quotient;
  86. uint32_t divisor;
  87. uint32_t remainder;
  88. uint32_t dividendIndex;
  89. uint32_t divisorIndex;
  90. uint32_t iteration;
  91. for (dividendIndex = 0U;
  92. dividendIndex < (uint32_t)(sizeof(dividends) / sizeof(dividends[0]));
  93. dividendIndex++)
  94. {
  95. for (divisorIndex = 0U;
  96. divisorIndex < (uint32_t)(sizeof(divisors) / sizeof(divisors[0]));
  97. divisorIndex++)
  98. {
  99. dividend = dividends[dividendIndex];
  100. divisor = divisors[divisorIndex];
  101. quotient = PlsrTestDivideU64ByU32(dividend, divisor, &remainder);
  102. EXPECT_TRUE(quotient == dividend / divisor);
  103. EXPECT_U((uint32_t)(dividend % divisor), remainder);
  104. }
  105. }
  106. for (iteration = 0U; iteration < 250000UL; iteration++)
  107. {
  108. state = state * 1664525UL + 1013904223UL;
  109. dividend = (uint64_t)state << 32U;
  110. state = state * 1664525UL + 1013904223UL;
  111. dividend |= state;
  112. state = state * 1664525UL + 1013904223UL;
  113. divisor = state | 1UL;
  114. quotient = PlsrTestDivideU64ByU32(dividend, divisor, &remainder);
  115. EXPECT_TRUE(quotient == dividend / divisor);
  116. EXPECT_U((uint32_t)(dividend % divisor), remainder);
  117. }
  118. }
  119. static uint64_t PulsePeriodNs(uint32_t frequencyHz)
  120. {
  121. return (1000000000ULL + frequencyHz / 2UL) / frequencyHz;
  122. }
  123. static uint64_t UnsignedDifference64(uint64_t first, uint64_t second)
  124. {
  125. return (first > second) ? (first - second) : (second - first);
  126. }
  127. static uint32_t IntegerSquareRoot64(uint64_t value)
  128. {
  129. uint64_t bit = (uint64_t)1U << 62U;
  130. uint64_t root = 0ULL;
  131. while (bit > value)
  132. {
  133. bit >>= 2U;
  134. }
  135. while (bit != 0ULL)
  136. {
  137. if (value >= root + bit)
  138. {
  139. value -= root + bit;
  140. root = (root >> 1U) + bit;
  141. }
  142. else
  143. {
  144. root >>= 1U;
  145. }
  146. bit >>= 2U;
  147. }
  148. return (uint32_t)root;
  149. }
  150. static PLSR_MB_RESULT WriteWord(uint16_t address, uint16_t value)
  151. {
  152. return PlsrModbusWriteHolding(address, 1U, &value);
  153. }
  154. static PLSR_MB_RESULT WriteU32(uint16_t address, uint32_t value)
  155. {
  156. uint16_t words[2];
  157. words[0] = LowWord(value);
  158. words[1] = HighWord(value);
  159. return PlsrModbusWriteHolding(address, 2U, words);
  160. }
  161. static PLSR_MB_RESULT WriteI32(uint16_t address, int32_t value)
  162. {
  163. return WriteU32(address, (uint32_t)value);
  164. }
  165. static uint16_t ReadWord(uint16_t address)
  166. {
  167. uint16_t value = 0xDEADU;
  168. PLSR_MB_RESULT result = PlsrModbusReadHolding(address, 1U, &value);
  169. EXPECT_U(PLSR_MB_OK, result);
  170. return value;
  171. }
  172. static uint32_t ReadU32(uint16_t address)
  173. {
  174. uint16_t words[2] = {0xDEADU, 0xBEEFU};
  175. PLSR_MB_RESULT result = PlsrModbusReadHolding(address, 2U, words);
  176. EXPECT_U(PLSR_MB_OK, result);
  177. return (uint32_t)words[0] | ((uint32_t)words[1] << 16U);
  178. }
  179. static int32_t ReadPosition(void)
  180. {
  181. return (int32_t)ReadU32(PLSR_STATUS_FIRST_ADDRESS);
  182. }
  183. static uint32_t ReadFrequency(void)
  184. {
  185. return ReadU32((uint16_t)(PLSR_STATUS_FIRST_ADDRESS + 2U));
  186. }
  187. static uint16_t ReadStatus(void)
  188. {
  189. return ReadWord((uint16_t)(PLSR_STATUS_FIRST_ADDRESS + 4U));
  190. }
  191. static uint16_t ReadCurrentSegment(void)
  192. {
  193. return ReadWord((uint16_t)(PLSR_STATUS_FIRST_ADDRESS + 5U));
  194. }
  195. static uint16_t ReadError(void)
  196. {
  197. return ReadWord((uint16_t)(PLSR_STATUS_FIRST_ADDRESS + 6U));
  198. }
  199. static PLSR_MB_RESULT QueueCommand(uint16_t command)
  200. {
  201. return PlsrModbusWriteHolding(PLSR_CONTROL_ADDRESS, 1U, &command);
  202. }
  203. static PLSR_MB_RESULT SendCommand(uint16_t command)
  204. {
  205. PLSR_MB_RESULT result = QueueCommand(command);
  206. if (result == PLSR_MB_OK)
  207. {
  208. PlsrPoll1ms();
  209. }
  210. return result;
  211. }
  212. static void ResetCore(void)
  213. {
  214. PlsrTestClearPersistentStorage();
  215. EXPECT_U(1U, PlsrInit());
  216. EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
  217. }
  218. static void ConfigureCommon(uint16_t curveMode,
  219. uint16_t positionMode,
  220. uint16_t segmentCount,
  221. uint16_t sendMode,
  222. uint32_t defaultSpeedHz,
  223. uint32_t startSpeedHz,
  224. uint32_t stopSpeedHz,
  225. uint16_t accelerationTimeMs,
  226. uint16_t decelerationTimeMs)
  227. {
  228. uint16_t words[0x14U];
  229. PLSR_MB_RESULT result;
  230. result = PlsrModbusReadHolding(0x1000U, 0x14U, words);
  231. EXPECT_U(PLSR_MB_OK, result);
  232. words[0x04U] = sendMode;
  233. words[0x05U] = 0U;
  234. words[0x07U] = curveMode;
  235. words[0x08U] = positionMode;
  236. words[0x09U] = segmentCount;
  237. words[0x0AU] = 1U;
  238. words[0x0BU] = LowWord(defaultSpeedHz);
  239. words[0x0CU] = HighWord(defaultSpeedHz);
  240. words[0x0DU] = LowWord(startSpeedHz);
  241. words[0x0EU] = HighWord(startSpeedHz);
  242. words[0x0FU] = 0U;
  243. words[0x10U] = LowWord(stopSpeedHz);
  244. words[0x11U] = HighWord(stopSpeedHz);
  245. words[0x12U] = accelerationTimeMs;
  246. words[0x13U] = decelerationTimeMs;
  247. result = PlsrModbusWriteHolding(0x1000U, 0x14U, words);
  248. EXPECT_U(PLSR_MB_OK, result);
  249. }
  250. static PLSR_MB_RESULT SetSegment(uint8_t segmentNumber,
  251. uint32_t frequencyHz,
  252. int32_t pulses,
  253. uint16_t waitType,
  254. uint16_t waitTimeMs,
  255. uint16_t actTimeMs,
  256. uint16_t jumpSegment)
  257. {
  258. uint16_t words[8];
  259. uint16_t address = (uint16_t)(0x1100U
  260. + ((uint16_t)segmentNumber - 1U) * 0x10U);
  261. words[0] = LowWord(frequencyHz);
  262. words[1] = HighWord(frequencyHz);
  263. words[2] = LowWord((uint32_t)pulses);
  264. words[3] = HighWord((uint32_t)pulses);
  265. words[4] = waitType;
  266. words[5] = waitTimeMs;
  267. words[6] = actTimeMs;
  268. words[7] = jumpSegment;
  269. return PlsrModbusWriteHolding(address, 8U, words);
  270. }
  271. static void StopAndSettle(void)
  272. {
  273. unsigned int pulse;
  274. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
  275. for (pulse = 0U; (pulse < 4U) && (PlsrTestPulseIsActive() != 0U);
  276. pulse++)
  277. {
  278. PlsrTestEmitPulses(1UL);
  279. }
  280. PlsrPoll1ms();
  281. EXPECT_U(0U, PlsrTestPulseIsActive());
  282. EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
  283. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  284. }
  285. static void TestProtocolBoundaries(void)
  286. {
  287. uint16_t value = 0U;
  288. uint16_t values[2];
  289. uint16_t before;
  290. ResetCore();
  291. EXPECT_U(PLSR_MB_NOT_HANDLED,
  292. PlsrModbusReadHolding(0x0FFEU, 1U, &value));
  293. EXPECT_U(PLSR_MB_NOT_HANDLED,
  294. PlsrModbusReadHolding(0x1198U, 1U, &value));
  295. EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS,
  296. PlsrModbusReadHolding(0x0FFFU, 2U, values));
  297. EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS,
  298. PlsrModbusReadHolding(0x1197U, 2U, values));
  299. EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS,
  300. PlsrModbusReadHolding(0x2006U, 2U, values));
  301. EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS,
  302. PlsrModbusReadHolding(0xFFFFU, 2U, values));
  303. EXPECT_U(PLSR_MB_ILLEGAL_VALUE,
  304. PlsrModbusReadHolding(0x1000U, 0U, &value));
  305. EXPECT_U(PLSR_MB_ILLEGAL_VALUE,
  306. PlsrModbusReadHolding(0x1000U, 1U, NULL));
  307. EXPECT_U(0U, ReadWord(0x100FU));
  308. EXPECT_U(PLSR_MB_OK, WriteWord(0x100FU, 0U));
  309. EXPECT_U(PLSR_MB_ILLEGAL_VALUE, WriteWord(0x100FU, 1U));
  310. EXPECT_U(0U, ReadWord(0x1108U));
  311. EXPECT_U(PLSR_MB_OK, WriteWord(0x1108U, 0U));
  312. EXPECT_U(PLSR_MB_ILLEGAL_VALUE, WriteWord(0x1108U, 1U));
  313. EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS, WriteWord(0x100BU, 2000U));
  314. EXPECT_U(PLSR_MB_OK, WriteU32(0x100BU, 2000UL));
  315. EXPECT_U(2000UL, ReadU32(0x100BU));
  316. EXPECT_U(PLSR_MB_ILLEGAL_VALUE, WriteU32(0x100BU, 100001UL));
  317. EXPECT_U(2000UL, ReadU32(0x100BU));
  318. before = ReadWord(0x1013U);
  319. values[0] = 77U;
  320. values[1] = 1U;
  321. EXPECT_U(PLSR_MB_ILLEGAL_VALUE,
  322. PlsrModbusWriteHolding(0x1013U, 2U, values));
  323. EXPECT_U(before, ReadWord(0x1013U));
  324. EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS,
  325. PlsrModbusWriteHolding(0x2000U, 1U, &value));
  326. EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS,
  327. PlsrModbusWriteHolding(0x3000U, 2U, values));
  328. value = 3U;
  329. EXPECT_U(PLSR_MB_ILLEGAL_VALUE,
  330. PlsrModbusWriteHolding(0x3000U, 1U, &value));
  331. value = 0U;
  332. EXPECT_U(PLSR_MB_OK,
  333. PlsrModbusWriteHolding(0x3000U, 1U, &value));
  334. EXPECT_U(0U, ReadWord(0x3000U));
  335. EXPECT_U(PLSR_MB_OK, WriteWord(0x1197U, 0U));
  336. EXPECT_U(0U, ReadWord(0x1197U));
  337. EXPECT_U(PLSR_MB_NOT_HANDLED, WriteWord(0x1198U, 0U));
  338. }
  339. static void TestWaitZeroUsesOneMillisecond(void)
  340. {
  341. ResetCore();
  342. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U, PLSR_SEND_COMPLETE,
  343. 1000UL, 1000UL, 100UL, 0U, 0U);
  344. EXPECT_U(PLSR_MB_OK,
  345. SetSegment(1U, 1000UL, 1L, PLSR_WAIT_TIME, 0U, 0U, 0U));
  346. EXPECT_U(PLSR_MB_OK,
  347. SetSegment(2U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
  348. 0U, 0U, 0U));
  349. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  350. PlsrTestEmitPulses(1UL);
  351. PlsrPoll1ms();
  352. EXPECT_U(PLSR_STATUS_WAITING, ReadStatus());
  353. EXPECT_U(1U, ReadCurrentSegment());
  354. EXPECT_U(0U, PlsrTestPulseIsActive());
  355. PlsrPoll1ms();
  356. EXPECT_U(2U, ReadCurrentSegment());
  357. EXPECT_U(1U, PlsrTestPulseIsActive());
  358. PlsrTestEmitPulses(1UL);
  359. PlsrPoll1ms();
  360. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  361. EXPECT_I(2L, ReadPosition());
  362. }
  363. static void TestActZeroSkipsWithoutPulse(void)
  364. {
  365. ResetCore();
  366. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U, PLSR_SEND_COMPLETE,
  367. 1000UL, 1000UL, 100UL, 0U, 0U);
  368. EXPECT_U(PLSR_MB_OK,
  369. SetSegment(1U, 1000UL, 100L, PLSR_ACT_TIME, 0U, 0U, 0U));
  370. EXPECT_U(PLSR_MB_OK,
  371. SetSegment(2U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
  372. 0U, 0U, 0U));
  373. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  374. EXPECT_U(0U, PlsrTestPulseIsActive());
  375. EXPECT_U(1U, ReadCurrentSegment());
  376. EXPECT_I(0L, ReadPosition());
  377. PlsrPoll1ms();
  378. EXPECT_U(2U, ReadCurrentSegment());
  379. EXPECT_U(1U, PlsrTestPulseIsActive());
  380. EXPECT_I(0L, ReadPosition());
  381. PlsrTestEmitPulses(1UL);
  382. PlsrPoll1ms();
  383. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  384. EXPECT_I(1L, ReadPosition());
  385. }
  386. static void TestRelativeAndAbsoluteZeroDisplacement(void)
  387. {
  388. ResetCore();
  389. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  390. 1000UL, 1000UL, 100UL, 0U, 0U);
  391. EXPECT_U(PLSR_MB_OK,
  392. SetSegment(1U, 1000UL, 0L, PLSR_EXT_OR_COMPLETE,
  393. 0U, 0U, 0U));
  394. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  395. EXPECT_U(PLSR_STATUS_RUNNING, ReadStatus());
  396. EXPECT_U(0U, PlsrTestPulseIsActive());
  397. PlsrPoll1ms();
  398. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  399. EXPECT_I(0L, ReadPosition());
  400. EXPECT_U(PLSR_MB_OK,
  401. SetSegment(1U, 1000UL, 5L, PLSR_EXT_OR_COMPLETE,
  402. 0U, 0U, 0U));
  403. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  404. PlsrTestEmitPulses(5UL);
  405. PlsrPoll1ms();
  406. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  407. EXPECT_I(5L, ReadPosition());
  408. EXPECT_U(PLSR_MB_OK, WriteWord(0x1008U, PLSR_POSITION_ABSOLUTE));
  409. EXPECT_U(PLSR_MB_OK,
  410. SetSegment(1U, 1000UL, 5L, PLSR_EXT_OR_COMPLETE,
  411. 0U, 0U, 0U));
  412. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  413. EXPECT_U(0U, PlsrTestPulseIsActive());
  414. PlsrPoll1ms();
  415. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  416. EXPECT_I(5L, ReadPosition());
  417. }
  418. static void TestSelfJumpCanStop(void)
  419. {
  420. unsigned int loop;
  421. ResetCore();
  422. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  423. 1000UL, 1000UL, 100UL, 0U, 0U);
  424. EXPECT_U(PLSR_MB_OK,
  425. SetSegment(1U, 1000UL, 2L, PLSR_EXT_OR_COMPLETE,
  426. 0U, 0U, 1U));
  427. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  428. for (loop = 0U; loop < 3U; loop++)
  429. {
  430. PlsrTestEmitPulses(2UL);
  431. PlsrPoll1ms();
  432. EXPECT_U(PLSR_STATUS_RUNNING, ReadStatus());
  433. EXPECT_U(1U, ReadCurrentSegment());
  434. EXPECT_U(1U, PlsrTestPulseIsActive());
  435. }
  436. StopAndSettle();
  437. }
  438. static void TestStopDeceleratesBeforeCut(void)
  439. {
  440. unsigned int tick;
  441. uint32_t middleFrequency;
  442. ResetCore();
  443. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  444. 1000UL, 1000UL, 100UL, 0U, 1000U);
  445. EXPECT_U(PLSR_MB_OK,
  446. SetSegment(1U, 1000UL, 10000L, PLSR_EXT_OR_COMPLETE,
  447. 0U, 0U, 0U));
  448. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  449. EXPECT_U(1000UL, PlsrTestOutputFrequency());
  450. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
  451. EXPECT_U(PLSR_STATUS_DECELERATING, ReadStatus());
  452. EXPECT_U(1U, PlsrTestPulseIsActive());
  453. for (tick = 0U; tick < 450U; tick++)
  454. {
  455. PlsrPoll1ms();
  456. PlsrTestEmitPulses(1UL);
  457. }
  458. middleFrequency = PlsrTestOutputFrequency();
  459. EXPECT_TRUE((middleFrequency > 100UL) && (middleFrequency < 1000UL));
  460. EXPECT_U(1U, PlsrTestPulseIsActive());
  461. EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_STOP));
  462. for (tick = 450U; tick < 900U; tick++)
  463. {
  464. PlsrPoll1ms();
  465. PlsrTestEmitPulses(1UL);
  466. }
  467. EXPECT_TRUE(PlsrTestOutputFrequency() > 100UL);
  468. EXPECT_TRUE(PlsrTestOutputFrequency() <= 103UL);
  469. EXPECT_U(PLSR_STATUS_DECELERATING, ReadStatus());
  470. EXPECT_U(1U, PlsrTestPulseIsActive());
  471. PlsrTestEmitPulses(1UL);
  472. EXPECT_U(100UL, PlsrTestOutputFrequency());
  473. EXPECT_U(1U, PlsrTestPulseIsActive());
  474. PlsrTestEmitPulses(1UL);
  475. EXPECT_U(0U, PlsrTestPulseIsActive());
  476. PlsrPoll1ms();
  477. EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
  478. EXPECT_I(902L, ReadPosition());
  479. }
  480. static void TestStopAtPendingBoundary(void)
  481. {
  482. ResetCore();
  483. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  484. 1000UL, 1000UL, 100UL, 0U, 0U);
  485. EXPECT_U(PLSR_MB_OK,
  486. SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
  487. 0U, 0U, 0U));
  488. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  489. PlsrTestEmitPulses(1UL);
  490. EXPECT_U(0U, PlsrTestPulseIsActive());
  491. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
  492. EXPECT_U(PLSR_STATUS_RUNNING, ReadStatus());
  493. PlsrPoll1ms();
  494. EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
  495. EXPECT_U(0U, ReadCurrentSegment());
  496. EXPECT_I(1L, ReadPosition());
  497. PlsrPoll1ms();
  498. EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
  499. EXPECT_U(0U, PlsrTestPulseIsActive());
  500. }
  501. static void TestOneMillisecondDirectionDelay(void)
  502. {
  503. ResetCore();
  504. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  505. 1000UL, 1000UL, 100UL, 0U, 0U);
  506. EXPECT_U(PLSR_MB_OK, WriteWord(0x1005U, 1U));
  507. EXPECT_U(PLSR_MB_OK,
  508. SetSegment(1U, 1000UL, 10L, PLSR_EXT_OR_COMPLETE,
  509. 0U, 0U, 0U));
  510. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  511. EXPECT_U(0U, PlsrTestPulseIsActive());
  512. PlsrPoll1ms();
  513. EXPECT_U(1U, PlsrTestPulseIsActive());
  514. EXPECT_U(1000UL, PlsrTestOutputFrequency());
  515. StopAndSettle();
  516. }
  517. static void TestExtEdgeAtNaturalBoundary(void)
  518. {
  519. ResetCore();
  520. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  521. 1000UL, 1000UL, 100UL, 0U, 0U);
  522. PlsrTestSetInput(0U, 0U);
  523. EXPECT_U(PLSR_MB_OK,
  524. SetSegment(1U, 1000UL, 1L, PLSR_EXT_SIGNAL,
  525. 0U, 0U, 0U));
  526. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  527. PlsrTestEmitPulseOnCriticalEntry();
  528. PlsrTestSetInput(0U, 1U);
  529. PlsrPoll1ms();
  530. EXPECT_U(0U, PlsrTestPulseIsActive());
  531. PlsrPoll1ms();
  532. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  533. EXPECT_U(0U, ReadCurrentSegment());
  534. EXPECT_I(1L, ReadPosition());
  535. }
  536. static void ConfigureExtBoundaryCarryRace(void)
  537. {
  538. ResetCore();
  539. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
  540. PLSR_SEND_SUBSEQUENT, 2000UL, 500UL, 1000UL,
  541. 0U, 1000U);
  542. PlsrTestSetInput(0U, 0U);
  543. EXPECT_U(PLSR_MB_OK,
  544. SetSegment(1U, 2000UL, 1L, PLSR_EXT_SIGNAL,
  545. 0U, 0U, 0U));
  546. EXPECT_U(PLSR_MB_OK,
  547. SetSegment(2U, 1000UL, 70000L, PLSR_EXT_OR_COMPLETE,
  548. 0U, 0U, 0U));
  549. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  550. EXPECT_U(2000UL, PlsrTestOutputFrequency());
  551. PlsrTestSetInput(0U, 1U);
  552. }
  553. static void ExpectExtBoundaryCarry(void)
  554. {
  555. EXPECT_U(0U, PlsrTestPulseIsActive());
  556. EXPECT_U(1U, ReadCurrentSegment());
  557. PlsrPoll1ms();
  558. EXPECT_U(1U, PlsrTestPulseIsActive());
  559. EXPECT_U(2U, ReadCurrentSegment());
  560. EXPECT_U(2000UL, PlsrTestOutputFrequency());
  561. EXPECT_I(1L, ReadPosition());
  562. }
  563. static void TestExtCutAndNaturalBoundaryInterleavings(void)
  564. {
  565. ConfigureExtBoundaryCarryRace();
  566. PlsrTestEmitPulseAfterCriticalEntries(3U);
  567. PlsrPoll1ms();
  568. ExpectExtBoundaryCarry();
  569. ConfigureExtBoundaryCarryRace();
  570. PlsrPoll1ms();
  571. EXPECT_U(1U, PlsrTestPulseIsActive());
  572. PlsrTestEmitPulses(1UL);
  573. ExpectExtBoundaryCarry();
  574. }
  575. static void TestExtEdgeDuringDirectionDelay(void)
  576. {
  577. ResetCore();
  578. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  579. 1000UL, 1000UL, 100UL, 0U, 0U);
  580. EXPECT_U(PLSR_MB_OK, WriteWord(0x1005U, 2U));
  581. PlsrTestSetInput(0U, 0U);
  582. EXPECT_U(PLSR_MB_OK,
  583. SetSegment(1U, 1000UL, 1L, PLSR_EXT_SIGNAL,
  584. 0U, 0U, 0U));
  585. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  586. PlsrTestSetInput(0U, 1U);
  587. PlsrPoll1ms();
  588. EXPECT_U(0U, PlsrTestPulseIsActive());
  589. PlsrPoll1ms();
  590. EXPECT_U(1U, PlsrTestPulseIsActive());
  591. PlsrTestEmitPulses(1UL);
  592. PlsrPoll1ms();
  593. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  594. EXPECT_I(1L, ReadPosition());
  595. }
  596. static void TestStoppedTaskClearsPendingExtEdge(void)
  597. {
  598. ResetCore();
  599. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  600. 1000UL, 1000UL, 100UL, 0U, 0U);
  601. EXPECT_U(PLSR_MB_OK, WriteWord(0x1005U, 2U));
  602. PlsrTestSetInput(0U, 0U);
  603. EXPECT_U(PLSR_MB_OK,
  604. SetSegment(1U, 1000UL, 100L, PLSR_EXT_SIGNAL,
  605. 0U, 0U, 0U));
  606. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  607. EXPECT_U(0U, PlsrTestPulseIsActive());
  608. PlsrTestSetInput(0U, 1U);
  609. PlsrPoll1ms();
  610. EXPECT_U(0U, PlsrTestPulseIsActive());
  611. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
  612. EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
  613. PlsrTestSetInput(0U, 0U);
  614. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  615. EXPECT_U(0U, PlsrTestPulseIsActive());
  616. PlsrPoll1ms();
  617. EXPECT_U(0U, PlsrTestPulseIsActive());
  618. PlsrPoll1ms();
  619. EXPECT_U(1U, PlsrTestPulseIsActive());
  620. PlsrPoll1ms();
  621. EXPECT_U(1U, PlsrTestPulseIsActive());
  622. EXPECT_I(0L, ReadPosition());
  623. StopAndSettle();
  624. }
  625. static void TestExtEdgeDoesNotCutSeamlessNextSegment(void)
  626. {
  627. ResetCore();
  628. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
  629. PLSR_SEND_SUBSEQUENT, 1000UL, 1000UL, 100UL, 0U, 0U);
  630. PlsrTestSetInput(0U, 0U);
  631. EXPECT_U(PLSR_MB_OK,
  632. SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
  633. 0U, 0U, 0U));
  634. EXPECT_U(PLSR_MB_OK,
  635. SetSegment(2U, 2000UL, 4L, PLSR_EXT_OR_COMPLETE,
  636. 0U, 0U, 0U));
  637. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  638. PlsrTestSetInput(0U, 1U);
  639. PlsrTestEmitPulseAfterCriticalEntries(3U);
  640. PlsrPoll1ms();
  641. EXPECT_U(1U, PlsrTestPulseIsActive());
  642. EXPECT_U(2U, ReadCurrentSegment());
  643. EXPECT_U(2000UL, PlsrTestOutputFrequency());
  644. EXPECT_I(1L, ReadPosition());
  645. PlsrTestEmitPulses(4UL);
  646. PlsrPoll1ms();
  647. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  648. EXPECT_I(5L, ReadPosition());
  649. }
  650. static void TestOldRampDoesNotRetargetSeamlessNextSegment(void)
  651. {
  652. ResetCore();
  653. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
  654. PLSR_SEND_SUBSEQUENT, 2000UL, 1000UL, 100UL, 100U, 0U);
  655. PlsrTestSetInput(0U, 0U);
  656. EXPECT_U(PLSR_MB_OK,
  657. SetSegment(1U, 2000UL, 1L, PLSR_EXT_OR_COMPLETE,
  658. 0U, 0U, 0U));
  659. EXPECT_U(PLSR_MB_OK,
  660. SetSegment(2U, 3000UL, 4L, PLSR_EXT_OR_COMPLETE,
  661. 0U, 0U, 0U));
  662. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  663. PlsrTestEmitPulseAfterCriticalEntries(3U);
  664. PlsrPoll1ms();
  665. EXPECT_U(1U, PlsrTestPulseIsActive());
  666. EXPECT_U(2U, ReadCurrentSegment());
  667. EXPECT_U(3000UL, PlsrTestOutputFrequency());
  668. EXPECT_I(1L, ReadPosition());
  669. PlsrTestEmitPulses(4UL);
  670. PlsrPoll1ms();
  671. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  672. EXPECT_I(5L, ReadPosition());
  673. }
  674. static void TestShortProfileBoundaryMatrix(void)
  675. {
  676. static const uint16_t pulseCounts[] = {1U, 2U, 10U, 99U, 100U, 101U};
  677. uint32_t samples[3][101];
  678. uint64_t previousDurationNs[3] = {0ULL, 0ULL, 0ULL};
  679. uint64_t durationNs[3];
  680. unsigned int countIndex;
  681. uint16_t curveMode;
  682. unsigned int pulse;
  683. unsigned int firstPeak;
  684. unsigned int lastPeak;
  685. uint32_t peakFrequencyHz;
  686. uint32_t expectedPeakHz;
  687. uint64_t expectedDurationNs;
  688. uint64_t toleranceNs;
  689. uint8_t linearDiffersFromSmooth;
  690. uint8_t smoothDiffersFromSine;
  691. uint8_t anyLinearDiffersFromSmooth = 0U;
  692. uint8_t anySmoothDiffersFromSine = 0U;
  693. for (countIndex = 0U;
  694. countIndex < sizeof(pulseCounts) / sizeof(pulseCounts[0]);
  695. countIndex++)
  696. {
  697. for (curveMode = 0U; curveMode <= 2U; curveMode++)
  698. {
  699. ResetCore();
  700. ConfigureCommon(curveMode, PLSR_POSITION_RELATIVE, 1U,
  701. PLSR_SEND_COMPLETE, 1000UL, 100UL, 100UL,
  702. 1000U, 1000U);
  703. EXPECT_U(PLSR_MB_OK,
  704. SetSegment(1U, 1000UL, pulseCounts[countIndex],
  705. PLSR_EXT_OR_COMPLETE, 0U, 0U, 0U));
  706. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  707. EXPECT_U(1U, PlsrTestPulseIsActive());
  708. durationNs[curveMode] = 0ULL;
  709. for (pulse = 0U; pulse < pulseCounts[countIndex]; pulse++)
  710. {
  711. samples[curveMode][pulse] = PlsrTestOutputFrequency();
  712. EXPECT_TRUE(samples[curveMode][pulse] >= 100UL);
  713. EXPECT_TRUE(samples[curveMode][pulse] <= 1000UL);
  714. durationNs[curveMode] +=
  715. PulsePeriodNs(samples[curveMode][pulse]);
  716. PlsrTestEmitPulses(1UL);
  717. if ((pulse + 1U) < pulseCounts[countIndex])
  718. {
  719. EXPECT_U(1U, PlsrTestPulseIsActive());
  720. }
  721. }
  722. peakFrequencyHz = samples[curveMode][0];
  723. firstPeak = 0U;
  724. lastPeak = 0U;
  725. for (pulse = 1U; pulse < pulseCounts[countIndex]; pulse++)
  726. {
  727. if (samples[curveMode][pulse] > peakFrequencyHz)
  728. {
  729. peakFrequencyHz = samples[curveMode][pulse];
  730. firstPeak = pulse;
  731. lastPeak = pulse;
  732. }
  733. else if (samples[curveMode][pulse] == peakFrequencyHz)
  734. {
  735. lastPeak = pulse;
  736. }
  737. }
  738. for (pulse = 1U; pulse <= firstPeak; pulse++)
  739. {
  740. EXPECT_TRUE(samples[curveMode][pulse]
  741. >= samples[curveMode][pulse - 1U]);
  742. }
  743. for (pulse = firstPeak + 1U; pulse <= lastPeak; pulse++)
  744. {
  745. EXPECT_U(peakFrequencyHz, samples[curveMode][pulse]);
  746. }
  747. for (pulse = lastPeak + 1U;
  748. pulse < pulseCounts[countIndex]; pulse++)
  749. {
  750. EXPECT_TRUE(samples[curveMode][pulse]
  751. <= samples[curveMode][pulse - 1U]);
  752. }
  753. EXPECT_TRUE((samples[curveMode][0]
  754. > samples[curveMode][pulseCounts[countIndex] - 1U]
  755. ? samples[curveMode][0]
  756. - samples[curveMode][pulseCounts[countIndex] - 1U]
  757. : samples[curveMode][pulseCounts[countIndex] - 1U]
  758. - samples[curveMode][0]) <= 2UL);
  759. EXPECT_U(0U, PlsrTestPulseIsActive());
  760. PlsrPoll1ms();
  761. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  762. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  763. EXPECT_I((long)pulseCounts[countIndex], ReadPosition());
  764. EXPECT_TRUE(durationNs[curveMode]
  765. > previousDurationNs[curveMode]);
  766. previousDurationNs[curveMode] = durationNs[curveMode];
  767. expectedPeakHz = IntegerSquareRoot64(
  768. 10000ULL + (uint64_t)pulseCounts[countIndex] * 1000ULL);
  769. expectedDurationNs =
  770. (uint64_t)2U * (expectedPeakHz - 100UL) * 1000000ULL;
  771. toleranceNs = expectedDurationNs / 8ULL + 2000000ULL;
  772. EXPECT_TRUE(UnsignedDifference64(durationNs[curveMode],
  773. expectedDurationNs)
  774. <= toleranceNs);
  775. }
  776. toleranceNs = durationNs[0] / 50ULL + 1000000ULL;
  777. EXPECT_TRUE(UnsignedDifference64(durationNs[0], durationNs[1])
  778. <= toleranceNs);
  779. EXPECT_TRUE(UnsignedDifference64(durationNs[1], durationNs[2])
  780. <= toleranceNs);
  781. if (pulseCounts[countIndex] >= 10U)
  782. {
  783. linearDiffersFromSmooth = 0U;
  784. smoothDiffersFromSine = 0U;
  785. for (pulse = 0U; pulse < pulseCounts[countIndex]; pulse++)
  786. {
  787. if (samples[0][pulse] != samples[1][pulse])
  788. {
  789. linearDiffersFromSmooth = 1U;
  790. }
  791. if (samples[1][pulse] != samples[2][pulse])
  792. {
  793. smoothDiffersFromSine = 1U;
  794. }
  795. }
  796. EXPECT_U(1U, linearDiffersFromSmooth);
  797. if (linearDiffersFromSmooth != 0U)
  798. {
  799. anyLinearDiffersFromSmooth = 1U;
  800. }
  801. if (smoothDiffersFromSine != 0U)
  802. {
  803. anySmoothDiffersFromSine = 1U;
  804. }
  805. }
  806. }
  807. EXPECT_U(1U, anyLinearDiffersFromSmooth);
  808. EXPECT_U(1U, anySmoothDiffersFromSine);
  809. }
  810. static void TestShortFinalDeceleratesWithoutPoll(void)
  811. {
  812. uint16_t curveMode;
  813. unsigned int pulse;
  814. uint32_t previousFrequencyHz;
  815. uint32_t currentFrequencyHz;
  816. uint64_t durationNs;
  817. for (curveMode = 0U; curveMode <= 2U; curveMode++)
  818. {
  819. ResetCore();
  820. ConfigureCommon(curveMode, PLSR_POSITION_RELATIVE, 1U,
  821. PLSR_SEND_COMPLETE, 100000UL, 100000UL, 100UL,
  822. 0U, 1000U);
  823. EXPECT_U(PLSR_MB_OK,
  824. SetSegment(1U, 100000UL, 10L, PLSR_EXT_OR_COMPLETE,
  825. 0U, 0U, 0U));
  826. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  827. previousFrequencyHz = PlsrTestOutputFrequency();
  828. EXPECT_TRUE(previousFrequencyHz >= 99990UL);
  829. EXPECT_TRUE(previousFrequencyHz <= 100000UL);
  830. durationNs = PulsePeriodNs(previousFrequencyHz);
  831. for (pulse = 1U; pulse < 10U; pulse++)
  832. {
  833. PlsrTestEmitPulses(1UL);
  834. EXPECT_U(1U, PlsrTestPulseIsActive());
  835. currentFrequencyHz = PlsrTestOutputFrequency();
  836. EXPECT_TRUE(currentFrequencyHz <= previousFrequencyHz);
  837. EXPECT_TRUE(currentFrequencyHz >= 99990UL);
  838. durationNs += PulsePeriodNs(currentFrequencyHz);
  839. previousFrequencyHz = currentFrequencyHz;
  840. }
  841. EXPECT_TRUE(durationNs >= 99990ULL);
  842. EXPECT_TRUE(durationNs <= 100010ULL);
  843. PlsrTestEmitPulses(1UL);
  844. EXPECT_U(0U, PlsrTestPulseIsActive());
  845. PlsrPoll1ms();
  846. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  847. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  848. EXPECT_I(10L, ReadPosition());
  849. }
  850. }
  851. static void TestZeroToMaximumRampKeepsConfiguredDuration(void)
  852. {
  853. uint16_t curveMode;
  854. uint32_t firstFrequencyHz[3];
  855. uint32_t previousFrequencyHz;
  856. uint32_t currentFrequencyHz;
  857. uint32_t frequencyStepHz;
  858. uint32_t maximumStepHz;
  859. uint32_t pulse;
  860. uint64_t durationNs;
  861. const uint64_t expectedDurationNs = 20000000ULL;
  862. const uint64_t toleranceNs = 100000ULL;
  863. for (curveMode = 0U; curveMode <= 2U; curveMode++)
  864. {
  865. ResetCore();
  866. ConfigureCommon(curveMode, PLSR_POSITION_RELATIVE, 1U,
  867. PLSR_SEND_COMPLETE, 100000UL, 0UL, 100000UL,
  868. 20U, 0U);
  869. EXPECT_U(PLSR_MB_OK,
  870. SetSegment(1U, 100000UL, 1000L,
  871. PLSR_EXT_OR_COMPLETE, 0U, 0U, 0U));
  872. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  873. EXPECT_U(1U, PlsrTestPulseIsActive());
  874. previousFrequencyHz = PlsrTestOutputFrequency();
  875. firstFrequencyHz[curveMode] = previousFrequencyHz;
  876. EXPECT_TRUE(previousFrequencyHz >= 400UL);
  877. EXPECT_TRUE(previousFrequencyHz <= 2500UL);
  878. maximumStepHz = 0UL;
  879. durationNs = PulsePeriodNs(previousFrequencyHz);
  880. for (pulse = 1UL; pulse < 1000UL; pulse++)
  881. {
  882. PlsrTestEmitPulses(1UL);
  883. EXPECT_U(1U, PlsrTestPulseIsActive());
  884. currentFrequencyHz = PlsrTestOutputFrequency();
  885. EXPECT_TRUE(currentFrequencyHz >= previousFrequencyHz);
  886. EXPECT_TRUE(currentFrequencyHz <= 100000UL);
  887. frequencyStepHz = currentFrequencyHz - previousFrequencyHz;
  888. if (frequencyStepHz > maximumStepHz)
  889. {
  890. maximumStepHz = frequencyStepHz;
  891. }
  892. durationNs += PulsePeriodNs(currentFrequencyHz);
  893. previousFrequencyHz = currentFrequencyHz;
  894. }
  895. EXPECT_TRUE(maximumStepHz <= 10000UL);
  896. EXPECT_TRUE(previousFrequencyHz >= 99000UL);
  897. EXPECT_TRUE(UnsignedDifference64(durationNs, expectedDurationNs)
  898. <= toleranceNs);
  899. PlsrTestEmitPulses(1UL);
  900. EXPECT_U(0U, PlsrTestPulseIsActive());
  901. PlsrPoll1ms();
  902. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  903. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  904. EXPECT_I(1000L, ReadPosition());
  905. }
  906. EXPECT_TRUE(firstFrequencyHz[0] > firstFrequencyHz[1]);
  907. EXPECT_TRUE(firstFrequencyHz[1] > firstFrequencyHz[2]);
  908. }
  909. static void TestMaximumPulseRampKeepsReachableDuration(void)
  910. {
  911. uint16_t curveMode;
  912. uint32_t previousFrequencyHz;
  913. uint32_t currentFrequencyHz;
  914. uint32_t frequencyStepHz;
  915. uint32_t maximumStepHz;
  916. uint32_t pulse;
  917. uint32_t reachablePeakHz = IntegerSquareRoot64(
  918. (uint64_t)2U * 65535UL * 100000UL * 1000UL / 1311UL);
  919. uint64_t durationNs;
  920. uint64_t expectedDurationNs =
  921. (uint64_t)2U * 65535UL * 1000000000ULL / reachablePeakHz;
  922. uint64_t toleranceNs = expectedDurationNs / 500ULL + 1000000ULL;
  923. for (curveMode = 0U; curveMode <= 2U; curveMode++)
  924. {
  925. ResetCore();
  926. ConfigureCommon(curveMode, PLSR_POSITION_RELATIVE, 1U,
  927. PLSR_SEND_COMPLETE, 100000UL, 0UL, 100000UL,
  928. 1311U, 0U);
  929. EXPECT_U(PLSR_MB_OK,
  930. SetSegment(1U, 100000UL, 65535L,
  931. PLSR_EXT_OR_COMPLETE, 0U, 0U, 0U));
  932. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  933. EXPECT_U(1U, PlsrTestPulseIsActive());
  934. previousFrequencyHz = PlsrTestOutputFrequency();
  935. EXPECT_TRUE(previousFrequencyHz > 1UL);
  936. EXPECT_TRUE(previousFrequencyHz < reachablePeakHz);
  937. maximumStepHz = 0UL;
  938. durationNs = PulsePeriodNs(previousFrequencyHz);
  939. for (pulse = 1UL; pulse < 65535UL; pulse++)
  940. {
  941. PlsrTestEmitPulses(1UL);
  942. EXPECT_U(1U, PlsrTestPulseIsActive());
  943. currentFrequencyHz = PlsrTestOutputFrequency();
  944. EXPECT_TRUE(currentFrequencyHz >= previousFrequencyHz);
  945. EXPECT_TRUE(currentFrequencyHz <= reachablePeakHz + 5UL);
  946. frequencyStepHz = currentFrequencyHz - previousFrequencyHz;
  947. if (frequencyStepHz > maximumStepHz)
  948. {
  949. maximumStepHz = frequencyStepHz;
  950. }
  951. durationNs += PulsePeriodNs(currentFrequencyHz);
  952. previousFrequencyHz = currentFrequencyHz;
  953. }
  954. EXPECT_TRUE(maximumStepHz <= 5000UL);
  955. EXPECT_TRUE(previousFrequencyHz * 100UL
  956. >= reachablePeakHz * 99UL);
  957. EXPECT_TRUE(UnsignedDifference64(durationNs, expectedDurationNs)
  958. <= toleranceNs);
  959. PlsrTestEmitPulses(1UL);
  960. EXPECT_U(0U, PlsrTestPulseIsActive());
  961. PlsrPoll1ms();
  962. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  963. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  964. EXPECT_I(65535L, ReadPosition());
  965. }
  966. }
  967. static void TestMaximumSingleRampWithoutPoll(void)
  968. {
  969. uint16_t curveMode;
  970. uint32_t previousFrequencyHz;
  971. uint32_t currentFrequencyHz;
  972. uint32_t minimumFrequencyHz;
  973. uint32_t maximumFrequencyHz;
  974. uint32_t pulse;
  975. for (curveMode = 0U; curveMode <= 2U; curveMode++)
  976. {
  977. ResetCore();
  978. ConfigureCommon(curveMode, PLSR_POSITION_RELATIVE, 1U,
  979. PLSR_SEND_COMPLETE, 1000UL, 100000UL, 0UL,
  980. 1000U, 1000U);
  981. EXPECT_U(PLSR_MB_OK,
  982. SetSegment(1U, 100000UL, 65535L,
  983. PLSR_EXT_OR_COMPLETE, 0U, 0U, 0U));
  984. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  985. previousFrequencyHz = PlsrTestOutputFrequency();
  986. minimumFrequencyHz = previousFrequencyHz;
  987. maximumFrequencyHz = previousFrequencyHz;
  988. EXPECT_TRUE(previousFrequencyHz >= 99000UL);
  989. EXPECT_TRUE(previousFrequencyHz <= 100000UL);
  990. for (pulse = 1UL; pulse < 65535UL; pulse++)
  991. {
  992. PlsrTestEmitPulses(1UL);
  993. EXPECT_U(1U, PlsrTestPulseIsActive());
  994. currentFrequencyHz = PlsrTestOutputFrequency();
  995. EXPECT_TRUE(currentFrequencyHz <= previousFrequencyHz);
  996. EXPECT_TRUE(currentFrequencyHz >= 99000UL);
  997. if (currentFrequencyHz < minimumFrequencyHz)
  998. {
  999. minimumFrequencyHz = currentFrequencyHz;
  1000. }
  1001. if (currentFrequencyHz > maximumFrequencyHz)
  1002. {
  1003. maximumFrequencyHz = currentFrequencyHz;
  1004. }
  1005. previousFrequencyHz = currentFrequencyHz;
  1006. }
  1007. EXPECT_TRUE(minimumFrequencyHz > 1UL);
  1008. EXPECT_TRUE(maximumFrequencyHz <= 100000UL);
  1009. EXPECT_TRUE(minimumFrequencyHz < maximumFrequencyHz);
  1010. PlsrTestEmitPulses(1UL);
  1011. EXPECT_U(0U, PlsrTestPulseIsActive());
  1012. PlsrPoll1ms();
  1013. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  1014. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  1015. EXPECT_I(65535L, ReadPosition());
  1016. }
  1017. }
  1018. static void TestShortProfileTimerFailure(void)
  1019. {
  1020. ResetCore();
  1021. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1022. 1000UL, 100UL, 100UL, 1000U, 1000U);
  1023. EXPECT_U(PLSR_MB_OK,
  1024. SetSegment(1U, 1000UL, 10L, PLSR_EXT_OR_COMPLETE,
  1025. 0U, 0U, 0U));
  1026. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1027. PlsrTestFailNextFrequencyAtUpdate();
  1028. PlsrTestEmitPulses(1UL);
  1029. EXPECT_U(0U, PlsrTestPulseIsActive());
  1030. PlsrPoll1ms();
  1031. EXPECT_U(PLSR_STATUS_ERROR, ReadStatus());
  1032. EXPECT_U(PLSR_ERROR_TIMER, ReadError());
  1033. EXPECT_I(1L, ReadPosition());
  1034. }
  1035. static void TestStopImmediatelyAfterSubsequentHandoff(void)
  1036. {
  1037. unsigned int tick;
  1038. ResetCore();
  1039. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
  1040. PLSR_SEND_SUBSEQUENT, 1000UL, 1000UL, 100UL,
  1041. 0U, 100U);
  1042. EXPECT_U(PLSR_MB_OK,
  1043. SetSegment(1U, 1000UL, 3L, PLSR_EXT_OR_COMPLETE,
  1044. 0U, 0U, 0U));
  1045. EXPECT_U(PLSR_MB_OK,
  1046. SetSegment(2U, 2000UL, 20L, PLSR_EXT_OR_COMPLETE,
  1047. 0U, 0U, 0U));
  1048. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1049. PlsrTestEmitPulses(3UL);
  1050. EXPECT_U(2U, ReadCurrentSegment());
  1051. EXPECT_TRUE(PlsrTestOutputFrequency() <= 2000UL);
  1052. EXPECT_TRUE(PlsrTestOutputFrequency() > 100UL);
  1053. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
  1054. PlsrPoll1ms();
  1055. PlsrTestEmitPulses(1UL);
  1056. EXPECT_U(PLSR_STATUS_DECELERATING, ReadStatus());
  1057. EXPECT_U(1U, PlsrTestPulseIsActive());
  1058. EXPECT_TRUE(PlsrTestOutputFrequency() < 2000UL);
  1059. EXPECT_TRUE(PlsrTestOutputFrequency() > 100UL);
  1060. for (tick = 1U; tick < 190U; tick++)
  1061. {
  1062. PlsrPoll1ms();
  1063. }
  1064. while (PlsrTestPulseIsActive() != 0U)
  1065. {
  1066. PlsrTestEmitPulses(1UL);
  1067. }
  1068. PlsrPoll1ms();
  1069. EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
  1070. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  1071. EXPECT_I(7L, ReadPosition());
  1072. }
  1073. static void TestShortProfileZeroSpeedEdges(void)
  1074. {
  1075. unsigned int tick;
  1076. ResetCore();
  1077. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1078. 1000UL, 0UL, 0UL, 1000U, 1000U);
  1079. EXPECT_U(PLSR_MB_OK,
  1080. SetSegment(1U, 1000UL, 2L, PLSR_EXT_OR_COMPLETE,
  1081. 0U, 0U, 0U));
  1082. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1083. EXPECT_U(1U, PlsrTestPulseIsActive());
  1084. EXPECT_TRUE(PlsrTestOutputFrequency() > 0UL);
  1085. PlsrTestEmitPulses(1UL);
  1086. EXPECT_U(1U, PlsrTestPulseIsActive());
  1087. EXPECT_TRUE(PlsrTestOutputFrequency() > 0UL);
  1088. PlsrTestEmitPulses(1UL);
  1089. EXPECT_U(0U, PlsrTestPulseIsActive());
  1090. PlsrPoll1ms();
  1091. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  1092. EXPECT_I(2L, ReadPosition());
  1093. ResetCore();
  1094. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1095. 1000UL, 0UL, 0UL, 1000U, 1000U);
  1096. EXPECT_U(PLSR_MB_OK,
  1097. SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
  1098. 0U, 0U, 0U));
  1099. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1100. for (tick = 0U; (tick < 10U) && (PlsrTestPulseIsActive() == 0U);
  1101. tick++)
  1102. {
  1103. PlsrPoll1ms();
  1104. }
  1105. EXPECT_U(1U, PlsrTestPulseIsActive());
  1106. PlsrTestEmitPulses(1UL);
  1107. PlsrPoll1ms();
  1108. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  1109. EXPECT_I(1L, ReadPosition());
  1110. }
  1111. static void TestShortProfileDynamicRetarget(void)
  1112. {
  1113. unsigned int tick;
  1114. uint32_t frequencyAfterRetarget;
  1115. int32_t positionBeforeStop;
  1116. int32_t positionAfterStop;
  1117. ResetCore();
  1118. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1119. 1000UL, 100UL, 100UL, 1000U, 1000U);
  1120. EXPECT_U(PLSR_MB_OK,
  1121. SetSegment(1U, 1000UL, 50L, PLSR_EXT_OR_COMPLETE,
  1122. 0U, 0U, 0U));
  1123. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1124. PlsrTestEmitPulses(3UL);
  1125. EXPECT_U(PLSR_MB_OK, WriteU32(0x1100U, 2000UL));
  1126. PlsrPoll1ms();
  1127. PlsrTestEmitPulses(1UL);
  1128. frequencyAfterRetarget = PlsrTestOutputFrequency();
  1129. PlsrTestEmitPulses(1UL);
  1130. EXPECT_TRUE(PlsrTestOutputFrequency() > 0UL);
  1131. for (tick = 0U; tick < 10U; tick++)
  1132. {
  1133. PlsrPoll1ms();
  1134. PlsrTestEmitPulses(1UL);
  1135. }
  1136. EXPECT_TRUE(PlsrTestOutputFrequency() > frequencyAfterRetarget);
  1137. positionBeforeStop = ReadPosition();
  1138. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
  1139. for (tick = 0U; tick < 2000U; tick++)
  1140. {
  1141. PlsrPoll1ms();
  1142. }
  1143. while (PlsrTestPulseIsActive() != 0U)
  1144. {
  1145. PlsrTestEmitPulses(1UL);
  1146. }
  1147. PlsrPoll1ms();
  1148. EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
  1149. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  1150. positionAfterStop = ReadPosition();
  1151. EXPECT_TRUE(positionAfterStop > positionBeforeStop);
  1152. EXPECT_TRUE(positionAfterStop <= positionBeforeStop + 3L);
  1153. }
  1154. static void TestShortProfileExtCut(void)
  1155. {
  1156. uint32_t frequencyBeforeCut;
  1157. ResetCore();
  1158. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1159. 1000UL, 100UL, 100UL, 1000U, 1000U);
  1160. EXPECT_U(PLSR_MB_OK,
  1161. SetSegment(1U, 1000UL, 50L, PLSR_EXT_SIGNAL,
  1162. 0U, 0U, 0U));
  1163. PlsrTestSetInput(0U, 0U);
  1164. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1165. PlsrTestEmitPulses(3UL);
  1166. frequencyBeforeCut = PlsrTestOutputFrequency();
  1167. PlsrTestSetInput(0U, 1U);
  1168. PlsrPoll1ms();
  1169. PlsrTestEmitPulses(1UL);
  1170. EXPECT_U(0U, PlsrTestPulseIsActive());
  1171. EXPECT_U(0UL, PlsrTestOutputFrequency());
  1172. PlsrPoll1ms();
  1173. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  1174. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  1175. EXPECT_I(4L, ReadPosition());
  1176. EXPECT_TRUE(frequencyBeforeCut > 100UL);
  1177. }
  1178. static void TestCurrentFrequencyIsDynamic(void)
  1179. {
  1180. ResetCore();
  1181. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1182. 1000UL, 1000UL, 100UL, 0U, 0U);
  1183. EXPECT_U(PLSR_MB_OK,
  1184. SetSegment(1U, 1000UL, 100L, PLSR_EXT_OR_COMPLETE,
  1185. 0U, 0U, 0U));
  1186. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1187. EXPECT_U(1000UL, PlsrTestOutputFrequency());
  1188. EXPECT_U(PLSR_MB_OK, WriteU32(0x1100U, 2000UL));
  1189. PlsrPoll1ms();
  1190. EXPECT_U(1000UL, PlsrTestOutputFrequency());
  1191. PlsrTestEmitPulses(1UL);
  1192. EXPECT_U(1000UL, PlsrTestOutputFrequency());
  1193. EXPECT_U(1000UL, ReadFrequency());
  1194. PlsrTestEmitPulses(1UL);
  1195. EXPECT_U(2000UL, PlsrTestOutputFrequency());
  1196. EXPECT_U(2000UL, ReadFrequency());
  1197. EXPECT_U(PLSR_MB_OK, WriteI32(0x1102U, 1L));
  1198. PlsrTestEmitPulses(2UL);
  1199. EXPECT_U(1U, PlsrTestPulseIsActive());
  1200. StopAndSettle();
  1201. }
  1202. static void TestPollMailboxDefersPlatformFailure(void)
  1203. {
  1204. ResetCore();
  1205. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1206. 1000UL, 1000UL, 100UL, 0U, 0U);
  1207. EXPECT_U(PLSR_MB_OK,
  1208. SetSegment(1U, 1000UL, 100L, PLSR_EXT_OR_COMPLETE,
  1209. 0U, 0U, 0U));
  1210. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1211. PlsrTestFailNextFrequencyAtUpdate();
  1212. EXPECT_U(PLSR_MB_OK, WriteU32(0x1100U, 2000UL));
  1213. PlsrPoll1ms();
  1214. EXPECT_U(PLSR_STATUS_RUNNING, ReadStatus());
  1215. EXPECT_U(1U, PlsrTestPulseIsActive());
  1216. EXPECT_U(1000UL, PlsrTestOutputFrequency());
  1217. PlsrTestEmitPulses(1UL);
  1218. EXPECT_U(0U, PlsrTestPulseIsActive());
  1219. PlsrPoll1ms();
  1220. EXPECT_U(PLSR_STATUS_ERROR, ReadStatus());
  1221. EXPECT_U(PLSR_ERROR_TIMER, ReadError());
  1222. EXPECT_I(1L, ReadPosition());
  1223. }
  1224. static void TestFutureSegmentFrequencyAppliesOnArrival(void)
  1225. {
  1226. ResetCore();
  1227. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U, PLSR_SEND_COMPLETE,
  1228. 1000UL, 1000UL, 100UL, 0U, 0U);
  1229. EXPECT_U(PLSR_MB_OK,
  1230. SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
  1231. 0U, 0U, 0U));
  1232. EXPECT_U(PLSR_MB_OK,
  1233. SetSegment(2U, 3000UL, 10L, PLSR_EXT_OR_COMPLETE,
  1234. 0U, 0U, 0U));
  1235. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1236. EXPECT_U(PLSR_MB_OK, WriteU32(0x1110U, 5000UL));
  1237. EXPECT_U(1000UL, PlsrTestOutputFrequency());
  1238. PlsrTestEmitPulses(1UL);
  1239. PlsrPoll1ms();
  1240. EXPECT_U(2U, ReadCurrentSegment());
  1241. EXPECT_U(5000UL, PlsrTestOutputFrequency());
  1242. EXPECT_U(5000UL, ReadFrequency());
  1243. StopAndSettle();
  1244. }
  1245. static void TestSubsequentFutureFrequencyRebuildsHandoff(void)
  1246. {
  1247. ResetCore();
  1248. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
  1249. PLSR_SEND_SUBSEQUENT, 1000UL, 1000UL, 100UL, 0U, 0U);
  1250. EXPECT_U(PLSR_MB_OK,
  1251. SetSegment(1U, 1000UL, 3L, PLSR_EXT_OR_COMPLETE,
  1252. 0U, 0U, 0U));
  1253. EXPECT_U(PLSR_MB_OK,
  1254. SetSegment(2U, 2000UL, 4L, PLSR_EXT_OR_COMPLETE,
  1255. 0U, 0U, 0U));
  1256. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1257. EXPECT_U(PLSR_MB_OK, WriteU32(0x1110U, 5000UL));
  1258. EXPECT_U(1000UL, PlsrTestOutputFrequency());
  1259. PlsrTestEmitPulses(3UL);
  1260. EXPECT_U(1U, PlsrTestPulseIsActive());
  1261. EXPECT_U(2U, ReadCurrentSegment());
  1262. EXPECT_U(5000UL, PlsrTestOutputFrequency());
  1263. EXPECT_U(5000UL, ReadFrequency());
  1264. PlsrTestEmitPulses(4UL);
  1265. EXPECT_U(0U, PlsrTestPulseIsActive());
  1266. PlsrPoll1ms();
  1267. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  1268. EXPECT_I(7L, ReadPosition());
  1269. }
  1270. static void TestFutureFrequencyRaceAtLastPulse(void)
  1271. {
  1272. ResetCore();
  1273. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
  1274. PLSR_SEND_SUBSEQUENT, 1000UL, 1000UL, 100UL, 0U, 0U);
  1275. EXPECT_U(PLSR_MB_OK,
  1276. SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
  1277. 0U, 0U, 0U));
  1278. EXPECT_U(PLSR_MB_OK,
  1279. SetSegment(2U, 2000UL, 4L, PLSR_EXT_OR_COMPLETE,
  1280. 0U, 0U, 0U));
  1281. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1282. PlsrTestEmitPulseOnCriticalExit();
  1283. EXPECT_U(PLSR_MB_OK, WriteU32(0x1110U, 5000UL));
  1284. EXPECT_U(1U, PlsrTestPulseIsActive());
  1285. EXPECT_U(2U, ReadCurrentSegment());
  1286. EXPECT_U(5000UL, PlsrTestOutputFrequency());
  1287. EXPECT_I(1L, ReadPosition());
  1288. PlsrTestEmitPulses(4UL);
  1289. EXPECT_U(0U, PlsrTestPulseIsActive());
  1290. PlsrPoll1ms();
  1291. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  1292. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  1293. EXPECT_I(5L, ReadPosition());
  1294. }
  1295. static void TestLatchedUpdateDrainsBeforeFutureFrequencyCommit(void)
  1296. {
  1297. ResetCore();
  1298. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
  1299. PLSR_SEND_SUBSEQUENT, 1000UL, 1000UL, 100UL, 0U, 0U);
  1300. EXPECT_U(PLSR_MB_OK,
  1301. SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
  1302. 0U, 0U, 0U));
  1303. EXPECT_U(PLSR_MB_OK,
  1304. SetSegment(2U, 2000UL, 4L, PLSR_EXT_OR_COMPLETE,
  1305. 0U, 0U, 0U));
  1306. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1307. EXPECT_U(1000UL, PlsrTestOutputFrequency());
  1308. EXPECT_U(2000UL, PlsrTestQueuedFrequency());
  1309. /* The physical edge latches 2000 Hz while interrupts are masked by the
  1310. configuration commit. The ISR must consume that old handoff before
  1311. the new 5000 Hz preload replaces it. */
  1312. PlsrTestLatchPulseOnCriticalEntry();
  1313. EXPECT_U(PLSR_MB_OK, WriteU32(0x1110U, 5000UL));
  1314. EXPECT_U(2U, ReadCurrentSegment());
  1315. EXPECT_I(1L, ReadPosition());
  1316. EXPECT_U(2000UL, ReadFrequency());
  1317. EXPECT_U(2000UL, PlsrTestOutputFrequency());
  1318. PlsrPoll1ms();
  1319. EXPECT_U(5000UL, PlsrTestQueuedFrequency());
  1320. PlsrTestEmitPulses(1UL);
  1321. EXPECT_U(2U, ReadCurrentSegment());
  1322. EXPECT_I(2L, ReadPosition());
  1323. EXPECT_U(5000UL, ReadFrequency());
  1324. EXPECT_U(5000UL, PlsrTestOutputFrequency());
  1325. PlsrTestEmitPulses(3UL);
  1326. EXPECT_U(0U, PlsrTestPulseIsActive());
  1327. PlsrPoll1ms();
  1328. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  1329. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  1330. EXPECT_I(5L, ReadPosition());
  1331. }
  1332. static void TestSubsequentHandoffHasNoPollGap(void)
  1333. {
  1334. ResetCore();
  1335. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
  1336. PLSR_SEND_SUBSEQUENT, 1000UL, 1000UL, 100UL, 0U, 0U);
  1337. EXPECT_U(PLSR_MB_OK,
  1338. SetSegment(1U, 1000UL, 3L, PLSR_EXT_OR_COMPLETE,
  1339. 0U, 0U, 0U));
  1340. EXPECT_U(PLSR_MB_OK,
  1341. SetSegment(2U, 2000UL, 4L, PLSR_EXT_OR_COMPLETE,
  1342. 0U, 0U, 0U));
  1343. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1344. PlsrTestEmitPulses(3UL);
  1345. EXPECT_U(1U, PlsrTestPulseIsActive());
  1346. EXPECT_U(2U, ReadCurrentSegment());
  1347. EXPECT_U(2000UL, PlsrTestOutputFrequency());
  1348. EXPECT_I(3L, ReadPosition());
  1349. PlsrTestEmitPulses(4UL);
  1350. EXPECT_U(0U, PlsrTestPulseIsActive());
  1351. PlsrPoll1ms();
  1352. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  1353. EXPECT_I(7L, ReadPosition());
  1354. }
  1355. static void TestThreeSinglePulseSubsequentWithoutPoll(void)
  1356. {
  1357. ResetCore();
  1358. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 3U,
  1359. PLSR_SEND_SUBSEQUENT, 3000UL, 1000UL, 3000UL,
  1360. 0U, 0U);
  1361. EXPECT_U(PLSR_MB_OK,
  1362. SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
  1363. 0U, 0U, 0U));
  1364. EXPECT_U(PLSR_MB_OK,
  1365. SetSegment(2U, 2000UL, 1L, PLSR_EXT_OR_COMPLETE,
  1366. 0U, 0U, 0U));
  1367. EXPECT_U(PLSR_MB_OK,
  1368. SetSegment(3U, 3000UL, 1L, PLSR_EXT_OR_COMPLETE,
  1369. 0U, 0U, 0U));
  1370. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1371. EXPECT_U(1000UL, PlsrTestOutputFrequency());
  1372. PlsrTestEmitPulses(1UL);
  1373. EXPECT_U(1U, PlsrTestPulseIsActive());
  1374. EXPECT_U(2U, ReadCurrentSegment());
  1375. EXPECT_U(2000UL, PlsrTestOutputFrequency());
  1376. EXPECT_I(1L, ReadPosition());
  1377. PlsrTestEmitPulses(1UL);
  1378. EXPECT_U(1U, PlsrTestPulseIsActive());
  1379. EXPECT_U(3U, ReadCurrentSegment());
  1380. EXPECT_U(3000UL, PlsrTestOutputFrequency());
  1381. EXPECT_I(2L, ReadPosition());
  1382. PlsrTestEmitPulses(1UL);
  1383. EXPECT_U(0U, PlsrTestPulseIsActive());
  1384. EXPECT_I(3L, ReadPosition());
  1385. PlsrPoll1ms();
  1386. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  1387. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  1388. }
  1389. static void ConfigureHandoffFailureCase(void)
  1390. {
  1391. ResetCore();
  1392. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
  1393. PLSR_SEND_SUBSEQUENT, 2000UL, 1000UL, 2000UL,
  1394. 0U, 0U);
  1395. EXPECT_U(PLSR_MB_OK,
  1396. SetSegment(1U, 1000UL, 3L, PLSR_EXT_OR_COMPLETE,
  1397. 0U, 0U, 0U));
  1398. EXPECT_U(PLSR_MB_OK,
  1399. SetSegment(2U, 2000UL, 2L, PLSR_EXT_OR_COMPLETE,
  1400. 0U, 0U, 0U));
  1401. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1402. }
  1403. static void ExpectHandoffTimerError(void)
  1404. {
  1405. EXPECT_U(0U, PlsrTestPulseIsActive());
  1406. PlsrPoll1ms();
  1407. EXPECT_U(PLSR_STATUS_ERROR, ReadStatus());
  1408. EXPECT_U(PLSR_ERROR_TIMER, ReadError());
  1409. EXPECT_U(0U, ReadCurrentSegment());
  1410. EXPECT_I(3L, ReadPosition());
  1411. }
  1412. static void TestHandoffQueueFailuresBecomeTimerError(void)
  1413. {
  1414. ConfigureHandoffFailureCase();
  1415. PlsrTestEmitPulses(1UL);
  1416. PlsrTestFailNextFrequencyAtUpdate();
  1417. PlsrTestEmitPulses(1UL);
  1418. EXPECT_U(1U, PlsrTestPulseIsActive());
  1419. PlsrTestEmitPulses(1UL);
  1420. ExpectHandoffTimerError();
  1421. ConfigureHandoffFailureCase();
  1422. PlsrTestEmitPulses(2UL);
  1423. PlsrTestFailNextFrequencyAtUpdate();
  1424. PlsrTestEmitPulses(1UL);
  1425. ExpectHandoffTimerError();
  1426. }
  1427. static void TestCommandStateRestrictions(void)
  1428. {
  1429. ResetCore();
  1430. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1431. 1000UL, 1000UL, 100UL, 0U, 0U);
  1432. EXPECT_U(PLSR_MB_OK,
  1433. SetSegment(1U, 1000UL, 100L, PLSR_EXT_OR_COMPLETE,
  1434. 0U, 0U, 0U));
  1435. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
  1436. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_CLEAR));
  1437. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1438. EXPECT_U(PLSR_MB_DEVICE_BUSY, SendCommand(PLSR_COMMAND_START));
  1439. EXPECT_U(PLSR_MB_DEVICE_BUSY, SendCommand(PLSR_COMMAND_CLEAR));
  1440. EXPECT_U(PLSR_MB_DEVICE_BUSY, WriteWord(0x1000U, 1U));
  1441. EXPECT_U(PLSR_MB_DEVICE_BUSY, WriteWord(0x1001U, 1U));
  1442. EXPECT_U(PLSR_MB_OK, WriteWord(0x1002U, 1U));
  1443. EXPECT_U(PLSR_MB_ILLEGAL_VALUE, SendCommand(3U));
  1444. StopAndSettle();
  1445. }
  1446. static void TestCommandMailboxStartSnapshotAndConflicts(void)
  1447. {
  1448. ResetCore();
  1449. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1450. 1000UL, 1000UL, 1000UL, 0U, 0U);
  1451. EXPECT_U(PLSR_MB_OK,
  1452. SetSegment(1U, 1000UL, 20L, PLSR_EXT_OR_COMPLETE,
  1453. 0U, 0U, 0U));
  1454. EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_START));
  1455. EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
  1456. EXPECT_U(0U, ReadCurrentSegment());
  1457. EXPECT_U(0UL, ReadFrequency());
  1458. EXPECT_U(0U, PlsrTestPulseIsActive());
  1459. EXPECT_I(0L, ReadPosition());
  1460. EXPECT_U(PLSR_MB_OK, WriteI32(0x1102U, 1L));
  1461. EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_START));
  1462. EXPECT_U(PLSR_MB_DEVICE_BUSY, QueueCommand(PLSR_COMMAND_STOP));
  1463. EXPECT_U(PLSR_MB_DEVICE_BUSY, QueueCommand(PLSR_COMMAND_CLEAR));
  1464. EXPECT_U(PLSR_MB_ILLEGAL_VALUE, QueueCommand(3U));
  1465. EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
  1466. EXPECT_U(0U, PlsrTestPulseIsActive());
  1467. PlsrPoll1ms();
  1468. EXPECT_U(PLSR_STATUS_RUNNING, ReadStatus());
  1469. EXPECT_U(1U, ReadCurrentSegment());
  1470. EXPECT_U(1U, PlsrTestPulseIsActive());
  1471. PlsrTestEmitPulses(1UL);
  1472. EXPECT_U(1U, PlsrTestPulseIsActive());
  1473. EXPECT_I(1L, ReadPosition());
  1474. StopAndSettle();
  1475. }
  1476. static void TestCommandMailboxStopAndClearAreDeferred(void)
  1477. {
  1478. ResetCore();
  1479. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1480. 1000UL, 1000UL, 1000UL, 0U, 0U);
  1481. EXPECT_U(PLSR_MB_OK,
  1482. SetSegment(1U, 1000UL, 100L, PLSR_EXT_OR_COMPLETE,
  1483. 0U, 0U, 0U));
  1484. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1485. PlsrTestEmitPulses(2UL);
  1486. EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_STOP));
  1487. EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_STOP));
  1488. EXPECT_U(PLSR_MB_DEVICE_BUSY, QueueCommand(PLSR_COMMAND_CLEAR));
  1489. EXPECT_U(PLSR_MB_DEVICE_BUSY, QueueCommand(PLSR_COMMAND_START));
  1490. EXPECT_U(PLSR_STATUS_RUNNING, ReadStatus());
  1491. EXPECT_U(1U, PlsrTestPulseIsActive());
  1492. EXPECT_I(2L, ReadPosition());
  1493. PlsrPoll1ms();
  1494. EXPECT_U(PLSR_STATUS_DECELERATING, ReadStatus());
  1495. EXPECT_U(1U, PlsrTestPulseIsActive());
  1496. PlsrTestEmitPulses(1UL);
  1497. PlsrPoll1ms();
  1498. EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
  1499. EXPECT_U(0U, PlsrTestPulseIsActive());
  1500. PlsrTestSetPosition(17L, 1U);
  1501. EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_CLEAR));
  1502. EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_CLEAR));
  1503. EXPECT_U(PLSR_MB_DEVICE_BUSY, QueueCommand(PLSR_COMMAND_START));
  1504. EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
  1505. EXPECT_I(17L, ReadPosition());
  1506. PlsrPoll1ms();
  1507. EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
  1508. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  1509. EXPECT_I(0L, ReadPosition());
  1510. }
  1511. static void TestCommandMailboxValidatesBeforeQueue(void)
  1512. {
  1513. ResetCore();
  1514. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1515. 1000UL, 1000UL, 1000UL, 0U, 0U);
  1516. EXPECT_U(PLSR_MB_OK,
  1517. SetSegment(1U, 1000UL, 10L, PLSR_EXT_OR_COMPLETE,
  1518. 0U, 0U, 0U));
  1519. EXPECT_U(PLSR_MB_OK, WriteWord(0x100AU, 2U));
  1520. EXPECT_U(PLSR_MB_ILLEGAL_VALUE, QueueCommand(PLSR_COMMAND_START));
  1521. EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
  1522. EXPECT_U(0U, PlsrTestPulseIsActive());
  1523. EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_STOP));
  1524. PlsrPoll1ms();
  1525. EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
  1526. EXPECT_U(PLSR_MB_OK, WriteWord(0x100AU, 1U));
  1527. EXPECT_U(PLSR_MB_OK, WriteWord(0x1008U, PLSR_POSITION_ABSOLUTE));
  1528. PlsrTestSetPosition(3L, 0U);
  1529. EXPECT_U(PLSR_MB_ILLEGAL_VALUE, QueueCommand(PLSR_COMMAND_START));
  1530. EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
  1531. EXPECT_U(0U, PlsrTestPulseIsActive());
  1532. }
  1533. static void TestCommandMailboxStartFailureBecomesError(void)
  1534. {
  1535. ResetCore();
  1536. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1537. 1000UL, 1000UL, 1000UL, 0U, 0U);
  1538. EXPECT_U(PLSR_MB_OK,
  1539. SetSegment(1U, 1000UL, 10L, PLSR_EXT_OR_COMPLETE,
  1540. 0U, 0U, 0U));
  1541. PlsrTestFailNextStart();
  1542. EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_START));
  1543. EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
  1544. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  1545. EXPECT_U(0U, PlsrTestPulseIsActive());
  1546. PlsrPoll1ms();
  1547. EXPECT_U(PLSR_STATUS_ERROR, ReadStatus());
  1548. EXPECT_U(PLSR_ERROR_INVALID_RESOURCE, ReadError());
  1549. EXPECT_U(0U, ReadCurrentSegment());
  1550. EXPECT_U(0U, PlsrTestPulseIsActive());
  1551. EXPECT_U(PLSR_MB_DEVICE_BUSY, QueueCommand(PLSR_COMMAND_START));
  1552. EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_CLEAR));
  1553. PlsrPoll1ms();
  1554. EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
  1555. EXPECT_U(PLSR_ERROR_NONE, ReadError());
  1556. }
  1557. static void TestWaitSignalPositivePath(void)
  1558. {
  1559. ResetCore();
  1560. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1561. 1000UL, 1000UL, 100UL, 0U, 0U);
  1562. EXPECT_U(PLSR_MB_OK,
  1563. SetSegment(1U, 1000UL, 2L, PLSR_WAIT_SIGNAL,
  1564. 0U, 0U, 0U));
  1565. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1566. PlsrTestEmitPulses(2UL);
  1567. PlsrPoll1ms();
  1568. EXPECT_U(PLSR_STATUS_WAITING, ReadStatus());
  1569. PlsrTestSetInput(0U, 1U);
  1570. PlsrPoll1ms();
  1571. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  1572. }
  1573. static void TestPersistenceAcrossReinit(void)
  1574. {
  1575. ResetCore();
  1576. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1577. 2345UL, 2345UL, 100UL, 0U, 0U);
  1578. EXPECT_U(PLSR_MB_OK, WriteWord(0x1000U, 2U));
  1579. EXPECT_U(PLSR_MB_OK, WriteWord(0x1001U, 3U));
  1580. EXPECT_U(PLSR_MB_OK,
  1581. SetSegment(1U, 2345UL, 4L, PLSR_EXT_OR_COMPLETE,
  1582. 0U, 0U, 0U));
  1583. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1584. PlsrTestEmitPulses(4UL);
  1585. PlsrPoll1ms();
  1586. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  1587. EXPECT_I(4L, ReadPosition());
  1588. EXPECT_U(1U, PlsrInit());
  1589. EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
  1590. EXPECT_U(2U, ReadWord(0x1000U));
  1591. EXPECT_U(3U, ReadWord(0x1001U));
  1592. EXPECT_U(2345UL, ReadU32(0x1100U));
  1593. EXPECT_I(4L, ReadPosition());
  1594. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_CLEAR));
  1595. PlsrPoll1ms();
  1596. EXPECT_U(1U, PlsrInit());
  1597. EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
  1598. EXPECT_I(0L, ReadPosition());
  1599. }
  1600. static void TestPositionSchedulesFlashSave(void)
  1601. {
  1602. unsigned int tick;
  1603. ResetCore();
  1604. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1605. 1000UL, 1000UL, 100UL, 0U, 0U);
  1606. EXPECT_U(PLSR_MB_OK,
  1607. SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
  1608. 0U, 0U, 0U));
  1609. for (tick = 0U; tick < 1001U; tick++)
  1610. {
  1611. PlsrPoll1ms();
  1612. }
  1613. PlsrTestResetSaveCount();
  1614. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1615. PlsrTestEmitPulses(1UL);
  1616. PlsrPoll1ms();
  1617. EXPECT_U(0UL, PlsrTestSaveCount());
  1618. for (tick = 0U; tick < 1001U; tick++)
  1619. {
  1620. PlsrPoll1ms();
  1621. }
  1622. EXPECT_U(1UL, PlsrTestSaveCount());
  1623. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_CLEAR));
  1624. for (tick = 0U; tick < 1001U; tick++)
  1625. {
  1626. PlsrPoll1ms();
  1627. }
  1628. EXPECT_U(2UL, PlsrTestSaveCount());
  1629. }
  1630. static void TestBusyResetInvalidatesAbsolutePosition(void)
  1631. {
  1632. unsigned int tick;
  1633. ResetCore();
  1634. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1635. 1000UL, 1000UL, 100UL, 0U, 0U);
  1636. EXPECT_U(PLSR_MB_OK,
  1637. SetSegment(1U, 1000UL, 100L, PLSR_EXT_OR_COMPLETE,
  1638. 0U, 0U, 0U));
  1639. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1640. PlsrTestEmitPulses(5UL);
  1641. for (tick = 0U; tick < 10U; tick++)
  1642. {
  1643. PlsrPoll1ms();
  1644. }
  1645. EXPECT_I(5L, ReadPosition());
  1646. EXPECT_U(1U, PlsrInit());
  1647. EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
  1648. EXPECT_I(5L, ReadPosition());
  1649. EXPECT_U(PLSR_MB_OK, WriteWord(0x1008U, PLSR_POSITION_ABSOLUTE));
  1650. EXPECT_U(PLSR_MB_OK,
  1651. SetSegment(1U, 1000UL, 5L, PLSR_EXT_OR_COMPLETE,
  1652. 0U, 0U, 0U));
  1653. EXPECT_U(PLSR_MB_ILLEGAL_VALUE, SendCommand(PLSR_COMMAND_START));
  1654. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_CLEAR));
  1655. EXPECT_I(0L, ReadPosition());
  1656. EXPECT_U(PLSR_MB_OK,
  1657. SetSegment(1U, 1000UL, 0L, PLSR_EXT_OR_COMPLETE,
  1658. 0U, 0U, 0U));
  1659. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1660. PlsrPoll1ms();
  1661. EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
  1662. }
  1663. static void TestPositionOverflowStopsWithError(void)
  1664. {
  1665. ResetCore();
  1666. ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
  1667. 1000UL, 1000UL, 100UL, 0U, 0U);
  1668. EXPECT_U(PLSR_MB_OK,
  1669. SetSegment(1U, 1000UL, 2L, PLSR_EXT_OR_COMPLETE,
  1670. 0U, 0U, 0U));
  1671. PlsrTestSetPosition(INT32_MAX, 1U);
  1672. EXPECT_I(INT32_MAX, ReadPosition());
  1673. EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
  1674. PlsrTestEmitPulses(1UL);
  1675. EXPECT_U(0U, PlsrTestPulseIsActive());
  1676. PlsrPoll1ms();
  1677. EXPECT_U(PLSR_STATUS_ERROR, ReadStatus());
  1678. EXPECT_U(PLSR_ERROR_COUNT, ReadError());
  1679. EXPECT_I(INT32_MIN, ReadPosition());
  1680. }
  1681. typedef void (*TEST_FUNCTION)(void);
  1682. typedef struct
  1683. {
  1684. const char *name;
  1685. TEST_FUNCTION function;
  1686. } TEST_CASE;
  1687. static const TEST_CASE TestCases[] =
  1688. {
  1689. {"u64_by_u32_division", TestU64ByU32Division},
  1690. {"protocol_boundaries", TestProtocolBoundaries},
  1691. {"wait_zero_one_ms", TestWaitZeroUsesOneMillisecond},
  1692. {"act_zero_no_pulse", TestActZeroSkipsWithoutPulse},
  1693. {"relative_absolute_zero", TestRelativeAndAbsoluteZeroDisplacement},
  1694. {"self_jump_stop", TestSelfJumpCanStop},
  1695. {"stop_deceleration", TestStopDeceleratesBeforeCut},
  1696. {"stop_pending_boundary", TestStopAtPendingBoundary},
  1697. {"direction_delay_one_ms", TestOneMillisecondDirectionDelay},
  1698. {"ext_edge_at_natural_boundary", TestExtEdgeAtNaturalBoundary},
  1699. {"ext_cut_natural_boundary_interleavings",
  1700. TestExtCutAndNaturalBoundaryInterleavings},
  1701. {"ext_edge_during_direction_delay", TestExtEdgeDuringDirectionDelay},
  1702. {"stopped_clears_pending_ext", TestStoppedTaskClearsPendingExtEdge},
  1703. {"ext_edge_seamless_epoch", TestExtEdgeDoesNotCutSeamlessNextSegment},
  1704. {"ramp_seamless_epoch", TestOldRampDoesNotRetargetSeamlessNextSegment},
  1705. {"short_profile_boundary_matrix", TestShortProfileBoundaryMatrix},
  1706. {"short_final_no_poll", TestShortFinalDeceleratesWithoutPoll},
  1707. {"zero_to_maximum_ramp_duration",
  1708. TestZeroToMaximumRampKeepsConfiguredDuration},
  1709. {"maximum_pulse_ramp_duration",
  1710. TestMaximumPulseRampKeepsReachableDuration},
  1711. {"maximum_single_ramp_no_poll", TestMaximumSingleRampWithoutPoll},
  1712. {"short_timer_failure", TestShortProfileTimerFailure},
  1713. {"stop_after_subsequent_handoff",
  1714. TestStopImmediatelyAfterSubsequentHandoff},
  1715. {"short_zero_speed_edges", TestShortProfileZeroSpeedEdges},
  1716. {"short_dynamic_retarget", TestShortProfileDynamicRetarget},
  1717. {"short_ext_cut", TestShortProfileExtCut},
  1718. {"current_frequency_dynamic", TestCurrentFrequencyIsDynamic},
  1719. {"poll_mailbox_failure", TestPollMailboxDefersPlatformFailure},
  1720. {"future_frequency_on_arrival",
  1721. TestFutureSegmentFrequencyAppliesOnArrival},
  1722. {"subsequent_future_frequency_handoff",
  1723. TestSubsequentFutureFrequencyRebuildsHandoff},
  1724. {"future_frequency_last_pulse_race",
  1725. TestFutureFrequencyRaceAtLastPulse},
  1726. {"latched_update_before_future_frequency_commit",
  1727. TestLatchedUpdateDrainsBeforeFutureFrequencyCommit},
  1728. {"subsequent_no_poll_gap", TestSubsequentHandoffHasNoPollGap},
  1729. {"three_single_pulse_no_poll", TestThreeSinglePulseSubsequentWithoutPoll},
  1730. {"handoff_queue_failures", TestHandoffQueueFailuresBecomeTimerError},
  1731. {"command_state_restrictions", TestCommandStateRestrictions},
  1732. {"command_mailbox_start_snapshot",
  1733. TestCommandMailboxStartSnapshotAndConflicts},
  1734. {"command_mailbox_stop_clear_deferred",
  1735. TestCommandMailboxStopAndClearAreDeferred},
  1736. {"command_mailbox_validation", TestCommandMailboxValidatesBeforeQueue},
  1737. {"command_mailbox_start_failure",
  1738. TestCommandMailboxStartFailureBecomesError},
  1739. {"wait_signal_positive", TestWaitSignalPositivePath},
  1740. {"persistence_reinit", TestPersistenceAcrossReinit},
  1741. {"position_flash_save", TestPositionSchedulesFlashSave},
  1742. {"busy_reset_absolute_gate", TestBusyResetInvalidatesAbsolutePosition},
  1743. {"position_overflow", TestPositionOverflowStopsWithError}
  1744. };
  1745. int main(void)
  1746. {
  1747. unsigned int index;
  1748. for (index = 0U;
  1749. index < (unsigned int)(sizeof(TestCases) / sizeof(TestCases[0]));
  1750. index++)
  1751. {
  1752. unsigned int failuresBefore = FailureCount;
  1753. CurrentTest = TestCases[index].name;
  1754. (void)printf("RUN %s\n", CurrentTest);
  1755. TestCases[index].function();
  1756. if (FailureCount == failuresBefore)
  1757. {
  1758. (void)printf("PASS %s\n", CurrentTest);
  1759. }
  1760. else
  1761. {
  1762. (void)printf("FAIL %s (%u new failure(s))\n",
  1763. CurrentTest, FailureCount - failuresBefore);
  1764. }
  1765. }
  1766. (void)printf("SUMMARY tests=%u assertions=%u failures=%u\n",
  1767. (unsigned int)(sizeof(TestCases) / sizeof(TestCases[0])),
  1768. AssertionCount, FailureCount);
  1769. return (FailureCount == 0U) ? 0 : 1;
  1770. }