ctr_mcu/trunk/pm.c
fujita_ryohei 6acd9cc0f6 歩数計の変更
・時計あわせで何もしなくて良い
・歩数計を止めている間のケアも不要
・読み出し時、先頭に最終記録時刻[Hour]を付ける
・ログの一括クリア実装
歩数計ログ、自己アップデートに使っていた u8 pool[512] → u16 pool[256]に
 歩数計でこちらの方が都合がよい
 自己書き換えは影響受けず(一応チェック済)

電源投入時に、ロードスイッチの前に /resetをアサートしていたのをやめた。
 意味がないので

互換性検証100115用にリリース

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

891 lines
22 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.

/* ========================================================
対PMIC
藤田@開技
nintendo
'08 Dec
======================================================== */
#pragma nop
#include "incs.h"
#include "adc.h"
#include "led.h"
#include "pm.h"
#include "renge.h"
// ========================================================
// ========================================================
static const u8 BT_BT_PARAM_PANA[64] = {
0xAD, 0x30, 0xAE, 0x70, 0xB0, 0x00, 0xB3, 0x00,
0xB4, 0x70, 0xB5, 0xA0, 0xB7, 0x80, 0xBA, 0x00,
0xBB, 0x90, 0xBD, 0x00, 0xBE, 0x00, 0xBF, 0xF0,
0xC3, 0x00, 0xC5, 0xC0, 0xC8, 0x00, 0xCA, 0xC0,
0x04, 0x00, 0x12, 0x00, 0x0C, 0x10, 0x24, 0x00,
0x10, 0xD0, 0x1B, 0xF0, 0x0A, 0xF0, 0x08, 0xE0,
0x0C, 0xF0, 0x08, 0xC0, 0x08, 0xB0, 0x07, 0xF0,
0x0B, 0x00, 0x05, 0xD0, 0x02, 0x00, 0x09, 0x00
};
static const unsigned char BT_PANA_RCOMP = 135;
static const float BT_PANA_TEMPCOUP = 0.3;
static const float BT_PANA_TEMPCODN = 0.5;
// ========================================================
u8 raw_adc_temperature;
u8 rcomp;
float temp_co_up;
float temp_co_dn;
// ========================================================
static void PM_get_batt_left();
/******************************************************//**
PMIC達の初期化
\n 電池メーカー識別
\n 電池残量ICのセット
\n バージョン情報の取得
\n
\n 以下のピンは主にここで操作・監視されます。
\n ・PM_BT_DET,_P
*********************************************************/
#define swap_endian_16( x ) (unsigned int)( x << 8 | x >> 8 )
void PM_init( )
{
u8 temp;
u8 origParam[4];
union{
u16 _u16; // ↓でわかるように、little endian です。注意。
struct{
u8 lsb;
u8 msb;
}chars;
}dat_16;
wait_ms( 150 );
// -1. なんかおかしい… リセットをかけてみる
dat_16._u16 = swap_endian_16( 0x5400 ); // reset
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_COMMAND, 2, &dat_16 );
// 0. バッテリ残量IC クイックスタート
dat_16._u16 = swap_endian_16( 0x4000 ); // quick start
if( iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_MODE, 2, &dat_16 ) != ERR_SUCCESS )
{
vreg_ctr[ VREG_C_STATUS_1 ] |= REG_BIT_GASGAUGE_ERR;
}
else
{
// 1. ロック解除
dat_16._u16 = swap_endian_16( 0x4057 ); // unlock key
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_LOCK, 2, &dat_16 );
// 2. 初期パラメータを一時保存
iic_mcu_read( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_RCOMP, 4, origParam );
// 3. 一時的にOCVを変更
dat_16._u16 = swap_endian_16( 0xD4C0 ); // マジックナンバー的なもの。メーカー指定
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_OCV, 2, &dat_16 );
// 4. 一時的にRCOMPを変更
dat_16._u16 = swap_endian_16( 0xFF00 );
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_RCOMP, 2, &dat_16 );
// 電池メーカーの識別
BT_DET_P = 1;
temp = ( u8 ) ( get_adc( ADC_SEL_BATT_DET ) >> 6 );
BT_DET_P = 0;
iic_mcu_set_wo_dma( );
// 5.メーカー別パラメータのロード
switch ( temp )
{
// case( BT_VENDER_PANA ):
default:
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_BT_PARAM, 64, BT_BT_PARAM_PANA );
rcomp = BT_PANA_RCOMP;
temp_co_up = BT_PANA_TEMPCOUP;
temp_co_dn = BT_PANA_TEMPCODN;
break;
}
// 6. 150ms以上待つ
wait_ms( 200 );
// 7. OCVに「とある値」を書く
dat_16._u16 = swap_endian_16( 0xD4C0 );
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_OCV, 2, &dat_16 );
// 8. 150600ms待つ。600msは厳守
wait_ms( 200 );
// 9. SOCを読む。ベリファイのため。
temp = iic_mcu_read_a_byte( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_SOC );
if( 0x6D == temp || temp == 0x6E || temp == 0x6F ){
// カスタムモデル書き込みOK
}else{
// 失敗だったらリトライするのか?
}
// 10.元のRCOMPとOCVを書き戻す
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_RCOMP, 4, origParam );
// 11. ロック
dat_16._u16 = swap_endian_16( 0x0000 ); // lock key
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_LOCK, 2, &dat_16 );
// おしまい //
}
// 電池温度測定
BT_TEMP_P = 1; // 電池温度監視スタート
raw_adc_temperature = get_adc( ADC_SEL_BATT_TEMP ); // 温度のtemp。
renge_task_immed_add( PM_bt_temp_update );
// PMIC バージョン読み出し
// temp = iic_mcu_read_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_VER );
// vreg_ctr[ VREG_C_PM_INFO ] = temp;
}
/* ========================================================
raw_adc_temperatureに入っている値を℃に変換するとともに、
・レジスタにセット
・残量ICにセット
todo
======================================================== */
task_status_immed PM_bt_temp_update( )
{
static u8 count = 0; // たまにしか書きに行かない
static u8 rawdat_old;
static s16 temperature; // todo
u16 newrcomp;
/*
サーミスタ - 10kΩ分圧点の時、
常用温度では分圧比のカーブがほぼリニアで、
村田 T[℃] = 81.48 - 111.97 x ratio
TDK T = 81.406 - 111.81 x ratio
*/
if( rawdat_old != raw_adc_temperature ){
DBG_P_n = 1;
temperature = 81.45 - 111.9 * raw_adc_temperature/256.0;
vreg_ctr[VREG_C_BT_TEMP] = (u8)temperature;
vreg_ctr[VREG_C_FREE0 ] = (u8)( temperature % 100 * 100 );
DBG_P_n = 0;
}
// 時々書きにゆく
if( count == 0 )
{
DBG_P_n = 1;
if( vreg_ctr[VREG_C_BT_TEMP] > 20 )
{
newrcomp = -( ( temperature - 20 ) * temp_co_up );
}
else
{
newrcomp = -( ( temperature - 20 ) * temp_co_dn );
}
newrcomp += rcomp;
newrcomp = swap_endian_16( (u16)newrcomp );
DBG_P_n = 0;
if( iic_mcu_write
( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_RCOMP, 2, &newrcomp ) == ERR_SUCCESS )
{
rawdat_old = raw_adc_temperature;
}
}
count += 1;
return ( ERR_SUCCESS );
}
#ifdef _PMIC_TWL_
u8 blset;
#endif
#ifndef _PARRADIUM_
/* ========================================================
液晶系の電源制御
 ステータスフラグはすぐに立ててしまう。
 不感応時間があるし、
起動失敗であれば電源が落ちる
別のタスクで電源落ちは監視していて、ステータスもクリアする
======================================================== */
err PM_LCD_on( )
{
u8 rv;
PM_VDDLCD_on( );
wait_ms( DELAY_PM_TSS_50B_AND_TCOM );
PM_TCOM_on( );
wait_ms( DELAY_PM_TCOM_TO_VCS );
PM_VCS_on( );
wait_ms( DELAY_PM_VCS_TO_BL );
#ifdef _PM_BUG_
iic_mcu_write_a_byte( IIC_SLA_PMIC, 0x22, 0x4A ); // バグ持ちPMIC対策
#endif
rv = PM_chk_LDSW( );
if( rv != 0 )
{
// 電源起動エラーなら電源も切れてしまう。ここではケアしない
vreg_ctr[VREG_C_STATUS] |= REG_BIT_LCD_POW;
set_irq( VREG_C_IRQ3, REG_BIT_LCD_ON );
SND_DEPOP = 0; // 1でミュート
}
#ifdef _PMIC_TWL_
PM_TEG_LCD_dis( 0 );
blset = ( PM_REG_BIT_BL_U | PM_REG_BIT_BL_L );
#endif
return ( rv );
}
void PM_LCD_off()
{
SND_DEPOP = 1;
// BLついてたら消す
#ifdef _PMIC_TWL_
if( blset != 0 )
#else
if( ( iic_mcu_read_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_BL ) & 0x03 ) != 0 )
#endif
{
u8 tot;
PM_BL_set( REG_BIT_CMD_BL_U_OFF | REG_BIT_CMD_BL_L_OFF );
vreg_ctr[VREG_C_STATUS] &= 0b10011111;
if( (( REG_BIT_BL_U_OFF | REG_BIT_BL_L_OFF ) & ~vreg_ctr[ VREG_C_IRQ_MASK3 ] ) != 0 )
{
vreg_ctr[ VREG_C_IRQ3 ] |= ( ( REG_BIT_BL_U_OFF | REG_BIT_BL_L_OFF ) & ~vreg_ctr[ VREG_C_IRQ_MASK3 ] );
IRQ0_neg;
tot = 0;
while( !IRQ0 && ( ++tot != 0 ) ){;}
IRQ0_ast;
}
vreg_ctr[VREG_C_COMMAND2] &= ~( REG_BIT_CMD_BL_U_OFF | REG_BIT_CMD_BL_L_OFF );
}
#ifdef _PMIC_TWL_
PM_TEG_LCD_dis( 1 );
blset = 0;
#endif
PM_TCOM_VCS_off( );
wait_ms( DELAY_PM_LCD_OFF );
PM_VDDLCD_off( ); // 残ってたの全部止めます。
vreg_ctr[VREG_C_STATUS] &= ~REG_BIT_LCD_POW;
set_irq( VREG_C_IRQ3, REG_BIT_LCD_OFF );
}
/* ========================================================
 バックライトの個別on/off
 現状から on/off/維持 のフラグなので面倒
  例えば、BL on/on の状態で、on/onにしろと言われても、on/on割り込みを入れます。
======================================================== */
err PM_BL_set( u8 dat )
{
#ifndef _PMIC_TWL_
u8 blset;
#endif
u8 intset = 0;
// RMWを行う
#ifndef _PMIC_TWL_
// Read
blset = iic_mcu_read_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_BL ) ;
#endif
// Modify
// ue
if(( dat & REG_BIT_CMD_BL_U_ON ) != 0 )
{
blset |= PM_REG_BIT_BL_U;
intset |= REG_BIT_BL_U_ON;
}
else if(( dat & REG_BIT_CMD_BL_U_OFF ) != 0 )
{
blset &= ~PM_REG_BIT_BL_U;
intset |= REG_BIT_BL_U_OFF;
}
// shita
if(( dat & REG_BIT_CMD_BL_L_ON ) != 0 )
{
blset |= PM_REG_BIT_BL_L;
intset |= REG_BIT_BL_L_ON;
}
else if(( dat & REG_BIT_CMD_BL_L_OFF ) != 0 )
{
blset &= ~PM_REG_BIT_BL_L;
intset |= REG_BIT_BL_L_OFF;
}
/*
SoCがPWMを出すようレジスタをセットしてから遅延が有るため、ステータスを先に
更新してしまう。
// Write
iic_mcu_write_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_BL, blset );
if( blset != 0x00 ){
wait_ms( 10 );
}
*/
vreg_ctr[VREG_C_STATUS] = (( vreg_ctr[VREG_C_STATUS] & 0b10011111 )
| (( blset << 6 ) | ( blset << 4 )) & 0b01100000 );
// PMICのBLのビットと、MCUのSTATUSレジスタのビット位置が逆なため入れ替え
{
u8 tot;
if( ( intset & ~vreg_ctr[ VREG_C_IRQ_MASK3 ] ) != 0 )
{
vreg_ctr[ VREG_C_IRQ3 ] |= ( intset & ~vreg_ctr[ VREG_C_IRQ_MASK3 ] );
IRQ0_neg;
tot = 0;
while( !IRQ0 && ( ++tot != 0 ) ){;}
IRQ0_ast;
}
}
// Write
wait_ms( 10 );
iic_mcu_write_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_BL, blset );
if( blset != 0x00 ){
// wait_ms( 10 );
}
return( ERR_SUCCESS ); // ここでは異常チェック不要
}
/* ========================================================
液晶の対向電圧の設定を行います。
仮想レジスタの内容を送るだけ
======================================================== */
err PM_LCD_vcom_set( )
{
u8 rv;
rv = iic_mcu_write_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_POW_DAC1, vreg_ctr[VREG_C_VCOM_T] ); // がっかりなことに、PMICはバースト書き込み不可
rv |= iic_mcu_write_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_POW_DAC2, vreg_ctr[VREG_C_VCOM_B] );
return ( rv );
}
#else
// パラディウム上のSoCでチェックしたいとき、PMICも液晶もつながってないので
// 異常終了しないようにダミー関数にする
err PM_LCD_on( )
{
vreg_ctr[VREG_C_STATUS] |= REG_BIT_LCD_POW;
set_irq( VREG_C_IRQ3, REG_BIT_LCD_ON );
SND_DEPOP = 0; // 1でミュート
return ( ERR_SUCCESS );
}
void PM_LCD_off( )
{
SND_DEPOP = 1;
vreg_ctr[VREG_C_STATUS] &= ~REG_BIT_LCD_POW;
set_irq( VREG_C_IRQ3, REG_BIT_LCD_OFF );
}
err PM_BL_set( u8 )
{
wait_ms( 10 );
vreg_ctr[VREG_C_STATUS] = ( vreg_ctr[VREG_C_STATUS] & ~( REG_BIT_BL_U | REG_BIT_BL_L )
| ( command_bl_set & REG_BIT_CMD_BL_U_ON )? REG_BIT_BL_U
| ( command_bl_set & REG_BIT_CMD_BL_L_ON )? REG_BIT_BL_L
);
return ( PM_chk_LDSW( ) );
}
err PM_LCD_vcom_set( )
{
return ( ERR_SUCCESS );
}
#endif
/* ========================================================
↑で、レジスタ書き込みから呼び出される時のため
 I2Cの取り合いの関係でここから呼ぶ
======================================================== */
task_status_immed tski_vcom_set( )
{
PM_LCD_vcom_set( );
return ( ERR_FINISED );
}
/* ========================================================
シーケンスの通り電源を立ち上げてゆきます。
返値 0 最後まで正常に完了した。
1 ショートなどで電源があがりきらなかった
以下のピンは主にここで操作・監視されます。
・POW_CONT1,2 TEG電源のみ
======================================================== */
err PM_sys_pow_on( )
{
#ifdef _PMIC_CTR_
u8 temp;
// 電池温度測定
while( ADCEN != 0 )
{;
}
BT_TEMP_P = 1;
vreg_ctr[VREG_C_BT_TEMP] = get_adc( ADC_SEL_BATT_TEMP );
BT_TEMP_P = 0;
PM_bt_temp_update( ); // 温度のtemp。 残量ICに行きます
// 残量チェック
PM_get_batt_left(); // 先に、PM_init()が実行されている必要があります。(大丈夫)
// todo: batt remain -> volatage?
if( vreg_ctr[VREG_C_BT_REMAIN] < 0 )
{
return ( 1 );
}
// 電源順次立ち上げ
// PM_reset_ast( ); 不要 PM_LDSW_onまかせ
RESET2_ast;
FCRAM_RST_ast;
PM_LDSW_on( );
wait_ms( 1 );
#ifdef _PM_BUG_
iic_mcu_write_a_byte( IIC_SLA_PMIC, 0x22, 0xCA ); // バグ持ちPMIC対策 OVP解除
#endif
wait_ms( DELAY_PM_TW_PWUP );
PM_VDD_on( );
wait_ms( DELAY_PM_TW_PWUP );
PM_VDD50A_on( ); // 液晶電源ではなく、ledとかに使うものです
wait_ms( DELAY_PM_TW_PWUP );
PM_VDD_normMode();
#ifdef _PM_BUG_
iic_mcu_write_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_POW_SAVE, 0x03 ); // バグ持ちPMIC対策 強制PWM
#endif
if( PM_chk_LDSW( ) == 0 )
{
return ( ERR_ERR );
}
PM_reset_neg( );
RESET2_neg;
FCRAM_RST_neg;
#else
// TWL PMIC
u8 temp;
// 電源投入
RESET1_ast;
RESET2_ast;
FCRAM_RST_ast;
PM_TEG_PWSW = 1;
wait_ms( 160 );
PM_TEG_PWSW = 0;
// 残量確認
temp = 99;
if( temp < ( 255 * 0.03 ) )
{
return ( ERR_ERR );
}
vreg_ctr[VREG_C_BT_REMAIN] = temp;
RESET1_neg;
RESET2_neg;
FCRAM_RST_neg;
wait_ms( 100 );
if( !RESET1_n )
{
// 起動失敗
RESET1_ast;
RESET2_ast;
FCRAM_RST_ast;
return ( ERR_ERR );
}
#endif
return ( ERR_SUCCESS );
}
/* ========================================================
電源OFFシーケンス
todo: 電源異常断の場合
======================================================== */
err PM_sys_pow_off( )
{
#ifdef _PMIC_CTR_
// PM_BL_set( REG_BIT_CMD_BL_U_OFF | REG_BIT_CMD_BL_L_OFF );
// PM_LCD_off( ); // TCOM,VCS OFF も消してきます。
PM_reset_ast( );
RESET2_ast;
FCRAM_RST_ast;
PM_off( );
PM_LDSW_off( );
#else
if( RESET1_n )
{
RESET1_ast;
RESET2_ast;
FCRAM_RST_ast;
PM_TEG_PWSW = 1;
wait_ms( 250 );
wait_ms( 250 );
wait_ms( 250 );
PM_TEG_PWSW = 0;
}
RESET1_ast;
RESET2_ast;
FCRAM_RST_ast;
#endif
return ( ERR_SUCCESS );
}
/* ========================================================
電池の管理
以下のピンは主にここで操作・監視されます。
・PM_BT_AUTH 現状、GPI in
・PM_CHARGE_n CCIC /CHG in
・PM_CHARGE_ERR_n /FLT in
・PM_EXTDC_n /DOK INTP4 in
・PM_CHARGE_EN_n /CEN out
以下の物は関係ありそうですが別のところで主に監視されています。
・LED_Pow R, B, Charge tsk_LED
・BT_TEMP,_P tsk_ADC
PM_EXTDCは割り込みメインにするかも
======================================================== */
#define INTERVAL_TSK_BATT 100
void tsk_batt( )
{
static u8 task_interval = 0;
static u8 charge_hys = 0; // ヒステリシスで上限下限を拡張するとき1
static bit pm_extdc_old;
if( task_interval-- != 0 )
{
return;
}
else
{
task_interval = (u8)( INTERVAL_TSK_BATT / SYS_INTERVAL_TICK );
}
// アダプタ? //
if( pm_extdc_old != !PM_EXTDC_n )
{
pm_extdc_old = !PM_EXTDC_n;
if( pm_extdc_old )
{
set_bit( 1, vreg_ctr[VREG_C_STATUS], REG_BIT_POW_SUPPLY );
set_irq( VREG_C_IRQ1, REG_BIT_BT_DC_CONNECT );
}
else
{
set_bit( 0, vreg_ctr[VREG_C_STATUS], REG_BIT_POW_SUPPLY );
set_irq( VREG_C_IRQ1, REG_BIT_BT_DC_DISC );
}
}
// 充電 ///////////////////////////
// 温度付きヒステリシス
if( vreg_ctr[VREG_C_BT_TEMP] < 0x36 )
{
charge_hys = 1;
}
if( ( 1 < vreg_ctr[VREG_C_BT_TEMP] )
&& ( vreg_ctr[VREG_C_BT_TEMP] < 0x2C ) )
{
charge_hys = 0;
}
if( ( ( charge_hys == 1 )
&& ( 1 < vreg_ctr[VREG_C_BT_TEMP] )
&& ( vreg_ctr[VREG_C_BT_TEMP] < 0x2C ) )
||
( ( charge_hys == 0 )
&& ( vreg_ctr[VREG_C_BT_TEMP] < 0x36 ) ) )
{
#ifndef _MODEL_WM0_
BT_CHG_EN_n = 0; // 温度範囲OKで充電再開
}
else
{
BT_CHG_EN_n = 1; // 温度危険! 充電停止
#endif
}
#ifdef _MODEL_WM0_
BT_CHG_EN_n = 0; // /WL_RSTです...
#endif
// 充電 //
// →割り込み。miscの中でよろしくやってくれている。
set_bit( !BT_CHG_n, vreg_ctr[VREG_C_STATUS], REG_BIT_BATT_CHARGE );
LED_CHARGE = !BT_CHG_n ? 1 : 0;
// 電池残量 //
PM_get_batt_left();
// dubug monitor
vreg_ctr[ VREG_C_FREE1 ] = iic_mcu_read_a_byte( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_VCELL );
return;
}
/*=========================================================
extDC割り込み
電源OFFから起こす充電の温度監視のためのみ
普段はポーリング(pm)
=========================================================*/
__interrupt void intp4_extdc( )
{
;
}
/*=========================================================
フタ開け閉め割り込み
普段はポーング(misc)
=========================================================*/
__interrupt void intp5_shell( )
{
;
}
/*=========================================================
旧PMICへのコマンド書き込み
=========================================================*/
__interrupt void intp6_PM_irq( )
{
if( system_status.pwr_state == ON )
{
EI();
renge_task_immed_add( ntr_pmic_comm );
}
}
extern u8 temp_debug_3;
/* ========================================================
PMICからの割り込みを受けて、NTR PMIC互換レジスタからリード
======================================================== */
task_status_immed ntr_pmic_comm( )
{
static u8 reg_shadow;
u8 reg1_old;
reg1_old = reg_shadow;
if( iic_mcu_read( IIC_SLA_CODEC, CODEC_REG_PM, 1, &reg_shadow ) != ERR_SUCCESS )
{
return ( ERR_FINISED );
}
DI( );
if( ( ( reg1_old ^ reg_shadow ) & REG_BIT_TWL_REQ_BL_U ) != 0 )
{
if( ( reg_shadow & REG_BIT_TWL_REQ_BL_U ) == 0 ) // 消えた
{
set_irq( VREG_C_IRQ2, REG_BIT_TWL_BL_U_OFF );
}
else
{
set_irq( VREG_C_IRQ2, REG_BIT_TWL_BL_U_ON );
}
}
// バックライト 下
if( ( ( reg1_old ^ reg_shadow ) & REG_BIT_TWL_REQ_BL_L ) != 0 )
{
if( ( reg_shadow & REG_BIT_TWL_REQ_BL_L ) == 0 ) // 消えた
{
set_irq( VREG_C_IRQ2, REG_BIT_TWL_BL_L_OFF );
}
else
{
set_irq( VREG_C_IRQ2, REG_BIT_TWL_BL_L_ON );
}
}
// offリクエスト
if( ( reg_shadow & REG_BIT_TWL_REQ_OFF_REQ ) != 0 )
{
set_irq( VREG_C_IRQ2, REG_BIT_TWL_OFF_REQ );
}
// リセットリクエスト
if( ( reg_shadow & REG_BIT_TWL_REQ_RST_REQ ) != 0 )
{
// CODECバグ回避
// リセット単品でなかったら無視
if( ( reg1_old ^ reg_shadow ) == REG_BIT_TWL_REQ_RST_REQ )
{
set_irq( VREG_C_IRQ2, REG_BIT_TWL_RESET_REQ );
}
}
// バックライトをマスクして書き戻す
EI( );
reg_shadow &= ~( REG_BIT_TWL_REQ_OFF_REQ | REG_BIT_TWL_REQ_RST_REQ );
iic_mcu_write_a_byte( IIC_SLA_CODEC, CODEC_REG_PM, reg_shadow );
return ( ERR_FINISED );
}
/**********************************************************
電池残量ICから残量を取得し、レジスタに書き込む。
 電池残量ICが無い・故障などの時はとりあえず残量99%とする。
        ↑は status_1で確認可能。電源投入時にチェックしています。
 PM_init()が実行されている必要があります。
**********************************************************/
static void PM_get_batt_left(){
if(( vreg_ctr[ VREG_C_STATUS_1 ] & REG_BIT_GASGAUGE_ERR ) == 0 )
{
// 電池残量の取得
{
u8 temp[2];
iic_mcu_read( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_SOC, 2, temp );
vreg_ctr[ VREG_C_BT_REMAIN ] = temp[0];
vreg_ctr[ VREG_C_BT_REMAIN_FINE ] = temp[1];
// todo 閾値を超えたら割り込み
}
vreg_ctr[ VREG_C_BT_VOLTAGE ] = iic_mcu_read_a_byte( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_VCELL );
}
else
{
vreg_ctr[ VREG_C_BT_REMAIN ] = 99;
}
// PMIC-NTRに電池残量を教えてあげる
iic_mcu_write_a_byte( IIC_SLA_CODEC,
CODEC_REG_BT,
( vreg_ctr[ VREG_C_BT_REMAIN ] < 5 )? 1 : 0 ); // 1で電池切れ
}
/**********************************************************
command2 液晶系
  ラッパー的な物。ERR_SUCCESSしか返さないが…
**********************************************************/
task_status_immed tski_PM_LCD_on()
{
PM_LCD_on();
return( ERR_SUCCESS );
}
task_status_immed tski_PM_LCD_off()
{
PM_LCD_off();
return( ERR_SUCCESS );
}
task_status_immed tski_PM_BL_set()
{
u8 cmd_BL; // ↓volatileとか付けなくても大丈夫みたい
do
{
cmd_BL = vreg_ctr[VREG_C_COMMAND2];
PM_BL_set( cmd_BL ); // マスク済み
}
while( cmd_BL != vreg_ctr[VREG_C_COMMAND2] );
vreg_ctr[VREG_C_COMMAND2] = 0;
return( ERR_SUCCESS );
}