generated from hulk/gd32e23x_template_cmake_vscode
debug version
This commit is contained in:
@@ -27,6 +27,14 @@
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
#define MCU_CODE 23u
|
||||
|
||||
#define FW_VERSION_MAJOR 0
|
||||
#define FW_VERSION_MINOR 0
|
||||
#define FW_VERSION_PATCH 3
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
/* Dynamic USART Configuration Structure */
|
||||
typedef struct {
|
||||
uint32_t rcu_usart;
|
||||
|
72
Inc/i2c.h
72
Inc/i2c.h
@@ -107,15 +107,76 @@ i2c_result_t i2c_write_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data
|
||||
*/
|
||||
i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
|
||||
|
||||
/* Generic read/write functions with configurable length */
|
||||
/*!
|
||||
\brief read 16-bit data from I2C device
|
||||
\param[in] slave_addr: 7-bit slave address
|
||||
\brief write data to I2C device with configurable length
|
||||
\param[in] slave_addr: slave device address (7-bit)
|
||||
\param[in] reg_addr: register address
|
||||
\param[out] data: pointer to 2-byte data buffer
|
||||
\retval i2c_result_t
|
||||
\param[in] data: pointer to data buffer
|
||||
\param[in] length: number of bytes to write (1-255)
|
||||
\param[out] none
|
||||
\retval i2c_result_t: operation result
|
||||
*/
|
||||
i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
|
||||
i2c_result_t i2c_write(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t length);
|
||||
|
||||
/*!
|
||||
\brief read data from I2C device with configurable length
|
||||
\param[in] slave_addr: slave device address (7-bit)
|
||||
\param[in] reg_addr: register address
|
||||
\param[out] data: pointer to data buffer
|
||||
\param[in] length: number of bytes to read (1-255)
|
||||
\retval i2c_result_t: operation result
|
||||
*/
|
||||
i2c_result_t i2c_read(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t length);
|
||||
|
||||
/* Convenience functions for common operations */
|
||||
/*!
|
||||
\brief write single byte to I2C device
|
||||
\param[in] slave_addr: slave device address (7-bit)
|
||||
\param[in] reg_addr: register address
|
||||
\param[in] data: data byte to write
|
||||
\retval i2c_result_t: operation result
|
||||
*/
|
||||
i2c_result_t i2c_write_8bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data);
|
||||
|
||||
/*!
|
||||
\brief read single byte from I2C device
|
||||
\param[in] slave_addr: slave device address (7-bit)
|
||||
\param[in] reg_addr: register address
|
||||
\param[out] data: pointer to data byte
|
||||
\retval i2c_result_t: operation result
|
||||
*/
|
||||
i2c_result_t i2c_read_8bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
|
||||
|
||||
/*!
|
||||
\brief write 32-bit data to I2C device
|
||||
\param[in] slave_addr: slave device address (7-bit)
|
||||
\param[in] reg_addr: register address
|
||||
\param[in] data: pointer to 4-byte data array
|
||||
\retval i2c_result_t: operation result
|
||||
*/
|
||||
i2c_result_t i2c_write_32bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[4]);
|
||||
|
||||
/*!
|
||||
\brief read 32-bit data from I2C device
|
||||
\param[in] slave_addr: slave device address (7-bit)
|
||||
\param[in] reg_addr: register address
|
||||
\param[out] data: pointer to 4-byte data buffer
|
||||
\retval i2c_result_t: operation result
|
||||
*/
|
||||
i2c_result_t i2c_read_32bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data);
|
||||
|
||||
/*!
|
||||
\brief read display panel parameters (multi-byte)
|
||||
\param[in] slave_addr: slave device address (7-bit)
|
||||
\param[in] reg_addr: register address
|
||||
\param[out] data: pointer to data buffer
|
||||
\param[in] length: number of bytes to read (1-13)
|
||||
\retval i2c_result_t: operation result
|
||||
*/
|
||||
i2c_result_t i2c_read_display_params(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t length);
|
||||
|
||||
#ifdef DEBUG_VERBOSE
|
||||
/*!
|
||||
\brief get status string for debugging
|
||||
\param[in] status: i2c_result_t value
|
||||
@@ -123,5 +184,6 @@ i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data
|
||||
\retval const char* status string
|
||||
*/
|
||||
const char* i2c_get_status_string(i2c_result_t status);
|
||||
#endif
|
||||
|
||||
#endif //I2C_H
|
||||
|
@@ -306,6 +306,7 @@ void handle_command(const uint8_t *frame, uint8_t len) {
|
||||
|
||||
case 2u: // M2: disable sensor report
|
||||
set_eddy_sensor_report_status(false);
|
||||
send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok));
|
||||
return;
|
||||
|
||||
case 3u:
|
||||
@@ -314,12 +315,26 @@ void handle_command(const uint8_t *frame, uint8_t len) {
|
||||
|
||||
case 4u:
|
||||
set_temp_sensor_report_status(false);
|
||||
send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok));
|
||||
return;
|
||||
|
||||
// case 201u: // M201命令
|
||||
// send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok));
|
||||
// return;
|
||||
|
||||
case 999u: //M999: 输出固件版本号(vMCU_CODE.FW_VERSION_MAJOR.FW_VERSION_MINOR.FW_VERSION_PATCH)
|
||||
char version_str[16];
|
||||
int n = snprintf(version_str, sizeof(version_str), "v%u.%u.%u.%u", MCU_CODE, FW_VERSION_MAJOR, FW_VERSION_MINOR, FW_VERSION_PATCH);
|
||||
send_response(RESP_TYPE_OK, (uint8_t *)version_str, (uint8_t)n);
|
||||
// send_response(RESP_TYPE_OK, (uint8_t *)"v23.0.0.3", 9);
|
||||
return;
|
||||
|
||||
case 9999u:
|
||||
// M9999: 重启系统
|
||||
__disable_irq(); // 关闭全局中断(GD32E230 CMSIS标准函数)
|
||||
nvic_system_reset(); // 系统复位(GD32E230标准库函数)
|
||||
break;
|
||||
|
||||
default:
|
||||
// 其它无参数命令在此扩展(示例:M100)处理逻辑该如何待定
|
||||
// send_response(RESP_TYPE_OK, s_report_status_ok, sizeof(s_report_status_ok));
|
||||
|
481
Src/i2c.c
481
Src/i2c.c
@@ -649,6 +649,487 @@ i2c_result_t i2c_read_16bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data
|
||||
return I2C_RESULT_TIMEOUT;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief write data to I2C device with configurable length
|
||||
\param[in] slave_addr: slave device address (7-bit)
|
||||
\param[in] reg_addr: register address
|
||||
\param[in] data: pointer to data buffer
|
||||
\param[in] length: number of bytes to write (1-255)
|
||||
\param[out] none
|
||||
\retval i2c_result_t: operation result
|
||||
*/
|
||||
i2c_result_t i2c_write(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t length) {
|
||||
i2c_state_t state = I2C_STATE_START;
|
||||
uint16_t timeout = 0;
|
||||
uint8_t retry_count = 0;
|
||||
uint8_t data_index = 0;
|
||||
|
||||
/* parameter validation */
|
||||
if (data == NULL || slave_addr > 0x7F || length == 0) {
|
||||
return I2C_RESULT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
while (retry_count < I2C_MAX_RETRY) {
|
||||
switch (state) {
|
||||
case I2C_STATE_START:
|
||||
timeout = 0;
|
||||
data_index = 0;
|
||||
|
||||
/* wait for bus to be idle */
|
||||
while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
i2c_start_on_bus(I2C0);
|
||||
timeout = 0;
|
||||
state = I2C_STATE_SEND_ADDRESS;
|
||||
break;
|
||||
|
||||
case I2C_STATE_SEND_ADDRESS:
|
||||
/* wait for start condition to be sent. SBSEND flag */
|
||||
while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* send slave address */
|
||||
i2c_master_addressing(I2C0, slave_addr << 1, I2C_TRANSMITTER);
|
||||
timeout = 0;
|
||||
state = I2C_STATE_CLEAR_ADDRESS;
|
||||
break;
|
||||
|
||||
case I2C_STATE_CLEAR_ADDRESS:
|
||||
/* wait for address to be acknowledged.ADDSEND set means i2c slave sends ACK */
|
||||
while ((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (!i2c_flag_get(I2C0, I2C_FLAG_AERR)) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
} else if (i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) {
|
||||
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
|
||||
timeout = 0;
|
||||
state = I2C_STATE_TRANSMIT_REG;
|
||||
break;
|
||||
} else {
|
||||
i2c_flag_clear(I2C0, I2C_FLAG_AERR);
|
||||
timeout = 0;
|
||||
#ifdef DEBUG_VERBOSE
|
||||
printf("IIC write failed for Error Slave Address. \n");
|
||||
#endif
|
||||
return I2C_RESULT_NACK;
|
||||
}
|
||||
|
||||
case I2C_STATE_TRANSMIT_REG:
|
||||
/* wait until the transmit data buffer is empty */
|
||||
while ((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* send register address */
|
||||
i2c_data_transmit(I2C0, reg_addr);
|
||||
timeout = 0;
|
||||
state = I2C_STATE_TRANSMIT_DATA;
|
||||
break;
|
||||
|
||||
case I2C_STATE_TRANSMIT_DATA:
|
||||
/* wait until the transmit data buffer is empty */
|
||||
while ((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* send data byte */
|
||||
i2c_data_transmit(I2C0, data[data_index]);
|
||||
data_index++;
|
||||
|
||||
/* check for errors */
|
||||
if (i2c_flag_get(I2C0, I2C_FLAG_AERR)) {
|
||||
i2c_stop_on_bus(I2C0);
|
||||
return I2C_RESULT_NACK;
|
||||
} else if (i2c_flag_get(I2C0, I2C_FLAG_BERR) || i2c_flag_get(I2C0, I2C_FLAG_LOSTARB)) {
|
||||
i2c_stop_on_bus(I2C0);
|
||||
return I2C_RESULT_ERROR;
|
||||
}
|
||||
|
||||
/* check if all data has been sent */
|
||||
if (data_index >= length) {
|
||||
/* wait until BTC bit is set for last byte */
|
||||
timeout = 0;
|
||||
while (!i2c_flag_get(I2C0, I2C_FLAG_BTC) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
state = I2C_STATE_STOP;
|
||||
}
|
||||
timeout = 0;
|
||||
break;
|
||||
|
||||
case I2C_STATE_STOP:
|
||||
/* send a stop condition to I2C bus */
|
||||
i2c_stop_on_bus(I2C0);
|
||||
|
||||
timeout = 0;
|
||||
while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* success */
|
||||
return I2C_RESULT_SUCCESS;
|
||||
|
||||
case I2C_STATE_ERROR:
|
||||
/* send a stop condition to I2C bus */
|
||||
i2c_stop_on_bus(I2C0);
|
||||
|
||||
timeout = 0;
|
||||
while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
|
||||
i2c_flag_clear(I2C0, I2C_FLAG_AERR);
|
||||
i2c_flag_clear(I2C0, I2C_FLAG_BERR);
|
||||
i2c_flag_clear(I2C0, I2C_FLAG_LOSTARB);
|
||||
|
||||
retry_count++;
|
||||
if (retry_count >= I2C_MAX_RETRY) {
|
||||
#ifdef DEBUG_VERBOSE
|
||||
printf("IIC write failed after %d retries\n", I2C_MAX_RETRY);
|
||||
#endif
|
||||
return I2C_RESULT_ERROR;
|
||||
}
|
||||
|
||||
/* reset state machine for retry */
|
||||
state = I2C_STATE_START;
|
||||
timeout = 0;
|
||||
|
||||
/* small delay before retry */
|
||||
delay_10us(10);
|
||||
break;
|
||||
|
||||
default:
|
||||
state = I2C_STATE_START;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return I2C_RESULT_TIMEOUT;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief read data from I2C device with configurable length
|
||||
\param[in] slave_addr: slave device address (7-bit)
|
||||
\param[in] reg_addr: register address
|
||||
\param[out] data: pointer to data buffer
|
||||
\param[in] length: number of bytes to read (1-255)
|
||||
\retval i2c_result_t: operation result
|
||||
*/
|
||||
i2c_result_t i2c_read(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t length) {
|
||||
i2c_state_t state = I2C_STATE_START;
|
||||
uint16_t timeout = 0;
|
||||
uint8_t retry_count = 0;
|
||||
bool write_phase = true;
|
||||
uint8_t data_index = 0;
|
||||
|
||||
/* parameter validation */
|
||||
if (data == NULL || slave_addr > 0x7F || length == 0) {
|
||||
return I2C_RESULT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/* enable acknowledge */
|
||||
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
|
||||
|
||||
while (retry_count < (uint8_t)I2C_MAX_RETRY) {
|
||||
switch (state) {
|
||||
case I2C_STATE_START:
|
||||
timeout = 0;
|
||||
data_index = 0;
|
||||
|
||||
/* wait for bus to be idle */
|
||||
while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* send start condition */
|
||||
i2c_start_on_bus(I2C0);
|
||||
state = I2C_STATE_SEND_ADDRESS;
|
||||
timeout = 0;
|
||||
break;
|
||||
|
||||
case I2C_STATE_SEND_ADDRESS:
|
||||
/* wait for start condition to be sent */
|
||||
while ((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* send slave address */
|
||||
if (write_phase) {
|
||||
/* write phase: send address with write bit */
|
||||
i2c_master_addressing(I2C0, (slave_addr << 1), I2C_TRANSMITTER);
|
||||
} else {
|
||||
/* read phase: send address with read bit */
|
||||
i2c_master_addressing(I2C0, (slave_addr << 1) | 0x01, I2C_RECEIVER);
|
||||
}
|
||||
|
||||
state = I2C_STATE_CLEAR_ADDRESS;
|
||||
timeout = 0;
|
||||
break;
|
||||
|
||||
case I2C_STATE_CLEAR_ADDRESS:
|
||||
/* wait for address to be acknowledged */
|
||||
while ((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
if (write_phase) {
|
||||
/* clear address flag (write phase) */
|
||||
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
|
||||
state = I2C_STATE_TRANSMIT_DATA;
|
||||
} else {
|
||||
/* read phase setup based on length */
|
||||
if (length == 1) {
|
||||
/* single byte read: disable ACK before clearing ADDR */
|
||||
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
|
||||
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
|
||||
/* send STOP immediately after clearing ADDR for single byte */
|
||||
i2c_stop_on_bus(I2C0);
|
||||
} else if (length == 2) {
|
||||
/* two bytes read: set POS=NEXT and disable ACK before clearing ADDR */
|
||||
i2c_ackpos_config(I2C0, I2C_ACKPOS_NEXT);
|
||||
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
|
||||
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
|
||||
} else {
|
||||
/* multi-byte read: clear ADDR with ACK enabled */
|
||||
i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND);
|
||||
}
|
||||
state = I2C_STATE_RECEIVE_DATA;
|
||||
}
|
||||
timeout = 0;
|
||||
break;
|
||||
|
||||
case I2C_STATE_TRANSMIT_DATA:
|
||||
/* wait for transmit buffer to be empty */
|
||||
while ((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* send register address */
|
||||
i2c_data_transmit(I2C0, reg_addr);
|
||||
state = I2C_STATE_RESTART;
|
||||
timeout = 0;
|
||||
break;
|
||||
|
||||
case I2C_STATE_RESTART:
|
||||
/* wait for byte transfer complete */
|
||||
while ((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* generate repeated start condition */
|
||||
i2c_start_on_bus(I2C0);
|
||||
|
||||
/* wait for repeated start condition to be sent */
|
||||
timeout = 0;
|
||||
while ((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* send slave address with read bit */
|
||||
i2c_master_addressing(I2C0, (slave_addr << 1), I2C_RECEIVER);
|
||||
|
||||
/* switch to read phase */
|
||||
write_phase = false;
|
||||
state = I2C_STATE_CLEAR_ADDRESS;
|
||||
timeout = 0;
|
||||
break;
|
||||
|
||||
case I2C_STATE_RECEIVE_DATA:
|
||||
if (length == 1) {
|
||||
/* single byte read */
|
||||
while ((!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
data[0] = i2c_data_receive(I2C0);
|
||||
state = I2C_STATE_STOP;
|
||||
} else if (length == 2) {
|
||||
/* two bytes read */
|
||||
while ((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
/* send STOP before reading the last two bytes */
|
||||
i2c_stop_on_bus(I2C0);
|
||||
/* read the two bytes back-to-back */
|
||||
data[0] = i2c_data_receive(I2C0);
|
||||
data[1] = i2c_data_receive(I2C0);
|
||||
state = I2C_STATE_STOP;
|
||||
} else {
|
||||
/* multi-byte read (length > 2) */
|
||||
while (data_index < length) {
|
||||
/* wait for RBNE (receive buffer not empty) */
|
||||
while ((!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* special handling for last 3 bytes */
|
||||
if (data_index == length - 3) {
|
||||
/* wait for BTF (byte transfer finished) before reading N-2 */
|
||||
while ((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
/* disable ACK for last 2 bytes */
|
||||
i2c_ack_config(I2C0, I2C_ACK_DISABLE);
|
||||
}
|
||||
|
||||
/* read data byte */
|
||||
data[data_index] = i2c_data_receive(I2C0);
|
||||
data_index++;
|
||||
|
||||
/* send STOP after reading N-1 byte */
|
||||
if (data_index == length - 1) {
|
||||
i2c_stop_on_bus(I2C0);
|
||||
}
|
||||
|
||||
timeout = 0;
|
||||
}
|
||||
state = I2C_STATE_STOP;
|
||||
}
|
||||
break;
|
||||
|
||||
case I2C_STATE_STOP:
|
||||
/* wait for stop condition to complete */
|
||||
while ((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) {
|
||||
timeout++;
|
||||
}
|
||||
if (timeout >= I2C_TIME_OUT) {
|
||||
state = I2C_STATE_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
/* reset ACK configuration for next operation */
|
||||
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
|
||||
i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);
|
||||
|
||||
/* success */
|
||||
return I2C_RESULT_SUCCESS;
|
||||
|
||||
case I2C_STATE_ERROR:
|
||||
/* send stop condition to release bus */
|
||||
i2c_stop_on_bus(I2C0);
|
||||
|
||||
/* reset ACK configuration */
|
||||
i2c_ack_config(I2C0, I2C_ACK_ENABLE);
|
||||
i2c_ackpos_config(I2C0, I2C_ACKPOS_CURRENT);
|
||||
|
||||
retry_count++;
|
||||
if (retry_count >= I2C_MAX_RETRY) {
|
||||
#ifdef DEBUG_VERBOSE
|
||||
printf("I2C read failed after %d retries\n", I2C_MAX_RETRY);
|
||||
#endif
|
||||
return I2C_RESULT_ERROR;
|
||||
}
|
||||
|
||||
/* reset state machine for retry */
|
||||
state = I2C_STATE_START;
|
||||
write_phase = true;
|
||||
timeout = 0;
|
||||
|
||||
/* small delay before retry */
|
||||
delay_10us(10);
|
||||
break;
|
||||
|
||||
default:
|
||||
state = I2C_STATE_START;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return I2C_RESULT_TIMEOUT;
|
||||
}
|
||||
|
||||
/* convenience functions for common operations */
|
||||
i2c_result_t i2c_write_8bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data) {
|
||||
return i2c_write(slave_addr, reg_addr, &data, 1);
|
||||
}
|
||||
|
||||
i2c_result_t i2c_read_8bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) {
|
||||
return i2c_read(slave_addr, reg_addr, data, 1);
|
||||
}
|
||||
|
||||
i2c_result_t i2c_write_32bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t data[4]) {
|
||||
return i2c_write(slave_addr, reg_addr, data, 4);
|
||||
}
|
||||
|
||||
i2c_result_t i2c_read_32bits(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data) {
|
||||
return i2c_read(slave_addr, reg_addr, data, 4);
|
||||
}
|
||||
|
||||
/* 显示面板专用函数 - 支持读取显示界面参数 */
|
||||
i2c_result_t i2c_read_display_params(uint8_t slave_addr, uint8_t reg_addr, uint8_t *data, uint8_t length) {
|
||||
/* 针对显示面板的多字节读取,支持13字节的完整参数读取 */
|
||||
if (length > 13) {
|
||||
return I2C_RESULT_INVALID_PARAM;
|
||||
}
|
||||
return i2c_read(slave_addr, reg_addr, data, length);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_VERBOSE
|
||||
/*!
|
||||
\brief get status string for debugging
|
||||
|
@@ -60,7 +60,7 @@ int main(void)
|
||||
|
||||
// led_init();
|
||||
|
||||
printf("Flash size: %d Kbytes\n", get_flash_size());
|
||||
// printf("Flash size: %d Kbytes\n", get_flash_size());
|
||||
|
||||
#ifdef DEBUG_VERBOSE
|
||||
char hello_world[] = {"Hello World!\r\n"};
|
||||
|
@@ -86,7 +86,8 @@ tmp112a_status_t tmp112a_read_temperature(tmp112a_result_t *result) {
|
||||
}
|
||||
|
||||
void tmp112a_get_raw_temperature_value(uint8_t *value) {
|
||||
i2c_read_16bits(TMP112A_ADDR, TMP112A_TEMP_REG, value);
|
||||
// i2c_read_16bits(TMP112A_ADDR, TMP112A_TEMP_REG, value);
|
||||
i2c_read(TMP112A_ADDR, TMP112A_TEMP_REG, value, 2);
|
||||
return;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user