FreeCalypso > hg > freecalypso-tools
view ffstools/newcomp/compile-fc-chg.c @ 461:10e168596dfd
doc/SIM-hardware-debugging: article written
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 10 Feb 2019 20:40:56 +0000 |
parents | 0937521ec2f4 |
children |
line wrap: on
line source
/* * This utility compiles a FreeCalypso battery charging configuration file * from ASCII source into the binary form suitable for uploading into * /etc/charging on a FreeCalypso device. */ #include <ctype.h> #include <string.h> #include <strings.h> #include <stdio.h> #include <stdlib.h> #include "../../rvinterf/include/exitcodes.h" char *infname; FILE *inf; char linebuf[256]; int lineno; struct setting { char *kw; int allow_always; int allow_never; int mandatory; unsigned default_value; unsigned set_value; int is_set; } settings[] = { {"start-delay", 0, 0, 0, 0, 0, 0}, {"start-threshold", 1, 1, 1, 0, 0, 0}, {"restart-threshold", 0, 1, 1, 0, 0, 0}, {"ci2cv-threshold", 0, 0, 1, 0, 0, 0}, {"cv-initial-setpoint", 0, 0, 1, 0, 0, 0}, {"cv-ctrl-loop-high", 0, 0, 1, 0, 0, 0}, {"cv-ctrl-loop-low", 0, 0, 1, 0, 0, 0}, {"cv-dac-max-incr", 0, 0, 1, 0, 0, 0}, {"cv-dac-max-decr", 0, 0, 1, 0, 0, 0}, {"cv-ctrl-loop-sample-count", 0, 0, 1, 0, 0, 0}, {"overvoltage", 0, 0, 0, 0xFFFF, 0, 0}, {"ci-current", 0, 0, 1, 0, 0, 0}, {"end-current", 0, 0, 1, 0, 0, 0}, {"ichg-max-spike", 0, 0, 0, 0x400, 0, 0}, {"ichg-low-samples-needed", 0, 0, 1, 0, 0, 0}, {"charging-time-limit", 0, 0, 0, 0xFFFF, 0, 0}, {"restart-delay", 0, 0, 0, 0, 0, 0}, {"i2v-offset", 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0} }; static void do_setting(tp, arg) struct setting *tp; char *arg; { char *endp; if (tp->allow_always && !strcmp(arg, "always")) { tp->set_value = 0xFFFF; return; } if (tp->allow_never && !strcmp(arg, "never")) { tp->set_value = 0; return; } tp->set_value = strtoul(arg, &endp, 0); if (*endp || tp->set_value > 0xFFFF) { fprintf(stderr, "%s line %d: invalid argument to %s\n", infname, lineno, tp->kw); exit(ERROR_USAGE); } } process_line() { char *cp, *kw, *arg; struct setting *tp; for (cp = linebuf; isspace(*cp); cp++) ; if (*cp == '\0' || *cp == '#') return(0); kw = cp; while (*cp && !isspace(*cp)) cp++; if (!*cp) { inv: fprintf(stderr, "%s line %d: invalid syntax\n", infname, lineno); exit(ERROR_USAGE); } *cp++ = '\0'; while (isspace(*cp)) cp++; if (*cp == '\0' || *cp == '#') goto inv; arg = cp; while (*cp && !isspace(*cp)) cp++; if (*cp) *cp++ = '\0'; while (isspace(*cp)) cp++; if (*cp != '\0' && *cp != '#') goto inv; for (tp = settings; tp->kw; tp++) if (!strcmp(tp->kw, kw)) break; if (!tp->kw) { fprintf(stderr, "%s line %d: setting \"%s\" not known\n", infname, lineno, kw); exit(ERROR_USAGE); } if (tp->is_set) { fprintf(stderr, "%s line %d: %s set more than once\n", infname, lineno, kw); exit(ERROR_USAGE); } do_setting(tp, arg); tp->is_set = 1; return(1); } set_defaults() { struct setting *tp; for (tp = settings; tp->kw; tp++) { if (tp->is_set) continue; if (tp->mandatory) { fprintf(stderr, "error: required setting %s is not set\n", tp->kw); exit(ERROR_USAGE); } tp->set_value = tp->default_value; } } write_output(filename) char *filename; { FILE *of; struct setting *tp; of = fopen(filename, "w"); if (!of) { perror(filename); exit(ERROR_UNIX); } for (tp = settings; tp->kw; tp++) { putc(tp->set_value, of); putc(tp->set_value >> 8, of); } fclose(of); } main(argc, argv) char **argv; { if (argc != 3) { fprintf(stderr, "usage: %s srcfile output-binfile\n", argv[0]); exit(ERROR_USAGE); } infname = argv[1]; inf = fopen(infname, "r"); if (!inf) { perror(infname); exit(ERROR_UNIX); } for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) process_line(); fclose(inf); set_defaults(); write_output(argv[2]); exit(0); }