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@43 013db118-44a6-b54f-8bf7-843cb86687b1
277 lines
7.4 KiB
C
277 lines
7.4 KiB
C
/* ========================================================
|
||
藤田@開技
|
||
nintendo
|
||
'09 Apr
|
||
======================================================== */
|
||
#include "incs.h"
|
||
#include "adc.h"
|
||
#include "pm.h"
|
||
|
||
#include "led.h"
|
||
|
||
bit adc_updated;
|
||
|
||
|
||
#define INTERVAL_TSK_ADC 16
|
||
/* ========================================================
|
||
ADC設定と、開始
|
||
|
||
以下のピンは主にここで操作・監視されます。
|
||
・BT_TEMP,_P
|
||
・ADIN1
|
||
・VOL
|
||
|
||
関係ありそうですが別のところで管理しています
|
||
・PM_BT_DET,_P PM_init
|
||
|
||
・8tics毎に呼ばれ、3チャンネル分取り込むとADCを停止します。
|
||
タスク起動時、レジスタには前回の取り込み値が入っています。
|
||
======================================================== */
|
||
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 )
|
||
{
|
||
if( system_status.pwr_state == ON )
|
||
{
|
||
// Tune //
|
||
#if 0
|
||
tune ・フ変化では割り込みを入れない
|
||
// tune
|
||
if( abs( old_tune - vreg_ctr[VREG_TUNE] ) >= 4 )
|
||
{
|
||
old_tune = vreg_ctr[VREG_TUNE];
|
||
vreg_ctr[VREG_C_IRQ0] |= REG_BIT_VR_TUNE_CHANGE;
|
||
if( ( vreg_ctr[VREG_C_IRQ_MASK0] & REG_BIT_VR_TUNE_CHANGE ) == 0 )
|
||
{
|
||
IRQ0_ast;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
// Volume //
|
||
{
|
||
static u8 vol_old;
|
||
static u8 class_old;
|
||
u8 class;
|
||
static u8 tokidoki = 0; // todo ポーリングは不要になる予定
|
||
|
||
if( abs( vol_old - vreg_ctr[VREG_C_SND_VOL] ) > 3 )
|
||
{
|
||
vol_old = vreg_ctr[VREG_C_SND_VOL];
|
||
|
||
// TWLに通知してやる
|
||
vreg_twl[ REG_TWL_INT_ADRS_VOL ] = vol_old / ( 256 / 32 );
|
||
// 割り込みはHorizonを通してコマンドを発行されるのを待てばよい
|
||
|
||
class = vreg_ctr[VREG_C_SND_VOL] / ( 256 / 8 );
|
||
if( class != class_old )
|
||
{
|
||
class_old = class;
|
||
set_irq( VREG_C_IRQ0, REG_BIT_VR_SNDVOL_CHANGE );
|
||
}
|
||
}
|
||
|
||
// デバイスに伝える
|
||
if(( sndvol_codec != vreg_ctr[VREG_C_SND_VOL] )
|
||
|| ( tokidoki == 0 ))
|
||
{
|
||
sndvol_codec = vreg_ctr[VREG_C_SND_VOL];
|
||
// DCPにも伝えておく
|
||
iic_mcu_write_a_byte( IIC_SLA_DCP, 0,
|
||
sndvol_codec / 2 + sndvol_codec / 4 ); // 簡易スケーリング todo
|
||
// codecに伝える
|
||
iic_mcu_write_a_byte( IIC_SLA_CODEC, CODEC_REG_VOL,
|
||
127 - ( sndvol_codec / 2 + sndvol_codec / 4 )/2 );
|
||
}
|
||
tokidoki += 1;
|
||
}
|
||
|
||
|
||
// TUNE_LED //
|
||
// ここで?仕様?
|
||
{
|
||
switch ( vreg_ctr[VREG_C_LED_TUNE] )
|
||
{
|
||
case LED_TUNE_ILM_ON:
|
||
LED_duty_TUNE = vreg_ctr[VREG_C_LED_BRIGHT];
|
||
break;
|
||
|
||
case LED_TUNE_ILM_SVR:
|
||
LED_duty_TUNE = vreg_ctr[VREG_C_TUNE] / 16;
|
||
break;
|
||
|
||
case LED_TUNE_ILM_OFF:
|
||
default:
|
||
LED_duty_TUNE = 0;
|
||
break;
|
||
}
|
||
}
|
||
|
||
adc_updated = 0;
|
||
}
|
||
}
|
||
|
||
|
||
ADCEN = 1;
|
||
ADM = 0b00011011; // セレクトモード、章圧、fCLK/6 ///ここから ↓
|
||
|
||
ADPC = 0x02; // ADCポートのセレクト
|
||
ADS = ADC_SEL_AMB_BRIT;
|
||
// NOP();
|
||
ADCS = 1; // AD開始。 /// ここまで ↑ までに1us以上開ける
|
||
|
||
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;
|
||
u8 temp;
|
||
|
||
EI( );
|
||
switch ( ADS )
|
||
{
|
||
case ( ADC_SEL_AMB_BRIT ):
|
||
vreg_ctr[ VREG_C_AMBIENT_BRIGHTNESS ] = ADCRH;
|
||
break;
|
||
|
||
case ( ADC_SEL_GYRO_YAW ):
|
||
vreg_ctr[ VREG_C_GYRO_YAW ] = ADCRH;
|
||
break;
|
||
|
||
case ( ADC_SEL_GYRO_PITCH ):
|
||
vreg_ctr[ VREG_C_GYRO_PITCH ] = ADCRH;
|
||
break;
|
||
|
||
case ( ADC_SEL_GYRO_ROLL ):
|
||
vreg_ctr[ VREG_C_GYRO_ROLL ] = ADCRH;
|
||
break;
|
||
|
||
case ( ADC_SEL_TUNE ):
|
||
hist_tune[index] = ADCRH;
|
||
#ifdef _MODEL_WM0_
|
||
vreg_ctr[ VREG_C_TUNE ] = 255 - getmean3( hist_tune );
|
||
#else
|
||
vreg_ctr[ VREG_C_TUNE ] = getmean3( hist_tune );
|
||
#endif
|
||
break;
|
||
|
||
case ( ADC_SEL_VOL ):
|
||
hist_snd_vol[index] = ADCRH;
|
||
vreg_ctr[VREG_C_SND_VOL] = getmean3( hist_snd_vol );
|
||
break;
|
||
|
||
case ( ADC_SEL_BATT_TEMP ):
|
||
hist_bt_temp[index] = ADCRH;
|
||
raw_adc_temperature = getmean3( hist_bt_temp );
|
||
renge_task_immed_add( PM_bt_temp_update );
|
||
break;
|
||
|
||
case ( ADC_SEL_BATT_DET ):
|
||
// vreg_ctr[ VREG_C_DBG_BATT_DET ] = ADCRH;
|
||
// todo
|
||
break;
|
||
}
|
||
|
||
|
||
// もっとまともな書き方がありそうだ
|
||
// if( ADS == ADC_SEL_BATT_DET ){b
|
||
if( ADS != ADC_SEL_BATT_TEMP )
|
||
{ // 電池判別は電源投入の一回のみ
|
||
ADS += 1; // 次のチャンネル
|
||
BT_TEMP_P = 1; // 電池温度監視スタート
|
||
|
||
}
|
||
else
|
||
{
|
||
ADCEN = 0; // 止めてしまう
|
||
BT_TEMP_P = 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;
|
||
ADCS = 0;
|
||
ADM = 0b00100011; // セレクトモード、昇圧、fCLK/6 ///ここから↓
|
||
|
||
ADPC = 0x02; // ADCポートのセレクト
|
||
ADS = ch;
|
||
ADCS = 1; // AD開始。 /// ここまで↑ に、1us以上開ける
|
||
|
||
ADMK = 0;
|
||
while( ADIF == 0 ){;}
|
||
temp = ADCRH;
|
||
ADCEN = 0;
|
||
|
||
return ( temp );
|
||
}
|