From 9d7d0935ba3cc592f4a01d38236fb32523556357 Mon Sep 17 00:00:00 2001 From: yelvlab Date: Thu, 26 Sep 2024 17:32:57 +0800 Subject: [PATCH] i2c function --- CMakeLists.txt | 1 + inc/gd32e23x_hw_i2c.h | 75 ++++ inc/ultrasonic_driver.h | 4 +- src/gd32e23x_hw_i2c.c | 742 ++++++++++++++++++++++++++++++++++++++++ src/main.c | 3 +- src/mlx90614.c | 6 + src/ultrasonic_driver.c | 6 +- 7 files changed, 831 insertions(+), 6 deletions(-) create mode 100644 inc/gd32e23x_hw_i2c.h create mode 100644 src/gd32e23x_hw_i2c.c diff --git a/CMakeLists.txt b/CMakeLists.txt index ce84bb8..f8d182c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ set(TARGET_C_SRC ${CMAKE_SOURCE_DIR}/src/systick.c ${CMAKE_SOURCE_DIR}/src/ultrasonic_driver.c ${CMAKE_SOURCE_DIR}/src/mlx90614.c + ${CMAKE_SOURCE_DIR}/src/gd32e23x_hw_i2c.c ) add_executable(xlsw_3dp_ultrasonic_300K ${TARGET_C_SRC}) diff --git a/inc/gd32e23x_hw_i2c.h b/inc/gd32e23x_hw_i2c.h new file mode 100644 index 0000000..e44d36d --- /dev/null +++ b/inc/gd32e23x_hw_i2c.h @@ -0,0 +1,75 @@ +#ifndef GD32E23X_HW_I2C_H +#define GD32E23X_HW_I2C_H + +#define I2C0_BUS_RCU RCU_I2C0 +#define I2C0_GPIO_RCU RCU_GPIOF +#define I2C0_GPIO_PORT GPIOF +#define I2C0_GPIO_SDA_PIN GPIO_PIN_0 +#define I2C0_GPIO_SCL_PIN GPIO_PIN_1 +#define I2C0_GPIO_AF GPIO_AF_1 + +#define I2C0_SPEED 400000U +#define I2C0_DCTY I2C_DTCY_2 +#define I2C0_ADDR7 0xA0 + + + + + +#define I2C_TIME_OUT (uint16_t)(5000) +#define I2C_OK 1 +#define I2C_FAIL 0 +#define I2C_END 1 + +typedef enum { + I2C_START = 0, + I2C_SEND_ADDR, + I2C_CLEAR_ADDRESS_FLAG, + I2C_TRANSMIT_DATA, + I2C_STOP +} i2c_process_enum; + + + +/** + * \brief Return codes for IIC APIs. + * @{ + */ +#define IIC_SUCCESS 0 +#define IIC_INVALID_ARGUMENT 1 +#define IIC_ARBITRATION_LOST 2 +#define IIC_NO_CHIP_FOUND 3 +#define IIC_RECEIVE_OVERRUN 4 +#define IIC_RECEIVE_NACK 5 +#define IIC_SEND_OVERRUN 6 +#define IIC_SEND_NACK 7 +#define IIC_BUSY 8 +#define IIC_ERROR_TIMEOUT 9 +/** + * @} + */ + +void i2c_master_initialize1(void); +void i2c_master_initialize3(void); +void i2c_master_init(void); +void i2c_master_deinit1(void); +void i2c_master_deinit3(void); + +uint8_t i2c_master_read_register1(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue); +uint8_t i2c_master_read_register3(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue); + +uint8_t i2c_master_read_register1_raw(unsigned char Address, unsigned short len, unsigned char *data); +uint8_t i2c_master_read_register3_raw(unsigned char Address, unsigned short len, unsigned char *data); + + +uint8_t i2c_master_write_register1(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue); +uint8_t i2c_master_write_register3(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue); + +uint8_t i2c_master_write_register1_raw(unsigned char Address, unsigned short len, unsigned char *data); +uint8_t i2c_master_write_register3_raw(unsigned char Address, unsigned short len, unsigned char *data); + + +void i2c0_master_init(void); + + +#endif /* GD32E23X_HW_I2C_H */ \ No newline at end of file diff --git a/inc/ultrasonic_driver.h b/inc/ultrasonic_driver.h index e81be91..182a85d 100644 --- a/inc/ultrasonic_driver.h +++ b/inc/ultrasonic_driver.h @@ -67,9 +67,9 @@ void ultrasonic_config(void); void ultrasonic_transmit_config(void); void ultrasonic_pwm_out_cycles(const uint8_t cycles); void ultrasonic_transmit_delay(const uint16_t micro_second); -void recevice_exti_config(void); +void receive_exti_config(void); void ultrasonic_echo_timer_config(void); -void ultrasonic_recevice_config(void); +void ultrasonic_receive_config(void); uint16_t calculate_distance(uint32_t us_value); #endif //ULTRASONIC_DRIVER_H diff --git a/src/gd32e23x_hw_i2c.c b/src/gd32e23x_hw_i2c.c new file mode 100644 index 0000000..f05594c --- /dev/null +++ b/src/gd32e23x_hw_i2c.c @@ -0,0 +1,742 @@ +#include +#include +#include "gd32e23x.h" +#include "gd32e23x_hw_i2c.h" +#include "gd32e23x.h" + +/*! + \brief Enable IIC0 & NVIC + \param[in] none + \param[out] none + \retval none +*/ +void i2c0_init(void) { + /* IIC config */ + rcu_periph_clock_enable(RCU_I2C0); + rcu_periph_clock_enable(I2C0_GPIO_RCU); + + gpio_af_set(I2C0_GPIO_PORT, I2C0_GPIO_AF, I2C0_GPIO_SDA_PIN | I2C0_GPIO_SCL_PIN); + gpio_output_options_set(I2C0_GPIO_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C0_GPIO_SDA_PIN | I2C0_GPIO_SCL_PIN); + + i2c_clock_config(I2C0, I2C0_SPEED, I2C0_DCTY); + i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C0_ADDR7); + i2c_enable(I2C0); + i2c_ack_config(I2C0, I2C_ACK_ENABLE); +} + +void i2c_bus_reset(void) +{ + i2c_deinit(I2C0); + /* configure SDA/SCL for GPIO */ + GPIO_BC(I2C0_GPIO_PORT) |= I2C0_GPIO_SDA_PIN | I2C0_GPIO_SCL_PIN; + gpio_output_options_set(I2C0_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, I2C0_GPIO_SDA_PIN | I2C0_GPIO_SCL_PIN); + __NOP();__NOP();__NOP();__NOP();__NOP(); + /* stop signal */ + GPIO_BOP(I2C0_GPIO_PORT) |= I2C0_GPIO_SCL_PIN; + __NOP();__NOP();__NOP();__NOP();__NOP(); + GPIO_BOP(I2C0_GPIO_PORT) |= I2C0_GPIO_SDA_PIN; + /* connect I2C_SCL_PIN to I2C_SCL */ + /* connect I2C_SDA_PIN to I2C_SDA */ + gpio_output_options_set(I2C0_GPIO_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C0_GPIO_SDA_PIN | I2C0_GPIO_SCL_PIN); + /* configure the I2CX interface */ + i2c0_init(); +} + +/*! + \brief Deinit IIC0. + \param[in] none + \param[out] none + \retval none +*/ +void i2c0_deinit(void) +{ + rcu_periph_clock_disable(RCU_I2C0); + i2c_disable(I2C0); + + nvic_irq_disable(I2C0_EV_IRQn); + nvic_irq_disable(I2C0_ER_IRQn); +} + +/*! + \brief TWI1(IIC0) read data from the IIC Slave Device + \param[in] Address: the IIC Slave Device's IIC Device Address + \param[in] RegisterAddr: the IIC Slave Device's internal address to start reading from + \param[in] RegisterLen: number of bytes to reads from the IIC Slave Device + \param[in] RegisterValue: pointer to the buffer that receives the data read from the IIC Slave Device + \param[out] RegisterValue: pointer to the buffer that receives the data read from the IIC Slave Device + \retval IIC_SUCCESS +*/ +uint8_t i2c_master_receive(uint32_t i2c_periph, uint8_t Dev_Address, uint8_t) +uint8_t i2c_master_read_register1(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue){ + uint8_t state = I2C_START; + uint8_t read_cycle = 0; + uint16_t timeout = 0; + uint8_t i2c_timeout_flag = 0; + unsigned char IIC_SLAVE_ADDR = (Address << 1); + + i2c_ack_config(I2C0, I2C_ACK_ENABLE); + while (!(i2c_timeout_flag)) + { + switch (state) + { + case I2C_START: + if(RESET == read_cycle) + { + /* i2c master sends start signal only when the bus is idle */ + while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < i2c_timeout_flag)) + { + timeout ++; + } + if(timeout < I2C_TIME_OUT) + { + /* whether to send ACK or not for the next byte */ + if(2 == RegisterLen) { + i2c_ackpos_config(I2C0, I2C_ACKPOS_NEXT); + } + } else { + i2c_bus_reset(); + timeout = 0; + state = I2C_START; + printf("i2c bus is busy in READ!\n"); + } + } + /* send the start signal */ + i2c_start_on_bus(I2C0); + timeout = 0; + state = I2C_SEND_ADDR; + break; + + case I2C_SEND_ADDR: + /* i2c master sends START signal successfully */ + while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) + { + timeout++; + } + if(timeout < I2C_TIME_OUT) + { + if(RESET == read_cycle) + { + i2c_master_addressing(I2C0, IIC_SLAVE_ADDR, I2C_TRANSMITTER); + state = I2C_CLEAR_ADDRESS_FLAG; + } else { + i2c_master_addressing(I2C0, IIC_SLAVE_ADDR, I2C_RECEIVER); + if(RegisterLen < 3) { + /* disable acknowledge */ + i2c_ack_config(I2C0, I2C_ACK_DISABLE); + } + state = I2C_CLEAR_ADDRESS_FLAG; + } + timeout = 0; + } else { + timeout = 0; + state = I2C_START; + read_cycle = 0; + printf("i2c master sends start signal timeout in READ!\n"); + } + break; + + case I2C_CLEAR_ADDRESS_FLAG: + /* address flag set means i2c slave sends ACK */ + while((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) + { + timeout++; + } + if(timeout < I2C_TIME_OUT) + { + i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); + if((SET == read_cycle) && (1 == RegisterLen)) { + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(I2C0); + } + timeout = 0; + state = I2C_TRANSMIT_DATA; + } else { + timeout = 0; + state = I2C_START; + read_cycle = 0; + printf("i2c master clears address flag timeout in READ!\n"); + } + break; + + case I2C_TRANSMIT_DATA: + if(RESET == read_cycle) { + /* 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) { + /* send the EEPROM's internal address to write to : only one byte address */ + i2c_data_transmit(I2C0, RegisterAddr); + timeout = 0; + } else { + timeout = 0; + state = I2C_START; + read_cycle = 0; + printf("i2c master wait data buffer is empty timeout in READ!\n"); + } + /* wait until BTC bit is set */ + while((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + timeout = 0; + state = I2C_START; + read_cycle++; + } else { + timeout = 0; + state = I2C_START; + read_cycle = 0; + printf("i2c master sends i2c_master_read_register1 internal address timeout in READ!\n"); + } + } else { + while(RegisterLen) { + timeout++; + if(3 == RegisterLen) { + /* wait until BTC bit is set */ + while(!i2c_flag_get(I2C0, I2C_FLAG_BTC)); + /* disable acknowledge */ + i2c_ack_config(I2C0, I2C_ACK_DISABLE); + } + if(2 == RegisterLen) { + /* wait until BTC bit is set */ + while(!i2c_flag_get(I2C0, I2C_FLAG_BTC)); + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(I2C0); + } + /* wait until RBNE bit is set */ + if(i2c_flag_get(I2C0, I2C_FLAG_RBNE)) { + /* read a byte from the EEPROM */ + *RegisterValue = i2c_data_receive(I2C0); + /* point to the next location where the byte read will be saved */ + RegisterValue++; + /* decrement the read bytes counter */ + RegisterLen--; + timeout = 0; + } + if(timeout > I2C_TIME_OUT) { + timeout = 0; + state = I2C_START; + read_cycle = 0; + printf("i2c master sends data timeout in READ!\n"); + } + } + timeout = 0; + state = I2C_STOP; + } + break; + + case I2C_STOP: + /* i2c master sends STOP signal successfully */ + while((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + timeout = 0; + state = I2C_END; + i2c_timeout_flag = I2C_OK; + } else { + timeout = 0; + state = I2C_START; + read_cycle = 0; + printf("i2c master sends stop signal timeout in READ!\n"); + } + break; + + default: + state = I2C_START; + read_cycle = 0; + i2c_timeout_flag = I2C_OK; + timeout = 0; + printf("i2c master sends start signal in READ.\n"); + break; + } + } + return IIC_SUCCESS; +} + +/*! + \brief TWI3(none) read data from the IIC Slave Device + \param[in] Address: the IIC Slave Device's IIC Device Address + \param[in] RegisterAddr: the IIC Slave Device's internal address to start reading from + \param[in] RegisterLen: number of bytes to reads from the IIC Slave Device + \param[in] RegisterValue: pointer to the buffer that receives the data read from the IIC Slave Device + \param[out] RegisterValue: pointer to the buffer that receives the data read from the IIC Slave Device + \retval IIC_SUCCESS + \note No TWI3(IIC3) - No operation - Error log. +*/ +uint8_t i2c_master_read_register3(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue){ + __NOP(); + #ifdef DEBUG_VERBOES + printf("\n[DebugVerboes]i2c_master_read_register3 @ i2c.c, no TWI3 \n"); + #endif + return IIC_SUCCESS; +} + +/*! + \brief TWI1(IIC0) read data from the IIC Slave Device + \param[in] Address: the IIC Slave Device's IIC Device Address + \param[in] len: number of bytes to reads from the IIC Slave Device + \param[in] data: pointer to the buffer that receives the data read from the IIC Slave Device + \param[out] data: pointer to the buffer that receives the data read from the IIC Slave Device + \retval IIC_SUCCESS +*/ +uint8_t i2c_master_read_register1_raw(unsigned char Address, unsigned short len, unsigned char *data){ + uint8_t state = I2C_START; + // uint8_t read_cycle = 0; + uint16_t timeout = 0; + uint8_t i2c_timeout_flag = 0; + unsigned char IIC_SLAVE_ADDR = (Address << 1); + + i2c_ack_config(I2C0, I2C_ACK_ENABLE); + while (!(i2c_timeout_flag)) + { + switch (state) + { + case I2C_START: + /* i2c master sends start signal only when the bus is idle */ + while (i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < i2c_timeout_flag)) + { + timeout ++; + } + if(timeout < I2C_TIME_OUT) + { + /* whether to send ACK or not for the next byte */ + if(2 == len) { + i2c_ackpos_config(I2C0, I2C_ACKPOS_NEXT); + } + } else { + i2c_bus_reset(); + timeout = 0; + state = I2C_START; + printf("i2c bus is busy in READ!\n"); + } + /* send the start signal */ + i2c_start_on_bus(I2C0); + timeout = 0; + state = I2C_SEND_ADDR; + break; + + case I2C_SEND_ADDR: + /* i2c master sends START signal successfully */ + while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) + { + timeout++; + } + if(timeout < I2C_TIME_OUT) + { + i2c_master_addressing(I2C0, IIC_SLAVE_ADDR, I2C_RECEIVER); + if(len < 3) { + /* disable acknowledge */ + i2c_ack_config(I2C0, I2C_ACK_DISABLE); + } + state = I2C_CLEAR_ADDRESS_FLAG; + timeout = 0; + } else { + timeout = 0; + state = I2C_START; + // read_cycle = 0; + printf("i2c master sends start signal timeout in READ!\n"); + } + break; + + case I2C_CLEAR_ADDRESS_FLAG: + /* address flag set means i2c slave sends ACK */ + while((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) + { + timeout++; + } + if(timeout < I2C_TIME_OUT) + { + i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); + timeout = 0; + state = I2C_TRANSMIT_DATA; + } else { + timeout = 0; + state = I2C_START; + // read_cycle = 0; + printf("i2c master clears address flag timeout in READ!\n"); + } + break; + + case I2C_TRANSMIT_DATA: + while(len) { + timeout++; + if(3 == len) { + /* wait until BTC bit is set */ + while(!i2c_flag_get(I2C0, I2C_FLAG_BTC)); + /* disable acknowledge */ + i2c_ack_config(I2C0, I2C_ACK_DISABLE); + } + if(2 == len) { + /* wait until BTC bit is set */ + while(!i2c_flag_get(I2C0, I2C_FLAG_BTC)); + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(I2C0); + } + /* wait until RBNE bit is set */ + if(i2c_flag_get(I2C0, I2C_FLAG_RBNE)) { + /* read a byte from the EEPROM */ + *data = i2c_data_receive(I2C0); + /* point to the next location where the byte read will be saved */ + data++; + /* decrement the read bytes counter */ + len--; + timeout = 0; + } + if(timeout > I2C_TIME_OUT) { + timeout = 0; + state = I2C_START; + // read_cycle = 0; + printf("i2c master sends data timeout in READ!\n"); + } + } + timeout = 0; + state = I2C_STOP; + // } + break; + + case I2C_STOP: + /* i2c master sends STOP signal successfully */ + while((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + timeout = 0; + state = I2C_END; + i2c_timeout_flag = I2C_OK; + } else { + timeout = 0; + state = I2C_START; + // read_cycle = 0; + printf("i2c master sends stop signal timeout in READ!\n"); + } + break; + + default: + state = I2C_START; + // read_cycle = 0; + i2c_timeout_flag = I2C_OK; + timeout = 0; + printf("i2c master sends start signal in READ.\n"); + break; + } + } + return IIC_SUCCESS; +} + +/*! + \brief TWI3(none) read data from the IIC Slave Device with no regisiter address + \param[in] Address: the IIC Slave Device's IIC Device Address + \param[in] len: number of bytes to reads from the IIC Slave Device + \param[in] data: pointer to the buffer that receives the data read from the IIC Slave Device + \param[out] data: pointer to the buffer that receives the data read from the IIC Slave Device + \retval IIC_SUCCESS + \note No TWI3(IIC3) - No operation - Error log. +*/ +uint8_t i2c_master_read_register3_raw(unsigned char Address, unsigned short len, unsigned char *data){ + __NOP(); + #ifdef DEBUG_VERBOES + printf("\n[DebugVerboes]i2c_master_read_register3_raw @ i2c.c, no TWI3 \n"); + #endif + return IIC_SUCCESS; +} + +/*! + \brief TWI1(IIC0) write data to the IIC Slave Device + \param[in] Address: the IIC Slave Device's IIC Device Address + \param[in] RegisterAddr: the IIC Slave Device's internal address to start writing to + \param[in] RegisterLen: number of bytes to write to the IIC Slave Device + \param[in] RegisterValue: pointer to the buffer that transfer the data write to the IIC Slave Device + \param[out] RegisterValue: pointer to the buffer that transfer the data write to the IIC Slave Device + \retval IIC_SUCCESS +*/ + +uint8_t i2c_master_write_register1(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue) +{ + uint8_t state = I2C_START; + uint16_t timeout = 0; + uint8_t i2c_timeout_flag = 0; + unsigned char IIC_SLAVE_ADDR = (Address << 1); + + /* enable acknowledge */ + i2c_ack_config(I2C0, I2C_ACK_ENABLE); + while(!(i2c_timeout_flag)) { + switch(state) { + case I2C_START: + /* i2c master sends start signal only when the bus is idle */ + while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + i2c_start_on_bus(I2C0); + timeout = 0; + state = I2C_SEND_ADDR; + } else { + i2c_bus_reset(); + timeout = 0; + state = I2C_START; + printf("i2c bus is busy in WRITE!\n"); + } + break; + + case I2C_SEND_ADDR: + /* i2c master sends START signal successfully */ + while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + i2c_master_addressing(I2C0, IIC_SLAVE_ADDR, I2C_TRANSMITTER); + timeout = 0; + state = I2C_CLEAR_ADDRESS_FLAG; + } else { + timeout = 0; + state = I2C_START; + printf("i2c master sends start signal timeout in WRITE!\n"); + } + break; + + case I2C_CLEAR_ADDRESS_FLAG: + /* address flag set means i2c slave sends ACK */ + while((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); + timeout = 0; + state = I2C_TRANSMIT_DATA; + } else { + timeout = 0; + state = I2C_START; + printf("i2c master clears address flag timeout in WRITE!\n"); + } + break; + + case I2C_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) { + /* send the EEPROM's internal address to write to : only one byte address */ + i2c_data_transmit(I2C0, RegisterAddr); + timeout = 0; + } else { + timeout = 0; + state = I2C_START; + printf("i2c master sends i2c_master_write_register1 internal address timeout in WRITE!\n"); + } + /* wait until BTC bit is set */ + while((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + timeout = 0; + } else { + timeout = 0; + state = I2C_START; + printf("i2c master sends data timeout in WRITE!\n"); + } + while(RegisterLen--) { + i2c_data_transmit(I2C0, *RegisterValue); + /* point to the next byte to be written */ + RegisterValue++; + /* wait until BTC bit is set */ + while((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + timeout = 0; + } else { + timeout = 0; + state = I2C_START; + printf("i2c master sends data timeout in WRITE!\n"); + } + } + timeout = 0; + state = I2C_STOP; + break; + + case I2C_STOP: + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(I2C0); + /* i2c master sends STOP signal successfully */ + while((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + timeout = 0; + state = I2C_END; + i2c_timeout_flag = I2C_OK; + } else { + timeout = 0; + state = I2C_START; + printf("i2c master sends stop signal timeout in WRITE!\n"); + } + break; + + default: + state = I2C_START; + i2c_timeout_flag = I2C_OK; + timeout = 0; + printf("i2c master sends start signal in WRITE.\n"); + break; + } + } + return IIC_SUCCESS; +} + +/*! + \brief TWI3(none) write data to the IIC Slave Device + \param[in] Address: the IIC Slave Device's IIC Device Address + \param[in] RegisterAddr: the IIC Slave Device's internal address to start writing to + \param[in] RegisterLen: number of bytes to write to the IIC Slave Device + \param[in] RegisterValue: pointer to the buffer that transfer the data write to the IIC Slave Device + \param[out] RegisterValue: pointer to the buffer that transfer the data write to the IIC Slave Device + \retval IIC_SUCCESS + \note No TWI3(IIC3) - No operation - Error log. +*/ +uint8_t i2c_master_write_register3(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue){ + __NOP(); + #ifdef DEBUG_VERBOES + printf("\n[DebugVerboes]i2c_master_write_register3 @ i2c.c, no TWI3 \n"); + #endif + return IIC_SUCCESS; +} + +/*! + \brief TWI1(IIC0) write data to the IIC Slave Device with no regisiter address + \param[in] Address: the IIC Slave Device's IIC Device Address + \param[in] len: number of bytes to write to the IIC Slave Device + \param[in] data: pointer to the buffer that transfer the data write to the IIC Slave Device + \param[out] data: pointer to the buffer that transfer the data write to the IIC Slave Device + \retval IIC_SUCCESS +*/ +uint8_t i2c_master_write_register1_raw(unsigned char Address, unsigned short len, unsigned char *data){ + uint8_t state = I2C_START; + uint16_t timeout = 0; + uint8_t i2c_timeout_flag = 0; + unsigned char IIC_SLAVE_ADDR = (Address << 1); + + /* enable acknowledge */ + i2c_ack_config(I2C0, I2C_ACK_ENABLE); + while(!(i2c_timeout_flag)) { + switch(state) { + case I2C_START: + /* i2c master sends start signal only when the bus is idle */ + while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + i2c_start_on_bus(I2C0); + timeout = 0; + state = I2C_SEND_ADDR; + } else { + i2c_bus_reset(); + timeout = 0; + state = I2C_START; + printf("i2c bus is busy in WRITE!\n"); + } + break; + + case I2C_SEND_ADDR: + /* i2c master sends START signal successfully */ + while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + i2c_master_addressing(I2C0, IIC_SLAVE_ADDR, I2C_TRANSMITTER); + timeout = 0; + state = I2C_CLEAR_ADDRESS_FLAG; + } else { + timeout = 0; + state = I2C_START; + printf("i2c master sends start signal timeout in WRITE!\n"); + } + break; + + case I2C_CLEAR_ADDRESS_FLAG: + /* address flag set means i2c slave sends ACK */ + while((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); + timeout = 0; + state = I2C_TRANSMIT_DATA; + } else { + timeout = 0; + state = I2C_START; + printf("i2c master clears address flag timeout in WRITE!\n"); + } + break; + + case I2C_TRANSMIT_DATA: + /* wait until the transmit data buffer is empty */ + while((!i2c_flag_get(I2C0, I2C_FLAG_TBE)) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + while(len--) { + i2c_data_transmit(I2C0, *data); + /* point to the next byte to be written */ + data++; + /* wait until BTC bit is set */ + while((!i2c_flag_get(I2C0, I2C_FLAG_BTC)) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + timeout = 0; + } else { + timeout = 0; + state = I2C_START; + printf("i2c master sends data timeout in WRITE!\n"); + } + } + timeout = 0; + state = I2C_STOP; + break; + + case I2C_STOP: + /* send a stop condition to I2C bus */ + i2c_stop_on_bus(I2C0); + /* i2c master sends STOP signal successfully */ + while((I2C_CTL0(I2C0) & I2C_CTL0_STOP) && (timeout < I2C_TIME_OUT)) { + timeout++; + } + if(timeout < I2C_TIME_OUT) { + timeout = 0; + state = I2C_END; + i2c_timeout_flag = I2C_OK; + } else { + timeout = 0; + state = I2C_START; + printf("i2c master sends stop signal timeout in WRITE!\n"); + } + break; + + default: + state = I2C_START; + i2c_timeout_flag = I2C_OK; + timeout = 0; + printf("i2c master sends start signal in WRITE.\n"); + break; + } + } + return IIC_SUCCESS; +} + +/*! + \brief TWI3(none) write data to the IIC Slave Device with no regisiter address + \param[in] Address: the IIC Slave Device's IIC Device Address + \param[in] len: number of bytes to write to the IIC Slave Device + \param[in] data: pointer to the buffer that transfer the data write to the IIC Slave Device + \param[out] data: pointer to the buffer that transfer the data write to the IIC Slave Device + \retval IIC_SUCCESS + \note No TWI3(IIC3) - No operation - Error log. +*/ +uint8_t i2c_master_write_register3_raw(unsigned char Address, unsigned short len, unsigned char *data){ + __NOP(); + #ifdef DEBUG_VERBOES + printf("\n[DebugVerboes]i2c_master_write_register3_raw @ i2c.c, no TWI3 \n"); + #endif + return IIC_SUCCESS; +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 1ff7b84..2c95257 100644 --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,7 @@ #include "gd32e23x_libopt.h" #include "ultrasonic_driver.h" +#include "mlx90614.h" extern uint32_t capture_value; uint16_t distance_uint16; @@ -27,7 +28,7 @@ int main(void) systick_config(); /* configure ultrasonic board hardware */ ultrasonic_transmit_config(); - ultrasonic_recevice_config(); + ultrasonic_receive_config(); /* ---------- debug start ---------- */ diff --git a/src/mlx90614.c b/src/mlx90614.c index b260e5a..8d99213 100644 --- a/src/mlx90614.c +++ b/src/mlx90614.c @@ -3,3 +3,9 @@ // #include "mlx90614.h" +#include "gd32e23x.h" +#include "systick.h" + +int read_ir_mlx90614(void) { + +} \ No newline at end of file diff --git a/src/ultrasonic_driver.c b/src/ultrasonic_driver.c index ded0228..a6dcaa3 100644 --- a/src/ultrasonic_driver.c +++ b/src/ultrasonic_driver.c @@ -137,7 +137,7 @@ void ultrasonic_transmit_delay(const uint16_t micro_second) { nvic_irq_enable(TIMER15_IRQn, 1U); } -void recevice_exti_config(void) { +void receive_exti_config(void) { rcu_periph_clock_enable(US_FB_GPIO_RCU); rcu_periph_clock_enable(US_FB_EXTI_RCU); @@ -174,9 +174,9 @@ void ultrasonic_echo_timer_config(void) { timer_input_capture_config(US_ECHO_TIMER, US_ECHO_CH, &timer_icinitpara); } -void ultrasonic_recevice_config(void) { +void ultrasonic_receive_config(void) { ultrasonic_transmit_delay(TIME_CORRECTION_US); - recevice_exti_config(); + receive_exti_config(); ultrasonic_echo_timer_config(); }