Hello NXP team,
i want to use magic packet to wakeup my rt1064board, then i follow the IMXRT1064RM.pdf
1. set the ECR[MAGICEN] and ECR[SLEEP] BIT, the mac enter the sleep mode.
2.Then i use udp send a magic packet to the imxrt1064 board. Before first step,the board can recieve the magic packet,but after the first step the EIR[WAKUP] can not set.
Here is the code,
int macsleep111(void)
{
// ENET_EnableSleepMode(ENET,1);
ENET->ECR |= (1 <<2 );
ENET->ECR |= (1 <<3 );
DisableIRQ(ENET_IRQn);
ENET_EnableInterrupts(ENET,ENET_ERR_INTERRUPT|kENET_WakeupInterrupt );
NVIC_ClearPendingIRQ(ENET_IRQn);
NVIC_EnableIRQ(ENET_IRQn);
EnableIRQ(ENET_IRQn);
LPM_EnableWakeupSource(ENET_IRQn);
return 0;
}
MSH_CMD_EXPORT(macsleep111, wakeup_demo );
Hello @zrx,
I did try also this feature without success. I will investigate this issue and let you know as soon as I made some progress.
Best Regards,
Alexis Andalon
here you should add the kENET_WakeupInterrupt interrupt
#define ENET_ERR_INTERRUPT \
(kENET_BabrInterrupt | kENET_BabtInterrupt | kENET_EBusERInterrupt | kENET_LateCollisionInterrupt | \
kENET_RetryLimitInterrupt | kENET_UnderrunInterrupt | kENET_PayloadRxInterrupt |kENET_WakeupInterrupt)
so enet can set error handler when init the enet intterupt
here is the code:
static void ENET_SetHandler(ENET_Type *base,
enet_handle_t *handle,
const enet_config_t *config,
const enet_buffer_config_t *bufferConfig)
{
uint8_t count;
uint32_t instance = ENET_GetInstance(base);
const enet_buffer_config_t *buffCfg = bufferConfig;
/* Store transfer parameters in handle pointer. */
memset(handle, 0, sizeof(enet_handle_t));
handle->ringNum = (config->ringNum > FSL_FEATURE_ENET_QUEUE) ? FSL_FEATURE_ENET_QUEUE : config->ringNum;
for (count = 0; count < handle->ringNum; count++)
{
assert(buffCfg->rxBuffSizeAlign * buffCfg->rxBdNumber > config->rxMaxFrameLen);
handle->rxBdBase[count] = buffCfg->rxBdStartAddrAlign;
handle->rxBdCurrent[count] = buffCfg->rxBdStartAddrAlign;
handle->rxBuffSizeAlign[count] = buffCfg->rxBuffSizeAlign;
handle->txBdBase[count] = buffCfg->txBdStartAddrAlign;
handle->txBdCurrent[count] = buffCfg->txBdStartAddrAlign;
handle->txBuffSizeAlign[count] = buffCfg->txBuffSizeAlign;
buffCfg++;
}
/* Save the handle pointer in the global variables. */
s_ENETHandle[instance] = handle;
/* Set the IRQ handler when the interrupt is enabled. */
if (config->interrupt & ENET_TX_INTERRUPT)
{
s_enetTxIsr = ENET_TransmitIRQHandler;
EnableIRQ(s_enetTxIrqId[instance]);
}
if (config->interrupt & ENET_RX_INTERRUPT)
{
s_enetRxIsr = ENET_ReceiveIRQHandler;
EnableIRQ(s_enetRxIrqId[instance]);
}
if (config->interrupt & ENET_ERR_INTERRUPT)
{
s_enetErrIsr = ENET_ErrorIRQHandler;
EnableIRQ(s_enetErrIrqId[instance]);
}
}
then the EIR[WAKEUP] can be set by magic packet,but can not wakeup by magic packet.
here is the code:
int enetwakeup(void)
{
uint32_t freq;
int i = 0;
/* When wakeup from suspend, peripheral's doze & stop requests won't be cleared, need to clear them manually */
IOMUXC_GPR->GPR4 = 0x00000000;
IOMUXC_GPR->GPR7 = 0x00000000;
IOMUXC_GPR->GPR8 = 0x00000000;
IOMUXC_GPR->GPR12 = 0x00000000;
CLOCK_SetMux(kCLOCK_UartMux, 1);
CLOCK_SetDiv(kCLOCK_UartDiv, 0);
BOARD_InitBootPeripherals();
DEBUG_MSG("\r\nCPU wakeup source 0x%x...\r\n", SRC->SRSR);
APP_PrintRunFrequency(0);
LPM_Init();
APP_PowerModeSwitch(s_curRunMode);
ENET_EnableSleepMode(ENET,1);
while (1)
{
freq = CLOCK_GetFreq(kCLOCK_CpuClk);
DEBUG_MSG("\r\n########## Power Mode Switch Demo %d times(build %s) ########### \n\r\n", i++,__DATE__);
DEBUG_MSG(" Core Clock = %dHz \r\n", freq);
APP_ShowPowerMode(s_curRunMode);
s_targetPowerMode = LPM_PowerModeSysIdle;
if (s_targetPowerMode <= LPM_PowerModeEnd)
{
/* If could not set the target power mode, loop continue. */
if (!APP_CheckPowerMode(s_curRunMode, s_targetPowerMode))
{
continue;
}
DisableIRQ(ENET_IRQn);
ENET_EnableSleepMode(ENET,1);
NVIC_ClearPendingIRQ(ENET_IRQn); //唤醒源的设置
ENET_EnableInterrupts(ENET,kENET_WakeupInterrupt ); //使能错误中断 唤醒中断
NVIC_EnableIRQ(ENET_IRQn);
EnableIRQ(ENET_IRQn);
LPM_EnableWakeupSource(ENET_IRQn); //使能唤醒源
ENET->ECR |= 0X02; //使能网卡
APP_PowerPreSwitchHook(s_targetPowerMode);
APP_PowerModeSwitch(s_targetPowerMode);
APP_PowerPostSwitchHook(s_targetPowerMode);
// ENET_EnableSleepMode(ENET,0);// MAC退出休眠
}
DEBUG_MSG("\r\nNext loop\r\n");
}
}
so please let me know when you make some progress. thank you.
about this enet intterupt ,you you should add kENET_WakeupInterrupt here
#define ENET_ERR_INTERRUPT \
(kENET_BabrInterrupt | kENET_BabtInterrupt | kENET_EBusERInterrupt | kENET_LateCollisionInterrupt | \
kENET_RetryLimitInterrupt | kENET_UnderrunInterrupt | kENET_PayloadRxInterrupt |kENET_WakeupInterrupt)
so when you config the kENET_WakeupInterrup interrupt ,the enet can set error hanlder here,
static void ENET_SetHandler(ENET_Type *base, enet_handle_t *handle, const enet_config_t *config,
const enet_buffer_config_t *bufferConfig)
{
uint8_t count;
uint32_t instance = ENET_GetInstance(base);
const enet_buffer_config_t *buffCfg = bufferConfig;
/* Store transfer parameters in handle pointer. */
memset(handle, 0, sizeof(enet_handle_t));
handle->ringNum = (config->ringNum > FSL_FEATURE_ENET_QUEUE) ? FSL_FEATURE_ENET_QUEUE : config->ringNum;
for (count = 0; count < handle->ringNum; count++)
{
assert(buffCfg->rxBuffSizeAlign * buffCfg->rxBdNumber > config->rxMaxFrameLen);
handle->rxBdBase[count] = buffCfg->rxBdStartAddrAlign;
handle->rxBdCurrent[count] = buffCfg->rxBdStartAddrAlign;
handle->rxBuffSizeAlign[count] = buffCfg->rxBuffSizeAlign;
handle->txBdBase[count] = buffCfg->txBdStartAddrAlign;
handle->txBdCurrent[count] = buffCfg->txBdStartAddrAlign;
handle->txBuffSizeAlign[count] = buffCfg->txBuffSizeAlign;
buffCfg++;
}
/* Save the handle pointer in the global variables. */
s_ENETHandle[instance] = handle;
/* Set the IRQ handler when the interrupt is enabled. */
if (config->interrupt & ENET_TX_INTERRUPT)
{
s_enetTxIsr = ENET_TransmitIRQHandler;
EnableIRQ(s_enetTxIrqId[instance]);
}
if (config->interrupt & ENET_RX_INTERRUPT)
{
s_enetRxIsr = ENET_ReceiveIRQHandler;
EnableIRQ(s_enetRxIrqId[instance]);
}
if (config->interrupt & ENET_ERR_INTERRUPT)
{
s_enetErrIsr = ENET_ErrorIRQHandler;
EnableIRQ(s_enetErrIrqId[instance]);
}
}
then the EIR[WAKEUP] can set by magic packet, but i can not wakeup by it in my rt1064 board.
here is my code,
int enetwakeup(void)
{
uint32_t freq;
int i = 0;
/* When wakeup from suspend, peripheral's doze & stop requests won't be cleared, need to clear them manually */
IOMUXC_GPR->GPR4 = 0x00000000;
IOMUXC_GPR->GPR7 = 0x00000000;
IOMUXC_GPR->GPR8 = 0x00000000;
IOMUXC_GPR->GPR12 = 0x00000000;
CLOCK_SetMux(kCLOCK_UartMux, 1);
CLOCK_SetDiv(kCLOCK_UartDiv, 0);
BOARD_InitBootPeripherals();
DEBUG_MSG("\r\nCPU wakeup source 0x%x...\r\n", SRC->SRSR);
APP_PrintRunFrequency(0);
LPM_Init();
ENET_EnableSleepMode(ENET,1);
while (1)
{
freq = CLOCK_GetFreq(kCLOCK_CpuClk);
DEBUG_MSG("\r\n########## Power Mode Switch Demo %d times(build %s) ########### \n\r\n", i++,__DATE__);
DEBUG_MSG(" Core Clock = %dHz \r\n", freq);
APP_ShowPowerMode(s_curRunMode);
s_targetPowerMode = LPM_PowerModeSysIdle;
if (s_targetPowerMode <= LPM_PowerModeEnd)
{
/* If could not set the target power mode, loop continue. */
if (!APP_CheckPowerMode(s_curRunMode, s_targetPowerMode))
{
continue;
}
DisableIRQ(ENET_IRQn);
ENET_EnableSleepMode(ENET,1);
NVIC_ClearPendingIRQ(ENET_IRQn);
ENET_EnableInterrupts(ENET,kENET_WakeupInterrupt );
NVIC_EnableIRQ(ENET_IRQn);
EnableIRQ(ENET_IRQn);
LPM_EnableWakeupSource(ENET_IRQn);
ENET->ECR |= 0X02;
APP_PowerPreSwitchHook(s_targetPowerMode);
APP_PowerModeSwitch(s_targetPowerMode);
APP_PowerPostSwitchHook(s_targetPowerMode);
// ENET_EnableSleepMode(ENET,0);/
}
DEBUG_MSG("\r\nNext loop\r\n");
}
}
MSH_CMD_EXPORT(enetwakeup, wakeup_demo );
so please let me know as soon as you made some progress,thank you.