1250 lines
43 KiB
C
1250 lines
43 KiB
C
#include "bsp_bmp390.h"
|
||
#include "bsp_motor.h"
|
||
#include "bsp_led.h"
|
||
#include "bsp_key.h"
|
||
#include "bsp_adc.h"
|
||
#include "CONFIG.h"
|
||
#include "log.h"
|
||
#include "bsp_ml307r.h"
|
||
#include "SLEEP.h"
|
||
|
||
uint8_t flag;
|
||
uint8_t keydown_flag = 0;
|
||
uint8_t keydown_time = 0;
|
||
uint8_t volatile fault_state = 0;
|
||
|
||
TsValveRawData ValveRawData;
|
||
TsValveRawData ValveRawData_buffer[5];
|
||
|
||
|
||
TsValveInfo ValveInfo;
|
||
|
||
|
||
|
||
// 安全状态全局变量
|
||
TsValveSafetyStatus valve_safety = {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_8)
|
||
#define PRESS_IN_CS_LOW() GPIOA_ResetBits(GPIO_Pin_8)
|
||
|
||
#define PRESS_OUT_CS_HIGH() GPIOA_SetBits(GPIO_Pin_2)
|
||
#define PRESS_OUT_CS_LOW() GPIOA_ResetBits(GPIO_Pin_2)
|
||
|
||
#define PRESS_ATOM_CS_HIGH() GPIOA_SetBits(GPIO_Pin_0)
|
||
#define PRESS_ATOM_CS_LOW() GPIOA_ResetBits(GPIO_Pin_0)
|
||
|
||
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_2);
|
||
GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeOut_PP_5mA);
|
||
|
||
GPIOA_SetBits(GPIO_Pin_8);
|
||
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeOut_PP_5mA);
|
||
|
||
GPIOA_SetBits(GPIO_Pin_0);
|
||
GPIOA_ModeCfg(GPIO_Pin_0, 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_2);
|
||
GPIOA_ModeCfg(GPIO_Pin_2, GPIO_ModeIN_PU);
|
||
|
||
// CSB2: PA5
|
||
GPIOA_SetBits(GPIO_Pin_8);
|
||
GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
|
||
|
||
// CSB1: PA3
|
||
GPIOA_SetBits(GPIO_Pin_0);
|
||
GPIOA_ModeCfg(GPIO_Pin_0, GPIO_ModeIN_PU);
|
||
}
|
||
|
||
void Lower_IO_Deinit(void)
|
||
{
|
||
// LED
|
||
GPIOB_ResetBits(LED_VALVE_R_PIN | LED_VALVE_G_PIN);
|
||
GPIOB_ModeCfg(LED_VALVE_R_PIN | LED_VALVE_G_PIN, GPIO_ModeIN_PD);
|
||
GPIOA_ResetBits(LED_VBAT_PIN | LED_ALARM_PIN);
|
||
GPIOA_ModeCfg(LED_VBAT_PIN | LED_ALARM_PIN, GPIO_ModeIN_PD);
|
||
|
||
// KEY | RESET KEY | boot KEY
|
||
GPIOB_ResetBits(KEY_BPIN);
|
||
GPIOB_ModeCfg(KEY_BPIN, 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(ADC_VBAT_PIN);
|
||
GPIOA_ModeCfg(ADC_VBAT_PIN, GPIO_ModeIN_Floating);
|
||
ADC_DisablePower();
|
||
|
||
// BMP390
|
||
// INT1: PA2 | INT2: PA6 | INT3: PA12
|
||
GPIOA_ModeCfg(GPIO_Pin_6 | GPIO_Pin_9 | GPIO_Pin_3, 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, GPIO_ModeIN_PD);
|
||
GPIOB_ModeCfg(ML307_UART_RX_PIN, GPIO_ModeIN_PU);
|
||
// SIM卡检测引脚配置为下拉输入
|
||
GPIOB_ModeCfg(USIM_DECT_PIN, GPIO_ModeIN_PD);
|
||
|
||
// motor
|
||
GPIOA_ResetBits(COIL_ADC);
|
||
GPIOA_ModeCfg(COIL_ADC, 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};
|
||
|
||
// 定义滑动窗口函数
|
||
void slideValveRawDataBuffer(TsValveRawData *newData)
|
||
{
|
||
// 将数组元素左移一位
|
||
for (int i = 0; i < 4; i++)
|
||
{
|
||
tmos_memcpy(&ValveRawData_buffer[i], &ValveRawData_buffer[i + 1], sizeof(TsValveRawData));
|
||
}
|
||
// 将新数据存入数组[4]
|
||
tmos_memcpy(&ValveRawData_buffer[4], &newData[0], sizeof(TsValveRawData));
|
||
|
||
// for (int i = 0; i < 5; i++)
|
||
// {
|
||
// logDebug("Buffer[%d]: in_press=%d, out_press=%d, diff=%d",
|
||
// i,
|
||
// ValveRawData_buffer[i].in_press,
|
||
// ValveRawData_buffer[i].out_press,
|
||
// ValveRawData_buffer[i].in_out_press_diff);
|
||
// }
|
||
}
|
||
|
||
__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);
|
||
|
||
logDebug("**********************************");
|
||
logDebug("%d, %d, %d, %d, %d, %d \r\n", T[0], T[1], T[2], P[0], P[1], P[2]);
|
||
logDebug("P1: %d,P2: %d ,^P: %d \r\n", P[0] - P[2], P[1] - P[2], P[0] - P[1]);
|
||
logDebug("**********************************");
|
||
}
|
||
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;
|
||
|
||
// TODO:读完三个气压传感器数据后在做计算
|
||
ValveRawData.in_press_raw = P[0];
|
||
ValveRawData.out_press_raw = P[1];
|
||
ValveRawData.atom_press = P[2];
|
||
|
||
ValveRawData.in_temp = T[0];
|
||
ValveRawData.out_temp = T[1];
|
||
ValveRawData.atom_temp = T[2];
|
||
|
||
ValveRawData.in_press = ValveRawData.in_press_raw - ValveRawData.atom_press;
|
||
ValveRawData.out_press = ValveRawData.out_press_raw - ValveRawData.atom_press;
|
||
ValveRawData.in_out_press_diff = ValveRawData.in_press - ValveRawData.out_press;
|
||
|
||
logDebug("in_press: %d, out_press: %d, atom_press: %d\r\n", ValveRawData.in_press, ValveRawData.out_press, ValveRawData.atom_press);
|
||
logDebug("in_temp: %d, out_temp: %d, atom_temp: %d\r\n", ValveRawData.in_temp, ValveRawData.out_temp, ValveRawData.atom_temp);
|
||
logDebug("in_out_press_diff: %d\r\n", ValveRawData.in_out_press_diff);
|
||
|
||
// 刷新ValveRawData_buffer,把之前的ValveRawData按时间顺序向右滑动
|
||
// ,最新的ValveRawData 存在数组[4]
|
||
|
||
slideValveRawDataBuffer(&ValveRawData);
|
||
|
||
loop = loop + 1;
|
||
return (events ^ BMP390_EVT_READ);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
void VALVE_SetInfo()
|
||
{
|
||
ValveInfo.over_press = 6200;
|
||
ValveInfo.low_press = 680;
|
||
ValveInfo.over_temp = 65;
|
||
ValveInfo.delay_close_count = 6;
|
||
|
||
ValveInfo.over_flow_press_diff_1kpa = 650;
|
||
ValveInfo.over_flow_press_diff_2kpa = 650;
|
||
ValveInfo.over_flow_press_diff_3kpa = 650;
|
||
}
|
||
|
||
void BSP_PRESS_Init(void)
|
||
{
|
||
PRESS_IO_SPI_Init();
|
||
|
||
// 中断引脚的配置
|
||
GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeIN_PD);
|
||
GPIOA_ITModeCfg(GPIO_Pin_9, GPIO_ITMode_RiseEdge);
|
||
|
||
GPIOA_ModeCfg(GPIO_Pin_3, GPIO_ModeIN_PD);
|
||
GPIOA_ITModeCfg(GPIO_Pin_3, GPIO_ITMode_RiseEdge);
|
||
|
||
GPIOA_ModeCfg(GPIO_Pin_6, GPIO_ModeIN_PD);
|
||
GPIOA_ITModeCfg(GPIO_Pin_6, 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);
|
||
|
||
VALVE_SetInfo();
|
||
}
|
||
|
||
/**
|
||
* @brief 判断参考值是否在测量值的误差范围内
|
||
*
|
||
* @param ref_value 参考值
|
||
* @param measured_value 测量值
|
||
* @param tolerance 误差范围(正负)
|
||
*
|
||
* @return uint8_t 返回 1 表示在范围内,返回 0 表示不在范围内
|
||
*/
|
||
uint8_t isWithinTolerance(int32_t ref_value, int32_t measured_value, uint8_t tolerance)
|
||
{
|
||
if ((measured_value - tolerance <= ref_value) && (ref_value <= measured_value + tolerance))
|
||
{
|
||
return 1; // 在范围内
|
||
}
|
||
else
|
||
{
|
||
return 0; // 不在范围内
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 检测管道是否无流量状态
|
||
*
|
||
* @return uint8_t 返回1表示无流量,返回0表示有流量
|
||
*/
|
||
uint8_t isNoFlowDetected(void)
|
||
{
|
||
// 检测进出口压差是否在无流量阈值范围内 (0±2Pa)
|
||
if (ValveRawData.in_out_press_diff >= -AUTO_CLOSE_NO_FLOW_THRESHOLD &&
|
||
ValveRawData.in_out_press_diff <= AUTO_CLOSE_NO_FLOW_THRESHOLD)
|
||
{
|
||
logDebug("No flow detected: pressure diff = %d Pa", ValveRawData.in_out_press_diff);
|
||
return 1; // 无流量
|
||
}
|
||
|
||
logDebug("Flow detected: pressure diff = %d Pa", ValveRawData.in_out_press_diff);
|
||
return 0; // 有流量
|
||
}
|
||
|
||
/**
|
||
* @brief 启动延时关阀功能
|
||
*/
|
||
void startAutoCloseTimer(void)
|
||
{
|
||
if (!valve_safety.auto_close_enabled)
|
||
{
|
||
valve_safety.auto_close_enabled = 1;
|
||
valve_safety.auto_close_active = 1;
|
||
valve_safety.auto_close_check_count = 0;
|
||
valve_safety.auto_close_start_time = BSP_Get_Tick();
|
||
|
||
logDebug("Auto close timer started");
|
||
|
||
// 开始第一次检测,延时5分钟
|
||
tmos_start_task(check_task_id, AUTO_CLOSE_CHECK_EVT, MS1_TO_SYSTEM_TIME(AUTO_CLOSE_CHECK_INTERVAL_MS));
|
||
|
||
// 设置35分钟超时保护(30分钟+5分钟误差容限)
|
||
tmos_start_task(check_task_id, AUTO_CLOSE_TIMEOUT_EVT, MS1_TO_SYSTEM_TIME(35 * 60 * 1000));
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 停止延时关阀功能
|
||
*/
|
||
void stopAutoCloseTimer(void)
|
||
{
|
||
if (valve_safety.auto_close_enabled)
|
||
{
|
||
valve_safety.auto_close_enabled = 0;
|
||
valve_safety.auto_close_active = 0;
|
||
valve_safety.auto_close_check_count = 0;
|
||
|
||
// 停止定时器
|
||
tmos_stop_task(check_task_id, AUTO_CLOSE_CHECK_EVT);
|
||
tmos_stop_task(check_task_id, AUTO_CLOSE_TIMEOUT_EVT);
|
||
|
||
logDebug("Auto close timer stopped");
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief 启动微泄漏检测
|
||
*/
|
||
void startMicroLeakDetection(void)
|
||
{
|
||
// 重置微泄漏计数器
|
||
valve_safety.micro_leak_count = 0;
|
||
|
||
// 启动10秒定时检测
|
||
tmos_start_task(check_task_id, MICRO_LEAK_CHECK_EVT, MS1_TO_SYSTEM_TIME(MICRO_LEAK_CHECK_INTERVAL_MS));
|
||
|
||
logDebug("微泄漏检测启动");
|
||
}
|
||
|
||
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)
|
||
{
|
||
// TODO:状态切换不对
|
||
if (gValveData.switch_status == kOpened)
|
||
{
|
||
// 延时关阀功能启动条件检测
|
||
// 只在未启动延时关阀时检测无流量状态,一旦启动就交给定时检测处理
|
||
if (!valve_safety.auto_close_enabled)
|
||
{
|
||
if (isNoFlowDetected())
|
||
{
|
||
startAutoCloseTimer();
|
||
logDebug("延时关阀启动:检测到无流量状态");
|
||
}
|
||
}
|
||
|
||
// 超压检测
|
||
// 后端关阀,进气端压力超过阈值6200关阀
|
||
// 流量0.45时候,进气端压力超过阈值6200关阀
|
||
if (ValveRawData.in_press >= ValveInfo.over_press)
|
||
{
|
||
logError("******************************");
|
||
logError("超压关阀并锁定");
|
||
logDebug("in_press = %d; over_press = %d", ValveRawData.in_press, ValveInfo.over_press);
|
||
|
||
BSP_VALVE_Close(kValveCmdOverPressure); // 使用超压关阀原因
|
||
BSP_VALVE_Lock(kValveCmdOverPressure); // 锁定阀门,防止再次开启
|
||
fault_state = 1;
|
||
// 超压关阀时停止延时关阀功能
|
||
stopAutoCloseTimer();
|
||
}
|
||
// 欠压检测
|
||
else if (ValveRawData.in_press <= ValveInfo.low_press)
|
||
{
|
||
BSP_VALVE_Close(kValveCmdUnderPressure); // 使用欠压关阀原因
|
||
BSP_VALVE_Lock(kValveCmdUnderPressure); // 锁定阀门,防止再次开启
|
||
fault_state = 2;
|
||
// 欠压关阀时停止延时关阀功能
|
||
stopAutoCloseTimer();
|
||
logError("******************************");
|
||
logError("欠压关阀");
|
||
}
|
||
#if 1
|
||
// 1、过流自动关闭:
|
||
// 进气端压力2kpa时,额定流量调到0.9
|
||
// 进气端压力升到 3kpa左右时,阀门不能关,流量不超过1.4
|
||
|
||
// 3、进气端压力 1kpa左右时,出气端阀口全开,需要关闭(过流自动关闭)
|
||
// if (isWithinTolerance(1000, ValveRawData.in_press, 50)
|
||
// && ValveRawData.in_out_press_diff)
|
||
// {
|
||
// /* code */
|
||
// }
|
||
// 进气端压力2kpa时,额定流量调到1.4(切断流量)要关阀
|
||
if (ValveRawData.in_out_press_diff >= ValveInfo.over_flow_press_diff_2kpa)
|
||
{
|
||
if (keydown_flag > 0)
|
||
{
|
||
logDebug("keydown_time !%d", keydown_time);
|
||
keydown_time++;
|
||
if (keydown_time > 30)
|
||
{
|
||
keydown_time = 0;
|
||
keydown_flag = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
keydown_time = 0;
|
||
logError("******************************");
|
||
logError("过流关阀并锁定");
|
||
logDebug("in_out_press_diff = %d; threshold = %d", ValveRawData.in_out_press_diff, ValveInfo.over_flow_press_diff_2kpa);
|
||
|
||
// 先关阀再锁定
|
||
BSP_VALVE_Close(kValveCmdOverCurrent); // 使用过流关阀原因
|
||
BSP_VALVE_Lock(kValveCmdOverCurrent); // 锁定阀门,防止再次开启
|
||
|
||
fault_state = 3;
|
||
logDebug("Over current status !");
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
else if (gValveData.switch_status == kClosed)
|
||
{
|
||
// 阀门关闭时停止延时关阀功能
|
||
if (valve_safety.auto_close_enabled)
|
||
{
|
||
stopAutoCloseTimer();
|
||
}
|
||
|
||
// 点火开阀
|
||
// 监测ValveRawData_buffer,当前最新的压差值大于上一秒的压差
|
||
if (isWithinTolerance(ValveRawData_buffer[2].in_press, ValveRawData_buffer[4].in_press, 50)
|
||
&& ValveRawData_buffer[4].in_out_press_diff >= 900)
|
||
{
|
||
logError("******************************");
|
||
logError("点火开阀");
|
||
for (int i = 2; i < 5; i++)
|
||
{
|
||
logDebug("[%d]: in_press = %d; out_press = %d; in_out_press_diff = %d", i, ValveRawData_buffer[i].in_press, ValveRawData_buffer[i].out_press, ValveRawData_buffer[i].in_out_press_diff);
|
||
}
|
||
BSP_VALVE_Open(kValveCmdOpenWithStove); // 使用点火开阀原因
|
||
}
|
||
// else
|
||
// {
|
||
// logDebug("点火开阀失败");
|
||
// for (int i = 2; i < 5; i++)
|
||
// {
|
||
// logDebug("[%d]: in_press = %d; out_press = %d; in_out_press_diff = %d", i
|
||
// , ValveRawData_buffer[i].in_press, ValveRawData_buffer[i].out_press, ValveRawData_buffer[i].in_out_press_diff);
|
||
// }
|
||
// }
|
||
}
|
||
|
||
// 超温关阀功能:检测至少两个传感器的温度超过阈值
|
||
if (gValveData.switch_status == kOpened)
|
||
{
|
||
// 计算超过阈值的传感器数量
|
||
uint8_t over_temp_count = 0;
|
||
|
||
// 检查三个传感器的温度是否超过阈值
|
||
if (T[0] > ValveInfo.over_temp) over_temp_count++;
|
||
if (T[1] > ValveInfo.over_temp) over_temp_count++;
|
||
if (T[2] > ValveInfo.over_temp) over_temp_count++;
|
||
|
||
// 如果至少有两个传感器超过阈值,触发关阀
|
||
if (over_temp_count >= 2)
|
||
{
|
||
logDebug("Over temperature detected! T1=%d, T2=%d, T3=%d", T[0], T[1], T[2]);
|
||
BSP_VALVE_Close(kValveCmdOverTemperature);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 检查阀门是否处于锁定状态,如果是则检查隐患是否已排除
|
||
if (gValveData.Lock == 1)
|
||
{
|
||
// 检查隐患是否已排除(过流除外,过流只能手动解锁)
|
||
if (valve_safety.lock_reason != kValveCmdOverCurrent && BSP_VALVE_CheckHazardCleared())
|
||
{
|
||
// 隐患已排除,自动解锁
|
||
BSP_VALVE_Unlock();
|
||
}
|
||
}
|
||
|
||
// logDebug("motor_flag_end = %d",motor_flag);
|
||
// 手动关阀
|
||
if (motor_flag == 1)
|
||
{
|
||
motor_flag = 0;
|
||
BSP_VALVE_Open(kValveCmdManualOpen); // 使用普通开阀命令
|
||
keydown_flag = 1;
|
||
IotFlag_t.Valve_Open_flag = 1;
|
||
fault_state = 0;
|
||
logDebug("motor/LED open!!!");
|
||
}
|
||
else if (motor_flag == 2)
|
||
{
|
||
motor_flag = 0;
|
||
|
||
// 直接使用普通关阀命令
|
||
BSP_VALVE_Close(kValveCmdManualClose);
|
||
// fault_state = 4;
|
||
logDebug("motor/LED close!!!");
|
||
}
|
||
else if (motor_flag == 3)
|
||
{
|
||
motor_flag = 0;
|
||
if (gValveData.switch_status == kOpened)
|
||
{
|
||
LED_VALVE_OPEN;
|
||
}
|
||
else
|
||
{
|
||
LED_VALVE_CLOSE;
|
||
}
|
||
// DelayMs(500);
|
||
}
|
||
tmos_start_task(check_task_id, CHECK_EVT_START, MS1_TO_SYSTEM_TIME(200)); // 100
|
||
return (events ^ CHECK_EVT_START);
|
||
}
|
||
|
||
// 延时关阀检测事件处理
|
||
if (events & AUTO_CLOSE_CHECK_EVT)
|
||
{
|
||
if (valve_safety.auto_close_enabled && valve_safety.auto_close_active)
|
||
{
|
||
valve_safety.auto_close_check_count++;
|
||
|
||
logDebug("延时关阀第%d次检测 (共需6次)", valve_safety.auto_close_check_count);
|
||
|
||
// 检测当前是否仍为无流量状态
|
||
if (isNoFlowDetected())
|
||
{
|
||
logDebug("第%d次检测确认无流量 (in_out_press_diff=%d Pa)",
|
||
valve_safety.auto_close_check_count, ValveRawData.in_out_press_diff);
|
||
|
||
// 如果已经检测了6次(30分钟),执行关阀
|
||
if (valve_safety.auto_close_check_count >= ValveInfo.delay_close_count)
|
||
{
|
||
logError("******************************");
|
||
logError("延时关阀:30分钟无流量,自动关闭阀门");
|
||
logError("6次检测均确认无流量,总耗时: %d ms", BSP_Get_Tick() - valve_safety.auto_close_start_time);
|
||
|
||
// 执行关阀动作
|
||
BSP_VALVE_Close(kValveCmdDelayClose); // 使用延时关阀原因
|
||
|
||
// 停止延时关阀功能
|
||
stopAutoCloseTimer();
|
||
}
|
||
else
|
||
{
|
||
// 继续下一次检测,再等5分钟
|
||
logDebug("第%d次检测完成,5分钟后进行第%d次检测",
|
||
valve_safety.auto_close_check_count, valve_safety.auto_close_check_count + 1);
|
||
tmos_start_task(check_task_id, AUTO_CLOSE_CHECK_EVT,
|
||
MS1_TO_SYSTEM_TIME(AUTO_CLOSE_CHECK_INTERVAL_MS));
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 检测到有流量,停止延时关阀
|
||
logDebug("第%d次检测发现有流量 (in_out_press_diff=%d Pa),停止延时关阀",
|
||
valve_safety.auto_close_check_count, ValveRawData.in_out_press_diff);
|
||
stopAutoCloseTimer();
|
||
}
|
||
}
|
||
|
||
return (events ^ AUTO_CLOSE_CHECK_EVT);
|
||
}
|
||
|
||
// 延时关阀超时事件处理(备用安全机制)
|
||
if (events & AUTO_CLOSE_TIMEOUT_EVT)
|
||
{
|
||
if (valve_safety.auto_close_enabled)
|
||
{
|
||
logError("******************************");
|
||
logError("延时关阀:超时保护,强制关闭阀门");
|
||
|
||
// 强制执行关阀动作
|
||
BSP_VALVE_Close(kValveCmdDelayClose); // 使用延时关阀原因
|
||
|
||
// 停止延时关阀功能
|
||
stopAutoCloseTimer();
|
||
}
|
||
|
||
return (events ^ AUTO_CLOSE_TIMEOUT_EVT);
|
||
}
|
||
|
||
// 微泄漏检测事件处理
|
||
if (events & MICRO_LEAK_CHECK_EVT)
|
||
{
|
||
// 只在阀门关闭状态下检测微泄漏
|
||
if (gValveData.switch_status == kClosed)
|
||
{
|
||
logDebug("微泄漏趋检测!!!!");
|
||
// 记录当前压差值
|
||
static int last_press = 0;
|
||
|
||
// 比较当前值与上次值
|
||
if (ValveRawData.out_press < last_press)
|
||
{
|
||
// 出口压力逐渐增小,可能是微泄漏
|
||
valve_safety.micro_leak_count++;
|
||
logError("微泄漏检测: 出口压力减小 %d -> %d (第%d次/共需%d次)",
|
||
last_press, ValveRawData.out_press,
|
||
valve_safety.micro_leak_count, MICRO_LEAK_CHECK_COUNT);
|
||
|
||
// 连续6次检测到压差增大,判定为微泄漏
|
||
if (valve_safety.micro_leak_count >= MICRO_LEAK_CHECK_COUNT)
|
||
{
|
||
logError("******************************");
|
||
logError("检测到微泄漏");
|
||
|
||
BSP_VALVE_Close(kValveCmdMicroLeak); // 使用微泄漏关阀原因
|
||
BSP_VALVE_Lock(kValveCmdMicroLeak); // 锁定阀门,防止再次开启
|
||
valve_safety.micro_leak_count = 0; // 重置计数器
|
||
|
||
// 微泄漏关阀时停止延时关阀功能
|
||
stopAutoCloseTimer();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 压差未增大,重置计数器
|
||
if (valve_safety.micro_leak_count > 0)
|
||
{
|
||
logDebug("微泄漏趋势中断,重置计数器");
|
||
valve_safety.micro_leak_count = 0;
|
||
}
|
||
}
|
||
|
||
// 更新上次压差值
|
||
last_press = ValveRawData.out_press;
|
||
}
|
||
else
|
||
{
|
||
// 阀门关闭状态,重置微泄漏计数器
|
||
valve_safety.micro_leak_count = 0;
|
||
}
|
||
|
||
// 继续下一次检测
|
||
tmos_start_task(check_task_id, MICRO_LEAK_CHECK_EVT, MS1_TO_SYSTEM_TIME(MICRO_LEAK_CHECK_INTERVAL_MS));
|
||
|
||
return (events ^ MICRO_LEAK_CHECK_EVT);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
void Function_Check(void)
|
||
{
|
||
check_task_id = TMOS_ProcessEventRegister(Check_ProcessEvent);
|
||
tmos_set_event(check_task_id, CHECK_EVT_START);
|
||
|
||
// 如果阀门处于开启状态,启动微泄漏检测
|
||
if (gValveData.switch_status == kOpened)
|
||
{
|
||
startMicroLeakDetection();
|
||
}
|
||
}
|
||
|
||
__INTERRUPT
|
||
__HIGH_CODE
|
||
void GPIOA_IRQHandler(void)
|
||
{
|
||
if (R16_PA_INT_IF & GPIO_Pin_9)
|
||
{
|
||
R16_PA_INT_IF = GPIO_Pin_9;
|
||
flag = 1;
|
||
tmos_set_event(press_task_id, BMP390_EVT_READ);
|
||
}
|
||
else if (R16_PA_INT_IF & GPIO_Pin_3)
|
||
{
|
||
R16_PA_INT_IF = GPIO_Pin_3;
|
||
flag = 2;
|
||
tmos_set_event(press_task_id, BMP390_EVT_READ);
|
||
}
|
||
else if (R16_PA_INT_IF & GPIO_Pin_6)
|
||
{
|
||
R16_PA_INT_IF = GPIO_Pin_6;
|
||
flag = 3;
|
||
tmos_set_event(press_task_id, BMP390_EVT_READ);
|
||
}
|
||
}
|