Compare commits
16 Commits
master
...
developmen
| Author | SHA1 | Date |
|---|---|---|
|
|
d83cbec862 | 1 day ago |
|
|
f99d2cd6c7 | 1 day ago |
|
|
f5dfae3549 | 2 days ago |
|
|
a2f046d7ab | 3 weeks ago |
|
|
befdc9c6bf | 3 weeks ago |
|
|
3800ba2a4a | 1 month ago |
|
|
592e0faa24 | 1 month ago |
|
|
bc6bd16e70 | 1 month ago |
|
|
06263ffdd9 | 1 month ago |
|
|
601c3256ed | 1 month ago |
|
|
37d1564bb6 | 1 month ago |
|
|
294d8e2eac | 1 month ago |
|
|
2dcaa0c406 | 1 month ago |
|
|
c0dd680c5f | 2 months ago |
|
|
304e882ce8 | 2 months ago |
|
|
d5a978ba62 | 2 months ago |
61 changed files with 5713 additions and 2593 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
File diff suppressed because it is too large
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,181 @@ |
|||
#include "app_cmd_parser.h" |
|||
#include <string.h> |
|||
#include <ctype.h> |
|||
|
|||
static int parse_x_v_addr(const char *line, uint8_t *addr) |
|||
{ |
|||
if (!line || !addr) return 0; |
|||
if (!(line[0] == 'x' || line[0] == 'X')) return 0; |
|||
if (!isdigit((unsigned char)line[1]) || !isdigit((unsigned char)line[2])) return 0; |
|||
if (!(line[3] == 'v' || line[3] == 'V')) return 0; |
|||
if (line[4] != '\0') return 0; |
|||
|
|||
*addr = (uint8_t)((line[1] - '0') * 10 + (line[2] - '0')); |
|||
return 1; |
|||
} |
|||
|
|||
static int find_payload_pos(const char *line) |
|||
{ |
|||
const char *p = strchr(line, ':'); |
|||
if (!p) return -1; |
|||
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; |
|||
|
|||
/* ?? ?? ?? ?? */ |
|||
strncpy(job->line, line, sizeof(job->line) - 1); |
|||
job->line[sizeof(job->line) - 1] = '\0'; |
|||
|
|||
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); |
|||
job->line[sizeof(job->line) - 1] = '\0'; |
|||
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) { |
|||
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; |
|||
|
|||
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; |
|||
} |
|||
} |
|||
pos += (int)job->len * 2; |
|||
|
|||
/* payload ?? ??? ? ??? parse ?? */ |
|||
if (pos != len) return 0; |
|||
|
|||
} else { |
|||
if (job->len == 0 || job->len > APP_JOB_PAYLOAD_MAX) return 0; |
|||
|
|||
/* OR? payload? ??? ??? len ?? ?? ??? ? */ |
|||
if (pos != len) return 0; |
|||
} |
|||
|
|||
return 1; |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
#ifndef APP_CMD_PARSER_H |
|||
#define APP_CMD_PARSER_H |
|||
|
|||
#include "app_types.h" |
|||
|
|||
int app_cmd_parse_line(app_cmd_src_t src, const char *line, app_job_t *job); |
|||
|
|||
#endif |
|||
@ -0,0 +1,140 @@ |
|||
#include "app_owi_service.h" |
|||
#include "owi.h" |
|||
#include "delay.h" |
|||
#include "r_cg_wdt.h" |
|||
#include <string.h> |
|||
|
|||
static app_owi_result_t app_owi_from_raw(const owi_io_result_t *io) |
|||
{ |
|||
app_owi_result_t r; |
|||
uint16_t i; |
|||
|
|||
memset(&r, 0, sizeof(r)); |
|||
|
|||
if (!io) { |
|||
r.ok = 0; |
|||
return r; |
|||
} |
|||
|
|||
r.ok = io->ok; |
|||
r.timeout = io->timeout; |
|||
r.read_len = io->read_len; |
|||
r.timeout_byte_index = io->timeout_byte_index; |
|||
r.timeout_bit_index = io->timeout_bit_index; |
|||
|
|||
for (i = 0; i < io->read_len && i < OWI_IO_MAX_BYTES; i++) { |
|||
r.data[i] = io->data[i]; |
|||
} |
|||
|
|||
return r; |
|||
} |
|||
|
|||
static uint8_t is_long_owi_read(int length) |
|||
{ |
|||
return (length == 119 || length == 127) ? 1u : 0u; |
|||
} |
|||
|
|||
static uint8_t looks_bad_tail(const owi_io_result_t *io) |
|||
{ |
|||
uint16_t i; |
|||
uint8_t zero_run = 0; |
|||
uint8_t ff_run = 0; |
|||
|
|||
if (!io) return 1u; |
|||
if (io->read_len < 24u) return 1u; |
|||
|
|||
for (i = (uint16_t)(io->read_len - 24u); i < io->read_len; i++) { |
|||
uint8_t b = io->data[i]; |
|||
|
|||
if (b == 0x00u) zero_run++; |
|||
else zero_run = 0; |
|||
|
|||
if (b == 0xFFu) ff_run++; |
|||
else ff_run = 0; |
|||
|
|||
/* tail ?? 8??? ?? ?? 00/FF? ??? */ |
|||
if (zero_run >= 8u || ff_run >= 8u) { |
|||
return 1u; |
|||
} |
|||
} |
|||
|
|||
return 0u; |
|||
} |
|||
|
|||
/* ? ? ?? 4???? ?? 00 ?? ?? FF? ????? ?? */ |
|||
static uint8_t looks_bad_last_bytes(const owi_io_result_t *io) |
|||
{ |
|||
uint16_t start; |
|||
uint8_t i; |
|||
uint8_t all_zero = 1u; |
|||
uint8_t all_ff = 1u; |
|||
|
|||
if (!io) return 1u; |
|||
if (io->read_len < 3u) return 1u; |
|||
|
|||
start = (uint16_t)(io->read_len - 3u); |
|||
|
|||
for (i = 0; i < 3u; i++) { |
|||
uint8_t b = io->data[start + i]; |
|||
|
|||
if (b != 0x00u) all_zero = 0u; |
|||
if (b != 0xFFu) all_ff = 0u; |
|||
} |
|||
|
|||
return (uint8_t)(all_zero || all_ff); |
|||
} |
|||
|
|||
static uint8_t needs_retry_for_long_read(const owi_io_result_t *io, int length) |
|||
{ |
|||
if (!is_long_owi_read(length)) return 0u; |
|||
if (!io) return 1u; |
|||
|
|||
if (!io->ok) return 1u; |
|||
if (io->timeout) return 1u; |
|||
if (io->read_len < (uint16_t)length) return 1u; |
|||
if (looks_bad_tail(io)) return 1u; |
|||
if (looks_bad_last_bytes(io)) return 1u; |
|||
|
|||
return 0u; |
|||
} |
|||
|
|||
app_owi_result_t app_owi_read_basic(uint8_t id, int length) |
|||
{ |
|||
owi_io_result_t io; |
|||
|
|||
R_WDT_Restart(); |
|||
OWI_ReadBytesRaw(length, id, &io); |
|||
R_WDT_Restart(); |
|||
|
|||
if (needs_retry_for_long_read(&io, length)) { |
|||
R_WDT_Restart(); |
|||
delay_us(3000u); |
|||
R_WDT_Restart(); |
|||
OWI_ReadBytesRaw(length, id, &io); |
|||
R_WDT_Restart(); |
|||
|
|||
/* ??? ??? ???? ?? ?? */ |
|||
if (needs_retry_for_long_read(&io, length)) { |
|||
io.ok = 0u; |
|||
io.timeout = 1u; |
|||
io.timeout_byte_index = 0xFFFEu; |
|||
io.timeout_bit_index = 0xFEu; |
|||
} |
|||
} |
|||
|
|||
return app_owi_from_raw(&io); |
|||
} |
|||
|
|||
app_owi_result_t app_owi_write_basic(uint8_t id, const uint8_t *tx_data, uint8_t tx_len) |
|||
{ |
|||
owi_io_result_t io; |
|||
OWI_CommandModeRaw(tx_data, tx_len, id, &io); |
|||
return app_owi_from_raw(&io); |
|||
} |
|||
|
|||
app_owi_result_t app_owi_write_t_basic(uint8_t id, const uint8_t *tx_data, uint8_t tx_len) |
|||
{ |
|||
owi_io_result_t io; |
|||
OWI_T_CommandModeRaw(tx_data, tx_len, id, &io); |
|||
return app_owi_from_raw(&io); |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
#ifndef APP_OWI_SERVICE_H |
|||
#define APP_OWI_SERVICE_H |
|||
|
|||
#include "r_cg_macrodriver.h" |
|||
#include "owi.h" |
|||
|
|||
typedef struct { |
|||
uint8_t ok; |
|||
uint8_t timeout; |
|||
uint16_t read_len; |
|||
uint8_t data[OWI_IO_MAX_BYTES]; |
|||
uint16_t timeout_byte_index; |
|||
uint8_t timeout_bit_index; |
|||
} app_owi_result_t; |
|||
|
|||
app_owi_result_t app_owi_read_basic(uint8_t id, int length); |
|||
app_owi_result_t app_owi_write_basic(uint8_t id, const uint8_t *tx_data, uint8_t tx_len); |
|||
app_owi_result_t app_owi_write_t_basic(uint8_t id, const uint8_t *tx_data, uint8_t tx_len); |
|||
|
|||
#endif |
|||
@ -0,0 +1,12 @@ |
|||
#include "app_result.h" |
|||
#include "uart.h" |
|||
|
|||
void app_result_print_ok(const char *msg) |
|||
{ |
|||
uart1_send_string(msg); |
|||
} |
|||
|
|||
void app_result_print_err(const char *msg) |
|||
{ |
|||
uart1_send_string(msg); |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
#ifndef APP_RESULT_H |
|||
#define APP_RESULT_H |
|||
|
|||
void app_result_print_ok(const char *msg); |
|||
void app_result_print_err(const char *msg); |
|||
|
|||
#endif |
|||
@ -0,0 +1,51 @@ |
|||
#include "app_scheduler.h" |
|||
#include <string.h> |
|||
|
|||
#define APP_JOB_QUEUE_SIZE 8 |
|||
|
|||
static app_job_t g_queue[APP_JOB_QUEUE_SIZE]; |
|||
static uint8_t g_head; |
|||
static uint8_t g_tail; |
|||
static uint8_t g_count; |
|||
|
|||
void app_scheduler_init(void) |
|||
{ |
|||
g_head = 0; |
|||
g_tail = 0; |
|||
g_count = 0; |
|||
memset(g_queue, 0, sizeof(g_queue)); |
|||
} |
|||
|
|||
int app_scheduler_push(const app_job_t *job) |
|||
{ |
|||
if (!job) return 0; |
|||
if (g_count >= APP_JOB_QUEUE_SIZE) return 0; |
|||
|
|||
g_queue[g_tail] = *job; |
|||
g_tail = (uint8_t)((g_tail + 1U) % APP_JOB_QUEUE_SIZE); |
|||
g_count++; |
|||
return 1; |
|||
} |
|||
|
|||
int app_scheduler_pop(app_job_t *job) |
|||
{ |
|||
if (!job) return 0; |
|||
if (g_count == 0) return 0; |
|||
|
|||
*job = g_queue[g_head]; |
|||
g_head = (uint8_t)((g_head + 1U) % APP_JOB_QUEUE_SIZE); |
|||
g_count--; |
|||
return 1; |
|||
} |
|||
|
|||
int app_scheduler_is_empty(void) |
|||
{ |
|||
return (g_count == 0U); |
|||
} |
|||
void app_scheduler_clear(void) |
|||
{ |
|||
g_head = 0; |
|||
g_tail = 0; |
|||
g_count = 0; |
|||
memset(g_queue, 0, sizeof(g_queue)); |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
#ifndef APP_SCHEDULER_H |
|||
#define APP_SCHEDULER_H |
|||
|
|||
#include "app_types.h" |
|||
|
|||
void app_scheduler_init(void); |
|||
int app_scheduler_push(const app_job_t *job); |
|||
int app_scheduler_pop(app_job_t *job); |
|||
int app_scheduler_is_empty(void); |
|||
void app_scheduler_clear(void); |
|||
|
|||
#endif |
|||
@ -0,0 +1,51 @@ |
|||
|
|||
#ifndef APP_TYPES_H |
|||
#define APP_TYPES_H |
|||
|
|||
#include "r_cg_macrodriver.h" |
|||
|
|||
#define APP_JOB_PAYLOAD_MAX 320 |
|||
#define APP_JOB_LINE_MAX 320 |
|||
|
|||
typedef enum { |
|||
APP_CMD_SRC_PC = 0, |
|||
APP_CMD_SRC_RS485 = 1 |
|||
} app_cmd_src_t; |
|||
|
|||
typedef enum { |
|||
APP_JOB_NONE = 0, |
|||
APP_JOB_SCAN_ADDR, |
|||
APP_JOB_PROTO_OW, |
|||
APP_JOB_PROTO_OR, |
|||
APP_JOB_FORWARD_LINE, |
|||
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 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[APP_JOB_LINE_MAX]; |
|||
} app_job_t; |
|||
|
|||
#endif |
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Loading…
Reference in new issue