mirror of
https://github.com/rvtr/twl_mcu.git
synced 2025-06-18 14:45:41 -04:00
173 lines
4.9 KiB
C
173 lines
4.9 KiB
C
#pragma interrupt INTIIC0 MD_INTIIC0
|
||
#define ignore_NAK 0
|
||
|
||
#include "macrodriver.h"
|
||
#include "I2C.h"
|
||
#include "user_define.h"
|
||
#include "jhl_defs.h"
|
||
#include "vreg.h"
|
||
#include "I2C_selfprog.h"
|
||
|
||
#include "wdt.h"
|
||
|
||
extern u8 vregs[];
|
||
#include "PMIC_TWL2.h"
|
||
|
||
|
||
|
||
|
||
extern bit self_prog_mode;
|
||
|
||
/*****************************************************************************
|
||
低レベル向け?
|
||
*****************************************************************************/
|
||
volatile UCHAR gIic0SlaveStatusFlag;
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
プロトコル層?向け
|
||
*****************************************************************************/
|
||
extern UCHAR vregs[];
|
||
UCHAR i2c_Send_start_addr;
|
||
UCHAR i2c_accessRegAdr;
|
||
|
||
u8 vreg_adrs;
|
||
u8 rcvd_buff;
|
||
|
||
u8 pre_dat;
|
||
|
||
|
||
// 注! ↓はマクロなので、returnはメインループに戻ります。
|
||
#define wait_next { \
|
||
while( IICIF0 != 1 ){ \
|
||
if( SPD0 ){ \
|
||
LREL0 = 1; \
|
||
return; \
|
||
} \
|
||
} \
|
||
}
|
||
|
||
|
||
__interrupt void MD_INTIIC0( void ){
|
||
WREL0 = 1; // ウェイト解除して次のバイトを待つ
|
||
// フラグ1回目 スレーブアドレス,R/W
|
||
if( COI0 != 1 ){ // 被呼び出し?
|
||
LREL0 = 1; // 呼ばれたのは他のID
|
||
return;
|
||
}else{
|
||
// ACKE0 = 1; // 自動でackを返すようにする
|
||
// WREL0 = 1; // ウェイト解除して次のバイトを待つ
|
||
}
|
||
|
||
wait_next; // 1バイト受信完了を待つ
|
||
|
||
// 2回目 R/W レジスタアドレス
|
||
WREL0 = 1;
|
||
IICIF0 = 0;
|
||
vreg_adrs = adrs_table_ext2int( IIC0 );
|
||
|
||
// 3回目
|
||
// スタートコンディションか、データ受信完了フラグ待ち
|
||
|
||
while( 1 ){
|
||
if( IICIF0 == 1 ){
|
||
// 受信 //
|
||
IICIF0 = 0;
|
||
WREL0 = 1;
|
||
|
||
if( ( IIC0 == 0x4A ) && ( vreg_adrs == REG_INT_ADRS_TEMP7 ) ){
|
||
// 自己プログラム書き換えモード //
|
||
// ここで分岐は美しくない気もします...
|
||
vregs[ REG_INT_ADRS_MODE ] = 0x00; // 電源オフ時間を短くせんがため。
|
||
PM_set_VRSET();
|
||
self_programming();
|
||
// 帰ってきません
|
||
}else{
|
||
// 通常アクセス(ライト) //
|
||
LREL0 = 1;
|
||
debug_led_on;
|
||
vregs_write( vreg_adrs, IIC0 );
|
||
debug_led_off;
|
||
return; // 受信おしまい //
|
||
}
|
||
}else if( STD0 ){
|
||
// 送信 // (スタートコンディション検出)
|
||
pre_dat = vregs_read( vreg_adrs ); // mcu内部アドレスを渡す。一バイト目の準備 IIc0に書き込むとウェイト解除
|
||
|
||
// 自局をRで呼ばれるのを待つ
|
||
wait_next;
|
||
IICIF0 = 0;
|
||
if( COI0 != 1 ){ // 被呼び出し?
|
||
LREL0 = 1; // 呼ばれたのは他のID(あれ?)
|
||
return;
|
||
}
|
||
IIC0 = pre_dat; // データを送る
|
||
|
||
wait_next;
|
||
// 4回目。(送信データ後の、ACK/NACK後) どうしても発生してしまう。
|
||
IICIF0 = 0; // おしまい
|
||
LREL0 = 1;
|
||
return;
|
||
}else if( SPD0 ){ // 強制終了
|
||
LREL0 = 1;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
/*****************************************************************************
|
||
基本API
|
||
*****************************************************************************/
|
||
void IIC0_Init( void )
|
||
{
|
||
IICE0 = 0; /* IIC0 disable */
|
||
|
||
IICMK0 = 1; /* INTIIC0 disable */
|
||
IICIF0 = 0; /* clear INTIIC0 interrupt flag */
|
||
|
||
IICPR0 = 0; /* set INTIIC0 high priority */
|
||
|
||
PM6 &= ~0x1; /* set clock pin for IIC0 */
|
||
P6 &= ~0x1;
|
||
|
||
PM6 &= ~0x2; /* set data transfer I/O pin for IIC0 */
|
||
P6 &= ~0x2;
|
||
|
||
IICCL0 = IICCL0_INITIALVALUE | IIC0_CLOCK4; // レジスタ初期化、高速モード
|
||
IICX0 = IIC0_EXPENSION0; // 〃
|
||
SVA0 = IIC0_SLAVEADDRESS;
|
||
STCEN = 1; // リスタートの許可
|
||
IICRSV = 1; // 通信予約をさせない:スレーブに徹する
|
||
|
||
SPIE0 = 0; // ストップコンディションでの割り込みを禁止
|
||
WTIM0 = 1; // 自動でACKを返した後clkをLに固定する
|
||
ACKE0 = 1; // ダメCPUは無視して次の通信をはじめるかもしれないんで早くclkを開放しないといけない
|
||
IICMK0 = 0; // 割り込みを許可
|
||
|
||
IICE0 = 1;
|
||
}
|
||
|
||
|
||
//****************************************************************************
|
||
void IIC0_Stop( void ){
|
||
IICE0 = 0; /* IIC0 disable */
|
||
}
|
||
|
||
|
||
|
||
void IIC0_SlaveReceiveStart(){
|
||
gIic0SlaveStatusFlag = 0;
|
||
IICE0 = 1;
|
||
LREL0 = 1;
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
|
||
|