mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-06-18 16:45:33 -04:00

flower、CTRと同じバッテリーを使うそうなのでパラメータを削除(マップは改変後のままにしてある) flower の LCD に合わせて修正(SoCにはバックライトが二枚あるように見せている。プロセス変更不要) ほか、もういらないコメントアウトなど削除 git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@500 013db118-44a6-b54f-8bf7-843cb86687b1
313 lines
8.2 KiB
C
313 lines
8.2 KiB
C
/* ========================================================
|
||
対SoC 新規チャンネル I2C通信
|
||
藤田@開技.nintendo
|
||
'09 Apr
|
||
$Id: i2c_ctr.c 418 2011-09-22 01:35:37Z n2232 $
|
||
======================================================== */
|
||
#ifndef _WIN32
|
||
#pragma interrupt INTIICA1 int_iic_ctr RB1
|
||
#endif
|
||
|
||
|
||
#include "incs.h"
|
||
#include "rtc.h"
|
||
#include "pedometer.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
|
||
#define PortMode PM20
|
||
#define Port P20
|
||
|
||
#endif
|
||
|
||
|
||
|
||
// ==============================================
|
||
enum en_IIC_STATE
|
||
{
|
||
IIC_IDLE = 0,
|
||
IIC_RCV_REG_ADRS,
|
||
IIC_TX_OR_RX,
|
||
IIC_TX,
|
||
IIC_RX
|
||
};
|
||
|
||
|
||
|
||
// ==============================================
|
||
extern bit irq_readed; // いずれかのIRQレジスタが読まれた
|
||
|
||
u8 iic_burst_state;
|
||
static enum en_IIC_STATE state = IIC_IDLE;
|
||
|
||
#define bit_iics_spd (i2c_stat & (1<<0))
|
||
#define bit_iics_std (i2c_stat & (1<<1))
|
||
#define bit_iics_ackd (i2c_stat & (1<<2))
|
||
#define bit_iics_trc (i2c_stat & (1<<3))
|
||
#define bit_iics_coi (i2c_stat & (1<<4))
|
||
|
||
|
||
|
||
/********************************************//**
|
||
isr
|
||
|
||
ステート毎に割り込みが入り処理を進める
|
||
***********************************************/
|
||
__interrupt void int_iic_ctr( )
|
||
{
|
||
static u8 reg_adrs;
|
||
static u8 tx_buf;
|
||
u8 rx_buf;
|
||
static u8 adrs_access_from; // バーストアクセスの時に使う
|
||
|
||
u8 i2c_stat = IICS; // volatileのため
|
||
|
||
// 読み出し終了
|
||
if( !bit_iics_ackd // 割り込み要因はNAK(データ送信の最後)
|
||
|| bit_iics_spd ) // ストップコンディション(!ACKD に来たときは割り込み来ない (SPIE = 0))
|
||
{
|
||
/*
|
||
I2Cの反応が遅くてこのフラグを処理する前にSTDがきてしまうことがある
|
||
けど、問題なく動作するつもり
|
||
*/
|
||
|
||
// レジスタリードで、割り込みピンをネゲート
|
||
// まだ読まれてない割り込みがあれば、再度アサート
|
||
if( irq_readed )
|
||
{
|
||
IRQ0_neg;
|
||
irq_readed = false;
|
||
if( !( (( vreg_ctr[VREG_C_IRQ0] & vreg_ctr[VREG_C_IRQ_MASK0 ] ) == 0 )
|
||
&& (( vreg_ctr[VREG_C_IRQ1] & vreg_ctr[VREG_C_IRQ_MASK1 ] ) == 0 )
|
||
&& (( vreg_ctr[VREG_C_IRQ2] & vreg_ctr[VREG_C_IRQ_MASK2 ] ) == 0 )
|
||
&& (( vreg_ctr[VREG_C_IRQ3] & vreg_ctr[VREG_C_IRQ_MASK3 ] ) == 0 ) ))
|
||
{
|
||
while( !IRQ0 ){;} // 時間稼ぎ不要かも
|
||
IRQ0_ast;
|
||
}
|
||
}
|
||
|
||
// I2C終了時に何かする物 //
|
||
hosu_read_end( ); // 歩数計読み出し終了
|
||
rtc_unlock( );
|
||
|
||
state = IIC_IDLE;
|
||
SPIE = 0;
|
||
LREL = 1;
|
||
EI();
|
||
return;
|
||
}
|
||
|
||
if( bit_iics_std ) // 割り込み要因:スタートコンディション
|
||
{
|
||
if( !( state == IIC_IDLE || state == IIC_TX_OR_RX ))
|
||
{
|
||
// sp/nack 取り損ねた
|
||
// dbg_nop(); // こないはず...
|
||
/*
|
||
// パケットの先頭のstと見なす。
|
||
// 普通に続行
|
||
state = IIC_IDLE;
|
||
/*/
|
||
// リトライしてもらう
|
||
state = IIC_IDLE;
|
||
SPIE = 0;
|
||
LREL = 1;
|
||
EI();
|
||
//*/
|
||
}
|
||
// 通常
|
||
}
|
||
|
||
EI();
|
||
|
||
switch ( state )
|
||
{
|
||
case ( IIC_IDLE ):
|
||
// 自局呼び出しに応答。
|
||
// 初期化など
|
||
iic_burst_state = 0;
|
||
SPIE = 1;
|
||
WREL = 1; // ウェイト解除
|
||
state = IIC_RCV_REG_ADRS;
|
||
return;
|
||
|
||
case ( IIC_RCV_REG_ADRS ): // 2バイト目(レジスタアドレス)受信後に来る
|
||
// レジスタアドレス受信
|
||
reg_adrs = IICA;
|
||
|
||
WREL = 1;
|
||
adrs_access_from = reg_adrs;
|
||
tx_buf = vreg_ctr_read( reg_adrs ); // データの準備をしておく
|
||
state = IIC_TX_OR_RX;
|
||
return;
|
||
|
||
case ( IIC_TX_OR_RX ): // ↑の次に来る割り込み。STなら送信準備、データが来たら書き込まれ
|
||
// if( TRC ) // 送信方向フラグ で区別するのは、割り込み遅延時に不具合が起こりえる
|
||
if( bit_iics_std )
|
||
{ // スタートコンディション検出フラグ
|
||
// リードされる
|
||
if( bit_iics_coi )
|
||
{ // アドレス一致フラグ
|
||
state = IIC_TX;
|
||
// no break, no return //
|
||
}
|
||
else
|
||
{
|
||
// リスタートで違うデバイスが呼ばれた!
|
||
SPIE = 0;
|
||
LREL = 1; // ウェイト解除?
|
||
state = IIC_IDLE; // 終了処理
|
||
return;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
state = IIC_RX; // データ1バイト受信の割り込みだった
|
||
// no break, no return //
|
||
}
|
||
/* FALLTHROUGH */
|
||
|
||
default: // バースト R/W でここが何回も呼ばれることになる
|
||
if( state == IIC_TX )
|
||
{ // 送信
|
||
IICA = tx_buf;
|
||
vreg_ctr_after_read( reg_adrs, tx_buf ); // 読んだらクリアなどの処理
|
||
}
|
||
else
|
||
{ // 受信
|
||
rx_buf = IICA;
|
||
|
||
#ifdef _I2C_ERR_ABORT_
|
||
if( reg_adrs >= 0x80 || reg_adrs <= 1 )
|
||
{
|
||
LREL = 1; // なんかデータ化けたので通信終了 nakが返るのがなぁ…
|
||
return;
|
||
}
|
||
#endif
|
||
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:
|
||
reg_adrs ++;
|
||
}
|
||
|
||
if( state == IIC_TX )
|
||
{ // さらにつぎに送るデータの準備だけシテオク。SPが来て使われないかもしれない
|
||
tx_buf = vreg_ctr_read( reg_adrs );
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
モジュール初期化
|
||
|
||
todo twl の init と統合?
|
||
|
||
ビット操作が多いのでかえって不経済かもしれない
|
||
***********************************************/
|
||
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 */ スタック不足
|
||
|
||
Port &= ~0x03;
|
||
|
||
SVA = IIC_C_SLAVEADDRESS;
|
||
IICF = 0x01;
|
||
|
||
STCEN = 1; // リスタートの許可
|
||
IICRSV = 1; // 通信予約をさせない:スレーブに徹する
|
||
|
||
SPIE = 0; // ストップコンディションでの割り込みを禁止
|
||
WTIM = 1; // 自動でACKを返した後clkをLに固定する
|
||
ACKE = 1;
|
||
|
||
IICWH = 9;
|
||
IICWL = 11; // L期間の長さ
|
||
|
||
SMC = 1; // 高速モード
|
||
DFC = 1; // デジタルフィルタon (@fast mode)
|
||
|
||
IICAMK = 0; // 割り込みを許可
|
||
|
||
IICE = 1;
|
||
|
||
PortMode &= ~0x03;
|
||
|
||
state = IIC_IDLE;
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
|
||
***********************************************/
|
||
void IIC_ctr_Stop( void )
|
||
{
|
||
IICE = 0; /* IICA disable */
|
||
IICAEN = 0;
|
||
}
|
||
|
||
|
||
|