mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-06-18 16:45:33 -04:00

・レジスタ書き込みでの強制ボリュームセット実装 ・パナソニックのバッテリパラメータをダミーから差し替え(まだ機能してない) ・フルカラーお知らせLEDにきちんと対応 現行の電源ボード、電源赤がPWMできたりするが実機に合わせてコードも整理 でないと自動判別後が大変な為 ・電源断時にLEDを何となくフェードアウト ・CTR側のI2Cレジスタの実装を修正。220バイト程ROMを節約 エンバグ怖い ・I2C_mcuのモジュール初期化チェックなどの無駄を少し整理 ・TWL I2Cの通信がどうにも間に合わないとき、リトライされてタイミングが悪いと0x00などを返していた。 リトライ時にも正常に動作するように修正。エンバグ怖い ・廃止enumをちょっと整理 ・I2Cレジスタの初期値・リセット時の初期化などを修正 ・温度で充電停止周りを実装 ・プラットフォームの判定を誤っていた。(0x7Fで読める) ・RCOMPの値の計算を間違えていた。算数もできないのか! ・デバッグコードを抜いた。(pm.c) ・rengeOSのデバッグを有効にしたままだった。I2C_TWLのパフォーマンスが全くでず不具合の嵐 ・6秒で電源断を追加。(CTRレジスタから可変) デバッグで耐えられないのでまだ#ifdefでデフォルトを1秒にしてある ・電池無しからアダプタ差したり、アダプタ有りの状態から電池をつないだりで充電したりしなかったり電源はいらなかったり…を修正 ・電源LEDが赤になるタイミングと、TWLへの電池残量への通知、NTRへの通知などの閾値がばらばらだったのを修正 git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@171 013db118-44a6-b54f-8bf7-843cb86687b1
338 lines
8.8 KiB
C
338 lines
8.8 KiB
C
/* ========================================================
|
||
藤田@開技
|
||
nintendo
|
||
'09 Apr
|
||
======================================================== */
|
||
#include "incs.h"
|
||
#include "adc.h"
|
||
#include "pm.h"
|
||
|
||
#include "led.h"
|
||
|
||
|
||
//#define _4db_
|
||
#define _15db_
|
||
|
||
// ===================================================== //
|
||
bit adc_updated;
|
||
|
||
u8 adc_raw_vol;
|
||
u8 adc_raw_dep;
|
||
|
||
|
||
|
||
// ===================================================== //
|
||
extern void nop8();
|
||
|
||
|
||
|
||
// ===================================================== //
|
||
#define INTERVAL_TSK_ADC 15
|
||
|
||
|
||
|
||
/* ========================================================
|
||
ADC設定と、開始
|
||
|
||
以下のピンは主にここで操作・監視されます。
|
||
・BT_TEMP,_P
|
||
・ADIN1
|
||
・VOL
|
||
|
||
関係ありそうですが別のところで管理しています
|
||
・PM_BT_DET,_P BT_init
|
||
|
||
・8tics毎に呼ばれ、3チャンネル分取り込むとADCを停止します。
|
||
タスク起動時、レジスタには前回の取り込み値が入っています。
|
||
======================================================== */
|
||
|
||
#ifdef _15db_
|
||
// max -15db
|
||
const u8 slider_to_codec[64] =
|
||
{
|
||
127, 127, 127, 126, 125, 124, 123, 122,
|
||
121, 120, 119, 118, 117, 116, 115, 114,
|
||
113, 112, 111, 110, 109, 108, 107, 106,
|
||
105, 104, 103, 102, 101, 100, 99, 98,
|
||
97, 96, 95, 94, 93, 92, 91, 90,
|
||
89, 88, 87, 86, 85, 84, 83, 82,
|
||
81, 80, 79, 78, 77, 76, 75, 74,
|
||
73, 72, 71, 70, 69, 68, 67, 66
|
||
};
|
||
#endif
|
||
|
||
#ifdef _4db_
|
||
// max -4db
|
||
const u8 slider_to_codec[64] =
|
||
{
|
||
127, 127, 126, 125, 123, 122, 121, 119,
|
||
118, 117, 115, 114, 112, 111, 110, 108,
|
||
107, 106, 104, 103, 101, 100, 99, 97,
|
||
96, 94, 93, 92, 90, 89, 88, 86,
|
||
85, 83, 82, 81, 79, 78, 77, 75,
|
||
74, 72, 71, 70, 68, 67, 66, 64,
|
||
64, 63, 61, 60, 59, 57, 56, 54,
|
||
53, 52, 50, 49, 48, 46, 44, 44
|
||
};
|
||
#endif
|
||
|
||
|
||
void tsk_adc( )
|
||
{
|
||
static u8 task_interval = 0;
|
||
static u8 old_tune;
|
||
static u8 sndvol_codec;
|
||
static u8 bt_temp_old;
|
||
|
||
if( task_interval-- != 0 )
|
||
{
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
task_interval = (u8)( INTERVAL_TSK_ADC / SYS_INTERVAL_TICK );
|
||
}
|
||
|
||
|
||
if( adc_updated )
|
||
{
|
||
adc_updated = 0;
|
||
|
||
if( system_status.pwr_state == ON )
|
||
{
|
||
// 3D /////////////////////////////////////////
|
||
{
|
||
// 似非ヒステリシス V2
|
||
// ガリオームには適さない
|
||
#define KIKAN 32
|
||
static u8 old_value;
|
||
static s8 diffs;
|
||
u8 temp;
|
||
|
||
if( abs( adc_raw_dep - old_value ) >= 2 )
|
||
{
|
||
// 大きく離れた
|
||
vreg_ctr[ VREG_C_TUNE ] = adc_raw_dep;
|
||
old_value = adc_raw_dep;
|
||
#if 0
|
||
割り込み入れない;
|
||
割り込みを入れるようであれば、ちゃんと変化チェックする;
|
||
|
||
set_irq( VREG_C_IRQ0, REG_BIT_VR_TUNE_CHANGE );
|
||
#endif
|
||
diffs = 0;
|
||
}
|
||
else
|
||
{
|
||
// 近所の値でも、ある期間でいっぱい偏っていたらそっちに寄せる
|
||
static u8 kikan_count = KIKAN;
|
||
if( old_value < adc_raw_dep )
|
||
{
|
||
diffs += 1;
|
||
}
|
||
else if( old_value > adc_raw_dep )
|
||
{
|
||
diffs -= 1;
|
||
}
|
||
|
||
if( --kikan_count == 0 )
|
||
{
|
||
if( diffs >= KIKAN && ( diffs < 64 ))
|
||
{
|
||
old_value += 1;
|
||
}
|
||
else if( ( diffs <= ( 256 - KIKAN )) && ( diffs > ( 128 + 64 ) )) // あらー?
|
||
{
|
||
old_value -= 1;
|
||
}
|
||
vreg_ctr[ VREG_C_TUNE ] = old_value;
|
||
kikan_count = KIKAN;
|
||
diffs = 0;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Volume /////////////////////////////////////
|
||
{
|
||
static u8 vol_old;
|
||
static u8 force_update_vol;
|
||
|
||
if(( vreg_ctr[ VREG_C_VOL_DIGITAL ] & 0x80 ) != 0 )
|
||
{
|
||
// レジスタから強制セット
|
||
adc_raw_vol = ( vreg_ctr[ VREG_C_VOL_DIGITAL ] * 4 );
|
||
}
|
||
|
||
if( ( abs( adc_raw_vol - vol_old ) >= 2 ) // 生値でこれくらいずれたら更新(似非ヒステリシス)
|
||
|| ( --force_update_vol == 0 ) ) // ポーリング
|
||
{
|
||
vol_old = adc_raw_vol;
|
||
// レジスタ更新
|
||
vreg_twl[ REG_TWL_INT_ADRS_VOL ] = vol_old / ( 256 / 32 ); // ←adc値でよい
|
||
vreg_ctr[ VREG_C_SND_VOL ] = ( vol_old / 4 ); // 64段
|
||
|
||
// codecに伝える
|
||
iic_mcu_write_a_byte( IIC_SLA_CODEC, CODEC_REG_VOL, slider_to_codec[ vol_old / 4 ] );
|
||
#ifndef _MODEL_CTR_
|
||
iic_mcu_write_a_byte( IIC_SLA_DCP, 0, slider_to_codec[ ( 255 - vol_old ) / 4 ] );
|
||
#endif
|
||
// set_irq( VREG_C_IRQ0, REG_BIT_VR_SNDVOL_CHANGE ); // 割り込み廃止
|
||
force_update_vol = 10;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
ADCEN = 1;
|
||
ADM = 0b00001011; // セレクトモード、昇圧、fCLK/6 ///ここから ↓
|
||
|
||
ADPC = 0x06; // ADCポートのセレクト
|
||
ADS = ADC_SEL_TUNE;
|
||
nop8();
|
||
ADCS = 1; // AD開始。 /// ここまで ↑ までに1us=8clk以上開ける
|
||
|
||
ADIF = 0;
|
||
ADMK = 0;
|
||
|
||
}
|
||
|
||
|
||
/* ========================================================
|
||
過去3つのminでもMAXでもない値を返す
|
||
突発的なノイズを除く。
|
||
根本対策ではないが、これはこれで使い道がある。
|
||
======================================================== */
|
||
static u8 getmean3( u8 * hist )
|
||
{
|
||
if( *hist > *( hist + 1 ) )
|
||
{
|
||
if( *hist > *( hist + 2 ) )
|
||
{
|
||
return( ( *( hist + 1 ) > *( hist + 2 ) ) ? *( hist + 1 ) : *( hist + 2 ) );
|
||
}
|
||
else
|
||
{
|
||
return( *hist );
|
||
}
|
||
}else{
|
||
if( *hist > *( hist + 2 ) )
|
||
{
|
||
return( *hist );
|
||
}
|
||
else
|
||
{
|
||
return( ( *( hist + 1 ) < *( hist + 2 ) ) ? *( hist + 1 ) : *( hist + 2 ) );
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
自前で次のチャンネル
|
||
一通り終わったら止める
|
||
======================================================== */
|
||
__interrupt void int_adc( )
|
||
{
|
||
static u8 hist_tune[3];
|
||
static u8 hist_snd_vol[3];
|
||
static u8 hist_bt_temp[3];
|
||
static u8 index;
|
||
|
||
// EI( );
|
||
switch ( ADS )
|
||
{
|
||
/*
|
||
case ( ADC_SEL_AMB_BRIT ): // 環境明るさ
|
||
vreg_ctr[ VREG_C_AMBIENT_BRIGHTNESS ] = ADCRH;
|
||
break;
|
||
*/
|
||
|
||
case ( ADC_SEL_TUNE ):
|
||
hist_tune[index] = ADCRH;
|
||
#ifdef _MODEL_WM0_
|
||
adc_raw_dep = 255 - getmean3( hist_tune );
|
||
#else
|
||
adc_raw_dep = getmean3( hist_tune );
|
||
#endif
|
||
break;
|
||
|
||
case ( ADC_SEL_VOL ):
|
||
hist_snd_vol[index] = ADCRH;
|
||
#ifdef _MODEL_CTR_
|
||
if( system_status.model == MODEL_TS_BOARD )
|
||
{
|
||
adc_raw_vol = getmean3( hist_snd_vol );
|
||
}
|
||
else
|
||
{
|
||
adc_raw_vol = ( 255 - getmean3( hist_snd_vol ));
|
||
}
|
||
#else
|
||
adc_raw_vol = getmean3( hist_snd_vol );
|
||
#endif
|
||
if( adc_raw_vol == 0 )
|
||
{
|
||
NOP();
|
||
}
|
||
|
||
break;
|
||
|
||
case ( ADC_SEL_BATT_TEMP ):
|
||
hist_bt_temp[index] = ADCRH;
|
||
raw_adc_temperature = getmean3( hist_bt_temp );
|
||
renge_task_immed_add( BT_temp_update );
|
||
break;
|
||
|
||
case ( ADC_SEL_BATT_DET ):
|
||
// 呼ばれない
|
||
break;
|
||
}
|
||
|
||
|
||
// もっとまともな書き方がありそうだ
|
||
// if( ADS == ADC_SEL_BATT_DET ){
|
||
if( ADS != ADC_SEL_BATT_TEMP )
|
||
{ // 電池判別は電源投入の一回のみ
|
||
ADS += 1; // 次のチャンネル
|
||
ADIF = 0;
|
||
}
|
||
else
|
||
{
|
||
ADCEN = 0; // 止めてしまう
|
||
adc_updated = 1;
|
||
index = ( index == 2 ) ? 0 : ( index + 1 );
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/* ========================================================
|
||
tsk_adcと競合することを考慮していません。
|
||
======================================================== */
|
||
u8 get_adc( u8 ch )
|
||
{
|
||
u8 temp;
|
||
|
||
ADMK = 1;
|
||
ADIF = 0;
|
||
|
||
ADCEN = 1;
|
||
ADM = 0b00001011; // セレクトモード、昇圧、fCLK/6 ///ここから↓
|
||
|
||
ADPC = 0x06; // ADCポートのセレクト
|
||
ADS = ch;
|
||
|
||
nop8();
|
||
|
||
ADCS = 1; // AD開始。 /// ここまで↑ に、1us以上開ける
|
||
|
||
while( ADIF == 0 ){;}
|
||
temp = ADCRH;
|
||
ADCEN = 0;
|
||
|
||
ADMK = 0;
|
||
return ( temp );
|
||
}
|