#include "bsp_bmp390.h"
#include "bsp_motor.h"
#include "bsp_led.h"
#include "bsp_key.h"
#include "CONFIG.h"
#include "log.h"
#include "bsp_ml307r.h"
#include "SLEEP.h"

uint8_t flag;
uint8_t volatile fault_state = 0;
extern uint8_t motor_flag;
extern Shell shell;

static tmosTaskID check_task_id = INVALID_TASK_ID;
typedef enum
{
    kPressIn   = 0,
    kPressOut  = 1,
    kPressAtom = 2,
    kPressMaxIndex
} TePressSensorIndex;

static tmosTaskID press_task_id = INVALID_TASK_ID;

#define PRESS_IN_CS_HIGH()   GPIOA_SetBits(GPIO_Pin_5)
#define PRESS_IN_CS_LOW()    GPIOA_ResetBits(GPIO_Pin_5)

#define PRESS_OUT_CS_HIGH()  GPIOA_SetBits(GPIO_Pin_0)
#define PRESS_OUT_CS_LOW()   GPIOA_ResetBits(GPIO_Pin_0)

#define PRESS_ATOM_CS_HIGH() GPIOA_SetBits(GPIO_Pin_3)
#define PRESS_ATOM_CS_LOW()  GPIOA_ResetBits(GPIO_Pin_3)

uint8_t volatile press_done_flag = 0;

uint8_t SPI0_SendByte(uint8_t data);
void SPI_CsStart(TePressSensorIndex index);
void SPI_CsStop(TePressSensorIndex index);

/* Variable to store the device address */
static uint8_t dev_in_addr;
static uint8_t dev_out_addr;
static uint8_t dev_atom_addr;

uint8_t Bmp_ReadData(uint8_t *reg_data, uint32_t len)
{
    while (len--)
    {
        *reg_data = SPI0_SendByte(0x00);
        reg_data++;
    }
    return BMP3_INTF_RET_SUCCESS;
}

BMP3_INTF_RET_TYPE Bmp_WriteData(const uint8_t *reg_data, uint32_t len)
{
    uint8_t i = 0;
    for (i = 0; i < len; i++)
    {
        SPI0_SendByte(reg_data[i]);
    }
    return BMP3_INTF_RET_SUCCESS;
}

BMP3_INTF_RET_TYPE BMP390_IN_SPI_Read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    BMP3_INTF_RET_TYPE rslt = 0;

    uint8_t reg_spi[1] = {(reg_addr & 0x7F) | 0x80};
    SPI_CsStart(kPressIn);     // 拉低片选
    Bmp_WriteData(reg_spi, 1); // 写入控制字节
    rslt = Bmp_ReadData(reg_data, len);
    SPI_CsStop(kPressIn);
    return rslt;
}

/*!
 * SPI write function map to COINES platform
 */
BMP3_INTF_RET_TYPE BMP390_IN_SPI_Write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    uint8_t reg_spi[1]      = {reg_addr & 0x7f};
    BMP3_INTF_RET_TYPE rslt = 0;

    SPI_CsStart(kPressIn);
    Bmp_WriteData(reg_spi, 1);
    rslt = Bmp_WriteData(reg_data, len);
    SPI_CsStop(kPressIn);
    //    printf("BMP390_OUT_SPI_Write: %d" , rslt);

    return rslt;
}

/*!
 * SPI read function map to COINES platform
 */
BMP3_INTF_RET_TYPE BMP390_OUT_SPI_Read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    BMP3_INTF_RET_TYPE rslt = 0;

    uint8_t reg_spi[1] = {(reg_addr & 0x7F) | 0x80};
    SPI_CsStart(kPressOut);    // 拉低片选
    Bmp_WriteData(reg_spi, 1); // 写入控制字节
    rslt = Bmp_ReadData(reg_data, len);
    SPI_CsStop(kPressOut);
    return rslt;
}

/*!
 * SPI write function map to COINES platform
 */
BMP3_INTF_RET_TYPE BMP390_OUT_SPI_Write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    uint8_t reg_spi[1]      = {reg_addr & 0x7f};
    BMP3_INTF_RET_TYPE rslt = 0;

    SPI_CsStart(kPressOut);
    Bmp_WriteData(reg_spi, 1);
    rslt = Bmp_WriteData(reg_data, len);
    SPI_CsStop(kPressOut);
    //    printf("BMP390_OUT_SPI_Write: %d" , rslt);

    return rslt;
}

BMP3_INTF_RET_TYPE BMP390_ATOM_SPI_Read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    BMP3_INTF_RET_TYPE rslt = 0;

    uint8_t reg_spi[1] = {(reg_addr & 0x7F) | 0x80};
    SPI_CsStart(kPressAtom);     // 拉低片选
    Bmp_WriteData(reg_spi, 1); // 写入控制字节
    rslt = Bmp_ReadData(reg_data, len);
    SPI_CsStop(kPressAtom);
    return rslt;
}

/*!
 * SPI write function map to COINES platform
 */
BMP3_INTF_RET_TYPE BMP390_ATOM_SPI_Write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    uint8_t reg_spi[1]      = {reg_addr & 0x7f};
    BMP3_INTF_RET_TYPE rslt = 0;

    SPI_CsStart(kPressAtom);
    Bmp_WriteData(reg_spi, 1);
    rslt = Bmp_WriteData(reg_data, len);
    SPI_CsStop(kPressAtom);
    //    printf("BMP390_OUT_SPI_Write: %d" , rslt);

    return rslt;
}

void bmp3_delay_us(uint32_t period, void *intf_ptr)
{
    DelayUs(period);
}

void bmp3_check_rslt(const char api_name[], int8_t rslt)
{
    switch (rslt)
    {
        case BMP3_OK:

            /* Do nothing */
            break;
        case BMP3_E_NULL_PTR:
            printf("API [%s] Error [%d] : Null pointer\r\n", api_name, rslt);
            break;
        case BMP3_E_COMM_FAIL:
            printf("API [%s] Error [%d] : Communication failure\r\n", api_name, rslt);
            break;
        case BMP3_E_INVALID_LEN:
            printf("API [%s] Error [%d] : Incorrect length parameter\r\n", api_name, rslt);
            break;
        case BMP3_E_DEV_NOT_FOUND:
            printf("API [%s] Error [%d] : Device not found\r\n", api_name, rslt);
            break;
        case BMP3_E_CONFIGURATION_ERR:
            printf("API [%s] Error [%d] : Configuration Error\r\n", api_name, rslt);
            break;
        case BMP3_W_SENSOR_NOT_ENABLED:
            printf("API [%s] Error [%d] : Warning when Sensor not enabled\r\n", api_name, rslt);
            break;
        case BMP3_W_INVALID_FIFO_REQ_FRAME_CNT:
            printf("API [%s] Error [%d] : Warning when Fifo watermark level is not in limit\r\n", api_name, rslt);
            break;
        default:
            printf("API [%s] Error [%d] : Unknown error code\r\n", api_name, rslt);
            break;
    }
}

BMP3_INTF_RET_TYPE BMP390_IN_InterfaceInit(struct bmp3_dev *bmp3, uint8_t intf)
{
    int8_t rslt = BMP3_OK;

    /* Bus configuration : SPI */
    if (intf == BMP3_SPI_INTF)
    {
        printf("SPI Interface\n");
        bmp3->read  = BMP390_IN_SPI_Read;
        bmp3->write = BMP390_IN_SPI_Write;
        bmp3->intf  = BMP3_SPI_INTF;
        printf("spi init ok\r\n");
    }

    DelayMs(100);
    bmp3->delay_us = bmp3_delay_us;
    bmp3->intf_ptr = &dev_in_addr;

    return rslt;
}

BMP3_INTF_RET_TYPE BMP390_OUT_InterfaceInit(struct bmp3_dev *bmp3, uint8_t intf)
{
    int8_t rslt = BMP3_OK;

    /* Bus configuration : SPI */
    if (intf == BMP3_SPI_INTF)
    {
        printf("SPI Interface\n");
        bmp3->read  = BMP390_OUT_SPI_Read;
        bmp3->write = BMP390_OUT_SPI_Write;
        bmp3->intf  = BMP3_SPI_INTF;
        printf("spi init ok\r\n");
    }

    DelayMs(100);
    bmp3->delay_us = bmp3_delay_us;
    bmp3->intf_ptr = &dev_out_addr;

    return rslt;
}

BMP3_INTF_RET_TYPE BMP390_ATOM_InterfaceInit(struct bmp3_dev *bmp3, uint8_t intf)
{
    int8_t rslt = BMP3_OK;

    /* Bus configuration : SPI */
    if (intf == BMP3_SPI_INTF)
    {
        printf("SPI Interface\n");
        bmp3->read  = BMP390_ATOM_SPI_Read;
        bmp3->write = BMP390_ATOM_SPI_Write;
        bmp3->intf  = BMP3_SPI_INTF;
        printf("spi init ok\r\n");
    }

    DelayMs(100);
    bmp3->delay_us = bmp3_delay_us;
    bmp3->intf_ptr = &dev_atom_addr;

    return rslt;
}

void SPI_CsStart(TePressSensorIndex index)
{
    switch (index)
    {
        case kPressIn:
            PRESS_IN_CS_LOW();
            break;
        case kPressOut:
            PRESS_OUT_CS_LOW();
            break;
        case kPressAtom:
            PRESS_ATOM_CS_LOW();
            break;

        default:
            break;
    }
}

void SPI_CsStop(TePressSensorIndex index)
{
    switch (index)
    {
        case kPressIn:
            PRESS_IN_CS_HIGH();
            break;
        case kPressOut:
            PRESS_OUT_CS_HIGH();
            break;
        case kPressAtom:
            PRESS_ATOM_CS_HIGH();
            break;

        default:
            break;
    }
}

uint8_t SPI0_SendByte(uint8_t data)
{
    R8_SPI0_BUFFER = data;
    while (!(R8_SPI0_INT_FLAG & RB_SPI_FREE));
    return (R8_SPI0_BUFFER);
}

void PRESS_IO_SPI_Init(void)
{
    /**
     * CSB1: PA3
     * CSB2: PA5
     * CSB3: PA0
     * SCL: PA13
     * SDA: PA14
     * SDO: PA15
     */

    // SDA: MOSI
    // SDO: MISO
    GPIOA_SetBits(GPIO_Pin_0);
    GPIOA_ModeCfg(GPIO_Pin_0, GPIO_ModeOut_PP_5mA);

    GPIOA_SetBits(GPIO_Pin_5);
    GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeOut_PP_5mA);

    GPIOA_SetBits(GPIO_Pin_3);
    GPIOA_ModeCfg(GPIO_Pin_3, GPIO_ModeOut_PP_5mA);

    SPI_CsStop(kPressIn);
    SPI_CsStop(kPressOut);
    SPI_CsStop(kPressAtom);

    // spi初始化，模式0
    GPIOA_ModeCfg(GPIO_Pin_13 | GPIO_Pin_14, GPIO_ModeOut_PP_5mA);
    GPIOA_ModeCfg(GPIO_Pin_15, GPIO_ModeIN_PU);

    SPI0_MasterDefInit();
}

void PRESS_LowerIO_Init(void)
{
    // BMP390默认供电时，其他IO都是高电平,INT引脚为低电平
    // SPI
    GPIOA_SetBits(GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15);
    GPIOA_ModeCfg(GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15, GPIO_ModeIN_PU);

    // CSB3: PA0
    GPIOA_SetBits(GPIO_Pin_0);
    GPIOA_ModeCfg(GPIO_Pin_0, GPIO_ModeIN_PU);

    // CSB2: PA5
    GPIOA_SetBits(GPIO_Pin_5);
    GPIOA_ModeCfg(GPIO_Pin_5, GPIO_ModeIN_PU);

    // CSB1: PA3
    GPIOA_SetBits(GPIO_Pin_3);
    GPIOA_ModeCfg(GPIO_Pin_3, GPIO_ModeIN_PU);
}

void Lower_IO_Deinit(void)
{
    // LED
    GPIOA_ResetBits(LED_VALVE_R_PIN | LED_VALVE_G_PIN | LED_VALVE_Y_PIN);
    GPIOA_ModeCfg(LED_VALVE_R_PIN | LED_VALVE_G_PIN | LED_VALVE_Y_PIN, GPIO_ModeIN_PD);
    GPIOB_ResetBits(LED_VBAT_PIN | LED_ALARM_PIN);
    GPIOB_ModeCfg(LED_VBAT_PIN | LED_ALARM_PIN, GPIO_ModeIN_PD);

    // KEY  | RESET KEY | boot KEY
    GPIOB_ResetBits(KEY_B_PIN );
    GPIOB_ModeCfg(KEY_B_PIN, GPIO_ModeIN_PU);
    // GPIOB_ResetBits(GPIO_Pin_23 | GPIO_Pin_22);
    // GPIOB_ModeCfg(GPIO_Pin_23 | GPIO_Pin_22, GPIO_ModeIN_PD);

    // ADC
    GPIOA_ResetBits(GPIO_Pin_4);
    GPIOA_ModeCfg(GPIO_Pin_4, GPIO_ModeIN_Floating);
    ADC_DisablePower();

    // BMP390
    // INT1: PA2 | INT2: PA6  | INT3: PA12
    GPIOA_ModeCfg(GPIO_Pin_2 | GPIO_Pin_6 | GPIO_Pin_12, GPIO_ModeIN_PD);
    // spi初始化
    GPIOA_ModeCfg(GPIO_Pin_13 | GPIO_Pin_14, GPIO_ModeIN_PD);  
    GPIOA_ModeCfg(GPIO_Pin_15, GPIO_ModeIN_PD); 

    //4G
    // 关闭3.8V供电
    GPIOB_ResetBits(ENABLE_3_8_V);
    GPIOB_ModeCfg(ENABLE_3_8_V, GPIO_ModeIN_PD);
    // 将控制引脚设为下拉，减少漏电流
    GPIOB_ModeCfg(ML307_PWR_PIN | ML307_RST_PIN, GPIO_ModeIN_PD);
    // UART引脚设为下拉
    GPIOB_ModeCfg(ML307_UART_TX_PIN | ML307_UART_RX_PIN, GPIO_ModeIN_PU);
    // SIM卡检测引脚配置为下拉输入
    GPIOB_ModeCfg(USIM_DECT_PIN, GPIO_ModeIN_PD);

    //motor
    GPIOB_ResetBits(NSLEEP_PIN);
    GPIOB_ModeCfg(NSLEEP_PIN, GPIO_ModeIN_PD);
    //IN1 + ; IN2 +
    //GPIOB_SetBits(COIL_A);
    //GPIOB_SetBits(COIL_B);
    GPIOB_ModeCfg(COIL_A | COIL_B, GPIO_ModeIN_PD);

    // UART3
    // GPIOB_ModeCfg(GPIO_Pin_21 | GPIO_Pin_20, GPIO_ModeIN_PD);
    // // 关闭UART3时钟
    // sys_safe_access_enable();
    // R8_SLP_CLK_OFF0 |= RB_SLP_CLK_UART3;
    // sys_safe_access_disable();
    // // 关闭shell和日志系统
    // shell.write = NULL;  // 禁用shell输出

    // 关闭外部低速晶振
    // GPIOA_ModeCfg(GPIO_Pin_10 | GPIO_Pin_11, GPIO_ModeIN_PD);
}

void PRESS_LowPower(void)
{
    Lower_IO_Deinit();
    if (press_done_flag == 1)
    {
        PRESS_LowerIO_Init();
    }
}

int8_t ret   = 0;
uint8_t loop = 0;
struct bmp3_dev DevIn;
struct bmp3_dev DevOut;
struct bmp3_dev DevAtom;
uint16_t settings_sel;
struct bmp3_data data         = {0};
struct bmp3_settings settings = {0};
struct bmp3_status status     = {{0}};

//T,P
int32_t T[3] = {0};
int32_t P[3] = {0};

__HIGH_CODE
__attribute__((noinline))
uint16_t
BMP390_ProcessEvent(uint8_t task_id, uint16_t events)
{
    if (events & BMP390_IN_START)
    {
        press_done_flag = 0;
        PRESS_IO_SPI_Init();

        settings.op_mode = BMP3_MODE_FORCED;
        ret              = bmp3_set_op_mode(&settings, &DevIn);
        bmp3_check_rslt("bmp3_set_op_mode", ret);

        return (events ^ BMP390_IN_START);
    }
    else if(events & BMP390_OUT_START)
    {
        press_done_flag = 0;
        PRESS_IO_SPI_Init();

        settings.op_mode = BMP3_MODE_FORCED;
        ret              = bmp3_set_op_mode(&settings, &DevOut);
        bmp3_check_rslt("bmp3_set_op_mode", ret);
        return (events ^ BMP390_OUT_START);
    }
    else if(events & BMP390_ATOM_START)
    {
        press_done_flag = 0;
        PRESS_IO_SPI_Init();

        settings.op_mode = BMP3_MODE_FORCED;
        ret              = bmp3_set_op_mode(&settings, &DevAtom);
        bmp3_check_rslt("bmp3_set_op_mode", ret);

        return (events ^ BMP390_ATOM_START);
    }
    else if (events & BMP390_EVT_READ)
    {
        PRESS_IO_SPI_Init();
#if 0
         PRESS_IO_SPI_Init();

                // IN
                ret = bmp3_get_status(&status, &DevIn);
                bmp3_check_rslt("bmp3_get_status", ret);

                /* Read temperature and pressure data iteratively based on data ready interrupt */
                if ((ret == BMP3_OK) && (status.intr.drdy == BMP3_ENABLE))
                {
                    /*
                     * First parameter indicates the type of data to be read
                     * BMP3_PRESS_TEMP : To read pressure and temperature data
                     * BMP3_TEMP       : To read only temperature data
                     * BMP3_PRESS      : To read only pressure data
                     */
                    ret = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &data, &DevIn);
                    bmp3_check_rslt("bmp3_get_sensor_data", ret);

                    /* NOTE : Read status register again to clear data ready interrupt status */
                    ret = bmp3_get_status(&status, &DevIn);
                    bmp3_check_rslt("bmp3_get_status", ret);

         #ifdef BMP3_FLOAT_COMPENSATION
                    printf("IN[%d]  T: %.2f deg C, P: %.2f Pa\n", loop, (data.temperature), (data.pressure));
         #else
                    printf("IN[%d]  T: %ld deg C, P: %lu Pa\n", loop, (long int)(int32_t)(data.temperature / 100),
                           (long unsigned int)(uint32_t)(data.pressure / 100));
         #endif
                }

                // OUT
                ret = bmp3_get_status(&status, &DevOut);
                bmp3_check_rslt("bmp3_get_status", ret);

                /* Read temperature and pressure data iteratively based on data ready interrupt */
                if ((ret == BMP3_OK) && (status.intr.drdy == BMP3_ENABLE))
                {
                    /*
                     * First parameter indicates the type of data to be read
                     * BMP3_PRESS_TEMP : To read pressure and temperature data
                     * BMP3_TEMP       : To read only temperature data
                     * BMP3_PRESS      : To read only pressure data
                     */
                    ret = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &data, &DevOut);
                    bmp3_check_rslt("bmp3_get_sensor_data", ret);

                    /* NOTE : Read status register again to clear data ready interrupt status */
                    ret = bmp3_get_status(&status, &DevOut);
                    bmp3_check_rslt("bmp3_get_status", ret);

         #ifdef BMP3_FLOAT_COMPENSATION
                    printf("OUT[%d]  T: %.2f deg C, P: %.2f Pa\n", loop, (data.temperature), (data.pressure));
         #else
                    printf("OUT[%d]  T: %ld deg C, P: %lu Pa\n", loop, (long int)(int32_t)(data.temperature / 100),
                           (long unsigned int)(uint32_t)(data.pressure / 100));
         #endif
                    loop = loop + 1;
                }
        tmos_start_task(press_task_id, WF5803_EVT_START, MS1_TO_SYSTEM_TIME(2000));
#endif
        if(flag == 1)
        {
              ret = bmp3_get_status(&status, &DevIn); // 配置中断引脚为锁存模式，需要读取int_status.drdy位才能清除中断状态标志
              bmp3_check_rslt("bmp3_get_status", ret);

              if (status.intr.drdy == BMP3_ENABLE)
              {
                  /*
                   * First parameter indicates the type of data to be read
                   * BMP3_PRESS_TEMP : To read pressure and temperature data
                   * BMP3_TEMP       : To read only temperature data
                   * BMP3_PRESS      : To read only pressure data
                   */
                  ret = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &data, &DevIn);
                  bmp3_check_rslt("bmp3_get_sensor_data", ret);

                  /* NOTE : Read status register again to clear data ready interrupt status */
                  ret = bmp3_get_status(&status, &DevIn);
                  bmp3_check_rslt("bmp3_get_status", ret);

//                  printf("IN[%d]  T: %ld deg C, P: %lu Pa\r\n", loop, (long int)(int32_t)(data.temperature / 100),
//                         (long unsigned int)(uint32_t)(data.pressure / 100));
                  T[0] = (int32_t)(data.temperature / 100);
                  P[0] = (uint32_t)(data.pressure / 100);
              }
              //tmos_start_task(press_task_id, BMP390_ATOM_START, MS1_TO_SYSTEM_TIME(100));
              tmos_start_task(press_task_id, BMP390_OUT_START, MS1_TO_SYSTEM_TIME(500));  //100
              //tmos_start_task(press_task_id, BMP390_IN_START, MS1_TO_SYSTEM_TIME(1000));
           }
            else if(flag == 2)
            {
                  ret = bmp3_get_status(&status, &DevOut); // 配置中断引脚为锁存模式，需要读取int_status.drdy位才能清除中断状态标志
                  bmp3_check_rslt("bmp3_get_status", ret);

                  if (status.intr.drdy == BMP3_ENABLE)
                  {
                      /*
                       * First parameter indicates the type of data to be read
                       * BMP3_PRESS_TEMP : To read pressure and temperature data
                       * BMP3_TEMP       : To read only temperature data
                       * BMP3_PRESS      : To read only pressure data
                       */
                      ret = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &data, &DevOut);
                      bmp3_check_rslt("bmp3_get_sensor_data", ret);

                      /* NOTE : Read status register again to clear data ready interrupt status */
                      ret = bmp3_get_status(&status, &DevOut);
                      bmp3_check_rslt("bmp3_get_status", ret);

//                      printf("OUT[%d]  T: %ld deg C, P: %lu Pa\r\n", loop, (long int)(int32_t)(data.temperature / 100),
//                                                (long unsigned int)(uint32_t)(data.pressure / 100));
                      T[1] = (int32_t)(data.temperature / 100);
                      P[1] = (uint32_t)(data.pressure / 100);
                  }
                  tmos_start_task(press_task_id, BMP390_ATOM_START, MS1_TO_SYSTEM_TIME(500));  //100
                  //tmos_start_task(press_task_id, BMP390_OUT_START, MS1_TO_SYSTEM_TIME(1000));
            }
            else if(flag == 3)
            {
                  ret = bmp3_get_status(&status, &DevAtom); // 配置中断引脚为锁存模式，需要读取int_status.drdy位才能清除中断状态标志
                  bmp3_check_rslt("bmp3_get_status", ret);

                  if (status.intr.drdy == BMP3_ENABLE)
                  {
                      /*
                       * First parameter indicates the type of data to be read
                       * BMP3_PRESS_TEMP : To read pressure and temperature data
                       * BMP3_TEMP       : To read only temperature data
                       * BMP3_PRESS      : To read only pressure data
                       */
                      ret = bmp3_get_sensor_data(BMP3_PRESS_TEMP, &data, &DevAtom);
                      bmp3_check_rslt("bmp3_get_sensor_data", ret);

                      /* NOTE : Read status register again to clear data ready interrupt status */
                      ret = bmp3_get_status(&status, &DevAtom);
                      bmp3_check_rslt("bmp3_get_status", ret);

//                      printf("ATOM[%d]  T: %ld deg C, P: %lu Pa\r\n", loop, (long int)(int32_t)(data.temperature / 100),
//                                                (long unsigned int)(uint32_t)(data.pressure / 100));
                      T[2] = (int32_t)(data.temperature / 100);
                      P[2] = (uint32_t)(data.pressure / 100);

                      //printf("%d, %d, %d\r\n",T[0],T[1],T[2]);
                      printf("%d, %d, %d, %d, %d, %d, %d \r\n",T[0],T[1],T[2],P[0],P[1],P[2],P[0]-P[1]);
                  }
                  tmos_start_task(press_task_id, BMP390_IN_START, MS1_TO_SYSTEM_TIME(500));  //100
                  //tmos_start_task(press_task_id, BMP390_ATOM_START, MS1_TO_SYSTEM_TIME(1000));
            }
            flag = 0;
            press_done_flag = 1;
            loop = loop + 1;
            return (events ^ BMP390_EVT_READ);
        }
    return 0;
}

void BSP_PRESS_Init(void)
{
    PRESS_IO_SPI_Init();

    // 中断引脚的配置
    GPIOA_ModeCfg(GPIO_Pin_6, GPIO_ModeIN_PD);
    GPIOA_ITModeCfg(GPIO_Pin_6, GPIO_ITMode_RiseEdge);

    GPIOA_ModeCfg(GPIO_Pin_12, GPIO_ModeIN_PD);
    GPIOA_ITModeCfg(GPIO_Pin_12, GPIO_ITMode_RiseEdge);

    GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeIN_PD);
    GPIOA_ITModeCfg(GPIO_Pin_2, GPIO_ITMode_RiseEdge);

    PWR_PeriphWakeUpCfg(ENABLE, RB_GPIO_WAKE_MODE | RB_SLP_GPIO_WAKE, Long_Delay);
    PFIC_EnableIRQ(GPIO_A_IRQn);

    // IN
    ret = BMP390_IN_InterfaceInit(&DevIn, BMP3_SPI_INTF);
    bmp3_check_rslt("BMP390_OUT_InterfaceInit", ret);

    ret = bmp3_init(&DevIn);
    bmp3_check_rslt("bmp3_init", ret);
    settings.int_settings.drdy_en     = BMP3_ENABLE;
    settings.int_settings.latch       = BMP3_INT_PIN_LATCH;
    settings.int_settings.level       = BMP3_INT_PIN_ACTIVE_HIGH;
    settings.int_settings.output_mode = BMP3_INT_PIN_PUSH_PULL;

    settings.press_en = BMP3_ENABLE;
    settings.temp_en  = BMP3_ENABLE;

    settings.odr_filter.press_os   = BMP3_OVERSAMPLING_2X;  //BMP3_OVERSAMPLING_2X
    settings.odr_filter.temp_os    = BMP3_OVERSAMPLING_2X;  //BMP3_OVERSAMPLING_2X
    settings.odr_filter.odr        = BMP3_ODR_0_39_HZ;        //BMP3_ODR_1_5_HZ
    settings.odr_filter.iir_filter = BMP3_IIR_FILTER_COEFF_1;  //BMP3_IIR_FILTER_COEFF_3

    settings_sel = BMP3_SEL_PRESS_EN | BMP3_SEL_TEMP_EN | BMP3_SEL_PRESS_OS | BMP3_SEL_TEMP_OS | BMP3_SEL_ODR | BMP3_SEL_DRDY_EN | BMP3_SEL_IIR_FILTER | BMP3_SEL_OUTPUT_MODE | BMP3_SEL_LEVEL | BMP3_SEL_LATCH;

    ret = bmp3_set_sensor_settings(settings_sel, &settings, &DevIn);
    bmp3_check_rslt("bmp3_set_sensor_settings", ret);

    // OUT
    ret = BMP390_OUT_InterfaceInit(&DevOut, BMP3_SPI_INTF);
    bmp3_check_rslt("BMP390_OUT_InterfaceInit", ret);

    ret = bmp3_init(&DevOut);
    bmp3_check_rslt("bmp3_init", ret);
    settings.int_settings.drdy_en     = BMP3_ENABLE;
    settings.int_settings.latch       = BMP3_INT_PIN_LATCH;
    settings.int_settings.level       = BMP3_INT_PIN_ACTIVE_HIGH;
    settings.int_settings.output_mode = BMP3_INT_PIN_PUSH_PULL;
    settings.press_en                 = BMP3_ENABLE;
    settings.temp_en                  = BMP3_ENABLE;

    settings.odr_filter.press_os   = BMP3_OVERSAMPLING_2X;
    settings.odr_filter.temp_os    = BMP3_OVERSAMPLING_2X;
    settings.odr_filter.odr        = BMP3_ODR_0_39_HZ;
    settings.odr_filter.iir_filter = BMP3_IIR_FILTER_COEFF_1;

    settings_sel = BMP3_SEL_PRESS_EN | BMP3_SEL_TEMP_EN | BMP3_SEL_PRESS_OS | BMP3_SEL_TEMP_OS | BMP3_SEL_ODR | BMP3_SEL_DRDY_EN | BMP3_SEL_IIR_FILTER | BMP3_SEL_OUTPUT_MODE | BMP3_SEL_LEVEL | BMP3_SEL_LATCH;

    ret = bmp3_set_sensor_settings(settings_sel, &settings, &DevOut);
    bmp3_check_rslt("bmp3_set_sensor_settings", ret);

    // ATOM
    ret = BMP390_ATOM_InterfaceInit(&DevAtom, BMP3_SPI_INTF);
    bmp3_check_rslt("BMP390_ATOM_InterfaceInit", ret);

    ret = bmp3_init(&DevAtom);
    bmp3_check_rslt("bmp3_init", ret);
    settings.int_settings.drdy_en     = BMP3_ENABLE;
    settings.int_settings.latch       = BMP3_INT_PIN_LATCH;
    settings.int_settings.level       = BMP3_INT_PIN_ACTIVE_HIGH;
    settings.int_settings.output_mode = BMP3_INT_PIN_PUSH_PULL;

    settings.press_en = BMP3_ENABLE;
    settings.temp_en  = BMP3_ENABLE;

    settings.odr_filter.press_os   = BMP3_OVERSAMPLING_2X;
    settings.odr_filter.temp_os    = BMP3_OVERSAMPLING_2X;
    settings.odr_filter.odr        = BMP3_ODR_0_39_HZ;
    settings.odr_filter.iir_filter = BMP3_IIR_FILTER_COEFF_1;

    settings_sel = BMP3_SEL_PRESS_EN | BMP3_SEL_TEMP_EN | BMP3_SEL_PRESS_OS | BMP3_SEL_TEMP_OS | BMP3_SEL_ODR | BMP3_SEL_DRDY_EN | BMP3_SEL_IIR_FILTER | BMP3_SEL_OUTPUT_MODE | BMP3_SEL_LEVEL | BMP3_SEL_LATCH;

    ret = bmp3_set_sensor_settings(settings_sel, &settings, &DevAtom);
    bmp3_check_rslt("bmp3_set_sensor_settings", ret);

    press_task_id = TMOS_ProcessEventRegister(BMP390_ProcessEvent);
    tmos_set_event(press_task_id, BMP390_IN_START);
    //tmos_set_event(press_task_id, BMP390_OUT_START);
    //tmos_set_event(press_task_id, BMP390_ATOM_START);
}

uint16_t Check_ProcessEvent(uint8_t task_id, uint16_t events)
{
    if (events & CHECK_EVT_START)
    {
        // logDebug("fault_state = %d \r\n",fault_state);
        if(!fault_state)
        {
            //超压检测
            if(P[0] - P[2] >= 80)  //8000
            {
                VALVE_CLOSE();
                fault_state = 1;
                tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(1500));  //1000
                logDebug("motor high close");
            }
            //欠压检测
            if(P[0] - P[2] <= 80)  //800
            {
                VALVE_CLOSE();
                fault_state = 2;
                tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(1500)); //1000
                logDebug("motor low close");
            }
            //过流检测
            if( P[0] - P[1] >= 7)  //700
            {
                VALVE_CLOSE();
                fault_state = 3;
                tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(1500)); //1000
                logDebug("motor  ver close");
            }
        }
        // logDebug("motor_flag_end = %d",motor_flag);
        //手动关阀
        if(motor_flag == 1)
        {
            motor_flag = 0;
            VALVE_OPEN();
            IotFlag_t.Valve_Open_flag = 1;
            fault_state = 0;
            LED_VALVE_OPEN;
            logDebug("motor/LED open");
            tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(1000));
        }
        else if(motor_flag == 2)
        {
            motor_flag = 0;
            VALVE_CLOSE();
            LED_VALVE_CLOSE;
            fault_state = 4;
            logDebug("motor/LED close");
            tmos_start_task(check_task_id, MOTOR_STOP_EVT, MS1_TO_SYSTEM_TIME(1000));
        }
        tmos_start_task(check_task_id, CHECK_EVT_START, MS1_TO_SYSTEM_TIME(200));  //100
        return (events ^ CHECK_EVT_START);
    }
    if (events & MOTOR_STOP_EVT)
    {
        VALVE_STOP();
        logDebug("motor STOP");
        if(fault_state == 4)
        {
            IotFlag_t.Valve_Close_flag = 1;
            Iot_Send_Data();
        }
        return (events ^ MOTOR_STOP_EVT);
    }
    return 0;
}
void Function_Check(void)
{
    check_task_id = TMOS_ProcessEventRegister(Check_ProcessEvent);
    tmos_set_event(check_task_id, CHECK_EVT_START);
}

__INTERRUPT
__HIGH_CODE
void GPIOA_IRQHandler(void)
{
    if (R16_PA_INT_IF & GPIO_Pin_6)
    {
        R16_PA_INT_IF = GPIO_Pin_6;
        flag = 1;
        tmos_set_event(press_task_id, BMP390_EVT_READ);
        // logDebug("INT2 \r\n");
    }
    else if (R16_PA_INT_IF & GPIO_Pin_12)
    {
        R16_PA_INT_IF = GPIO_Pin_12;
        flag = 2;
        tmos_set_event(press_task_id, BMP390_EVT_READ);
        // logDebug("INT3 \r\n");
    }
    else if (R16_PA_INT_IF & GPIO_Pin_2)
    {
        R16_PA_INT_IF = GPIO_Pin_2;
        flag = 3;
        tmos_set_event(press_task_id, BMP390_EVT_READ);
        // logDebug("INT1 \r\n");
    }
}
