X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=ao-tools%2Flib%2Fao-eeprom-read.c;fp=ao-tools%2Flib%2Fao-eeprom-read.c;h=7ed47151255a25c9fd410bed37467397a9c89241;hp=0000000000000000000000000000000000000000;hb=98f7c1c116aab672a29db1f81213cabe2d72ae16;hpb=e3eb285ff6be17afe592dca4a2fb5526c0626283 diff --git a/ao-tools/lib/ao-eeprom-read.c b/ao-tools/lib/ao-eeprom-read.c new file mode 100644 index 00000000..7ed47151 --- /dev/null +++ b/ao-tools/lib/ao-eeprom-read.c @@ -0,0 +1,258 @@ +/* + * Copyright © 2017 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include "ao-eeprom-read.h" +#include +#include +#include + +static struct json_object * +ao_eeprom_read_config(FILE *file) +{ + char line[1024]; + struct json_tokener *tok; + struct json_object *obj = NULL; + enum json_tokener_error err; + + tok = json_tokener_new(); + if (!tok) + goto fail_tok; + + for (;;) { + if (fgets(line, sizeof(line), file) == NULL) + goto fail_read; + obj = json_tokener_parse_ex(tok, line, strlen(line)); + err = json_tokener_get_error(tok); + if (err == json_tokener_success) + break; + if (err != json_tokener_continue) + goto fail_read; + } + json_tokener_free(tok); + return obj; +fail_read: + json_tokener_free(tok); +fail_tok: + return NULL; +} + +static int +ao_eeprom_read_byte(FILE *file) +{ + int byte; + if (fscanf(file, "%x", &byte) != 1) + return EOF; + return byte; +} + +static int +ao_eeprom_read_data(FILE *file, struct ao_eeprom *eeprom) +{ + uint8_t *data = NULL, *ndata; + int len = 0; + int size = 0; + int byte; + + data = malloc(size = 64); + if (!data) + goto fail_alloc; + while ((byte = ao_eeprom_read_byte(file)) != EOF) { + if (len == size) { + ndata = realloc(data, size *= 2); + if (!ndata) + goto fail_realloc; + data = ndata; + } + data[len++] = (uint8_t) byte; + } + eeprom->data = data; + eeprom->len = len; + return 1; +fail_realloc: + free(data); +fail_alloc: + return 0; +} + +static int +ao_json_get_int(struct json_object *obj, const char *key, int def) +{ + struct json_object *value; + int i; + + if (!json_object_object_get_ex(obj, key, &value)) + return def; + errno = 0; + i = (int) json_object_get_int(value); + if (errno != 0) + return def; + return i; +} + +static const char * +ao_json_get_string(struct json_object *obj, const char *key, const char *def) +{ + struct json_object *value; + const char *str; + + if (!json_object_object_get_ex(obj, key, &value)) + return def; + errno = 0; + str = json_object_get_string(value); + if (errno) + return def; + if (!str) + return def; + return str; +} + +static int +ao_eeprom_get_pyro(struct ao_config *config, struct json_object *obj) +{ + struct json_object *pyros; + struct json_object *pyro; + int i, p; + + if (!json_object_object_get_ex(obj, "pyros", &pyros)) + return 1; + + if (json_object_get_type(pyros) != json_type_array) + return 0; + + for (i = 0; i < json_object_array_length(pyros); i++) { + pyro = json_object_array_get_idx(pyros, i); + if (pyro) { + p = ao_json_get_int(pyro, "channel", -1); + if (0 <= p && p < AO_PYRO_NUM) { + config->pyro[p].flags = ao_json_get_int(pyro, "flags", 0); + config->pyro[p].accel_less = ao_json_get_int(pyro, "accel_less", 0); + config->pyro[p].accel_greater = ao_json_get_int(pyro, "accel_greater", 0); + config->pyro[p].speed_less = ao_json_get_int(pyro, "speed_less", 0); + config->pyro[p].speed_greater = ao_json_get_int(pyro, "speed_greater", 0); + config->pyro[p].height_less = ao_json_get_int(pyro, "height_less", 0); + config->pyro[p].height_greater = ao_json_get_int(pyro, "height_greater", 0); + config->pyro[p].orient_less = ao_json_get_int(pyro, "orient_less", 0); + config->pyro[p].orient_greater = ao_json_get_int(pyro, "orient_greater", 0); + config->pyro[p].time_less = ao_json_get_int(pyro, "time_less", 0); + config->pyro[p].time_greater = ao_json_get_int(pyro, "time_greater", 0); + config->pyro[p].delay = ao_json_get_int(pyro, "delay", 0); + config->pyro[p].state_less = ao_json_get_int(pyro, "state_less", 0); + config->pyro[p].state_greater_or_equal = ao_json_get_int(pyro, "state_greater_or_equal", 0); + config->pyro[p].motor = ao_json_get_int(pyro, "motor", 0); + } + } + } + return 1; +} + +static int +ao_eeprom_get_ms5607(struct ao_ms5607_prom *ms5607_prom, struct json_object *obj) +{ + struct json_object *ms5607; + + if (!json_object_object_get_ex(obj, "ms5607", &ms5607)) + return 1; + + if (json_object_get_type(ms5607) != json_type_object) + return 0; + + ms5607_prom->reserved = ao_json_get_int(ms5607, "reserved", 0); + ms5607_prom->sens = ao_json_get_int(ms5607, "sens", 0); + ms5607_prom->off = ao_json_get_int(ms5607, "off", 0); + ms5607_prom->tcs = ao_json_get_int(ms5607, "tcs", 0); + ms5607_prom->tco = ao_json_get_int(ms5607, "tco", 0); + ms5607_prom->tref = ao_json_get_int(ms5607, "tref", 0); + ms5607_prom->tempsens = ao_json_get_int(ms5607, "tempsens", 0); + ms5607_prom->crc = ao_json_get_int(ms5607, "crc", 0); + return 1; +} + +static int +ao_eeprom_get_config(struct ao_eeprom *ao_eeprom, struct json_object *obj) +{ + struct ao_config *config = &ao_eeprom->config; + const char *s; + + if (json_object_get_type(obj) != json_type_object) + return 0; + + ao_eeprom->log_format = ao_json_get_int(obj, "log_format", 0); + ao_eeprom->serial_number = ao_json_get_int(obj, "serial", 0); + + config->major = ao_json_get_int(obj, "config_major", 0); + config->minor = ao_json_get_int(obj, "config_minor", 0); + if (config->major == 0 || config->minor == 0) + return 0; + + config->main_deploy = ao_json_get_int(obj, "main_deploy", 250); + config->accel_plus_g = ao_json_get_int(obj, "accel_cal_plus", 0); + + s = ao_json_get_string(obj, "callsign", "N0CALL"); + strncpy(config->callsign, s, sizeof(config->callsign)-1); + + config->apogee_delay = ao_json_get_int(obj, "apogee_delay", 0); + config->accel_minus_g = ao_json_get_int(obj, "accel_cal_minus", 0); + config->radio_cal = ao_json_get_int(obj, "radio_calibration", 0); + config->flight_log_max = ao_json_get_int(obj, "flight_log_max", 0); + config->ignite_mode = ao_json_get_int(obj, "ignite_mode", 0); + config->pad_orientation = ao_json_get_int(obj, "pad_orientation", 0); + config->radio_setting = ao_json_get_int(obj, "radio_setting", 0); + config->radio_enable = ao_json_get_int(obj, "radio_enable", 1); + config->frequency = ao_json_get_int(obj, "frequency", 434550); + config->apogee_lockout = ao_json_get_int(obj, "apogee_lockout", 0); + if (!ao_eeprom_get_pyro(config, obj)) + return 0; + config->ignite_mode = ao_json_get_int(obj, "ignite_mode", 0); + config->ignite_mode = ao_json_get_int(obj, "ignite_mode", 0); + config->ignite_mode = ao_json_get_int(obj, "ignite_mode", 0); + config->ignite_mode = ao_json_get_int(obj, "ignite_mode", 0); + config->ignite_mode = ao_json_get_int(obj, "ignite_mode", 0); + config->ignite_mode = ao_json_get_int(obj, "ignite_mode", 0); + + if (!ao_eeprom_get_ms5607(&ao_eeprom->ms5607_prom, obj)) + return 0; + + return 1; +} + +struct ao_eeprom * +ao_eeprom_read(FILE *file) +{ + struct ao_eeprom *ao_eeprom; + struct json_object *obj; + int ret; + + ao_eeprom = calloc(1, sizeof (struct ao_eeprom)); + if (!ao_eeprom) + goto fail_ao_eeprom; + + obj = ao_eeprom_read_config(file); + if (!obj) + goto fail_config; + + ret = ao_eeprom_get_config(ao_eeprom, obj); + json_object_put(obj); + if (!ret) + goto fail_config; + + if (!ao_eeprom_read_data(file, ao_eeprom)) + goto fail_data; + + return ao_eeprom; +fail_data: +fail_config: + free(ao_eeprom); +fail_ao_eeprom: + return NULL; +}