#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_tune_count, SW_wifi_count; bit SW_pow_mask, SW_home_mask, SW_tune_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_tune_mask = 1; SW_wifi_mask = 1; // 何か他に電源ON要因はあるか? // 蓋開け // アダプタ(充電の温度を監視しなくてはならない) // 時計 // 電源投入 // iic_mcu_start(); PM_init(); // 電池残量ICの設定 // 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 ); } PM_LCD_vcom_set(); // LCDの対向電圧値など書き込み if( PM_LCD_on() == 0 ){ renge_task_interval_run_force = 1; iic_mcu_stop(); system_status.pwr_state = OFF; return( 0 ); } if( PM_BL_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; #ifndef _PMIC_TWL_ { u8 temp; // do{ temp = iic_mcu_write_a_byte( IIC_SLA_DCP, 0x08, 0x80 ); // ACR←0x80 揮発モードへ NOP(); // }while( temp != ERR_SUCCESS ); } #endif vreg_ctr[ VREG_C_ACC_CONFIG_HOSU ] = 0x01; renge_task_immed_add( acc_hosu_set ); break; case ON: //--------------------------------------------- if( !RESET1_n ){ // 電源異常チェック /// コマンドで、正規にリセットをかけたときには、 /// このチェックに引っかからないので大丈夫 system_status.pwr_state = OFF_TRIG; renge_task_interval_run_force = 1; } break; case SLEEP_TRIG: //------------------------------------- system_status.pwr_state = SLEEP; PM_BL_off(); break; case SLEEP: //------------------------------------------ // system_status.pwr_state = ON_TRIG; if( !RESET1_n ){ system_status.pwr_state = OFF_TRIG; renge_task_interval_run_force = 1; } 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_IRQ2 ] = 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 } // 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(); // 割り込み待ちで寝る // while( SW_POW_n ){;} 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_tune_mask ); count_sw_n( SW_TUNE_n, SW_tune_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_tune_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; if( ( vreg_ctr[ VREG_C_IRQ_MASK0 ] & REG_BIT_SW_HOME_CLICK ) != 0 ){ IRQ0_ast; } }else if( SW_pow_count == 66 ){ vreg_ctr[ VREG_C_IRQ0 ] |= REG_BIT_SW_HOME_HOLD; if( ( vreg_ctr[ VREG_C_IRQ_MASK0 ] & REG_BIT_SW_HOME_HOLD ) != 0 ){ IRQ0_ast; } } */ // wifi sw if( SW_wifi_count == 10 ){ vreg_ctr[ VREG_C_IRQ0 ] |= REG_BIT_SW_WIFI_CLICK; if( ( vreg_ctr[ VREG_C_IRQ_MASK0 ] & REG_BIT_SW_WIFI_CLICK ) != 0 ){ IRQ0_ast; } } // tune sw if( SW_tune_count == 10 ){ vreg_ctr[ VREG_C_IRQ0 ] |= REG_BIT_SW_TUNE_CLICK; if( ( vreg_ctr[ VREG_C_IRQ_MASK0 ] & REG_BIT_SW_TUNE_CLICK ) != 0 ){ IRQ0_ast; } } 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_TUNE_CLICK ) ) != 0 ){ IRQ0_ast; } */ return( 8 ); }