ctr_mcu/trunk/i2c_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

289 lines
7.7 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.

/* ========================================================
対SoC 新規チャンネル I2C通信
藤田@開技.nintendo
'09 Apr
======================================================== */
#include "config.h"
#ifdef _MCU_KE3_
#pragma interrupt INTIICA int_iic_ctr // CTR側
#else
// TSはマザボでテレコ、WMは回路図がテレコで結局一致…
#pragma interrupt INTIICA1 int_iic_ctr RB1
#endif
#include "incs.h"
#ifdef _MCU_BSR_
// #ifdef _MODEL_TS0_ || _MODEL_WM0_
// ワーキングモデルはI2Cが逆
// TEGは回路図でテレコ
#define ACKD ACKD1
#define ACKE ACKE1
#define COI COI1
#define IICAEN IICA1EN
#define IICRSV IICRSV1
#define IICA IICA1
#define IICAIF IICAIF1
#define IICAMK IICAMK1
#define IICAPR0 IICAPR11
#define IICAPR1 IICAPR01
#define IICCTL0 IICCTL10
#define IICE IICE1
#define IICF IICF1
#define IICS IICS1
#define IICWH IICWH1
#define IICWL IICWL1
#define LREL LREL1
#define SPD SPD1
#define SPIE SPIE1
#define STCEN STCEN1
#define STD STD1
#define SVA SVA1
#define WREL WREL1
#define WTIM WTIM1
#define TRC TRC1
#define SMC SMC1
#define DFC DFC1
#endif
// ==============================================
extern bit irq_readed; // いずれかのIRQレジスタが読まれた
u8 iic_burst_state;
/* ========================================================
======================================================== */
enum
{
IIC_IDLE = 0,
IIC_RCV_REG_ADRS,
IIC_TX_OR_RX,
IIC_TX,
IIC_RX
};
// 1バイト送受の度に割り込みが発生するバージョン
__interrupt void int_iic_ctr( )
{
static u8 state = IIC_IDLE;
static u8 reg_adrs;
static u8 reg_adrs_internal;
static u8 tx_buf;
u8 rx_buf;
static u8 adrs_access_from;
EI();
// 読み出し終了
if( !ACKD ) // 割り込み要因はNAKデータ送信の最後
{
state = IIC_IDLE;
SPIE = 0;
LREL = 1;
// レジスタリードで、割り込みピンをネゲート
// まだ読まれてない割り込みがあれば、再度アサート
if( irq_readed )
{
IRQ0_neg;
irq_readed = 0;
if( !( ( vreg_ctr[VREG_C_IRQ0] == 0 )
&& ( vreg_ctr[VREG_C_IRQ1] == 0 )
&& ( vreg_ctr[VREG_C_IRQ2] == 0 )
&& ( vreg_ctr[VREG_C_IRQ3] == 0 ) ) )
{
while( !IRQ0 ){;} // 時間稼ぎ不要かも
IRQ0_ast;
}
}
// 歩数計読み出し終了
hosu_read_end( );
rtc_unlock( );
iic_burst_state = 0;
return;
}
if( SPD ) // 割り込み要因はストップコンディション
// 通信の最後。↑の !ACKD に来たときは割り込み来ない (SPIE = 0 のため )
{
state = IIC_IDLE;
SPIE = 0;
// I2C終了時に何かする物 //
rtc_unlock( );
return;
}
if( STD ) // 割り込み要因:スタートコンディション
{
if( ( state == IIC_TX ) || ( state == IIC_RX )
|| ( state == IIC_RCV_REG_ADRS )
)
{
state = IIC_IDLE;
// no break //
}
}
switch ( state )
{
case ( IIC_IDLE ):
// 自局呼び出しに応答。
// 初期化など
SPIE = 1;
state = IIC_RCV_REG_ADRS;
WREL = 1; // ウェイト解除
break;
case ( IIC_RCV_REG_ADRS ): // 2バイト目(レジスタアドレス)受信後に来る
// レジスタアドレス受信
reg_adrs = IICA;
adrs_access_from = reg_adrs;
tx_buf = vreg_ctr_read( reg_adrs ); // データの準備をしておく
if( reg_adrs != VREG_CX_INFO ) // 特殊なバーストリードを行うため、割り込み駆動から外す
{
state = IIC_TX_OR_RX;
}
else
{
state = IIC_IDLE;
}
WREL = 1;
break;
case ( IIC_TX_OR_RX ): // ↑の次に来る割り込み。STなら送信準備、データが来たら書き込まれ
// if( TRC ){ // 送信方向フラグ で区別するのは、割り込み遅延時に不具合が起こりえる
if( STD )
{ // スタートコンディション検出フラグ
// リードされる
if( COI )
{ // アドレス一致フラグ
state = IIC_TX;
// no break, no return //
}
else
{
// リスタートで違うデバイスが呼ばれた!
state = IIC_IDLE; // 終了処理
SPIE = 0;
LREL = 1; // ウェイト解除?
return;
}
}
else
{
state = IIC_RX; // データ1バイト受信の割り込みだった
// no break, no return //
}
default: // バースト R/W でここが何回も呼ばれることになる
if( state == IIC_TX )
{ // 送信
IICA = tx_buf;
vreg_ctr_after_read( reg_adrs ); // 読んだらクリアなどの処理
}
else
{ // 受信
rx_buf = IICA;
vreg_ctr_write( reg_adrs, rx_buf );
WREL = 1;
}
// レジスタアドレスのインクリメント
/// アクセスポインタを進めない特殊なレジスタ
switch( adrs_access_from )
{
case( VREG_C_ACC_HOSU_HIST ):
case( VREG_C_LED_NOTIFY_DATA ):
case( VREG_C_LED_POW ):
case( VREG_CX_INFO ):
case( VREG_CX_FREE_DATA ):
break;
case( VREG_CX_FREE_ADRS ):
if( reg_adrs == VREG_CX_FREE_ADRS )
{
reg_adrs = VREG_CX_FREE_DATA;
}
break;
default:
iic_burst_state = 0; // 保険
reg_adrs += 1;
}
if( state == IIC_TX )
{ // さらにつぎに送るデータの準備だけシテオク。SPが来て使われないかもしれない
tx_buf = vreg_ctr_read( reg_adrs );
}
break;
}
}
// ========================================================
void IIC_ctr_Init( void )
{
IICAEN = 1;
IICE = 0; /* IICA disable */
IICAMK = 1; /* INTIICA disable */
IICAIF = 0; /* clear INTIICA interrupt flag */
IICAPR0 = 1; /* set INTIICA high priority */
IICAPR1 = 0; /* set INTIICA high priority */
#ifdef _MODEL_TEG2_
P6 &= ~0x3;
#else
P20 &= ~0x3;
#endif
SVA = IIC_C_SLAVEADDRESS;
IICF = 0x01;
STCEN = 1; // リスタートの許可
IICRSV = 1; // 通信予約をさせない:スレーブに徹する
SPIE = 0; // ストップコンディションでの割り込みを禁止
WTIM = 1; // 自動でACKを返した後clkをLに固定する
ACKE = 1; // ダメCPUは無視して次の通信をはじめるかもしれないんで早くclkを開放しないといけない
IICWH = 5;
IICWL = 10; // L期間の長さ
SMC = 1; // 高速モード
DFC = 1; // デジタルフィルタon (@fast mode)
IICAMK = 0; // 割り込みを許可
IICE = 1;
#ifdef _MODEL_TEG2_
PM6 &= ~0x3; /* set clock pin for IICA */
#else
PM20 &= ~0x3; /* set clock pin for IICA */
#endif
}
// ========================================================
void IIC_ctr_Stop( void )
{
IICE = 0; /* IICA disable */
IICAEN = 0;
}