mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-06-19 09:05:48 -04:00

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@234 013db118-44a6-b54f-8bf7-843cb86687b1
1159 lines
32 KiB
C
1159 lines
32 KiB
C
/* ========================================================
|
||
対PMIC
|
||
藤田@開技
|
||
nintendo
|
||
'08 Dec
|
||
======================================================== */
|
||
#pragma nop
|
||
|
||
#include "incs.h"
|
||
#include "adc.h"
|
||
#include "led.h"
|
||
#include "pm.h"
|
||
#include "renge\renge.h"
|
||
|
||
#include "batt_params.h"
|
||
|
||
#include <fsl.h>
|
||
#include "fsl_user.h"
|
||
|
||
|
||
|
||
// ========================================================
|
||
u8 raw_adc_temperature;
|
||
BT_VENDER battery_manufacturer = BT_VENDER_NOT_CHECKED;
|
||
st_bt_comp bt_comp; // バッテリパラメータ構造体
|
||
u8 reg_shadow; // NTR PMIC レジスタミラー
|
||
bit bt_chg_ready; // バッテリパラメータ送信済。充電開始許可
|
||
u8 chg_led_override; // アダプタ差したとき、充電するしないに関わらずしばらく点灯させる
|
||
|
||
u8 ntr_pm_bt_low_old;
|
||
|
||
|
||
// ========================================================
|
||
static void BT_model_detect();
|
||
static void BT_mgic_quick_start();
|
||
static void BT_mgic_init();
|
||
|
||
|
||
|
||
// ========================================================
|
||
#define swap_endian_16( x ) (unsigned int)(( x << 8 ) | ( x >> 8 ))
|
||
|
||
|
||
|
||
|
||
/* ========================================================
|
||
電池の管理
|
||
|
||
以下のピンは主にここで操作・監視されます。
|
||
・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
|
||
|
||
bit temp_zone_charge_disable; // 温度で充電停止する時にヒステリシスを付けるため
|
||
void tsk_batt( )
|
||
{
|
||
static u8 task_interval = 0;
|
||
static u8 heikinka_h,heikinka_l;
|
||
|
||
if( system_status.pwr_state != OFF_TRIG )
|
||
{
|
||
if( task_interval-- != 0 )
|
||
{
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
task_interval = (u8)( INTERVAL_TSK_BATT / SYS_INTERVAL_TICK );
|
||
}
|
||
}
|
||
|
||
// アダプタステータス更新 /////////
|
||
pm_chk_adapter();
|
||
|
||
// 充電 ///////////////////////////
|
||
// 温度付きヒステリシス
|
||
if(( 75 <= raw_adc_temperature )
|
||
&& ( raw_adc_temperature <= 184 ))
|
||
{
|
||
if( heikinka_h < 40 )
|
||
{
|
||
heikinka_h++;
|
||
}
|
||
else
|
||
{
|
||
temp_zone_charge_disable = false; // 充電許可
|
||
}
|
||
}
|
||
else if(( raw_adc_temperature <= 61 )
|
||
|| ( 189 <= raw_adc_temperature ))
|
||
{
|
||
if( heikinka_l < 40 )
|
||
{
|
||
heikinka_l++;
|
||
}
|
||
else
|
||
{
|
||
temp_zone_charge_disable = true; // 充電禁止
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// temp_zone_charge_disable そのまま
|
||
heikinka_h = 0;
|
||
heikinka_l = 0;
|
||
}
|
||
|
||
#ifndef _MODEL_WM0_
|
||
// WM0ではCHG_ENABLEピンは /WL_RST に配線されており、充電制御しない
|
||
if( !temp_zone_charge_disable && bt_chg_ready && !PM_EXTDC_n )
|
||
{
|
||
BT_CHG_ENABLE(); // 温度範囲OKで充電再開
|
||
}
|
||
else
|
||
{
|
||
BT_CHG_DISABLE(); // 温度危険! 充電停止
|
||
}
|
||
#endif
|
||
|
||
|
||
// 充電 //
|
||
// →割り込み。
|
||
{
|
||
static u8 anti_chatter;
|
||
u8 temp_CHARGE;
|
||
|
||
temp_CHARGE = !BT_IN_CHG_n; // volatileのため。このピンはチャタらない。
|
||
|
||
if( !temp_CHARGE )
|
||
{
|
||
anti_chatter = 0;
|
||
set_bit( 0, vreg_ctr[VREG_C_STATUS], REG_BIT_BATT_CHARGE ); // set_bitのみ。
|
||
/// 割り込みはmiscが引き受ける
|
||
LED_CHARGE = 0;
|
||
}
|
||
else
|
||
{
|
||
if( anti_chatter < 2 ) // 電池無しでアダプタさして、電極をさわさわ
|
||
{ // すると充電LEDががさがさするので
|
||
anti_chatter++;
|
||
}
|
||
else
|
||
{
|
||
set_bit( 1, vreg_ctr[VREG_C_STATUS], REG_BIT_BATT_CHARGE );
|
||
LED_CHARGE = 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
if( chg_led_override != 0 ){ // 気がつく人いるかな…?
|
||
chg_led_override -= 1;
|
||
LED_CHARGE = 1;
|
||
}
|
||
|
||
// 電池残量 //
|
||
if(( system_status.pwr_state != OFF )&&
|
||
( system_status.pwr_state != BT_CHARGE ))
|
||
{
|
||
BT_get_left();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/********************************************************
|
||
アダプタの有無チェック
|
||
電源off中のアダプタ抜き差しで外から呼ばれるため分離
|
||
***********************************************************/
|
||
void pm_chk_adapter()
|
||
{
|
||
static u8 pm_extdc_old;
|
||
u8 temp_pm_extdc;
|
||
|
||
temp_pm_extdc = !PM_EXTDC_n; // volatileのため
|
||
if( pm_extdc_old != temp_pm_extdc )
|
||
{
|
||
pm_extdc_old = temp_pm_extdc;
|
||
if( temp_pm_extdc )
|
||
{
|
||
set_bit( 1, vreg_ctr[VREG_C_STATUS], REG_BIT_POW_SUPPLY );
|
||
set_irq( VREG_C_IRQ1, REG_BIT_BT_DC_CONNECT );
|
||
chg_led_override = (u8)( 1000 / INTERVAL_TSK_BATT / SYS_INTERVAL_TICK );
|
||
}
|
||
else
|
||
{
|
||
set_bit( 0, vreg_ctr[VREG_C_STATUS], REG_BIT_POW_SUPPLY );
|
||
set_irq( VREG_C_IRQ1, REG_BIT_BT_DC_DISC );
|
||
chg_led_override = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/********************************************************
|
||
電池関係の初期化
|
||
|
||
ゲージ | 有り | 無し
|
||
ーーーーーーーーーーーーーーーーーーーーーーー
|
||
電池 有り| 実機 | ?
|
||
ーーーーーーーーーーーーーーーーーーーーーーー
|
||
無し| 白箱 | TS
|
||
| 実機電池無し |
|
||
ーーーーーーーーーーーーーーーーーーーーーーー
|
||
|
||
ゲージ有り、電池無し の白箱/実機判別は、
|
||
電池温度で判定する
|
||
|
||
返値: 電池無し 0xFF
|
||
電池変わってない 0
|
||
電池変わった 1
|
||
|
||
***********************************************************/
|
||
bit bt_force_update;
|
||
|
||
void BT_chk()
|
||
{
|
||
BT_VENDER battery_manufacturer_old;
|
||
|
||
battery_manufacturer_old = battery_manufacturer;
|
||
|
||
BT_model_detect();
|
||
if( system_status.model != MODEL_JIKKI )
|
||
{
|
||
bt_chg_ready = false;
|
||
return;
|
||
// おしまい
|
||
}
|
||
|
||
if(( battery_manufacturer_old != battery_manufacturer ) ||
|
||
bt_force_update )
|
||
{
|
||
bt_force_update = false;
|
||
iic_mcu_start( ); // 中で初期化フラグをもってるので呼びまくって良い こんなところに…orz
|
||
if( (( battery_manufacturer_old == BT_VENDER_OPEN ) ||
|
||
( battery_manufacturer_old == BT_VENDER_NOT_CHECKED )) &&
|
||
!system_status.reboot )
|
||
{
|
||
BT_mgic_quick_start();
|
||
}
|
||
BT_mgic_init(); // 機種判定も行います
|
||
}
|
||
bt_chg_ready = true;
|
||
renge_task_immed_add( tski_BT_temp_update ); // 電池温度監視スタート
|
||
}
|
||
|
||
|
||
|
||
|
||
void BT_model_detect()
|
||
{
|
||
u8 temp;
|
||
|
||
BT_DET_P = 1;
|
||
BT_TEMP_P = 1;
|
||
wait_ms(1); // 電圧が上がるのに時間が掛かる
|
||
|
||
raw_adc_temperature = get_adc( ADC_SEL_BATT_TEMP );
|
||
temp = get_adc( ADC_SEL_BATT_DET );
|
||
BT_DET_P = 0;
|
||
|
||
system_status.captureBox = 0;
|
||
// プラットフォーム判定 //
|
||
if( raw_adc_temperature > 0xF0 )
|
||
{
|
||
// TS //
|
||
system_status.model = MODEL_TS_BOARD;
|
||
}
|
||
else if( raw_adc_temperature < 4 )
|
||
{
|
||
// 白箱 //
|
||
system_status.model = MODEL_SHIROBAKO;
|
||
|
||
// もしかして:キャプチャボード //
|
||
if(( iic_mcu_read_a_byte( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_VERSION ) == 0x01 ) &&
|
||
( iic_mcu_result == ERR_OK ))
|
||
{
|
||
system_status.captureBox = 1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 実機、残量IC NACK( バッテリ無しまたは残量IC故障 )
|
||
system_status.model = MODEL_JIKKI;
|
||
}
|
||
|
||
// 電池メーカーの識別 //
|
||
if( temp > 233 )
|
||
battery_manufacturer = BT_VENDER_OPEN;
|
||
else if( temp > 197 )
|
||
battery_manufacturer = BT_VENDER_6;
|
||
else if( temp > 158 )
|
||
battery_manufacturer = BT_VENDER_PANA;
|
||
else if( temp > 123 )
|
||
battery_manufacturer = BT_VENDER_4;
|
||
else if( temp > 79 )
|
||
battery_manufacturer = BT_VENDER_3;
|
||
else if( temp > 33 )
|
||
battery_manufacturer = BT_VENDER_2;
|
||
else if( temp > 5 )
|
||
battery_manufacturer = BT_VENDER_1;
|
||
else
|
||
battery_manufacturer = BT_VENDER_MAXELL;
|
||
|
||
|
||
if( ( battery_manufacturer == BT_VENDER_OPEN ) &&
|
||
( system_status.model == MODEL_JIKKI ) )
|
||
{
|
||
system_status.model = MODEL_JIKKI_NOBATT;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
static void BT_mgic_quick_start()
|
||
{
|
||
union{
|
||
u16 _u16; // endian 注意
|
||
struct{
|
||
u8 lsb;
|
||
u8 msb;
|
||
}chars;
|
||
}dat_16;
|
||
|
||
wait_ms( 10 ); // MGICの起動に掛かる
|
||
|
||
dat_16._u16 = swap_endian_16( 0x4000 );
|
||
// 0. バッテリ残量IC クイックスタート
|
||
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_MODE, 2, &dat_16 );
|
||
|
||
wait_ms( 150 );
|
||
}
|
||
|
||
|
||
|
||
static void BT_mgic_init()
|
||
{
|
||
u8 temp;
|
||
u8 origParam[4];
|
||
union{
|
||
u16 _u16; // endian 注意
|
||
struct{
|
||
u8 lsb;
|
||
u8 msb;
|
||
}chars;
|
||
}dat_16;
|
||
|
||
bt_comp = BT_COMP[ battery_manufacturer ]; // バッテリパラメータ変更
|
||
|
||
/*
|
||
// -1. リセットをかけてみる
|
||
dat_16._u16 = swap_endian_16( 0x5400 ); // reset
|
||
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_COMMAND, 2, &dat_16 ); // こいつはNACKを返す
|
||
*/
|
||
|
||
if( system_status.model != MODEL_JIKKI )
|
||
{
|
||
return;
|
||
// おしまい
|
||
}
|
||
|
||
// 1. ロック解除
|
||
dat_16._u16 = swap_endian_16( 0x4A57 ); // unlock key
|
||
if( iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_LOCK, 2, &dat_16 ) != ERR_SUCCESS )
|
||
{
|
||
// 残量IC NACK
|
||
vreg_ctr[ VREG_C_STATUS_1 ] |= REG_BIT_GASGAUGE_ERR;
|
||
return;
|
||
// おしまい
|
||
}
|
||
|
||
vreg_ctr[ VREG_C_STATUS_1 ] &= ~REG_BIT_GASGAUGE_ERR;
|
||
|
||
// wait_ms( 5 + 1 ); 前にウェイト入れてるので不要
|
||
|
||
// 2. 初期パラメータを一時保存
|
||
iic_mcu_read( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_RCOMP, 4, origParam );
|
||
|
||
// 3. 一時的にOCVを変更
|
||
dat_16._u16 = swap_endian_16( BT_OCV[ battery_manufacturer ] ); // マジックナンバー的なもの。メーカー指定
|
||
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 );
|
||
|
||
// 5.メーカー別パラメータのロード
|
||
{
|
||
// 16バイトごとに区切れとのこと
|
||
iic_mcu_set_wo_dma( );
|
||
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_BT_PARAM, 16, &BT_PARAM[ battery_manufacturer ] );
|
||
iic_mcu_set_wo_dma( );
|
||
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_BT_PARAM +16, 16, &BT_PARAM[ battery_manufacturer ][16] );
|
||
iic_mcu_set_wo_dma( );
|
||
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_BT_PARAM +32, 16, &BT_PARAM[ battery_manufacturer ][32] );
|
||
iic_mcu_set_wo_dma( );
|
||
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_BT_PARAM +48, 16, &BT_PARAM[ battery_manufacturer ][48] );
|
||
}
|
||
|
||
// 6. 150ms以上待つ
|
||
wait_ms( 150 + 15 );
|
||
|
||
// 7. OCVに「とある値」を書く
|
||
dat_16._u16 = swap_endian_16( BT_OCV[ battery_manufacturer ] ); // マジックナンバー的なもの。メーカー指定
|
||
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_OCV, 2, &dat_16 );
|
||
|
||
// 8. 150~600ms待つ。600msは厳守
|
||
wait_ms( 150 + 15 );
|
||
|
||
// 9. SOCを読む。ベリファイのため。
|
||
temp = iic_mcu_read_a_byte( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_SOC );
|
||
|
||
if(( BT_VERIFY_L[ battery_manufacturer ] <= temp ) && ( temp <= BT_VERIFY_H[ battery_manufacturer ] ))
|
||
{
|
||
// カスタムモデル書き込みOK!
|
||
}else{
|
||
// 失敗だったらリトライするのか?
|
||
// NOP();
|
||
}
|
||
|
||
// 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 );
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
extern u16 _dbg_rcomp;
|
||
/* ========================================================
|
||
raw_adc_temperatureに入っている値を℃に変換するとともに、
|
||
・レジスタにセット
|
||
・残量ICにセット
|
||
======================================================== */
|
||
task_status_immed tski_BT_temp_update( )
|
||
{
|
||
static u8 rawdat_old;
|
||
static s8 temperature;
|
||
s16 newrcomp;
|
||
static u8 heikinka;
|
||
|
||
/*
|
||
サーミスタ - 10kΩ分圧点の時、
|
||
常用温度では分圧比のカーブがほぼリニアで、
|
||
村田 T[℃] = 81.48 - 111.97 x ratio
|
||
TDK T = 81.406 - 111.81 x ratio
|
||
*/
|
||
|
||
if( rawdat_old != raw_adc_temperature )
|
||
{
|
||
if( heikinka < 40 )
|
||
{
|
||
heikinka++;
|
||
}
|
||
else
|
||
{
|
||
heikinka = 0;
|
||
rawdat_old = raw_adc_temperature;
|
||
// temperature = 81.45 - 111.9 * raw_adc_temperature/256.0;
|
||
// それぞれ256倍してある
|
||
temperature = ( 20851 - 112 * raw_adc_temperature + (256/2) ) /256;
|
||
vreg_ctr[VREG_C_BT_TEMP] = (u8)temperature;
|
||
|
||
newrcomp = 0;
|
||
if( temperature > 20 )
|
||
{
|
||
newrcomp = ( ( temperature - 20 ) * bt_comp.temp_co_up )/256;
|
||
}
|
||
else
|
||
{
|
||
newrcomp = ( ( temperature - 20 ) * bt_comp.temp_co_dn )/256;
|
||
}
|
||
newrcomp = bt_comp.rcomp + newrcomp;
|
||
|
||
if( newrcomp > 255 )
|
||
{
|
||
newrcomp = 255;
|
||
}
|
||
if( newrcomp < 0 )
|
||
{
|
||
newrcomp = 0;
|
||
}
|
||
newrcomp = newrcomp;
|
||
_dbg_rcomp = newrcomp;
|
||
|
||
if( iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_RCOMP, 2, &newrcomp ) == ERR_SUCCESS )
|
||
{
|
||
rawdat_old = raw_adc_temperature;
|
||
}
|
||
else
|
||
{
|
||
vreg_ctr[ VREG_C_STATUS_1 ] |= REG_BIT_GASGAUGE_ERR;
|
||
}
|
||
}
|
||
}
|
||
return ( ERR_FINISED );
|
||
}
|
||
|
||
|
||
|
||
/**********************************************************
|
||
電池残量ICから残量を取得し、レジスタに書き込む。
|
||
電池残量ICが無い・故障などの時はとりあえず残量99%とする。
|
||
↑は status_1で確認可能。電源投入時にチェックしています。
|
||
BT_chk()が実行されている必要があります。
|
||
**********************************************************/
|
||
void BT_get_left(){
|
||
u8 temp_fuel[2];
|
||
static u16 hysteresis;
|
||
|
||
#ifdef _DEBUG_BT_FUEL_
|
||
if( vreg_ctr[ VREG_C_COMMAND3 ] == 'd' )
|
||
{
|
||
vreg_ctr[ VREG_C_BT_REMAIN ] = vreg_ctr[ VREG_C_DBG01 ];
|
||
}
|
||
else
|
||
#endif
|
||
{
|
||
if( system_status.model == MODEL_TS_BOARD )
|
||
{
|
||
// TS //
|
||
vreg_ctr[ VREG_C_BT_REMAIN ] = 99;
|
||
vreg_ctr[ VREG_C_BT_VOLTAGE ] = 200;
|
||
}
|
||
else if( system_status.model == MODEL_SHIROBAKO )
|
||
{
|
||
// 白箱 //
|
||
if( iic_mcu_read( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_SOC, 2, temp_fuel ) != ERR_SUCCESS )
|
||
{
|
||
// エミュレーション機能がおかしい
|
||
vreg_ctr[ VREG_C_BT_REMAIN ] = 99;
|
||
}
|
||
else
|
||
{
|
||
vreg_ctr[ VREG_C_BT_REMAIN ] = temp_fuel[0];
|
||
vreg_ctr[ VREG_C_BT_REMAIN_FINE ] = temp_fuel[1];
|
||
}
|
||
vreg_ctr[ VREG_C_BT_VOLTAGE ] = 200;
|
||
}
|
||
else
|
||
{
|
||
// 実機 //
|
||
u8 temp_v[2];
|
||
u8 temp_force_fule_left;
|
||
u16 temp16;
|
||
|
||
// 残量リード
|
||
if( iic_mcu_read( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_SOC, 2, temp_fuel ) != ERR_SUCCESS )
|
||
{
|
||
// 残量ICがNACK
|
||
vreg_ctr[ VREG_C_STATUS_1 ] |= REG_BIT_GASGAUGE_ERR;
|
||
bt_chg_ready = false;
|
||
vreg_ctr[ VREG_C_BT_REMAIN ] = 0;
|
||
system_status.force_off = 1; // 強制電源断フラグ(カウンタ)
|
||
}
|
||
else
|
||
{
|
||
// バッテリパラメータの関係でビットシフトが必要
|
||
temp16 = ( temp_fuel[0] << 8 ) + temp_fuel[1];
|
||
temp16 /= BT_RCOMP_SCALE[ battery_manufacturer ];
|
||
temp_fuel[0] = ( temp16 >> 8 ) & 0xFF;
|
||
temp_fuel[1] = temp16 & 0xFF;
|
||
|
||
// 電圧でキャップ
|
||
if( iic_mcu_read( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_VCELL, 2, temp_v ) == ERR_SUCCESS )
|
||
{
|
||
vreg_ctr[ VREG_C_BT_VOLTAGE ] = temp_v[0];
|
||
|
||
temp16 = ( temp_v[0] << 8 ) + temp_v[1];
|
||
|
||
if( temp16 > V_TH_30 )
|
||
{
|
||
temp_force_fule_left = 100;
|
||
hysteresis = 0;
|
||
}
|
||
else if( temp16 > V_TH_LO + hysteresis )
|
||
{
|
||
temp_force_fule_left = 30;
|
||
hysteresis = 0;
|
||
}
|
||
else if( temp16 > V_TH_EMPTY )
|
||
{
|
||
temp_force_fule_left = BATT_TH_LO; // ここから赤
|
||
hysteresis = 500;
|
||
}
|
||
else if( temp16 > V_TH_ZERO )
|
||
{
|
||
temp_force_fule_left = BATT_TH_EMPTY;
|
||
hysteresis = 500;
|
||
}
|
||
else
|
||
{
|
||
// temp_force_fule_left = 0;
|
||
system_status.force_off = 1; // 強制電源断フラグ(カウンタ)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 充電許可(=アダプタも刺さってる)のに充電してない = 充電完了
|
||
if( BT_CHG_Ena && !BT_IN_CHG_n ){
|
||
vreg_ctr[ VREG_C_BT_REMAIN ] = 100;
|
||
vreg_ctr[ VREG_C_BT_REMAIN_FINE ] = 0;
|
||
}
|
||
else
|
||
{ // 少ない方にキャップ
|
||
if( temp_force_fule_left > temp_fuel[0] )
|
||
{
|
||
vreg_ctr[ VREG_C_BT_REMAIN ] = temp_fuel[0];
|
||
vreg_ctr[ VREG_C_BT_REMAIN_FINE ] = temp_fuel[1];
|
||
}
|
||
else
|
||
{
|
||
vreg_ctr[ VREG_C_BT_REMAIN ] = temp_force_fule_left;
|
||
vreg_ctr[ VREG_C_BT_REMAIN_FINE ] = 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// 残量で割り込み。急激に減ると飛ぶことがある //
|
||
{
|
||
static u8 bt_remain_old_ctr;
|
||
|
||
if( system_status.pwr_state == OFF_TRIG )
|
||
{
|
||
bt_remain_old_ctr = 100;
|
||
}
|
||
|
||
// twlに教えてあげる(先にやらないと割り込みのタイミングがまずいかもしれない)
|
||
if( bt_remain_old_ctr != vreg_ctr[ VREG_C_BT_REMAIN ] )
|
||
{
|
||
if( vreg_ctr[ VREG_C_BT_REMAIN ] > 80 ){
|
||
vreg_twl[ REG_TWL_INT_ADRS_POWER_INFO ] = 0x0F;
|
||
}else if( vreg_ctr[ VREG_C_BT_REMAIN ] > 50 ){
|
||
vreg_twl[ REG_TWL_INT_ADRS_POWER_INFO ] = 0x0B;
|
||
}else if( vreg_ctr[ VREG_C_BT_REMAIN ] > BATT_TH_LO ){
|
||
vreg_twl[ REG_TWL_INT_ADRS_POWER_INFO ] = 0x07;
|
||
}else if( vreg_ctr[ VREG_C_BT_REMAIN ] > BATT_TH_EMPTY ){
|
||
vreg_twl[ REG_TWL_INT_ADRS_POWER_INFO ] = 0x03;
|
||
}else if( vreg_ctr[ VREG_C_BT_REMAIN ] > 0 ){
|
||
vreg_twl[ REG_TWL_INT_ADRS_POWER_INFO ] = 0x01;
|
||
}else{
|
||
vreg_twl[ REG_TWL_INT_ADRS_POWER_INFO ] = 0x00;
|
||
}
|
||
}
|
||
|
||
// CTRに通知
|
||
{
|
||
if( (( vreg_ctr[ VREG_C_BT_REMAIN ] <= BATT_TH_LO ) && ( BATT_TH_LO < bt_remain_old_ctr ))||
|
||
(( vreg_ctr[ VREG_C_BT_REMAIN ] <= BATT_TH_EMPTY ) && ( BATT_TH_EMPTY < bt_remain_old_ctr ))||
|
||
(( vreg_ctr[ VREG_C_BT_REMAIN ] == 0 ) && ( bt_remain_old_ctr != 0 )) )
|
||
{
|
||
set_irq( VREG_C_IRQ1, REG_BIT_BT_REMAIN );
|
||
}
|
||
}
|
||
|
||
bt_remain_old_ctr = vreg_ctr[ VREG_C_BT_REMAIN ];
|
||
}
|
||
|
||
// PMIC-NTRに電池残量を教えてあげる
|
||
{
|
||
static bit initialized;
|
||
static bit flag; // あれ?staticでないとコンパイラに怒られる
|
||
|
||
if( system_status.pwr_state == OFF_TRIG )
|
||
{
|
||
initialized = false;
|
||
}
|
||
else
|
||
{
|
||
|
||
flag = (( vreg_ctr[ VREG_C_BT_REMAIN ] <= BATT_TH_LO )? NTR_PM_BT_EMPTY: NTR_PM_BT_ENOUGH ); // 1で電池切れ
|
||
|
||
if(( ntr_pm_bt_low_old != flag ) || !initialized )
|
||
{
|
||
initialized = true;
|
||
ntr_pm_bt_low_old = flag;
|
||
iic_mcu_write_a_byte_codec( CODEC_REG_BT, flag );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
液晶系の電源制御
|
||
ステータスフラグはすぐに立ててしまう。
|
||
不感応時間があるし、
|
||
起動失敗であれば電源が落ちる
|
||
別のタスクで電源落ちは監視していて、ステータスもクリアする
|
||
======================================================== */
|
||
// BSR //
|
||
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 );
|
||
|
||
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_SND_ENABLE;
|
||
return ( ERR_ERR );
|
||
}
|
||
return ( ERR_SUCCESS );
|
||
}
|
||
|
||
// BSR //
|
||
void PM_LCD_off()
|
||
{
|
||
SND_DEPOP_SND_MUTE;
|
||
|
||
// BLついてたら消す
|
||
if( ( iic_mcu_read_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_BL ) & 0x03 ) != 0 )
|
||
{
|
||
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 );
|
||
}
|
||
|
||
if( iic_mcu_read_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_VDD_LCD ) != 0 )
|
||
{
|
||
PM_TCOM_off();
|
||
wait_ms( 1 );
|
||
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 )
|
||
{
|
||
u8 blset;
|
||
u8 intset = 0;
|
||
// RMWを行う
|
||
|
||
// Read
|
||
blset = iic_mcu_read_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_BL ) ;
|
||
|
||
// 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;
|
||
}
|
||
|
||
if( blset != 0 ) // BLを付ける場合はウェイトを挟まないとPWMが来ておらず
|
||
// シャットダウンすることがある
|
||
{
|
||
wait_ms( 16 + 10 );
|
||
// wait_ms( 84 ); ミツミの1stバグ回避
|
||
}
|
||
iic_mcu_write_a_byte( IIC_SLA_PMIC, PM_REG_ADRS_BL, blset );
|
||
|
||
#if 0
|
||
// SoCがPWMを出すようレジスタをセットしてから遅延が有るため、ステータスを先に
|
||
// 更新してしまう。
|
||
#endif
|
||
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;
|
||
}
|
||
}
|
||
|
||
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 );
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
↑で、レジスタ書き込みから呼び出される時のため
|
||
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( )
|
||
{
|
||
// 電源順次立ち上げ
|
||
// PM_reset_ast( ); 不要 PM_LDSW_onまかせ
|
||
RESET2_ast;
|
||
FCRAM_RST_ast;
|
||
GYRO_DISABLE();
|
||
|
||
PM_LDSW_on( );
|
||
|
||
wait_ms( 1 + DELAY_PM_TW_PWUP );
|
||
|
||
PM_VDD_normMode();
|
||
PM_VDD_on( );
|
||
// wait_ms( DELAY_PM_TW_PWUP ); // GYROを挟むため
|
||
wait_ms( 10 );
|
||
GYRO_ENABLE();
|
||
wait_ms( DELAY_PM_TW_PWUP - 10 );
|
||
|
||
PM_VDD50A_on( ); // 液晶電源ではなく、ledとかに使うものです
|
||
|
||
wait_ms( DELAY_PM_TW_PWUP );
|
||
|
||
// 無事電源が起動したかチェック。
|
||
if( !PM_chk_LDSW() )
|
||
{
|
||
return ( ERR_ERR ); // reset1はほっといて良い
|
||
}
|
||
|
||
PM_reset_neg();
|
||
FCRAM_RST_neg;
|
||
RESET2_neg;
|
||
|
||
codec_reg_init(); // CODEC 不定レジスタ初期化
|
||
reg_shadow = 0; // 〃 こんなところで...
|
||
|
||
return ( ERR_SUCCESS );
|
||
}
|
||
|
||
|
||
|
||
|
||
/* ========================================================
|
||
電源OFFシーケンス
|
||
======================================================== */
|
||
err PM_sys_pow_off( )
|
||
{
|
||
// if( RESET1_n )
|
||
if( PM_chk_LDSW() )
|
||
{
|
||
// 異常時は呼ばない
|
||
PM_BL_set( REG_BIT_CMD_BL_U_OFF | REG_BIT_CMD_BL_L_OFF );
|
||
PM_LCD_off(); // TCOM,VCS OFF も消してきます。
|
||
wait_ms( 20 );
|
||
|
||
PM_reset_ast();
|
||
}
|
||
|
||
RESET2_ast;
|
||
FCRAM_RST_ast;
|
||
|
||
PM_off( );
|
||
PM_LDSW_off( );
|
||
|
||
return ( ERR_SUCCESS );
|
||
}
|
||
|
||
|
||
|
||
/*=========================================================
|
||
extDC割り込み
|
||
電源OFFから起こす(充電の温度監視のため)のみ
|
||
普段はポーリング(pm)
|
||
=========================================================*/
|
||
__interrupt void intp4_extdc( )
|
||
{
|
||
// chg_led_override = (u8)( 1000 / INTERVAL_TSK_BATT / SYS_INTERVAL_TICK );
|
||
// chg_led_override = 4;
|
||
}
|
||
|
||
|
||
|
||
/*=========================================================
|
||
フタ開け閉め割り込み
|
||
普段はポーング(misc)
|
||
=========================================================*/
|
||
__interrupt void intp5_shell( )
|
||
{
|
||
;
|
||
}
|
||
|
||
|
||
/*=========================================================
|
||
旧PMICへのコマンド書き込み
|
||
=========================================================*/
|
||
__interrupt void intp6_PM_irq( )
|
||
{
|
||
EI();
|
||
if( system_status.pwr_state == ON )
|
||
{
|
||
renge_task_immed_add( ntr_pmic_comm );
|
||
}
|
||
}
|
||
|
||
|
||
#define _type1_
|
||
/* ========================================================
|
||
PMICからの割り込みを受けて、NTR PMIC互換レジスタからリード
|
||
======================================================== */
|
||
task_status_immed ntr_pmic_comm( )
|
||
{
|
||
u8 reg1_old;
|
||
u8 irq_work = 0;
|
||
|
||
reg1_old = reg_shadow;
|
||
reg_shadow = iic_mcu_read_a_byte( IIC_SLA_CODEC, CODEC_REG_PM );
|
||
if( iic_mcu_result != 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 ) // 消えた
|
||
{
|
||
#ifdef _type1_
|
||
irq_work = REG_BIT_TWL_BL_U_OFF;
|
||
#else
|
||
set_irq( VREG_C_IRQ2, REG_BIT_TWL_BL_U_OFF );
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
#ifdef _type1_
|
||
irq_work = REG_BIT_TWL_BL_U_ON;
|
||
#else
|
||
set_irq( VREG_C_IRQ2, REG_BIT_TWL_BL_U_ON );
|
||
#endif
|
||
}
|
||
}
|
||
|
||
// バックライト 下
|
||
if( ( ( reg1_old ^ reg_shadow ) & REG_BIT_TWL_REQ_BL_L ) != 0 )
|
||
{
|
||
if( ( reg_shadow & REG_BIT_TWL_REQ_BL_L ) == 0 ) // 消えた
|
||
{
|
||
#ifdef _type1_
|
||
irq_work |= REG_BIT_TWL_BL_L_OFF;
|
||
#else
|
||
set_irq( VREG_C_IRQ2, REG_BIT_TWL_BL_L_OFF );
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
#ifdef _type1_
|
||
irq_work |= REG_BIT_TWL_BL_L_ON;
|
||
#else
|
||
set_irq( VREG_C_IRQ2, REG_BIT_TWL_BL_L_ON );
|
||
#endif
|
||
}
|
||
}
|
||
|
||
// EI();
|
||
|
||
vreg_ctr[ VREG_C_STATUS_1 ] = ( vreg_ctr[ VREG_C_STATUS_1 ] & ~0x0C ) | ( reg_shadow & 0x0C ); // TWLバックライト情報のミラー
|
||
|
||
#ifdef _type1_
|
||
irq_work &= ~vreg_ctr[ VREG_C_IRQ_MASK2 ];
|
||
// set_irq 相当品
|
||
if( irq_work != 0 )
|
||
{
|
||
u8 tot;
|
||
|
||
vreg_ctr[ VREG_C_IRQ2 ] |= irq_work;
|
||
IRQ0_neg; // 一瞬上げてパルスを送り直す
|
||
tot = 0;
|
||
while( !IRQ0 && ( ++tot != 0 ) ){;} // O.Dなのでちゃんとあがるのを待つ & IRQ_mcu がLに縛られてると困る(基板不良)
|
||
IRQ0_ast;
|
||
}
|
||
#endif
|
||
|
||
#if 0
|
||
// バックライト設定
|
||
// 勝手に消しておく
|
||
/// 今のところさらに細かくは分けないけど…
|
||
if( ( reg_shadow & ( REG_BIT_TWL_REQ_BL_U | REG_BIT_TWL_REQ_BL_U ) ) == 0 )
|
||
{
|
||
vreg_ctr[ VREG_C_COMMAND2 ] = ( REG_BIT_CMD_BL_U_OFF | REG_BIT_CMD_BL_U_OFF );
|
||
renge_task_immed_add( tski_PM_BL_set );
|
||
}
|
||
#endif
|
||
|
||
// 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 )
|
||
{
|
||
#if 0
|
||
// CODECバグ回避
|
||
// リセット単品でなかったら無視
|
||
if( ( reg1_old ^ reg_shadow ) == REG_BIT_TWL_REQ_RST_REQ )
|
||
#endif
|
||
{
|
||
set_irq( VREG_C_IRQ2, REG_BIT_TWL_RESET_REQ );
|
||
}
|
||
}
|
||
|
||
// バックライトをマスクして書き戻す
|
||
EI( );
|
||
if( ( reg_shadow & ( REG_BIT_TWL_REQ_OFF_REQ | REG_BIT_TWL_REQ_RST_REQ )) != 0 )
|
||
{
|
||
reg_shadow &= ~( REG_BIT_TWL_REQ_OFF_REQ | REG_BIT_TWL_REQ_RST_REQ );
|
||
iic_mcu_write_a_byte_codec( CODEC_REG_PM, reg_shadow );
|
||
}
|
||
return ( ERR_FINISED );
|
||
}
|
||
|
||
|
||
|
||
/**********************************************************
|
||
command2 液晶系
|
||
ラッパー的な物。ERR_SUCCESSしか返さないが…
|
||
**********************************************************/
|
||
task_status_immed tski_PM_LCD_on()
|
||
{
|
||
PM_LCD_on();
|
||
return( ERR_FINISED );
|
||
}
|
||
|
||
task_status_immed tski_PM_LCD_off()
|
||
{
|
||
PM_LCD_off();
|
||
return( ERR_FINISED );
|
||
}
|
||
|
||
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] ); // <- PM_BL_setが更新する
|
||
vreg_ctr[VREG_C_COMMAND2] = 0;
|
||
|
||
return( ERR_FINISED );
|
||
}
|
||
|
||
|
||
|
||
/**********************************************************
|
||
reset2 で CODEC にリセットがかかり、レジスタが不定になるため
|
||
**********************************************************/
|
||
void codec_reg_init()
|
||
{
|
||
wait_ms( 100 );
|
||
|
||
ntr_pm_bt_low_old = (( vreg_ctr[ VREG_C_BT_REMAIN ] <= BATT_TH_LO )? NTR_PM_BT_EMPTY: NTR_PM_BT_ENOUGH ); // 1で電池切れ
|
||
iic_mcu_write_a_byte_codec( CODEC_REG_BT, ntr_pm_bt_low_old ); // SoC から書けず
|
||
|
||
vol_reset();
|
||
renge_task_immed_add( tski_vol_update );
|
||
}
|