//###########################################################################
//
//! \addtogroup f2803x_example_list
//!
I2C EEPROM(i2c_eeprom)
//!
//! This program requires an external I2C EEPROM connected to
//! the I2C bus at address 0x50.
//! This program will write 1-14 words to EEPROM and read them back.
//! The data written and the EEPROM address written to are contained
//! in the message structure, \b I2cMsgOut1. The data read back will be
//! contained in the message structure \b I2cMsgIn1.
//!
//! \note This program will only work on kits that have an on-board I2C EEPROM. T
//! (e.g. F2803x eZdsp)
//!
//! \b Watch \b Variables \n
//! - I2cMsgIn1
//! - I2cMsgOut1
//
//###########################################################################
// $TI Release: F2803x C/C++ Header Files and Peripheral Examples V127 $
// $Release Date: March 30, 2013 $
//###########################################################################
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
// Note: I2C Macros used in this example can be found in the
// DSP2803x_I2C_defines.h file
// Prototype statements for functions found within this file.
void I2CA_Init(void);
Uint16 I2CA_WriteData(struct I2CMSG *msg);
Uint16 I2CA_ReadData(struct I2CMSG *msg);
__interrupt void i2c_int1a_isr(void);
void pass(void);
void fail(void);
void compare_I2C_RW(void);
Uint16 correct=0;
#define I2C_SLAVE_ADDR 0x50
#define I2C_SLAVE_ADDR_READ 0x51
//#define I2C_NUMBYTES 2
#define I2C_NUMBYTES 10
#define I2C_EEPROM_HIGH_ADDR 0x00
#define I2C_EEPROM_LOW_ADDR 0x30
// Global variables
// Two bytes will be used for the outgoing address,
// thus only setup 14 bytes maximum
struct I2CMSG I2cMsgOut1={I2C_MSGSTAT_SEND_WITHSTOP,
I2C_SLAVE_ADDR,
I2C_NUMBYTES,
I2C_EEPROM_HIGH_ADDR,
I2C_EEPROM_LOW_ADDR,
0x12, // Msg Byte 1
0x34,
0x56,
0x78,
0x06,
0x06,
0x06,
0x06, // Msg Byte 2
0x06,
0x06};
struct I2CMSG I2cMsgIn1={ I2C_MSGSTAT_SEND_NOSTOP,
I2C_SLAVE_ADDR,
I2C_NUMBYTES,
I2C_EEPROM_HIGH_ADDR,
I2C_EEPROM_LOW_ADDR};
struct I2CMSG *CurrentMsgPtr; // Used in interrupts
Uint16 PassCount;
Uint16 FailCount;
Uint16 GlobalCount=0;
void main(void)
{
Uint16 Error;
Uint16 i;
CurrentMsgPtr = &I2cMsgOut1;
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP2803x_SysCtrl.c file.
InitSysCtrl();
// Step 2. Initialize GPIO:
// This example function is found in the DSP2803x_Gpio.c file and
// illustrates how to set the GPIO to it's default state.
// InitGpio();
// Setup only the GP I/O only for I2C functionality
InitI2CGpio();
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2803x_PieCtrl.c file.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP2803x_DefaultIsr.c.
// This function is found in DSP2803x_PieVect.c.
InitPieVectTable();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
// PieVectTable.I2CINT1A = &i2c_int1a_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2803x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
I2CA_Init();
for (i = 0; i < I2C_MAX_BUFFER_SIZE; i++)
{
I2cMsgIn1.MsgBuffer[i] = 0x0000;
}
I2CA_WriteData(&I2cMsgOut1);
CurrentMsgPtr = &I2cMsgIn1;
I2CA_ReadData(&I2cMsgIn1);
compare_I2C_RW();
}
// Step 5. User specific code
Uint16 I2CA_WriteData(struct I2CMSG *msg)
{
Uint16 i=0;
//I2caRegs.I2CMDR.all = 0x2620;//Start condition, Master transmitter, 7 bit addr, nonrepeat mode
// Setup slave address
I2caRegs.I2CSAR = msg->SlaveAddress;
I2caRegs.I2CMDR.all = 0x2E20;//Start condition, Master transmitter, 7 bit addr, nonrepeat mode
I2caRegs.I2CCNT = msg->NumOfBytes+2;
I2caRegs.I2CDXR = msg->MemoryHighAddr;
while(!(I2caRegs.I2CSTR.bit.XRDY));
I2caRegs.I2CDXR = msg->MemoryLowAddr;
while(!(I2caRegs.I2CSTR.bit.XRDY));
for (i=0; iNumOfBytes; i++)
{
//while(!(I2caRegs.I2CSTR.bit.XRDY))
I2caRegs.I2CDXR = *(msg->MsgBuffer+i);
while(!(I2caRegs.I2CSTR.bit.XRDY));
}
// Send start as master transmitter, free running with breakpoint, IRS=1,STP=1,STT=1,NACKMODE=0,MST=1,TRX=1,FREE=1,STB=1
return I2C_SUCCESS;
}
Uint16 I2CA_ReadData(struct I2CMSG *msg)
{
Uint16 i=0;
I2caRegs.I2CSAR = msg->SlaveAddress;
I2caRegs.I2CMDR.all = 0x2620;//Start condition, Master transmitter, 7 bit addr, nonrepeat mode
I2caRegs.I2CCNT = 2;
I2caRegs.I2CDXR = msg->MemoryHighAddr;
// I2caRegs.I2CSTR.bit.XRDY=1;
while(!(I2caRegs.I2CSTR.bit.XRDY));
I2caRegs.I2CDXR = msg->MemoryLowAddr;
while(!(I2caRegs.I2CSTR.bit.XRDY));
I2caRegs.I2CSAR = msg->SlaveAddress;
I2caRegs.I2CMDR.all=0x2C20;
I2caRegs.I2CCNT=msg->NumOfBytes;
for (i=0; iNumOfBytes; i++)
{
;
while(!(I2caRegs.I2CSTR.bit.RRDY));
*(msg->MsgBuffer+i)=I2caRegs.I2CDRR;
}
return I2C_SUCCESS;
}
void I2CA_Init(void)
{
I2caRegs.I2CPSC.all = 6; // Prescaler - need 7-12 Mhz on module clk
I2caRegs.I2CCLKL = 10; // NOTE: must be non zero
I2caRegs.I2CCLKH = 5; // NOTE: must be non zero
//I2caRegs.I2CIER.all = 0x24; // Enable SCD & ARDY interrupts
I2caRegs.I2CMDR.all = 0;
I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset
return;
}
void compare_I2C_RW()
{
Uint16 i;
//Uint16 correct=0;
for(i=0;i