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.

874 lines
25 KiB

2 weeks ago
#include "owi.h"
#include "delay.h"
#include <string.h>
#include "uart.h"
/**
* : OWI_EnablePower
* : 1-Wire .
*
* :
*
* : (void)
*
* :
* - MCU P7의 1 (P7.1) HIGH(_02_Pn1_OUTPUT_1)
* 1-Wire .
*/
void OWI_EnablePower(void) {
P7 = _02_Pn1_OUTPUT_1;
}
/**
* : OWI_DisablePower
* : 1-Wire .
*
* :
*
* : (void)
*
* :
* - MCU P7의 1 (P7.1) LOW(_00_Pn1_OUTPUT_0)
* 1-Wire .
*/
void OWI_DisablePower(void) {
P7 = _00_Pn1_OUTPUT_0;
}
/**
* : GPIO_Clear
* : 1-Wire GPIO(P70) Low .
*
* :
*
* : (void)
*
* :
* - OWI_PORT_P (OWI_PIN_MASK) 0 P70을 Low로 .
* - OWI_PORT_PM 0 P70을 .
* - P70 Low .
*/
void GPIO_Clear(void) {
OWI_PORT_P &= ~OWI_PIN_MASK; // P70 = 0 (Low)
OWI_PORT_PM &= ~OWI_PIN_MASK; // P70 출력 모드
}
/**
* : GPIO_Input
* : 1-Wire GPIO(P70) .
*
* :
*
* : (void)
*
* :
* - OWI_PORT_PM (OWI_PIN_MASK) 1 P70을 (High-Z) .
* - .
*/
void GPIO_Input(void) {
OWI_PORT_PM |= OWI_PIN_MASK; // P70 입력 모드 (High-Z)
}
/**
* : GPIO_Read
* : 1-Wire GPIO(P70) .
*
* :
*
* :
* - 1 : P70 High
* - 0 : P70 Low
*
* :
* - OWI_PORT_P (OWI_PIN_MASK) .
* - 1 High, 0 Low로 .
* - , GPIO .
*/
int GPIO_Read(void) {
return (OWI_PORT_P & OWI_PIN_MASK) ? 1 : 0;
}
/**
* : OWI_Init
* : 1-Wire GPIO .
*
* :
* - bit_time_us : 1 ( )
*
* : (void)
*
* :
* 1. bit_period_us .
* 2. OWI_PORT_POM (OWI_PIN_MASK) Open-drain(n-channel) .
* 3. OWI_PORT_PU .
* 4. GPIO를 .
*
*/
void OWI_Init(uint32_t bit_time_us) {
bit_period_us = bit_time_us;
OWI_PORT_POM |= OWI_PIN_MASK; // Open-drain (n-channel)
OWI_PORT_PU |= OWI_PIN_MASK; // 내부 풀업 활성화
GPIO_Input(); // 초기엔 입력으로 대기
}
// ----------------------------------------
// OWI Start/Stop/Secure
// ----------------------------------------
/**
* : OWI_Start
* : 1-Wire Start .
*
* :
*
* : (void)
*
* :
* 1. GPIO_Clear() : P70 Low Start .
* 2. delay_us(TSTART_HOLD): Start .
* 3. GPIO_Input() : (High-Z) .
* 4. delay_us(TBIT / 2): 1-Wire .
*
*/
void OWI_Start(void)
{
GPIO_Clear();
delay_us(TSTART_HOLD);
GPIO_Input();
delay_us(TBIT / 2);
}
/**
* : OWI_Stop
* : 1-Wire .
*
* :
*
* : (void)
*
* :
* 1. GPIO_Input() : (High-Z) .
* 2. delay_us(TSTOP_LOW): Stop .
* 3. delay_us(TIDLE): .
* 4. GPIO_Clear() : Low로 .
*
*/
void OWI_Stop(void)
{
GPIO_Input();
delay_us(TSTOP_LOW);
delay_us(TIDLE);
GPIO_Clear();
}
/**
* : OWI_SecureStop
* : 1-Wire .
*
* :
*
* : (void)
*
* :
* 1. GPIO_Clear() SECURE_HIGH : Low .
* 2. SECURE_TOGGLE_COUNT만큼 :
* - GPIO_Input() High-Z SECURE_TOGGLE_HIGH .
* - GPIO_Clear() Low SECURE_TOGGLE_LOW .
* - .
* 3. GPIO_Input() SECURE_HIGH GPIO_Clear() TSTART_HOLD GPIO_Input() :
* - .
*
*/
void OWI_SecureStop(void)
{
int i;
GPIO_Clear();
delay_us(SECURE_HIGH);
for (i = 0; i < 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();
}
// ----------------------------------------
// OWI Bit/Byte Write & Read
// ----------------------------------------
/**
* : OWI_WriteBit
* : 1-Wire (bit) .
*
* :
* - bit : (0 1)
*
* : (void)
*
* :
* 1. Low (t_low) :
* - bit가 1 TLOW_1, 0 TLOW_0
* 2. t_high = TBIT - t_low : High .
* 3. GPIO_Input() : (High-Z) .
* 4. delay_us(t_high): High .
* 5. GPIO_Clear() : Low .
* 6. delay_us(t_low): Low .
*
*/
void OWI_WriteBit(int bit)
{
uint32_t t_low = bit ? TLOW_1 : TLOW_0;
uint32_t t_high = TBIT - t_low;
GPIO_Input(); // 풀업 상태 유지
delay_us(t_high); // High 유지
GPIO_Clear(); // Low로 드라이브
delay_us(t_low); // Low 시간 유지
}
/**
* : OWI_WriteByte
* : 1-Wire 1 .
*
* :
* - data : 1 (uint8_t)
*
* : (void)
*
* :
* 1. (MSB) (LSB) :
* - OWI_WriteBit() .
* - (data >> i) & 0x01 i번째 .
* 2. 8 GPIO_Input() :
* - High-Z .
*
*/
void OWI_WriteByte(uint8_t data)
{
int i;
for (i = 7; i >= 0; i--) {
OWI_WriteBit((data >> i) & 0x01);
}
GPIO_Input();
}
/**
* : OWI_ReadBit
* : 1-Wire .
*
* :
*
* :
* - 0 1 :
* - 0xFF :
*
* :
* 1. GPIO_Read() High가 :
* - 500us까지 (timeout).
* - UART로 0xFF .
* 2. delay_us(50) .
* 3. GPIO_Read() .
* 4. delay_us(30) .
* 5. .
*
*/
uint8_t OWI_ReadBit(void)
{
uint8_t bit;
int timeout = 500;
while (!(GPIO_Read()) && timeout-- > 0) {
delay_us(1);
}
if (timeout <= 0) {
1 week ago
HOST_PRINT("OWI Timeout\r\n");
2 weeks ago
return 0xFF;
}
delay_us(50);
bit = GPIO_Read();
delay_us(30);
return bit;
}
/**
* : OWI_ReadByte
* : 1-Wire 1 .
*
* :
*
* :
* - 1 (uint8_t)
*
* :
* 1. (MSB) (LSB) :
* - OWI_ReadBit() 1 .
* - data .
* 2. 8 data .
*
*/
uint8_t OWI_ReadByte(void)
{
uint8_t data = 0;
int i;
for (i = 7; i >= 0; i--) {
data |= (OWI_ReadBit() << i);
}
return data;
}
/**
* : OWI_T_ReadBytesAndPrint
* : 1-Wire , UART로 .
*
* :
* - length :
*
* : (void)
*
* :
* 1. buf length만큼 OWI_ReadByte() 1 .
* 2. (buf[0]) 16 2 UART .
* 3. 16 4 UART :
* - delay(10000) .
* 4. UART sprintf strcpy uart_send_string .
*
* :
* - buf[0] , 2 .
* - delay를 UART .
* - 1-Wire .
*/
void OWI_T_ReadBytesAndPrint(int length)
{
uint8_t buf[129];
int i;
char uart_buf[8];
char tmp_buf[8];
uint8_t va0, va1;
for (i = 0; i < length; i++) {
buf[i] = OWI_ReadByte();
}
sprintf(uart_buf, "%02X ", buf[0]);
strcpy(tmp_buf, uart_buf);
1 week ago
HOST_PRINT(tmp_buf);
2 weeks ago
for (i = 1; i < length; i+=2) {
va0 = buf[i];
va1 = buf[i+1];
delay(10000);
sprintf(uart_buf, "%02X%02X ", va0, va1);
strcpy(tmp_buf, uart_buf);
1 week ago
HOST_PRINT(tmp_buf);
2 weeks ago
delay(10000);
}
}
/**
* : OWI_A_CommandMode
* : 1-Wire ADC (CMD) UART로 .
*
* :
* - tx_data : (3)
* - tx_len :
* - id : ID
*
* : (void)
*
* :
* 1) ADC
* - ADC_ReadAndSend_UART() ADC .
* - g_adc_bytes 2 line .
* - ADC "Err:adc_count" .
*
* 2) 1-Wire
* - OWI_EnablePower() .
* - 7ms .
*
* 3) (CMD)
* - CMD_LIST에 6 4 .
* - / OWI_SecureStop() .
* - read_address(0x51) .
* - 0xFF OWI_MAX_RETRY만큼 .
* - Rx 2, 3 line 16 .
*
* 4) CMD (tx_data )
* - tx_len가 3 ID를 write read .
* - Rx 0xFF OWI_MAX_RETRY .
* - line 2, 3 .
* - tx_data가 "0000" line .
*
* 5) UART
* - line CRLF uart_send_string() .
*
* 6)
* - delay(10000) OWI_DisablePower() .
*
* :
* - OWI_SecureStop() delay_us() 1-Wire .
* - g_adc_bytes, RAM_BYTES, OWI_MAX_RETRY .
* - UART로 ADC값, CMD , CMD .
*/
#define OWI_MAX_RETRY 2 // 재시도 2회
#define OWI_RECOVERY_MIN_US 500 // datasheet 기준 최소 recovery 시간
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}, // BR
{0x50,0x2E,0x01,0x00}, // BR_AZ
{0x50,0x2E,0x02,0x00}, // T_RAW
{0x50,0x2E,0x16,0x00}, // Y_data
{0x50,0x2E,0x41,0x00}, // BR_AOUT
{0x50,0x2E,0x00,0x00} // BR_AOUT duplicate
};
char line[128];
size_t n = 0;
uint8_t rx[RAM_BYTES];
int i, j, retry, all_ff;
float v;
uint8_t read_address = 0x51;
// ===== 2) OWI Power On =====
OWI_EnablePower();
delay_us(7000); // Power-on delay
// ===== 3) CMD 전송 및 안전한 읽기 =====
for (j = 0; j < 6; j++) {
OWI_SecureStop();
for (i = 0; i < 4; i++) OWI_WriteByte(CMD_LIST[j][i]);
OWI_Stop();
// CMD → read 회복 시간
delay_us(OWI_RECOVERY_MIN_US);
// Rx 초기화
for (i = 0; i < RAM_BYTES; i++) rx[i] = 0xFF;
for (retry = 0; retry <= OWI_MAX_RETRY; retry++) {
// read 전 충분한 recovery 확보
delay_us(OWI_RECOVERY_MIN_US);
OWI_SecureStop();
OWI_WriteByte(read_address);
for (i = 0; i < RAM_BYTES; i++) rx[i] = OWI_ReadByte();
OWI_Stop();
all_ff = 1;
for (i = 0; i < RAM_BYTES; i++) {
if (rx[i] != 0xFF) { all_ff = 0; break; }
}
if (!all_ff) break; // 정상 데이터 수신
if (retry == OWI_MAX_RETRY) { // 모든 재시도 실패
OWI_DisablePower();
return;
}
}
n += sprintf(&line[n], "%02X%02X", rx[1], rx[2]);
line[n++] = ',';
}
// ===== 4) 사용자 CMD 처리 =====
if (tx_data != NULL && tx_len == 3) {
for (retry = 0; retry <= OWI_MAX_RETRY; retry++) {
// write CMD
OWI_SecureStop();
OWI_WriteByte(id << 1);
for (i = 0; i < 3; i++) OWI_WriteByte(tx_data[i]);
OWI_Stop();
// read 준비
delay_us(OWI_RECOVERY_MIN_US);
// read
for (i = 0; i < RAM_BYTES; i++) rx[i] = 0xFF;
OWI_SecureStop();
OWI_WriteByte((id << 1) | 1);
for (i = 0; i < RAM_BYTES; i++) rx[i] = OWI_ReadByte();
OWI_Stop();
all_ff = 1;
for (i = 0; i < RAM_BYTES; i++) {
if (rx[i] != 0xFF) { all_ff = 0; break; }
}
if (!all_ff) break;
if (retry == OWI_MAX_RETRY) {
OWI_DisablePower();
return;
}
}
n += sprintf(&line[n], "%02X%02X", rx[1], rx[2]);
} else {
n += sprintf(&line[n], "0000");
}
// ===== 5) UART 출력 =====
line[n++] = '\r';
line[n++] = '\n';
line[n] = '\0';
1 week ago
HOST_PRINT(line);
2 weeks ago
delay(10000);
OWI_DisablePower();
}
/**
* : OWI_Diagnostic
* : 1-Wire UART로 .
*
* :
* - id : ID ( )
*
* : (void)
*
* :
* 1) CMD_LIST에 10 4 .
* - OWI_SecureStop() .
* - OWI_Stop() .
* - OWI_RECOVERY_MIN_US .
*
* 2) read_address(0x51) .
* - Rx (0xFF) OWI_ReadByte() .
* - 0xFF OWI_MAX_RETRY만큼 .
*
* 3) rx[1], rx[2] 16 line .
* - (,) .
*
* 4) UART
* - line CRLF uart_send_string() .
*
* :
* - OWI_SecureStop() delay_us() 1-Wire .
* - .
*/
void OWI_Diagnostic(uint8_t id)
{
uint8_t CMD_LIST[10][4] = {
{0x50,0x2E,0x01,0x00}, // BR
{0x50,0x2E,0x00,0x00}, // BR_AZ
{0x50,0x2E,0x02,0x00}, // T_RAW
{0x50,0x2E,0x03,0x00}, // Y_data
{0x50,0x2E,0x21,0x00}, // BR_AOUT
{0x50,0x2E,0x04,0x00},
{0x50,0x2E,0x05,0x00},
{0x50,0x2E,0x07,0x00},
{0x50,0x2E,0x19,0x00},
{0x50,0x2E,0x0B,0x00}
};
char line[128];
size_t n = 0;
uint8_t rx[RAM_BYTES];
int i, j, retry, all_ff;
float v;
uint8_t read_address = 0x51;
// ===== 3) CMD 전송 및 안전한 읽기 =====
for (j = 0; j < 10; j++) {
OWI_SecureStop();
for (i = 0; i < 4; i++) OWI_WriteByte(CMD_LIST[j][i]);
OWI_Stop();
// CMD → read 회복 시간
delay_us(OWI_RECOVERY_MIN_US);
// Rx 초기화
for (i = 0; i < RAM_BYTES; i++) rx[i] = 0xFF;
for (retry = 0; retry <= OWI_MAX_RETRY; retry++) {
// read 전 충분한 recovery 확보
delay_us(OWI_RECOVERY_MIN_US);
OWI_SecureStop();
OWI_WriteByte(read_address);
for (i = 0; i < RAM_BYTES; i++) rx[i] = OWI_ReadByte();
OWI_Stop();
all_ff = 1;
for (i = 0; i < RAM_BYTES; i++) {
if (rx[i] != 0xFF) { all_ff = 0; break; }
}
if (!all_ff) break; // 정상 데이터 수신
if (retry == OWI_MAX_RETRY) { // 모든 재시도 실패
OWI_DisablePower();
return;
}
}
// 데이터 추가
n += sprintf(&line[n], "%02X%02X", rx[1], rx[2]);
// 마지막이 아닐 때만 콤마 추가
if (j < 9) {
line[n++] = ',';
}
}
// ===== 5) UART 출력 =====
line[n++] = '\r';
line[n++] = '\n';
line[n] = '\0';
1 week ago
HOST_PRINT(line);
2 weeks ago
delay(10000);
}
/**
* : OWI_disable
* : 1-Wire , UART로 .
*
* :
*
* : (void)
*
* :
* 1) OWI_DisablePower() 1-Wire .
* 2) UART로 "51" CRLF .
*
* :
* - UART .
*/
void OWI_disable()
{
OWI_DisablePower();
1 week ago
HOST_PRINT("51\r\n");
2 weeks ago
}
/**
* : OWI_T_CommandMode
* : 1-Wire , UART로 .
*
* :
* - tx_data :
* - tx_len :
* - id : 1-Wire ID ( )
*
* : (void)
*
* :
* 1) 1-Wire
* - OWI_EnablePower()
* - 7ms
*
* 2) 1-Wire
* - OWI_Init()
*
* 3) (Write sequence)
* - OWI_SecureStop()
* - (id << 1) ( )
* - tx_data
* - OWI_Stop()
*
* 4) UART
* - "51"
*
* :
* - , .
* - OWI_SecureStop() OWI_Stop() 1-Wire .
*/
void OWI_T_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id)
{
uint8_t rx[3] = {0};
char uart_buf[16];
int i;
OWI_EnablePower();
delay_us(7000); // Power-on delay
OWI_Init(OWI_BIT_PERIOD_US);
// Write sequence (슬레이브 주소와 명령 전송)
OWI_SecureStop(); // 통신 준비
OWI_WriteByte(id << 1); // 슬레이브 write 주소
for (i = 0; i < tx_len; i++) {
OWI_WriteByte(tx_data[i]); // 명령 전송
}
OWI_Stop(); // 쓰기 종료
1 week ago
HOST_PRINT("51\r\n");
2 weeks ago
}
/**
* : OWI_CommandMode
* : 1-Wire , UART로 .
*
* :
* - tx_data :
* - tx_len :
* - id : 1-Wire ID ( )
*
* : (void)
*
* :
* 1) (Write sequence)
* - OWI_SecureStop()
* - (id << 1) ( )
* - tx_data
* - OWI_Stop()
*
* 2) UART
* - "51"
*
* :
* - /
* - ,
* - OWI_SecureStop() OWI_Stop() 1-Wire
*/
void OWI_CommandMode(const uint8_t *tx_data, uint8_t tx_len, uint8_t id)
{
uint8_t rx[3] = {0};
char uart_buf[16];
int i;
// Write sequence (슬레이브 주소와 명령 전송)
OWI_SecureStop(); // 통신 준비
OWI_WriteByte(id << 1); // 슬레이브 write 주소
for (i = 0; i < tx_len; i++) {
OWI_WriteByte(tx_data[i]); // 명령 전송
}
OWI_Stop(); // 쓰기 종료
1 week ago
HOST_PRINT("51\r\n");
2 weeks ago
}
/**
* : OWI_ReadBytesAndPrint
* : 1-Wire , UART로 .
*
* :
* - length :
* - id : 1-Wire ID ( )
*
* : (void)
*
* :
* 1)
* - OWI_SecureStop()
* - (id << 1) | 1
*
* 2) length만큼 OWI_ReadByte()
* - buf
*
* 3) UART
* - buf[0]
* - 1
* -
* - delay(10000) (UART )
* - : 16
* - CRLF("\r\n")
*
* :
* - UART (uart_buf, tmp_buf)
* - delay를
*/
void OWI_ReadBytesAndPrint(int length, uint8_t id)
{
uint8_t buf[600];
int i;
char uart_buf[8];
char tmp_buf[8];
uint8_t va0, va1;
OWI_SecureStop();
OWI_WriteByte((id << 1) | 1);
for (i = 0; i < length; i++) {
buf[i] = OWI_ReadByte();
}
sprintf(uart_buf, "%02X ", buf[0]);
strcpy(tmp_buf, uart_buf);
1 week ago
HOST_PRINT(tmp_buf);
2 weeks ago
for (i = 1; i < length; i += 2) {
va0 = buf[i];
if (i + 1 < length) {
// 완전한 페어
va1 = buf[i + 1];
delay(10000);
sprintf(uart_buf, "%02X%02X ", va0, va1);
strcpy(tmp_buf, uart_buf);
1 week ago
HOST_PRINT(tmp_buf);
2 weeks ago
delay(10000);
} else {
// 마지막 1바이트가 남은 경우 단독 출력
delay(10000);
sprintf(uart_buf, "%02X", va0);
strcpy(tmp_buf, uart_buf);
1 week ago
HOST_PRINT(tmp_buf);
2 weeks ago
delay(10000);
}
}
1 week ago
HOST_PRINT("\r\n");
2 weeks ago
}