ctr_mcu/trunk/vreg_ctr.c
n2232 7e58fd13c4 typo修正
iic_mcu_read_a_byte() 失敗時、返値が不定だったのを 0xff に固定
市部も関数名・マクロ名を、体を表すよう変更(_snake向けからの輸入)

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@597 013db118-44a6-b54f-8bf7-843cb86687b1
2014-01-07 01:22:23 +00:00

639 lines
17 KiB
C
Raw Permalink 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.

/* ========================================================
CTR MCU I2Cレジスタ
$Id$
====================================================== */
#include "incs.h"
#include "vreg_ctr.h"
#include "rtc.h"
#include "led.h"
#include "accero.h"
#include "pm.h"
#include "pool.h"
#include "vreg_twl.h"
#include "sw.h"
#include "WDT.h"
#include <fsl.h>
#include "fsl_user.h"
extern u8 extinfo_read(); // task_misc.c
extern u8 iic_burst_state; // 特殊バーストアクセスする時のカウンタ
extern bit info_led_pattern_updated; // お知らせLEDのパターンを先頭に戻す
extern bit pedolog_overflow;
extern bit reserve_pedo_increnent;
// ********************************************************
u8 vreg_ctr[VREG_C_ENDMARK_];
static u8 vreg_free_adrs; // アドレス飛んでるのでしばらくはこれで
bit irq_readed; // AAA型のため。
// ********************************************************
extern task_status_immed tski_firm_update();
extern task_status_immed tski_mcu_reset();
extern unsigned char get_ei();
// ********************************************************
#ifdef _MCU_BSR_
#define IICAMK IICAMK1
#endif
/********************************************//**
初期化
非ゼロの初期値の指定が必要なアドレス
マイコンリセット時に呼ばれます
***********************************************/
void vreg_ctr_init( )
{
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;
vreg_ctr[ VREG_C_VOL_CAL_MIN ] = 0x36;
vreg_ctr[ VREG_C_VOL_CAL_MAX ] = 0xFF - 0x36;
}
/********************************************//**
初期値セット
システムリセット時に呼ばれます
***********************************************/
void vreg_ctr_reset( )
{
vreg_ctr[ VREG_C_MCU_VER_MAJOR ] = MCU_VER_MAJOR | 0x10;
vreg_ctr[ VREG_C_MCU_VER_MINOR ] = MCU_VER_MINOR;
// vreg_ctr[ VREG_C_STATUS ] &= bits8(0,0,0,1, 1,1,1,1);
vreg_ctr[ VREG_C_LED_BRIGHT ] = 0xFF;
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_3D ] = 0;
{
u8 i;
for( i = 0; i < sizeof( uni_info_LED ); i++ )
{
info_LED.bindata[ i ] = 0;
}
}
vreg_ctr[ VREG_C_WIFI_CALIB ] = 0;
// ここでやるのは気持ち悪いが…
RTC_32k_on();
RESET1_neg;
RESET2_neg;
FCRAM_RST_neg;
}
/********************************************//**
I2C仮想レジスタに書きます。
 引数 adrs は内部アドレス
 書けないアドレスにアクセスした場合、何もしません。
●書き込んだ結果、I2C_mcu通信が発生する場合、renge_task_immed_add()
を使用しないと、I2C_mcu使用中でエラー終了した場合にリトライしません。
***********************************************/
void vreg_ctr_write( u8 adrs, u8 data )
{
switch ( adrs )
{
case VREG_C_COMMAND0:
if( data != 0 )
{
renge_task_immed_add( tski_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 )
{
// u8 temp; 中間変数使ったらばかでかくなった...
// 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_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 ++;
}
else
{
dbg_nop();
}
break;
case VREG_CX_FREE_ADRS:
vreg_free_adrs = data;
break;
case VREG_C_LED_POW:
if( iic_burst_state == 0 )
{
vreg_ctr[ VREG_C_LED_POW ] = data;
iic_burst_state ++;
}
else if( iic_burst_state < 5 )
{
led_red_batt_empty.dats[ iic_burst_state -1 ] = data;
iic_burst_state ++;
}
break;
case VREG_C_LED_WIFI:
case VREG_C_LED_CAM:
case VREG_C_LED_3D:
vreg_ctr[adrs] = (u8)( data & 0x0F );
break;
case VREG_C_LED_NOTIFY_DATA:
if( iic_burst_state < sizeof( uni_info_LED ) )
{
if(( iic_burst_state == 1 ) && ( data == 0 )) // fade_time == 0 禁止
{
data = 1;
}
info_LED.bindata[ iic_burst_state ] = data;
iic_burst_state ++;
if( iic_burst_state > 4 ) // パターンを1文字でも書いた
{
info_led_pattern_updated = true;
}
}
break;
case VREG_C_MCU_STATUS:
// vreg_twl[ REG_TWL_INT_ADRS_MODE ] = (u8)( ( data >> 6 ) & 0x03 ); Rでよい。その代わりリセットでクリア
vreg_ctr[ VREG_C_MCU_STATUS ] &= data; // bitクリアはするがセットはしない。
// 上の方のtwlレジスタミラーは読み出され時に合成
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;
/// 非同期で動いているためここでは書かない。
// 予約するだけで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:
WDT_Restart();
while(1)
{
RWAIT = 1;
while( !RWST ){}
if( SEC != 0 )
{
break;
}
RWAIT = 0;
}
SUBCUD = data;
RWAIT = 0;
vreg_ctr[ VREG_C_RTC_COMP ] = data;
break;
case VREG_C_RTC_ALARM_MIN:
rtc_alarm_dirty = true;
vreg_ctr[ VREG_C_RTC_ALARM_MIN ] = (u8)( data & 0x7F );
break;
case VREG_C_RTC_ALARM_HOUR:
rtc_alarm_dirty = true;
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( tski_acc_setup );
vreg_ctr[ VREG_C_ACC_CONFIG ] = data;
break;
case VREG_C_ACC_R_ADRS:
renge_task_immed_add( tski_acc_read );
vreg_ctr[ VREG_C_ACC_R_ADRS ] = data;
break;
case VREG_C_ACC_W_BUF:
renge_task_immed_add( tski_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_C_WIFI_CALIB:
if( data & REG_BIT_WIFI_CALIB_32K_HI_Z )
{
RTC_32k_HI_Z();
}
else{
RTC_32k_on();
}
if( data & REG_BIT_WIFI_CALIB_RSTS_AST )
{
RESET1_ast;
// RESET2_ast; RESET1のみ。
// FCRAM_RST_ast;
}
else{
/*
SoC が止まってしまうのでここに来ない
RESET1_neg;
RESET2_neg;
FCRAM_RST_neg;
*/
}
vreg_ctr[ VREG_C_WIFI_CALIB ] = data;
break;
case VREG_C_COMMAND3:
switch ( data )
{
#ifdef _ENABLE_COMMAND3_
case 'r':
// 割り込みルーチンからFSLライブラリを呼ぶのは禁止
// マイコンを再起動。 レジスタ類も初期化される。
renge_task_immed_add( tski_mcu_reset );
break;
case 'w':
// WDTで再起動テスト向け
// mcu_wdt_reset; // このコマンド使ったら意味ないでしょ!
while(1)
{
dbg_nop();
}
break;
#endif //_ENABLE_COMMAND3_
#ifdef _ENABLE_HAL_
case 'p':
reserve_pedo_increnent = 1;
// ここで増やすにはスタックが足りない。↑で予約のみ、task_misc内で処理
// hosu_increment_if_necessary(); // 今、一歩増えた
break;
#endif //_ENABLE_HAL_
}
// vreg_ctr[ VREG_C_COMMAND3 ] = data; // 書く必要なし
break;
case VREG_C_RBR_CONTROL:
// vreg_ctr[ VREG_C_RBR_CONTROL ] = data; // todo debug ブレークポイントを置くため。現状、フリーレジスタ
break;
// read only //////////////////////////////////////////
case VREG_C_MCU_VER_MAJOR:
case VREG_C_MCU_VER_MINOR:
case VREG_C_3D: // すぐにリフレッシュされる
case VREG_C_SND_VOL: // すぐにリフレッシュされる
case VREG_C_BT_TEMP: // すぐにリフレッシュされる
case VREG_C_BT_REMAIN: // すぐにリフレッシュされる
case VREG_C_BT_REMAIN_FINE: // すぐにリフレッシュされる
case 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,
case VREG_C_ACC_XH: // すぐリフレッシュされる
case VREG_C_ACC_XL:
case VREG_C_ACC_YH:
case VREG_C_ACC_YL:
case VREG_C_ACC_ZH:
case VREG_C_ACC_ZL:
// dbg_nop();
// return( ERROR )
break;
case VREG_C_ACC_HOSU_L: // 書けてもいいけど、デバッグ用。(アドレス0x4B == mcu sla(r))
// dbg_nop();
/* FALLTHROUGH */
// 普通に書かれるだけ /////////////////////////////////
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:
case VREG_C_HAL_OVW_CONT0:
case VREG_C_HAL_OVW_DAT0:
case VREG_C_HAL_OVW_CONT1:
case VREG_C_HAL_OVW_DAT1:
*/
if( adrs < VREG_C_ENDMARK_ )
{
vreg_ctr[adrs] = data;
break;
}
else
{
// dbg_nop(); // 未定義アドレスに書いた なんかバグってない?
// return( ERROR )
break;
}
}
// return( SUCCESS )
return;
}
/********************************************//**
I2C仮想レジスタから読みます。
戻り: xx データ
注意:次のアドレスの準備で呼ばれる ので、
リードされたらクリアなどは気をつける
( →vreg_ctr_after_read( u8 adrs ) )
***********************************************/
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_refresh( );
}
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_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 ) );
}
/*
// debug 的な
else if( adrs == VREG_C_IRQ_MASK0 )
{
return( vreg_ctr[ VREG_C_IRQ_MASK0 ] & 0x7F ); // ぜったいにMSBは0。1なら通信エラー
}
*/
else if( adrs == VREG_C_ACC_HOSU_HIST )
{
return( hosu_read() );
}
else if( adrs == VREG_CX_FREE_DATA )
{
if( vreg_free_adrs >= VREG_C_FREE_SIZE )
{
temp = 0x00;
}
else
{
temp = pool.vreg_c_ext.vreg_c_free[ vreg_free_adrs ];
// vreg_free_adrs ++; // ここで加算してしまうとインデックスがずれる
}
return( temp );
}
else if( adrs == VREG_CX_INFO )
{
return( extinfo_read() );
}
else if( adrs == VREG_C_ACC_HOSU_SETTING )
{
if( pedolog_overflow )
{
return( 0x10 );
}
else
{
return( 0 );
}
}
if( adrs >= VREG_C_ENDMARK_ )
{
// VREG_C_INFO > VREG_C_ENDMARK_ なのでいじるとき注意
return( 0xFF );
}
return ( vreg_ctr[adrs] );
}
/********************************************//**
I2C仮想レジスタから読まれて何かするレジスタ
***********************************************/
void vreg_ctr_after_read( u8 adrs, u8 data )
{
// 割り込みフラグはリードでクリア
switch( adrs )
{
case VREG_C_IRQ0:
case VREG_C_IRQ1:
case VREG_C_IRQ2:
case VREG_C_IRQ3:
case VREG_C_IRQ4:
DI_wt_chk();
vreg_ctr[ adrs ] ^= data;
EI();
irq_readed = true;
break;
case VREG_CX_FREE_DATA:
vreg_free_adrs ++;
break;
default:
break;
}
}
/********************************************//**
割り込みを入れる
-  マスクされてたら、フラグ「立てない」、割り込み入れない。
-  割り込みを入れ、読み出される前にマスクがかかったときは、SoC上の処理キュー上には
IRQを読むタスクが積んであるので、読みには来る。
 それと、念のため、マスクをいじるときは空読みしてもらう。
★すでにDIかのチェック不要。
 DI中に来るのはI2C_twlか、RTC_アラーム。この中で無頓着にEIして実使用上問題ない
***********************************************/
void set_irq( u8 irqreg, u8 irq_flg )
{
u8 tot;
//0 u8 ei_orig; // EIフラグ保存
if(( system_status.pwr_state == ON ) ||
( system_status.pwr_state == SLEEP ))
{
/*0 すでにDI状態ならケアが必要かもしれない
ei_orig = get_ei();
//. debug
if( !ei_orig )
{
dbg_nop();
}
DI_wt_chk();
*/
DI();
if( ( vreg_ctr[ irqreg + 8 ] & irq_flg ) == 0 )
{
vreg_ctr[ irqreg ] |= irq_flg;
IRQ0_neg; // 一瞬上げて...
//0 if( ei_orig )
{
EI();
}
tot = 0;
while( !IRQ0 && ( ++tot != 0 ) ){;} // O.D.なのでちゃんとあがるのを待つ IRQ_mcu がLに縛られてると困る(基板不良)
IRQ0_ast; // 落とし直す。(エッジ割り込みの為)
}
//0 if( ei_orig )
{
EI();
}
}
}