|
- #include "plsr_job.h"
- #include "plc_device.h"
- #include "plsr_address_map.h"
- #include <limits.h>
- #include <string.h>
-
- #define PLSR_S0_HEADER_WORDS (10UL)
- #define PLSR_S0_SEGMENT_WORDS (10UL)
- #define PLSR_S1_WORDS (4UL)
- #define PLSR_SFD_AXIS_STRIDE (130U)
- #define PLSR_SFD_SET_OFFSET (50U)
- #define PLSR_S2_SET_WORDS (20U)
- #define PLSR_HSD_SET_BASE (460U)
- #define PLSR_TIMER_168MHZ (168000000UL)
- #define PLSR_TIMER_84MHZ (84000000UL)
-
- static void PlsrSetDetail(PLSR_PARSE_DETAIL *detail,
- PLSR_RESULT result,
- PLSR_PARSE_BLOCK block,
- uint32_t address,
- int32_t value,
- uint16_t segment)
- {
- if (detail != NULL)
- {
- detail->result = result;
- detail->block = block;
- detail->address = address;
- detail->value = value;
- detail->segment = segment;
- }
- }
-
- static uint8_t PlsrIsWordDevice(PLSR_DEVICE_TYPE device)
- {
- return ((device == PLSR_DEVICE_D) || (device == PLSR_DEVICE_HD)
- || (device == PLSR_DEVICE_FD))
- ? 1U
- : 0U;
- }
-
- static uint8_t PlsrSourceIsUsable(const PLSR_DATA_SOURCE *source)
- {
- return ((source != NULL) && (source->validateWords != NULL)
- && (source->readWord != NULL))
- ? 1U
- : 0U;
- }
-
- static PLSR_RESULT PlsrValidateRange(const PLSR_DATA_SOURCE *source,
- PLSR_DATA_REF reference,
- uint32_t wordCount,
- PLSR_PARSE_BLOCK block,
- PLSR_PARSE_DETAIL *detail)
- {
- uint64_t endAddress;
-
- if ((PlsrIsWordDevice(reference.device) == 0U) || (wordCount == 0UL))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_DATA_ACCESS,
- block,
- reference.address,
- (int32_t)reference.device,
- 0U);
- return PLSR_RESULT_DATA_ACCESS;
- }
- endAddress = (uint64_t)reference.address + (uint64_t)wordCount - 1ULL;
- if (endAddress > UINT32_MAX)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_ADDRESS_OVERFLOW,
- block,
- reference.address,
- (int32_t)wordCount,
- 0U);
- return PLSR_RESULT_ADDRESS_OVERFLOW;
- }
- if (source->validateWords(source->context,
- reference.device,
- reference.address,
- wordCount)
- == 0U)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_DATA_ACCESS,
- block,
- reference.address,
- (int32_t)wordCount,
- 0U);
- return PLSR_RESULT_DATA_ACCESS;
- }
- return PLSR_RESULT_OK;
- }
-
- static PLSR_RESULT PlsrReadWord(const PLSR_DATA_SOURCE *source,
- PLSR_DEVICE_TYPE device,
- uint32_t address,
- uint16_t *value,
- PLSR_PARSE_BLOCK block,
- uint16_t segment,
- PLSR_PARSE_DETAIL *detail)
- {
- if ((value == NULL)
- || (source->readWord(source->context, device, address, value) == 0U))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_DATA_ACCESS,
- block,
- address,
- 0,
- segment);
- return PLSR_RESULT_DATA_ACCESS;
- }
- return PLSR_RESULT_OK;
- }
-
- static PLSR_RESULT PlsrReadInt32(const PLSR_DATA_SOURCE *source,
- PLSR_DEVICE_TYPE device,
- uint32_t address,
- int32_t *value,
- PLSR_PARSE_BLOCK block,
- uint16_t segment,
- PLSR_PARSE_DETAIL *detail)
- {
- uint16_t lowWord;
- uint16_t highWord;
- PLSR_RESULT result;
-
- if (address == UINT32_MAX)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_ADDRESS_OVERFLOW,
- block,
- address,
- 2,
- segment);
- return PLSR_RESULT_ADDRESS_OVERFLOW;
- }
- result = PlsrReadWord(source,
- device,
- address,
- &lowWord,
- block,
- segment,
- detail);
- if (result != PLSR_RESULT_OK)
- {
- return result;
- }
- result = PlsrReadWord(source,
- device,
- address + 1UL,
- &highWord,
- block,
- segment,
- detail);
- if (result != PLSR_RESULT_OK)
- {
- return result;
- }
- *value = (int32_t)(((uint32_t)highWord << 16U) | (uint32_t)lowWord);
- return PLSR_RESULT_OK;
- }
-
- static uint8_t PlsrBlocksOverlap(PLSR_DATA_REF first,
- uint32_t firstWords,
- PLSR_DATA_REF second,
- uint32_t secondWords)
- {
- uint64_t firstEnd;
- uint64_t secondEnd;
-
- if (first.device != second.device)
- {
- return 0U;
- }
- firstEnd = (uint64_t)first.address + (uint64_t)firstWords - 1ULL;
- secondEnd = (uint64_t)second.address + (uint64_t)secondWords - 1ULL;
- return (((uint64_t)first.address <= secondEnd)
- && ((uint64_t)second.address <= firstEnd))
- ? 1U
- : 0U;
- }
-
- static PLSR_RESULT PlsrReadFixedWord(uint8_t useHsd,
- uint16_t address,
- uint16_t *value,
- PLSR_PARSE_DETAIL *detail)
- {
- PLC_DEVICE_RESULT deviceResult;
-
- deviceResult = (useHsd != 0U) ? PlcDeviceReadHsd(address, value)
- : PlcDeviceReadSfd(address, value);
- if (deviceResult != PLC_DEVICE_OK)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_S2,
- PLSR_PARSE_BLOCK_S2,
- address,
- 0,
- 0U);
- return PLSR_RESULT_INVALID_S2;
- }
- return PLSR_RESULT_OK;
- }
-
- static PLSR_RESULT PlsrReadFixedDword(uint8_t useHsd,
- uint16_t address,
- uint32_t *value,
- PLSR_PARSE_DETAIL *detail)
- {
- uint16_t lowWord;
- uint16_t highWord;
- PLSR_RESULT result;
-
- result = PlsrReadFixedWord(useHsd, address, &lowWord, detail);
- if (result != PLSR_RESULT_OK)
- {
- return result;
- }
- result = PlsrReadFixedWord(useHsd,
- (uint16_t)(address + 1U),
- &highWord,
- detail);
- if (result != PLSR_RESULT_OK)
- {
- return result;
- }
- *value = ((uint32_t)highWord << 16U) | (uint32_t)lowWord;
- return PLSR_RESULT_OK;
- }
-
- PLSR_RESULT PlsrCalculateTimerDivider(uint32_t timerClockHz,
- uint32_t frequencyHz,
- uint16_t *psc,
- uint16_t *arr)
- {
- uint64_t minimumDivider;
- uint64_t periodTicks;
-
- if ((timerClockHz == 0UL) || (frequencyHz == 0UL) || (psc == NULL)
- || (arr == NULL))
- {
- return PLSR_RESULT_INVALID_ARGUMENT;
- }
-
- minimumDivider = ((uint64_t)timerClockHz
- + ((uint64_t)frequencyHz * 65536ULL) - 1ULL)
- / ((uint64_t)frequencyHz * 65536ULL);
- if (minimumDivider == 0ULL)
- {
- minimumDivider = 1ULL;
- }
- if (minimumDivider > 65536ULL)
- {
- return PLSR_RESULT_DIVIDER_UNREPRESENTABLE;
- }
- periodTicks = ((uint64_t)timerClockHz
- + ((uint64_t)frequencyHz * minimumDivider) / 2ULL)
- / ((uint64_t)frequencyHz * minimumDivider);
- if ((periodTicks < 2ULL) || (periodTicks > 65536ULL))
- {
- return PLSR_RESULT_DIVIDER_UNREPRESENTABLE;
- }
- *psc = (uint16_t)(minimumDivider - 1ULL);
- *arr = (uint16_t)(periodTicks - 1ULL);
- return PLSR_RESULT_OK;
- }
-
- static PLSR_RESULT PlsrValidateFrequencyDivider(
- const PLSR_JOB_SNAPSHOT *snapshot,
- uint32_t frequency,
- PLSR_PARSE_DETAIL *detail,
- uint16_t segment)
- {
- uint16_t psc;
- uint16_t arr;
- PLSR_RESULT result;
-
- result = PlsrCalculateTimerDivider(snapshot->timerClockHz,
- frequency,
- &psc,
- &arr);
- if ((result == PLSR_RESULT_OK)
- && (snapshot->pairedTimerClockHz != 0UL))
- {
- result = PlsrCalculateTimerDivider(snapshot->pairedTimerClockHz,
- frequency,
- &psc,
- &arr);
- }
- if (result != PLSR_RESULT_OK)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_DIVIDER_UNREPRESENTABLE,
- PLSR_PARSE_BLOCK_S0,
- snapshot->s0.address
- + (uint32_t)segment * PLSR_S0_SEGMENT_WORDS,
- (int32_t)frequency,
- segment);
- return PLSR_RESULT_DIVIDER_UNREPRESENTABLE;
- }
- return PLSR_RESULT_OK;
- }
-
- static PLSR_RESULT PlsrResolveOperand(const PLSR_CALL *call,
- const PLSR_VALUE_OPERAND *operand,
- int32_t *value,
- PLSR_PARSE_DETAIL *detail)
- {
- PLSR_RESULT result;
-
- if (operand->type == PLSR_OPERAND_CONSTANT)
- {
- *value = operand->constant;
- return PLSR_RESULT_OK;
- }
- if ((operand->type != PLSR_OPERAND_DATA)
- || (PlsrIsWordDevice(operand->data.device) == 0U))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_S2,
- PLSR_PARSE_BLOCK_S2,
- operand->data.address,
- (int32_t)operand->type,
- 0U);
- return PLSR_RESULT_INVALID_S2;
- }
- result = PlsrValidateRange(&call->source,
- operand->data,
- 2UL,
- PLSR_PARSE_BLOCK_S2,
- detail);
- if (result != PLSR_RESULT_OK)
- {
- return result;
- }
- return PlsrReadInt32(&call->source,
- operand->data.device,
- operand->data.address,
- value,
- PLSR_PARSE_BLOCK_S2,
- 0U,
- detail);
- }
-
- static PLSR_RESULT PlsrLoadS2(const PLSR_CALL *call,
- PLSR_JOB_SNAPSHOT *snapshot,
- PLSR_PARSE_DETAIL *detail)
- {
- uint16_t commonBase;
- uint16_t setBase;
- uint16_t word;
- uint16_t commonFlags;
- uint16_t switchLogic;
- uint16_t limitPoints;
- uint32_t rawLimit;
- int32_t selectedSet;
- uint8_t useHsd;
- PLSR_RESULT result;
-
- result = PlsrResolveOperand(call, &call->s2, &selectedSet, detail);
- if (result != PLSR_RESULT_OK)
- {
- return result;
- }
- if ((selectedSet < 0) || (selectedSet > 4))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_S2,
- PLSR_PARSE_BLOCK_S2,
- call->s2.data.address,
- selectedSet,
- 0U);
- return PLSR_RESULT_INVALID_S2;
- }
- snapshot->s2Set = (uint8_t)selectedSet;
- commonBase = (uint16_t)(PLSR_SFD_CONFIG_START
- + (uint16_t)call->dAxis
- * PLSR_SFD_AXIS_STRIDE);
- if (snapshot->s2Set == 0U)
- {
- useHsd = 1U;
- setBase = (uint16_t)(PLSR_HSD_SET_BASE
- + (uint16_t)call->dAxis * PLSR_S2_SET_WORDS);
- }
- else
- {
- useHsd = 0U;
- setBase = (uint16_t)(commonBase + PLSR_SFD_SET_OFFSET
- + (uint16_t)(snapshot->s2Set - 1U)
- * PLSR_S2_SET_WORDS);
- }
-
- result = PlsrReadFixedDword(useHsd,
- setBase,
- &snapshot->s2.defaultSpeed,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrReadFixedWord(useHsd,
- (uint16_t)(setBase + 2U),
- &snapshot->s2.accelerationMs,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrReadFixedWord(useHsd,
- (uint16_t)(setBase + 3U),
- &snapshot->s2.decelerationMs,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrReadFixedWord(useHsd,
- (uint16_t)(setBase + 4U),
- &snapshot->s2.gapAccelerationMs,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrReadFixedWord(useHsd,
- (uint16_t)(setBase + 5U),
- &word,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- snapshot->s2.curveMode = (uint8_t)(word & 0x03U);
- result = PlsrReadFixedDword(useHsd,
- (uint16_t)(setBase + 6U),
- &snapshot->s2.maximumSpeed,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrReadFixedDword(useHsd,
- (uint16_t)(setBase + 8U),
- &snapshot->s2.startSpeed,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrReadFixedDword(useHsd,
- (uint16_t)(setBase + 10U),
- &snapshot->s2.stopSpeed,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrReadFixedWord(useHsd,
- (uint16_t)(setBase + 12U),
- &word,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- if ((word < 1U) || (word > 100U))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_S2,
- PLSR_PARSE_BLOCK_S2,
- (uint16_t)(setBase + 12U),
- word,
- 0U);
- return PLSR_RESULT_INVALID_S2;
- }
- snapshot->s2.follow = (uint8_t)word;
- result = PlsrReadFixedWord(useHsd,
- (uint16_t)(setBase + 13U),
- &word,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- if (word > 100U)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_S2,
- PLSR_PARSE_BLOCK_S2,
- (uint16_t)(setBase + 13U),
- word,
- 0U);
- return PLSR_RESULT_INVALID_S2;
- }
- snapshot->s2.feedforwardPercent = (uint8_t)word;
- result = PlsrReadFixedWord(useHsd,
- (uint16_t)(setBase + 14U),
- &word,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- snapshot->s2.refreshCode = (uint8_t)(word & 0x03U);
- result = PlsrReadFixedDword(useHsd,
- (uint16_t)(setBase + 16U),
- &snapshot->s2.zrnHighSpeed,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrReadFixedDword(useHsd,
- (uint16_t)(setBase + 18U),
- &snapshot->s2.zrnCrawlSpeed,
- detail);
- if (result != PLSR_RESULT_OK) return result;
-
- result = PlsrReadFixedWord(0U, commonBase, &word, detail);
- if (result != PLSR_RESULT_OK) return result;
- commonFlags = word;
- snapshot->directionActiveHigh =
- ((commonFlags & (1U << 1U)) != 0U) ? 1U : 0U;
- snapshot->limits.softLimitEnabled =
- ((commonFlags & (1U << 2U)) != 0U) ? 1U : 0U;
- snapshot->equivalent.unitCode =
- (uint8_t)((commonFlags >> 8U) & 0x07U);
- if (PlsrPositionUnitCodeIsValid(snapshot->equivalent.unitCode) == 0U)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_S2,
- PLSR_PARSE_BLOCK_S2,
- commonBase,
- snapshot->equivalent.unitCode,
- 0U);
- return PLSR_RESULT_INVALID_S2;
- }
- result = PlsrReadFixedDword(0U,
- (uint16_t)(commonBase + 2U),
- &snapshot->equivalent.pulsesPerRevolution,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrReadFixedDword(0U,
- (uint16_t)(commonBase + 4U),
- &snapshot->equivalent.movementPerRevolution,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- if (PlsrPositionValidateEquivalent(&snapshot->equivalent)
- != PLSR_RESULT_OK)
- {
- uint16_t invalidAddress =
- (snapshot->equivalent.pulsesPerRevolution == 0UL)
- ? (uint16_t)(commonBase + 2U)
- : (uint16_t)(commonBase + 4U);
-
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_S2,
- PLSR_PARSE_BLOCK_S2,
- invalidAddress,
- 0,
- 0U);
- return PLSR_RESULT_INVALID_S2;
- }
-
- result = PlsrReadFixedWord(0U,
- (uint16_t)(commonBase + 12U),
- &switchLogic,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrReadFixedWord(0U,
- (uint16_t)(commonBase + 15U),
- &limitPoints,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- snapshot->limits.positiveInputPoint = (uint8_t)(limitPoints & 0xFFU);
- snapshot->limits.negativeInputPoint = (uint8_t)(limitPoints >> 8U);
- snapshot->limits.positiveInputActiveLow =
- ((switchLogic & (1U << 2U)) != 0U) ? 1U : 0U;
- snapshot->limits.negativeInputActiveLow =
- ((switchLogic & (1U << 3U)) != 0U) ? 1U : 0U;
- if (((snapshot->limits.positiveInputPoint != 0xFFU)
- || (snapshot->limits.negativeInputPoint != 0xFFU))
- && (call->source.readBit == NULL))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_DATA_ACCESS,
- PLSR_PARSE_BLOCK_S2,
- (uint16_t)(commonBase + 15U),
- limitPoints,
- 0U);
- return PLSR_RESULT_DATA_ACCESS;
- }
-
- result = PlsrReadFixedDword(0U,
- (uint16_t)(commonBase + 30U),
- &rawLimit,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrPositionAbsoluteUnitsToPulses(
- &snapshot->equivalent,
- (int32_t)rawLimit,
- &snapshot->limits.positiveSoftLimitPulses);
- if (result != PLSR_RESULT_OK)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_POSITION_OVERFLOW,
- PLSR_PARSE_BLOCK_POSITION,
- (uint16_t)(commonBase + 30U),
- (int32_t)rawLimit,
- 0U);
- return PLSR_RESULT_POSITION_OVERFLOW;
- }
- result = PlsrReadFixedDword(0U,
- (uint16_t)(commonBase + 32U),
- &rawLimit,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrPositionAbsoluteUnitsToPulses(
- &snapshot->equivalent,
- (int32_t)rawLimit,
- &snapshot->limits.negativeSoftLimitPulses);
- if (result != PLSR_RESULT_OK)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_POSITION_OVERFLOW,
- PLSR_PARSE_BLOCK_POSITION,
- (uint16_t)(commonBase + 32U),
- (int32_t)rawLimit,
- 0U);
- return PLSR_RESULT_POSITION_OVERFLOW;
- }
- if ((snapshot->limits.softLimitEnabled != 0U)
- && (snapshot->limits.positiveSoftLimitPulses
- <= snapshot->limits.negativeSoftLimitPulses))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_S2,
- PLSR_PARSE_BLOCK_S2,
- (uint16_t)(commonBase + 30U),
- (int32_t)rawLimit,
- 0U);
- return PLSR_RESULT_INVALID_S2;
- }
- if (call->outputModeOverride == PLSR_OUTPUT_MODE_FROM_SFD)
- {
- snapshot->outputMode = ((commonFlags & (1U << 13U)) != 0U)
- ? (uint8_t)PLSR_OUTPUT_AB
- : (uint8_t)PLSR_OUTPUT_PULSE_DIR;
- }
- else if (call->outputModeOverride <= (uint8_t)PLSR_OUTPUT_CW_CCW)
- {
- snapshot->outputMode = call->outputModeOverride;
- }
- else
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_RESOURCE,
- PLSR_PARSE_BLOCK_OUTPUT,
- commonBase,
- call->outputModeOverride,
- 0U);
- return PLSR_RESULT_INVALID_RESOURCE;
- }
- result = PlsrReadFixedWord(0U,
- (uint16_t)(commonBase + 6U),
- &word,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- if (word > UINT8_MAX)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_RESOURCE,
- PLSR_PARSE_BLOCK_OUTPUT,
- (uint16_t)(commonBase + 6U),
- word,
- 0U);
- return PLSR_RESULT_INVALID_RESOURCE;
- }
- snapshot->directionPoint = (uint8_t)word;
- result = PlsrReadFixedWord(0U,
- (uint16_t)(commonBase + 7U),
- &snapshot->s2.directionDelayMs,
- detail);
- if (result != PLSR_RESULT_OK) return result;
-
- if ((snapshot->s2.maximumSpeed < PLSR_FREQUENCY_MIN_HZ)
- || (snapshot->s2.maximumSpeed > PLSR_FREQUENCY_MAX_HZ)
- || (snapshot->s2.curveMode > 2U) || (snapshot->s2.follow < 1U)
- || (snapshot->s2.follow > 100U)
- || (snapshot->s2.feedforwardPercent > 100U)
- || ((snapshot->s2.refreshCode != 0U)
- && (snapshot->s2.refreshCode != 2U)))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_S2,
- PLSR_PARSE_BLOCK_S2,
- setBase,
- (int32_t)snapshot->s2.maximumSpeed,
- 0U);
- return PLSR_RESULT_INVALID_S2;
- }
- if (snapshot->s2.startSpeed > snapshot->s2.maximumSpeed)
- {
- snapshot->s2.startSpeed = snapshot->s2.maximumSpeed;
- snapshot->speedClamped = 1U;
- }
- if (snapshot->s2.stopSpeed > snapshot->s2.maximumSpeed)
- {
- snapshot->s2.stopSpeed = snapshot->s2.maximumSpeed;
- snapshot->speedClamped = 1U;
- }
- snapshot->inputDefaultSpeed = snapshot->s2.defaultSpeed;
- snapshot->inputMaximumSpeed = snapshot->s2.maximumSpeed;
- return PLSR_RESULT_OK;
- }
-
- static PLSR_RESULT PlsrValidateVariableReference(
- const PLSR_CALL *call,
- uint8_t sourceCode,
- int32_t addressValue,
- uint8_t bitReference,
- int32_t *currentValue,
- PLSR_PARSE_BLOCK block,
- uint16_t segment,
- PLSR_PARSE_DETAIL *detail)
- {
- PLSR_DEVICE_TYPE device;
- PLSR_DATA_REF reference;
- uint8_t bitValue;
- PLSR_RESULT result;
-
- if ((sourceCode == 0U) || (sourceCode > 6U) || (addressValue < 0))
- {
- PlsrSetDetail(detail,
- (block == PLSR_PARSE_BLOCK_S0)
- ? PLSR_RESULT_INVALID_WAIT
- : PLSR_RESULT_DATA_ACCESS,
- block,
- (uint32_t)addressValue,
- sourceCode,
- segment);
- return (block == PLSR_PARSE_BLOCK_S0) ? PLSR_RESULT_INVALID_WAIT
- : PLSR_RESULT_DATA_ACCESS;
- }
- device = (PLSR_DEVICE_TYPE)(sourceCode - 1U);
- if (bitReference != 0U)
- {
- if ((device < PLSR_DEVICE_X) || (call->source.readBit == NULL)
- || (call->source.readBit(call->source.context,
- device,
- (uint32_t)addressValue,
- &bitValue)
- == 0U))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_WAIT,
- block,
- (uint32_t)addressValue,
- sourceCode,
- segment);
- return PLSR_RESULT_INVALID_WAIT;
- }
- *currentValue = (int32_t)bitValue;
- return PLSR_RESULT_OK;
- }
-
- if (PlsrIsWordDevice(device) == 0U)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_WAIT,
- block,
- (uint32_t)addressValue,
- sourceCode,
- segment);
- return PLSR_RESULT_INVALID_WAIT;
- }
- reference.device = device;
- reference.address = (uint32_t)addressValue;
- result = PlsrValidateRange(&call->source,
- reference,
- 2UL,
- block,
- detail);
- if (result != PLSR_RESULT_OK)
- {
- return result;
- }
- return PlsrReadInt32(&call->source,
- device,
- reference.address,
- currentValue,
- block,
- segment,
- detail);
- }
-
- static PLSR_RESULT PlsrValidateWait(const PLSR_CALL *call,
- PLSR_SEGMENT_SNAPSHOT *segmentData,
- uint16_t segment,
- PLSR_PARSE_DETAIL *detail)
- {
- int32_t currentValue;
- PLSR_RESULT result;
-
- if ((segmentData->waitCondition > PLSR_WAIT_EXT_OR_COMPLETE)
- || (segmentData->waitSource > PLSR_VALUE_HM))
- {
- goto invalidWait;
- }
- if (segmentData->waitCondition == PLSR_WAIT_PULSE_COMPLETE)
- {
- if (segmentData->waitSource != PLSR_VALUE_CONSTANT)
- {
- goto invalidWait;
- }
- return PLSR_RESULT_OK;
- }
- if ((segmentData->waitCondition == PLSR_WAIT_TIME)
- || (segmentData->waitCondition == PLSR_WAIT_ACT_TIME))
- {
- if (segmentData->waitSource == PLSR_VALUE_CONSTANT)
- {
- currentValue = segmentData->waitValueOrAddress;
- }
- else
- {
- if (segmentData->waitSource > PLSR_VALUE_FD)
- {
- goto invalidWait;
- }
- result = PlsrValidateVariableReference(call,
- segmentData->waitSource,
- segmentData->waitValueOrAddress,
- 0U,
- ¤tValue,
- PLSR_PARSE_BLOCK_S0,
- segment,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- }
- if (currentValue < 0) goto invalidWait;
- return PLSR_RESULT_OK;
- }
- if (segmentData->waitCondition == PLSR_WAIT_SIGNAL)
- {
- if ((segmentData->waitSource < PLSR_VALUE_X)
- || (segmentData->waitSource > PLSR_VALUE_HM))
- {
- goto invalidWait;
- }
- }
- else if ((segmentData->waitCondition == PLSR_WAIT_EXT)
- || (segmentData->waitCondition == PLSR_WAIT_EXT_OR_COMPLETE))
- {
- if (segmentData->waitSource != PLSR_VALUE_X)
- {
- goto invalidWait;
- }
- }
- result = PlsrValidateVariableReference(call,
- segmentData->waitSource,
- segmentData->waitValueOrAddress,
- 1U,
- ¤tValue,
- PLSR_PARSE_BLOCK_S0,
- segment,
- detail);
- return result;
-
- invalidWait:
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_WAIT,
- PLSR_PARSE_BLOCK_S0,
- call->s0.address
- + (uint32_t)segment * PLSR_S0_SEGMENT_WORDS + 4UL,
- ((int32_t)segmentData->waitCondition << 8)
- | segmentData->waitSource,
- segment);
- return PLSR_RESULT_INVALID_WAIT;
- }
-
- static PLSR_RESULT PlsrValidateJump(const PLSR_CALL *call,
- const PLSR_JOB_SNAPSHOT *snapshot,
- PLSR_SEGMENT_SNAPSHOT *segmentData,
- uint16_t segment,
- int32_t *resolvedJump,
- PLSR_PARSE_DETAIL *detail)
- {
- PLSR_RESULT result;
-
- if (segmentData->jumpSource > PLSR_VALUE_FD)
- {
- goto invalidJump;
- }
- if (segmentData->jumpSource == PLSR_VALUE_CONSTANT)
- {
- *resolvedJump = segmentData->jumpValueOrAddress;
- }
- else
- {
- result = PlsrValidateVariableReference(call,
- segmentData->jumpSource,
- segmentData->jumpValueOrAddress,
- 0U,
- resolvedJump,
- PLSR_PARSE_BLOCK_NONE,
- segment,
- detail);
- if (result != PLSR_RESULT_OK)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_JUMP,
- PLSR_PARSE_BLOCK_S0,
- (uint32_t)segmentData->jumpValueOrAddress,
- segmentData->jumpSource,
- segment);
- return PLSR_RESULT_INVALID_JUMP;
- }
- }
- if ((*resolvedJump < 0)
- || (*resolvedJump > (int32_t)snapshot->segmentCount))
- {
- goto invalidJump;
- }
- if (*resolvedJump == (int32_t)segment)
- {
- segmentData->flags |= PLSR_SEGMENT_FLAG_SELF_LOOP;
- }
- return PLSR_RESULT_OK;
-
- invalidJump:
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_JUMP,
- PLSR_PARSE_BLOCK_S0,
- call->s0.address
- + (uint32_t)segment * PLSR_S0_SEGMENT_WORDS + 7UL,
- *resolvedJump,
- segment);
- return PLSR_RESULT_INVALID_JUMP;
- }
-
- static PLSR_RESULT PlsrCheckConstantPath(PLSR_JOB_SNAPSHOT *snapshot,
- PLSR_PARSE_DETAIL *detail)
- {
- uint8_t visited[PLSR_MAX_SEGMENTS];
- uint16_t segment = snapshot->startSegment;
- int32_t next;
-
- (void)memset(visited, 0, sizeof(visited));
- while ((segment >= 1U) && (segment <= snapshot->segmentCount))
- {
- if (visited[segment - 1U] != 0U)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_PATH_CYCLE,
- PLSR_PARSE_BLOCK_S0,
- snapshot->s0.address
- + (uint32_t)segment * PLSR_S0_SEGMENT_WORDS
- + 8UL,
- segment,
- segment);
- return PLSR_RESULT_PATH_CYCLE;
- }
- visited[segment - 1U] = 1U;
- if (snapshot->segments[segment - 1U].jumpSource
- != PLSR_VALUE_CONSTANT)
- {
- return PLSR_RESULT_OK;
- }
- next = snapshot->segments[segment - 1U].jumpValueOrAddress;
- if (next == (int32_t)segment)
- {
- snapshot->hasSelfLoop = 1U;
- return PLSR_RESULT_OK;
- }
- if (next == 0)
- {
- if (segment == snapshot->segmentCount)
- {
- return PLSR_RESULT_OK;
- }
- segment++;
- }
- else
- {
- segment = (uint16_t)next;
- }
- }
- return PLSR_RESULT_OK;
- }
-
- static PLSR_RESULT PlsrCheckInitialPosition(
- PLSR_JOB_SNAPSHOT *snapshot,
- const PLSR_PARSE_CONTEXT *context,
- PLSR_PARSE_DETAIL *detail)
- {
- uint8_t visited[PLSR_MAX_SEGMENTS];
- int64_t position = context->logicalPosition;
- int64_t movement;
- int64_t targetPosition;
- int64_t remainder = 0;
- int32_t next;
- uint16_t segment = snapshot->startSegment;
- PLSR_RESULT result;
-
- if ((snapshot->positioningMode != 0U) && (context->positionValid == 0U))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_POSITION_INVALID,
- PLSR_PARSE_BLOCK_POSITION,
- snapshot->s1.address,
- 1,
- 0U);
- return PLSR_RESULT_POSITION_INVALID;
- }
-
- (void)memset(visited, 0, sizeof(visited));
- while ((segment >= 1U) && (segment <= snapshot->segmentCount)
- && (visited[segment - 1U] == 0U))
- {
- PLSR_SEGMENT_SNAPSHOT *segmentData = &snapshot->segments[segment - 1U];
- visited[segment - 1U] = 1U;
- if (snapshot->positioningMode == 0U)
- {
- result = PlsrPositionUnitsToPulses(&snapshot->equivalent,
- segmentData->pulseOrTarget,
- remainder,
- &movement,
- &remainder);
- if (result != PLSR_RESULT_OK)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_POSITION_OVERFLOW,
- PLSR_PARSE_BLOCK_POSITION,
- snapshot->s0.address
- + (uint32_t)segment
- * PLSR_S0_SEGMENT_WORDS
- + 2UL,
- segmentData->pulseOrTarget,
- segment);
- return PLSR_RESULT_POSITION_OVERFLOW;
- }
- if (((movement > 0) && (position > INT64_MAX - movement))
- || ((movement < 0) && (position < INT64_MIN - movement)))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_POSITION_OVERFLOW,
- PLSR_PARSE_BLOCK_POSITION,
- snapshot->s0.address
- + (uint32_t)segment
- * PLSR_S0_SEGMENT_WORDS
- + 2UL,
- movement,
- segment);
- return PLSR_RESULT_POSITION_OVERFLOW;
- }
- position += movement;
- }
- else
- {
- result = PlsrPositionAbsoluteUnitsToPulses(
- &snapshot->equivalent,
- segmentData->pulseOrTarget,
- &targetPosition);
- if (result != PLSR_RESULT_OK)
- {
- return PLSR_RESULT_POSITION_OVERFLOW;
- }
- movement = (targetPosition > position)
- ? 1
- : ((targetPosition < position) ? -1 : 0);
- position = targetPosition;
- }
- if ((movement != 0) && (snapshot->initialDirectionPositive == 0U))
- {
- snapshot->initialDirectionPositive = (movement > 0) ? 2U : 1U;
- }
- if (segmentData->jumpSource != PLSR_VALUE_CONSTANT)
- {
- break;
- }
- next = segmentData->jumpValueOrAddress;
- if (next == (int32_t)segment)
- {
- break;
- }
- if (next == 0)
- {
- if (segment == snapshot->segmentCount) break;
- segment++;
- }
- else
- {
- segment = (uint16_t)next;
- }
- }
- snapshot->initialDirectionPositive =
- (snapshot->initialDirectionPositive == 2U) ? 1U : 0U;
- return PLSR_RESULT_OK;
- }
-
- static PLSR_RESULT PlsrConvertSnapshotSpeeds(
- PLSR_JOB_SNAPSHOT *snapshot,
- PLSR_PARSE_DETAIL *detail)
- {
- uint16_t segment;
- PLSR_RESULT result;
-
- result = PlsrPositionSpeedToPulseFrequency(&snapshot->equivalent,
- snapshot->s2.defaultSpeed,
- &snapshot->s2.defaultSpeed);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrPositionSpeedToPulseFrequency(&snapshot->equivalent,
- snapshot->s2.maximumSpeed,
- &snapshot->s2.maximumSpeed);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrPositionSpeedToPulseFrequency(&snapshot->equivalent,
- snapshot->s2.startSpeed,
- &snapshot->s2.startSpeed);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrPositionSpeedToPulseFrequency(&snapshot->equivalent,
- snapshot->s2.stopSpeed,
- &snapshot->s2.stopSpeed);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrPositionSpeedToPulseFrequency(&snapshot->equivalent,
- snapshot->s2.zrnHighSpeed,
- &snapshot->s2.zrnHighSpeed);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrPositionSpeedToPulseFrequency(&snapshot->equivalent,
- snapshot->s2.zrnCrawlSpeed,
- &snapshot->s2.zrnCrawlSpeed);
- if (result != PLSR_RESULT_OK) return result;
-
- if ((snapshot->s2.maximumSpeed < PLSR_FREQUENCY_MIN_HZ)
- || (snapshot->s2.maximumSpeed > PLSR_FREQUENCY_MAX_HZ))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_FREQUENCY,
- PLSR_PARSE_BLOCK_S2,
- 0UL,
- (int32_t)snapshot->s2.maximumSpeed,
- 0U);
- return PLSR_RESULT_INVALID_FREQUENCY;
- }
- for (segment = 1U; segment <= snapshot->segmentCount; segment++)
- {
- PLSR_SEGMENT_SNAPSHOT *segmentData =
- &snapshot->segments[segment - 1U];
-
- if (segmentData->targetFrequency == 0UL)
- {
- continue;
- }
- result = PlsrPositionSpeedToPulseFrequency(
- &snapshot->equivalent,
- segmentData->targetFrequency,
- &segmentData->targetFrequency);
- if ((result != PLSR_RESULT_OK)
- || (segmentData->targetFrequency < PLSR_FREQUENCY_MIN_HZ)
- || (segmentData->targetFrequency > PLSR_FREQUENCY_MAX_HZ))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_FREQUENCY,
- PLSR_PARSE_BLOCK_S0,
- snapshot->s0.address
- + (uint32_t)segment * PLSR_S0_SEGMENT_WORDS,
- (int32_t)segmentData->targetFrequency,
- segment);
- return PLSR_RESULT_INVALID_FREQUENCY;
- }
- result = PlsrValidateFrequencyDivider(snapshot,
- segmentData->targetFrequency,
- detail,
- segment);
- if (result != PLSR_RESULT_OK) return result;
- }
- return PLSR_RESULT_OK;
- }
-
- PLSR_RESULT PlsrBuildJobSnapshot(const PLSR_CALL *call,
- const PLSR_PARSE_CONTEXT *context,
- PLSR_JOB_SNAPSHOT *snapshot,
- PLSR_PARSE_DETAIL *detail)
- {
- uint64_t s0Words64;
- uint32_t s0Words;
- uint32_t segmentBase;
- int32_t intValue;
- int32_t resolvedJump;
- uint16_t word;
- uint16_t segment;
- uint8_t index;
- PLSR_RESULT result;
-
- if ((call == NULL) || (context == NULL) || (snapshot == NULL)
- || (PlsrSourceIsUsable(&call->source) == 0U))
- {
- return PLSR_RESULT_INVALID_ARGUMENT;
- }
- if (call->dAxis >= PLSR_AXIS_COUNT)
- {
- return PLSR_RESULT_INVALID_AXIS;
- }
- (void)memset(snapshot, 0, sizeof(*snapshot));
- if (detail != NULL) (void)memset(detail, 0, sizeof(*detail));
- snapshot->source = call->source;
- snapshot->s0 = call->s0;
- snapshot->s1 = call->s1;
- snapshot->dAxis = call->dAxis;
- snapshot->timerClockHz = ((call->dAxis == 0U) || (call->dAxis == 2U))
- ? PLSR_TIMER_168MHZ
- : PLSR_TIMER_84MHZ;
-
- result = PlsrValidateRange(&call->source,
- call->s0,
- PLSR_S0_HEADER_WORDS,
- PLSR_PARSE_BLOCK_S0,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrReadInt32(&call->source,
- call->s0.device,
- call->s0.address,
- &intValue,
- PLSR_PARSE_BLOCK_S0,
- 0U,
- detail);
- if ((result != PLSR_RESULT_OK) || (intValue < 1)
- || (intValue > (int32_t)PLSR_MAX_SEGMENTS))
- {
- if (result == PLSR_RESULT_OK)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_SEGMENT_OVERFLOW,
- PLSR_PARSE_BLOCK_S0,
- call->s0.address,
- intValue,
- 0U);
- result = PLSR_RESULT_SEGMENT_OVERFLOW;
- }
- return result;
- }
- snapshot->segmentCount = (uint16_t)intValue;
- s0Words64 = (uint64_t)snapshot->segmentCount * PLSR_S0_SEGMENT_WORDS
- + PLSR_S0_HEADER_WORDS;
- if (s0Words64 > UINT32_MAX)
- {
- return PLSR_RESULT_ADDRESS_OVERFLOW;
- }
- s0Words = (uint32_t)s0Words64;
- result = PlsrValidateRange(&call->source,
- call->s0,
- s0Words,
- PLSR_PARSE_BLOCK_S0,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrValidateRange(&call->source,
- call->s1,
- PLSR_S1_WORDS,
- PLSR_PARSE_BLOCK_S1,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- if (PlsrBlocksOverlap(call->s0, s0Words, call->s1, PLSR_S1_WORDS) != 0U)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_BLOCK_OVERLAP,
- PLSR_PARSE_BLOCK_S1,
- call->s1.address,
- (int32_t)s0Words,
- 0U);
- return PLSR_RESULT_BLOCK_OVERLAP;
- }
- for (index = 2U; index < 10U; index++)
- {
- result = PlsrReadWord(&call->source,
- call->s0.device,
- call->s0.address + index,
- &word,
- PLSR_PARSE_BLOCK_S0,
- 0U,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- if (word != 0U)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_RESERVED_NOT_ZERO,
- PLSR_PARSE_BLOCK_S0,
- call->s0.address + index,
- word,
- 0U);
- return PLSR_RESULT_RESERVED_NOT_ZERO;
- }
- }
-
- result = PlsrReadInt32(&call->source,
- call->s1.device,
- call->s1.address,
- &intValue,
- PLSR_PARSE_BLOCK_S1,
- 0U,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- if ((intValue < 0) || (intValue > 1))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_POSITION_MODE,
- PLSR_PARSE_BLOCK_S1,
- call->s1.address,
- intValue,
- 0U);
- return PLSR_RESULT_INVALID_POSITION_MODE;
- }
- snapshot->positioningMode = (uint8_t)intValue;
- result = PlsrReadInt32(&call->source,
- call->s1.device,
- call->s1.address + 2UL,
- &intValue,
- PLSR_PARSE_BLOCK_S1,
- 0U,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- if ((intValue < 0) || (intValue > snapshot->segmentCount))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_ARGUMENT,
- PLSR_PARSE_BLOCK_S1,
- call->s1.address + 2UL,
- intValue,
- 0U);
- return PLSR_RESULT_INVALID_ARGUMENT;
- }
- snapshot->startSegment = (intValue <= 1) ? 1U : (uint16_t)intValue;
-
- result = PlsrLoadS2(call, snapshot, detail);
- if (result != PLSR_RESULT_OK) return result;
- if ((snapshot->outputMode == PLSR_OUTPUT_AB)
- || (snapshot->outputMode == PLSR_OUTPUT_CW_CCW))
- {
- if ((call->dAxis != 0U) && (call->dAxis != 2U))
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_RESOURCE,
- PLSR_PARSE_BLOCK_OUTPUT,
- call->dAxis,
- snapshot->outputMode,
- 0U);
- return PLSR_RESULT_INVALID_RESOURCE;
- }
- snapshot->pairedTimerClockHz = PLSR_TIMER_84MHZ;
- }
-
- for (segment = 1U; segment <= snapshot->segmentCount; segment++)
- {
- PLSR_SEGMENT_SNAPSHOT *segmentData = &snapshot->segments[segment - 1U];
- segmentBase = call->s0.address
- + (uint32_t)segment * PLSR_S0_SEGMENT_WORDS;
- result = PlsrReadInt32(&call->source,
- call->s0.device,
- segmentBase,
- &intValue,
- PLSR_PARSE_BLOCK_S0,
- segment,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- if (intValue < 0)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_FREQUENCY,
- PLSR_PARSE_BLOCK_S0,
- segmentBase,
- intValue,
- segment);
- return PLSR_RESULT_INVALID_FREQUENCY;
- }
- segmentData->targetFrequency = (uint32_t)intValue;
- result = PlsrReadInt32(&call->source,
- call->s0.device,
- segmentBase + 2UL,
- &segmentData->pulseOrTarget,
- PLSR_PARSE_BLOCK_S0,
- segment,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrReadWord(&call->source,
- call->s0.device,
- segmentBase + 4UL,
- &word,
- PLSR_PARSE_BLOCK_S0,
- segment,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- segmentData->waitSource = (uint8_t)(word & 0xFFU);
- segmentData->waitCondition = (uint8_t)(word >> 8U);
- result = PlsrReadInt32(&call->source,
- call->s0.device,
- segmentBase + 5UL,
- &segmentData->waitValueOrAddress,
- PLSR_PARSE_BLOCK_S0,
- segment,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrReadWord(&call->source,
- call->s0.device,
- segmentBase + 7UL,
- &word,
- PLSR_PARSE_BLOCK_S0,
- segment,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- if ((word & 0xFF00U) != 0U)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_RESERVED_NOT_ZERO,
- PLSR_PARSE_BLOCK_S0,
- segmentBase + 7UL,
- word,
- segment);
- return PLSR_RESULT_RESERVED_NOT_ZERO;
- }
- segmentData->jumpSource = (uint8_t)(word & 0xFFU);
- result = PlsrReadInt32(&call->source,
- call->s0.device,
- segmentBase + 8UL,
- &segmentData->jumpValueOrAddress,
- PLSR_PARSE_BLOCK_S0,
- segment,
- detail);
- if (result != PLSR_RESULT_OK) return result;
-
- if ((snapshot->positioningMode == 0U)
- && (segmentData->pulseOrTarget == 0))
- {
- segmentData->flags |= PLSR_SEGMENT_FLAG_ZERO_PULSE;
- segmentData->targetFrequency = 0UL;
- }
- else if (segmentData->targetFrequency == 0UL)
- {
- if (snapshot->s2.defaultSpeed == 0UL)
- {
- PlsrSetDetail(detail,
- PLSR_RESULT_INVALID_FREQUENCY,
- PLSR_PARSE_BLOCK_S2,
- 0UL,
- 0,
- segment);
- return PLSR_RESULT_INVALID_FREQUENCY;
- }
- segmentData->targetFrequency = snapshot->s2.defaultSpeed;
- segmentData->flags |= PLSR_SEGMENT_FLAG_DEFAULT_SPEED;
- }
- if (segmentData->targetFrequency > snapshot->s2.maximumSpeed)
- {
- segmentData->targetFrequency = snapshot->s2.maximumSpeed;
- segmentData->flags |= PLSR_SEGMENT_FLAG_SPEED_CLAMPED;
- snapshot->speedClamped = 1U;
- }
- result = PlsrValidateWait(call, segmentData, segment, detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrValidateJump(call,
- snapshot,
- segmentData,
- segment,
- &resolvedJump,
- detail);
- if (result != PLSR_RESULT_OK) return result;
- }
-
- result = PlsrConvertSnapshotSpeeds(snapshot, detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrCheckConstantPath(snapshot, detail);
- if (result != PLSR_RESULT_OK) return result;
- result = PlsrCheckInitialPosition(snapshot, context, detail);
- if (result != PLSR_RESULT_OK) return result;
- if (detail != NULL) detail->result = PLSR_RESULT_OK;
- return PLSR_RESULT_OK;
- }
-
- PLSR_RESULT PlsrResolveLiveFrequency(const PLSR_JOB_SNAPSHOT *snapshot,
- uint16_t segment,
- uint32_t *frequency,
- uint8_t *clamped)
- {
- int32_t rawFrequency;
- uint32_t segmentAddress;
- PLSR_RESULT result;
-
- if ((snapshot == NULL) || (frequency == NULL) || (clamped == NULL)
- || (segment < 1U) || (segment > snapshot->segmentCount))
- {
- return PLSR_RESULT_INVALID_ARGUMENT;
- }
- if ((snapshot->segments[segment - 1U].flags
- & PLSR_SEGMENT_FLAG_ZERO_PULSE)
- != 0U)
- {
- *frequency = 0UL;
- *clamped = 0U;
- return PLSR_RESULT_OK;
- }
- segmentAddress = snapshot->s0.address
- + (uint32_t)segment * PLSR_S0_SEGMENT_WORDS;
- result = PlsrReadInt32(&snapshot->source,
- snapshot->s0.device,
- segmentAddress,
- &rawFrequency,
- PLSR_PARSE_BLOCK_S0,
- segment,
- NULL);
- if (result != PLSR_RESULT_OK) return result;
- if (rawFrequency < 0) return PLSR_RESULT_INVALID_FREQUENCY;
- *frequency = (rawFrequency == 0) ? snapshot->inputDefaultSpeed
- : (uint32_t)rawFrequency;
- *clamped = 0U;
- if (*frequency > snapshot->inputMaximumSpeed)
- {
- *frequency = snapshot->inputMaximumSpeed;
- *clamped = 1U;
- }
- if (*frequency == 0UL) return PLSR_RESULT_INVALID_FREQUENCY;
- result = PlsrPositionSpeedToPulseFrequency(&snapshot->equivalent,
- *frequency,
- frequency);
- if ((result != PLSR_RESULT_OK) || (*frequency == 0UL)
- || (*frequency > PLSR_FREQUENCY_MAX_HZ))
- {
- return PLSR_RESULT_INVALID_FREQUENCY;
- }
- return PlsrValidateFrequencyDivider(snapshot, *frequency, NULL, segment);
- }
|