• 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 == '')     
    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, '');    
    80.     else {    
    81.         /* Terminate the token and make *SAVE_PTR point past it.  */    
    82.         *s = '';    
    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. ")));  
    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. ")));  
    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 "),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 "),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(" ")));  
    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 "),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 "),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 "), 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 "), 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 ")));  
    294.             ret = FALSE;  
    295.             break;  
    296.         }  
    297.   
    298.         if (((c == ' ') || (c == ' ') || (c == ' ')  
    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 "),line_num));  
    305.             if (c == ' ')  
    306.                 line_num++;  
    307.             continue;   /* blank line, let's continue */  
    308.         } else if (c == ' ') {  
    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.. "), 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.. "),line_num));  
    328.             ret = FALSE;  
    329.             break;  
    330.         }  
    331.     }  
    332.   
    333.     *buffer = buf;  
    334.     buf[i] = '';  
    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 "),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 "),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. "),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 "),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... ")));  
    434.   
    435.     bqfs_file = fopen(fname, "r");  
    436.     if (!bqfs_file) {  
    437.         RETAILMSG(1,(TEXT("bqfs_flush fopen failed. ")));  
    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. ")));  
    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. ")));  
    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! ")));  
    475.         ret = 0;  
    476.     } else {  
    477.         RETAILMSG(1, (TEXT("programming failed!! ")));  
    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. }  

  • 相关阅读:
    kettle入门(四) 之kettle取昨天时间&设置任意时间变量案例
    用法
    Win10任务计划调度执行kettle作业
    Kettle 合并记录和Merge Join组件实现数据增量迁移(数据同步比插入更新快)
    鼠标右键新建没有excel
    python的to_sql
    leetcode1105 Filling Bookcase Shelves
    leetcode96 Unique Binary Search Trees
    leetcode111 Minimum Depth of Binary Tree
    leetcode128 Longest Consecutive Sequence
  • 原文地址:https://www.cnblogs.com/LoongEmbedded/p/5298241.html
Copyright © 2020-2023  润新知