内容介绍
内容介绍
1 板卡介绍
本次funpack活动给我们带来的是来自Infineon的AURIX TC275 lite评估板。他是一款家庭微控制器产品,具备丰富的外设,方便我们的开发和配置,包括:
- Arduino 连接器
- Arduino ICSP 连接器
- 稳压器 5V 至 3.3V
- 可选 0 欧姆电阻器(1210 英制中的 R39_opt/R40_opt)
- Arduino 连接器(数字)
- 用于 AURIX™ TM的 20 MHz 晶振和用于 OCDS 的 12 MHz 晶振
- 用于 WIFI/BLE 的 Mikrobus 连接器
- 英飞凌 CAN 收发器 TLE9251VSJ 和 CAN 连接器
- 针连接器 X2
- 电源指示灯 (D5)
- LED D1/D2 用于 ADBUS7/4 和 LED3 用于 ESR0 信号(低电平有效)
- Arduino 针连接器(电源和模拟输入)
- 电位器 (10 kOhm) 和可焊接的 0 Ohm 电阻器(0805 英制中的 R33)
- 微型 USB(推荐 USB3.0)
- 10 针 DAP 连接器
- 复位按钮
- 2 x Shield2GO 连接器,用于 Infineon Maker Shields
- EEPROM 1Kbit
2 任务介绍
本次我选择的是任务一:使用TC275的三个核心,轮流休眠待机,分别控制板卡上的LED灯,如core0检测按键按下,唤醒core1翻转LED1,一秒后,唤醒core2翻转LED2,系统休眠
需实现的功能如下:
- 只有core0启动,并控制LED1以0.1s的频率闪烁
- 监听到按键按下后,core0休眠,core1启动翻转LED1
- 一秒后,core1休眠,core2启动翻转LED2
- 唤醒core2翻转LED2,系统休眠
3 任务分析
- 使用GPIO口的输入模式,监测按键的输入,读取用户输入
- 使用GPIO口的输出模式,控制GPIO口输出低电平时,LED被点亮
- 使用IfxCpu_setCoreMode方法,设置指定的CPU核心为休眠、运行模式
- 使用寄存器配置设置整个系统进入睡眠模式
4 代码思路
代码主要参考了TC257休眠的样例,进行修改。在SCU_Power_Down_Idle.c中定义GPIO, CPU休眠,CPU睡眠,定时器等方法。最后在Cpu0_Main.c,Cpu1_Main.c,Cpu2_Main.c中进行调用,进行编排即可。
5 代码实现
这里是SCU_Power_Down_Idle.c,设置了主要的功能,包括设置各个CPU进入休眠模式的方法,设置各个CPU运行的方法,设置系统进入睡眠模式的方法,GPIO初始化的方法以及设置读取和设置GPIO的方法。
#define ISR_PRIORITY_2 2
/* Defines CPU that triggers the interrupt */
#define ISR_PROVIDER_CPU0 0
/* Defines CPU that triggers the interrupt */
#define ISR_PROVIDER_CPU2 2
/* Rate 0.5 Hz */
#define RATE_0_5_HZ 0.25
/* Rate 1 Hz */
#define RATE_1_HZ 0.5
/* LED */
#define LED1 &MODULE_P00,5
#define LED2 &MODULE_P00,6
#define BUTTON &MODULE_P00,7 /* Port pin for the button */
#define ALLOW_SLEEP_MODE 0x0 /* Allow sleep mode for GTM */
#define BLOCK_SLEEP_MODE 0x1 /* Block sleep mode for STM */
#define PMSWCR1_CPUSEL 0x1 /* Set the CPU0 as CPU master */
#define PMCSR0_REQSLP 0x2 /* Request sleep mode */
/*********************************************************************************************************************/
/*----------------------------------------------Function Implementations---------------------------------------------*/
/*********************************************************************************************************************/
/* Maps the Interrupt Service Routine with the CPU and Priority */
IFX_INTERRUPT(systemTimerIsrCmp0, ISR_PROVIDER_CPU2, ISR_PRIORITY_2);
/* Interrupt Service Routine to switch the CPU0 between idle and run mode */
void systemTimerIsrCmp0(void)
{
IfxCpu_setCoreMode(&MODULE_CPU2, IfxCpu_CoreMode_idle); /* Set CPU2 in IDLE mode */
// static boolean setIdle = TRUE; /* Alternating between Idle and non-Idle */
// IfxCpu_enableInterrupts(); /* Enabling interrupts as ISR disables it */
// IfxStm_Timer_acknowledgeTimerIrq(&g_myTimer); /* IR acknowledge and set new compare value */
// if(setIdle == TRUE)
// {
// IfxCpu_setCoreMode(&MODULE_CPU2, IfxCpu_CoreMode_idle); /* Set CPU2 in IDLE mode */
// setIdle = FALSE;
// }
// else
// {
// setIdle = FALSE;
// }
}
/* Defines the routine to initialize and start the system timer */
void configSystemTimer(void)
{
IfxStm_Timer_Config timerConfig;
IfxStm_Timer_initConfig(&timerConfig, &MODULE_STM0); /* Setup timerConfig with default values */
timerConfig.base.frequency = RATE_0_5_HZ; /* Interrupt rate 0.5 Hz or every 2s */
timerConfig.base.isrPriority = ISR_PRIORITY_2; /* Interrupt priority */
timerConfig.base.isrProvider = (IfxSrc_Tos)ISR_PROVIDER_CPU2; /* CPU0 to trigger the interrupt */
timerConfig.comparator = IfxStm_Comparator_0; /* Comparator 0 register is used */
IfxStm_Timer_init(&g_myTimer, &timerConfig); /* Use timerConfig to initialize the STM */
IfxStm_Timer_run(&g_myTimer); /* Run STM and set Compare Value */
}
/* Initialize the LED port pin */
void configLED(void)
{
/* Set Port Pin 00.5 to output mode and turn off the LED (LED is low-level active) */
IfxPort_setPinModeOutput(LED1, IfxPort_OutputMode_pushPull, IfxPort_OutputIdx_general);
IfxPort_setPinHigh(LED1);
}
/* Toggle the LED port pin state */
void toggleLED(void)
{
IfxPort_togglePin(LED1); /* Toggle Port Pin 00.5 */
}
void configLED2(void)
{
/* Set Port Pin 00.5 to output mode and turn off the LED (LED is low-level active) */
IfxPort_setPinModeOutput(LED2, IfxPort_OutputMode_pushPull, IfxPort_OutputIdx_general);
IfxPort_setPinHigh(LED2);
IfxPort_setPinMode(BUTTON, IfxPort_Mode_inputPullUp);
}
/* Toggle the LED port pin state */
void toggleLED2(void)
{
IfxPort_togglePin(LED2); /* Toggle Port Pin 00.5 */
}
#define WAIT_TIME 50
static boolean setIdle = TRUE; /* Alternating between Idle and non-Idle */
int if_key_is_pushed(void)
{
/* With the routine getPinState() the value of a particular pin can be retrieved. This
* function can be used to retrieve any port state by just specifying the port number
* as illustrated.
*/
if(IfxPort_getPinState(BUTTON) == 0)
{
/* With the routine setPinState() the state of the port can be set to drive either
* LOW or HIGH. This function can be used to retrieve any port state by just
* specifying the port number as illustrated.
*/
waitTime(IfxStm_getTicksFromMilliseconds(BSP_DEFAULT_TIMER, WAIT_TIME));
if (IfxPort_getPinState(BUTTON) == 0){
IfxCpu_enableInterrupts(); /* Enabling interrupts as ISR disables it */
// IfxStm_Timer_acknowledgeTimerIrq(&g_myTimer); /* IR acknowledge and set new compare value */
// if(setIdle == TRUE)
// {
// IfxCpu_setCoreMode(&MODULE_CPU0, IfxCpu_CoreMode_idle); /* Set CPU0 in IDLE mode */
// setIdle = FALSE;
// }
// else
// {
// IfxCpu_setCoreMode(&MODULE_CPU0, IfxCpu_CoreMode_run); /* Set CPU0 in IDLE mode */
// setIdle = TRUE;
// }
while (1) {
if (IfxPort_getPinState(BUTTON) != 0) {
return 1;
}
}
}
}
return 0;
}
设置CPU休眠,睡眠相关代码
void set_c1_c2_idle(void)
{
/*
* 设置cpu1, cpu2为idle.
*/
IfxCpu_enableInterrupts();
IfxCpu_setCoreMode(&MODULE_CPU1, IfxCpu_CoreMode_idle);
IfxCpu_setCoreMode(&MODULE_CPU2, IfxCpu_CoreMode_idle);
}
void set_c0_idle(void)
{
/*
* 设置cpu0为idle.
*/
IfxCpu_enableInterrupts();
IfxCpu_setCoreMode(&MODULE_CPU0, IfxCpu_CoreMode_idle);
}
void set_c0_run(void)
{
/*
* 设置cpu0为run.
*/
IfxCpu_enableInterrupts();
IfxCpu_setCoreMode(&MODULE_CPU0, IfxCpu_CoreMode_run);
}
void set_c1_idle(void)
{
/*
* 设置cpu1为idle.
*/
IfxCpu_enableInterrupts();
IfxCpu_setCoreMode(&MODULE_CPU1, IfxCpu_CoreMode_idle);
}
void set_c1_run(void)
{
/*
* 设置cpu1为run.
*/
IfxCpu_enableInterrupts();
IfxCpu_setCoreMode(&MODULE_CPU1, IfxCpu_CoreMode_run);
set_c0_idle();
}
void set_c2_idle(void)
{
/*
* 设置cpu2为idle.
*/
IfxCpu_enableInterrupts();
IfxCpu_setCoreMode(&MODULE_CPU2, IfxCpu_CoreMode_idle);
}
void set_c2_run(void)
{
/*
* 设置cpu1为run.
*/
// set_c0_idle();
IfxCpu_enableInterrupts();
IfxCpu_setCoreMode(&MODULE_CPU2, IfxCpu_CoreMode_run);
set_c1_idle();
}
#define ISR_PRIORITY_STM 20
IFX_INTERRUPT(stmIsr, 0, ISR_PRIORITY_STM);
IfxGtm_Tom_Timer g_gtmTimer; /* TOM driver handle */
IfxStm_Timer g_stmTimer; /* STM driver handle */
float32 g_stmPeriod = 0.1; /* Period in seconds at which power modes toggle */
uint8 g_sleep = 0; /* Variable used to monitor the current set mode (sleep/run mode) */
#define ISR_PRIORITY_TOM 10 /* TOM Interrupt priority */
#define TOM_FREQ 25.0f /* TOM frequency */
#define LED &MODULE_P00, 5 /* LED which is toggled in Interrupt Service Routine (ISR) */
void set_sleep(void) {
if(g_sleep == 0)
{
/* Next interrupt --> run mode */
g_sleep = 1;
/* Clear safety EndInit protection */
IfxScuWdt_clearSafetyEndinitInline(IfxScuWdt_getSafetyWatchdogPasswordInline());
/* Clear EndInit protection */
IfxScuWdt_clearCpuEndinit(IfxScuWdt_getCpuWatchdogPassword());
GTM_CLC.B.EDIS = ALLOW_SLEEP_MODE; /* Allow GTM to go into sleep mode */
STM0_CLC.B.EDIS = BLOCK_SLEEP_MODE; /* Prohibit STM to go into sleep mode */
SCU_PMSWCR1.B.CPUSEL = PMSWCR1_CPUSEL; /* Set the CPU0 as CPU master to trigger a power down mode */
SCU_PMCSR0.B.REQSLP = PMCSR0_REQSLP; /* Request System Sleep Mode CPU0 */
/* Set safety EndInit protection */
IfxScuWdt_setSafetyEndinitInline(IfxScuWdt_getSafetyWatchdogPasswordInline());
/* Set EndInit protection */
IfxScuWdt_setCpuEndinit(IfxScuWdt_getCpuWatchdogPassword());
}
else
{
/* Next interrupt --> sleep mode */
g_sleep = 1;
}
}
void initStm(void)
{
IfxStm_Timer_Config timerConfig; /* Timer configuration structure */
IfxStm_Timer_initConfig(&timerConfig, &MODULE_STM0); /* Initialize it with default values */
timerConfig.base.frequency = 1 / g_stmPeriod; /* Interrupt rate every STM_PERIOD seconds */
timerConfig.base.isrPriority = ISR_PRIORITY_STM; /* Interrupt priority */
timerConfig.base.isrProvider = IfxSrc_Tos_cpu2; /* CPU0 to trigger the interrupt */
timerConfig.comparator = IfxStm_Comparator_0; /* Comparator 0 register is used */
IfxStm_Timer_init(&g_stmTimer, &timerConfig); /* Use timerConfig to initialize the STM */
IfxStm_Timer_run(&g_stmTimer); /* Run the STM and set the compare Value */
}
void initTom(void)
{
IfxGtm_enable(&MODULE_GTM); /* Enable the GTM */
IfxGtm_Tom_Timer_Config timerConfig; /* Timer configuration structure */
IfxGtm_Tom_Timer_initConfig(&timerConfig, &MODULE_GTM); /* Initialize the timer configuration */
timerConfig.base.frequency = TOM_FREQ; /* Set the timer frequency */
timerConfig.base.isrPriority = ISR_PRIORITY_TOM; /* Set the interrupt priority */
timerConfig.base.isrProvider = IfxSrc_Tos_cpu0; /* Set the interrupt provider */
timerConfig.tom = IfxGtm_Tom_1; /* Define the used timer */
timerConfig.timerChannel = IfxGtm_Tom_Ch_0; /* Define the used channel */
timerConfig.clock = IfxGtm_Tom_Ch_ClkSrc_cmuFxclk3; /* Define the used CMU clock */
IfxGtm_Cmu_enableClocks(&MODULE_GTM, IFXGTM_CMU_CLKEN_FXCLK); /* Enable the CMU clock */
IfxGtm_Tom_Timer_init(&g_gtmTimer, &timerConfig); /* Initialize the TOM */
IfxPort_setPinModeOutput(LED, IfxPort_OutputMode_pushPull, IfxPort_OutputIdx_general); /* Set port pin mode */
IfxGtm_Tom_Timer_run(&g_gtmTimer); /* Start the TOM */
}
6 运行状态
下面是运行时的状态
上电时:
第一次按下按键:
按键按下一秒后休眠:
7 心得体会
这是我第一次通过英飞凌的评估套件进行开发,不同于以往的通过Keil进行开发。英飞凌强大的生态大大得简化了开发步骤,让我省去了板卡适配环节。同时英飞凌提供了完善的开发样例,让我们了更加清楚地了解到各个外设如何调用。
十分感谢硬禾,能够提供机会让我们接触到如此优秀的板卡,也希望Funpack能继续办下去,让广大爱好者既能学到东西,又能接触到优秀的硬件。
附件下载
TC275多核编程.zip
团队介绍
caiyi
评论
0 / 100
查看更多