点击打开链接

根据TI官方MSP430平台移植修改过来的,在Omap37xx(wince)平台测试,理论上和平台无关,伸手党,赶紧复制粘贴代码吧。如果这篇文章帮助了你,给了好评也无妨。

  1. /*
  2. ================================================================================
  3. *             Texas Instruments OMAP(TM) Platform Software
  4. * (c) Copyright Texas Instruments, Incorporated. All Rights Reserved.
  5. *
  6. * Use of this software is controlled by the terms and conditions found
  7. * in the license agreement under which this software has been supplied.
  8. *
  9. ================================================================================
  10. */
  11. //
  12. //  File:  bqtool.c
  13. //
  14. #include <windows.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18. #include <i2cproxy.h>
  19. #include "bq27500.h"
  20. #define CMD_MAX_DATA_SIZE   512
  21. #define MAX_LINE_LEN        ((CMD_MAX_DATA_SIZE + 4) * 3)
  22. #define CMD_RETRY_DELAY     100 /* in ms */
  23. #define RETRY_LIMIT     3
  24. typedef enum {
  25. CMD_INVALID = 0,
  26. CMD_R,  /* Read */
  27. CMD_W,  /* Write */
  28. CMD_C,  /* Compare */
  29. CMD_X,  /* Delay */
  30. } cmd_type_t;
  31. /*
  32. * DO NOT change the order of fields - particularly reg
  33. * should be immediately followed by data
  34. */
  35. typedef struct {
  36. cmd_type_t cmd_type;
  37. unsigned char addr;
  38. unsigned char reg;
  39. union {
  40. unsigned char bytes[CMD_MAX_DATA_SIZE + 1];
  41. UINT delay;
  42. } data;
  43. unsigned char data_len;
  44. UINT32 line_num;
  45. CHAR    *line;
  46. }cmd_t;
  47. static UINT32 line_num;
  48. /* Parse S into tokens separated by characters in DELIM.
  49. If S is NULL, the saved pointer in SAVE_PTR is used as
  50. the next starting point.  For example:
  51. char s[] = "-abc-=-def";
  52. char *sp;
  53. x = strtok_r(s, "-", &sp);      // x = "abc", sp = "=-def"
  54. x = strtok_r(NULL, "-=", &sp);  // x = "def", sp = NULL
  55. x = strtok_r(NULL, "=", &sp);   // x = NULL
  56. // s = "abc/0-def/0"
  57. */
  58. static char *strtok_r(char *s, const char *delim, char **save_ptr) {
  59. char *token;
  60. if (s == NULL) s = *save_ptr;
  61. /* Scan leading delimiters.  */
  62. s += strspn(s, delim);
  63. if (*s == '\0')
  64. return NULL;
  65. /* Find the end of the token.  */
  66. token = s;
  67. s = strpbrk(token, delim);
  68. if (s == NULL)
  69. /* This token finishes the string.  */
  70. *save_ptr = strchr(token, '\0');
  71. else {
  72. /* Terminate the token and make *SAVE_PTR point past it.  */
  73. *s = '\0';
  74. *save_ptr = s + 1;
  75. }
  76. return token;
  77. }
  78. static char *strtok(char *s, const char *delim)
  79. {
  80. static char *last;
  81. return strtok_r(s, delim, &last);
  82. }
  83. //写I2C,根据自己平台修改相关实现
  84. static BOOL i2c_write(HANDLE hI2C, cmd_t *cmd)
  85. {
  86. int ret;
  87. DWORD udwTemp;
  88. if(hI2C)
  89. {
  90. udwTemp=cmd->addr >>1;
  91. DeviceIoControl(hI2C, IOCTL_I2C_SET_SLAVE_ADDRESS, &udwTemp, sizeof(udwTemp), NULL, 0, NULL, NULL);
  92. SetFilePointer(hI2C,LOWORD(cmd->reg),NULL,FILE_BEGIN);
  93. if(!WriteFile(hI2C, cmd->data.bytes, cmd->data_len, &udwTemp, NULL))
  94. {
  95. RETAILMSG(1,(TEXT("ERROR: i2c_write: I2c WriteFile failed.\r\n")));
  96. }
  97. }
  98. return TRUE;
  99. }
  100. //读I2C,根据自己平台修改相关实现
  101. static BOOL i2c_Read(HANDLE hI2C, cmd_t *cmd)
  102. {
  103. int ret;
  104. DWORD udwTemp;
  105. if(hI2C)
  106. {
  107. udwTemp=cmd->addr >>1;
  108. DeviceIoControl(hI2C, IOCTL_I2C_SET_SLAVE_ADDRESS, &udwTemp, sizeof(udwTemp), NULL, 0, NULL, NULL);
  109. SetFilePointer(hI2C,LOWORD(cmd->reg),NULL,FILE_BEGIN);
  110. if(!ReadFile(hI2C, cmd->data.bytes, cmd->data_len,&udwTemp, NULL))
  111. {
  112. RETAILMSG(1,(TEXT("ERROR: i2c_Read: I2c ReadFile failed.\r\n")));
  113. return FALSE;
  114. }else
  115. {
  116. cmd->data_len=udwTemp;
  117. }
  118. }
  119. return TRUE;
  120. }
  121. static BOOL do_exec_cmd(HANDLE i2c_file, cmd_t *cmd)
  122. {
  123. unsigned char tmp_buf[CMD_MAX_DATA_SIZE];
  124. int j=0;
  125. switch (cmd->cmd_type) {
  126. case CMD_R:
  127. return i2c_Read(i2c_file, cmd);
  128. case CMD_W:
  129. return i2c_write(i2c_file, cmd);
  130. case CMD_C:
  131. memcpy(tmp_buf, cmd->data.bytes, cmd->data_len);
  132. if (!i2c_Read(i2c_file, cmd))
  133. return FALSE;
  134. if (memcmp(tmp_buf, cmd->data.bytes, cmd->data_len)) {
  135. RETAILMSG(1, (TEXT("Command C failed at line %d\r\n"),cmd->line_num));
  136. return FALSE;
  137. }
  138. return TRUE;
  139. case CMD_X:
  140. Sleep(cmd->data.delay);
  141. return TRUE;
  142. default:
  143. RETAILMSG(1, (TEXT("Unsupported command at line %d\r\n"),cmd->line_num));
  144. return FALSE;
  145. }
  146. }
  147. static BOOL execute_cmd(HANDLE i2c_file, cmd_t *cmd)
  148. {
  149. int i = 1,j=0;
  150. BOOL ret;
  151. RETAILMSG(0,(TEXT("cmd:cmd_type=%d;addr=%02x,reg=%02x,cmd->data_len=%d,"),cmd->cmd_type,cmd->addr,cmd->reg,cmd->data_len));
  152. #if 0   //only for debug TODO:delete
  153. RETAILMSG(1,(TEXT("line=%d:"),cmd->line_num));
  154. for(j=0;j<cmd->data_len;j++)
  155. {
  156. RETAILMSG(1,(TEXT("%02x "),cmd->data.bytes[j]));
  157. }
  158. RETAILMSG(1,(TEXT("\r\n")));
  159. #endif
  160. ret = do_exec_cmd(i2c_file, cmd);
  161. //if execute failed,retry three times
  162. while (!ret && i < RETRY_LIMIT) {
  163. Sleep(CMD_RETRY_DELAY);
  164. ret = do_exec_cmd(i2c_file, cmd);
  165. i++;
  166. }
  167. if (!ret) {
  168. RETAILMSG(1, (TEXT("Command execution failed at line %d addr=0x%02x reg=0x%02x\r\n"),cmd->line_num, cmd->addr, cmd->reg));
  169. }
  170. return ret;
  171. }
  172. static BOOL get_delay(UINT *delay)
  173. {
  174. char *tok;
  175. UINT temp;
  176. tok = strtok(NULL, " ");
  177. if (!tok)
  178. return FALSE; /*end of line or file */
  179. if (1 != sscanf(tok, "%u", &temp)) {
  180. RETAILMSG(1, (TEXT("Syntax error while parsing delay at line %d\r\n"),line_num));
  181. return FALSE; /* syntax error */
  182. }
  183. *delay = (UINT)temp;
  184. return TRUE;
  185. }
  186. /*
  187. * Returns:
  188. *   0: success
  189. *   1: EOF
  190. *  -1: Parse error
  191. */
  192. static int get_byte(unsigned char *byte)
  193. {
  194. char *tok;
  195. unsigned char temp;
  196. tok = strtok(NULL, " ");
  197. if (!tok)
  198. return 1; /*end of line or file */
  199. if ((strlen(tok) != 2) || (sscanf(tok, "%2x", &temp) != 1)) {
  200. RETAILMSG(1, (TEXT("Syntax error at line %d\r\n"), line_num));
  201. return -1; /* syntax error */
  202. }
  203. *byte = (unsigned char)temp;
  204. return 0;   /* success */
  205. }
  206. static BOOL get_addr_n_reg(cmd_t *cmd)
  207. {
  208. if (get_byte(&cmd->addr))
  209. return FALSE;
  210. if (get_byte(&cmd->reg))
  211. return FALSE;
  212. return TRUE;
  213. }
  214. static BOOL get_data_bytes(cmd_t *cmd)
  215. {
  216. int ret, i = 0;
  217. cmd->data_len = 0;
  218. do {
  219. ret = get_byte(&cmd->data.bytes[i++]);
  220. } while ((ret == 0) && (i <= CMD_MAX_DATA_SIZE));
  221. if (ret == 0) {
  222. RETAILMSG(1, (TEXT("More than allowed number of data bytes at line %d, data_len %d, i %d\r\n"), cmd->line_num,cmd->data_len, i));
  223. return FALSE;
  224. }
  225. cmd->data_len = i - 1;
  226. return TRUE;
  227. }
  228. static BOOL get_line(FILE *bqfs_file, char **buffer)
  229. {
  230. int c;
  231. int i = 0;
  232. BOOL ret = TRUE;
  233. char *buf;
  234. buf = malloc(MAX_LINE_LEN);
  235. line_num++;
  236. while (1) {
  237. c = fgetc(bqfs_file);
  238. if (feof(bqfs_file)) {
  239. break;
  240. } else if (ferror(bqfs_file)) {
  241. RETAILMSG(1, (TEXT("File read error\r\n")));
  242. ret = FALSE;
  243. break;
  244. }
  245. if (((c == '\r') || (c == '\n') || (c == '\t')
  246. || (c == ' ')) && (i == 0)) {
  247. /*
  248. * Skip leading white space, if any, at the beginning
  249. * of the line because this interferes with strtok
  250. */
  251. RETAILMSG(1, (TEXT("Leading whitespace at line %d\r\n"),line_num));
  252. if (c == '\n')
  253. line_num++;
  254. continue;   /* blank line, let's continue */
  255. } else if (c == '\n') {
  256. /* We've reached end of line */
  257. break;
  258. }
  259. buf[i++] = c;
  260. if (i == MAX_LINE_LEN) {
  261. /*
  262. * Re-allocate in case the line is longer than
  263. * expected
  264. */
  265. buf = realloc(buf, MAX_LINE_LEN * 2);
  266. RETAILMSG(1, (TEXT("Line %d longer than expected,reallocating..\r\n"), line_num));
  267. } else if (i == MAX_LINE_LEN * 2) {
  268. /*
  269. * The line is already twice the expected maximum length
  270. * - maybe the bqfs/dffs needs to be fixed
  271. */
  272. RETAILMSG(1, (TEXT("Line %d too long, abort parsing..\r\n"),line_num));
  273. ret = FALSE;
  274. break;
  275. }
  276. }
  277. *buffer = buf;
  278. buf[i] = '\0';
  279. if (i < 1)
  280. ret = FALSE;
  281. return ret;
  282. }
  283. static BOOL get_cmd(FILE *bqfs_file, cmd_t *cmd)
  284. {
  285. char *res;
  286. char *tok;
  287. char *buf = NULL;
  288. BOOL ret;
  289. while ((ret = get_line(bqfs_file, &buf))) {
  290. if (buf[0] == ';') {
  291. /*
  292. * Comment line - ignore it and get the
  293. * next line
  294. */
  295. RETAILMSG(0, (TEXT("Comment line,line_num=%d\r\n"),line_num));
  296. free(buf);
  297. } else {
  298. break;
  299. }
  300. }
  301. if (!ret)
  302. goto error;
  303. cmd->line_num = line_num;
  304. tok = strtok(buf, ":");
  305. if (!tok || (strlen(tok) != 1)) {
  306. RETAILMSG(1, (TEXT("Error parsing command at line %d\r\n"),line_num));
  307. goto error;
  308. }
  309. switch (tok[0]) {
  310. case 'R':
  311. case 'r':
  312. cmd->cmd_type = CMD_R;
  313. if (!get_addr_n_reg(cmd))
  314. goto error;
  315. break;
  316. case 'W':
  317. case 'w':
  318. cmd->cmd_type = CMD_W;
  319. if (!get_addr_n_reg(cmd))
  320. goto error;
  321. if (!get_data_bytes(cmd))
  322. goto error;
  323. break;
  324. case 'C':
  325. case 'c':
  326. cmd->cmd_type = CMD_C;
  327. if (!get_addr_n_reg(cmd))
  328. goto error;
  329. if (!get_data_bytes(cmd))
  330. goto error;
  331. break;
  332. case 'X':
  333. case 'x':
  334. cmd->cmd_type = CMD_X;
  335. cmd->data_len = 1;       //only one data
  336. if (!get_delay(&cmd->data.delay))
  337. goto error;
  338. break;
  339. default:
  340. RETAILMSG(1, (TEXT("No command or unexpected command at line %d.\r\n"),line_num));
  341. goto error;
  342. }
  343. if(buf)
  344. {
  345. free(buf);
  346. }
  347. return TRUE;
  348. error:
  349. RETAILMSG(1, (TEXT("get_line error,line_num=%d\r\n"),line_num));
  350. cmd->cmd_type = CMD_INVALID;
  351. free(buf);
  352. return FALSE;
  353. }
  354. //Param:char *fname
  355. //  File to flash BQ27510 generate by TI's engineer.
  356. //  for example:bq27510G3.bqfs(with G2 update G3 firmware)
  357. int bqfs_flash(char *fname)
  358. {
  359. FILE *bqfs_file = NULL;
  360. cmd_t *cmd = NULL;
  361. int ret = 0;
  362. DWORD udwTemp;
  363. HANDLE hI2C=NULL;
  364. RETAILMSG(0,(TEXT("bqfs_flush beging...\r\n")));
  365. bqfs_file = fopen(fname, "r");
  366. if (!bqfs_file) {
  367. RETAILMSG(1,(TEXT("bqfs_flush fopen failed.\r\n")));
  368. ret = -1;
  369. goto end;
  370. }
  371. hI2C=CreateFile(BATT_I2C_PORT, GENERIC_READ | GENERIC_WRITE, 0,NULL, OPEN_EXISTING, 0, NULL);
  372. if(!hI2C)
  373. {
  374. RETAILMSG(1,(TEXT("bqfs_flash: I2c CreateFile failed.\r\n")));
  375. ret = -1;
  376. goto end;
  377. }
  378. //I2C相关配置寻址,根据自己平台修改相关实现
  379. //set slave address
  380. udwTemp=I2CSLAVEADDR;
  381. DeviceIoControl(hI2C, IOCTL_I2C_SET_SLAVE_ADDRESS, &udwTemp, sizeof(udwTemp), NULL, 0, NULL, NULL);
  382. //set i2c work mode
  383. udwTemp=I2C_SUBADDRESS_MODE_8;
  384. DeviceIoControl(hI2C, IOCTL_I2C_SET_SUBADDRESS_MODE, &udwTemp, sizeof(udwTemp), NULL, 0, NULL, NULL);
  385. //set i2c transfer speed
  386. udwTemp=SLOWSPEED_MODE;
  387. DeviceIoControl(hI2C, IOCTL_I2C_SET_BAUD_INDEX, &udwTemp, sizeof(udwTemp), NULL, 0, NULL, NULL);
  388. cmd = malloc(sizeof(cmd_t));
  389. if(!cmd)
  390. {
  391. RETAILMSG(1, (TEXT("bqfs_flash malloc failed.\r\n")));
  392. ret=-1;
  393. goto end;
  394. }
  395. while (get_cmd(bqfs_file, cmd) && execute_cmd(hI2C, cmd));
  396. if (feof(bqfs_file)) {
  397. RETAILMSG(1, (TEXT("programmed successfully!\r\n")));
  398. ret = 0;
  399. } else {
  400. RETAILMSG(1, (TEXT("programming failed!!\r\n")));
  401. ret = -1;
  402. }
  403. end:
  404. if (cmd)
  405. free(cmd);
  406. if(hI2C)
  407. {
  408. CloseHandle(hI2C);
  409. hI2C=NULL;
  410. }
  411. if (bqfs_file)
  412. fclose(bqfs_file);
  413. return ret;
  414. }

BQ27510 电量计的校准 的 C语言实现的更多相关文章

  1. C/C++学习----使用C语言代替cmd命令、cmd命令大全

    [开发环境] 物理机版本:Win 7 旗舰版(64位) IDE版本:Visual Studio 2013简体中文旗舰版(cn_visual_studio_ultimate_2013_with_upda ...

  2. 【转】android电池(四):电池 电量计(MAX17040)驱动分析篇

    关键词:android 电池  电量计  MAX17040 任务初始化宏 power_supply 平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台: ...

  3. C语言学习及应用笔记之七:C语言中的回调函数及使用方式

    我们在使用C语言实现相对复杂的软件开发时,经常会碰到使用回调函数的问题.但是回调函数的理解和使用却不是一件简单的事,在本篇我们根据我们个人的理解和应用经验对回调函数做简要的分析. 1.什么是回调函数 ...

  4. android电池(四):电池 电量计(MAX17040)驱动分析篇【转】

    本文转载自:http://blog.csdn.net/xubin341719/article/details/8969369 电池电量计,库仑计,用max17040这颗电量IC去计量电池电量,这种方法 ...

  5. Go语言经典库使用分析——高性能可扩展 HTTP 路由 httprouter(转载)

    转载自 飞雪无情的博客 Go语言(golang)的一个很大的优势,就是很容易的开发出网络后台服务,而且性能快,效率高.在开发后端HTTP网络应用服务的时候,我们需要处理很多HTTP的请求访问,比如常见 ...

  6. C语言 · 高精度加法

    问题描述 输入两个整数a和b,输出这两个整数的和.a和b都不超过100位. 算法描述 由于a和b都比较大,所以不能直接使用语言中的标准数据类型来存储.对于这种问题,一般使用数组来处理. 定义一个数组A ...

  7. Windows server 2012 添加中文语言包(英文转为中文)(离线)

    Windows server 2012 添加中文语言包(英文转为中文)(离线) 相关资料: 公司环境:亚马孙aws虚拟机 英文版Windows2012 中文SQL Server2012安装包,需要安装 ...

  8. iOS开发系列--Swift语言

    概述 Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题.Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在 ...

  9. C语言 · Anagrams问题

    问题描述 Anagrams指的是具有如下特性的两个单词:在这两个单词当中,每一个英文字母(不区分大小写)所出现的次数都是相同的.例如,"Unclear"和"Nuclear ...

随机推荐

  1. rails创建项目,部署,测试流程(rails5.0+ruby2.3.1)

    rails new test_app --skip-test-unit 不生成默认的test,稍后用rspeccd test_app 修改Gemfile(大部分为自动生成) source 'https ...

  2. windows下pip升级到8.1.2

    升级pip只要切换到easy_install-3.5目录下:  easy_install-3.5 pip==8.1.2

  3. emulator-arm.exe 已停止工作、 emulator-x86 已停止工作

    问题描述: emulator-arm.exe 已停止工作. emulator-x86 已停止工作.AVD模拟器启动一直黑屏.AVD模拟器启动一直显示andorid界面 解决方法: 1.   sdk的安 ...

  4. 使用php模拟post的几种方法

    <?phpfunction file_get_contents_post($url,$post){$options=array('http'=>array('method'=>'PO ...

  5. RobotFrameWork接口报文测试-----(二)demo的升级版

    在上一篇,简单的demo实现了讲xml的数据发送服务器端并取得recvi_buf,然后进行了简单的解析的操作.现在就要解决之前提过的2个问题: 1. 步骤这么多,难道每写一个脚本都要重复一次么? 2. ...

  6. css在IE和Firefox下的兼容性

    1.div的垂直居中问题 vertical-align:middle,将行距增加到和整个div高度一样,加line-height:200px;然后插入文字就垂直居中了.缺点是要控制内容不要换行. 2. ...

  7. knockout之各种数据绑定方法:text、attr、visible、html、css、style绑定

    http://knockoutjs.com/documentation/attr-binding.html(Knockout官网文档) 1.text绑定 目的:text 绑定到DOM元素上,使得该元素 ...

  8. Swift 注释

    注释就是对代码的解释和说明.目的是为了让别人和自己很容易看懂.为了让别人一看就知道这段代码是做什么用的. 正确的程序注释一般包括序言性注释和功能性注释.序言性注释的主要内容包括模块的接口.数据的描述和 ...

  9. DOM4J解析xml案例

  10. 好用的 diskpart 命令,操作磁盘分区,并创建 EFI 引导分区

    进入 win8 pe, 或在安装 win8 选择安装磁盘分区时按 shift+F10,都是可能用到 diskpart 去操作的时候. 进入cmd后, diskpart 进入 list disk---- ...