Compare commits

...

21 Commits

  1. 596
      1/owi.c
  2. 602
      2/owi.c
  3. 666
      3/owi.c
  4. BIN
      DefaultBuild/app_cmd_parser.obj
  5. BIN
      DefaultBuild/app_owi_service.obj
  6. BIN
      DefaultBuild/app_result.obj
  7. BIN
      DefaultBuild/app_scheduler.obj
  8. BIN
      DefaultBuild/cstart.obj
  9. BIN
      DefaultBuild/delay.obj
  10. BIN
      DefaultBuild/dipSwitch.obj
  11. BIN
      DefaultBuild/gatectrl.obj
  12. BIN
      DefaultBuild/i2c.obj
  13. BIN
      DefaultBuild/multical.abs
  14. 8
      DefaultBuild/multical.clnk
  15. 832
      DefaultBuild/multical.map
  16. 3100
      DefaultBuild/multical.mot
  17. BIN
      DefaultBuild/owi.obj
  18. BIN
      DefaultBuild/r_cg_cgc.obj
  19. BIN
      DefaultBuild/r_cg_cgc_user.obj
  20. BIN
      DefaultBuild/r_cg_port.obj
  21. BIN
      DefaultBuild/r_cg_port_user.obj
  22. BIN
      DefaultBuild/r_cg_serial.obj
  23. BIN
      DefaultBuild/r_cg_serial_user.obj
  24. BIN
      DefaultBuild/r_cg_wdt.obj
  25. BIN
      DefaultBuild/r_cg_wdt_user.obj
  26. BIN
      DefaultBuild/r_main.obj
  27. BIN
      DefaultBuild/r_systeminit.obj
  28. BIN
      DefaultBuild/stkinit.obj
  29. BIN
      DefaultBuild/uart.obj
  30. 118
      QualityReport(multical,DefaultBuild).txt
  31. 181
      app_cmd_parser.c
  32. 8
      app_cmd_parser.h
  33. 221
      app_owi_service.c
  34. 20
      app_owi_service.h
  35. 12
      app_result.c
  36. 7
      app_result.h
  37. 51
      app_scheduler.c
  38. 12
      app_scheduler.h
  39. 51
      app_types.h
  40. 117
      gatectrl.c
  41. 218
      multical.MSI.mtud
  42. 6673
      multical.guseo.mtud
  43. 247
      multical.mtpj
  44. 52
      multical.rcpe
  45. 281
      multical.temp.mtud
  46. 523
      owi.c
  47. 62
      owi.h
  48. 2
      r_cg_cgc.c
  49. 2
      r_cg_cgc.h
  50. 2
      r_cg_cgc_user.c
  51. 2
      r_cg_macrodriver.h
  52. 2
      r_cg_port.c
  53. 2
      r_cg_port.h
  54. 2
      r_cg_port_user.c
  55. 2
      r_cg_serial.c
  56. 2
      r_cg_serial.h
  57. 107
      r_cg_serial_user.c
  58. 2
      r_cg_userdefine.h
  59. 6
      r_cg_wdt.c
  60. 2
      r_cg_wdt.h
  61. 15
      r_cg_wdt_user.c
  62. 1894
      r_main.c
  63. 4
      r_systeminit.c
  64. 38
      uart.c

596
1/owi.c

@ -0,0 +1,596 @@
#include "owi.h"
/*
* Test 1: bit-period-only variant.
* This local override keeps the replacement self-contained in owi.c.
* TBIT and all timing macros in owi.h expand from this value at use time.
*/
#undef OWI_BIT_PERIOD_US
#define OWI_BIT_PERIOD_US 2000u
#include "delay.h"
#include "r_cg_wdt.h"
#include <string.h>
#include <stdio.h>
#include "uart.h"
#include "r_cg_wdt.h"
#ifndef OWI_STRONG_DRIVE_HIGH_US
#define OWI_STRONG_DRIVE_HIGH_US 5u
#endif
/* 내부 상태 */
static uint32_t bit_period_us = OWI_BIT_PERIOD_US;
static uint8_t g_owi_timeout_latched = 0;
static uint16_t g_owi_last_timeout_byte_index = 0xFFFFu;
static uint8_t g_owi_last_timeout_bit_index = 0xFFu;
static uint16_t g_owi_current_read_byte_index = 0u;
static uint8_t g_owi_current_read_bit_index = 0u;
/* =========================================================
* GPIO helpers (P70 / HW Open-Drain)
* - LOW : + 0
* - HIGH : (Hi-Z) release
* ========================================================= */
void GPIO_Clear(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
}
void GPIO_Input(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PM |= (uint8_t)OWI_PIN_MASK;
}
int GPIO_Read(void)
{
return (OWI_PORT_P & (uint8_t)OWI_PIN_MASK) ? 1 : 0;
}
static void OWI_Release(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PM |= (uint8_t)OWI_PIN_MASK;
}
static void GPIO_StrongDriveHighKick(uint32_t kick_us)
{
OWI_Release();
if (!GPIO_Read()) {
return;
}
OWI_PORT_POM &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_P |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
delay_us(kick_us);
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_Release();
}
void GPIO_ForceHighKick(void)
{
GPIO_StrongDriveHighKick(OWI_STRONG_DRIVE_HIGH_US);
}
static void OWI_DriveLow(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
}
/* =========================================================
* Diagnostics
* ========================================================= */
uint8_t OWI_HasTimeout(void)
{
return g_owi_timeout_latched;
}
void OWI_ClearTimeout(void)
{
g_owi_timeout_latched = 0;
g_owi_last_timeout_byte_index = 0xFFFFu;
g_owi_last_timeout_bit_index = 0xFFu;
}
uint16_t OWI_GetLastTimeoutByteIndex(void)
{
return g_owi_last_timeout_byte_index;
}
uint8_t OWI_GetLastTimeoutBitIndex(void)
{
return g_owi_last_timeout_bit_index;
}
/* =========================================================
* OWI Init
* ========================================================= */
void OWI_Init(uint32_t bit_time_us)
{
bit_period_us = bit_time_us;
(void)bit_period_us;
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PU &= (uint8_t)~OWI_PIN_MASK;
OWI_ClearTimeout();
GPIO_Input();
}
/* =========================================================
* Start/Stop/Secure
* ========================================================= */
void OWI_Start(void)
{
GPIO_Clear();
delay_us(TSTART_HOLD);
GPIO_Input();
delay_us(TBIT);
}
void OWI_Stop(void)
{
GPIO_Input();
delay_us(TSTOP_LOW);
delay_us(TIDLE);
}
static void OWI_StopWrite(void)
{
OWI_Release();
delay_us(TSTOP_LOW);
delay_us(TIDLE);
}
static void OWI_StopRead(void)
{
OWI_DriveLow();
delay_us(TSTOP_LOW);
OWI_Release();
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;
GPIO_Clear();
delay_us(SECURE_HIGH);
for (i = 0; i < (int)SECURE_TOGGLE_COUNT; i++) {
GPIO_Input();
delay_us(SECURE_TOGGLE_HIGH);
GPIO_Clear();
delay_us(SECURE_TOGGLE_LOW);
}
GPIO_Input();
delay_us(SECURE_HIGH);
GPIO_Clear();
delay_us(TSTART_HOLD);
GPIO_Input();
}
/* =========================================================
* Bit/Byte IO
* ========================================================= */
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)
{
int i;
for (i = 7; i >= 0; i--) {
OWI_WriteBit((data >> i) & 0x01u);
}
GPIO_Input();
}
uint8_t OWI_ReadBit(void)
{
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;
}
/* 2) 다음 LOW 시작 대기 */
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;
}
/* 3) LOW가 유지되는 시간을 직접 측정 */
while (!GPIO_Read() && low_width < (int)(bit_period_us * 2u)) {
delay_us(1u);
low_width++;
}
/* 4) LOW 폭 기준으로 판정
- 1
- 0
threshold ~= TBIT/2
*/
return (low_width < (int)(bit_period_us / 2u)) ? 1u : 0u;
}
uint8_t OWI_ReadByte(void)
{
uint8_t data = 0;
int i;
for (i = 7; i >= 0; i--) {
g_owi_current_read_bit_index = (uint8_t)(7 - i);
data |= (uint8_t)(OWI_ReadBit() << i);
if (OWI_HasTimeout()) {
break;
}
}
return data;
}
/* =========================================================
* Debug Print
* ========================================================= */
void OWI_T_ReadBytesAndPrint(int length)
{
uint8_t buf[129];
int i;
char uart_buf[8];
char tmp_buf[8];
uint8_t va0, va1;
if (length > 129) length = 129;
if (length <= 0) return;
OWI_ClearTimeout();
for (i = 0; i < length; i++) {
R_WDT_Restart();
g_owi_current_read_byte_index = (uint16_t)i;
buf[i] = OWI_ReadByte();
if (OWI_HasTimeout()) {
i++;
break;
}
}
sprintf(uart_buf, "%02X ", buf[0]);
strcpy(tmp_buf, uart_buf);
HOST_PRINT(tmp_buf);
for (i = 1; i < length; i += 2) {
va0 = buf[i];
va1 = (uint8_t)((i + 1 < length) ? buf[i + 1] : 0u);
delay_us(200);
sprintf(uart_buf, "%02X%02X ", va0, va1);
strcpy(tmp_buf, uart_buf);
HOST_PRINT(tmp_buf);
delay_us(200);
}
}
/* =========================================================
* Raw helpers
* ========================================================= */
static void owi_result_init(owi_io_result_t *r)
{
if (!r) return;
memset(r, 0, sizeof(*r));
r->ok = 1;
r->timeout_byte_index = 0xFFFFu;
r->timeout_bit_index = 0xFFu;
}
static void owi_result_latch_timeout(owi_io_result_t *r)
{
if (!r) return;
if (OWI_HasTimeout()) {
r->ok = 0;
r->timeout = 1;
r->timeout_byte_index = OWI_GetLastTimeoutByteIndex();
r->timeout_bit_index = OWI_GetLastTimeoutBitIndex();
}
}
void OWI_T_CommandModeRaw(const uint8_t *tx_data, uint8_t tx_len, uint8_t id, owi_io_result_t *r)
{
int i;
owi_result_init(r);
//delay_us(200);
OWI_Init(OWI_BIT_PERIOD_US);
OWI_ClearTimeout();
R_WDT_Restart();
OWI_SecureStop();
R_WDT_Restart();
OWI_WriteByte((uint8_t)(id << 1));
R_WDT_Restart();
for (i = 0; i < (int)tx_len; i++) {
R_WDT_Restart();
OWI_WriteByte(tx_data[i]);
R_WDT_Restart();
}
OWI_Stop();
R_WDT_Restart();
owi_result_latch_timeout(r);
}
void OWI_CommandModeRaw(const uint8_t *tx_data, uint8_t tx_len, uint8_t id, owi_io_result_t *r)
{
int i;
owi_result_init(r);
OWI_Init(OWI_BIT_PERIOD_US);
OWI_ClearTimeout();
R_WDT_Restart();
OWI_SecureStop();
R_WDT_Restart();
OWI_WriteByte((uint8_t)(id << 1));
R_WDT_Restart();
for (i = 0; i < (int)tx_len; i++) {
R_WDT_Restart();
OWI_WriteByte(tx_data[i]);
R_WDT_Restart();
}
OWI_Stop();
R_WDT_Restart();
owi_result_latch_timeout(r);
}
void OWI_ReadBytesRaw(int length, uint8_t id, owi_io_result_t *r)
{
int i;
int max_len;
uint8_t is_long_read;
if (!r) return;
owi_result_init(r);
OWI_Init(OWI_BIT_PERIOD_US);
if (length <= 0) {
r->ok = 0;
return;
}
max_len = (int)OWI_IO_MAX_BYTES;
if (length > max_len) {
length = max_len;
}
r->read_len = (uint16_t)length;
OWI_ClearTimeout();
/* Only 119 keeps the established mid-stream sync. */
is_long_read = (length == 119) ? 1u : 0u;
R_WDT_Restart();
OWI_SecureStop();
OWI_WriteByte((uint8_t)((id << 1) | 1u));
/*
* For 129 bytes, wait for the first edge immediately after the read ID.
* The old 100us delay could enter an already-started first pulse.
* Preserve the established delay for every other read length.
*/
if (length != 129) {
delay_us(100u);
}
R_WDT_Restart();
if (!OWI_WaitForFallingEdge(0u, 0u)) {
owi_result_latch_timeout(r);
OWI_StopRead();
return;
}
for (i = 0; i < length; i++) {
R_WDT_Restart();
/* Preserve the existing mid-stream sync for the 119-byte path only. */
if (is_long_read && i == (length - 50)) {
R_WDT_Restart();
if (!OWI_WaitForFallingEdge((uint16_t)i, 0u)) {
owi_result_latch_timeout(r);
break;
}
}
r->data[i] = OWI_ReadByte_StreamSynced((uint16_t)i);
if (OWI_HasTimeout()) {
owi_result_latch_timeout(r);
break;
}
}
OWI_StopRead();
}
void OWI_disable(void)
{
HOST_PRINT("51\r\n");
}
void OWI_T_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id)
{
owi_io_result_t r;
(void)r;
OWI_T_CommandModeRaw(tx_data, tx_len, id, &r);
HOST_PRINT("51\r\n");
}
void OWI_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id)
{
owi_io_result_t r;
(void)r;
OWI_CommandModeRaw(tx_data, tx_len, id, &r);
HOST_PRINT("51\r\n");
}
void OWI_ReadBytesAndPrint(int length, uint8_t id)
{
owi_io_result_t r;
char out[(2 * OWI_IO_MAX_BYTES) + 40];
int i;
uint16_t p = 0;
if (length <= 0) {
HOST_PRINT("Err:read_len_nonzero\r\n");
return;
}
OWI_ReadBytesRaw(length, id, &r);
if (r.read_len == 0) {
HOST_PRINT("Err:read_len_nonzero\r\n");
return;
}
for (i = 0; i < (int)r.read_len; i++) {
uint8_t b = r.data[i];
out[p++] = "0123456789ABCDEF"[b >> 4];
out[p++] = "0123456789ABCDEF"[b & 0x0F];
}
if (r.timeout) {
p += (uint16_t)sprintf(&out[p], " !TO(B%u b%u)",
(unsigned)r.timeout_byte_index,
(unsigned)r.timeout_bit_index);
}
out[p++] = '\r';
out[p++] = '\n';
out[p] = '\0';
HOST_PRINT(out);
}

602
2/owi.c

@ -0,0 +1,602 @@
#include "owi.h"
#include "delay.h"
#include "r_cg_wdt.h"
#include <string.h>
#include <stdio.h>
#include "uart.h"
#include "r_cg_wdt.h"
#ifndef OWI_STRONG_DRIVE_HIGH_US
#define OWI_STRONG_DRIVE_HIGH_US 5u
#endif
/*
* Test 2 hardware time base
* -------------------------
* Project clock: fCLK = 32 MHz
* TAU0 channel 5: CK03 = fCLK / 32 = 1 MHz (one count per microsecond)
*
* Channel 5 and CK03 are otherwise unused by this project. Only the CK03
* field of TPS0 is changed, so CK00 to CK02 remain untouched.
*/
#define OWI_TIMER_CHANNEL_MASK 0x0020u
#define OWI_TIMER_CK03_DIV32 0x5000u
#define OWI_TIMER_TMR_CK03_INTERVAL 0xC000u
/* 내부 상태 */
static uint32_t bit_period_us = OWI_BIT_PERIOD_US;
static uint8_t g_owi_timeout_latched = 0;
static uint16_t g_owi_last_timeout_byte_index = 0xFFFFu;
static uint8_t g_owi_last_timeout_bit_index = 0xFFu;
static uint16_t g_owi_current_read_byte_index = 0u;
static uint8_t g_owi_current_read_bit_index = 0u;
static uint16_t g_owi_next_sample_tick = 0u;
static void OWI_TimerStart1MHz(void)
{
TAU0EN = 1U;
NOP();
NOP();
NOP();
NOP();
TT0 |= (uint16_t)OWI_TIMER_CHANNEL_MASK;
TMMK05 = 1U;
TMIF05 = 0U;
TOE0 &= (uint16_t)~OWI_TIMER_CHANNEL_MASK;
TPS0 = (uint16_t)((TPS0 & 0x0FFFu) | OWI_TIMER_CK03_DIV32);
TMR05 = OWI_TIMER_TMR_CK03_INTERVAL;
TDR05 = 0xFFFFu;
TS0 |= (uint16_t)OWI_TIMER_CHANNEL_MASK;
}
static void OWI_TimerStop(void)
{
TT0 |= (uint16_t)OWI_TIMER_CHANNEL_MASK;
TMIF05 = 0U;
}
static uint16_t OWI_TimerNow(void)
{
return (uint16_t)(0xFFFFu - TCR05);
}
static void OWI_TimerWaitUntil(uint16_t deadline)
{
while ((int16_t)(uint16_t)(OWI_TimerNow() - deadline) < 0) {
NOP();
}
}
/* =========================================================
* GPIO helpers (P70 / HW Open-Drain)
* - LOW : + 0
* - HIGH : (Hi-Z) release
* ========================================================= */
void GPIO_Clear(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
}
void GPIO_Input(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PM |= (uint8_t)OWI_PIN_MASK;
}
int GPIO_Read(void)
{
return (OWI_PORT_P & (uint8_t)OWI_PIN_MASK) ? 1 : 0;
}
static void OWI_Release(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PM |= (uint8_t)OWI_PIN_MASK;
}
static void GPIO_StrongDriveHighKick(uint32_t kick_us)
{
OWI_Release();
if (!GPIO_Read()) {
return;
}
OWI_PORT_POM &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_P |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
delay_us(kick_us);
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_Release();
}
void GPIO_ForceHighKick(void)
{
GPIO_StrongDriveHighKick(OWI_STRONG_DRIVE_HIGH_US);
}
static void OWI_DriveLow(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
}
/* =========================================================
* Diagnostics
* ========================================================= */
uint8_t OWI_HasTimeout(void)
{
return g_owi_timeout_latched;
}
void OWI_ClearTimeout(void)
{
g_owi_timeout_latched = 0;
g_owi_last_timeout_byte_index = 0xFFFFu;
g_owi_last_timeout_bit_index = 0xFFu;
}
uint16_t OWI_GetLastTimeoutByteIndex(void)
{
return g_owi_last_timeout_byte_index;
}
uint8_t OWI_GetLastTimeoutBitIndex(void)
{
return g_owi_last_timeout_bit_index;
}
/* =========================================================
* OWI Init
* ========================================================= */
void OWI_Init(uint32_t bit_time_us)
{
bit_period_us = bit_time_us;
(void)bit_period_us;
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PU &= (uint8_t)~OWI_PIN_MASK;
OWI_ClearTimeout();
GPIO_Input();
}
/* =========================================================
* Start/Stop/Secure
* ========================================================= */
void OWI_Start(void)
{
GPIO_Clear();
delay_us(TSTART_HOLD);
GPIO_Input();
delay_us(TBIT);
}
void OWI_Stop(void)
{
GPIO_Input();
delay_us(TSTOP_LOW);
delay_us(TIDLE);
}
static void OWI_StopWrite(void)
{
OWI_Release();
delay_us(TSTOP_LOW);
delay_us(TIDLE);
}
static void OWI_StopRead(void)
{
OWI_DriveLow();
delay_us(TSTOP_LOW);
OWI_Release();
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_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;
/*
* The deadline is advanced from the R-bit end reference, never from
* the end of the previous CPU delay. Per-byte processing time
* therefore cannot accumulate as sampling drift.
*/
OWI_TimerWaitUntil(g_owi_next_sample_tick);
bit = GPIO_Read() ? 1u : 0u;
data |= (uint8_t)(bit << b);
g_owi_next_sample_tick =
(uint16_t)(g_owi_next_sample_tick + (uint16_t)bit_period_us);
}
return data;
}
void OWI_SecureStop(void)
{
int i;
GPIO_Clear();
delay_us(SECURE_HIGH);
for (i = 0; i < (int)SECURE_TOGGLE_COUNT; i++) {
GPIO_Input();
delay_us(SECURE_TOGGLE_HIGH);
GPIO_Clear();
delay_us(SECURE_TOGGLE_LOW);
}
GPIO_Input();
delay_us(SECURE_HIGH);
GPIO_Clear();
delay_us(TSTART_HOLD);
GPIO_Input();
}
/* =========================================================
* Bit/Byte IO
* ========================================================= */
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)
{
int i;
for (i = 7; i >= 0; i--) {
OWI_WriteBit((data >> i) & 0x01u);
}
GPIO_Input();
}
uint8_t OWI_ReadBit(void)
{
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;
}
/* 2) 다음 LOW 시작 대기 */
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;
}
/* 3) LOW가 유지되는 시간을 직접 측정 */
while (!GPIO_Read() && low_width < (int)(bit_period_us * 2u)) {
delay_us(1u);
low_width++;
}
/* 4) LOW 폭 기준으로 판정
- 1
- 0
threshold ~= TBIT/2
*/
return (low_width < (int)(bit_period_us / 2u)) ? 1u : 0u;
}
uint8_t OWI_ReadByte(void)
{
uint8_t data = 0;
int i;
for (i = 7; i >= 0; i--) {
g_owi_current_read_bit_index = (uint8_t)(7 - i);
data |= (uint8_t)(OWI_ReadBit() << i);
if (OWI_HasTimeout()) {
break;
}
}
return data;
}
/* =========================================================
* Debug Print
* ========================================================= */
void OWI_T_ReadBytesAndPrint(int length)
{
uint8_t buf[129];
int i;
char uart_buf[8];
char tmp_buf[8];
uint8_t va0, va1;
if (length > 129) length = 129;
if (length <= 0) return;
OWI_ClearTimeout();
for (i = 0; i < length; i++) {
R_WDT_Restart();
g_owi_current_read_byte_index = (uint16_t)i;
buf[i] = OWI_ReadByte();
if (OWI_HasTimeout()) {
i++;
break;
}
}
sprintf(uart_buf, "%02X ", buf[0]);
strcpy(tmp_buf, uart_buf);
HOST_PRINT(tmp_buf);
for (i = 1; i < length; i += 2) {
va0 = buf[i];
va1 = (uint8_t)((i + 1 < length) ? buf[i + 1] : 0u);
delay_us(200);
sprintf(uart_buf, "%02X%02X ", va0, va1);
strcpy(tmp_buf, uart_buf);
HOST_PRINT(tmp_buf);
delay_us(200);
}
}
/* =========================================================
* Raw helpers
* ========================================================= */
static void owi_result_init(owi_io_result_t *r)
{
if (!r) return;
memset(r, 0, sizeof(*r));
r->ok = 1;
r->timeout_byte_index = 0xFFFFu;
r->timeout_bit_index = 0xFFu;
}
static void owi_result_latch_timeout(owi_io_result_t *r)
{
if (!r) return;
if (OWI_HasTimeout()) {
r->ok = 0;
r->timeout = 1;
r->timeout_byte_index = OWI_GetLastTimeoutByteIndex();
r->timeout_bit_index = OWI_GetLastTimeoutBitIndex();
}
}
void OWI_T_CommandModeRaw(const uint8_t *tx_data, uint8_t tx_len, uint8_t id, owi_io_result_t *r)
{
int i;
owi_result_init(r);
//delay_us(200);
OWI_Init(OWI_BIT_PERIOD_US);
OWI_ClearTimeout();
R_WDT_Restart();
OWI_SecureStop();
R_WDT_Restart();
OWI_WriteByte((uint8_t)(id << 1));
R_WDT_Restart();
for (i = 0; i < (int)tx_len; i++) {
R_WDT_Restart();
OWI_WriteByte(tx_data[i]);
R_WDT_Restart();
}
OWI_Stop();
R_WDT_Restart();
owi_result_latch_timeout(r);
}
void OWI_CommandModeRaw(const uint8_t *tx_data, uint8_t tx_len, uint8_t id, owi_io_result_t *r)
{
int i;
owi_result_init(r);
OWI_Init(OWI_BIT_PERIOD_US);
OWI_ClearTimeout();
R_WDT_Restart();
OWI_SecureStop();
R_WDT_Restart();
OWI_WriteByte((uint8_t)(id << 1));
R_WDT_Restart();
for (i = 0; i < (int)tx_len; i++) {
R_WDT_Restart();
OWI_WriteByte(tx_data[i]);
R_WDT_Restart();
}
OWI_Stop();
R_WDT_Restart();
owi_result_latch_timeout(r);
}
void OWI_ReadBytesRaw(int length, uint8_t id, owi_io_result_t *r)
{
int i;
int max_len;
if (!r) return;
owi_result_init(r);
OWI_Init(OWI_BIT_PERIOD_US);
if (length <= 0) {
r->ok = 0;
return;
}
max_len = (int)OWI_IO_MAX_BYTES;
if (length > max_len) {
length = max_len;
}
r->read_len = (uint16_t)length;
OWI_ClearTimeout();
R_WDT_Restart();
OWI_SecureStop();
OWI_TimerStart1MHz();
OWI_WriteByte((uint8_t)((id << 1) | 1u));
/*
* OWI_WriteByte() returns at the end of the R bit. Every sample deadline
* is an absolute 1 MHz timer value derived from this one reference.
*/
g_owi_next_sample_tick =
(uint16_t)(OWI_TimerNow() + (uint16_t)(bit_period_us / 2u));
for (i = 0; i < length; i++) {
R_WDT_Restart();
r->data[i] = OWI_ReadByte_StreamSynced((uint16_t)i);
if (OWI_HasTimeout()) {
owi_result_latch_timeout(r);
break;
}
}
OWI_TimerStop();
OWI_StopRead();
}
void OWI_disable(void)
{
HOST_PRINT("51\r\n");
}
void OWI_T_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id)
{
owi_io_result_t r;
(void)r;
OWI_T_CommandModeRaw(tx_data, tx_len, id, &r);
HOST_PRINT("51\r\n");
}
void OWI_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id)
{
owi_io_result_t r;
(void)r;
OWI_CommandModeRaw(tx_data, tx_len, id, &r);
HOST_PRINT("51\r\n");
}
void OWI_ReadBytesAndPrint(int length, uint8_t id)
{
owi_io_result_t r;
char out[(2 * OWI_IO_MAX_BYTES) + 40];
int i;
uint16_t p = 0;
if (length <= 0) {
HOST_PRINT("Err:read_len_nonzero\r\n");
return;
}
OWI_ReadBytesRaw(length, id, &r);
if (r.read_len == 0) {
HOST_PRINT("Err:read_len_nonzero\r\n");
return;
}
for (i = 0; i < (int)r.read_len; i++) {
uint8_t b = r.data[i];
out[p++] = "0123456789ABCDEF"[b >> 4];
out[p++] = "0123456789ABCDEF"[b & 0x0F];
}
if (r.timeout) {
p += (uint16_t)sprintf(&out[p], " !TO(B%u b%u)",
(unsigned)r.timeout_byte_index,
(unsigned)r.timeout_bit_index);
}
out[p++] = '\r';
out[p++] = '\n';
out[p] = '\0';
HOST_PRINT(out);
}

666
3/owi.c

@ -0,0 +1,666 @@
#include "owi.h"
#include "delay.h"
#include "r_cg_wdt.h"
#include <string.h>
#include <stdio.h>
#include "uart.h"
#include "r_cg_wdt.h"
#ifndef OWI_STRONG_DRIVE_HIGH_US
#define OWI_STRONG_DRIVE_HIGH_US 5u
#endif
/*
* Test 3 hardware time base
* -------------------------
* Project clock: fCLK = 32 MHz
* TAU0 channel 5: CK03 = fCLK / 32 = 1 MHz (one count per microsecond)
*
* Channel 5 and CK03 are otherwise unused by this project. Only the CK03
* field of TPS0 is changed, so CK00 to CK02 remain untouched.
*/
#define OWI_TIMER_CHANNEL_MASK 0x0020u
#define OWI_TIMER_CK03_DIV32 0x5000u
#define OWI_TIMER_TMR_CK03_INTERVAL 0xC000u
/* 내부 상태 */
static uint32_t bit_period_us = OWI_BIT_PERIOD_US;
static uint8_t g_owi_timeout_latched = 0;
static uint16_t g_owi_last_timeout_byte_index = 0xFFFFu;
static uint8_t g_owi_last_timeout_bit_index = 0xFFu;
static uint16_t g_owi_current_read_byte_index = 0u;
static uint8_t g_owi_current_read_bit_index = 0u;
static uint16_t g_owi_next_bit_start_tick = 0u;
static void OWI_TimerStart1MHz(void)
{
TAU0EN = 1U;
NOP();
NOP();
NOP();
NOP();
TT0 |= (uint16_t)OWI_TIMER_CHANNEL_MASK;
TMMK05 = 1U;
TMIF05 = 0U;
TOE0 &= (uint16_t)~OWI_TIMER_CHANNEL_MASK;
TPS0 = (uint16_t)((TPS0 & 0x0FFFu) | OWI_TIMER_CK03_DIV32);
TMR05 = OWI_TIMER_TMR_CK03_INTERVAL;
TDR05 = 0xFFFFu;
TS0 |= (uint16_t)OWI_TIMER_CHANNEL_MASK;
}
static void OWI_TimerStop(void)
{
TT0 |= (uint16_t)OWI_TIMER_CHANNEL_MASK;
TMIF05 = 0U;
}
static uint16_t OWI_TimerNow(void)
{
return (uint16_t)(0xFFFFu - TCR05);
}
static uint8_t OWI_TimerDeadlineReached(uint16_t deadline)
{
return ((int16_t)(uint16_t)(OWI_TimerNow() - deadline) >= 0) ? 1u : 0u;
}
static void OWI_TimerWaitUntil(uint16_t deadline)
{
while (!OWI_TimerDeadlineReached(deadline)) {
NOP();
}
}
static void OWI_LatchReadTimeout(uint16_t byte_index, uint8_t bit_index)
{
if (!g_owi_timeout_latched) {
g_owi_timeout_latched = 1u;
g_owi_last_timeout_byte_index = byte_index;
g_owi_last_timeout_bit_index = bit_index;
}
}
static uint8_t OWI_MeasureFallingEdge(uint16_t bit_start,
uint16_t byte_index,
uint8_t bit_index,
uint16_t *edge_tick)
{
uint16_t bit_end =
(uint16_t)(bit_start + (uint16_t)bit_period_us);
uint16_t edge;
OWI_TimerWaitUntil(bit_start);
/*
* Each OWI bit starts HIGH. First discard a possible LOW remainder at
* the exact boundary, then capture the next HIGH-to-LOW transition.
*/
while (!GPIO_Read()) {
if (OWI_TimerDeadlineReached(bit_end)) {
OWI_LatchReadTimeout(byte_index, bit_index);
return 0u;
}
}
while (GPIO_Read()) {
if (OWI_TimerDeadlineReached(bit_end)) {
OWI_LatchReadTimeout(byte_index, bit_index);
return 0u;
}
}
edge = OWI_TimerNow();
if ((uint16_t)(edge - bit_start) >= (uint16_t)bit_period_us) {
OWI_LatchReadTimeout(byte_index, bit_index);
return 0u;
}
*edge_tick = edge;
return 1u;
}
/* =========================================================
* GPIO helpers (P70 / HW Open-Drain)
* - LOW : + 0
* - HIGH : (Hi-Z) release
* ========================================================= */
void GPIO_Clear(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
}
void GPIO_Input(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PM |= (uint8_t)OWI_PIN_MASK;
}
int GPIO_Read(void)
{
return (OWI_PORT_P & (uint8_t)OWI_PIN_MASK) ? 1 : 0;
}
static void OWI_Release(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PM |= (uint8_t)OWI_PIN_MASK;
}
static void GPIO_StrongDriveHighKick(uint32_t kick_us)
{
OWI_Release();
if (!GPIO_Read()) {
return;
}
OWI_PORT_POM &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_P |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
delay_us(kick_us);
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_Release();
}
void GPIO_ForceHighKick(void)
{
GPIO_StrongDriveHighKick(OWI_STRONG_DRIVE_HIGH_US);
}
static void OWI_DriveLow(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
}
/* =========================================================
* Diagnostics
* ========================================================= */
uint8_t OWI_HasTimeout(void)
{
return g_owi_timeout_latched;
}
void OWI_ClearTimeout(void)
{
g_owi_timeout_latched = 0;
g_owi_last_timeout_byte_index = 0xFFFFu;
g_owi_last_timeout_bit_index = 0xFFu;
}
uint16_t OWI_GetLastTimeoutByteIndex(void)
{
return g_owi_last_timeout_byte_index;
}
uint8_t OWI_GetLastTimeoutBitIndex(void)
{
return g_owi_last_timeout_bit_index;
}
/* =========================================================
* OWI Init
* ========================================================= */
void OWI_Init(uint32_t bit_time_us)
{
bit_period_us = bit_time_us;
(void)bit_period_us;
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PU &= (uint8_t)~OWI_PIN_MASK;
OWI_ClearTimeout();
GPIO_Input();
}
/* =========================================================
* Start/Stop/Secure
* ========================================================= */
void OWI_Start(void)
{
GPIO_Clear();
delay_us(TSTART_HOLD);
GPIO_Input();
delay_us(TBIT);
}
void OWI_Stop(void)
{
GPIO_Input();
delay_us(TSTOP_LOW);
delay_us(TIDLE);
}
static void OWI_StopWrite(void)
{
OWI_Release();
delay_us(TSTOP_LOW);
delay_us(TIDLE);
}
static void OWI_StopRead(void)
{
OWI_DriveLow();
delay_us(TSTOP_LOW);
OWI_Release();
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_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;
uint16_t edge_tick;
uint16_t edge_position;
g_owi_current_read_byte_index = byte_index;
g_owi_current_read_bit_index = bit_index;
if (!OWI_MeasureFallingEdge(g_owi_next_bit_start_tick,
byte_index,
bit_index,
&edge_tick)) {
break;
}
edge_position =
(uint16_t)(edge_tick - g_owi_next_bit_start_tick);
/*
* OWI write timing is HIGH first and LOW second:
* 0: falling edge near TBIT/4
* 1: falling edge near 3*TBIT/4
*/
bit = (edge_position < (uint16_t)(bit_period_us / 2u)) ? 0u : 1u;
data |= (uint8_t)(bit << b);
g_owi_next_bit_start_tick =
(uint16_t)(g_owi_next_bit_start_tick +
(uint16_t)bit_period_us);
}
return data;
}
void OWI_SecureStop(void)
{
int i;
GPIO_Clear();
delay_us(SECURE_HIGH);
for (i = 0; i < (int)SECURE_TOGGLE_COUNT; i++) {
GPIO_Input();
delay_us(SECURE_TOGGLE_HIGH);
GPIO_Clear();
delay_us(SECURE_TOGGLE_LOW);
}
GPIO_Input();
delay_us(SECURE_HIGH);
GPIO_Clear();
delay_us(TSTART_HOLD);
GPIO_Input();
}
/* =========================================================
* Bit/Byte IO
* ========================================================= */
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)
{
int i;
for (i = 7; i >= 0; i--) {
OWI_WriteBit((data >> i) & 0x01u);
}
GPIO_Input();
}
uint8_t OWI_ReadBit(void)
{
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;
}
/* 2) 다음 LOW 시작 대기 */
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;
}
/* 3) LOW가 유지되는 시간을 직접 측정 */
while (!GPIO_Read() && low_width < (int)(bit_period_us * 2u)) {
delay_us(1u);
low_width++;
}
/* 4) LOW 폭 기준으로 판정
- 1
- 0
threshold ~= TBIT/2
*/
return (low_width < (int)(bit_period_us / 2u)) ? 1u : 0u;
}
uint8_t OWI_ReadByte(void)
{
uint8_t data = 0;
int i;
for (i = 7; i >= 0; i--) {
g_owi_current_read_bit_index = (uint8_t)(7 - i);
data |= (uint8_t)(OWI_ReadBit() << i);
if (OWI_HasTimeout()) {
break;
}
}
return data;
}
/* =========================================================
* Debug Print
* ========================================================= */
void OWI_T_ReadBytesAndPrint(int length)
{
uint8_t buf[129];
int i;
char uart_buf[8];
char tmp_buf[8];
uint8_t va0, va1;
if (length > 129) length = 129;
if (length <= 0) return;
OWI_ClearTimeout();
for (i = 0; i < length; i++) {
R_WDT_Restart();
g_owi_current_read_byte_index = (uint16_t)i;
buf[i] = OWI_ReadByte();
if (OWI_HasTimeout()) {
i++;
break;
}
}
sprintf(uart_buf, "%02X ", buf[0]);
strcpy(tmp_buf, uart_buf);
HOST_PRINT(tmp_buf);
for (i = 1; i < length; i += 2) {
va0 = buf[i];
va1 = (uint8_t)((i + 1 < length) ? buf[i + 1] : 0u);
delay_us(200);
sprintf(uart_buf, "%02X%02X ", va0, va1);
strcpy(tmp_buf, uart_buf);
HOST_PRINT(tmp_buf);
delay_us(200);
}
}
/* =========================================================
* Raw helpers
* ========================================================= */
static void owi_result_init(owi_io_result_t *r)
{
if (!r) return;
memset(r, 0, sizeof(*r));
r->ok = 1;
r->timeout_byte_index = 0xFFFFu;
r->timeout_bit_index = 0xFFu;
}
static void owi_result_latch_timeout(owi_io_result_t *r)
{
if (!r) return;
if (OWI_HasTimeout()) {
r->ok = 0;
r->timeout = 1;
r->timeout_byte_index = OWI_GetLastTimeoutByteIndex();
r->timeout_bit_index = OWI_GetLastTimeoutBitIndex();
}
}
void OWI_T_CommandModeRaw(const uint8_t *tx_data, uint8_t tx_len, uint8_t id, owi_io_result_t *r)
{
int i;
owi_result_init(r);
//delay_us(200);
OWI_Init(OWI_BIT_PERIOD_US);
OWI_ClearTimeout();
R_WDT_Restart();
OWI_SecureStop();
R_WDT_Restart();
OWI_WriteByte((uint8_t)(id << 1));
R_WDT_Restart();
for (i = 0; i < (int)tx_len; i++) {
R_WDT_Restart();
OWI_WriteByte(tx_data[i]);
R_WDT_Restart();
}
OWI_Stop();
R_WDT_Restart();
owi_result_latch_timeout(r);
}
void OWI_CommandModeRaw(const uint8_t *tx_data, uint8_t tx_len, uint8_t id, owi_io_result_t *r)
{
int i;
owi_result_init(r);
OWI_Init(OWI_BIT_PERIOD_US);
OWI_ClearTimeout();
R_WDT_Restart();
OWI_SecureStop();
R_WDT_Restart();
OWI_WriteByte((uint8_t)(id << 1));
R_WDT_Restart();
for (i = 0; i < (int)tx_len; i++) {
R_WDT_Restart();
OWI_WriteByte(tx_data[i]);
R_WDT_Restart();
}
OWI_Stop();
R_WDT_Restart();
owi_result_latch_timeout(r);
}
void OWI_ReadBytesRaw(int length, uint8_t id, owi_io_result_t *r)
{
int i;
int max_len;
if (!r) return;
owi_result_init(r);
OWI_Init(OWI_BIT_PERIOD_US);
if (length <= 0) {
r->ok = 0;
return;
}
max_len = (int)OWI_IO_MAX_BYTES;
if (length > max_len) {
length = max_len;
}
r->read_len = (uint16_t)length;
OWI_ClearTimeout();
R_WDT_Restart();
OWI_SecureStop();
OWI_TimerStart1MHz();
OWI_WriteByte((uint8_t)((id << 1) | 1u));
/*
* OWI_WriteByte() returns at the end of the R bit. Each bit slot and its
* falling-edge position are measured from this absolute reference.
*/
g_owi_next_bit_start_tick = OWI_TimerNow();
for (i = 0; i < length; i++) {
R_WDT_Restart();
r->data[i] = OWI_ReadByte_StreamSynced((uint16_t)i);
if (OWI_HasTimeout()) {
owi_result_latch_timeout(r);
break;
}
}
OWI_TimerStop();
OWI_StopRead();
}
void OWI_disable(void)
{
HOST_PRINT("51\r\n");
}
void OWI_T_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id)
{
owi_io_result_t r;
(void)r;
OWI_T_CommandModeRaw(tx_data, tx_len, id, &r);
HOST_PRINT("51\r\n");
}
void OWI_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id)
{
owi_io_result_t r;
(void)r;
OWI_CommandModeRaw(tx_data, tx_len, id, &r);
HOST_PRINT("51\r\n");
}
void OWI_ReadBytesAndPrint(int length, uint8_t id)
{
owi_io_result_t r;
char out[(2 * OWI_IO_MAX_BYTES) + 40];
int i;
uint16_t p = 0;
if (length <= 0) {
HOST_PRINT("Err:read_len_nonzero\r\n");
return;
}
OWI_ReadBytesRaw(length, id, &r);
if (r.read_len == 0) {
HOST_PRINT("Err:read_len_nonzero\r\n");
return;
}
for (i = 0; i < (int)r.read_len; i++) {
uint8_t b = r.data[i];
out[p++] = "0123456789ABCDEF"[b >> 4];
out[p++] = "0123456789ABCDEF"[b & 0x0F];
}
if (r.timeout) {
p += (uint16_t)sprintf(&out[p], " !TO(B%u b%u)",
(unsigned)r.timeout_byte_index,
(unsigned)r.timeout_bit_index);
}
out[p++] = '\r';
out[p++] = '\n';
out[p] = '\0';
HOST_PRINT(out);
}

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/cstart.obj

Binary file not shown.

BIN
DefaultBuild/delay.obj

Binary file not shown.

BIN
DefaultBuild/dipSwitch.obj

Binary file not shown.

BIN
DefaultBuild/gatectrl.obj

Binary file not shown.

BIN
DefaultBuild/i2c.obj

Binary file not shown.

BIN
DefaultBuild/multical.abs

Binary file not shown.

8
DefaultBuild/multical.clnk

@ -14,6 +14,12 @@
-Input=DefaultBuild\delay.obj
-Input=DefaultBuild\dipSwitch.obj
-Input=DefaultBuild\gatectrl.obj
-Input=DefaultBuild\app_result.obj
-Input=DefaultBuild\app_cmd_parser.obj
-Input=DefaultBuild\app_scheduler.obj
-Input=DefaultBuild\app_owi_service.obj
-Input=DefaultBuild\r_cg_wdt.obj
-Input=DefaultBuild\r_cg_wdt_user.obj
-SECURITY_ID=00000000000000000000
-DEVICE=C:\Program Files (x86)\Renesas Electronics\CS+\CC\Device\RL78\Devicefile\DR5F10PPJ.DVF
-DEBug
@ -22,7 +28,7 @@
-OUtput=DefaultBuild\multical.abs
-OCDBG=84
-DEBUG_MONITOR=3FE00-3FFFF
-USER_OPT_BYTE=E9FFF8
-USER_OPT_BYTE=78FFF8
-OCDTR
-LISt=DefaultBuild\multical.map
-SHow=SYmbol,Total_size

832
DefaultBuild/multical.map

File diff suppressed because it is too large

3100
DefaultBuild/multical.mot

File diff suppressed because it is too large

BIN
DefaultBuild/owi.obj

Binary file not shown.

BIN
DefaultBuild/r_cg_cgc.obj

Binary file not shown.

BIN
DefaultBuild/r_cg_cgc_user.obj

Binary file not shown.

BIN
DefaultBuild/r_cg_port.obj

Binary file not shown.

BIN
DefaultBuild/r_cg_port_user.obj

Binary file not shown.

BIN
DefaultBuild/r_cg_serial.obj

Binary file not shown.

BIN
DefaultBuild/r_cg_serial_user.obj

Binary file not shown.

BIN
DefaultBuild/r_cg_wdt.obj

Binary file not shown.

BIN
DefaultBuild/r_cg_wdt_user.obj

Binary file not shown.

BIN
DefaultBuild/r_main.obj

Binary file not shown.

BIN
DefaultBuild/r_systeminit.obj

Binary file not shown.

BIN
DefaultBuild/stkinit.obj

Binary file not shown.

BIN
DefaultBuild/uart.obj

Binary file not shown.

118
QualityReport(multical,DefaultBuild).txt

@ -1,13 +1,113 @@
QualityReport
2026년 2월 9일 월요일 오후 12:23:59
2026년 7월 30일 목요일 오전 9:19:08
------ Start build(multical, DefaultBuild) ------
------ Build ended(Error:0, Warning:0)(multical, DefaultBuild) ------
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\Bin\ccrl.exe r_main.c -cpu=S3 -o DefaultBuild\r_main.obj "-dev=C:\Program Files (x86)\Renesas Electronics\CS+\CC\Device\RL78\Devicefile\DR5F10PPJ.DVF" -g -g_line -I "..\..\Documents\카카오톡 받은 파일\IDH1.1\IDH1.1" -I ..\IDH1.1 -I . -c -msg_lang=english
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\Bin\ccrl.exe app_owi_service.c -cpu=S3 -o DefaultBuild\app_owi_service.obj "-dev=C:\Program Files (x86)\Renesas Electronics\CS+\CC\Device\RL78\Devicefile\DR5F10PPJ.DVF" -g -g_line -I "..\..\Documents\카카오톡 받은 파일\IDH1.1\IDH1.1" -I ..\IDH1.1 -I . -c -msg_lang=english
W0511106:The folder "..\..\Documents\카카오톡 받은 파일\IDH1.1\IDH1.1" specified by the "-I" option is not found.
W0511106:The folder "..\..\Documents\카카오톡 받은 파일\IDH1.1\IDH1.1" specified by the "-I" option is not found.
W0511187:The evaluation period for the option "-Odefault" of CC-RL V1 has expired. It is implicitly changed to "-Olite". Please consider purchasing the product to continue using "-Odefault". By explicitly specifying "-Olite" or "-Onothing", this warning message disappears.
W0511187:The evaluation period for the option "-Odefault" of CC-RL V1 has expired. It is implicitly changed to "-Olite". Please consider purchasing the product to continue using "-Odefault". By explicitly specifying "-Olite" or "-Onothing", this warning message disappears.
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(18):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(19):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(20):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(25):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(26):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(27):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(18):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(19):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(20):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(25):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(26):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(27):W0520301:Typedef name has already been declared (with same type)
i2c.h(8):W0520047:Incompatible redefinition of macro "RAM_BYTES" (declared at line 15 of "uart.h")
r_main.c(692):W0520172:External/internal linkage conflict with previous declaration
r_main.c(811):W0520177:Variable "dbg" was declared but never referenced
r_main.c(1302):W0520177:Variable "dbg" was declared but never referenced
r_main.c(1933):W0520177:Variable "total_us" was declared but never referenced
r_main.c(1934):W0520177:Variable "idle_us" was declared but never referenced
r_main.c(1936):W0520177:Variable "got_any" was declared but never referenced
r_main.c(102):W0520177:Variable "s_end_pat" was declared but never referenced
r_main.c(268):W0520177:Function "UART1_SendBytes_Safe" was declared but never referenced
r_main.c(429):W0520177:Function "bridge_wait_until_end" was declared but never referenced
r_main.c(770):W0520177:Function "connect_verify_reset" was declared but never referenced
r_main.c(775):W0520177:Function "print_hex_line" was declared but never referenced
r_main.c(1637):W0520177:Function "execute_owi_service_from_line" was declared but never referenced
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\Bin\ccrl.exe owi.c -cpu=S3 -o DefaultBuild\owi.obj "-dev=C:\Program Files (x86)\Renesas Electronics\CS+\CC\Device\RL78\Devicefile\DR5F10PPJ.DVF" -g -g_line -I "..\..\Documents\카카오톡 받은 파일\IDH1.1\IDH1.1" -I ..\IDH1.1 -I . -c -msg_lang=english
W0511106:The folder "..\..\Documents\카카오톡 받은 파일\IDH1.1\IDH1.1" specified by the "-I" option is not found.
W0511187:The evaluation period for the option "-Odefault" of CC-RL V1 has expired. It is implicitly changed to "-Olite". Please consider purchasing the product to continue using "-Odefault". By explicitly specifying "-Olite" or "-Onothing", this warning message disappears.
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(18):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(19):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(20):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(25):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(26):W0520301:Typedef name has already been declared (with same type)
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\inc\stdint.h(27):W0520301:Typedef name has already been declared (with same type)
uart.h(15):W0520047:Incompatible redefinition of macro "RAM_BYTES" (declared at line 29 of "owi.h")
owi.c(537):W0520549:Variable "r" is used before its value is set
owi.c(546):W0520549:Variable "r" is used before its value is set
owi.c(143):W0520177:Function "OWI_StopWrite" was declared but never referenced
owi.c(158):W0520177:Function "OWI_WaitFirstBitStart" was declared but never referenced
C:\Program Files (x86)\Renesas Electronics\CS+\CC\CC-RL\V1.15.00\Bin\rlink.exe -subcommand=DefaultBuild\multical.clnk
W0561017:Paid license of CC-RL V1 is not found, and the evaluation period has expired. Please consider purchasing the product.
W0561017:Paid license of CC-RL V1 is not found, and the evaluation period has expired. Please consider purchasing the product.
Renesas Optimizing Linker Completed
------ Build ended(Error:0, Warning:44)(multical, DefaultBuild) ------
--- CommandFile 1 ---
DefaultBuild\multical.clnk :
-Input=DefaultBuild\cstart.obj
-Input=DefaultBuild\stkinit.obj
-Input=DefaultBuild\r_main.obj
-Input=DefaultBuild\r_systeminit.obj
-Input=DefaultBuild\r_cg_cgc.obj
-Input=DefaultBuild\r_cg_cgc_user.obj
-Input=DefaultBuild\r_cg_serial.obj
-Input=DefaultBuild\r_cg_serial_user.obj
-Input=DefaultBuild\r_cg_port.obj
-Input=DefaultBuild\r_cg_port_user.obj
-Input=DefaultBuild\owi.obj
-Input=DefaultBuild\i2c.obj
-Input=DefaultBuild\uart.obj
-Input=DefaultBuild\delay.obj
-Input=DefaultBuild\dipSwitch.obj
-Input=DefaultBuild\gatectrl.obj
-Input=DefaultBuild\app_result.obj
-Input=DefaultBuild\app_cmd_parser.obj
-Input=DefaultBuild\app_scheduler.obj
-Input=DefaultBuild\app_owi_service.obj
-Input=DefaultBuild\r_cg_wdt.obj
-Input=DefaultBuild\r_cg_wdt_user.obj
-SECURITY_ID=00000000000000000000
-DEVICE=C:\Program Files (x86)\Renesas Electronics\CS+\CC\Device\RL78\Devicefile\DR5F10PPJ.DVF
-DEBug
-NOCOmpress
-NOOPtimize
-OUtput=DefaultBuild\multical.abs
-OCDBG=84
-DEBUG_MONITOR=3FE00-3FFFF
-USER_OPT_BYTE=78FFF8
-OCDTR
-LISt=DefaultBuild\multical.map
-SHow=SYmbol,Total_size
-AUTO_SECTION_LAYOUT
-ROm=.data=.dataR
-ROm=.sdata=.sdataR
-NOMessage
-MEMory=High
-NOLOgo
-LIBrary=DefaultBuild\multical.lib
-end
-Input=DefaultBuild\multical.abs
-DEVICE=C:\Program Files (x86)\Renesas Electronics\CS+\CC\Device\RL78\Devicefile\DR5F10PPJ.DVF
-OUtput=DefaultBuild\multical.mot
-FOrm=Stype
-NOMessage
-exit
--- SHA1 hash value of output files ---
C:\Users\temp\Desktop\new_fw\DefaultBuild\multical.abs: 8170c2063f1fe5917df15deaedaccc67af363ea0
C:\Users\temp\Desktop\new_fw\DefaultBuild\multical.mot: 3c42028cd93f8de719bdcf8a03dae4038a857ae6
C:\Users\temp\Desktop\new_fw\DefaultBuild\multical.abs: b7c6b666e469b31beca03f72cf76832a7a7fd1de
C:\Users\temp\Desktop\new_fw\DefaultBuild\multical.mot: ea661bdc3d677102e44160d16233eb2c7f15ec1c
--- System Information ---
@ -18,7 +118,7 @@ C:\Users\temp\Desktop\new_fw\DefaultBuild\multical.mot: 3c42028cd93f8de719bdcf8a
*.NET Framework Version
Microsoft .NET Framework 4 [.NET 4.8 or later] (533325)
*WebView2 Version
144.0.3719.115
150.0.4078.105
--- Application Information ---
*Product Name
@ -35,13 +135,13 @@ C:\Users\temp\Desktop\new_fw\DefaultBuild\multical.mot: 3c42028cd93f8de719bdcf8a
C:\Program Files (x86)\Renesas Electronics\CS+\CC
*Memory Usage
*Private Working Set
333 MB
289 MB
*Number of GDI Objects
2650
2840
*Number of USER Objects
1618
1765
*Opened Files
24 editors, 24 files, 197 KB
36 editors, 36 files, 256 KB
--- Build Tool Plug-in Information ---
RH850 Build tool CC-RH Plug-in

181
app_cmd_parser.c

@ -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;
}

8
app_cmd_parser.h

@ -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

221
app_owi_service.c

@ -0,0 +1,221 @@
#include "app_owi_service.h"
#include "owi.h"
#include "delay.h"
#include "r_cg_wdt.h"
#include <string.h>
#define OWI_VERIFIED_MAX_LEN 129u
#define OWI_VERIFIED_127_ATTEMPTS 6u
#define OWI_VERIFIED_129_ATTEMPTS 8u
#define OWI_VERIFIED_FIRST_US 30000u
#define OWI_VERIFIED_RETRY_US 10000u
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 s_verified_long[OWI_VERIFIED_MAX_LEN];
static uint8_t s_verified_long_len = 0u;
static uint8_t is_long_owi_read(int length)
{
return (length == 119) ? 1u : 0u;
}
static app_owi_result_t app_owi_read_verified_long(uint8_t id,
uint8_t length,
uint8_t max_attempts)
{
static uint8_t samples[3][OWI_VERIFIED_MAX_LEN];
owi_io_result_t io;
uint8_t sample_count = 0u;
uint8_t attempt;
uint8_t sample;
uint8_t replace_index = 0u;
memset(&io, 0, sizeof(io));
for (attempt = 0u; attempt < max_attempts; attempt++) {
delay_us((attempt == 0u) ? OWI_VERIFIED_FIRST_US
: OWI_VERIFIED_RETRY_US);
R_WDT_Restart();
OWI_ReadBytesRaw((int)length, id, &io);
R_WDT_Restart();
if (!io.ok || io.timeout || io.read_len < length ||
io.data[0] != 0x26u) {
continue;
}
/* One fresh full read matching a previously verified value is enough. */
if (s_verified_long_len == length &&
memcmp(s_verified_long, io.data, length) == 0) {
return app_owi_from_raw(&io);
}
for (sample = 0u; sample < sample_count; sample++) {
if (memcmp(samples[sample], io.data, length) == 0) {
memcpy(s_verified_long, io.data, length);
s_verified_long_len = length;
return app_owi_from_raw(&io);
}
}
if (sample_count < 3u) {
memcpy(samples[sample_count], io.data, length);
sample_count++;
} else {
/* Keep recent distinct samples so a later stable pair can match. */
memcpy(samples[replace_index], io.data, length);
replace_index++;
if (replace_index >= 3u) {
replace_index = 0u;
}
}
}
/* Do not return a possibly corrupted long sample. */
memset(&io, 0, sizeof(io));
io.ok = 0u;
io.timeout = 1u;
io.timeout_byte_index = 0xFFFEu;
io.timeout_bit_index = 0xFEu;
return app_owi_from_raw(&io);
}
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;
if (length == 127) {
return app_owi_read_verified_long(id, 127u,
OWI_VERIFIED_127_ATTEMPTS);
}
if (length == 129) {
return app_owi_read_verified_long(id, 129u,
OWI_VERIFIED_129_ATTEMPTS);
}
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);
}

20
app_owi_service.h

@ -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

12
app_result.c

@ -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);
}

7
app_result.h

@ -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

51
app_scheduler.c

@ -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));
}

12
app_scheduler.h

@ -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

51
app_types.h

@ -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

117
gatectrl.c

@ -72,65 +72,66 @@ void Gate_SetByNum(uint8_t ch, uint8_t hash_on, uint8_t anaout_on, uint8_t check
PORT_BIT_SETCLR(P10, 0x10, check_on); // P10.4
break;
case 11: /* P10.3, P5.2, P10.5 */
PORT_BIT_SETCLR(P10, 0x08, hash_on); // P10.3
PORT_BIT_SETCLR(P5, 0x04, anaout_on); // P5.2
PORT_BIT_SETCLR(P10, 0x20, check_on); // P10.5
break;
case 12: /* P10.2, P6.0, P10.6 */
PORT_BIT_SETCLR(P10, 0x04, hash_on); // P10.2
PORT_BIT_SETCLR(P6, 0x01, anaout_on); // P6.0
PORT_BIT_SETCLR(P10, 0x40, check_on); // P10.6
break;
case 13: /* P10.1, P6.1, P10.7 */
PORT_BIT_SETCLR(P10, 0x02, hash_on); // P10.1
PORT_BIT_SETCLR(P6, 0x02, anaout_on); // P6.1
PORT_BIT_SETCLR(P10, 0x80, check_on); // P10.7
break;
case 14: /* P10.0, P7.2, P5.7 */
PORT_BIT_SETCLR(P10, 0x01, hash_on); // P10.0
PORT_BIT_SETCLR(P7, 0x04, anaout_on); // P7.2
PORT_BIT_SETCLR(P5, 0x80, check_on); // P5.7
break;
case 15: /* P9.7, P7.3, P5.6 */
PORT_BIT_SETCLR(P9, 0x80, hash_on); // P9.7
PORT_BIT_SETCLR(P7, 0x08, anaout_on); // P7.3
PORT_BIT_SETCLR(P5, 0x40, check_on); // P5.6
break;
case 11: /* P9.2, P13.0, P1.4 */
PORT_BIT_SETCLR(P9, 0x04, hash_on); // P9.2
PORT_BIT_SETCLR(P13, 0x01, anaout_on); // P13.0
PORT_BIT_SETCLR(P1, 0x10, check_on); // P1.4
break;
case 12: /* P9.3, P7.7, P1.3 */
PORT_BIT_SETCLR(P9, 0x08, hash_on); // P9.3
PORT_BIT_SETCLR(P7, 0x80, anaout_on); // P7.7
PORT_BIT_SETCLR(P1, 0x08, check_on); // P1.3
break;
case 13: /* P9.4, P7.6, P1.0 */
PORT_BIT_SETCLR(P9, 0x10, hash_on); // P9.4
PORT_BIT_SETCLR(P7, 0x40, anaout_on); // P7.6
PORT_BIT_SETCLR(P1, 0x01, check_on); // P1.0
break;
case 14: /* P9.5, P7.4, P5.4 */
PORT_BIT_SETCLR(P9, 0x20, hash_on); // P9.5
PORT_BIT_SETCLR(P7, 0x10, anaout_on); // P7.4
PORT_BIT_SETCLR(P5, 0x10, check_on); // P5.4
break;
case 15: /* P9.6, P7.5, P5.5 */
PORT_BIT_SETCLR(P9, 0x40, hash_on); // P9.6
PORT_BIT_SETCLR(P7, 0x20, anaout_on); // P7.5
PORT_BIT_SETCLR(P5, 0x20, check_on); // P5.5
break;
case 16: /* P9.7, P7.3, P5.6 */
PORT_BIT_SETCLR(P9, 0x80, hash_on); // P9.7
PORT_BIT_SETCLR(P7, 0x08, anaout_on); // P7.3
PORT_BIT_SETCLR(P5, 0x40, check_on); // P5.6
break;
case 17: /* P10.0, P7.2, P5.7 */
PORT_BIT_SETCLR(P10, 0x01, hash_on); // P10.0
PORT_BIT_SETCLR(P7, 0x04, anaout_on); // P7.2
PORT_BIT_SETCLR(P5, 0x80, check_on); // P5.7
break;
case 18: /* P10.1, P6.1, P10.7 */
PORT_BIT_SETCLR(P10, 0x02, hash_on); // P10.1
PORT_BIT_SETCLR(P6, 0x02, anaout_on); // P6.1
PORT_BIT_SETCLR(P10, 0x80, check_on); // P10.7
break;
case 19: /* P10.2, P6.0, P10.6 */
PORT_BIT_SETCLR(P10, 0x04, hash_on); // P10.2
PORT_BIT_SETCLR(P6, 0x01, anaout_on); // P6.0
PORT_BIT_SETCLR(P10, 0x40, check_on); // P10.6
break;
case 20: /* P10.3, P5.2, P10.5 */
PORT_BIT_SETCLR(P10, 0x08, hash_on); // P10.3
PORT_BIT_SETCLR(P5, 0x04, anaout_on); // P5.2
PORT_BIT_SETCLR(P10, 0x20, check_on); // P10.5
break;
case 16: /* P9.6, P7.5, P5.5 */
PORT_BIT_SETCLR(P9, 0x40, hash_on); // P9.6
PORT_BIT_SETCLR(P7, 0x20, anaout_on); // P7.5
PORT_BIT_SETCLR(P5, 0x20, check_on); // P5.5
break;
case 17: /* P9.5, P7.4, P5.4 */
PORT_BIT_SETCLR(P9, 0x20, hash_on); // P9.5
PORT_BIT_SETCLR(P7, 0x10, anaout_on); // P7.4
PORT_BIT_SETCLR(P5, 0x10, check_on); // P5.4
break;
case 18: /* P9.4, P7.6, P1.0 */
PORT_BIT_SETCLR(P9, 0x10, hash_on); // P9.4
PORT_BIT_SETCLR(P7, 0x40, anaout_on); // P7.6
PORT_BIT_SETCLR(P1, 0x01, check_on); // P1.0
break;
case 19: /* P9.3, P7.7, P1.3 */
PORT_BIT_SETCLR(P9, 0x08, hash_on); // P9.3
PORT_BIT_SETCLR(P7, 0x80, anaout_on); // P7.7
PORT_BIT_SETCLR(P1, 0x08, check_on); // P1.3
break;
case 20: /* P9.2, P13.0, P1.4 */
PORT_BIT_SETCLR(P9, 0x04, hash_on); // P9.2
PORT_BIT_SETCLR(P13, 0x01, anaout_on); // P13.0
PORT_BIT_SETCLR(P1, 0x10, check_on); // P1.4
break;
default:
break;

218
multical.MSI.mtud

File diff suppressed because one or more lines are too long

6673
multical.guseo.mtud

File diff suppressed because one or more lines are too long

247
multical.mtpj

@ -133,6 +133,27 @@
<TreeImageGuid>03cad1e8-2eb3-4cde-a8a3-982423631122</TreeImageGuid>
<ParentItem>cd2e4292-1297-4c3b-8415-f027a507b349</ParentItem>
</Instance>
<Instance Guid="610b5d3e-5adf-4fc8-bc41-c1567dd1faae">
<Name>r_cg_wdt.c</Name>
<Type>File</Type>
<RelativePath>r_cg_wdt.c</RelativePath>
<TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
<ParentItem>cd2e4292-1297-4c3b-8415-f027a507b349</ParentItem>
</Instance>
<Instance Guid="d4ee09ce-e601-4016-8b3a-a0b2e977801f">
<Name>r_cg_wdt_user.c</Name>
<Type>File</Type>
<RelativePath>r_cg_wdt_user.c</RelativePath>
<TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
<ParentItem>cd2e4292-1297-4c3b-8415-f027a507b349</ParentItem>
</Instance>
<Instance Guid="2f586378-d17a-4310-92df-0695b86477dc">
<Name>r_cg_wdt.h</Name>
<Type>File</Type>
<RelativePath>r_cg_wdt.h</RelativePath>
<TreeImageGuid>03cad1e8-2eb3-4cde-a8a3-982423631122</TreeImageGuid>
<ParentItem>cd2e4292-1297-4c3b-8415-f027a507b349</ParentItem>
</Instance>
<Instance Guid="82861e3a-5f66-47ce-b5d0-07c183f03a69">
<Name>OWI</Name>
<Type>Category</Type>
@ -176,6 +197,69 @@
<ParentItem>c3051400-9e2f-456f-9dab-7f2327a849a2</ParentItem>
<Property>dc0a1372-85cd-4333-b337-b22d6cefcb74</Property>
</Instance>
<Instance Guid="b2af3922-e2e6-4866-b112-fef6559c706e">
<Name>app_types.h</Name>
<Type>File</Type>
<RelativePath>app_types.h</RelativePath>
<TreeImageGuid>03cad1e8-2eb3-4cde-a8a3-982423631122</TreeImageGuid>
<ParentItem>c3051400-9e2f-456f-9dab-7f2327a849a2</ParentItem>
</Instance>
<Instance Guid="0960f7c9-320b-4b2d-a81a-b478a71746d0">
<Name>app_result.c</Name>
<Type>File</Type>
<RelativePath>app_result.c</RelativePath>
<TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
<ParentItem>c3051400-9e2f-456f-9dab-7f2327a849a2</ParentItem>
</Instance>
<Instance Guid="a9266d00-2d18-421c-a56e-aba2f9ff25a4">
<Name>app_result.h</Name>
<Type>File</Type>
<RelativePath>app_result.h</RelativePath>
<TreeImageGuid>03cad1e8-2eb3-4cde-a8a3-982423631122</TreeImageGuid>
<ParentItem>c3051400-9e2f-456f-9dab-7f2327a849a2</ParentItem>
</Instance>
<Instance Guid="a9cdf116-8cac-46ba-8657-b2800695938c">
<Name>app_cmd_parser.c</Name>
<Type>File</Type>
<RelativePath>app_cmd_parser.c</RelativePath>
<TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
<ParentItem>c3051400-9e2f-456f-9dab-7f2327a849a2</ParentItem>
</Instance>
<Instance Guid="7b6f52af-ad42-4968-a9b7-be81f4027de5">
<Name>app_cmd_parser.h</Name>
<Type>File</Type>
<RelativePath>app_cmd_parser.h</RelativePath>
<TreeImageGuid>03cad1e8-2eb3-4cde-a8a3-982423631122</TreeImageGuid>
<ParentItem>c3051400-9e2f-456f-9dab-7f2327a849a2</ParentItem>
</Instance>
<Instance Guid="bc73e110-ae8d-4f27-9dac-e0c97daecd6b">
<Name>app_scheduler.c</Name>
<Type>File</Type>
<RelativePath>app_scheduler.c</RelativePath>
<TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
<ParentItem>c3051400-9e2f-456f-9dab-7f2327a849a2</ParentItem>
</Instance>
<Instance Guid="7349a282-2652-4989-a303-4e6b811cc21b">
<Name>app_scheduler.h</Name>
<Type>File</Type>
<RelativePath>app_scheduler.h</RelativePath>
<TreeImageGuid>03cad1e8-2eb3-4cde-a8a3-982423631122</TreeImageGuid>
<ParentItem>c3051400-9e2f-456f-9dab-7f2327a849a2</ParentItem>
</Instance>
<Instance Guid="0ddbc036-0fd2-430d-b3c5-4eea25bba043">
<Name>app_owi_service.c</Name>
<Type>File</Type>
<RelativePath>app_owi_service.c</RelativePath>
<TreeImageGuid>941832c1-fc3b-4e1b-94e8-01ea17128b42</TreeImageGuid>
<ParentItem>c3051400-9e2f-456f-9dab-7f2327a849a2</ParentItem>
</Instance>
<Instance Guid="92e9584a-76ef-456d-bb4f-aa95c905dee8">
<Name>app_owi_service.h</Name>
<Type>File</Type>
<RelativePath>app_owi_service.h</RelativePath>
<TreeImageGuid>03cad1e8-2eb3-4cde-a8a3-982423631122</TreeImageGuid>
<ParentItem>c3051400-9e2f-456f-9dab-7f2327a849a2</ParentItem>
</Instance>
<Instance Guid="b8660be6-a832-48ed-b793-0021d8b0eadb">
<Name>owi.c</Name>
<Type>File</Type>
@ -349,19 +433,31 @@
<SourceItemType8>CSource</SourceItemType8>
<SourceItemGuid9>fc2298e3-7084-48f1-82a2-73802f131ffc</SourceItemGuid9>
<SourceItemType9>CSource</SourceItemType9>
<SourceItemGuid10>b8660be6-a832-48ed-b793-0021d8b0eadb</SourceItemGuid10>
<SourceItemGuid10>610b5d3e-5adf-4fc8-bc41-c1567dd1faae</SourceItemGuid10>
<SourceItemType10>CSource</SourceItemType10>
<SourceItemGuid11>e000232c-04f7-4af8-946d-b2621666c76d</SourceItemGuid11>
<SourceItemGuid11>d4ee09ce-e601-4016-8b3a-a0b2e977801f</SourceItemGuid11>
<SourceItemType11>CSource</SourceItemType11>
<SourceItemGuid12>810f033a-ef5c-49ee-a998-4b61acf35f60</SourceItemGuid12>
<SourceItemGuid12>0960f7c9-320b-4b2d-a81a-b478a71746d0</SourceItemGuid12>
<SourceItemType12>CSource</SourceItemType12>
<SourceItemGuid13>05b3a7f6-13fe-4cd9-8718-94fa300c412c</SourceItemGuid13>
<SourceItemGuid13>a9cdf116-8cac-46ba-8657-b2800695938c</SourceItemGuid13>
<SourceItemType13>CSource</SourceItemType13>
<SourceItemGuid14>3ec4bd88-055b-45d8-a20b-523e530c6a87</SourceItemGuid14>
<SourceItemGuid14>bc73e110-ae8d-4f27-9dac-e0c97daecd6b</SourceItemGuid14>
<SourceItemType14>CSource</SourceItemType14>
<SourceItemGuid15>b7caf418-449c-4afa-9d64-16f7aef4371a</SourceItemGuid15>
<SourceItemGuid15>0ddbc036-0fd2-430d-b3c5-4eea25bba043</SourceItemGuid15>
<SourceItemType15>CSource</SourceItemType15>
<SourceItemCount>16</SourceItemCount>
<SourceItemGuid16>b8660be6-a832-48ed-b793-0021d8b0eadb</SourceItemGuid16>
<SourceItemType16>CSource</SourceItemType16>
<SourceItemGuid17>e000232c-04f7-4af8-946d-b2621666c76d</SourceItemGuid17>
<SourceItemType17>CSource</SourceItemType17>
<SourceItemGuid18>810f033a-ef5c-49ee-a998-4b61acf35f60</SourceItemGuid18>
<SourceItemType18>CSource</SourceItemType18>
<SourceItemGuid19>05b3a7f6-13fe-4cd9-8718-94fa300c412c</SourceItemGuid19>
<SourceItemType19>CSource</SourceItemType19>
<SourceItemGuid20>3ec4bd88-055b-45d8-a20b-523e530c6a87</SourceItemGuid20>
<SourceItemType20>CSource</SourceItemType20>
<SourceItemGuid21>b7caf418-449c-4afa-9d64-16f7aef4371a</SourceItemGuid21>
<SourceItemType21>CSource</SourceItemType21>
<SourceItemCount>22</SourceItemCount>
<LastDeviceChangedCounter>0</LastDeviceChangedCounter>
<LastDeviceNameOnPG>R5F10PPJ</LastDeviceNameOnPG>
<LastDeviceChangedCounterOnPG>0</LastDeviceChangedCounterOnPG>
@ -813,7 +909,7 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
<LinkOptionRrm-DefaultValue>False</LinkOptionRrm-DefaultValue>
<LinkOptionRrmValue-DefaultValue />
<IsLockedByUser>False</IsLockedByUser>
<TimeTagModified--0>-8584319544808423931</TimeTagModified--0>
<TimeTagModified--0>-8584259869236164714</TimeTagModified--0>
<LinkOptionAutoSectionLayout-0>True</LinkOptionAutoSectionLayout-0>
<LinkOptionCpu-0>False</LinkOptionCpu-0>
<LinkOptionDebug-0>Debug</LinkOptionDebug-0>
@ -891,7 +987,7 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
<LinkOptionChangeMessageError-0>None</LinkOptionChangeMessageError-0>
<LinkOptionSameCodeForbid-0 />
<LinkOptionShowStruct-0>False</LinkOptionShowStruct-0>
<LinkOptionUserOptByteValue-0>E9FFF8</LinkOptionUserOptByteValue-0>
<LinkOptionUserOptByteValue-0>78FFF8</LinkOptionUserOptByteValue-0>
<LinkOptionChangeMessageErrorNumber-0 />
<LinkOptionSectionForbid-0 />
<LinkOptionSelf-0>None</LinkOptionSelf-0>
@ -1269,6 +1365,54 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
<ItemAddTime>639039961488844302</ItemAddTime>
<ItemAddTimeCount>0</ItemAddTimeCount>
</Instance>
<Instance Guid="b2af3922-e2e6-4866-b112-fef6559c706e">
<ItemAddTime>639087100227379169</ItemAddTime>
<ItemAddTimeCount>0</ItemAddTimeCount>
</Instance>
<Instance Guid="0960f7c9-320b-4b2d-a81a-b478a71746d0">
<ItemAddTime>639087100971742572</ItemAddTime>
<ItemAddTimeCount>0</ItemAddTimeCount>
</Instance>
<Instance Guid="a9266d00-2d18-421c-a56e-aba2f9ff25a4">
<ItemAddTime>639087101079868969</ItemAddTime>
<ItemAddTimeCount>0</ItemAddTimeCount>
</Instance>
<Instance Guid="a9cdf116-8cac-46ba-8657-b2800695938c">
<ItemAddTime>639087101690974087</ItemAddTime>
<ItemAddTimeCount>0</ItemAddTimeCount>
</Instance>
<Instance Guid="7b6f52af-ad42-4968-a9b7-be81f4027de5">
<ItemAddTime>639087101760942722</ItemAddTime>
<ItemAddTimeCount>0</ItemAddTimeCount>
</Instance>
<Instance Guid="bc73e110-ae8d-4f27-9dac-e0c97daecd6b">
<ItemAddTime>639087102133391109</ItemAddTime>
<ItemAddTimeCount>0</ItemAddTimeCount>
</Instance>
<Instance Guid="7349a282-2652-4989-a303-4e6b811cc21b">
<ItemAddTime>639087102209912960</ItemAddTime>
<ItemAddTimeCount>0</ItemAddTimeCount>
</Instance>
<Instance Guid="0ddbc036-0fd2-430d-b3c5-4eea25bba043">
<ItemAddTime>639087102641219680</ItemAddTime>
<ItemAddTimeCount>0</ItemAddTimeCount>
</Instance>
<Instance Guid="92e9584a-76ef-456d-bb4f-aa95c905dee8">
<ItemAddTime>639087102722017417</ItemAddTime>
<ItemAddTimeCount>0</ItemAddTimeCount>
</Instance>
<Instance Guid="610b5d3e-5adf-4fc8-bc41-c1567dd1faae">
<ItemAddTime>639112491618550995</ItemAddTime>
<ItemAddTimeCount>0</ItemAddTimeCount>
</Instance>
<Instance Guid="d4ee09ce-e601-4016-8b3a-a0b2e977801f">
<ItemAddTime>639112491618550995</ItemAddTime>
<ItemAddTimeCount>1</ItemAddTimeCount>
</Instance>
<Instance Guid="2f586378-d17a-4310-92df-0695b86477dc">
<ItemAddTime>639112491618550995</ItemAddTime>
<ItemAddTimeCount>2</ItemAddTimeCount>
</Instance>
<Instance Guid="0b7e78c3-aadd-45ee-9f9d-ffac6141eeb2">
<TimeTagModified-SourceItem0--0>-8584334295854395005</TimeTagModified-SourceItem0--0>
<SourceItem0-IsLockedByUser>False</SourceItem0-IsLockedByUser>
@ -1312,30 +1456,54 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
<SourceItem9-IsLockedByUser>False</SourceItem9-IsLockedByUser>
<SourceItem9-BuildingTarget-0>True</SourceItem9-BuildingTarget-0>
<SourceItem9-IndividualCompileOption-0>False</SourceItem9-IndividualCompileOption-0>
<TimeTagModified-SourceItem10--0>-8584333156752273418</TimeTagModified-SourceItem10--0>
<TimeTagModified-SourceItem10--0>-8584259869236224813</TimeTagModified-SourceItem10--0>
<SourceItem10-IsLockedByUser>False</SourceItem10-IsLockedByUser>
<SourceItem10-BuildingTarget-0>True</SourceItem10-BuildingTarget-0>
<SourceItem10-IndividualCompileOption-0>False</SourceItem10-IndividualCompileOption-0>
<TimeTagModified-SourceItem11--0>-8584333156677193010</TimeTagModified-SourceItem11--0>
<TimeTagModified-SourceItem11--0>-8584259869236214846</TimeTagModified-SourceItem11--0>
<SourceItem11-IsLockedByUser>False</SourceItem11-IsLockedByUser>
<SourceItem11-BuildingTarget-0>True</SourceItem11-BuildingTarget-0>
<SourceItem11-IndividualCompileOption-0>False</SourceItem11-IndividualCompileOption-0>
<TimeTagModified-SourceItem12--0>-8584333156562053237</TimeTagModified-SourceItem12--0>
<TimeTagModified-SourceItem12--0>-8584285259883033236</TimeTagModified-SourceItem12--0>
<SourceItem12-IsLockedByUser>False</SourceItem12-IsLockedByUser>
<SourceItem12-BuildingTarget-0>True</SourceItem12-BuildingTarget-0>
<SourceItem12-IndividualCompileOption-0>False</SourceItem12-IndividualCompileOption-0>
<TimeTagModified-SourceItem13--0>-8584333156436902697</TimeTagModified-SourceItem13--0>
<TimeTagModified-SourceItem13--0>-8584285259163801721</TimeTagModified-SourceItem13--0>
<SourceItem13-IsLockedByUser>False</SourceItem13-IsLockedByUser>
<SourceItem13-BuildingTarget-0>True</SourceItem13-BuildingTarget-0>
<SourceItem13-IndividualCompileOption-0>False</SourceItem13-IndividualCompileOption-0>
<TimeTagModified-SourceItem14--0>-8584332530203484147</TimeTagModified-SourceItem14--0>
<TimeTagModified-SourceItem14--0>-8584285258721384699</TimeTagModified-SourceItem14--0>
<SourceItem14-IsLockedByUser>False</SourceItem14-IsLockedByUser>
<SourceItem14-BuildingTarget-0>True</SourceItem14-BuildingTarget-0>
<SourceItem14-IndividualCompileOption-0>False</SourceItem14-IndividualCompileOption-0>
<TimeTagModified-SourceItem15--0>-8584332399365931506</TimeTagModified-SourceItem15--0>
<TimeTagModified-SourceItem15--0>-8584285258213556128</TimeTagModified-SourceItem15--0>
<SourceItem15-IsLockedByUser>False</SourceItem15-IsLockedByUser>
<SourceItem15-BuildingTarget-0>True</SourceItem15-BuildingTarget-0>
<SourceItem15-IndividualCompileOption-0>False</SourceItem15-IndividualCompileOption-0>
<TimeTagModified-SourceItem16--0>-8584333156752273418</TimeTagModified-SourceItem16--0>
<SourceItem16-IsLockedByUser>False</SourceItem16-IsLockedByUser>
<SourceItem16-BuildingTarget-0>True</SourceItem16-BuildingTarget-0>
<SourceItem16-IndividualCompileOption-0>False</SourceItem16-IndividualCompileOption-0>
<TimeTagModified-SourceItem17--0>-8584333156677193010</TimeTagModified-SourceItem17--0>
<SourceItem17-IsLockedByUser>False</SourceItem17-IsLockedByUser>
<SourceItem17-BuildingTarget-0>True</SourceItem17-BuildingTarget-0>
<SourceItem17-IndividualCompileOption-0>False</SourceItem17-IndividualCompileOption-0>
<TimeTagModified-SourceItem18--0>-8584333156562053237</TimeTagModified-SourceItem18--0>
<SourceItem18-IsLockedByUser>False</SourceItem18-IsLockedByUser>
<SourceItem18-BuildingTarget-0>True</SourceItem18-BuildingTarget-0>
<SourceItem18-IndividualCompileOption-0>False</SourceItem18-IndividualCompileOption-0>
<TimeTagModified-SourceItem19--0>-8584333156436902697</TimeTagModified-SourceItem19--0>
<SourceItem19-IsLockedByUser>False</SourceItem19-IsLockedByUser>
<SourceItem19-BuildingTarget-0>True</SourceItem19-BuildingTarget-0>
<SourceItem19-IndividualCompileOption-0>False</SourceItem19-IndividualCompileOption-0>
<TimeTagModified-SourceItem20--0>-8584332530203484147</TimeTagModified-SourceItem20--0>
<SourceItem20-IsLockedByUser>False</SourceItem20-IsLockedByUser>
<SourceItem20-BuildingTarget-0>True</SourceItem20-BuildingTarget-0>
<SourceItem20-IndividualCompileOption-0>False</SourceItem20-IndividualCompileOption-0>
<TimeTagModified-SourceItem21--0>-8584332399365931506</TimeTagModified-SourceItem21--0>
<SourceItem21-IsLockedByUser>False</SourceItem21-IsLockedByUser>
<SourceItem21-BuildingTarget-0>True</SourceItem21-BuildingTarget-0>
<SourceItem21-IndividualCompileOption-0>False</SourceItem21-IndividualCompileOption-0>
</Instance>
</Class>
<Class Guid="44fa27c9-0aa0-4297-bd3b-2c5c5bdb8881">
@ -2686,6 +2854,7 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;CellActivation&gt;3&lt;/CellActivation&gt;
&lt;Header href="#ref-62"/&gt;
&lt;Key id="ref-63"&gt;Recommend Connection for Unused&lt;/Key&gt;
&lt;Width&gt;239&lt;/Width&gt;
&lt;IsBound&gt;true&lt;/IsBound&gt;
&lt;/a1:UltraGridColumn&gt;
&lt;a1:UltraGridColumn id="ref-42" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/Infragistics.Win.UltraWinGrid/Infragistics4.Win.UltraWinGrid.v12.2"&gt;
@ -3078,6 +3247,7 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;Header href="#ref-57"/&gt;
&lt;Hidden&gt;true&lt;/Hidden&gt;
&lt;Key id="ref-58"&gt;fldParentID&lt;/Key&gt;
&lt;Width&gt;112&lt;/Width&gt;
&lt;IsBound&gt;true&lt;/IsBound&gt;
&lt;ExcludeFromColumnChooser&gt;1&lt;/ExcludeFromColumnChooser&gt;
&lt;/a1:UltraGridColumn&gt;
@ -3120,6 +3290,7 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;Header href="#ref-70"/&gt;
&lt;Hidden&gt;true&lt;/Hidden&gt;
&lt;Key id="ref-71"&gt;MacroGroupName&lt;/Key&gt;
&lt;Width&gt;132&lt;/Width&gt;
&lt;IsBound&gt;true&lt;/IsBound&gt;
&lt;ExcludeFromColumnChooser&gt;1&lt;/ExcludeFromColumnChooser&gt;
&lt;/a1:UltraGridColumn&gt;
@ -3139,6 +3310,7 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;Header href="#ref-73"/&gt;
&lt;Hidden&gt;true&lt;/Hidden&gt;
&lt;Key href="#ref-58"/&gt;
&lt;Width&gt;112&lt;/Width&gt;
&lt;IsBound&gt;true&lt;/IsBound&gt;
&lt;ExcludeFromColumnChooser&gt;1&lt;/ExcludeFromColumnChooser&gt;
&lt;/a1:UltraGridColumn&gt;
@ -3209,6 +3381,7 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;CellActivation&gt;3&lt;/CellActivation&gt;
&lt;Header href="#ref-92"/&gt;
&lt;Key id="ref-93"&gt;Recommend Connection for Unused&lt;/Key&gt;
&lt;Width&gt;239&lt;/Width&gt;
&lt;IsBound&gt;true&lt;/IsBound&gt;
&lt;/a1:UltraGridColumn&gt;
&lt;a1:UltraGridColumn id="ref-55" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/Infragistics.Win.UltraWinGrid/Infragistics4.Win.UltraWinGrid.v12.2"&gt;
@ -3638,6 +3811,7 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;Header href="#ref-51"/&gt;
&lt;Hidden&gt;true&lt;/Hidden&gt;
&lt;Key id="ref-52"&gt;relation&lt;/Key&gt;
&lt;Width&gt;112&lt;/Width&gt;
&lt;IsBound&gt;true&lt;/IsBound&gt;
&lt;ExcludeFromColumnChooser&gt;1&lt;/ExcludeFromColumnChooser&gt;
&lt;/a1:UltraGridColumn&gt;
@ -3666,6 +3840,7 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;Header href="#ref-59"/&gt;
&lt;Hidden&gt;true&lt;/Hidden&gt;
&lt;Key href="#ref-52"/&gt;
&lt;Width&gt;112&lt;/Width&gt;
&lt;IsBound&gt;true&lt;/IsBound&gt;
&lt;ExcludeFromColumnChooser&gt;1&lt;/ExcludeFromColumnChooser&gt;
&lt;/a1:UltraGridColumn&gt;
@ -3736,6 +3911,7 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;CellActivation&gt;3&lt;/CellActivation&gt;
&lt;Header href="#ref-78"/&gt;
&lt;Key id="ref-79"&gt;Recommend Connection for Unused&lt;/Key&gt;
&lt;Width&gt;239&lt;/Width&gt;
&lt;IsBound&gt;true&lt;/IsBound&gt;
&lt;/a1:UltraGridColumn&gt;
&lt;a1:UltraGridColumn id="ref-50" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/Infragistics.Win.UltraWinGrid/Infragistics4.Win.UltraWinGrid.v12.2"&gt;
@ -3820,11 +3996,11 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
<KeyTopViewPartsCollapsed />
<KEY_SAVE_ALLOCATED_FUNCTION>False</KEY_SAVE_ALLOCATED_FUNCTION>
<KEY_SAVE_DEVICE_PIN_LIST_ZOOM>100</KEY_SAVE_DEVICE_PIN_LIST_ZOOM>
<KEY_SAVE_COLUMN_WIDTH_PIN_NUMBER>0:78:78,1:77:77,2:400:400,3:61:61,4:40:40,5:50:50,6:160:160,7:210:210,8:239:210,9:210:210,10:100:100</KEY_SAVE_COLUMN_WIDTH_PIN_NUMBER>
<KEY_SAVE_COLUMN_WIDTH_MACRO_PARENT>0:112:98,1:245:245,2:42:42,3:44:44,4:121:121,5:132:120,6:97:85</KEY_SAVE_COLUMN_WIDTH_MACRO_PARENT>
<KEY_SAVE_COLUMN_WIDTH_MACRO_CHILD>0:112:98,1:77:77,2:77:77,3:400:400,4:61:61,5:40:40,6:50:50,7:160:160,8:210:210,9:239:210,10:210:210,11:100:100</KEY_SAVE_COLUMN_WIDTH_MACRO_CHILD>
<KEY_SAVE_COLUMN_WIDTH_EXTERNAL_PARENT>0:112:98,1:100:100,2:43:43,3:169:150</KEY_SAVE_COLUMN_WIDTH_EXTERNAL_PARENT>
<KEY_SAVE_COLUMN_WIDTH_EXTERNAL_CHILD>0:112:98,1:78:78,2:77:77,3:400:400,4:61:61,5:40:40,6:50:50,7:160:160,8:210:210,9:239:210,10:210:210</KEY_SAVE_COLUMN_WIDTH_EXTERNAL_CHILD>
<KEY_SAVE_COLUMN_WIDTH_PIN_NUMBER>0:78:78,1:77:77,2:400:400,3:61:61,4:40:40,5:50:50,6:160:160,7:210:210,8:239:239,9:210:210,10:100:100</KEY_SAVE_COLUMN_WIDTH_PIN_NUMBER>
<KEY_SAVE_COLUMN_WIDTH_MACRO_PARENT>0:112:112,1:245:245,2:42:42,3:44:44,4:121:121,5:132:132,6:97:85</KEY_SAVE_COLUMN_WIDTH_MACRO_PARENT>
<KEY_SAVE_COLUMN_WIDTH_MACRO_CHILD>0:112:112,1:77:77,2:77:77,3:400:400,4:61:61,5:40:40,6:50:50,7:160:160,8:210:210,9:239:239,10:210:210,11:100:100</KEY_SAVE_COLUMN_WIDTH_MACRO_CHILD>
<KEY_SAVE_COLUMN_WIDTH_EXTERNAL_PARENT>0:112:112,1:100:100,2:43:43,3:169:150</KEY_SAVE_COLUMN_WIDTH_EXTERNAL_PARENT>
<KEY_SAVE_COLUMN_WIDTH_EXTERNAL_CHILD>0:112:112,1:78:78,2:77:77,3:400:400,4:61:61,5:40:40,6:50:50,7:160:160,8:210:210,9:239:239,10:210:210</KEY_SAVE_COLUMN_WIDTH_EXTERNAL_CHILD>
<KEY_SAVE_CREATED_PROJECT_DATA>True</KEY_SAVE_CREATED_PROJECT_DATA>
<KEY_SAVE_DEVICE_CHANGED_COUNTER>0</KEY_SAVE_DEVICE_CHANGED_COUNTER>
</Instance>
@ -4300,7 +4476,7 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;StartAddressOfOnChipDebugOptionBytes Name="GOStart" Text="3FE00" /&gt;
&lt;SizeOfOnChipDebugOptionBytesArea Name="GOSizeValue" Text="512" /&gt;
&lt;UserOptionBytes Name="GB" Text="1" /&gt;
&lt;UserOptionBytesValue Name="GBValue" Text="E9FFF8" /&gt;
&lt;UserOptionBytesValue Name="GBValue" Text="78FFF8" /&gt;
&lt;RAMStartAddress Chip="R5F10PGJ,R5F10PLJ,R5F10PMJ,R5F10PPJ" Name="RAMStartAddress" Fixed="" Text="000FAF00" /&gt;
&lt;RAMEndAddress Name="RAMEndAddress" Fixed="" Text="000FFEFF" /&gt;
&lt;ROMEndAddress Chip="R5F10PGJ,R5F10PLJ,R5F10PMJ,R5F10PPJ" Name="ROMEndAddress" Fixed="" Text="0003FFFF" /&gt;
@ -5548,17 +5724,17 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;r_cg_timer.h UserName="r_cg_timer.h" LibName=".h" InUse="0" /&gt;
&lt;/TAU&gt;
&lt;WDT&gt;
&lt;r_cg_wdt.c UserName="r_cg_wdt.c" LibName=".c" InUse="0"&gt;
&lt;r_cg_wdt.c UserName="r_cg_wdt.c" LibName=".c" InUse="1"&gt;
&lt;Type R_WDT_Create="void R_WDT_Create(void)" R_WDT_Restart="void R_WDT_Restart(void)" /&gt;
&lt;R_WDT_Create UserName="R_WDT_Create" LibName="R_WDT_Create" InUse="0" Init="1" InitMode="" /&gt;
&lt;R_WDT_Restart UserName="R_WDT_Restart" LibName="R_WDT_Restart" InUse="0" /&gt;
&lt;R_WDT_Create UserName="R_WDT_Create" LibName="R_WDT_Create" InUse="1" Init="1" InitMode="" /&gt;
&lt;R_WDT_Restart UserName="R_WDT_Restart" LibName="R_WDT_Restart" InUse="1" /&gt;
&lt;/r_cg_wdt.c&gt;
&lt;r_cg_wdt_user.c UserName="r_cg_wdt_user.c" LibName="_user.c" InUse="0"&gt;
&lt;r_cg_wdt_user.c UserName="r_cg_wdt_user.c" LibName="_user.c" InUse="1"&gt;
&lt;Type R_WDT_Create_UserInit="void R_WDT_Create_UserInit(void)" r_wdt_interrupt="__interrupt static void r_wdt_interrupt(void)" /&gt;
&lt;R_WDT_Create_UserInit UserName="R_WDT_Create_UserInit" LibName="R_WDT_Create_UserInit" InUse="0" /&gt;
&lt;r_wdt_interrupt UserName="r_wdt_interrupt" INTHandle="" LibName="r_wdt_interrupt" InUse="0" /&gt;
&lt;/r_cg_wdt_user.c&gt;
&lt;r_cg_wdt.h UserName="r_cg_wdt.h" LibName=".h" InUse="0" /&gt;
&lt;r_cg_wdt.h UserName="r_cg_wdt.h" LibName=".h" InUse="1" /&gt;
&lt;/WDT&gt;
&lt;RTC&gt;
&lt;r_cg_rtc.c UserName="r_cg_rtc.c" LibName=".c" InUse="0"&gt;
@ -5788,7 +5964,7 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;cg_ocd_trace_size Name="cg_ocd_trace_size" Value="512" /&gt;
&lt;cg_security8 Name="cg_security8" Value="00" /&gt;
&lt;cg_security4 Name="cg_security4" Value="00" /&gt;
&lt;wdt_option Name="wdt_option" Value="E9" /&gt;
&lt;wdt_option Name="wdt_option" Value="78" /&gt;
&lt;cg_crc_area Name="cg_crc_area" Value="00" /&gt;
&lt;cg_security3 Name="cg_security3" Value="00" /&gt;
&lt;cg_iawctl_value Name="cg_iawctl_value" Value="00" /&gt;
@ -5850,8 +6026,8 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;TMRD0 SetFlag="False" MacroName="TMRD" Channel="0" TabEnable="True" /&gt;
&lt;TMRD1 SetFlag="False" MacroName="TMRD" Channel="1" TabEnable="True" /&gt;
&lt;/TAU&gt;
&lt;WDT Prepared="true" SetFlag="False" HelpID="watchdogtimer" NeedRefresh="False"&gt;
&lt;WDT SetFlag="False" MacroName="WDT" /&gt;
&lt;WDT Prepared="true" SetFlag="True" HelpID="watchdogtimer" NeedRefresh="False"&gt;
&lt;WDT SetFlag="True" MacroName="WDT" /&gt;
&lt;/WDT&gt;
&lt;RTC SetFlag="False" HelpID="rtc" NeedRefresh="False"&gt;
&lt;RTC MacroName="RTC" SetFlag="False" /&gt;
@ -7120,13 +7296,13 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;/PortP15&gt;
&lt;/PORT&gt;
&lt;WDT&gt;
&lt;setting name="WDT_MODULE_USED" value="false" /&gt;
&lt;setting name="WDT_MODULE_UNUSE" value="true" /&gt;
&lt;setting name="WDT_MODULE_USED" value="true" /&gt;
&lt;setting name="WDT_MODULE_UNUSE" value="false" /&gt;
&lt;setting name="WDT_OVERFLOW_TIME" value="4" /&gt;
&lt;setting name="WDT_WINDOW_OPEN_TIME" value="2" /&gt;
&lt;setting name="WDT_HALT_STOP_OPERATION_ENABLE" value="true" /&gt;
&lt;setting name="WDT_HALT_STOP_OPERATION_STOP" value="false" /&gt;
&lt;setting name="WDT_INTERRUPT_USED" value="true" /&gt;
&lt;setting name="WDT_WINDOW_OPEN_TIME" value="0" /&gt;
&lt;setting name="WDT_HALT_STOP_OPERATION_ENABLE" value="false" /&gt;
&lt;setting name="WDT_HALT_STOP_OPERATION_STOP" value="true" /&gt;
&lt;setting name="WDT_INTERRUPT_USED" value="false" /&gt;
&lt;setting name="WDT_INTERRUPT_PRIORITY" value="3" /&gt;
&lt;/WDT&gt;
&lt;ADC&gt;
@ -7303,7 +7479,6 @@ C:\Program Files (x86)\Renesas Electronics\CS+\CC\FAA\V1.05.00
&lt;/RL78F14&gt;</CodeGenerator>
<FormatVersion>1.0</FormatVersion>
<ToolGUID>95279bbe-6d22-4c1c-844e-cd135cf17b88</ToolGUID>
<CodeGeneratorItem>cd2e4292-1297-4c3b-8415-f027a507b349</CodeGeneratorItem>
</Instance>
</Class>
<Class Guid="2a2c2a43-ecdb-4e88-80bd-e75f3e33db90">

52
multical.rcpe

@ -24,6 +24,9 @@
<Path>r_cg_port.c</Path>
<Path>r_cg_port_user.c</Path>
<Path>r_cg_port.h</Path>
<Path>r_cg_wdt.c</Path>
<Path>r_cg_wdt_user.c</Path>
<Path>r_cg_wdt.h</Path>
</Category>
<Category Name="drivers">
<Category Name="OWI">
@ -51,6 +54,15 @@
<Path>gatectrl.h</Path>
<Path>gatectrl.c</Path>
</Category>
<Path>app_types.h</Path>
<Path>app_result.c</Path>
<Path>app_result.h</Path>
<Path>app_cmd_parser.c</Path>
<Path>app_cmd_parser.h</Path>
<Path>app_scheduler.c</Path>
<Path>app_scheduler.h</Path>
<Path>app_owi_service.c</Path>
<Path>app_owi_service.h</Path>
</Category>
</Files>
<DebugOptions>
@ -79,6 +91,12 @@
<Path>DefaultBuild\delay.obj</Path>
<Path>DefaultBuild\dipSwitch.obj</Path>
<Path>DefaultBuild\gatectrl.obj</Path>
<Path>DefaultBuild\app_result.obj</Path>
<Path>DefaultBuild\app_cmd_parser.obj</Path>
<Path>DefaultBuild\app_scheduler.obj</Path>
<Path>DefaultBuild\app_owi_service.obj</Path>
<Path>DefaultBuild\r_cg_wdt.obj</Path>
<Path>DefaultBuild\r_cg_wdt_user.obj</Path>
</LinkOrder>
<CommonOptions>
<IncludePathForC>..\..\Documents\카카오톡 받은 파일\IDH1.1\IDH1.1</IncludePathForC>
@ -115,7 +133,7 @@
<Option>-OUtput=%BuildModeName%\%ProjectName%.abs</Option>
<Option>-OCDBG=84</Option>
<Option>-DEBUG_MONITOR=3FE00-3FFFF</Option>
<Option>-USER_OPT_BYTE=E9FFF8</Option>
<Option>-USER_OPT_BYTE=78FFF8</Option>
<Option>-OCDTR</Option>
<Option>-LISt=%BuildModeName%\%ProjectName%.map</Option>
<Option>-SHow=SYmbol,Total_size</Option>
@ -379,7 +397,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\temp\Desktop\new_fw" /&gt;
&lt;ProjectPath Name="PrjPath" Text="C:\Users\guseo\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;
@ -396,7 +414,7 @@
&lt;StartAddressOfOnChipDebugOptionBytes Name="GOStart" Text="3FE00" /&gt;
&lt;SizeOfOnChipDebugOptionBytesArea Name="GOSizeValue" Text="512" /&gt;
&lt;UserOptionBytes Name="GB" Text="1" /&gt;
&lt;UserOptionBytesValue Name="GBValue" Text="E9FFF8" /&gt;
&lt;UserOptionBytesValue Name="GBValue" Text="78FFF8" /&gt;
&lt;RAMStartAddress Chip="R5F10PGJ,R5F10PLJ,R5F10PMJ,R5F10PPJ" Name="RAMStartAddress" Fixed="" Text="000FAF00" /&gt;
&lt;RAMEndAddress Name="RAMEndAddress" Fixed="" Text="000FFEFF" /&gt;
&lt;ROMEndAddress Chip="R5F10PGJ,R5F10PLJ,R5F10PMJ,R5F10PPJ" Name="ROMEndAddress" Fixed="" Text="0003FFFF" /&gt;
@ -1644,17 +1662,17 @@
&lt;r_cg_timer.h UserName="r_cg_timer.h" LibName=".h" InUse="0" /&gt;
&lt;/TAU&gt;
&lt;WDT&gt;
&lt;r_cg_wdt.c UserName="r_cg_wdt.c" LibName=".c" InUse="0"&gt;
&lt;r_cg_wdt.c UserName="r_cg_wdt.c" LibName=".c" InUse="1"&gt;
&lt;Type R_WDT_Create="void R_WDT_Create(void)" R_WDT_Restart="void R_WDT_Restart(void)" /&gt;
&lt;R_WDT_Create UserName="R_WDT_Create" LibName="R_WDT_Create" InUse="0" Init="1" InitMode="" /&gt;
&lt;R_WDT_Restart UserName="R_WDT_Restart" LibName="R_WDT_Restart" InUse="0" /&gt;
&lt;R_WDT_Create UserName="R_WDT_Create" LibName="R_WDT_Create" InUse="1" Init="1" InitMode="" /&gt;
&lt;R_WDT_Restart UserName="R_WDT_Restart" LibName="R_WDT_Restart" InUse="1" /&gt;
&lt;/r_cg_wdt.c&gt;
&lt;r_cg_wdt_user.c UserName="r_cg_wdt_user.c" LibName="_user.c" InUse="0"&gt;
&lt;r_cg_wdt_user.c UserName="r_cg_wdt_user.c" LibName="_user.c" InUse="1"&gt;
&lt;Type R_WDT_Create_UserInit="void R_WDT_Create_UserInit(void)" r_wdt_interrupt="__interrupt static void r_wdt_interrupt(void)" /&gt;
&lt;R_WDT_Create_UserInit UserName="R_WDT_Create_UserInit" LibName="R_WDT_Create_UserInit" InUse="0" /&gt;
&lt;r_wdt_interrupt UserName="r_wdt_interrupt" INTHandle="" LibName="r_wdt_interrupt" InUse="0" /&gt;
&lt;/r_cg_wdt_user.c&gt;
&lt;r_cg_wdt.h UserName="r_cg_wdt.h" LibName=".h" InUse="0" /&gt;
&lt;r_cg_wdt.h UserName="r_cg_wdt.h" LibName=".h" InUse="1" /&gt;
&lt;/WDT&gt;
&lt;RTC&gt;
&lt;r_cg_rtc.c UserName="r_cg_rtc.c" LibName=".c" InUse="0"&gt;
@ -1884,7 +1902,7 @@
&lt;cg_ocd_trace_size Name="cg_ocd_trace_size" Value="512" /&gt;
&lt;cg_security8 Name="cg_security8" Value="00" /&gt;
&lt;cg_security4 Name="cg_security4" Value="00" /&gt;
&lt;wdt_option Name="wdt_option" Value="E9" /&gt;
&lt;wdt_option Name="wdt_option" Value="78" /&gt;
&lt;cg_crc_area Name="cg_crc_area" Value="00" /&gt;
&lt;cg_security3 Name="cg_security3" Value="00" /&gt;
&lt;cg_iawctl_value Name="cg_iawctl_value" Value="00" /&gt;
@ -1946,8 +1964,8 @@
&lt;TMRD0 SetFlag="False" MacroName="TMRD" Channel="0" TabEnable="True" /&gt;
&lt;TMRD1 SetFlag="False" MacroName="TMRD" Channel="1" TabEnable="True" /&gt;
&lt;/TAU&gt;
&lt;WDT Prepared="true" SetFlag="False" HelpID="watchdogtimer" NeedRefresh="False"&gt;
&lt;WDT SetFlag="False" MacroName="WDT" /&gt;
&lt;WDT Prepared="true" SetFlag="True" HelpID="watchdogtimer" NeedRefresh="False"&gt;
&lt;WDT SetFlag="True" MacroName="WDT" /&gt;
&lt;/WDT&gt;
&lt;RTC SetFlag="False" HelpID="rtc" NeedRefresh="False"&gt;
&lt;RTC MacroName="RTC" SetFlag="False" /&gt;
@ -3216,13 +3234,13 @@
&lt;/PortP15&gt;
&lt;/PORT&gt;
&lt;WDT&gt;
&lt;setting name="WDT_MODULE_USED" value="false" /&gt;
&lt;setting name="WDT_MODULE_UNUSE" value="true" /&gt;
&lt;setting name="WDT_MODULE_USED" value="true" /&gt;
&lt;setting name="WDT_MODULE_UNUSE" value="false" /&gt;
&lt;setting name="WDT_OVERFLOW_TIME" value="4" /&gt;
&lt;setting name="WDT_WINDOW_OPEN_TIME" value="2" /&gt;
&lt;setting name="WDT_HALT_STOP_OPERATION_ENABLE" value="true" /&gt;
&lt;setting name="WDT_HALT_STOP_OPERATION_STOP" value="false" /&gt;
&lt;setting name="WDT_INTERRUPT_USED" value="true" /&gt;
&lt;setting name="WDT_WINDOW_OPEN_TIME" value="0" /&gt;
&lt;setting name="WDT_HALT_STOP_OPERATION_ENABLE" value="false" /&gt;
&lt;setting name="WDT_HALT_STOP_OPERATION_STOP" value="true" /&gt;
&lt;setting name="WDT_INTERRUPT_USED" value="false" /&gt;
&lt;setting name="WDT_INTERRUPT_PRIORITY" value="3" /&gt;
&lt;/WDT&gt;
&lt;ADC&gt;

281
multical.temp.mtud

File diff suppressed because one or more lines are too long

523
owi.c

@ -1,30 +1,42 @@
#include "owi.h"
#include "delay.h"
#include "r_cg_wdt.h"
#include <string.h>
#include <stdio.h>
#include "uart.h"
#include "r_cg_wdt.h"
#ifndef OWI_STRONG_DRIVE_HIGH_US
#define OWI_STRONG_DRIVE_HIGH_US 5u
#endif
/* 내부 상태 */
static uint32_t bit_period_us = OWI_BIT_PERIOD_US;
static uint8_t g_owi_timeout_latched = 0;
static uint16_t g_owi_last_timeout_byte_index = 0xFFFFu;
static uint8_t g_owi_last_timeout_bit_index = 0xFFu;
static uint16_t g_owi_current_read_byte_index = 0u;
static uint8_t g_owi_current_read_bit_index = 0u;
/* =========================================================
* GPIO helpers (P70 / HW Open-Drain)
* - LOW : + 0
* - HIGH : (Hi-Z) release (pull-up으로 )
* - HIGH : (Hi-Z) release
* ========================================================= */
void GPIO_Clear(void)
{
/* latch low (P70만) */
OWI_PORT_P &= (uint8_t)~OWI_PIN_MASK;
/* output mode (P70만) */
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
}
void GPIO_Input(void)
{
/* input mode (Hi-Z) */
OWI_PORT_PM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PM |= (uint8_t)OWI_PIN_MASK;
}
int GPIO_Read(void)
@ -32,22 +44,80 @@ int GPIO_Read(void)
return (OWI_PORT_P & (uint8_t)OWI_PIN_MASK) ? 1 : 0;
}
static void OWI_Release(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PM |= (uint8_t)OWI_PIN_MASK;
}
static void GPIO_StrongDriveHighKick(uint32_t kick_us)
{
OWI_Release();
if (!GPIO_Read()) {
return;
}
OWI_PORT_POM &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_P |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
delay_us(kick_us);
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_Release();
}
void GPIO_ForceHighKick(void)
{
GPIO_StrongDriveHighKick(OWI_STRONG_DRIVE_HIGH_US);
}
static void OWI_DriveLow(void)
{
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
}
/* =========================================================
* Diagnostics
* ========================================================= */
uint8_t OWI_HasTimeout(void)
{
return g_owi_timeout_latched;
}
void OWI_ClearTimeout(void)
{
g_owi_timeout_latched = 0;
g_owi_last_timeout_byte_index = 0xFFFFu;
g_owi_last_timeout_bit_index = 0xFFu;
}
uint16_t OWI_GetLastTimeoutByteIndex(void)
{
return g_owi_last_timeout_byte_index;
}
uint8_t OWI_GetLastTimeoutBitIndex(void)
{
return g_owi_last_timeout_bit_index;
}
/* =========================================================
* OWI Init
* ========================================================= */
void OWI_Init(uint32_t bit_time_us)
{
bit_period_us = bit_time_us;
(void)bit_period_us; /* 현재 타이밍은 매크로(TBIT) 사용 */
(void)bit_period_us;
/* HW Open-Drain enable: P70만 */
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PU &= (uint8_t)~OWI_PIN_MASK;
/* 내부 Pull-up: 필요 시 사용(외부 풀업이면 꺼도 됨) */
//OWI_PORT_PU |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PU &= (uint8_t)~OWI_PIN_MASK; // P70만 OFF
/* idle = release */
OWI_ClearTimeout();
GPIO_Input();
}
@ -58,8 +128,9 @@ void OWI_Start(void)
{
GPIO_Clear();
delay_us(TSTART_HOLD);
GPIO_Input();
delay_us(TBIT / 2u);
delay_us(TBIT);
}
void OWI_Stop(void)
@ -67,7 +138,88 @@ void OWI_Stop(void)
GPIO_Input();
delay_us(TSTOP_LOW);
delay_us(TIDLE);
GPIO_Clear();
}
static void OWI_StopWrite(void)
{
OWI_Release();
delay_us(TSTOP_LOW);
delay_us(TIDLE);
}
static void OWI_StopRead(void)
{
OWI_DriveLow();
delay_us(TSTOP_LOW);
OWI_Release();
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)
@ -80,12 +232,14 @@ void OWI_SecureStop(void)
for (i = 0; i < (int)SECURE_TOGGLE_COUNT; i++) {
GPIO_Input();
delay_us(SECURE_TOGGLE_HIGH);
GPIO_Clear();
delay_us(SECURE_TOGGLE_LOW);
}
GPIO_Input();
delay_us(SECURE_HIGH);
GPIO_Clear();
delay_us(TSTART_HOLD);
GPIO_Input();
@ -99,12 +253,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;
/* 기존 동작 순서 유지 */
GPIO_Input(); /* Release (High by pull-up) */
/* HIGH 구간 */
OWI_Release();
delay_us(t_high);
GPIO_Clear(); /* Drive Low */
/* LOW 구간 */
OWI_DriveLow();
delay_us(t_low);
/* 다음 슬롯 시작 전 반드시 release */
OWI_Release();
}
void OWI_WriteByte(uint8_t data)
@ -118,23 +276,51 @@ void OWI_WriteByte(uint8_t data)
uint8_t OWI_ReadBit(void)
{
uint8_t bit;
int timeout = 500;
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) {
delay_us(1);
/* 2) 다음 LOW 시작 대기 */
timeout = (int)(bit_period_us * 2u);
while (GPIO_Read() && timeout-- > 0) {
delay_us(1u);
}
if (timeout <= 0) {
HOST_PRINT("OWI Timeout\r\n");
return 0xFF;
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;
}
delay_us(50);
bit = (uint8_t)GPIO_Read();
delay_us(30);
/* 3) LOW가 유지되는 시간을 직접 측정 */
while (!GPIO_Read() && low_width < (int)(bit_period_us * 2u)) {
delay_us(1u);
low_width++;
}
return bit;
/* 4) LOW 폭 기준으로 판정
- 1
- 0
threshold ~= TBIT/2
*/
return (low_width < (int)(bit_period_us / 2u)) ? 1u : 0u;
}
uint8_t OWI_ReadByte(void)
@ -143,7 +329,11 @@ uint8_t OWI_ReadByte(void)
int i;
for (i = 7; i >= 0; i--) {
g_owi_current_read_bit_index = (uint8_t)(7 - i);
data |= (uint8_t)(OWI_ReadBit() << i);
if (OWI_HasTimeout()) {
break;
}
}
return data;
}
@ -160,9 +350,18 @@ void OWI_T_ReadBytesAndPrint(int length)
uint8_t va0, va1;
if (length > 129) length = 129;
if (length <= 0) return;
OWI_ClearTimeout();
for (i = 0; i < length; i++) {
R_WDT_Restart();
g_owi_current_read_byte_index = (uint16_t)i;
buf[i] = OWI_ReadByte();
if (OWI_HasTimeout()) {
i++;
break;
}
}
sprintf(uart_buf, "%02X ", buf[0]);
@ -171,121 +370,160 @@ void OWI_T_ReadBytesAndPrint(int length)
for (i = 1; i < length; i += 2) {
va0 = buf[i];
va1 = buf[i + 1];
va1 = (uint8_t)((i + 1 < length) ? buf[i + 1] : 0u);
delay(10000);
delay_us(200);
sprintf(uart_buf, "%02X%02X ", va0, va1);
strcpy(tmp_buf, uart_buf);
HOST_PRINT(tmp_buf);
delay(10000);
delay_us(200);
}
}
/* =========================================================
* Command / Diagnostic ( )
* Raw helpers
* ========================================================= */
#define OWI_MAX_RETRY 2
#define OWI_RECOVERY_MIN_US 500
void OWI_A_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id)
{
uint8_t CMD_LIST[6][4] = {
{0x50,0x2E,0x00,0x00},
{0x50,0x2E,0x01,0x00},
{0x50,0x2E,0x02,0x00},
{0x50,0x2E,0x16,0x00},
{0x50,0x2E,0x41,0x00},
{0x50,0x2E,0x00,0x00}
};
char line[128];
size_t n = 0;
uint8_t rx[RAM_BYTES];
int i, j, retry, all_ff;
uint8_t read_address = 0x51;
delay_us(7000);
for (j = 0; j < 6; j++) {
OWI_SecureStop();
for (i = 0; i < 4; i++) {
OWI_WriteByte(CMD_LIST[j][i]);
}
OWI_Stop();
static void owi_result_init(owi_io_result_t *r)
{
if (!r) return;
memset(r, 0, sizeof(*r));
r->ok = 1;
r->timeout_byte_index = 0xFFFFu;
r->timeout_bit_index = 0xFFu;
}
delay_us(OWI_RECOVERY_MIN_US);
static void owi_result_latch_timeout(owi_io_result_t *r)
{
if (!r) return;
if (OWI_HasTimeout()) {
r->ok = 0;
r->timeout = 1;
r->timeout_byte_index = OWI_GetLastTimeoutByteIndex();
r->timeout_bit_index = OWI_GetLastTimeoutBitIndex();
}
}
for (i = 0; i < RAM_BYTES; i++) rx[i] = 0xFF;
void OWI_T_CommandModeRaw(const uint8_t *tx_data, uint8_t tx_len, uint8_t id, owi_io_result_t *r)
{
int i;
for (retry = 0; retry <= OWI_MAX_RETRY; retry++) {
delay_us(OWI_RECOVERY_MIN_US);
owi_result_init(r);
OWI_SecureStop();
OWI_WriteByte(read_address);
for (i = 0; i < RAM_BYTES; i++) rx[i] = OWI_ReadByte();
OWI_Stop();
//delay_us(200);
OWI_Init(OWI_BIT_PERIOD_US);
OWI_ClearTimeout();
all_ff = 1;
for (i = 0; i < RAM_BYTES; i++) {
if (rx[i] != 0xFF) { all_ff = 0; break; }
}
R_WDT_Restart();
OWI_SecureStop();
R_WDT_Restart();
OWI_WriteByte((uint8_t)(id << 1));
R_WDT_Restart();
if (!all_ff) break;
for (i = 0; i < (int)tx_len; i++) {
R_WDT_Restart();
OWI_WriteByte(tx_data[i]);
R_WDT_Restart();
}
if (retry == OWI_MAX_RETRY) {
return;
}
}
OWI_Stop();
R_WDT_Restart();
owi_result_latch_timeout(r);
}
void OWI_CommandModeRaw(const uint8_t *tx_data, uint8_t tx_len, uint8_t id, owi_io_result_t *r)
{
int i;
owi_result_init(r);
OWI_Init(OWI_BIT_PERIOD_US);
OWI_ClearTimeout();
R_WDT_Restart();
OWI_SecureStop();
R_WDT_Restart();
OWI_WriteByte((uint8_t)(id << 1));
R_WDT_Restart();
n += sprintf(&line[n], "%02X%02X", rx[1], rx[2]);
line[n++] = ',';
for (i = 0; i < (int)tx_len; i++) {
R_WDT_Restart();
OWI_WriteByte(tx_data[i]);
R_WDT_Restart();
}
if (tx_data != NULL && tx_len == 3) {
for (retry = 0; retry <= OWI_MAX_RETRY; retry++) {
OWI_Stop();
R_WDT_Restart();
owi_result_latch_timeout(r);
}
OWI_SecureStop();
OWI_WriteByte((uint8_t)(id << 1));
for (i = 0; i < 3; i++) {
OWI_WriteByte(tx_data[i]);
}
OWI_Stop();
void OWI_ReadBytesRaw(int length, uint8_t id, owi_io_result_t *r)
{
int i;
int max_len;
uint8_t is_long_read;
delay_us(OWI_RECOVERY_MIN_US);
if (!r) return;
for (i = 0; i < RAM_BYTES; i++) rx[i] = 0xFF;
owi_result_init(r);
OWI_Init(OWI_BIT_PERIOD_US);
OWI_SecureStop();
OWI_WriteByte((uint8_t)((id << 1) | 1u));
for (i = 0; i < RAM_BYTES; i++) {
rx[i] = OWI_ReadByte();
}
OWI_Stop();
if (length <= 0) {
r->ok = 0;
return;
}
all_ff = 1;
for (i = 0; i < RAM_BYTES; i++) {
if (rx[i] != 0xFF) { all_ff = 0; break; }
}
max_len = (int)OWI_IO_MAX_BYTES;
if (length > max_len) {
length = max_len;
}
if (!all_ff) break;
r->read_len = (uint16_t)length;
OWI_ClearTimeout();
if (retry == OWI_MAX_RETRY) {
return;
}
}
/* Only 119 keeps the established mid-stream sync. */
is_long_read = (length == 119) ? 1u : 0u;
R_WDT_Restart();
OWI_SecureStop();
OWI_WriteByte((uint8_t)((id << 1) | 1u));
/*
* For 129 bytes, wait for the first edge immediately after the read ID.
* The old 100us delay could enter an already-started first pulse.
* Preserve the established delay for every other read length.
*/
if (length != 129) {
delay_us(100u);
}
n += sprintf(&line[n], "%02X%02X", rx[1], rx[2]);
} else {
n += sprintf(&line[n], "0000");
R_WDT_Restart();
if (!OWI_WaitForFallingEdge(0u, 0u)) {
owi_result_latch_timeout(r);
OWI_StopRead();
return;
}
line[n++] = '\r';
line[n++] = '\n';
line[n] = '\0';
for (i = 0; i < length; i++) {
R_WDT_Restart();
/* Preserve the existing mid-stream sync for the 119-byte path only. */
if (is_long_read && i == (length - 50)) {
R_WDT_Restart();
if (!OWI_WaitForFallingEdge((uint16_t)i, 0u)) {
owi_result_latch_timeout(r);
break;
}
}
r->data[i] = OWI_ReadByte_StreamSynced((uint16_t)i);
HOST_PRINT(line);
if (OWI_HasTimeout()) {
owi_result_latch_timeout(r);
break;
}
}
delay(10000);
OWI_StopRead();
}
void OWI_disable(void)
@ -295,42 +533,26 @@ void OWI_disable(void)
void OWI_T_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id)
{
int i;
delay_us(7000);
OWI_Init(OWI_BIT_PERIOD_US);
owi_io_result_t r;
(void)r;
OWI_SecureStop();
OWI_WriteByte((uint8_t)(id << 1));
for (i = 0; i < (int)tx_len; i++) {
OWI_WriteByte(tx_data[i]);
}
OWI_Stop();
OWI_T_CommandModeRaw(tx_data, tx_len, id, &r);
HOST_PRINT("51\r\n");
}
void OWI_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id)
{
int i;
OWI_SecureStop();
OWI_WriteByte((uint8_t)(id << 1));
owi_io_result_t r;
(void)r;
for (i = 0; i < (int)tx_len; i++) {
OWI_WriteByte(tx_data[i]);
}
OWI_Stop();
OWI_CommandModeRaw(tx_data, tx_len, id, &r);
HOST_PRINT("51\r\n");
}
void OWI_ReadBytesAndPrint(int length, uint8_t id)
{
static uint8_t buf[600];
static char out[2*600 + 3];
owi_io_result_t r;
char out[(2 * OWI_IO_MAX_BYTES) + 40];
int i;
uint16_t p = 0;
@ -338,26 +560,29 @@ void OWI_ReadBytesAndPrint(int length, uint8_t id)
HOST_PRINT("Err:read_len_nonzero\r\n");
return;
}
if (length > 600) length = 600;
OWI_SecureStop();
OWI_WriteByte((uint8_t)((id << 1) | 1u));
OWI_ReadBytesRaw(length, id, &r);
for (i = 0; i < length; i++) {
buf[i] = OWI_ReadByte();
if (r.read_len == 0) {
HOST_PRINT("Err:read_len_nonzero\r\n");
return;
}
/* ✅ 공백 없이 전부 붙이기 */
for (i = 0; i < length; i++) {
uint8_t b = buf[i];
for (i = 0; i < (int)r.read_len; i++) {
uint8_t b = r.data[i];
out[p++] = "0123456789ABCDEF"[b >> 4];
out[p++] = "0123456789ABCDEF"[b & 0x0F];
}
if (r.timeout) {
p += (uint16_t)sprintf(&out[p], " !TO(B%u b%u)",
(unsigned)r.timeout_byte_index,
(unsigned)r.timeout_bit_index);
}
out[p++] = '\r';
out[p++] = '\n';
out[p] = '\0';
HOST_PRINT(out); /* ✅ 딱 1번만 출력 */
HOST_PRINT(out);
}

62
owi.h

@ -6,42 +6,39 @@
#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 */
#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)
/* P70 = bit0 */
#define OWI_PIN_MASK (1u << 0)
/* =========================================================
* Timing ( )
* ========================================================= */
#define OWI_BIT_PERIOD_US 100u
/* 먼저 1200us로 고정해서 테스트 */
#define OWI_BIT_PERIOD_US 1200u
#define TBIT OWI_BIT_PERIOD_US
#define TLOW_0 (TBIT * 0.75) /* 75us (double calc) */
#define TLOW_1 (TBIT * 0.25) /* 25us */
#define TSTOP_LOW (TBIT * 2) /* 200us */
#define TIDLE (TBIT * 3) /* 300us */
#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)
/* =========================================================
* External dependencies
* ========================================================= */
#ifndef RAM_BYTES
#define RAM_BYTES 3
#endif
/* =========================================================
* API
* ========================================================= */
#define OWI_IO_MAX_BYTES 320u
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;
} owi_io_result_t;
void GPIO_Clear(void);
void GPIO_Input(void);
@ -64,7 +61,16 @@ void OWI_T_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id);
void OWI_CommandMode (const uint8_t *tx_data, uint8_t tx_len, uint8_t id);
void OWI_A_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id);
void OWI_T_CommandModeRaw(const uint8_t *tx_data, uint8_t tx_len, uint8_t id, owi_io_result_t *r);
void OWI_CommandModeRaw (const uint8_t *tx_data, uint8_t tx_len, uint8_t id, owi_io_result_t *r);
void OWI_ReadBytesRaw (int length, uint8_t id, owi_io_result_t *r);
void OWI_disable(void);
void GPIO_ForceHighKick(void);
uint8_t OWI_HasTimeout(void);
void OWI_ClearTimeout(void);
uint16_t OWI_GetLastTimeoutByteIndex(void);
uint8_t OWI_GetLastTimeoutBitIndex(void);
#endif /* OWI_H */
#endif

2
r_cg_cgc.c

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements device driver for CGC module.
* Creation Date: 2026-02-04
* Creation Date: 2026-04-08
***********************************************************************************************************************/
/***********************************************************************************************************************

2
r_cg_cgc.h

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements device driver for CGC module.
* Creation Date: 2026-02-04
* Creation Date: 2026-04-08
***********************************************************************************************************************/
#ifndef CGC_H

2
r_cg_cgc_user.c

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements device driver for CGC module.
* Creation Date: 2026-02-04
* Creation Date: 2026-04-08
***********************************************************************************************************************/
/***********************************************************************************************************************

2
r_cg_macrodriver.h

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements general head file.
* Creation Date: 2026-02-04
* Creation Date: 2026-04-08
***********************************************************************************************************************/
#ifndef STATUS_H

2
r_cg_port.c

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements device driver for PORT module.
* Creation Date: 2026-02-04
* Creation Date: 2026-04-08
***********************************************************************************************************************/
/***********************************************************************************************************************

2
r_cg_port.h

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements device driver for PORT module.
* Creation Date: 2026-02-04
* Creation Date: 2026-04-08
***********************************************************************************************************************/
#ifndef PORT_H

2
r_cg_port_user.c

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements device driver for PORT module.
* Creation Date: 2026-02-04
* Creation Date: 2026-04-08
***********************************************************************************************************************/
/***********************************************************************************************************************

2
r_cg_serial.c

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements device driver for Serial module.
* Creation Date: 2026-02-04
* Creation Date: 2026-04-08
***********************************************************************************************************************/
/***********************************************************************************************************************

2
r_cg_serial.h

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements device driver for Serial module.
* Creation Date: 2026-02-04
* Creation Date: 2026-04-08
***********************************************************************************************************************/
#ifndef SERIAL_H

107
r_cg_serial_user.c

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements device driver for Serial module.
* Creation Date: 2026-02-04
* Creation Date: 2026-04-08
***********************************************************************************************************************/
/***********************************************************************************************************************
@ -99,27 +99,30 @@ static void __near r_uart0_interrupt_receive(void)
{
volatile uint8_t rx_data;
volatile uint8_t err_type;
err_type = (uint8_t)(SSR01 & 0x0007U);
SIR01 = (uint16_t)err_type;
rx_data = SDR01L;
if (err_type != 0U) {
if (err_type != 0U)
{
r_uart0_callback_error(err_type);
return;
}
rx_data = SDR01L;
/* ---- CodeGenerator ?? ?? ?? ---- */
if (g_uart0_rx_length > g_uart0_rx_count) {
*gp_uart0_rx_address = (uint8_t)rx_data;
if (g_uart0_rx_length > g_uart0_rx_count)
{
*gp_uart0_rx_address = rx_data;
gp_uart0_rx_address++;
g_uart0_rx_count++;
g_uart0_rx_count++;
if (g_uart0_rx_length == g_uart0_rx_count) {
if (g_uart0_rx_length == g_uart0_rx_count)
{
r_uart0_callback_receiveend();
}
} else {
}
else
{
r_uart0_callback_softwareoverrun(rx_data);
}
}
@ -152,63 +155,45 @@ static void __near r_uart0_interrupt_send(void)
***********************************************************************************************************************/
static void r_uart0_callback_receiveend(void)
{
/* =========================
* (A) BRIDGE MODE: always 1 byte at buffer[0]
* ========================= */
if (g_rs485_bridge_active) {
uint8_t c = rs485_rx_buffer[0];
/* Start user code. Do not edit comment generated here */
uint8_t c = rs485_rx_buffer[rs485_rx_index];
if (g_rs485_bridge_active)
{
RS485_Bridge_Push(c);
g_rs485_bridge_seq++;
/* keep index/length reset in bridge */
rs485_rx_index = 0;
rs485_rx_length = 0;
R_UART0_Receive((uint8_t*)&rs485_rx_buffer[0], 1);
R_UART0_Receive((uint8_t *)&rs485_rx_buffer[0], 1);
return;
}
/* =========================
* (B) NORMAL MODE: accumulate line
* - IMPORTANT: current byte is already stored at rs485_rx_buffer[rs485_rx_index]
* - so update index/length AFTER using c
* ========================= */
if (rs485_rx_index < (UART_RX_BUF_SIZE - 1))
{
uint8_t c = rs485_rx_buffer[rs485_rx_index];
/* ?? ????? ?? */
rs485_rx_index++;
rs485_rx_length = rs485_rx_index;
}
else
{
rs485_rx_done = 1;
return;
}
/* ? ?? or ?? ?? */
if (c == '\r' || c == '\n' || rs485_rx_index >= (UART_RX_BUF_SIZE - 1))
{
/* length? CR/LF ?? ????, main? build_line_from_rx? CR/LF ???? OK */
/* x? ???? ??? main loop? ?? */
if (rs485_rx_length > 0) {
uint8_t first = rs485_rx_buffer[0];
if (first == 'x' || first == 'X') {
rs485_rx_done = 1;
return; /* main loop? ?? ? re-arm */
}
}
/* x? ??? ??? ?? ?? */
rs485_rx_index = 0;
rs485_rx_length = 0;
R_UART0_Receive((uint8_t*)&rs485_rx_buffer[0], 1);
return;
}
if (c == '\r')
{
R_UART0_Receive((uint8_t *)&rs485_rx_buffer[rs485_rx_index], 1);
return;
}
/* ?? 1??? ?? ?? */
R_UART0_Receive((uint8_t*)&rs485_rx_buffer[rs485_rx_index], 1);
if (c == '\n')
{
rs485_rx_done = 1;
return;
}
}
R_UART0_Receive((uint8_t *)&rs485_rx_buffer[rs485_rx_index], 1);
/* End user code. Do not edit comment generated here */
}
/***********************************************************************************************************************
* Function Name: r_uart0_callback_softwareoverrun
@ -272,23 +257,22 @@ static void __near r_uart1_interrupt_receive(void)
{
volatile uint8_t rx_data;
volatile uint8_t err_type;
err_type = (uint8_t)(SSR11 & 0x0007U);
SIR11 = (uint16_t)err_type;
if (err_type != 0U) {
(void)SDR11L; /* dummy read to clear */
if (err_type != 0U)
{
r_uart1_callback_error(err_type);
return;
}
rx_data = SDR11L;
if (g_uart1_rx_length > g_uart1_rx_count)
{
*gp_uart1_rx_address = rx_data;
gp_uart1_rx_address++;
g_uart1_rx_count++;
g_uart1_rx_count++;
if (g_uart1_rx_length == g_uart1_rx_count)
{
@ -301,7 +285,6 @@ static void __near r_uart1_interrupt_receive(void)
}
}
/***********************************************************************************************************************
* Function Name: r_uart1_interrupt_send
* Description : This function is INTST1 interrupt service routine.

2
r_cg_userdefine.h

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file includes user definition.
* Creation Date: 2026-02-04
* Creation Date: 2026-04-08
***********************************************************************************************************************/
#ifndef _USER_DEF_H

6
r_cg_wdt.c

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements device driver for WDT module.
* Creation Date: 2026-01-29
* Creation Date: 2026-04-08
***********************************************************************************************************************/
/***********************************************************************************************************************
@ -57,10 +57,6 @@ void R_WDT_Create(void)
{
WDTIMK = 1U; /* disable INTWDTI interrupt */
WDTIIF = 0U; /* clear INTWDTI interrupt flag */
/* Set INTWDTI low priority */
WDTIPR1 = 1U;
WDTIPR0 = 1U;
WDTIMK = 0U; /* enable INTWDTI interrupt */
}
/***********************************************************************************************************************

2
r_cg_wdt.h

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements device driver for WDT module.
* Creation Date: 2026-01-29
* Creation Date: 2026-04-08
***********************************************************************************************************************/
#ifndef WDT_H

15
r_cg_wdt_user.c

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements device driver for WDT module.
* Creation Date: 2026-01-29
* Creation Date: 2026-04-08
***********************************************************************************************************************/
/***********************************************************************************************************************
@ -38,7 +38,6 @@ Includes
/***********************************************************************************************************************
Pragma directive
***********************************************************************************************************************/
#pragma interrupt r_wdt_interrupt(vect=INTWDTI)
/* Start user code for pragma. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */
@ -48,17 +47,5 @@ Global variables and functions
/* Start user code for global. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */
/***********************************************************************************************************************
* Function Name: r_wdt_interrupt
* Description : This function is INTWDTI interrupt service routine.
* Arguments : None
* Return Value : None
***********************************************************************************************************************/
static void __near r_wdt_interrupt(void)
{
/* Start user code. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */
}
/* Start user code for adding. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */

1894
r_main.c

File diff suppressed because it is too large

4
r_systeminit.c

@ -23,7 +23,7 @@
* Device(s) : R5F10PPJ
* Tool-Chain : CCRL
* Description : This file implements system initializing function.
* Creation Date: 2026-02-04
* Creation Date: 2026-04-08
***********************************************************************************************************************/
/***********************************************************************************************************************
@ -33,6 +33,7 @@ Includes
#include "r_cg_cgc.h"
#include "r_cg_port.h"
#include "r_cg_serial.h"
#include "r_cg_wdt.h"
/* Start user code for include. Do not edit comment generated here */
/* End user code. Do not edit comment generated here */
#include "r_cg_userdefine.h"
@ -73,6 +74,7 @@ void R_Systeminit(void)
R_SAU0_Create();
R_SAU1_Create();
R_IICA0_Create();
R_WDT_Create();
/* Set invalid memory access detection control */
IAWCTL = 0x00U;

38
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[];
@ -25,7 +25,7 @@ volatile uint8_t g_rs485_need_recover = 0;
void rs485_recover(void)
{
DI(); // ISR 경쟁 줄이기 (권장)
DI(); // ISR 경쟁 줄이기
rs485_set_tx(0); // RX 모드 고정
// UART0 재시작
@ -49,14 +49,17 @@ void rs485_recover(void)
rs485_rx_length = 0;
R_UART0_Receive((uint8_t*)&rs485_rx_buffer[0], 1);
g_rs485_need_recover = 0; // recover 완료 처리 (여기서 내려도 OK)
g_rs485_need_recover = 0;
EI();
}
/* UART1 송신용 내부 버퍼(스택 포인터 안전) */
static uint16_t s_uart1_txbuf[1024]; // 너 출력 단위가 "72 " / "7272 " 정도라 64면 충분
// (더 길게 보내면 키워도 됨)
static uint8_t s_uart1_txbuf[1024];
/* 129 data bytes as HEX plus diagnostics/CRLF. */
static uint8_t s_uart0_txbuf[320];
static volatile uint16_t s_uart0_tx_len = 0;
static void UART1_WaitTxIdle(void)
{
@ -91,11 +94,24 @@ void RS485_Send(const uint8_t* data, uint16_t len)
{
if (!data || len == 0) return;
/* 송신 시작을 명확히 */
/* 이전 전송 완료 대기 */
UART0_WaitTxDone_Us(20000U);
/* 내부 버퍼 크기 제한 */
if (len >= (uint16_t)sizeof(s_uart0_txbuf)) {
len = (uint16_t)(sizeof(s_uart0_txbuf) - 1);
}
/* 호출자 버퍼 -> 내부 안전 버퍼 복사 */
memcpy(s_uart0_txbuf, data, len);
s_uart0_tx_len = len;
g_uart0_tx_done = 0;
rs485_set_tx(1);
delay_us(30U);
R_UART0_Send((uint8_t*)data, len);
/* 내부 버퍼 기준 비동기 송신 */
R_UART0_Send((uint8_t*)s_uart0_txbuf, len);
}
void RS485_SendString(const char* s)
@ -152,21 +168,21 @@ void uart1_send_string(const char *str)
if (str == 0) return;
while (str[len] != '\0') len++;
/* 이전 전송 끝날 때까지 대기 */
/* 이전 전송 끝날 때까지 대기 */
UART1_WaitTxIdle();
g_uart1_tx_done = 0;
/* 스택 포인터/버퍼 수명 문제 방지: 내부 버퍼로 복사 */
/* 스택 포인터/버퍼 수명 문제 방지: 내부 버퍼로 복사 */
if (len >= (uint16_t)sizeof(s_uart1_txbuf))
len = (uint16_t)(sizeof(s_uart1_txbuf) - 1);
memcpy(s_uart1_txbuf, str, len);
/* 비동기 송신 시작 */
/* 비동기 송신 시작 */
R_UART1_Send(s_uart1_txbuf, len);
/* ❌ 여기서 또 기다리지 마(속도 저하). 다음 호출이 알아서 대기함 */
/* 여기서 또 기다리지 말고(속도 저하). 다음 호출이 알아서 대기함 */
}
/**
* : uart_send_hex

Loading…
Cancel
Save