|
- #include "plsr_core.h"
- #include "plc_device.h"
- #include "plsr_address_map.h"
- #include "plsr_resource.h"
- #include <string.h>
-
- #ifndef PLSR_HOST_TEST
- #include "stm32f4xx.h"
- #include "ucos_ii.h"
- #endif
-
- typedef struct
- {
- PLSR_STATE state;
- PLSR_OUTPUT_MODE outputMode;
- PLSR_ERROR error;
- PLSR_STOP_REASON stopReason;
- PLSR_STATE pendingTerminal;
- PLSR_RESOURCE_LEASE lease;
- PLSR_JOB_SNAPSHOT job;
- PLSR_PARSE_DETAIL parseDetail;
- volatile uint32_t pendingEvents;
- uint32_t lastCommandSequence;
- PLSR_RESULT lastCommandResult;
- uint32_t illegalTransitionCount;
- int64_t logicalPosition;
- int64_t totalPulses;
- uint8_t hasLastCommand;
- uint8_t done;
- uint8_t directionPositive;
- uint8_t immediateStopPending;
- uint8_t positionValid;
- uint8_t jobValid;
- } PLSR_AXIS;
-
- typedef struct
- {
- PLSR_COMMAND command;
- PLSR_START_REQUEST start;
- PLSR_CALL call;
- uint32_t ticket;
- uint8_t hasStart;
- uint8_t hasCall;
- uint8_t occupied;
- } PLSR_COMMAND_SLOT;
-
- static PLSR_AXIS PlsrAxes[PLSR_AXIS_COUNT];
- static PLSR_COMMAND_SLOT PlsrCommandQueue[PLSR_COMMAND_QUEUE_DEPTH];
- static uint32_t PlsrNextTicket;
- static uint8_t PlsrInitialized;
- static PLSR_JOB_SNAPSHOT PlsrJobScratch;
-
- static uint32_t PlsrCoreEnterCritical(void)
- {
- #ifdef PLSR_HOST_TEST
- return 0UL;
- #else
- uint32_t interruptState = __get_PRIMASK();
- __disable_irq();
- __DMB();
- return interruptState;
- #endif
- }
-
- static void PlsrCoreExitCritical(uint32_t interruptState)
- {
- #ifdef PLSR_HOST_TEST
- (void)interruptState;
- #else
- __DMB();
- if (interruptState == 0UL)
- {
- __enable_irq();
- }
- #endif
- }
-
- static uint8_t PlsrStateIsBusy(PLSR_STATE state)
- {
- return ((state == PLSR_STATE_ACCEL) || (state == PLSR_STATE_RUN)
- || (state == PLSR_STATE_DECEL) || (state == PLSR_STATE_WAIT)
- || (state == PLSR_STATE_PAUSED))
- ? 1U
- : 0U;
- }
-
- static uint8_t PlsrStateIsPulseActive(PLSR_STATE state)
- {
- return ((state == PLSR_STATE_ACCEL) || (state == PLSR_STATE_RUN)
- || (state == PLSR_STATE_DECEL))
- ? 1U
- : 0U;
- }
-
- static void PlsrPublishAxis(uint8_t axis)
- {
- PLSR_AXIS *axisObject = &PlsrAxes[axis];
- uint8_t compatibleRun;
-
- compatibleRun = (uint8_t)((PlsrStateIsPulseActive(axisObject->state) != 0U)
- || (axisObject->state == PLSR_STATE_WAIT));
- (void)PlcDevicePublishSm(axis,
- compatibleRun,
- axisObject->directionPositive);
- }
-
- static void PlsrSetStopReason(PLSR_AXIS *axis,
- PLSR_STOP_REASON stopReason)
- {
- if (stopReason > axis->stopReason)
- {
- axis->stopReason = stopReason;
- }
- }
-
- static uint8_t PlsrTransitionIsAllowed(PLSR_STATE current,
- PLSR_STATE target)
- {
- if (current == target)
- {
- return 1U;
- }
- if (target == PLSR_STATE_ERROR)
- {
- return 1U;
- }
-
- switch (current)
- {
- case PLSR_STATE_UNINITIALIZED:
- return (target == PLSR_STATE_IDLE) ? 1U : 0U;
-
- case PLSR_STATE_IDLE:
- case PLSR_STATE_COMPLETED:
- case PLSR_STATE_STOPPED:
- return ((target == PLSR_STATE_ACCEL)
- || (target == PLSR_STATE_WAIT)
- || (target == PLSR_STATE_COMPLETED))
- ? 1U
- : 0U;
-
- case PLSR_STATE_ACCEL:
- case PLSR_STATE_RUN:
- return ((target == PLSR_STATE_RUN)
- || (target == PLSR_STATE_DECEL)
- || (target == PLSR_STATE_WAIT)
- || (target == PLSR_STATE_COMPLETED)
- || (target == PLSR_STATE_STOPPED))
- ? 1U
- : 0U;
-
- case PLSR_STATE_DECEL:
- return ((target == PLSR_STATE_RUN)
- || (target == PLSR_STATE_WAIT)
- || (target == PLSR_STATE_PAUSED)
- || (target == PLSR_STATE_COMPLETED)
- || (target == PLSR_STATE_STOPPED))
- ? 1U
- : 0U;
-
- case PLSR_STATE_WAIT:
- return ((target == PLSR_STATE_ACCEL)
- || (target == PLSR_STATE_RUN)
- || (target == PLSR_STATE_PAUSED)
- || (target == PLSR_STATE_COMPLETED)
- || (target == PLSR_STATE_STOPPED))
- ? 1U
- : 0U;
-
- case PLSR_STATE_PAUSED:
- return ((target == PLSR_STATE_ACCEL)
- || (target == PLSR_STATE_RUN)
- || (target == PLSR_STATE_STOPPED))
- ? 1U
- : 0U;
-
- case PLSR_STATE_ERROR:
- return (target == PLSR_STATE_IDLE) ? 1U : 0U;
-
- default:
- return 0U;
- }
- }
-
- PLSR_RESULT PlsrStateTransition(uint8_t axis,
- PLSR_STATE target,
- PLSR_TRANSITION_REASON reason)
- {
- PLSR_AXIS *axisObject;
-
- (void)reason;
- if (axis >= PLSR_AXIS_COUNT)
- {
- return PLSR_RESULT_INVALID_AXIS;
- }
- if ((uint32_t)target > (uint32_t)PLSR_STATE_ERROR)
- {
- return PLSR_RESULT_INVALID_ARGUMENT;
- }
-
- axisObject = &PlsrAxes[axis];
- if (PlsrTransitionIsAllowed(axisObject->state, target) == 0U)
- {
- axisObject->illegalTransitionCount++;
- axisObject->error = PLSR_ERROR_ILLEGAL_TRANSITION;
- axisObject->stopReason = PLSR_STOP_REASON_FAULT;
- axisObject->done = 0U;
- axisObject->state = PLSR_STATE_ERROR;
- axisObject->pendingTerminal = PLSR_STATE_UNINITIALIZED;
- axisObject->immediateStopPending = 0U;
- PlsrResourceRelease(&axisObject->lease);
- PlsrPublishAxis(axis);
- return PLSR_RESULT_INVALID_STATE;
- }
-
- axisObject->state = target;
- if (target == PLSR_STATE_COMPLETED)
- {
- axisObject->done = 1U;
- }
- if ((target == PLSR_STATE_COMPLETED) || (target == PLSR_STATE_STOPPED)
- || (target == PLSR_STATE_ERROR))
- {
- axisObject->pendingTerminal = PLSR_STATE_UNINITIALIZED;
- axisObject->immediateStopPending = 0U;
- PlsrResourceRelease(&axisObject->lease);
- }
- PlsrPublishAxis(axis);
- return PLSR_RESULT_OK;
- }
-
- static uint8_t PlsrCommandPriority(PLSR_COMMAND_OPCODE opcode)
- {
- switch (opcode)
- {
- case PLSR_CMD_STOP_IMMEDIATE:
- return 0U;
- case PLSR_CMD_STOP_DECEL:
- return 1U;
- case PLSR_CMD_PAUSE:
- return 2U;
- case PLSR_CMD_RESUME:
- return 3U;
- default:
- return 4U;
- }
- }
-
- static PLSR_RESULT PlsrQueueCommand(const PLSR_COMMAND *command,
- const PLSR_START_REQUEST *start,
- const PLSR_CALL *call)
- {
- uint32_t interruptState;
- uint8_t freeSlot = PLSR_COMMAND_QUEUE_DEPTH;
- uint8_t index;
-
- interruptState = PlsrCoreEnterCritical();
- if ((PlsrAxes[command->axis].hasLastCommand != 0U)
- && (PlsrAxes[command->axis].lastCommandSequence == command->sequence))
- {
- PLSR_RESULT result = PlsrAxes[command->axis].lastCommandResult;
- PlsrCoreExitCritical(interruptState);
- return result;
- }
-
- for (index = 0U; index < PLSR_COMMAND_QUEUE_DEPTH; index++)
- {
- if (PlsrCommandQueue[index].occupied != 0U)
- {
- if ((PlsrCommandQueue[index].command.axis == command->axis)
- && (PlsrCommandQueue[index].command.sequence
- == command->sequence))
- {
- PlsrCoreExitCritical(interruptState);
- return PLSR_RESULT_QUEUED;
- }
- }
- else if (freeSlot == PLSR_COMMAND_QUEUE_DEPTH)
- {
- freeSlot = index;
- }
- }
-
- if (freeSlot == PLSR_COMMAND_QUEUE_DEPTH)
- {
- PlsrCoreExitCritical(interruptState);
- return PLSR_RESULT_QUEUE_FULL;
- }
-
- PlsrCommandQueue[freeSlot].command = *command;
- if (start != NULL)
- {
- PlsrCommandQueue[freeSlot].start = *start;
- PlsrCommandQueue[freeSlot].hasStart = 1U;
- }
- else
- {
- (void)memset(&PlsrCommandQueue[freeSlot].start,
- 0,
- sizeof(PlsrCommandQueue[freeSlot].start));
- PlsrCommandQueue[freeSlot].hasStart = 0U;
- }
- if (call != NULL)
- {
- PlsrCommandQueue[freeSlot].call = *call;
- PlsrCommandQueue[freeSlot].hasCall = 1U;
- }
- else
- {
- (void)memset(&PlsrCommandQueue[freeSlot].call,
- 0,
- sizeof(PlsrCommandQueue[freeSlot].call));
- PlsrCommandQueue[freeSlot].hasCall = 0U;
- }
- PlsrCommandQueue[freeSlot].ticket = PlsrNextTicket++;
- PlsrCommandQueue[freeSlot].occupied = 1U;
- PlsrCoreExitCritical(interruptState);
- return PLSR_RESULT_QUEUED;
- }
-
- static uint8_t PlsrPopHighestPriorityCommand(PLSR_COMMAND_SLOT *slot)
- {
- uint32_t interruptState;
- uint32_t selectedTicket = 0UL;
- uint8_t selectedPriority = 0xFFU;
- uint8_t selected = PLSR_COMMAND_QUEUE_DEPTH;
- uint8_t index;
- uint8_t priority;
-
- interruptState = PlsrCoreEnterCritical();
- for (index = 0U; index < PLSR_COMMAND_QUEUE_DEPTH; index++)
- {
- if (PlsrCommandQueue[index].occupied == 0U)
- {
- continue;
- }
- priority = PlsrCommandPriority(PlsrCommandQueue[index].command.opcode);
- if ((selected == PLSR_COMMAND_QUEUE_DEPTH)
- || (priority < selectedPriority)
- || ((priority == selectedPriority)
- && ((int32_t)(PlsrCommandQueue[index].ticket
- - selectedTicket)
- < 0)))
- {
- selected = index;
- selectedPriority = priority;
- selectedTicket = PlsrCommandQueue[index].ticket;
- }
- }
-
- if (selected == PLSR_COMMAND_QUEUE_DEPTH)
- {
- PlsrCoreExitCritical(interruptState);
- return 0U;
- }
-
- *slot = PlsrCommandQueue[selected];
- PlsrCommandQueue[selected].occupied = 0U;
- PlsrCoreExitCritical(interruptState);
- return 1U;
- }
-
- PLSR_RESULT PlsrPostStart(const PLSR_START_REQUEST *request)
- {
- PLSR_COMMAND command;
-
- if (request == NULL)
- {
- return PLSR_RESULT_INVALID_ARGUMENT;
- }
- if (request->axis >= PLSR_AXIS_COUNT)
- {
- return PLSR_RESULT_INVALID_AXIS;
- }
- if (PlsrInitialized == 0U)
- {
- return PLSR_RESULT_INVALID_STATE;
- }
-
- command.sequence = request->sequence;
- command.axis = request->axis;
- command.opcode = PLSR_CMD_START;
- command.argument = 0;
- return PlsrQueueCommand(&command, request, NULL);
- }
-
- PLSR_RESULT PlsrPostCall(const PLSR_CALL *call)
- {
- PLSR_COMMAND command;
-
- if (call == NULL)
- {
- return PLSR_RESULT_INVALID_ARGUMENT;
- }
- if (call->dAxis >= PLSR_AXIS_COUNT)
- {
- return PLSR_RESULT_INVALID_AXIS;
- }
- if (PlsrInitialized == 0U)
- {
- return PLSR_RESULT_INVALID_STATE;
- }
- command.sequence = call->sequence;
- command.axis = call->dAxis;
- command.opcode = PLSR_CMD_START;
- command.argument = 0;
- return PlsrQueueCommand(&command, NULL, call);
- }
-
- PLSR_RESULT PlsrPostCommand(const PLSR_COMMAND *command)
- {
- if (command == NULL)
- {
- return PLSR_RESULT_INVALID_ARGUMENT;
- }
- if (command->axis >= PLSR_AXIS_COUNT)
- {
- return PLSR_RESULT_INVALID_AXIS;
- }
- if (((uint32_t)command->opcode > (uint32_t)PLSR_CMD_SELF_TEST)
- || (command->opcode == PLSR_CMD_START))
- {
- return PLSR_RESULT_INVALID_ARGUMENT;
- }
- if (PlsrInitialized == 0U)
- {
- return PLSR_RESULT_INVALID_STATE;
- }
- return PlsrQueueCommand(command, NULL, NULL);
- }
-
- PLSR_RESULT PlsrPostEvent(uint8_t axis, uint32_t eventMask)
- {
- uint32_t interruptState;
-
- if (axis >= PLSR_AXIS_COUNT)
- {
- return PLSR_RESULT_INVALID_AXIS;
- }
- if ((eventMask == 0UL) || ((eventMask & ~PLSR_EVENT_ALL_MASK) != 0UL))
- {
- return PLSR_RESULT_INVALID_ARGUMENT;
- }
-
- interruptState = PlsrCoreEnterCritical();
- PlsrAxes[axis].pendingEvents |= eventMask;
- PlsrCoreExitCritical(interruptState);
- return PLSR_RESULT_OK;
- }
-
- static uint32_t PlsrTakeEvents(uint8_t axis, uint32_t mask)
- {
- uint32_t interruptState;
- uint32_t events;
-
- interruptState = PlsrCoreEnterCritical();
- events = PlsrAxes[axis].pendingEvents & mask;
- PlsrAxes[axis].pendingEvents &= ~events;
- PlsrCoreExitCritical(interruptState);
- return events;
- }
-
- static uint8_t PlsrAnyAxisBusy(void)
- {
- uint8_t axis;
-
- for (axis = 0U; axis < PLSR_AXIS_COUNT; axis++)
- {
- if (PlsrStateIsBusy(PlsrAxes[axis].state) != 0U)
- {
- return 1U;
- }
- }
- return 0U;
- }
-
- static PLSR_RESULT PlsrStartAxis(PLSR_AXIS *axisObject,
- const PLSR_START_REQUEST *start)
- {
- PLSR_RESOURCE_REQUEST resourceRequest;
- PLSR_RESULT result;
-
- if ((axisObject->state != PLSR_STATE_IDLE)
- && (axisObject->state != PLSR_STATE_COMPLETED)
- && (axisObject->state != PLSR_STATE_STOPPED))
- {
- return PLSR_RESULT_INVALID_STATE;
- }
-
- resourceRequest.ownerAxis = start->axis;
- resourceRequest.outputMode = start->outputMode;
- resourceRequest.dAxis = start->axis;
- resourceRequest.directionPoint = start->directionPoint;
- result = PlsrResourceReserve(&resourceRequest, &axisObject->lease);
- if (result != PLSR_RESULT_OK)
- {
- axisObject->error = (result == PLSR_RESULT_RESOURCE_CONFLICT)
- ? PLSR_ERROR_RESOURCE_CONFLICT
- : PLSR_ERROR_INVALID_RESOURCE;
- return result;
- }
-
- axisObject->outputMode = start->outputMode;
- axisObject->directionPositive = (start->directionPositive != 0U) ? 1U : 0U;
- axisObject->error = PLSR_ERROR_NONE;
- axisObject->stopReason = PLSR_STOP_REASON_NONE;
- axisObject->pendingTerminal = PLSR_STATE_UNINITIALIZED;
- axisObject->immediateStopPending = 0U;
- axisObject->done = 0U;
- axisObject->jobValid = 0U;
- result = PlsrStateTransition(start->axis,
- PLSR_STATE_ACCEL,
- PLSR_TRANSITION_START);
- if (result != PLSR_RESULT_OK)
- {
- PlsrResourceRelease(&axisObject->lease);
- }
- return result;
- }
-
- static PLSR_RESULT PlsrStartCall(PLSR_AXIS *axisObject,
- const PLSR_CALL *call)
- {
- PLSR_RESOURCE_REQUEST resourceRequest;
- PLSR_PARSE_CONTEXT parseContext;
- PLSR_RESULT result;
-
- if ((axisObject->state != PLSR_STATE_IDLE)
- && (axisObject->state != PLSR_STATE_COMPLETED)
- && (axisObject->state != PLSR_STATE_STOPPED))
- {
- return PLSR_RESULT_INVALID_STATE;
- }
-
- parseContext.logicalPosition = axisObject->logicalPosition;
- parseContext.positionValid = axisObject->positionValid;
- result = PlsrBuildJobSnapshot(call,
- &parseContext,
- &PlsrJobScratch,
- &axisObject->parseDetail);
- if (result != PLSR_RESULT_OK)
- {
- return result;
- }
-
- resourceRequest.ownerAxis = call->dAxis;
- resourceRequest.outputMode =
- (PLSR_OUTPUT_MODE)PlsrJobScratch.outputMode;
- resourceRequest.dAxis = call->dAxis;
- resourceRequest.directionPoint = PlsrJobScratch.directionPoint;
- result = PlsrResourceReserve(&resourceRequest, &axisObject->lease);
- if (result != PLSR_RESULT_OK)
- {
- axisObject->error = (result == PLSR_RESULT_RESOURCE_CONFLICT)
- ? PLSR_ERROR_RESOURCE_CONFLICT
- : PLSR_ERROR_INVALID_RESOURCE;
- axisObject->parseDetail.result = result;
- axisObject->parseDetail.block = PLSR_PARSE_BLOCK_OUTPUT;
- return result;
- }
-
- axisObject->job = PlsrJobScratch;
- axisObject->jobValid = 1U;
- axisObject->outputMode = (PLSR_OUTPUT_MODE)axisObject->job.outputMode;
- axisObject->directionPositive = axisObject->job.initialDirectionPositive;
- axisObject->error = PLSR_ERROR_NONE;
- axisObject->stopReason = PLSR_STOP_REASON_NONE;
- axisObject->pendingTerminal = PLSR_STATE_UNINITIALIZED;
- axisObject->immediateStopPending = 0U;
- axisObject->done = 0U;
- result = PlsrStateTransition(call->dAxis,
- PLSR_STATE_ACCEL,
- PLSR_TRANSITION_START);
- if (result != PLSR_RESULT_OK)
- {
- axisObject->jobValid = 0U;
- PlsrResourceRelease(&axisObject->lease);
- }
- return result;
- }
-
- static PLSR_RESULT PlsrStopImmediate(uint8_t axis)
- {
- PLSR_AXIS *axisObject = &PlsrAxes[axis];
-
- if ((axisObject->state == PLSR_STATE_IDLE)
- || (axisObject->state == PLSR_STATE_COMPLETED)
- || (axisObject->state == PLSR_STATE_STOPPED))
- {
- return PLSR_RESULT_OK;
- }
- if (axisObject->state == PLSR_STATE_ERROR)
- {
- return PLSR_RESULT_INVALID_STATE;
- }
- if (axisObject->immediateStopPending != 0U)
- {
- return PLSR_RESULT_OK;
- }
-
- PlsrSetStopReason(axisObject, PLSR_STOP_REASON_STOP_IMMEDIATE);
- axisObject->pendingTerminal = PLSR_STATE_STOPPED;
- if ((axisObject->state == PLSR_STATE_WAIT)
- || (axisObject->state == PLSR_STATE_PAUSED))
- {
- return PlsrStateTransition(axis,
- PLSR_STATE_STOPPED,
- PLSR_TRANSITION_STOP);
- }
-
- axisObject->immediateStopPending = 1U;
- return PLSR_RESULT_OK;
- }
-
- static PLSR_RESULT PlsrStopDecel(uint8_t axis)
- {
- PLSR_AXIS *axisObject = &PlsrAxes[axis];
-
- if ((axisObject->state == PLSR_STATE_IDLE)
- || (axisObject->state == PLSR_STATE_COMPLETED)
- || (axisObject->state == PLSR_STATE_STOPPED))
- {
- return PLSR_RESULT_OK;
- }
- if (axisObject->state == PLSR_STATE_ERROR)
- {
- return PLSR_RESULT_INVALID_STATE;
- }
- if (axisObject->stopReason >= PLSR_STOP_REASON_STOP_IMMEDIATE)
- {
- return PLSR_RESULT_OK;
- }
-
- PlsrSetStopReason(axisObject, PLSR_STOP_REASON_STOP_DECEL);
- axisObject->pendingTerminal = PLSR_STATE_STOPPED;
- if ((axisObject->state == PLSR_STATE_WAIT)
- || (axisObject->state == PLSR_STATE_PAUSED))
- {
- return PlsrStateTransition(axis,
- PLSR_STATE_STOPPED,
- PLSR_TRANSITION_STOP);
- }
- if (axisObject->state == PLSR_STATE_DECEL)
- {
- return PLSR_RESULT_OK;
- }
- return PlsrStateTransition(axis,
- PLSR_STATE_DECEL,
- PLSR_TRANSITION_DECEL_REQUEST);
- }
-
- static PLSR_RESULT PlsrPause(uint8_t axis)
- {
- PLSR_AXIS *axisObject = &PlsrAxes[axis];
-
- if (axisObject->state == PLSR_STATE_PAUSED)
- {
- return PLSR_RESULT_OK;
- }
- if (axisObject->stopReason >= PLSR_STOP_REASON_STOP_DECEL)
- {
- return PLSR_RESULT_BUSY;
- }
- if (axisObject->state == PLSR_STATE_WAIT)
- {
- PlsrSetStopReason(axisObject, PLSR_STOP_REASON_PAUSE);
- return PlsrStateTransition(axis,
- PLSR_STATE_PAUSED,
- PLSR_TRANSITION_DECEL_COMPLETE);
- }
- if ((axisObject->state != PLSR_STATE_ACCEL)
- && (axisObject->state != PLSR_STATE_RUN)
- && (axisObject->state != PLSR_STATE_DECEL))
- {
- return PLSR_RESULT_INVALID_STATE;
- }
-
- PlsrSetStopReason(axisObject, PLSR_STOP_REASON_PAUSE);
- axisObject->pendingTerminal = PLSR_STATE_PAUSED;
- if (axisObject->state == PLSR_STATE_DECEL)
- {
- return PLSR_RESULT_OK;
- }
- return PlsrStateTransition(axis,
- PLSR_STATE_DECEL,
- PLSR_TRANSITION_DECEL_REQUEST);
- }
-
- static PLSR_RESULT PlsrExecuteCommand(const PLSR_COMMAND_SLOT *slot)
- {
- PLSR_AXIS *axisObject = &PlsrAxes[slot->command.axis];
- PLC_DEVICE_RESULT deviceResult;
- PLSR_RESULT result;
-
- switch (slot->command.opcode)
- {
- case PLSR_CMD_START:
- if (slot->hasCall != 0U)
- {
- result = PlsrStartCall(axisObject, &slot->call);
- }
- else
- {
- result = (slot->hasStart != 0U)
- ? PlsrStartAxis(axisObject, &slot->start)
- : PLSR_RESULT_INVALID_ARGUMENT;
- }
- break;
-
- case PLSR_CMD_STOP_DECEL:
- result = PlsrStopDecel(slot->command.axis);
- break;
-
- case PLSR_CMD_STOP_IMMEDIATE:
- result = PlsrStopImmediate(slot->command.axis);
- break;
-
- case PLSR_CMD_PAUSE:
- result = PlsrPause(slot->command.axis);
- break;
-
- case PLSR_CMD_RESUME:
- if (axisObject->state != PLSR_STATE_PAUSED)
- {
- result = PLSR_RESULT_INVALID_STATE;
- }
- else
- {
- axisObject->stopReason = PLSR_STOP_REASON_NONE;
- axisObject->pendingTerminal = PLSR_STATE_UNINITIALIZED;
- result = PlsrStateTransition(slot->command.axis,
- PLSR_STATE_ACCEL,
- PLSR_TRANSITION_WAIT_COMPLETE);
- }
- break;
-
- case PLSR_CMD_SET_POSITION:
- if (PlsrStateIsBusy(axisObject->state) != 0U)
- {
- result = PLSR_RESULT_BUSY;
- }
- else
- {
- axisObject->logicalPosition = slot->command.argument;
- axisObject->positionValid = 1U;
- (void)PlcDevicePublishHsdPair(
- (uint16_t)(slot->command.axis
- * PLSR_HSD_RUNTIME_AXIS_COUNT),
- axisObject->logicalPosition);
- result = PLSR_RESULT_OK;
- }
- break;
-
- case PLSR_CMD_CLEAR_POSITION:
- if (PlsrStateIsBusy(axisObject->state) != 0U)
- {
- result = PLSR_RESULT_BUSY;
- }
- else
- {
- axisObject->logicalPosition = 0;
- axisObject->positionValid = 1U;
- (void)PlcDevicePublishHsdPair(
- (uint16_t)(slot->command.axis
- * PLSR_HSD_RUNTIME_AXIS_COUNT),
- 0);
- result = PLSR_RESULT_OK;
- }
- break;
-
- case PLSR_CMD_CLEAR_TOTAL:
- if (PlsrStateIsBusy(axisObject->state) != 0U)
- {
- result = PLSR_RESULT_BUSY;
- }
- else
- {
- axisObject->totalPulses = 0;
- result = PLSR_RESULT_OK;
- }
- break;
-
- case PLSR_CMD_SAVE_CONFIG:
- if (PlsrAnyAxisBusy() != 0U)
- {
- result = PLSR_RESULT_BUSY;
- }
- else
- {
- deviceResult = PlcDeviceSaveSfd();
- result = (deviceResult == PLC_DEVICE_OK)
- ? PLSR_RESULT_OK
- : PLSR_RESULT_PERSISTENCE_ERROR;
- }
- break;
-
- case PLSR_CMD_LOAD_CONFIG:
- if (PlsrAnyAxisBusy() != 0U)
- {
- result = PLSR_RESULT_BUSY;
- }
- else
- {
- deviceResult = PlcDeviceLoadSfd();
- result = (deviceResult == PLC_DEVICE_OK)
- ? PLSR_RESULT_OK
- : PLSR_RESULT_PERSISTENCE_ERROR;
- }
- break;
-
- case PLSR_CMD_RESET_ERROR:
- if (axisObject->state != PLSR_STATE_ERROR)
- {
- result = PLSR_RESULT_INVALID_STATE;
- }
- else
- {
- axisObject->error = PLSR_ERROR_NONE;
- axisObject->stopReason = PLSR_STOP_REASON_NONE;
- axisObject->done = 0U;
- result = PlsrStateTransition(slot->command.axis,
- PLSR_STATE_IDLE,
- PLSR_TRANSITION_RESET_ERROR);
- }
- break;
-
- case PLSR_CMD_SELF_TEST:
- result = ((PlsrAnyAxisBusy() == 0U)
- && (PlsrResourceCheckInvariant() != 0U))
- ? PLSR_RESULT_OK
- : PLSR_RESULT_BUSY;
- break;
-
- default:
- result = PLSR_RESULT_INVALID_ARGUMENT;
- break;
- }
-
- axisObject->lastCommandSequence = slot->command.sequence;
- axisObject->lastCommandResult = result;
- axisObject->hasLastCommand = 1U;
- PlsrPublishAxis(slot->command.axis);
- return result;
- }
-
- static void PlsrProcessCriticalEvents(uint8_t axis, uint32_t events)
- {
- PLSR_AXIS *axisObject = &PlsrAxes[axis];
-
- if ((events & PLSR_EVENT_SOFTWARE_EMERGENCY) != 0UL)
- {
- if (PlsrStateIsBusy(axisObject->state) != 0U)
- {
- PlsrSetStopReason(axisObject,
- PLSR_STOP_REASON_SOFTWARE_EMERGENCY);
- axisObject->done = 0U;
- (void)PlsrStateTransition(axis,
- PLSR_STATE_STOPPED,
- PLSR_TRANSITION_STOP);
- }
- return;
- }
-
- if ((events & PLSR_EVENT_LIMIT_POSITIVE) != 0UL)
- {
- if ((axisObject->directionPositive != 0U)
- && (PlsrStateIsBusy(axisObject->state) != 0U))
- {
- axisObject->error = PLSR_ERROR_LIMIT_POSITIVE;
- PlsrSetStopReason(axisObject,
- PLSR_STOP_REASON_LIMIT_POSITIVE);
- axisObject->pendingTerminal = PLSR_STATE_STOPPED;
- if ((axisObject->state == PLSR_STATE_WAIT)
- || (axisObject->state == PLSR_STATE_PAUSED))
- {
- (void)PlsrStateTransition(axis,
- PLSR_STATE_STOPPED,
- PLSR_TRANSITION_STOP);
- }
- else if (axisObject->state != PLSR_STATE_DECEL)
- {
- (void)PlsrStateTransition(axis,
- PLSR_STATE_DECEL,
- PLSR_TRANSITION_DECEL_REQUEST);
- }
- }
- return;
- }
-
- if ((events & PLSR_EVENT_LIMIT_NEGATIVE) != 0UL)
- {
- if ((axisObject->directionPositive == 0U)
- && (PlsrStateIsBusy(axisObject->state) != 0U))
- {
- axisObject->error = PLSR_ERROR_LIMIT_NEGATIVE;
- PlsrSetStopReason(axisObject,
- PLSR_STOP_REASON_LIMIT_NEGATIVE);
- axisObject->pendingTerminal = PLSR_STATE_STOPPED;
- if ((axisObject->state == PLSR_STATE_WAIT)
- || (axisObject->state == PLSR_STATE_PAUSED))
- {
- (void)PlsrStateTransition(axis,
- PLSR_STATE_STOPPED,
- PLSR_TRANSITION_STOP);
- }
- else if (axisObject->state != PLSR_STATE_DECEL)
- {
- (void)PlsrStateTransition(axis,
- PLSR_STATE_DECEL,
- PLSR_TRANSITION_DECEL_REQUEST);
- }
- }
- return;
- }
-
- if ((events & (PLSR_EVENT_TIMER_FAULT | PLSR_EVENT_COUNTER_FAULT)) != 0UL)
- {
- axisObject->error = ((events & PLSR_EVENT_TIMER_FAULT) != 0UL)
- ? PLSR_ERROR_TIMER_FAULT
- : PLSR_ERROR_COUNTER_FAULT;
- PlsrSetStopReason(axisObject, PLSR_STOP_REASON_FAULT);
- axisObject->done = 0U;
- (void)PlsrStateTransition(axis,
- PLSR_STATE_ERROR,
- PLSR_TRANSITION_FAULT);
- }
- }
-
- static void PlsrProcessNormalEvents(uint8_t axis, uint32_t events)
- {
- PLSR_AXIS *axisObject = &PlsrAxes[axis];
-
- if (((events & PLSR_EVENT_STOP_IMMEDIATE_DONE) != 0UL)
- && (axisObject->immediateStopPending != 0U))
- {
- (void)PlsrStateTransition(axis,
- PLSR_STATE_STOPPED,
- PLSR_TRANSITION_STOP);
- return;
- }
-
- if (((events & PLSR_EVENT_ACCEL_COMPLETE) != 0UL)
- && (axisObject->state == PLSR_STATE_ACCEL)
- && (axisObject->immediateStopPending == 0U))
- {
- (void)PlsrStateTransition(axis,
- PLSR_STATE_RUN,
- PLSR_TRANSITION_ACCEL_COMPLETE);
- }
-
- if (((events & PLSR_EVENT_DECEL_COMPLETE) != 0UL)
- && (axisObject->state == PLSR_STATE_DECEL))
- {
- if (axisObject->pendingTerminal == PLSR_STATE_PAUSED)
- {
- (void)PlsrStateTransition(axis,
- PLSR_STATE_PAUSED,
- PLSR_TRANSITION_DECEL_COMPLETE);
- }
- else if (axisObject->pendingTerminal == PLSR_STATE_STOPPED)
- {
- (void)PlsrStateTransition(axis,
- PLSR_STATE_STOPPED,
- PLSR_TRANSITION_DECEL_COMPLETE);
- }
- else
- {
- (void)PlsrStateTransition(axis,
- PLSR_STATE_RUN,
- PLSR_TRANSITION_DECEL_COMPLETE);
- }
- }
-
- if (((events & PLSR_EVENT_WAIT_BEGIN) != 0UL)
- && ((axisObject->state == PLSR_STATE_ACCEL)
- || (axisObject->state == PLSR_STATE_RUN)))
- {
- (void)PlsrStateTransition(axis,
- PLSR_STATE_WAIT,
- PLSR_TRANSITION_WAIT_BEGIN);
- }
-
- if (((events & PLSR_EVENT_WAIT_COMPLETE) != 0UL)
- && (axisObject->state == PLSR_STATE_WAIT))
- {
- (void)PlsrStateTransition(axis,
- PLSR_STATE_ACCEL,
- PLSR_TRANSITION_WAIT_COMPLETE);
- }
-
- if (((events & PLSR_EVENT_JOB_COMPLETE) != 0UL)
- && (PlsrStateIsBusy(axisObject->state) != 0U)
- && (axisObject->pendingTerminal == PLSR_STATE_UNINITIALIZED)
- && (axisObject->immediateStopPending == 0U))
- {
- axisObject->stopReason = PLSR_STOP_REASON_NORMAL_COMPLETE;
- (void)PlsrStateTransition(axis,
- PLSR_STATE_COMPLETED,
- PLSR_TRANSITION_JOB_COMPLETE);
- }
- }
-
- PLSR_RESULT PlsrInit(void)
- {
- int64_t restoredPosition;
- uint8_t axis;
-
- (void)memset(PlsrAxes, 0, sizeof(PlsrAxes));
- (void)memset(PlsrCommandQueue, 0, sizeof(PlsrCommandQueue));
- PlsrNextTicket = 0UL;
- PlsrResourceInit();
- PlsrInitialized = 1U;
-
- for (axis = 0U; axis < PLSR_AXIS_COUNT; axis++)
- {
- PlsrAxes[axis].state = PLSR_STATE_UNINITIALIZED;
- PlsrAxes[axis].pendingTerminal = PLSR_STATE_UNINITIALIZED;
- PlsrAxes[axis].lease.directionPoint = PLSR_DIRECTION_POINT_NONE;
- if ((PlcDeviceGetLastHsdLoadResult() == PLSR_PERSISTENCE_OK)
- && (PlcDeviceReadHsdPair(
- (uint16_t)(axis * PLSR_HSD_RUNTIME_AXIS_COUNT),
- &restoredPosition)
- == PLC_DEVICE_OK))
- {
- PlsrAxes[axis].logicalPosition = restoredPosition;
- PlsrAxes[axis].positionValid = 1U;
- }
- if (PlsrStateTransition(axis,
- PLSR_STATE_IDLE,
- PLSR_TRANSITION_INITIALIZED)
- != PLSR_RESULT_OK)
- {
- return PLSR_RESULT_INTERNAL_ERROR;
- }
- }
- return PLSR_RESULT_OK;
- }
-
- void PlsrProcess(void)
- {
- PLSR_COMMAND_SLOT slot;
- uint32_t events;
- uint8_t processedCommands = 0U;
- uint8_t axis;
-
- if (PlsrInitialized == 0U)
- {
- return;
- }
-
- for (axis = 0U; axis < PLSR_AXIS_COUNT; axis++)
- {
- events = PlsrTakeEvents(axis, PLSR_EVENT_CRITICAL_MASK);
- if (events != 0UL)
- {
- PlsrProcessCriticalEvents(axis, events);
- }
- }
-
- while ((processedCommands < PLSR_COMMAND_QUEUE_DEPTH)
- && (PlsrPopHighestPriorityCommand(&slot) != 0U))
- {
- (void)PlsrExecuteCommand(&slot);
- processedCommands++;
- }
-
- for (axis = 0U; axis < PLSR_AXIS_COUNT; axis++)
- {
- events = PlsrTakeEvents(axis,
- PLSR_EVENT_ALL_MASK
- & ~PLSR_EVENT_CRITICAL_MASK);
- if (events != 0UL)
- {
- PlsrProcessNormalEvents(axis, events);
- }
- }
- }
-
- void PlsrTask(void *argument)
- {
- (void)argument;
- #ifdef PLSR_HOST_TEST
- PlsrProcess();
- #else
- while (1)
- {
- PlsrProcess();
- OSTimeDly(1U);
- }
- #endif
- }
-
- PLSR_RESULT PlsrGetStatus(uint8_t axis, PLSR_STATUS *status)
- {
- PLSR_AXIS *axisObject;
- uint32_t interruptState;
-
- if (axis >= PLSR_AXIS_COUNT)
- {
- return PLSR_RESULT_INVALID_AXIS;
- }
- if (status == NULL)
- {
- return PLSR_RESULT_INVALID_ARGUMENT;
- }
-
- interruptState = PlsrCoreEnterCritical();
- axisObject = &PlsrAxes[axis];
- status->state = axisObject->state;
- status->outputMode = axisObject->outputMode;
- status->error = axisObject->error;
- status->stopReason = axisObject->stopReason;
- status->lastCommandResult = axisObject->lastCommandResult;
- status->lastCommandSequence = axisObject->lastCommandSequence;
- status->illegalTransitionCount = axisObject->illegalTransitionCount;
- status->pendingEvents = axisObject->pendingEvents;
- status->logicalPosition = axisObject->logicalPosition;
- status->totalPulses = axisObject->totalPulses;
- status->busy = PlsrStateIsBusy(axisObject->state);
- status->pulseActive = PlsrStateIsPulseActive(axisObject->state);
- status->done = axisObject->done;
- status->wait = (axisObject->state == PLSR_STATE_WAIT) ? 1U : 0U;
- status->directionPositive = axisObject->directionPositive;
- status->highResourceMask = axisObject->lease.highMask;
- status->directionPoint = (axisObject->lease.valid != 0U)
- ? axisObject->lease.directionPoint
- : PLSR_DIRECTION_POINT_NONE;
- status->positionValid = axisObject->positionValid;
- status->jobValid = axisObject->jobValid;
- status->s2Set = (axisObject->jobValid != 0U) ? axisObject->job.s2Set : 0U;
- status->speedClamped = (axisObject->jobValid != 0U)
- ? axisObject->job.speedClamped
- : 0U;
- status->segmentCount = (axisObject->jobValid != 0U)
- ? axisObject->job.segmentCount
- : 0U;
- status->startSegment = (axisObject->jobValid != 0U)
- ? axisObject->job.startSegment
- : 0U;
- PlsrCoreExitCritical(interruptState);
- return PLSR_RESULT_OK;
- }
-
- PLSR_RESULT PlsrGetLastParseDetail(uint8_t axis,
- PLSR_PARSE_DETAIL *detail)
- {
- uint32_t interruptState;
-
- if (axis >= PLSR_AXIS_COUNT)
- {
- return PLSR_RESULT_INVALID_AXIS;
- }
- if (detail == NULL)
- {
- return PLSR_RESULT_INVALID_ARGUMENT;
- }
- interruptState = PlsrCoreEnterCritical();
- *detail = PlsrAxes[axis].parseDetail;
- PlsrCoreExitCritical(interruptState);
- return PLSR_RESULT_OK;
- }
|