Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

1965 Zeilen
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. }