Browse Source

add i2c && EEPROM driver

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui 5 years ago
parent
commit
44d21d8943

+ 149 - 0
Application/bsp/AT24CXX.c

@@ -0,0 +1,149 @@
+#include "i2c.h"
+#include "AT24CXX.h"
+
+void AT24CXX_Init(void)
+{
+	gd32_i2c_init(0, 100*1000);
+}
+
+uint8_t AT24CXX_ReadOneByte(uint16_t ReadAddr)
+{
+	uint8_t value = 0;
+	uint8_t device_addr = 0xA0 | ((ReadAddr >>8) << 1);
+	int try_count = 100;
+	while(0 >= gd32_i2c_read_byte(0, device_addr, (uint8_t)(ReadAddr&0xFF), (uint8_t *)&value)){
+		if (try_count-- <= 0){
+			break;
+		}
+	};
+	return value;
+}
+
+void AT24CXX_WriteOneByte(uint16_t WriteAddr,uint8_t DataToWrite)
+{	
+	uint8_t device_addr = 0xA0 | ((WriteAddr >>8) << 1);
+	int try_count = 100;
+	while(0 >= gd32_i2c_write_byte(0, device_addr, (uint8_t)(WriteAddr & 0xFF), (uint8_t)DataToWrite)){
+		if (try_count-- <= 0){
+			break;
+		}
+
+	};
+	
+}
+
+void AT24CXX_WriteLenByte(uint16_t WriteAddr,uint32_t DataToWrite,uint8_t Len)
+{  	
+	uint8_t t;
+	for(t=0;t<Len;t++)
+	{
+		AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);
+	}												    
+}
+
+
+uint32_t AT24CXX_ReadLenByte(uint16_t ReadAddr,uint8_t Len)
+{  	
+	uint8_t t;
+	uint32_t temp=0;
+	for(t=0;t<Len;t++)
+	{
+		temp<<=8;
+		temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1); 	 				   
+	}
+	return temp;												    
+}
+
+uint8_t AT24CXX_Check(void)
+{
+	uint8_t temp;
+	temp=AT24CXX_ReadOneByte(255); 
+	if(temp==0X55)return 0;		   
+	else
+	{
+		AT24CXX_WriteOneByte(255,0X55);
+		temp=AT24CXX_ReadOneByte(255);	  
+		if(temp==0X55)return 0;
+	}
+	return 1;											  
+}
+
+void AT24CXX_Read(uint16_t ReadAddr,uint8_t *pBuffer,uint16_t NumToRead)
+{
+	uint8_t device_addr = 0xA0 | ((ReadAddr >>8) << 1);
+	int try_count = 100;
+	while(0 >= gd32_i2c_read_nbytes(0, device_addr, (uint8_t)(ReadAddr&0xFF), pBuffer, NumToRead)){
+		if (try_count-- <= 0){
+			break;
+		}
+	};
+
+}  
+
+/* use page write to improve write time */
+static int AT24CXX_Write_Pages(uint16_t WriteAddr,uint8_t *pBuffer,uint16_t NumToWrite){
+	uint8_t device_addr = 0xA0 | ((WriteAddr >>8) << 1);
+	int try_count = 100;
+	while(0 >= gd32_i2c_write_nbytes(0, device_addr, (uint8_t)(WriteAddr&0xFF), pBuffer, NumToWrite)){
+		if (try_count-- <= 0){
+			return -1;
+		}
+
+	};
+	return 0;
+}
+void AT24CXX_Write(uint16_t WriteAddr,uint8_t *pBuffer,uint16_t NumToWrite){
+	uint16_t remain_len = NumToWrite;
+	while(remain_len > 0){
+		uint16_t w_len = (remain_len > PAGE_SIZE)?PAGE_SIZE:remain_len;
+		if (AT24CXX_Write_Pages(WriteAddr, pBuffer, w_len) < 0){
+			return;
+		}
+		WriteAddr += w_len;
+		pBuffer += w_len;
+		remain_len -= w_len;
+	}
+}
+
+#if 0
+
+#define ADDR_START 	(2<<7)
+
+static U8 buffr[128];
+static int index = 0;
+static int _AT24CXX_test(void)
+{
+	int i=0;
+	char wdata = 0x5A;
+	if (index % 2 == 1){
+		wdata = 0xA5;
+	}
+	for(i=0;i<128;i++)
+	{
+		buffr[i] = wdata;
+	}
+	
+	AT24CXX_Write(ADDR_START,buffr,128);
+	
+	memset(buffr,0,128);
+	
+	AT24CXX_Read(ADDR_START,buffr,128);
+	
+	for(i=0;i<128;i++)
+	{
+		if (buffr[i] != wdata){
+			return -1;
+		}
+	}
+	return 0;
+}
+
+
+void AT24CXX_test(void){
+	while(_AT24CXX_test() == 0){
+		index++;
+	};
+}
+
+#endif
+

+ 44 - 0
Application/bsp/AT24CXX.h

@@ -0,0 +1,44 @@
+
+
+#ifndef __24CXX_H
+#define __24CXX_H
+
+
+#define AT24C01		127
+#define AT24C02		255
+#define AT24C04		511
+#define AT24C08		1023
+#define AT24C16		2047
+#define AT24C32		4095
+#define AT24C64	    8191
+#define AT24C128	16383
+#define AT24C256	32767  
+//Mini STM32开发板使用的是24c02,所以定义EE_TYPE为AT24C02
+#define EE_TYPE AT24C08
+#define PAGE_SIZE 16
+uint8_t AT24CXX_ReadOneByte(uint16_t ReadAddr);							//指定地址读取一个字节
+void AT24CXX_WriteOneByte(uint16_t WriteAddr,uint8_t DataToWrite);		//指定地址写入一个字节
+void AT24CXX_WriteLenByte(uint16_t WriteAddr,uint32_t DataToWrite,uint8_t Len);//指定地址开始写入指定长度的数据
+uint32_t AT24CXX_ReadLenByte(uint16_t ReadAddr,uint8_t Len);					//指定地址开始读取指定长度数据
+void AT24CXX_Write(uint16_t WriteAddr,uint8_t *pBuffer,uint16_t NumToWrite);	//从指定地址开始写入指定长度的数据
+void AT24CXX_Read(uint16_t ReadAddr,uint8_t *pBuffer,uint16_t NumToRead);   	//从指定地址开始读出指定长度的数据
+
+uint8_t AT24CXX_Check(void);  //检查器件
+void AT24CXX_Init(void); //初始化IIC
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 3 - 0
Application/bsp/gpio.h

@@ -29,6 +29,9 @@ static __inline__ void gpio_mode_output(uint32_t gpio_periph, uint32_t pull_up_d
 	gpio_output_options_set(gpio_periph, otype, speed, pin);
 	gpio_output_options_set(gpio_periph, otype, speed, pin);
 }
 }
 
 
+static __inline__ void gpio_mode_af(uint32_t gpio_periph, uint32_t pull_up_down, uint32_t pin){
+	gpio_mode_set(gpio_periph, GPIO_MODE_AF, pull_up_down, pin);
+}
 
 
 #endif /* _GPIO_H__ */
 #endif /* _GPIO_H__ */
 
 

+ 219 - 0
Application/bsp/i2c.c

@@ -0,0 +1,219 @@
+#include "gd32f1x0.h"
+#include "gd32f1x0_i2c.h"
+#include "gpio.h"
+#include "i2c.h"
+
+static int _gd32_i2c_rw_bytes(uint32_t index, uint8_t address, uint8_t reg, uint8_t *buffer, int length, int write);
+
+#define iic_device(id) ((id == 0)?I2C0:I2C1)
+
+static void _delay_1us(uint32_t n)
+{
+	while(n-->0)
+	{
+		int N=1000;
+		while(N-->0);
+	}
+}
+
+static void _i2c_deinit(uint32_t i2c_periph)
+{
+    switch(i2c_periph){
+    case I2C0:
+        /* reset I2C0 */
+        rcu_periph_reset_enable(RCU_I2C0RST);
+		_delay_1us(10);
+        rcu_periph_reset_disable(RCU_I2C0RST);
+        break;
+    case I2C1:
+        /* reset I2C1 */
+        rcu_periph_reset_enable(RCU_I2C1RST);
+		_delay_1us(10);
+        rcu_periph_reset_disable(RCU_I2C1RST);
+        break;
+    default:
+        break;
+    }
+}
+
+
+void gd32_i2c_init(uint32_t i2c_device, uint32_t rate){
+	uint32_t device = iic_device(i2c_device);
+
+	rcu_periph_clock_enable(RCU_GPIOB);
+	if (device == I2C0) {
+		gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_8|GPIO_PIN_9);
+		gpio_mode_af(GPIOB ,GPIO_PUPD_NONE, GPIO_PIN_8|GPIO_PIN_9);
+		rcu_periph_clock_enable(RCU_I2C0);
+		_i2c_deinit(I2C0);
+	 	
+	} else {
+		gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_10|GPIO_PIN_11);
+		gpio_mode_af(GPIOB ,GPIO_PUPD_NONE, GPIO_PIN_10|GPIO_PIN_11);	
+		rcu_periph_clock_enable(RCU_I2C1);
+		_i2c_deinit(I2C1);
+	}
+	i2c_clock_config(device, rate, I2C_DTCY_2);
+	i2c_enable(device);
+}
+
+
+static int gd32_i2c_write_address(uint32_t deivce, uint8_t address, uint8_t write){
+	uint32_t times;
+	if (!write){
+		address |= 1;
+	}
+ 
+    I2C_DATA((deivce)) = address;
+ 	for (times = 10000; times > 0; times--) {
+  		if (i2c_flag_get((deivce), I2C_FLAG_ADDSEND)) {
+   			return 0;
+  		}
+ 	}
+
+ 	return -1;	
+}
+
+
+int gd32_i2c_read_byte(uint32_t index, uint8_t address, uint8_t reg, uint8_t *value){
+	return _gd32_i2c_rw_bytes(index, address, reg, value, 1, 0);
+}
+
+int gd32_i2c_read_nbytes(uint32_t index, uint8_t address, uint8_t reg, uint8_t *buffer, int length){
+	return _gd32_i2c_rw_bytes(index, address, reg, buffer, length, 0);
+}
+
+int gd32_i2c_write_byte(uint32_t index, uint8_t address, uint8_t reg, uint8_t value){
+	return _gd32_i2c_rw_bytes(index, address, reg, &value, 1, 1);
+}
+
+int gd32_i2c_write_nbytes(uint32_t index, uint8_t address, uint8_t reg, uint8_t *value, int length){
+	return _gd32_i2c_rw_bytes(index, address, reg, value, length, 1);
+}
+
+
+static int gd32_i2c_wait_flags(uint32_t i2c_periph, i2c_flag_enum flag, FlagStatus status){
+	int remain = 100000;
+	while (i2c_flag_get(i2c_periph, flag) != status) {
+		if (remain-- <= 0){
+			return -1;
+		}
+	}
+	return 0;
+}
+
+static void gd32_i2c_wait_stop(uint32_t i2c_periph){
+	int remain = 100000;
+	while(I2C_CTL0(i2c_periph) & 0x0200){
+		if (remain-- <= 0){
+			break;
+		}
+	};
+}
+
+static int _gd32_i2c_rw_bytes(uint32_t index, uint8_t address, uint8_t reg, uint8_t *buffer, int length, int write){
+	int ret = length;
+	uint32_t device = iic_device(index);
+
+	i2c_ackpos_config(device, length == 2?I2C_ACKPOS_NEXT:I2C_ACKPOS_CURRENT);
+	i2c_ack_config(device, I2C_ACK_ENABLE);
+
+	if (gd32_i2c_wait_flags(device, I2C_FLAG_I2CBSY, RESET) < 0){
+		ret = -1;
+		goto out_i2c_stop_on_bus;
+	}
+	
+	//send reg
+	i2c_start_on_bus(device);
+
+	if (gd32_i2c_wait_flags(device, I2C_FLAG_SBSEND, SET) < 0){
+		ret = -2;
+		goto out_i2c_stop_on_bus;
+	}
+	
+	if (gd32_i2c_write_address(device, address, 1) < 0){
+		ret = -3;
+		goto out_i2c_stop_on_bus;
+	}
+	i2c_flag_clear(device, I2C_FLAG_ADDSEND);
+
+    /* wait until the transmit data buffer is empty */
+	if (gd32_i2c_wait_flags(device, I2C_FLAG_TBE, SET) < 0){
+		ret = -4;
+		goto out_i2c_stop_on_bus;
+	}
+
+	i2c_data_transmit(device, reg);
+
+	if (gd32_i2c_wait_flags(device, I2C_FLAG_BTC, SET) < 0){
+		ret = -5;
+		goto out_i2c_stop_on_bus;
+	}
+
+	if (write){
+		int index = 0;
+		for (; index < length; index++){
+			if (gd32_i2c_wait_flags(device, I2C_FLAG_TBE, SET) < 0){
+				ret = -6;
+				goto out_i2c_stop_on_bus;
+			}
+			i2c_data_transmit(device, buffer[index]);
+		}
+		if (gd32_i2c_wait_flags(device, I2C_FLAG_BTC, SET) < 0){
+			ret = -7;
+			goto out_i2c_stop_on_bus;
+		}
+		ret = length;
+		goto out_i2c_stop_on_bus;
+	}
+
+	
+	//begin read
+	i2c_start_on_bus(device);
+	if (gd32_i2c_wait_flags(device, I2C_FLAG_SBSEND, SET) < 0){
+		ret = -8;
+		goto out_i2c_stop_on_bus;
+	}
+
+	if (gd32_i2c_write_address(device, address, 0) < 0){
+		ret = -9;
+		goto out_i2c_stop_on_bus;
+	}
+	i2c_flag_clear(device, I2C_FLAG_ADDSEND);
+	if (length< 3) {
+	 	i2c_ack_config(device, I2C_ACK_DISABLE);
+	 	
+	} else {
+	 	while (length > 3) {
+			if (gd32_i2c_wait_flags(device, I2C_FLAG_RBNE, SET) < 0){
+				ret = -10;
+				goto out_i2c_stop_on_bus;
+			}
+	  		*buffer++ = i2c_data_receive(device);
+	 		 length--;
+	 	}
+		if (gd32_i2c_wait_flags(device, I2C_FLAG_BTC, SET) < 0){
+			ret = -11;
+			goto out_i2c_stop_on_bus;
+		}
+		i2c_ack_config(device, I2C_ACK_DISABLE);
+	}
+	
+	while (length > 0) {
+		if (gd32_i2c_wait_flags(device, I2C_FLAG_RBNE, SET) < 0){
+			ret = -12;
+			goto out_i2c_stop_on_bus;
+		}
+	 	*buffer++ = i2c_data_receive(device);
+	 	length--;
+	}
+	if (length != 0){
+		ret = -13;
+	}
+out_i2c_stop_on_bus:
+ 	i2c_stop_on_bus(device);
+	gd32_i2c_wait_stop(device);
+ 	return ret;
+}
+
+

+ 11 - 0
Application/bsp/i2c.h

@@ -0,0 +1,11 @@
+#ifndef __iic_h__
+#define __iic_h__
+#include <stdint.h>
+
+extern void gd32_i2c_init(uint32_t i2c_device, uint32_t rate);
+extern int gd32_i2c_read_byte(uint32_t index, uint8_t address, uint8_t reg, uint8_t *value);
+extern int gd32_i2c_read_nbytes(uint32_t index, uint8_t address, uint8_t reg, uint8_t *buffer, int length);
+extern int gd32_i2c_write_byte(uint32_t index, uint8_t address, uint8_t reg, uint8_t value);
+extern int gd32_i2c_write_nbytes(uint32_t index, uint8_t address, uint8_t reg, uint8_t *value, int length);
+#endif /* __iic_h__ */
+

+ 26 - 2
Project/BMS.uvoptx

@@ -575,6 +575,30 @@
       <RteFlg>0</RteFlg>
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
       <bShared>0</bShared>
     </File>
     </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>33</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Application\bsp\AT24CXX.c</PathWithFileName>
+      <FilenameWithoutPath>AT24CXX.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
+    <File>
+      <GroupNumber>3</GroupNumber>
+      <FileNumber>34</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Application\bsp\i2c.c</PathWithFileName>
+      <FilenameWithoutPath>i2c.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
   </Group>
   </Group>
 
 
   <Group>
   <Group>
@@ -593,7 +617,7 @@
     <RteFlg>0</RteFlg>
     <RteFlg>0</RteFlg>
     <File>
     <File>
       <GroupNumber>5</GroupNumber>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>33</FileNumber>
+      <FileNumber>35</FileNumber>
       <FileType>2</FileType>
       <FileType>2</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -605,7 +629,7 @@
     </File>
     </File>
     <File>
     <File>
       <GroupNumber>5</GroupNumber>
       <GroupNumber>5</GroupNumber>
-      <FileNumber>34</FileNumber>
+      <FileNumber>36</FileNumber>
       <FileType>1</FileType>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
       <tvExpOptDlg>0</tvExpOptDlg>

+ 10 - 0
Project/BMS.uvprojx

@@ -553,6 +553,16 @@
               <FileType>1</FileType>
               <FileType>1</FileType>
               <FilePath>..\Application\bsp\ml5238.c</FilePath>
               <FilePath>..\Application\bsp\ml5238.c</FilePath>
             </File>
             </File>
+            <File>
+              <FileName>AT24CXX.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Application\bsp\AT24CXX.c</FilePath>
+            </File>
+            <File>
+              <FileName>i2c.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Application\bsp\i2c.c</FilePath>
+            </File>
           </Files>
           </Files>
         </Group>
         </Group>
         <Group>
         <Group>