Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 
 

344 rader
12 KiB

  1. #include "plsr_self_test.h"
  2. #include "plc_device.h"
  3. #include "plsr_core.h"
  4. #include "plsr_job.h"
  5. #include <string.h>
  6. /* 上电自测(验证后可删除):
  7. * - AB 模式使用 Q0(A)/Q1(B),其余用出厂默认参数(K1)
  8. * - 任务:3 段完整 AB 周期(H00 完成,顺序衔接):
  9. * 段1:2000Hz / +1000 周期(A 超前 B)
  10. * 段2:5000Hz / +6000 周期(A 超前 B)
  11. * 段3:1000Hz / -500 周期(B 超前 A,验证反向)
  12. * 数据源为静态数组,仅自测使用(正式 D 设备适配器见 Modbus 阶段)。 */
  13. #define SELF_TEST_WORD_CAPACITY (192U)
  14. #define SELF_TEST_S0_BASE (10U)
  15. #define SELF_TEST_S1_BASE (60U)
  16. #define SELF_TEST_DIR_POINT (4U)
  17. #define SELF_TEST_SFD_AXIS_STRIDE (130U)
  18. #define SELF_TEST_SFD_SET_OFFSET (50U)
  19. static uint16_t SelfTestWords[3][SELF_TEST_WORD_CAPACITY];
  20. static uint8_t SelfTestValidateWords(void *context,
  21. PLSR_DEVICE_TYPE device,
  22. uint32_t firstAddress,
  23. uint32_t wordCount)
  24. {
  25. (void)context;
  26. if ((device > PLSR_DEVICE_FD) || (wordCount == 0UL))
  27. {
  28. return 0U;
  29. }
  30. return (((uint64_t)firstAddress + wordCount)
  31. <= SELF_TEST_WORD_CAPACITY)
  32. ? 1U
  33. : 0U;
  34. }
  35. static uint8_t SelfTestReadWord(void *context,
  36. PLSR_DEVICE_TYPE device,
  37. uint32_t address,
  38. uint16_t *value)
  39. {
  40. (void)context;
  41. if ((device > PLSR_DEVICE_FD) || (value == NULL)
  42. || (address >= SELF_TEST_WORD_CAPACITY))
  43. {
  44. return 0U;
  45. }
  46. *value = SelfTestWords[device][address];
  47. return 1U;
  48. }
  49. static uint8_t SelfTestReadBit(void *context,
  50. PLSR_DEVICE_TYPE device,
  51. uint32_t address,
  52. uint8_t *value)
  53. {
  54. (void)context;
  55. (void)device;
  56. (void)address;
  57. *value = 0U;
  58. return 1U;
  59. }
  60. static void SelfTestWriteDword(PLSR_DEVICE_TYPE device,
  61. uint32_t address,
  62. uint32_t value)
  63. {
  64. SelfTestWords[device][address] = (uint16_t)(value & 0xFFFFUL);
  65. SelfTestWords[device][address + 1UL] = (uint16_t)(value >> 16U);
  66. }
  67. static void SelfTestWriteSfdDword(uint16_t address, uint32_t value)
  68. {
  69. (void)PlcDeviceWriteSfd(address, (uint16_t)(value & 0xFFFFUL));
  70. (void)PlcDeviceWriteSfd((uint16_t)(address + 1U),
  71. (uint16_t)(value >> 16U));
  72. }
  73. PLSR_RESULT PlsrSelfTestQueue(void)
  74. {
  75. PLSR_CALL call;
  76. (void)memset(SelfTestWords, 0, sizeof(SelfTestWords));
  77. /* 方向端子 Y4(PULSE/DIR 模式必需,接线参数)。 */
  78. (void)PlcDeviceWriteSfd(906U, SELF_TEST_DIR_POINT);
  79. (void)PlcDeviceWriteSfd(912U, 0U);
  80. (void)PlcDeviceWriteSfd(915U, 0xFFFFU);
  81. /* S0:3 段,H00 完成,顺序跳转。 */
  82. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE, 3U);
  83. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 10U, 2000UL);
  84. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 12U, 1000UL);
  85. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 20U, 5000UL);
  86. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 22U, 6000UL);
  87. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 30U, 1000UL);
  88. SelfTestWriteDword(PLSR_DEVICE_D,
  89. SELF_TEST_S0_BASE + 32U,
  90. (uint32_t)(int32_t)-500);
  91. /* S1:相对模式,起始段 0(=段1)。 */
  92. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S1_BASE, 0U);
  93. (void)memset(&call, 0, sizeof(call));
  94. call.sequence = 0xA5A5UL;
  95. call.source.context = NULL;
  96. call.source.validateWords = SelfTestValidateWords;
  97. call.source.readWord = SelfTestReadWord;
  98. call.source.readBit = SelfTestReadBit;
  99. call.s0.device = PLSR_DEVICE_D;
  100. call.s0.address = SELF_TEST_S0_BASE;
  101. call.s1.device = PLSR_DEVICE_D;
  102. call.s1.address = SELF_TEST_S1_BASE;
  103. call.s2.type = PLSR_OPERAND_CONSTANT;
  104. call.s2.constant = 1;
  105. call.dAxis = 0U;
  106. call.outputModeOverride = PLSR_OUTPUT_AB;
  107. return PlsrPostCall(&call);
  108. }
  109. PLSR_RESULT PlsrEquivalentSelfTestQueue(void)
  110. {
  111. PLSR_CALL call;
  112. (void)memset(SelfTestWords, 0, sizeof(SelfTestWords));
  113. /* SFD900 Bit10~8=001(1um当量);3脉冲/2单位。 */
  114. (void)PlcDeviceWriteSfd(900U, (1U << 8U));
  115. SelfTestWriteSfdDword(902U, 3UL);
  116. SelfTestWriteSfdDword(904U, 2UL);
  117. (void)PlcDeviceWriteSfd(906U, SELF_TEST_DIR_POINT);
  118. (void)PlcDeviceWriteSfd(907U, 10U);
  119. (void)PlcDeviceWriteSfd(912U, 0U);
  120. (void)PlcDeviceWriteSfd(915U, 0xFFFFU);
  121. /* 当量换算后物理最高速度=90000Hz,不超过硬件100kHz。 */
  122. SelfTestWriteSfdDword(956U, 60000UL);
  123. /* 板端可观察版本:两段各1001工程单位。
  124. * 3脉冲/2单位带余数换算后分别输出1501、1502脉冲,累计3003脉冲;
  125. * 1500Hz附近持续约2s,避免原3脉冲自检在逻辑分析仪启动前已经结束。 */
  126. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE, 2U);
  127. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 10U, 1000UL);
  128. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 12U, 1001UL);
  129. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 20U, 1000UL);
  130. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 22U, 1001UL);
  131. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S1_BASE, 0U);
  132. (void)memset(&call, 0, sizeof(call));
  133. call.sequence = 0xA5A6UL;
  134. call.source.context = NULL;
  135. call.source.validateWords = SelfTestValidateWords;
  136. call.source.readWord = SelfTestReadWord;
  137. call.source.readBit = SelfTestReadBit;
  138. call.s0.device = PLSR_DEVICE_D;
  139. call.s0.address = SELF_TEST_S0_BASE;
  140. call.s1.device = PLSR_DEVICE_D;
  141. call.s1.address = SELF_TEST_S1_BASE;
  142. call.s2.type = PLSR_OPERAND_CONSTANT;
  143. call.s2.constant = 1;
  144. call.dAxis = 0U;
  145. call.outputModeOverride = PLSR_OUTPUT_PULSE_DIR;
  146. return PlsrPostCall(&call);
  147. }
  148. PLSR_RESULT PlsrProtectionSelfTestQueue(void)
  149. {
  150. PLSR_CALL call;
  151. PLSR_COMMAND command;
  152. PLSR_RESULT result;
  153. (void)memset(SelfTestWords, 0, sizeof(SelfTestWords));
  154. /* Pulse unit, soft limits enabled, 1 pulse per position unit. */
  155. (void)PlcDeviceWriteSfd(900U, (1U << 2U));
  156. SelfTestWriteSfdDword(902U, 1UL);
  157. SelfTestWriteSfdDword(904U, 1UL);
  158. (void)PlcDeviceWriteSfd(906U, SELF_TEST_DIR_POINT);
  159. (void)PlcDeviceWriteSfd(907U, 10U);
  160. (void)PlcDeviceWriteSfd(912U, 0U);
  161. (void)PlcDeviceWriteSfd(915U, 0xFFFFU);
  162. SelfTestWriteSfdDword(930U, 500UL);
  163. SelfTestWriteSfdDword(932U, (uint32_t)(int32_t)-500);
  164. /* K1: 1000Hz, 100ms acceleration/deceleration, 1ms refresh. */
  165. SelfTestWriteSfdDword(950U, 1000UL);
  166. (void)PlcDeviceWriteSfd(952U, 100U);
  167. (void)PlcDeviceWriteSfd(953U, 100U);
  168. (void)PlcDeviceWriteSfd(954U, 0U);
  169. (void)PlcDeviceWriteSfd(955U, 0U);
  170. SelfTestWriteSfdDword(956U, 100000UL);
  171. SelfTestWriteSfdDword(958U, 1000UL);
  172. SelfTestWriteSfdDword(960U, 0UL);
  173. (void)PlcDeviceWriteSfd(962U, 50U);
  174. (void)PlcDeviceWriteSfd(963U, 0U);
  175. (void)PlcDeviceWriteSfd(964U, 0U);
  176. SelfTestWriteSfdDword(966U, 2000UL);
  177. SelfTestWriteSfdDword(968U, 200UL);
  178. /* One relative segment requests +10000 pulses; +500 must stop it. */
  179. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE, 1U);
  180. SelfTestWriteDword(PLSR_DEVICE_D,
  181. SELF_TEST_S0_BASE + 10U,
  182. 1000UL);
  183. SelfTestWriteDword(PLSR_DEVICE_D,
  184. SELF_TEST_S0_BASE + 12U,
  185. 10000UL);
  186. SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S1_BASE, 0U);
  187. (void)memset(&command, 0, sizeof(command));
  188. command.sequence = 0xA5A7UL;
  189. command.axis = 0U;
  190. command.opcode = PLSR_CMD_SET_POSITION;
  191. command.argument = 0;
  192. result = PlsrPostCommand(&command);
  193. if (result != PLSR_RESULT_QUEUED)
  194. {
  195. return result;
  196. }
  197. (void)memset(&call, 0, sizeof(call));
  198. call.sequence = 0xA5A8UL;
  199. call.source.context = NULL;
  200. call.source.validateWords = SelfTestValidateWords;
  201. call.source.readWord = SelfTestReadWord;
  202. call.source.readBit = SelfTestReadBit;
  203. call.s0.device = PLSR_DEVICE_D;
  204. call.s0.address = SELF_TEST_S0_BASE;
  205. call.s1.device = PLSR_DEVICE_D;
  206. call.s1.address = SELF_TEST_S1_BASE;
  207. call.s2.type = PLSR_OPERAND_CONSTANT;
  208. call.s2.constant = 1;
  209. call.dAxis = 0U;
  210. call.outputModeOverride = PLSR_OUTPUT_PULSE_DIR;
  211. return PlsrPostCall(&call);
  212. }
  213. PLSR_RESULT PlsrFourAxisSelfTestQueue(void)
  214. {
  215. static const uint16_t s0Base[PLSR_AXIS_COUNT] =
  216. {
  217. 10U, 40U, 70U, 100U
  218. };
  219. static const uint16_t s1Base[PLSR_AXIS_COUNT] =
  220. {
  221. 160U, 164U, 168U, 172U
  222. };
  223. static const uint32_t frequencyHz[PLSR_AXIS_COUNT] =
  224. {
  225. 1000UL, 2000UL, 3000UL, 4000UL
  226. };
  227. static const int32_t pulseCount[PLSR_AXIS_COUNT] =
  228. {
  229. 1000, 2000, 3000, 4000
  230. };
  231. PLSR_CALL call;
  232. PLSR_COMMAND command;
  233. PLSR_RESULT result;
  234. uint16_t commonBase;
  235. uint16_t setBase;
  236. uint8_t axis;
  237. (void)memset(SelfTestWords, 0, sizeof(SelfTestWords));
  238. for (axis = 0U; axis < PLSR_AXIS_COUNT; axis++)
  239. {
  240. commonBase = (uint16_t)(900U
  241. + (uint16_t)axis
  242. * SELF_TEST_SFD_AXIS_STRIDE);
  243. setBase = (uint16_t)(commonBase + SELF_TEST_SFD_SET_OFFSET);
  244. /* Pulse unit, PULSE/DIR, no limit input, Q4..Q7 as DIR. */
  245. (void)PlcDeviceWriteSfd(commonBase, 0U);
  246. SelfTestWriteSfdDword((uint16_t)(commonBase + 2U), 1UL);
  247. SelfTestWriteSfdDword((uint16_t)(commonBase + 4U), 1UL);
  248. (void)PlcDeviceWriteSfd((uint16_t)(commonBase + 6U),
  249. (uint16_t)(SELF_TEST_DIR_POINT + axis));
  250. (void)PlcDeviceWriteSfd((uint16_t)(commonBase + 7U), 10U);
  251. (void)PlcDeviceWriteSfd((uint16_t)(commonBase + 12U), 0U);
  252. (void)PlcDeviceWriteSfd((uint16_t)(commonBase + 15U), 0xFFFFU);
  253. /* K1 has no ramp so all four channels keep an exact fixed rate. */
  254. SelfTestWriteSfdDword(setBase, frequencyHz[axis]);
  255. (void)PlcDeviceWriteSfd((uint16_t)(setBase + 2U), 0U);
  256. (void)PlcDeviceWriteSfd((uint16_t)(setBase + 3U), 0U);
  257. (void)PlcDeviceWriteSfd((uint16_t)(setBase + 4U), 0U);
  258. (void)PlcDeviceWriteSfd((uint16_t)(setBase + 5U), 0U);
  259. SelfTestWriteSfdDword((uint16_t)(setBase + 6U), 100000UL);
  260. SelfTestWriteSfdDword((uint16_t)(setBase + 8U),
  261. frequencyHz[axis]);
  262. SelfTestWriteSfdDword((uint16_t)(setBase + 10U), 0UL);
  263. (void)PlcDeviceWriteSfd((uint16_t)(setBase + 12U), 50U);
  264. (void)PlcDeviceWriteSfd((uint16_t)(setBase + 13U), 0U);
  265. (void)PlcDeviceWriteSfd((uint16_t)(setBase + 14U), 0U);
  266. SelfTestWriteSfdDword((uint16_t)(setBase + 16U), 2000UL);
  267. SelfTestWriteSfdDword((uint16_t)(setBase + 18U), 200UL);
  268. SelfTestWriteDword(PLSR_DEVICE_D, s0Base[axis], 1U);
  269. SelfTestWriteDword(PLSR_DEVICE_D,
  270. (uint32_t)s0Base[axis] + 10UL,
  271. frequencyHz[axis]);
  272. SelfTestWriteDword(PLSR_DEVICE_D,
  273. (uint32_t)s0Base[axis] + 12UL,
  274. (uint32_t)pulseCount[axis]);
  275. SelfTestWriteDword(PLSR_DEVICE_D, s1Base[axis], 0U);
  276. /* Make the board-test result independent of a previously restored
  277. * Backup SRAM position. */
  278. (void)memset(&command, 0, sizeof(command));
  279. command.sequence = 0xA500UL + axis;
  280. command.axis = axis;
  281. command.opcode = PLSR_CMD_SET_POSITION;
  282. command.argument = 0;
  283. result = PlsrPostCommand(&command);
  284. if (result != PLSR_RESULT_QUEUED)
  285. {
  286. return result;
  287. }
  288. (void)memset(&call, 0, sizeof(call));
  289. call.sequence = 0xA600UL + axis;
  290. call.source.context = NULL;
  291. call.source.validateWords = SelfTestValidateWords;
  292. call.source.readWord = SelfTestReadWord;
  293. call.source.readBit = SelfTestReadBit;
  294. call.s0.device = PLSR_DEVICE_D;
  295. call.s0.address = s0Base[axis];
  296. call.s1.device = PLSR_DEVICE_D;
  297. call.s1.address = s1Base[axis];
  298. call.s2.type = PLSR_OPERAND_CONSTANT;
  299. call.s2.constant = 1;
  300. call.dAxis = axis;
  301. call.outputModeOverride = PLSR_OUTPUT_PULSE_DIR;
  302. result = PlsrPostCall(&call);
  303. if (result != PLSR_RESULT_QUEUED)
  304. {
  305. return result;
  306. }
  307. }
  308. return PLSR_RESULT_QUEUED;
  309. }