15 Commits

26 changed files with 665 additions and 591 deletions

View File

@@ -37,7 +37,8 @@
* If the pointer is invalid, the function using this macro will return with
* CONFIG_PARSER_PARAM_ERR
*/
#define config_parser_check_handle(handle) do { if (!(handle) || \
#define config_parser_check_handle(handle) do { \
if (!(handle) || \
((struct config_parser *)(handle))->magic != CONFIG_PARSER_MAGIC) \
return CONFIG_PARSER_PARAM_ERR; \
} while (0)
@@ -92,17 +93,17 @@ static int parse_value(struct config_parser_entry *entry, char *value_start_toke
if (value_start_token[0] != '-') {
/* Try parsing as ul */
entry->value.uint_val = strtoul(value_start_token, &endptr, 0);
if (endptr == value_start_token) {
if (endptr == value_start_token)
return -1;
}
entry->type = CONFIG_PARSER_TYPE_UINT;
goto exit;
} else {
/* Try parsing as int */
entry->value.int_val = strtod(value_start_token, &endptr);
if (endptr == value_start_token) {
if (endptr == value_start_token)
return -1;
}
entry->type = CONFIG_PARSER_TYPE_INT;
}
@@ -110,14 +111,16 @@ exit:
return 0;
}
enum config_parser_ret config_parser_get_line(config_parser_handle_t handle, struct config_parser_entry *entry, bool force_float)
enum config_parser_ret config_parser_get_line(config_parser_handle_t handle, struct config_parser_entry *entry,
bool force_float)
{
struct config_parser *p;
config_parser_check_handle(handle);
p = CONFIG_PARSER(handle);
char *token;
int token_round = 0;
config_parser_check_handle(handle);
p = CONFIG_PARSER(handle);
if (!entry)
return CONFIG_PARSER_PARAM_ERR;
@@ -131,7 +134,6 @@ enum config_parser_ret config_parser_get_line(config_parser_handle_t handle, str
if (token[0] == '#') {
if (token_round == 0)
return CONFIG_PARSER_LINE_COMMENT;
else
break;
}
@@ -140,9 +142,8 @@ enum config_parser_ret config_parser_get_line(config_parser_handle_t handle, str
entry->name = token;
break;
case 1: /* = Symbol */
if (strcmp(token, "=")) {
if (strcmp(token, "="))
return CONFIG_PARSER_LINE_MALFORM;
}
break;
case 2: /* VALUE */
if (parse_value(entry, token))
@@ -172,6 +173,7 @@ enum config_parser_ret config_parser_reset_to_start(config_parser_handle_t handl
{
FRESULT res;
struct config_parser *p;
config_parser_check_handle(handle);
p = CONFIG_PARSER(handle);
@@ -194,6 +196,7 @@ enum config_parser_ret config_parser_close_file(config_parser_handle_t handle)
{
struct config_parser *p;
FRESULT res;
config_parser_check_handle(handle);
p = CONFIG_PARSER(handle);

View File

@@ -70,14 +70,14 @@ struct timing_monitor_info {
* You have to call safety_controller_handle
* If this function fails, it will hang, because errors in the safety controller are not recoverable
*/
void safety_controller_init();
void safety_controller_init(void);
/**
* @brief Handle the safety controller.
* @note This function must be executed periodically in order to prevent the watchdog from resetting the firmware
* @return 0 if successful
*/
int safety_controller_handle();
int safety_controller_handle(void);
/**
* @brief Report one or multiple errors to the safety controller
@@ -170,13 +170,13 @@ bool safety_controller_get_flags_by_mask(enum safety_flag mask);
* @brief Get the count of error flags
* @return Error flag count
*/
uint32_t safety_controller_get_flag_count();
uint32_t safety_controller_get_flag_count(void);
/**
* @brief Get the count of analog monitors
* @return Analog monitor count
*/
uint32_t safety_controller_get_analog_monitor_count();
uint32_t safety_controller_get_analog_monitor_count(void);
/**
* @brief Get an error flag's name by its index.

View File

@@ -28,12 +28,12 @@
* @brief Initialize the SPI for the eeprom.
* @return 0 if succesful
*/
int spi_eeprom_init();
int spi_eeprom_init(void);
/**
* @brief Uninitialize the SPI EEPROM
*/
void spi_eeprom_deinit();
void spi_eeprom_deinit(void);
/**
* @brief Read from SPI EEPROM

View File

@@ -33,7 +33,7 @@ enum random_number_error {
void random_number_gen_init(bool int_enable);
void random_number_gen_deinit();
void random_number_gen_deinit(void);
void random_number_gen_reset(bool int_en);

View File

@@ -33,4 +33,6 @@ void stm_unique_id_get(uint32_t *high, uint32_t *mid, uint32_t *low);
void stm_dev_rev_id_get(uint32_t *device_id, uint32_t *revision_id);
void stm_cpuid_get(uint8_t *implementer, uint8_t *variant, uint16_t *part_no, uint8_t *rev);
#endif /* __UNIQUE_ID_H__ */

View File

@@ -78,5 +78,6 @@ void panic_mode(void)
}
/* Let the watchdog do the rest */
while (1);
while (1)
;
}

View File

@@ -1,22 +1,22 @@
/* Reflow Oven Controller
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @addtogroup safety-adc
@@ -60,7 +60,8 @@ void safety_adc_init(void)
rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(RCC_AHB1ENR_DMA2EN));
if (hw_rev != HW_REV_V1_2) {
rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(SAFETY_ADC_SUPPLY_VOLTAGE_MONITOR_PORT_RCC_MASK));
rcc_manager_enable_clock(&RCC->AHB1ENR,
BITMASK_TO_BITNO(SAFETY_ADC_SUPPLY_VOLTAGE_MONITOR_PORT_RCC_MASK));
SAFETY_ADC_SUPPLY_VOLTAGE_MONITOR_PORT->MODER &= MODER_DELETE(SAFETY_ADC_SUPPLY_VOLTAGE_MONITOR_PIN);
SAFETY_ADC_SUPPLY_VOLTAGE_MONITOR_PORT->MODER |= ANALOG(SAFETY_ADC_SUPPLY_VOLTAGE_MONITOR_PIN);
}
@@ -72,7 +73,7 @@ void safety_adc_init(void)
SAFETY_ADC_ADC_PERIPHERAL->SMPR1 |= ADC_SMPR1_SMP17 | ADC_SMPR1_SMP16 | ADC_SMPR1_SMP15;
/* Standard sequence. Measure all channels in one sequence */
SAFETY_ADC_ADC_PERIPHERAL->SQR1 = (SAFETY_ADC_NUM_OF_CHANNELS - 1) << 20 ;
SAFETY_ADC_ADC_PERIPHERAL->SQR1 = (SAFETY_ADC_NUM_OF_CHANNELS - 1) << 20;
SAFETY_ADC_ADC_PERIPHERAL->SQR2 = 0UL;
SAFETY_ADC_ADC_PERIPHERAL->SQR3 = 0UL;
@@ -97,7 +98,8 @@ void safety_adc_init(void)
DMA2_Stream4->PAR = (uint32_t)&SAFETY_ADC_ADC_PERIPHERAL->DR;
DMA2_Stream4->M0AR = (uint32_t)safety_adc_conversions;
DMA2_Stream4->NDTR = SAFETY_ADC_NUM_OF_CHANNELS;
DMA2_Stream4->CR = DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_CIRC | DMA_SxCR_TCIE | DMA_SxCR_EN;
DMA2_Stream4->CR = DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_CIRC |
DMA_SxCR_TCIE | DMA_SxCR_EN;
NVIC_EnableIRQ(DMA2_Stream4_IRQn);
/* Enable ADC */
@@ -175,7 +177,7 @@ void safety_adc_trigger_meas(void)
safety_adc_triggered = 1;
}
void DMA2_Stream4_IRQHandler()
void DMA2_Stream4_IRQHandler(void)
{
uint32_t hisr;

View File

@@ -1,22 +1,22 @@
/* Reflow Oven Controller
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @addtogroup safety-controller
@@ -298,7 +298,7 @@ static const struct crc_monitor_register meas_adc_crc_regs[] = {
ADC_SQR2_SQ12 | ADC_SQR2_SQ11 | ADC_SQR2_SQ10 | ADC_SQR2_SQ9 |
ADC_SQR2_SQ8 | ADC_SQR2_SQ7, 4),
CRC_MON_REGISTER_ENTRY(ADC_PT1000_PERIPH->SQR3, ADC_SQR3_SQ6 | ADC_SQR3_SQ5 | ADC_SQR3_SQ4 |
ADC_SQR3_SQ3| ADC_SQR3_SQ2 | ADC_SQR3_SQ1, 4),
ADC_SQR3_SQ3 | ADC_SQR3_SQ2 | ADC_SQR3_SQ1, 4),
{NULL, 0, 0}
};
@@ -314,12 +314,11 @@ static const struct crc_monitor_register safety_adc_crc_regs[] = {
ADC_SQR2_SQ12 | ADC_SQR2_SQ11 | ADC_SQR2_SQ10 | ADC_SQR2_SQ9 |
ADC_SQR2_SQ8 | ADC_SQR2_SQ7, 4),
CRC_MON_REGISTER_ENTRY(SAFETY_ADC_ADC_PERIPHERAL->SQR3, ADC_SQR3_SQ6 | ADC_SQR3_SQ5 | ADC_SQR3_SQ4 |
ADC_SQR3_SQ3| ADC_SQR3_SQ2 | ADC_SQR3_SQ1, 4),
ADC_SQR3_SQ3 | ADC_SQR3_SQ2 | ADC_SQR3_SQ1, 4),
{NULL, 0, 0}
};
static struct crc_mon IN_SECTION(.ccm.data) crc_monitors[] =
{
static struct crc_mon IN_SECTION(.ccm.data) crc_monitors[] = {
{
.registers = meas_adc_crc_regs,
.monitor = ERR_CRC_MON_MEAS_ADC,
@@ -360,7 +359,8 @@ static void set_overtemp_config(float over_temperature)
safety_controller_overtemp_config.crc_dummy_seed = 0xA4F5C7E6UL;
safety_controller_overtemp_config.overtemp_deg_celsius = over_temperature;
safety_controller_overtemp_config.overtemp_equiv_resistance = resistance;
crc_unit_input_array((const uint32_t *)&safety_controller_overtemp_config, wordsize_of(struct overtemp_config) - 1);
crc_unit_input_array((const uint32_t *)&safety_controller_overtemp_config,
wordsize_of(struct overtemp_config) - 1);
safety_controller_overtemp_config.crc = crc_unit_get_crc();
}
@@ -369,7 +369,8 @@ static bool over_temperature_config_check(void)
if (safety_controller_overtemp_config.crc_dummy_seed != 0xA4F5C7E6UL)
return true;
crc_unit_reset();
crc_unit_input_array((const uint32_t *)&safety_controller_overtemp_config, wordsize_of(struct overtemp_config) - 1);
crc_unit_input_array((const uint32_t *)&safety_controller_overtemp_config,
wordsize_of(struct overtemp_config) - 1);
if (crc_unit_get_crc() != safety_controller_overtemp_config.crc)
return true;
@@ -442,7 +443,7 @@ static int flag_weight_table_crc_check(void)
static int flag_persistence_table_crc_check(void)
{
crc_unit_reset();
crc_unit_input_array((uint32_t*)flag_persistencies, wordsize_of(flag_persistencies));
crc_unit_input_array((uint32_t *)flag_persistencies, wordsize_of(flag_persistencies));
if (crc_unit_get_crc() != flag_persistencies_crc)
return -1;
@@ -519,9 +520,8 @@ static int safety_controller_check_crc_monitors(void)
if (crc_monitor_calculate_crc(mon->registers, &crc))
return -1;
if (mon->expected_crc != crc || ~mon->expected_crc_inv != crc) {
if (mon->expected_crc != crc || ~mon->expected_crc_inv != crc)
safety_controller_report_error(mon->flag_to_set);
}
mon->last_crc = crc;
}
@@ -548,7 +548,7 @@ static void init_safety_flag_weight_table_from_default(void)
}
crc_unit_reset();
crc_unit_input_array((uint32_t*)flag_weights, wordsize_of(flag_weights));
crc_unit_input_array((uint32_t *)flag_weights, wordsize_of(flag_weights));
flag_weight_crc = crc_unit_get_crc();
}
@@ -608,16 +608,14 @@ static void apply_config_overrides(void)
case SAFETY_MEMORY_CONFIG_OVERRIDE_WEIGHT:
flag_enum = flag_no_to_flag_enum(override.entry.weight_override.flag);
flag = find_error_flag(flag_enum);
if (flag && flag->weight) {
if (flag && flag->weight)
flag->weight->weight = override.entry.weight_override.weight;
}
break;
case SAFETY_MEMORY_CONFIG_OVERRIDE_PERSISTENCE:
flag_enum = flag_no_to_flag_enum(override.entry.persistence_override.flag);
flag = find_error_flag(flag_enum);
if (flag && flag->persistence) {
if (flag && flag->persistence)
flag->persistence->persistence = override.entry.persistence_override.persistence;
}
break;
default:
continue;
@@ -629,7 +627,7 @@ static void apply_config_overrides(void)
crc_unit_input_array((uint32_t *)flag_persistencies, wordsize_of(flag_persistencies));
flag_persistencies_crc = crc_unit_get_crc();
crc_unit_reset();
crc_unit_input_array((uint32_t*)flag_weights, wordsize_of(flag_weights));
crc_unit_input_array((uint32_t *)flag_weights, wordsize_of(flag_weights));
flag_weight_crc = crc_unit_get_crc();
}
@@ -647,11 +645,10 @@ static bool error_flag_get_status(const volatile struct error_flag *flag)
if (!flag)
return true;
if (flag->error_state == flag->error_state_inv) {
if (flag->error_state == flag->error_state_inv)
return true;
} else {
else
return flag->error_state;
}
}
/**
@@ -693,7 +690,7 @@ static volatile struct timing_mon *find_timing_mon(enum timing_monitor mon)
/**
* @brief Check the active timing monitors and set the appropriate flags in case of an error.
*/
static void safety_controller_process_active_timing_mons()
static void safety_controller_process_active_timing_mons(void)
{
uint32_t i;
volatile struct timing_mon *current_mon;
@@ -716,7 +713,8 @@ static void safety_controller_process_active_timing_mons()
* Process the analog and timing monitors and set the relevant flags in case of a monitor outside its limits.
* Furthermore, the PT1000 resistance is checked for overtemperature
*
* The checking of the analog monitors will only be armed after a startup delay of 1000 ms to allow the values to stabilize.
* The checking of the analog monitors will only be armed after a startup delay of 1000 ms to
* allow the values to stabilize.
*/
static void safety_controller_process_monitor_checks(void)
{
@@ -731,21 +729,18 @@ static void safety_controller_process_monitor_checks(void)
if (startup_completed) {
analog_mon_count = safety_controller_get_analog_monitor_count();
for (idx = 0; idx < analog_mon_count; idx++) {
for (idx = 0; idx < analog_mon_count; idx++)
if (safety_controller_get_analog_mon_by_index(idx, &amon_info)) {
panic_mode();
}
if (amon_info.status != ANALOG_MONITOR_OK) {
if (amon_info.status != ANALOG_MONITOR_OK)
safety_controller_report_error(amon_info.associated_flag);
}
}
}
adc_pt1000_get_current_resistance(&pt1000_val);
if (pt1000_val > safety_controller_overtemp_config.overtemp_equiv_resistance) {
if (pt1000_val > safety_controller_overtemp_config.overtemp_equiv_resistance)
safety_controller_report_error(ERR_FLAG_OVERTEMP);
}
(void)safety_controller_check_crc_monitors();
@@ -820,10 +815,9 @@ void safety_controller_report_timing(enum timing_monitor monitor)
tim = find_timing_mon(monitor);
if (tim) {
if (tim->enabled) {
if (!systick_ticks_have_passed(tim->last, tim->min_delta) && tim->min_delta > 0U) {
if (!systick_ticks_have_passed(tim->last, tim->min_delta) && tim->min_delta > 0U)
safety_controller_report_error(tim->associated_flag);
}
}
tim->calculated_delta = timestamp - tim->last;
tim->last = timestamp;
@@ -870,10 +864,9 @@ static int get_safety_flags_from_error_mem(enum safety_flag *flags)
for (idx = 0; idx < count; idx++) {
res = safety_memory_get_error_entry(idx, &entry);
if (entry.type == SAFETY_MEMORY_ERR_ENTRY_FLAG) {
if (entry.type == SAFETY_MEMORY_ERR_ENTRY_FLAG)
return_flags |= flag_no_to_flag_enum(entry.flag_num);
}
}
*flags = return_flags;
return 0;
@@ -884,11 +877,12 @@ static int get_safety_flags_from_error_mem(enum safety_flag *flags)
*
* The external harware watchdog has to be periodically reset or it will reset hte controller.
* Because debugging is not possible, when the watchdog is active, it is only activated, if the application is
* compiled in release mode. Any interruption of the main programm will then trigger the internal and/or the external watchdog.
* compiled in release mode. Any interruption of the main programm will then trigger the internal and/or
* the external watchdog.
*
* @note When enabled, execute the @ref external_watchdog_toggle function to reset the external watchdog.
*/
static void safety_controller_init_external_watchdog()
static void safety_controller_init_external_watchdog(void)
{
rcc_manager_enable_clock(&RCC->AHB1ENR, BITMASK_TO_BITNO(SAFETY_EXT_WATCHDOG_RCC_MASK));
SAFETY_EXT_WATCHDOG_PORT->MODER &= MODER_DELETE(SAFETY_EXT_WATCHDOG_PIN);
@@ -899,7 +893,7 @@ static void safety_controller_init_external_watchdog()
__DSB();
}
void safety_controller_init()
void safety_controller_init(void)
{
enum safety_memory_state found_memory_state;
enum safety_flag flags_in_err_mem = ERR_FLAG_NO_FLAG;
@@ -967,7 +961,7 @@ void safety_controller_init()
* 1) Checking the remaining free space at the moment between stack pointer and top of heap.
* 2) Checking The CRC of the corruption detect area between heap and stack
*/
static void safety_controller_check_stack()
static void safety_controller_check_stack(void)
{
int32_t free_stack;
@@ -975,18 +969,17 @@ static void safety_controller_check_stack()
if (free_stack < SAFETY_MIN_STACK_FREE)
safety_controller_report_error(ERR_FLAG_STACK);
if (stack_check_corruption_detect_area()) {
if (stack_check_corruption_detect_area())
safety_controller_report_error(ERR_FLAG_STACK);
}
}
/**
* @brief Handle the Safety ADC
*
* This function handles the safety ADC.
* If the safety ADC ius not executing a measurment and the time since the last measurement has
* passed @ref SAFETY_CONTROLLER_ADC_DELAY_MS, the safety ADC is retriggered and will automatically perform a measurement
* on all of its channels.
* If the safety ADC is not executing a measurment and the time since the last measurement has
* passed @ref SAFETY_CONTROLLER_ADC_DELAY_MS, the safety ADC is retriggered and will automatically perform a
* measurement on all of its channels.
* When called again, this function will retrieve the data from the safety ADC and converts it into the
* appropriate analog values for the analog value monitors.
*
@@ -995,7 +988,7 @@ static void safety_controller_check_stack()
*
* The channels, the ssafety ADC will convert is defined in its header file using the define @ref SAFETY_ADC_CHANNELS.
*/
static void safety_controller_handle_safety_adc()
static void safety_controller_handle_safety_adc(void)
{
static uint64_t last_result_timestamp = 0;
const uint16_t *channels;
@@ -1066,10 +1059,9 @@ static void safety_controller_handle_memory_checks(void)
/* Check the safety memory */
if (safety_memory_check()) {
(void)safety_memory_reinit(&found_state);
if (found_state != SAFETY_MEMORY_INIT_VALID_MEMORY) {
if (found_state != SAFETY_MEMORY_INIT_VALID_MEMORY)
safety_controller_report_error(ERR_FLAG_SAFETY_MEM_CORRUPT);
}
}
/* If flag weight table is broken, reinit to default and set flag */
if (flag_weight_table_crc_check()) {
@@ -1078,7 +1070,7 @@ static void safety_controller_handle_memory_checks(void)
}
/* If persistence table is broken, reinit to default and set flag */
if(flag_persistence_table_crc_check()) {
if (flag_persistence_table_crc_check()) {
safety_controller_report_error(ERR_FLAG_SAFETY_TAB_CORRUPT);
init_safety_flag_persistencies_from_default();
}
@@ -1097,7 +1089,7 @@ static void safety_controller_handle_memory_checks(void)
* If the systick stays constant for more than 1000 calls of this function,
* the @ref ERR_FLAG_SYSTICK flag is set.
*/
static void safety_controller_do_systick_checking()
static void safety_controller_do_systick_checking(void)
{
static uint64_t last_systick;
static uint32_t same_systick_cnt = 0UL;
@@ -1122,7 +1114,7 @@ static void safety_controller_do_systick_checking()
* @note If no flag weigth is present for a given error flag, it is treated as the most critical category
* (@ref SAFETY_FLAG_CONFIG_WEIGHT_PANIC)
*/
static void safety_controller_handle_weighted_flags()
static void safety_controller_handle_weighted_flags(void)
{
uint32_t flag_index;
volatile struct error_flag *current_flag;
@@ -1132,9 +1124,8 @@ static void safety_controller_handle_weighted_flags()
current_flag = &flags[flag_index];
/* Continue if this flag is not set */
if (!error_flag_get_status(current_flag)) {
if (!error_flag_get_status(current_flag))
continue;
}
flag_weigth = get_flag_weight(current_flag);
switch (flag_weigth) {
@@ -1155,13 +1146,13 @@ static void safety_controller_handle_weighted_flags()
}
#ifndef DEBUGBUILD
static void external_watchdog_toggle()
static void external_watchdog_toggle(void)
{
SAFETY_EXT_WATCHDOG_PORT->ODR ^= (1<<SAFETY_EXT_WATCHDOG_PIN);
}
#endif
int safety_controller_handle()
int safety_controller_handle(void)
{
int ret = 0;
#ifndef DEBUGBUILD
@@ -1273,9 +1264,8 @@ int safety_controller_ack_flag_with_key(enum safety_flag flag, uint32_t key)
int ret = -1;
volatile struct error_flag *found_flag;
if (!is_power_of_two(flag)) {
if (!is_power_of_two(flag))
return -1001;
}
found_flag = find_error_flag(flag);
if (found_flag) {
@@ -1306,17 +1296,17 @@ bool safety_controller_get_flags_by_mask(enum safety_flag mask)
return ret;
}
uint32_t safety_controller_get_flag_count()
uint32_t safety_controller_get_flag_count(void)
{
return COUNT_OF(flags);
}
uint32_t safety_controller_get_analog_monitor_count()
uint32_t safety_controller_get_analog_monitor_count(void)
{
return COUNT_OF(analog_mons);
}
uint32_t safety_controller_get_timing_monitor_count()
uint32_t safety_controller_get_timing_monitor_count(void)
{
return COUNT_OF(timings);
}
@@ -1423,9 +1413,8 @@ int safety_controller_get_timing_mon_by_index(uint32_t index, struct timing_moni
if (!info)
return -1002;
if (index >= COUNT_OF(timings)) {
if (index >= COUNT_OF(timings))
return -1001;
}
mon = &timings[index];
@@ -1462,14 +1451,13 @@ extern const uint32_t __ld_sdata;
extern const uint32_t __ld_edata;
extern const uint32_t __ld_load_data;
int safety_controller_trigger_flash_crc_check()
int safety_controller_trigger_flash_crc_check(void)
{
/* This structs needs to be volatile!!
* This prevents the compiler form optimizing out the reads to the crcs which will be patched in later by
* a separate python script!
*/
static volatile const struct flash_crcs IN_SECTION(.flashcrc) crcs_in_flash =
{
static volatile const struct flash_crcs IN_SECTION(.flashcrc) crcs_in_flash = {
.start_magic = 0xA8BE53F9UL,
.crc_section_ccm_data = 0UL,
.crc_section_text = 0UL,
@@ -1491,10 +1479,9 @@ int safety_controller_trigger_flash_crc_check()
crc_unit_reset();
crc_unit_input_array(&__ld_vectors_start, len);
crc = crc_unit_get_crc();
if (crc != crcs_in_flash.crc_section_vectors) {
if (crc != crcs_in_flash.crc_section_vectors)
safety_controller_report_error(ERR_FLAG_FLASH_CRC_CODE);
}
}
/* Perform CRC check over text section */
len = (uint32_t)((void *)&__ld_text_end - (void *)&__ld_text_start);
@@ -1505,10 +1492,9 @@ int safety_controller_trigger_flash_crc_check()
crc_unit_reset();
crc_unit_input_array(&__ld_text_start, len);
crc = crc_unit_get_crc();
if (crc != crcs_in_flash.crc_section_text) {
if (crc != crcs_in_flash.crc_section_text)
safety_controller_report_error(ERR_FLAG_FLASH_CRC_CODE);
}
}
/* Perform CRC check over data section */
len = (uint32_t)((void *)&__ld_edata - (void *)&__ld_sdata);
@@ -1519,10 +1505,9 @@ int safety_controller_trigger_flash_crc_check()
crc_unit_reset();
crc_unit_input_array(&__ld_load_data, len);
crc = crc_unit_get_crc();
if (crc != crcs_in_flash.crc_section_data) {
if (crc != crcs_in_flash.crc_section_data)
safety_controller_report_error(ERR_FLAG_FLASH_CRC_DATA);
}
}
/* Perform CRC check over ccm data section */
len = (uint32_t)((void *)&__ld_edata_ccm - (void *)&__ld_sdata_ccm);
@@ -1533,10 +1518,9 @@ int safety_controller_trigger_flash_crc_check()
crc_unit_reset();
crc_unit_input_array(&__ld_load_ccm_data, len);
crc = crc_unit_get_crc();
if (crc != crcs_in_flash.crc_section_ccm_data) {
if (crc != crcs_in_flash.crc_section_ccm_data)
safety_controller_report_error(ERR_FLAG_FLASH_CRC_DATA);
}
}
ret = 0;
return ret;

View File

@@ -1,22 +1,22 @@
/* Reflow Oven Controller
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <reflow-controller/safety/safety-memory.h>
#include <helper-macros/helper-macros.h>
@@ -99,7 +99,8 @@ static enum safety_memory_state safety_memory_get_header(struct safety_memory_he
res = 0;
if (header->boot_status_offset < wordsize_of(struct safety_memory_header))
res++;
if (header->config_overrides_offset < header->boot_status_offset + wordsize_of(struct safety_memory_boot_status))
if (header->config_overrides_offset < header->boot_status_offset +
wordsize_of(struct safety_memory_boot_status))
res++;
if (header->config_overrides_len > SAFETY_MEMORY_CONFIG_OVERRIDE_COUNT)
res++;
@@ -107,7 +108,8 @@ static enum safety_memory_state safety_memory_get_header(struct safety_memory_he
res++;
if (header->err_memory_offset < header->firmware_update_filename + (SAFETY_MEMORY_UPDATE_FILENAME_MAXSIZE / 4))
res++;
if (header->err_memory_end >= backup_ram_get_size_in_words() || header->err_memory_end < header->err_memory_offset)
if (header->err_memory_end >= backup_ram_get_size_in_words() ||
header->err_memory_end < header->err_memory_offset)
res++;
if (res) {
@@ -148,7 +150,7 @@ static void safety_memory_write_new_header(void)
safety_memory_write_and_patch_header(&header);
}
static int safety_memory_check_crc()
static int safety_memory_check_crc(void)
{
struct safety_memory_header header;
enum safety_memory_state state = safety_memory_get_header(&header);
@@ -181,7 +183,7 @@ static int safety_memory_check_crc()
return 0;
}
static int safety_memory_gen_crc()
static int safety_memory_gen_crc(void)
{
struct safety_memory_header header;
uint32_t word_addr;
@@ -268,9 +270,8 @@ int safety_memory_get_boot_status(struct safety_memory_boot_status *status)
if (!status)
return -1001;
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
return -2000;
}
if (safety_memory_check_crc())
return -2001;
@@ -289,9 +290,8 @@ int safety_memory_set_boot_status(const struct safety_memory_boot_status *status
if (!status)
return -1001;
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
return -2000;
}
if (safety_memory_check_crc())
return -2001;
@@ -304,7 +304,7 @@ int safety_memory_set_boot_status(const struct safety_memory_boot_status *status
return 0;
}
static int safety_memory_check_error_entries()
static int safety_memory_check_error_entries(void)
{
struct safety_memory_header header;
uint32_t addr;
@@ -312,9 +312,8 @@ static int safety_memory_check_error_entries()
int ret = 0;
int res;
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
return -2000;
}
for (addr = header.err_memory_offset; addr < header.err_memory_end; addr++) {
res = backup_ram_get_data(addr, &data, 1UL);
@@ -340,9 +339,8 @@ int safety_memory_get_error_entry_count(uint32_t *count)
if (!count)
return -1001;
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
return -2000;
}
*count = header.err_memory_end - header.err_memory_offset;
@@ -354,9 +352,8 @@ int safety_memory_check(void)
int res;
res = safety_memory_check_crc();
if (!res) {
if (!res)
res |= safety_memory_check_error_entries();
}
return -!!res;
}
@@ -372,9 +369,8 @@ int safety_memory_get_error_entry(uint32_t idx, struct error_memory_entry *entry
if (!entry)
return -1001;
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
return -2000;
}
err_mem_count = header.err_memory_end - header.err_memory_offset;
if (idx < err_mem_count && err_mem_count > 0) {
@@ -410,9 +406,8 @@ int safety_memory_insert_error_entry(struct error_memory_entry *entry)
input_data = error_memory_entry_to_word(entry);
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
return -2000;
}
if (entry->type == SAFETY_MEMORY_ERR_ENTRY_NOP) {
/* Append to end */
@@ -510,9 +505,8 @@ int safety_memory_insert_config_override(struct config_override *config_override
int res;
int ret = -3;
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
return -2000;
}
if (header.config_overrides_len == 0)
return -1;
@@ -550,9 +544,8 @@ int safety_memory_get_config_override_count(uint32_t *count)
*count = 0UL;
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
return -2000;
}
if (header.config_overrides_len == 0)
return 0;
@@ -582,18 +575,15 @@ int safety_memory_get_config_override(uint32_t idx, struct config_override *conf
if (!config_override)
return -1002;
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY) {
if (safety_memory_get_header(&header) != SAFETY_MEMORY_INIT_VALID_MEMORY)
return -2000;
}
if (idx >= header.config_overrides_len) {
if (idx >= header.config_overrides_len)
return -1001;
}
res = backup_ram_get_data(header.config_overrides_offset + idx, &data, 1UL);
if (res) {
if (res)
return -1;
}
switch (data & 0xFF) {
case 0xA2:
@@ -649,8 +639,8 @@ int safety_memory_get_update_filename(char *filename, size_t *outlen)
{
struct safety_memory_header header;
unsigned int i;
volatile char *ptr;
size_t len = 0u;
volatile char *ptr;
/* If filename and outlen are both NULL, we don't do anything */
if (!filename && !outlen)
@@ -696,9 +686,9 @@ int safety_memory_set_update_filename(const char *filename)
ram_ptr = backup_ram_get_base_ptr();
ram_ptr += header.firmware_update_filename * 4;
for (i = 0u; i < len; i++) {
for (i = 0u; i < len; i++)
ram_ptr[i] = filename[i];
}
ram_ptr[i] = 0;
ret = safety_memory_gen_crc();

View File

@@ -1,22 +1,22 @@
/* Reflow Oven Controller
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <reflow-controller/safety/stack-check.h>
#include <stdint.h>
@@ -26,7 +26,7 @@
extern char __ld_top_of_stack;
extern char __ld_end_stack;
int32_t stack_check_get_usage()
int32_t stack_check_get_usage(void)
{
uint32_t stack_top;
uint32_t stack_ptr;
@@ -37,7 +37,7 @@ int32_t stack_check_get_usage()
return stack_top - stack_ptr;
}
int32_t stack_check_get_free()
int32_t stack_check_get_free(void)
{
uint32_t upper_heap_boundary;
uint32_t stack_ptr;
@@ -102,9 +102,6 @@ int stack_check_corruption_detect_area(void)
&__ld_start_stack_corruption_detect_area;
crc_unit_reset();
crc_unit_input_array(&__ld_start_stack_corruption_detect_area, area_size_in_words);
if (crc_unit_get_crc() == 0UL) {
return 0;
} else {
return -1;
}
return crc_unit_get_crc() == 0UL ? 0 : -1;
}

View File

@@ -1,22 +1,22 @@
/* Reflow Oven Controller
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
/**
* @addtogroup watchdog
@@ -50,7 +50,8 @@ int watchdog_setup(uint8_t prescaler)
RCC->CSR |= RCC_CSR_LSION;
__DSB();
/** - Wait for the oscillator to be ready */
while (!(RCC->CSR & RCC_CSR_LSIRDY));
while (!(RCC->CSR & RCC_CSR_LSIRDY))
;
if (prescaler == 4U)
prescaler_reg_val = 0UL;
@@ -68,23 +69,24 @@ int watchdog_setup(uint8_t prescaler)
prescaler_reg_val = 6UL;
/** - (De)activate the watchdog during debug access according to @ref WATCHDOG_HALT_DEBUG */
if (WATCHDOG_HALT_DEBUG) {
if (WATCHDOG_HALT_DEBUG)
DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_IWDG_STOP;
} else {
else
DBGMCU->APB1FZ &= ~DBGMCU_APB1_FZ_DBG_IWDG_STOP;
}
/** - Unlock registers */
IWDG->KR = STM32_WATCHDOG_REGISTER_ACCESS_KEY;
/** - Wait until prescaler can be written */
while (IWDG->SR & IWDG_SR_PVU);
while (IWDG->SR & IWDG_SR_PVU)
;
/** - Write prescaler value */
IWDG->PR = prescaler_reg_val;
/* - Wait until reload value can be written */
while (IWDG->SR & IWDG_SR_RVU);
while (IWDG->SR & IWDG_SR_RVU)
;
/** - Set reload value fixed to 0xFFF */
IWDG->RLR = 0xFFFU;

View File

@@ -1,22 +1,22 @@
/* Reflow Oven Controller
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <reflow-controller/settings/settings-eeprom.h>
#include <reflow-controller/settings/spi-eeprom.h>
@@ -37,6 +37,7 @@ struct eeprom_calibration_settings {
};
#define EEPROM_OVER_TEMP_CONFIG_BASE_ADDR (EEPROM_CALIBRATION_BASE_ADDR + sizeof(struct eeprom_calibration_settings))
struct eeprom_over_temp_config {
float over_temperature;
uint32_t over_temp_crc;
@@ -54,7 +55,7 @@ static bool check_eeprom_header(void)
return true;
}
static void settings_eeprom_zero()
static void settings_eeprom_zero(void)
{
settings_eeprom_save_calibration(0.0f, 0.0f, false);
settings_eeprom_save_overtemp_limit(0.0f, false);
@@ -62,7 +63,7 @@ static void settings_eeprom_zero()
bool settings_eeprom_detect_and_prepare(void)
{
bool eeprom_ready = false;;
bool eeprom_ready = false;
int res;
@@ -77,7 +78,10 @@ bool settings_eeprom_detect_and_prepare(void)
if (check_eeprom_header() == false) {
/* Try to write a new header and check it again */
spi_eeprom_write(0, expected_header, sizeof(expected_header));
while (spi_eeprom_write_in_progress());
while (spi_eeprom_write_in_progress())
;
if (check_eeprom_header() == false) {
goto ret_deinit_crc;
} else {

View File

@@ -1,22 +1,22 @@
/* Reflow Oven Controller
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <reflow-controller/settings/settings-sd-card.h>
#include <stm-periph/unique-id.h>
@@ -72,18 +72,12 @@ static int create_controller_folder(void)
ret = 0;
} else {
filesystem_result = f_mkdir(foldername);
if (filesystem_result == FR_OK) {
ret = 1;
} else {
ret = -1;
}
ret = filesystem_result == FR_OK ? 1 : -1;
}
return ret;
}
int sd_card_settings_save_calibration(float sens_deviation, float offset, bool active)
{
char path[200];

View File

@@ -1,22 +1,22 @@
/* Reflow Oven Controller
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
*
* Copyright (C) 2020 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <reflow-controller/settings/settings.h>
#include <reflow-controller/settings/settings-sd-card.h>
@@ -39,7 +39,7 @@ int settings_load_calibration(float *sens_dev, float *offset)
int res;
if (settings_use_eeprom) {
res =settings_eeprom_load_calibration(sens_dev, offset, &active);
res = settings_eeprom_load_calibration(sens_dev, offset, &active);
if (!res && !active)
res = -1;
} else {

View File

@@ -1,22 +1,22 @@
/* Reflow Oven Controller
*
* Copyright (C) 2021 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
*
* Copyright (C) 2021 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <reflow-controller/settings/spi-eeprom.h>
#include <stm-periph/spi.h>
@@ -52,7 +52,7 @@ static void eeprom_cs_deactivate(void)
SPI_EEPROM_SPI_PORT->ODR |= (1<<SPI_EEPROM_CS_PIN);
}
int spi_eeprom_init()
int spi_eeprom_init(void)
{
static struct stm_spi_dev spi_dev;
struct stm_spi_settings settings;
@@ -61,7 +61,8 @@ int spi_eeprom_init()
SPI_EEPROM_SPI_PORT->MODER &= MODER_DELETE(SPI_EEPROM_CS_PIN) & MODER_DELETE(SPI_EEPROM_MISO_PIN) &
MODER_DELETE(SPI_EEPROM_MOSI_PIN) & MODER_DELETE(SPI_EEPROM_SCK_PIN);
SPI_EEPROM_SPI_PORT->MODER |= ALTFUNC(SPI_EEPROM_MISO_PIN) | ALTFUNC(SPI_EEPROM_SCK_PIN) | ALTFUNC(SPI_EEPROM_MOSI_PIN);
SPI_EEPROM_SPI_PORT->MODER |= ALTFUNC(SPI_EEPROM_MISO_PIN) | ALTFUNC(SPI_EEPROM_SCK_PIN) |
ALTFUNC(SPI_EEPROM_MOSI_PIN);
SPI_EEPROM_SPI_PORT->MODER |= OUTPUT(SPI_EEPROM_CS_PIN);
SETAF(SPI_EEPROM_SPI_PORT, SPI_EEPROM_MISO_PIN, SPI_EEPROM_SPI_ALTFUNC_NO);
@@ -85,7 +86,7 @@ int spi_eeprom_init()
return -1;
}
void spi_eeprom_deinit()
void spi_eeprom_deinit(void)
{
spi_deinit(eeprom_spi_handle);
@@ -166,7 +167,8 @@ static void spi_eeprom_do_write_page(uint32_t addr, const uint8_t *data, uint8_t
uint8_t cmd[2];
/* Wait for the previous write to finish */
while (spi_eeprom_write_in_progress());
while (spi_eeprom_write_in_progress())
;
/* Set the write enable latch */
spi_eeprom_set_write_enable_latch(true);

View File

@@ -46,7 +46,8 @@ void backup_ram_init(bool use_backup_regulator)
PWR->CSR |= PWR_CSR_BRE;
/* Wait until regulator is ready */
while (!(PWR->CSR & PWR_CSR_BRR));
while (!(PWR->CSR & PWR_CSR_BRR))
;
}
/* Enable clock for backup ram interface */

View File

@@ -37,11 +37,10 @@ static size_t calculate_ring_buffer_fill_level(size_t buffer_size, size_t get_id
{
size_t fill_level;
if (put_idx >= get_idx) {
if (put_idx >= get_idx)
fill_level = (put_idx - get_idx);
} else {
else
fill_level = buffer_size - get_idx + put_idx;
}
return fill_level;
}
@@ -49,7 +48,7 @@ static size_t calculate_ring_buffer_fill_level(size_t buffer_size, size_t get_id
static int dma_ring_buffer_switch_clock_enable(uint8_t base_dma, bool clk_en)
{
int ret_val;
int (*clk_func)(volatile uint32_t *, uint8_t);
int (*clk_func)(volatile uint32_t *reg, uint8_t bit_no);
if (clk_en)
clk_func = rcc_manager_enable_clock;
@@ -72,8 +71,9 @@ static int dma_ring_buffer_switch_clock_enable(uint8_t base_dma, bool clk_en)
}
int dma_ring_buffer_periph_to_mem_initialize(struct dma_ring_buffer_to_mem *dma_buffer, uint8_t base_dma_id,
DMA_Stream_TypeDef *dma_stream, size_t buffer_element_count, size_t element_size,
volatile void *data_buffer, void* src_reg, uint8_t dma_trigger_channel)
DMA_Stream_TypeDef *dma_stream, size_t buffer_element_count,
size_t element_size, volatile void *data_buffer,
void *src_reg, uint8_t dma_trigger_channel)
{
int ret_val = 0;
@@ -106,7 +106,8 @@ int dma_ring_buffer_periph_to_mem_initialize(struct dma_ring_buffer_to_mem *dma_
return 0;
}
int dma_ring_buffer_periph_to_mem_get_data(struct dma_ring_buffer_to_mem *buff, const volatile void **data_buff, size_t *len)
int dma_ring_buffer_periph_to_mem_get_data(struct dma_ring_buffer_to_mem *buff, const volatile void **data_buff,
size_t *len)
{
int ret_code = 0;
uint32_t ndtr;
@@ -167,7 +168,10 @@ int dma_ring_buffer_periph_to_mem_fill_level(struct dma_ring_buffer_to_mem *buff
return 0;
}
int dma_ring_buffer_mem_to_periph_initialize(struct dma_ring_buffer_to_periph *dma_buffer, uint8_t base_dma_id, DMA_Stream_TypeDef *dma_stream, size_t buffer_element_count, size_t element_size, volatile void *data_buffer, uint8_t dma_trigger_channel, void *dest_reg)
int dma_ring_buffer_mem_to_periph_initialize(struct dma_ring_buffer_to_periph *dma_buffer, uint8_t base_dma_id,
DMA_Stream_TypeDef *dma_stream, size_t buffer_element_count,
size_t element_size, volatile void *data_buffer,
uint8_t dma_trigger_channel, void *dest_reg)
{
if (!dma_buffer || !dma_stream || !data_buffer || !dest_reg)
return -1000;
@@ -221,7 +225,8 @@ static void queue_or_start_dma_transfer(struct dma_ring_buffer_to_periph *buff)
buff->dma->CR |= DMA_SxCR_EN;
}
int dma_ring_buffer_mem_to_periph_insert_data(struct dma_ring_buffer_to_periph *buff, const void *data_to_insert, size_t count)
int dma_ring_buffer_mem_to_periph_insert_data(struct dma_ring_buffer_to_periph *buff, const void *data_to_insert,
size_t count)
{
int ret = 0;
size_t free_item_count;
@@ -234,7 +239,8 @@ int dma_ring_buffer_mem_to_periph_insert_data(struct dma_ring_buffer_to_periph *
return -1000;
/* Check if data fits into buffer minus one element. If not: try full-1 buffer and rest
* Buffer is not allowed to be completely full, because I cannot ddifferentiate a full buffer from a completely empty one
* Buffer is not allowed to be completely full, because I cannot ddifferentiate a full buffer from a
* completely empty one
*/
if (count >= buff->buffer_count) {
ret = dma_ring_buffer_mem_to_periph_insert_data(buff, data_to_insert, buff->buffer_count - 1);
@@ -247,7 +253,9 @@ int dma_ring_buffer_mem_to_periph_insert_data(struct dma_ring_buffer_to_periph *
/* Wait for buffer to be able to handle input */
do {
free_item_count = buff->buffer_count - calculate_ring_buffer_fill_level(buff->buffer_count, buff->dma_get_idx_current, buff->sw_put_idx);
free_item_count = buff->buffer_count -
calculate_ring_buffer_fill_level(buff->buffer_count, buff->dma_get_idx_current,
buff->sw_put_idx);
} while (free_item_count < count+1);
/* Fillup buffer (max is buffer end, wrap around afterwards) */
@@ -261,7 +269,7 @@ int dma_ring_buffer_mem_to_periph_insert_data(struct dma_ring_buffer_to_periph *
buff->sw_put_idx += count;
/* If buffer is used up to last element, set put index to beginning */
if(buff->sw_put_idx >= buff->buffer_count)
if (buff->sw_put_idx >= buff->buffer_count)
buff->sw_put_idx = 0;
} else {
/* Fill up to end of buffer and fill rest after wrap around */

View File

@@ -76,12 +76,14 @@ int stm_option_bytes_program(const struct option_bytes *opts)
reg |= (opts->read_protection << 8) & FLASH_OPTCR_RDP;
reg |= (opts->wdg_sw << 5) & FLASH_OPTCR_WDG_SW;
while (FLASH->SR & FLASH_SR_BSY);
while (FLASH->SR & FLASH_SR_BSY)
;
FLASH->OPTCR = reg;
FLASH->OPTCR |= FLASH_OPTCR_OPTSTRT;
__DSB();
while (FLASH->SR & FLASH_SR_BSY);
while (FLASH->SR & FLASH_SR_BSY)
;
FLASH->OPTCR |= FLASH_OPTCR_OPTLOCK;

View File

@@ -95,9 +95,8 @@ int rcc_manager_enable_clock(volatile uint32_t *rcc_enable_register, uint8_t bit
int ret_val = 0;
struct rcc_enable_count *entry;
if (!rcc_enable_register || bit_no > 31) {
if (!rcc_enable_register || bit_no > 31)
return -1000;
}
/* Enable the clock in any case, no matter what follows */
*rcc_enable_register |= (1U<<bit_no);
@@ -132,9 +131,8 @@ int rcc_manager_disable_clock(volatile uint32_t *rcc_enable_register, uint8_t bi
int ret_val = -1;
struct rcc_enable_count *entry;
if (!rcc_enable_register || bit_no > 31) {
if (!rcc_enable_register || bit_no > 31)
return -1000;
}
entry = search_enable_entry_in_list(rcc_enable_register, bit_no);

View File

@@ -30,7 +30,7 @@ void random_number_gen_init(bool int_enable)
random_number_gen_reset(int_enable);
}
void random_number_gen_deinit()
void random_number_gen_deinit(void)
{
RNG->CR = 0;
__DSB();
@@ -66,5 +66,5 @@ enum random_number_error random_number_gen_get_number(uint32_t *random_number, b
*random_number = RNG->DR;
/* Return from function with proper status */
return (value_ready ? RNG_ERROR_OK : RNG_ERROR_NOT_READY);
return value_ready ? RNG_ERROR_OK : RNG_ERROR_NOT_READY;
}

View File

@@ -1,22 +1,22 @@
/* Reflow Oven Controller
*
* Copyright (C) 2021 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
*
* Copyright (C) 2021 Mario Hüttel <mario.huettel@gmx.net>
*
* This file is part of the Reflow Oven Controller Project.
*
* The reflow oven controller is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* The Reflow Oven Control 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 the reflow oven controller project.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <stm-periph/spi.h>
#include <helper-macros/helper-macros.h>
@@ -65,7 +65,8 @@ static struct stm_spi_dev *spi_handle_to_struct(stm_spi_handle handle)
return dev;
}
stm_spi_handle spi_init(struct stm_spi_dev *spi_dev_struct, SPI_TypeDef *spi_regs, const struct stm_spi_settings *settings)
stm_spi_handle spi_init(struct stm_spi_dev *spi_dev_struct, SPI_TypeDef *spi_regs,
const struct stm_spi_settings *settings)
{
stm_spi_handle ret_handle = NULL;
uint32_t reg_val;
@@ -131,10 +132,14 @@ void spi_deinit(stm_spi_handle handle)
static uint8_t transfer_byte(uint8_t byte, struct stm_spi_dev *dev)
{
while (dev->spi_regs->SR & SPI_SR_BSY);
while (dev->spi_regs->SR & SPI_SR_BSY)
;
dev->spi_regs->DR = (uint16_t)byte;
__DSB();
while((dev->spi_regs->SR & SPI_SR_BSY) || !(dev->spi_regs->SR & SPI_SR_TXE));
while ((dev->spi_regs->SR & SPI_SR_BSY) || !(dev->spi_regs->SR & SPI_SR_TXE))
;
return (uint8_t)dev->spi_regs->DR;
}

View File

@@ -126,7 +126,9 @@ void uart_send_char(struct stm_uart *uart, char c)
if (!uart || !uart->uart_dev)
return;
while(!(uart->uart_dev->SR & USART_SR_TXE));
while (!(uart->uart_dev->SR & USART_SR_TXE))
;
uart->uart_dev->DR = c;
}
@@ -175,7 +177,8 @@ char uart_get_char(struct stm_uart *uart)
if (!uart)
return 0;
/* Wait for data to be available */
while (!(uart->uart_dev->SR & USART_SR_RXNE));
while (!(uart->uart_dev->SR & USART_SR_RXNE))
;
return (char)uart->uart_dev->DR;
}

View File

@@ -43,3 +43,23 @@ void stm_dev_rev_id_get(uint32_t *device_id, uint32_t *revision_id)
if (revision_id)
*revision_id = (DBGMCU->IDCODE & DBGMCU_IDCODE_REV_ID) >> 16;
}
void stm_cpuid_get(uint8_t *implementer, uint8_t *variant, uint16_t *part_no, uint8_t *rev)
{
uint32_t cpuid;
cpuid = SCB->CPUID;
if (implementer)
*implementer = (uint8_t)((cpuid >> 24) & 0xFFU);
if (variant)
*variant = (uint8_t)((cpuid >> 20) & 0x0FU);
if (part_no)
*part_no = (uint16_t)((cpuid >> 4) & 0x0FFFU);
if (rev)
*rev = (uint8_t)(cpuid & 0x0FU);
}

View File

@@ -691,6 +691,37 @@ static void gui_update_firmware(struct lcd_menu *menu, enum menu_entry_func_entr
}
}
static void gui_connector_info(struct lcd_menu *menu, enum menu_entry_func_entry entry_type, void *parent)
{
static void *my_parent;
enum button_state button;
if (entry_type == MENU_ENTRY_FIRST_ENTER) {
my_parent = parent;
menu_display_clear(menu);
menu_lcd_output(menu, 0, "2,4: DIGIO[0,1]");
menu_lcd_output(menu, 1, "6: DIGIO2 (TX)");
menu_lcd_output(menu, 2, "8: DIGIO3 (RX)");
menu_lcd_output(menu, 3, "10:3V3 Rest:GND");
}
if (menu_get_button_ready_state(menu)) {
/* Buttons are ready. Read button */
button = menu_get_button_state(menu);
/* Throw away any rotation */
(void)menu_get_rotary_delta(menu);
if (button == BUTTON_SHORT_RELEASED || button == BUTTON_LONG ||
button == BUTTON_LONG_RELEASED) {
/* Exit menu */
menu_entry_dropback(menu, my_parent);
}
}
}
static char *overlay_heading = NULL;
static char *overlay_text = NULL;
@@ -740,6 +771,7 @@ static void gui_menu_root_entry(struct lcd_menu *menu, enum menu_entry_func_entr
"Error Flags",
"About",
"Update",
"Connector Info",
NULL
};
static const menu_func_t root_entry_funcs[] = {
@@ -749,6 +781,7 @@ static void gui_menu_root_entry(struct lcd_menu *menu, enum menu_entry_func_entr
gui_menu_err_flags,
gui_menu_about,
gui_update_firmware,
gui_connector_info,
};
enum button_state push_button;
int16_t rot_delta;

View File

@@ -70,6 +70,10 @@ static shellmatta_retCode_t shell_cmd_ver(const shellmatta_handle_t handle,
uint32_t high_id;
uint32_t stm_rev_id;
uint32_t stm_dev_id;
uint8_t core_rev;
uint8_t core_implementer;
uint8_t core_variant;
uint16_t core_part_no;
const char *hw_rev_str;
enum hw_revision pcb_rev;
@@ -100,6 +104,12 @@ static shellmatta_retCode_t shell_cmd_ver(const shellmatta_handle_t handle,
shellmatta_printf(handle, "STM Device ID: 0x%04X\r\n", stm_dev_id);
shellmatta_printf(handle, "STM Revision ID: 0x%04X\r\n", stm_rev_id);
stm_cpuid_get(&core_implementer, &core_variant, &core_part_no, &core_rev);
shellmatta_printf(handle, "CPU Implementer: 0x%02X\r\n", (unsigned int)core_implementer);
shellmatta_printf(handle, "CPU Variant: 0x%02X\r\n", (unsigned int)core_variant);
shellmatta_printf(handle, "CPU Part No.: 0x%04X\r\n", (unsigned int)core_part_no);
shellmatta_printf(handle, "CPU Revision: 0x%02X\r\n", (unsigned int)core_rev);
return SHELLMATTA_OK;
}
@@ -849,6 +859,7 @@ shellmatta_retCode_t shell_cmd_execute(const shellmatta_handle_t handle, const c
shellmatta_retCode_t shell_cmd_cycle_count(const shellmatta_handle_t handle, const char *args, uint32_t len)
{
uint64_t counter;
uint32_t core_cycle_count;
(void)args;
(void)len;
char option;
@@ -856,8 +867,10 @@ shellmatta_retCode_t shell_cmd_cycle_count(const shellmatta_handle_t handle, con
uint32_t arg_len;
int opt_stat;
bool clear = false;
bool hex = false;
const shellmatta_opt_long_t options[] = {
{"clear", 'c', SHELLMATTA_OPT_ARG_NONE},
{"hex", 'h', SHELLMATTA_OPT_ARG_NONE},
{NULL, '\0', SHELLMATTA_OPT_ARG_NONE},
};
@@ -869,6 +882,8 @@ shellmatta_retCode_t shell_cmd_cycle_count(const shellmatta_handle_t handle, con
case 'c':
clear = true;
break;
case 'h':
hex = true;
default:
break;
}
@@ -876,10 +891,18 @@ shellmatta_retCode_t shell_cmd_cycle_count(const shellmatta_handle_t handle, con
counter = main_cycle_counter_get();
shellmatta_printf(handle, "%"PRIu64"\r\n", counter);
if (clear)
core_cycle_count = DWT->CYCCNT;
if (hex) {
shellmatta_printf(handle, "Main loop: 0x%016"PRIX64"\r\n", counter);
shellmatta_printf(handle, "CPU cycles: 0x%08"PRIX32"\r\n", core_cycle_count);
} else {
shellmatta_printf(handle, "Main loop: %"PRIu64"\r\n", counter);
shellmatta_printf(handle, "CPU cycles: %"PRIu32"\r\n", core_cycle_count);
}
if (clear) {
main_cycle_counter_init();
DWT->CYCCNT = 0UL;
}
return SHELLMATTA_OK;
}
@@ -1202,7 +1225,7 @@ static shellmatta_cmd_t cmd[25] = {
},
{
.cmd = "baudrate",
.cmdAlias = "opt-bytes",
.cmdAlias = "baud",
.helpText = "Set a new temporary baudrate for the UART",
.usageText = "baudrate <new baud>",
.cmdFct = shell_cmd_set_baud,