ctr_mcu/trunk/i2c_ctr.c
fujita_ryohei 55ef3eee63 レジスタマップの変更に対応
一部のマクロを関数に置き換え
温度の計算をまじめに行う。浮動小数点を使ったら1msも掛かった
 場合によっては戻す


git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@25 013db118-44a6-b54f-8bf7-843cb86687b1
2009-11-12 08:59:53 +00:00

248 lines
6.0 KiB
C

/* ========================================================
対SoC 新規チャンネル I2C通信
藤田@開技.nintendo
'09 Apr
======================================================== */
#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
#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 trx_buf;
EI();
if( SPD )
{
state = IIC_IDLE;
SPIE = 0;
// I2C終了時に何かする物 //
rtc_unlock( );
return;
}
// 読み出し終了
if( !ACKD )
{
state = IIC_IDLE;
SPIE = 0;
LREL = 1;
rtc_unlock( );
// レジスタリードで、割り込みピンをネゲート
// まだ読まれてない割り込みがあれば、再度アサート
if( irq_readed )
{
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 )
&& ( vreg_ctr[VREG_C_IRQ4] == 0 ) ) )
{
IRQ0_neg;
while( !IRQ0 )
{;
}
IRQ0_ast;
}
else
{
IRQ0_neg;
}
}
return;
}
if( STD )
{
if( ( state == IIC_TX ) || ( state == IIC_RX ) )
{
state = IIC_IDLE;
rtc_unlock( );
}
}
switch ( state )
{
case ( IIC_IDLE ):
// 自局呼び出しに応答。
// 初期化など
SPIE = 1;
WREL = 1; // ウェイト解除
state = IIC_RCV_REG_ADRS;
break;
case ( IIC_RCV_REG_ADRS ):
// レジスタアドレス受信
reg_adrs = IICA;
WREL = 1;
// reg_adrs_internal = adrs_table_ctr_ext2int( reg_adrs );
trx_buf = vreg_ctr_read( reg_adrs ); // データの準備をしておく
state = IIC_TX_OR_RX;
break;
case ( IIC_TX_OR_RX ):
// 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:
if( state == IIC_TX )
{ // 送信
IICA = trx_buf;
vreg_ctr_after_read( reg_adrs ); // 読んだらクリアなどの処理
}
else
{
// RX
trx_buf = IICA;
vreg_ctr_write( reg_adrs, trx_buf );
WREL = 1;
}
reg_adrs += 1;
// reg_adrs_internal = adrs_table_ctr_ext2int( reg_adrs );
if( state == IIC_TX )
{
trx_buf = vreg_ctr_read( reg_adrs );
// temp = vreg_ctr[ 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_WM0_
P20 &= ~0x3;
#else
P6 &= ~0x3;
#endif
SVA = IIC_C_SLAVEADDRESS;
IICF = 0x01;
STCEN = 1; // リスタートの許可
IICRSV = 1; // 通信予約をさせない:スレーブに徹する
SPIE = 0; // ストップコンディションでの割り込みを禁止
WTIM = 1; // 自動でACKを返した後clkをLに固定する
ACKE = 1; // ダメCPUは無視して次の通信をはじめるかもしれないんで早くclkを開放しないといけない
IICWH = 8;
IICWL = 10; // L期間の長さ
SMC = 1; // 高速モード
IICAMK = 0; // 割り込みを許可
IICE = 1;
#ifdef _MODEL_WM0_
PM20 &= ~0x3; /* set clock pin for IICA */
#else
PM6 &= ~0x3; /* set clock pin for IICA */
#endif
}
// ========================================================
void IIC_ctr_Stop( void )
{
IICE = 0; /* IICA disable */
IICAEN = 0;
}