Part Number: LAUNCHXL-F280049C
Tool/software: Code Composer Studio
Dear Sir
I have a problem with the I2C in the LAUNCHXL-F280049C board.
I simply want write to I2C a data. I configure the board in several way, adapting code for other microcontroller.
My problem is that: after write, in SDA and SCL pin (GPIO35, GPIO37) I don't see anything. Both the pin keep always high (I use external pull up resistor).
In the following code, the program stops in "I2CA_Wait();" at "while (I2caRegs.I2CMDR.bit.STP == 1);" instruction.
Any suggestion?
Regards
Piero
// Included Files
#include "F28x_Project.h"
#include "stdio.h"
//--------------------------------------------
// Defines
//--------------------------------------------
// Error Messages
#define I2C_ERROR 0xFFFF
#define I2C_ARB_LOST_ERROR 0x0001
#define I2C_NACK_ERROR 0x0002
#define I2C_BUS_BUSY_ERROR 0x1000
#define I2C_STP_NOT_READY_ERROR 0x5555
#define I2C_NO_FLAGS 0xAAAA
#define I2C_SUCCESS 0x0000
// Clear Status Flags
#define I2C_CLR_AL_BIT 0x0001
#define I2C_CLR_NACK_BIT 0x0002
#define I2C_CLR_ARDY_BIT 0x0004
#define I2C_CLR_RRDY_BIT 0x0008
#define I2C_CLR_SCD_BIT 0x0020
// Interrupt Source Messages
#define I2C_NO_ISRC 0x0000
#define I2C_ARB_ISRC 0x0001
#define I2C_NACK_ISRC 0x0002
#define I2C_ARDY_ISRC 0x0003
#define I2C_RX_ISRC 0x0004
#define I2C_TX_ISRC 0x0005
#define I2C_SCD_ISRC 0x0006
#define I2C_AAS_ISRC 0x0007
// Prototype statements for functions found within this file.
void I2CA_Init(void);
void I2CA_Write(int);
void I2CA_Read(int);
void I2CA_Wait(void);
interrupt void i2c_int1a_isr(void);
struct FLAGREG_BITS
{
volatile unsigned int Rsvd:16; //bits 0-14
};
union FLAG_REG
{
volatile unsigned int all;
struct FLAGREG_BITS bit;
}Flags;
Uint16 Register;
Uint16 Reg[6];
Uint16 ReadReg[6] = {0,0,0,0,0,0};
Uint16 InData[3];
Uint16 OutData[3];
Uint16 I2cIndex;
#define I2C_SLAVE_ADDR 0x2c
void main(void)
{
// Step 1. Initialize System Control:
// PLL, WatchDog, enable Peripheral Clocks
// This example function is found in the DSP280x_SysCtrl.c file.
InitSysCtrl();
// Step 2. Initalize GPIO:
// This example function is found in the DSP280x_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();
EALLOW;
// Enable internal pull-up for the selected pins
// Pull-ups can be enabled or disabled disabled by the user.
GpioCtrlRegs.GPBPUD.bit.GPIO35 = 1; // Disable pull-up for GPIO35 (I2CA_SDA)
GpioCtrlRegs.GPBPUD.bit.GPIO37 = 1; // Disable pull-up for GPIO37 (I2CA_SCL)
// Set qualification for selected pins to asynch only
// This will select asynch (no qualification) for the selected pins.
GpioCtrlRegs.GPBQSEL1.bit.GPIO35 = 3; // Asynch input GPIO35 (I2CA_SDA)
GpioCtrlRegs.GPBQSEL1.bit.GPIO37 = 3; // Asynch input GPIO37 (I2CA_SCL)
// Configure SCI pins using GPIO regs
// This specifies which of the possible GPIO pins will be I2C functional pins.
GpioCtrlRegs.GPBMUX1.bit.GPIO35 = 3; // Configure GPIO35 for I2CA_SDA operation
GpioCtrlRegs.GPBMUX1.bit.GPIO37 = 3; // Configure GPIO37 for I2CA_SCL operation
EDIS;
// 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 DSP280x_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 DSP280x_DefaultIsr.c.
// This function is found in DSP280x_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.I2CA_FIFO_INT = &i2c_int1a_isr;
PieVectTable.I2CA_INT = &i2c_int1a_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
I2cIndex = 0;
// Step 4. Initialize all the Device Peripherals:
I2CA_Init();
// Step 5, Master I2C register initialization
//
Reg[0] = 0x0055;
Reg[1] = 0x01AA;
Reg[2] = 0x0234;
Reg[3] = 0x0321;
Reg[4] = 0x0468;
Reg[5] = 0x0531;
// Enable interrupts required for this example
// Enable I2C interrupt 1 in the PIE: Group 8 interrupt 1
PieCtrlRegs.PIEIER8.bit.INTx1 = 1;
// Enable CPU INT8 which is connected to PIE group 8
IER |= M_INT8;
EINT;
// Application loop
while(1){
I2caRegs.I2CSAR.all = I2C_SLAVE_ADDR;// Set up address written to.
I2CA_Write(0); // Transfer Register 0 contents to slave.
I2CA_Wait(); // Wait for I2C bus to clear
/*I2CA_Write(1);
I2CA_Wait(); // Wait for I2C bus to clear
I2CA_Write(2);
I2CA_Wait(); // Wait for I2C bus to clear
I2CA_Write(3);
I2CA_Wait(); // Wait for I2C bus to clear
I2CA_Write(4);
I2CA_Wait(); // Wait for I2C bus to clear
I2CA_Write(5);
I2CA_Wait(); // Wait for I2C bus to clear
///////////////////////////////////
// Read data from slave section //
///////////////////////////////////
//
// This needs to be changed to (1) Send out the Register as a write,
// followed by (2) Receiving the response.
//
I2CA_Read(0);
I2CA_Wait();
ReadReg[0] = (InData[0]<<8) + InData[1];
I2CA_Read(1);
I2CA_Wait();
ReadReg[1] = (InData[0]<<8) + InData[1];
I2CA_Read(2);
I2CA_Wait();
ReadReg[2] = (InData[0]<<8) + InData[1];
I2CA_Read(3);
I2CA_Wait();
ReadReg[3] = (InData[0]<<8) + InData[1];
I2CA_Read(4);
I2CA_Wait();
ReadReg[4] = (InData[0]<<8) + InData[1];
I2CA_Read(5);
I2CA_Wait();
ReadReg[5] = (InData[0]<<8) + InData[1];*/
}
} // end of main
void I2CA_Init(void)
{
// Initialize I2C
I2caRegs.I2CSAR.all = I2C_SLAVE_ADDR;//0x002C; // Slave Address.
I2caRegs.I2COAR.all = 0x002D; // address as Master.
I2caRegs.I2CPSC.all = 9; // Prescaler - need 7-12 Mhz on module clk
I2caRegs.I2CCLKL = 45; // NOTE: must be non zero
I2caRegs.I2CCLKH = 45; // NOTE: must be non zero
I2caRegs.I2CIER.all = 0x2C; // Enable SCD & ARDY interrupts
I2caRegs.I2CMDR.bit.IRS = 1; // Take I2C out of reset
// Stop I2C when suspended
I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
// I2caRegs.I2CFFRX.all = 0x2040; // Enable RXFIFO, clear RXFFINT,
return;
}
void I2CA_Write(Register)
{
int Byte0;
int Byte1;
Byte0 = Reg[Register]&0x0FF; // Get low byte of selected register.
Byte1 = Reg[Register]>>8; // Get high byte of selected register.
// Slave Address info gets passed with Start Condition
// I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
I2caRegs.I2CCNT = 3; // 3 Additional Bytes being tranferred.
I2caRegs.I2CDXR.all = Register; // Send Register to be updated.
I2caRegs.I2CDXR.all = Byte1; // Next is high byte of register.
I2caRegs.I2CDXR.all = Byte0; // Next is low byte of register.
I2caRegs.I2CMDR.all = 0x6E20; // Set up the control register:
// bit 14 FREE = 1
// bit 13 STT = 1 (Start condition)
// bit 11 STP = 1 (Stop condition after
// transfer of bytes.)
// bit 10 MST = 1 Master
// bit 9 TRX = 1 Transmit
// bit 5 IRS = 1 to Reset I2C bus.
}
void I2CA_Read(Register)
{
I2cIndex = 0; // Reset value for ISR.
// Slave Address info gets passed with Start Condition
I2caRegs.I2CCNT = 1; // 1 Additional Byte being tranferred.
I2caRegs.I2CDXR.all = Register; // Send Register to be updated.
I2caRegs.I2CMDR.all = 0x6620; // Set up the control register:
// bit 14 FREE = 1
// bit 13 STT = 1 (Start condition)
// bit 11 STP = 0 (Stop condition after
// transfer of bytes.)
// bit 10 MST = 1 Master
// bit 9 TRX = 1 Transmit
// bit 5 IRS = 1 to Reset I2C bus.
DELAY_US(50); // Delay 50 usec
I2caRegs.I2CCNT = 2; // Set up receive of 2 bytes.
I2caRegs.I2CMDR.all = 0x6C20; // Send "repeated" Start with Read (TRX off)
// and Stop.
// while (I2caRegs.I2CMDR.bit.STP == 1); // Wait for Stop condition bit to be zero.
// while (I2caRegs.I2CSTR.bit.BB == 1); // Wait for Bus Busy to be zero.
}
void I2CA_Wait(void)
{
// Wait until the STP bit is cleared from any previous master communication.
// Clearing of this bit by the module is delayed until after the SCD bit is
// set. If this bit is not checked prior to initiating a new message, the
// I2C could get confused.
while (I2caRegs.I2CMDR.bit.STP == 1); // Wait for Stop condition bit to be zero.
while (I2caRegs.I2CSTR.bit.BB == 1); // Wait for Bus Busy to be zero.
}
interrupt void i2c_int1a_isr(void) // I2C-A
{
Uint16 IntSource;
// Read interrupt source
IntSource = I2caRegs.I2CISRC.bit.INTCODE & 0x7;
switch(IntSource)
{
case I2C_NO_ISRC: // =0
break;
case I2C_ARB_ISRC: // =1
break;
case I2C_NACK_ISRC: // =2
break;
case I2C_ARDY_ISRC: // =3
break;
case I2C_RX_ISRC: // =4
InData[I2cIndex++] = I2caRegs.I2CDRR.all;
break;
case I2C_TX_ISRC: // =5
break;
case I2C_SCD_ISRC: // =6
break;
case I2C_AAS_ISRC: // =7
break;
default:
asm(" ESTOP0"); // Halt on invalid number.
}
// Enable future I2C (PIE Group 8) interrupts
PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
}