hal_sy6970.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. #include "hal_sy6970.h"
  2. #define READ_SDA4 GPIO_ReadInputPins(GPIO_PORT_A,GPIO_PIN_12)
  3. #define IIC_SDA4(n) (n?GPIO_SetPins(GPIO_PORT_A, GPIO_PIN_12):GPIO_ResetPins(GPIO_PORT_A, GPIO_PIN_12))
  4. #define IIC_SCL4(n) (n?GPIO_SetPins(GPIO_PORT_A, GPIO_PIN_11):GPIO_ResetPins(GPIO_PORT_A, GPIO_PIN_11))
  5. #define sy6970_speed 5
  6. //需要示波器调1us的时间
  7. static void delay_us(uint16_t time)
  8. {
  9. uint16_t i;
  10. for(i=time;i>0;i--)
  11. {
  12. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  13. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  14. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  15. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  16. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  17. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  18. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  19. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  20. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  21. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  22. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  23. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  24. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  25. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  26. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  27. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  28. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  29. __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
  30. }
  31. }
  32. static void iic4_init(void)
  33. {
  34. stc_gpio_init_t pstcGpioInit1;
  35. GPIO_StructInit(&pstcGpioInit1);
  36. pstcGpioInit1.u16PinDir = PIN_DIR_OUT;
  37. pstcGpioInit1.u16PinState = PIN_STAT_RST;
  38. GPIO_Init(GPIO_PORT_A, GPIO_PIN_11,&pstcGpioInit1);
  39. GPIO_Init(GPIO_PORT_A, GPIO_PIN_12,&pstcGpioInit1);
  40. GPIO_SetPins(GPIO_PORT_A, GPIO_PIN_11);
  41. GPIO_SetPins(GPIO_PORT_A, GPIO_PIN_12);
  42. }
  43. void sy6970_init(void)
  44. {
  45. iic4_init();
  46. }
  47. static void SDA_IN4(void)
  48. {
  49. stc_gpio_init_t pstcGpioInit3;//iic的引脚
  50. pstcGpioInit3.u16PinDir = PIN_DIR_IN;
  51. //pstcGpioInit3.u16PinInputType = PIN_PU_ON;
  52. GPIO_Init(GPIO_PORT_A, GPIO_PIN_12,&pstcGpioInit3);
  53. }
  54. static void SDA_OUT4(void)
  55. {
  56. stc_gpio_init_t pstcGpioInit3;
  57. pstcGpioInit3.u16PinDir = PIN_DIR_OUT;
  58. pstcGpioInit3.u16PinOutputType=PIN_OUT_TYPE_NMOS;
  59. GPIO_Init(GPIO_PORT_A, GPIO_PIN_12,&pstcGpioInit3);
  60. }
  61. static void iic_start(void)
  62. {
  63. SDA_OUT4();
  64. IIC_SDA4(1);
  65. IIC_SCL4(1);
  66. delay_us(sy6970_speed);
  67. IIC_SDA4(0);
  68. delay_us(sy6970_speed);
  69. IIC_SCL4(0);
  70. }
  71. static void iic_stop(void)
  72. {
  73. SDA_OUT4();
  74. IIC_SCL4(0);
  75. IIC_SDA4(0);
  76. delay_us(sy6970_speed);
  77. IIC_SCL4(1);
  78. IIC_SDA4(1);
  79. delay_us(sy6970_speed);
  80. }
  81. static void iic_ack(void)
  82. {
  83. SDA_OUT4();
  84. IIC_SCL4(0);
  85. IIC_SDA4(0);
  86. delay_us(sy6970_speed);
  87. IIC_SCL4(1);
  88. delay_us(sy6970_speed);
  89. IIC_SCL4(0);
  90. }
  91. static void iic_nack(void)
  92. {
  93. SDA_OUT4();
  94. IIC_SCL4(0);
  95. IIC_SDA4(1);
  96. delay_us(sy6970_speed);
  97. IIC_SCL4(1);
  98. delay_us(sy6970_speed);
  99. IIC_SCL4(0);
  100. }
  101. static uint8_t iic_wait_ack(void)
  102. {
  103. uint16_t t =200;
  104. SDA_OUT4();
  105. IIC_SDA4(1);delay_us(1);
  106. IIC_SCL4(1);delay_us(1);
  107. SDA_IN4();
  108. while(READ_SDA4)
  109. {
  110. t--;
  111. if(t==0)
  112. {
  113. iic_stop();
  114. return 1;
  115. }
  116. delay_us(1);
  117. }
  118. IIC_SCL4(0);
  119. return 0;
  120. }
  121. static void iic_send_byte(uint8_t byte)
  122. {
  123. uint8_t bit_cnt;
  124. SDA_OUT4();
  125. IIC_SCL4(0);
  126. for(bit_cnt=0;bit_cnt<8;bit_cnt++)
  127. {
  128. if(byte&0x80)
  129. IIC_SDA4(1);
  130. else
  131. IIC_SDA4(0);
  132. byte<<=1;
  133. delay_us(sy6970_speed);
  134. IIC_SCL4(1);
  135. delay_us(sy6970_speed);
  136. IIC_SCL4(0);
  137. }
  138. }
  139. static uint8_t iic_recive_byte(unsigned char ack)
  140. {
  141. uint8_t retc = 0;
  142. uint8_t bit_cnt;
  143. SDA_IN4();
  144. delay_us(1);
  145. for(bit_cnt=0;bit_cnt<8;bit_cnt++)
  146. {
  147. IIC_SCL4(0);
  148. delay_us(sy6970_speed);
  149. IIC_SCL4(1);
  150. retc=retc<<1;
  151. if(READ_SDA4)
  152. retc++;
  153. delay_us(sy6970_speed);
  154. }
  155. return(retc);
  156. }
  157. static void sy6970_write_byte(uint8_t dev_addr,uint8_t RAddr, uint8_t WData)
  158. {
  159. iic_start();
  160. iic_send_byte(dev_addr);
  161. iic_wait_ack();
  162. iic_send_byte(RAddr);
  163. iic_wait_ack();
  164. iic_send_byte(WData);
  165. iic_wait_ack();
  166. iic_stop();
  167. }
  168. static void sy6970_read_byte(uint8_t dev_addr,uint8_t RAddr, uint8_t *RData)
  169. {
  170. iic_start();
  171. iic_send_byte(dev_addr);
  172. iic_wait_ack();
  173. iic_send_byte(RAddr);
  174. iic_wait_ack();
  175. iic_start();
  176. iic_send_byte(dev_addr|0x01);
  177. iic_wait_ack();
  178. *RData = iic_recive_byte(0);
  179. iic_stop();
  180. }
  181. _Bool sy6970_write_bytes ( unsigned char SlaveAddr, unsigned char RegAddr, unsigned char *Buf, unsigned char Num )
  182. {
  183. iic_start(); //起始信号
  184. //发送设备地址(写)
  185. iic_send_byte ( SlaveAddr ); //等待应答
  186. iic_wait_ack();
  187. //发送寄存器地址
  188. iic_send_byte ( RegAddr ) ; //等待应答
  189. iic_wait_ack();
  190. while ( Num-- ) //循环写入数据
  191. {
  192. //发送数据
  193. iic_send_byte ( *Buf ); //等待应答
  194. iic_wait_ack();
  195. Buf++; //数据指针偏移到下一个
  196. delay_us(10);
  197. }
  198. iic_stop(); //停止信号
  199. return 0;
  200. }
  201. _Bool sy6970_read_bytes ( unsigned char SlaveAddr, unsigned char RegAddr, unsigned char *Buf, unsigned char Num )
  202. {
  203. iic_start(); //起始信号
  204. //发送设备地址(写)
  205. iic_send_byte ( SlaveAddr ); //等待应答
  206. iic_wait_ack();
  207. //发送寄存器地址
  208. iic_send_byte ( RegAddr ); //等待应答
  209. iic_wait_ack();
  210. iic_start(); //重启信号
  211. //发送设备地址(读)
  212. iic_send_byte ( SlaveAddr + 1 ); //等待应答
  213. iic_wait_ack();
  214. while ( Num-- )
  215. {
  216. //偏移到下一个数据存储地址
  217. if ( Num == 0 )
  218. {
  219. *Buf = iic_recive_byte ( 0 ); //最后一个数据需要回NOACK
  220. }
  221. else
  222. {
  223. *Buf = iic_recive_byte ( 1 ); //回应ACK
  224. }
  225. Buf++;
  226. }
  227. iic_stop();
  228. return 0;
  229. }
  230. /**********************************************SY6970 操作函数****************************************************/
  231. /*
  232. * 设置sy6970输入电流的大小
  233. *
  234. * set_val 需要操作的从机设备
  235. Fast Charge Current Limit:
  236. ICHG=[ICHG]*64mA
  237. Range:0mA(0000000)-5056mA(1001111)
  238. 0000000=0mA(Disable Charge)
  239. 0000001=64mA
  240. 0100000=2048mA(Default)
  241. 1001111~1111111=5056mA
  242. *
  243. * 返回值:void
  244. * */
  245. void sy6970_set_input_current_limit(uint8_t set_val)
  246. {
  247. set_val&= 0x7F;
  248. sy6970_write_byte(SY6970_ADDR,0x04,set_val);
  249. }
  250. /*
  251. * 设置sy6970输入电压的大小
  252. *
  253. * set_val 需要操作的从机设备
  254. Charge Voltage Limit:
  255. VREG=3.840V+[VREG]*16mV
  256. Range:3.840V-4.608V(110000)
  257. 000000=3.840V
  258. 000001=3.856V
  259. 010111=4.208V(Default)
  260. 110000~111111=4.608V
  261. *
  262. * 返回值:void
  263. * */
  264. void sy6970_set_input_voltage_limit(uint8_t set_val)
  265. {
  266. set_val&= 0xFC;
  267. sy6970_write_byte(SY6970_ADDR,0x06,set_val);
  268. }
  269. /*充电使能*/
  270. void sy6970_charge_enable(void)
  271. {
  272. uint8_t set_val = 0x00;
  273. set_val&= 0x01<<4;
  274. sy6970_write_byte(SY6970_ADDR,0x03,set_val);
  275. }
  276. /*充电不使能*/
  277. void sy6970_charge_disable(void)
  278. {
  279. uint8_t set_val = 0x00;
  280. set_val&= 0x00<<4;
  281. sy6970_write_byte(SY6970_ADDR,0x03,set_val);
  282. }
  283. /*充电状态查询
  284. 返回值:
  285. 00-Not Charging
  286. 01-Pre-charge (VBAT <VBATLOWV)
  287. 10-Fast Charging
  288. 11-Charge Termination Done
  289. */
  290. uint8_t sy6970_charge_status(void)
  291. {
  292. uint8_t status = 0;
  293. sy6970_read_byte(SY6970_ADDR,0x0b,&status);
  294. status >>=3;
  295. status &=0x03;
  296. return status;
  297. }
  298. uint8_t statusx = 0;
  299. #include "FreeRTOS.h"
  300. #include "task.h"
  301. void sy6970_task(void *argv)
  302. {
  303. while(1)
  304. {
  305. statusx = sy6970_charge_status();
  306. vTaskDelay(500);
  307. }
  308. }