串口唤醒功能主要是从supernova 待机进入PM后,串口接收PC端口发送过来的特定字串,然后将主板唤醒,与IR、KEYPAD、WOL、CEC、MHL 等等基本流程一致,触发源不一样而已。
1.待机前设置待机参数
vendormstarkernellinaromstar2drvpmmdrv_pm.c
pstPMCfg->stPMWakeCfg.bPmWakeEnableIR = TRUE; pstPMCfg->stPMWakeCfg.bPmWakeEnableSAR = TRUE; pstPMCfg->stPMWakeCfg.bPmWakeEnableGPIO0 = FALSE; pstPMCfg->stPMWakeCfg.bPmWakeEnableGPIO1 = FALSE; pstPMCfg->stPMWakeCfg.bPmWakeEnableUART1 = TRUE;
bPmWakeEnableUART1 设置为TRUE,开启该口的唤醒功能,然后EnterSleepMode里面设置到PM里面
vendormstarsupernovaprojectsmsrvcontrolsrcMSrv_Control_common.cpp
mapi_interface::Get_mapi_system()->PowerDown(&stPMCfg,bTrigger);
2.PM 开启相关参数
(1)开启PM_WK_UART_EN
vendormstarpmzenoniaProjectMstarSourceConfigurationscusProj_config.h //-----Uart Wakeup--- #ifndef PM_WK_UART_EN #define PM_WK_UART_EN 1 #endif
(2)开启串口,设置串口波特率为19200(平台目前不支持115200)
vendormstarpmzenoniaProjectMstarSourceConfigurationscusProj_config.h vendormstarpmzenoniaProjectSourcecus_config.h
#define UART1_BAUDRATE 19200//38400//9600//38400 #define ENABLE_UART0 ENABLE
(3)设置UART口的寄存器CLK
Cus_Sys_ChangeUartForPllClk 里面设置串口clk,配置好S1CON,PCON 否则后面无法获取到唤醒的字串。
vendormstarpmzenoniaProjectSourcecustomer.c
void Cus_Sys_ChangeUartForPllClk(U32 u32Mcu_Clk) { // Change MCU clock --> Change UART baud rate #if ENABLE_UART0 ADCON |= 0x80; S0RELL = (UART_CLKREL(u32Mcu_Clk, UART0_BAUDRATE) & 0xff); S0RELH = ((UART_CLKREL(u32Mcu_Clk, UART0_BAUDRATE) >> 8) & 0x3); S0CON = 0x50; PCON |= 0x80; //S0BUF = (char)"*"; TI0=1; #endif #if ENABLE_UART1 S1RELL = (UART1_CLKREL(u32Mcu_Clk, UART1_BAUDRATE) & 0xff); S1RELH = ((UART1_CLKREL(u32Mcu_Clk, UART1_BAUDRATE) >> 8) & 0x3); S1CON = 0x90; // mode 1, 8-bit UART, enable receive S1CON |= BIT1; #endif #if PM_WK_UART_EN S1RELL = (UART_CLKREL(u32Mcu_Clk, UART1_BAUDRATE) & 0xff); S1RELH = ((UART_CLKREL(u32Mcu_Clk, UART1_BAUDRATE) >> 8) & 0x3); S1CON = 0xd0; PCON |= 0x80; S1CON |= BIT1; #endif }
(4)设置唤醒字串
UART_WAKEUP_COMMAND 设置唤醒字串。
vendormstarpmzenoniaProjectMstarSourceCusProj_Inf.h
#if PM_WK_UART_EN #define UART_WAKEUP_COMMAND "mstar" #define UART_RECEIVED_TIMEOUT 0xFFFF #endif
(5)循环监听
CusProj_InfUart1Polling 中通过S1BUF不停读取字串,与唤醒字串匹配后,就唤醒
BOOLEAN CusProj_InfUart1Polling(void) { U8 u8UartWakeupCmd[32] = { 0 }; U32 u32UartRxCount = 0; U32 u32UartRxTimeout = 0; if(strlen(UART_WAKEUP_COMMAND) == 0) return TRUE; while((u32UartRxTimeout < UART_RECEIVED_TIMEOUT) && (u32UartRxCount < strlen(UART_WAKEUP_COMMAND))) { //WriteByte(0x0EEC, ReadByte(0x0EEC)&(~BIT1));//swtich gpio_pm[5] to 51's uart_rx1 and gpio_pm[1] to 51's uart_tx1 //WriteByte(0x0EEC, ReadByte(0x0EEC)|(BIT0));//swtich gpio_pm[5] to 51's uart_rx1 and gpio_pm[1] to 51's uart_tx1 if (S1CON & BIT0) // UART1 have received a ascii data { //printf("S1BUF = 0x%x ", S1BUF); u8UartWakeupCmd[u32UartRxCount++] = S1BUF; if(u32UartRxCount == strlen(UART_WAKEUP_COMMAND)) { if (strcmp(u8UartWakeupCmd, UART_WAKEUP_COMMAND) == 0) { u32UartRxCount = 0; return TRUE; } else { S1CON &= ~BIT0; // clear received flag return FALSE; } } S1CON &= ~BIT0; // clear received flag } u32UartRxTimeout++; } if (u32UartRxTimeout >= u32UartRxTimeout) { u32UartRxCount = 0; memset(u8UartWakeupCmd, 0, 32); u32UartRxTimeout = 0; } return FALSE; } void CusProj_InfUart1Isr(void) { if( Read2Byte(0x0F0A) & BIT8 ) //gpio_pm_5_fiq_final_status { if(CusProj_InfUart1Polling() == TRUE) { WriteByte(0x0E6B, (ReadByte(0x0E6B)&(~BIT1)));// disable swtich gpio_pm[5] to HK51's uart_rx1 and gpio_pm[1] to HK51's uart_tx1 MDrv_PM_PowerUp(PM_WKUP_UART); WriteByte(0x0F0A, (ReadByte(0x0F0A))|(BIT6)); //clear PAD_GPIO_PM5 WriteByte(0x0F0A, (ReadByte(0x0F0A))&(~BIT6)); WriteByte(0x0F0A, ReadByte(0x0F0A)&(~BIT7)); //gpio_pm_5_fiq_pol WriteByte(0x0F0A, ReadByte(0x0F0A)|(BIT4)); //mask gpio_pm_5_fiq_mask WriteByte(0x0F0A, ReadByte(0x0F0A)& ~(BIT0));// gpio_pm[5] is output enable while(1); } else { WriteByte(0x0F0A, (ReadByte(0x0F0A))|(BIT6)); //clear PAD_GPIO_PM5 WriteByte(0x0F0A, (ReadByte(0x0F0A))&(~BIT6)); } } }
(6)唤醒
通过PM_WKUP_UART 事件唤醒。
MDrv_PM_PowerUp(PM_WKUP_UART); INTERFACE void MDrv_PM_PowerUp(PM_WkupSrc eWkupSrc);
//PM 唤醒源如下:
typedef enum { PM_WKUP_NONE = 0, ///No wakeup event happens PM_WKUP_IR = 1, ///Wakeup event IR PM_WKUP_DVI = 2, ///Wakeup event DVI PM_WKUP_DVI2 = 3, ///Wakeup event DVI2 PM_WKUP_CEC = 4, ///Wakeup event CEC PM_WKUP_SAR = 5, ///Wakeup event SAR PM_WKUP_ESYNC = 6, ///Wakeup event ESYNC PM_WKUP_SYNC = 7, ///Wakeup event SYNC PM_WKUP_RTC = 8, ///Wakeup event RTC PM_WKUP_RTC2 = 9, ///Wakeup event RTC2 PM_WKUP_AVLINK = 10,///Wakeup event AVLINK PM_WKUP_UART = 11, ///Wakeup event UART PM_WKUP_GPIO = 12, ///Wakeup event GPIO PM_WKUP_MHL = 13, ///Wakeup event MHL PM_WKUP_WOL = 14 ///Wakeup event WOL //13~15: reserved } PM_WkupSrc;