Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

210 wiersze
5.6 KiB

  1. #include "plsr_resource.h"
  2. #include "plsr_address_map.h"
  3. #include <string.h>
  4. #ifndef PLSR_HOST_TEST
  5. #include "stm32f4xx.h"
  6. #endif
  7. #define PLSR_HIGH_OUTPUT_MASK (0x0000000FUL)
  8. #define PLSR_VALID_OUTPUT_MASK (0x0013FCFFUL)
  9. #define PLSR_OUTPUT_POINT_COUNT (21U)
  10. #define PLSR_RESOURCE_OWNER_NONE (0xFFU)
  11. static uint32_t PlsrUsedOutputMask;
  12. static uint8_t PlsrUsedHighMask;
  13. static uint8_t PlsrOutputOwners[PLSR_OUTPUT_POINT_COUNT];
  14. static uint32_t PlsrResourceEnterCritical(void)
  15. {
  16. #ifdef PLSR_HOST_TEST
  17. return 0UL;
  18. #else
  19. uint32_t interruptState = __get_PRIMASK();
  20. __disable_irq();
  21. __DMB();
  22. return interruptState;
  23. #endif
  24. }
  25. static void PlsrResourceExitCritical(uint32_t interruptState)
  26. {
  27. #ifdef PLSR_HOST_TEST
  28. (void)interruptState;
  29. #else
  30. __DMB();
  31. if (interruptState == 0UL)
  32. {
  33. __enable_irq();
  34. }
  35. #endif
  36. }
  37. static uint8_t PlsrResourceOutputPointIsValid(uint8_t point)
  38. {
  39. if (point >= PLSR_OUTPUT_POINT_COUNT)
  40. {
  41. return 0U;
  42. }
  43. return ((PLSR_VALID_OUTPUT_MASK & (1UL << point)) != 0UL) ? 1U : 0U;
  44. }
  45. void PlsrResourceInit(void)
  46. {
  47. uint32_t interruptState = PlsrResourceEnterCritical();
  48. PlsrUsedOutputMask = 0UL;
  49. PlsrUsedHighMask = 0U;
  50. (void)memset(PlsrOutputOwners,
  51. PLSR_RESOURCE_OWNER_NONE,
  52. sizeof(PlsrOutputOwners));
  53. PlsrResourceExitCritical(interruptState);
  54. }
  55. PLSR_RESULT PlsrResourceReserve(const PLSR_RESOURCE_REQUEST *request,
  56. PLSR_RESOURCE_LEASE *lease)
  57. {
  58. uint32_t requestedOutputMask;
  59. uint32_t interruptState;
  60. uint8_t requestedHighMask;
  61. uint8_t point;
  62. if ((request == NULL) || (lease == NULL))
  63. {
  64. return PLSR_RESULT_INVALID_ARGUMENT;
  65. }
  66. if ((request->ownerAxis >= PLSR_AXIS_COUNT)
  67. || (request->dAxis >= PLSR_AXIS_COUNT)
  68. || (request->ownerAxis != request->dAxis))
  69. {
  70. return PLSR_RESULT_INVALID_AXIS;
  71. }
  72. if (lease->valid != 0U)
  73. {
  74. return PLSR_RESULT_BUSY;
  75. }
  76. if (request->outputMode == PLSR_OUTPUT_PULSE_DIR)
  77. {
  78. if ((PlsrResourceOutputPointIsValid(request->directionPoint) == 0U)
  79. || (request->directionPoint == request->dAxis))
  80. {
  81. return PLSR_RESULT_INVALID_RESOURCE;
  82. }
  83. requestedHighMask = (uint8_t)(1U << request->dAxis);
  84. requestedOutputMask = (uint32_t)requestedHighMask
  85. | (1UL << request->directionPoint);
  86. }
  87. else if ((request->outputMode == PLSR_OUTPUT_AB)
  88. || (request->outputMode == PLSR_OUTPUT_CW_CCW))
  89. {
  90. if ((request->dAxis != 0U) && (request->dAxis != 2U))
  91. {
  92. return PLSR_RESULT_INVALID_RESOURCE;
  93. }
  94. requestedHighMask = (uint8_t)(0x03U << request->dAxis);
  95. requestedOutputMask = (uint32_t)requestedHighMask;
  96. }
  97. else
  98. {
  99. return PLSR_RESULT_INVALID_RESOURCE;
  100. }
  101. interruptState = PlsrResourceEnterCritical();
  102. if ((PlsrUsedOutputMask & requestedOutputMask) != 0UL)
  103. {
  104. PlsrResourceExitCritical(interruptState);
  105. return PLSR_RESULT_RESOURCE_CONFLICT;
  106. }
  107. PlsrUsedOutputMask |= requestedOutputMask;
  108. PlsrUsedHighMask |= requestedHighMask;
  109. for (point = 0U; point < PLSR_OUTPUT_POINT_COUNT; point++)
  110. {
  111. if ((requestedOutputMask & (1UL << point)) != 0UL)
  112. {
  113. PlsrOutputOwners[point] = request->ownerAxis;
  114. }
  115. }
  116. PlsrResourceExitCritical(interruptState);
  117. lease->outputMask = requestedOutputMask;
  118. lease->highMask = requestedHighMask;
  119. lease->ownerAxis = request->ownerAxis;
  120. lease->directionPoint = (request->outputMode == PLSR_OUTPUT_PULSE_DIR)
  121. ? request->directionPoint
  122. : PLSR_DIRECTION_POINT_NONE;
  123. lease->outputMode = request->outputMode;
  124. lease->valid = 1U;
  125. return PLSR_RESULT_OK;
  126. }
  127. void PlsrResourceRelease(PLSR_RESOURCE_LEASE *lease)
  128. {
  129. uint32_t releaseMask = 0UL;
  130. uint32_t interruptState;
  131. uint8_t point;
  132. if ((lease == NULL) || (lease->valid == 0U))
  133. {
  134. return;
  135. }
  136. interruptState = PlsrResourceEnterCritical();
  137. for (point = 0U; point < PLSR_OUTPUT_POINT_COUNT; point++)
  138. {
  139. if (((lease->outputMask & (1UL << point)) != 0UL)
  140. && (PlsrOutputOwners[point] == lease->ownerAxis))
  141. {
  142. releaseMask |= (1UL << point);
  143. PlsrOutputOwners[point] = PLSR_RESOURCE_OWNER_NONE;
  144. }
  145. }
  146. PlsrUsedOutputMask &= ~releaseMask;
  147. PlsrUsedHighMask = (uint8_t)(PlsrUsedOutputMask & PLSR_HIGH_OUTPUT_MASK);
  148. PlsrResourceExitCritical(interruptState);
  149. (void)memset(lease, 0, sizeof(*lease));
  150. lease->directionPoint = PLSR_DIRECTION_POINT_NONE;
  151. }
  152. void PlsrResourceGetStatus(PLSR_RESOURCE_STATUS *status)
  153. {
  154. uint32_t interruptState;
  155. if (status == NULL)
  156. {
  157. return;
  158. }
  159. interruptState = PlsrResourceEnterCritical();
  160. status->outputMask = PlsrUsedOutputMask;
  161. status->highMask = PlsrUsedHighMask;
  162. PlsrResourceExitCritical(interruptState);
  163. }
  164. uint8_t PlsrResourceCheckInvariant(void)
  165. {
  166. uint32_t interruptState;
  167. uint8_t valid = 1U;
  168. uint8_t point;
  169. interruptState = PlsrResourceEnterCritical();
  170. if (PlsrUsedHighMask
  171. != (uint8_t)(PlsrUsedOutputMask & PLSR_HIGH_OUTPUT_MASK))
  172. {
  173. valid = 0U;
  174. }
  175. for (point = 0U; point < PLSR_OUTPUT_POINT_COUNT; point++)
  176. {
  177. if (((PlsrUsedOutputMask & (1UL << point)) == 0UL)
  178. != (PlsrOutputOwners[point] == PLSR_RESOURCE_OWNER_NONE))
  179. {
  180. valid = 0U;
  181. }
  182. }
  183. PlsrResourceExitCritical(interruptState);
  184. return valid;
  185. }