c
复制代码
#include "sbc_fs65_drv_if.h"
#include "sbc_fs65.h"
#include "dtdef.h"
#include "spi_if.h"
#include "pin.h"
#include "spi.h"
#include "sbc_fs65_communication.h"
#include "dithread.h"
#include "sbc_fs65_reg.h"
/* Number of registers with status information. Note that this define can be
* used by user to create array of required size for function FS65_GetStatus(). */
#define FS65_STAT_NUM1 11
#define FS65_STAT_NUM2 4
#define FS65_STAT_NUM3 6
#define SBC_SPI_NAME "spi2"
/*跟MCU连接相关的引脚*/
//VSENSE引脚采样放在EPB_ADC采样模块里初始化
#define PIN_SBC_INTB dt_pin_get("P1.1")
#define PIN_SBC_FS0B dt_pin_get("P2.5")
#define PIN_SBC_FS1B dt_pin_get("P2.10")
typedef enum
{
EM_INT_AND_TIMING = 0, //中断和定时读取
EM_SHORT_TIMING, //定短时间读取
EM_LONG_TIMING, //定长时间读取
}RStatRegType_em;
typedef struct
{
uint16_t SbcStatusCnt1;
uint16_t SbcStatusCnt2;
uint16_t SbcStatusCnt3;
uint8_t u8ReadSbcStatusFlg1;
uint8_t u8ReadSbcStatusFlg2;
uint8_t u8ReadSbcStatusFlg3;
struct dt_timer stSbcStatusTimer; //读取sbc状态定时器
}SbcStatus_st;
/*******************************************************************************
* Variables
******************************************************************************/
/* This structure holds information about configurable registers.
* See comments of the fs65_user_config_t structure for details. */
static fs65_user_config_t s_stUserConfig = {0};
static uint8_t u8SbcFS65InitResult = 0;//SBC初始化结果
static uint8_t u8SbcFS65Intcounter = 0;//中断次数
static uint8_t s_u8WdRefreshFlg = 0; //看门狗刷新标志,每次定时时间到就置1
static uint8_t s_u8IntbStatus = 0; //sbc中断引脚状态,0.无中断产生,1.有中断产生
struct dt_timer stWdTimer; //看门狗定时器
static struct dt_spi_device stSbcSpiDev;
static SbcStatus_st s_stSbcStatus;
static SbcStatusReg_st s_stSbcStatusReg; //状态寄存器结构体
/*******************************************************************************
* FS65 configuration structures
*
* See description for the fs65_user_config_t structure for more information.
*
******************************************************************************/
static const fs65_reg_config_value_t s_stInitMainRegs[] =
{
{
FS65_M_INIT_VREG_ADDR,
FS65_RW_M_VAUX_TRK_EN_NO_TRACKING | FS65_RW_M_TAUX_LIM_OFF_50_MS |
FS65_RW_M_VCAN_OV_MON_OFF | FS65_RW_M_IPFF_DIS_ENABLED | FS65_RW_M_TCCA_LIM_OFF_50_MS |
FS65_RW_M_ICCA_LIM_ICCA_LIM_OUT,
FS65_RW_M_VAUX_TRK_EN_MASK | FS65_RW_M_TAUX_LIM_OFF_MASK | FS65_RW_M_VCAN_OV_MON_MASK |
FS65_RW_M_IPFF_DIS_MASK | FS65_RW_M_TCCA_LIM_OFF_MASK | FS65_RW_M_ICCA_LIM_MASK,
false
},
{
FS65_M_INIT_WU1_ADDR,
FS65_RW_M_WU_IO4_RISING_EDGE | FS65_RW_M_WU_IO3_NO_WAKEUP | FS65_RW_M_WU_IO2_NO_WAKEUP |
FS65_RW_M_WU_IO0_RISING_EDGE,
0xFFU,
false
},
{
FS65_M_INIT_WU2_ADDR,
FS65_RW_M_LIN_SR_20KBITS | FS65_RW_M_LIN_J2602_DIS_COMPLIANT | FS65_RW_M_CAN_WU_TO_120US |
FS65_RW_M_CAN_DIS_CFG_RX_ONLY | FS65_RW_M_WU_IO5_NO_WAKEUP,
0xFFU,
false
},
{
FS65_M_INIT_INH_INT_ADDR,
FS65_RW_M_INT_INH_0_NOT_MASKED | FS65_RW_M_INT_INH_2_MASKED | FS65_RW_M_INT_INH_3_MASKED |
FS65_RW_M_INT_INH_4_NOT_MASKED | FS65_RW_M_INT_INH_5_MASKED,
FS65_RW_M_INT_INH_0_MASK | FS65_RW_M_INT_INH_2_MASK | FS65_RW_M_INT_INH_3_MASK |
FS65_RW_M_INT_INH_4_MASK | FS65_RW_M_INT_INH_5_MASK,
false
}
};
static const fs65_reg_config_value_t s_stInitFailSafeRegs[] =
{
{
FS65_FS_INIT_FS1B_TIMING_ADDR,
FS65_R_FS_FS1B_TIME_106_848MS,
FS65_R_FS_FS1B_TIME_MASK,
true
},
{
FS65_FS_INIT_SUPERVISOR_ADDR,
FS65_R_FS_FS1B_TIME_RANGE_X1 | FS65_R_FS_VAUX_5D_NORMAL | FS65_R_FS_VCCA_5D_NORMAL |
FS65_R_FS_VCORE_5D_NORMAL,
0x0FU,
true
},
{
FS65_FS_INIT_FAULT_ADDR,
FS65_R_FS_FLT_ERR_IMP_RSTB | FS65_R_FS_FLT_ERR_FS_INT3_FIN6, /* FS65_R_FS_FS1B_CAN_IMPACT_RX_ONLY cannot be set in the device which has no FS1B. */
0x0FU,
true
},
{
FS65_FS_INIT_FSSM_ADDR,
FS65_R_FS_RSTB_DURATION_10MS | FS65_R_FS_PS_HIGH | FS65_R_FS_IO_23_FS_NOT_SAFETY |
FS65_R_FS_IO_45_FS_NOT_SAFETY,
0x0FU,
true
},
{
FS65_FS_INIT_SF_IMPACT_ADDR,
FS65_R_FS_WD_IMPACT_RSTB | FS65_R_FS_DIS_8S_ENABLED | FS65_R_FS_TDLY_TDUR_DELAY,
0x0FU,
true
},
{
FS65_FS_WD_WINDOW_ADDR,
FS65_R_FS_WD_WINDOW_64MS,
0x0FU,
true
},
{
FS65_FS_WD_LFSR_ADDR,
FS65_WD_SEED_DEFAULT,
0xFFU,
false
},
{
FS65_FS_INIT_WD_CNT_ADDR,
FS65_R_FS_WD_CNT_RFR_6 | FS65_R_FS_WD_CNT_ERR_6,
0x0FU,
true
},
{
FS65_FS_INIT_VCORE_OVUV_IMPACT_ADDR,
FS65_R_FS_VCORE_FS_UV_FS0B | FS65_R_FS_VCORE_FS_OV_RSTB_FS0B,
0x0FU,
true
},
{
FS65_FS_INIT_VCCA_OVUV_IMPACT_ADDR,
FS65_R_FS_VCCA_FS_UV_FS0B | FS65_R_FS_VCCA_FS_OV_RSTB_FS0B,
0x0FU,
true
},
{
FS65_FS_INIT_VAUX_OVUV_IMPACT_ADDR,
FS65_R_FS_VAUX_FS_UV_FS0B | FS65_R_FS_VAUX_FS_OV_RSTB_FS0B,
0x0FU,
true
}
};
static const fs65_reg_config_value_t s_stNonInitRegs[] =
{
{
FS65_M_MODE_ADDR,
FS65_RW_M_VKAM_EN_DISABLED,
FS65_RW_M_VKAM_EN_MASK,
true
},
{
FS65_M_REG_MODE_ADDR,
FS65_R_M_VCAN_EN_ENABLED | FS65_R_M_VAUX_EN_ENABLED | FS65_R_M_VCCA_EN_ENABLED |
FS65_R_M_VCORE_EN_ENABLED,
FS65_R_M_VCAN_EN_MASK | FS65_R_M_VAUX_EN_MASK | FS65_R_M_VCCA_EN_MASK |
FS65_R_M_VCORE_EN_MASK,
true
},
{
FS65_M_IO_OUT_AMUX_ADDR,
FS65_RW_M_AMUX_VREF | FS65_RW_M_IO_OUT_4_LOW | FS65_RW_M_IO_OUT_4_EN_Z,
FS65_RW_M_AMUX_MASK | FS65_RW_M_IO_OUT_4_MASK | FS65_RW_M_IO_OUT_4_EN_MASK,
false
}
};
/* This array contains addresses of registers with status information. */
static const uint8_t u8StatAddrMap1[] = { //需要触发读取的状态寄存器
FS65_M_DIAG_VPRE_ADDR, FS65_M_DIAG_VCORE_ADDR, FS65_M_DIAG_VCCA_ADDR,
FS65_M_DIAG_VAUX_ADDR, FS65_M_DIAG_VSUP_VCAN_ADDR, FS65_M_DIAG_CAN_FD_ADDR,
FS65_M_DIAG_CAN_LIN_ADDR, FS65_M_DIAG_SPI_ADDR,FS65_M_DIAG_SF_IOS_ADDR,
FS65_M_WD_COUNTER_ADDR, FS65_M_DIAG_SF_ERR_ADDR,
};
static const uint8_t u8StatAddrMap2[] = { //定时时间短读取的状态寄存器
FS65_M_WU_SOURCE_ADDR, FS65_M_IO_INPUT_ADDR,
FS65_M_MODE_ADDR, FS65_FS_RELEASE_FSXB_ADDR,
};
static const uint8_t u8StatAddrMap3[] = { //定时时间长读取的状态寄存器
FS65_M_INIT_VREG_ADDR, FS65_M_HW_CONFIG_ADDR, FS65_M_DEVICE_ID_ADDR,
FS65_M_REG_MODE_ADDR, FS65_M_CAN_LIN_MODE_ADDR, FS65_M_DEVICE_ID_FS_ADDR,
FS65_FS_BIST_ADDR,
};
/*******************************************************************************
* Functions
******************************************************************************/
/* Implementation of driver function for SPI communication. */
fs65_status_t MCU_SPI_TransferData(uint8_t* txFrame, uint8_t* rxFrame)
{
#if 0
uint8_t tmp_data[2];
tmp_data[0] = txFrame[0];
tmp_data[1] = txFrame[1];
#endif
spi_transmit(&stSbcSpiDev, txFrame, rxFrame, 2); //
return fs65StatusOk;
}
/* Implementation of driver function for blocking wait. */
void MCU_WaitUs(uint16_t delay)
{
for(int time_us = 0; time_us<delay; time_us++)
{
for(int i; i<40; i++) //1us
{
}
}
}
/* This function reads content of registers of the SBC with status
* values (wake-up sources, diagnostics, device ID, etc.)
* Note that it is up to user to evaluate obtained data. In order to
* facilitate this task, user is advice to use masks in register map. */
static uint8_t SbcGetStatus(uint8_t *address, fs65_rx_data_t* pSbcStatusData, uint8_t data_len)
{
fs65_status_t err; /* Status variable. */
uint8_t i; /* Index to array. */
//DEV_ASSERT(pSbcStatusData != NULL);
for (i = 0U; i < data_len; i++)
{
err = FS65_ReadRegister(address[i], &pSbcStatusData[i]);
if (err != fs65StatusOk)
{
return 1;
}
}
return 0;
}
/* Loads used configuration structure. */
static void LoadUserConfig(fs65_user_config_t* pConfig)
{
pConfig->initMainRegs = s_stInitMainRegs;
pConfig->initMainRegsCount = 4;
pConfig->initFailSafeRegs = s_stInitFailSafeRegs;
pConfig->initFailSafeRegsCount = 11;
pConfig->nonInitRegs = s_stNonInitRegs;
pConfig->nonInitRegsCount = 3;
pConfig->initIntReg = 0;
}
/*SBC中断信号处理*/
static void SBC_FS65_Intb_handle(void *para)
{
s_u8IntbStatus = 1;
u8SbcFS65Intcounter++;
s_stSbcStatus.u8ReadSbcStatusFlg1 = 1;
}
/*MCU引脚初始化*/
static void SBC_FS65_Hardware_Init(void)
{
/*FSXB引脚初始化*/
dt_pin_mode(PIN_SBC_FS0B, PIN_MODE_INPUT);
dt_pin_mode(PIN_SBC_FS1B, PIN_MODE_INPUT);
//dt_pin_mode(PIN_SBC_INTB, PIN_MODE_INPUT);
/*中断引脚初始化*/
dt_pin_attach_irq(PIN_SBC_INTB, PIN_IRQ_MODE_FALLING, SBC_FS65_Intb_handle, NULL);
dt_pin_irq_enable(PIN_SBC_INTB, PIN_IRQ_ENABLE);
/*SPI口初始化*/
stSbcSpiDev.mode = SPI_MODE_1;
stSbcSpiDev.chip_select = 1;
stSbcSpiDev.bits_per_word = 16;
stSbcSpiDev.max_speed_hz = 4000000; //4M
spi_init(&stSbcSpiDev, SBC_SPI_NAME);
}
/*看门狗定时回调函数*/
static void SBC_FS65_Wd_Timeout(void *para)
{
s_u8WdRefreshFlg = 1;
}
/*读取SBC状态定时回调函数*/
static void SBC_FS65_Read_Status_Timeout(void *para)
{
if(++s_stSbcStatus.SbcStatusCnt1 > 50) //500ms
{
s_stSbcStatus.SbcStatusCnt1 = 0;
s_stSbcStatus.u8ReadSbcStatusFlg1 = 1;
}
if(++s_stSbcStatus.SbcStatusCnt2 > 60) //600ms
{
s_stSbcStatus.SbcStatusCnt2 = 0;
s_stSbcStatus.u8ReadSbcStatusFlg2 = 1;
}
if(++s_stSbcStatus.SbcStatusCnt3 > 120) //1200ms
{
s_stSbcStatus.SbcStatusCnt3 = 0;
s_stSbcStatus.u8ReadSbcStatusFlg3 = 1;
}
}
/*FS65芯片寄存器初始化*/
uint8_t SBC_FS65_Init(void)
{
uint8_t u8InitStatus = 0;
/*数据初始化*/
memset(&s_stSbcStatus, 0, sizeof(s_stSbcStatus));
memset(&s_stSbcStatusReg, 0, sizeof(s_stSbcStatusReg));
/*gpio初始化*/
SBC_FS65_Hardware_Init();
/*开启看门狗刷新定时器*/
dt_timer_init(&stWdTimer, "WdTimer", SBC_FS65_Wd_Timeout, NULL, 40, DT_TIMER_FLAG_PERIODIC); //看门狗周期喂狗40ms
dt_timer_start(&stWdTimer);
/*开启读取SBC状态定时器*/
dt_timer_init(&s_stSbcStatus.stSbcStatusTimer, "SbcStatusTimer", SBC_FS65_Read_Status_Timeout, NULL, 10, DT_TIMER_FLAG_PERIODIC);
dt_timer_start(&s_stSbcStatus.stSbcStatusTimer);
/*加载FS65初始化数据*/
LoadUserConfig(&s_stUserConfig);
/*初始化FS65*/
u8InitStatus = FS65_Init(&s_stUserConfig);
u8SbcFS65InitResult = u8InitStatus;
if(u8InitStatus != fs65StatusOk)
{
return u8InitStatus;
}
return 0;
}
INIT_COMPONENT_EXPORT(SBC_FS65_Init);
/*FS65看门狗刷新,建议调用周期≤5ms*/
void SBC_FS65_Wd_Refresh(void)
{
if(s_u8WdRefreshFlg)
{
(void)FS65_WD_Refresh();
s_u8WdRefreshFlg = 0;
}
}
void SbcStatusRegUpdateData(fs65_rx_data_t* pSbcStatus, RStatRegType_em emRStatRegType)
{
switch (emRStatRegType)
{
case EM_INT_AND_TIMING:
s_stSbcStatusReg.unSbcRegDiagVpre.u8Data = pSbcStatus[0].readData;
s_stSbcStatusReg.unSbcRegDiagVcore.u8Data = pSbcStatus[1].readData;
s_stSbcStatusReg.unSbcRegDiagVcca.u8Data = pSbcStatus[2].readData;
s_stSbcStatusReg.unSbcRegDiagVaux.u8Data = pSbcStatus[3].readData;
s_stSbcStatusReg.unSbcRegDiagVsupVcan.u8Data = pSbcStatus[4].readData;
s_stSbcStatusReg.unSbcRegDiagCanFd.u8Data = pSbcStatus[5].readData;
s_stSbcStatusReg.unSbcRegDiagCanLin.u8Data = pSbcStatus[6].readData;
s_stSbcStatusReg.unSbcRegDiagSpi.u8Data = pSbcStatus[7].readData;
s_stSbcStatusReg.unSbcRegDiagSfIos.u8Data = pSbcStatus[8].readData;
s_stSbcStatusReg.unSbcRegWdCounter.u8Data = pSbcStatus[9].readData;
s_stSbcStatusReg.unSbcRegDiagSfErr.u8Data = pSbcStatus[10].readData;
break;
case EM_SHORT_TIMING:
s_stSbcStatusReg.unSbcRegWuSource.u8Data = pSbcStatus[0].readData;
s_stSbcStatusReg.unSbcRegIoInput.u8Data = pSbcStatus[1].readData;
s_stSbcStatusReg.unSbcRegMode.u8Data = pSbcStatus[2].readData;
s_stSbcStatusReg.unSbcRegReleaseFsxb.u8Data = pSbcStatus[3].readData;
break;
case EM_LONG_TIMING:
s_stSbcStatusReg.unSbcRegInitVreg.u8Data = pSbcStatus[0].readData;
s_stSbcStatusReg.unSbcRegHwConfig.u8Data = pSbcStatus[1].readData;
s_stSbcStatusReg.unSbcRegDeviceId.u8Data = pSbcStatus[2].readData;
s_stSbcStatusReg.unSbcRegRegMode.u8Data = pSbcStatus[3].readData;
s_stSbcStatusReg.unSbcRegCanLinMode.u8Data = pSbcStatus[4].readData;
s_stSbcStatusReg.unSbcRegDeviceIdFs.u8Data = pSbcStatus[5].readData;
s_stSbcStatusReg.unSbcRegBist.u8Data = pSbcStatus[6].readData;
break;
default:
break;
}
}
/*读取FS65状态*/
void SBC_FS65_Read_SbcStatus(void)
{
if(!s_u8WdRefreshFlg) //看门狗不处于刷新状态
{
if(s_stSbcStatus.u8ReadSbcStatusFlg1)
{
/*读取故障相关寄存器*/
fs65_status_t status = fs65StatusOk;
fs65_rx_data_t stSbcStatus[FS65_STAT_NUM1];
if(SbcGetStatus(u8StatAddrMap1, stSbcStatus, FS65_STAT_NUM1) == 0)
{
status = fs65StatusOk;
SbcStatusRegUpdateData(stSbcStatus, EM_INT_AND_TIMING);
}
else
{
status = fs65StatusError;
}
s_stSbcStatus.u8ReadSbcStatusFlg1 = 0;
}
else if(s_stSbcStatus.u8ReadSbcStatusFlg2)
{
/*读取故障相关寄存器*/
fs65_status_t status = fs65StatusOk;
fs65_rx_data_t stSbcStatus[FS65_STAT_NUM2];
if(SbcGetStatus(u8StatAddrMap2, stSbcStatus, FS65_STAT_NUM2) == 0)
{
status = fs65StatusOk;
SbcStatusRegUpdateData(stSbcStatus, EM_SHORT_TIMING);
}
else
{
status = fs65StatusError;
}
s_stSbcStatus.u8ReadSbcStatusFlg2 = 0;
}
else if(s_stSbcStatus.u8ReadSbcStatusFlg3)
{
/*读取故障相关寄存器*/
fs65_status_t status = fs65StatusOk;
fs65_rx_data_t stSbcStatus[FS65_STAT_NUM3];
if(SbcGetStatus(u8StatAddrMap3, stSbcStatus, FS65_STAT_NUM3) == 0)
{
status = fs65StatusOk;
SbcStatusRegUpdateData(stSbcStatus, EM_LONG_TIMING);
}
else
{
status = fs65StatusError;
}
s_stSbcStatus.u8ReadSbcStatusFlg3 = 0;
}
else
{
//do nothing
}
}
}
/*释放SBC FS0B和FS1B*/
uint8_t SBC_FS65_ReleaseFSxB(void)
{
fs65_status_t sbcStatus;
uint8_t status = 0; /* Return status code. */
uint8_t errorCounter = 0xFF; /* Fault Error Counter value. */
fs65_rx_data_t rxData;
if(!s_u8WdRefreshFlg) //看门狗不处于刷新状态
{
sbcStatus = FS65_GetFaultErrorCounterValue(&errorCounter);
sbcStatus |= FS65_ReadRegister(FS65_FS_RELEASE_FSXB_ADDR, &rxData);
if (sbcStatus != fs65StatusOk)
{
return sbcStatus;
}
/* FS0b pin asserted, start release procedure. */
if (errorCounter == 0 &&
(rxData.readData & FS65_R_FS_FS0B_SNS_MASK) == FS65_R_FS_FS0B_SNS_LOW)
{
/* Close S1 switch between VPRE and VPU_FS if FS1B backup delay was engaged (FS1B_DLY_DRV bit = 1). */
sbcStatus = FS65_WriteRegister(FS65_FS_SF_OUTPUT_REQUEST_ADDR, 0, NULL);
/* Try to release the FS0b pin. */
sbcStatus |= FS65_ReleaseFSx(fs65ReleaseFs0bFs1b);
if (sbcStatus != fs65StatusOk)
{
return 1;
}
else
{
return 0;
}
}
}
return 1;
}
#if 0
struct dt_spi_device spidev1;
struct dt_spi_message m;
struct dt_spi_transfer t;
#endif
void SBC_FS65_Test(void)
{
// uint8_t tx_buf[2] = {0x00,0x68}, rx_buf[2];
// spi_transmit(&stSbcSpiDev, tx_buf, rx_buf, 1);
// FS65_CheckLbistAbistOk();
SBC_FS65_Wd_Refresh();
SBC_FS65_Read_SbcStatus();
}
c
复制代码
#include "sbc_fs65_drv_if.h"
#include "sbc_fs65.h"
#include "dtdef.h"
#include "spi_if.h"
#include "pin.h"
#include "spi.h"
#include "sbc_fs65_communication.h"
#include "dithread.h"
#include "sbc_fs65_reg.h"
/* Number of registers with status information. Note that this define can be
* used by user to create array of required size for function FS65_GetStatus(). */
#define FS65_STAT_NUM1 11
#define FS65_STAT_NUM2 4
#define FS65_STAT_NUM3 6
#define SBC_SPI_NAME "spi2"
/*跟MCU连接相关的引脚*/
//VSENSE引脚采样放在EPB_ADC采样模块里初始化
#define PIN_SBC_INTB dt_pin_get("P1.1")
#define PIN_SBC_FS0B dt_pin_get("P2.5")
#define PIN_SBC_FS1B dt_pin_get("P2.10")
// 定义SbcStatus_st结构体,用于存储SBC状态的相关数据
typedef struct
{
uint16_t SbcStatusCnt1; // 用于记录SBC状态计数器1(500ms周期)
uint16_t SbcStatusCnt2; // 用于记录SBC状态计数器2(600ms周期)
uint16_t SbcStatusCnt3; // 用于记录SBC状态计数器3(1200ms周期)
uint8_t u8ReadSbcStatusFlg1; // 500ms状态标志位
uint8_t u8ReadSbcStatusFlg2; // 600ms状态标志位
uint8_t u8ReadSbcStatusFlg3; // 1200ms状态标志位
struct dt_timer stSbcStatusTimer; // 定义读取SBC状态的定时器
} SbcStatus_st;
/*******************************************************************************
* 变量定义
*******************************************************************************/
// 用于存储FS65芯片的用户配置数据的结构体
static fs65_user_config_t s_stUserConfig = {0};
// SBC初始化结果的状态变量,初始化为0
static uint8_t u8SbcFS65InitResult = 0;
// 用于记录SBC中断次数的变量
static uint8_t u8SbcFS65Intcounter = 0;
// 看门狗刷新标志,每次定时时间到时就置1
static uint8_t s_u8WdRefreshFlg = 0;
// SBC中断引脚状态,0表示无中断产生,1表示有中断产生
static uint8_t s_u8IntbStatus = 0;
// 定义看门狗定时器结构体
struct dt_timer stWdTimer;
// 定义SBC SPI设备的结构体
static struct dt_spi_device stSbcSpiDev;
// 定义用于存储SBC状态的结构体
static SbcStatus_st s_stSbcStatus;
// 定义状态寄存器结构体,存储SBC的各类状态寄存器数据
static SbcStatusReg_st s_stSbcStatusReg;
解释:
SbcStatus_st 结构体保存了多个SBC状态的相关信息,包括状态计数器和读取状态的定时器。计数器用于判断500ms、600ms、1200ms的时间间隔是否到达。
fs65_user_config_t 结构体用于保存FS65芯片的用户配置。
u8SbcFS65InitResult 用于存储FS65芯片的初始化结果。
u8SbcFS65Intcounter 用于记录中断的次数。
s_u8WdRefreshFlg 表示看门狗定时器是否触发刷新,每次触发后会置1。
s_u8IntbStatus 保存SBC中断引脚的状态,表示是否有中断发生。
stWdTimer 和 stSbcStatusTimer 是定时器结构体,分别用于看门狗刷新和读取SBC状态。
stSbcSpiDev 保存SBC的SPI设备信息。
s_stSbcStatus 和 s_stSbcStatusReg 分别保存SBC的状态信息和状态寄存器的数据。
typedef enum
{
EM_INT_AND_TIMING = 0, //中断和定时读取
EM_SHORT_TIMING, //定短时间读取
EM_LONG_TIMING, //定长时间读取
}RStatRegType_em;
typedef struct
{
uint16_t SbcStatusCnt1;
uint16_t SbcStatusCnt2;
uint16_t SbcStatusCnt3;
uint8_t u8ReadSbcStatusFlg1;
uint8_t u8ReadSbcStatusFlg2;
uint8_t u8ReadSbcStatusFlg3;
struct dt_timer stSbcStatusTimer; //读取sbc状态定时器
}SbcStatus_st;
/*******************************************************************************
* Variables
******************************************************************************/
/* This structure holds information about configurable registers.
* See comments of the fs65_user_config_t structure for details. */
static fs65_user_config_t s_stUserConfig = {0};
static uint8_t u8SbcFS65InitResult = 0; //SBC初始化结果
static uint8_t u8SbcFS65Intcounter = 0; //中断次数
static uint8_t s_u8WdRefreshFlg = 0; //看门狗刷新标志,每次定时时间到就置1
static uint8_t s_u8IntbStatus = 0; //sbc中断引脚状态,0.无中断产生,1.有中断产生
struct dt_timer stWdTimer; //看门狗定时器
static struct dt_spi_device stSbcSpiDev;
static SbcStatus_st s_stSbcStatus;
static SbcStatusReg_st s_stSbcStatusReg; //状态寄存器结构体
/*******************************************************************************
* FS65 configuration structures
*
* See description for the fs65_user_config_t structure for more information.
*
******************************************************************************/
static const fs65_reg_config_value_t s_stInitMainRegs[] = {
{
FS65_M_INIT_VREG_ADDR,
FS65_RW_M_VAUX_TRK_EN_NO_TRACKING | FS65_RW_M_TAUX_LIM_OFF_50_MS |
FS65_RW_M_VCAN_OV_MON_OFF | FS65_RW_M_IPFF_DIS_ENABLED | FS65_RW_M_TCCA_LIM_OFF_50_MS |
FS65_RW_M_ICCA_LIM_ICCA_LIM_OUT,
FS65_RW_M_VAUX_TRK_EN_MASK | FS65_RW_M_TAUX_LIM_OFF_MASK | FS65_RW_M_VCAN_OV_MON_MASK |
FS65_RW_M_IPFF_DIS_MASK | FS65_RW_M_TCCA_LIM_OFF_MASK | FS65_RW_M_ICCA_LIM_MASK,
false
},
{
FS65_M_INIT_WU1_ADDR,
FS65_RW_M_WU_IO4_RISING_EDGE | FS65_RW_M_WU_IO3_NO_WAKEUP | FS65_RW_M_WU_IO2_NO_WAKEUP |
FS65_RW_M_WU_IO0_RISING_EDGE,
0xFFU,
false
},
{
FS65_M_INIT_WU2_ADDR,
FS65_RW_M_LIN_SR_20KBITS | FS65_RW_M_LIN_J2602_DIS_COMPLIANT | FS65_RW_M_CAN_WU_TO_120US |
FS65_RW_M_CAN_DIS_CFG_RX_ONLY | FS65_RW_M_WU_IO5_NO_WAKEUP,
0xFFU,
false
},
{
FS65_M_INIT_INH_INT_ADDR,
FS65_RW_M_INT_INH_0_NOT_MASKED | FS65_RW_M_INT_INH_2_MASKED | FS65_RW_M_INT_INH_3_MASKED |
FS65_RW_M_INT_INH_4_NOT_MASKED | FS65_RW_M_INT_INH_5_MASKED,
FS65_RW_M_INT_INH_0_MASK | FS65_RW_M_INT_INH_2_MASK | FS65_RW_M_INT_INH_3_MASK |
FS65_RW_M_INT_INH_4_MASK | FS65_RW_M_INT_INH_5_MASK,
false
}
};
static const fs65_reg_config_value_t s_stInitFailSafeRegs[] =
{
{
FS65_FS_INIT_FS1B_TIMING_ADDR,
FS65_R_FS_FS1B_TIME_106_848MS,
FS65_R_FS_FS1B_TIME_MASK,
true
},
{
FS65_FS_INIT_SUPERVISOR_ADDR,
FS65_R_FS_FS1B_TIME_RANGE_X1 | FS65_R_FS_VAUX_5D_NORMAL | FS65_R_FS_VCCA_5D_NORMAL |
FS65_R_FS_VCORE_5D_NORMAL,
0x0FU,
true
},
{
FS65_FS_INIT_FAULT_ADDR,
FS65_R_FS_FLT_ERR_IMP_RSTB | FS65_R_FS_FLT_ERR_FS_INT3_FIN6, /* FS65_R_FS_FS1B_CAN_IMPACT_RX_ONLY cannot be set in the device which has no FS1B. */
0x0FU,
true
},
{
FS65_FS_INIT_FSSM_ADDR,
FS65_R_FS_RSTB_DURATION_10MS | FS65_R_FS_PS_HIGH | FS65_R_FS_IO_23_FS_NOT_SAFETY |
FS65_R_FS_IO_45_FS_NOT_SAFETY,
0x0FU,
true
},
{
FS65_FS_INIT_SF_IMPACT_ADDR,
FS65_R_FS_WD_IMPACT_RSTB | FS65_R_FS_DIS_8S_ENABLED | FS65_R_FS_TDLY_TDUR_DELAY,
0x0FU,
true
},
{
FS65_FS_WD_WINDOW_ADDR,
FS65_R_FS_WD_WINDOW_64MS,
0x0FU,
true
},
{
FS65_FS_WD_LFSR_ADDR,
FS65_WD_SEED_DEFAULT,
0xFFU,
false
},
{
FS65_FS_INIT_WD_CNT_ADDR,
FS65_R_FS_WD_CNT_RFR_6 | FS65_R_FS_WD_CNT_ERR_6,
0x0FU,
true
},
{
FS65_FS_INIT_VCORE_OVUV_IMPACT_ADDR,
FS65_R_FS_VCORE_FS_UV_FS0B | FS65_R_FS_VCORE_FS_OV_RSTB_FS0B,
0x0FU,
true
},
{
FS65_FS_INIT_VCCA_OVUV_IMPACT_ADDR,
FS65_R_FS_VCCA_FS_UV_FS0B | FS65_R_FS_VCCA_FS_OV_RSTB_FS0B,
0x0FU,
true
},
{
FS65_FS_INIT_VAUX_OVUV_IMPACT_ADDR,
FS65_R_FS_VAUX_FS_UV_FS0B | FS65_R_FS_VAUX_FS_OV_RSTB_FS0B,
0x0FU,
true
}
};
static const fs65_reg_config_value_t s_stNonInitRegs[] =
{
{
FS65_M_MODE_ADDR,
FS65_RW_M_VKAM_EN_DISABLED,
FS65_RW_M_VKAM_EN_MASK,
true
},
{
FS65_M_REG_MODE_ADDR,
FS65_R_M_VCAN_EN_ENABLED | FS65_R_M_VAUX_EN_ENABLED | FS65_R_M_VCCA_EN_ENABLED |
FS65_R_M_VCORE_EN_ENABLED,
FS65_R_M_VCAN_EN_MASK | FS65_R_M_VAUX_EN_MASK | FS65_R_M_VCCA_EN_MASK |
FS65_R_M_VCORE_EN_MASK,
true
},
{
FS65_M_IO_OUT_AMUX_ADDR,
FS65_RW_M_AMUX_VREF | FS65_RW_M_IO_OUT_4_LOW | FS65_RW_M_IO_OUT_4_EN_Z,
FS65_RW_M_AMUX_MASK | FS65_RW_M_IO_OUT_4_MASK | FS65_RW_M_IO_OUT_4_EN_MASK,
false
}
};
/* This array contains addresses of registers with status information. */
static const uint8_t u8StatAddrMap1[] = { //需要触发读取的状态寄存器
FS65_M_DIAG_VPRE_ADDR, FS65_M_DIAG_VCORE_ADDR, FS65_M_DIAG_VCCA_ADDR,
FS65_M_DIAG_VAUX_ADDR, FS65_M_DIAG_VSUP_VCAN_ADDR, FS65_M_DIAG_CAN_FD_ADDR,
FS65_M_DIAG_CAN_LIN_ADDR, FS65_M_DIAG_SPI_ADDR,FS65_M_DIAG_SF_IOS_ADDR,
FS65_M_WD_COUNTER_ADDR, FS65_M_DIAG_SF_ERR_ADDR,
};
static const uint8_t u8StatAddrMap2[] = { //定时时间短读取的状态寄存器
FS65_M_WU_SOURCE_ADDR, FS65_M_IO_INPUT_ADDR,
FS65_M_MODE_ADDR, FS65_FS_RELEASE_FSXB_ADDR,
};
static const uint8_t u8StatAddrMap3[] = { //定时时间长读取的状态寄存器
FS65_M_INIT_VREG_ADDR, FS65_M_HW_CONFIG_ADDR, FS65_M_DEVICE_ID_ADDR,
FS65_M_REG_MODE_ADDR, FS65_M_CAN_LIN_MODE_ADDR, FS65_M_DEVICE_ID_FS_ADDR,
FS65_FS_BIST_ADDR,
};
/*******************************************************************************
* FS65配置结构体
*
* 这些结构体用于初始化和配置FS65芯片的寄存器。
* 详细说明可以参考fs65_user_config_t结构体的文档。
*******************************************************************************/
// FS65初始化主寄存器的配置数据
static const fs65_reg_config_value_t s_stInitMainRegs[] = {
{
FS65_M_INIT_VREG_ADDR, // 初始化电压寄存器地址
// 配置寄存器的各个选项,如无辅助电压跟踪、定时器50ms、电流保护等
FS65_RW_M_VAUX_TRK_EN_NO_TRACKING | FS65_RW_M_TAUX_LIM_OFF_50_MS |
FS65_RW_M_VCAN_OV_MON_OFF | FS65_RW_M_IPFF_DIS_ENABLED | FS65_RW_M_TCCA_LIM_OFF_50_MS |
FS65_RW_M_ICCA_LIM_ICCA_LIM_OUT,
// 掩码,用于配置哪些选项被有效应用
FS65_RW_M_VAUX_TRK_EN_MASK | FS65_RW_M_TAUX_LIM_OFF_MASK | FS65_RW_M_VCAN_OV_MON_MASK |
FS65_RW_M_IPFF_DIS_MASK | FS65_RW_M_TCCA_LIM_OFF_MASK | FS65_RW_M_ICCA_LIM_MASK,
false
},
{
FS65_M_INIT_WU1_ADDR, // 初始化唤醒寄存器1地址
// 配置唤醒边沿触发,指定引脚使用上升沿触发
FS65_RW_M_WU_IO4_RISING_EDGE | FS65_RW_M_WU_IO3_NO_WAKEUP | FS65_RW_M_WU_IO2_NO_WAKEUP |
FS65_RW_M_WU_IO0_RISING_EDGE,
0xFFU,
false
},
{
FS65_M_INIT_WU2_ADDR, // 初始化唤醒寄存器2地址
// 配置LIN和CAN唤醒信号、失效模式等
FS65_RW_M_LIN_SR_20KBITS | FS65_RW_M_LIN_J2602_DIS_COMPLIANT | FS65_RW_M_CAN_WU_TO_120US |
FS65_RW_M_CAN_DIS_CFG_RX_ONLY | FS65_RW_M_WU_IO5_NO_WAKEUP,
0xFFU,
false
},
{
FS65_M_INIT_INH_INT_ADDR, // 初始化中断抑制寄存器地址
// 配置抑制或不抑制特定中断
FS65_RW_M_INT_INH_0_NOT_MASKED | FS65_RW_M_INT_INH_2_MASKED | FS65_RW_M_INT_INH_3_MASKED |
FS65_RW_M_INT_INH_4_NOT_MASKED | FS65_RW_M_INT_INH_5_MASKED,
FS65_RW_M_INT_INH_0_MASK | FS65_RW_M_INT_INH_2_MASK | FS65_RW_M_INT_INH_3_MASK |
FS65_RW_M_INT_INH_4_MASK | FS65_RW_M_INT_INH_5_MASK,
false
}
};
// FS65安全寄存器的初始化配置数据
static const fs65_reg_config_value_t s_stInitFailSafeRegs[] = {
{
FS65_FS_INIT_FS1B_TIMING_ADDR, // 安全定时器1B的配置地址
FS65_R_FS_FS1B_TIME_106_848MS, // 配置定时器1B的时间为106.848ms
FS65_R_FS_FS1B_TIME_MASK, // 掩码
true
},
{
FS65_FS_INIT_SUPERVISOR_ADDR, // 监管寄存器的配置地址
FS65_R_FS_FS1B_TIME_RANGE_X1 | FS65_R_FS_VAUX_5D_NORMAL | FS65_R_FS_VCCA_5D_NORMAL |
FS65_R_FS_VCORE_5D_NORMAL, // 监管VAUX、VCCA、VCORE的状态
0x0FU,
true
},
{
FS65_FS_INIT_FAULT_ADDR, // 故障寄存器的配置地址
FS65_R_FS_FLT_ERR_IMP_RSTB | FS65_R_FS_FLT_ERR_FS_INT3_FIN6, // 配置故障模式和重置行为
0x0FU,
true
},
{
FS65_FS_INIT_FSSM_ADDR, // FSSM寄存器的配置地址
FS65_R_FS_RSTB_DURATION_10MS | FS65_R_FS_PS_HIGH | FS65_R_FS_IO_23_FS_NOT_SAFETY |
FS65_R_FS_IO_45_FS_NOT_SAFETY, // 配置重置持续时间和I/O安全模式
0x0FU,
true
},
{
FS65_FS_INIT_SF_IMPACT_ADDR, // SF影响寄存器的配置地址
FS65_R_FS_WD_IMPACT_RSTB | FS65_R_FS_DIS_8S_ENABLED | FS65_R_FS_TDLY_TDUR_DELAY, // 配置看门狗影响和延迟
0x0FU,
true
},
{
FS65_FS_WD_WINDOW_ADDR, // 看门狗窗口寄存器地址
FS65_R_FS_WD_WINDOW_64MS, // 设置看门狗窗口时间为64ms
0x0FU,
true
},
{
FS65_FS_WD_LFSR_ADDR, // 看门狗LFSR寄存器地址
FS65_WD_SEED_DEFAULT, // 使用默认的看门狗种子
0xFFU,
false
},
{
FS65_FS_INIT_WD_CNT_ADDR, // 看门狗计数器寄存器地址
FS65_R_FS_WD_CNT_RFR_6 | FS65_R_FS_WD_CNT_ERR_6, // 配置看门狗计数器和错误计数
0x0FU,
true
},
{
FS65_FS_INIT_VCORE_OVUV_IMPACT_ADDR, // VCORE过压欠压影响寄存器地址
FS65_R_FS_VCORE_FS_UV_FS0B | FS65_R_FS_VCORE_FS_OV_RSTB_FS0B, // 配置VCORE过压欠压影响行为
0x0FU,
true
},
{
FS65_FS_INIT_VCCA_OVUV_IMPACT_ADDR, // VCCA过压欠压影响寄存器地址
FS65_R_FS_VCCA_FS_UV_FS0B | FS65_R_FS_VCCA_FS_OV_RSTB_FS0B, // 配置VCCA过压欠压影响行为
0x0FU,
true
},
{
FS65_FS_INIT_VAUX_OVUV_IMPACT_ADDR, // VAUX过压欠压影响寄存器地址
FS65_R_FS_VAUX_FS_UV_FS0B | FS65_R_FS_VAUX_FS_OV_RSTB_FS0B, // 配置VAUX过压欠压影响行为
0x0FU,
true
}
};
// 非初始化寄存器的配置数据
static const fs65_reg_config_value_t s_stNonInitRegs[] = {
{
FS65_M_MODE_ADDR, // 模式寄存器地址
FS65_RW_M_VKAM_EN_DISABLED, // 禁用VKAM
FS65_RW_M_VKAM_EN_MASK,
true
},
{
FS65_M_REG_MODE_ADDR, // 寄存器模式寄存器地址
FS65_R_M_VCAN_EN_ENABLED | FS65_R_M_VAUX_EN_ENABLED | FS65_R_M_VCCA_EN_ENABLED |
FS65_R_M_VCORE_EN_ENABLED, // 启用VCAN、VAUX、VCCA、VCORE
FS65_R_M_VCAN_EN_MASK | FS65_R_M_VAUX_EN_MASK | FS65_R_M_VCCA_EN_MASK |
FS65_R_M_VCORE_EN_MASK,
true
},
{
FS65_M_IO_OUT_AMUX_ADDR, // I/O输出寄存器地址
FS65_RW_M_AMUX_VREF | FS65_RW_M_IO_OUT_4_LOW | FS65_RW_M_IO_OUT_4_EN_Z, // 配置AMUX和I/O输出模式
FS65_RW_M_AMUX_MASK | FS65_RW_M_IO_OUT_4_MASK | FS65_RW_M_IO_OUT_4_EN_MASK,
false
}
};
// 这些数组包含状态寄存器的地址映射,用于定时读取不同类型的状态信息
// 地址映射1:需要定期读取的故障诊断状态寄存器
static const uint8_t u8StatAddrMap1[] = {
FS65_M_DIAG_VPRE_ADDR, FS65_M_DIAG_VCORE_ADDR, FS65_M_DIAG_VCCA_ADDR,
FS65_M_DIAG_VAUX_ADDR, FS65_M_DIAG_VSUP_VCAN_ADDR, FS65_M_DIAG_CAN_FD_ADDR,
FS65_M_DIAG_CAN_LIN_ADDR, FS65_M_DIAG_SPI_ADDR, FS65_M_DIAG_S
/*******************************************************************************
* Functions
******************************************************************************/
/* Implementation of driver function for SPI communication. */
fs65_status_t MCU_SPI_TransferData(uint8_t* txFrame, uint8_t* rxFrame)
{
#if 0
uint8_t tmp_data[2];
tmp_data[0] = txFrame[0];
tmp_data[1] = txFrame[1];
#endif
spi_transmit(&stSbcSpiDev, txFrame, rxFrame, 2); //
return fs65StatusOk;
}
/* Implementation of driver function for blocking wait. */
void MCU_WaitUs(uint16_t delay)
{
for(int time_us = 0; time_us<delay; time_us++)
{
for(int i; i<40; i++) //1us
{
}
}
}
/* 该函数读取SBC的寄存器内容,获取状态值(唤醒源、诊断、设备ID等)。
* 注意,评估获取的数据由用户自行负责。为了便于此任务,建议用户使用寄存器映射中的掩码。 */
static uint8_t SbcGetStatus(uint8_t *address, fs65_rx_data_t* pSbcStatusData, uint8_t data_len)
{
fs65_status_t err; /* 状态变量,用于存储读取结果。 */
uint8_t i; /* 数组索引。 */
for (i = 0U; i < data_len; i++) /* 遍历指定长度的数据。 */
{
err = FS65_ReadRegister(address[i], &pSbcStatusData[i]); /* 读取寄存器值并存储到相应的位置。 */
if (err != fs65StatusOk) /* 检查读取是否成功。 */
{
return 1; /* 如果失败,返回错误代码1。 */
}
}
return 0; /* 所有寄存器读取成功,返回0。 */
}
/* 加载用户配置结构体。 */
static void LoadUserConfig(fs65_user_config_t* pConfig)
{
pConfig->initMainRegs = s_stInitMainRegs; /* 设置主寄存器初始化结构体。 */
pConfig->initMainRegsCount = 4; /* 主寄存器初始化的数量为4个。 */
pConfig->initFailSafeRegs = s_stInitFailSafeRegs; /* 设置故障安全寄存器初始化结构体。 */
pConfig->initFailSafeRegsCount = 11; /* 故障安全寄存器初始化的数量为11个。 */
pConfig->nonInitRegs = s_stNonInitRegs; /* 设置非初始化寄存器结构体。 */
pConfig->nonInitRegsCount = 3; /* 非初始化寄存器的数量为3个。 */
pConfig->initIntReg = 0; /* 初始化内部寄存器的值为0。 */
}
/* SBC中断信号处理 */
static void SBC_FS65_Intb_handle(void *para)
{
s_u8IntbStatus = 1; /* 设置中断状态标志为1,表示中断已发生。 */
u8SbcFS65Intcounter++; /* 增加SBC FS65中断计数器。 */
s_stSbcStatus.u8ReadSbcStatusFlg1 = 1; /* 设置标志,表示需要读取SBC状态。 */
}
/* MCU引脚初始化 */
static void SBC_FS65_Hardware_Init(void)
{
/* FSXB引脚初始化 */
dt_pin_mode(PIN_SBC_FS0B, PIN_MODE_INPUT); /* 设置SBC FS0B引脚为输入模式。 */
dt_pin_mode(PIN_SBC_FS1B, PIN_MODE_INPUT); /* 设置SBC FS1B引脚为输入模式。 */
//dt_pin_mode(PIN_SBC_INTB, PIN_MODE_INPUT); /* (已注释)设置SBC中断引脚为输入模式。 */
/* 中断引脚初始化 */
dt_pin_attach_irq(PIN_SBC_INTB, PIN_IRQ_MODE_FALLING, SBC_FS65_Intb_handle, NULL); /* 将中断处理函数附加到SBC中断引脚,触发方式为下降沿。 */
dt_pin_irq_enable(PIN_SBC_INTB, PIN_IRQ_ENABLE); /* 启用SBC中断引脚的中断。 */
/* SPI口初始化 */
stSbcSpiDev.mode = SPI_MODE_1; /* 设置SPI模式为模式1。 */
stSbcSpiDev.chip_select = 1; /* 设置芯片选择引脚。 */
stSbcSpiDev.bits_per_word = 16; /* 设置每个字的位数为16位。 */
stSbcSpiDev.max_speed_hz = 4000000; // 4MHz最大速度
spi_init(&stSbcSpiDev, SBC_SPI_NAME); /* 初始化SPI设备。 */
}
/*看门狗定时回调函数*/
static void SBC_FS65_Wd_Timeout(void *para)
{
s_u8WdRefreshFlg = 1;
}
/* 读取SBC状态的定时回调函数 */
static void SBC_FS65_Read_Status_Timeout(void *para)
{
// 判断SbcStatusCnt1是否超过50(对应500ms),每次调用函数时对其进行自增操作
if(++s_stSbcStatus.SbcStatusCnt1 > 50) // 500ms
{
s_stSbcStatus.SbcStatusCnt1 = 0; // 计数器重置为0
s_stSbcStatus.u8ReadSbcStatusFlg1 = 1; // 设置状态标志位,表示500ms间隔已达到
}
// 判断SbcStatusCnt2是否超过60(对应600ms),每次调用函数时对其进行自增操作
if(++s_stSbcStatus.SbcStatusCnt2 > 60) // 600ms
{
s_stSbcStatus.SbcStatusCnt2 = 0; // 计数器重置为0
s_stSbcStatus.u8ReadSbcStatusFlg2 = 1; // 设置状态标志位,表示600ms间隔已达到
}
// 判断SbcStatusCnt3是否超过120(对应1200ms),每次调用函数时对其进行自增操作
if(++s_stSbcStatus.SbcStatusCnt3 > 120) // 1200ms
{
s_stSbcStatus.SbcStatusCnt3 = 0; // 计数器重置为0
s_stSbcStatus.u8ReadSbcStatusFlg3 = 1; // 设置状态标志位,表示1200ms间隔已达到
}
}
这是一个定时回调函数,用来读取SBC(系统基础芯片)状态。
代码中有三个计数器 SbcStatusCnt1, SbcStatusCnt2 和 SbcStatusCnt3,它们分别记录500ms、600ms 和 1200ms的间隔。
每次函数被调用时,这三个计数器都会递增,当它们达到指定的阈值时(分别为50、60、120次调用),对应的标志位 u8ReadSbcStatusFlg1, u8ReadSbcStatusFlg2, u8ReadSbcStatusFlg3 会被置1,表示时间到了需要读取SBC状态。
/* FS65芯片寄存器初始化函数 */
uint8_t SBC_FS65_Init(void)
{
uint8_t u8InitStatus = 0; // 初始化状态变量
/* 数据初始化 */
memset(&s_stSbcStatus, 0, sizeof(s_stSbcStatus)); // 将 SBC 状态结构体内存清零
memset(&s_stSbcStatusReg, 0, sizeof(s_stSbcStatusReg)); // 将 SBC 状态寄存器结构体内存清零
/* GPIO 初始化 */
SBC_FS65_Hardware_Init(); // 调用硬件初始化函数
/* 开启看门狗刷新定时器 */
// 初始化看门狗定时器,定时周期为40ms,每40ms触发一次定时器中断,执行SBC_FS65_Wd_Timeout函数
dt_timer_init(&stWdTimer, "WdTimer", SBC_FS65_Wd_Timeout, NULL, 40, DT_TIMER_FLAG_PERIODIC);
dt_timer_start(&stWdTimer); // 启动定时器
/* 开启读取SBC状态定时器 */
// 初始化定时器用于定期读取SBC状态,定时周期为10ms,每10ms执行一次SBC_FS65_Read_Status_Timeout函数
dt_timer_init(&s_stSbcStatus.stSbcStatusTimer, "SbcStatusTimer", SBC_FS65_Read_Status_Timeout, NULL, 10, DT_TIMER_FLAG_PERIODIC);
dt_timer_start(&s_stSbcStatus.stSbcStatusTimer); // 启动定时器
/* 加载FS65初始化数据 */
LoadUserConfig(&s_stUserConfig); // 加载用户配置数据到s_stUserConfig结构体
/* 初始化FS65芯片 */
u8InitStatus = FS65_Init(&s_stUserConfig); // 使用用户配置数据初始化FS65芯片
u8SbcFS65InitResult = u8InitStatus; // 记录初始化结果
if(u8InitStatus != fs65StatusOk) // 如果初始化失败,返回错误状态
{
return u8InitStatus;
}
return 0; // 初始化成功,返回0
}
/* 将SBC_FS65_Init函数注册为系统初始化组件 */
INIT_COMPONENT_EXPORT(SBC_FS65_Init);
这个函数用于初始化FS65芯片的寄存器和相关的硬件模块,包括GPIO接口和定时器。
它首先初始化一些数据结构,确保存储状态的结构体清零,然后通过 SBC_FS65_Hardware_Init() 完成硬件的初始化。
它还启动了两个定时器,一个用于看门狗的刷新,另一个用于定期读取FS65芯片的状态。
最后,通过 FS65_Init() 完成FS65芯片的初始化,并加载配置数据。根据初始化结果,函数会返回不同的状态值。
/*FS65看门狗刷新,建议调用周期≤5ms*/
void SBC_FS65_Wd_Refresh(void)
{
if(s_u8WdRefreshFlg)
{
(void)FS65_WD_Refresh();
s_u8WdRefreshFlg = 0;
}
}
void SbcStatusRegUpdateData(fs65_rx_data_t* pSbcStatus, RStatRegType_em emRStatRegType)
{
// 根据传入的寄存器类型(emRStatRegType)更新不同的SBC状态寄存器数据
switch (emRStatRegType)
{
// 当寄存器类型为 EM_INT_AND_TIMING 时,更新多个诊断和计时相关寄存器的数据
case EM_INT_AND_TIMING:
s_stSbcStatusReg.unSbcRegDiagVpre.u8Data = pSbcStatus[0].readData; // 更新诊断Vpre寄存器
s_stSbcStatusReg.unSbcRegDiagVcore.u8Data = pSbcStatus[1].readData; // 更新诊断Vcore寄存器
s_stSbcStatusReg.unSbcRegDiagVcca.u8Data = pSbcStatus[2].readData; // 更新诊断Vcca寄存器
s_stSbcStatusReg.unSbcRegDiagVaux.u8Data = pSbcStatus[3].readData; // 更新诊断Vaux寄存器
s_stSbcStatusReg.unSbcRegDiagVsupVcan.u8Data = pSbcStatus[4].readData; // 更新诊断Vsup和Vcan寄存器
s_stSbcStatusReg.unSbcRegDiagCanFd.u8Data = pSbcStatus[5].readData; // 更新诊断CAN FD寄存器
s_stSbcStatusReg.unSbcRegDiagCanLin.u8Data = pSbcStatus[6].readData; // 更新诊断CAN LIN寄存器
s_stSbcStatusReg.unSbcRegDiagSpi.u8Data = pSbcStatus[7].readData; // 更新诊断SPI寄存器
s_stSbcStatusReg.unSbcRegDiagSfIos.u8Data = pSbcStatus[8].readData; // 更新诊断SF I/O寄存器
s_stSbcStatusReg.unSbcRegWdCounter.u8Data = pSbcStatus[9].readData; // 更新看门狗计数器寄存器
s_stSbcStatusReg.unSbcRegDiagSfErr.u8Data = pSbcStatus[10].readData; // 更新诊断SF错误寄存器
break;
// 当寄存器类型为 EM_SHORT_TIMING 时,更新短计时相关寄存器的数据
case EM_SHORT_TIMING:
s_stSbcStatusReg.unSbcRegWuSource.u8Data = pSbcStatus[0].readData; // 更新唤醒源寄存器
s_stSbcStatusReg.unSbcRegIoInput.u8Data = pSbcStatus[1].readData; // 更新I/O输入寄存器
s_stSbcStatusReg.unSbcRegMode.u8Data = pSbcStatus[2].readData; // 更新模式寄存器
s_stSbcStatusReg.unSbcRegReleaseFsxb.u8Data = pSbcStatus[3].readData; // 更新FSXB释放寄存器
break;
// 当寄存器类型为 EM_LONG_TIMING 时,更新长计时相关寄存器的数据
case EM_LONG_TIMING:
s_stSbcStatusReg.unSbcRegInitVreg.u8Data = pSbcStatus[0].readData; // 更新初始化电压寄存器
s_stSbcStatusReg.unSbcRegHwConfig.u8Data = pSbcStatus[1].readData; // 更新硬件配置寄存器
s_stSbcStatusReg.unSbcRegDeviceId.u8Data = pSbcStatus[2].readData; // 更新设备ID寄存器
s_stSbcStatusReg.unSbcRegRegMode.u8Data = pSbcStatus[3].readData; // 更新寄存器模式寄存器
s_stSbcStatusReg.unSbcRegCanLinMode.u8Data = pSbcStatus[4].readData; // 更新CAN LIN模式寄存器
s_stSbcStatusReg.unSbcRegDeviceIdFs.u8Data = pSbcStatus[5].readData; // 更新设备ID FS寄存器
s_stSbcStatusReg.unSbcRegBist.u8Data = pSbcStatus[6].readData; // 更新内建自测试寄存器
break;
// 如果寄存器类型不匹配,默认不进行任何操作
default:
break;
}
}
这个函数根据传入的寄存器类型(emRStatRegType)来选择更新不同类型的SBC状态寄存器。
函数的输入包括一个fs65_rx_data_t类型的数组 pSbcStatus,它存储了从FS65芯片读取的数据,每个数组元素包含一个 readData 字段,用于表示从寄存器读取到的值。
根据寄存器类型的不同,会更新不同的一组寄存器,分别对应中断和计时、短计时以及长计时相关的数据。
/* 读取FS65芯片状态的函数 */
void SBC_FS65_Read_SbcStatus(void)
{
// 如果看门狗不处于刷新状态
if(!s_u8WdRefreshFlg)
{
// 如果标志位1被置位(表示500ms已经到达)
if(s_stSbcStatus.u8ReadSbcStatusFlg1)
{
/* 读取与中断和计时相关的寄存器 */
fs65_status_t status = fs65StatusOk; // 初始化状态为OK
fs65_rx_data_t stSbcStatus[FS65_STAT_NUM1]; // 定义读取状态的数组
// 通过地址映射u8StatAddrMap1读取FS65寄存器数据,返回0表示成功
if(SbcGetStatus(u8StatAddrMap1, stSbcStatus, FS65_STAT_NUM1) == 0)
{
status = fs65StatusOk; // 状态正常
SbcStatusRegUpdateData(stSbcStatus, EM_INT_AND_TIMING); // 更新寄存器数据
}
else
{
status = fs65StatusError; // 如果读取失败,状态为错误
}
s_stSbcStatus.u8ReadSbcStatusFlg1 = 0; // 复位标志位1
}
// 如果标志位2被置位(表示600ms已经到达)
else if(s_stSbcStatus.u8ReadSbcStatusFlg2)
{
/* 读取与短计时相关的寄存器 */
fs65_status_t status = fs65StatusOk; // 初始化状态为OK
fs65_rx_data_t stSbcStatus[FS65_STAT_NUM2]; // 定义读取状态的数组
// 通过地址映射u8StatAddrMap2读取FS65寄存器数据,返回0表示成功
if(SbcGetStatus(u8StatAddrMap2, stSbcStatus, FS65_STAT_NUM2) == 0)
{
status = fs65StatusOk; // 状态正常
SbcStatusRegUpdateData(stSbcStatus, EM_SHORT_TIMING); // 更新寄存器数据
}
else
{
status = fs65StatusError; // 如果读取失败,状态为错误
}
s_stSbcStatus.u8ReadSbcStatusFlg2 = 0; // 复位标志位2
}
// 如果标志位3被置位(表示1200ms已经到达)
else if(s_stSbcStatus.u8ReadSbcStatusFlg3)
{
/* 读取与长计时相关的寄存器 */
fs65_status_t status = fs65StatusOk; // 初始化状态为OK
fs65_rx_data_t stSbcStatus[FS65_STAT_NUM3]; // 定义读取状态的数组
// 通过地址映射u8StatAddrMap3读取FS65寄存器数据,返回0表示成功
if(SbcGetStatus(u8StatAddrMap3, stSbcStatus, FS65_STAT_NUM3) == 0)
{
status = fs65StatusOk; // 状态正常
SbcStatusRegUpdateData(stSbcStatus, EM_LONG_TIMING); // 更新寄存器数据
}
else
{
status = fs65StatusError; // 如果读取失败,状态为错误
}
s_stSbcStatus.u8ReadSbcStatusFlg3 = 0; // 复位标志位3
}
else
{
// 如果没有标志位被置位,则不做任何操作
}
}
}
这个函数用于定期读取FS65芯片的状态数据。它根据不同的标志位来判断是否需要读取芯片的寄存器,并执行对应的操作。
函数首先检查看门狗是否处于刷新状态,如果看门狗没有刷新,那么检查是否有标志位(u8ReadSbcStatusFlg1、u8ReadSbcStatusFlg2、u8ReadSbcStatusFlg3)被置位。
每个标志位对应不同的读取周期(500ms、600ms、1200ms),根据不同的标志位来读取芯片的不同寄存器,并调用 SbcStatusRegUpdateData() 更新寄存器数据。
如果数据读取失败,则将状态设置为 fs65StatusError,否则设置为 fs65StatusOk。
#if 0
struct dt_spi_device spidev1;
struct dt_spi_message m;
struct dt_spi_transfer t;
#endif
void SBC_FS65_Test(void)
{
// uint8_t tx_buf[2] = {0x00,0x68}, rx_buf[2];
// spi_transmit(&stSbcSpiDev, tx_buf, rx_buf, 1);
// FS65_CheckLbistAbistOk();
SBC_FS65_Wd_Refresh();
SBC_FS65_Read_SbcStatus();
}