/*! * @文件名 logic_power.c * * @功能描述 * 1.通过检测主机控制的FCD_EN信号,控制系统的上下电 * 2.通过检测948的LVDS Lock信号,控制屏幕的显示与关闭 * 3.通过硬件机制,保证系统可执行自断电操作,从而不需要进入stop模式 */ #include "logic_public.h" #define PERIOD_CHECK_WAKEUP 10 //检测FCD_EN信号的周期,10ms #define PERIOD_CHECK_LVDS_LOCK 10 //检测LVDS lock信号的周期,10ms static eNotifyEvent g_BattStatus = EN_NOTIFY_VOLTAGE_NORMAL; //电源状态 static bool g_bPowerDown = true; //false[已上电] true[已下电] static bool g_bWakeUp = false; //false[系统未唤醒] true[系统已唤醒] static bool bWakeUpStatusOld = false; static bool bLockStatusOld = false; extern task_t s_bist_check_task; //bist任务 task_t s_logic_check_lvds; //周期检测LVDS lock信号的任务句柄 task_t s_logic_check_wakeup; //周期检测Wakup信号的任务句柄(即主机FCD_EN信号) /*FUNCTION********************************************************************** * * Function Name : logic_power_up_step1 * Description : 检测到FCD_EN信号时,先给948等外围器件 供电,以便与解串器实现信号LOCK * * 供电关系说明: * 1.FCD_EN信号->SW_3V3_EN[H]->SW_3V3[H]: AD上拉有了,器件3.3v供电有了,948,max25512,pmic供上电 * 2. * *END**************************************************************************/ static void logic_power_up_step1(void) { //1.检测到FCD_EN信号->SW_3V3_EN[H]->SW_3V3[H]: AD上拉有了,器件3.3v供电有了,948,max25512,pmic供上电 //2.拉高PON_HOLD自锁接管电源 fml_gpio_write(OUT_PON_HOLD,true); //3.拉高LDO_1V2_EN,使能1.2v电压输出,948有用到1.2v fml_gpio_write(OUT_LDO_1V2_EN,true); //4.拉高3V3_TFT_EN,使能TFT_VDD输出,给TDDI供电 fml_gpio_write(OUT_3V3_TFT_EN,true); //5.使能948 LVDS输出 fml_gpio_write(OUT_LVDS_PDB,true); //6.拉低TP_RST,将TDDI TP触摸复位 fml_gpio_write(OUT_TP_RST,false); //7.拉低TFT_RST,将TDDI DP显示复位 fml_gpio_write(OUT_TFT_RST,false); logWrite("logic_power_up_step1\r\n"); } /*FUNCTION********************************************************************** * * Function Name : logic_power_up_step2 * Description : 检测到LVDS Lock信号时,输出TFT相关电压,打开背光 * *END**************************************************************************/ void logic_power_up_step2(void) { //1.拉高TP_RST fml_gpio_write(OUT_TP_RST,true); //2.拉高TFT_RST fml_gpio_write(OUT_TFT_RST,true); //3.拉高TFT_SHLR,左右镜像控制 fml_gpio_write(OUT_TFT_SHLR,true); //4.拉高TFT_SYBYB,TDDI退出Standby模式 fml_gpio_write(OUT_TFT_SYBYB,true); //5.拉高TFT_DISP,使能显示 fml_gpio_write(OUT_TFT_DISP,true); //6.拉低TFT_BIST,退出BIST测试模式 fml_gpio_write(OUT_TFT_BIST,false); //7.拉高PMIC_EN,使能屏电压输出,具体输出还要写寄存器 fml_gpio_write(OUT_PMIC_EN,true); //8.拉高BL_EN,使能MAX25512背光输出,具体输出还要写寄存器 fml_gpio_write(OUT_BL_EN,true); //10.找到master i2c这路设备 fml_tft_init(); cola_delay_ms(10);//必须加延时,否则后面i2c写入会出现失败情况! //11.按TFT规格书,i2c配置pmic输出电压:PAVDD,NAVDD,VGH,VGL fml_pmic_init(); //12.i2c配置max25512背光输出 fml_max25512_init(); //13.输出PWM背光控制(pwm输出放在最后,可避免闪屏!!) fml_pwm_init(); fml_pwm_adjust(false); logWrite("logic_power_up_step2\r\n"); } /*FUNCTION********************************************************************** * * Function Name : logic_power_down * Description : 屏端系统下电函数 * *END**************************************************************************/ static void logic_power_down(void) { //1.关闭pwm输出 fml_pwm_change_duty(0); fml_pwm_deinit(); //6.拉低TFT_SYBYB,TDDI进入Standby模式 fml_gpio_write(OUT_TFT_SYBYB,false); cola_delay_ms(50); //5.拉低TFT_DISP,关闭显示 fml_gpio_write(OUT_TFT_DISP,false); cola_delay_ms(16); //2.拉低BL_EN,关闭MAX25512背光输出 fml_gpio_write(OUT_BL_EN,false); //3.拉低PMIC_EN,关闭PMIC给屏的相关供电 fml_gpio_write(OUT_PMIC_EN,false); //4.拉低TFT_BIST,退出BIST测试模式 fml_gpio_write(OUT_TFT_BIST,false); //7.拉低TFT_RST,复位DP fml_gpio_write(OUT_TFT_RST,false); //8.拉低TP_RST,复位TP fml_gpio_write(OUT_TP_RST,false); //9.关闭948 LVDS输出 fml_gpio_write(OUT_LVDS_PDB,false); //10.拉低3V3_TFT_EN,关闭TFT_VDD输出,给TDDI断电 fml_gpio_write(OUT_3V3_TFT_EN,false); //11.拉低LDO_1V2_EN,关闭1.2v电压输出 fml_gpio_write(OUT_LDO_1V2_EN,false); //12.拉低PON_HOLD,MCU关闭整个系统电源,包括自身供电[但电源异常时不能关闭电源] if(g_BattStatus == EN_NOTIFY_VOLTAGE_NORMAL) fml_gpio_write(OUT_PON_HOLD,false); } /*FUNCTION********************************************************************** * * Function Name : logic_task_check_lvds_lock * Description : 周期检测948 LVDS Lock信号,控制TFT的显示与关闭 * *END**************************************************************************/ static void logic_task_check_lvds_lock(void *arg, uint32_t event) { (void)arg; (void)event; static int iDlyCnt = 0; if(g_bWakeUp == false) return; if(g_BattStatus != EN_NOTIFY_VOLTAGE_NORMAL) return; bool bLockStatus = fml_gpio_read(IN_LVDS_UNLOCK); if(bLockStatusOld != bLockStatus) { iDlyCnt = 10; #if 0 if(bLockStatus) logWrite("detect bLockStatus = %d,signal match\r\n",bLockStatus); else logWrite("detect bLockStatus = %d,signal lost\r\n",bLockStatus); #endif bLockStatusOld = bLockStatus; } if(iDlyCnt > 0) { iDlyCnt--; if(0 == iDlyCnt) { if(bLockStatus) {//检测lvds锁信号生效 if(g_bPowerDown) { g_bPowerDown = false; logic_power_up_step2(); logWrite("first lock, power on tft\r\n"); if(cola_get_ticker() > 15000) {//用于解决上电没有接lvds线,后面再接上不亮屏的情况 logWrite("tft self make bk light on\r\n"); fml_max25512_set_bklight_on(true); } } else { logWrite("lock signal match,enable backlight\r\n"); fml_max25512_set_bklight_on(true); } } else {//检测lvds锁信号丢失 //fml_max25512_set_bklight_on(false); //logWrite("lock signal lost,disable backlight\r\n"); } } } } /*FUNCTION********************************************************************** * * Function Name : logic_task_check_wakeup_signal * Description : 周期检测主机给过来的FCD_EN信号,控制系统的上下电 * *END**************************************************************************/ static void logic_task_check_wakeup_signal(void *arg, uint32_t event) { (void)arg; (void)event; static int iDlyCnt = 0; bool bWakeUpStatus = fml_gpio_read(IN_WAKEUP); bool bEnable = false; if(bWakeUpStatusOld != bWakeUpStatus) { iDlyCnt = 10; bWakeUpStatusOld = bWakeUpStatus; } if(iDlyCnt > 0) { iDlyCnt--; if(0 == iDlyCnt) { bEnable = true; logWrite("detect fcd_en=%d:",bWakeUpStatus); } } if(event > 0) { if((event & EN_NOTIFY_VOLTAGE_LOW) == EN_NOTIFY_VOLTAGE_LOW) { bEnable = true; logWrite("detect bat low:"); } if((event & EN_NOTIFY_VOLTAGE_HIGH) == EN_NOTIFY_VOLTAGE_HIGH) { bEnable = true; logWrite("detect bat high:"); } if((event & EN_NOTIFY_VOLTAGE_NORMAL) == EN_NOTIFY_VOLTAGE_NORMAL) { bEnable = true; logWrite("detect bat normal:"); } } if(bEnable) { if(g_bWakeUp == false) {//上电 logWrite("power up\r\n"); g_bWakeUp = true; bLockStatusOld = false; logic_power_up_step1(); cola_timer_create(&s_logic_check_lvds, logic_task_check_lvds_lock, NULL); cola_timer_start(&s_logic_check_lvds, EN_COLA_TIMER_ALWAYS, PERIOD_CHECK_LVDS_LOCK); cola_set_event(&s_bist_check_task,EN_NOTIFY_SYS_POWER_UP); } else if(g_bWakeUp == true) {//下电 logWrite("power down\r\n"); cola_set_event(&s_bist_check_task,EN_NOTIFY_SYS_POWER_DOWN); cola_timer_stop(&s_logic_check_lvds); cola_timer_delete(&s_logic_check_lvds); g_bWakeUp = false; g_bPowerDown = true; logic_power_down(); cola_delay_ms(200); } } } /*FUNCTION********************************************************************** * * Function Name : logic_power_init * Description : 初始化电源管理检测任务 * *END**************************************************************************/ void logic_power_init(void) { logWrite("getSoftwareVersion:%s\r\n",getSoftwareVersion()); bWakeUpStatusOld = !fml_gpio_read(IN_WAKEUP); cola_timer_create(&s_logic_check_wakeup, logic_task_check_wakeup_signal, NULL); cola_timer_start(&s_logic_check_wakeup, EN_COLA_TIMER_ALWAYS, PERIOD_CHECK_WAKEUP); }