目录
本教程使用英飞凌TLE9262芯片
SBC休眠策略
系统基础芯片(SBC,System Basis Chip),从广义上来说,是一种包含电源、通信、监控诊断、安全监控等特性以及GPIO的独立芯片。
SBC模式切换
SBC模式分为 Init Mode 、 Normal Mode 、 Sleep Mode 、 Stop Mode、Restart Mode 、 Fail-Safe Mode。下图为SBC各个模式之间的切换的流程图。
通过在寄存器M_S_CTRL中设置各自的SBC模式位,通过SPI来选择不同的SBC模式。当通过SBC重新启动模式时,SBC模式位将被清除,因此总是显示当前的SBC模式。
SBC在上电之后自动进入Init Mode,经过任意一SPI指令即可进入Normal Mode,在Normal Mode中,使用SPI指令对SBC各个模块进行初始化配置。
这里使用的是开发者模式,看门狗的配置与喂狗操作在这里先不做描述,重点讲SBC在休眠模式与正常模式之间的转换。(SBC开发模式是一组超级状态机,其中WD计时器停止,CAN/LINx在SBC初始化模式下的行为不同。否则,在行为上就没有差异了,进入SBC开发模式的方法为FO3引脚接GND)
SBC在进入Sleep Mode之前肯定是要配置唤醒源的,否则SBC将一直停留在睡眠模式,无法被唤醒了,SBC设计者在CAN模块中也提到——在进入SBC睡眠模式之前,必须设置为CAN唤醒能力/ CAN关闭模式。
除了CAN唤醒,还有三个WKx引脚作为唤醒源,这些唤醒源需在SBC的WK_CTRL_2寄存器中进行使能配置。可在WK_PUPD_CTRL选择高电平唤醒、低电平唤醒,高低都不唤醒,自动选择高低电平唤醒。
SBC唤醒源
SBC中实现以下唤醒源:
Static Sense静态感知:WK输入永久激活
Cyclic Sense循环感知:WK输入仅在周期感知期间的准时期间激活
Cyclic Wake循环唤醒:内部唤醒源通过内部定时器控制
CAN唤醒:通过CAN消息唤醒
LIN唤醒:通过LIN消息唤醒
Cyclic Sense
一般使用SBC作为控制器电源管理芯片,为了更好的控制休眠时的电流消耗,可以在进入休眠模式前对其唤醒策略进行设置。SBC也提供了循环检测唤醒源的功能,即Cyclic Sense。
循环感知功能旨在降低设备和应用程序的静止电流。在循环感知配置中,一个或多个高端驱动程序由TIMER1_CTRL和TIMER2_CTRL定期打开。各自的高侧驱动器(HSx)提供外部电路,例如开关和/或电阻阵列,它们连接到一个或多个尾流输入。在循环感知周期的准时时间期间,WKx输入信号的任何边缘变化都会导致唤醒。根据SBC模式,将INT拉低(SBC正常模式和停止模式)或唤醒SBC以启用VCC1(在SBC休眠和SBC故障安全模式之后)。
如图,HS3和HS4分别对外部开关和霍尔进行供电,当SBC配置Cyclic Sense模式之后,进入休眠模式,HS3和HS4对开关和霍尔进行轮询供电,而WK1和WK2作为开关和霍尔的唤醒信号输入检测,当检测到电平变化后,立刻唤醒SBC自动切换到正常模式。
配置循环感知的正确序列如图所示。在TIMERx_CTRL寄存器中设置准时之前,必须执行所有的配置。设置“OFF/LOW”和“OFF/HIGH”定义了在循环检测开始前各自的HS驱动器的电压水平。这种选择的目的是为了避免在循环感觉开始时由于电压电平变化而无意的觉醒。循环感知(=TimerX)将开始,一旦相应的准时被选择独立于分配的HS和过滤器配置。因此,必须在启动计时器之前,先选择相应的计时器。正确的配置顺序如下:
•配置初始级别
•映射定时器到各自的HSx输出
•配置相应的滤波器时序和WK引脚
•配置定时器周期和on-time
配置如图:
Cyclic Sense检测WK信号时序图:
SBC在进入休眠模式之后,HS在每20ms period内,polling-on 0.1ms,在polling-on的时间之内检测到电平变化,但是在Filter time中又变为低电平将被判断为杂波,被过滤。当在第n个周期检测到电平变化,在Filter time结束一直为高,则在第n+1个polling-on的时间WK电平被拉高,触发wake event,将SBC唤醒。
配置过程
实现代码
void SBC_CyclicSense(void)
{
/* Enable WK Timer 1 */
SBC_SPI_TRANSFER16(SBC_WRITE_BIT | SBC_WK_CTRL_1, 0xC0);
/* Enable Wake-up1 & Wake-up2 */
SBC_SPI_TRANSFER16(SBC_WRITE_BIT | SBC_WK_CTRL_2, 0x03);//0x03 0000 0011 1 hall 0 sw
/* config High-switch 1 High-switch 2 */
/* Shut down HS1 HS2 and change HS3 HS4 to polling mode */
SBC_SPI_TRANSFER16(SBC_WRITE_BIT | SBC_HS_CTRL_1, 0x00);
SBC_SPI_TRANSFER16(SBC_WRITE_BIT | SBC_HS_CTRL_2, 0x32);//22 4 hall 3 sw
/* config SBC_WK_FLT_CTRL WK1 & WK2 by 16us Timer1*/
SBC_SPI_TRANSFER16(SBC_WRITE_BIT | SBC_WK_FLT_CTRL, 0x0E);
/* WK1 & WK2 Pull-down for wake */
SBC_SPI_TRANSFER16(SBC_WRITE_BIT | SBC_WK_PUPD_CTRL, 0x05);
/* config Timer1 Timer2*/
SBC_SPI_TRANSFER16(SBC_WRITE_BIT | SBC_TIMER1_CTRL, 0x11); /* 0x11 20ms polling 0x12 50ms polling 0x13 100ms polling*/
SBC_SPI_TRANSFER16(SBC_WRITE_BIT | SBC_TIMER2_CTRL, 0x11);
/* config Timer1 Timer2 */
/*SBC_SPI_TRANSFER16(SBC_WRITE_BIT | SBC_TIMER1_CTRL, 0x11); // 20ms polling*/
}
void SBC_Sleep_Mode(void)
{
/* Set SWK Configuration valid */
sbc_write_reg_field(SBC_SWK_CTRL, CFG_VAL_MASK, SBC_CFG_VAL_VALID, NULL);
/* Clear SYSERR bit */
sbc_write_reg_field(SBC_BUS_STAT_1, SYSERR_MASK, 0x00, NULL);
/* Set CAN Mode to off and once again to desired configuration */
sbc_write_reg_field(SBC_BUS_CTRL_1, CAN_MASK, CAN_OFF, NULL);
/* set CAN WAKECAPABLE */
SBC_SPI_TRANSFER16(SBC_WRITE_BIT | SBC_BUS_CTRL_1, 0x21);
/* Clear Wake Status Registers, so that SBC can sleep. */
SBC_SPI_TRANSFER16(SBC_WRITE_BIT | SBC_WK_STAT_1, 0x00);
SBC_SPI_TRANSFER16(SBC_WRITE_BIT | SBC_WK_STAT_2, 0x00);
SBC_SPI_TRANSFER16(SBC_WRITE_BIT | SBC_M_S_CTRL, 0x40);
/* Select sleep mode */
// sbc_write_reg_field(SBC_M_S_CTRL, MODE_MASK, SBC_SLEEP_MODE, NULL);
}
//这里做的睡眠策略是通过CAN信号作为休眠指令:
void SBC_Sleep_Handler(void)
{
can_message_t *msg = &g_RecvMsg_CAN0;
uint8_t SBC_Cmd = 0;
SBC_Cmd = CanIf_MsgUnpack(msg->data,0,1);
if (SBC_Cmd == 1)
{
SBC_CyclicSense();
SBC_Sleep_Mode();
SBC_Cmd = 0;
}