[feat] add quadratic and calc concentration by pp value
This commit is contained in:
parent
e12afdc85a
commit
98ae861a70
@ -24,7 +24,7 @@ add_definitions(-DUSE_STDPERIPH_DRIVER)
|
|||||||
|
|
||||||
enable_language(ASM)
|
enable_language(ASM)
|
||||||
add_executable(${PROJ_NAME}.elf main.c)
|
add_executable(${PROJ_NAME}.elf main.c)
|
||||||
target_sources(${PROJ_NAME}.elf PUBLIC start.S)
|
target_sources(${PROJ_NAME}.elf PUBLIC ${CMAKE_CURRENT_LIST_DIR}/start.S)
|
||||||
|
|
||||||
add_subdirectory(../driver driver)
|
add_subdirectory(../driver driver)
|
||||||
target_link_libraries(${PROJ_NAME}.elf driver)
|
target_link_libraries(${PROJ_NAME}.elf driver)
|
||||||
|
|||||||
@ -175,7 +175,7 @@ void adc_loop(void)
|
|||||||
val = adc_det_temp_from_ltc1867;
|
val = adc_det_temp_from_ltc1867;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
debug_write_data(DEBUG_CH_ADC_RAW + ch, (float)val);
|
// debug_write_data(DEBUG_CH_ADC_RAW + ch, (float)val);
|
||||||
adc_input_data(ch, val); /* input data from ADC to sort buffer */
|
adc_input_data(ch, val); /* input data from ADC to sort buffer */
|
||||||
if (ch == 0) {
|
if (ch == 0) {
|
||||||
val = adc_get_filter_data(ch);
|
val = adc_get_filter_data(ch);
|
||||||
@ -184,19 +184,19 @@ void adc_loop(void)
|
|||||||
#else
|
#else
|
||||||
value = adc_rtot(val);
|
value = adc_rtot(val);
|
||||||
#endif
|
#endif
|
||||||
debug_write_data(DEBUG_CH_ADC_FILTER + ch, (float)value);
|
// debug_write_data(DEBUG_CH_ADC_FILTER + ch, (float)value);
|
||||||
device_data.detector_temperature = value;
|
device_data.detector_temperature = value;
|
||||||
ch = 1;
|
ch = 1;
|
||||||
} else if (ch == 1) {
|
} else if (ch == 1) {
|
||||||
val = adc_get_filter_data(ch);
|
val = adc_get_filter_data(ch);
|
||||||
value = adc_rtot(val);
|
value = adc_rtot(val);
|
||||||
debug_write_data(DEBUG_CH_ADC_FILTER + ch, (float)value);
|
// debug_write_data(DEBUG_CH_ADC_FILTER + ch, (float)value);
|
||||||
device_data.lamp_temperature = value;
|
device_data.lamp_temperature = value;
|
||||||
ch = 3;
|
ch = 3;
|
||||||
} else if (ch == 3) {
|
} else if (ch == 3) {
|
||||||
val = adc_get_filter_data(ch);
|
val = adc_get_filter_data(ch);
|
||||||
value = (uint32_t)val * 6600 / 4096;
|
value = (uint32_t)val * 6600 / 4096;
|
||||||
debug_write_data(DEBUG_CH_ADC_FILTER + ch, (float)value);
|
// debug_write_data(DEBUG_CH_ADC_FILTER + ch, (float)value);
|
||||||
device_data.lamp_voltage = value;
|
device_data.lamp_voltage = value;
|
||||||
ch = 0;
|
ch = 0;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
#define __CALC_H__
|
#define __CALC_H__
|
||||||
|
|
||||||
#define NUM_TYPE float
|
#define NUM_TYPE float
|
||||||
#define CALC_POINTS (128)
|
#define CALC_POINTS (32)
|
||||||
|
|
||||||
/* y = a * x^2 + b * x + c */
|
/* y = a * x^2 + b * x + c */
|
||||||
struct quadratic_coefficient_s {
|
struct quadratic_coefficient_s {
|
||||||
|
|||||||
@ -6,8 +6,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LEDIR_FREQ (8)
|
#define LEDIR_FREQ (8)
|
||||||
#define SAMPLES_PER_PERIOD (64)
|
#define SAMPLES_PER_PERIOD (256)
|
||||||
#define CALC_CNT (SAMPLES_PER_PERIOD / 2)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,13 +14,12 @@
|
|||||||
#define DEBUG_UART_BAUDRATE (2 * 1000 * 1000)
|
#define DEBUG_UART_BAUDRATE (2 * 1000 * 1000)
|
||||||
|
|
||||||
#define DEBUG_CH_RAW (0 * 4)
|
#define DEBUG_CH_RAW (0 * 4)
|
||||||
#define DEBUG_CH_SUM_1 (1 * 4)
|
#define DEBUG_CH_QUADRATIC (1 * 4)
|
||||||
#define DEBUG_CH_SUM_2 (2 * 4)
|
#define DEBUG_CH_MEDIAN (2 * 4)
|
||||||
#define DEBUG_CH_MEDIAN (3 * 4)
|
#define DEBUG_CH_WINDOW (3 * 4)
|
||||||
#define DEBUG_CH_WINDOW (4 * 4)
|
// #define DEBUG_CH_ADC_RAW (4 * 4)
|
||||||
#define DEBUG_CH_ADC_RAW (5 * 4)
|
// #define DEBUG_CH_ADC_FILTER (5 * 4)
|
||||||
#define DEBUG_CH_ADC_FILTER (6 * 4)
|
#define DEBUG_CHAN_MAX (4 * 4)
|
||||||
#define DEBUG_CHAN_MAX (7 * 4)
|
|
||||||
|
|
||||||
struct debug_data_s {
|
struct debug_data_s {
|
||||||
uint8_t enable;
|
uint8_t enable;
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "ltc1867.h"
|
#include "ltc1867.h"
|
||||||
|
#include "calc.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "user_misc.h"
|
#include "user_misc.h"
|
||||||
|
|
||||||
static uint32_t sum_gas1[FILTER_SUM_LEN_GAS1] __attribute__((section(".bss_ccm")));
|
|
||||||
static uint32_t sum_gas2[FILTER_SUM_LEN_GAS2] __attribute__((section(".bss_ccm")));
|
|
||||||
static uint32_t sum_gas3[FILTER_SUM_LEN_GAS3] __attribute__((section(".bss_ccm")));
|
|
||||||
static uint32_t sum_gas4[FILTER_SUM_LEN_GAS4] __attribute__((section(".bss_ccm")));
|
|
||||||
static struct list_s median_gas1[FILTER_MEDIAN_LEN_GAS1] __attribute__((section(".bss_ccm")));
|
static struct list_s median_gas1[FILTER_MEDIAN_LEN_GAS1] __attribute__((section(".bss_ccm")));
|
||||||
static struct list_s median_gas2[FILTER_MEDIAN_LEN_GAS2] __attribute__((section(".bss_ccm")));
|
static struct list_s median_gas2[FILTER_MEDIAN_LEN_GAS2] __attribute__((section(".bss_ccm")));
|
||||||
static struct list_s median_gas3[FILTER_MEDIAN_LEN_GAS3] __attribute__((section(".bss_ccm")));
|
static struct list_s median_gas3[FILTER_MEDIAN_LEN_GAS3] __attribute__((section(".bss_ccm")));
|
||||||
@ -22,26 +19,18 @@ struct data_filter_s data_filter[4] __attribute__((section(".bss_ccm")));
|
|||||||
void filter_init(void)
|
void filter_init(void)
|
||||||
{
|
{
|
||||||
/* data_filter parameter init */
|
/* data_filter parameter init */
|
||||||
data_filter[0].sum_len = FILTER_SUM_LEN_GAS1;
|
|
||||||
data_filter[0].sum_buff = sum_gas1;
|
|
||||||
data_filter[0].median_len = FILTER_MEDIAN_LEN_GAS1;
|
data_filter[0].median_len = FILTER_MEDIAN_LEN_GAS1;
|
||||||
data_filter[0].median_buff = median_gas1;
|
data_filter[0].median_buff = median_gas1;
|
||||||
data_filter[0].window_len = FILTER_WINDOW_LEN_GAS1;
|
data_filter[0].window_len = FILTER_WINDOW_LEN_GAS1;
|
||||||
data_filter[0].window_buff = window_gas1;
|
data_filter[0].window_buff = window_gas1;
|
||||||
data_filter[1].sum_len = FILTER_SUM_LEN_GAS2;
|
|
||||||
data_filter[1].sum_buff = sum_gas2;
|
|
||||||
data_filter[1].median_len = FILTER_MEDIAN_LEN_GAS2;
|
data_filter[1].median_len = FILTER_MEDIAN_LEN_GAS2;
|
||||||
data_filter[1].median_buff = median_gas2;
|
data_filter[1].median_buff = median_gas2;
|
||||||
data_filter[1].window_len = FILTER_WINDOW_LEN_GAS2;
|
data_filter[1].window_len = FILTER_WINDOW_LEN_GAS2;
|
||||||
data_filter[1].window_buff = window_gas2;
|
data_filter[1].window_buff = window_gas2;
|
||||||
data_filter[2].sum_len = FILTER_SUM_LEN_GAS3;
|
|
||||||
data_filter[2].sum_buff = sum_gas3;
|
|
||||||
data_filter[2].median_len = FILTER_MEDIAN_LEN_GAS3;
|
data_filter[2].median_len = FILTER_MEDIAN_LEN_GAS3;
|
||||||
data_filter[2].median_buff = median_gas3;
|
data_filter[2].median_buff = median_gas3;
|
||||||
data_filter[2].window_len = FILTER_WINDOW_LEN_GAS3;
|
data_filter[2].window_len = FILTER_WINDOW_LEN_GAS3;
|
||||||
data_filter[2].window_buff = window_gas3;
|
data_filter[2].window_buff = window_gas3;
|
||||||
data_filter[3].sum_len = FILTER_SUM_LEN_GAS4;
|
|
||||||
data_filter[3].sum_buff = sum_gas4;
|
|
||||||
data_filter[3].median_len = FILTER_MEDIAN_LEN_GAS4;
|
data_filter[3].median_len = FILTER_MEDIAN_LEN_GAS4;
|
||||||
data_filter[3].median_buff = median_gas4;
|
data_filter[3].median_buff = median_gas4;
|
||||||
data_filter[3].window_len = FILTER_WINDOW_LEN_GAS4;
|
data_filter[3].window_len = FILTER_WINDOW_LEN_GAS4;
|
||||||
@ -50,14 +39,6 @@ void filter_init(void)
|
|||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
|
|
||||||
/* sum filter init */
|
|
||||||
len = data_filter[i].sum_len;
|
|
||||||
for (uint16_t j = 0; j < len; j++) {
|
|
||||||
data_filter[i].sum_buff[j] = 0;
|
|
||||||
}
|
|
||||||
data_filter[i].sum_sum = 0;
|
|
||||||
data_filter[i].sum_idx = 0;
|
|
||||||
|
|
||||||
/* media filter init */
|
/* media filter init */
|
||||||
data_filter[i].median_idx = 0;
|
data_filter[i].median_idx = 0;
|
||||||
len = data_filter[i].median_len;
|
len = data_filter[i].median_len;
|
||||||
@ -91,29 +72,27 @@ void filter_init(void)
|
|||||||
flag.filter_climb = FILTER_WINDOW_LEN_GAS1 + FILTER_MEDIAN_LEN_GAS1;
|
flag.filter_climb = FILTER_WINDOW_LEN_GAS1 + FILTER_MEDIAN_LEN_GAS1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void filter_input_data(uint8_t channel, uint32_t data)
|
void filter_quadratic_process(void)
|
||||||
{
|
{
|
||||||
data_filter[channel].input = data;
|
struct quadratic_coefficient_s coeff;
|
||||||
}
|
float rative, peak;
|
||||||
|
uint32_t pos_ravine, pos_peak;
|
||||||
void filter_sum_process(void)
|
|
||||||
{
|
|
||||||
uint32_t sum, val;
|
|
||||||
uint16_t idx;
|
|
||||||
|
|
||||||
|
pos_ravine = data_ltc1867.pos_ravine + SAMPLES_PER_PERIOD / 4 - CALC_POINTS / 2;
|
||||||
|
pos_peak = data_ltc1867.pos_peak + SAMPLES_PER_PERIOD / 4 - CALC_POINTS / 2;
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
idx = data_filter[i].sum_idx;
|
calc_quadratic_fit(data_ltc1867.p_calc[i] + pos_ravine, &coeff, CALC_POINTS);
|
||||||
sum = data_filter[i].sum_sum;
|
rative = coeff.c - coeff.b * coeff.b / (4.0f * coeff.a);
|
||||||
val = data_filter[i].input;
|
calc_quadratic_fit(data_ltc1867.p_calc[i] + pos_peak, &coeff, CALC_POINTS);
|
||||||
debug_write_data(DEBUG_CH_SUM_1 + i, (float)val);
|
peak = coeff.c - coeff.b * coeff.b / (4.0f * coeff.a);
|
||||||
sum = sum - data_filter[i].sum_buff[idx];
|
data_filter[i].raw_f = peak - rative;
|
||||||
data_filter[i].sum_buff[idx] = val;
|
debug_write_data(DEBUG_CH_QUADRATIC + i, data_filter[i].raw_f);
|
||||||
sum = sum + val;
|
if (data_filter[i].raw_f < 0.0f) {
|
||||||
data_filter[i].sum_sum = sum;
|
data_filter[i].raw_u = 0;
|
||||||
debug_write_data(DEBUG_CH_SUM_2 + i, (float)(data_filter[i].sum_sum));
|
} else if (data_filter[i].raw_f >= 65535.0f) {
|
||||||
data_filter[i].sum_idx++;
|
data_filter[i].raw_u = 65535;
|
||||||
if (data_filter[i].sum_idx >= data_filter[i].sum_len) {
|
} else {
|
||||||
data_filter[i].sum_idx = 0;
|
data_filter[i].raw_u = (uint32_t)(data_filter[i].raw_f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -131,7 +110,7 @@ void filter_median_process(void)
|
|||||||
list->prev->next = list->next; /* connect prev to next */
|
list->prev->next = list->next; /* connect prev to next */
|
||||||
list->next->prev = list->prev; /* connect next to prev */
|
list->next->prev = list->prev; /* connect next to prev */
|
||||||
/* add new node */
|
/* add new node */
|
||||||
data = data_filter[i].sum_sum;
|
data = data_filter[i].raw_u;
|
||||||
data_filter[i].median_buff[idx].data = data;
|
data_filter[i].median_buff[idx].data = data;
|
||||||
len = data_filter[i].median_len + 1;
|
len = data_filter[i].median_len + 1;
|
||||||
data_filter[i].head.data = 0xFFFFFFFF;
|
data_filter[i].head.data = 0xFFFFFFFF;
|
||||||
@ -207,7 +186,7 @@ void filter_loop(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
flag.filter = data_ltc1867.calc_flag;
|
flag.filter = data_ltc1867.calc_flag;
|
||||||
filter_sum_process();
|
filter_quadratic_process();
|
||||||
filter_median_process();
|
filter_median_process();
|
||||||
filter_window_process();
|
filter_window_process();
|
||||||
filter_output_process();
|
filter_output_process();
|
||||||
|
|||||||
@ -7,11 +7,6 @@
|
|||||||
|
|
||||||
#include "stm32f4xx.h"
|
#include "stm32f4xx.h"
|
||||||
|
|
||||||
#define FILTER_SUM_LEN_GAS1 (8 * 2)
|
|
||||||
#define FILTER_SUM_LEN_GAS2 (8 * 2)
|
|
||||||
#define FILTER_SUM_LEN_GAS3 (8 * 2)
|
|
||||||
#define FILTER_SUM_LEN_GAS4 (8 * 2)
|
|
||||||
|
|
||||||
#define FILTER_MEDIAN_LEN_GAS1 (128)
|
#define FILTER_MEDIAN_LEN_GAS1 (128)
|
||||||
#define FILTER_MEDIAN_LEN_GAS2 (64)
|
#define FILTER_MEDIAN_LEN_GAS2 (64)
|
||||||
#define FILTER_MEDIAN_LEN_GAS3 (64)
|
#define FILTER_MEDIAN_LEN_GAS3 (64)
|
||||||
@ -29,12 +24,8 @@ struct list_s {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct data_filter_s {
|
struct data_filter_s {
|
||||||
uint32_t input;
|
float raw_f;
|
||||||
|
uint32_t raw_u;
|
||||||
uint16_t sum_len;
|
|
||||||
uint16_t sum_idx;
|
|
||||||
uint32_t *sum_buff;
|
|
||||||
uint32_t sum_sum;
|
|
||||||
|
|
||||||
uint16_t median_len;
|
uint16_t median_len;
|
||||||
uint16_t median_idx;
|
uint16_t median_idx;
|
||||||
@ -50,8 +41,7 @@ struct data_filter_s {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern void filter_init(void);
|
extern void filter_init(void);
|
||||||
extern void filter_input_data(uint8_t channel, uint32_t data);
|
extern void filter_quadratic_process(void);
|
||||||
extern void filter_sum_process(void);
|
|
||||||
extern void filter_median_process(void);
|
extern void filter_median_process(void);
|
||||||
extern void filter_window_process(void);
|
extern void filter_window_process(void);
|
||||||
extern void filter_output_process(void);
|
extern void filter_output_process(void);
|
||||||
|
|||||||
@ -10,10 +10,9 @@
|
|||||||
#include "stm32f4xx_tim.h"
|
#include "stm32f4xx_tim.h"
|
||||||
#include "stm32f4xx_spi.h"
|
#include "stm32f4xx_spi.h"
|
||||||
|
|
||||||
#define diff32768(data) ((data > 32768) ? (data - 32768) : (32768 - data))
|
float data_ltc1867_raw[2][4][SAMPLES_PER_PERIOD * 2] __attribute__((section(".bss_ccm")));
|
||||||
|
|
||||||
struct data_ltc1867_s data_ltc1867 __attribute__((section(".bss_ccm")));
|
struct data_ltc1867_s data_ltc1867 __attribute__((section(".bss_ccm")));
|
||||||
static const uint16_t ltc1867_spi_data[LTC1867_CH_CNT] = {0xC400, 0x9400, 0xD400, 0xA400, 0x8400}; /* order: ch1, ch2, ch3, ch4, ch0 */
|
__attribute__((section(".data_ccm"))) uint16_t ltc1867_spi_data[LTC1867_CH_CNT] = {0xC400, 0x9400, 0xD400, 0xA400, 0x8400}; /* order: ch1, ch2, ch3, ch4, ch0 */
|
||||||
|
|
||||||
void ltc1867_init(void)
|
void ltc1867_init(void)
|
||||||
{
|
{
|
||||||
@ -101,15 +100,14 @@ void ltc1867_init(void)
|
|||||||
ltc1867_transfer(ltc1867_spi_data[LTC1867_CH_CNT - 1]);
|
ltc1867_transfer(ltc1867_spi_data[LTC1867_CH_CNT - 1]);
|
||||||
|
|
||||||
/* data_ltc1867 init */
|
/* data_ltc1867 init */
|
||||||
data_ltc1867.sum[0] = 0; /* store temporary sum of half period sum */
|
data_ltc1867.calc_cnt = 0;
|
||||||
data_ltc1867.sum[1] = 0;
|
data_ltc1867.calc_flag = 0; /* 2 period complete, need calc */
|
||||||
data_ltc1867.sum[2] = 0;
|
|
||||||
data_ltc1867.sum[3] = 0;
|
|
||||||
data_ltc1867.calc_flag = 0; /* half period complete, need calc */
|
|
||||||
data_ltc1867.ledir_cnt = 0; /* index of led count, for togglr IR led */
|
data_ltc1867.ledir_cnt = 0; /* index of led count, for togglr IR led */
|
||||||
data_ltc1867.val_idx = 0; /* index of value in half period, for sum */
|
data_ltc1867.state_idx = 0; /* index for search point of 32768 */
|
||||||
data_ltc1867.warm = SAMPLES_PER_PERIOD * LEDIR_FREQ; /* in first 1s, only toggle IR led, discard sample ADC value */
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
data_ltc1867.locked = 0; /* zero point capture */
|
data_ltc1867.p_samp[i] = data_ltc1867_raw[0][i];
|
||||||
|
data_ltc1867.p_calc[i] = data_ltc1867_raw[1][i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ltc1867_ledir_on(void)
|
void ltc1867_ledir_on(void)
|
||||||
@ -175,17 +173,19 @@ uint16_t ltc1867_transfer(uint16_t data_send)
|
|||||||
|
|
||||||
void TIM2_IRQHandler(void)
|
void TIM2_IRQHandler(void)
|
||||||
{
|
{
|
||||||
|
static uint16_t pre_ref = 0;
|
||||||
uint16_t val[LTC1867_CH_CNT];
|
uint16_t val[LTC1867_CH_CNT];
|
||||||
|
|
||||||
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
|
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
|
||||||
|
|
||||||
/* for control led IR */
|
/* for control led IR */
|
||||||
data_ltc1867.ledir_cnt++;
|
data_ltc1867.ledir_cnt++;
|
||||||
if (data_ltc1867.ledir_cnt == (SAMPLES_PER_PERIOD / 2)) {
|
if ((data_ltc1867.ledir_cnt == (SAMPLES_PER_PERIOD / 2)) || \
|
||||||
|
(data_ltc1867.ledir_cnt == (SAMPLES_PER_PERIOD / 2 * 3))) {
|
||||||
ltc1867_ledir_on();
|
ltc1867_ledir_on();
|
||||||
} else if (data_ltc1867.ledir_cnt >= SAMPLES_PER_PERIOD) {
|
} else if ((data_ltc1867.ledir_cnt == (SAMPLES_PER_PERIOD)) || \
|
||||||
|
(data_ltc1867.ledir_cnt == (SAMPLES_PER_PERIOD * 2))) {
|
||||||
ltc1867_ledir_off();
|
ltc1867_ledir_off();
|
||||||
data_ltc1867.ledir_cnt = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sample 5 channel adc data */
|
/* sample 5 channel adc data */
|
||||||
@ -195,66 +195,81 @@ void TIM2_IRQHandler(void)
|
|||||||
ltc1867_spi_select(); /* convert complete, make convert pin low for reading sample data by SPI */
|
ltc1867_spi_select(); /* convert complete, make convert pin low for reading sample data by SPI */
|
||||||
val[i] = ltc1867_transfer(ltc1867_spi_data[i]); /* read convert data and send next channel information */
|
val[i] = ltc1867_transfer(ltc1867_spi_data[i]); /* read convert data and send next channel information */
|
||||||
}
|
}
|
||||||
/* split 2 for loop, because sample timing is strict, only place important code in sample duration */
|
|
||||||
|
/* ltc1867 original sample data */
|
||||||
for (uint8_t i = 0; i < 4; i++) {
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
data_ltc1867.sum[i] += diff32768(val[i]); /* add every channel original data for next process */
|
float val_f = (float)val[i]; /* convert to float */
|
||||||
debug_write_data(DEBUG_CH_RAW + i, (float)val[i]); /* channel 0~3 for ltc1867 original sample data */
|
data_ltc1867.p_samp[i][data_ltc1867.ledir_cnt - 1] = val_f;
|
||||||
}
|
debug_write_data(DEBUG_CH_RAW + i, val_f);
|
||||||
adc_det_temp_from_ltc1867 = val[4]; /* channel 4 for ltc1867 detector temperature sample data */
|
|
||||||
data_ltc1867.val_idx++;
|
|
||||||
if ((data_ltc1867.val_idx >= CALC_CNT) && (data_ltc1867.locked != 0)) {
|
|
||||||
data_ltc1867.val_idx = 0;
|
|
||||||
if (cli_data_comb.force_available & CLI_FORCE_FILTER_INPUT1_MASK) {
|
|
||||||
filter_input_data(0, cli_data_comb.force_data[CLI_FORCE_FILTER_INPUT1] / FILTER_SUM_LEN_GAS1);
|
|
||||||
} else {
|
|
||||||
filter_input_data(0, data_ltc1867.sum[0]);
|
|
||||||
}
|
|
||||||
if (cli_data_comb.force_available & CLI_FORCE_FILTER_INPUT2_MASK) {
|
|
||||||
filter_input_data(1, cli_data_comb.force_data[CLI_FORCE_FILTER_INPUT2] / FILTER_SUM_LEN_GAS2);
|
|
||||||
} else {
|
|
||||||
filter_input_data(1, data_ltc1867.sum[1]);
|
|
||||||
}
|
|
||||||
if (cli_data_comb.force_available & CLI_FORCE_FILTER_INPUT3_MASK) {
|
|
||||||
filter_input_data(2, cli_data_comb.force_data[CLI_FORCE_FILTER_INPUT3] / FILTER_SUM_LEN_GAS3);
|
|
||||||
} else {
|
|
||||||
filter_input_data(2, data_ltc1867.sum[2]);
|
|
||||||
}
|
|
||||||
if (cli_data_comb.force_available & CLI_FORCE_FILTER_INPUT4_MASK) {
|
|
||||||
filter_input_data(3, cli_data_comb.force_data[CLI_FORCE_FILTER_INPUT4] / FILTER_SUM_LEN_GAS4);
|
|
||||||
} else {
|
|
||||||
filter_input_data(3, data_ltc1867.sum[3]);
|
|
||||||
}
|
|
||||||
data_ltc1867.sum[0] = 0;
|
|
||||||
data_ltc1867.sum[1] = 0;
|
|
||||||
data_ltc1867.sum[2] = 0;
|
|
||||||
data_ltc1867.sum[3] = 0;
|
|
||||||
data_ltc1867.calc_flag++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data_ltc1867.warm > 0) {
|
/* channel 4 for ltc1867 detector temperature sample data */
|
||||||
/* in warm stage */
|
adc_det_temp_from_ltc1867 = val[4];
|
||||||
data_ltc1867.warm--;
|
|
||||||
} else {
|
/* search point of 32768 */
|
||||||
/* warm complete */
|
if ((pre_ref < 32768) && (val[0] >= 32768)) {
|
||||||
if (data_ltc1867.locked > 0) {
|
data_ltc1867.state_pos[data_ltc1867.state_idx] = data_ltc1867.ledir_cnt - 1;
|
||||||
/* nothing, normal running state */
|
data_ltc1867.state_edge[data_ltc1867.state_idx++] = 1; /* 1 for rising edge */
|
||||||
} else {
|
} else if ((pre_ref >= 32768) && (val[0] < 32768)) {
|
||||||
/* has not locked wave */
|
data_ltc1867.state_pos[data_ltc1867.state_idx] = data_ltc1867.ledir_cnt - 1;
|
||||||
static uint16_t pre_ref = 32768;
|
data_ltc1867.state_edge[data_ltc1867.state_idx++] = 0; /* 0 for falling edge */
|
||||||
if ((pre_ref < 32768) && (val[0] >= 32768)) {
|
}
|
||||||
/* meet lock condition */
|
pre_ref = val[0];
|
||||||
data_ltc1867.sum[0] = diff32768(val[0]);
|
|
||||||
data_ltc1867.sum[1] = diff32768(val[1]);
|
/* 2 cycle complete */
|
||||||
data_ltc1867.sum[2] = diff32768(val[2]);
|
if (data_ltc1867.ledir_cnt >= SAMPLES_PER_PERIOD * 2) {
|
||||||
data_ltc1867.sum[3] = diff32768(val[3]);
|
float *p;
|
||||||
data_ltc1867.val_idx = 1;
|
/* exchange pointor of calc/samp data */
|
||||||
data_ltc1867.locked = 1;
|
for (uint8_t i = 0; i < 4; i++) {
|
||||||
} else {
|
p = data_ltc1867.p_calc[i];
|
||||||
/* not meet lock condition */
|
data_ltc1867.p_calc[i] = data_ltc1867.p_samp[i];
|
||||||
pre_ref = val[0];
|
data_ltc1867.p_samp[i] = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ledir count need empty */
|
||||||
|
data_ltc1867.ledir_cnt = 0;
|
||||||
|
data_ltc1867.calc_cnt++;
|
||||||
|
|
||||||
|
/* check whether the data meets requirements */
|
||||||
|
if (data_ltc1867.state_idx == 4) {
|
||||||
|
if ((data_ltc1867.state_pos[0] < SAMPLES_PER_PERIOD / 4) && \
|
||||||
|
(data_ltc1867.state_pos[1] >= SAMPLES_PER_PERIOD / 2) && (data_ltc1867.state_pos[1] < SAMPLES_PER_PERIOD / 4 * 3) && \
|
||||||
|
(data_ltc1867.state_pos[2] >= SAMPLES_PER_PERIOD) && (data_ltc1867.state_pos[2] < SAMPLES_PER_PERIOD / 4 * 5) && \
|
||||||
|
(data_ltc1867.state_pos[3] >= SAMPLES_PER_PERIOD / 2 * 3) && (data_ltc1867.state_pos[3] < SAMPLES_PER_PERIOD / 4 * 7)) {
|
||||||
|
/* pos is head */
|
||||||
|
if ((data_ltc1867.state_edge[0] == 0) && (data_ltc1867.state_edge[1] == 1) && (data_ltc1867.state_edge[2] == 0) && (data_ltc1867.state_edge[3] == 1)) {
|
||||||
|
data_ltc1867.state = 1; /* first ravine late */
|
||||||
|
data_ltc1867.pos_peak = data_ltc1867.state_pos[1];
|
||||||
|
data_ltc1867.pos_ravine = data_ltc1867.state_pos[2];
|
||||||
|
data_ltc1867.calc_flag++; /* trig calc */
|
||||||
|
} else if ((data_ltc1867.state_edge[0] == 1) && (data_ltc1867.state_edge[1] == 0) && (data_ltc1867.state_edge[2] == 1) && (data_ltc1867.state_edge[3] == 0)) {
|
||||||
|
data_ltc1867.state = 3; /* first peak late */
|
||||||
|
data_ltc1867.pos_ravine = data_ltc1867.state_pos[1];
|
||||||
|
data_ltc1867.pos_peak = data_ltc1867.state_pos[2];
|
||||||
|
data_ltc1867.calc_flag++; /* trig calc */
|
||||||
|
}
|
||||||
|
} else if ((data_ltc1867.state_pos[0] >= SAMPLES_PER_PERIOD / 4) && (data_ltc1867.state_pos[0] < SAMPLES_PER_PERIOD / 2) && \
|
||||||
|
(data_ltc1867.state_pos[1] >= SAMPLES_PER_PERIOD / 4 * 3) && (data_ltc1867.state_pos[1] < SAMPLES_PER_PERIOD) && \
|
||||||
|
(data_ltc1867.state_pos[2] >= SAMPLES_PER_PERIOD / 4 * 5) && (data_ltc1867.state_pos[2] < SAMPLES_PER_PERIOD / 2 * 3) && \
|
||||||
|
(data_ltc1867.state_pos[3] >= SAMPLES_PER_PERIOD / 4 * 7) && (data_ltc1867.state_pos[3] < SAMPLES_PER_PERIOD *2)) {
|
||||||
|
/* pos is later */
|
||||||
|
if ((data_ltc1867.state_edge[0] == 0) && (data_ltc1867.state_edge[1] == 1) && (data_ltc1867.state_edge[2] == 0) && (data_ltc1867.state_edge[3] == 1)) {
|
||||||
|
data_ltc1867.state = 2; /* first peak ahead */
|
||||||
|
data_ltc1867.pos_ravine = data_ltc1867.state_pos[0];
|
||||||
|
data_ltc1867.pos_peak = data_ltc1867.state_pos[1];
|
||||||
|
data_ltc1867.calc_flag++; /* trig calc */
|
||||||
|
} else if ((data_ltc1867.state_edge[0] == 1) && (data_ltc1867.state_edge[1] == 0) && (data_ltc1867.state_edge[2] == 1) && (data_ltc1867.state_edge[3] == 0)) {
|
||||||
|
data_ltc1867.state = 0; /* first ravine ahead */
|
||||||
|
data_ltc1867.pos_peak = data_ltc1867.state_pos[0];
|
||||||
|
data_ltc1867.pos_ravine = data_ltc1867.state_pos[1];
|
||||||
|
data_ltc1867.calc_flag++; /* trig calc */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data_ltc1867.state_idx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cali_flash_write();
|
cali_flash_write();
|
||||||
debug_send_frame();
|
debug_send_frame();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,12 +25,17 @@
|
|||||||
#define PIN_SPI_SDI (GPIO_Pin_7)
|
#define PIN_SPI_SDI (GPIO_Pin_7)
|
||||||
|
|
||||||
struct data_ltc1867_s {
|
struct data_ltc1867_s {
|
||||||
uint32_t sum[4]; /* store temporary sum of half period sum */
|
uint32_t calc_flag; /* double period complete, need calc */
|
||||||
uint32_t calc_flag; /* half period complete, need calc */
|
uint32_t calc_cnt; /* totle count of double period complete */
|
||||||
uint16_t ledir_cnt; /* index of led count, for togglr IR led */
|
uint16_t ledir_cnt; /* index of led count, for togglr IR led */
|
||||||
uint16_t val_idx; /* index of value in half period, for sum */
|
uint8_t state; /* 0~3 is available, 0:first ravine ahead, 1:first ravine late, 2:first peak ahead, 3:first peak late */
|
||||||
uint16_t warm; /* in first 1s, only toggle IR led, discard sample ADC value */
|
uint8_t state_idx; /* 0~3 is available, sample 4 times of point 32768 */
|
||||||
uint8_t locked; /* 32768 point capture */
|
uint8_t state_edge[4]; /* 0 or 1 is available, 0:falling edge, 1:rising edge */
|
||||||
|
uint16_t state_pos[4]; /* position of every edge, 0~(SAMPLES_PER_PERIOD*2-1) is available */
|
||||||
|
uint16_t pos_ravine; /* position of ravine */
|
||||||
|
uint16_t pos_peak; /* position of peak */
|
||||||
|
float *p_calc[4]; /* pointor for calculation */
|
||||||
|
float *p_samp[4]; /* pointor for store sample data */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct data_ltc1867_s data_ltc1867;
|
extern struct data_ltc1867_s data_ltc1867;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user