ctr_mcu/trunk/task_sys.c
N2232 611a0cbf84 戻り値の型が誤っているのを修正 動いているコードを触るなと言う格言もあるが…
無名な列挙型、一通り名前を付けた。VSのメンバ表示の可読を上げたいため。今更。
LED お知らせLED、リピート設定でなくても最終フレームフラグを立てる
(パターンを差し替えるときに使ってほしかったが意味ないかもとのこと)
WiFiLEDの点滅は現状(TWL同等)で良いらしい。
スリープ中だが、masterBrightnessで下げた状態にしてもらうことになりそう。
 うっすらついてるかわかるか程度なら消してしまえばいいのに...
充電停止・再開温度を変更。ただし評価を待ってまたいじられるかもしれない
 電池残量割り込みのデバッグコードを入れた。
 加速度センサが動いていると、強制オフに時間が掛かるとの事でシステムチックタイマを数えてみたが、ジッタは増えるものの、問題無いような気がするし、手元で試しても同じ気がする。条件を確認しよう
 

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@189 013db118-44a6-b54f-8bf7-843cb86687b1
2010-06-03 08:39:03 +00:00

506 lines
13 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"
//=========================================================
extern void nop8();
//=========================================================
static void chk_emergencyExit();
static void force_off_check();
//=========================================================
extern bit info_led_off;
/* ========================================================
マイコン内部で必要なもの
・省電力に入れる
 system_status.pwr_state == OFF_TRIG で、このタスクが呼ばれると、
省電力モードに入ります
======================================================== */
void tsk_sys( )
{
static u8 timeout = 0;
switch ( system_status.pwr_state )
{
case OFF: //-------------------------------------------------------
// スイッチ操作などで割り込みが発生し、スリープが解除されるとここに来ます。
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_TRIG; // スイッチはノイズだった。寝る。
renge_task_interval_run_force = 1;
return;
}
if( SW_pow_count < 10 )
{
// もう少しスイッチの様子を見る
return;
}
// 電源投入
system_status.poweron_reason = PWSW;
}
SW_pow_mask = 1;
timeout = 0;
// todo debug
#ifdef _debug_bt_irq_
vreg_ctr[ VREG_C_DBG01 ] = 63; // todo (仮)
#endif
vreg_ctr[ VREG_C_COMMAND3 ] = 0;
// 電源投入 //
iic_mcu_start( );
BT_chk();
BT_init(); // 実機やバッテリの判定、電池残量ICの設定
if( system_status.model == MODEL_JIKKI_NOBATT )
{
renge_task_interval_run_force = 1;
system_status.pwr_state = OFF_TRIG;
return;
}
// 残量チェック
BT_get_left(); // 先に、BT_init()が実行されている必要があります。
if( vreg_ctr[VREG_C_BT_REMAIN] < 1 )
{
renge_task_interval_run_force = 1;
system_status.pwr_state = OFF_TRIG;
return;
}
if( PM_sys_pow_on( ) != ERR_SUCCESS )
{ // 電源起動不可エラー
renge_task_interval_run_force = 1;
system_status.pwr_state = OFF_TRIG;
return;
}
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の対向電圧値など書き込み
#ifdef _PMIC_TWL_
PM_TEG_LCD_dis( 0 );
#endif
break;
case ON_TRIG: //-------------------------------------------------------
PU5 = 0b00000010; // 1:PM_CHARGE
PU7 = 0b00011101; // 4:SW_WIFI 3:SW_PWSW 2:PM_IRQ 0:PM_EXTDC_n
#ifdef _MODEL_CTR_
# ifdef _SW_HOME_ENABLE_
PU20 = 0b00010000; // SW_HOME
# else
PU20 = 0b00000000;
# endif
#endif
IIC_ctr_Init( );
IIC_twl_Init( );
RTC_32k_on( );
vreg_twl_init( );
vreg_ctr_reset( );
KRM = 0b00000000;
system_status.poweron_reason = NONE;
renge_task_interval_run_force = 1;
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();
BT_init();
}
LED_init( ); // reboot時の↑BT_Chk,BT_init後に行いたい
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( SLP_REQ ){
system_status.pwr_state = SLEEP_TRIG;
renge_task_interval_run_force = 1;
}
// 強制offカウント
force_off_check();
break;
case SLEEP_TRIG: //-------------------------------------
PM_VDD_ecoMode();
system_status.pwr_state = SLEEP;
break;
case SLEEP: //------------------------------------------
chk_emergencyExit();
// スリープから復帰
if( !SLP_REQ ){
PM_VDD_normMode();
wait_ms( 5 ); // tdly_sw
#ifdef _MODEL_CTR_
SLP_ACK = 1;
nop8(); // 適当ウェイト
SLP_ACK = 0;
#endif
system_status.pwr_state = ON;
}
force_off_check();
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_TUNE ] = LED_TUNE_ILM_OFF;
info_led_off = 1;
if( system_status.info_fullcolor )
{
if( LED_duty_pow_blu != 0 )
{
return;
}
}
else
{
if( LED_duty_old_pow_blu != 0 )
{
return;
}
}
system_status.cnt_force_off = 0;
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
#ifdef _PMIC_TWL_
PM_TEG_LCD_dis( 1 );
#endif
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 = 0x00; // SW_HOME 停止
IF0 = 0;
IF1 = 0;
IF2 = 0;
PM_sys_pow_off( );
BT_set_relax_timer();
timeout = 0;
system_status.pwr_state = BT_CHARGE;
SW_pow_mask = 1;
SW_pow_count = 0;
// no break //
case BT_CHARGE:
if( !PM_EXTDC_n || ( BT_is_relaxed() == 0 ) )
{
// アダプタが刺さってるときはこのブロックを繰り返す。
/// ↓は中で初期化フラグをもってるので呼びまくって良い
iic_mcu_start( );
BT_chk( );
// アダプタ有り:充電温度監視
if( SW_pow_count >= 10 ) // 電源スイッチが押されるのを待つ
{
// 電源投入
system_status.poweron_reason = PWSW;
system_status.pwr_state = OFF;
}
if( !PM_EXTDC_n )
{
BT_set_relax_timer();
}
}
else
{
// 省電力へ移行
system_status.poweron_reason = NONE;
PM_Chg_Stop();
while( RWST )
{;}
iic_mcu_stop( );
// 割り込み待ちで寝る //
RTCIMK = 1;
# ifdef _MCU_BSR_
CKC = 0b00001001;
OSMC = 0x00;
# endif
STOP( );
// 起きる //
// 起きる条件は
// ・KeyReturn割り込み電源ボたん
// ・RTCアラーム
// ・アダプタ挿抜
if( PM_EXTDC_n )
{
// 一度起こしてしまう。ペリフェラルの初期化など流用のため。
// 電源ボタンのタイムアウトで返ってくる
SW_pow_mask = 0;
}
# ifdef _MCU_BSR_
OSMC = 0x01;
CKC = 0b00001000;
# endif
RTCIMK = 0;
system_status.pwr_state = OFF;
}
return;
default:
while( 1 )
{
NOP( );
// あり得ないステート
}
}
}
/*******************************************************//**
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 = 1;
}
else
{
// 白箱の仕業
shirobako_power_control_count = 1;
}
}
}
else
{
if( shirobako_power_control_count == 240 ) // <- 240はマジックナンバー
// デバッガが何かした。reset1を解除するまでは無視
{
if( RESET1_n ) // リセットネゲート待ち
{
shirobako_power_control_count = 0;
}
else
{
// nothing to do
}
}
else if( shirobako_power_control_count == 200 )
// デバッガが何かしたいらしい
{
// 白箱は電源を切りたいらしい
system_status.pwr_state = OFF_TRIG;
renge_task_interval_run_force = 1;
shirobako_power_control_count = 240;
}
else
{
if( !RESET1_n )
{
shirobako_power_control_count += 1;
}
else
{
// リセットをかけたらしい
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( do_command0 );
shirobako_power_control_count = 240;
}
}
}
}
/* ========================================================
・電源ボタン長押し
・電池切れ
・電池抜け
での強制OFF。発動すると解除不能
======================================================== */
static void force_off_check()
{
if( system_status.cnt_force_off != 0 )
{
system_status.cnt_force_off += 1;
if( system_status.cnt_force_off >= ( vreg_ctr[ VREG_C_OFF_DELAY ] * 64 ) )
{
system_status.pwr_state = OFF_TRIG;
renge_task_interval_run_force = 1;
}
}
}
/* ========================================================
CPUからのスリープ要求
 ポーリングにしました。
======================================================== */
/*
__interrupt void intp0_slp( )
{ // SLP
if( SLP_REQ ){
system_status.pwr_state = SLEEP_TRIG;
renge_task_interval_run_force = 1;
}else{
system_status.pwr_state = ON;
PM_VDD_normMode();
wait_ms( 5 ); // tdly_sw
#ifdef _MODEL_CTR_
SLP_ACK = 1;
NOP(); // 適当ウェイト
NOP();
NOP();
NOP();
SLP_ACK = 0;
#endif
system_status.pwr_state = ON;
}
}
*/
/*******************************************************//**
firm_update()を task_status_immed型 を返すようにすればいいのですが...
**********************************************************/
task_status_immed tski_firm_update(){
firm_update();
return( ERR_SUCCESS );
}