mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-06-18 16:45:33 -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@613 013db118-44a6-b54f-8bf7-843cb86687b1
1540 lines
41 KiB
C
1540 lines
41 KiB
C
/* ========================================================
|
||
対PMIC
|
||
藤田@開技
|
||
nintendo
|
||
'08 Dec
|
||
|
||
$Id: pm.c 418 2011-09-22 01:35:37Z n2232 $
|
||
======================================================== */
|
||
#ifndef _WIN32
|
||
|
||
#pragma nop
|
||
|
||
#endif
|
||
|
||
#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"
|
||
|
||
#include "vreg_twl.h"
|
||
#include "i2c_mcu.h"
|
||
|
||
// ========================================================
|
||
u8 raw_adc_temperature;
|
||
BT_VENDER battery_manufacturer = BT_VENDER_NOT_CHECKED;
|
||
static u8 ntr_pm_reg_shadow; // NTR PMIC レジスタミラー
|
||
bit bt_authorized; // バッテリパラメータ送信済。充電開始許可
|
||
u8 chg_led_override; // アダプタ差したとき、充電するしないに関わらずしばらく点灯させる
|
||
|
||
static u16 bt_volt16;
|
||
|
||
static bit ntr_pm_bt_low_old;
|
||
|
||
bit BT_IN_CHG_delayed_n;
|
||
bit temp_zone_charge_disable; // 温度で充電停止する時にヒステリシスを付けるため
|
||
|
||
u8 pmic_version;
|
||
u8 mgic_version[2];
|
||
|
||
u8 pm_reg_bit_vddlcd;
|
||
|
||
static bt_param_* p_bt_param;
|
||
extern const bt_param_ bt_param[];
|
||
|
||
bit pm_extdc_old; // 前回アダプタチェックしたとき刺さっていたか?
|
||
|
||
u8 pmreg_v_core; // SoCのコア電圧設定。SNAKE(LAGER)で変更があるため。
|
||
|
||
#define K_RCOMP_SEG 0x0080
|
||
|
||
// 充電停止温度関係
|
||
static u8 raw_temp_lh;
|
||
static u8 raw_temp_ll;
|
||
#define RAW_TEMP_HL 184 // 1
|
||
#define RAW_TEMP_HH 189 // -1
|
||
#define RAW_TEMP_LH_CTR 75 // 50 [degC]
|
||
#define RAW_TEMP_LL_CTR 61 // 59
|
||
#define RAW_TEMP_LH_SNAKE 84 // 45
|
||
#define RAW_TEMP_LL_SNAKE 68 // 54
|
||
|
||
|
||
// ========================================================
|
||
static void BT_model_detect();
|
||
static void BT_mgic_quick_start();
|
||
static void BT_mgic_init();
|
||
static void bt_chk_temparature();
|
||
static void bt_get_charge_status();
|
||
static void bt_param_select();
|
||
static void bt_batt_update_twl();
|
||
static void bt_batt_update_ntr();
|
||
static void update_chg_led();
|
||
|
||
|
||
// ラッパー
|
||
static err send_cmd_mgic_2B( u8 reg, u16 dat );
|
||
static err read_mgic_2B( u8 reg, u8* dat );
|
||
static err read_BT_SOC( u8* dest );
|
||
static err read_BT_voltage( u8* dest );
|
||
static u8 conv_ctr_bt_to_twl_bt();
|
||
|
||
|
||
|
||
// ========================================================
|
||
#define swap_endian_16( x ) (unsigned int)(( x << 8 ) | ( x >> 8 ))
|
||
|
||
|
||
|
||
// ========================================================
|
||
const u8 BT_MANUF_BORDER[] = {
|
||
5, 33, 79, 123, 158, 197, 233
|
||
};
|
||
|
||
|
||
|
||
/********************************************//**
|
||
電池の管理
|
||
|
||
以下のピンは主にここで操作・監視されます。
|
||
- PM_BT_AUTH 現状、GPI in
|
||
- PM_CHARGE_n CCIC /CHG in
|
||
- PM_EXTDC_n /DOK INTP4 in
|
||
- PM_CHARGE_EN_n /CEN out
|
||
|
||
以下の物は関係ありそうですが別のところで監視されています。
|
||
- LED Charge tsk_LED
|
||
- BT_TEMP,_P tsk_ADC
|
||
|
||
PM_EXTDCは割り込みメインにするかも
|
||
***********************************************/
|
||
#define INTERVAL_TSK_BATT 60
|
||
// ↑100だと充電エラー時にうまく点滅しないので
|
||
|
||
/********************************************//**
|
||
電源周りの監視
|
||
- アダプタの監視
|
||
- 充電制御、LED更新
|
||
- 残量取得、LED更新
|
||
***********************************************/
|
||
void tsk_batt( )
|
||
{
|
||
static u8 task_interval;
|
||
|
||
if( task_interval -- != 0 )
|
||
{
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
task_interval = (u8)( INTERVAL_TSK_BATT / SYS_INTERVAL_TICK );
|
||
}
|
||
|
||
// アダプタステータス更新 //
|
||
pm_chk_adapter();
|
||
|
||
// 充電 //
|
||
bt_chk_temparature(); // 温度チェック
|
||
if( !temp_zone_charge_disable && bt_authorized && !PM_EXTDC_n )
|
||
{
|
||
BT_CHG_ENABLE(); // 温度範囲OKで充電再開
|
||
}
|
||
else
|
||
{
|
||
BT_CHG_DISABLE(); // 温度危険! 充電停止
|
||
}
|
||
|
||
bt_get_charge_status(); // 充電状況チェック
|
||
update_chg_led(); // chg led更新
|
||
|
||
// 電池残量 //
|
||
BT_get_left();
|
||
}
|
||
|
||
|
||
/********************************************//**
|
||
充電LED更新
|
||
|
||
- CCICが充電中といえば点灯する。
|
||
- でなくても、アダプタ刺したばかりなら5秒点灯する
|
||
- ただし、ヘタレ電池対応で嘘充電中の時、ヒューズ切れ(MGICがNAK)なら消灯
|
||
***********************************************/
|
||
static void update_chg_led()
|
||
{
|
||
static bit temp_led_chg; // static つけないとコンパイル通らず
|
||
|
||
temp_led_chg = false;
|
||
|
||
// アダプタつないだ瞬間、満充電でも数秒わざと点灯させる。給電してることをわからせるため。
|
||
if( chg_led_override != 0 )
|
||
{
|
||
chg_led_override --;
|
||
temp_led_chg = true;
|
||
}
|
||
|
||
// CCIC は充電中と言っているか?
|
||
if( ! BT_IN_CHG_delayed_n // bt_get_charge_status()で更新されます。
|
||
&& ! PM_EXTDC_n )
|
||
{
|
||
temp_led_chg = true;
|
||
}
|
||
|
||
LED_CHARGE = temp_led_chg;
|
||
|
||
// レジスタの充電中ビットはLEDに同期する
|
||
set_bit_if( LED_CHARGE, vreg_ctr[VREG_C_STATUS], REG_BIT_BATT_CHARGE ); // set_bit_ifのみ。
|
||
/// 割り込みはtask_status()で行う
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
温度チェック
|
||
温度付きヒステリシス有り
|
||
***********************************************/
|
||
#define AVG_COUNT 40
|
||
void bt_chk_temparature()
|
||
{
|
||
static u8 heikinka_h,heikinka_l;
|
||
|
||
if(( raw_temp_lh <= raw_adc_temperature )
|
||
&& ( raw_adc_temperature <= RAW_TEMP_HL ))
|
||
{
|
||
if( heikinka_h < AVG_COUNT )
|
||
{
|
||
heikinka_h++;
|
||
}
|
||
else
|
||
{
|
||
temp_zone_charge_disable = false; // 充電許可
|
||
}
|
||
}
|
||
else if(( raw_adc_temperature <= raw_temp_ll )
|
||
|| ( RAW_TEMP_HH <= raw_adc_temperature ))
|
||
{
|
||
if( heikinka_l < AVG_COUNT )
|
||
{
|
||
heikinka_l++;
|
||
}
|
||
else
|
||
{
|
||
temp_zone_charge_disable = true; // 充電禁止
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// temp_zone_charge_disable そのまま
|
||
heikinka_h = 0;
|
||
heikinka_l = 0;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
充電中かのチェック
|
||
|
||
充電ICのバグ対策も行う。
|
||
***********************************************/
|
||
#define TIME_DENOIZE (u8)( 1000 / INTERVAL_TSK_BATT )
|
||
void bt_get_charge_status()
|
||
{
|
||
// CCICの不具合回避のため、/CHGのネゲートをちょっと丁寧に遅延させる
|
||
static u8 anti_chatter;
|
||
|
||
if( !BT_IN_CHG_n )
|
||
{
|
||
// さらにチャタリング除去
|
||
if( anti_chatter < 2 ) // 電池無しでアダプタさして、電極をさわさわ
|
||
{ // すると充電LEDががさがさするので
|
||
anti_chatter++;
|
||
}
|
||
else
|
||
|
||
{
|
||
BT_IN_CHG_delayed_n = 0; // 充電中
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if( !BT_CHG_Ena_n
|
||
&& ( vreg_ctr[ VREG_C_BT_REMAIN ] < 60 )
|
||
&& !( is_mgic_error )
|
||
)
|
||
{
|
||
BT_IN_CHG_delayed_n = 0; // 充電中と扱う。充電が終わっているはずがない
|
||
}
|
||
else
|
||
{
|
||
BT_IN_CHG_delayed_n = 1;
|
||
anti_chatter = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
アダプタの有無チェック
|
||
***********************************************/
|
||
void pm_chk_adapter()
|
||
{
|
||
set_bit_if( !PM_EXTDC_n, vreg_ctr[VREG_C_STATUS], REG_BIT_POW_SUPPLY );
|
||
|
||
if( pm_extdc_old != PM_EXTDC_n ) // HAL を通すため、 PM_EXTDC_n の volatile にする心配なし
|
||
{
|
||
pm_extdc_old = PM_EXTDC_n;
|
||
if( !PM_EXTDC_n )
|
||
{
|
||
// 刺さった
|
||
set_irq( VREG_C_IRQ1, REG_BIT_BT_DC_CONNECT );
|
||
chg_led_override = (u8)( 2500 / INTERVAL_TSK_BATT ); // bt_chckのwait_ms(5)のせいで伸ばされる。
|
||
}
|
||
else
|
||
{
|
||
u8 temp_v[2];
|
||
|
||
// 抜けた
|
||
set_irq( VREG_C_IRQ1, REG_BIT_BT_DC_DISC );
|
||
chg_led_override = 0;
|
||
|
||
// 電池残量が1%台で、アダプタ有りの時には本体が起動し、ゲームが動くが
|
||
// 1%台に回復する前にアダプタが抜けたとき、割り込みを入れないと期待通りの
|
||
// 動作でない。特別対応のためここで対応
|
||
if( read_mgic_2B( BT_GAUGE_REG_VCELL, temp_v ) == ERR_SUCCESS )
|
||
{
|
||
bt_volt16 = ( temp_v[0] * 256 + temp_v[1] );
|
||
}
|
||
|
||
if(( bt_volt16 < V_TH_ZERO ) || ( vreg_ctr[ VREG_C_BT_REMAIN ] == 0 ))
|
||
{
|
||
set_irq( VREG_C_IRQ1, REG_BIT_BT_REMAIN );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/********************************************************
|
||
電池関係の初期化
|
||
|
||
ゲージ | 有り | 無し
|
||
ーーーーーーーーーーーーーーーーーーーーーーー
|
||
電池 有り| 実機 | ?
|
||
ーーーーーーーーーーーーーーーーーーーーーーー
|
||
無し| 白箱 | TS
|
||
| 実機電池無し |
|
||
ーーーーーーーーーーーーーーーーーーーーーーー
|
||
|
||
ゲージ有り、電池無し の白箱/実機判別は、
|
||
電池温度で判定する
|
||
|
||
返値: 電池無し 0xFF
|
||
電池変わってない 0
|
||
電池変わった 1
|
||
|
||
***********************************************************/
|
||
bit bt_force_update;
|
||
|
||
|
||
|
||
/********************************************//**
|
||
バッテリのチェック、と、本体種別識別(ピンを共用のため)
|
||
***********************************************/
|
||
void BT_chk()
|
||
{
|
||
static BT_VENDER battery_manufacturer_old;
|
||
|
||
battery_manufacturer_old = battery_manufacturer;
|
||
|
||
BT_model_detect();
|
||
bt_param_select(); // バッテリ残量補正パラメータなどセット 非実機でも、とりあえずの値(パナ)指定にしておく。
|
||
|
||
if( system_status.model != MODEL_JIKKI )
|
||
{
|
||
bt_authorized = 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_authorized = 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( 3 ); // 電圧が上がるのに時間が掛かる
|
||
|
||
raw_adc_temperature = get_adc( ADC_SEL_BATT_TEMP );
|
||
temp = get_adc( ADC_SEL_BATT_DET );
|
||
BT_DET_P = 0;
|
||
|
||
system_status.captureBox = false;
|
||
// プラットフォーム判定 //
|
||
if( raw_adc_temperature > 0xF0 )
|
||
{
|
||
// TS //
|
||
system_status.model = MODEL_TS_BOARD;
|
||
system_status.family = FAMILY_CTR; // 旧回路での誤判定を上書き
|
||
pm_reg_bit_vddlcd = PM_REG_BIT_VDDLCD_CGS;
|
||
// set_voltages( system_status.family ); 不要?
|
||
}
|
||
else if( raw_adc_temperature < 4 )
|
||
{
|
||
// 白箱(KuC) //
|
||
system_status.model = MODEL_KUC_DEBUGGER;
|
||
}
|
||
else
|
||
{
|
||
// 実機、残量IC NACK( バッテリ無しまたは残量IC故障 )
|
||
system_status.model = MODEL_JIKKI; // バッテリ無しの時は↓で上書きする
|
||
}
|
||
|
||
// キャプチャか? //
|
||
if( iic_mcu_read_a_byte( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_VERSION ) == 0x01 )
|
||
{
|
||
if( iic_mcu_result == I2C_ERR_OK ) // バラに書かないと評価順が処理系依存
|
||
{
|
||
system_status.captureBox = true;
|
||
}
|
||
}
|
||
|
||
// TSのhomeボタン、実機は未接続なので要端子処理 /// gndにしとけばよかった…
|
||
if( system_status.model == MODEL_TS_BOARD )
|
||
{
|
||
PM_SW_HOME_n_TSBOARD = 1;
|
||
}
|
||
else
|
||
{
|
||
PM_SW_HOME_n_TSBOARD = 0;
|
||
SW_HOME_n_TSBOARD_RAW = 0; /// 実機open どっちでもいいんだけど
|
||
}
|
||
|
||
// 電池メーカーの識別 //
|
||
{
|
||
u8 i;
|
||
|
||
battery_manufacturer = BT_VENDER_OPEN; // デフォルト値
|
||
for(i=0; i<=7; i++)
|
||
{
|
||
if( temp <= BT_MANUF_BORDER[ i ] )
|
||
{
|
||
battery_manufacturer = (BT_VENDER)i;
|
||
break;
|
||
/*
|
||
BT_VENDER_MAXELL; // = 0
|
||
BT_VENDER_1;
|
||
BT_VENDER_2;
|
||
BT_VENDER_3;
|
||
BT_VENDER_4;
|
||
BT_VENDER_PANA;
|
||
BT_VENDER_6;
|
||
|
||
BT_VENDER_OPEN;
|
||
*/
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
if( ( battery_manufacturer == BT_VENDER_OPEN ) &&
|
||
( system_status.model == MODEL_JIKKI ) )
|
||
{
|
||
system_status.model = MODEL_JIKKI_NOBATT;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
#define MGIC_CMD_QUICKSTART 0x4000
|
||
/********************************************//**
|
||
MGICクイックスタート(主にバグ対策)
|
||
***********************************************/
|
||
static void BT_mgic_quick_start()
|
||
{
|
||
wait_ms( 10 ); // MGICの起動に掛かる
|
||
|
||
// 0. バッテリ残量IC クイックスタート
|
||
send_cmd_mgic_2B( BT_GAUGE_REG_MODE, swap_endian_16( MGIC_CMD_QUICKSTART ) );
|
||
|
||
wait_ms( 150 );
|
||
}
|
||
|
||
|
||
/********************************************//**
|
||
電池残量測定初期化
|
||
|
||
電池パラメータなども転送する
|
||
***********************************************/
|
||
|
||
#define MGIC_CMD_UNLOCK_KEY 0x4A57
|
||
#define MGIC_CMD_RESET 0x5400
|
||
#define RCOMP_SIZE 16
|
||
static void BT_mgic_init()
|
||
{
|
||
u8 origParam[4];
|
||
|
||
if( system_status.model != MODEL_JIKKI )
|
||
{
|
||
return;
|
||
// おしまい
|
||
}
|
||
|
||
// 1. ロック解除
|
||
if( send_cmd_mgic_2B( BT_GAUGE_REG_LOCK, swap_endian_16( MGIC_CMD_UNLOCK_KEY ) ) != ERR_SUCCESS )
|
||
{
|
||
// 残量IC NACK
|
||
vreg_set_mgic_error;
|
||
return;
|
||
// おしまい
|
||
}
|
||
|
||
vreg_clear_mgic_error;
|
||
|
||
// wait_ms( 5 + 1 ); 前にウェイト入れてるので不要
|
||
|
||
// 2. 初期パラメータを一時保存
|
||
//. バーストリード、2バイトまでみたい。(読み出し途中の書き換わり防止のためか?)
|
||
iic_mcu_read( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_RCOMP, 2, &origParam[0] );
|
||
iic_mcu_read( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_RCOMP+2, 2, &origParam[2] );
|
||
|
||
// 3. 一時的にOCVを変更
|
||
send_cmd_mgic_2B( BT_GAUGE_REG_OCV, swap_endian_16( p_bt_param->ocv )); // マジックナンバー的なもの。メーカー指定
|
||
|
||
// 4. 一時的にRCOMPを変更
|
||
send_cmd_mgic_2B( BT_GAUGE_REG_RCOMP, swap_endian_16( 0xFF00 ) );
|
||
|
||
// 5.メーカー別パラメータのロード
|
||
{
|
||
u8 loop;
|
||
u16 temp;
|
||
|
||
// -16バイトごとに区切れとのこと (ノイズ対策とか言うんだけど、意味あるんか?)-
|
||
// 2バイト単位で送れとのこと。
|
||
for( loop = 0; loop < BATT_PARAM_SIZE; loop +=2 )
|
||
{
|
||
// 最悪
|
||
temp = *(p_bt_param->mg_param + loop) | (*(p_bt_param->mg_param + loop+1)) << 8 ;
|
||
send_cmd_mgic_2B( BT_GAUGE_REG_BT_PARAM + loop, temp );
|
||
}
|
||
}
|
||
|
||
{
|
||
// 5.1 拡張 RCOMP 更新
|
||
// 基本使わないが、不意に書き換わってしまったときのため、規定値を書く。
|
||
// 17048 で必要。17040(CTR) に書いてしまっても不具合なし
|
||
u8 loop;
|
||
|
||
for( loop=0; loop < RCOMP_SIZE*2; loop+=2 )
|
||
{
|
||
send_cmd_mgic_2B( BT_GAUGE_REG_RCOMP_EXT + loop, swap_endian_16(K_RCOMP_SEG) );
|
||
}
|
||
}
|
||
|
||
// 6. 150ms以上待つ
|
||
wait_ms( 150 + 15 );
|
||
|
||
// 7. OCVに「とある値」を書く
|
||
send_cmd_mgic_2B( BT_GAUGE_REG_OCV, swap_endian_16( p_bt_param->ocv ) ); // マジックナンバー的なもの。メーカー指定
|
||
|
||
|
||
// 7.1 ロック
|
||
send_cmd_mgic_2B( BT_GAUGE_REG_LOCK, swap_endian_16( 0x0000 ) ); // lock key
|
||
|
||
|
||
// 8. 150~600ms待つ。600msは厳守
|
||
wait_ms( 150 + 15 );
|
||
|
||
// 9. SOCを読む。ベリファイのため。
|
||
{
|
||
u8 temp;
|
||
temp = iic_mcu_read_a_byte( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_SOC );
|
||
|
||
if(( p_bt_param->verify.low <= temp ) && ( temp <= p_bt_param->verify.hi ))
|
||
{
|
||
// カスタムモデル書き込みOK!
|
||
}else{
|
||
// 失敗だったらリトライするのか?
|
||
// dbg_nop(); // 今は無視
|
||
}
|
||
}
|
||
|
||
// 9.1 再度モデル案ロック
|
||
send_cmd_mgic_2B( BT_GAUGE_REG_LOCK, swap_endian_16( MGIC_CMD_UNLOCK_KEY ) );
|
||
|
||
// 10.元のRCOMPとOCVを書き戻す
|
||
// 2B x 2times write に
|
||
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_RCOMP, 2, &origParam[0] );
|
||
iic_mcu_write( IIC_SLA_BT_GAUGE, BT_GAUGE_REG_RCOMP+2, 2, &origParam[2] );
|
||
|
||
// 11. ロック
|
||
send_cmd_mgic_2B( BT_GAUGE_REG_LOCK, swap_endian_16( 0x0000 ) ); // lock key
|
||
|
||
// 12. MAX17048時、ウェイトが必要。
|
||
wait_ms( 150 + 15 );
|
||
}
|
||
|
||
|
||
|
||
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 = (u8)(( 20851 - 112 * raw_adc_temperature + (256/2) ) /256);
|
||
vreg_ctr[VREG_C_BT_TEMP] = temperature;
|
||
|
||
newrcomp = 0;
|
||
if( temperature > 20 )
|
||
{
|
||
newrcomp = ( ( temperature - 20 ) * p_bt_param->rcomp.up )/256;
|
||
}
|
||
else
|
||
{
|
||
newrcomp = ( ( temperature - 20 ) * p_bt_param->rcomp.down )/256;
|
||
}
|
||
newrcomp = p_bt_param->rcomp.rcomp + newrcomp;
|
||
|
||
if( newrcomp > 255 )
|
||
{
|
||
newrcomp = 255;
|
||
}
|
||
if( newrcomp < 0 )
|
||
{
|
||
newrcomp = 0;
|
||
}
|
||
_dbg_rcomp = newrcomp;
|
||
|
||
if( send_cmd_mgic_2B( BT_GAUGE_REG_RCOMP, newrcomp ) == ERR_SUCCESS ) // swap不要
|
||
{
|
||
rawdat_old = raw_adc_temperature;
|
||
}
|
||
else
|
||
{
|
||
vreg_set_mgic_error;
|
||
}
|
||
}
|
||
}
|
||
return ( TSKI_FINISHED );
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
電池残量ICから残量を取得し、レジスタに書き込む。
|
||
|
||
電池残量ICが無い・故障などの時はとりあえず残量99%とする。
|
||
|
||
↑は status_1で確認可能。電源投入時にチェックしています。
|
||
|
||
BT_chk()が実行されている必要があります。
|
||
***********************************************/
|
||
void BT_get_left(){
|
||
u8 temp[2];
|
||
u8 reg_volatile_temp_bt_remain,reg_volatile_temp_bt_remain_fine; // I2Cの非同期読み込みでのちらつき防止 キャップ処理の所為
|
||
u8 fuel_cap_by_voltage; // 電圧でキャップに使う
|
||
|
||
// 電池残量
|
||
if( system_status.model == MODEL_TS_BOARD
|
||
|| system_status.model == MODEL_KUC_DEBUGGER )
|
||
{
|
||
// TS & 白箱 //
|
||
if( read_BT_SOC( temp ) == ERR_SUCCESS )
|
||
{
|
||
reg_volatile_temp_bt_remain = temp[0];
|
||
reg_volatile_temp_bt_remain_fine = temp[1];
|
||
}
|
||
else
|
||
{
|
||
// エミュレーション機能がおかしい
|
||
// それで電源断は不便すぎるだろう
|
||
reg_volatile_temp_bt_remain = 99;
|
||
reg_volatile_temp_bt_remain_fine = 0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 実機 //
|
||
// 残量リード
|
||
if( read_BT_SOC( temp ) != ERR_SUCCESS )
|
||
{
|
||
// 残量ICがNACK …バッテリはずれた
|
||
vreg_set_mgic_error;
|
||
bt_authorized = false;
|
||
reg_volatile_temp_bt_remain = 0;
|
||
force_off = true;
|
||
}
|
||
else
|
||
{
|
||
u16 temp_u16;
|
||
|
||
vreg_clear_mgic_error;
|
||
// バッテリパラメータの関係でビットシフトが必要
|
||
temp_u16 = temp[0] * 256 + temp[1];
|
||
temp_u16 /= p_bt_param->v_scale;
|
||
reg_volatile_temp_bt_remain = (u8)(( temp_u16 >> 8 ) & 0xFF );
|
||
if( reg_volatile_temp_bt_remain == 0 )
|
||
{
|
||
// 0%台の時は1.00%に上げ底
|
||
// 充電開始後もしばらくは電池残量が減るので
|
||
// 0%に到達してしまうことがあるのだ
|
||
reg_volatile_temp_bt_remain = 1;
|
||
reg_volatile_temp_bt_remain_fine = 0;
|
||
}
|
||
else
|
||
{
|
||
reg_volatile_temp_bt_remain_fine = (u8)(temp_u16 & 0xFF);
|
||
}
|
||
#ifdef _DBG_BT_FULL_
|
||
reg_volatile_temp_bt_remain = 100;
|
||
reg_volatile_temp_bt_remain_fine = 0;
|
||
#endif
|
||
}
|
||
}
|
||
|
||
// 電池電圧
|
||
{
|
||
if( read_BT_voltage( temp ) != ERR_SUCCESS ) // 2byte read
|
||
{
|
||
temp[0] = (u8)( V_BT_4000MV / 256 ); // 電池電圧読めなかったら4000mVだったことにしておく。
|
||
temp[1] = 0;
|
||
}
|
||
vreg_ctr[ VREG_C_BT_VOLTAGE ] = temp[0];
|
||
bt_volt16 = ( temp[0] * 256 + temp[1] );
|
||
}
|
||
|
||
|
||
// 電圧でキャップ...の準備
|
||
{
|
||
static u16 hysteresis;
|
||
|
||
if( bt_volt16 > V_TH_30 )
|
||
{
|
||
fuel_cap_by_voltage = 100;
|
||
hysteresis = 0;
|
||
}
|
||
else if( bt_volt16 - hysteresis > V_TH_LO ) // 測定値からヒステリシス分引いてる。読むとき注意。
|
||
{
|
||
fuel_cap_by_voltage = 30;
|
||
hysteresis = 0;
|
||
}
|
||
else if( bt_volt16 > V_TH_EMPTY )
|
||
{
|
||
fuel_cap_by_voltage = BATT_TH_LO; // ここから赤
|
||
hysteresis = 500;
|
||
}
|
||
else if( bt_volt16 > V_TH_ZERO )
|
||
{
|
||
fuel_cap_by_voltage = BATT_TH_EMPTY;
|
||
hysteresis = 500;
|
||
}
|
||
else if( bt_volt16 > V_TH_FORCE_OFF )
|
||
{
|
||
fuel_cap_by_voltage = 0;
|
||
hysteresis = 500;
|
||
}
|
||
else
|
||
{
|
||
force_off = true;
|
||
hysteresis = 500;
|
||
}
|
||
}
|
||
|
||
|
||
// 充電許可(=アダプタも刺さってる)のに充電してない
|
||
// かつ、(少なくとも)素の電池残量が60%以上(CCICバグ回避、BT_IN_CHG_delayed_nに織り込み済み)
|
||
// = 充電完了。電池がへたってくるとMGICが100%を返さない
|
||
if( !BT_CHG_Ena_n && BT_IN_CHG_delayed_n ){
|
||
reg_volatile_temp_bt_remain = 100;
|
||
reg_volatile_temp_bt_remain_fine = 0;
|
||
}
|
||
else
|
||
{ // 電圧でのキャップを掛けるか?
|
||
if( fuel_cap_by_voltage < reg_volatile_temp_bt_remain )
|
||
{
|
||
reg_volatile_temp_bt_remain = fuel_cap_by_voltage;
|
||
reg_volatile_temp_bt_remain_fine = 0;
|
||
}
|
||
}
|
||
|
||
/*
|
||
十分に問題ない電圧が供給されてるらしいのでケアせずでよし
|
||
if( system_status.taikendai_nbd && system_status.model != MODEL_TS_BOARD ) // 電池端子に電源がつながってて値が不正なため上書き。
|
||
{
|
||
reg_volatile_temp_bt_remain = 100;
|
||
}
|
||
*/
|
||
|
||
vreg_ctr[ VREG_C_BT_REMAIN ] = reg_volatile_temp_bt_remain;
|
||
vreg_ctr[ VREG_C_BT_REMAIN_FINE ] = reg_volatile_temp_bt_remain_fine;
|
||
|
||
// twlのレジスタ更新 (CTRに割り込み入れる前に更新しないと割り込みのタイミングがまずいかもしれない)
|
||
bt_batt_update_twl();
|
||
|
||
// 残量で割り込み。急激に減ると飛ぶことがある //
|
||
{
|
||
static u8 bt_remain_old_ctr;
|
||
|
||
if( bt_remain_old_ctr != reg_volatile_temp_bt_remain )
|
||
// 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に電池残量を教えてあげる
|
||
bt_batt_update_ntr();
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
液晶系の電源制御
|
||
|
||
ステータスフラグはすぐに立ててしまう。
|
||
|
||
不感応時間があるし、
|
||
|
||
起動失敗であれば電源が落ちる
|
||
|
||
別のタスクで電源落ちは監視していて、ステータスもクリアする
|
||
***********************************************/
|
||
err PM_LCD_on( )
|
||
{
|
||
err rv = ERR_ERR;
|
||
|
||
PM_VDDLCD_on( ); // 内部で CGS と AMO 切り替えてます
|
||
|
||
if( system_status.LCD_is_CGS == true )
|
||
{
|
||
// CTR 時
|
||
wait_ms( DELAY_PM_TSS_50B_AND_TCOM );
|
||
}
|
||
else
|
||
{
|
||
// SPFL/SNAKE ならアモルファスHV on を間に挟む
|
||
wait_ms( 10 );
|
||
LCD_AMOL_HV_CTRL = 1;
|
||
wait_ms( DELAY_PM_TSS_50B_AND_TCOM - 10 );
|
||
}
|
||
|
||
PM_TCOM_on( );
|
||
|
||
wait_ms( DELAY_PM_TCOM_TO_VCS );
|
||
|
||
PM_VCS_on( );
|
||
|
||
wait_ms( DELAY_PM_VCS_TO_BL );
|
||
|
||
if( PM_chk_LDSW() != 0 ) // 正常パス
|
||
{
|
||
// 電源起動エラーなら電源も切れてしまう。ここではケアしない
|
||
vreg_ctr[VREG_C_STATUS] |= REG_BIT_LCD_POW;
|
||
set_irq( VREG_C_IRQ3, REG_BIT_LCD_ON );
|
||
rv = ERR_SUCCESS;
|
||
}
|
||
|
||
return rv;
|
||
}
|
||
|
||
|
||
void PM_LCD_off()
|
||
{
|
||
// BLついてたら消す。
|
||
// チェックするのは割り込みの関係
|
||
if( ( read_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] &= bits8(1,0,0,1, 1,1,1,1);
|
||
|
||
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 );
|
||
}
|
||
|
||
|
||
// LCD 電源落とす
|
||
// 50ms も wait あるので点いてるか確認する
|
||
if( read_pmic( PM_REG_ADRS_VDD_LCD ) != 0 )
|
||
{
|
||
PM_TCOM_off();
|
||
wait_ms( 1 );
|
||
PM_TCOM_VCS_off( );
|
||
wait_ms( DELAY_PM_LCD_OFF );
|
||
|
||
if( system_status.LCD_is_CGS == false )
|
||
{
|
||
// アモルファスならポート操作
|
||
LCD_AMOL_HV_CTRL = 0; // 他のファミリでもL縛りなので弊害なしだが。
|
||
wait_ms( 10 ); // アモルファス15Vを切ったときのウェイト。
|
||
}
|
||
|
||
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; // PMIC レジスタに書き込む値
|
||
u8 intset = 0; // 割り込みレジスタに反映する値
|
||
// RMWを行う
|
||
|
||
// Read
|
||
blset = read_pmic( PM_REG_ADRS_BL );
|
||
|
||
// Modify
|
||
// 上画面
|
||
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;
|
||
}
|
||
|
||
// 下画面
|
||
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( system_status.family == FAMILY_FLOWER )
|
||
{
|
||
// パネルが一枚なので、off/off でなければ点灯、LX1(未接続側)を立ち上げない
|
||
// ただし、割り込みは嘘をついて SoC が設定したと思い込んだ値にする。
|
||
// todo: 要周知。
|
||
if( blset != 0 )
|
||
{
|
||
blset = PM_REG_BIT_BL_L;
|
||
}
|
||
}
|
||
|
||
// write
|
||
if( blset != 0 ) // BLを付ける場合はウェイトを挟まないとPWMが来ておらず
|
||
// シャットダウンすることがある
|
||
{
|
||
wait_ms( 16 + 10 );
|
||
}
|
||
send_cmd_pmic( PM_REG_ADRS_BL, blset );
|
||
|
||
// SoCがPWMを出すようレジスタをセットしてから遅延が有るため、ステータスを先に
|
||
// 更新してしまう。してほしいとの要求。
|
||
|
||
// PMICのBLのビットと、MCUのSTATUSレジスタのビット位置が逆なため入れ替え
|
||
vreg_ctr[VREG_C_STATUS] = (( vreg_ctr[VREG_C_STATUS] & bits8(1,0,0,1, 1,1,1,1) )
|
||
| ( (( blset << 6 ) | ( blset << 4 )) & bits8(0,1,1,0, 0,0,0,0) ));
|
||
|
||
// 割り込み
|
||
/// 複数ビットまとめて行うので、set_irq()使わない方が無難
|
||
{
|
||
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 ); // ここでは異常チェック不要
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
液晶の対向電圧の設定を行います。
|
||
|
||
仮想レジスタの内容を送るだけ
|
||
***********************************************/
|
||
void PM_LCD_vcom_set( )
|
||
{
|
||
send_cmd_pmic( PM_REG_ADRS_POW_DAC1, vreg_ctr[VREG_C_VCOM_T] ); // がっかりなことに、PMICはバースト書き込み不可
|
||
send_cmd_pmic( PM_REG_ADRS_POW_DAC2, vreg_ctr[VREG_C_VCOM_B] );
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
↑で、レジスタ書き込みから呼び出される時のため
|
||
|
||
I2Cの取り合いの関係でここから呼ぶ
|
||
***********************************************/
|
||
task_status_immed tski_vcom_set( )
|
||
{
|
||
PM_LCD_vcom_set( );
|
||
return ( TSKI_FINISHED );
|
||
}
|
||
|
||
|
||
void set_vdd_voltages( enum family_ family )
|
||
{
|
||
if(( family == FAMILY_SNAKE ) || ( family == FAMILY_CLOSER ))
|
||
{
|
||
// SNAKE
|
||
pmreg_v_core = PM_REG_BIT_VDD1P_1R05;
|
||
}
|
||
else
|
||
{
|
||
// NORMAL
|
||
pmreg_v_core = PM_REG_BIT_VDD1P_1R15;
|
||
}
|
||
}
|
||
|
||
/********************************************//**
|
||
シーケンスの通り電源を立ち上げてゆきます。
|
||
|
||
- 返値 0 最後まで正常に完了した。
|
||
- 1 ショートなどで電源があがりきらなかった
|
||
***********************************************/
|
||
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はほっといて良い
|
||
}
|
||
|
||
// 電源周りIC情報
|
||
pmic_version = read_pmic( PM_REG_ADRS_VER );
|
||
read_mgic_2B( BT_GAUGE_REG_VERSION, mgic_version );
|
||
|
||
return ( ERR_SUCCESS );
|
||
}
|
||
|
||
|
||
|
||
void reset_release()
|
||
{
|
||
// リセット解除など。システム起動!
|
||
PM_reset_neg();
|
||
FCRAM_RST_neg;
|
||
RESET2_neg;
|
||
|
||
codec_reg_init(); // CODEC 不定レジスタ初期化(reset2の後でないといけないので)
|
||
ntr_pm_reg_shadow = 0; // 〃 こんなところで...
|
||
}
|
||
|
||
|
||
|
||
|
||
/********************************************//**
|
||
電源OFFシーケンス
|
||
***********************************************/
|
||
void PM_sys_pow_off( )
|
||
{
|
||
// 一応 LCD 関係消すのを試みる。
|
||
PM_BL_set( REG_BIT_CMD_BL_U_OFF | REG_BIT_CMD_BL_L_OFF );
|
||
PM_LCD_off(); // 消えてれば何もしない
|
||
wait_ms( 20 );
|
||
|
||
PM_reset_ast();
|
||
|
||
RESET2_ast;
|
||
FCRAM_RST_ast;
|
||
|
||
wait_ms( 20 );
|
||
|
||
PM_off( );
|
||
PM_LDSW_off( );
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
extDC割り込み
|
||
|
||
電源OFFから起こす(充電の温度監視のため)のみ
|
||
|
||
普段はポーリング(pm)
|
||
***********************************************/
|
||
__interrupt void intp4_extdc( )
|
||
{
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
フタ開け閉め割り込み
|
||
|
||
普段はポーング(misc)
|
||
***********************************************/
|
||
__interrupt void intp5_shell( )
|
||
{
|
||
;
|
||
}
|
||
|
||
|
||
/********************************************//**
|
||
旧PMICへのコマンド書き込み
|
||
***********************************************/
|
||
__interrupt void intp6_PM_irq( )
|
||
{
|
||
EI();
|
||
if( system_status.pwr_state == ON )
|
||
{
|
||
renge_task_immed_add( tski_ntr_pmic_comm );
|
||
}
|
||
}
|
||
|
||
|
||
/********************************************//**
|
||
CODECからの割り込みを受けて、NTR PMIC互換レジスタからリード
|
||
***********************************************/
|
||
task_status_immed tski_ntr_pmic_comm( )
|
||
{
|
||
u8 reg1_old;
|
||
u8 irq_work = 0;
|
||
|
||
reg1_old = ntr_pm_reg_shadow;
|
||
ntr_pm_reg_shadow = iic_mcu_read_a_byte( IIC_SLA_CODEC, CODEC_REG_PM );
|
||
if( iic_mcu_result != ERR_SUCCESS )
|
||
{
|
||
return ( TSKI_FINISHED );
|
||
}
|
||
|
||
// DI( );
|
||
|
||
// バックライト 上 ////////////////////////////////////
|
||
if( ( ( reg1_old ^ ntr_pm_reg_shadow ) & REG_BIT_TWL_REQ_BL_U ) != 0 )
|
||
{
|
||
if( ( ntr_pm_reg_shadow & REG_BIT_TWL_REQ_BL_U ) == 0 ) // 消えた
|
||
{
|
||
irq_work = REG_BIT_TWL_BL_U_OFF;
|
||
}
|
||
else
|
||
{
|
||
irq_work = REG_BIT_TWL_BL_U_ON;
|
||
}
|
||
}
|
||
|
||
// バックライト 下
|
||
if( ( ( reg1_old ^ ntr_pm_reg_shadow ) & REG_BIT_TWL_REQ_BL_L ) != 0 )
|
||
{
|
||
if( ( ntr_pm_reg_shadow & REG_BIT_TWL_REQ_BL_L ) == 0 ) // 消えた
|
||
{
|
||
irq_work |= REG_BIT_TWL_BL_L_OFF;
|
||
}
|
||
else
|
||
{
|
||
irq_work |= REG_BIT_TWL_BL_L_ON;
|
||
}
|
||
}
|
||
|
||
// EI();
|
||
|
||
vreg_ctr[ VREG_C_STATUS_1 ] = ( vreg_ctr[ VREG_C_STATUS_1 ] & ~REG_BIT_MASK_STATUS1_NTR_PM_REG )
|
||
| ( ntr_pm_reg_shadow & REG_BIT_MASK_STATUS1_NTR_PM_REG ); // TWLバックライト情報のミラー
|
||
|
||
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;
|
||
}
|
||
|
||
/// バックライト、気を利かせて消したりしません。
|
||
|
||
// offリクエスト //////////////////////////////////////
|
||
if( ( ntr_pm_reg_shadow & REG_BIT_TWL_REQ_OFF_REQ ) != 0 )
|
||
{
|
||
set_irq( VREG_C_IRQ2, REG_BIT_TWL_OFF_REQ );
|
||
}
|
||
|
||
// リセットリクエスト /////////////////////////////////
|
||
if( ( ntr_pm_reg_shadow & REG_BIT_TWL_REQ_RST_REQ ) != 0 )
|
||
{
|
||
set_irq( VREG_C_IRQ2, REG_BIT_TWL_RESET_REQ );
|
||
}
|
||
|
||
// バックライトをマスクして書き戻す
|
||
EI( );
|
||
if( ( ntr_pm_reg_shadow & ( REG_BIT_TWL_REQ_OFF_REQ | REG_BIT_TWL_REQ_RST_REQ )) != 0 )
|
||
{
|
||
ntr_pm_reg_shadow &= ~( REG_BIT_TWL_REQ_OFF_REQ | REG_BIT_TWL_REQ_RST_REQ );
|
||
iic_mcu_write_a_byte_codec( CODEC_REG_PM, ntr_pm_reg_shadow );
|
||
}
|
||
return ( TSKI_FINISHED );
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
command2 液晶系
|
||
|
||
ラッパー的な物。ERR_SUCCESSしか返さないが…
|
||
***********************************************/
|
||
task_status_immed tski_PM_LCD_on()
|
||
{
|
||
PM_LCD_on();
|
||
return( TSKI_FINISHED );
|
||
}
|
||
|
||
task_status_immed tski_PM_LCD_off()
|
||
{
|
||
PM_LCD_off();
|
||
return( TSKI_FINISHED );
|
||
}
|
||
|
||
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( TSKI_FINISHED );
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
reset2 で CODEC にリセットがかかり、レジスタが不定になるため
|
||
***********************************************/
|
||
void codec_reg_init()
|
||
{
|
||
wait_ms( 100 );
|
||
|
||
ntr_pm_bt_low_old = conv_ctr_bt_to_twl_bt();
|
||
|
||
iic_mcu_write_a_byte_codec( CODEC_REG_BT, (u8)ntr_pm_bt_low_old ); // SoC から書けず
|
||
|
||
vol_reset();
|
||
// renge_task_immed_add( tski_vol_update ); ポーリングするので。
|
||
vol_polling = 3;
|
||
}
|
||
|
||
|
||
/********************************************//**
|
||
ヘルパーというかラッパーというか?
|
||
|
||
ROM節約のため
|
||
***********************************************/
|
||
err send_cmd_mgic_2B( u8 reg, u16 dat )
|
||
{
|
||
u16 temp = dat; // 送信バッファ
|
||
return iic_mcu_write( IIC_SLA_BT_GAUGE, reg, 2, &temp ); // DMA転送するので送信データバッファのポインタがどうせ必要
|
||
}
|
||
|
||
err read_mgic_2B( u8 reg, u8* dat ) // 送信バッファは固定
|
||
{
|
||
return iic_mcu_read( IIC_SLA_BT_GAUGE, reg, 2, dat );
|
||
}
|
||
|
||
err send_cmd_pmic( u8 reg, u8 dat )
|
||
{
|
||
return iic_mcu_write_a_byte( IIC_SLA_PMIC, reg, dat );
|
||
}
|
||
|
||
u8 read_pmic( u8 reg )
|
||
{
|
||
return iic_mcu_read_a_byte( IIC_SLA_PMIC, reg );
|
||
}
|
||
|
||
/********************************************//**
|
||
電池メーカーとモデルから、使う電池パラメータの決定
|
||
***********************************************/
|
||
void bt_param_select()
|
||
{
|
||
BT_TYPE bt_type_temp;
|
||
|
||
// バッテリメーカー識別
|
||
if( battery_manufacturer <= BT_VENDER_3 ) // 余裕を持って中間に閾値をとる
|
||
{
|
||
bt_type_temp = BT_PARAM_CTR_MAXELL;
|
||
}
|
||
else
|
||
{
|
||
bt_type_temp = BT_PARAM_CTR_PANA;
|
||
}
|
||
|
||
// モデル識別
|
||
switch( system_status.family )
|
||
{
|
||
case( FAMILY_SPFL ): bt_type_temp += BT_PARAM_SPFL_MAXELL; break; // オフセット 残念な実装で…。
|
||
case( FAMILY_SNAKE ): bt_type_temp += BT_PARAM_SNAKE_MAXELL; break;
|
||
case( FAMILY_CLOSER ): bt_type_temp += BT_PARAM_SPFL_MAXELL; break;
|
||
case( FAMILY_CTR ):
|
||
case( FAMILY_FLOWER ): // CTR と同じ
|
||
default: /* bt_type_temp そのまま */ break;
|
||
}
|
||
|
||
p_bt_param = &bt_param[ bt_type_temp ];
|
||
|
||
// 充電停止温度の設定
|
||
/// 後付けなのと、分岐が少ないのでこういう実装
|
||
if(( system_status.family == FAMILY_SNAKE ) ||
|
||
( system_status.family == FAMILY_CLOSER ))
|
||
{
|
||
raw_temp_lh = RAW_TEMP_LH_SNAKE;
|
||
raw_temp_ll = RAW_TEMP_LL_SNAKE;
|
||
}
|
||
else
|
||
{
|
||
raw_temp_lh = RAW_TEMP_LH_CTR;
|
||
raw_temp_ll = RAW_TEMP_LL_CTR;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
#define TWL_BT_LEVEL_THREASH_F 60
|
||
#define TWL_BT_LEVEL_THREASH_B 30
|
||
#define TWL_BT_LEVEL_THREASH_1 0
|
||
|
||
/********************************************//**
|
||
TWLに電池残量を教えてあげる
|
||
***********************************************/
|
||
static void bt_batt_update_twl()
|
||
{
|
||
if (vreg_ctr[VREG_C_BT_REMAIN] > TWL_BT_LEVEL_THREASH_F )
|
||
{
|
||
vreg_twl[REG_TWL_INT_ADRS_POWER_INFO] = 0x0F;
|
||
}
|
||
else if (vreg_ctr[VREG_C_BT_REMAIN] > TWL_BT_LEVEL_THREASH_B )
|
||
{
|
||
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 )||
|
||
!BT_CHG_Ena_n )
|
||
{ // アダプタの有無で底上げ
|
||
vreg_twl[REG_TWL_INT_ADRS_POWER_INFO] = 0x03;
|
||
}
|
||
else if (vreg_ctr[VREG_C_BT_REMAIN] > TWL_BT_LEVEL_THREASH_1 )
|
||
{
|
||
vreg_twl[REG_TWL_INT_ADRS_POWER_INFO] = 0x01;
|
||
}
|
||
else
|
||
{
|
||
vreg_twl[REG_TWL_INT_ADRS_POWER_INFO] = 0x00;
|
||
}
|
||
}
|
||
|
||
|
||
/********************************************//**
|
||
NTRに電池残量を教えてあげる
|
||
***********************************************/
|
||
static void bt_batt_update_ntr()
|
||
{
|
||
static bit initialized;
|
||
static bit flag; // あれ?staticでないとコンパイラに怒られる
|
||
|
||
if( system_status.pwr_state == OFF_TRIG )
|
||
{
|
||
initialized = false;
|
||
}
|
||
else
|
||
{
|
||
|
||
flag = conv_ctr_bt_to_twl_bt();
|
||
|
||
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, (u8)flag );
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/********************************************//**
|
||
電池残量を読んでくる
|
||
***********************************************/
|
||
static err read_BT_SOC( u8* dest )
|
||
{
|
||
#ifdef _ENABLE_HAL_
|
||
if( vreg_ctr[ VREG_C_HAL_OVW_BT_FUEL ] != 0xFF ) // trueならHAL有効
|
||
#else
|
||
if( 0 )
|
||
#endif
|
||
{
|
||
*dest = vreg_ctr[ VREG_C_HAL_OVW_BT_FUEL ];
|
||
*(dest+1) = 0x00;
|
||
return ERR_SUCCESS;
|
||
}
|
||
else
|
||
{
|
||
return( read_mgic_2B( BT_GAUGE_REG_SOC, dest ) );
|
||
}
|
||
}
|
||
|
||
|
||
/********************************************//**
|
||
電池電圧を読んでくる
|
||
***********************************************/
|
||
static err read_BT_voltage( u8* dest )
|
||
{
|
||
#ifdef _ENABLE_HAL_
|
||
if( vreg_ctr[ VREG_C_HAL_OVW_BT_VOLTAGE ] != 0xFF ) // trueならHAL有効
|
||
#else
|
||
if( 0 )
|
||
#endif
|
||
{
|
||
*dest = vreg_ctr[ VREG_C_HAL_OVW_BT_VOLTAGE ];
|
||
// *(dest+1) = 0x00; // 使わないよ けど2バイトリード関数しか用意してないのです
|
||
return ERR_SUCCESS;
|
||
}
|
||
else
|
||
{
|
||
return( read_mgic_2B( BT_GAUGE_REG_VCELL, dest ) );
|
||
}
|
||
}
|
||
|
||
|
||
/********************************************//**
|
||
電池残量をtwlにフラグに変換する
|
||
***********************************************/
|
||
static u8 conv_ctr_bt_to_twl_bt()
|
||
{
|
||
// ntr_pm_bt_low_old = ( vreg_ctr[ VREG_C_BT_REMAIN ] <= BATT_TH_LO )? NTR_PM_BT_EMPTY: NTR_PM_BT_ENOUGH; // 1で電池切れ
|
||
if( vreg_ctr[ VREG_C_BT_REMAIN ] <= BATT_TH_LO )
|
||
{
|
||
return NTR_PM_BT_EMPTY;
|
||
}
|
||
else
|
||
{
|
||
return NTR_PM_BT_ENOUGH;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
void PM_reset_ast()
|
||
{
|
||
char temp;
|
||
temp = read_pmic( PM_REG_ADRS_CONT );
|
||
send_cmd_pmic( PM_REG_ADRS_CONT, temp & ~(PM_REG_BIT_nRST1));
|
||
}
|
||
|