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.
 
 

487 lines
13 KiB

#include "i2c.h"
#include "delay.h"
#include "uart.h"
#include <string.h>
uint8_t g_i2c_last_command[3] = {0};
uint8_t g_i2c_command_valid = 0;
/**
* 함수명: disable
* 목적: I2C 장치에 비활성화(disable) 명령을 전송
*
* 매개변수: 없음
*
* 반환값: 없음 (void)
*
* 동작 방식:
* 1) 전송할 데이터 준비
* - dis 배열에 {0x01, 0x02} 값 저장
*
* 2) I2C 송신
* - R_IICA0_Master_Send() 호출하여 슬레이브 주소로 데이터 전송
* - 전송 성공 시 다음 단계로 진행
* - 전송 실패 시 UART로 "I2C Send Failed" 메시지 출력 후 함수 종료
*
* 참고:
* - SLAVE_ADDR는 전송 대상 I2C 장치 주소
* - sizeof(dis)를 통해 전송할 데이터 길이 자동 계산
* - 전송 타임아웃은 100ms
*/
void disable(void){
static uint8_t dis[] = {0x01, 0x02};
//static uint8_t tx[] = {0xT0, 0x00, 0x00};
// I2C 마스터 송신
if (R_IICA0_Master_Send(SLAVE_ADDR << 1, dis, sizeof(dis), 100) != MD_OK)
{
uart_send_string("I2C Send Failed\r\n");
return;
}
}
/**
* 함수명: I2C_EnablePower
* 목적: I2C 장치 전원을 켠다.
*
* 매개변수: 없음
*
* 반환값: 없음 (void)
*
* 동작 방식:
* 1) P7 레지스터의 특정 비트를 설정하여 전원 출력 HIGH 상태로 변경
* - _02_Pn1_OUTPUT_1 : P7 포트의 1번 핀을 출력 모드로 HIGH 설정
*
* 참고:
* - I2C 장치 전원 공급용 핀을 제어
* - 출력 HIGH 상태로 전원이 켜짐
*/
void I2C_EnablePower(void) {
P7 = _02_Pn1_OUTPUT_1;
}
/**
* 함수명: I2C_DisablePower
* 목적: I2C 장치 전원을 끈다.
*
* 매개변수: 없음
*
* 반환값: 없음 (void)
*
* 동작 방식:
* 1) P7 레지스터의 특정 비트를 클리어하여 전원 출력 LOW 상태로 변경
* - _00_Pn1_OUTPUT_0 : P7 포트의 1번 핀을 출력 모드로 LOW 설정
*
* 참고:
* - I2C 장치 전원 공급용 핀을 제어
* - 출력 LOW 상태로 전원이 꺼짐
*/
void I2C_DisablePower(void) {
P7 = _00_Pn1_OUTPUT_0;
}
/**
* 함수명: I2C_A_Command_Mode_receiveData
* 목적: I2C 장치에서 ADC 데이터와 명령 리스트를 읽고,
* 최종적으로 UART로 데이터를 전송한다.
*
* 매개변수:
* - tx_data : 사용자 명령(UserCmd) 데이터 배열
* - tx_len : 사용자 명령 데이터 길이
* - id : I2C 슬레이브 장치 주소
*
* 반환값: 없음 (void)
*
* 동작 방식:
* 1) ADC 읽기
* - ADC_ReadAndSend_UART() 호출로 4채널 ADC 값을 읽음
* - 읽은 값이 4개가 아니면 오류 메시지 UART 출력 후 종료
* - TOP, BRP, BRN, BRP-BRN, BOT 값 순서대로 UART 문자열 구성
*
* 2) CMD_LIST 순서대로 I2C 읽기
* - CMD_LIST는 장치 내부 명령 6개 정의
* - R_IICA0_Master_Send()로 명령 전송
* - R_IICA0_Master_Receive()로 응답 읽음
* - 읽은 값(rx[1], rx[2])을 UART 문자열에 추가
*
* 3) 사용자 CMD 처리
* - tx_data와 tx_len이 유효하면 해당 데이터를 I2C 장치로 전송
* - 응답을 rx 배열로 읽고 UART 문자열에 추가
* - 없으면 "0000"으로 표시
*
* 4) 최종 출력
* - 완성된 문자열(line)을 UART로 전송
* - 각 단계마다 적절한 delay로 통신 안정성 확보
*
* 참고:
* - RAM_BYTES는 I2C 응답 버퍼 크기
* - UART 출력은 ","로 각 값 구분 후, 마지막에 CRLF 추가
* - ADC와 I2C 읽기 순서가 고정되어 있어 코드만 봐도 데이터 처리 흐름 이해 가능
*/
void I2C_A_Command_Mode_receiveData(const uint8_t *tx_data, uint8_t tx_len,uint8_t id )
{
uint8_t CMD_LIST[6][3] = {
{0x2E, 0x00, 0x00}, // BR
{0x2E, 0x01, 0x00}, // BR_AZ
{0x2E, 0x02, 0x00}, // T_RAW
{0x2E, 0x16, 0x00}, // Y_data
{0x2E, 0x41, 0x00}, // BR_AOUT
{0x2E, 0x40, 0x00}
};
char line[128];
size_t n = 0;
uint8_t rx[RAM_BYTES] = {0};
int j;
// 1) ADC 읽기 (4채널)
ADC_ReadAndSend_UART();
if (g_adc_len != 4) { // TOP, BRP, BRN, BOT만 읽음
uart_send_string("Err:adc_count\r\n");
return;
}
// 2) UART 문자열 구성 (5개 값)
for (j = 0; j < 5; j++) {
float v = 0.0f;
switch (j) {
case 0: // 1번: TOP
v = g_adc_bytes[0];
break;
case 1: // 2번: BRP
v = g_adc_bytes[1];
break;
case 2: // 3번: BRN
v = g_adc_bytes[2];
break;
case 3: // 4번: BRP - BRN
v = g_adc_bytes[1] - g_adc_bytes[2];
break;
case 4: // 5번: BOT
v = g_adc_bytes[3];
break;
}
n += sprintf(&line[n], "%.2f", v);
line[n++] = ',';
}
delay(100000);
// 2) CMD_LIST 순서대로 I2C 읽기
for (j = 0; j < 6; j++) {
if (R_IICA0_Master_Send((id << 1), CMD_LIST[j], 3, 100) != MD_OK) {
uart_send_string("I2C Send Failed\r\n");
return;
}
delay(10000);
if (R_IICA0_Master_Receive((id << 1), rx, RAM_BYTES, 100) != MD_OK) {
uart_send_string("I2C Receive Failed\r\n");
return;
}
delay(10000);
n += sprintf(&line[n], "%02X%02X", rx[1], rx[2]);
// 마지막 CMD 뒤에는 쉼표 붙이지 않음
if (j < 5) {
line[n++] = ',';
}
}
// 3) UserCmd 처리
line[n++] = ','; // UserCmd 앞 쉼표
if (tx_data != NULL && tx_len > 0) {
if (R_IICA0_Master_Send((id << 1), tx_data, tx_len, 100) != MD_OK) {
uart_send_string("I2C UserCmd Send Failed\r\n");
return;
}
delay(100000);
if (R_IICA0_Master_Receive((id << 1), rx, RAM_BYTES, 100) != MD_OK) {
uart_send_string("I2C UserCmd Receive Failed\r\n");
return;
}
delay(10000);
n += sprintf(&line[n], "%02X%02X", rx[1], rx[2]);
} else {
n += sprintf(&line[n], "0000");
}
// 마지막에 CRLF
line[n++] = '\r';
line[n++] = '\n';
line[n] = '\0';
uart_send_string(line);
delay(10000);
}
/**
* 함수명: I2C_Diagnostic
* 목적: I2C 장치의 진단용 데이터를 읽어 UART로 출력
*
* 매개변수:
* - id : I2C 슬레이브 장치 주소
*
* 반환값: 없음 (void)
*
* 동작 방식:
* 1) CMD_LIST 정의
* - 장치에서 읽어야 하는 10개의 진단 명령
* - 각 명령은 3바이트: {명령 코드, 파라미터1, 파라미터2}
*
* 2) CMD_LIST 순서대로 I2C 통신 수행
* - R_IICA0_Master_Send()로 명령 전송
* - R_IICA0_Master_Receive()로 응답 읽기
* - 읽은 데이터(rx[1], rx[2])를 UART 문자열(line)에 추가
* - 마지막 CMD 뒤에는 쉼표 생략
* - 각 전송/수신 후 delay로 통신 안정성 확보
*
* 3) UART 출력
* - 완성된 문자열(line)을 UART로 전송
* - 마지막에 CRLF 추가
*
* 참고:
* - RAM_BYTES는 I2C 응답 버퍼 크기
* - UART 출력 문자열은 각 CMD별 2바이트씩 HEX로 표시
* - 함수는 I2C 장치 상태 확인용 진단 루틴으로 사용
*/
void I2C_Diagnostic(uint8_t id )
{
uint8_t CMD_LIST[10][3] = {
{0x2E, 0x01, 0x00}, // BR
{0x2E, 0x00, 0x00}, // BR_AZ
{0x2E, 0x02, 0x00}, // T_RAW
{0x2E, 0x03, 0x00}, // Y_data
{0x2E, 0x21, 0x00}, // BR_AOUT
{0x2E, 0x40, 0x00},
{0x2E, 0x05, 0x00},
{0x2E, 0x07, 0x00},
{0x2E, 0x19, 0x00},
{0x2E, 0x0B, 0x00}
};
char line[128];
size_t n = 0;
uint8_t rx[RAM_BYTES] = {0};
int j;
// 2) CMD_LIST 순서대로 I2C 읽기
for (j = 0; j < 10; j++) {
if (R_IICA0_Master_Send((id << 1), CMD_LIST[j], 3, 100) != MD_OK) {
uart_send_string("I2C Send Failed\r\n");
return;
}
delay(10000);
if (R_IICA0_Master_Receive((id << 1), rx, RAM_BYTES, 100) != MD_OK) {
uart_send_string("I2C Receive Failed\r\n");
return;
}
delay(10000);
n += sprintf(&line[n], "%02X%02X", rx[1], rx[2]);
// 마지막 CMD 뒤에는 쉼표 붙이지 않음
if (j < 9) {
line[n++] = ',';
}
}
// 마지막에 CRLF
line[n++] = '\r';
line[n++] = '\n';
line[n] = '\0';
uart_send_string(line);
delay(10000);
}
/**
* 함수명: I2C_T_Command_Mode_receiveData
* 목적: I2C 장치에 명령(tx_data) 전송 후, 상태를 UART로 출력
*
* 매개변수:
* - tx_data : I2C로 전송할 데이터 버퍼
* - tx_len : 전송할 데이터 길이 (바이트)
* - id : I2C 슬레이브 장치 주소
*
* 반환값: 없음 (void)
*
* 동작 방식:
* 1) I2C 하드웨어 초기화
* - R_IICA0_Create()를 호출하여 I2C 모듈 초기화
* - I2C 장치에 전원 공급 (I2C_EnablePower())
* - 전원 안정화를 위해 약간의 delay(1초)
*
* 2) I2C 명령 전송
* - R_IICA0_Master_Send()로 장치에 tx_data 전송
* - 전송 실패 시 UART로 "I2C Send Failed" 출력하고 함수 종료
*
* 3) UART 출력
* - 전송 성공 여부와 상관없이 "51" 문자열을 UART로 출력
*
* 참고:
* - 이 함수는 읽기(read) 기능 없이 명령 전송만 수행
* - UART 출력 "51"은 전송 완료 신호/디버깅용
*/
void I2C_T_Command_Mode_receiveData(const uint8_t *tx_data, uint8_t tx_len,uint8_t id )
{
char uart_buf[16];
int j;
uint8_t rx[3] = {0};
R_IICA0_Create();
I2C_EnablePower();
delay(1000000);
if (R_IICA0_Master_Send((id << 1), tx_data, tx_len, 100) != MD_OK)
{
uart_send_string("I2C Send Failed\r\n");
return;
}
uart_send_string("51\r\n");
}
/**
* 함수명: I2C_Command_Mode_receiveData
* 목적: I2C 장치에 명령(tx_data)을 전송하고, 상태를 UART로 출력
*
* 매개변수:
* - tx_data : I2C로 전송할 데이터 버퍼
* - tx_len : 전송할 데이터 길이 (바이트)
* - id : I2C 슬레이브 장치 주소
*
* 반환값: 없음 (void)
*
* 동작 방식:
* 1) I2C 명령 전송
* - R_IICA0_Master_Send()로 지정한 슬레이브(id)에 tx_data 전송
* - 전송 실패 시 UART로 "I2C Send Failed" 출력 후 함수 종료
*
* 2) UART 출력
* - 전송 성공 시 "51" 문자열을 UART로 전송
* - 디버깅 또는 전송 완료 신호용
*
* 참고:
* - 읽기 기능 없이 명령 전송만 수행
* - I2C 전원 제어나 초기화는 포함되어 있지 않음
*/
void I2C_Command_Mode_receiveData(const uint8_t *tx_data, uint8_t tx_len,uint8_t id )
{
char uart_buf[16];
int j;
uint8_t rx[3] = {0};
if (R_IICA0_Master_Send((id << 1), tx_data, tx_len, 100) != MD_OK)
{
uart_send_string("I2C Send Failed\r\n");
return;
}
uart_send_string("51\r\n");
}
/**
* 함수명: I2C_Command_Mode_Send
* 목적: I2C 슬레이브 장치로부터 데이터를 읽고, UART로 출력
*
* 매개변수:
* - tx_len : 읽을 데이터 길이 (바이트)
* - id : I2C 슬레이브 장치 주소
*
* 반환값: 없음 (void)
*
* 동작 방식:
* 1) I2C 데이터 수신
* - R_IICA0_Master_Receive()를 사용하여 지정된 슬레이브(id)로부터 tx_len 바이트 읽기
* - 실패 시 UART로 "I2C Receive Failed" 출력 후 함수 종료
*
* 2) UART 출력
* - 첫 번째 바이트는 "%02X " 형식으로 바로 출력
* - 그 다음 바이트들은 2바이트씩 묶어서 "%02X%02X " 형식으로 출력
* - 마지막에 남은 1바이트는 단독으로 "%02X" 출력
* - 모든 출력 후 줄바꿈("\r\n") 추가
*
* 3) delay
* - 각 출력 사이에 delay를 넣어 UART 전송 안정화
*
* 참고:
* - I2C 전원 제어나 초기화는 포함되어 있지 않음
* - 출력 포맷은 디버깅 또는 로그용
*/
void I2C_Command_Mode_Send(uint8_t tx_len, uint8_t id)
{
char uart_buf[16];
char tmp_buf[8];
int i,j;
uint8_t rx[600];
uint8_t va0, va1;
uint8_t status = 0x00;
int tries = 0;
/* ★추가: 버퍼 초기화 (기존 로직/출력 형식 유지) */
memset(uart_buf, 0, sizeof(uart_buf));
memset(tmp_buf, 0, sizeof(tmp_buf));
memset(rx, 0x00, sizeof(rx)); // 가드 패턴(0x00으로 해도 무방)
if (R_IICA0_Master_Receive((id << 1), rx, (uint8_t)(tx_len), 1000) != MD_OK) {
uart_send_string("I2C Receive Failed\r\n");
return;
}
delay(1000000);
sprintf(uart_buf, "%02X ", rx[0]);
strcpy(tmp_buf, uart_buf);
uart_send_string(uart_buf);
delay(10000);
for (i = 1; i < (tx_len); i += 2) {
va0 = rx[i];
if (i + 1 < (tx_len)) {
va1 = rx[i + 1];
delay(10000);
sprintf(uart_buf, "%02X%02X ", va0, va1);
uart_send_string(uart_buf);
delay(10000);
} else {
delay(10000);
sprintf(uart_buf, "%02X", va0);
strcpy(tmp_buf, uart_buf);
uart_send_string(uart_buf);
delay(10000);
}
}
uart_send_string("\r\n");
}