According to TI official MSP430 platform transplant modified, in the OMAP37XX (wince) platform testing, theoretically and platform-independent, you can use
/*================================================================================* Texas Instruments OMAP (TM) Platform software* (c) Copyright Texas Instruments, Incorporated. All rights reserved.** Use of this software are controlled by the terms and conditions found* in the license Agreement Unde R which this software have been supplied.*=========================================================================== =====*/////file:bqtool.c//#include <windows.h> #include <stdio.h> #include <stdlib.h> #include < string.h> #include <i2cproxy.h> #include "bq27500.h" #define Cmd_max_data_size512#define Max_line_len (cmd_ Max_data_size + 4) * 3) #define CMD_RETRY_DELAY100/* in MS */#define RETRY_LIMIT3TYPEDEF enum {cmd_invalid = 0,cmd_r,/* Re Ad */cmd_w,/* Write */cmd_c,/* Compare */cmd_x,/* Delay */} cmd_type_t;/* * Do not change the order of Fields-particular LY Reg * Should is immediately followed by data */typedef struct {cmd_type_t cmd_type;unsigned chaR addr;unsigned Char reg;union {unsigned char bytes[cmd_max_data_size + 1]; UINT delay;} data;unsigned Char Data_len; UINT32 Line_num; Char*line;} Cmd_t;static UINT32 line_num;/* Parse S into tokens separated by characters in DELIM. If S is NULL, the saved pointer in Save_ptr are used as the next starting point. For Example:char s[] = "-abc-=-def"; Char *sp; x = Strtok_r (S, "-", &SP); x = "abc", SP = "=-def" x = Strtok_r (NULL, "-=", &SP); x = "Def", sp = null x = Strtok_r (null, "=", &sp); x = NULL//s = "abc/0-def/0" */Static char *strtok_r (char *s, const char *delim, char **save_ptr) { Char *token; if (s = = NULL) s = *save_ptr; /* Scan leading delimiters. */S + = STRSPN (s, Delim); if (*s = = ' + ') return NULL; /* Find The end of the token. */token = s; s = strpbrk (token, delim); if (s = = NULL)/* This token finishes the string. */*save_ptr = STRCHR (token, ' + '); else {/* Terminate the token and make *save_ptr point past it. */*s = ' + '; *save_ptr = s + 1; } return token; }static Char *strtok (char *s, const char *delim) {static char *last; Return Strtok_r (S, Delim, &last);} Write i²c, modify the relevant implementation according to your own platform static BOOL I2c_write (HANDLE hi2c, cmd_t *cmd) {int Ret;dword udwtemp;if (hi2c) {udwtemp=cmd->addr >>1; DeviceIoControl (HI2C, ioctl_i2c_set_slave_address, &udwtemp, sizeof (UDWTEMP), NULL, 0, NULL, NULL); SetFilePointer (Hi2c,loword (Cmd->reg), null,file_begin); WriteFile (HI2C, Cmd->data.bytes, Cmd->data_len, &udwtemp, NULL)) {retailmsg (1, (TEXT ("ERROR:i2c_write:I2c WriteFile failed.\r\n ")));}} return TRUE;} Read I²c, modify the relevant implementation according to your own platform static BOOL I2c_read (HANDLE hi2c, cmd_t *cmd) {int Ret;dword udwtemp;if (hi2c) {udwtemp=cmd->addr >>1; DeviceIoControl (HI2C, ioctl_i2c_set_slave_address, &udwtemp, sizeof (udwtemp), NULL, 0, NULL, NULL); SetFilePointer (Hi2c,loword (Cmd->reg), null,file_begin); ReadFile (HI2C, Cmd->data.bytes, Cmd->data_len,&udwtemp, NULL)) {retailmsg (1, (TEXT ("ERROR:i2c_Read:I2c ReadFile failed.\r\n "))); return FALSE;} Else{cmd->data_len=udwtemp;}} return TRUE;} Static BOOL Do_exec_cmd (HANDLE i2c_file, cmd_t *cmd) {unsigned char tmp_buf[cmd_max_data_size];int j=0;switch (cmd-> Cmd_type) {case Cmd_r:return i2c_read (i2c_file, cmd); case Cmd_w:return I2c_write (i2c_file, cmd); case cmd_c:memcpy (Tmp_ BUF, Cmd->data.bytes, Cmd->data_len), if (!i2c_read (I2c_file, cmd)) return False;if (memcmp (Tmp_buf, cmd-> Data.bytes, Cmd->data_len)) {retailmsg (1, (TEXT ("Command C failed at line%d\r\n"), Cmd->line_num)); return FALSE;} Return true;case Cmd_x:sleep (cmd->data.delay); return true;default:retailmsg (1, (TEXT ("Unsupported command at line%") D\r\n "), Cmd->line_num)); return FALSE;}} Static BOOL Execute_cmd (HANDLE i2c_file, cmd_t *cmd) {int i = 1,j=0; BOOL ret; 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)) ; #if 0//only for Debug todo:deleteretailmsg (1, (TEXT ("line=%d:"), Cmd->line_num)); for (j=0;j<cmd->data_len;j + +) {retailmsg (1, (TEXT ("%02x"), Cmd->data.bytes[j]));} Retailmsg (1, (TEXT ("\ r \ n")); #endifret = Do_exec_cmd (i2c_file, cmd);//if execute failed,retry three timeswhile (!ret && I < Retry_limit) {Sleep (cmd_retry_delay); ret = Do_exec_cmd (I2c_file, CMD); i++;} if (!ret) {retailmsg (1, (TEXT ("Command execution failed at line%d addr=0x%02x reg=0x%02x\r\n"), Cmd->line_num, Cmd-> ; addr, Cmd->reg));} return ret;} Static BOOL Get_delay (UINT *delay) {char *tok; UINT Temp;tok = strtok (NULL, ""); if (!tok) return FALSE; /*end of line or file */if (1! = sscanf (tok, "%u", &temp)) {retailmsg (1, (TEXT ("Syntax error while parsing delay at Li Ne%d\r\n "), Line_num); return FALSE; /* Syntax error */}*delay = (UINT) Temp;return TRUE;} /* * Returns: * 0:success * 1:eof *-1:PARSE Error */static int get_byte (unsigned char *byte) {char *tok;unsigned char temp;tok = strtok (NULL, ""); if (!tok) return 1; /*end of line or file */if ((strlen (tok)! = 2) | | (Sscanf (Tok, "%2x", &temp)! = 1)) {retailmsg (1, (TEXT ("Syntax error at line%d\r\n"), Line_num)), return-1;/* Syntax Error */}*byte = (unsigned char) temp;r Eturn 0;/* Success */}static BOOL Get_addr_n_reg (cmd_t *cmd) {if (Get_byte (&CMD->ADDR)) return False;if (Get_byte ( &cmd->reg)) return False;return TRUE;} Static BOOL get_data_bytes (cmd_t *cmd) {int ret, i = 0;cmd->data_len = 0;do {ret = Get_byte (&cmd->data.bytes[i++] );} while (ret = = 0) && (i <= cmd_max_data_size)), if (ret = = 0) {retailmsg (1, (TEXT ("More than allowed number of D Ata bytes at line%d, Data_len%d, I%d\r\n "), Cmd->line_num,cmd->data_len, i)); return FALSE;} Cmd->data_len = I-1;return TRUE;} Static BOOL Get_line (FILE *bqfs_file, char **buffer) {int C;int i = 0; BOOL ret = True;char *buf;buf = malloc (max_line_len); Line_num++;while (1) {c = fgetc (Bqfs_file), if (feof (Bqfs_file)) {break;} else if (Ferror (Bqfs_file)) {retailmsg (1, (TEXT ("File read error\r\n")); ret = False;break;} if ((c = = ' \ r ') | | (c = = ' \ n ') | | (c = = ' \ t ') | | (c = = ")) && (i = = 0)) {/* * Skip leading white space, if any, on the beginning * of the line because this interferes with s Trtok */retailmsg (1, (TEXT ("leading whitespace at line%d\r\n"), line_num)); if (c = = ' \ n ') line_num++;continue;/* blank Lin E, let's continue */} else if (c = = ' \ n ') {/* We ' ve reached end of line */break;} buf[i++] = c;if (i = = Max_line_len) {/* * re-allocate in case the line is longer than * expected */BUF = realloc (buf, Max_ Line_len * 2); Retailmsg (1, (TEXT ("line%d longer than expected,reallocating. \ r \ n "), line_num);} else if (i = = Max_line_len * 2) {/* * The line is already twice the expected maximum length *-maybe the bqfs/dffs needs To is fixed */retailmsg (1, (TEXT ("line%d too long, abort parsing). \ r \ n "), line_num); ret = False;break;}} *buffer = buf;buf[i] = ' + '; if (I < 1) ret = False;return ret;} Static BOOL Get_cmd (FILE *bqfs_file, cmd_t *cmd) {char *res;char *tok;char *buf = NULL; BOOL ret;while (ret = Get_line (Bqfs_file, &buf)) {if (buf[0] = = '; ') {/* * Comment Line-ignore it and get the * Next line */retailmsg (0, (TEXT ("Comment line,line_num=%d\r\n"), Line_num)); fre E (BUF);} else {break;}} if (!ret) goto error;cmd->line_num = Line_num;tok = Strtok (buf, ":"); if (!tok | | (Strlen (tok)! = 1)) {retailmsg (1, (TEXT ("Error parsing command at line%d\r\n"), line_num)); goto Error;} Switch (tok[0]) {case ' R ': Case ' r ': Cmd->cmd_type = cmd_r;if (!get_addr_n_reg (cmd)) goto error;break;case ' W ': Case ' W ': Cmd->cmd_type = Cmd_w;if (!get_addr_n_reg (cmd)) goto error;if (!get_data_bytes (cmd)) goto error;break;case ' C ': Case ' C ': Cmd->cmd_type = cmd_c;if (!get_addr_n_reg (cmd)) goto error;if (!get_data_bytes (cmd)) goto error;break;case ' X ': Case ' x ': Cmd->cmd_type = Cmd_x;cmd->data_len = 1;//only One dataif (!get_delay (&AMp;cmd->data.delay)) Goto error;break;default:retailmsg (1, (TEXT ("No command or unexpected command at line%d.\r\n"), line_num)); goto error;} if (BUF) {free (BUF);} Return True;error:retailmsg (1, (TEXT ("Get_line error,line_num=%d\r\n"), Line_num)); cmd->cmd_type = Cmd_invalid; Free (BUF); return FALSE;} Param:char *fname//file to Flash BQ27510 generate by TI's engineer.//for example:bq27510G3.bqfs (with G2 update G3 FIRMWA RE) int Bqfs_flash (char *fname) {FILE *bqfs_file = null;cmd_t *cmd = null;int ret = 0;dword udwtemp; HANDLE Hi2c=null; Retailmsg (0, (Text ("Bqfs_flush beging...\r\n")), Bqfs_file = fopen (fname, "R"), if (!bqfs_file) {retailmsg (1, (Text (" Bqfs_flush fopen failed.\r\n ")); ret = -1;goto end;} Hi2c=createfile (Batt_i2c_port, Generic_read | Generic_write, 0,null, open_existing, 0, NULL), if (!HI2C) {retailmsg (1, (TEXT ("BQFS_FLASH:I2C CreateFile failed.\r\n")) ); ret = -1;goto end;} I²C-related configuration addressing, according to their own platform to modify the relevant implementation of//set slave addressudwtemp=i2cslaveaddr; DeviceIoControl (HI2C, Ioctl_i2c_set_slave_addreSS, &udwtemp, sizeof (UDWTEMP), NULL, 0, NULL, NULL);//set i²c work Modeudwtemp=i2c_subaddress_mode_8;d Eviceiocontrol (HI2C, Ioctl_i2c_set_subaddress_mode, &udwtemp, sizeof (UDWTEMP), NULL, 0, NULL, NULL);//set i²c Transfer Speedudwtemp=slowspeed_mode;deviceiocontrol (HI2C, Ioctl_i2c_set_baud_index, &udwtemp, sizeof (UDWTEMP) , NULL, 0, NULL, null), cmd = malloc (sizeof (cmd_t)), if (!cmd) {retailmsg (1, (TEXT ("Bqfs_flash malloc failed.\r\n")); ret=- 1;goto end;} while (Get_cmd (bqfs_file, cmd) && execute_cmd (hi2c, cmd)), if (feof (Bqfs_file)) {retailmsg (1, (TEXT ("programmed Successfully!\r\n ")); ret = 0;} else {retailmsg (1, (TEXT ("Programming failed!! \ r \ n ")); ret =-1;} End:if (cmd) free (cmd), if (HI2C) {CloseHandle (HI2C); hi2c=null;} if (bqfs_file) fclose (bqfs_file); return ret;}
C-language implementation of the calibration of the BQ27510 fuel gauge