ctr_mcu/branches/sim/task_sys.c
n2232 3775d247c2 HAL 電源アダプタ有無 論理間違い
HWレジスタ初期化誤り修正
HAL 初期化忘れ これにアップデートしてきたときに電源が切れるなど
アダプタを刺した瞬間に電源を切ると、充電LED5sec強制点灯の間、電源投入できなかったのを修正(この場合はLEDを消してしまう事に
電源投入したいとき、数回押さなくてはならない件、修正に問題があった
PINモニタ(拡張レジスタ) RBR追加
電源off時、ポート設定ミスを確認するコード追加 #define _DBG_CHK_OFF_LEAK_ で有効
SPFL MAXELLバッテリパラメータ追加
I2C_m のプルアップon/off 修正


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

638 lines
18 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.

#ifndef _WIN32
#pragma SFR
#pragma NOP
#pragma HALT
#pragma STOP
#endif
#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
//=========================================================
#define PWSW_POWON_TIME (u8)( 50 / INTERVAL_TSK_SW ) // [ms]
/* ========================================================
マイコン内部で必要なもの
・省電力に入れる
 system_status.pwr_state == OFF_TRIG で、このタスクが呼ばれると、
省電力モードに入ります
======================================================== */
void tsk_sys( )
{
static u8 pwsw_timeout = 0; // 電源ボタンチャタリング回避。 タイムアウトするまでに電源投入確定しないとoffに戻る
hal_update();
switch ( system_status.pwr_state )
{
case ON_CHECK: //-------------------------------------------------------
// pwswか、他の割り込みでスリープが解除されると来ます。
if( system_status.poweron_reason == RSN_PWSW ) // アダプタなしで電源スイッチ押したときしか回らない
{
// スイッチで電源on
if( SW_pow_count != 0 )
{
pwsw_timeout = 0;
}
else
{
pwsw_timeout ++;
}
if( pwsw_timeout > 100 )
{
SW_pow_count = 0;
system_status.pwr_state = OFF_TRIG; // スイッチはノイズだった。寝る。
renge_task_interval_run_force = true;
return;
}
if( SW_pow_count < PWSW_POWON_TIME )
{
// もう少しスイッチの様子を見る
return;
}
}
SW_pow_mask = true;
// 電源投入 //
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;
}
// ポートの方向設定 電源入れる前に。
PM_SW_WIFI_n = 1;
PM_SW_HOME_n_JIKKI = 1;
PM_WL_TX = 1;
PM_SW_SEL_n = 1;
PM_ACCEL_INT1 = 1;
PM_ACC_VALID = 1;
if( PM_sys_pow_on( ) != ERR_SUCCESS ) // リセット解除もしてきます
{ // 電源起動不可エラー
renge_task_interval_run_force = true;
system_status.pwr_state = OFF_TRIG;
return;
}
// ここまで来ると、電源投入確定 //
// プルアップon
PU_BT_IN_CHG_n = 1;
PU7 = bits8(0,0,0,1, 1,1,0,1); // 4:SW_WIFI 3:SW_PWSW 2:PM_IRQ 0:PM_EXTDC_n
PU_SW_HOME_n_JIKKI = 1; // SW_HOME
if( system_status.poweron_reason == RSN_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 = bits8(0,0,0,0, 0,0,0,0);
PIF0 = 0;
system_status.poweron_reason = NONE;
renge_task_interval_run_force = true;
MK0 = INT_MSK0_RSV;
MK1 = INT_MSK1_RSV;
iic_mcu_start();
// MK2 = ~( INT_MSK2_IIC_TWL | INT_MSK2_WIFI_TX_BSR | INT_MSK2_CODEC_PMIRQ );
// PMK21 = 0; // wifi 使わない
PMK6 = 0; // pm_irq
// todo 将来的には完全にレジスタ制御に
RBR_RESET_n = 1;
RBR_FLIGHT = 0;
// リブート時、ステータスを何となく更新
if( system_status.reboot )
{
u8 bl_status_temp;
bl_status_temp = read_pmic( PM_REG_ADRS_BL );
vreg_ctr[ VREG_C_STATUS ] |= (( bl_status_temp & 0x03 ) << 5 );
set_bit( ( read_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 ++;
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; // あり得ないステート。デバッグ用
/* FALLTHROUGH */
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();
// todo マクロにでもするよ
RBR_RESET_n = 0;
RBR_FLIGHT = 0;
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_RTCINTVAL ); // INT_MSK1_RTCALARM | RTCアラーム封印中
MK2L = 0xFF;
// PU5 そのまま
PU7 = bits8(0,0,0,0, 1,0,0,1); // PWSWI,PM_EXTTDC,( IRQ0_deactive(), PM_IRQ_deactive )
PU_SW_HOME_n_JIKKI = 0; // SW_HOME 停止
IF0 = 0;
IF1 = 0;
IF2 = 0;
IRQ0_disable;
PM_sys_pow_off( );
// ポート類を停止モードに。こういう回路でも、L出力にしなきゃだめだそうな。
SW_WIFI_n_RAW = 0;
PM_SW_WIFI_n = 0;
SW_HOME_n_JIKKI_RAW = 0;
PM_SW_HOME_n_JIKKI = 0;
WL_TX = 0;
PM_WL_TX = 0;
SW_SEL_n = 0;
PM_SW_SEL_n = 0;
ACCEL_INT1 = 0;
PM_ACCEL_INT1 = 0;
ACC_VALID = 0;
PM_ACC_VALID = 0;
system_status.pwr_state = OFF;
SW_pow_mask = true;
SW_pow_count = 0;
// HALデバッグリセット 忘れると電源on出来なくなることが…
vreg_ctr[ VREG_C_HAL_OVW_CONT0 ] = 0;
vreg_ctr[ VREG_C_HAL_OVW_CONT1 ] = 0;
vreg_ctr[ VREG_C_HAL_OVW_TEMPERATURE ] = 0xFF;
vreg_ctr[ VREG_C_HAL_OVW_BT_FUEL ] = 0xFF;
vreg_ctr[ VREG_C_HAL_OVW_BT_VOLTAGE ] = 0xFF;
/* FALLTHROUGH */
case OFF:
system_status.poweron_reason = NONE;
pwsw_timeout = 0;
if( !PM_EXTDC_n )
{
// アダプタ有り ///////////////////////////////
BT_chk(); // 要ポーリング(電池抜かれ検出のため)
// ↑の中で必要だったらI2C_m_init呼んでます
// アダプタ有り:充電温度監視
if( SW_pow_count > PWSW_POWON_TIME ) // 電源スイッチが押されるのを待つ
{
// 電源投入
system_status.pwr_state = ON_CHECK; // 直ちに押し時間チェックは合格して電源投入に入る
}
if( system_status.model != MODEL_JIKKI )
{
iic_mcu_stop( );
}
if( system_status.taikendai )
{
vreg_ctr[ VREG_C_HAL_OVW_CONT0 ] = vreg_ctr[ VREG_C_HAL_OVW_CONT1 ] = 0;
// 電源投入
wait_ms(46); // pmicの電源再投入仕様のため
system_status.poweron_reason = RSN_PWSW;
system_status.pwr_state = ON_CHECK;
}
}
else
{
// アダプタなし ///////////////////////////////
u8 irq_mask_original_1; // RTCアラームで起動しないように。 現状、他の割り込みでは起きない
if( chg_led_override != 0 ) // これがゼロになるまで待つ todo
{
return;
};
// 省電力へ移行
iic_mcu_stop( );
pm_chk_adapter();
PM_Chg_Stop();
bt_force_update = true;
while( RWST )
{;}
// 割り込み待ちで寝る //
RTCIMK = 1; // systick用インターバルタイマー割り込みマスク
CKC = bits8(0,0,0,0, 1,0,0,1);
OSMC = 0x00;
#ifdef _DBG_CHK_OFF_LEAK_
{
// off中のpin設定ミスチェック
volatile u8 ports_i[12];
volatile u8 ports_o[12];
ports_i[0] = ( PM0 & PU0 & ~P0 ); // プルアップ切り忘れ?
ports_i[1] = ( PM1 & PU1 & ~P1 );
ports_i[2] = 0;
ports_i[3] = ( PM3 & PU3 & ~P3 );
ports_i[4] = ( PM4 & PU4 & ~P4 );
ports_i[5] = ( PM5 & PU5 & ~P5 );
ports_i[6] = 0;
ports_i[7] = ( PM7 & PU7 & ~P7 );
ports_i[8] = ( PM12 & PU12 & ~P12 );
ports_i[9] = ( PM14 & PU14 & ~P14 );
ports_i[10] = 0;
ports_i[11] = ( PM20 & PU20 & ~P20 );
ports_o[0] = ( ~PM0 & P0 ); // H 出力しちゃってるかも
ports_o[1] = ( ~PM1 & P1 );
ports_o[2] = ( ~PM2 & P2 );
ports_o[3] = ( ~PM3 & P3 & ~POM3 );
ports_o[4] = ( ~PM4 & P4 ); // bit3はchg_enなので1でもよい
ports_o[5] = ( ~PM5 & P5 );
ports_o[6] = ( ~PM6 & P6 );
ports_o[7] = ( ~PM7 & P7 );
ports_o[8] = ( ~PM12 & P12 );
ports_o[9] = ( ~PM14 & P14 );
ports_o[10] = ( ~PM15 & P15 );
ports_o[11] = ( ~PM20 & P20 );
NOP(); // ←ブレーク置くため
}
#endif
if( PM_EXTDC_n ) // きわどいタイミングで挿抜が起きることがある
{
STOP();
}
// 起きる //
// 起きる条件は
// ・KeyReturn割り込み電源ボタン
// ・RTCアラーム現在封印
renge_flg_interval = 0;
hal_update();
OSMC = 0x01;
CKC = bits8(0,0,0,0, 1,0,0,0);
// 起きた理由は?
if( !PM_EXTDC_n ){
system_status.pwr_state = OFF; // OFFを回って充電監視
}
/* // RTCアラーム。封印中
else if( vreg_ctr[ VREG_C_IRQ1 ] & REG_BIT_RTC_ALARM )
{
system_status.poweron_reason = RSN_RTC_ALARM;
system_status.pwr_state = ON_CHECK;
}
// else if( 他の割り込みで電源on ){
// これ以外の許可割り込みで起きないんだけど、いいんですよね
// }
*/
else // if( !SW_POW_n ) // (それ以外なら)電源ボタンで起きた
{
SW_pow_mask = false;
system_status.poweron_reason = RSN_PWSW;
system_status.pwr_state = ON_CHECK;
}
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]
// デバッガが何かしたいらしい
{
#ifndef _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 )
{
if( shirobako_power_control_count != 255 )
shirobako_power_control_count ++;
}
else
{
// (TSボードで手動で/デバッガが)リセットをかけたらしい
send_cmd_pmic( PM_REG_ADRS_BL, 0 );
vreg_ctr[VREG_C_STATUS] = ( vreg_ctr[VREG_C_STATUS] & bits8(1,0,0,1, 1,1,1,1) );
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( 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 );
}