RL78/G1D 簡易i2cのやり方について

初めまして。恐らく初歩的な質問となると思うのですが、よろしければご教授お願い致します。

使用している総合開発環境はCS+forCCです。

RL78/G1D R5F11AGJ の簡易i2cを使用して6軸加速度センサLSM6DS3との通信を実現したいと思っています。

今まではArduinoを使用していたのですが、諸事情によりRL78/G1Dに変更することになりました。

ハードウェアマニュアルやサンプルプログラムを見ながら試行錯誤しているのですが、いまいち要領を得ません。

シリアルアレイユニットのIIC00をコード生成後、加速度センサの値を読みたい時のおおまかな流れは以下の様な理解で良いのでしょうか?

/*********************************************************************************************/

R_SAU0_Create()/*シリアルアレイユニット0、IIC00初期設定*/

R_IIC00_Master_Send(uint8_t slave_address,uint8_t register_address,1)/*スレーブアドレス、アクセスするレジスタアドレス、バッファーサイズを指定*/

/***r_iic00_interrupt()により転送完了割り込みが発生,アドレスフィールド送信***/

R_IIC00_Master_Receive(uint8_t slave_address, (uint8_t *)data_address, buffer_size) /*data_addressはスレーブから受け取ったデータを格納*/

/***r_iic00_interrupt()により転送完了割り込みが発生,data_addressに指定したレジスタアドレスの値をバッファーサイズ分格納***/

 

/*********************************************************************************************/

割り込み処理についてよく理解ができておらず、その辺りの流れに頭を悩ませております。

この様なちゃんとした?マイコンを扱うのが初めてで、右も左もわからない状態なのですが是非よろしくお願いいたします。

 

 

以下にコード生成されたMaster_Send,Master_Receive,r_iic00_interruptのソースを貼ります。

/***********************************************************************************************************************
* Function Name: R_IIC00_Master_Send
* Description : This function starts transferring data for IIC00 in master mode.
* Arguments : adr -
* set address for select slave
* tx_buf -
* transfer buffer pointer
* tx_num -
* buffer size
* Return Value : None
***********************************************************************************************************************/
void R_IIC00_Master_Send(uint8_t adr, uint8_t * const tx_buf, uint16_t tx_num)
{
g_iic00_master_status_flag = _00_SAU_IIC_MASTER_FLAG_CLEAR; /* clear IIC00 master status flag */
adr &= 0xFEU; /* send mode */
g_iic00_master_status_flag = _01_SAU_IIC_SEND_FLAG; /* set master status flag */
SCR00 &= ~_C000_SAU_RECEPTION_TRANSMISSION;
SCR00 |= _8000_SAU_TRANSMISSION;
/* Set paramater */
g_iic00_tx_count = tx_num;
gp_iic00_tx_address = tx_buf;
/* Start condition */
R_IIC00_StartCondition();
IICIF00 = 0U; /* clear INTIIC00 interrupt flag */
IICMK00 = 0U; /* enable INTIIC00 */
SIO00 = adr;
}
/***********************************************************************************************************************
* Function Name: R_IIC00_Master_Receive
* Description : This function starts receiving data for IIC00 in master mode.
* Arguments : adr -
* set address for select slave
* rx_buf -
* receive buffer pointer
* rx_num -
* buffer size
* Return Value : None
***********************************************************************************************************************/
void R_IIC00_Master_Receive(uint8_t adr, uint8_t * const rx_buf, uint16_t rx_num)
{
g_iic00_master_status_flag = _00_SAU_IIC_MASTER_FLAG_CLEAR; /* clear master status flag */
adr |= 0x01U; /* receive mode */
g_iic00_master_status_flag = _02_SAU_IIC_RECEIVE_FLAG; /* set master status flag */
SCR00 &= ~_C000_SAU_RECEPTION_TRANSMISSION;
SCR00 |= _8000_SAU_TRANSMISSION;
/* Set parameter */
g_iic00_rx_length = rx_num;
g_iic00_rx_count = 0U;
gp_iic00_rx_address = rx_buf;
/* Start condition */
R_IIC00_StartCondition();
IICIF00 = 0U; /* clear INTIIC00 interrupt flag */
IICMK00 = 0U; /* enable INTIIC00 */
SIO00 = adr;
}

/***********************************************************************************************************************
* Function Name: r_iic00_interrupt
* Description : None
* Arguments : None
* Return Value : None
***********************************************************************************************************************/
static void __near r_iic00_interrupt(void)
{
if (((SSR00 & _0002_SAU_PARITY_ERROR) == 0x0002U) && (g_iic00_tx_count != 0U))
{
r_iic00_callback_master_error(MD_NACK);
}
else if(((SSR00 & _0001_SAU_OVERRUN_ERROR) == 0x0001U) && (g_iic00_tx_count != 0U))
{
r_iic00_callback_master_error(MD_OVERRUN);
}
else
{
/* Control for master send */
if ((g_iic00_master_status_flag & _01_SAU_IIC_SEND_FLAG) == 1U)
{
if (g_iic00_tx_count > 0U)
{
SIO00 = *gp_iic00_tx_address;
gp_iic00_tx_address++;
g_iic00_tx_count--;
}
else
{
R_IIC00_StopCondition();
r_iic00_callback_master_sendend();
}
}
/* Control for master receive */
else
{
if ((g_iic00_master_status_flag & _04_SAU_IIC_SENDED_ADDRESS_FLAG) == 0U)
{
ST0 |= _0001_SAU_CH0_STOP_TRG_ON;
SCR00 &= ~_C000_SAU_RECEPTION_TRANSMISSION;
SCR00 |= _4000_SAU_RECEPTION;
SS0 |= _0001_SAU_CH0_START_TRG_ON;
g_iic00_master_status_flag |= _04_SAU_IIC_SENDED_ADDRESS_FLAG;

if (g_iic00_rx_length == 1U)
{
SOE0 &= ~_0001_SAU_CH0_OUTPUT_ENABLE; /* disable IIC00 out */
}

SIO00 = 0xFFU;
}
else
{
if (g_iic00_rx_count < g_iic00_rx_length)
{
*gp_iic00_rx_address = SIO00;
gp_iic00_rx_address++;
g_iic00_rx_count++;

if (g_iic00_rx_count == (g_iic00_rx_length - 1U))
{
SOE0 &= ~_0001_SAU_CH0_OUTPUT_ENABLE; /* disable IIC00 out */
SIO00 = 0xFFU;
}
else if (g_iic00_rx_count == g_iic00_rx_length)
{
R_IIC00_StopCondition();
r_iic00_callback_master_receiveend();
}
else
{
SIO00 = 0xFFU;
}
}
}
}
}
}

  • チョコです。
    これまで何回かコメントしているのですが,通信関係のコード生成のAPI部分は使い物にならないと判断しています。
    "設定に合わせすべて出力する"にすると,初期設定に加えて,送信や受信起動関数や割り込み処理関数も生成されてしまいます。その一部に問題がある(正しく動かない場合がありますというか,特定の条件でしか動作しません)。それに,通信完了の確認のための処理に対するサポートがなされていません。特にIIC関係のAPI関数はこれまでもいろんな指摘を行い,かなり修正してもらってはいますが,まだ十分とは思えません。

    そこで,コード生成は初期設定だけに限定するためにそのような設定にしています。
    その代わりに,通信関係のプログラムを「r_iic_lib.c」としてライブラリ化してそこ必要なライブラリに入れています。「r_iic_lib.c」と「r_iic_lib.h」をプロジェクトに組込み,「r_iic_lib.h」をインクルードすることで,簡単に使えるようにしています。

    気にされている"R_IIC00_Master_Send"のような関数ですが,割り込みでの処理方法が異なるので,それに合わせた処理が必要なので,同じ名前の(同じ目的の)I/F関数も準備しています。「r_iic_lib.h」の中にI/F関数のプロトタイプ宣言があるので,それを眺めてみてください。
  • チョコ様
    夜遅く、ご指導ありがとうございます。
    そういうことなわけですね。了解いたしました。
    プロジェクトを再度作成して、「IIC通信のマスタ側(RL78/G13の簡易IIC版)改 2C」のr_iic_lib.cと.hを組み込んで試験を行います。