Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

680 linhas
18 KiB

  1. #include "plc_device.h"
  2. #include <string.h>
  3. #ifndef PLSR_HOST_TEST
  4. #include "stm32f4xx.h"
  5. #endif
  6. #define PLC_SM_PULSE_ACTIVE_MASK (0x01U)
  7. #define PLC_SM_DIRECTION_MASK (0x02U)
  8. const PLSR_AXIS_ADDRESS_MAP PlsrAxisAddressMap[PLSR_AXIS_COUNT] =
  9. {
  10. {0U, 1000U, 1001U, 1000U, 6000U},
  11. {4U, 1020U, 1021U, 1020U, 6100U},
  12. {8U, 1040U, 1041U, 1040U, 6200U},
  13. {12U, 1060U, 1061U, 1060U, 6300U}
  14. };
  15. static PLSR_HSD_DATA PlcHsdData;
  16. static PLSR_SFD_DATA PlcSfdData;
  17. static int32_t PlcSdRuntime[PLSR_AXIS_COUNT][PLSR_SD_AXIS_ITEM_COUNT];
  18. static uint8_t PlcSmFlags[PLSR_AXIS_COUNT];
  19. static uint8_t PlcHsdDirty;
  20. static uint8_t PlcSfdDirty;
  21. static uint8_t PlcSfdOperationActive;
  22. static uint32_t PlcHsdChangeCounter;
  23. static PLSR_PERSISTENCE_RESULT PlcLastHsdLoadResult;
  24. static PLSR_PERSISTENCE_RESULT PlcLastSfdLoadResult;
  25. static uint8_t PlcRestoredHsdPositionValid;
  26. static uint8_t PlcRestoredHsdLastBusy;
  27. static uint32_t PlcDeviceEnterCritical(void)
  28. {
  29. #ifdef PLSR_HOST_TEST
  30. return 0UL;
  31. #else
  32. uint32_t interruptState = __get_PRIMASK();
  33. __disable_irq();
  34. __DMB();
  35. return interruptState;
  36. #endif
  37. }
  38. static void PlcDeviceExitCritical(uint32_t interruptState)
  39. {
  40. #ifdef PLSR_HOST_TEST
  41. (void)interruptState;
  42. #else
  43. __DMB();
  44. if (interruptState == 0UL)
  45. {
  46. __enable_irq();
  47. }
  48. #endif
  49. }
  50. static uint8_t PlcDeviceBeginSfdOperation(void)
  51. {
  52. uint8_t axis;
  53. uint8_t busy;
  54. uint32_t interruptState;
  55. #ifndef PLSR_HOST_TEST
  56. if (__get_IPSR() != 0UL)
  57. {
  58. return 0U;
  59. }
  60. #endif
  61. interruptState = PlcDeviceEnterCritical();
  62. busy = PlcSfdOperationActive;
  63. for (axis = 0U; axis < PLSR_AXIS_COUNT; axis++)
  64. {
  65. if ((PlcSmFlags[axis] & PLC_SM_PULSE_ACTIVE_MASK) != 0U)
  66. {
  67. busy = 1U;
  68. }
  69. }
  70. if (busy == 0U)
  71. {
  72. PlcSfdOperationActive = 1U;
  73. }
  74. PlcDeviceExitCritical(interruptState);
  75. return (busy == 0U) ? 1U : 0U;
  76. }
  77. static void PlcDeviceEndSfdOperation(void)
  78. {
  79. uint32_t interruptState = PlcDeviceEnterCritical();
  80. PlcSfdOperationActive = 0U;
  81. PlcDeviceExitCritical(interruptState);
  82. }
  83. static uint16_t *PlcDeviceResolveHsd(uint16_t address)
  84. {
  85. if (address < PLSR_HSD_RUNTIME_START + PLSR_HSD_RUNTIME_COUNT)
  86. {
  87. return &PlcHsdData.runtime[address - PLSR_HSD_RUNTIME_START];
  88. }
  89. if ((address >= PLSR_HSD_CONFIG_START)
  90. && (address < PLSR_HSD_CONFIG_START + PLSR_HSD_CONFIG_COUNT))
  91. {
  92. return &PlcHsdData.config[address - PLSR_HSD_CONFIG_START];
  93. }
  94. return NULL;
  95. }
  96. static int32_t *PlcDeviceResolveSd(uint16_t address,
  97. uint8_t *axis,
  98. uint8_t *item)
  99. {
  100. uint8_t axisIndex;
  101. uint16_t base;
  102. for (axisIndex = 0U; axisIndex < PLSR_AXIS_COUNT; axisIndex++)
  103. {
  104. base = PlsrAxisAddressMap[axisIndex].sdRuntimeBase;
  105. if ((address >= base)
  106. && (address < base + PLSR_SD_AXIS_ITEM_COUNT))
  107. {
  108. if (axis != NULL)
  109. {
  110. *axis = axisIndex;
  111. }
  112. if (item != NULL)
  113. {
  114. *item = (uint8_t)(address - base);
  115. }
  116. return &PlcSdRuntime[axisIndex][address - base];
  117. }
  118. }
  119. return NULL;
  120. }
  121. static PLC_DEVICE_RESULT PlcDeviceResolveSm(uint16_t address,
  122. uint8_t *axis,
  123. uint8_t *mask)
  124. {
  125. uint8_t axisIndex;
  126. if ((axis == NULL) || (mask == NULL))
  127. {
  128. return PLC_DEVICE_NULL_POINTER;
  129. }
  130. for (axisIndex = 0U; axisIndex < PLSR_AXIS_COUNT; axisIndex++)
  131. {
  132. if (address == PlsrAxisAddressMap[axisIndex].smPulseActiveAddress)
  133. {
  134. *axis = axisIndex;
  135. *mask = PLC_SM_PULSE_ACTIVE_MASK;
  136. return PLC_DEVICE_OK;
  137. }
  138. if (address == PlsrAxisAddressMap[axisIndex].smDirectionAddress)
  139. {
  140. *axis = axisIndex;
  141. *mask = PLC_SM_DIRECTION_MASK;
  142. return PLC_DEVICE_OK;
  143. }
  144. }
  145. return PLC_DEVICE_INVALID_ADDRESS;
  146. }
  147. PLC_DEVICE_RESULT PlcDeviceInit(void)
  148. {
  149. (void)memset(&PlcHsdData, 0, sizeof(PlcHsdData));
  150. (void)memset(&PlcSfdData, 0, sizeof(PlcSfdData));
  151. (void)memset(PlcSdRuntime, 0, sizeof(PlcSdRuntime));
  152. (void)memset(PlcSmFlags, 0, sizeof(PlcSmFlags));
  153. PlcSfdOperationActive = 0U;
  154. PlcHsdChangeCounter = 0UL;
  155. PlcRestoredHsdPositionValid = 0U;
  156. PlcRestoredHsdLastBusy = 0U;
  157. PlcLastHsdLoadResult = PlsrPersistenceLoadHsd(&PlcHsdData);
  158. PlcHsdDirty = (PlcLastHsdLoadResult == PLSR_PERSISTENCE_DEFAULTED)
  159. ? 1U
  160. : 0U;
  161. if ((PlcLastHsdLoadResult != PLSR_PERSISTENCE_OK)
  162. && (PlcLastHsdLoadResult != PLSR_PERSISTENCE_DEFAULTED))
  163. {
  164. return PLC_DEVICE_PERSISTENCE_ERROR;
  165. }
  166. PlcRestoredHsdPositionValid =
  167. ((PlcHsdData.metadata & PLSR_HSD_META_POSITION_VALID) != 0UL)
  168. ? 1U
  169. : 0U;
  170. PlcRestoredHsdLastBusy =
  171. ((PlcHsdData.metadata & PLSR_HSD_META_LAST_BUSY) != 0UL) ? 1U : 0U;
  172. PlcLastSfdLoadResult = PlsrPersistenceLoadSfd(&PlcSfdData);
  173. PlcSfdDirty = (PlcLastSfdLoadResult == PLSR_PERSISTENCE_OK) ? 0U : 1U;
  174. if ((PlcLastSfdLoadResult != PLSR_PERSISTENCE_OK)
  175. && (PlcLastSfdLoadResult != PLSR_PERSISTENCE_DEFAULTED))
  176. {
  177. return PLC_DEVICE_PERSISTENCE_ERROR;
  178. }
  179. return PLC_DEVICE_OK;
  180. }
  181. PLC_DEVICE_RESULT PlcDeviceReadHsd(uint16_t address, uint16_t *value)
  182. {
  183. uint16_t *source;
  184. if (value == NULL)
  185. {
  186. return PLC_DEVICE_NULL_POINTER;
  187. }
  188. source = PlcDeviceResolveHsd(address);
  189. if (source == NULL)
  190. {
  191. return PLC_DEVICE_INVALID_ADDRESS;
  192. }
  193. *value = *source;
  194. return PLC_DEVICE_OK;
  195. }
  196. PLC_DEVICE_RESULT PlcDeviceWriteHsdConfig(uint16_t address, uint16_t value)
  197. {
  198. if ((address < PLSR_HSD_CONFIG_START)
  199. || (address >= PLSR_HSD_CONFIG_START + PLSR_HSD_CONFIG_COUNT))
  200. {
  201. return (address < PLSR_HSD_RUNTIME_START
  202. + PLSR_HSD_RUNTIME_COUNT)
  203. ? PLC_DEVICE_READ_ONLY
  204. : PLC_DEVICE_INVALID_ADDRESS;
  205. }
  206. PlcHsdData.config[address - PLSR_HSD_CONFIG_START] = value;
  207. PlcHsdChangeCounter++;
  208. PlcHsdDirty = 1U;
  209. return PLC_DEVICE_OK;
  210. }
  211. PLC_DEVICE_RESULT PlcDevicePublishHsdRuntime(uint16_t address, uint16_t value)
  212. {
  213. if (address >= PLSR_HSD_RUNTIME_START + PLSR_HSD_RUNTIME_COUNT)
  214. {
  215. return PLC_DEVICE_INVALID_ADDRESS;
  216. }
  217. PlcHsdData.runtime[address - PLSR_HSD_RUNTIME_START] = value;
  218. PlcHsdChangeCounter++;
  219. PlcHsdDirty = 1U;
  220. return PLC_DEVICE_OK;
  221. }
  222. /* 两个相邻 WORD 组成一个 32 位值:低地址=低16位,高地址=高16位(信捷兼容布局)。 */
  223. PLC_DEVICE_RESULT PlcDeviceReadHsdDword(uint16_t lowAddress, int32_t *value)
  224. {
  225. uint32_t combined;
  226. uint32_t interruptState;
  227. uint16_t offset;
  228. if (value == NULL)
  229. {
  230. return PLC_DEVICE_NULL_POINTER;
  231. }
  232. if ((lowAddress >= PLSR_HSD_RUNTIME_COUNT)
  233. || ((lowAddress & 1U) != 0U)
  234. || ((uint16_t)(lowAddress + 1U) >= PLSR_HSD_RUNTIME_COUNT))
  235. {
  236. return PLC_DEVICE_INVALID_ADDRESS;
  237. }
  238. offset = (uint16_t)(lowAddress - PLSR_HSD_RUNTIME_START);
  239. interruptState = PlcDeviceEnterCritical();
  240. combined = (uint32_t)PlcHsdData.runtime[offset];
  241. combined |= ((uint32_t)PlcHsdData.runtime[offset + 1U]) << 16U;
  242. PlcDeviceExitCritical(interruptState);
  243. *value = (int32_t)combined;
  244. return PLC_DEVICE_OK;
  245. }
  246. PLC_DEVICE_RESULT PlcDevicePublishHsdDword(uint16_t lowAddress, int32_t value)
  247. {
  248. uint32_t rawValue;
  249. uint32_t interruptState;
  250. uint16_t offset;
  251. if ((lowAddress >= PLSR_HSD_RUNTIME_COUNT)
  252. || ((lowAddress & 1U) != 0U)
  253. || ((uint16_t)(lowAddress + 1U) >= PLSR_HSD_RUNTIME_COUNT))
  254. {
  255. return PLC_DEVICE_INVALID_ADDRESS;
  256. }
  257. rawValue = (uint32_t)value;
  258. offset = (uint16_t)(lowAddress - PLSR_HSD_RUNTIME_START);
  259. interruptState = PlcDeviceEnterCritical();
  260. PlcHsdData.runtime[offset] = (uint16_t)(rawValue & 0xFFFFUL);
  261. PlcHsdData.runtime[offset + 1U] = (uint16_t)(rawValue >> 16U);
  262. PlcHsdChangeCounter++;
  263. PlcHsdDirty = 1U;
  264. PlcDeviceExitCritical(interruptState);
  265. return PLC_DEVICE_OK;
  266. }
  267. PLC_DEVICE_RESULT PlcDeviceSetHsdCheckpointMeta(uint8_t positionValid,
  268. uint8_t lastBusy)
  269. {
  270. uint32_t interruptState = PlcDeviceEnterCritical();
  271. PlcHsdData.metadata &= ~(PLSR_HSD_META_POSITION_VALID
  272. | PLSR_HSD_META_LAST_BUSY);
  273. if (positionValid != 0U)
  274. {
  275. PlcHsdData.metadata |= PLSR_HSD_META_POSITION_VALID;
  276. }
  277. if (lastBusy != 0U)
  278. {
  279. PlcHsdData.metadata |= PLSR_HSD_META_LAST_BUSY;
  280. }
  281. PlcHsdChangeCounter++;
  282. PlcHsdDirty = 1U;
  283. PlcDeviceExitCritical(interruptState);
  284. return PLC_DEVICE_OK;
  285. }
  286. uint8_t PlcDeviceGetRestoredHsdPositionValid(void)
  287. {
  288. return PlcRestoredHsdPositionValid;
  289. }
  290. uint8_t PlcDeviceGetRestoredHsdLastBusy(void)
  291. {
  292. return PlcRestoredHsdLastBusy;
  293. }
  294. PLC_DEVICE_RESULT PlcDeviceCheckpointHsd(void)
  295. {
  296. PLSR_HSD_DATA snapshot;
  297. PLSR_PERSISTENCE_RESULT result;
  298. uint32_t snapshotCounter;
  299. uint32_t interruptState;
  300. if (PlcHsdDirty == 0U)
  301. {
  302. return PLC_DEVICE_OK;
  303. }
  304. interruptState = PlcDeviceEnterCritical();
  305. snapshot = PlcHsdData;
  306. snapshotCounter = PlcHsdChangeCounter;
  307. PlcDeviceExitCritical(interruptState);
  308. result = PlsrPersistenceSaveHsd(&snapshot);
  309. if (result != PLSR_PERSISTENCE_OK)
  310. {
  311. return PLC_DEVICE_PERSISTENCE_ERROR;
  312. }
  313. interruptState = PlcDeviceEnterCritical();
  314. if (PlcHsdChangeCounter == snapshotCounter)
  315. {
  316. PlcHsdDirty = 0U;
  317. }
  318. PlcDeviceExitCritical(interruptState);
  319. return PLC_DEVICE_OK;
  320. }
  321. PLC_DEVICE_RESULT PlcDeviceReadSfd(uint16_t address, uint16_t *value)
  322. {
  323. uint32_t interruptState;
  324. if (value == NULL)
  325. {
  326. return PLC_DEVICE_NULL_POINTER;
  327. }
  328. if ((address < PLSR_SFD_CONFIG_START)
  329. || (address >= PLSR_SFD_CONFIG_START + PLSR_SFD_CONFIG_COUNT))
  330. {
  331. return PLC_DEVICE_INVALID_ADDRESS;
  332. }
  333. interruptState = PlcDeviceEnterCritical();
  334. if (PlcSfdOperationActive != 0U)
  335. {
  336. PlcDeviceExitCritical(interruptState);
  337. return PLC_DEVICE_BUSY;
  338. }
  339. *value = PlcSfdData.config[address - PLSR_SFD_CONFIG_START];
  340. PlcDeviceExitCritical(interruptState);
  341. return PLC_DEVICE_OK;
  342. }
  343. PLC_DEVICE_RESULT PlcDeviceWriteSfd(uint16_t address, uint16_t value)
  344. {
  345. uint32_t interruptState;
  346. if ((address < PLSR_SFD_CONFIG_START)
  347. || (address >= PLSR_SFD_CONFIG_START + PLSR_SFD_CONFIG_COUNT))
  348. {
  349. return PLC_DEVICE_INVALID_ADDRESS;
  350. }
  351. interruptState = PlcDeviceEnterCritical();
  352. if (PlcSfdOperationActive != 0U)
  353. {
  354. PlcDeviceExitCritical(interruptState);
  355. return PLC_DEVICE_BUSY;
  356. }
  357. PlcSfdData.config[address - PLSR_SFD_CONFIG_START] = value;
  358. PlcSfdDirty = 1U;
  359. PlcDeviceExitCritical(interruptState);
  360. return PLC_DEVICE_OK;
  361. }
  362. PLC_DEVICE_RESULT PlcDeviceLoadSfd(void)
  363. {
  364. if (PlcDeviceBeginSfdOperation() == 0U)
  365. {
  366. return PLC_DEVICE_BUSY;
  367. }
  368. PlcLastSfdLoadResult = PlsrPersistenceLoadSfd(&PlcSfdData);
  369. if ((PlcLastSfdLoadResult != PLSR_PERSISTENCE_OK)
  370. && (PlcLastSfdLoadResult != PLSR_PERSISTENCE_DEFAULTED))
  371. {
  372. PlcDeviceEndSfdOperation();
  373. return PLC_DEVICE_PERSISTENCE_ERROR;
  374. }
  375. PlcSfdDirty = (PlcLastSfdLoadResult == PLSR_PERSISTENCE_OK) ? 0U : 1U;
  376. PlcDeviceEndSfdOperation();
  377. return PLC_DEVICE_OK;
  378. }
  379. PLC_DEVICE_RESULT PlcDeviceSaveSfd(void)
  380. {
  381. PLSR_PERSISTENCE_RESULT result;
  382. if (PlcDeviceBeginSfdOperation() == 0U)
  383. {
  384. return PLC_DEVICE_BUSY;
  385. }
  386. if (PlcSfdDirty == 0U)
  387. {
  388. PlcDeviceEndSfdOperation();
  389. return PLC_DEVICE_OK;
  390. }
  391. result = PlsrPersistenceSaveSfd(&PlcSfdData);
  392. if (result != PLSR_PERSISTENCE_OK)
  393. {
  394. PlcDeviceEndSfdOperation();
  395. return PLC_DEVICE_PERSISTENCE_ERROR;
  396. }
  397. PlcSfdDirty = 0U;
  398. PlcDeviceEndSfdOperation();
  399. return PLC_DEVICE_OK;
  400. }
  401. PLC_DEVICE_RESULT PlcDeviceResetSfdDefaults(void)
  402. {
  403. PLSR_PERSISTENCE_RESULT result;
  404. if (PlcDeviceBeginSfdOperation() == 0U)
  405. {
  406. return PLC_DEVICE_BUSY;
  407. }
  408. result = PlsrPersistenceEraseSfd();
  409. if (result != PLSR_PERSISTENCE_OK)
  410. {
  411. PlcDeviceEndSfdOperation();
  412. return PLC_DEVICE_PERSISTENCE_ERROR;
  413. }
  414. PlcLastSfdLoadResult = PlsrPersistenceLoadSfd(&PlcSfdData);
  415. if (PlcLastSfdLoadResult != PLSR_PERSISTENCE_DEFAULTED)
  416. {
  417. PlcDeviceEndSfdOperation();
  418. return PLC_DEVICE_PERSISTENCE_ERROR;
  419. }
  420. PlcSfdDirty = 1U;
  421. PlcDeviceEndSfdOperation();
  422. return PLC_DEVICE_OK;
  423. }
  424. PLC_DEVICE_RESULT PlcDeviceReadSm(uint16_t address, uint8_t *state)
  425. {
  426. uint8_t axis;
  427. uint8_t mask;
  428. PLC_DEVICE_RESULT result;
  429. if (state == NULL)
  430. {
  431. return PLC_DEVICE_NULL_POINTER;
  432. }
  433. result = PlcDeviceResolveSm(address, &axis, &mask);
  434. if (result != PLC_DEVICE_OK)
  435. {
  436. return result;
  437. }
  438. *state = ((PlcSmFlags[axis] & mask) != 0U) ? 1U : 0U;
  439. return PLC_DEVICE_OK;
  440. }
  441. PLC_DEVICE_RESULT PlcDeviceWriteSm(uint16_t address, uint8_t state)
  442. {
  443. uint8_t axis;
  444. uint8_t mask;
  445. PLC_DEVICE_RESULT result;
  446. (void)state;
  447. result = PlcDeviceResolveSm(address, &axis, &mask);
  448. return (result == PLC_DEVICE_OK) ? PLC_DEVICE_READ_ONLY : result;
  449. }
  450. PLC_DEVICE_RESULT PlcDevicePublishSm(uint8_t axis,
  451. uint8_t pulseActive,
  452. uint8_t direction)
  453. {
  454. uint8_t flags = 0U;
  455. uint32_t interruptState;
  456. if (axis >= PLSR_AXIS_COUNT)
  457. {
  458. return PLC_DEVICE_INVALID_ARGUMENT;
  459. }
  460. if (pulseActive != 0U)
  461. {
  462. flags |= PLC_SM_PULSE_ACTIVE_MASK;
  463. }
  464. if (direction != 0U)
  465. {
  466. flags |= PLC_SM_DIRECTION_MASK;
  467. }
  468. interruptState = PlcDeviceEnterCritical();
  469. if ((pulseActive != 0U) && (PlcSfdOperationActive != 0U))
  470. {
  471. PlcDeviceExitCritical(interruptState);
  472. return PLC_DEVICE_BUSY;
  473. }
  474. PlcSmFlags[axis] = flags;
  475. PlcDeviceExitCritical(interruptState);
  476. return PLC_DEVICE_OK;
  477. }
  478. PLC_DEVICE_RESULT PlcDeviceReadSd(uint16_t address, int32_t *value)
  479. {
  480. int32_t *source;
  481. uint32_t interruptState;
  482. if (value == NULL)
  483. {
  484. return PLC_DEVICE_NULL_POINTER;
  485. }
  486. source = PlcDeviceResolveSd(address, NULL, NULL);
  487. if (source == NULL)
  488. {
  489. return PLC_DEVICE_INVALID_ADDRESS;
  490. }
  491. interruptState = PlcDeviceEnterCritical();
  492. *value = *source;
  493. PlcDeviceExitCritical(interruptState);
  494. return PLC_DEVICE_OK;
  495. }
  496. PLC_DEVICE_RESULT PlcDeviceWriteSd(uint16_t address, int32_t value)
  497. {
  498. (void)value;
  499. return (PlcDeviceResolveSd(address, NULL, NULL) != NULL)
  500. ? PLC_DEVICE_READ_ONLY
  501. : PLC_DEVICE_INVALID_ADDRESS;
  502. }
  503. PLC_DEVICE_RESULT PlcDevicePublishSd(uint8_t axis,
  504. uint8_t item,
  505. int32_t value)
  506. {
  507. uint32_t interruptState;
  508. if ((axis >= PLSR_AXIS_COUNT) || (item >= PLSR_SD_AXIS_ITEM_COUNT))
  509. {
  510. return PLC_DEVICE_INVALID_ARGUMENT;
  511. }
  512. interruptState = PlcDeviceEnterCritical();
  513. PlcSdRuntime[axis][item] = value;
  514. PlcDeviceExitCritical(interruptState);
  515. return PLC_DEVICE_OK;
  516. }
  517. PLC_DEVICE_RESULT PlcDeviceReadSdDword(uint16_t lowAddress, int32_t *value)
  518. {
  519. int32_t *source;
  520. uint32_t rawValue;
  521. uint32_t interruptState;
  522. uint8_t axis;
  523. uint8_t item;
  524. if (value == NULL)
  525. {
  526. return PLC_DEVICE_NULL_POINTER;
  527. }
  528. source = PlcDeviceResolveSd(lowAddress, &axis, &item);
  529. if ((source == NULL) || ((item & 1U) != 0U)
  530. || (item > PLSR_SD_ITEM_SPEED))
  531. {
  532. return PLC_DEVICE_INVALID_ADDRESS;
  533. }
  534. interruptState = PlcDeviceEnterCritical();
  535. rawValue = (uint32_t)PlcSdRuntime[axis][item] & 0xFFFFUL;
  536. rawValue |= ((uint32_t)PlcSdRuntime[axis][item + 1U] & 0xFFFFUL)
  537. << 16U;
  538. PlcDeviceExitCritical(interruptState);
  539. *value = (int32_t)rawValue;
  540. return PLC_DEVICE_OK;
  541. }
  542. PLC_DEVICE_RESULT PlcDevicePublishSdDword(uint8_t axis,
  543. uint8_t lowItem,
  544. int32_t value)
  545. {
  546. uint32_t rawValue;
  547. uint32_t interruptState;
  548. if ((axis >= PLSR_AXIS_COUNT) || ((lowItem & 1U) != 0U)
  549. || (lowItem > PLSR_SD_ITEM_SPEED))
  550. {
  551. return PLC_DEVICE_INVALID_ARGUMENT;
  552. }
  553. rawValue = (uint32_t)value;
  554. interruptState = PlcDeviceEnterCritical();
  555. PlcSdRuntime[axis][lowItem] = (int32_t)(rawValue & 0xFFFFUL);
  556. PlcSdRuntime[axis][lowItem + 1U] = (int32_t)(rawValue >> 16U);
  557. PlcDeviceExitCritical(interruptState);
  558. return PLC_DEVICE_OK;
  559. }
  560. PLC_DEVICE_RESULT PlcDeviceGetEventAddress(uint8_t axis,
  561. uint16_t segmentNumber,
  562. uint16_t *eventAddress)
  563. {
  564. if (eventAddress == NULL)
  565. {
  566. return PLC_DEVICE_NULL_POINTER;
  567. }
  568. if ((axis >= PLSR_AXIS_COUNT) || (segmentNumber == 0U)
  569. || (segmentNumber > PLSR_EVENT_AXIS_ITEM_COUNT))
  570. {
  571. return PLC_DEVICE_INVALID_ARGUMENT;
  572. }
  573. *eventAddress = (uint16_t)(PlsrAxisAddressMap[axis].eventBase
  574. + segmentNumber - 1U);
  575. return PLC_DEVICE_OK;
  576. }
  577. uint8_t PlcDeviceIsHsdDirty(void)
  578. {
  579. return PlcHsdDirty;
  580. }
  581. uint8_t PlcDeviceIsSfdDirty(void)
  582. {
  583. return PlcSfdDirty;
  584. }
  585. PLSR_PERSISTENCE_RESULT PlcDeviceGetLastHsdLoadResult(void)
  586. {
  587. return PlcLastHsdLoadResult;
  588. }
  589. PLSR_PERSISTENCE_RESULT PlcDeviceGetLastSfdLoadResult(void)
  590. {
  591. return PlcLastSfdLoadResult;
  592. }