#include "bsp_can.h"
#include "bsp_led.h"
#include "bsp_timer.h"
stc_can_rxframe_t stcRxFrame;
stc_can_txframe_t TxFrame_Gain;
stc_can_txframe_t TxFrame_Keepalive;
stc_can_t APP_CAN;
en_ACC_Status ACC_Status = Off;
extern void PWM_duty_adjust(uint16_t adc_value, uint16_t MAX_Value);
static void Can_Gpio_Init(void)
{
stc_gpio_cfg_t stcGpioCfg;
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
///< 端口方向配置->输入
stcGpioCfg.enDir = GpioDirIn;
///< 端口驱动能力配置->高驱动能力
stcGpioCfg.enDrv = GpioDrvL;
///< 端口上下拉配置->无
stcGpioCfg.enPu = GpioPuDisable;
stcGpioCfg.enPd = GpioPdDisable;
///< 端口开漏输出配置->开漏输出关闭
stcGpioCfg.enOD = GpioOdDisable;
///< 端口输入/输出值寄存器总线控制模式配置->AHB
stcGpioCfg.enCtrlMode = GpioAHB;
Gpio_Init(EVB_CAN_RX_PORT, EVB_CAN_RX_PIN, &stcGpioCfg);
stcGpioCfg.enDir = GpioDirOut;
Gpio_Init(EVB_CAN_TX_PORT, EVB_CAN_TX_PIN, &stcGpioCfg);
Gpio_Init(EVB_CAN_STB_PORT, EVB_CAN_STB_PIN, &stcGpioCfg);
///<CAN RX\TX复用功能配置
Gpio_SetAfMode(EVB_CAN_RX_PORT, EVB_CAN_RX_PIN, GpioAf3);
Gpio_SetAfMode(EVB_CAN_TX_PORT, EVB_CAN_TX_PIN, GpioAf5);
///<STB 低-PHY有效
Gpio_ClrIO(EVB_CAN_STB_PORT, EVB_CAN_STB_PIN);
}
#ifdef CAN_CHIP_TJA1043
/*
TJA1043 刚上电是出于激活状态的,如果CAN总线没有数据,30s左右会休眠
3个IO需要配置:
IO_ERR 检测总线出错标志(可以忽略)
IO_EN 芯片使能
IO_INH 使能外部LDO +5V
IO_STB_N standby模式使能
*/
static void TJA1043_Gpio_Init(void)
{
stc_gpio_cfg_t stcGpioCfg;
Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);
///< 端口方向配置->输出
stcGpioCfg.enDir = GpioDirOut;
///< 端口驱动能力配置->高驱动能力
stcGpioCfg.enDrv = GpioDrvH;
///< 端口上下拉配置->无
stcGpioCfg.enPu = GpioPuDisable;
stcGpioCfg.enPd = GpioPdDisable;
///< 端口开漏输出配置->开漏输出关闭
stcGpioCfg.enOD = GpioOdDisable;
///< 端口输入/输出值寄存器总线控制模式配置->AHB
stcGpioCfg.enCtrlMode = GpioAHB;
Gpio_Init(GpioPortA, GpioPin3, &stcGpioCfg); // STB_N
Gpio_Init(GpioPortB, GpioPin3, &stcGpioCfg); //IO_INH
Gpio_Init(GpioPortB, GpioPin7, &stcGpioCfg); // IO_EN
Gpio_ClrIO(GpioPortB, GpioPin3); /* PB3 IO_INH*/
delay1ms(10);
Gpio_SetIO(EVB_CAN_STB_PORT, EVB_CAN_STB_PIN);
Gpio_SetIO(GpioPortB, GpioPin7);// IO_EN
}
void TJA1043_Goto_Sleep(void)
{
Gpio_ClrIO(EVB_CAN_STB_PORT, EVB_CAN_STB_PIN);
Gpio_SetIO(GpioPortB, GpioPin7);// IO_EN
}
#endif
void BSP_Can_Init(void)
{
stc_can_init_config_t stcCanInitCfg;
stc_can_filter_t stcFilter;
Can_Gpio_Init();
#ifdef CAN_CHIP_TJA1043
TJA1043_Gpio_Init();
#endif
Sysctrl_SetPeripheralGate(SysctrlPeripheralCan, TRUE);
//<<CAN 波特率配置
// 手册page884.exp: bt = (PRESC+1)((SEG_1+2) + (SEG_2+1))*(1/8M) = 1us (1000k)
#ifdef CAN_CONFIG_48MHZ_500K
stcCanInitCfg.stcCanBt.PRESC = 6-1;
stcCanInitCfg.stcCanBt.SEG_1 = 9-2;
stcCanInitCfg.stcCanBt.SEG_2 = 7-1;
stcCanInitCfg.stcCanBt.SJW = 3-1;
// stcCanInitCfg.stcCanBt.PRESC = 8-1;
// stcCanInitCfg.stcCanBt.SEG_1 = 7-2;
// stcCanInitCfg.stcCanBt.SEG_2 = 5-1;
// stcCanInitCfg.stcCanBt.SJW = 5-1;
#endif
stcCanInitCfg.stcWarningLimit.CanErrorWarningLimitVal = 10;
stcCanInitCfg.stcWarningLimit.CanWarningLimitVal = 16-1;
stcCanInitCfg.enCanRxBufAll = CanRxNormal;
stcCanInitCfg.enCanRxBufMode = CanRxBufNotStored;
stcCanInitCfg.enCanSTBMode = CanSTBFifoMode;
CAN_Init(&stcCanInitCfg);
//<<CAN 滤波器配置 /*u32MASK = 0x1FFFFFFF is all received*/
stcFilter.enAcfFormat = CanStdFrames;
stcFilter.enFilterSel = CanFilterSel1;
stcFilter.u32CODE = CAN_ID_BACKLIGHT;
stcFilter.u32MASK = 0x1FFFFFFF& (~CAN_ID_BACKLIGHT);
CAN_FilterConfig(&stcFilter, TRUE);
stcFilter.enFilterSel = CanFilterSel2;
stcFilter.u32CODE = CAN_ID_ACC;
stcFilter.u32MASK = 0x1FFFFFFF& (~CAN_ID_ACC);
CAN_FilterConfig(&stcFilter, TRUE);
stcFilter.enFilterSel = CanFilterSel3;
stcFilter.u32CODE = CAN_ID_BRAKE_X;
stcFilter.u32MASK = 0x1FFFFFFF& (~CAN_ID_BRAKE_X);
CAN_FilterConfig(&stcFilter, TRUE);
stcFilter.enFilterSel = CanFilterSel4;
stcFilter.u32CODE = CAN_ID_BRAKE_SIGNAL;
stcFilter.u32MASK = 0x1FFFFFFF& (~CAN_ID_BRAKE_SIGNAL);
CAN_FilterConfig(&stcFilter, TRUE);
CAN_IrqCmd(CanRxIrqEn, TRUE); /* 接收中断使能 */
CAN_IrqCmd(CanBusErrorIrqEn, TRUE); /*总线错误中断使能*/
EnableNvic(CAN_IRQn, IrqLevel0, TRUE);
}
/********************************************************************************************************
**函数信息 :void CAN_send_Frame()
**功能描述 :CAN发送一帧报文
**输入参数 :stcTxFrame
**输出参数 :None
** 备注 目前只考虑标准帧
********************************************************************************************************/
void CAN_send_Frame(stc_can_txframe_t *TxFrame, uint8_t frame_len)
{
TxFrame->Control_f.DLC = frame_len;
TxFrame->Control_f.IDE = 0; /*标准帧 or 扩展帧*/
TxFrame->Control_f.RTR = 0; /*数据帧 or 远程帧*/
TxFrame->enBufferSel = (en_can_buffer_sel_t)0U; /*使用主缓冲器*/
CAN_SetFrame(TxFrame); /*数据塞进fifo缓冲器*/
CAN_TransmitCmd(CanPTBTxCmd);
}
void Can_IRQHandler(void)
{
if(TRUE == CAN_Irq**Get(CanBusErrorIrq**)) /*当总线短路时,进入此中断*/
{
CAN_Irq**Clr(CanBusErrorIrq**);
APP_CAN.BusErrorFlag = TRUE;
// M0P_CAN->CFG_STAT = 0x00; /* 清除由硬件置位的Reset 标志位,必须在中断外部执行*/
}
if(TRUE == CAN_Irq**Get(CanRxIrq**))
{
CAN_Irq**Clr(CanRxIrq**);
CAN_Receive(&stcRxFrame);
APP_CAN.RxFlag = TRUE;
APP_CAN.Rx_cnt = 0;
/*总线上发送周期约500ms*/
if( CAN_ID_BACKLIGHT == stcRxFrame.StdID )
{
if(stcRxFrame.Data[0] & 0x04)
{
LED_ON;
}
else
{
LED_OFF;
}
}
/*
XX 00 00 20 52 FF FB 00
XX:02 (ON) 00(OFF)
*/
if (CAN_ID_ACC == stcRxFrame.StdID)
{
if(stcRxFrame.Data[0]&0x02)
{
ACC_Status = On;
}
else
{
ACC_Status = Off; /* ACC off 后延时30s进入休眠*/
}
}
if (CAN_ID_BRAKE_X == stcRxFrame.StdID)
{
APP_CAN.brake_value = (stcRxFrame.Data[0]<<8) + stcRxFrame.Data[1];
APP_CAN.RxFlag_Break = TRUE;
}
if (CAN_ID_BRAKE_SIGNAL == stcRxFrame.StdID)
{
if( stcRxFrame.Data[2]&0x80)
{
APP_CAN.brake_signal = TRUE;
}
else
{
APP_CAN.brake_signal = FALSE;
}
}
}
}
void CAN_BUS_Process(void)
{
//if(ACC_Status == On) // AccOff 状态也需要发送数据
{
if(APP_CAN.CANSendFlag) /*100ms*/
{
APP_CAN.CANSendFlag = FALSE;
CAN_send_Frame(&TxFrame_Gain, 8);
}
if(APP_CAN.CAN_keepalive_SendFlag) /*心跳包数据,1s发送一次*/
{
APP_CAN.CAN_keepalive_SendFlag = FALSE;
CAN_send_Frame(&TxFrame_Keepalive, 8);
}
}
if(APP_CAN.BusErrorFlag)
{
APP_CAN.BusErrorFlag = FALSE;
M0P_CAN->CFG_STAT = 0x00;
}
}