|
@@ -0,0 +1,398 @@
|
|
|
+#include "hal_sy6970.h"
|
|
|
+
|
|
|
+#define __nop() __asm__("NOP")
|
|
|
+
|
|
|
+#define GPIO_SDA DioConf_DioChannel_PTA10_GPIO_IN_OUT_MCU_BATT_IIC_SDA
|
|
|
+#define GPIO_SCL DioConf_DioChannel_PTC5_GPIO_IN_OUT_MCU_BATT_IIC_SCK
|
|
|
+
|
|
|
+#define READ_SDA4 Dio_ReadChannel(GPIO_SDA)
|
|
|
+
|
|
|
+#define GPIO_SETPIN(channel) Dio_WriteChannel(channel,1)
|
|
|
+#define GPIO_RESETPIN(channel) Dio_WriteChannel(channel,0)
|
|
|
+
|
|
|
+
|
|
|
+#define IIC_SDA4(n) (n?GPIO_SETPIN(GPIO_SDA):GPIO_RESETPIN(GPIO_SDA))
|
|
|
+#define IIC_SCL4(n) (n?GPIO_SETPIN(GPIO_SCL):GPIO_RESETPIN(GPIO_SCL))
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#define sy6970_speed 5
|
|
|
+
|
|
|
+//需要示波器调1us的时间
|
|
|
+static void delay_us(uint16_t time)
|
|
|
+{
|
|
|
+ uint16_t i;
|
|
|
+
|
|
|
+ for(i=time;i>0;i--)
|
|
|
+ {
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//static void iic4_init(void)
|
|
|
+//{
|
|
|
+// stc_gpio_init_t pstcGpioInit1;
|
|
|
+// GPIO_StructInit(&pstcGpioInit1);
|
|
|
+//
|
|
|
+// pstcGpioInit1.u16PinDir = PIN_DIR_OUT;
|
|
|
+// pstcGpioInit1.u16PinState = PIN_STAT_RST;
|
|
|
+// GPIO_Init(GPIO_PORT_A, GPIO_PIN_11,&pstcGpioInit1);
|
|
|
+// GPIO_Init(GPIO_PORT_A, GPIO_PIN_12,&pstcGpioInit1);
|
|
|
+//
|
|
|
+// GPIO_SetPins(GPIO_PORT_A, GPIO_PIN_11);
|
|
|
+// GPIO_SetPins(GPIO_PORT_A, GPIO_PIN_12);
|
|
|
+//}
|
|
|
+
|
|
|
+//void sy6970_init(void)
|
|
|
+//{
|
|
|
+// iic4_init();
|
|
|
+//}
|
|
|
+
|
|
|
+static void SDA_IN4(void)
|
|
|
+{
|
|
|
+// stc_gpio_init_t pstcGpioInit3;//iic的引脚
|
|
|
+// pstcGpioInit3.u16PinDir = PIN_DIR_IN;
|
|
|
+// //pstcGpioInit3.u16PinInputType = PIN_PU_ON;
|
|
|
+// GPIO_Init(GPIO_PORT_A, GPIO_PIN_12,&pstcGpioInit3);
|
|
|
+ Port_SetPinDirection(PortConfigSet_PortContainer_GPIO_PTA10_GPIO_IN_OUT_MCU_BATT_IIC_SDA,PORT_CI_PORT_PIN_IN);
|
|
|
+ //????Port_SetPinDirection(GPIO_SDA,PORT_CI_PORT_PIN_IN);
|
|
|
+}
|
|
|
+
|
|
|
+static void SDA_OUT4(void)
|
|
|
+{
|
|
|
+// stc_gpio_init_t pstcGpioInit3;
|
|
|
+// pstcGpioInit3.u16PinDir = PIN_DIR_OUT;
|
|
|
+// pstcGpioInit3.u16PinOutputType=PIN_OUT_TYPE_NMOS;
|
|
|
+// GPIO_Init(GPIO_PORT_A, GPIO_PIN_12,&pstcGpioInit3);
|
|
|
+ Port_SetPinDirection(PortConfigSet_PortContainer_GPIO_PTA10_GPIO_IN_OUT_MCU_BATT_IIC_SDA,PORT_CI_PORT_PIN_OUT);
|
|
|
+ //????Port_SetPinDirection(GPIO_SDA,PORT_CI_PORT_PIN_OUT);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+static void iic_start(void)
|
|
|
+{
|
|
|
+ SDA_OUT4();
|
|
|
+
|
|
|
+ IIC_SDA4(1);
|
|
|
+ IIC_SCL4(1);
|
|
|
+ delay_us(sy6970_speed);
|
|
|
+
|
|
|
+ IIC_SDA4(0);
|
|
|
+ delay_us(sy6970_speed);
|
|
|
+ IIC_SCL4(0);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static void iic_stop(void)
|
|
|
+{
|
|
|
+ SDA_OUT4();
|
|
|
+
|
|
|
+ IIC_SCL4(0);
|
|
|
+ IIC_SDA4(0);
|
|
|
+ delay_us(sy6970_speed);
|
|
|
+
|
|
|
+ IIC_SCL4(1);
|
|
|
+ IIC_SDA4(1);
|
|
|
+ delay_us(sy6970_speed);
|
|
|
+}
|
|
|
+
|
|
|
+static void iic_ack(void)
|
|
|
+{
|
|
|
+ SDA_OUT4();
|
|
|
+
|
|
|
+ IIC_SCL4(0);
|
|
|
+ IIC_SDA4(0);
|
|
|
+ delay_us(sy6970_speed);
|
|
|
+
|
|
|
+ IIC_SCL4(1);
|
|
|
+ delay_us(sy6970_speed);
|
|
|
+ IIC_SCL4(0);
|
|
|
+}
|
|
|
+
|
|
|
+static void iic_nack(void)
|
|
|
+{
|
|
|
+ SDA_OUT4();
|
|
|
+
|
|
|
+ IIC_SCL4(0);
|
|
|
+ IIC_SDA4(1);
|
|
|
+ delay_us(sy6970_speed);
|
|
|
+
|
|
|
+ IIC_SCL4(1);
|
|
|
+ delay_us(sy6970_speed);
|
|
|
+ IIC_SCL4(0);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static uint8_t iic_wait_ack(void)
|
|
|
+{
|
|
|
+ uint16_t t =200;
|
|
|
+ SDA_OUT4();
|
|
|
+
|
|
|
+ IIC_SDA4(1);delay_us(1);
|
|
|
+ IIC_SCL4(1);delay_us(1);
|
|
|
+
|
|
|
+ SDA_IN4();
|
|
|
+
|
|
|
+ while(READ_SDA4)
|
|
|
+ {
|
|
|
+ t--;
|
|
|
+
|
|
|
+ if(t==0)
|
|
|
+ {
|
|
|
+ iic_stop();
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ delay_us(1);
|
|
|
+ }
|
|
|
+ IIC_SCL4(0);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static void iic_send_byte(uint8_t byte)
|
|
|
+{
|
|
|
+ uint8_t bit_cnt;
|
|
|
+ SDA_OUT4();
|
|
|
+ IIC_SCL4(0);
|
|
|
+
|
|
|
+ for(bit_cnt=0;bit_cnt<8;bit_cnt++)
|
|
|
+ {
|
|
|
+ if(byte&0x80)
|
|
|
+ IIC_SDA4(1);
|
|
|
+ else
|
|
|
+ IIC_SDA4(0);
|
|
|
+
|
|
|
+ byte<<=1;
|
|
|
+ delay_us(sy6970_speed);
|
|
|
+ IIC_SCL4(1);
|
|
|
+ delay_us(sy6970_speed);
|
|
|
+ IIC_SCL4(0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static uint8_t iic_recive_byte(unsigned char ack)
|
|
|
+{
|
|
|
+ uint8_t retc = 0;
|
|
|
+ uint8_t bit_cnt;
|
|
|
+
|
|
|
+ SDA_IN4();
|
|
|
+ delay_us(1);
|
|
|
+
|
|
|
+ for(bit_cnt=0;bit_cnt<8;bit_cnt++)
|
|
|
+ {
|
|
|
+ IIC_SCL4(0);
|
|
|
+ delay_us(sy6970_speed);
|
|
|
+ IIC_SCL4(1);
|
|
|
+
|
|
|
+ retc=retc<<1;
|
|
|
+
|
|
|
+ if(READ_SDA4)
|
|
|
+ retc++;
|
|
|
+
|
|
|
+ delay_us(sy6970_speed);
|
|
|
+ }
|
|
|
+
|
|
|
+ return(retc);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+static void sy6970_write_byte(uint8_t dev_addr,uint8_t RAddr, uint8_t WData)
|
|
|
+{
|
|
|
+ iic_start();
|
|
|
+ iic_send_byte(dev_addr);
|
|
|
+ iic_wait_ack();
|
|
|
+ iic_send_byte(RAddr);
|
|
|
+ iic_wait_ack();
|
|
|
+ iic_send_byte(WData);
|
|
|
+ iic_wait_ack();
|
|
|
+ iic_stop();
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static void sy6970_read_byte(uint8_t dev_addr,uint8_t RAddr, uint8_t *RData)
|
|
|
+{
|
|
|
+ iic_start();
|
|
|
+ iic_send_byte(dev_addr);
|
|
|
+ iic_wait_ack();
|
|
|
+ iic_send_byte(RAddr);
|
|
|
+ iic_wait_ack();
|
|
|
+ iic_start();
|
|
|
+ iic_send_byte(dev_addr|0x01);
|
|
|
+ iic_wait_ack();
|
|
|
+ *RData = iic_recive_byte(0);
|
|
|
+ iic_stop();
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+_Bool sy6970_write_bytes ( unsigned char SlaveAddr, unsigned char RegAddr, unsigned char *Buf, unsigned char Num )
|
|
|
+{
|
|
|
+ iic_start(); //起始信号
|
|
|
+ //发送设备地址(写)
|
|
|
+ iic_send_byte ( SlaveAddr ); //等待应答
|
|
|
+ iic_wait_ack();
|
|
|
+
|
|
|
+ //发送寄存器地址
|
|
|
+ iic_send_byte ( RegAddr ) ; //等待应答
|
|
|
+ iic_wait_ack();
|
|
|
+ while ( Num-- ) //循环写入数据
|
|
|
+ {
|
|
|
+ //发送数据
|
|
|
+ iic_send_byte ( *Buf ); //等待应答
|
|
|
+ iic_wait_ack();
|
|
|
+ Buf++; //数据指针偏移到下一个
|
|
|
+ delay_us(10);
|
|
|
+ }
|
|
|
+ iic_stop(); //停止信号
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+_Bool sy6970_read_bytes ( unsigned char SlaveAddr, unsigned char RegAddr, unsigned char *Buf, unsigned char Num )
|
|
|
+{
|
|
|
+ iic_start(); //起始信号
|
|
|
+ //发送设备地址(写)
|
|
|
+ iic_send_byte ( SlaveAddr ); //等待应答
|
|
|
+ iic_wait_ack();
|
|
|
+ //发送寄存器地址
|
|
|
+ iic_send_byte ( RegAddr ); //等待应答
|
|
|
+ iic_wait_ack();
|
|
|
+ iic_start(); //重启信号
|
|
|
+ //发送设备地址(读)
|
|
|
+ iic_send_byte ( SlaveAddr + 1 ); //等待应答
|
|
|
+ iic_wait_ack();
|
|
|
+ while ( Num-- )
|
|
|
+ {
|
|
|
+ //偏移到下一个数据存储地址
|
|
|
+ if ( Num == 0 )
|
|
|
+ {
|
|
|
+ *Buf = iic_recive_byte ( 0 ); //最后一个数据需要回NOACK
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ *Buf = iic_recive_byte ( 1 ); //回应ACK
|
|
|
+ }
|
|
|
+ Buf++;
|
|
|
+ }
|
|
|
+ iic_stop();
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/**********************************************SY6970 操作函数****************************************************/
|
|
|
+/*
|
|
|
+ * 设置sy6970输入电流的大小
|
|
|
+ *
|
|
|
+ * set_val 需要操作的从机设备
|
|
|
+ Fast Charge Current Limit:
|
|
|
+ ICHG=[ICHG]*64mA
|
|
|
+ Range:0mA(0000000)-5056mA(1001111)
|
|
|
+ 0000000=0mA(Disable Charge)
|
|
|
+ 0000001=64mA
|
|
|
+ …
|
|
|
+ 0100000=2048mA(Default)
|
|
|
+ …
|
|
|
+ 1001111~1111111=5056mA
|
|
|
+ *
|
|
|
+ * 返回值:void
|
|
|
+ * */
|
|
|
+void sy6970_set_input_current_limit(uint8_t set_val)
|
|
|
+{
|
|
|
+ set_val&= 0x7F;
|
|
|
+ sy6970_write_byte(SY6970_ADDR,0x04,set_val);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+ * 设置sy6970输入电压的大小
|
|
|
+ *
|
|
|
+ * set_val 需要操作的从机设备
|
|
|
+ Charge Voltage Limit:
|
|
|
+ VREG=3.840V+[VREG]*16mV
|
|
|
+ Range:3.840V-4.608V(110000)
|
|
|
+ 000000=3.840V
|
|
|
+ 000001=3.856V
|
|
|
+ …
|
|
|
+ 010111=4.208V(Default)
|
|
|
+ …
|
|
|
+ 110000~111111=4.608V
|
|
|
+ *
|
|
|
+ * 返回值:void
|
|
|
+ * */
|
|
|
+void sy6970_set_input_voltage_limit(uint8_t set_val)
|
|
|
+{
|
|
|
+ set_val&= 0xFC;
|
|
|
+ sy6970_write_byte(SY6970_ADDR,0x06,set_val);
|
|
|
+}
|
|
|
+
|
|
|
+/*充电使能*/
|
|
|
+void sy6970_charge_enable(void)
|
|
|
+{
|
|
|
+ uint8_t set_val = 0x00;
|
|
|
+ set_val&= 0x01<<4;
|
|
|
+ sy6970_write_byte(SY6970_ADDR,0x03,set_val);
|
|
|
+}
|
|
|
+
|
|
|
+/*充电不使能*/
|
|
|
+void sy6970_charge_disable(void)
|
|
|
+{
|
|
|
+ uint8_t set_val = 0x00;
|
|
|
+ set_val&= 0x00<<4;
|
|
|
+ sy6970_write_byte(SY6970_ADDR,0x03,set_val);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+/*充电状态查询
|
|
|
+返回值:
|
|
|
+00-Not Charging
|
|
|
+01-Pre-charge (VBAT <VBATLOWV)
|
|
|
+10-Fast Charging
|
|
|
+11-Charge Termination Done
|
|
|
+*/
|
|
|
+uint8_t sy6970_charge_status(void)
|
|
|
+{
|
|
|
+ uint8_t status = 0;
|
|
|
+ sy6970_read_byte(SY6970_ADDR,0x0b,&status);
|
|
|
+ status >>=3;
|
|
|
+ status &=0x03;
|
|
|
+ return status;
|
|
|
+}
|
|
|
+
|
|
|
+uint8_t statusx = 0;
|
|
|
+#include "FreeRTOS.h"
|
|
|
+#include "task.h"
|
|
|
+void sy6970_task(void *argv)
|
|
|
+{
|
|
|
+ while(1)
|
|
|
+ {
|
|
|
+ statusx = sy6970_charge_status();
|
|
|
+ vTaskDelay(500);
|
|
|
+ }
|
|
|
+}
|