ctr_mcu/trunk/vreg_ctr.c
N2232 bcefe4d511 ■0.21
いつの間にか使われ方が変わって長手意を表していない変数などを一部名前変更
一部エラーコードで0を返しなどしてた。ERR_SUCCESSなどを返すように修正
ADCのノイズフィルタを改良
ヒステリシス+四捨五入を追加
Volテーブルを更新。最大音量を-10dbに
TWLからの音量設定を無視→反映、スライダの設定と後着優先になるように修正
 Volのポーリング書き込み廃止、CODECリセット時のために強制セットコマンド追加(command.4)
 そのつもりがなかったので修正量が割とあった。
Vol書き込み時、ベリファイ、一度だけリトライするようにした。発生頻度からすれば良かろう。評価中
バッテリー補正パラメータ更新
I2C_mにライトコマンドがきた直後に次の通信が来ると対応出来ずにバスが衝突(ウェイトコンディション理解してくれないから...)してしまっていた。
 結果:一瞬BL消えや突然の電源断
 一時的にスレーブアドレスを変えてNAKを返し、リトライしてもらうことにした。評価中。
電池残量ゼロ時のパターンをとりあえず高速点滅をプリセットにした。
 交換した電池が0や、完全放電などでMCUがリセットされてSoCからパターンをもらってない場合にLEDが青赤とも消灯になりユーザーが心配するため
お知らせLEDのフルカラー化の両対応コードが間違えていてめちゃめちゃになっていたのを修正
お知らせLEDフルカラー判定を誤ることがあった。マージンを増やした。
白箱を実機と誤判定していた。(FPGAの準備がまだ)判定方法を変更
本体設定や無線スイッチでWiFiを切ったときはフェードなしに。すぱっと変化した方がかっこいい
電源OFFにするとき、3DとWiFiはすぱっと消す。電源とお知らせはフェード(以前のまま)
スリープ期間が極短いとSoC.SLP_OのH期間を取り逃す事があった。
 症状:スリープに入ると電源断以外受け付けなくなる
 I2Cで予告してもらう。
歩数計のログポインタ進めるタイミング、秒レジスタ追加。
割り込み禁止区間の調整
電池残量ICとの通信・通信後のケアなど修正
電池残量0での強制電源断復活
.bin,.hexをリポジトリに追加

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@198 013db118-44a6-b54f-8bf7-843cb86687b1
2010-06-30 05:50:16 +00:00

490 lines
14 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

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.

/* ========================================================
CTR MCU I2Cレジスタ
====================================================== */
#include "incs.h"
#include "vreg_ctr.h"
#include "rtc.h"
#include "led.h"
#include "accero.h"
#include "pm.h"
#include "pool.h"
#include <fsl.h>
#include "fsl_user.h"
extern u8 mcu_info_read(); // task_misc.c
extern u8 iic_burst_state;
// ********************************************************
#ifdef _DBG_PEDO_AUTO_ENABLE_
u8 vreg_ctr[VREG_C_ENDMARK_ + 16];
#else
u8 vreg_ctr[VREG_C_ENDMARK_];
#endif
u8 vreg_free_adrs; // アドレス飛んでるのでしばらくはこれで
bit irq_readed; // AAA型のため。
// ********************************************************
extern task_status_immed tski_firm_update();
extern task_status_immed tski_mcu_info_read();
extern task_status_immed tski_mcu_reset();
// ********************************************************
#ifdef _MCU_BSR_
#define IICAMK IICAMK1
#endif
// ********************************************************
// 非ゼロの初期値の指定が必要なアドレス
// マイコンリセット時に呼ばれます
void vreg_ctr_init( )
{
vreg_ctr[ VREG_C_LED_BRIGHT ] = 0xFF;
vreg_ctr[ VREG_C_VCOM_T ] = VCOM_DEFAULT_T;
vreg_ctr[ VREG_C_VCOM_B ] = VCOM_DEFAULT_B;
vreg_ctr[ VREG_C_OFF_DELAY ] = FORCEOFF_THREASHOLD;
}
// ********************************************************
// 本体の電源投入時にセットされます
void vreg_ctr_reset( )
{
#ifdef _PMIC_TWL_
vreg_ctr[ VREG_C_MCU_VER_MAJOR ] = MCU_VER_MAJOR;
#else
vreg_ctr[ VREG_C_MCU_VER_MAJOR ] = MCU_VER_MAJOR | 0x10;
#endif
vreg_ctr[ VREG_C_MCU_VER_MINOR ] = MCU_VER_MINOR;
vreg_ctr[ VREG_C_VOL_DIGITAL ] = 0x20;
vreg_ctr[ VREG_C_LED_POW ] = 0;
vreg_ctr[ VREG_C_LED_WIFI ] = 0;
vreg_ctr[ VREG_C_LED_CAM ] = 0;
vreg_ctr[ VREG_C_LED_TUNE ] = 0;
{
u8 i;
for( i = 0; i < sizeof( uni_info_LED ); i++ )
{
info_LED.bindata[ i ] = 0;
}
}
}
// ********************************************************
// I2C仮想レジスタに書きます。
// 引数 adrs は内部アドレス
//  書けないアドレスにアクセスした場合、何もしません。
// ●書き込んだ結果、I2C_mcu通信が発生する場合、renge_task_immed_add()
// を使用しないと、I2C_mcu使用中でエラー終了した場合にリトライしません。
void vreg_ctr_write( u8 adrs, u8 data )
{
switch ( adrs )
{
case ( VREG_C_MCU_STATUS ):
// vreg_twl[ REG_TWL_INT_ADRS_MODE ] = (u8)( ( data >> 6 ) & 0x03 ); Rでよい。その代わりリセットでクリア
vreg_ctr[ VREG_C_MCU_STATUS ] = data;
break;
case ( VREG_C_VCOM_T ):
case ( VREG_C_VCOM_B ):
renge_task_immed_add( tski_vcom_set );
vreg_ctr[adrs] = data;
break;
case ( VREG_C_DBG03 ):
if( ( vreg_ctr[VREG_C_DBG01] == 'j' )
&& ( vreg_ctr[VREG_C_DBG02] == 'h' )
&& ( data == 'l' ) )
{
renge_task_immed_add( tski_firm_update );
IICAMK = 1;
}
vreg_ctr[ VREG_C_DBG03 ] = data;
break;
case ( VREG_C_COMMAND0 ):
if( data != 0 )
{
renge_task_immed_add( do_command0 );
}
vreg_ctr[ VREG_C_COMMAND0 ] |= data;
break;
case ( VREG_C_COMMAND2 ):
// こちらからの完了割り込みを待ってくれないそうです。 #-ω-) 何のための割り込みだ
// 液晶電源
if(( data & REG_BIT_CMD_LCD_ON ) != 0 )
{
renge_task_immed_add( tski_PM_LCD_on );
}
else if(( data & REG_BIT_CMD_LCD_OFF ) != 0 )
{
renge_task_immed_add( tski_PM_LCD_off );
}
// バックライト設定
/// 今のところさらに細かくは分けないけど…
if(( data & REG_BITS_CMD_BL ) != 0 )
{
renge_task_immed_add( tski_PM_BL_set );
vreg_ctr[adrs] = (u8)( data & REG_BITS_CMD_BL );
}
break;
case ( VREG_C_COMMAND1 ):
if( data != 0 )
{
// TWLに割り込みを入れる
/// 実際に割り込みを入れるのはSoC
vreg_twl[REG_TWL_INT_ADRS_IRQ] = ( ( data & REG_BIT_SEND_TWL_PWSW_DET ) != 0 ) ? REG_BIT_TWL_IRQ_PWSW_DET : 0x00; //pwsw_det
vreg_twl[REG_TWL_INT_ADRS_IRQ] |= ( ( data & REG_BIT_SEND_TWL_RESET_DET ) != 0 ) ? REG_BIT_TWL_IRQ_RESET : 0x00; //reset_req
vreg_twl[REG_TWL_INT_ADRS_IRQ] |= ( ( data & REG_BIT_SEND_TWL_OFF_DET ) != 0 ) ? REG_BIT_TWL_IRQ_OFF : 0x00; //off_req
vreg_twl[REG_TWL_INT_ADRS_IRQ] |= ( ( data & REG_BIT_SEND_TWL_BATT_LOW ) != 0 ) ? REG_BIT_TWL_IRQ_BT_LOW : 0x00; //batt_low
vreg_twl[REG_TWL_INT_ADRS_IRQ] |= ( ( data & REG_BIT_SEND_TWL_BATT_EMPTY ) != 0 ) ? REG_BIT_TWL_IRQ_BT_EMPTY : 0x00; //batt_empty
if(( data & REG_BIT_SEND_TWL_VOL_CLICK ) != 0 )
{
vreg_twl[REG_TWL_INT_ADRS_IRQ] |= REG_BIT_TWL_IRQ_VOL_CHANGE; //vol_changed
}
}
break;
case ( VREG_C_LED_POW ):
if( iic_burst_state == 0 )
{
vreg_ctr[ VREG_C_LED_POW ] = data;
iic_burst_state += 1;
}
else if( iic_burst_state < 5 )
{
led_red_batt_empty.dats[ iic_burst_state -1 ] = data;
iic_burst_state += 1;
}
break;
case ( VREG_C_LED_WIFI ):
case ( VREG_C_LED_CAM ):
case ( VREG_C_LED_TUNE ):
vreg_ctr[adrs] = (u8)( data & 0x0F );
break;
case ( VREG_C_LED_NOTIFY_DATA ):
if( iic_burst_state < sizeof( uni_info_LED ) )
{
info_LED.bindata[ iic_burst_state ] = data;
iic_burst_state += 1;
}
/// 非同期で動いているためここでは書かない。
// 予約するだけでstopで書く
case ( VREG_C_RTC_SEC ):
case ( VREG_C_RTC_MIN ):
set_rtc( adrs - VREG_C_RTC_SEC, data & 0x7F );
break;
case ( VREG_C_RTC_DAY ):
case ( VREG_C_RTC_HOUR ):
set_rtc( adrs - VREG_C_RTC_SEC, data & 0x3F );
break;
case ( VREG_C_RTC_YOBI ):
set_rtc( adrs - VREG_C_RTC_SEC, data & 0x07 );
break;
case ( VREG_C_RTC_MONTH ):
set_rtc( adrs - VREG_C_RTC_SEC, data & 0x1F );
break;
case ( VREG_C_RTC_YEAR ):
set_rtc( adrs - VREG_C_RTC_SEC, data );
break;
case ( VREG_C_RTC_COMP ):
SUBCUD = data;
vreg_ctr[ VREG_C_RTC_COMP ] = data;
break;
case ( VREG_C_RTC_ALARM_MIN ):
rtc_alarm_dirty = 1;
vreg_ctr[ VREG_C_RTC_ALARM_MIN ] = (u8)( data & 0x7F );
break;
case ( VREG_C_RTC_ALARM_HOUR ):
rtc_alarm_dirty = 1;
vreg_ctr[ VREG_C_RTC_ALARM_HOUR ] = (u8)( data & 0x3F );
break;
// 書くだけでよい
case ( VREG_C_RTC_ALARM_DAY ):
vreg_ctr[ VREG_C_RTC_ALARM_DAY ] = (u8)( data & 0x3F );
break;
case ( VREG_C_RTC_ALARM_MONTH ):
vreg_ctr[ VREG_C_RTC_ALARM_MONTH ] = (u8)( data & 0x1F );
break;
case ( VREG_C_ACC_CONFIG ):
renge_task_immed_add( acc_hosu_set );
vreg_ctr[ VREG_C_ACC_CONFIG ] = data;
break;
case ( VREG_C_ACC_R_ADRS ):
renge_task_immed_add( acc_read );
vreg_ctr[ VREG_C_ACC_R_ADRS ] = data;
break;
case ( VREG_C_ACC_W_BUF ):
renge_task_immed_add( acc_write );
vreg_ctr[ VREG_C_ACC_W_BUF ] = data;
break;
case ( VREG_C_ACC_HOSU_SETTING ):
if( ( data & 0x01 ) != 0 )
{
clear_hosu_hist(); // 履歴クリア
}
break;
case ( VREG_CX_FREE_DATA ):
if( vreg_free_adrs < VREG_C_FREE_SIZE )
{
pool.vreg_c_ext.vreg_c_free[ vreg_free_adrs ] = data;
vreg_free_adrs += 1;
}
break;
case ( VREG_CX_FREE_ADRS ):
vreg_free_adrs = data;
break;
case ( VREG_C_COMMAND3 ):
switch ( data )
{
case ( 'r' ):
// 割り込みルーチンからFSLライブラリを呼ぶのは禁止のため
renge_task_immed_add( tski_mcu_reset );
break;
case ( 'w' ):
// WDTで再起動テスト向け
WDTE = 0xAA;
break;
}
vreg_ctr[ VREG_C_COMMAND3 ] = data;
break;
case ( VREG_C_VOL_DIGITAL ):
vreg_ctr[ VREG_C_VOL_DIGITAL ] = ( data & ~0x40 ); // force vol update bit
if(( data & 0x40 ) != 0 )
{
renge_task_immed_add( tski_vol_update );
}
break;
case ( VREG_C_MCU_VER_MAJOR ):
case ( VREG_C_MCU_VER_MINOR ):
// VREG_C_TUNE = 0x08,
// VREG_C_SND_VOL,
// VREG_C_BT_TEMP,
// VREG_C_BT_REMAIN,
// VREG_C_BT_REMAIN_FINE,
// VREG_C_BT_VOLTAGE,
case ( VREG_C_STATUS_1 ):
case ( VREG_C_STATUS ):
case ( VREG_C_IRQ0 ):
case ( VREG_C_IRQ1 ):
case ( VREG_C_IRQ2 ):
case ( VREG_C_IRQ3 ):
case ( VREG_C_IRQ4 ):
case ( VREG_C_LED_NOTIFY_FLAG ):
case ( VREG_C_RTC_SEC_FINE_L ):
case ( VREG_C_RTC_SEC_FINE_H ):
// VREG_C_ACC_RESERVE,
// VREG_C_ACC_HOSU_HIST = 0x4F,
// read only //
break;
default:
/*
case ( VREG_C_IRQ_MASK0 ):
case ( VREG_C_IRQ_MASK1 ):
case ( VREG_C_IRQ_MASK2 ):
case ( VREG_C_IRQ_MASK3 ):
case ( VREG_C_IRQ_MASK4 ):
case ( VREG_C_DBG01 ):
case ( VREG_C_DBG02 ):
case ( VREG_C_LED_BRIGHT ):
case ( VREG_C_ACC_HOSU_L ):
case ( VREG_C_ACC_HOSU_M ):
case ( VREG_C_ACC_HOSU_H ):
case ( VREG_C_ACC_HOSU_HOUR_BOUNDARY ):
case ( VREG_C_FREE_ADRS ):
case ( VREG_C_RTC_ALARM_YEAR ):
case ( VREG_C_ACC_W_ADRS ):
case ( VREG_C_OFF_DELAY ):
*/
if( adrs < VREG_C_ENDMARK_ )
{
vreg_ctr[adrs] = data;
break;
}
else
{
break;
}
}
return;
}
// ********************************************************
// I2C仮想レジスタから読みます。
// 戻り: xx データ
// 注意:次のアドレスの準備で呼ばれる ので、
// リードされたらクリアなどは気をつける
u8 vreg_ctr_read( u8 adrs )
{
static u16 rsub_temp;
u8 temp;
// RTCは読み出し途中に繰り上がるのを避けるため
if( ( VREG_C_RTC_SEC <= adrs ) && ( adrs <= VREG_C_RTC_YEAR ) )
{
rtc_buf_reflesh( );
}
else if( adrs == VREG_C_MCU_STATUS )
{
return( ( vreg_ctr[ VREG_C_MCU_STATUS ] & 0x03 ) |
( ( vreg_twl[ REG_TWL_INT_ADRS_MODE ] & 0x03 ) << 6 ) | // sys_mode
( ( vreg_twl[ REG_TWL_INT_ADRS_MODE ] & 0x80 ) >> 2 )); // vol32
}
else if( adrs == VREG_C_ACC_HOSU_HIST )
{
return( hosu_read() );
}
else if( adrs == VREG_CX_FREE_DATA )
{
temp = pool.vreg_c_ext.vreg_c_free[ vreg_free_adrs ];
// vreg_free_adrs += 1; // ここで加算してしまうとインデックスがずれる
return( temp );
}
else if( adrs == VREG_C_RTC_SEC_FINE_L )
{
rsub_temp = RSUBC;
return( (u8)( rsub_temp & 0xFF ) );
}
else if( adrs == VREG_C_RTC_SEC_FINE_H )
{
return( (u8)( ( rsub_temp >> 8 ) & 0xFF ) );
}
else if( adrs == VREG_CX_INFO )
{
// I2C_mを使うので、ここからでは割り込みが使えなくて困る
// なのでタスク登録する。
// 強制的にI2C_2割り込みをマスクする
renge_task_immed_add( tski_mcu_info_read );
IICAMK = 1;
return( 0x4A );
}
#if 0
if( adrs >= VREG_C_ENDMARK_ )
{
// VREG_C_INFO > VREG_C_ENDMARK_ なので
// いじるときは注意
return( 0xEE );
}
#endif
return ( vreg_ctr[adrs] );
}
// ********************************************************
// I2C仮想レジスタから読まれて何かするレジスタ
void vreg_ctr_after_read( u8 adrs )
{
// 割り込みフラグはリードでクリア
switch( adrs )
{
case VREG_C_IRQ0:
case VREG_C_IRQ1:
case VREG_C_IRQ2:
case VREG_C_IRQ3:
case VREG_C_IRQ4:
vreg_ctr[ adrs ] = 0;
irq_readed = 1;
break;
case VREG_CX_FREE_DATA:
vreg_free_adrs += 1;
break;
default:
break;
}
}
/******************************************************************************
割り込みを入れる
割り込みマスクが必要と言うことでこんな事をする羽目になりました
*****************************************************************************/
#if 0
// マスクされてたら、フラグは立てるが、割り込みは入れない。
#define set_irq( irqreg, bitpos ) \
{ \
vreg_ctr[ irqreg ] |= bitpos; \
if( ( vreg_ctr[ irqreg+8 ] & bitpos ) == 0 ){ \
IRQ0_ast; \
} \
}
#endif
// マスクされてたら、フラグも立てず、割り込みも入れない。
void set_irq( u8 irqreg, u8 irq_flg )
{
u8 tot;
if(( system_status.pwr_state == ON ) ||
( system_status.pwr_state == SLEEP ))
{
// DI();
if( ( vreg_ctr[ irqreg + 8 ] & irq_flg ) == 0 ){
vreg_ctr[ irqreg ] |= irq_flg;
IRQ0_neg; // 一瞬上げて...
// EI();
tot = 0;
while( !IRQ0 && ( ++tot != 0 ) ){;} // O.D.なのでちゃんとあがるのを待つ IRQ_mcu がLに縛られてると困る(基板不良)
IRQ0_ast; // 落とし直す。
}
}
// EI();
}