hal_sy6970.c 8.6 KB

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