|
- #include "plc_device.h"
- #include <string.h>
-
- #ifndef PLSR_HOST_TEST
- #include "stm32f4xx.h"
- #endif
-
- #define PLC_SM_PULSE_ACTIVE_MASK (0x01U)
- #define PLC_SM_DIRECTION_MASK (0x02U)
-
- const PLSR_AXIS_ADDRESS_MAP PlsrAxisAddressMap[PLSR_AXIS_COUNT] =
- {
- {0U, 1000U, 1001U, 1000U, 6000U},
- {4U, 1020U, 1021U, 1020U, 6100U},
- {8U, 1040U, 1041U, 1040U, 6200U},
- {12U, 1060U, 1061U, 1060U, 6300U}
- };
-
- static PLSR_HSD_DATA PlcHsdData;
- static PLSR_SFD_DATA PlcSfdData;
- static int32_t PlcSdRuntime[PLSR_AXIS_COUNT][PLSR_SD_AXIS_ITEM_COUNT];
- static uint8_t PlcSmFlags[PLSR_AXIS_COUNT];
- static uint8_t PlcHsdDirty;
- static uint8_t PlcSfdDirty;
- static uint32_t PlcHsdChangeCounter;
- static PLSR_PERSISTENCE_RESULT PlcLastHsdLoadResult;
- static PLSR_PERSISTENCE_RESULT PlcLastSfdLoadResult;
-
- static uint32_t PlcDeviceEnterCritical(void)
- {
- #ifdef PLSR_HOST_TEST
- return 0UL;
- #else
- uint32_t interruptState = __get_PRIMASK();
- __disable_irq();
- __DMB();
- return interruptState;
- #endif
- }
-
- static void PlcDeviceExitCritical(uint32_t interruptState)
- {
- #ifdef PLSR_HOST_TEST
- (void)interruptState;
- #else
- __DMB();
- if (interruptState == 0UL)
- {
- __enable_irq();
- }
- #endif
- }
-
- static int32_t *PlcDeviceResolveHsd(uint16_t address)
- {
- if (address < PLSR_HSD_RUNTIME_START + PLSR_HSD_RUNTIME_COUNT)
- {
- return &PlcHsdData.runtime[address - PLSR_HSD_RUNTIME_START];
- }
- if ((address >= PLSR_HSD_CONFIG_START)
- && (address < PLSR_HSD_CONFIG_START + PLSR_HSD_CONFIG_COUNT))
- {
- return &PlcHsdData.config[address - PLSR_HSD_CONFIG_START];
- }
-
- return NULL;
- }
-
- static int32_t *PlcDeviceResolveSd(uint16_t address,
- uint8_t *axis,
- uint8_t *item)
- {
- uint8_t axisIndex;
- uint16_t base;
-
- for (axisIndex = 0U; axisIndex < PLSR_AXIS_COUNT; axisIndex++)
- {
- base = PlsrAxisAddressMap[axisIndex].sdRuntimeBase;
- if ((address >= base)
- && (address < base + PLSR_SD_AXIS_ITEM_COUNT))
- {
- if (axis != NULL)
- {
- *axis = axisIndex;
- }
- if (item != NULL)
- {
- *item = (uint8_t)(address - base);
- }
- return &PlcSdRuntime[axisIndex][address - base];
- }
- }
-
- return NULL;
- }
-
- static PLC_DEVICE_RESULT PlcDeviceResolveSm(uint16_t address,
- uint8_t *axis,
- uint8_t *mask)
- {
- uint8_t axisIndex;
-
- if ((axis == NULL) || (mask == NULL))
- {
- return PLC_DEVICE_NULL_POINTER;
- }
-
- for (axisIndex = 0U; axisIndex < PLSR_AXIS_COUNT; axisIndex++)
- {
- if (address == PlsrAxisAddressMap[axisIndex].smPulseActiveAddress)
- {
- *axis = axisIndex;
- *mask = PLC_SM_PULSE_ACTIVE_MASK;
- return PLC_DEVICE_OK;
- }
- if (address == PlsrAxisAddressMap[axisIndex].smDirectionAddress)
- {
- *axis = axisIndex;
- *mask = PLC_SM_DIRECTION_MASK;
- return PLC_DEVICE_OK;
- }
- }
-
- return PLC_DEVICE_INVALID_ADDRESS;
- }
-
- PLC_DEVICE_RESULT PlcDeviceInit(void)
- {
- (void)memset(&PlcHsdData, 0, sizeof(PlcHsdData));
- (void)memset(&PlcSfdData, 0, sizeof(PlcSfdData));
- (void)memset(PlcSdRuntime, 0, sizeof(PlcSdRuntime));
- (void)memset(PlcSmFlags, 0, sizeof(PlcSmFlags));
- PlcHsdChangeCounter = 0UL;
-
- PlcLastHsdLoadResult = PlsrPersistenceLoadHsd(&PlcHsdData);
- PlcHsdDirty = (PlcLastHsdLoadResult == PLSR_PERSISTENCE_DEFAULTED)
- ? 1U
- : 0U;
- if ((PlcLastHsdLoadResult != PLSR_PERSISTENCE_OK)
- && (PlcLastHsdLoadResult != PLSR_PERSISTENCE_DEFAULTED))
- {
- return PLC_DEVICE_PERSISTENCE_ERROR;
- }
-
- PlcLastSfdLoadResult = PlsrPersistenceLoadSfd(&PlcSfdData);
- PlcSfdDirty = (PlcLastSfdLoadResult == PLSR_PERSISTENCE_OK) ? 0U : 1U;
- if ((PlcLastSfdLoadResult != PLSR_PERSISTENCE_OK)
- && (PlcLastSfdLoadResult != PLSR_PERSISTENCE_NOT_IMPLEMENTED))
- {
- return PLC_DEVICE_PERSISTENCE_ERROR;
- }
-
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDeviceReadHsd(uint16_t address, int32_t *value)
- {
- int32_t *source;
-
- if (value == NULL)
- {
- return PLC_DEVICE_NULL_POINTER;
- }
- source = PlcDeviceResolveHsd(address);
- if (source == NULL)
- {
- return PLC_DEVICE_INVALID_ADDRESS;
- }
-
- *value = *source;
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDeviceWriteHsdConfig(uint16_t address, int32_t value)
- {
- if ((address < PLSR_HSD_CONFIG_START)
- || (address >= PLSR_HSD_CONFIG_START + PLSR_HSD_CONFIG_COUNT))
- {
- return (address < PLSR_HSD_RUNTIME_START
- + PLSR_HSD_RUNTIME_COUNT)
- ? PLC_DEVICE_READ_ONLY
- : PLC_DEVICE_INVALID_ADDRESS;
- }
-
- PlcHsdData.config[address - PLSR_HSD_CONFIG_START] = value;
- PlcHsdChangeCounter++;
- PlcHsdDirty = 1U;
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDevicePublishHsdRuntime(uint16_t address, int32_t value)
- {
- if (address >= PLSR_HSD_RUNTIME_START + PLSR_HSD_RUNTIME_COUNT)
- {
- return PLC_DEVICE_INVALID_ADDRESS;
- }
-
- PlcHsdData.runtime[address - PLSR_HSD_RUNTIME_START] = value;
- PlcHsdChangeCounter++;
- PlcHsdDirty = 1U;
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDeviceReadHsdPair(uint16_t lowAddress, int64_t *value)
- {
- uint64_t combined;
- uint32_t interruptState;
- uint16_t offset;
-
- if (value == NULL)
- {
- return PLC_DEVICE_NULL_POINTER;
- }
- if ((lowAddress >= PLSR_HSD_RUNTIME_COUNT)
- || ((lowAddress & 1U) != 0U)
- || ((uint16_t)(lowAddress + 1U) >= PLSR_HSD_RUNTIME_COUNT))
- {
- return PLC_DEVICE_INVALID_ADDRESS;
- }
-
- offset = (uint16_t)(lowAddress - PLSR_HSD_RUNTIME_START);
- interruptState = PlcDeviceEnterCritical();
- combined = (uint64_t)(uint32_t)PlcHsdData.runtime[offset];
- combined |= ((uint64_t)(uint32_t)PlcHsdData.runtime[offset + 1U]) << 32U;
- PlcDeviceExitCritical(interruptState);
- *value = (int64_t)combined;
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDevicePublishHsdPair(uint16_t lowAddress, int64_t value)
- {
- uint64_t rawValue;
- uint32_t interruptState;
- uint16_t offset;
-
- if ((lowAddress >= PLSR_HSD_RUNTIME_COUNT)
- || ((lowAddress & 1U) != 0U)
- || ((uint16_t)(lowAddress + 1U) >= PLSR_HSD_RUNTIME_COUNT))
- {
- return PLC_DEVICE_INVALID_ADDRESS;
- }
-
- rawValue = (uint64_t)value;
- offset = (uint16_t)(lowAddress - PLSR_HSD_RUNTIME_START);
- interruptState = PlcDeviceEnterCritical();
- PlcHsdData.runtime[offset] = (int32_t)(uint32_t)rawValue;
- PlcHsdData.runtime[offset + 1U] = (int32_t)(uint32_t)(rawValue >> 32U);
- PlcHsdChangeCounter++;
- PlcHsdDirty = 1U;
- PlcDeviceExitCritical(interruptState);
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDeviceCheckpointHsd(void)
- {
- PLSR_HSD_DATA snapshot;
- PLSR_PERSISTENCE_RESULT result;
- uint32_t snapshotCounter;
- uint32_t interruptState;
-
- if (PlcHsdDirty == 0U)
- {
- return PLC_DEVICE_OK;
- }
-
- interruptState = PlcDeviceEnterCritical();
- snapshot = PlcHsdData;
- snapshotCounter = PlcHsdChangeCounter;
- PlcDeviceExitCritical(interruptState);
-
- result = PlsrPersistenceSaveHsd(&snapshot);
- if (result != PLSR_PERSISTENCE_OK)
- {
- return PLC_DEVICE_PERSISTENCE_ERROR;
- }
-
- interruptState = PlcDeviceEnterCritical();
- if (PlcHsdChangeCounter == snapshotCounter)
- {
- PlcHsdDirty = 0U;
- }
- PlcDeviceExitCritical(interruptState);
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDeviceReadSfd(uint16_t address, int32_t *value)
- {
- if (value == NULL)
- {
- return PLC_DEVICE_NULL_POINTER;
- }
- if ((address < PLSR_SFD_CONFIG_START)
- || (address >= PLSR_SFD_CONFIG_START + PLSR_SFD_CONFIG_COUNT))
- {
- return PLC_DEVICE_INVALID_ADDRESS;
- }
-
- *value = PlcSfdData.config[address - PLSR_SFD_CONFIG_START];
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDeviceWriteSfd(uint16_t address, int32_t value)
- {
- if ((address < PLSR_SFD_CONFIG_START)
- || (address >= PLSR_SFD_CONFIG_START + PLSR_SFD_CONFIG_COUNT))
- {
- return PLC_DEVICE_INVALID_ADDRESS;
- }
-
- PlcSfdData.config[address - PLSR_SFD_CONFIG_START] = value;
- PlcSfdDirty = 1U;
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDeviceLoadSfd(void)
- {
- PlcLastSfdLoadResult = PlsrPersistenceLoadSfd(&PlcSfdData);
- if (PlcLastSfdLoadResult == PLSR_PERSISTENCE_NOT_IMPLEMENTED)
- {
- return PLC_DEVICE_NOT_IMPLEMENTED;
- }
- if (PlcLastSfdLoadResult != PLSR_PERSISTENCE_OK)
- {
- return PLC_DEVICE_PERSISTENCE_ERROR;
- }
-
- PlcSfdDirty = 0U;
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDeviceSaveSfd(void)
- {
- PLSR_PERSISTENCE_RESULT result = PlsrPersistenceSaveSfd(&PlcSfdData);
-
- if (result == PLSR_PERSISTENCE_NOT_IMPLEMENTED)
- {
- return PLC_DEVICE_NOT_IMPLEMENTED;
- }
- if (result != PLSR_PERSISTENCE_OK)
- {
- return PLC_DEVICE_PERSISTENCE_ERROR;
- }
-
- PlcSfdDirty = 0U;
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDeviceReadSm(uint16_t address, uint8_t *state)
- {
- uint8_t axis;
- uint8_t mask;
- PLC_DEVICE_RESULT result;
-
- if (state == NULL)
- {
- return PLC_DEVICE_NULL_POINTER;
- }
- result = PlcDeviceResolveSm(address, &axis, &mask);
- if (result != PLC_DEVICE_OK)
- {
- return result;
- }
-
- *state = ((PlcSmFlags[axis] & mask) != 0U) ? 1U : 0U;
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDeviceWriteSm(uint16_t address, uint8_t state)
- {
- uint8_t axis;
- uint8_t mask;
- PLC_DEVICE_RESULT result;
-
- (void)state;
- result = PlcDeviceResolveSm(address, &axis, &mask);
- return (result == PLC_DEVICE_OK) ? PLC_DEVICE_READ_ONLY : result;
- }
-
- PLC_DEVICE_RESULT PlcDevicePublishSm(uint8_t axis,
- uint8_t pulseActive,
- uint8_t direction)
- {
- uint8_t flags = 0U;
-
- if (axis >= PLSR_AXIS_COUNT)
- {
- return PLC_DEVICE_INVALID_ARGUMENT;
- }
- if (pulseActive != 0U)
- {
- flags |= PLC_SM_PULSE_ACTIVE_MASK;
- }
- if (direction != 0U)
- {
- flags |= PLC_SM_DIRECTION_MASK;
- }
-
- PlcSmFlags[axis] = flags;
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDeviceReadSd(uint16_t address, int32_t *value)
- {
- int32_t *source;
-
- if (value == NULL)
- {
- return PLC_DEVICE_NULL_POINTER;
- }
- source = PlcDeviceResolveSd(address, NULL, NULL);
- if (source == NULL)
- {
- return PLC_DEVICE_INVALID_ADDRESS;
- }
-
- *value = *source;
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDeviceWriteSd(uint16_t address, int32_t value)
- {
- (void)value;
- return (PlcDeviceResolveSd(address, NULL, NULL) != NULL)
- ? PLC_DEVICE_READ_ONLY
- : PLC_DEVICE_INVALID_ADDRESS;
- }
-
- PLC_DEVICE_RESULT PlcDevicePublishSd(uint8_t axis,
- uint8_t item,
- int32_t value)
- {
- if ((axis >= PLSR_AXIS_COUNT) || (item >= PLSR_SD_AXIS_ITEM_COUNT))
- {
- return PLC_DEVICE_INVALID_ARGUMENT;
- }
-
- PlcSdRuntime[axis][item] = value;
- return PLC_DEVICE_OK;
- }
-
- PLC_DEVICE_RESULT PlcDeviceGetEventAddress(uint8_t axis,
- uint16_t segmentNumber,
- uint16_t *eventAddress)
- {
- if (eventAddress == NULL)
- {
- return PLC_DEVICE_NULL_POINTER;
- }
- if ((axis >= PLSR_AXIS_COUNT) || (segmentNumber == 0U)
- || (segmentNumber > PLSR_EVENT_AXIS_ITEM_COUNT))
- {
- return PLC_DEVICE_INVALID_ARGUMENT;
- }
-
- *eventAddress = (uint16_t)(PlsrAxisAddressMap[axis].eventBase
- + segmentNumber - 1U);
- return PLC_DEVICE_OK;
- }
-
- uint8_t PlcDeviceIsHsdDirty(void)
- {
- return PlcHsdDirty;
- }
-
- uint8_t PlcDeviceIsSfdDirty(void)
- {
- return PlcSfdDirty;
- }
-
- PLSR_PERSISTENCE_RESULT PlcDeviceGetLastHsdLoadResult(void)
- {
- return PlcLastHsdLoadResult;
- }
-
- PLSR_PERSISTENCE_RESULT PlcDeviceGetLastSfdLoadResult(void)
- {
- return PlcLastSfdLoadResult;
- }
|