#include "app_owi_service.h" #include "owi.h" #include "delay.h" #include "r_cg_wdt.h" #include static app_owi_result_t app_owi_from_raw(const owi_io_result_t *io) { app_owi_result_t r; uint16_t i; memset(&r, 0, sizeof(r)); if (!io) { r.ok = 0; return r; } r.ok = io->ok; r.timeout = io->timeout; r.read_len = io->read_len; r.timeout_byte_index = io->timeout_byte_index; r.timeout_bit_index = io->timeout_bit_index; for (i = 0; i < io->read_len && i < OWI_IO_MAX_BYTES; i++) { r.data[i] = io->data[i]; } return r; } static uint8_t is_long_owi_read(int length) { return (length == 119 || length == 127) ? 1u : 0u; } static uint8_t looks_bad_tail(const owi_io_result_t *io) { uint16_t i; uint8_t zero_run = 0; uint8_t ff_run = 0; if (!io) return 1u; if (io->read_len < 24u) return 1u; for (i = (uint16_t)(io->read_len - 24u); i < io->read_len; i++) { uint8_t b = io->data[i]; if (b == 0x00u) zero_run++; else zero_run = 0; if (b == 0xFFu) ff_run++; else ff_run = 0; /* tail ?? 8??? ?? ?? 00/FF? ??? */ if (zero_run >= 8u || ff_run >= 8u) { return 1u; } } return 0u; } /* ? ? ?? 4???? ?? 00 ?? ?? FF? ????? ?? */ static uint8_t looks_bad_last_bytes(const owi_io_result_t *io) { uint16_t start; uint8_t i; uint8_t all_zero = 1u; uint8_t all_ff = 1u; if (!io) return 1u; if (io->read_len < 3u) return 1u; start = (uint16_t)(io->read_len - 3u); for (i = 0; i < 3u; i++) { uint8_t b = io->data[start + i]; if (b != 0x00u) all_zero = 0u; if (b != 0xFFu) all_ff = 0u; } return (uint8_t)(all_zero || all_ff); } static uint8_t needs_retry_for_long_read(const owi_io_result_t *io, int length) { if (!is_long_owi_read(length)) return 0u; if (!io) return 1u; if (!io->ok) return 1u; if (io->timeout) return 1u; if (io->read_len < (uint16_t)length) return 1u; if (looks_bad_tail(io)) return 1u; if (looks_bad_last_bytes(io)) return 1u; return 0u; } app_owi_result_t app_owi_read_basic(uint8_t id, int length) { owi_io_result_t io; R_WDT_Restart(); OWI_ReadBytesRaw(length, id, &io); R_WDT_Restart(); if (needs_retry_for_long_read(&io, length)) { R_WDT_Restart(); delay_us(3000u); R_WDT_Restart(); OWI_ReadBytesRaw(length, id, &io); R_WDT_Restart(); /* ??? ??? ???? ?? ?? */ if (needs_retry_for_long_read(&io, length)) { io.ok = 0u; io.timeout = 1u; io.timeout_byte_index = 0xFFFEu; io.timeout_bit_index = 0xFEu; } } return app_owi_from_raw(&io); } app_owi_result_t app_owi_write_basic(uint8_t id, const uint8_t *tx_data, uint8_t tx_len) { owi_io_result_t io; OWI_CommandModeRaw(tx_data, tx_len, id, &io); return app_owi_from_raw(&io); } app_owi_result_t app_owi_write_t_basic(uint8_t id, const uint8_t *tx_data, uint8_t tx_len) { owi_io_result_t io; OWI_T_CommandModeRaw(tx_data, tx_len, id, &io); return app_owi_from_raw(&io); }