ctr_mcu/trunk/tasks_sys.c
fujita_ryohei be17613348 電池温度監視修正(未完)
動作中にPMICが異常検出でOFF/デバッガがリセットかけた の判定修正

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@18 013db118-44a6-b54f-8bf7-843cb86687b1
2009-11-02 00:00:09 +00:00

431 lines
11 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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_wifi_count;
bit SW_pow_mask, SW_home_mask, SW_wifi_mask;
//=========================================================
static void chk_emergencyExit();
/* ========================================================
マイコン内部で必要なもの
・省電力に入れる
 system_status.pwr_state == OFF_TRIG で、このタスクが呼ばれると、
省電力モードに入ります
======================================================== */
void tsk_sys( )
{
static u8 timeout = 0;
RTCIMK = 0; // インターバル割り込み許可
switch ( system_status.pwr_state )
{
case OFF: //-------------------------------------------------------
// スイッチ操作などで割り込みが発生し、スリープが解除されるとここに来ます。
switch ( system_status.poweron_reason )
{
default:
// スイッチで電源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;
}
if( ( SW_pow_count < 3 ) && ( SW_wifi_count < 3 ) )
{
// もう少しスイッチの様子を見る
return;
}
break;
case ( RTC_ALARM ):
break;
// 何か他に電源ON要因はあるか
// 蓋開け
// アダプタ(充電の温度を監視しなくてはならない)
}
timeout = 0;
// 電源投入
SW_pow_mask = 1;
SW_home_mask = 1;
SW_wifi_mask = 1;
// 電源投入 //
iic_mcu_start( );
// ↓で電池残量ICの起動待ちウェイトなどがあります。
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;
}
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
{
vreg_ctr[VREG_C_LED_POW] = LED_POW_ILM_OFF;
// 他には?
}
// ここまで来ると、電源投入確定
system_status.pwr_state = ON_TRIG;
renge_task_interval_run_force = 1;
break;
case ON_TRIG: //-------------------------------------------------------
LED_init( );
{
PU7 = 0b00011101; // 4:SW_WIFI 3:SW_PWSW 2:PM_IRQ 0:PM_EXTDC
}
// アクティブ中に使用するピン変化割り込み
// I2CやDMAは個別にセットしてください
// KRM = 0b00000000;
MK0 = INT_MSK0_RSV;
MK1 = INT_MSK1_RSV;
#ifdef _MCU_BSR_
MK2 = INT_MSK2_RSV;
#else
MK2L = INT_MSK2L_RSV;
#endif
// ほか、必要ペリフェラルの初期化
IIC_ctr_Init( ); // とりあえずはここで初期化
IIC_twl_Init( );
RTC_32k_on( );
system_status.pwr_state = ON;
iic_mcu_write_a_byte( IIC_SLA_DCP, 0x08, 0x80 ); // ACR←0x80 揮発モードへ
// todo
system_status.poweron_reason = PWSW;
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: //-------------------------------------
#ifdef _MODEL_CTR_
PM_VDD_ecoMode();
#endif
system_status.pwr_state = SLEEP;
break;
case SLEEP: //------------------------------------------
chk_emergencyExit();
// スリープから復帰
if( !SLP_REQ ){
#ifdef _MODEL_CTR_
PM_VDD_normMode();
#endif
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_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;
vreg_ctr[VREG_C_IRQ3] = 0;
BT_TEMP_P = 0;
// 電源オン条件の割り込みセット
// PWSW KR3 押すとL
// BG24 KR4
// ふた開け INTP5 閉じるとL
// ACアダプタ INTP4 アダプタありでL
// RTC
DI( );
#ifdef _PMIC_TWL_
PM_TEG_LCD_dis( 1 );
#endif
PM_sys_pow_off( );
// iic_mcu_stop();
// 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なのだそうだ。紛らわしい
// intp20系は後ほど
MK0 = 0b1111111110111111; // INT(EXTDC)
MK1 = 0b1111010111111111; // KR(SW_PW,SW_WiFi,...), RTC(Alarm)
MK2L = 0b11111111;
IF0 = 0;
IF1 = 0;
IF2 = 0;
timeout = 0;
system_status.pwr_state = OFF;
while( RWST )
{;
}
iic_mcu_stop( );
STOP( ); // 割り込み待ちで寝る //
// while( SW_POW_n ){;}
KRMK = 1;
RTCIMK = 0; // インターバル割り込み許可
EI( );
renge_task_interval_run_force = 1;
break;
default:
while( 1 )
{
NOP( );
// あり得ないステート
}
}
}
#define INTERVAL_TSK_SW 16
#define CLICK_THRESHOLD 3
#define HOLD_THREASHOLD ( 800 / INTERVAL_TSK_SW )
/* ========================================================
スイッチの監視
 チャタリングをはねたり、長押しや、押したトリガなどの検出など
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; \
} \
} \
}
void tsk_sw( )
{
static u8 cnt_force_off = 0;
static u8 task_interval = 0;
if( task_interval != 0 )
{
task_interval -= 1;
return;
}
else
{
task_interval = ( INTERVAL_TSK_SW / SYS_INTERVAL_TICK );
}
switch ( system_status.pwr_state )
{
case ( OFF_TRIG ):
SW_pow_count = 0;
SW_wifi_count = 0;
SW_home_count = 0;
cnt_force_off = 0;
break;
case ( ON ):
case ( SLEEP ):
// 電源スイッチの監視 //
if( SW_POW_n )
{
if( ( CLICK_THRESHOLD < SW_pow_count ) && ( SW_pow_count < HOLD_THREASHOLD ) )
{
set_irq( VREG_C_IRQ0, REG_BIT_SW_POW_CLICK );
}
}
else if( SW_pow_count == HOLD_THREASHOLD )
{
set_irq( VREG_C_IRQ0, REG_BIT_SW_POW_HOLD );
}
else if( SW_pow_count == ( HOLD_THREASHOLD * 4 ) )
{ // todo
// vreg_ctr[ VREG_C_LED_POW ] = LED_POW_ONLY_RED;
system_status.pwr_state = OFF_TRIG;
renge_task_interval_run_force = 1;
}
// 電源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] = 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;
}
// HOME スイッチ //
if( SW_HOME_n )
{
if( ( CLICK_THRESHOLD < SW_home_count ) && ( SW_home_count < HOLD_THREASHOLD ) )
{
set_irq( VREG_C_IRQ0, REG_BIT_SW_HOME_CLICK );
}
}
else if( SW_home_count == HOLD_THREASHOLD )
{
set_irq( VREG_C_IRQ0, REG_BIT_SW_HOME_HOLD );
}
// wifi sw //
if( SW_wifi_count == 10 )
{
set_irq( VREG_C_IRQ0, REG_BIT_SW_WIFI_CLICK );
}
break;
}
// ボタン押し時間のカウント
if( ( system_status.pwr_state == ON ) || ( system_status.pwr_state == OFF ) )
{
count_sw_n( SW_POW_n, SW_pow_count, SW_pow_mask );
#ifdef _SW_HOME_ENABLE_
count_sw_n( SW_HOME_n, SW_home_count, SW_home_mask );
#endif
count_sw_n( SW_WIFI_n, SW_wifi_count, SW_wifi_mask );
}
return;
}
/*******************************************************//**
PMICが電源異常で止めたか確認
**********************************************************/
static void chk_emergencyExit(){
if( !RESET1_n )
{
if( PM_chk_LDSW( ) == 0 )
{
// PMICが異常終了判断をした
system_status.pwr_state = OFF_TRIG;
renge_task_interval_run_force = 1;
}
else
{
// デバッガなりがリセットをかけた
vreg_ctr[VREG_C_COMMAND0] |= REG_BIT_RESET1_REQ;
renge_task_immed_add( do_command0 );
}
}
}