|
|
|
@ -58,8 +58,8 @@ Includes |
|
|
|
#define UART_RX_BUF_SIZE 1024 |
|
|
|
#define RS485_BRIDGE_FIFO_SZ 2048 |
|
|
|
|
|
|
|
#define BRIDGE_IDLE_DONE_US 2000000U // ? 3ms ? ?
|
|
|
|
#define BRIDGE_TOTAL_WAIT_US 6000000U |
|
|
|
#define BRIDGE_IDLE_DONE_US 2500000U /* sweep 중 성공 라인 사이 최대 무응답 허용 시간 */ |
|
|
|
#define BRIDGE_TOTAL_WAIT_US 30000000U /* sweep 전체 브리지 최대 대기 시간 */ |
|
|
|
|
|
|
|
/* =========================
|
|
|
|
* UART RX Buffers |
|
|
|
@ -695,7 +695,7 @@ static void print_hex_line(CmdSource src, const uint8_t *data, uint16_t len) |
|
|
|
OUT_PRINT(src, out); |
|
|
|
} |
|
|
|
|
|
|
|
static int execute_connect_verify_sequence(CmdSource src, const app_job_t *job) |
|
|
|
static int run_connect_verify_one_channel(const app_job_t *job, uint8_t ch) |
|
|
|
{ |
|
|
|
app_owi_result_t r_write1; |
|
|
|
app_owi_result_t r_read2; |
|
|
|
@ -708,25 +708,7 @@ static int execute_connect_verify_sequence(CmdSource src, const app_job_t *job) |
|
|
|
uint8_t attempt; |
|
|
|
|
|
|
|
if (!job) return 0; |
|
|
|
|
|
|
|
/* connect 전용 패턴
|
|
|
|
xNNc_XXX...:owt28006 AABBCC DDEEFF |
|
|
|
- id = 0x28 |
|
|
|
- len = 6 |
|
|
|
- payload[0..2] = 첫 write 3바이트 |
|
|
|
- payload[3..5] = 최종 비교 기대값 3바이트 |
|
|
|
*/ |
|
|
|
if (job->type != APP_JOB_PROTO_OW) return 0; |
|
|
|
if (job->proto != APP_PROTO_OWIT) return 0; |
|
|
|
if (job->id != 0x28u) return 0; |
|
|
|
if (job->len != 6u) return 0; |
|
|
|
|
|
|
|
if (job->addr != g_fixed_addr) return 0; |
|
|
|
|
|
|
|
if (job->channel < 1 || job->channel > 20) { |
|
|
|
OUT_PRINT(src, "Err:ch_range\r\n"); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
if (ch < 1 || ch > 20) return 0; |
|
|
|
|
|
|
|
memcpy(write1_data, &job->payload[0], 3); |
|
|
|
memcpy(expected_tail, &job->payload[3], 3); |
|
|
|
@ -748,8 +730,8 @@ static int execute_connect_verify_sequence(CmdSource src, const app_job_t *job) |
|
|
|
Eol_Init(); |
|
|
|
} |
|
|
|
|
|
|
|
Gate_SetByNum(job->channel, job->hash_on, job->anaout_on, job->check_on); |
|
|
|
GateCtrl_SelectChannel(job->channel); |
|
|
|
Gate_SetByNum(ch, job->hash_on, job->anaout_on, job->check_on); |
|
|
|
GateCtrl_SelectChannel(ch); |
|
|
|
|
|
|
|
delay_us(30000); |
|
|
|
|
|
|
|
@ -771,20 +753,80 @@ static int execute_connect_verify_sequence(CmdSource src, const app_job_t *job) |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
/* 4) OR 28 003 -> 실제 칩 결과 읽기 */ |
|
|
|
/* 4) OR 28 003 */ |
|
|
|
r_read3 = app_owi_read_basic(0x28u, 3); |
|
|
|
if (!r_read3.ok || r_read3.timeout || r_read3.read_len < 3) { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
/* 실제 읽은 3바이트와 기대값 비교 */ |
|
|
|
if (memcmp(r_read3.data, expected_tail, 3) == 0) { |
|
|
|
OUT_PRINT(src, "Success\r\n"); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static void print_connect_sweep_result(CmdSource src, uint8_t ch, uint8_t ok) |
|
|
|
{ |
|
|
|
char msg[32]; |
|
|
|
sprintf(msg, "ch%u: %s\r\n", (unsigned)ch, ok ? "Success" : "Fail"); |
|
|
|
OUT_PRINT(src, msg); |
|
|
|
} |
|
|
|
|
|
|
|
static int execute_connect_verify_sequence(CmdSource src, const app_job_t *job) |
|
|
|
{ |
|
|
|
uint8_t ch; |
|
|
|
uint8_t success_count = 0; |
|
|
|
|
|
|
|
if (!job) return 0; |
|
|
|
|
|
|
|
/* connect 전용 패턴
|
|
|
|
xNNc_XXX...:owt28006 AABBCC DDEEFF |
|
|
|
- id = 0x28 |
|
|
|
- len = 6 |
|
|
|
- payload[0..2] = 첫 write 3바이트 |
|
|
|
- payload[3..5] = 최종 비교 기대값 3바이트 |
|
|
|
*/ |
|
|
|
if (job->type != APP_JOB_PROTO_OW) return 0; |
|
|
|
if (job->proto != APP_PROTO_OWIT) return 0; |
|
|
|
if (job->id != 0x28u) return 0; |
|
|
|
if (job->len != 6u) return 0; |
|
|
|
|
|
|
|
if (job->addr != g_fixed_addr) return 0; |
|
|
|
|
|
|
|
/* 000 이면 1~20 sweep */ |
|
|
|
if (job->channel == 0u) { |
|
|
|
for (ch = 1; ch <= 20; ch++) { |
|
|
|
uint8_t ok = (uint8_t)run_connect_verify_one_channel(job, ch); |
|
|
|
|
|
|
|
if (ok) { |
|
|
|
print_connect_sweep_result(src, ch, 1); |
|
|
|
success_count++; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (success_count == 0u) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
} |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
/* 단일 채널 */ |
|
|
|
if (job->channel < 1 || job->channel > 20) { |
|
|
|
OUT_PRINT(src, "Err:ch_range\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
if (run_connect_verify_one_channel(job, job->channel)) { |
|
|
|
OUT_PRINT(src, "Success\r\n"); |
|
|
|
} else { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
} |
|
|
|
delay_us(30000); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -805,6 +847,7 @@ static int execute_direct_read_sequence(CmdSource src, const app_job_t *job) |
|
|
|
|
|
|
|
if (job->channel < 1 || job->channel > 20) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -840,6 +883,7 @@ static int execute_direct_read_sequence(CmdSource src, const app_job_t *job) |
|
|
|
r_write = app_owi_write_basic(0x28u, job->payload, 3); |
|
|
|
if (!r_write.ok || r_write.timeout) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -847,11 +891,13 @@ static int execute_direct_read_sequence(CmdSource src, const app_job_t *job) |
|
|
|
r_read = app_owi_read_basic(0x28u, read_len); |
|
|
|
if (!r_read.ok || r_read.timeout || r_read.read_len < read_len) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
/* 3) 읽은 값만 출력 */ |
|
|
|
print_owi_read_result(src, &r_read); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -902,11 +948,13 @@ static int execute_write_coeff_sequence(CmdSource src, const app_job_t *job) |
|
|
|
/* 길이는 정확히 33바이트여야 함 */ |
|
|
|
if (job->len != 33u) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
if (job->channel < 1 || job->channel > 20) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -927,6 +975,7 @@ static int execute_write_coeff_sequence(CmdSource src, const app_job_t *job) |
|
|
|
r_write1 = app_owi_write_basic(0x28u, job->payload, (uint8_t)job->len); |
|
|
|
if (!r_write1.ok || r_write1.timeout) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -934,11 +983,13 @@ static int execute_write_coeff_sequence(CmdSource src, const app_job_t *job) |
|
|
|
r_read1 = app_owi_read_basic(0x28u, 1); |
|
|
|
if (!r_read1.ok || r_read1.timeout || r_read1.read_len < 1) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
if (r_read1.data[0] != 0x23u) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -946,6 +997,7 @@ static int execute_write_coeff_sequence(CmdSource src, const app_job_t *job) |
|
|
|
r_write2 = app_owi_write_basic(0x28u, nvm_read_cmd, 3); |
|
|
|
if (!r_write2.ok || r_write2.timeout) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -953,12 +1005,14 @@ static int execute_write_coeff_sequence(CmdSource src, const app_job_t *job) |
|
|
|
r_read2 = app_owi_read_basic(0x28u, 127); |
|
|
|
if (!r_read2.ok || r_read2.timeout || r_read2.read_len < 127) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
/* NVM read 응답 첫 바이트는 0x26 이어야 정상 */ |
|
|
|
if (r_read2.data[0] != 0x26u) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -973,7 +1027,7 @@ static int execute_write_coeff_sequence(CmdSource src, const app_job_t *job) |
|
|
|
} else { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
} |
|
|
|
|
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1017,11 +1071,13 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
/* 전체 길이는 정확히 121바이트 */ |
|
|
|
if (job->len != 121u) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
if (job->channel < 1 || job->channel > 20) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1043,6 +1099,7 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_write = app_owi_write_basic(0x28u, job->payload, 119u); |
|
|
|
if (!r_write.ok || r_write.timeout) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1054,6 +1111,7 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
} |
|
|
|
if (r_read.data[0] != 0x23u) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1061,6 +1119,7 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_write = app_owi_write_basic(0x28u, cmd_crc_44, 3); |
|
|
|
if (!r_write.ok || r_write.timeout) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1068,15 +1127,18 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_read = app_owi_read_basic(0x28u, 3); |
|
|
|
if (!r_read.ok || r_read.timeout || r_read.read_len < 3) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
if (r_read.data[0] != 0x44u) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
if (memcmp(&r_read.data[1], gui_crc, 2) != 0) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1084,6 +1146,7 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_write = app_owi_write_basic(0x28u, cmd_15_3c5b, 3); |
|
|
|
if (!r_write.ok || r_write.timeout) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1091,10 +1154,12 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_read = app_owi_read_basic(0x28u, 3); |
|
|
|
if (!r_read.ok || r_read.timeout || r_read.read_len < 3) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
if (!(r_read.data[0] == 0x15u && r_read.data[1] == 0x00u && r_read.data[2] == 0x01u)) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1102,6 +1167,7 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_write = app_owi_write_basic(0x28u, cmd_14, 1); |
|
|
|
if (!r_write.ok || r_write.timeout) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1109,10 +1175,12 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_read = app_owi_read_basic(0x28u, 3); |
|
|
|
if (!r_read.ok || r_read.timeout || r_read.read_len < 3) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
if (!(r_read.data[0] == 0x14u && r_read.data[1] == 0x00u && r_read.data[2] == 0x01u)) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1120,6 +1188,7 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_write = app_owi_write_basic(0x28u, cmd_1a, 1); |
|
|
|
if (!r_write.ok || r_write.timeout) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1129,6 +1198,7 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_read = app_owi_read_basic(0x28u, 3); |
|
|
|
if (!r_read.ok || r_read.timeout || r_read.read_len < 3) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1143,6 +1213,7 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
|
|
|
|
if (poll_count >= 50u) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1150,6 +1221,7 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_write = app_owi_write_basic(0x28u, cmd_crc_40, 3); |
|
|
|
if (!r_write.ok || r_write.timeout) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1157,14 +1229,17 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_read = app_owi_read_basic(0x28u, 3); |
|
|
|
if (!r_read.ok || r_read.timeout || r_read.read_len < 3) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
if (r_read.data[0] != 0x40u) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
if (memcmp(&r_read.data[1], gui_crc, 2) != 0) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1172,6 +1247,7 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_write = app_owi_write_basic(0x28u, cmd_crc_42, 3); |
|
|
|
if (!r_write.ok || r_write.timeout) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1179,14 +1255,17 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_read = app_owi_read_basic(0x28u, 3); |
|
|
|
if (!r_read.ok || r_read.timeout || r_read.read_len < 3) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
if (r_read.data[0] != 0x42u) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
if (memcmp(&r_read.data[1], gui_crc, 2) != 0) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1194,6 +1273,7 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_write = app_owi_write_basic(0x28u, cmd_15_0000, 3); |
|
|
|
if (!r_write.ok || r_write.timeout) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1201,10 +1281,12 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_read = app_owi_read_basic(0x28u, 3); |
|
|
|
if (!r_read.ok || r_read.timeout || r_read.read_len < 3) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
if (!(r_read.data[0] == 0x15u && r_read.data[1] == 0x00u && r_read.data[2] == 0x00u)) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1212,6 +1294,7 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_write = app_owi_write_basic(0x28u, cmd_nvm_read, 3); |
|
|
|
if (!r_write.ok || r_write.timeout) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1219,14 +1302,17 @@ static int execute_shadow_write_copy_nvm_sequence(CmdSource src, const app_job_t |
|
|
|
r_read = app_owi_read_basic(0x28u, 127); |
|
|
|
if (!r_read.ok || r_read.timeout || r_read.read_len < 127) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
if (r_read.data[0] != 0x26u) { |
|
|
|
OUT_PRINT(src, "Fail\r\n"); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
print_owi_read_result(src, &r_read); |
|
|
|
send_end_response(src); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1296,7 +1382,6 @@ static void forward_line_rs485_and_bridge(const char *line) |
|
|
|
{ |
|
|
|
static char txbuf[UART_RX_BUF_SIZE + 4]; |
|
|
|
uint32_t total_us; |
|
|
|
uint32_t idle_us = 0; |
|
|
|
char linebuf[320]; |
|
|
|
int line_len = 0; |
|
|
|
int n; |
|
|
|
@ -1333,58 +1418,50 @@ static void forward_line_rs485_and_bridge(const char *line) |
|
|
|
linebuf[0] = '\0'; |
|
|
|
|
|
|
|
while (total_us >= 50U) { |
|
|
|
uint8_t had_byte = 0; |
|
|
|
|
|
|
|
/* FIFO에서 바이트를 하나씩 꺼내 누적 */ |
|
|
|
while (s_rb_tail != s_rb_head) { |
|
|
|
char c = (char)s_rb_fifo[s_rb_tail]; |
|
|
|
s_rb_tail++; |
|
|
|
if (s_rb_tail >= RS485_BRIDGE_FIFO_SZ) s_rb_tail = 0; |
|
|
|
|
|
|
|
had_byte = 1; |
|
|
|
|
|
|
|
/* CR 무시 */ |
|
|
|
if (c == '\r') continue; |
|
|
|
|
|
|
|
/* 버퍼에 누적 */ |
|
|
|
/* line buffer 누적 */ |
|
|
|
if (line_len < (int)sizeof(linebuf) - 1) { |
|
|
|
linebuf[line_len++] = c; |
|
|
|
linebuf[line_len] = '\0'; |
|
|
|
} else { |
|
|
|
/* overflow 보호: 강제로 한 줄 종료 처리 */ |
|
|
|
/* overflow 보호 */ |
|
|
|
linebuf[line_len] = '\0'; |
|
|
|
|
|
|
|
if (!(linebuf[0] == 'x' || linebuf[0] == 'X')) { |
|
|
|
PC_PrintLine_CRLF(linebuf); |
|
|
|
got_any_line = 1; |
|
|
|
|
|
|
|
if (strstr(linebuf, "<end>") != 0) { |
|
|
|
g_rs485_bridge_active = 0; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
line_len = 0; |
|
|
|
linebuf[0] = '\0'; |
|
|
|
} |
|
|
|
|
|
|
|
/* LF 도착 = 한 줄 완성 */ |
|
|
|
/* LF = 한 줄 완성 */ |
|
|
|
if (c == '\n') { |
|
|
|
if (!(linebuf[0] == 'x' || linebuf[0] == 'X')) { |
|
|
|
PC_PrintLine_CRLF(linebuf); |
|
|
|
got_any_line = 1; |
|
|
|
} |
|
|
|
|
|
|
|
line_len = 0; |
|
|
|
linebuf[0] = '\0'; |
|
|
|
|
|
|
|
/* OFF 응답처럼 <end>가 오면 종료 */ |
|
|
|
if (g_rs485_bridge_done) { |
|
|
|
if (strstr(linebuf, "<end>") != 0) { |
|
|
|
g_rs485_bridge_active = 0; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (had_byte) { |
|
|
|
idle_us = 0; |
|
|
|
} else if (got_any_line) { |
|
|
|
idle_us += 50U; |
|
|
|
if (idle_us >= BRIDGE_IDLE_DONE_US) { |
|
|
|
break; |
|
|
|
line_len = 0; |
|
|
|
linebuf[0] = '\0'; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -1392,17 +1469,33 @@ static void forward_line_rs485_and_bridge(const char *line) |
|
|
|
total_us -= 50U; |
|
|
|
} |
|
|
|
|
|
|
|
/* 남은 partial line이 있으면 마지막으로 출력 */ |
|
|
|
/* timeout 시 partial line도 보여줌 */ |
|
|
|
if (line_len > 0) { |
|
|
|
linebuf[line_len] = '\0'; |
|
|
|
|
|
|
|
if (!(linebuf[0] == 'x' || linebuf[0] == 'X')) { |
|
|
|
PC_PrintLine_CRLF(linebuf); |
|
|
|
got_any_line = 1; |
|
|
|
|
|
|
|
if (strstr(linebuf, "<end>") != 0) { |
|
|
|
g_rs485_bridge_active = 0; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!got_any_line) { |
|
|
|
OUT_PRINT(CMD_SRC_PC, "Err:rs485_no_response\r\n"); |
|
|
|
} else { |
|
|
|
char dbg[128]; |
|
|
|
|
|
|
|
if (line_len > 0) { |
|
|
|
sprintf(dbg, "Err:rs485_no_end partial=%s\r\n", linebuf); |
|
|
|
} else { |
|
|
|
sprintf(dbg, "Err:rs485_no_end partial=<none>\r\n"); |
|
|
|
} |
|
|
|
|
|
|
|
OUT_PRINT(CMD_SRC_PC, dbg); |
|
|
|
} |
|
|
|
|
|
|
|
g_rs485_bridge_active = 0; |
|
|
|
@ -1637,6 +1730,7 @@ static void process_one_line_now(CmdSource src, const char *input_line) |
|
|
|
for (a = 1; a <= 31; a++) { |
|
|
|
scan_one_addr_rs485(a); |
|
|
|
} |
|
|
|
send_end_response(CMD_SRC_PC); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1914,7 +2008,7 @@ static void app_job_tick(void) |
|
|
|
g_app_runtime_job.current_scan_addr++; |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
send_end_response(CMD_SRC_PC); |
|
|
|
app_runtime_reset(); |
|
|
|
return; |
|
|
|
} |
|
|
|
|