mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-06-19 00:55:37 -04:00

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@94 013db118-44a6-b54f-8bf7-843cb86687b1
249 lines
6.6 KiB
C
249 lines
6.6 KiB
C
/* ========================================================
|
||
対SoC 新規チャンネル I2C通信
|
||
藤田@開技.nintendo
|
||
'09 Apr
|
||
======================================================== */
|
||
#include "incs.h"
|
||
#include "accero.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レジスタが読まれた
|
||
|
||
|
||
|
||
/* ========================================================
|
||
======================================================== */
|
||
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;
|
||
|
||
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( );
|
||
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;
|
||
tx_buf = vreg_ctr_read( reg_adrs ); // データの準備をしておく
|
||
state = IIC_TX_OR_RX;
|
||
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;
|
||
}
|
||
if( reg_adrs != VREG_C_ACC_HOSU_HIST )
|
||
{
|
||
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;
|
||
}
|