|
- #include "plsr_resource.h"
- #include "plsr_address_map.h"
- #include <string.h>
-
- #ifndef PLSR_HOST_TEST
- #include "stm32f4xx.h"
- #endif
-
- #define PLSR_HIGH_OUTPUT_MASK (0x0000000FUL)
- #define PLSR_VALID_OUTPUT_MASK (0x0013FCFFUL)
- #define PLSR_OUTPUT_POINT_COUNT (21U)
- #define PLSR_RESOURCE_OWNER_NONE (0xFFU)
-
- static uint32_t PlsrUsedOutputMask;
- static uint8_t PlsrUsedHighMask;
- static uint8_t PlsrOutputOwners[PLSR_OUTPUT_POINT_COUNT];
-
- static uint32_t PlsrResourceEnterCritical(void)
- {
- #ifdef PLSR_HOST_TEST
- return 0UL;
- #else
- uint32_t interruptState = __get_PRIMASK();
- __disable_irq();
- __DMB();
- return interruptState;
- #endif
- }
-
- static void PlsrResourceExitCritical(uint32_t interruptState)
- {
- #ifdef PLSR_HOST_TEST
- (void)interruptState;
- #else
- __DMB();
- if (interruptState == 0UL)
- {
- __enable_irq();
- }
- #endif
- }
-
- static uint8_t PlsrResourceOutputPointIsValid(uint8_t point)
- {
- if (point >= PLSR_OUTPUT_POINT_COUNT)
- {
- return 0U;
- }
- return ((PLSR_VALID_OUTPUT_MASK & (1UL << point)) != 0UL) ? 1U : 0U;
- }
-
- void PlsrResourceInit(void)
- {
- uint32_t interruptState = PlsrResourceEnterCritical();
-
- PlsrUsedOutputMask = 0UL;
- PlsrUsedHighMask = 0U;
- (void)memset(PlsrOutputOwners,
- PLSR_RESOURCE_OWNER_NONE,
- sizeof(PlsrOutputOwners));
- PlsrResourceExitCritical(interruptState);
- }
-
- PLSR_RESULT PlsrResourceReserve(const PLSR_RESOURCE_REQUEST *request,
- PLSR_RESOURCE_LEASE *lease)
- {
- uint32_t requestedOutputMask;
- uint32_t interruptState;
- uint8_t requestedHighMask;
- uint8_t point;
-
- if ((request == NULL) || (lease == NULL))
- {
- return PLSR_RESULT_INVALID_ARGUMENT;
- }
- if ((request->ownerAxis >= PLSR_AXIS_COUNT)
- || (request->dAxis >= PLSR_AXIS_COUNT)
- || (request->ownerAxis != request->dAxis))
- {
- return PLSR_RESULT_INVALID_AXIS;
- }
- if (lease->valid != 0U)
- {
- return PLSR_RESULT_BUSY;
- }
-
- if (request->outputMode == PLSR_OUTPUT_PULSE_DIR)
- {
- if ((PlsrResourceOutputPointIsValid(request->directionPoint) == 0U)
- || (request->directionPoint == request->dAxis))
- {
- return PLSR_RESULT_INVALID_RESOURCE;
- }
- requestedHighMask = (uint8_t)(1U << request->dAxis);
- requestedOutputMask = (uint32_t)requestedHighMask
- | (1UL << request->directionPoint);
- }
- else if ((request->outputMode == PLSR_OUTPUT_AB)
- || (request->outputMode == PLSR_OUTPUT_CW_CCW))
- {
- if ((request->dAxis != 0U) && (request->dAxis != 2U))
- {
- return PLSR_RESULT_INVALID_RESOURCE;
- }
- requestedHighMask = (uint8_t)(0x03U << request->dAxis);
- requestedOutputMask = (uint32_t)requestedHighMask;
- }
- else
- {
- return PLSR_RESULT_INVALID_RESOURCE;
- }
-
- interruptState = PlsrResourceEnterCritical();
- if ((PlsrUsedOutputMask & requestedOutputMask) != 0UL)
- {
- PlsrResourceExitCritical(interruptState);
- return PLSR_RESULT_RESOURCE_CONFLICT;
- }
-
- PlsrUsedOutputMask |= requestedOutputMask;
- PlsrUsedHighMask |= requestedHighMask;
- for (point = 0U; point < PLSR_OUTPUT_POINT_COUNT; point++)
- {
- if ((requestedOutputMask & (1UL << point)) != 0UL)
- {
- PlsrOutputOwners[point] = request->ownerAxis;
- }
- }
- PlsrResourceExitCritical(interruptState);
-
- lease->outputMask = requestedOutputMask;
- lease->highMask = requestedHighMask;
- lease->ownerAxis = request->ownerAxis;
- lease->directionPoint = (request->outputMode == PLSR_OUTPUT_PULSE_DIR)
- ? request->directionPoint
- : PLSR_DIRECTION_POINT_NONE;
- lease->outputMode = request->outputMode;
- lease->valid = 1U;
- return PLSR_RESULT_OK;
- }
-
- void PlsrResourceRelease(PLSR_RESOURCE_LEASE *lease)
- {
- uint32_t releaseMask = 0UL;
- uint32_t interruptState;
- uint8_t point;
-
- if ((lease == NULL) || (lease->valid == 0U))
- {
- return;
- }
-
- interruptState = PlsrResourceEnterCritical();
- for (point = 0U; point < PLSR_OUTPUT_POINT_COUNT; point++)
- {
- if (((lease->outputMask & (1UL << point)) != 0UL)
- && (PlsrOutputOwners[point] == lease->ownerAxis))
- {
- releaseMask |= (1UL << point);
- PlsrOutputOwners[point] = PLSR_RESOURCE_OWNER_NONE;
- }
- }
- PlsrUsedOutputMask &= ~releaseMask;
- PlsrUsedHighMask = (uint8_t)(PlsrUsedOutputMask & PLSR_HIGH_OUTPUT_MASK);
- PlsrResourceExitCritical(interruptState);
-
- (void)memset(lease, 0, sizeof(*lease));
- lease->directionPoint = PLSR_DIRECTION_POINT_NONE;
- }
-
- void PlsrResourceGetStatus(PLSR_RESOURCE_STATUS *status)
- {
- uint32_t interruptState;
-
- if (status == NULL)
- {
- return;
- }
-
- interruptState = PlsrResourceEnterCritical();
- status->outputMask = PlsrUsedOutputMask;
- status->highMask = PlsrUsedHighMask;
- PlsrResourceExitCritical(interruptState);
- }
-
- uint8_t PlsrResourceCheckInvariant(void)
- {
- uint32_t interruptState;
- uint8_t valid = 1U;
- uint8_t point;
-
- interruptState = PlsrResourceEnterCritical();
- if (PlsrUsedHighMask
- != (uint8_t)(PlsrUsedOutputMask & PLSR_HIGH_OUTPUT_MASK))
- {
- valid = 0U;
- }
-
- for (point = 0U; point < PLSR_OUTPUT_POINT_COUNT; point++)
- {
- if (((PlsrUsedOutputMask & (1UL << point)) == 0UL)
- != (PlsrOutputOwners[point] == PLSR_RESOURCE_OWNER_NONE))
- {
- valid = 0U;
- }
- }
- PlsrResourceExitCritical(interruptState);
- return valid;
- }
|