#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" u8 SW_pow_count, SW_home_count, SW_3d_count, SW_wifi_count; bit SW_pow_mask, SW_home_mask, SW_3d_mask, SW_wifi_mask; /***************************************************************************** マイコン内部で必要なもの ・省電力に入れる  system_status.pwr_state == OFF_TRIG で、このタスクが呼ばれると、 省電力モードに入ります *****************************************************************************/ task_interval tsk_sys(){ static u8 timeout = 0; switch( system_status.pwr_state ){ case OFF: //------------------------------------------------------- // スイッチ操作などで割り込みが発生し、スリープが解除されるとここに来ます。 RTCIMK = 0; // インターバル割り込み許可 KRMK = 1; // スイッチで電源on if(( SW_pow_count != 0 ) || ( SW_wifi_count != 0 )){ timeout = 0; }else{ timeout += 1; } if( timeout > 127 ){ system_status.pwr_state = OFF_TRIG; // スイッチはノイズだった。寝る。 renge_task_interval_run_force = 1; return( 0 ); } if(( SW_pow_count > 3 ) || ( SW_wifi_count > 3 )){ // 何か他に電源ON要因はあるか? SW_pow_mask = 1; SW_3d_mask = 1; SW_wifi_mask = 1; // 何か他に電源ON要因はあるか? // 蓋開け // アダプタ(充電の温度を監視しなくてはならない) // 時計 // 電源投入 // iic_mcu_start(); PM_init(); // todo bt_auth if( PM_bt_auth() != ERR_SUCCESS ){ // どうするの? renge_task_interval_run_force = 1; system_status.pwr_state = OFF_TRIG; while(1){ NOP(); } // return( 0 ); } if( PM_sys_pow_on() != ERR_SUCCESS ){ // 電源起動不可エラー renge_task_interval_run_force = 1; iic_mcu_stop(); system_status.pwr_state = OFF; return( 0 ); } if( PM_LCD_on() == 0 ){ renge_task_interval_run_force = 1; iic_mcu_stop(); system_status.pwr_state = OFF; return( 0 ); } // ここまで来ると、電源投入確定 system_status.pwr_state = ON_TRIG; renge_task_interval_run_force = 1; } return( 0 ); break; case ON_TRIG: //------------------------------------------------------- LED_init(); // パワースイッチでのonの時は、LEDを点灯させる if( SW_pow_count > 3 ){ vreg_ctr[ VREG_C_LED_POW_ILUMI ] = LED_POW_ILM_AUTO; }else{ vreg_ctr[ VREG_C_LED_POW_ILUMI ] = LED_POW_ILM_OFF; } iic_mcu_write_a_byte( IIC_SLA_8LEDS, IIC_8LEDS_REG_DIR, 0x00 ); iic_mcu_write_a_byte( IIC_SLA_8LEDS, IIC_8LEDS_REG_DO, 0x00 ); { PU7 = 0b00011101; // 4:SW_WIFI 3:SW_PWSW 2:PM_IRQ 0:PM_EXTDC } // ほか、必要ペリフェラルの初期化 IIC_ctr_Init(); // とりあえずはここで初期化 IIC_twl_Init(); RTC_32k_on(); // アクティブ中に使用するピン変化割り込み // I2CやDMAは個別にセットしてください // KRM = 0b00000000; EGP0 = 0b00110001; EGN0 = 0b01110001; // intp20系は後ほど MK0 = INT_MSK0_RSV; MK1 = INT_MSK1_RSV; MK2L= INT_MSK2L_RSV; system_status.pwr_state = ON; iic_mcu_write_a_byte( IIC_SLA_8LEDS, IIC_8LEDS_REG_DO, 0x00 ); #ifdef _PMIC_TWL_ { u8 temp; do{ temp = iic_mcu_write_a_byte( IIC_SLA_DCP, 0x08, 0x80 ); // ACR←0x80 揮発モードへ NOP(); }while( temp != ERR_SUCCESS ); } #endif accero_hosu_start(); break; case ON: //------------------------------------------------------- break; case SLEEP_TRIG: //------------------------------------------------------- system_status.pwr_state = SLEEP; break; case SLEEP: //------------------------------------------------------- system_status.pwr_state = ON_TRIG; break; case OFF_TRIG: //------------------------------------------------------- LED_stop(); IIC_ctr_Stop(); IIC_twl_Stop(); vreg_ctr[ VREG_C_IRQ0 ] = 0; vreg_ctr[ VREG_C_IRQ1 ] = 0; vreg_ctr[ VREG_C_IRQ1 ] = 0; BT_TEMP_P = 0; // 電源オン条件の割り込みセット // PWSW KR3 押すとL // BG24 KR4 // ふた開け INTP5 閉じるとL // ACアダプタ INTP4 アダプタありでL // RTC // pullup_off(); { // PU5 = 0b00000011; // PM_CHG,PM_CHGERR // PU7 = 0b00011001; // SW_WiFi,PWSWI,PM_EXTTDC PU5 = 0b00000000; PU7 = 0b00001001; // PWSWI,PM_EXTDC } // KRM = ( KR_SW_POW | KR_SW_WIFI ); // Mask ではなく、Modeなのだそうだ。紛らわしい KRM = ( KR_SW_POW ); // Mask ではなく、Modeなのだそうだ。紛らわしい // EGP0 = 0b00100000; // SHELL, 0で検出しない EGP0 = 0b00000000; // SHELL, 0で検出しない EGN0 = 0b00010000; // EXTDC // intp20系は後ほど MK0 = 0b1111111110111111; // INT(EXTDC) // MK0 = 0b1111111100111111; // INT(SHELL), INT(EXTDC) MK1 = 0b1111011111111111; // KR(SW_PW,SW_WiFi,...) // MK1 = 0b1111010111111111; // KR, RTC(Alarm) MK2L= 0b11111111; PM_sys_pow_off(); iic_mcu_stop(); IF0 = 0; IF1 = 0; IF2 = 0; timeout = 0; system_status.pwr_state = OFF; DI(); STOP(); // 割り込み待ちで寝る EI(); #ifdef _PMIC_TWL_ MK2L = 0b01111111; // wifi_TX 割り込み EGP0 |= 0x80; #else // todo #endif renge_task_interval_run_force = 1; break; default: while(1){ NOP(); // あり得ないステート } } return 1; } /***************************************************************************** スイッチの監視  チャタリングをはねたり、長押しや、押したトリガなどの検出など todo 必要に応じてマスク *****************************************************************************/ // 押した時間を数える。押しっぱなしでも0に戻らない // maskが非0の時は、一度離すまで無視する #define count_sw_n( sw, counter, mask ) \ { \ if( sw ){ \ mask = 0; \ counter = 0; \ }else{ \ if( mask != 0 ){ \ counter = 0; \ }else{ \ counter += 1; \ if( counter == 0 ) counter = 255; \ } \ } \ } task_interval tsk_sw(){ static u8 cnt_force_off = 0; if(( system_status.pwr_state == ON ) || ( system_status.pwr_state == OFF )){ count_sw_n( SW_POW_n, SW_pow_count, SW_pow_mask ); count_sw_n( SW_WIFI_n, SW_wifi_count, SW_3d_mask ); count_sw_n( SW_2D3D_n, SW_3d_count, SW_wifi_mask ); // count_sw_n( SW_HOME_n, SW_home_count, SW_home_mask ); } switch( system_status.pwr_state ){ case( OFF_TRIG ): SW_pow_count = 0; SW_wifi_count = 0; SW_3d_count = 0; cnt_force_off = 0; break; case( ON ): case( SLEEP ): // 電源スイッチの監視 // if( SW_pow_count == 6 ){ vreg_ctr[ VREG_C_IRQ0 ] |= REG_BIT_SW_POW_CLICK; }else if( SW_pow_count == 66 ){ vreg_ctr[ VREG_C_IRQ0 ] |= REG_BIT_SW_POW_HOLD; } // 電源OFF割り込みを入れたが… if(( vreg_ctr[ VREG_C_IRQ0 ] & REG_BIT_SW_POW_HOLD ) != 0 ){ cnt_force_off += 1; if( cnt_force_off >= 13 ){ // …返事がない。強制的に切る。 vreg_ctr[ VREG_C_LED_POW_ILUMI ] = LED_POW_ILM_OFF; if(( LED_duty_pow_H == 0 ) && ( LED_duty_pow_L == 0 )){ system_status.pwr_state = OFF_TRIG; renge_task_interval_run_force = 1; } } }else{ cnt_force_off = 0; } /* todo // HOME スイッチ…だと? // if( SW_home_count == 6 ){ vreg_ctr[ VREG_C_IRQ0 ] |= REG_BIT_SW_HOME_CLICK; IRQ0_ast; }else if( SW_pow_count == 66 ){ vreg_ctr[ VREG_C_IRQ0 ] |= REG_BIT_SW_HOME_HOLD; IRQ0_ast; } */ // wifi sw if( SW_wifi_count == 10 ){ vreg_ctr[ VREG_C_IRQ0 ] |= REG_BIT_SW_WIFI_CLICK; } // 3d sw if( SW_3d_count == 10 ){ vreg_ctr[ VREG_C_IRQ0 ] |= REG_BIT_SW_3D_CLICK; } break; } if(( vreg_ctr[ VREG_C_IRQ0 ] & ( REG_BIT_SW_POW_CLICK | REG_BIT_SW_POW_HOLD | REG_BIT_SW_HOME_CLICK | REG_BIT_SW_HOME_HOLD | REG_BIT_SW_WIFI_CLICK | REG_BIT_SW_3D_CLICK ) ) != 0 ){ IRQ0_ast; } return( 8 ); }