/*
Copyright 2022 Benjamin Vedder benjamin@vedder.se
This file is part of the VESC firmware.
The VESC firmware 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 3 of the License, or
(at your option) any later version.
The VESC firmware 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.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include "vesc_c_if.h"
#include "conf/datatypes.h"
#include "conf/confparser.h"
#include "conf/confxml.h"
#include
HEADER
typedef struct {
balance_config balance_conf;
} data;
static int get_cfg(uint8_t *buffer, bool is_default) {
data *d = (data*)ARG;
balance_config cfg = d->balance_conf;
if (is_default) {
confparser_set_defaults_balance_config(&cfg);
}
return confparser_serialize_balance_config(buffer, &cfg);
}
static bool set_cfg(uint8_t *buffer) {
data *d = (data*)ARG;
bool res = confparser_deserialize_balance_config(buffer, &(d->balance_conf));
// Store to EEPROM
if (res) {
uint32_t ints = sizeof(balance_config) / 4 + 1;
uint32_t buffer[ints];
bool write_ok = true;
memcpy(buffer, &(d->balance_conf), sizeof(balance_config));
for (uint32_t i = 0;i < ints;i++) {
eeprom_var v;
v.as_u32 = buffer[i];
if (!VESC_IF->store_eeprom_var(&v, i + 1)) {
write_ok = false;
break;
}
}
if (write_ok) {
eeprom_var v;
v.as_u32 = BALANCE_CONFIG_SIGNATURE;
VESC_IF->store_eeprom_var(&v, 0);
}
}
return res;
}
static int get_cfg_xml(uint8_t **buffer) {
// Note: As the address of data_balance_config_ is not known
// at compile time it will be relative to where it is in the
// linked binary. Therefore we add PROG_ADDR to it so that it
// points to where it ends up on the STM32.
*buffer = data_balance_config_ + PROG_ADDR;
return DATA_BALANCE_CONFIG__SIZE;
}
// Called when code is stopped
static void stop(void *arg) {
(void)arg;
VESC_IF->conf_custom_clear_configs();
}
INIT_FUN(lib_info *info) {
INIT_START
data *d = VESC_IF->malloc(sizeof(data));
memset(d, 0, sizeof(data));
// Read config from EEPROM if signature is correct
eeprom_var v;
uint32_t ints = sizeof(balance_config) / 4 + 1;
uint32_t buffer[ints];
bool read_ok = VESC_IF->read_eeprom_var(&v, 0);
if (read_ok && v.as_u32 == BALANCE_CONFIG_SIGNATURE) {
for (uint32_t i = 0;i < ints;i++) {
if (!VESC_IF->read_eeprom_var(&v, i + 1)) {
read_ok = false;
break;
}
buffer[i] = v.as_u32;
}
} else {
read_ok = false;
}
if (read_ok) {
memcpy(&(d->balance_conf), buffer, sizeof(balance_config));
} else {
confparser_set_defaults_balance_config(&(d->balance_conf));
}
info->stop_fun = stop;
info->arg = d;
VESC_IF->conf_custom_add_config(get_cfg, set_cfg, get_cfg_xml);
return true;
}