Compare commits
No commits in common. "f0bf10d91d5955afd29152445cf51b8de34b7f39" and "0fca4c6c204b19000dc17772a7d053c0417f02a3" have entirely different histories.
f0bf10d91d
...
0fca4c6c20
@ -25,28 +25,9 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <reflow-controller/pid-controller.h>
|
#include <reflow-controller/pid-controller.h>
|
||||||
|
|
||||||
enum oven_pid_error_report {
|
|
||||||
OVEN_PID_NO_ERROR = 0,
|
|
||||||
OVEN_PID_ERR_PT1000_ADC_WATCHDOG = (1<<0),
|
|
||||||
OVEN_PID_ERR_PT1000_ADC_OFF = (1<<1),
|
|
||||||
OVEN_PID_ERR_PT1000_OTHER = (1<<2),
|
|
||||||
OVEN_PID_ERR_VREF_TOL = (1<<3),
|
|
||||||
OVEN_PID_ERR_OVERTEMP = (1<<4),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct oven_pid_errors {
|
|
||||||
bool generic_error;
|
|
||||||
bool pt1000_adc_watchdog;
|
|
||||||
bool pt1000_adc_off;
|
|
||||||
bool pt1000_other;
|
|
||||||
bool vref_tol;
|
|
||||||
bool controller_overtemp;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct oven_pid_status {
|
struct oven_pid_status {
|
||||||
bool active;
|
bool active;
|
||||||
bool aborted;
|
bool aborted;
|
||||||
struct oven_pid_errors error_flags;
|
|
||||||
float target_temp;
|
float target_temp;
|
||||||
float current_temp;
|
float current_temp;
|
||||||
uint64_t timestamp_last_run;
|
uint64_t timestamp_last_run;
|
||||||
@ -60,11 +41,11 @@ void oven_driver_disable(void);
|
|||||||
|
|
||||||
void oven_pid_init(struct pid_controller *controller_to_copy);
|
void oven_pid_init(struct pid_controller *controller_to_copy);
|
||||||
|
|
||||||
void oven_pid_handle(float target_temp);
|
void oven_pid_handle(float target_temp, float current_temp);
|
||||||
|
|
||||||
void oven_pid_stop();
|
void oven_pid_stop();
|
||||||
|
|
||||||
void oven_pid_report_error(enum oven_pid_error_report report);
|
void oven_pid_report_error(void);
|
||||||
|
|
||||||
const struct oven_pid_status *oven_pid_get_status(void);
|
const struct oven_pid_status *oven_pid_get_status(void);
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Handle the reflow controller's LCD Menu
|
* @brief Handle the reflow controller's LCD Menu
|
||||||
* @return 0 if no delay is requested, 1 if delay is requested
|
* @return 0 if a delay is requested, 1 if no delay is requested
|
||||||
*/
|
*/
|
||||||
int reflow_menu_handle(void);
|
int reflow_menu_handle(void);
|
||||||
|
|
||||||
|
@ -24,10 +24,11 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define SAFETY_ADC_VREF_MVOLT (2500.0f)
|
#define SAFETY_ADC_FRAC_BITS (8)
|
||||||
#define SAFETY_ADC_VREF_TOL_MVOLT (100.0f)
|
#define SAFETY_ADC_VREF_VOLT (2.5)
|
||||||
#define SAFETY_ADC_TEMP_LOW_LIM (0.0f)
|
#define SAFETY_ADC_VREF_TOL (0.25)
|
||||||
#define SAFETY_ADC_TEMP_HIGH_LIM (65.0f)
|
#define SAFETY_ADC_VREF_INT ()
|
||||||
|
|
||||||
|
|
||||||
enum safety_adc_meas_channel {SAFETY_ADC_MEAS_VREF, SAFETY_ADC_MEAS_TEMP};
|
enum safety_adc_meas_channel {SAFETY_ADC_MEAS_VREF, SAFETY_ADC_MEAS_TEMP};
|
||||||
enum safety_adc_check_result {
|
enum safety_adc_check_result {
|
||||||
|
@ -32,9 +32,9 @@
|
|||||||
* @brief Reload value for the systick timer.
|
* @brief Reload value for the systick timer.
|
||||||
*
|
*
|
||||||
* This value has to be configured to set the systick to a one milliscond tick interval
|
* This value has to be configured to set the systick to a one milliscond tick interval
|
||||||
* The default value is 16800, which results in a 100us tick for 168 MHz CPU speed
|
* The default value is 168000, which results in a 1ms tick for 168 MHz CPU speed
|
||||||
*/
|
*/
|
||||||
#define SYSTICK_RELOAD (16800UL)
|
#define SYSTICK_RELOAD (168000UL)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Variable used by the systick_wait_ms function
|
* @brief Variable used by the systick_wait_ms function
|
||||||
@ -52,7 +52,7 @@ extern volatile uint64_t global_tick_ms;
|
|||||||
/**
|
/**
|
||||||
* @brief Wait counter for the display. This must not be used anywhere else
|
* @brief Wait counter for the display. This must not be used anywhere else
|
||||||
*/
|
*/
|
||||||
extern volatile uint32_t lcd_tick_100us;
|
extern volatile uint32_t lcd_tick_ms;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Setup the Systick timer to generate a 1 ms tick
|
* @brief Setup the Systick timer to generate a 1 ms tick
|
||||||
@ -71,8 +71,6 @@ void systick_wait_ms(uint32_t ms);
|
|||||||
|
|
||||||
uint64_t systick_get_global_tick();
|
uint64_t systick_get_global_tick();
|
||||||
|
|
||||||
void systick_get_uptime_from_tick(uint32_t *days, uint32_t *hours, uint32_t *minutes, uint32_t *seconds);
|
|
||||||
|
|
||||||
bool systick_ticks_have_passed(uint64_t start_timestamp, uint64_t ticks);
|
bool systick_ticks_have_passed(uint64_t start_timestamp, uint64_t ticks);
|
||||||
|
|
||||||
#endif /* __SYSTICK_H__ */
|
#endif /* __SYSTICK_H__ */
|
||||||
|
@ -66,16 +66,10 @@ void menu_entry_dropback(struct lcd_menu *menu, menu_func_t parent_func);
|
|||||||
|
|
||||||
void menu_entry_enter(struct lcd_menu *menu, menu_func_t entry, bool handle_immediately);
|
void menu_entry_enter(struct lcd_menu *menu, menu_func_t entry, bool handle_immediately);
|
||||||
|
|
||||||
void menu_lcd_output(struct lcd_menu *menu, uint8_t row_num, const char *text);
|
void menu_override_lcd_output(struct lcd_menu *menu, uint8_t row_num, const char *text);
|
||||||
|
|
||||||
void menu_lcd_outputf(struct lcd_menu *menu, uint8_t row_num, const char *format, ...);
|
|
||||||
|
|
||||||
void menu_list_display(struct menu_list *list, uint32_t top_row, uint32_t bottom_row);
|
void menu_list_display(struct menu_list *list, uint32_t top_row, uint32_t bottom_row);
|
||||||
|
|
||||||
int16_t menu_get_rotary_delta(const struct lcd_menu *menu);
|
|
||||||
|
|
||||||
enum button_state menu_get_button_state(const struct lcd_menu *menu);
|
|
||||||
|
|
||||||
void menu_list_compute_count(struct menu_list *list);
|
void menu_list_compute_count(struct menu_list *list);
|
||||||
|
|
||||||
void menu_list_scroll_down(struct menu_list *list);
|
void menu_list_scroll_down(struct menu_list *list);
|
||||||
|
@ -58,8 +58,11 @@ static void setup_nvic_priorities()
|
|||||||
NVIC_SetPriority(DMA2_Stream7_IRQn, 3);
|
NVIC_SetPriority(DMA2_Stream7_IRQn, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Process parameters are defined static globally to be watched in debugger from any context */
|
||||||
|
static float target_temperature;
|
||||||
|
|
||||||
FATFS fs;
|
FATFS fs;
|
||||||
FATFS * const fs_ptr = &fs;
|
FATFS *fs_ptr = &fs;
|
||||||
|
|
||||||
static inline void uart_gpio_config()
|
static inline void uart_gpio_config()
|
||||||
{
|
{
|
||||||
@ -198,17 +201,15 @@ static void zero_ccm_ram(void)
|
|||||||
ptr[i] = 0UL;
|
ptr[i] = 0UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
volatile bool error_state = false;
|
|
||||||
volatile enum safety_adc_check_result safety_adc_status = SAFETY_ADC_CHECK_OK;
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
bool sd_card_mounted = false;
|
bool sd_card_mounted = false;
|
||||||
shellmatta_handle_t shell_handle;
|
shellmatta_handle_t shell_handle;
|
||||||
int menu_wait_request;
|
int menu_wait_request;
|
||||||
uint64_t quarter_sec_timestamp = 0ULL;
|
uint64_t quarter_sec_timestamp = 0ULL;
|
||||||
const struct oven_pid_status *pid_status;
|
enum safety_adc_check_result safety_adc_status;
|
||||||
enum adc_pt1000_error pt1000_status;
|
|
||||||
|
target_temperature = 25.0f;
|
||||||
|
|
||||||
zero_ccm_ram();
|
zero_ccm_ram();
|
||||||
setup_system();
|
setup_system();
|
||||||
@ -219,47 +220,15 @@ int main()
|
|||||||
while (1) {
|
while (1) {
|
||||||
sd_card_mounted = mount_sd_card_if_avail(sd_card_mounted);
|
sd_card_mounted = mount_sd_card_if_avail(sd_card_mounted);
|
||||||
|
|
||||||
pid_status = oven_pid_get_status();
|
|
||||||
|
|
||||||
if(systick_ticks_have_passed(quarter_sec_timestamp, 250)) {
|
if(systick_ticks_have_passed(quarter_sec_timestamp, 250)) {
|
||||||
safety_adc_status = handle_safety_adc();
|
safety_adc_status = handle_safety_adc();
|
||||||
quarter_sec_timestamp = systick_get_global_tick();
|
quarter_sec_timestamp = systick_get_global_tick();
|
||||||
|
|
||||||
if (safety_adc_status & SAFETY_ADC_CHECK_TEMP_LOW || safety_adc_status & SAFETY_ADC_CHECK_TEMP_HIGH) {
|
|
||||||
oven_pid_report_error(OVEN_PID_ERR_OVERTEMP);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (safety_adc_status & SAFETY_ADC_CHECK_VREF_LOW || safety_adc_status & SAFETY_ADC_CHECK_VREF_HIGH) {
|
|
||||||
oven_pid_report_error(OVEN_PID_ERR_VREF_TOL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (safety_adc_status & SAFETY_ADC_INTERNAL_ERROR) {
|
|
||||||
oven_pid_report_error(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error_state) {
|
|
||||||
led_set(0, !led_get(0));
|
|
||||||
} else {
|
|
||||||
led_set(0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
pt1000_status = adc_pt1000_check_error();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
error_state = pid_status->aborted | !!safety_adc_status | !!pt1000_status;
|
|
||||||
|
|
||||||
menu_wait_request = reflow_menu_handle();
|
|
||||||
|
|
||||||
/* Deactivate oven output in case of error! */
|
|
||||||
if (!pid_status->active || pid_status->aborted || error_state) {
|
|
||||||
oven_pid_stop();
|
|
||||||
oven_driver_set_power(0U);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handle_shell_uart_input(shell_handle);
|
handle_shell_uart_input(shell_handle);
|
||||||
|
|
||||||
if (menu_wait_request)
|
menu_wait_request = reflow_menu_handle();
|
||||||
|
if (!menu_wait_request)
|
||||||
__WFI();
|
__WFI();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,6 @@
|
|||||||
#include <reflow-controller/periph-config/oven-driver-hwcfg.h>
|
#include <reflow-controller/periph-config/oven-driver-hwcfg.h>
|
||||||
#include <stm-periph/clock-enable-manager.h>
|
#include <stm-periph/clock-enable-manager.h>
|
||||||
#include <reflow-controller/systick.h>
|
#include <reflow-controller/systick.h>
|
||||||
#include <reflow-controller/adc-meas.h>
|
|
||||||
#include <reflow-controller/temp-converter.h>
|
|
||||||
|
|
||||||
static struct pid_controller oven_pid;
|
static struct pid_controller oven_pid;
|
||||||
|
|
||||||
@ -78,70 +76,29 @@ void oven_pid_init(struct pid_controller *controller_to_copy)
|
|||||||
oven_pid.output_sat_max = 100.0f;
|
oven_pid.output_sat_max = 100.0f;
|
||||||
oven_pid_current_status.timestamp_last_run = 0ULL;
|
oven_pid_current_status.timestamp_last_run = 0ULL;
|
||||||
oven_pid_current_status.active = true;
|
oven_pid_current_status.active = true;
|
||||||
oven_pid_current_status.error_flags.vref_tol = false;
|
|
||||||
oven_pid_current_status.error_flags.pt1000_other = false;
|
|
||||||
oven_pid_current_status.error_flags.generic_error = false;
|
|
||||||
oven_pid_current_status.error_flags.pt1000_adc_off = false;
|
|
||||||
oven_pid_current_status.error_flags.controller_overtemp = false;
|
|
||||||
oven_pid_current_status.error_flags.pt1000_adc_watchdog = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void oven_pid_handle(float target_temp)
|
void oven_pid_handle(float target_temp, float current_temp)
|
||||||
{
|
{
|
||||||
float pid_out;
|
float pid_out;
|
||||||
float current_temp;
|
|
||||||
int resistance_status;
|
|
||||||
enum adc_pt1000_error pt1000_error;
|
|
||||||
|
|
||||||
if (oven_pid_current_status.active && !oven_pid_current_status.aborted) {
|
if (oven_pid_current_status.active) {
|
||||||
if (systick_ticks_have_passed(oven_pid_current_status.timestamp_last_run,
|
if (systick_ticks_have_passed(oven_pid_current_status.timestamp_last_run,
|
||||||
(uint64_t)(oven_pid.sample_period * 1000))) {
|
(uint64_t)(oven_pid.sample_period * 1000))) {
|
||||||
|
|
||||||
resistance_status = adc_pt1000_get_current_resistance(¤t_temp);
|
|
||||||
if (resistance_status < 0) {
|
|
||||||
oven_driver_set_power(0);
|
|
||||||
pt1000_error = adc_pt1000_check_error();
|
|
||||||
if (pt1000_error & ADC_PT1000_WATCHDOG_ERROR)
|
|
||||||
oven_pid_report_error(OVEN_PID_ERR_PT1000_ADC_WATCHDOG);
|
|
||||||
if (pt1000_error & ADC_PT1000_INACTIVE)
|
|
||||||
oven_pid_report_error(OVEN_PID_ERR_PT1000_ADC_OFF);
|
|
||||||
if (pt1000_error & ADC_PT1000_OVERFLOW)
|
|
||||||
oven_pid_report_error(OVEN_PID_ERR_PT1000_OTHER);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)temp_converter_convert_resistance_to_temp(current_temp, ¤t_temp);
|
|
||||||
|
|
||||||
pid_out = pid_sample(&oven_pid, target_temp - current_temp);
|
pid_out = pid_sample(&oven_pid, target_temp - current_temp);
|
||||||
oven_driver_set_power((uint8_t)pid_out);
|
oven_driver_set_power((uint8_t)pid_out);
|
||||||
oven_pid_current_status.timestamp_last_run = systick_get_global_tick();
|
oven_pid_current_status.timestamp_last_run = systick_get_global_tick();
|
||||||
|
oven_pid_current_status.active = true;
|
||||||
oven_pid_current_status.target_temp = target_temp;
|
oven_pid_current_status.target_temp = target_temp;
|
||||||
oven_pid_current_status.current_temp = current_temp;
|
oven_pid_current_status.current_temp = current_temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void oven_pid_report_error(enum oven_pid_error_report report)
|
void oven_pid_report_error()
|
||||||
{
|
{
|
||||||
struct oven_pid_errors *e = &oven_pid_current_status.error_flags;
|
|
||||||
|
|
||||||
oven_pid_current_status.active = false;
|
oven_pid_current_status.active = false;
|
||||||
oven_pid_current_status.aborted = true;
|
oven_pid_current_status.aborted = true;
|
||||||
|
|
||||||
if (report == 0) {
|
|
||||||
e->generic_error = true;
|
|
||||||
}
|
|
||||||
if (report & OVEN_PID_ERR_OVERTEMP)
|
|
||||||
e->controller_overtemp = true;
|
|
||||||
if (report & OVEN_PID_ERR_VREF_TOL)
|
|
||||||
e->controller_overtemp = true;
|
|
||||||
if (report & OVEN_PID_ERR_PT1000_OTHER)
|
|
||||||
e->pt1000_other = true;
|
|
||||||
if (report & OVEN_PID_ERR_PT1000_ADC_OFF)
|
|
||||||
e->pt1000_adc_off = true;
|
|
||||||
if (report & OVEN_PID_ERR_PT1000_ADC_WATCHDOG)
|
|
||||||
e->pt1000_adc_watchdog = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct oven_pid_status *oven_pid_get_status()
|
const struct oven_pid_status *oven_pid_get_status()
|
||||||
|
@ -27,16 +27,14 @@
|
|||||||
#include <reflow-controller/safety-adc.h>
|
#include <reflow-controller/safety-adc.h>
|
||||||
#include <reflow-controller/temp-converter.h>
|
#include <reflow-controller/temp-converter.h>
|
||||||
#include <helper-macros/helper-macros.h>
|
#include <helper-macros/helper-macros.h>
|
||||||
#include <stm-periph/unique-id.h>
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
static char __attribute__((section(".ccmram"))) display_buffer[4][21] = {0};
|
static char __attribute__((section(".ccmram"))) display_buffer[4][21] = {0};
|
||||||
static struct lcd_menu reflow_menu;
|
static struct lcd_menu reflow_menu;
|
||||||
static struct lcd_menu * const reflow_menu_ptr = &reflow_menu;
|
static struct lcd_menu *reflow_menu_ptr = &reflow_menu;
|
||||||
|
|
||||||
static void update_display_buffer(uint8_t row, const char *data)
|
static void update_display_buffer(uint8_t row, const char *data)
|
||||||
{
|
{
|
||||||
@ -108,91 +106,29 @@ static void reflow_menu_about(struct lcd_menu *menu, enum menu_entry_func_entry
|
|||||||
{
|
{
|
||||||
static void *my_parent;
|
static void *my_parent;
|
||||||
static bool button_ready;
|
static bool button_ready;
|
||||||
static int page = 0;
|
char buff[20];
|
||||||
static uint32_t uptime_secs;
|
|
||||||
uint32_t new_uptime_secs;
|
|
||||||
uint32_t uptime_mins;
|
|
||||||
uint32_t uptime_hours;
|
|
||||||
uint32_t uptime_days;
|
|
||||||
int16_t rot_delta;
|
|
||||||
uint32_t ser1, ser2, ser3;
|
|
||||||
enum button_state push_button;
|
|
||||||
|
|
||||||
if (entry_type == MENU_ENTRY_FIRST_ENTER) {
|
if (entry_type == MENU_ENTRY_FIRST_ENTER) {
|
||||||
uptime_secs = 0ULL;
|
|
||||||
page = 0;
|
|
||||||
my_parent = parent;
|
my_parent = parent;
|
||||||
button_ready = false;
|
button_ready = false;
|
||||||
menu_display_clear(menu);
|
menu_display_clear(menu);
|
||||||
menu_ack_rotary_delta(menu);
|
|
||||||
}
|
|
||||||
|
|
||||||
rot_delta = menu_get_rotary_delta(menu);
|
menu->update_display(0, LCD_SHIMATTA_STRING " Reflow");
|
||||||
if (rot_delta >= 4) {
|
snprintf(buff, sizeof(buff), "%.*s", LCD_CHAR_WIDTH, xstr(GIT_VER));
|
||||||
menu_ack_rotary_delta(menu);
|
menu->update_display(1, buff);
|
||||||
if (page < 4) {
|
|
||||||
page++;
|
|
||||||
menu_display_clear(menu);
|
|
||||||
}
|
|
||||||
} else if (rot_delta <= -4) {
|
|
||||||
menu_ack_rotary_delta(menu);
|
|
||||||
if (page > 0) {
|
|
||||||
page--;
|
|
||||||
menu_display_clear(menu);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (page) {
|
|
||||||
case 0:
|
|
||||||
menu_lcd_output(menu, 0, LCD_SHIMATTA_STRING " Shimatta");
|
|
||||||
menu_lcd_output(menu, 1, "Oven Controller");
|
|
||||||
menu_lcd_output(menu, 2, "(c) Mario H\xF5ttel");
|
|
||||||
menu_lcd_output(menu, 3, "Page 1/5");
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
menu_lcd_output(menu, 0, "Version Number:");
|
|
||||||
menu_lcd_outputf(menu, 1, "%.*s", LCD_CHAR_WIDTH, xstr(GIT_VER));
|
|
||||||
if (strlen(xstr(GIT_VER)) > LCD_CHAR_WIDTH) {
|
if (strlen(xstr(GIT_VER)) > LCD_CHAR_WIDTH) {
|
||||||
menu_lcd_outputf(menu, 2, "%s", &xstr(GIT_VER)[LCD_CHAR_WIDTH]);
|
snprintf(buff, sizeof(buff), "%s", &xstr(GIT_VER)[LCD_CHAR_WIDTH]);
|
||||||
}
|
menu->update_display(2, buff);
|
||||||
menu_lcd_output(menu, 3, "Page 2/5");
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
menu_lcd_output(menu, 0, "Compile Info");
|
|
||||||
menu_lcd_output(menu, 1, __DATE__);
|
|
||||||
menu_lcd_output(menu, 2, __TIME__);
|
|
||||||
menu_lcd_output(menu, 3, "Page 3/5");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
unique_id_get(&ser1, &ser2, &ser3);
|
|
||||||
|
|
||||||
menu_lcd_outputf(menu, 0, "Serial: %08X", ser1);
|
|
||||||
menu_lcd_outputf(menu, 1, " %08X", ser2);
|
|
||||||
menu_lcd_outputf(menu, 2, " %08X", ser3);
|
|
||||||
menu_lcd_output(menu, 3, "Page 4/5");
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
systick_get_uptime_from_tick(&uptime_days, &uptime_hours, &uptime_mins, &new_uptime_secs);
|
|
||||||
if (new_uptime_secs != uptime_secs) {
|
|
||||||
uptime_secs = new_uptime_secs;
|
|
||||||
menu_lcd_output(menu, 0, "Uptime:");
|
|
||||||
menu_lcd_outputf(menu, 1, "%lu day%s %02lu:%02lu:%02lu",
|
|
||||||
uptime_days, (uptime_days == 1 ? "" : "s"), uptime_hours, uptime_mins, uptime_secs);
|
|
||||||
menu_lcd_output(menu, 3, "Page 5/5");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
page = 0;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
push_button = menu_get_button_state(menu);
|
menu->update_display(3, __DATE__);
|
||||||
|
}
|
||||||
|
|
||||||
if (push_button == BUTTON_IDLE)
|
if (menu->inputs.push_button == BUTTON_IDLE)
|
||||||
button_ready = true;
|
button_ready = true;
|
||||||
|
|
||||||
if (button_ready &&
|
if (button_ready &&
|
||||||
(push_button == BUTTON_SHORT_RELEASED || push_button == BUTTON_LONG)) {
|
(menu->inputs.push_button == BUTTON_SHORT_RELEASED || menu->inputs.push_button == BUTTON_LONG)) {
|
||||||
menu_entry_dropback(menu, my_parent);
|
menu_entry_dropback(menu, my_parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -207,12 +143,11 @@ static void reflow_menu_root_entry(struct lcd_menu *menu, enum menu_entry_func_e
|
|||||||
"Monitoring",
|
"Monitoring",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static const menu_func_t root_entry_funcs[] = {
|
static const menu_func_t root_entry_funcs[] = {
|
||||||
reflow_menu_about,
|
reflow_menu_about,
|
||||||
reflow_menu_monitor
|
reflow_menu_monitor
|
||||||
};
|
};
|
||||||
enum button_state push_button;
|
|
||||||
int16_t rot_delta;
|
|
||||||
|
|
||||||
if (entry_type != MENU_ENTRY_CONTINUE) {
|
if (entry_type != MENU_ENTRY_CONTINUE) {
|
||||||
menu_display_clear(menu);
|
menu_display_clear(menu);
|
||||||
@ -228,20 +163,19 @@ static void reflow_menu_root_entry(struct lcd_menu *menu, enum menu_entry_func_e
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
push_button = menu_get_button_state(menu);
|
if (menu->inputs.push_button == BUTTON_IDLE) {
|
||||||
rot_delta = menu_get_rotary_delta(menu);
|
|
||||||
|
|
||||||
if (push_button == BUTTON_IDLE) {
|
|
||||||
button_valid = true;
|
button_valid = true;
|
||||||
} else if (button_valid && push_button == BUTTON_SHORT_RELEASED) {
|
} else if (button_valid && menu->inputs.push_button == BUTTON_SHORT_RELEASED) {
|
||||||
/* Enter currently selected menu_entry */
|
/* Enter currently selected menu_entry */
|
||||||
menu_list_enter_selected_entry(&list, menu);
|
menu_list_enter_selected_entry(&list, menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rot_delta >= 4) {
|
|
||||||
|
|
||||||
|
if (menu->inputs.rotary_encoder_delta >= 4) {
|
||||||
menu_list_scroll_down(&list);
|
menu_list_scroll_down(&list);
|
||||||
menu_ack_rotary_delta(menu);
|
menu_ack_rotary_delta(menu);
|
||||||
} else if (rot_delta <= -4) {
|
} else if (menu->inputs.rotary_encoder_delta <= -4) {
|
||||||
menu_list_scroll_up(&list);
|
menu_list_scroll_up(&list);
|
||||||
menu_ack_rotary_delta(menu);
|
menu_ack_rotary_delta(menu);
|
||||||
}
|
}
|
||||||
@ -249,6 +183,7 @@ static void reflow_menu_root_entry(struct lcd_menu *menu, enum menu_entry_func_e
|
|||||||
menu_list_display(&list, 1, 3);
|
menu_list_display(&list, 1, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int reflow_menu_handle()
|
int reflow_menu_handle()
|
||||||
{
|
{
|
||||||
int32_t rot_delta;
|
int32_t rot_delta;
|
||||||
@ -260,15 +195,15 @@ int reflow_menu_handle()
|
|||||||
|
|
||||||
menu_handle(reflow_menu_ptr, (int16_t)rot_delta, button);
|
menu_handle(reflow_menu_ptr, (int16_t)rot_delta, button);
|
||||||
|
|
||||||
if (lcd_ret == LCD_FSM_CALL_AGAIN || lcd_tick_100us >= 5) {
|
if (lcd_ret != LCD_FSM_WAIT_CALL || lcd_tick_ms >= 1) {
|
||||||
lcd_ret = lcd_fsm_write_buffer(display_buffer);
|
lcd_ret = lcd_fsm_write_buffer(display_buffer);
|
||||||
lcd_tick_100us = 0UL;
|
lcd_tick_ms = 0UL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lcd_ret == LCD_FSM_CALL_AGAIN)
|
if (lcd_ret == LCD_FSM_CALL_AGAIN)
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return 1;
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reflow_menu_init()
|
void reflow_menu_init()
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include <reflow-controller/safety-adc.h>
|
#include <reflow-controller/safety-adc.h>
|
||||||
#include <reflow-controller/periph-config/safety-adc-hwcfg.h>
|
#include <reflow-controller/periph-config/safety-adc-hwcfg.h>
|
||||||
#include <helper-macros/helper-macros.h>
|
|
||||||
#include <stm-periph/clock-enable-manager.h>
|
#include <stm-periph/clock-enable-manager.h>
|
||||||
|
|
||||||
void safety_adc_init()
|
void safety_adc_init()
|
||||||
@ -50,32 +50,18 @@ enum safety_adc_check_result safety_adc_check_results(uint16_t vref_result, uint
|
|||||||
float *vref_calculated, float *temp_calculated)
|
float *vref_calculated, float *temp_calculated)
|
||||||
{
|
{
|
||||||
enum safety_adc_check_result res = SAFETY_ADC_CHECK_OK;
|
enum safety_adc_check_result res = SAFETY_ADC_CHECK_OK;
|
||||||
float vref;
|
|
||||||
float temp;
|
|
||||||
|
|
||||||
|
|
||||||
vref = (SAFETY_ADC_INT_REF_MV * 4095.0f) / (float)vref_result;
|
|
||||||
if (vref_calculated) {
|
if (vref_calculated) {
|
||||||
*vref_calculated = vref;
|
*vref_calculated = (SAFETY_ADC_INT_REF_MV * 4095.0f) / (float)vref_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
temp = (((float)temp_result / 4095.0f * 2500.0f -
|
|
||||||
SAFETY_ADC_TEMP_NOM_MV) / SAFETY_ADC_TEMP_MV_SLOPE) + SAFETY_ADC_TEMP_NOM;
|
|
||||||
if (temp_calculated) {
|
if (temp_calculated) {
|
||||||
*temp_calculated = temp;
|
*temp_calculated = (((float)temp_result / 4095.0f * 2500.0f -
|
||||||
|
SAFETY_ADC_TEMP_NOM_MV) / SAFETY_ADC_TEMP_MV_SLOPE) + SAFETY_ADC_TEMP_NOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ABS(vref - SAFETY_ADC_VREF_MVOLT) > SAFETY_ADC_VREF_TOL_MVOLT) {
|
/* TODO: Implement safety ADC checking */
|
||||||
if (vref > SAFETY_ADC_VREF_MVOLT)
|
|
||||||
res |= SAFETY_ADC_CHECK_VREF_HIGH;
|
|
||||||
else
|
|
||||||
res |= SAFETY_ADC_CHECK_VREF_LOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (temp < SAFETY_ADC_TEMP_LOW_LIM)
|
|
||||||
res |= SAFETY_ADC_CHECK_TEMP_LOW;
|
|
||||||
else if (temp < SAFETY_ADC_CHECK_TEMP_HIGH)
|
|
||||||
res |= SAFETY_ADC_CHECK_TEMP_HIGH;
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -189,18 +189,8 @@ static shellmatta_retCode_t shell_cmd_uptime(const shellmatta_handle_t handle,
|
|||||||
{
|
{
|
||||||
(void)arguments;
|
(void)arguments;
|
||||||
(void)length;
|
(void)length;
|
||||||
uint32_t days;
|
|
||||||
uint32_t hours;
|
|
||||||
uint32_t mins;
|
|
||||||
uint32_t secs;
|
|
||||||
|
|
||||||
systick_get_uptime_from_tick(&days, &hours, &mins, &secs);
|
shellmatta_printf(handle, "Uptime: %llu secs", global_tick_ms/1000);
|
||||||
|
|
||||||
shellmatta_printf(handle, "Uptime: %u day%s %02u:%02u:%02u",
|
|
||||||
days, (days == 1 ? "" : "s"),
|
|
||||||
hours,
|
|
||||||
mins,
|
|
||||||
secs);
|
|
||||||
return SHELLMATTA_OK;
|
return SHELLMATTA_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,11 +28,11 @@
|
|||||||
|
|
||||||
volatile uint32_t wait_tick_ms = 0UL;
|
volatile uint32_t wait_tick_ms = 0UL;
|
||||||
volatile uint64_t global_tick_ms = 0ULL;
|
volatile uint64_t global_tick_ms = 0ULL;
|
||||||
volatile uint32_t lcd_tick_100us = 0UL;
|
volatile uint32_t lcd_tick_ms = 0UL;
|
||||||
|
|
||||||
void systick_setup(void)
|
void systick_setup(void)
|
||||||
{
|
{
|
||||||
/* Setup Systick for 100us tick @ 168 MHz Clock Speed */
|
/* Setup Systick for 1ms tick @ 168 MHz Clock Speed */
|
||||||
SysTick_Config(SYSTICK_RELOAD);
|
SysTick_Config(SYSTICK_RELOAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,35 +53,6 @@ uint64_t systick_get_global_tick()
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void systick_get_uptime_from_tick(uint32_t *days, uint32_t *hours, uint32_t *minutes, uint32_t *seconds)
|
|
||||||
{
|
|
||||||
uint64_t tick_secs;
|
|
||||||
uint32_t secs;
|
|
||||||
uint32_t mins;
|
|
||||||
uint32_t hs;
|
|
||||||
uint32_t ds;
|
|
||||||
|
|
||||||
|
|
||||||
tick_secs = systick_get_global_tick() / 1000;
|
|
||||||
secs = tick_secs % 60;
|
|
||||||
tick_secs /= 60;
|
|
||||||
mins = tick_secs % 60;
|
|
||||||
tick_secs /= 60;
|
|
||||||
hs = tick_secs % 60;
|
|
||||||
tick_secs /= 24;
|
|
||||||
ds = tick_secs;
|
|
||||||
|
|
||||||
if (days)
|
|
||||||
*days = ds;
|
|
||||||
if (hours)
|
|
||||||
*hours = hs;
|
|
||||||
if (minutes)
|
|
||||||
*minutes = mins;
|
|
||||||
if (seconds)
|
|
||||||
*seconds = secs;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool __attribute__((optimize("O3"))) systick_ticks_have_passed(uint64_t start_timestamp, uint64_t ticks)
|
bool __attribute__((optimize("O3"))) systick_ticks_have_passed(uint64_t start_timestamp, uint64_t ticks)
|
||||||
{
|
{
|
||||||
uint64_t end_timestamp = start_timestamp + ticks;
|
uint64_t end_timestamp = start_timestamp + ticks;
|
||||||
@ -111,14 +82,8 @@ bool __attribute__((optimize("O3"))) systick_ticks_have_passed(uint64_t start_ti
|
|||||||
*/
|
*/
|
||||||
void __attribute__((optimize("O3"))) SysTick_Handler()
|
void __attribute__((optimize("O3"))) SysTick_Handler()
|
||||||
{
|
{
|
||||||
static uint32_t pre_tick = 0UL;
|
|
||||||
|
|
||||||
pre_tick++;
|
|
||||||
if (pre_tick == 10) {
|
|
||||||
pre_tick = 0;
|
|
||||||
/* Increase tick counters */
|
/* Increase tick counters */
|
||||||
wait_tick_ms++;
|
wait_tick_ms++;
|
||||||
global_tick_ms++;
|
global_tick_ms++;
|
||||||
}
|
lcd_tick_ms++;
|
||||||
lcd_tick_100us++;
|
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ static void lcd_command(uint8_t data)
|
|||||||
// Set DD RAM Address --------- 0b1xxxxxxx (Display Data RAM)
|
// Set DD RAM Address --------- 0b1xxxxxxx (Display Data RAM)
|
||||||
#define LCD_SET_DDADR 0x80
|
#define LCD_SET_DDADR 0x80
|
||||||
|
|
||||||
static char __attribute__((section(".ccmram"))) shadow_display[4][21];
|
static char shadow_display[4][21];
|
||||||
|
|
||||||
void lcd_clear(void)
|
void lcd_clear(void)
|
||||||
{
|
{
|
||||||
@ -403,7 +403,7 @@ enum lcd_fsm_ret lcd_fsm_write_buffer(const char (*display_buffer)[21])
|
|||||||
state_cnt++;
|
state_cnt++;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if (!systick_ticks_have_passed(timestamp, 4)) {
|
if (!systick_ticks_have_passed(timestamp, 5)) {
|
||||||
ret = LCD_FSM_WAIT_CALL;
|
ret = LCD_FSM_WAIT_CALL;
|
||||||
} else {
|
} else {
|
||||||
ret = LCD_FSM_CALL_AGAIN;
|
ret = LCD_FSM_CALL_AGAIN;
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include <reflow-controller/ui/menu.h>
|
#include <reflow-controller/ui/menu.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
void menu_handle(struct lcd_menu *menu, int16_t rotary_encoder_delta, enum button_state push_button)
|
void menu_handle(struct lcd_menu *menu, int16_t rotary_encoder_delta, enum button_state push_button)
|
||||||
{
|
{
|
||||||
@ -89,7 +88,7 @@ void menu_entry_enter(struct lcd_menu *menu, menu_func_t entry, bool handle_imme
|
|||||||
menu_handle(menu, menu->inputs.rotary_encoder_delta, menu->inputs.push_button);
|
menu_handle(menu, menu->inputs.rotary_encoder_delta, menu->inputs.push_button);
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu_lcd_output(struct lcd_menu *menu, uint8_t row_num, const char *text)
|
void menu_override_lcd_output(struct lcd_menu *menu, uint8_t row_num, const char *text)
|
||||||
{
|
{
|
||||||
if (!menu || !menu->update_display)
|
if (!menu || !menu->update_display)
|
||||||
return;
|
return;
|
||||||
@ -97,18 +96,6 @@ void menu_lcd_output(struct lcd_menu *menu, uint8_t row_num, const char *text)
|
|||||||
menu->update_display(row_num, text);
|
menu->update_display(row_num, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void menu_lcd_outputf(struct lcd_menu *menu, uint8_t row_num, const char *format, ...)
|
|
||||||
{
|
|
||||||
char buff[64];
|
|
||||||
va_list valist;
|
|
||||||
|
|
||||||
va_start(valist, format);
|
|
||||||
vsnprintf(buff, sizeof(buff), format, valist);
|
|
||||||
buff[sizeof(buff) - 1] = '\0';
|
|
||||||
menu_lcd_output(menu, row_num, buff);
|
|
||||||
va_end(valist);
|
|
||||||
}
|
|
||||||
|
|
||||||
void menu_list_display(struct menu_list *list, uint32_t top_row, uint32_t bottom_row)
|
void menu_list_display(struct menu_list *list, uint32_t top_row, uint32_t bottom_row)
|
||||||
{
|
{
|
||||||
uint8_t row_count;
|
uint8_t row_count;
|
||||||
@ -159,8 +146,7 @@ void menu_list_display(struct menu_list *list, uint32_t top_row, uint32_t bottom
|
|||||||
if (current_idx >= list->entry_count)
|
if (current_idx >= list->entry_count)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
snprintf(workbuff, sizeof(workbuff), "%c%s", (current_idx == list->currently_selected ? '>' : ' '),
|
snprintf(workbuff, sizeof(workbuff), "%c%s", (current_idx == list->currently_selected ? '>' : ' '), list->entry_names[current_idx]);
|
||||||
list->entry_names[current_idx]);
|
|
||||||
workbuff[sizeof(workbuff)-1] = 0;
|
workbuff[sizeof(workbuff)-1] = 0;
|
||||||
list->update_display((uint8_t)current_row, workbuff);
|
list->update_display((uint8_t)current_row, workbuff);
|
||||||
}
|
}
|
||||||
@ -223,26 +209,6 @@ void menu_ack_rotary_delta(struct lcd_menu *menu)
|
|||||||
menu->inputs.rotary_encoder_delta = 0;
|
menu->inputs.rotary_encoder_delta = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t menu_get_rotary_delta(const struct lcd_menu *menu)
|
|
||||||
{
|
|
||||||
int16_t ret = 0;
|
|
||||||
|
|
||||||
if (menu)
|
|
||||||
ret = menu->inputs.rotary_encoder_delta;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum button_state menu_get_button_state(const struct lcd_menu *menu)
|
|
||||||
{
|
|
||||||
enum button_state ret = BUTTON_IDLE;
|
|
||||||
|
|
||||||
if (menu)
|
|
||||||
ret = menu->inputs.push_button;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void menu_display_clear(struct lcd_menu *menu)
|
void menu_display_clear(struct lcd_menu *menu)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user