#pragma SFR #pragma NOP #pragma HALT #pragma STOP #include "incs.h" #include "i2c_twl.h" #include "i2c_ctr.h" #include "led.h" #include "accero.h" #include "pm.h" #include "rtc.h" #include "sw.h" #include "adc.h" //========================================================= static void chk_emergencyExit(); //========================================================= /* ======================================================== マイコン内部で必要なもの ・省電力に入れる  system_status.pwr_state == OFF_TRIG で、このタスクが呼ばれると、 省電力モードに入ります ======================================================== */ void tsk_sys( ) { static u8 timeout = 0; switch ( system_status.pwr_state ) { case OFF: //------------------------------------------------------- // スイッチ操作などで割り込みが発生し、スリープが解除されるとここに来ます。 #ifndef _PARRADIUM_ switch ( system_status.poweron_reason ) { default: // スイッチで電源on if( SW_pow_count != 0 ) { timeout = 0; } else { timeout += 1; } if( timeout > 127 ) { system_status.pwr_state = OFF_TRIG; // スイッチはノイズだった。寝る。 renge_task_interval_run_force = 1; return; } if( SW_pow_count < 3 ) { // もう少しスイッチの様子を見る return; } // 電源投入 system_status.poweron_reason = PWSW; break; case ( RTC_ALARM ): break; } timeout = 0; // 電源投入 // iic_mcu_start( ); // ↓で電池残量ICの起動待ちウェイトなどがあります。 PM_init( ); // 電池残量ICの設定 if( PM_sys_pow_on( ) != ERR_SUCCESS ) { // 電源起動不可エラー renge_task_interval_run_force = 1; iic_mcu_stop( ); system_status.pwr_state = OFF_TRIG; return; } PM_CHG_TIMEOUT_ENABLE(); // IRQ0_active; #else vreg_ctr[ VREG_C_STATUS_1 ] |= REG_BIT_GASGAUGE_ERR; system_status.poweron_reason = PWSW; #endif // _PARADDIUM_ PM_LCD_vcom_set( ); // LCDの対向電圧値など書き込み #ifdef _PMIC_TWL_ PM_TEG_LCD_dis( 0 ); #endif if( system_status.poweron_reason == PWSW ) { // 電源ボタンでのonの時は、LEDを点灯させる vreg_ctr[VREG_C_LED_POW] = LED_POW_ILM_AUTO; } else { // とりあえず、LED消灯状態で起動させる vreg_ctr[VREG_C_LED_POW] = LED_POW_ILM_OFF; // todo? } system_status.pwr_state = ON_TRIG; // ここまで来ると、電源投入確定 break; case ON_TRIG: //------------------------------------------------------- LED_init( ); PU7 = 0b00011101; // 4:SW_WIFI 3:SW_PWSW 2:PM_IRQ 0:PM_EXTDC_n IIC_ctr_Init( ); if( ( vreg_ctr[ VREG_C_MCU_STATUS ] & REG_BIT_STATUS_WDT_RESET ) /* if( vreg_ctr[ VREG_C_IRQ0 ] | vreg_ctr[ VREG_C_IRQ0 ] | vreg_ctr[ VREG_C_IRQ0 ] | vreg_ctr[ VREG_C_IRQ0 ] */ != 0 ) { set_irq( VREG_C_IRQ0, REG_BIT_IRQ_WDT_RESET ); } IIC_twl_Init( ); RTC_32k_on( ); KRM = 0b00000000; system_status.poweron_reason = NONE; renge_task_interval_run_force = 1; MK0 = INT_MSK0_RSV; MK1 = INT_MSK1_RSV; #ifdef _MCU_BSR_ // MK2 = ~( INT_MSK2_IIC_TWL | INT_MSK2_WIFI_TX_BSR | INT_MSK2_CODEC_PMIRQ ); // PMK21 = 0; // wifi 使わない PMK6 = 0; // pm_irq #else MK2L = ~INT_MSK2_WIFI_TX_KE3; #endif system_status.reboot = 0; system_status.pwr_state = ON; break; case ON: //--------------------------------------------- // PMICによる強制電源断チェック // デバッガがreset1をアサートすることもある。そのときは全部リセット chk_emergencyExit(); // SLP監視 if( SLP_REQ ){ system_status.pwr_state = SLEEP_TRIG; renge_task_interval_run_force = 1; } break; case SLEEP_TRIG: //------------------------------------- PM_VDD_ecoMode(); system_status.pwr_state = SLEEP; break; case SLEEP: //------------------------------------------ chk_emergencyExit(); // スリープから復帰 if( !SLP_REQ ){ PM_VDD_normMode(); wait_ms( 5 ); // tdly_sw #ifdef _MODEL_CTR_ SLP_ACK = 1; NOP(); // 適当ウェイト NOP(); NOP(); NOP(); SLP_ACK = 0; #endif system_status.pwr_state = ON_TRIG; renge_task_interval_run_force = 1; } break; case OFF_TRIG: //--------------------------------------- // LED消灯を待つ vreg_ctr[VREG_C_LED_POW] = LED_POW_ILM_OFF; if(( LED_duty_pow_H != 0 ) || ( LED_duty_pow_L != 0 )) { return; } PM_CHG_TIMEOUT_ENABLE(); LED_stop( ); IIC_ctr_Stop( ); IIC_twl_Stop( ); RTC_32k_off(); vreg_ctr[VREG_C_IRQ0] = 0; vreg_ctr[VREG_C_IRQ1] = 0; vreg_ctr[VREG_C_IRQ2] = 0; vreg_ctr[VREG_C_IRQ3] = 0; // 電源オン条件の割り込みセット // PWSW KR3 押すとL // BG24 KR4 // ふた開け INTP5 閉じるとL // ACアダプタ INTP4 アダプタありでL // RTC #ifdef _PMIC_TWL_ PM_TEG_LCD_dis( 1 ); #endif // IRQ0_deactive; // pullup_off(); ↓ { PU5 = 0b00000011; // PM_CHG,PM_CHGERR PU7 = 0b00011001; // SW_WiFi,PWSWI,PM_EXTTDC } PM_sys_pow_off( ); KRM = ( KR_SW_POW ); // Mask ではなく、Modeなのだそうだ。紛らわしい // intp20系は後ほど MK0 = ~( INT_MSK0_EXTDC ); MK1 = ~( INT_MSK1_KR | INT_MSK1_RTCALARM | INT_MSK1_RTCINTVAL ); MK2L = 0b11111111; IF0 = 0; IF1 = 0; IF2 = 0; timeout = 0; system_status.pwr_state = BT_CHARGE; SW_pow_count = 0; SW_wifi_count = 0; // no break // case BT_CHARGE: if( !PM_EXTDC_n ) { // アダプタ有り:充電温度監視 BT_TEMP_P = 1; // 電源on? if( ( SW_pow_count > 3 ) || ( SW_wifi_count > 3 ) || ( system_status.poweron_reason == RTC_ALARM ) ) { system_status.pwr_state = OFF; // 若干抵抗有るが... renge_task_interval_run_force = 1; KRMK = 1; return; } return; } else { // 省電力へ移行 BT_TEMP_P = 0; while( RWST ) {;} iic_mcu_stop( ); // 割り込み待ちで寝る // RTCIMK = 1; #ifndef _PARRADIUM_ #ifdef _MCU_BSR_ CKC = 0b00001001; OSMC = 0x00; #endif STOP( ); #ifdef _MCU_BSR_ OSMC = 0x01; CKC = 0b00001000; #endif #endif RTCIMK = 0; // 起きる // // 起きる条件は // ・KeyReturn割り込み(電源ボたん) // ・RTCアラーム // ・アダプタ挿抜 system_status.pwr_state = OFF; // renge_task_interval_run_force = 1; KRMK = 1; return; } default: while( 1 ) { NOP( ); // あり得ないステート } } } /*******************************************************//** PMICが電源異常で止めたか確認 **********************************************************/ static void chk_emergencyExit(){ #ifndef _PARRADIUM_ static state; if( !RESET1_n ) { if( PM_chk_LDSW( ) == 0 ) { // PMICが異常終了判断をした system_status.pwr_state = OFF_TRIG; renge_task_interval_run_force = 1; } else { if( state == 0 ) { state = 1; // デバッガなりがリセットをかけた iic_mcu_write_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_BL, 0 ); vreg_ctr[VREG_C_STATUS] = ( vreg_ctr[VREG_C_STATUS] & 0b10011111 ); vreg_ctr[VREG_C_COMMAND0] |= REG_BIT_RESET1_REQ; renge_task_immed_add( do_command0 ); } } } else { state = 0; } #endif } /* ======================================================== CPUからのスリープ要求  ポーリングにしました。 ======================================================== */ /* __interrupt void intp0_slp( ) { // SLP if( SLP_REQ ){ system_status.pwr_state = SLEEP_TRIG; }else{ system_status.pwr_state = ON_TRIG; if( PM_BL_set() != ERR_SUCCESS ){ renge_task_interval_run_force = 1; iic_mcu_stop(); system_status.pwr_state = OFF_TRIG; } } renge_task_interval_run_force = 1; } */ /*******************************************************//** 全く意味ないですが、気分的な物で... **********************************************************/ task_status_immed tski_firm_update(){ firm_update(); return( ERR_SUCCESS ); }