Browse Source

modify

old-version
gudae 1 month ago
parent
commit
294d8e2eac
  1. BIN
      DefaultBuild/app_cmd_parser.obj
  2. BIN
      DefaultBuild/app_owi_service.obj
  3. BIN
      DefaultBuild/app_result.obj
  4. BIN
      DefaultBuild/app_scheduler.obj
  5. BIN
      DefaultBuild/gatectrl.obj
  6. BIN
      DefaultBuild/multical.abs
  7. 700
      DefaultBuild/multical.map
  8. 2921
      DefaultBuild/multical.mot
  9. BIN
      DefaultBuild/owi.obj
  10. BIN
      DefaultBuild/r_main.obj
  11. BIN
      DefaultBuild/uart.obj
  12. 20
      QualityReport(multical,DefaultBuild).txt
  13. 131
      app_cmd_parser.c
  14. 24
      app_types.h
  15. 3005
      multical.mtpj
  16. 2
      multical.rcpe
  17. 190
      multical.temp.mtud
  18. 128
      owi.c
  19. 45
      owi.h
  20. 216
      r_main.c
  21. 2
      uart.c

BIN
DefaultBuild/app_cmd_parser.obj

Binary file not shown.

BIN
DefaultBuild/app_owi_service.obj

Binary file not shown.

BIN
DefaultBuild/app_result.obj

Binary file not shown.

BIN
DefaultBuild/app_scheduler.obj

Binary file not shown.

BIN
DefaultBuild/gatectrl.obj

Binary file not shown.

BIN
DefaultBuild/multical.abs

Binary file not shown.

700
DefaultBuild/multical.map

File diff suppressed because it is too large

2921
DefaultBuild/multical.mot

File diff suppressed because it is too large

BIN
DefaultBuild/owi.obj

Binary file not shown.

BIN
DefaultBuild/r_main.obj

Binary file not shown.

BIN
DefaultBuild/uart.obj

Binary file not shown.

20
QualityReport(multical,DefaultBuild).txt

@ -1,22 +1,22 @@
QualityReport
2026년 3월 10일 화요일 오전 5:47:16
2026년 3월 10일 화요일 오후 3:54:12
------ Start build(multical, DefaultBuild) ------
------ Build ended(Error:0, Warning:0)(multical, DefaultBuild) ------
--- SHA1 hash value of output files ---
C:\Users\guseo\Desktop\new_fw\DefaultBuild\multical.abs: 92e3ea10b4980f36a64be50e2742704b9d4d675b
C:\Users\guseo\Desktop\new_fw\DefaultBuild\multical.mot: 63552288c18df90e0de3ff438441e543570b1204
C:\Users\temp\Desktop\new_fw\DefaultBuild\multical.abs: e144e2578b18d88b4cecc39ec3f958b951e2dc36
C:\Users\temp\Desktop\new_fw\DefaultBuild\multical.mot: 11c38870df999474ddbde22943e325e6360b3c55
--- System Information ---
*OS Version
Microsoft Windows 11 Home (-, 10.0.26200, WOW64)
Microsoft Windows 10 Pro (-, 10.0.19045, WOW64)
*Language
한국어(대한민국)
*.NET Framework Version
Microsoft .NET Framework 4 [.NET 4.8 or later] (533509)
Microsoft .NET Framework 4 [.NET 4.8 or later] (533325)
*WebView2 Version
145.0.3800.97
@ -35,13 +35,13 @@ C:\Users\guseo\Desktop\new_fw\DefaultBuild\multical.mot: 63552288c18df90e0de3ff4
C:\Program Files (x86)\Renesas Electronics\CS+\CC
*Memory Usage
*Private Working Set
418 MB
292 MB
*Number of GDI Objects
2736
2782
*Number of USER Objects
1718
1708
*Opened Files
20 editors, 20 files, 121 KB
30 editors, 30 files, 219 KB
--- Build Tool Plug-in Information ---
RH850 Build tool CC-RH Plug-in
@ -177,7 +177,7 @@ Device Information Common Interface
DeviceInformation.dll
--- Main Project Information ---
C:\Users\guseo\Desktop\new_fw\multical.mtpj
C:\Users\temp\Desktop\new_fw\multical.mtpj
Microcontroller Information
*R5F10PPJ
*File Name: Version

131
app_cmd_parser.c

@ -21,16 +21,40 @@ static int find_payload_pos(const char *line)
return (int)(p - line + 1);
}
static uint8_t hex_nibble(char c)
{
c = (char)toupper((unsigned char)c);
if (c >= '0' && c <= '9') return (uint8_t)(c - '0');
if (c >= 'A' && c <= 'F') return (uint8_t)(10 + (c - 'A'));
return 0xFFu;
}
static int hex_pair_to_u8(char hi, char lo, uint8_t *out)
{
uint8_t h = hex_nibble(hi);
uint8_t l = hex_nibble(lo);
if (h == 0xFFu || l == 0xFFu || !out) return 0;
*out = (uint8_t)((h << 4) | l);
return 1;
}
int app_cmd_parse_line(app_cmd_src_t src, const char *line, app_job_t *job)
{
uint8_t addr = 0;
int payload_pos;
int len;
int pos;
unsigned int k;
if (!line || !job) return 0;
memset(job, 0, sizeof(*job));
job->src = src;
job->check_on = 1;
len = (int)strlen(line);
/* ÀÏ¹Ý ¶óÀÎ */
if (line[0] != 'x' && line[0] != 'X') {
job->type = APP_JOB_LOCAL_EXEC;
strncpy(job->line, line, sizeof(job->line) - 1);
@ -38,37 +62,108 @@ int app_cmd_parse_line(app_cmd_src_t src, const char *line, app_job_t *job)
return 1;
}
/* xNNv */
if (parse_x_v_addr(line, &addr)) {
job->type = APP_JOB_SCAN_ADDR;
job->addr = addr;
strncpy(job->line, line, sizeof(job->line) - 1);
job->line[sizeof(job->line) - 1] = '\0';
return 1;
}
payload_pos = find_payload_pos(line);
if (payload_pos >= 0) {
const char *payload = &line[payload_pos];
if ((payload[0] == 'o' || payload[0] == 'O') &&
(payload[1] == 'w' || payload[1] == 'W')) {
job->type = APP_JOB_PROTO_OW;
strncpy(job->line, line, sizeof(job->line) - 1);
job->line[sizeof(job->line) - 1] = '\0';
return 1;
if (payload_pos < 0) {
job->type = APP_JOB_FORWARD_LINE;
strncpy(job->line, line, sizeof(job->line) - 1);
job->line[sizeof(job->line) - 1] = '\0';
return 1;
}
if (len < payload_pos) return 0;
if (!isdigit((unsigned char)line[1]) || !isdigit((unsigned char)line[2])) return 0;
job->addr = (uint8_t)((line[1] - '0') * 10 + (line[2] - '0'));
/* xNNc_001101:... ±âÁØ¿¡¼­ channel = 001 */
if (payload_pos >= 8 &&
isdigit((unsigned char)line[5]) &&
isdigit((unsigned char)line[6]) &&
isdigit((unsigned char)line[7])) {
job->channel = (uint8_t)((line[5] - '0') * 100 +
(line[6] - '0') * 10 +
(line[7] - '0'));
}
job->mode = (char)toupper((unsigned char)line[3]);
if (payload_pos >= 11) {
job->hash_on = (uint8_t)(line[8] == '1');
job->anaout_on = (uint8_t)(line[9] == '1');
job->check_on = (uint8_t)(line[10] == '1');
}
pos = payload_pos;
if (pos + 1 >= len) return 0;
if ((line[pos] == 'o' || line[pos] == 'O') &&
(line[pos + 1] == 'w' || line[pos + 1] == 'W')) {
job->type = APP_JOB_PROTO_OW;
pos += 2;
if (pos < len && (line[pos] == 't' || line[pos] == 'T')) {
job->proto = APP_PROTO_OWIT;
pos++;
} else {
job->proto = APP_PROTO_OWIW;
}
}
else if ((line[pos] == 'o' || line[pos] == 'O') &&
(line[pos + 1] == 'r' || line[pos + 1] == 'R')) {
job->type = APP_JOB_PROTO_OR;
job->proto = APP_PROTO_OWIR;
pos += 2;
}
else {
job->type = APP_JOB_FORWARD_LINE;
strncpy(job->line, line, sizeof(job->line) - 1);
job->line[sizeof(job->line) - 1] = '\0';
return 1;
}
if (pos < len && (line[pos] == '_' || line[pos] == ':')) pos++;
if (pos + 1 >= len) return 0;
if (!hex_pair_to_u8(line[pos], line[pos + 1], &job->id)) return 0;
pos += 2;
if (pos + 2 >= len ||
!isdigit((unsigned char)line[pos]) ||
!isdigit((unsigned char)line[pos + 1]) ||
!isdigit((unsigned char)line[pos + 2])) {
return 0;
}
job->len = (uint16_t)(100 * (line[pos] - '0') +
10 * (line[pos + 1] - '0') +
(line[pos + 2] - '0'));
pos += 3;
if (job->type == APP_JOB_PROTO_OW) {
if (job->len == 0 || job->len > APP_JOB_PAYLOAD_MAX) return 0;
if (pos + ((int)job->len * 2) > len) return 0;
if ((payload[0] == 'o' || payload[0] == 'O') &&
(payload[1] == 'r' || payload[1] == 'R')) {
job->type = APP_JOB_PROTO_OR;
strncpy(job->line, line, sizeof(job->line) - 1);
job->line[sizeof(job->line) - 1] = '\0';
return 1;
for (k = 0; k < job->len; k++) {
if (!hex_pair_to_u8(line[pos + (int)(2 * k)],
line[pos + (int)(2 * k + 1)],
&job->payload[k])) {
return 0;
}
}
} else {
if (job->len == 0 || job->len > APP_JOB_PAYLOAD_MAX) return 0;
}
job->type = APP_JOB_FORWARD_LINE;
strncpy(job->line, line, sizeof(job->line) - 1);
job->line[sizeof(job->line) - 1] = '\0';
return 1;
}

24
app_types.h

@ -1,8 +1,11 @@
#ifndef APP_TYPES_H
#define APP_TYPES_H
#include "r_cg_macrodriver.h"
#define APP_JOB_PAYLOAD_MAX 160
typedef enum {
APP_CMD_SRC_PC = 0,
APP_CMD_SRC_RS485 = 1
@ -17,12 +20,31 @@ typedef enum {
APP_JOB_LOCAL_EXEC
} app_job_type_t;
typedef enum {
APP_PROTO_NONE = 0,
APP_PROTO_OWIW,
APP_PROTO_OWIT,
APP_PROTO_OWIR
} app_proto_t;
typedef struct {
app_job_type_t type;
app_cmd_src_t src;
uint8_t addr;
uint8_t channel;
char line[320];
char mode;
uint8_t hash_on;
uint8_t anaout_on;
uint8_t check_on;
app_proto_t proto;
uint8_t id;
uint16_t len;
uint8_t payload[APP_JOB_PAYLOAD_MAX];
/* fallback용 짧은 line만 보관 */
char line[96];
} app_job_t;
#endif

3005
multical.mtpj

File diff suppressed because it is too large

2
multical.rcpe

@ -392,7 +392,7 @@
&lt;/RTC1HZ&gt;
&lt;RXD0 Name="RXD0" Text="enable" /&gt;
&lt;ProjectName Name="PrjName" Text="multical" /&gt;
&lt;ProjectPath Name="PrjPath" Text="C:\Users\guseo\Desktop\new_fw" /&gt;
&lt;ProjectPath Name="PrjPath" Text="C:\Users\temp\Desktop\new_fw" /&gt;
&lt;ProjectKind Name="PrjKind" Text="Project78K0R" /&gt;
&lt;DeviceName Name="DeviceName" Fixed="" Text="RL78F14" /&gt;
&lt;MCUName Name="MCUName" Text="RL78F14_100pin" /&gt;

190
multical.temp.mtud

File diff suppressed because one or more lines are too long

128
owi.c

@ -153,6 +153,73 @@ static void OWI_StopRead(void)
delay_us(TIDLE);
}
static uint8_t OWI_WaitFirstBitStart(void)
{
int timeout;
timeout = (int)(bit_period_us * 4u);
/* 첫 번째 HIGH->LOW 시작을 기다림 */
while (GPIO_Read() && timeout-- > 0) {
delay_us(1u);
}
if (timeout <= 0) {
if (!g_owi_timeout_latched) {
g_owi_timeout_latched = 1;
g_owi_last_timeout_byte_index = 0u;
g_owi_last_timeout_bit_index = 0u;
}
return 0u;
}
return 1u;
}
static uint8_t OWI_WaitForFallingEdge(uint16_t byte_index, uint8_t bit_index)
{
int timeout = (int)(bit_period_us * 4u);
while (GPIO_Read() && timeout-- > 0) {
delay_us(1u);
}
if (timeout <= 0) {
if (!g_owi_timeout_latched) {
g_owi_timeout_latched = 1;
g_owi_last_timeout_byte_index = byte_index;
g_owi_last_timeout_bit_index = bit_index;
}
return 0u;
}
return 1u;
}
static uint8_t OWI_ReadByte_StreamSynced(uint16_t byte_index)
{
uint8_t data = 0;
int b;
for (b = 7; b >= 0; b--) {
uint8_t bit_index = (uint8_t)(7 - b);
uint8_t bit;
g_owi_current_read_byte_index = byte_index;
g_owi_current_read_bit_index = bit_index;
/* 슬롯 시작 후 중앙 샘플 */
delay_us(bit_period_us / 2u);
bit = GPIO_Read() ? 1u : 0u;
data |= (uint8_t)(bit << b);
/* 남은 반 슬롯 대기 */
delay_us(bit_period_us / 2u);
}
return data;
}
void OWI_SecureStop(void)
{
int i;
@ -184,11 +251,16 @@ void OWI_WriteBit(int bit)
uint32_t t_low = bit ? (uint32_t)TLOW_1 : (uint32_t)TLOW_0;
uint32_t t_high = (uint32_t)TBIT - t_low;
/* HIGH 구간 */
OWI_Release();
delay_us(t_high);
/* LOW 구간 */
OWI_DriveLow();
delay_us(t_low);
/* 다음 슬롯 시작 전 반드시 release */
OWI_Release();
}
void OWI_WriteByte(uint8_t data)
@ -202,10 +274,27 @@ void OWI_WriteByte(uint8_t data)
uint8_t OWI_ReadBit(void)
{
uint8_t bit;
int timeout = (int)(bit_period_us * 2u);
int timeout;
int low_width = 0;
/* 1) 라인이 HIGH가 될 때까지 정리 */
timeout = (int)(bit_period_us * 2u);
while (!GPIO_Read() && timeout-- > 0) {
delay_us(1u);
}
if (timeout <= 0) {
if (!g_owi_timeout_latched) {
g_owi_timeout_latched = 1;
g_owi_last_timeout_byte_index = g_owi_current_read_byte_index;
g_owi_last_timeout_bit_index = g_owi_current_read_bit_index;
}
return 0u;
}
while (!(GPIO_Read()) && timeout-- > 0) {
/* 2) 다음 LOW 시작 대기 */
timeout = (int)(bit_period_us * 2u);
while (GPIO_Read() && timeout-- > 0) {
delay_us(1u);
}
@ -215,14 +304,21 @@ uint8_t OWI_ReadBit(void)
g_owi_last_timeout_byte_index = g_owi_current_read_byte_index;
g_owi_last_timeout_bit_index = g_owi_current_read_bit_index;
}
return 0u;
return 0u;
}
delay_us((bit_period_us * 1u) / 2u);
bit = (uint8_t)GPIO_Read();
delay_us((bit_period_us * 2u) / 5u);
/* 3) LOW가 유지되는 시간을 직접 측정 */
while (!GPIO_Read() && low_width < (int)(bit_period_us * 2u)) {
delay_us(1u);
low_width++;
}
return (bit ? 1u : 0u);
/* 4) LOW 폭 기준으로 판정
- 1
- 0
threshold ~= TBIT/2
*/
return (low_width < (int)(bit_period_us / 2u)) ? 1u : 0u;
}
uint8_t OWI_ReadByte(void)
@ -331,6 +427,7 @@ void OWI_CommandModeRaw(const uint8_t *tx_data, uint8_t tx_len, uint8_t id, owi_
int i;
owi_result_init(r);
OWI_Init(OWI_BIT_PERIOD_US);
OWI_ClearTimeout();
OWI_SecureStop();
@ -352,6 +449,7 @@ void OWI_ReadBytesRaw(int length, uint8_t id, owi_io_result_t *r)
if (!r) return;
owi_result_init(r);
OWI_Init(OWI_BIT_PERIOD_US);
if (length <= 0) {
r->ok = 0;
@ -364,15 +462,23 @@ void OWI_ReadBytesRaw(int length, uint8_t id, owi_io_result_t *r)
}
r->read_len = (uint16_t)length;
OWI_ClearTimeout();
OWI_SecureStop();
OWI_WriteByte((uint8_t)((id << 1) | 1u));
/* read 응답 준비 시간 */
delay_us(100u);
/* 첫 falling edge를 한 번만 잡는다 */
if (!OWI_WaitForFallingEdge(0u, 0u)) {
owi_result_latch_timeout(r);
OWI_StopRead();
return;
}
for (i = 0; i < length; i++) {
g_owi_current_read_byte_index = (uint16_t)i;
r->data[i] = OWI_ReadByte();
r->data[i] = OWI_ReadByte_StreamSynced((uint16_t)i);
if (OWI_HasTimeout()) {
owi_result_latch_timeout(r);

45
owi.h

@ -6,37 +6,30 @@
#include "r_cg_port.h"
#include <stdint.h>
/* =========================================================
* OWI GPIO: P70 (P7.0) + HW Open-Drain (POM7.0)
* ========================================================= */
#define OWI_PORT_P P7 /* port data (read/write latch) */
#define OWI_PORT_PM PM7 /* port mode (1=input, 0=output) */
#define OWI_PORT_PU PU7 /* pull-up enable */
#define OWI_PORT_POM POM7 /* open-drain enable */
/* P70 = bit0 */
#define OWI_PIN_MASK (1u << 0)
/* =========================================================
* Timing
* ========================================================= */
#define OWI_BIT_PERIOD_US 100u
#define OWI_PORT_P P7
#define OWI_PORT_PM PM7
#define OWI_PORT_PU PU7
#define OWI_PORT_POM POM7
#define OWI_PIN_MASK (1u << 0)
/* 먼저 1200us로 고정해서 테스트 */
#define OWI_BIT_PERIOD_US 1200u
#define TBIT OWI_BIT_PERIOD_US
#define TLOW_0 (TBIT * 0.75)
#define TLOW_1 (TBIT * 0.25)
#define TSTOP_LOW (TBIT * 2)
#define TIDLE (TBIT * 3)
#define TLOW_0 ((TBIT * 3u) / 4u)
#define TLOW_1 ((TBIT * 1u) / 4u)
#define TSTOP_LOW (TBIT * 2u)
#define TIDLE (TBIT * 3u)
#define TSTART_HOLD 50u
#define SECURE_HIGH 250u
#define SECURE_HIGH (2u * TBIT)
#define SECURE_TOGGLE_COUNT 3u
#define SECURE_TOGGLE_LOW 40u
#define SECURE_TOGGLE_HIGH 60u
#define SECURE_TOGGLE_LOW (TBIT / 4u)
#define SECURE_TOGGLE_HIGH (TBIT / 5u)
#ifndef RAM_BYTES
#define RAM_BYTES 3
#endif
#define OWI_IO_MAX_BYTES 64u
#define OWI_IO_MAX_BYTES 256u
typedef struct {
uint8_t ok;
@ -47,10 +40,6 @@ typedef struct {
uint8_t timeout_bit_index;
} owi_io_result_t;
/* =========================================================
* API
* ========================================================= */
void GPIO_Clear(void);
void GPIO_Input(void);
int GPIO_Read(void);
@ -84,4 +73,4 @@ void OWI_ClearTimeout(void);
uint16_t OWI_GetLastTimeoutByteIndex(void);
uint8_t OWI_GetLastTimeoutBitIndex(void);
#endif /* OWI_H */
#endif

216
r_main.c

@ -485,7 +485,10 @@ static void scan_one_addr_rs485(uint8_t addr)
RS485_FlushJunk(2, 100);
for (try = 0; try < 2; try++) {
for (try = 0; try < 1; try++) { /* 재시도도 우선 1회로 줄이기 */
uint32_t total_wait_us;
char linebuf[32];
if (g_rs485_need_recover) {
rs485_recover();
}
@ -502,25 +505,31 @@ static void scan_one_addr_rs485(uint8_t addr)
g_uart0_tx_done = 0;
RS485_PRINT(cmdline);
UART0_WaitTxDone_Flag(5000);
UART0_WaitTxDone_Flag(10000);
rs485_set_tx(0);
delay_us(250);
delay_us(500);
{
uint32_t total_wait_us = 8000;
char linebuf[32];
total_wait_us = 10000U;
while (total_wait_us >= 500U) {
int got = RS485_Bridge_ReadLine(linebuf, sizeof(linebuf), 500);
if (got) {
/* echo 라인은 무시 */
if (linebuf[0] == 'x' || linebuf[0] == 'X') {
total_wait_us -= 500U;
continue;
}
while (total_wait_us > 0) {
int got = RS485_Bridge_ReadLine(linebuf, sizeof(linebuf), 1000);
if (got && Is_V_Response_For(linebuf, addr)) {
if (Is_V_Response_For(linebuf, addr)) {
PC_PrintLine_CRLF(linebuf);
g_rs485_bridge_active = 0;
delay_us(500);
return;
}
if (total_wait_us >= 1000) total_wait_us -= 1000;
else total_wait_us = 0;
}
total_wait_us -= 500U;
}
g_rs485_bridge_active = 0;
@ -588,7 +597,21 @@ static void cmd_unknown(const unsigned char *d, unsigned int len)
static void print_owi_write_result(CmdSource src, const app_owi_result_t *r)
{
(void)r;
char msg[64];
if (!r) {
OUT_PRINT(src, "Err:owi_null\r\n");
return;
}
if (!r->ok || r->timeout) {
sprintf(msg, "51 !TO(B%u b%u)\r\n",
(unsigned)r->timeout_byte_index,
(unsigned)r->timeout_bit_index);
OUT_PRINT(src, msg);
return;
}
OUT_PRINT(src, "51\r\n");
}
@ -627,6 +650,109 @@ static void print_owi_read_result(CmdSource src, const app_owi_result_t *r)
OUT_PRINT(src, out);
}
static int execute_owi_service_from_job(CmdSource src, const app_job_t *job)
{
app_owi_result_t r;
if (!job) 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 (job->mode == 'C') {
s_prefix_mode = PREFIX_CAL;
Cal_Init();
} else {
s_prefix_mode = PREFIX_EOL;
Eol_Init();
}
Gate_SetByNum(job->channel, job->hash_on, job->anaout_on, job->check_on);
GateCtrl_SelectChannel(job->channel);
if (job->type == APP_JOB_PROTO_OW) {
if (job->proto == APP_PROTO_OWIT) {
r = app_owi_write_t_basic(job->id, job->payload, (uint8_t)job->len);
} else {
r = app_owi_write_basic(job->id, job->payload, (uint8_t)job->len);
}
print_owi_write_result(src, &r);
return 1;
}
if (job->type == APP_JOB_PROTO_OR) {
r = app_owi_read_basic(job->id, (int)job->len);
print_owi_read_result(src, &r);
return 1;
}
return 0;
}
static void forward_line_rs485_and_bridge(const char *line)
{
static char txbuf[UART_RX_BUF_SIZE + 4];
uint32_t total_us;
char linebuf[128];
int n;
uint8_t got_any_line = 0;
if (!line) return;
g_rs485_bridge_active = 1;
g_rs485_bridge_done = 0;
RS485_Bridge_ResetFifo();
rs485_rx_done = 0;
rs485_rx_index = 0;
rs485_rx_length = 0;
R_UART0_Receive((uint8_t*)&rs485_rx_buffer[0], 1);
n = (int)strlen(line);
if (n > (int)sizeof(txbuf) - 3) n = (int)sizeof(txbuf) - 3;
memcpy(txbuf, line, (size_t)n);
txbuf[n++] = '\r';
txbuf[n++] = '\n';
txbuf[n] = '\0';
g_uart0_tx_done = 0;
RS485_PRINT(txbuf);
/* scan_one_addr_rs485()와 동일하게 TX -> RX 전환 */
UART0_WaitTxDone_Flag(10000);
rs485_set_tx(0);
delay_us(500);
total_us = 100000U; /* 100 ms */
while (total_us >= 1000U) {
int got = RS485_Bridge_ReadLine(linebuf, sizeof(linebuf), 1000);
if (got) {
/* 자기 echo 무시 */
if (linebuf[0] == 'x' || linebuf[0] == 'X') {
total_us -= 1000U;
continue;
}
PC_PrintLine_CRLF(linebuf);
got_any_line = 1;
break;
}
total_us -= 1000U;
}
if (!got_any_line) {
OUT_PRINT(CMD_SRC_PC, "Err:rs485_no_response\r\n");
}
g_rs485_bridge_active = 0;
}
static int execute_owi_service_from_line(CmdSource src, const char *line)
{
uint8_t addr = 0, ch = 0;
@ -1186,6 +1312,18 @@ static void process_one_line(CmdSource src, const volatile uint8_t *rx_buf, uint
idx = build_line_from_rx(rx_buf, (int)rx_len, line, (int)sizeof(line));
if (idx <= 0) return;
/* RS485 xNNv는 큐를 타지 말고 즉시 응답 */
if (src == CMD_SRC_RS485) {
uint8_t vaddr = 0;
if (parse_x_v_cmd(line, idx, &vaddr)) {
if (vaddr == g_fixed_addr) {
send_v_response(CMD_SRC_RS485, g_fixed_addr);
}
return;
}
}
if (src == CMD_SRC_RS485) {
if (!(line[0] == 'x' || line[0] == 'X')) return;
}
@ -1239,38 +1377,58 @@ static void app_job_tick(void)
return;
}
/* 기존 x00v on master(0) from PC 만 분할 실행 */
if (g_fixed_addr == 0 && src == CMD_SRC_PC && scan_addr == 0) {
/* 마스터 x00v */
if (g_fixed_addr == 0 && src == CMD_SRC_PC && scan_addr == 0) {
if (!g_app_runtime_job.scan_started) {
send_v_response(CMD_SRC_PC, 0);
g_app_runtime_job.scan_started = 1;
g_app_runtime_job.current_scan_addr = 1;
return;
send_v_response(CMD_SRC_PC, 0);
g_app_runtime_job.scan_started = 1;
g_app_runtime_job.current_scan_addr = 1;
return;
}
if (g_app_runtime_job.current_scan_addr <= 31) {
scan_one_addr_rs485(g_app_runtime_job.current_scan_addr);
g_app_runtime_job.current_scan_addr++;
return;
scan_one_addr_rs485(g_app_runtime_job.current_scan_addr);
g_app_runtime_job.current_scan_addr++;
return;
}
app_runtime_reset();
return;
}
}
/* 슬레이브 xNNv 직접 처리 */
if (scan_addr == g_fixed_addr) {
send_v_response(src, g_fixed_addr);
}
app_runtime_reset();
return;
/* 나머지는 기존 실행 경로 그대로 */
process_one_line_now(src, g_app_runtime_job.job.line);
app_runtime_reset();
return;
case APP_JOB_PROTO_OW:
case APP_JOB_PROTO_OW:
case APP_JOB_PROTO_OR:
if (!execute_owi_service_from_line(src, g_app_runtime_job.job.line)) {
/* service로 못 처리하면 기존 경로로 fallback */
process_one_line_now(src, g_app_runtime_job.job.line);
if (g_app_runtime_job.job.addr == g_fixed_addr) {
if (!execute_owi_service_from_job(src, &g_app_runtime_job.job)) {
OUT_PRINT(src, "Err:job_exec\r\n");
}
app_runtime_reset();
return;
}
app_runtime_reset();
return;
/* 마스터가 PC 명령을 원격 보드로 forwarding */
if (g_fixed_addr == 0 && src == CMD_SRC_PC && g_app_runtime_job.job.addr != 0) {
forward_line_rs485_and_bridge(g_app_runtime_job.job.line);
app_runtime_reset();
return;
}
OUT_PRINT(src, "Err:job_exec\r\n");
app_runtime_reset();
return;
case APP_JOB_FORWARD_LINE:
case APP_JOB_LOCAL_EXEC:

2
uart.c

@ -13,7 +13,7 @@ volatile uint8_t g_uart1_tx_done = 1;
extern volatile uint16_t g_uart1_tx_count;
extern volatile uint8_t rs485_rx_done;
extern volatile uint8_t rs485_rx_index;
extern volatile uint16_t rs485_rx_index;
extern volatile uint16_t rs485_rx_length;
extern volatile uint8_t rs485_rx_buffer[];

Loading…
Cancel
Save