mirror of
https://github.com/rvtr/ctr_mcu.git
synced 2025-06-18 16:45:33 -04:00
247 lines
6.3 KiB
C
247 lines
6.3 KiB
C
/* ========================================================
|
||
TWL 互換I2C
|
||
|
||
$Id: i2c_twl.c 418 2011-09-22 01:35:37Z n2232 $
|
||
======================================================== */
|
||
#ifndef _WIN32
|
||
|
||
#pragma sfr /* 特殊機能レジスタ使用 */
|
||
|
||
#endif
|
||
|
||
|
||
/*============================================================================*/
|
||
#ifndef _WIN32
|
||
# pragma interrupt INTIICA0 int_iic_twl RB2
|
||
#endif
|
||
|
||
#include "incs_loader.h"
|
||
#include "i2c_twl_defs.h"
|
||
#include "i2c_twl.h"
|
||
#include "vreg_twl.h"
|
||
#include "WDT.h"
|
||
|
||
|
||
#ifdef _MCU_BSR_
|
||
//#ifdef _MODEL_TS0_ || _MODEL_WM0_
|
||
|
||
// ワーキングモデルはI2Cが逆
|
||
#define ACKD ACKD0
|
||
#define ACKE ACKE0
|
||
#define COI COI0
|
||
#define IICAEN IICA0EN
|
||
#define IICRSV IICRSV0
|
||
#define IICA IICA0
|
||
#define IICAIF IICAIF0
|
||
#define IICAMK IICAMK0
|
||
#define IICAPR0 IICAPR00
|
||
#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
|
||
#define SMC SMC0
|
||
#define TRC TRC0
|
||
#define DFC DFC0
|
||
#define PortMode PM6
|
||
#define Port P6
|
||
|
||
#endif // _MCU_BSR_
|
||
|
||
#ifndef _MCU_BSR_
|
||
|
||
// ke3の時はダミー関数
|
||
void IIC_twl_Stop( void )
|
||
{
|
||
}
|
||
void IIC_twl_Init( void )
|
||
{
|
||
}
|
||
#else // _MCU_BSR_
|
||
|
||
|
||
|
||
enum IIC_TWL_STATE{
|
||
WAIT_ADRS = 0,
|
||
WAIT_DATA,
|
||
DATA_READED
|
||
};
|
||
|
||
|
||
|
||
|
||
/*============================================================================*/
|
||
|
||
// 注! ↓はマクロなので、returnはメインループに戻ります。
|
||
#define wait_next { \
|
||
tot = 0; \
|
||
while( IICAIF != 1 ){ \
|
||
tot ++; \
|
||
if( tot == 0 ){ \
|
||
LREL = 1; \
|
||
return; \
|
||
} \
|
||
} \
|
||
}
|
||
|
||
|
||
/********************************************//**
|
||
isr
|
||
|
||
TWLはウェイトを理解してくれず、また、バーストR/W は
|
||
しないでもらっているので、ストップコンディションまで一気にやってしまう。
|
||
***********************************************/
|
||
__interrupt void int_iic_twl( )
|
||
{
|
||
u8 vreg_adrs;
|
||
u8 state;
|
||
|
||
// ①
|
||
WREL = 1; // ウェイト解除して次のバイトを待つ
|
||
WDT_Restart();
|
||
state = WAIT_ADRS;
|
||
|
||
while( 1 )
|
||
{
|
||
u8 my_iics;
|
||
|
||
{
|
||
u16 tot;
|
||
wait_next; // 1バイト受信完了を待つ
|
||
}
|
||
|
||
my_iics = IICS;
|
||
IICAIF = 0;
|
||
|
||
if( my_iics & 0x02 ) // ( STD && !SPD )
|
||
{
|
||
// スタートコンディションがきた
|
||
if( ( my_iics & 0x08 ) == 0 ) // ( TRC ) 送信方向フラグ 0:マイコンが受信
|
||
{
|
||
// ①’マイコンが応答できず、TWLがリトライしたときとか
|
||
// ここに来るのはスレーブ呼び出しの時 //
|
||
WREL = 1;
|
||
state = WAIT_ADRS;
|
||
/// レジスタアドレスが書かれるのを待つ
|
||
}
|
||
else
|
||
{
|
||
// ③R Rでのスレーブ呼び出し(リスタートコンディション) //
|
||
IICA = vreg_twl_read( vreg_adrs ); // データ送信
|
||
// ストップ待ち後、LREL = 1 にしないと、送信バッファが破壊されることがある
|
||
state = DATA_READED;
|
||
}
|
||
}
|
||
else if( ( my_iics & 0x03 ) == 0 ) // ( !STD && !SPD )
|
||
{
|
||
u8 rcvd;
|
||
|
||
// 何らか受信
|
||
rcvd = IICA;
|
||
WREL = 1;
|
||
|
||
if( state == WAIT_ADRS )
|
||
{
|
||
// ②
|
||
vreg_adrs = adrs_table_twl_ext2int( rcvd );
|
||
/// データが書かれるか、リスタートで読み出されるのを待つ
|
||
state = WAIT_DATA;
|
||
}
|
||
else if( state == DATA_READED )
|
||
{
|
||
// データ1バイト送信後発生する
|
||
LREL = 1;
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
// ③W
|
||
// データ書き込まれ
|
||
SVA = 0x5A; // ダミー
|
||
LREL = 1; // スタートコンディション待ちへ(連続書き込み未対応のため)
|
||
vreg_twl_write( vreg_adrs, rcvd );
|
||
SVA = IIC_T_SLAVEADDRESS;
|
||
return; // 受信おしまい //
|
||
}
|
||
}
|
||
else if( my_iics & 0x01 ) // SPD
|
||
{
|
||
// 終了
|
||
LREL = 1;
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
// NOP();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
モジュール初期化
|
||
***********************************************/
|
||
void IIC_twl_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 */
|
||
Port &= ~0x03;
|
||
|
||
SVA = IIC_T_SLAVEADDRESS;
|
||
IICF = 0x01;
|
||
|
||
STCEN = 1; // リスタートの許可
|
||
IICRSV = 1; // 通信予約をさせない:スレーブに徹する
|
||
|
||
SPIE = 0; // ストップコンディションでの割り込みを禁止
|
||
WTIM = 1; // 自動でACKを返した後clkをLに固定する
|
||
ACKE = 1; // ダメCPUは無視して次の通信をはじめるかもしれないんで早くclkを開放しないといけない
|
||
|
||
IICWH = 9;
|
||
IICWL = 11; // L期間の長さ(?)
|
||
|
||
SMC = 1;
|
||
DFC = 1; // デジタルフィルタon (@fast mode)
|
||
|
||
IICAMK = 0; // 割り込みを許可
|
||
|
||
IICE = 1;
|
||
|
||
PortMode &= ~0x03;
|
||
|
||
LREL = 1;
|
||
}
|
||
|
||
|
||
|
||
/********************************************//**
|
||
モジュール停止
|
||
***********************************************/
|
||
void IIC_twl_Stop( void )
|
||
{
|
||
IICE = 0; /* IICA disable */
|
||
IICAEN = 0;
|
||
}
|
||
|
||
|
||
#endif
|