#include "plsr_self_test.h" #include "plc_device.h" #include "plsr_core.h" #include "plsr_job.h" #include /* 上电自测(验证后可删除): * - AB 模式使用 Q0(A)/Q1(B),其余用出厂默认参数(K1) * - 任务:3 段完整 AB 周期(H00 完成,顺序衔接): * 段1:2000Hz / +1000 周期(A 超前 B) * 段2:5000Hz / +6000 周期(A 超前 B) * 段3:1000Hz / -500 周期(B 超前 A,验证反向) * 数据源为静态数组,仅自测使用(正式 D 设备适配器见 Modbus 阶段)。 */ #define SELF_TEST_WORD_CAPACITY (64U) #define SELF_TEST_S0_BASE (10U) #define SELF_TEST_S1_BASE (60U) #define SELF_TEST_DIR_POINT (4U) static uint16_t SelfTestWords[3][SELF_TEST_WORD_CAPACITY]; static uint8_t SelfTestValidateWords(void *context, PLSR_DEVICE_TYPE device, uint32_t firstAddress, uint32_t wordCount) { (void)context; if ((device > PLSR_DEVICE_FD) || (wordCount == 0UL)) { return 0U; } return (((uint64_t)firstAddress + wordCount) <= SELF_TEST_WORD_CAPACITY) ? 1U : 0U; } static uint8_t SelfTestReadWord(void *context, PLSR_DEVICE_TYPE device, uint32_t address, uint16_t *value) { (void)context; if ((device > PLSR_DEVICE_FD) || (value == NULL) || (address >= SELF_TEST_WORD_CAPACITY)) { return 0U; } *value = SelfTestWords[device][address]; return 1U; } static uint8_t SelfTestReadBit(void *context, PLSR_DEVICE_TYPE device, uint32_t address, uint8_t *value) { (void)context; (void)device; (void)address; *value = 0U; return 1U; } static void SelfTestWriteDword(PLSR_DEVICE_TYPE device, uint32_t address, uint32_t value) { SelfTestWords[device][address] = (uint16_t)(value & 0xFFFFUL); SelfTestWords[device][address + 1UL] = (uint16_t)(value >> 16U); } static void SelfTestWriteSfdDword(uint16_t address, uint32_t value) { (void)PlcDeviceWriteSfd(address, (uint16_t)(value & 0xFFFFUL)); (void)PlcDeviceWriteSfd((uint16_t)(address + 1U), (uint16_t)(value >> 16U)); } PLSR_RESULT PlsrSelfTestQueue(void) { PLSR_CALL call; (void)memset(SelfTestWords, 0, sizeof(SelfTestWords)); /* 方向端子 Y4(PULSE/DIR 模式必需,接线参数)。 */ (void)PlcDeviceWriteSfd(906U, SELF_TEST_DIR_POINT); /* S0:3 段,H00 完成,顺序跳转。 */ SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE, 3U); SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 10U, 2000UL); SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 12U, 1000UL); SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 20U, 5000UL); SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 22U, 6000UL); SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 30U, 1000UL); SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 32U, (uint32_t)(int32_t)-500); /* S1:相对模式,起始段 0(=段1)。 */ SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S1_BASE, 0U); (void)memset(&call, 0, sizeof(call)); call.sequence = 0xA5A5UL; call.source.context = NULL; call.source.validateWords = SelfTestValidateWords; call.source.readWord = SelfTestReadWord; call.source.readBit = SelfTestReadBit; call.s0.device = PLSR_DEVICE_D; call.s0.address = SELF_TEST_S0_BASE; call.s1.device = PLSR_DEVICE_D; call.s1.address = SELF_TEST_S1_BASE; call.s2.type = PLSR_OPERAND_CONSTANT; call.s2.constant = 1; call.dAxis = 0U; call.outputModeOverride = PLSR_OUTPUT_AB; return PlsrPostCall(&call); } PLSR_RESULT PlsrEquivalentSelfTestQueue(void) { PLSR_CALL call; (void)memset(SelfTestWords, 0, sizeof(SelfTestWords)); /* SFD900 Bit10~8=001(1um当量);3脉冲/2单位。 */ (void)PlcDeviceWriteSfd(900U, (1U << 8U)); SelfTestWriteSfdDword(902U, 3UL); SelfTestWriteSfdDword(904U, 2UL); (void)PlcDeviceWriteSfd(906U, SELF_TEST_DIR_POINT); (void)PlcDeviceWriteSfd(907U, 10U); /* 当量换算后物理最高速度=90000Hz,不超过硬件100kHz。 */ SelfTestWriteSfdDword(956U, 60000UL); /* 板端可观察版本:两段各1001工程单位。 * 3脉冲/2单位带余数换算后分别输出1501、1502脉冲,累计3003脉冲; * 1500Hz附近持续约2s,避免原3脉冲自检在逻辑分析仪启动前已经结束。 */ SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE, 2U); SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 10U, 1000UL); SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 12U, 1001UL); SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 20U, 1000UL); SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S0_BASE + 22U, 1001UL); SelfTestWriteDword(PLSR_DEVICE_D, SELF_TEST_S1_BASE, 0U); (void)memset(&call, 0, sizeof(call)); call.sequence = 0xA5A6UL; call.source.context = NULL; call.source.validateWords = SelfTestValidateWords; call.source.readWord = SelfTestReadWord; call.source.readBit = SelfTestReadBit; call.s0.device = PLSR_DEVICE_D; call.s0.address = SELF_TEST_S0_BASE; call.s1.device = PLSR_DEVICE_D; call.s1.address = SELF_TEST_S1_BASE; call.s2.type = PLSR_OPERAND_CONSTANT; call.s2.constant = 1; call.dAxis = 0U; call.outputModeOverride = PLSR_OUTPUT_PULSE_DIR; return PlsrPostCall(&call); }