#ifndef __CALI_H__
#define __CALI_H__

#ifdef __cplusplus
 extern "C" {
#endif

#include "stm32f4xx.h"
#include "device.h"

#define CALI_STAGE_EMPTY     (0)
#define CALI_STAGE_RECORDED  (1)
#define CALI_STAGE_ACTIVED   (2)

#define CALI_FLASH_CALI_SIZE (80)
#define CALI_FLASH_WORD_CNT  (CALI_FLASH_CALI_SIZE / 4)

/* total 80 bytes, [0] store ch1, [1] store ch2, [2] store ch3 */
struct data_cali_s {
    uint32_t id;
    uint32_t ref_zero[3];
    uint32_t sig_zero[3];
    uint32_t ref_span[3];
    uint32_t sig_span[3];
    uint32_t concentration[3];
    uint16_t temperature_zero[3];
    uint16_t temperature_span[3];
    uint8_t stage[3]; /* bit[3:0] for zero, bit[7:4] for span */
    uint8_t word_remain;
    /* below data will not be stored in flash */
    float zero_b0_diff[3];
    float span_b0b_scale[3];
    uint32_t bitmap[3];
};

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);
void cali_init(void);
void cali_update_from_flash(void);
void cali_zero_update_table(uint8_t ch);
void cali_span_update_table(uint8_t ch);
// void cali_update_concentration_table(uint8_t ch);
float cali_conc_calc_b0_static(uint8_t ch, uint32_t temperature);
float cali_conc_calc_b0_dynamic(uint8_t ch, uint32_t temperature);
uint8_t cali_zero_record(uint8_t ch);
float cali_conc_calc_b0b(uint8_t ch, uint32_t temperature, uint32_t concentration);
uint8_t cali_span_record(uint8_t ch, uint32_t conc);
uint8_t cali_zero_activate(uint8_t ch);
uint8_t cali_span_activate(uint8_t ch);
void cali_restore(uint8_t ch);
void cali_zero_parse_from_flash(uint8_t ch);
void cali_span_parse_from_flash(uint8_t ch);

#ifdef __cplusplus
}
#endif

#endif /* __CALI_H__ */
