ctr_mcu/trunk/adc.c
fujita_ryohei 218026b2e2 V0.3
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
2009-09-15 01:16:25 +00:00

193 lines
4.7 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* ========================================================
藤田@開技
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毎に呼ばれ、チャンネル分取り込むと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 );
}
}
/* ========================================================
 過去つの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 );
}