ctr_mcu/trunk/task_sys.c
n2232 0d13eb6bc2 □1.34 プラスアルファ
電池残量が30%未満の時に充電しながらoffすると充電LEDが消えない不具合修正
隠語を普通語に
コメント追加
しばらくほっといて電源を入れようとすると一発目電源が入らない件。まだ完全修正じゃないが
電源on時、シーケンスを誤っていた。(task_sys.c)


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

581 lines
16 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"
#include "sw.h"
#include "adc.h"
#include "self_flash.h"
//=========================================================
#define WAIT_SHIROBAKO_POW_CONTROL 240
//=========================================================
extern void nop8();
static void chk_emergencyExit();
static void force_off_check();
static void send_getup_to_soc();
//=========================================================
extern bit info_led_off;
extern bit going_to_sleep;
extern bit bt_authorized;
static u8 timeout_sleep;
extern u8 chg_led_override;
#ifdef i2c_timeout_test
extern bit i2c_mcu_time_out_error;
#endif
/* ========================================================
マイコン内部で必要なもの
・省電力に入れる
 system_status.pwr_state == OFF_TRIG で、このタスクが呼ばれると、
省電力モードに入ります
======================================================== */
void tsk_sys( )
{
static u8 timeout = 0;
switch ( system_status.pwr_state )
{
case ON_CHECK: //-------------------------------------------------------
// スイッチ操作などで割り込みが発生し、スリープが解除されるとここに来ます。
if( system_status.poweron_reason == NONE )
{
// スイッチで電源on
if( SW_pow_count != 0 )
{
timeout = 0;
}
else
{
timeout += 1;
}
if( timeout > 100 )
{
system_status.pwr_state = OFF; // スイッチはノイズだった。寝る。
renge_task_interval_run_force = true;
return;
}
if( SW_pow_count < 10 )
{
// もう少しスイッチの様子を見る
return;
}
// 電源投入
system_status.poweron_reason = PWSW;
}
SW_pow_mask = true;
timeout = 0;
// for debug
#ifdef _DEBUG_BT_FUEL_
vreg_ctr[ VREG_C_DBG01 ] = 99;
#endif
#ifdef _DEBUG_BT_TEMP_
vreg_ctr[ VREG_C_DBG01 ] = 0x80;
#endif
vreg_ctr[ VREG_C_COMMAND3 ] = 0;
// 電源投入 //
iic_mcu_start( );
bt_force_update = false;
BT_chk(); // 実機やバッテリの判定、電池残量ICの設定
#ifndef _ALLOW_NOBATT_
if( system_status.model == MODEL_JIKKI_NOBATT )
{
renge_task_interval_run_force = true;
system_status.pwr_state = OFF_TRIG;
return;
}
#endif
// 残量チェック
BT_get_left(); // 先に、BT_chk()が実行されている必要があります。
if(
// ( vreg_ctr[VREG_C_BT_REMAIN] < 1 ) // こっちで判定すると電池がほとんど無いときに
// && // アダプタ差しても数分起動できなくなっちゃう
( vreg_ctr[VREG_C_BT_VOLTAGE] < ( V_TH_ZERO / 256 ) )
)
{
// 電池が少ないので起動させない(電圧チェックもされてる)
renge_task_interval_run_force = true;
system_status.pwr_state = OFF_TRIG;
return;
}
// ポートの設定 電源入れる前に。
PM7.4 = 1; // SW_wifi
PM20.4 = 1; // sw_home
PM20.3 = 1; // wl_tx
PM2.3 = 1; // key_sel
PM2.5 = 1; // acc_valid1
PM14.1 = 1; // acc_valid2
if( PM_sys_pow_on( ) != ERR_SUCCESS )
{ // 電源起動不可エラー
renge_task_interval_run_force = true;
system_status.pwr_state = OFF_TRIG;
return;
}
// ここまで来ると、電源投入確定 //
PU5.1 = 1; // 1:PM_CHARGE
PU7 = 0b00011101; // 4:SW_WIFI 3:SW_PWSW 2:PM_IRQ 0:PM_EXTDC_n
PU20.4 = 1; // SW_HOME
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;
}
system_status.pwr_state = ON_TRIG;
PM_LCD_vcom_set( ); // LCDの対向電圧値など書き込み
break;
case ON_TRIG: //-------------------------------------------------------
#ifdef i2c_timeout_test
LED_duty_pow_blu = 0; // debug
LED_duty_3d = 0;
LED_duty_notify_red = 0;
LED_duty_notify_grn = 0;
LED_duty_notify_blu = 0;
LED_pow_red = 0;
LED_CAM = 0;
i2c_mcu_time_out_error = false;
#endif
IIC_ctr_Init( );
IIC_twl_Init( );
RTC_32k_on( );
vreg_twl_init( );
vreg_ctr_reset( );
KRM = 0b00000000;
PIF0 = 0;
system_status.poweron_reason = NONE;
renge_task_interval_run_force = true;
MK0 = INT_MSK0_RSV;
MK1 = INT_MSK1_RSV;
iic_mcu_start();
#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
// リブート時、ステータスを何となく更新
if( system_status.reboot )
{
u8 bl_status_temp;
bl_status_temp = iic_mcu_read_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_BL );
vreg_ctr[ VREG_C_STATUS ] |= (( bl_status_temp & 0x03 ) << 5 );
set_bit( ( iic_mcu_read_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_VDD_LCD ) != 0 ),
vreg_ctr[ VREG_C_STATUS ], REG_BIT_LCD_POW );
BT_chk();
}
LED_init( ); // reboot時の↑BT_Chk,BT_chk後に行いたい
system_status.reboot = 0;
system_status.pwr_state = ON;
// WDTリセット時、I2Cの初期化まで割り込み保留
// ほんとはここにべた書きしたくないが...
if( ( vreg_ctr[ VREG_C_MCU_STATUS ] & REG_BIT_STATUS_WDT_RESET ) != 0 )
{
set_irq( VREG_C_IRQ0, REG_BIT_IRQ_WDT_RESET );
}
break;
case ON: //---------------------------------------------
// PMICによる強制電源断チェック
// デバッガがreset1をアサートすることもある。そのときは全部リセット
chk_emergencyExit();
// SLP監視
if( going_to_sleep ) // 絶対に SLP_REQ の前に予告が来る
{
timeout_sleep += 1;
if( timeout_sleep == 0 || // オーバーフローを期待。sleepするって言ったけど一瞬で起きて気がつかなかった
( PIF0 && !SLP_REQ )) // slp割り込みが入った気がしたが、もう起きてしまった
{
PIF0 = 0;
send_getup_to_soc();
}
if( PIF0 && SLP_REQ ){
PIF0 = 0;
PM_VDD_ecoMode();
system_status.pwr_state = SLEEP;
renge_task_interval_run_force = true;
}
}
// 強制offカウント
force_off_check();
#ifndef _TAIKENDAI_SEISAN_SPECIAL_
if( system_status.taikendai ) // アダプタが抜けたら自動で電源off
{
if( PM_EXTDC_n )
{
system_status.pwr_state = OFF_TRIG;
}
}
#endif
break;
case SLEEP: //------------------------------------------
chk_emergencyExit();
// スリープから復帰
if( !SLP_REQ ){
PM_VDD_normMode();
wait_ms( 5 ); // tdly_sw
send_getup_to_soc();
system_status.pwr_state = ON;
}
force_off_check();
#ifndef _TAIKENDAI_SEISAN_SPECIAL_
if( system_status.taikendai ) // アダプタが刺さっていたら自動で電源on
{
if( PM_EXTDC_n )
{
system_status.pwr_state = OFF_TRIG;
}
}
break;
#endif
default: //---------------------------------------
system_status.pwr_state = OFF_TRIG;
// no break //
case OFF_TRIG: //---------------------------------------
// LED消灯を待つ
vreg_ctr[ VREG_C_LED_POW ] = LED_POW_ILM_OFF;
vreg_ctr[ VREG_C_LED_WIFI ] = WIFI_LED_OFF;
vreg_ctr[ VREG_C_LED_3D ] = LED_3D_ILM_OFF;
info_led_off = true;
if( LED_duty_pow_blu != 0 )
{
return;
}
clear_pow_off_countdown();
vreg_ctr[ VREG_C_ACC_CONFIG ] = 0x00;
tski_acc_hosu_set();
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
while( iic_mcu_busy )
{;}
KRM = ( KR_SW_POW ); // Mask ではなく、Modeなのだそうだ。紛らわしい
MK0 = ~( INT_MSK0_EXTDC );
MK1 = ~( INT_MSK1_KR | INT_MSK1_RTCALARM | INT_MSK1_RTCINTVAL );
MK2L = 0b11111111;
// PU5 そのまま
PU7 = 0b00001001; // PWSWI,PM_EXTTDC,( IRQ0_deactive(), PM_IRQ_deactive )
PU20.4 = 0; // SW_HOME 停止
IF0 = 0;
IF1 = 0;
IF2 = 0;
IRQ0_disable;
PM_sys_pow_off( );
P7.4 = 0; // SW_wifi
PM7.4 = 0;
P20.4 = 0; // sw_home
PM20.4 = 0;
P20.3 = 0; // WL_TX
PM20.3 = 0;
P2.3 = 0; // KEY_SEL
PM2.3 = 0;
P2.5 = 0; // ACC_ready1
PM2.5 = 0;
P14.1 = 0; // ACC_ready2
PM14.1 = 0;
iic_mcu_stop( );
system_status.pwr_state = OFF;
SW_pow_mask = true;
SW_pow_count = 0;
// no break //
case OFF:
system_status.poweron_reason = NONE;
if( !PM_EXTDC_n )
{
// アダプタが刺さってるときはこのブロックを繰り返す。
BT_chk(); // 要ポーリング(電池抜かれ検出のため)
// ↑の中で必要だったらI2C_m_init呼んでます
// アダプタ有り:充電温度監視
if( SW_pow_count >= 10 ) // 電源スイッチが押されるのを待つ
{
// 電源投入
system_status.pwr_state = ON_CHECK;
}
if( system_status.model != MODEL_JIKKI )
{
iic_mcu_stop( );
}
if( system_status.taikendai )
{
// 電源投入
wait_ms(46);
system_status.poweron_reason = PWSW;
system_status.pwr_state = ON_CHECK;
}
}
else
{
// アダプタなし
if( chg_led_override != 0 ) // これがゼロになるまで待つ
{
return;
};
// 省電力へ移行
iic_mcu_stop( );
pm_chk_adapter();
PM_Chg_Stop();
bt_force_update = true;
while( RWST )
{;}
// 割り込み待ちで寝る //
RTCIMK = 1;
CKC = 0b00001001;
OSMC = 0x00;
if( PM_EXTDC_n ) // きわどいタイミングで挿抜が起きることがある
{
STOP( );
}
// 起きる //
// 起きる条件は
// ・KeyReturn割り込み電源ボタン
// ・アダプタ挿抜
OSMC = 0x01;
CKC = 0b00001000;
if( PM_EXTDC_n )
{
// 電源ボタンで起きたとき
SW_pow_mask = false;
system_status.pwr_state = ON_CHECK;
timeout = 0;
}
// else{
// アダプタで起きたときは OFF の中をぐるぐるまわる
// }
RTCIMK = 0;
if( system_status.taikendai )
{
system_status.pwr_state = OFF_TRIG;
}
}
return;
#if 0
default:
NOP( ); // あり得ないステート
#endif
}
}
/*******************************************************//**
PMICが電源異常で止めたか確認
**********************************************************/
static void chk_emergencyExit(){
static u8 shirobako_power_control_count;
if( shirobako_power_control_count == 0 )
{
if( !RESET1_n ) // PM_chk_LDSW() はI2C_mを使用し、高コスト
{
if( PM_chk_LDSW( ) == 0 )
{
// リセットが下がってる
/// PMICが異常終了判断をした
system_status.pwr_state = OFF_TRIG;
renge_task_interval_run_force = true;
}
else
{
// 白箱の仕業
shirobako_power_control_count = 1;
}
}
}
else
{
if( shirobako_power_control_count == WAIT_SHIROBAKO_POW_CONTROL ) // マジックナンバー
// デバッガが何かした。reset1を解除するまでは無視
{
if( RESET1_n ) // リセットネゲート待ち
{
shirobako_power_control_count = 0;
}
else
{
// nothing to do
}
}
else if( shirobako_power_control_count == 200 ) // * (sys_tick)[ms]
// デバッガが何かしたいらしい
{
// #ifdef _RVD_
// 白箱は電源を切りたいらしい
system_status.pwr_state = OFF_TRIG;
renge_task_interval_run_force = true;
shirobako_power_control_count = WAIT_SHIROBAKO_POW_CONTROL;
// #endif
}
else
{
if( !RESET1_n )
{
// #ifdef _RVD_
if( shirobako_power_control_count != 255 )
// #endif
shirobako_power_control_count += 1;
}
else
{
// (TSボードで手動で/デバッガが)リセットをかけたらしい
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( tski_do_command0 );
shirobako_power_control_count = WAIT_SHIROBAKO_POW_CONTROL;
}
}
}
}
/* ========================================================
・電源ボタン長押し
・電池切れ
・電池抜け
での強制OFF。発動すると解除不能
======================================================== */
static void force_off_check()
{
if( system_status.force_off )
{
system_status.pwr_state = OFF_TRIG;
renge_task_interval_run_force = true;
}
}
/* ========================================================
SoCを起こす
  電圧が通常に戻ってから呼んで下さい。
======================================================== */
void send_getup_to_soc()
{
going_to_sleep = false;
timeout_sleep = 0;
#ifdef _MODEL_CTR_
SLP_ACK = 1;
nop8();
SLP_ACK = 0;
#endif
}
/*******************************************************//**
firm_update()を task_status_immed型 を返すようにすればいいのですが...
**********************************************************/
task_status_immed tski_firm_update(){
firm_update();
return( ERR_SUCCESS );
}