You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

445 lines
9.3 KiB

3 months ago
#include "owi.h"
#include "delay.h"
#include <string.h>
#include <stdio.h>
#include "uart.h"
1 month ago
#ifndef OWI_STRONG_DRIVE_HIGH_US
#define OWI_STRONG_DRIVE_HIGH_US 5u
#endif
3 months ago
/* 내부 상태 */
static uint32_t bit_period_us = OWI_BIT_PERIOD_US;
1 month ago
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;
3 months ago
/* =========================================================
* GPIO helpers (P70 / HW Open-Drain)
* - LOW : + 0
1 month ago
* - HIGH : (Hi-Z) release
3 months ago
* ========================================================= */
void GPIO_Clear(void)
{
1 month ago
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P &= (uint8_t)~OWI_PIN_MASK;
OWI_PORT_PM &= (uint8_t)~OWI_PIN_MASK;
3 months ago
}
void GPIO_Input(void)
{
1 month ago
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_P |= (uint8_t)OWI_PIN_MASK;
OWI_PORT_PM |= (uint8_t)OWI_PIN_MASK;
3 months ago
}
int GPIO_Read(void)
{
return (OWI_PORT_P & (uint8_t)OWI_PIN_MASK) ? 1 : 0;
}
1 month ago
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;
}
3 months ago
/* =========================================================
* OWI Init
* ========================================================= */
void OWI_Init(uint32_t bit_time_us)
{
bit_period_us = bit_time_us;
1 month ago
(void)bit_period_us;
3 months ago
OWI_PORT_POM |= (uint8_t)OWI_PIN_MASK;
1 month ago
OWI_PORT_PU &= (uint8_t)~OWI_PIN_MASK;
3 months ago
1 month ago
OWI_ClearTimeout();
3 months ago
GPIO_Input();
}
/* =========================================================
* Start/Stop/Secure
* ========================================================= */
void OWI_Start(void)
{
GPIO_Clear();
delay_us(TSTART_HOLD);
1 month ago
3 months ago
GPIO_Input();
1 month ago
delay_us(TBIT);
3 months ago
}
void OWI_Stop(void)
{
GPIO_Input();
delay_us(TSTOP_LOW);
delay_us(TIDLE);
1 month ago
}
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);
3 months ago
}
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);
1 month ago
3 months ago
GPIO_Clear();
delay_us(SECURE_TOGGLE_LOW);
}
GPIO_Input();
delay_us(SECURE_HIGH);
1 month ago
3 months ago
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;
1 month ago
OWI_Release();
3 months ago
delay_us(t_high);
1 month ago
OWI_DriveLow();
3 months ago
delay_us(t_low);
}
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)
{
uint8_t bit;
1 month ago
int timeout = (int)(bit_period_us * 2u);
3 months ago
while (!(GPIO_Read()) && timeout-- > 0) {
1 month ago
delay_us(1u);
3 months ago
}
if (timeout <= 0) {
1 month ago
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 months ago
}
1 month ago
delay_us((bit_period_us * 1u) / 2u);
3 months ago
bit = (uint8_t)GPIO_Read();
1 month ago
delay_us((bit_period_us * 2u) / 5u);
3 months ago
1 month ago
return (bit ? 1u : 0u);
3 months ago
}
uint8_t OWI_ReadByte(void)
{
uint8_t data = 0;
int i;
for (i = 7; i >= 0; i--) {
1 month ago
g_owi_current_read_bit_index = (uint8_t)(7 - i);
3 months ago
data |= (uint8_t)(OWI_ReadBit() << i);
1 month ago
if (OWI_HasTimeout()) {
break;
}
3 months ago
}
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;
1 month ago
if (length <= 0) return;
OWI_ClearTimeout();
3 months ago
for (i = 0; i < length; i++) {
1 month ago
g_owi_current_read_byte_index = (uint16_t)i;
3 months ago
buf[i] = OWI_ReadByte();
1 month ago
if (OWI_HasTimeout()) {
i++;
break;
}
3 months ago
}
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];
1 month ago
va1 = (uint8_t)((i + 1 < length) ? buf[i + 1] : 0u);
3 months ago
1 month ago
delay_us(200);
3 months ago
sprintf(uart_buf, "%02X%02X ", va0, va1);
strcpy(tmp_buf, uart_buf);
HOST_PRINT(tmp_buf);
1 month ago
delay_us(200);
3 months ago
}
}
/* =========================================================
1 month ago
* Raw helpers
3 months ago
* ========================================================= */
1 month ago
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;
}
3 months ago
1 month ago
static void owi_result_latch_timeout(owi_io_result_t *r)
3 months ago
{
1 month ago
if (!r) return;
3 months ago
1 month ago
if (OWI_HasTimeout()) {
r->ok = 0;
r->timeout = 1;
r->timeout_byte_index = OWI_GetLastTimeoutByteIndex();
r->timeout_bit_index = OWI_GetLastTimeoutBitIndex();
}
}
3 months ago
1 month ago
void OWI_T_CommandModeRaw(const uint8_t *tx_data, uint8_t tx_len, uint8_t id, owi_io_result_t *r)
{
int i;
3 months ago
1 month ago
owi_result_init(r);
3 months ago
1 month ago
delay_us(10000);
OWI_Init(OWI_BIT_PERIOD_US);
OWI_ClearTimeout();
3 months ago
1 month ago
OWI_SecureStop();
OWI_WriteByte((uint8_t)(id << 1));
3 months ago
1 month ago
for (i = 0; i < (int)tx_len; i++) {
OWI_WriteByte(tx_data[i]);
}
3 months ago
1 month ago
OWI_Stop();
owi_result_latch_timeout(r);
}
3 months ago
1 month ago
void OWI_CommandModeRaw(const uint8_t *tx_data, uint8_t tx_len, uint8_t id, owi_io_result_t *r)
{
int i;
3 months ago
1 month ago
owi_result_init(r);
OWI_ClearTimeout();
3 months ago
1 month ago
OWI_SecureStop();
OWI_WriteByte((uint8_t)(id << 1));
3 months ago
1 month ago
for (i = 0; i < (int)tx_len; i++) {
OWI_WriteByte(tx_data[i]);
}
3 months ago
1 month ago
OWI_Stop();
owi_result_latch_timeout(r);
}
3 months ago
1 month ago
void OWI_ReadBytesRaw(int length, uint8_t id, owi_io_result_t *r)
{
int i;
int max_len;
3 months ago
1 month ago
if (!r) return;
3 months ago
1 month ago
owi_result_init(r);
3 months ago
1 month ago
if (length <= 0) {
r->ok = 0;
return;
}
3 months ago
1 month ago
max_len = (int)OWI_IO_MAX_BYTES;
if (length > max_len) {
length = max_len;
3 months ago
}
1 month ago
r->read_len = (uint16_t)length;
3 months ago
1 month ago
OWI_ClearTimeout();
3 months ago
1 month ago
OWI_SecureStop();
OWI_WriteByte((uint8_t)((id << 1) | 1u));
for (i = 0; i < length; i++) {
g_owi_current_read_byte_index = (uint16_t)i;
r->data[i] = OWI_ReadByte();
if (OWI_HasTimeout()) {
owi_result_latch_timeout(r);
break;
}
}
OWI_StopRead();
3 months ago
}
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)
{
1 month ago
owi_io_result_t r;
(void)r;
3 months ago
1 month ago
OWI_T_CommandModeRaw(tx_data, tx_len, id, &r);
3 months ago
HOST_PRINT("51\r\n");
}
void OWI_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id)
{
1 month ago
owi_io_result_t r;
(void)r;
3 months ago
1 month ago
OWI_CommandModeRaw(tx_data, tx_len, id, &r);
3 months ago
HOST_PRINT("51\r\n");
}
void OWI_ReadBytesAndPrint(int length, uint8_t id)
{
1 month ago
owi_io_result_t r;
char out[(2 * OWI_IO_MAX_BYTES) + 40];
3 months ago
int i;
2 months ago
uint16_t p = 0;
3 months ago
2 months ago
if (length <= 0) {
HOST_PRINT("Err:read_len_nonzero\r\n");
return;
}
3 months ago
1 month ago
OWI_ReadBytesRaw(length, id, &r);
3 months ago
1 month ago
if (r.read_len == 0) {
HOST_PRINT("Err:read_len_nonzero\r\n");
return;
3 months ago
}
1 month ago
for (i = 0; i < (int)r.read_len; i++) {
uint8_t b = r.data[i];
2 months ago
out[p++] = "0123456789ABCDEF"[b >> 4];
out[p++] = "0123456789ABCDEF"[b & 0x0F];
3 months ago
}
1 month ago
if (r.timeout) {
p += (uint16_t)sprintf(&out[p], " !TO(B%u b%u)",
(unsigned)r.timeout_byte_index,
(unsigned)r.timeout_bit_index);
}
2 months ago
out[p++] = '\r';
out[p++] = '\n';
out[p] = '\0';
3 months ago
1 month ago
HOST_PRINT(out);
}