Other Parts Discussed in Thread: C2000WARE
I would like to use I2C to get the value of the temperature sensor.
The sensor used is "SparkFun (PID 14607) Grid-EYE Infrared Array".
I tried to configure the program by referring to the answers to the past questions, but the sensor value is not stored in the final rx_data_buff.
When I run the current program, I get stuck in the loop at ARDY on line 292. Similarly, how to escape from RRDY on line 360 remains unknown.
// Included Files
#include "DSP2833x_Device.h"     // Device Headerfile and Examples Include File
#include "dsp2833x_i2c_defines.h"
extern void InitSysCtrl(void);
extern void InitPieCtrl(void);
extern void InitPieVectTable(void);
// I2C Function Prototypes
void   I2CA_Init(void);
void InitI2CAGpio();
unsigned short I2CA_WriteToReg(unsigned short slave_addr, unsigned short reg, unsigned short data[], unsigned short data_size);
unsigned short I2CA_WriteToManyRegs(unsigned short slave_addr, unsigned short reg[], unsigned short reg_size, unsigned short data[], unsigned short data_size);
unsigned short I2CA_ReadFromReg(unsigned short slave_addr, unsigned short reg, unsigned short data[], unsigned short data_size);
unsigned short I2CA_ReadFromManyRegs(unsigned short slave_addr, unsigned short reg[], unsigned short reg_size, unsigned short data[], unsigned short data_size);
// Defines
#define I2C_SLAVE_ADDR        0x50
#define NACK_CHECK            1
// Globals
    // I2C通信用定義
    unsigned short reg[2];              // Register bytes buffer
    unsigned short tx_data_buff[64];    // Data bytes buffer
    unsigned short rx_data_buff[64];    // Data bytes buffer
// Main
void main(void)
{
    unsigned short Status;
    unsigned short i;
    // レジスタバイト初期化
    reg[0] = 0x00;
    reg[1] = 0x00;
    // データバイト初期化
    for(i = 0; i <= sizeof(tx_data_buff); i++)
    {
        tx_data_buff[i] = i;
        rx_data_buff[i] = 0;
    }
    // WARNING: RAMから関数を実行する前に必ずmemcpyを呼び出すようにしてください。
    // InitSysCtrlにはRAMベースの関数の呼び出しが含まれており、最初にmemcpyを呼び出さないとプロセッサは「雑草の中」に入ります。
#ifdef _FLASH
    memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
#endif
    // システム制御の初期化:
    // PLL、WatchDog、ペリフェラルクロックを有効にする
    // このサンプル関数は、DSP2833x_SysCtrl.cファイルにあります。
    InitSysCtrl();
    
    // I2C機能のGPIOのみをセットアップする
    InitI2CAGpio();
    // すべての割り込みをクリアし、PIEベクトルテーブルを初期化します。
    DINT;
    // PIE制御レジスタをデフォルト状態に初期化します。
    // デフォルトの状態は、すべてのPIE割り込みが無効でフラグが設定されていることです。
    // この関数はDSP2833x_PieCtrl.cファイルにあります。
    InitPieCtrl();
    // CPU割り込みを無効にし、すべてのCPU割り込みフラグをクリアします
    IER = 0x0000;
    IFR = 0x0000;
    // シェル割り込みサービスルーチン(ISR)へのポインタを使用してPIEベクトルテーブルを初期化します。
    // この例で割り込みが使用されていない場合でも、これによりテーブル全体にデータが入力されます。 これはデバッグの目的で役立ちます。
    // シェルISRルーチンはDSP2833x_DefaultIsr.cにあります。
    // この関数はDSP2833x_PieVect.cにあります。
    InitPieVectTable();
    // すべてのデバイス周辺機器を初期化します
    I2CA_Init();    // I2C-A only
    // 転送レジスタとデータバイト
    Status = I2CA_WriteToManyRegs(I2C_SLAVE_ADDR, reg, sizeof(reg), tx_data_buff, sizeof(tx_data_buff));
    if(Status == I2C_SUCCESS)
    {
        Status = I2CA_ReadFromManyRegs(I2C_SLAVE_ADDR, reg, sizeof(reg), rx_data_buff, sizeof(rx_data_buff));
        while(Status != I2C_SUCCESS)
        {
            Status = I2CA_ReadFromManyRegs(I2C_SLAVE_ADDR, reg, sizeof(reg), rx_data_buff, sizeof(rx_data_buff));
        }
    }
    __asm("   ESTOP0");
}
// I2CA_Init -
void I2CA_Init(void)
{
    // I2CCLK = SYSCLK/(I2CPSC+1)
    // 10 = 150/(14+1)
#if CPU_FRQ_150MHZ
    I2caRegs.I2CPSC.all = 14;       // Prescaler - need 7-12 Mhz on module clk
#endif
#if CPU_FRQ_100MHZ
    I2caRegs.I2CPSC.all = 9;       // Prescaler - need 7-12 Mhz on module clk
#endif
    // Set I2CCLKL/I2CCLKH for 150KHz SCL clock
    I2caRegs.I2CCLKL = 10;           // NOTE: must be non zero
    I2caRegs.I2CCLKH = 5;            // NOTE: must be non zero
    I2caRegs.I2CIER.all = 0x0;      // enable interrupts(XRDY,RRDY,ARDY)
    // Take I2C out of reset. Stop I2C when suspended
    I2caRegs.I2CMDR.all = 0x0020;
    return;
}
// InitI2CGpio-この関数は、GPIOピンを初期化してI2Cピンとして機能させます
//
// 各GPIOピンはGPIOピンまたは最大3つの異なるものとして構成できます
// 周辺機能ピン。 デフォルトでは、すべてのピンがGPIOとして表示されます
// リセット後に入力します。
//
// 注意:
// SDAA操作に対して1つのGPIOピンのみを有効にする必要があります。
// SCLA操作に対して有効にするGPIOピンは1つだけです。
// 他の不要な行をコメントアウトします。
void
InitI2CAGpio()
{
    EALLOW;
    //選択したピンの内部プルアップを有効
    GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;   // Enable pull-up for GPIO32 (SDAA)
    GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;   // Enable pull-up for GPIO33 (SCLA)
    //選択したピンの修飾を非同期のみに設定
    GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3;  // Asynch input GPIO32 (SDAA)
    GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;  // Asynch input GPIO33 (SCLA)
    // GPIOレジスタを使用してI2Cピンを構成
    GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1;   // Configure GPIO32 for SDAA
    GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1;   // Configure GPIO33 for SCLA
    EDIS;
}
// I2CA_WriteToReg-この関数はデータバイトをスレーブデバイスのレジスタに書き込みます。
//
// INPUTS:
//  --slave_addr ==>書き込まれるスレーブデバイスのアドレス
//  --reg [] ==>書き込み中のスレーブデバイスレジスタ
//  --reg_size ==>書き込まれるレジスタバイトの数、reg_sizeのバッファサイズ
//  --data [] ==>スレーブに書き込まれるバイトのデバイスレジスタデータバッファ
//  --data_size ==>書き込まれるデータバイトの数、データバッファのサイズ
unsigned short I2CA_WriteToManyRegs(unsigned short slave_addr, unsigned short reg[], unsigned short reg_size, unsigned short data[], unsigned short data_size)
{
    unsigned short i;
    unsigned short Status;
    Status = I2C_SUCCESS;
    // STPビットが以前のマスター通信からクリアされるまで待機します。
    // モジュールによるこのビットのクリアは、SCDビットが設定されるまで遅延されます。
    // 新しいメッセージを開始する前にこのビットがチェックされていないと、I2Cが混乱する可能性があります。
    if (I2caRegs.I2CMDR.bit.STP == 1)
    {
        return I2C_STP_NOT_READY_ERROR;
    }
    // Setup slave address
    I2caRegs.I2CSAR = slave_addr;
    // Check if bus busy
    if (I2caRegs.I2CSTR.bit.BB == 1)
    {
        return I2C_BUS_BUSY_ERROR;
    }
    // マスタートランスミッターとしてセットアップ
    // FREE + MST + TRX + IRS
    I2caRegs.I2CMDR.all = 0x4620;
    // 送信バイト数を設定
    // == (# of register bytes) + (# of data[] buffer bytes)
    I2caRegs.I2CCNT = reg_size + data_size;
    I2caRegs.I2CMDR.bit.STT = 0x1; // START条件を送信
    I2caRegs.I2CMDR.bit.STP = 0x1; // I2CCNTがゼロの場合、STOP条件が生成
    // I2Cモジュールは以下を送信:
    // register bytes ==> data bytes ==> STOP condition
    // レジスターバイトを送信
    while(!I2caRegs.I2CSTR.bit.XRDY){} // データを書き込む準備ができていることを確認
        #if NACK_CHECK // NACKを受信したかどうかを確認
            if(I2caRegs.I2CSTR.bit.NACK == 1)
            {
                I2caRegs.I2CMDR.bit.STP = 1;
                I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
                Status = I2C_ERROR;
                return Status;
            }
        #endif
    }
    // データバイトの送信とそれに続くSTOP条件
        while(!I2caRegs.I2CSTR.bit.XRDY){} // データを書き込む準備ができていることを確認
        #if NACK_CHECK // NACKを受信したかどうかを確認
            if(I2caRegs.I2CSTR.bit.NACK == 1)
            {
                I2caRegs.I2CMDR.bit.STP = 1;
                I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
                Status = I2C_ERROR;
                return Status;
            }
        #endif
    I2caRegs.I2CDXR = reg[0];
    I2caRegs.I2CDXR = reg[1];
    // Data successfully written
    return Status;
}
// I2CA_ReadFromManyRegs-この関数は、スレーブデバイスのレジスタからデータバイトを読み取ります。
// 初期書き込み時に複数のレジスタを送信する場合。
//
// INPUTS:
//  --slave_addr ==>読み取られているスレーブデバイスのアドレス
//  --reg [] ==>から読み取られるスレーブデバイスレジスタ
//  --reg_size ==>書き込まれるレジスタバイトの数、reg_sizeバッファのサイズ
//  --data [] ==>スレーブデバイスレジスタから読み取ったバイトを格納するデータバッファ
//  --data_size ==>受信するデータバイト数、データバッファのサイズ
unsigned short I2CA_ReadFromManyRegs(unsigned short slave_addr, unsigned short reg[], unsigned short reg_size, unsigned short data[], unsigned short data_size)
{
    unsigned short i;
    unsigned short Status;
    Status = I2C_SUCCESS;
    // STPビットが以前のマスター通信からクリアされるまで待機します
    // モジュールによるこのビットのクリアは、SCDビットが設定されるまで遅延されます。
    // 新しいメッセージを開始する前にこのビットがチェックされていないと、I2Cが混乱する可能性があります。
    if (I2caRegs.I2CMDR.bit.STP == 1)
    {
        return I2C_STP_NOT_READY_ERROR;
    }
    // スレーブアドレスの設定
    I2caRegs.I2CSAR = slave_addr;
    // Check if bus busy
    if (I2caRegs.I2CSTR.bit.BB == 1)
    {
        return I2C_BUS_BUSY_ERROR;
    }
    // 1. スレーブアドレスを送信し、続いてレジスタバイトを送信します。
    // 送信するバイト数を設定
    // == # of register bytes
    I2caRegs.I2CCNT = reg_size;
    // マスター送信機として設定
    // FREE + MST + TRX + IRS
    I2caRegs.I2CMDR.all = 0x4620;
    I2caRegs.I2CMDR.bit.STT = 0x1; // START条件を送信
    while(!I2caRegs.I2CSTR.bit.ARDY) // スレーブアドレスが送信されるまで待機
    {
        if(I2caRegs.I2CSTR.bit.XSMT == 0)
        {
            break; // スレーブアドレスでACKを受信
        }
    }
    #if NACK_CHECK // NACKを受信したかどうかを確認
        if(I2caRegs.I2CSTR.bit.NACK == 1)
        {
            I2caRegs.I2CMDR.bit.STP = 1;
            I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
            Status = I2C_ERROR;
            return Status;
        }
    #endif
    // レジスタバイトの送信
    for (i=0; i< reg_size; i++)
    {
        while(!I2caRegs.I2CSTR.bit.XRDY){} // データを書き込む準備ができていることを確認
        I2caRegs.I2CDXR = reg[i];
        #if NACK_CHECK // NACKを受信したかどうかを確認
            if(I2caRegs.I2CSTR.bit.NACK == 1)
            {
                I2caRegs.I2CMDR.bit.STP = 1;
                I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
                Status = I2C_ERROR;
                return Status;
            }
        #endif
    }
    // 前の通信が完了するのを待つ
    while(!I2caRegs.I2CSTR.bit.ARDY){}
    // 2. スレーブデバイスからデータバイトを受信する
    // マスターレシーバーとして設定
    // FREE + MST + IRS ==> (Master Receiver)
    I2caRegs.I2CMDR.all = 0x4420;
    // 受信するバイト数を設定
    // == # of data bytes
    I2caRegs.I2CCNT = data_size;
    I2caRegs.I2CMDR.bit.STT = 0x1; // I2CCNTがゼロのときに生成されるSTART条件とスレーブアドレスセットのSTOP条件を繰り返し送信
    I2caRegs.I2CMDR.bit.STP = 0x1;
    #if NACK_CHECK // NACKを受信したかどうかを確認
        if(I2caRegs.I2CSTR.bit.NACK == 1)
        {
            I2caRegs.I2CMDR.bit.STP = 1;
            I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT;
            Status = I2C_ERROR;
            return Status;
        }
    #endif
    for (i=0; i< data_size; i++)
    {
        while(!I2caRegs.I2CSTR.bit.RRDY){} // データを受信する準備ができていることを確認
        data[i] = I2caRegs.I2CDRR; // 受信したバイトをバッファリング
    }
    // Data successfully read
    return Status;
}
// End of File
We would appreciate it if you could suggest sample code.
Thank you.
				
                          