00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #include <stdio.h>
00035 #include <string.h>
00036 #include <stdlib.h>
00037 #include <unistd.h>
00038 #include <termios.h>
00039
00040
00041 #include "proto.h"
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #define ION_SERIO_FLAGS CS8
00054 #define ION_SERIO_SPEED B115200
00055
00056 #define ACTION_FIRMWARE 1
00057 #define ACTION_BOOTLOADER 2
00058 #define ACTION_GASGAUGE 3
00059 #define ACTION_READTYPE 4
00060 #define ACTION_WRITETYPE 5
00061
00062 #define DR1000 0
00063
00064 #define VPRINTF(...) { if (verbose) printf(__VA_ARGS__); }
00065
00066 static char *device_types[] = {
00067 "DR1000",
00068 "DR1000S",
00069 "DR1000SW",
00070 "DR800",
00071 "DR800S",
00072 "DR800SG",
00073 "DR800SW",
00074 NULL
00075 };
00076
00077
00078
00079
00080
00081
00082 static int action = ACTION_FIRMWARE;
00083 static int force_update = 0;
00084 static int only_check = 0;
00085 static int gg_req_version = 0;
00086 static int verbose = 1;
00087 char *filename;
00088 uint8_t devicetype;
00089 static int new_devicetype;
00090
00091
00092
00093
00094
00095
00096 static void usage();
00097 static int check_firmware(char *filename, uint16_t *version);
00098 static void parse_args(int argc, char **argv);
00099
00100
00101
00102
00103
00104
00105 int device_type_from_name(char *name)
00106 {
00107 int i = 0;
00108 while (device_types[i]) {
00109 if (strcasecmp(name, device_types[i]) == 0)
00110 {
00111 return i;
00112 }
00113 i++;
00114 }
00115 return 0xFF;
00116 }
00117
00118 void handle_gasgauge()
00119 {
00120
00121 if(devicetype != DR1000)
00122 {
00123 fatal("No support for GasGauge updates on DR800 series devices.");
00124 }
00125
00126 if (!micro_check_battery_charge(25))
00127 {
00128 fatalnum(2, "Battery too low or not charging");
00129 }
00130 if (!force_update)
00131 {
00132 uint16_t gg_ver_fw, gg_ver_hw;
00133 if (gasgauge_get_versions(&gg_ver_fw, &gg_ver_hw))
00134 {
00135 fatal("Can't get gas gauge firmware version");
00136 }
00137 if (gg_ver_fw!=gg_req_version)
00138 {
00139 fatal("Invalid gas gauge firmware: got %04d, need %04d",
00140 gg_ver_fw, gg_req_version);
00141 }
00142 usleep(1000000);
00143 }
00144 gasgauge_flash(filename);
00145 }
00146
00147 void handle_firmware()
00148 {
00149 uint16_t bver, aver, fver;
00150
00151 if (!check_firmware(filename, &fver))
00152 {
00153 fatal("Can't open firmware file %s", filename);
00154 }
00155
00156 if (devicetype == DR1000)
00157 {
00158 micro_enter_mode(MODE_BOOT);
00159 }
00160
00161 micro_get_versions(&bver, &aver);
00162 VPRINTF("Bootloader v%d.%d, app v%d.%d.\n",
00163 bver>>8,bver&0xFF,aver>>8,aver&0xFF);
00164 if (only_check)
00165 return;
00166 if ((!force_update) &&
00167 (((action != ACTION_BOOTLOADER) && fver<=aver && aver!=0xFFFF) ||
00168 ((action == ACTION_BOOTLOADER) && fver<=bver && bver!=0xFFFF)))
00169 {
00170
00171 warning("Firmware '%s' is v%d.%d, not upgrading.",
00172 filename, fver>>8, fver&0xFF);
00173 }
00174 else
00175 {
00176
00177 if (devicetype == DR1000)
00178 {
00179
00180 if (action == ACTION_BOOTLOADER)
00181 {
00182 fatal("DR1000 doesn't support bootloader upgrades");
00183 }
00184 else
00185 {
00186 micro_erase(MODE_APP, DR1000_APPL_ADDR_MIN, DR1000_APPL_ADDR_MAX);
00187 dr1000_micro_program_application(filename);
00188 }
00189 }
00190 else
00191 {
00192
00193 if (action == ACTION_BOOTLOADER)
00194 {
00195 micro_erase(MODE_BOOT, DR800_BOOT_ADDR_MIN, DR800_BOOT_ADDR_MAX);
00196 dr800_micro_program_bootloader(filename);
00197 }
00198 else
00199 {
00200 micro_erase(MODE_APP, DR800_APPL_ADDR_MIN, DR800_APPL_ADDR_MAX);
00201 dr800_micro_program_application(filename);
00202 }
00203 }
00204 }
00205 }
00206
00207 void handle_devicetype()
00208 {
00209 int mode = micro_get_mode();
00210 VPRINTF("Micro in %s mode\n", mode==MODE_APP ? "app" : "boot");
00211
00212 if (action == ACTION_READTYPE)
00213 {
00214 int devtype = micro_read_devicetype(mode);
00215 VPRINTF("Device type: ");
00216 printf("%s (%d)\n",
00217 devtype == 0xFF ? "Unknown" : device_types[devtype], devtype);
00218 }
00219 else
00220 {
00221 VPRINTF("Writing devicetype %d\n", new_devicetype);
00222 micro_write_devicetype(mode, new_devicetype);
00223 }
00224 }
00225
00226 int main(int argc, char **argv)
00227 {
00228 char *portname;
00229
00230
00231 parse_args(argc, argv);
00232 if (((action == ACTION_GASGAUGE || action == ACTION_FIRMWARE || action == ACTION_BOOTLOADER) &&
00233 ((argc-optind)!=2)) ||
00234 (((action == ACTION_WRITETYPE || action == ACTION_READTYPE) &&
00235 ((argc-optind)!=1))))
00236 {
00237 usage();
00238 }
00239 portname = argv[optind];
00240 filename = argv[optind+1];
00241
00242 port_open(portname, ION_SERIO_FLAGS, ION_SERIO_SPEED);
00243
00244 micro_get_devicetype(&devicetype);
00245 if(devicetype==0)
00246 {
00247 VPRINTF("Device type is DR1000 Series\n");
00248 }
00249 else
00250 {
00251 VPRINTF("Device type is DR800 Series\n");
00252 }
00253
00254 if (action == ACTION_GASGAUGE)
00255 {
00256 handle_gasgauge();
00257 }
00258 else if (action == ACTION_FIRMWARE || action == ACTION_BOOTLOADER)
00259 {
00260 handle_firmware();
00261 }
00262 else if (action == ACTION_WRITETYPE || action == ACTION_READTYPE)
00263 {
00264 handle_devicetype();
00265 }
00266 else
00267 {
00268 fatal("Unknown action: %d\n",action);
00269 }
00270
00271 return 0;
00272 }
00273
00274
00275
00276
00277
00278
00279 static void usage()
00280 {
00281 printf("kbdupgrade - keyboard microcontroller firmware upgrader\n");
00282 printf(" usage: kbdupgrade <options> <serial port> <firmware file>\n");
00283 printf(" options:\n");
00284 printf(" -b Upgrade bootloader instead of application\n");
00285 printf(" -c Only do version check\n");
00286 printf(" -f Ignore version check and force upgrade\n");
00287 printf(" -g Upgrade gas gauge, instead of micro\n");
00288 printf(" -q Don't print as much\n");
00289 printf(" -r XXXX Required gas gauge firmware version\n");
00290 printf(" -s XXXX Set device type (XXXX = DR[800|1000][SWG])\n");
00291 printf(" -t Get device type\n");
00292 printf(" -h This text\n");
00293 exit(1);
00294 }
00295
00296
00297 static int check_firmware(char *filename, uint16_t *version)
00298 {
00299 FILE *f = fopen(filename, "rb");
00300 if (f)
00301 {
00302 fread(version, 2, 1, f);
00303 fclose(f);
00304 return 1;
00305 }
00306 return 0;
00307 }
00308
00309
00310 static void parse_args(int argc, char **argv)
00311 {
00312 int c;
00313
00314 while (( c = getopt(argc, argv, "bcfghr:s:tq")) != -1)
00315 {
00316 switch (c)
00317 {
00318 case 'b':
00319 action = ACTION_BOOTLOADER;
00320 break;
00321
00322 case 'g':
00323 action = ACTION_GASGAUGE;
00324 break;
00325
00326 case 's':
00327 action = ACTION_WRITETYPE;
00328 new_devicetype = device_type_from_name(optarg);
00329 break;
00330
00331 case 't':
00332 action = ACTION_READTYPE;
00333 break;
00334
00335 case 'c':
00336 only_check = 1;
00337 break;
00338
00339 case 'f':
00340 force_update = 1;
00341 break;
00342
00343 case 'q':
00344 verbose = 0;
00345 break;
00346
00347 case 'r':
00348 gg_req_version = atoi(optarg);
00349 printf("Required gas gauge version: %04d\n", gg_req_version);
00350 break;
00351
00352 case 'h':
00353 default:
00354 usage();
00355 break;
00356 }
00357 }
00358 }