#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_3d_count, SW_wifi_count; bit SW_pow_mask, SW_3d_mask, SW_wifi_mask; /***************************************************************************** マイコン内部で必要なもの ・省電力に入れる  system_status.pwr_state == OFF_TRIG で、このタスクが呼ばれると、 省電力モードに入ります *****************************************************************************/ task_status 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 > 25 ) || ( SW_wifi_count > 25 )){ // 何か他に電源ON要因はあるか? // 何か他に電源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() != 0 ){ // 電源起動不可エラー renge_task_interval_run_force = 1; system_status.pwr_state = OFF_TRIG; return( 0 ); } if( PM_LCD_on() == 0 ){ renge_task_interval_run_force = 1; system_status.pwr_state = OFF_TRIG; return( 0 ); } // ここまで来ると、電源投入確定 // LED_init(); 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 } // ほか、必要ペリフェラルの初期化 IICA_Init(); // とりあえずはここで初期化 IICB_Init(); RTC_32k_on(); // アクティブ中に使用するピン変化割り込み // I2CやDMAは個別にセットしてください // KRM = 0b00000000; EGP0 = 0b01110001; EGN0 = 0b00110001; // intp20系は後ほど MK0 = INT_MSK0_RSV; MK1 = INT_MSK1_RSV; MK2L= INT_MSK2L_RSV; system_status.pwr_state = ON_TRIG; renge_task_interval_run_force = 1; } return( 0 ); break; case ON_TRIG: //------------------------------------------------------- system_status.pwr_state = ON; iic_mcu_write_a_byte( IIC_SLA_8LEDS, IIC_8LEDS_REG_DO, 0x00 ); accero_hosu_start(); 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(); IICA_Stop(); iic_mcu_stop(); BT_TEMP_P = 0; IF0 = 0; IF1 = 0; IF2 = 0; /* 電源オン条件の割り込みセット // PWSW KR3 押すとL // BG24 KR4 // ふた開け INTP5 閉じるとL // ACアダプタ INTP4 アダプタありでL // RTC */ KRM = ( KR_SW_POW | KR_SW_WIFI ); // Mask ではなく、Modeなのだそうだ。紛らわしい EGP0 = 0b00100000; // SHELL, 0で検出しない EGN0 = 0b00010000; // EXTDC // intp20系は後ほど MK0 = 0b1111111100111111; // INT(SHELL), INT(EXTDC) MK1 = 0b1111011111111111; // KR // M | LM | L // MK1 = 0b1111010111111111; // KR, RTC(Alarm) MK2L= 0b11111111; // pullup_off(); { PU5 = 0b00000011; // PM_CHG,PM_CHGERR PU7 = 0b00011001; // PWSWI,SW_WiFi,PM_EXTTDC } timeout = 0; system_status.pwr_state = OFF; STOP(); 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_status tsk_sw(){ 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 ); switch( system_status.pwr_state ){ case( OFF_TRIG ): SW_pow_count = 0; SW_wifi_count = 0; SW_3d_count = 0; break; case( ON ): if( SW_pow_count > 4 ){ // todo 割り込み } if( SW_wifi_count > 4 ){ // todo 割り込み } if( SW_3d_count > 4 ){ // todo 割り込み } break; case( SLEEP ): if( SW_pow_count > 4 ){ // todo 割り込み } if( SW_wifi_count > 4 ){ // todo 割り込み } return( 8 ); } }