ctr_mcu/trunk/task_sys.c
N2232 bcefe4d511 ■0.21
いつの間にか使われ方が変わって長手意を表していない変数などを一部名前変更
一部エラーコードで0を返しなどしてた。ERR_SUCCESSなどを返すように修正
ADCのノイズフィルタを改良
ヒステリシス+四捨五入を追加
Volテーブルを更新。最大音量を-10dbに
TWLからの音量設定を無視→反映、スライダの設定と後着優先になるように修正
 Volのポーリング書き込み廃止、CODECリセット時のために強制セットコマンド追加(command.4)
 そのつもりがなかったので修正量が割とあった。
Vol書き込み時、ベリファイ、一度だけリトライするようにした。発生頻度からすれば良かろう。評価中
バッテリー補正パラメータ更新
I2C_mにライトコマンドがきた直後に次の通信が来ると対応出来ずにバスが衝突(ウェイトコンディション理解してくれないから...)してしまっていた。
 結果:一瞬BL消えや突然の電源断
 一時的にスレーブアドレスを変えてNAKを返し、リトライしてもらうことにした。評価中。
電池残量ゼロ時のパターンをとりあえず高速点滅をプリセットにした。
 交換した電池が0や、完全放電などでMCUがリセットされてSoCからパターンをもらってない場合にLEDが青赤とも消灯になりユーザーが心配するため
お知らせLEDのフルカラー化の両対応コードが間違えていてめちゃめちゃになっていたのを修正
お知らせLEDフルカラー判定を誤ることがあった。マージンを増やした。
白箱を実機と誤判定していた。(FPGAの準備がまだ)判定方法を変更
本体設定や無線スイッチでWiFiを切ったときはフェードなしに。すぱっと変化した方がかっこいい
電源OFFにするとき、3DとWiFiはすぱっと消す。電源とお知らせはフェード(以前のまま)
スリープ期間が極短いとSoC.SLP_OのH期間を取り逃す事があった。
 症状:スリープに入ると電源断以外受け付けなくなる
 I2Cで予告してもらう。
歩数計のログポインタ進めるタイミング、秒レジスタ追加。
割り込み禁止区間の調整
電池残量ICとの通信・通信後のケアなど修正
電池残量0での強制電源断復活
.bin,.hexをリポジトリに追加

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

504 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();
static void send_getup_to_soc();
//=========================================================
extern bit info_led_off;
extern bit going_to_sleep;
static u8 timeout_sleep = 0;
/* ========================================================
マイコン内部で必要なもの
・省電力に入れる
 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 ] = 99; // todo (仮)
#endif
#ifdef _DEBUG_BT_TEMP_
vreg_ctr[ VREG_C_DBG01 ] = 0x80; // 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 ) &&
( vreg_ctr[VREG_C_BT_VOLTAGE] < ( 3150 / 16 / 1.25 ) ))
{
// 電池が少ないので起動させない(電圧チェックもされてる)
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;
PIF0 = 0;
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( PIF0 ){ // slp割り込み
PIF0 = 0;
if( !SLP_REQ ){ // 一瞬で起きた
send_getup_to_soc();
}
else
{
PM_VDD_ecoMode();
system_status.pwr_state = SLEEP;
renge_task_interval_run_force = 1;
}
}
if( going_to_sleep )
{
timeout_sleep += 1;
if( timeout_sleep == 255 ) // sleepするって言ったけど一瞬で起きて気がつかなかった
{
send_getup_to_soc();
}
}
// 強制offカウント
force_off_check();
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();
break;
case OFF_TRIG: //---------------------------------------
// LED消灯を待つasdf
vreg_ctr[ VREG_C_LED_POW ] = LED_POW_ILM_OFF;
vreg_ctr[ VREG_C_LED_WIFI ] = WIFI_LED_OFF;
info_led_off = 1;
if( LED_duty_pow_blu != 0 )
{
return;
}
vreg_ctr[ VREG_C_LED_TUNE ] = LED_TUNE_ILM_OFF;
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;
IRQ0_disable;
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;
}
}
}
/* ========================================================
SoCを起こす
  電圧が通常に戻ってから呼んで下さい。
======================================================== */
void send_getup_to_soc()
{
going_to_sleep = 0;
timeout_sleep = 0;
#ifdef _MODEL_CTR_
SLP_ACK = 1;
nop8();
nop8();
SLP_ACK = 0;
#endif
}
/*******************************************************//**
firm_update()を task_status_immed型 を返すようにすればいいのですが...
**********************************************************/
task_status_immed tski_firm_update(){
firm_update();
return( ERR_SUCCESS );
}