ctr_mcu/trunk/vreg_ctr.c
N2232 2a6ddf4d26 0.17
・レジスタ書き込みでの強制ボリュームセット実装
・パナソニックのバッテリパラメータをダミーから差し替え(まだ機能してない)
・フルカラーお知らせ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
2010-05-24 04:10:36 +00:00

441 lines
12 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;
// ********************************************************
u8 vreg_ctr[VREG_C_ENDMARK_];
u8 vreg_free_adrs; // アドレス飛んでるのでしばらくはこれで
bit irq_readed; // AAA型のため。
// ********************************************************
extern task_status_immed tski_firm_update();
extern task_status_immed tski_mcu_info_read();
// ********************************************************
#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 ] = ( ( data & 0xC0 ) >> 6 );
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] = ( 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
vreg_twl[REG_TWL_INT_ADRS_IRQ] |= ( ( data & REG_BIT_SEND_TWL_VOL_CLICK ) != 0 ) ? REG_BIT_TWL_IRQ_VOL_CHANGE : 0x00; //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] = 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_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 ] = ( data & 0x7F );
break;
case ( VREG_C_RTC_ALARM_HOUR ):
rtc_alarm_dirty = 1;
vreg_ctr[ VREG_C_RTC_ALARM_HOUR ] = ( data & 0x3F );
break;
// 書くだけでよい
case ( VREG_C_RTC_ALARM_DAY ):
vreg_ctr[ VREG_C_RTC_ALARM_DAY ] = ( data & 0x3F );
break;
case ( VREG_C_RTC_ALARM_MONTH ):
vreg_ctr[ VREG_C_RTC_ALARM_MONTH ] = ( 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;
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_VOL_DIGITAL ):
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 ] | ( ( vreg_twl[ REG_TWL_INT_ADRS_MODE ] & 0x03 ) << 6 ) );
}
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 1
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 ) ||
( system_status.pwr_state == SLEEP_TRIG ))
{
// 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();
}