|
- #include "plsr.h"
-
- #include <stdint.h>
- #include <stdio.h>
-
- #define PLSR_WAIT_TIME (0U)
- #define PLSR_WAIT_SIGNAL (1U)
- #define PLSR_ACT_TIME (2U)
- #define PLSR_EXT_SIGNAL (3U)
- #define PLSR_EXT_OR_COMPLETE (4U)
-
- #define PLSR_SEND_COMPLETE (0U)
- #define PLSR_SEND_SUBSEQUENT (1U)
- #define PLSR_POSITION_RELATIVE (0U)
- #define PLSR_POSITION_ABSOLUTE (1U)
-
- #define PLSR_COMMAND_START (0x0001U)
- #define PLSR_COMMAND_STOP (0x0002U)
- #define PLSR_COMMAND_CLEAR (0x0004U)
- #define PLSR_ERROR_COUNT (5U)
-
- static const char *CurrentTest;
- static unsigned int AssertionCount;
- static unsigned int FailureCount;
-
- static void ExpectUnsigned(unsigned long expected,
- unsigned long actual,
- const char *expression,
- int line)
- {
- AssertionCount++;
- if (expected != actual)
- {
- FailureCount++;
- (void)printf("FAIL %s:%d: %s expected %lu, got %lu\n",
- CurrentTest, line, expression, expected, actual);
- }
- }
-
- static void ExpectSigned(long expected,
- long actual,
- const char *expression,
- int line)
- {
- AssertionCount++;
- if (expected != actual)
- {
- FailureCount++;
- (void)printf("FAIL %s:%d: %s expected %ld, got %ld\n",
- CurrentTest, line, expression, expected, actual);
- }
- }
-
- static void ExpectTrue(int condition, const char *expression, int line)
- {
- AssertionCount++;
- if (!condition)
- {
- FailureCount++;
- (void)printf("FAIL %s:%d: expected true: %s\n",
- CurrentTest, line, expression);
- }
- }
-
- #define EXPECT_U(expected, actual) \
- ExpectUnsigned((unsigned long)(expected), \
- (unsigned long)(actual), #actual, __LINE__)
- #define EXPECT_I(expected, actual) \
- ExpectSigned((long)(expected), (long)(actual), #actual, __LINE__)
- #define EXPECT_TRUE(expression) ExpectTrue((expression), #expression, __LINE__)
-
- static uint16_t LowWord(uint32_t value)
- {
- return (uint16_t)(value & 0xFFFFUL);
- }
-
- static uint16_t HighWord(uint32_t value)
- {
- return (uint16_t)(value >> 16U);
- }
-
- static void TestU64ByU32Division(void)
- {
- static const uint64_t dividends[] =
- {
- 0ULL, 1ULL, 0xFFFFFFFFULL, 0x100000000ULL,
- 0x100000001ULL, 0xFFFFFFFFFFFFFFFFULL,
- 0x8000000000000000ULL, 0x7FFFFFFFFFFFFFFFULL
- };
- static const uint32_t divisors[] =
- {
- 1UL, 2UL, 3UL, 0xFFFFUL, 0x10000UL, 100000UL,
- 0x7FFFFFFFUL, 0x80000000UL, 0xFFFFFFFFUL
- };
- uint32_t state = 0xA5C39E17UL;
- uint64_t dividend;
- uint64_t quotient;
- uint32_t divisor;
- uint32_t remainder;
- uint32_t dividendIndex;
- uint32_t divisorIndex;
- uint32_t iteration;
-
- for (dividendIndex = 0U;
- dividendIndex < (uint32_t)(sizeof(dividends) / sizeof(dividends[0]));
- dividendIndex++)
- {
- for (divisorIndex = 0U;
- divisorIndex < (uint32_t)(sizeof(divisors) / sizeof(divisors[0]));
- divisorIndex++)
- {
- dividend = dividends[dividendIndex];
- divisor = divisors[divisorIndex];
- quotient = PlsrTestDivideU64ByU32(dividend, divisor, &remainder);
- EXPECT_TRUE(quotient == dividend / divisor);
- EXPECT_U((uint32_t)(dividend % divisor), remainder);
- }
- }
-
- for (iteration = 0U; iteration < 250000UL; iteration++)
- {
- state = state * 1664525UL + 1013904223UL;
- dividend = (uint64_t)state << 32U;
- state = state * 1664525UL + 1013904223UL;
- dividend |= state;
- state = state * 1664525UL + 1013904223UL;
- divisor = state | 1UL;
-
- quotient = PlsrTestDivideU64ByU32(dividend, divisor, &remainder);
- EXPECT_TRUE(quotient == dividend / divisor);
- EXPECT_U((uint32_t)(dividend % divisor), remainder);
- }
- }
-
- static uint64_t PulsePeriodNs(uint32_t frequencyHz)
- {
- return (1000000000ULL + frequencyHz / 2UL) / frequencyHz;
- }
-
- static uint64_t UnsignedDifference64(uint64_t first, uint64_t second)
- {
- return (first > second) ? (first - second) : (second - first);
- }
-
- static uint32_t IntegerSquareRoot64(uint64_t value)
- {
- uint64_t bit = (uint64_t)1U << 62U;
- uint64_t root = 0ULL;
-
- while (bit > value)
- {
- bit >>= 2U;
- }
- while (bit != 0ULL)
- {
- if (value >= root + bit)
- {
- value -= root + bit;
- root = (root >> 1U) + bit;
- }
- else
- {
- root >>= 1U;
- }
- bit >>= 2U;
- }
- return (uint32_t)root;
- }
-
- static PLSR_MB_RESULT WriteWord(uint16_t address, uint16_t value)
- {
- return PlsrModbusWriteHolding(address, 1U, &value);
- }
-
- static PLSR_MB_RESULT WriteU32(uint16_t address, uint32_t value)
- {
- uint16_t words[2];
-
- words[0] = LowWord(value);
- words[1] = HighWord(value);
- return PlsrModbusWriteHolding(address, 2U, words);
- }
-
- static PLSR_MB_RESULT WriteI32(uint16_t address, int32_t value)
- {
- return WriteU32(address, (uint32_t)value);
- }
-
- static uint16_t ReadWord(uint16_t address)
- {
- uint16_t value = 0xDEADU;
- PLSR_MB_RESULT result = PlsrModbusReadHolding(address, 1U, &value);
-
- EXPECT_U(PLSR_MB_OK, result);
- return value;
- }
-
- static uint32_t ReadU32(uint16_t address)
- {
- uint16_t words[2] = {0xDEADU, 0xBEEFU};
- PLSR_MB_RESULT result = PlsrModbusReadHolding(address, 2U, words);
-
- EXPECT_U(PLSR_MB_OK, result);
- return (uint32_t)words[0] | ((uint32_t)words[1] << 16U);
- }
-
- static int32_t ReadPosition(void)
- {
- return (int32_t)ReadU32(PLSR_STATUS_FIRST_ADDRESS);
- }
-
- static uint32_t ReadFrequency(void)
- {
- return ReadU32((uint16_t)(PLSR_STATUS_FIRST_ADDRESS + 2U));
- }
-
- static uint16_t ReadStatus(void)
- {
- return ReadWord((uint16_t)(PLSR_STATUS_FIRST_ADDRESS + 4U));
- }
-
- static uint16_t ReadCurrentSegment(void)
- {
- return ReadWord((uint16_t)(PLSR_STATUS_FIRST_ADDRESS + 5U));
- }
-
- static uint16_t ReadError(void)
- {
- return ReadWord((uint16_t)(PLSR_STATUS_FIRST_ADDRESS + 6U));
- }
-
- static PLSR_MB_RESULT QueueCommand(uint16_t command)
- {
- return PlsrModbusWriteHolding(PLSR_CONTROL_ADDRESS, 1U, &command);
- }
-
- static PLSR_MB_RESULT SendCommand(uint16_t command)
- {
- PLSR_MB_RESULT result = QueueCommand(command);
-
- if (result == PLSR_MB_OK)
- {
- PlsrPoll1ms();
- }
- return result;
- }
-
- static void ResetCore(void)
- {
- PlsrTestClearPersistentStorage();
- EXPECT_U(1U, PlsrInit());
- EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
- }
-
- static void ConfigureCommon(uint16_t curveMode,
- uint16_t positionMode,
- uint16_t segmentCount,
- uint16_t sendMode,
- uint32_t defaultSpeedHz,
- uint32_t startSpeedHz,
- uint32_t stopSpeedHz,
- uint16_t accelerationTimeMs,
- uint16_t decelerationTimeMs)
- {
- uint16_t words[0x14U];
- PLSR_MB_RESULT result;
-
- result = PlsrModbusReadHolding(0x1000U, 0x14U, words);
- EXPECT_U(PLSR_MB_OK, result);
- words[0x04U] = sendMode;
- words[0x05U] = 0U;
- words[0x07U] = curveMode;
- words[0x08U] = positionMode;
- words[0x09U] = segmentCount;
- words[0x0AU] = 1U;
- words[0x0BU] = LowWord(defaultSpeedHz);
- words[0x0CU] = HighWord(defaultSpeedHz);
- words[0x0DU] = LowWord(startSpeedHz);
- words[0x0EU] = HighWord(startSpeedHz);
- words[0x0FU] = 0U;
- words[0x10U] = LowWord(stopSpeedHz);
- words[0x11U] = HighWord(stopSpeedHz);
- words[0x12U] = accelerationTimeMs;
- words[0x13U] = decelerationTimeMs;
- result = PlsrModbusWriteHolding(0x1000U, 0x14U, words);
- EXPECT_U(PLSR_MB_OK, result);
- }
-
- static PLSR_MB_RESULT SetSegment(uint8_t segmentNumber,
- uint32_t frequencyHz,
- int32_t pulses,
- uint16_t waitType,
- uint16_t waitTimeMs,
- uint16_t actTimeMs,
- uint16_t jumpSegment)
- {
- uint16_t words[8];
- uint16_t address = (uint16_t)(0x1100U
- + ((uint16_t)segmentNumber - 1U) * 0x10U);
-
- words[0] = LowWord(frequencyHz);
- words[1] = HighWord(frequencyHz);
- words[2] = LowWord((uint32_t)pulses);
- words[3] = HighWord((uint32_t)pulses);
- words[4] = waitType;
- words[5] = waitTimeMs;
- words[6] = actTimeMs;
- words[7] = jumpSegment;
- return PlsrModbusWriteHolding(address, 8U, words);
- }
-
- static void StopAndSettle(void)
- {
- unsigned int pulse;
-
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
- for (pulse = 0U; (pulse < 4U) && (PlsrTestPulseIsActive() != 0U);
- pulse++)
- {
- PlsrTestEmitPulses(1UL);
- }
- PlsrPoll1ms();
- EXPECT_U(0U, PlsrTestPulseIsActive());
- EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- }
-
- static void TestProtocolBoundaries(void)
- {
- uint16_t value = 0U;
- uint16_t values[2];
- uint16_t before;
-
- ResetCore();
-
- EXPECT_U(PLSR_MB_NOT_HANDLED,
- PlsrModbusReadHolding(0x0FFEU, 1U, &value));
- EXPECT_U(PLSR_MB_NOT_HANDLED,
- PlsrModbusReadHolding(0x1198U, 1U, &value));
- EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS,
- PlsrModbusReadHolding(0x0FFFU, 2U, values));
- EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS,
- PlsrModbusReadHolding(0x1197U, 2U, values));
- EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS,
- PlsrModbusReadHolding(0x2006U, 2U, values));
- EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS,
- PlsrModbusReadHolding(0xFFFFU, 2U, values));
- EXPECT_U(PLSR_MB_ILLEGAL_VALUE,
- PlsrModbusReadHolding(0x1000U, 0U, &value));
- EXPECT_U(PLSR_MB_ILLEGAL_VALUE,
- PlsrModbusReadHolding(0x1000U, 1U, NULL));
-
- EXPECT_U(0U, ReadWord(0x100FU));
- EXPECT_U(PLSR_MB_OK, WriteWord(0x100FU, 0U));
- EXPECT_U(PLSR_MB_ILLEGAL_VALUE, WriteWord(0x100FU, 1U));
- EXPECT_U(0U, ReadWord(0x1108U));
- EXPECT_U(PLSR_MB_OK, WriteWord(0x1108U, 0U));
- EXPECT_U(PLSR_MB_ILLEGAL_VALUE, WriteWord(0x1108U, 1U));
-
- EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS, WriteWord(0x100BU, 2000U));
- EXPECT_U(PLSR_MB_OK, WriteU32(0x100BU, 2000UL));
- EXPECT_U(2000UL, ReadU32(0x100BU));
- EXPECT_U(PLSR_MB_ILLEGAL_VALUE, WriteU32(0x100BU, 100001UL));
- EXPECT_U(2000UL, ReadU32(0x100BU));
-
- before = ReadWord(0x1013U);
- values[0] = 77U;
- values[1] = 1U;
- EXPECT_U(PLSR_MB_ILLEGAL_VALUE,
- PlsrModbusWriteHolding(0x1013U, 2U, values));
- EXPECT_U(before, ReadWord(0x1013U));
-
- EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS,
- PlsrModbusWriteHolding(0x2000U, 1U, &value));
- EXPECT_U(PLSR_MB_ILLEGAL_ADDRESS,
- PlsrModbusWriteHolding(0x3000U, 2U, values));
- value = 3U;
- EXPECT_U(PLSR_MB_ILLEGAL_VALUE,
- PlsrModbusWriteHolding(0x3000U, 1U, &value));
- value = 0U;
- EXPECT_U(PLSR_MB_OK,
- PlsrModbusWriteHolding(0x3000U, 1U, &value));
- EXPECT_U(0U, ReadWord(0x3000U));
-
- EXPECT_U(PLSR_MB_OK, WriteWord(0x1197U, 0U));
- EXPECT_U(0U, ReadWord(0x1197U));
- EXPECT_U(PLSR_MB_NOT_HANDLED, WriteWord(0x1198U, 0U));
- }
-
- static void TestWaitZeroUsesOneMillisecond(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 1L, PLSR_WAIT_TIME, 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(2U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrTestEmitPulses(1UL);
-
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_WAITING, ReadStatus());
- EXPECT_U(1U, ReadCurrentSegment());
- EXPECT_U(0U, PlsrTestPulseIsActive());
-
- PlsrPoll1ms();
- EXPECT_U(2U, ReadCurrentSegment());
- EXPECT_U(1U, PlsrTestPulseIsActive());
- PlsrTestEmitPulses(1UL);
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_I(2L, ReadPosition());
- }
-
- static void TestActZeroSkipsWithoutPulse(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 100L, PLSR_ACT_TIME, 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(2U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(0U, PlsrTestPulseIsActive());
- EXPECT_U(1U, ReadCurrentSegment());
- EXPECT_I(0L, ReadPosition());
-
- PlsrPoll1ms();
- EXPECT_U(2U, ReadCurrentSegment());
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_I(0L, ReadPosition());
- PlsrTestEmitPulses(1UL);
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_I(1L, ReadPosition());
- }
-
- static void TestRelativeAndAbsoluteZeroDisplacement(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 0L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(PLSR_STATUS_RUNNING, ReadStatus());
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_I(0L, ReadPosition());
-
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 5L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrTestEmitPulses(5UL);
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_I(5L, ReadPosition());
-
- EXPECT_U(PLSR_MB_OK, WriteWord(0x1008U, PLSR_POSITION_ABSOLUTE));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 5L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_I(5L, ReadPosition());
- }
-
- static void TestSelfJumpCanStop(void)
- {
- unsigned int loop;
-
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 2L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 1U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
-
- for (loop = 0U; loop < 3U; loop++)
- {
- PlsrTestEmitPulses(2UL);
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_RUNNING, ReadStatus());
- EXPECT_U(1U, ReadCurrentSegment());
- EXPECT_U(1U, PlsrTestPulseIsActive());
- }
-
- StopAndSettle();
- }
-
- static void TestStopDeceleratesBeforeCut(void)
- {
- unsigned int tick;
- uint32_t middleFrequency;
-
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 1000U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 10000L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(1000UL, PlsrTestOutputFrequency());
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
- EXPECT_U(PLSR_STATUS_DECELERATING, ReadStatus());
- EXPECT_U(1U, PlsrTestPulseIsActive());
-
- for (tick = 0U; tick < 450U; tick++)
- {
- PlsrPoll1ms();
- PlsrTestEmitPulses(1UL);
- }
- middleFrequency = PlsrTestOutputFrequency();
- EXPECT_TRUE((middleFrequency > 100UL) && (middleFrequency < 1000UL));
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_STOP));
-
- for (tick = 450U; tick < 900U; tick++)
- {
- PlsrPoll1ms();
- PlsrTestEmitPulses(1UL);
- }
- EXPECT_TRUE(PlsrTestOutputFrequency() > 100UL);
- EXPECT_TRUE(PlsrTestOutputFrequency() <= 103UL);
- EXPECT_U(PLSR_STATUS_DECELERATING, ReadStatus());
- EXPECT_U(1U, PlsrTestPulseIsActive());
- PlsrTestEmitPulses(1UL);
- EXPECT_U(100UL, PlsrTestOutputFrequency());
- EXPECT_U(1U, PlsrTestPulseIsActive());
- PlsrTestEmitPulses(1UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
- EXPECT_I(902L, ReadPosition());
- }
-
- static void TestStopAtPendingBoundary(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
-
- PlsrTestEmitPulses(1UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
- EXPECT_U(PLSR_STATUS_RUNNING, ReadStatus());
-
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
- EXPECT_U(0U, ReadCurrentSegment());
- EXPECT_I(1L, ReadPosition());
-
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
- EXPECT_U(0U, PlsrTestPulseIsActive());
- }
-
- static void TestOneMillisecondDirectionDelay(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK, WriteWord(0x1005U, 1U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 10L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
-
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(0U, PlsrTestPulseIsActive());
-
- PlsrPoll1ms();
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_U(1000UL, PlsrTestOutputFrequency());
- StopAndSettle();
- }
-
- static void TestExtEdgeAtNaturalBoundary(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- PlsrTestSetInput(0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 1L, PLSR_EXT_SIGNAL,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
-
- PlsrTestEmitPulseOnCriticalEntry();
- PlsrTestSetInput(0U, 1U);
- PlsrPoll1ms();
- EXPECT_U(0U, PlsrTestPulseIsActive());
-
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_U(0U, ReadCurrentSegment());
- EXPECT_I(1L, ReadPosition());
- }
-
- static void ConfigureExtBoundaryCarryRace(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
- PLSR_SEND_SUBSEQUENT, 2000UL, 500UL, 1000UL,
- 0U, 1000U);
- PlsrTestSetInput(0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 2000UL, 1L, PLSR_EXT_SIGNAL,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(2U, 1000UL, 70000L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(2000UL, PlsrTestOutputFrequency());
- PlsrTestSetInput(0U, 1U);
- }
-
- static void ExpectExtBoundaryCarry(void)
- {
- EXPECT_U(0U, PlsrTestPulseIsActive());
- EXPECT_U(1U, ReadCurrentSegment());
- PlsrPoll1ms();
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_U(2U, ReadCurrentSegment());
- EXPECT_U(2000UL, PlsrTestOutputFrequency());
- EXPECT_I(1L, ReadPosition());
- }
-
- static void TestExtCutAndNaturalBoundaryInterleavings(void)
- {
- ConfigureExtBoundaryCarryRace();
- PlsrTestEmitPulseAfterCriticalEntries(3U);
- PlsrPoll1ms();
- ExpectExtBoundaryCarry();
-
- ConfigureExtBoundaryCarryRace();
- PlsrPoll1ms();
- EXPECT_U(1U, PlsrTestPulseIsActive());
- PlsrTestEmitPulses(1UL);
- ExpectExtBoundaryCarry();
- }
-
- static void TestExtEdgeDuringDirectionDelay(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK, WriteWord(0x1005U, 2U));
- PlsrTestSetInput(0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 1L, PLSR_EXT_SIGNAL,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
-
- PlsrTestSetInput(0U, 1U);
- PlsrPoll1ms();
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(1U, PlsrTestPulseIsActive());
- PlsrTestEmitPulses(1UL);
-
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_I(1L, ReadPosition());
- }
-
- static void TestStoppedTaskClearsPendingExtEdge(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK, WriteWord(0x1005U, 2U));
- PlsrTestSetInput(0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 100L, PLSR_EXT_SIGNAL,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(0U, PlsrTestPulseIsActive());
-
- PlsrTestSetInput(0U, 1U);
- PlsrPoll1ms();
- EXPECT_U(0U, PlsrTestPulseIsActive());
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
- EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
-
- PlsrTestSetInput(0U, 0U);
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(1U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_I(0L, ReadPosition());
- StopAndSettle();
- }
-
- static void TestExtEdgeDoesNotCutSeamlessNextSegment(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
- PLSR_SEND_SUBSEQUENT, 1000UL, 1000UL, 100UL, 0U, 0U);
- PlsrTestSetInput(0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(2U, 2000UL, 4L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
-
- PlsrTestSetInput(0U, 1U);
- PlsrTestEmitPulseAfterCriticalEntries(3U);
- PlsrPoll1ms();
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_U(2U, ReadCurrentSegment());
- EXPECT_U(2000UL, PlsrTestOutputFrequency());
- EXPECT_I(1L, ReadPosition());
-
- PlsrTestEmitPulses(4UL);
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_I(5L, ReadPosition());
- }
-
- static void TestOldRampDoesNotRetargetSeamlessNextSegment(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
- PLSR_SEND_SUBSEQUENT, 2000UL, 1000UL, 100UL, 100U, 0U);
- PlsrTestSetInput(0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 2000UL, 1L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(2U, 3000UL, 4L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
-
- PlsrTestEmitPulseAfterCriticalEntries(3U);
- PlsrPoll1ms();
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_U(2U, ReadCurrentSegment());
- EXPECT_U(3000UL, PlsrTestOutputFrequency());
- EXPECT_I(1L, ReadPosition());
-
- PlsrTestEmitPulses(4UL);
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_I(5L, ReadPosition());
- }
-
- static void TestShortProfileBoundaryMatrix(void)
- {
- static const uint16_t pulseCounts[] = {1U, 2U, 10U, 99U, 100U, 101U};
- uint32_t samples[3][101];
- uint64_t previousDurationNs[3] = {0ULL, 0ULL, 0ULL};
- uint64_t durationNs[3];
- unsigned int countIndex;
- uint16_t curveMode;
- unsigned int pulse;
- unsigned int firstPeak;
- unsigned int lastPeak;
- uint32_t peakFrequencyHz;
- uint32_t expectedPeakHz;
- uint64_t expectedDurationNs;
- uint64_t toleranceNs;
- uint8_t linearDiffersFromSmooth;
- uint8_t smoothDiffersFromSine;
- uint8_t anyLinearDiffersFromSmooth = 0U;
- uint8_t anySmoothDiffersFromSine = 0U;
-
- for (countIndex = 0U;
- countIndex < sizeof(pulseCounts) / sizeof(pulseCounts[0]);
- countIndex++)
- {
- for (curveMode = 0U; curveMode <= 2U; curveMode++)
- {
- ResetCore();
- ConfigureCommon(curveMode, PLSR_POSITION_RELATIVE, 1U,
- PLSR_SEND_COMPLETE, 1000UL, 100UL, 100UL,
- 1000U, 1000U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, pulseCounts[countIndex],
- PLSR_EXT_OR_COMPLETE, 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(1U, PlsrTestPulseIsActive());
- durationNs[curveMode] = 0ULL;
-
- for (pulse = 0U; pulse < pulseCounts[countIndex]; pulse++)
- {
- samples[curveMode][pulse] = PlsrTestOutputFrequency();
- EXPECT_TRUE(samples[curveMode][pulse] >= 100UL);
- EXPECT_TRUE(samples[curveMode][pulse] <= 1000UL);
- durationNs[curveMode] +=
- PulsePeriodNs(samples[curveMode][pulse]);
- PlsrTestEmitPulses(1UL);
- if ((pulse + 1U) < pulseCounts[countIndex])
- {
- EXPECT_U(1U, PlsrTestPulseIsActive());
- }
- }
-
- peakFrequencyHz = samples[curveMode][0];
- firstPeak = 0U;
- lastPeak = 0U;
- for (pulse = 1U; pulse < pulseCounts[countIndex]; pulse++)
- {
- if (samples[curveMode][pulse] > peakFrequencyHz)
- {
- peakFrequencyHz = samples[curveMode][pulse];
- firstPeak = pulse;
- lastPeak = pulse;
- }
- else if (samples[curveMode][pulse] == peakFrequencyHz)
- {
- lastPeak = pulse;
- }
- }
- for (pulse = 1U; pulse <= firstPeak; pulse++)
- {
- EXPECT_TRUE(samples[curveMode][pulse]
- >= samples[curveMode][pulse - 1U]);
- }
- for (pulse = firstPeak + 1U; pulse <= lastPeak; pulse++)
- {
- EXPECT_U(peakFrequencyHz, samples[curveMode][pulse]);
- }
- for (pulse = lastPeak + 1U;
- pulse < pulseCounts[countIndex]; pulse++)
- {
- EXPECT_TRUE(samples[curveMode][pulse]
- <= samples[curveMode][pulse - 1U]);
- }
- EXPECT_TRUE((samples[curveMode][0]
- > samples[curveMode][pulseCounts[countIndex] - 1U]
- ? samples[curveMode][0]
- - samples[curveMode][pulseCounts[countIndex] - 1U]
- : samples[curveMode][pulseCounts[countIndex] - 1U]
- - samples[curveMode][0]) <= 2UL);
-
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- EXPECT_I((long)pulseCounts[countIndex], ReadPosition());
- EXPECT_TRUE(durationNs[curveMode]
- > previousDurationNs[curveMode]);
- previousDurationNs[curveMode] = durationNs[curveMode];
-
- expectedPeakHz = IntegerSquareRoot64(
- 10000ULL + (uint64_t)pulseCounts[countIndex] * 1000ULL);
- expectedDurationNs =
- (uint64_t)2U * (expectedPeakHz - 100UL) * 1000000ULL;
- toleranceNs = expectedDurationNs / 8ULL + 2000000ULL;
- EXPECT_TRUE(UnsignedDifference64(durationNs[curveMode],
- expectedDurationNs)
- <= toleranceNs);
- }
-
- toleranceNs = durationNs[0] / 50ULL + 1000000ULL;
- EXPECT_TRUE(UnsignedDifference64(durationNs[0], durationNs[1])
- <= toleranceNs);
- EXPECT_TRUE(UnsignedDifference64(durationNs[1], durationNs[2])
- <= toleranceNs);
-
- if (pulseCounts[countIndex] >= 10U)
- {
- linearDiffersFromSmooth = 0U;
- smoothDiffersFromSine = 0U;
- for (pulse = 0U; pulse < pulseCounts[countIndex]; pulse++)
- {
- if (samples[0][pulse] != samples[1][pulse])
- {
- linearDiffersFromSmooth = 1U;
- }
- if (samples[1][pulse] != samples[2][pulse])
- {
- smoothDiffersFromSine = 1U;
- }
- }
- EXPECT_U(1U, linearDiffersFromSmooth);
- if (linearDiffersFromSmooth != 0U)
- {
- anyLinearDiffersFromSmooth = 1U;
- }
- if (smoothDiffersFromSine != 0U)
- {
- anySmoothDiffersFromSine = 1U;
- }
- }
- }
- EXPECT_U(1U, anyLinearDiffersFromSmooth);
- EXPECT_U(1U, anySmoothDiffersFromSine);
- }
-
- static void TestShortFinalDeceleratesWithoutPoll(void)
- {
- uint16_t curveMode;
- unsigned int pulse;
- uint32_t previousFrequencyHz;
- uint32_t currentFrequencyHz;
- uint64_t durationNs;
-
- for (curveMode = 0U; curveMode <= 2U; curveMode++)
- {
- ResetCore();
- ConfigureCommon(curveMode, PLSR_POSITION_RELATIVE, 1U,
- PLSR_SEND_COMPLETE, 100000UL, 100000UL, 100UL,
- 0U, 1000U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 100000UL, 10L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- previousFrequencyHz = PlsrTestOutputFrequency();
- EXPECT_TRUE(previousFrequencyHz >= 99990UL);
- EXPECT_TRUE(previousFrequencyHz <= 100000UL);
- durationNs = PulsePeriodNs(previousFrequencyHz);
-
- for (pulse = 1U; pulse < 10U; pulse++)
- {
- PlsrTestEmitPulses(1UL);
- EXPECT_U(1U, PlsrTestPulseIsActive());
- currentFrequencyHz = PlsrTestOutputFrequency();
- EXPECT_TRUE(currentFrequencyHz <= previousFrequencyHz);
- EXPECT_TRUE(currentFrequencyHz >= 99990UL);
- durationNs += PulsePeriodNs(currentFrequencyHz);
- previousFrequencyHz = currentFrequencyHz;
- }
- EXPECT_TRUE(durationNs >= 99990ULL);
- EXPECT_TRUE(durationNs <= 100010ULL);
- PlsrTestEmitPulses(1UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- EXPECT_I(10L, ReadPosition());
- }
- }
-
- static void TestZeroToMaximumRampKeepsConfiguredDuration(void)
- {
- uint16_t curveMode;
- uint32_t firstFrequencyHz[3];
- uint32_t previousFrequencyHz;
- uint32_t currentFrequencyHz;
- uint32_t frequencyStepHz;
- uint32_t maximumStepHz;
- uint32_t pulse;
- uint64_t durationNs;
- const uint64_t expectedDurationNs = 20000000ULL;
- const uint64_t toleranceNs = 100000ULL;
-
- for (curveMode = 0U; curveMode <= 2U; curveMode++)
- {
- ResetCore();
- ConfigureCommon(curveMode, PLSR_POSITION_RELATIVE, 1U,
- PLSR_SEND_COMPLETE, 100000UL, 0UL, 100000UL,
- 20U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 100000UL, 1000L,
- PLSR_EXT_OR_COMPLETE, 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(1U, PlsrTestPulseIsActive());
-
- previousFrequencyHz = PlsrTestOutputFrequency();
- firstFrequencyHz[curveMode] = previousFrequencyHz;
- EXPECT_TRUE(previousFrequencyHz >= 400UL);
- EXPECT_TRUE(previousFrequencyHz <= 2500UL);
- maximumStepHz = 0UL;
- durationNs = PulsePeriodNs(previousFrequencyHz);
-
- for (pulse = 1UL; pulse < 1000UL; pulse++)
- {
- PlsrTestEmitPulses(1UL);
- EXPECT_U(1U, PlsrTestPulseIsActive());
- currentFrequencyHz = PlsrTestOutputFrequency();
- EXPECT_TRUE(currentFrequencyHz >= previousFrequencyHz);
- EXPECT_TRUE(currentFrequencyHz <= 100000UL);
- frequencyStepHz = currentFrequencyHz - previousFrequencyHz;
- if (frequencyStepHz > maximumStepHz)
- {
- maximumStepHz = frequencyStepHz;
- }
- durationNs += PulsePeriodNs(currentFrequencyHz);
- previousFrequencyHz = currentFrequencyHz;
- }
-
- EXPECT_TRUE(maximumStepHz <= 10000UL);
- EXPECT_TRUE(previousFrequencyHz >= 99000UL);
- EXPECT_TRUE(UnsignedDifference64(durationNs, expectedDurationNs)
- <= toleranceNs);
- PlsrTestEmitPulses(1UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- EXPECT_I(1000L, ReadPosition());
- }
- EXPECT_TRUE(firstFrequencyHz[0] > firstFrequencyHz[1]);
- EXPECT_TRUE(firstFrequencyHz[1] > firstFrequencyHz[2]);
- }
-
- static void TestMaximumPulseRampKeepsReachableDuration(void)
- {
- uint16_t curveMode;
- uint32_t previousFrequencyHz;
- uint32_t currentFrequencyHz;
- uint32_t frequencyStepHz;
- uint32_t maximumStepHz;
- uint32_t pulse;
- uint32_t reachablePeakHz = IntegerSquareRoot64(
- (uint64_t)2U * 65535UL * 100000UL * 1000UL / 1311UL);
- uint64_t durationNs;
- uint64_t expectedDurationNs =
- (uint64_t)2U * 65535UL * 1000000000ULL / reachablePeakHz;
- uint64_t toleranceNs = expectedDurationNs / 500ULL + 1000000ULL;
-
- for (curveMode = 0U; curveMode <= 2U; curveMode++)
- {
- ResetCore();
- ConfigureCommon(curveMode, PLSR_POSITION_RELATIVE, 1U,
- PLSR_SEND_COMPLETE, 100000UL, 0UL, 100000UL,
- 1311U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 100000UL, 65535L,
- PLSR_EXT_OR_COMPLETE, 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(1U, PlsrTestPulseIsActive());
-
- previousFrequencyHz = PlsrTestOutputFrequency();
- EXPECT_TRUE(previousFrequencyHz > 1UL);
- EXPECT_TRUE(previousFrequencyHz < reachablePeakHz);
- maximumStepHz = 0UL;
- durationNs = PulsePeriodNs(previousFrequencyHz);
-
- for (pulse = 1UL; pulse < 65535UL; pulse++)
- {
- PlsrTestEmitPulses(1UL);
- EXPECT_U(1U, PlsrTestPulseIsActive());
- currentFrequencyHz = PlsrTestOutputFrequency();
- EXPECT_TRUE(currentFrequencyHz >= previousFrequencyHz);
- EXPECT_TRUE(currentFrequencyHz <= reachablePeakHz + 5UL);
- frequencyStepHz = currentFrequencyHz - previousFrequencyHz;
- if (frequencyStepHz > maximumStepHz)
- {
- maximumStepHz = frequencyStepHz;
- }
- durationNs += PulsePeriodNs(currentFrequencyHz);
- previousFrequencyHz = currentFrequencyHz;
- }
-
- EXPECT_TRUE(maximumStepHz <= 5000UL);
- EXPECT_TRUE(previousFrequencyHz * 100UL
- >= reachablePeakHz * 99UL);
- EXPECT_TRUE(UnsignedDifference64(durationNs, expectedDurationNs)
- <= toleranceNs);
- PlsrTestEmitPulses(1UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- EXPECT_I(65535L, ReadPosition());
- }
- }
-
- static void TestMaximumSingleRampWithoutPoll(void)
- {
- uint16_t curveMode;
- uint32_t previousFrequencyHz;
- uint32_t currentFrequencyHz;
- uint32_t minimumFrequencyHz;
- uint32_t maximumFrequencyHz;
- uint32_t pulse;
-
- for (curveMode = 0U; curveMode <= 2U; curveMode++)
- {
- ResetCore();
- ConfigureCommon(curveMode, PLSR_POSITION_RELATIVE, 1U,
- PLSR_SEND_COMPLETE, 1000UL, 100000UL, 0UL,
- 1000U, 1000U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 100000UL, 65535L,
- PLSR_EXT_OR_COMPLETE, 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- previousFrequencyHz = PlsrTestOutputFrequency();
- minimumFrequencyHz = previousFrequencyHz;
- maximumFrequencyHz = previousFrequencyHz;
- EXPECT_TRUE(previousFrequencyHz >= 99000UL);
- EXPECT_TRUE(previousFrequencyHz <= 100000UL);
-
- for (pulse = 1UL; pulse < 65535UL; pulse++)
- {
- PlsrTestEmitPulses(1UL);
- EXPECT_U(1U, PlsrTestPulseIsActive());
- currentFrequencyHz = PlsrTestOutputFrequency();
- EXPECT_TRUE(currentFrequencyHz <= previousFrequencyHz);
- EXPECT_TRUE(currentFrequencyHz >= 99000UL);
- if (currentFrequencyHz < minimumFrequencyHz)
- {
- minimumFrequencyHz = currentFrequencyHz;
- }
- if (currentFrequencyHz > maximumFrequencyHz)
- {
- maximumFrequencyHz = currentFrequencyHz;
- }
- previousFrequencyHz = currentFrequencyHz;
- }
- EXPECT_TRUE(minimumFrequencyHz > 1UL);
- EXPECT_TRUE(maximumFrequencyHz <= 100000UL);
- EXPECT_TRUE(minimumFrequencyHz < maximumFrequencyHz);
- PlsrTestEmitPulses(1UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- EXPECT_I(65535L, ReadPosition());
- }
- }
-
- static void TestShortProfileTimerFailure(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 100UL, 100UL, 1000U, 1000U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 10L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrTestFailNextFrequencyAtUpdate();
- PlsrTestEmitPulses(1UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_ERROR, ReadStatus());
- EXPECT_U(PLSR_ERROR_TIMER, ReadError());
- EXPECT_I(1L, ReadPosition());
- }
-
- static void TestStopImmediatelyAfterSubsequentHandoff(void)
- {
- unsigned int tick;
-
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
- PLSR_SEND_SUBSEQUENT, 1000UL, 1000UL, 100UL,
- 0U, 100U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 3L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(2U, 2000UL, 20L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrTestEmitPulses(3UL);
- EXPECT_U(2U, ReadCurrentSegment());
- EXPECT_TRUE(PlsrTestOutputFrequency() <= 2000UL);
- EXPECT_TRUE(PlsrTestOutputFrequency() > 100UL);
-
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
- PlsrPoll1ms();
- PlsrTestEmitPulses(1UL);
- EXPECT_U(PLSR_STATUS_DECELERATING, ReadStatus());
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_TRUE(PlsrTestOutputFrequency() < 2000UL);
- EXPECT_TRUE(PlsrTestOutputFrequency() > 100UL);
-
- for (tick = 1U; tick < 190U; tick++)
- {
- PlsrPoll1ms();
- }
- while (PlsrTestPulseIsActive() != 0U)
- {
- PlsrTestEmitPulses(1UL);
- }
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- EXPECT_I(7L, ReadPosition());
- }
-
- static void TestShortProfileZeroSpeedEdges(void)
- {
- unsigned int tick;
-
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 0UL, 0UL, 1000U, 1000U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 2L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_TRUE(PlsrTestOutputFrequency() > 0UL);
- PlsrTestEmitPulses(1UL);
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_TRUE(PlsrTestOutputFrequency() > 0UL);
- PlsrTestEmitPulses(1UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_I(2L, ReadPosition());
-
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 0UL, 0UL, 1000U, 1000U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- for (tick = 0U; (tick < 10U) && (PlsrTestPulseIsActive() == 0U);
- tick++)
- {
- PlsrPoll1ms();
- }
- EXPECT_U(1U, PlsrTestPulseIsActive());
- PlsrTestEmitPulses(1UL);
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_I(1L, ReadPosition());
- }
-
- static void TestShortProfileDynamicRetarget(void)
- {
- unsigned int tick;
- uint32_t frequencyAfterRetarget;
- int32_t positionBeforeStop;
- int32_t positionAfterStop;
-
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 100UL, 100UL, 1000U, 1000U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 50L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrTestEmitPulses(3UL);
- EXPECT_U(PLSR_MB_OK, WriteU32(0x1100U, 2000UL));
- PlsrPoll1ms();
- PlsrTestEmitPulses(1UL);
- frequencyAfterRetarget = PlsrTestOutputFrequency();
- PlsrTestEmitPulses(1UL);
- EXPECT_TRUE(PlsrTestOutputFrequency() > 0UL);
- for (tick = 0U; tick < 10U; tick++)
- {
- PlsrPoll1ms();
- PlsrTestEmitPulses(1UL);
- }
- EXPECT_TRUE(PlsrTestOutputFrequency() > frequencyAfterRetarget);
-
- positionBeforeStop = ReadPosition();
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
- for (tick = 0U; tick < 2000U; tick++)
- {
- PlsrPoll1ms();
- }
- while (PlsrTestPulseIsActive() != 0U)
- {
- PlsrTestEmitPulses(1UL);
- }
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- positionAfterStop = ReadPosition();
- EXPECT_TRUE(positionAfterStop > positionBeforeStop);
- EXPECT_TRUE(positionAfterStop <= positionBeforeStop + 3L);
- }
-
- static void TestShortProfileExtCut(void)
- {
- uint32_t frequencyBeforeCut;
-
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 100UL, 100UL, 1000U, 1000U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 50L, PLSR_EXT_SIGNAL,
- 0U, 0U, 0U));
- PlsrTestSetInput(0U, 0U);
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrTestEmitPulses(3UL);
- frequencyBeforeCut = PlsrTestOutputFrequency();
- PlsrTestSetInput(0U, 1U);
- PlsrPoll1ms();
- PlsrTestEmitPulses(1UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- EXPECT_U(0UL, PlsrTestOutputFrequency());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- EXPECT_I(4L, ReadPosition());
- EXPECT_TRUE(frequencyBeforeCut > 100UL);
- }
-
- static void TestCurrentFrequencyIsDynamic(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 100L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(1000UL, PlsrTestOutputFrequency());
- EXPECT_U(PLSR_MB_OK, WriteU32(0x1100U, 2000UL));
- PlsrPoll1ms();
- EXPECT_U(1000UL, PlsrTestOutputFrequency());
- PlsrTestEmitPulses(1UL);
- EXPECT_U(1000UL, PlsrTestOutputFrequency());
- EXPECT_U(1000UL, ReadFrequency());
- PlsrTestEmitPulses(1UL);
- EXPECT_U(2000UL, PlsrTestOutputFrequency());
- EXPECT_U(2000UL, ReadFrequency());
-
- EXPECT_U(PLSR_MB_OK, WriteI32(0x1102U, 1L));
- PlsrTestEmitPulses(2UL);
- EXPECT_U(1U, PlsrTestPulseIsActive());
- StopAndSettle();
- }
-
- static void TestPollMailboxDefersPlatformFailure(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 100L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrTestFailNextFrequencyAtUpdate();
- EXPECT_U(PLSR_MB_OK, WriteU32(0x1100U, 2000UL));
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_RUNNING, ReadStatus());
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_U(1000UL, PlsrTestOutputFrequency());
-
- PlsrTestEmitPulses(1UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_ERROR, ReadStatus());
- EXPECT_U(PLSR_ERROR_TIMER, ReadError());
- EXPECT_I(1L, ReadPosition());
- }
-
- static void TestFutureSegmentFrequencyAppliesOnArrival(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(2U, 3000UL, 10L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(PLSR_MB_OK, WriteU32(0x1110U, 5000UL));
- EXPECT_U(1000UL, PlsrTestOutputFrequency());
-
- PlsrTestEmitPulses(1UL);
- PlsrPoll1ms();
- EXPECT_U(2U, ReadCurrentSegment());
- EXPECT_U(5000UL, PlsrTestOutputFrequency());
- EXPECT_U(5000UL, ReadFrequency());
- StopAndSettle();
- }
-
- static void TestSubsequentFutureFrequencyRebuildsHandoff(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
- PLSR_SEND_SUBSEQUENT, 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 3L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(2U, 2000UL, 4L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(PLSR_MB_OK, WriteU32(0x1110U, 5000UL));
- EXPECT_U(1000UL, PlsrTestOutputFrequency());
-
- PlsrTestEmitPulses(3UL);
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_U(2U, ReadCurrentSegment());
- EXPECT_U(5000UL, PlsrTestOutputFrequency());
- EXPECT_U(5000UL, ReadFrequency());
-
- PlsrTestEmitPulses(4UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_I(7L, ReadPosition());
- }
-
- static void TestFutureFrequencyRaceAtLastPulse(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
- PLSR_SEND_SUBSEQUENT, 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(2U, 2000UL, 4L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
-
- PlsrTestEmitPulseOnCriticalExit();
- EXPECT_U(PLSR_MB_OK, WriteU32(0x1110U, 5000UL));
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_U(2U, ReadCurrentSegment());
- EXPECT_U(5000UL, PlsrTestOutputFrequency());
- EXPECT_I(1L, ReadPosition());
-
- PlsrTestEmitPulses(4UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- EXPECT_I(5L, ReadPosition());
- }
-
- static void TestLatchedUpdateDrainsBeforeFutureFrequencyCommit(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
- PLSR_SEND_SUBSEQUENT, 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(2U, 2000UL, 4L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(1000UL, PlsrTestOutputFrequency());
- EXPECT_U(2000UL, PlsrTestQueuedFrequency());
-
- /* The physical edge latches 2000 Hz while interrupts are masked by the
- configuration commit. The ISR must consume that old handoff before
- the new 5000 Hz preload replaces it. */
- PlsrTestLatchPulseOnCriticalEntry();
- EXPECT_U(PLSR_MB_OK, WriteU32(0x1110U, 5000UL));
- EXPECT_U(2U, ReadCurrentSegment());
- EXPECT_I(1L, ReadPosition());
- EXPECT_U(2000UL, ReadFrequency());
- EXPECT_U(2000UL, PlsrTestOutputFrequency());
-
- PlsrPoll1ms();
- EXPECT_U(5000UL, PlsrTestQueuedFrequency());
-
- PlsrTestEmitPulses(1UL);
- EXPECT_U(2U, ReadCurrentSegment());
- EXPECT_I(2L, ReadPosition());
- EXPECT_U(5000UL, ReadFrequency());
- EXPECT_U(5000UL, PlsrTestOutputFrequency());
-
- PlsrTestEmitPulses(3UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- EXPECT_I(5L, ReadPosition());
- }
-
- static void TestSubsequentHandoffHasNoPollGap(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
- PLSR_SEND_SUBSEQUENT, 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 3L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(2U, 2000UL, 4L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
-
- PlsrTestEmitPulses(3UL);
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_U(2U, ReadCurrentSegment());
- EXPECT_U(2000UL, PlsrTestOutputFrequency());
- EXPECT_I(3L, ReadPosition());
-
- PlsrTestEmitPulses(4UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_I(7L, ReadPosition());
- }
-
- static void TestThreeSinglePulseSubsequentWithoutPoll(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 3U,
- PLSR_SEND_SUBSEQUENT, 3000UL, 1000UL, 3000UL,
- 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(2U, 2000UL, 1L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(3U, 3000UL, 1L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(1000UL, PlsrTestOutputFrequency());
-
- PlsrTestEmitPulses(1UL);
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_U(2U, ReadCurrentSegment());
- EXPECT_U(2000UL, PlsrTestOutputFrequency());
- EXPECT_I(1L, ReadPosition());
-
- PlsrTestEmitPulses(1UL);
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_U(3U, ReadCurrentSegment());
- EXPECT_U(3000UL, PlsrTestOutputFrequency());
- EXPECT_I(2L, ReadPosition());
-
- PlsrTestEmitPulses(1UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- EXPECT_I(3L, ReadPosition());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- }
-
- static void ConfigureHandoffFailureCase(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 2U,
- PLSR_SEND_SUBSEQUENT, 2000UL, 1000UL, 2000UL,
- 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 3L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(2U, 2000UL, 2L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- }
-
- static void ExpectHandoffTimerError(void)
- {
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_ERROR, ReadStatus());
- EXPECT_U(PLSR_ERROR_TIMER, ReadError());
- EXPECT_U(0U, ReadCurrentSegment());
- EXPECT_I(3L, ReadPosition());
- }
-
- static void TestHandoffQueueFailuresBecomeTimerError(void)
- {
- ConfigureHandoffFailureCase();
- PlsrTestEmitPulses(1UL);
- PlsrTestFailNextFrequencyAtUpdate();
- PlsrTestEmitPulses(1UL);
- EXPECT_U(1U, PlsrTestPulseIsActive());
- PlsrTestEmitPulses(1UL);
- ExpectHandoffTimerError();
-
- ConfigureHandoffFailureCase();
- PlsrTestEmitPulses(2UL);
- PlsrTestFailNextFrequencyAtUpdate();
- PlsrTestEmitPulses(1UL);
- ExpectHandoffTimerError();
- }
-
- static void TestCommandStateRestrictions(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 100L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
-
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_STOP));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_CLEAR));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(PLSR_MB_DEVICE_BUSY, SendCommand(PLSR_COMMAND_START));
- EXPECT_U(PLSR_MB_DEVICE_BUSY, SendCommand(PLSR_COMMAND_CLEAR));
- EXPECT_U(PLSR_MB_DEVICE_BUSY, WriteWord(0x1000U, 1U));
- EXPECT_U(PLSR_MB_DEVICE_BUSY, WriteWord(0x1001U, 1U));
- EXPECT_U(PLSR_MB_OK, WriteWord(0x1002U, 1U));
- EXPECT_U(PLSR_MB_ILLEGAL_VALUE, SendCommand(3U));
- StopAndSettle();
- }
-
- static void TestCommandMailboxStartSnapshotAndConflicts(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 1000UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 20L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
-
- EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_START));
- EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
- EXPECT_U(0U, ReadCurrentSegment());
- EXPECT_U(0UL, ReadFrequency());
- EXPECT_U(0U, PlsrTestPulseIsActive());
- EXPECT_I(0L, ReadPosition());
-
- EXPECT_U(PLSR_MB_OK, WriteI32(0x1102U, 1L));
- EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_START));
- EXPECT_U(PLSR_MB_DEVICE_BUSY, QueueCommand(PLSR_COMMAND_STOP));
- EXPECT_U(PLSR_MB_DEVICE_BUSY, QueueCommand(PLSR_COMMAND_CLEAR));
- EXPECT_U(PLSR_MB_ILLEGAL_VALUE, QueueCommand(3U));
- EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
- EXPECT_U(0U, PlsrTestPulseIsActive());
-
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_RUNNING, ReadStatus());
- EXPECT_U(1U, ReadCurrentSegment());
- EXPECT_U(1U, PlsrTestPulseIsActive());
- PlsrTestEmitPulses(1UL);
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_I(1L, ReadPosition());
- StopAndSettle();
- }
-
- static void TestCommandMailboxStopAndClearAreDeferred(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 1000UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 100L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrTestEmitPulses(2UL);
-
- EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_STOP));
- EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_STOP));
- EXPECT_U(PLSR_MB_DEVICE_BUSY, QueueCommand(PLSR_COMMAND_CLEAR));
- EXPECT_U(PLSR_MB_DEVICE_BUSY, QueueCommand(PLSR_COMMAND_START));
- EXPECT_U(PLSR_STATUS_RUNNING, ReadStatus());
- EXPECT_U(1U, PlsrTestPulseIsActive());
- EXPECT_I(2L, ReadPosition());
-
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_DECELERATING, ReadStatus());
- EXPECT_U(1U, PlsrTestPulseIsActive());
- PlsrTestEmitPulses(1UL);
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
- EXPECT_U(0U, PlsrTestPulseIsActive());
-
- PlsrTestSetPosition(17L, 1U);
- EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_CLEAR));
- EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_CLEAR));
- EXPECT_U(PLSR_MB_DEVICE_BUSY, QueueCommand(PLSR_COMMAND_START));
- EXPECT_U(PLSR_STATUS_STOPPED, ReadStatus());
- EXPECT_I(17L, ReadPosition());
-
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- EXPECT_I(0L, ReadPosition());
- }
-
- static void TestCommandMailboxValidatesBeforeQueue(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 1000UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 10L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
-
- EXPECT_U(PLSR_MB_OK, WriteWord(0x100AU, 2U));
- EXPECT_U(PLSR_MB_ILLEGAL_VALUE, QueueCommand(PLSR_COMMAND_START));
- EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
- EXPECT_U(0U, PlsrTestPulseIsActive());
- EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_STOP));
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
-
- EXPECT_U(PLSR_MB_OK, WriteWord(0x100AU, 1U));
- EXPECT_U(PLSR_MB_OK, WriteWord(0x1008U, PLSR_POSITION_ABSOLUTE));
- PlsrTestSetPosition(3L, 0U);
- EXPECT_U(PLSR_MB_ILLEGAL_VALUE, QueueCommand(PLSR_COMMAND_START));
- EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
- EXPECT_U(0U, PlsrTestPulseIsActive());
- }
-
- static void TestCommandMailboxStartFailureBecomesError(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 1000UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 10L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- PlsrTestFailNextStart();
-
- EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_START));
- EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_ERROR, ReadStatus());
- EXPECT_U(PLSR_ERROR_INVALID_RESOURCE, ReadError());
- EXPECT_U(0U, ReadCurrentSegment());
- EXPECT_U(0U, PlsrTestPulseIsActive());
-
- EXPECT_U(PLSR_MB_DEVICE_BUSY, QueueCommand(PLSR_COMMAND_START));
- EXPECT_U(PLSR_MB_OK, QueueCommand(PLSR_COMMAND_CLEAR));
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
- EXPECT_U(PLSR_ERROR_NONE, ReadError());
- }
-
- static void TestWaitSignalPositivePath(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 2L, PLSR_WAIT_SIGNAL,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrTestEmitPulses(2UL);
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_WAITING, ReadStatus());
- PlsrTestSetInput(0U, 1U);
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- }
-
- static void TestPersistenceAcrossReinit(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 2345UL, 2345UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK, WriteWord(0x1000U, 2U));
- EXPECT_U(PLSR_MB_OK, WriteWord(0x1001U, 3U));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 2345UL, 4L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrTestEmitPulses(4UL);
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- EXPECT_I(4L, ReadPosition());
-
- EXPECT_U(1U, PlsrInit());
- EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
- EXPECT_U(2U, ReadWord(0x1000U));
- EXPECT_U(3U, ReadWord(0x1001U));
- EXPECT_U(2345UL, ReadU32(0x1100U));
- EXPECT_I(4L, ReadPosition());
-
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_CLEAR));
- PlsrPoll1ms();
- EXPECT_U(1U, PlsrInit());
- EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
- EXPECT_I(0L, ReadPosition());
- }
-
- static void TestPositionSchedulesFlashSave(void)
- {
- unsigned int tick;
-
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 1L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- for (tick = 0U; tick < 1001U; tick++)
- {
- PlsrPoll1ms();
- }
- PlsrTestResetSaveCount();
-
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrTestEmitPulses(1UL);
- PlsrPoll1ms();
- EXPECT_U(0UL, PlsrTestSaveCount());
- for (tick = 0U; tick < 1001U; tick++)
- {
- PlsrPoll1ms();
- }
- EXPECT_U(1UL, PlsrTestSaveCount());
-
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_CLEAR));
- for (tick = 0U; tick < 1001U; tick++)
- {
- PlsrPoll1ms();
- }
- EXPECT_U(2UL, PlsrTestSaveCount());
- }
-
- static void TestBusyResetInvalidatesAbsolutePosition(void)
- {
- unsigned int tick;
-
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 100L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrTestEmitPulses(5UL);
- for (tick = 0U; tick < 10U; tick++)
- {
- PlsrPoll1ms();
- }
- EXPECT_I(5L, ReadPosition());
-
- EXPECT_U(1U, PlsrInit());
- EXPECT_U(PLSR_STATUS_IDLE, ReadStatus());
- EXPECT_I(5L, ReadPosition());
- EXPECT_U(PLSR_MB_OK, WriteWord(0x1008U, PLSR_POSITION_ABSOLUTE));
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 5L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_ILLEGAL_VALUE, SendCommand(PLSR_COMMAND_START));
-
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_CLEAR));
- EXPECT_I(0L, ReadPosition());
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 0L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_COMPLETED, ReadStatus());
- }
-
- static void TestPositionOverflowStopsWithError(void)
- {
- ResetCore();
- ConfigureCommon(0U, PLSR_POSITION_RELATIVE, 1U, PLSR_SEND_COMPLETE,
- 1000UL, 1000UL, 100UL, 0U, 0U);
- EXPECT_U(PLSR_MB_OK,
- SetSegment(1U, 1000UL, 2L, PLSR_EXT_OR_COMPLETE,
- 0U, 0U, 0U));
- PlsrTestSetPosition(INT32_MAX, 1U);
- EXPECT_I(INT32_MAX, ReadPosition());
- EXPECT_U(PLSR_MB_OK, SendCommand(PLSR_COMMAND_START));
- PlsrTestEmitPulses(1UL);
- EXPECT_U(0U, PlsrTestPulseIsActive());
- PlsrPoll1ms();
- EXPECT_U(PLSR_STATUS_ERROR, ReadStatus());
- EXPECT_U(PLSR_ERROR_COUNT, ReadError());
- EXPECT_I(INT32_MIN, ReadPosition());
- }
-
- typedef void (*TEST_FUNCTION)(void);
-
- typedef struct
- {
- const char *name;
- TEST_FUNCTION function;
- } TEST_CASE;
-
- static const TEST_CASE TestCases[] =
- {
- {"u64_by_u32_division", TestU64ByU32Division},
- {"protocol_boundaries", TestProtocolBoundaries},
- {"wait_zero_one_ms", TestWaitZeroUsesOneMillisecond},
- {"act_zero_no_pulse", TestActZeroSkipsWithoutPulse},
- {"relative_absolute_zero", TestRelativeAndAbsoluteZeroDisplacement},
- {"self_jump_stop", TestSelfJumpCanStop},
- {"stop_deceleration", TestStopDeceleratesBeforeCut},
- {"stop_pending_boundary", TestStopAtPendingBoundary},
- {"direction_delay_one_ms", TestOneMillisecondDirectionDelay},
- {"ext_edge_at_natural_boundary", TestExtEdgeAtNaturalBoundary},
- {"ext_cut_natural_boundary_interleavings",
- TestExtCutAndNaturalBoundaryInterleavings},
- {"ext_edge_during_direction_delay", TestExtEdgeDuringDirectionDelay},
- {"stopped_clears_pending_ext", TestStoppedTaskClearsPendingExtEdge},
- {"ext_edge_seamless_epoch", TestExtEdgeDoesNotCutSeamlessNextSegment},
- {"ramp_seamless_epoch", TestOldRampDoesNotRetargetSeamlessNextSegment},
- {"short_profile_boundary_matrix", TestShortProfileBoundaryMatrix},
- {"short_final_no_poll", TestShortFinalDeceleratesWithoutPoll},
- {"zero_to_maximum_ramp_duration",
- TestZeroToMaximumRampKeepsConfiguredDuration},
- {"maximum_pulse_ramp_duration",
- TestMaximumPulseRampKeepsReachableDuration},
- {"maximum_single_ramp_no_poll", TestMaximumSingleRampWithoutPoll},
- {"short_timer_failure", TestShortProfileTimerFailure},
- {"stop_after_subsequent_handoff",
- TestStopImmediatelyAfterSubsequentHandoff},
- {"short_zero_speed_edges", TestShortProfileZeroSpeedEdges},
- {"short_dynamic_retarget", TestShortProfileDynamicRetarget},
- {"short_ext_cut", TestShortProfileExtCut},
- {"current_frequency_dynamic", TestCurrentFrequencyIsDynamic},
- {"poll_mailbox_failure", TestPollMailboxDefersPlatformFailure},
- {"future_frequency_on_arrival",
- TestFutureSegmentFrequencyAppliesOnArrival},
- {"subsequent_future_frequency_handoff",
- TestSubsequentFutureFrequencyRebuildsHandoff},
- {"future_frequency_last_pulse_race",
- TestFutureFrequencyRaceAtLastPulse},
- {"latched_update_before_future_frequency_commit",
- TestLatchedUpdateDrainsBeforeFutureFrequencyCommit},
- {"subsequent_no_poll_gap", TestSubsequentHandoffHasNoPollGap},
- {"three_single_pulse_no_poll", TestThreeSinglePulseSubsequentWithoutPoll},
- {"handoff_queue_failures", TestHandoffQueueFailuresBecomeTimerError},
- {"command_state_restrictions", TestCommandStateRestrictions},
- {"command_mailbox_start_snapshot",
- TestCommandMailboxStartSnapshotAndConflicts},
- {"command_mailbox_stop_clear_deferred",
- TestCommandMailboxStopAndClearAreDeferred},
- {"command_mailbox_validation", TestCommandMailboxValidatesBeforeQueue},
- {"command_mailbox_start_failure",
- TestCommandMailboxStartFailureBecomesError},
- {"wait_signal_positive", TestWaitSignalPositivePath},
- {"persistence_reinit", TestPersistenceAcrossReinit},
- {"position_flash_save", TestPositionSchedulesFlashSave},
- {"busy_reset_absolute_gate", TestBusyResetInvalidatesAbsolutePosition},
- {"position_overflow", TestPositionOverflowStopsWithError}
- };
-
- int main(void)
- {
- unsigned int index;
-
- for (index = 0U;
- index < (unsigned int)(sizeof(TestCases) / sizeof(TestCases[0]));
- index++)
- {
- unsigned int failuresBefore = FailureCount;
-
- CurrentTest = TestCases[index].name;
- (void)printf("RUN %s\n", CurrentTest);
- TestCases[index].function();
- if (FailureCount == failuresBefore)
- {
- (void)printf("PASS %s\n", CurrentTest);
- }
- else
- {
- (void)printf("FAIL %s (%u new failure(s))\n",
- CurrentTest, FailureCount - failuresBefore);
- }
- }
-
- (void)printf("SUMMARY tests=%u assertions=%u failures=%u\n",
- (unsigned int)(sizeof(TestCases) / sizeof(TestCases[0])),
- AssertionCount, FailureCount);
- return (FailureCount == 0U) ? 0 : 1;
- }
|