diff --git a/inc/gd32e23x_hw_i2c.h b/inc/gd32e23x_hw_i2c.h index e44d36d..5e41a66 100644 --- a/inc/gd32e23x_hw_i2c.h +++ b/inc/gd32e23x_hw_i2c.h @@ -1,7 +1,10 @@ #ifndef GD32E23X_HW_I2C_H #define GD32E23X_HW_I2C_H +// #define I2C1_ENABLE + #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 @@ -12,6 +15,24 @@ #define I2C0_DCTY I2C_DTCY_2 #define I2C0_ADDR7 0xA0 +#ifdef I2C1_ENABLE +#define I2C1_BUS_RCU RCU_I2C1 + +#define I2C1_GPIO_RCU RCU_GPIOA +#define I2C1_GPIO_PORT GPIOA +#define I2C1_GPIO_SDA_PIN GPIO_PIN_1 +#define I2C1_GPIO_SCL_PIN GPIO_PIN_0 +#define I2C1_GPIO_AF GPIO_AF_4 + +#define I2C1_SPEED 400000U +#define I2C1_DCTY I2C_DTCY_2 +#define I2C1_ADDR7 0xA1 +#endif + + + + + @@ -29,6 +50,19 @@ typedef enum { I2C_STOP } i2c_process_enum; +typedef struct +{ + uint32_t i2c_gpio_rcu; + uint32_t i2c_gpio_port; + uint32_t i2c_gpio_sda_pin; + uint32_t i2c_gpio_scl_pin; + uint32_t i2c_gpio_af; + uint32_t i2c_speed; + uint32_t i2c_dcty; + uint32_t i2c_addr7; +}i2c_parameter_struct; + + /** @@ -72,4 +106,11 @@ uint8_t i2c_master_write_register3_raw(unsigned char Address, unsigned short len void i2c0_master_init(void); +int read_ir_mlx90614(void); + +void i2c_struct_para_init(i2c_parameter_struct* initpara); +void i2c_init(uint32_t i2c_periph, i2c_parameter_struct* initpara); +void i2c0_config(void); + + #endif /* GD32E23X_HW_I2C_H */ \ No newline at end of file diff --git a/src/gd32e23x_hw_i2c.c b/src/gd32e23x_hw_i2c.c index f05594c..616ee9f 100644 --- a/src/gd32e23x_hw_i2c.c +++ b/src/gd32e23x_hw_i2c.c @@ -1,27 +1,84 @@ #include #include #include "gd32e23x.h" +#include "systick.h" #include "gd32e23x_hw_i2c.h" #include "gd32e23x.h" +void i2c_struct_para_init(i2c_parameter_struct* initpara) +{ + initpara->i2c_gpio_rcu = RCU_GPIOF; + initpara->i2c_gpio_port = GPIOF; + initpara->i2c_gpio_scl_pin = GPIO_PIN_1; + initpara->i2c_gpio_sda_pin = GPIO_PIN_0; + initpara->i2c_speed = 400000U; + initpara->i2c_dcty = I2C_DTCY_2; + initpara->i2c_addr7 = 0xA0; +} + + + +void i2c_init(uint32_t i2c_periph, i2c_parameter_struct* initpara) +{ + switch (i2c_periph){ + case I2C0: + rcu_periph_clock_enable(RCU_I2C0); + rcu_periph_clock_enable(initpara->i2c_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); + break; + case I2C1: + + break; + default: + break; + } +} + /*! \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); +void i2c_init(uint32_t i2c_periph) +{ + switch (i2c_periph) { + case I2C0: + 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); + 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); + 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); + break; +#ifdef I2C1_ENABLE + case I2C1: + rcu_periph_clock_enable(RCU_I2C1); + rcu_periph_clock_enable(I2C1_GPIO_RCU); + + gpio_af_set(I2C1_GPIO_PORT, I2C1_GPIO_AF, I2C1_GPIO_SDA_PIN | I2C1_GPIO_SCL_PIN); + gpio_output_options_set(I2C1_GPIO_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C1_GPIO_SDA_PIN | I2C1_GPIO_SCL_PIN); + + i2c_clock_config(I2C1, I2C1_SPEED, I2C1_DCTY); + i2c_mode_addr_config(I2C1, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, I2C1_ADDR7); + i2c_enable(I2C1); + i2c_ack_config(I2C1, I2C_ACK_ENABLE); + break; +#endif + default: + break; + } } void i2c_bus_reset(void) @@ -30,35 +87,20 @@ void i2c_bus_reset(void) /* 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(); + delay_5_nop(); /* stop signal */ GPIO_BOP(I2C0_GPIO_PORT) |= I2C0_GPIO_SCL_PIN; - __NOP();__NOP();__NOP();__NOP();__NOP(); + delay_5_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(); + i2c_init(I2C0); } /*! - \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 + \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 @@ -72,7 +114,7 @@ uint8_t i2c_master_read_register1(unsigned char Address, unsigned char RegisterA uint8_t read_cycle = 0; uint16_t timeout = 0; uint8_t i2c_timeout_flag = 0; - unsigned char IIC_SLAVE_ADDR = (Address << 1); + uint8_t IIC_SLAVE_ADDR = (Address << 1); i2c_ack_config(I2C0, I2C_ACK_ENABLE); while (!(i2c_timeout_flag)) @@ -80,14 +122,14 @@ uint8_t i2c_master_read_register1(unsigned char Address, unsigned char RegisterA switch (state) { case I2C_START: - if(RESET == read_cycle) + 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) + if(timeout < I2C_TIME_OUT) { /* whether to send ACK or not for the next byte */ if(2 == RegisterLen) { @@ -108,13 +150,13 @@ uint8_t i2c_master_read_register1(unsigned char Address, unsigned char RegisterA case I2C_SEND_ADDR: /* i2c master sends START signal successfully */ - while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) + while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) { timeout++; } - if(timeout < I2C_TIME_OUT) + if(timeout < I2C_TIME_OUT) { - if(RESET == read_cycle) + if(RESET == read_cycle) { i2c_master_addressing(I2C0, IIC_SLAVE_ADDR, I2C_TRANSMITTER); state = I2C_CLEAR_ADDRESS_FLAG; @@ -137,11 +179,11 @@ uint8_t i2c_master_read_register1(unsigned char Address, unsigned char RegisterA 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)) + while((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) { timeout++; } - if(timeout < I2C_TIME_OUT) + if(timeout < I2C_TIME_OUT) { i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); if((SET == read_cycle) && (1 == RegisterLen)) { @@ -255,7 +297,7 @@ uint8_t i2c_master_read_register1(unsigned char Address, unsigned char RegisterA } /*! - \brief TWI3(none) read data from the IIC Slave Device + \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 @@ -273,7 +315,7 @@ uint8_t i2c_master_read_register3(unsigned char Address, unsigned char RegisterA } /*! - \brief TWI1(IIC0) read data from the IIC Slave Device + \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 @@ -298,7 +340,7 @@ uint8_t i2c_master_read_register1_raw(unsigned char Address, unsigned short len, { timeout ++; } - if(timeout < I2C_TIME_OUT) + if(timeout < I2C_TIME_OUT) { /* whether to send ACK or not for the next byte */ if(2 == len) { @@ -318,11 +360,11 @@ uint8_t i2c_master_read_register1_raw(unsigned char Address, unsigned short len, case I2C_SEND_ADDR: /* i2c master sends START signal successfully */ - while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) + while((!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)) && (timeout < I2C_TIME_OUT)) { timeout++; } - if(timeout < I2C_TIME_OUT) + if(timeout < I2C_TIME_OUT) { i2c_master_addressing(I2C0, IIC_SLAVE_ADDR, I2C_RECEIVER); if(len < 3) { @@ -341,11 +383,11 @@ uint8_t i2c_master_read_register1_raw(unsigned char Address, unsigned short len, 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)) + while((!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) && (timeout < I2C_TIME_OUT)) { timeout++; } - if(timeout < I2C_TIME_OUT) + if(timeout < I2C_TIME_OUT) { i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); timeout = 0; @@ -494,7 +536,7 @@ uint8_t i2c_master_write_register1(unsigned char Address, unsigned char Register 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)) { @@ -585,23 +627,6 @@ uint8_t i2c_master_write_register1(unsigned char Address, unsigned char Register 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 @@ -653,7 +678,7 @@ uint8_t i2c_master_write_register1_raw(unsigned char Address, unsigned short len 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)) { @@ -724,19 +749,116 @@ uint8_t i2c_master_write_register1_raw(unsigned char Address, unsigned short len 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; + +int read_ir_mlx90614(void) +{ + uint8_t Data[5]; + int inttemp_ir=0; + uint32_t TIMEOUT=0; + while(TIMEOUT<10000&&i2c_flag_get(I2C0,I2C_FLAG_I2CBSY)) + TIMEOUT++; + if(TIMEOUT>=10000) + { + //printf("ERROR0\r\n"); + return -410; + } + TIMEOUT=0; + I2C_GenerateSTART(I2C0,ENABLE); + while(TIMEOUT<10000&&!I2C_CheckEvent(I2C0,I2C_EVENT_MASTER_MODE_SELECT)) + TIMEOUT++; + if(TIMEOUT>=10000) + { + //printf("ERROR1\r\n"); + return -410; + } +// I2C_AcknowledgeConfig(I2C0,DISABLE); + TIMEOUT=0; + I2C_Send7bitAddress(I2C0,0XB4,I2C_Direction_Transmitter); + while(TIMEOUT<10000&&!I2C_CheckEvent(I2C0,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) + TIMEOUT++; + if(TIMEOUT>=10000) + { + printf("ERROR2\r\n"); + return -410; + + } + I2C_SendData(I2C0,0x07); + + TIMEOUT=0; + I2C_GenerateSTART(I2C0,ENABLE); + while(TIMEOUT<10000&&!I2C_CheckEvent(I2C0,I2C_EVENT_MASTER_MODE_SELECT)) + TIMEOUT++; + if(TIMEOUT>=10000) + { + //printf("ERROR3\r\n"); + return -410; + } + TIMEOUT=0; + I2C_Send7bitAddress(I2C0,0XB4,I2C_Direction_Receiver); + while(TIMEOUT<10000&&!I2C_CheckEvent(I2C0,I2C_EVENT_MASTER_BYTE_RECEIVED )) + TIMEOUT++; + if(TIMEOUT>=10000) + { + //printf("ERROR4\r\n"); + return -410; + } + //I2C_AcknowledgeConfig(I2C0,DISABLE); + TIMEOUT=0; + Data[0]=I2C_ReceiveData(I2C0); + while(TIMEOUT<10000&&!I2C_CheckEvent(I2C0,I2C_EVENT_MASTER_BYTE_RECEIVED)) + TIMEOUT++; + if(TIMEOUT>=10000) + { + //printf("ERROR5\r\n"); + return -410; + } + + TIMEOUT=0; + Data[1]=I2C_ReceiveData(I2C0); + while(TIMEOUT<10000&&!I2C_CheckEvent(I2C0,I2C_EVENT_MASTER_BYTE_RECEIVED)) + TIMEOUT++; + if(TIMEOUT>=10000) + { + //printf("ERROR6\r\n"); + return -410; + } + + TIMEOUT=0; + Data[2]=I2C_ReceiveData(I2C0); + while(TIMEOUT<10000&&!I2C_CheckEvent(I2C0,I2C_EVENT_MASTER_BYTE_RECEIVED)) + TIMEOUT++; + if(TIMEOUT>=10000) + { + //printf("ERROR7\r\n"); + return -410; + } + + + + + + I2C_AcknowledgeConfig(I2C0,DISABLE); + Data[3]=I2C_ReceiveData(I2C0); + while(TIMEOUT<10000&&!I2C_CheckEvent(I2C0,I2C_EVENT_MASTER_BYTE_RECEIVED)) + TIMEOUT++; + if(TIMEOUT>=10000) + { + //printf("ERROR11\r\n"); + return -410; + } + + + I2C_GenerateSTOP(I2C0,ENABLE); + I2C_AcknowledgeConfig(I2C0,ENABLE); + //printf("data:%x,%x,%x\r\n",Data[0],Data[1],Data[2]); + inttemp_ir=(int)((Data[0]+Data[1]*255)*0.2-2731.5); +// printf("temp:%d\r\n",inttemp_ir); + + + if(inttemp_ir<-400) + inttemp_ir=-400; + if(inttemp_ir>850) + inttemp_ir=850; +// + return inttemp_ir; } \ No newline at end of file