/      English

SMBUS(I2C)関連の手続きを定義したSMBus.c,hの解説

TWENETライブラリ、SMBUS(I2C)関連の手続きを定義したSMBus.c,hの解説
TWENETライブラリ、SMBUS(I2C)関連の手続きを定義したSMBus.c,hの解説です。

SMBUS(I2C)

TWENETを用いたサンプルコードやアプリコードの多くは、I2Cバスの利用は、AHIライブラリ内の低レベル手続きは直接用いず、読み書き手続きを簡素化したSMBus.c, .h定義関数群を用いています。

以下に、利用する関数名を列挙します。

void vSMBusInit(void);
void vSMBusInit_setClk(uint32 u32Clk);
void vSMBusDeInit();
void vSMBusDeInit(void);
bool_t bSMBusWrite(uint8 u8Address, uint8 u8Command,
						  uint8 u8Length, uint8* pu8Data);
bool_t bSMBusSequentialRead(uint8 u8Address, uint8 u8Length,
		   uint8* pu8Data);

SMBus.c SMBus.h

I2C の代表的な手続きをまとめた関数群でTWENETmwx/source/sensors/legacy にソースコードを格納しています。

※TWENETmwx ライブラリをリンクしない場合(Cプロジェクト)は、このソースコードをコピーして利用します。

vSMBusInit()

void vSMBusInit(void);

I2Cバスを初期化します。使用するピンはDIO14(CLK),15(DATA)で、クロック周波数は100Kbpsです。

vSMBusInit_setClk(uint32)

void vSMBusInit_setClk(uint32 u32Clk);

vSMBusInit()の替わりに本関数を用いることで、u32clkに対応するクロックにてI2Cバスを初期化します。

  • u32clk>=7かつu32clk>=255の場合⇒クロック周波数320000ul/(u32clk+1)を指定して初期化します。例えば31を指定すると、100KHz、7を指定すると400kHzとなります。
  • u32clk >= 12500かつu32clk <= 400000u32clkを指定して初期化します。
  • それ以外⇒未定義

※ 実際の周波数は、ハードウェアのクロックディバイザに対応し近傍の周波数が選択されます。具体的な計算方法についてはソースコードを参照 (TWELITE GOLDの場合は NXP の FSL ライブラリの仕様を参照ください。

// TWELITE GOLDの実装
PUBLIC void  TWENET_smbus_vSMBusInit_setClk(uint32_t u32clk)
{
    ...
	if (u32clk >= 7 && u32clk <= 255) { // given by divisor
		u32clk = 3200000ul / (u32clk + 1);
	}

	if (u32clk < 12500ul || u32clk > 400000ul) {
		u32clk = 100000ul;
	}

	// initialize the I2C
    //...以下、呼び出し先関数の実装
      _conf.baudRate_bps = u32clk;
      I2C_MasterGetDefaultConfig(&_conf); // FSLライブラリ関数
}

// TWELITE BLUE/RED の実装
void vSMBusInit_setClk(uint32 u32Clk)
{
    /* convert clock to clock devisor */
    if (u32Clk > 255) {
    	u32Clk = (3200000UL / u32Clk) - 1;
    }
    if (u32Clk < 7 || u32Clk > 255) u32Clk = 31; // set 100kHz

    /* run bus at specified value */
    vAHI_SiMasterConfigure(TRUE, FALSE, u32Clk);
    // 16/[(PreScaler + 1) x 5]MHz
    //		--> 31:100KHz, 7:400KHz, 47:66Khz
}

vSMBusDeInit()

void vSMBusDeInit();

I2Cバスの利用を停止します。

  • TWELITE BLUE/RED はvAHI_SiMasterDisable()を呼び出します。
  • TWELITE GOLDはI2Cバスの利用の停止と、DIO14,15ピンを TWENET ライブラリ初期化時の設定 (入力ポート、プルアップ) に戻します。

bSMBusWrite()

bool_t bSMBusWrite(
	uint8 u8Address,
    uint8 u8Command,
	uint8 u8Length,
    uint8* pu8Data)

I2Cバスへの書き込みを行います。

  • u8Address⇒I2Cバスのデバイスアドレスを指定します。
  • u8Command⇒書き込み時のコマンド(最初の転送バイト)を指定します。
  • u8Length⇒続くバイト数。0の場合はコマンドのみの転送です。1以上を指定した場合はpu8Dataの定義が必須です。
  • pu8Data⇒転送するバイト列を格納したメモリ領域へのポインタを指定します。

転送が成功した場合は TRUE を戻し、失敗した場合は FALSE を戻します。

bSMBusSequentialRead()

bool_t bSMBusSequentialRead(
    uint8 u8Address,
    uint8 u8Length,
	uint8* pu8Data)

I2Cバスの読み込みを行います。

  • u8Address⇒I2Cバスのデバイスアドレスを指定します。
  • u8Length⇒読み出すバイト数(1以上)を指定します。
  • pu8Data⇒読み出すバイト列を格納するメモリ領域へのポインタを指定します。

転送が成功した場合は TRUE を戻し、失敗した場合は FALSE を戻します。

その他

スリープ時の取り扱い

  • TWELITE BLUE/REDは、スリープ復帰時にハードウェアの再初期化を行う必要があります。vSMBusDeInit()を呼び出さない場合のピンの状態は未定義(またはJN516x のペリフェラル仕様書に基づく)ですが、再度vSMBusInit() vSMBusInit_setClk() の呼び出しを行うことで初期化することができます。
  • TWELITE GOLDは、以下の振る舞いをします。
    • RAM ON(通常)スリープ時:スリープ手続きを行った時点で、I2Cバスが初期化されていた場合は、スリープ復帰時に再初期化を行います。I2Cバスが使用されていない場合は、通常の汎用IOのスリープ復帰時の手続きとなります。
    • RAM OFF(ディープ)スリープ時:スリープ復帰時にTWENETによるピンの初期化(入力ピン、プルアップ)行います。

TWELITE GOLD の実装

AHIライブラリ互換関数は用意せず SMBus.c,h に対応する関数を実装しています。

// TWENETcmptライブラリ内での実装
PUBLIC void TWENET_smbus_vSMBusInit(void);
PUBLIC void TWENET_smbus_vSMBusDeInit(void);
PUBLIC void TWENET_smbus_vSMBusInit_setClk(uint32 u32clk);
PUBLIC bool_t  TWENET_smbus_bSMBusWrite(uint8 u8Address,
    uint8 u8Command, uint8 u8Length, uint8* pu8Data);
PUBLIC bool_t TWENET_smbus_bSMBusSequentialRead(uint8 u8Address,
    uint8 u8Length,  uint8* pu8Data);

// SMBus.hで inline 定義により上記関数群を呼び出す
static inline void vSMBusInit(void) {
	TWENET_smbus_vSMBusInit();
}
static inline void vSMBusInit_setClk(uint32 u32Clk) {
	TWENET_smbus_vSMBusInit_setClk(u32Clk);
}
static inline void vSMBusDeInit() {
	TWENET_smbus_vSMBusDeInit();
}
static inline void vSMBusDeInit(void) {
	TWENET_smbus_vSMBusInit();
}
static inline bool_t bSMBusWrite(uint8 u8Address, uint8 u8Command,
						  uint8 u8Length, uint8* pu8Data) {
	return TWENET_smbus_bSMBusWrite(u8Address, u8Command, u8Length, pu8Data);
}
static inline bool_t bSMBusSequentialRead(uint8 u8Address, uint8 u8Length,
		   uint8* pu8Data) {
	return TWENET_smbus_bSMBusSequentialRead(u8Address, u8Length, pu8Data);
}