diff --git a/lark1fq/main.c b/lark1fq/main.c index c7a4ef5..54abe06 100755 --- a/lark1fq/main.c +++ b/lark1fq/main.c @@ -1,5 +1,6 @@ #include "misc.h" #include "user_misc.h" +#include "button.h" #include "ltc1867.h" #include "modbus.h" #include "filter.h" @@ -24,16 +25,6 @@ void system_tick_init(void) SysTick_Config(rcc_clocks.HCLK_Frequency / 1000); } -void led_loop(void) -{ - static uint32_t tick = 0; - - if (system_tick_cnt - tick > 500) { - led_toggle(LED1); - tick = system_tick_cnt; - } -} - void device_init(void) { flag.filter = data_ltc1867.calc_flag; @@ -47,6 +38,7 @@ void system_init(void) cali_update_from_flash(); led_init(LED1 | LED2); heat_init(); + button_init(); ltc1867_init(); modbus_init(); filter_init(); @@ -58,6 +50,7 @@ void system_init(void) device_init(); ltc2640_init(); ms5611_init(); + led_det_temperature_init(); } int main(void) @@ -72,9 +65,12 @@ int main(void) filter_loop(); concentration_loop(); adc_loop(); + led_det_temperature_loop(); + led_sig_loop(); cli_loop(); ltc2640_loop(); ms5611_loop(); + button_loop(); } return 0; } diff --git a/lark1fq/src/CMakeLists.txt b/lark1fq/src/CMakeLists.txt index f231d3a..a3a9385 100755 --- a/lark1fq/src/CMakeLists.txt +++ b/lark1fq/src/CMakeLists.txt @@ -7,6 +7,7 @@ add_definitions(-DDET_TEMPERATURE_LTC1867) file(GLOB FILELIST device.c user_misc.c +button.c ltc1867.c filter.c concentration.c diff --git a/lark1fq/src/button.c b/lark1fq/src/button.c new file mode 100755 index 0000000..2d236b8 --- /dev/null +++ b/lark1fq/src/button.c @@ -0,0 +1,138 @@ +#include "stm32f4xx_rcc.h" +#include "stm32f4xx_gpio.h" +#include "button.h" +#include "device.h" +#include "cali.h" +#include "user_misc.h" + +volatile uint8_t flag_cali_by_button = 0; + +static void button_cali_zero(void) +{ + uint8_t ret; + uint8_t count = 0; + + flag_cali_by_button = 1; + /* cali zero record */ + for (uint8_t ch = 0; ch < 4; ch++) { + ret = cali_zero_record(ch); + if (ret == 0xFF) { + /* invalid/reference channel */ + continue; + } else if (ret == 0) { + /* cali zero record success */ + device_status.cali_zero_record_status[ch] = 0; + } else { + /* cali zero record failed */ + device_status.cali_zero_record_status[ch] = ret; + return; + } + } + /* cali zero active */ + for (uint8_t ch = 0; ch < 4; ch++) { + ret = cali_zero_activate(ch); + if (ret == 0xFF) { + /* invalid/reference channel */ + count++; + continue; + } else if (ret == 0) { + /* cali zero active success */ + device_status.cali_activate_status &= ~(1 << ch); + count++; + } else { + /* cali zero active failed */ + device_status.cali_activate_status |= (1 << ch); + return; + } + } + flag_cali_by_button = 0; + /* failed or success */ + if (count >= 4) { + data_cali_flash.word_remain = CALI_FLASH_WORD_CNT; + led_ctrl[1].times_volatile = 0; + led_ctrl[1].times = 3; + led_ctrl[1].on_volatile = 0; + led_ctrl[1].on = 5; + led_ctrl[1].off = 5; + led_ctrl[1].state_save = led_ctrl[1].state; + led_ctrl[1].state = LED_BLINK_ON; + } +} + +static void button_cali_restore(void) +{ + flag_cali_by_button = 1; + for (uint8_t ch = 0; ch < 4; ch++) { + cali_restore(ch); + device_status.cali_restore_status &= ~(1 << ch); + } + flag_cali_by_button = 0; + data_cali_flash.word_remain = CALI_FLASH_WORD_CNT; + led_ctrl[1].times_volatile = 0; + led_ctrl[1].times = 5; + led_ctrl[1].on_volatile = 0; + led_ctrl[1].on = 5; + led_ctrl[1].off = 5; + led_ctrl[1].state_save = led_ctrl[1].state; + led_ctrl[1].state = LED_BLINK_ON; +} + +static void button_reset_system(void) +{ + NVIC_SystemReset(); +} + +void button_init(void) +{ + GPIO_InitTypeDef GPIO_InitStructure = { + .GPIO_Pin = PIN_BUTTON, + .GPIO_Mode = GPIO_Mode_IN, + .GPIO_OType = GPIO_OType_PP, + .GPIO_Speed = GPIO_Speed_2MHz, + .GPIO_PuPd = GPIO_PuPd_UP, + }; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); + GPIO_Init(PORT_BUTTON, &GPIO_InitStructure); +} + +int button_is_pressed(void) +{ + if (GPIO_ReadInputDataBit(PORT_BUTTON, PIN_BUTTON)) { + return 0; + } else { + return 1; + } +} + +void button_loop(void) +{ + static uint32_t ms = 0; + static uint32_t cnt_pressed = 0; + static uint32_t cnt_released = 0; + + if (system_tick_cnt < (ms + 100)) { + return; + } + ms = system_tick_cnt; + + if (button_is_pressed()) { + cnt_pressed++; + cnt_released = 0; + } else { + cnt_released++; + if ((cnt_pressed > 0) && (cnt_released > 2)) { + if (cnt_pressed < 3) { + /* do nothing */ + } else if (cnt_pressed < 30) { + button_cali_zero(); + } else if (cnt_pressed < 75) { + button_cali_restore(); + } else { + button_reset_system(); + } + cnt_released = 0; + cnt_pressed = 0; + } + } +} diff --git a/lark1fq/src/button.h b/lark1fq/src/button.h new file mode 100755 index 0000000..b852512 --- /dev/null +++ b/lark1fq/src/button.h @@ -0,0 +1,23 @@ +#ifndef __BUTTON_H__ +#define __BUTTON_H__ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "stm32f4xx.h" + +#define PORT_BUTTON (GPIOB) +#define PIN_BUTTON (GPIO_Pin_14) + +extern uint32_t system_tick_cnt; + +void button_init(void); +int button_is_pressed(void); +void button_loop(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __BUTTON_H__ */ diff --git a/lark1fq/src/cali.c b/lark1fq/src/cali.c index 92ce082..47aa2b0 100755 --- a/lark1fq/src/cali.c +++ b/lark1fq/src/cali.c @@ -365,7 +365,9 @@ uint8_t cali_zero_activate(uint8_t ch) data_cali_flash.sig_zero[ch - 1] = data_cali_ram.sig_zero[ch - 1]; data_cali_flash.temperature_zero[ch - 1] = data_cali_ram.temperature_zero[ch - 1]; data_cali_flash.stage[ch - 1] = CALI_STAGE_ACTIVED; /* bit[3:0] for zero, bit[7:4] for span */ - data_cali_flash.word_remain = CALI_FLASH_WORD_CNT; + if (flag_cali_by_button == 0) { + data_cali_flash.word_remain = CALI_FLASH_WORD_CNT; + } return 0; } @@ -434,7 +436,9 @@ void cali_restore(uint8_t ch) data_cali_flash.concentration[ch - 1] = 0; data_cali_flash.temperature_zero[ch - 1] = 0; data_cali_flash.temperature_span[ch - 1] = 0; - data_cali_flash.word_remain = CALI_FLASH_WORD_CNT; + if (flag_cali_by_button == 0) { + data_cali_flash.word_remain = CALI_FLASH_WORD_CNT; + } } void cali_zero_parse_from_flash(uint8_t ch) diff --git a/lark1fq/src/cali.h b/lark1fq/src/cali.h index 2c91dae..faf2078 100755 --- a/lark1fq/src/cali.h +++ b/lark1fq/src/cali.h @@ -35,6 +35,7 @@ struct data_cali_s { extern struct data_cali_s data_cali_flash; extern struct data_cali_s data_cali_ram; +extern volatile uint8_t flag_cali_by_button; uint8_t cali_get_zero_stage(uint8_t stage); uint8_t cali_get_span_stage(uint8_t stage); diff --git a/lark1fq/src/user_misc.c b/lark1fq/src/user_misc.c index cc32d38..f4dc1a7 100755 --- a/lark1fq/src/user_misc.c +++ b/lark1fq/src/user_misc.c @@ -4,6 +4,7 @@ #include "stm32f4xx_gpio.h" struct data_gas_info_s data_gas_info __attribute__((section(".bss_ccm"))); +struct led_ctrl_s led_ctrl[2]; void led_init(uint16_t led) { @@ -18,6 +19,9 @@ void led_init(uint16_t led) RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); GPIO_Init(PORT_LED, &GPIO_InitStructure); led_off(led); + for (uint8_t i = 0; i < 2; i++) { + led_ctrl[i].state = 0; + } } void led_off(uint16_t led) @@ -35,6 +39,124 @@ void led_toggle(uint16_t led) GPIO_ToggleBits(PORT_LED, led); } +void led_det_temperature_init(void) +{ + led_ctrl[0].times_volatile = 0; + led_ctrl[0].times = ~0; + led_ctrl[0].on_volatile = 0; + led_ctrl[0].on = 10; + led_ctrl[0].off = 10; + led_ctrl[0].state = LED_BLINK_ON; +} + +void led_det_temperature_loop(void) +{ + static uint32_t ms = 0; + static uint32_t det_temp = 0; + uint32_t diff; + + if (system_tick_cnt < (ms + 1000 * 60)) { + return; + } + ms = system_tick_cnt; + + if (det_temp < device_data.detector_temperature) { + diff = device_data.detector_temperature - det_temp; + } else { + diff = det_temp - device_data.detector_temperature; + } + det_temp = device_data.detector_temperature; + if (diff < 20) { + /* deterator temperature is stable */ + led_ctrl[0].state = LED_ON; + } else { + /* deterator temperature is not stable */ + led_det_temperature_init(); + } +} + +void led_sig_loop(void) +{ + static uint32_t ms = 0; + uint8_t count = 0; + uint8_t led; + + if (system_tick_cnt < (ms + 100)) { + return; + } + ms = system_tick_cnt; + + for (uint8_t ch = 0; ch < 4; ch++) { + if (data_gas_info.id[ch] == GAS_ID_INVALID) { + count++; + continue; + } else { + if (device_data.gas_sig[ch] < 10) { + break; + } else { + count++; + } + } + } + if (count >= 4) { + /* sig is all normal, LED on */ + led = LED_ON; + } else { + /* sig is not all normal, LED off */ + led = LED_OFF; + } + + if (led_ctrl[1].state == LED_BLINK_OFF || led_ctrl[1].state == LED_BLINK_ON) { + led_ctrl[1].state_save = led; + } else { + led_ctrl[1].state = led; + } +} + +void led_loop(void) +{ + static uint32_t ms = 0; + uint16_t led; + + if (system_tick_cnt < (ms + 100)) { + return; + } + ms = system_tick_cnt; + + for (uint8_t i = 0; i < 2; i++) { + led = (i == 0) ? LED1 : LED2; + if (led_ctrl[i].state == LED_OFF) { + led_off(led); + } else if (led_ctrl[i].state == LED_ON) { + led_on(led); + } else { + if (led_ctrl[i].state == LED_BLINK_OFF) { + led_off(led); + led_ctrl[i].off_volatile++; + if (led_ctrl[i].off_volatile >= led_ctrl[i].off) { + led_ctrl[i].off_volatile = 0; + led_ctrl[i].on_volatile = 0; + led_ctrl[i].state = LED_BLINK_ON; + led_ctrl[i].times_volatile++; + if (led_ctrl[i].times == ~0) { + /* blink forever */ + } else if (led_ctrl[i].times_volatile >= led_ctrl[i].times) { + led_ctrl[i].state = led_ctrl[i].state_save; + } + } + } else if (led_ctrl[i].state == LED_BLINK_ON) { + led_on(led); + led_ctrl[i].on_volatile++; + if (led_ctrl[i].on_volatile >= led_ctrl[i].on) { + led_ctrl[i].on_volatile = 0; + led_ctrl[i].off_volatile = 0; + led_ctrl[i].state = LED_BLINK_OFF; + } + } + } + } +} + void heat_init(void) { GPIO_InitTypeDef GPIO_InitStructure = { diff --git a/lark1fq/src/user_misc.h b/lark1fq/src/user_misc.h index dc9d79a..6639bc7 100755 --- a/lark1fq/src/user_misc.h +++ b/lark1fq/src/user_misc.h @@ -29,13 +29,37 @@ struct data_gas_info_s { uint8_t comb; }; +#define LED_OFF (0) +#define LED_ON (1) +#define LED_BLINK_ON (2) +#define LED_BLINK_OFF (3) + +struct led_ctrl_s { + uint8_t state_save; /* saved state before blink */ + uint8_t state; /* 0:off, 1:of, 2:blink_on, 3:blink_off */ + uint8_t on; /* led on time when blink, unit:0.1s */ + uint8_t off; /* led off time when blink, unit:0.1s */ + uint8_t times; /* times of blink */ + uint8_t on_volatile; + uint8_t off_volatile; + uint8_t times_volatile; +}; + +extern struct led_ctrl_s led_ctrl[2]; + extern struct data_gas_info_s data_gas_info; +extern uint32_t system_tick_cnt; void led_init(uint16_t led); void led_off(uint16_t led); void led_on(uint16_t led); void led_toggle(uint16_t led); +void led_det_temperature_init(void); +void led_det_temperature_loop(void); +void led_sig_loop(void); +void led_loop(void); + void heat_init(void); void heat_on(void); void heat_off(void);