292 lines
9.0 KiB
C
292 lines
9.0 KiB
C
|
|
/* ext_relay.c - 485 <20><>չ<EFBFBD>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD>(4 ·<><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)<29><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD><D6A7>
|
|||
|
|
*
|
|||
|
|
* Ӳ<EFBFBD><EFBFBD>: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>سӹ<EFBFBD><EFBFBD><EFBFBD> USART2 RS485 <EFBFBD><EFBFBD><EFBFBD><EFBFBD>(9600-8N1, DMA+IDLE <EFBFBD><EFBFBD>֡)
|
|||
|
|
* Э<EFBFBD><EFBFBD>: Modbus RTU, <EFBFBD>ӻ<EFBFBD><EFBFBD><EFBFBD>ַ 0x10, <EFBFBD><EFBFBD><EFBFBD><EFBFBD> Docs/RS485<EFBFBD><EFBFBD>չ<EFBFBD>̵<EFBFBD><EFBFBD><EFBFBD>Э<EFBFBD><EFBFBD>.md
|
|||
|
|
* FC05 д<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȧ(<EFBFBD><EFBFBD>Ȧ0~3=<EFBFBD>̵<EFBFBD><EFBFBD><EFBFBD>1~4, 0xFF00<EFBFBD><EFBFBD><EFBFBD><EFBFBD>/0x0000<EFBFBD>Ͽ<EFBFBD>), <EFBFBD>ӻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
* FC03 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ּĴ<EFBFBD><EFBFBD><EFBFBD> 0x0000 <EFBFBD><EFBFBD> 4 <EFBFBD><EFBFBD>: <EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬/<EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬/<EFBFBD><EFBFBD><EFBFBD>ϱ<EFBFBD>־/<EFBFBD>̼<EFBFBD><EFBFBD>汾
|
|||
|
|
* ʱ<EFBFBD><EFBFBD>: <EFBFBD><EFBFBD><EFBFBD>߾<EFBFBD>Ĭ >=50ms <EFBFBD>ŷ<EFBFBD>֡(<EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD>ѯ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> rs485_bus ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>);
|
|||
|
|
* Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ 300ms <EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1 <EFBFBD><EFBFBD>; <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ 2s <EFBFBD><EFBFBD>ѯһ<EFBFBD><EFBFBD>״̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
#include "ext_relay.h"
|
|||
|
|
#include "relay.h"
|
|||
|
|
#include "uart.h"
|
|||
|
|
#include "log.h"
|
|||
|
|
#include "network.h"
|
|||
|
|
#include "FreeRTOS.h"
|
|||
|
|
#include "task.h"
|
|||
|
|
#include <string.h>
|
|||
|
|
#include <stdio.h>
|
|||
|
|
|
|||
|
|
#define EXT_RESP_TIMEOUT_MS 300u /* Ӧ<><D3A6><EFBFBD><EFBFBD>ʱ */
|
|||
|
|
#define EXT_FB_SETTLE_MS 150u /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ժ<EFBFBD><D4BA>ȴ<EFBFBD><C8B4><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD>ȶ<EFBFBD><C8B6>ٶ<EFBFBD><D9B6><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
#define EXT_POLL_INTERVAL_MS 2000u /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD> */
|
|||
|
|
#define EXT_OFFLINE_MISS 3u /* <20><><EFBFBD><EFBFBD>ʧ<EFBFBD>ܴ<EFBFBD><DCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
|
|||
|
|
/* Modbus CRC16(<28><><EFBFBD><EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ) */
|
|||
|
|
static uint16_t ext_crc16(const uint8_t *data, uint16_t len)
|
|||
|
|
{
|
|||
|
|
uint16_t crc = 0xFFFF;
|
|||
|
|
for (uint16_t i = 0; i < len; i++) {
|
|||
|
|
crc ^= data[i];
|
|||
|
|
for (uint8_t j = 0; j < 8; j++) {
|
|||
|
|
crc = (crc & 0x0001) ? ((crc >> 1) ^ 0xA001) : (crc >> 1);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return crc;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD>߷<EFBFBD><DFB7><EFBFBD>: <20><> 50ms <20><>Ĭ + <20><><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD>(<28><><EFBFBD>¾<EFBFBD>֡) + <20><><EFBFBD><EFBFBD> + ˢ<><CBA2>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD> */
|
|||
|
|
static void ext_tx(const uint8_t *frame, uint16_t len)
|
|||
|
|
{
|
|||
|
|
uint32_t dt = HAL_GetTick() - rs485_bus_last_tick();
|
|||
|
|
if (dt < 50u) vTaskDelay(50u - dt);
|
|||
|
|
USART2_FlushRxBuf();
|
|||
|
|
HAL_UART_Transmit(&huart2, (uint8_t *)frame, len, 100);
|
|||
|
|
rs485_bus_touch();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void ext_send_fc05(uint8_t ch, uint8_t on)
|
|||
|
|
{
|
|||
|
|
uint8_t f[8];
|
|||
|
|
f[0] = EXT_RELAY_ADDR;
|
|||
|
|
f[1] = 0x05;
|
|||
|
|
f[2] = 0x00;
|
|||
|
|
f[3] = (uint8_t)(ch - 1); /* <20><>Ȧ<EFBFBD><C8A6>ַ 0~3 */
|
|||
|
|
f[4] = on ? 0xFF : 0x00;
|
|||
|
|
f[5] = 0x00;
|
|||
|
|
uint16_t c = ext_crc16(f, 6);
|
|||
|
|
f[6] = (uint8_t)(c & 0xFF);
|
|||
|
|
f[7] = (uint8_t)(c >> 8);
|
|||
|
|
ext_tx(f, 8);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void ext_send_fc03(void)
|
|||
|
|
{
|
|||
|
|
uint8_t f[8];
|
|||
|
|
f[0] = EXT_RELAY_ADDR;
|
|||
|
|
f[1] = 0x03;
|
|||
|
|
f[2] = 0x00; f[3] = 0x00; /* <20><>ʼ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD> 0x0000 */
|
|||
|
|
f[4] = 0x00; f[5] = 0x04; /* <20><> 4 <20><> */
|
|||
|
|
uint16_t c = ext_crc16(f, 6);
|
|||
|
|
f[6] = (uint8_t)(c & 0xFF);
|
|||
|
|
f[7] = (uint8_t)(c >> 8);
|
|||
|
|
ext_tx(f, 8);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* <20><>չ<EFBFBD><D5B9>״̬(<28><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> FC03 Ӧ<><D3A6>) */
|
|||
|
|
static uint8_t s_online = 0;
|
|||
|
|
static uint8_t s_state = 0; /* REG0 <20><><EFBFBD><EFBFBD>״̬ bit0~3 */
|
|||
|
|
static uint8_t s_fb = 0; /* REG1 <20><><EFBFBD><EFBFBD>״̬ */
|
|||
|
|
static uint8_t s_fault = 0; /* REG2 <20><><EFBFBD>ϱ<EFBFBD>־ */
|
|||
|
|
static uint16_t s_ver = 0; /* REG3 <20>ӻ<EFBFBD><D3BB>汾 */
|
|||
|
|
static uint8_t s_miss = 0; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
static uint32_t s_last_poll = 0;
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD>״̬<D7B4><CCAC> */
|
|||
|
|
static uint8_t cmd_pending = 0; /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
static uint8_t cmd_stage = 0; /* 0<><30> 1<><31>FC05<30><35><EFBFBD><EFBFBD> 2<><32><EFBFBD><EFBFBD><EFBFBD>ȶ<EFBFBD><C8B6><EFBFBD>ʱ 3<><33>FC03Ӧ<33><D3A6> */
|
|||
|
|
static uint8_t cmd_ch = 0, cmd_on = 0, cmd_retry = 0;
|
|||
|
|
static uint8_t cmd_is_poll = 0; /* <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ(<28><>Ӧ<EFBFBD><D3A6>ƽ̨) */
|
|||
|
|
static uint32_t cmd_tick = 0;
|
|||
|
|
static char cmd_id[20] = {0};
|
|||
|
|
|
|||
|
|
/* ֡<>¼<EFBFBD>(on_frame <20><>λ, process <20><><EFBFBD><EFBFBD>; ͬ<><CDAC> app_task <20><><EFBFBD>߳<EFBFBD>) */
|
|||
|
|
static uint8_t rx_echo_ok = 0;
|
|||
|
|
static uint8_t rx_state_ok = 0;
|
|||
|
|
static uint8_t rx_exc = 0;
|
|||
|
|
|
|||
|
|
uint8_t ext_relay_online(void) { return s_online; }
|
|||
|
|
uint8_t ext_relay_state_mask(void) { return s_state; }
|
|||
|
|
uint8_t ext_relay_fault_mask(void) { return s_fault; }
|
|||
|
|
|
|||
|
|
static void ext_note_success(void)
|
|||
|
|
{
|
|||
|
|
s_miss = 0;
|
|||
|
|
if (!s_online) {
|
|||
|
|
s_online = 1;
|
|||
|
|
log_info("> EXT: <20><>չ<EFBFBD>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28>ӻ<EFBFBD><D3BB>汾 V%u.%02X)", s_ver >> 8, s_ver & 0xFF);
|
|||
|
|
relayStatueUpdata(); /* <20><><EFBFBD>ߺ<EFBFBD><DFBA><EFBFBD>һ<EFBFBD><D2BB>ȫ״̬, ƽ̨ˢ<CCA8><CBA2> sw5~sw8 */
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void ext_note_fail(void)
|
|||
|
|
{
|
|||
|
|
if (s_miss < 255) s_miss++;
|
|||
|
|
if (s_online && s_miss >= EXT_OFFLINE_MISS) {
|
|||
|
|
s_online = 0;
|
|||
|
|
log_warn("> EXT: <20><>չ<EFBFBD>̵<EFBFBD><CCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD> %u <20><><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>)", EXT_OFFLINE_MISS);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static void ext_respond(int ok, const char *msg)
|
|||
|
|
{
|
|||
|
|
if (cmd_id[0]) {
|
|||
|
|
NET_publish_response(cmd_id, ok, msg);
|
|||
|
|
cmd_id[0] = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ext_relay_cmd(uint8_t ch, uint8_t on, const char *id)
|
|||
|
|
{
|
|||
|
|
if (ch < 1 || ch > EXT_RELAY_CH) return;
|
|||
|
|
if (!s_online) {
|
|||
|
|
log_warn("> EXT: <20><>չ<EFBFBD><D5B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20>ܾ<EFBFBD> SW%d <20><><EFBFBD><EFBFBD>", ch + 4);
|
|||
|
|
if (id) NET_publish_response(id, 0, "ext relay board offline");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (cmd_pending || cmd_stage != 0) {
|
|||
|
|
log_warn("> EXT: <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>, <20>ܾ<EFBFBD> SW%d <20><><EFBFBD><EFBFBD>", ch + 4);
|
|||
|
|
if (id) NET_publish_response(id, 0, "ext relay busy");
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
cmd_ch = ch;
|
|||
|
|
cmd_on = on ? 1 : 0;
|
|||
|
|
if (id) {
|
|||
|
|
strncpy(cmd_id, id, sizeof(cmd_id) - 1);
|
|||
|
|
cmd_id[sizeof(cmd_id) - 1] = 0;
|
|||
|
|
} else {
|
|||
|
|
cmd_id[0] = 0;
|
|||
|
|
}
|
|||
|
|
cmd_pending = 1;
|
|||
|
|
log_info("> EXT: SW%d %s (<28>·<EFBFBD><C2B7><EFBFBD>չ<EFBFBD><D5B9>)", ch + 4, on ? "<EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 485 ֡<><D6A1><EFBFBD><EFBFBD>: feed_scale <20><>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>վ<EFBFBD><D5BE> 0x10 <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|||
|
|
void ext_relay_on_frame(const uint8_t *b, uint16_t len)
|
|||
|
|
{
|
|||
|
|
if (len < 5) return;
|
|||
|
|
uint16_t c = ext_crc16(b, (uint16_t)(len - 2));
|
|||
|
|
uint16_t r = (uint16_t)(((uint16_t)b[len - 1] << 8) | b[len - 2]);
|
|||
|
|
if (c != r) {
|
|||
|
|
log_warn("> EXT: ֡ CRC <20><><EFBFBD><EFBFBD> (len=%u)", (unsigned)len);
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (b[1] & 0x80) { /* Modbus <20>쳣Ӧ<ECB3A3><D3A6> */
|
|||
|
|
log_warn("> EXT: <20>쳣Ӧ<ECB3A3><D3A6> FC=%02X <20><>=%02X", b[1] & 0x7F, b[2]);
|
|||
|
|
rx_exc = 1;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (b[1] == 0x05 && len == 8) {
|
|||
|
|
/* <20><><EFBFBD><EFBFBD>У<EFBFBD><D0A3>: <20><>Ȧ<EFBFBD><C8A6>ַ<EFBFBD><D6B7>ͨ<EFBFBD><CDA8>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> */
|
|||
|
|
if (b[2] == 0x00 && b[3] == (uint8_t)(cmd_ch - 1) &&
|
|||
|
|
((b[4] == 0xFF && cmd_on) || (b[4] == 0x00 && !cmd_on)) && b[5] == 0x00) {
|
|||
|
|
rx_echo_ok = 1;
|
|||
|
|
} else {
|
|||
|
|
log_warn("> EXT: FC05 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
if (b[1] == 0x03 && len == 13 && b[2] == 0x08) {
|
|||
|
|
/* 4 <20><><EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>: <20><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD>ֻ<EFBFBD>õ<EFBFBD><C3B5>ֽ<EFBFBD> */
|
|||
|
|
s_state = b[4] & 0x0F;
|
|||
|
|
s_fb = b[6] & 0x0F;
|
|||
|
|
s_fault = b[8] & 0x0F;
|
|||
|
|
s_ver = (uint16_t)(((uint16_t)b[9] << 8) | b[10]);
|
|||
|
|
rx_state_ok = 1;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
log_warn("> EXT: δʶ<CEB4><CAB6>֡ FC=%02X len=%u", b[1], (unsigned)len);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void ext_relay_process(void)
|
|||
|
|
{
|
|||
|
|
uint32_t now = HAL_GetTick();
|
|||
|
|
if (now < 3000u) return; /* <20>ϵ<EFBFBD><CFB5>ȶ<EFBFBD><C8B6><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD>״β<D7B4>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD> */
|
|||
|
|
|
|||
|
|
/* ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ) */
|
|||
|
|
if (cmd_pending && cmd_stage == 0) {
|
|||
|
|
cmd_pending = 0;
|
|||
|
|
cmd_is_poll = 0;
|
|||
|
|
cmd_retry = 0;
|
|||
|
|
cmd_stage = 1;
|
|||
|
|
ext_send_fc05(cmd_ch, cmd_on);
|
|||
|
|
cmd_tick = now;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (cmd_stage == 1) { /* <20><> FC05 <20><><EFBFBD><EFBFBD> */
|
|||
|
|
if (rx_echo_ok) {
|
|||
|
|
rx_echo_ok = 0;
|
|||
|
|
ext_note_success();
|
|||
|
|
cmd_stage = 2;
|
|||
|
|
cmd_tick = now;
|
|||
|
|
} else if (rx_exc || (now - cmd_tick) > EXT_RESP_TIMEOUT_MS) {
|
|||
|
|
rx_exc = 0;
|
|||
|
|
if (cmd_retry < 1) {
|
|||
|
|
cmd_retry++;
|
|||
|
|
ext_send_fc05(cmd_ch, cmd_on);
|
|||
|
|
cmd_tick = now;
|
|||
|
|
} else {
|
|||
|
|
log_warn("> EXT: SW%d <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>", cmd_ch + 4);
|
|||
|
|
ext_respond(0, "ext relay no response");
|
|||
|
|
ext_note_fail();
|
|||
|
|
cmd_stage = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (cmd_stage == 2) { /* <20><><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD><EFBFBD>ȶ<EFBFBD><C8B6><EFBFBD>ʱ */
|
|||
|
|
if ((now - cmd_tick) >= EXT_FB_SETTLE_MS) {
|
|||
|
|
cmd_retry = 0;
|
|||
|
|
cmd_stage = 3;
|
|||
|
|
ext_send_fc03();
|
|||
|
|
cmd_tick = now;
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (cmd_stage == 3) { /* <20><> FC03 ״̬Ӧ<CCAC><D3A6>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD>) */
|
|||
|
|
if (rx_state_ok) {
|
|||
|
|
rx_state_ok = 0;
|
|||
|
|
ext_note_success();
|
|||
|
|
if (cmd_is_poll) {
|
|||
|
|
cmd_is_poll = 0;
|
|||
|
|
if (s_fault) {
|
|||
|
|
log_warn("> EXT: <20><><EFBFBD><EFBFBD><EFBFBD>쳣<EFBFBD><ECB3A3>־=%02X (<28><><EFBFBD><EFBFBD>=%02X <20><><EFBFBD><EFBFBD>=%02X)", s_fault, s_state, s_fb);
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
uint8_t bit = (uint8_t)(1u << (cmd_ch - 1));
|
|||
|
|
int ok = (((s_state & bit) != 0) == cmd_on) && ((s_fault & bit) == 0);
|
|||
|
|
if (ok) {
|
|||
|
|
log_info("> EXT: SW%d %s<>ɹ<EFBFBD> (<28><><EFBFBD><EFBFBD>=%02X)", cmd_ch + 4, cmd_on ? "<EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>", s_fb);
|
|||
|
|
ext_respond(1, "OK");
|
|||
|
|
} else {
|
|||
|
|
log_warn("> EXT: SW%d %sδ<73><CEB4>Ч (<28><><EFBFBD><EFBFBD>=%02X <20><><EFBFBD><EFBFBD>=%02X <20><><EFBFBD><EFBFBD>=%02X)",
|
|||
|
|
cmd_ch + 4, cmd_on ? "<EFBFBD><EFBFBD>" : "<EFBFBD><EFBFBD>", s_state, s_fb, s_fault);
|
|||
|
|
ext_respond(0, "ext relay failed / load unpowered");
|
|||
|
|
}
|
|||
|
|
relayStatueUpdata(); /* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA>ϱ<EFBFBD>ȫ״̬ */
|
|||
|
|
}
|
|||
|
|
cmd_stage = 0;
|
|||
|
|
} else if (rx_exc || (now - cmd_tick) > EXT_RESP_TIMEOUT_MS) {
|
|||
|
|
rx_exc = 0;
|
|||
|
|
if (cmd_retry < 1) {
|
|||
|
|
cmd_retry++;
|
|||
|
|
ext_send_fc03();
|
|||
|
|
cmd_tick = now;
|
|||
|
|
} else {
|
|||
|
|
if (!cmd_is_poll) {
|
|||
|
|
log_warn("> EXT: SW%d ״̬ȷ<CCAC><C8B7><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>", cmd_ch + 4);
|
|||
|
|
ext_respond(0, "ext relay no response");
|
|||
|
|
}
|
|||
|
|
cmd_is_poll = 0;
|
|||
|
|
ext_note_fail();
|
|||
|
|
cmd_stage = 0;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* <20><><EFBFBD><EFBFBD>: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѯ(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DFBC><EFBFBD>) */
|
|||
|
|
if ((now - s_last_poll) >= EXT_POLL_INTERVAL_MS) {
|
|||
|
|
s_last_poll = now;
|
|||
|
|
cmd_is_poll = 1;
|
|||
|
|
cmd_retry = 0;
|
|||
|
|
cmd_stage = 3;
|
|||
|
|
ext_send_fc03();
|
|||
|
|
cmd_tick = now;
|
|||
|
|
}
|
|||
|
|
}
|