mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-10-31 13:51:10 -04:00
rengeの即時実行の方のタスク登録やらがおかしかったので修正。 タスクの管理?に不整合が出てしまう。タスク登録処理中に、割り込みからも登録しようとすると不整合が出る。 タスクを登録するが、呼ばなくなってしまう。 登録中に割り込み禁止にすると、I2Cのステートがおかしくなってしまう。 ↑解消のため、I2C_CTRをすべて割り込みドリブンにした。 RTCアラーム実装 IRQマスク実装 未:TWL側とのやりとり 歩数計 今回のタスク管理の修正で評価に入れる状態になったと思われ git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@9 013db118-44a6-b54f-8bf7-843cb86687b1
193 lines
4.7 KiB
C
193 lines
4.7 KiB
C
/* ========================================================
|
||
藤田@開技
|
||
nintendo
|
||
'09 Apr
|
||
======================================================== */
|
||
#include "incs.h"
|
||
#include "adc.h"
|
||
#include "pm.h"
|
||
|
||
#include "led.h"
|
||
|
||
bit adc_updated;
|
||
|
||
|
||
/* ========================================================
|
||
ADC設定と、開始
|
||
|
||
以下のピンは主にここで操作・監視されます。
|
||
・BT_TEMP,_P
|
||
・ADIN1
|
||
・VOL
|
||
|
||
関係ありそうですが別のところで管理しています
|
||
・PM_BT_DET,_P PM_init
|
||
|
||
・8tics毎に呼ばれ、3チャンネル分取り込むとADCを停止します。
|
||
タスク起動時、レジスタには前回の取り込み値が入っています。
|
||
======================================================== */
|
||
task_interval tsk_adc(){
|
||
static u8 old_tune;
|
||
static u8 old_sndvol;
|
||
static u8 sndvol_codec;
|
||
// static u8 bt_temp_old;
|
||
|
||
if(( system_status.pwr_state == ON )
|
||
|| ( system_status.pwr_state == SLEEP )){
|
||
if( adc_updated ){
|
||
|
||
#if 0
|
||
tune と Vol の変化では割り込みを入れない
|
||
// 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;
|
||
}
|
||
}
|
||
|
||
// Volume
|
||
if( abs( old_sndvol - vreg_ctr[ VREG_C_SND_VOL ] ) >= 4 ){
|
||
old_sndvol = vreg_ctr[ VREG_C_SND_VOL ];
|
||
vreg_ctr[ VREG_C_IRQ0 ] |= REG_BIT_VR_SNDVOL_CHANGE;
|
||
if( ( vreg_ctr[ VREG_C_IRQ_MASK0 ] & REG_BIT_VR_SNDVOL_CHANGE ) == 0 ){
|
||
IRQ0_ast;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
// codecに伝える
|
||
if( vreg_ctr[ VREG_C_SND_VOL ] != sndvol_codec ){
|
||
sndvol_codec = vreg_ctr[ VREG_C_SND_VOL ];
|
||
#ifndef _CODEC_CTR_
|
||
iic_mcu_write_a_byte( IIC_SLA_DCP, 0, sndvol_codec );
|
||
#else
|
||
なんとかする
|
||
iic_mcu_write_a_byte( IIC_SLA_CODEC, REG_ADRS_CODEC_VOL, sndvol_codec );
|
||
#endif
|
||
}
|
||
adc_updated = 0;
|
||
}
|
||
|
||
ADCEN = 1;
|
||
ADM = 0b00011011; // セレクトモード、章圧、fCLK/6 ///ここから
|
||
|
||
ADPC = 0x06; // ADCポートのセレクト
|
||
ADS = ADC_SEL_TUNE;
|
||
// NOP();
|
||
ADCS = 1; // AD開始。 /// ここまでに、1us以上開ける
|
||
|
||
ADIF = 0;
|
||
ADMK = 0;
|
||
|
||
LED_duty_TUNE = ((u16)( vreg_ctr[ VREG_C_TUNE ] ) << 2);
|
||
return( 8 );
|
||
}
|
||
}
|
||
|
||
|
||
/* ========================================================
|
||
過去3つのminでもMAXでもない値を返す
|
||
突発的なノイズを除く。
|
||
根本対策ではないが、これはこれで使い道がある。
|
||
======================================================== */
|
||
static u8 getmean3( u8* hist ){
|
||
u8 temp;
|
||
|
||
if( *hist < *( hist+1 ) ){
|
||
temp = *hist;
|
||
*hist = *(hist+1);
|
||
*(hist+1) = temp;
|
||
}
|
||
|
||
if( !( *hist > *(hist+1) )){
|
||
return *hist;
|
||
}else{
|
||
if( *(hist+1) > *(hist+2) ){
|
||
return *(hist+1);
|
||
}else{
|
||
return *(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_TUNE ):
|
||
hist_tune[ index ] = ADCRH;
|
||
vreg_ctr[ VREG_C_TUNE ] = getmean3( hist_tune );
|
||
break;
|
||
|
||
case( ADC_SEL_VOL ):
|
||
temp = ADCRH;
|
||
if( temp > 200 ){
|
||
temp = 200;
|
||
}
|
||
hist_snd_vol[ index ] = temp;
|
||
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_tune );
|
||
renge_task_immed_add( PM_bt_temp_update );
|
||
break;
|
||
|
||
case( ADC_SEL_BATT_DET ):
|
||
// vreg_ctr[ VREG_C_DBG_BATT_DET ] = ADCRH;
|
||
break;
|
||
}
|
||
|
||
|
||
// もっとまともな書き方がありそうだ
|
||
// if( ADS == ADC_SEL_BATT_DET ){
|
||
if( ADS != ADC_SEL_BATT_TEMP ){ // 電池判別は電源投入の一回のみ
|
||
ADS += 1; // 次のチャンネル
|
||
}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;
|
||
ADCS = 0;
|
||
ADM = 0b00100011; // セレクトモード、章圧、fCLK/6 ///ここから
|
||
|
||
ADPC = 0x06; // ADCポートのセレクト
|
||
ADS = ch;
|
||
ADCS = 1; // AD開始。 /// ここまでに、1us以上開ける
|
||
|
||
ADMK = 0;
|
||
while( ADIF == 0 ){;}
|
||
temp = ADCRH;
|
||
ADCEN = 0;
|
||
|
||
return( temp );
|
||
}
|
||
|