#include "gd32f30x.h" #include "bsp_iic.h" /********************************************************************************** Private define ***********************************************************************************/ #define _IIC_SDA_HIGH() gpio_bit_set(IIC_IO->SDA_group,IIC_IO->SDA_pin) #define _IIC_SDA_LOW() gpio_bit_reset(IIC_IO->SDA_group,IIC_IO->SDA_pin) #define _IIC_SCL_HIGH() gpio_bit_set(IIC_IO->SCL_group,IIC_IO->SCL_pin) #define _IIC_SCL_LOW() gpio_bit_reset(IIC_IO->SCL_group,IIC_IO->SCL_pin) /********************************************************************************** Private functions ***********************************************************************************/ static void IICStart(IIC_IO_Def *IIC_IO); static void IICStop(IIC_IO_Def *IIC_IO); static unsigned char IICGetACK(IIC_IO_Def *IIC_IO); static void IICSetACK(IIC_IO_Def *IIC_IO); static void IICSetNACK(IIC_IO_Def *IIC_IO); static void IICSendOneByte(IIC_IO_Def *IIC_IO, unsigned char data); static void IICGetOneByte(IIC_IO_Def *IIC_IO, unsigned char *out); extern void delay_us(unsigned int i); static void IICStart(IIC_IO_Def *IIC_IO) { _IIC_SDA_HIGH(); delay_us(2); _IIC_SCL_HIGH(); delay_us(2); _IIC_SDA_LOW(); delay_us(2); } static void IICStop(IIC_IO_Def *IIC_IO) { _IIC_SCL_LOW(); delay_us(1); _IIC_SDA_LOW(); delay_us(1); _IIC_SCL_HIGH(); delay_us(2); _IIC_SDA_HIGH(); delay_us(1); } static unsigned char IICGetACK(IIC_IO_Def *IIC_IO) { unsigned char return_value = 0; _IIC_SCL_LOW(); _IIC_SDA_HIGH(); /* Release SDA */ delay_us(1); _IIC_SCL_HIGH(); delay_us(3); if(gpio_input_bit_get(IIC_IO->SDA_group,IIC_IO->SDA_pin) == SET) { return_value = !0; } _IIC_SCL_LOW(); delay_us(1); return return_value; } static void IICSetACK(IIC_IO_Def *IIC_IO) { _IIC_SCL_LOW(); _IIC_SDA_LOW(); delay_us(1); _IIC_SCL_HIGH(); delay_us(5); _IIC_SCL_LOW(); delay_us(1); } static void IICSetNACK(IIC_IO_Def *IIC_IO) { _IIC_SCL_LOW(); _IIC_SDA_HIGH(); delay_us(1); _IIC_SCL_HIGH(); delay_us(5); _IIC_SCL_LOW(); delay_us(1); } static void IICSendOneByte(IIC_IO_Def *IIC_IO, unsigned char data) { signed char count; const unsigned char mask = 0x01; for (count = 7; count >= 0; count--) { _IIC_SCL_LOW(); delay_us(1); if((data >> count & mask) != 0) { _IIC_SDA_HIGH(); } else { _IIC_SDA_LOW(); } delay_us(1); _IIC_SCL_HIGH(); delay_us(5); _IIC_SCL_LOW(); delay_us(1); } } static void IICGetOneByte(IIC_IO_Def *IIC_IO, unsigned char *out) { signed char count; _IIC_SCL_LOW(); delay_us(1); _IIC_SDA_HIGH(); *out = 0; for (count = 7; count >= 0; count--) { _IIC_SCL_LOW(); delay_us(1); _IIC_SCL_HIGH(); delay_us(3); //*out &= 0xFE; if(gpio_input_bit_get(IIC_IO->SDA_group,IIC_IO->SDA_pin) == SET) { *out |= (0x01 << count); } //*out = *out << 1; _IIC_SCL_LOW(); delay_us(2); } } /********************************************************************************** Interface functions ***********************************************************************************/ void IICInit(IIC_IO_Def *IIC_IO) { rcu_periph_clock_enable((rcu_periph_enum)IIC_IO->SCL_RCC); gpio_init(IIC_IO->SCL_group, GPIO_MODE_OUT_OD, GPIO_OSPEED_10MHZ, IIC_IO->SCL_pin); gpio_init(IIC_IO->SDA_group, GPIO_MODE_OUT_OD, GPIO_OSPEED_10MHZ, IIC_IO->SDA_pin); gpio_bit_set(IIC_IO->SDA_group, IIC_IO->SDA_pin); gpio_bit_set(IIC_IO->SCL_group, IIC_IO->SCL_pin); } int IICRead(IIC_IO_Def *IIC_IO, unsigned char slave_addr, unsigned char command_code, unsigned short *out) { int is_OK = 0; /* return value */ unsigned char out_temp; *out = 0; slave_addr &= 0xFE; IICStart(IIC_IO); /* S */ IICSendOneByte(IIC_IO, slave_addr); /* Slave address + Wr */ if(IICGetACK(IIC_IO) != 0) /* Ack by slave */ { is_OK += -1; } IICSendOneByte(IIC_IO, command_code); /* Command code */ if(IICGetACK(IIC_IO) != 0) /* Ack by slave */ { is_OK += -1; } slave_addr |= 0x01; IICStart(IIC_IO); /* Sr */ IICSendOneByte(IIC_IO, slave_addr); /* Slave address + Rd */ if(IICGetACK(IIC_IO) != 0) /* Ack by slave */ { is_OK += -1; } IICGetOneByte(IIC_IO, &out_temp); /* Out data byte low */ *out |= out_temp; IICSetACK(IIC_IO); /* Ack by master */ IICGetOneByte(IIC_IO, &out_temp); /* Out data byte high */ *out |= ((out_temp << 8) & 0xFF00); IICSetNACK(IIC_IO); /* NAck by master */ IICStop(IIC_IO); return is_OK; } int IICWrite(IIC_IO_Def *IIC_IO, unsigned char slave_addr, unsigned char command_code, unsigned short data) { int is_OK = 0; slave_addr &= 0xFE; IICStart(IIC_IO); /* S */ IICSendOneByte(IIC_IO, slave_addr); /* Slave address + Wr */ if(IICGetACK(IIC_IO) != 0) /* Ack by slave */ { is_OK += -1; } IICSendOneByte(IIC_IO, command_code); /* Command code */ if(IICGetACK(IIC_IO) != 0) /* Ack by slave */ { is_OK += -1; } IICSendOneByte(IIC_IO, data&0xFF); /* Send data low */ if(IICGetACK(IIC_IO) != 0) /* Ack by slave */ { is_OK += -1; } IICSendOneByte(IIC_IO, (data>>8)&0xFF); /* Send data high */ if(IICGetACK(IIC_IO) != 0) /* Ack by slave */ { is_OK += -1; } IICStop(IIC_IO); return is_OK; } int IICReadByte(IIC_IO_Def *IIC_IO, unsigned char slave_addr, unsigned char command_code, unsigned char *out) { int is_OK = 0; /* return value */ unsigned char out_temp; *out = 0; slave_addr &= 0xFE; IICStart(IIC_IO); /* S */ IICSendOneByte(IIC_IO, slave_addr); /* Slave address + Wr */ if(IICGetACK(IIC_IO) != 0) /* Ack by slave */ { is_OK += -1; } IICSendOneByte(IIC_IO, command_code); /* Command code */ if(IICGetACK(IIC_IO) != 0) /* Ack by slave */ { is_OK += -1; } slave_addr |= 0x01; IICStart(IIC_IO); /* Sr */ IICSendOneByte(IIC_IO, slave_addr); /* Slave address + Rd */ if(IICGetACK(IIC_IO) != 0) /* Ack by slave */ { is_OK += -1; } IICGetOneByte(IIC_IO, &out_temp); /* Out data byte low */ *out = out_temp; IICSetNACK(IIC_IO); /* NAck by master */ IICStop(IIC_IO); return is_OK; } int IICWriteByte(IIC_IO_Def *IIC_IO, unsigned char slave_addr, unsigned char command_code, unsigned char data) { int is_OK = 0; slave_addr &= 0xFE; IICStart(IIC_IO); /* S */ IICSendOneByte(IIC_IO, slave_addr); /* Slave address + Wr */ if(IICGetACK(IIC_IO) != 0) /* Ack by slave */ { is_OK += -1; } IICSendOneByte(IIC_IO, command_code); /* Command code */ if(IICGetACK(IIC_IO) != 0) /* Ack by slave */ { is_OK += -1; } IICSendOneByte(IIC_IO, data); /* Send data */ if(IICGetACK(IIC_IO) != 0) /* Ack by slave */ { is_OK += -1; } IICStop(IIC_IO); return is_OK; }