BQ27510 电量计的校准 的 C语言实现

点击打开链接

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

posted @ 2015-07-28 13:44  LoongEmbedded  阅读(732)  评论(0编辑  收藏  举报