ctr_mcu/trunk/i2c_ctr.c
fujita_ryohei 4f86e7aa2d V0.3 final
V0.4でレジスタなどがらっと変えてしまうつもりで、#ifdef ではつらいため、
きれいにしてしまいます。

git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-05-23%20-%20ctr.7z%20+%20svn_v1.068.zip/ctr/svn/ctr_mcu@10 013db118-44a6-b54f-8bf7-843cb86687b1
2009-09-16 06:41:53 +00:00

315 lines
7.0 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 "incs.h"
// u16 tot;
#ifndef _PMIC_CTR_
#define IRQ0_neg { PM3.0 = 1; }
#else
#define IRQ0_neg { PM7.6 = 1; }
#endif
#ifdef _MCU_BSR_
#ifdef 1
//#ifdef _MODEL_WM0_
// ワーキングモデルはI2Cが逆
#define ACKD ACKD1
#define ACKE ACKE1
#define COI COI1
#define IICAEN IICA1EN
#define IICAPR0 IICAPR10
#define IICRSV IICRSV1
#define IICA IICA1
#define IICAEN IICA1EN
#define IICAIF IICAIF1
#define IICAMK IICAMK1
#define IICAPR1 IICAPR11
#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
#else
#define ACKD ACKD0
#define ACKE ACKE0
#define COI COI0
#define IICAEN IICA0EN
#define IICAPR0 IICAPR00
#define IICRSV IICRSV0
#define IICA IICA0
#define IICAEN IICA0EN
#define IICAIF IICAIF0
#define IICAMK IICAMK0
#define IICAPR1 IICAPR10
#define IICCTL0 IICCTL00
#define IICE IICE0
#define IICF IICF0
#define IICS IICS0
#define IICWH IICWH0
#define IICWL IICWL0
#define LREL LREL0
#define SPD SPD0
#define SPIE SPIE0
#define STCEN STCEN0
#define STD STD0
#define SVA SVA0
#define WREL WREL0
#define WTIM WTIM0
#endif
#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;
if( SPD ){
state = IIC_IDLE;
SPIE = 0;
// I2C終了時に何かする物 //
rtc_unlock();
return;
}
// 読み出し終了
if( !ACKD ){
state = IIC_IDLE;
SPIE = 0;
LREL = 1;
rtc_unlock();
// IRQレジスタリードで、割り込みピンの設定
IRQ0_neg;
if(! (( vreg_ctr[ VREG_C_IRQ0 ] == 0 )
&& ( vreg_ctr[ VREG_C_IRQ1 ] == 0 )
&& ( vreg_ctr[ VREG_C_IRQ2 ] == 0x02 )) ){ // 暫定
IRQ0_ast;
}
return;
}
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 = 0; /* 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を開放しないといけない
IICWL = 6; // L期間の長さ
IICWH = 5;
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;
}