ctr_mcu/trunk/i2c_ctr.c
fujita_ryohei 972a9bcd16 電源シーケンス 液晶電源周りのウェイト変更
tuneボタン廃止
検出スイッチ廃止でコードも削除

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@15 013db118-44a6-b54f-8bf7-843cb86687b1
2009-10-28 13:36:49 +00:00

336 lines
7.6 KiB
C

/* ========================================================
対SoC 新規チャンネル I2C通信
藤田@開技.nintendo
'09 Apr
======================================================== */
#include "incs.h"
// u16 tot;
#ifdef _MCU_BSR_
// #ifdef _MODEL_TS0_ || _MODEL_WM0_
// ワーキングモデルはI2Cが逆
#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
/* ========================================================
======================================================== */
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( ( reg_adrs - 1 ) == VREG_C_IRQ3 ){
// IRQ0_neg;
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 ) ) )
{
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;
}
}
#if 0
// 一度通信が始まったら終わるまで戻らないバージョン
__interrupt void int_iic_ctr( )
{
static u8 state = 0;
static u8 reg_adrs;
// static u8 reg_adrs_internal;
static u8 trx_buf;
if( SPD )
{
return;
}
// 自局呼び出しに応答。
// 初期化など
WREL = 1; // ウェイト解除
while( !IICAIF )
{;
}
IICAIF = 0;
// レジスタアドレス受信
reg_adrs = IICA;
WREL = 1;
trx_buf = vreg_ctr_read( reg_adrs ); // データの準備をしておく
while( !IICAIF )
{;
}
IICAIF = 0;
if( STD )
{ // リスタートコンディション
// リードされる
if( COI )
{
state = IIC_TX;
}
else
{
// リスタートで違うデバイスが呼ばれた!
WREL = 1; // ウェイト解除?
state = IIC_IDLE; // 終了処理
SPIE = 0;
return;
}
}
else
{ // ライト続行
state = IIC_RX;
}
if( state == IIC_TX )
{
// 送信 //
do
{
IICA = trx_buf;
vreg_ctr_after_read( reg_adrs ); // 読んだらクリアなどの処理
reg_adrs += 1;
trx_buf = vreg_ctr_read( reg_adrs );
while( !IICAIF )
{;
}
IICAIF = 0;
}
while( ACKD );
LREL = 1;
}
else
{
// 受信 //
SPIE = 1;
do
{
trx_buf = IICA;
vreg_ctr_write( reg_adrs, trx_buf );
reg_adrs += 1;
WREL = 1;
while( !IICAIF )
{;
}
IICAIF = 0;
}
while( !SPD );
SPIE = 0;
}
state = IIC_IDLE;
}
#endif
// ========================================================
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;
}