Currently I am using the TI F28335 MCU and try to read sensor data from some sensors via I2C communication, it didn't receive any updated data for all the sensors I use.
After checking the coding, I found that the process was always frozen at this line
while(I2caRegs.I2CSTR.bit.XRDY == 0); // wait until first byte is out
I2caRegs.I2CDXR = 0xE5 ;
which means the 1st byte was even not sent out
i pasted the code here and appreciated so much if anybody can help me .
NOTE: the code I use is based on a i2c sensor reading example I found from TI official teaching material.
//
// Lab12_2: TMS320F28335
// (C) Frank Bormann
//
//###########################################################################
//
// FILE: Lab12_2.c
//
// TITLE: DSP28335 I2C test
// Temperature Sensor TMP100 connected to GPIO33 (SCL) and GPIO32(SDA)
// LED GPIO34 as life indicator 100 ms toggle
// 12 bit mode of TMP100, 1/16 degree celcius resolution
// use watch window for variable "temperature" (type int; qvalue:8)
//###########################################################################
//
// Ver | dd mmm yyyy | Who | Description of changes
// =====|=============|======|===============================================
// 3.0 | 24 Jul 2009 | F.B. | Lab12_1 F28335; Header-files Version 1.20
// 3.1 | 15 Nov 2009 | F.B | Lab12_1 for F28335 @30MHz and PE revision 5
//###########################################################################
#include "DSP2833x_Device.h"
#define TCS24725_SLAVE 0x40 // slave address TCS24725
/*
#define POINTER_TEMPERATURE 0
#define POINTER_CONFIGURATION 1
#define POINTER_T_LOW 2
#define POINTER_T_HIGH 3
*/
#define TCS34725_COMMAND_BIT 0x80
#define TCS34725_ENABLE 0x00
#define TCS34725_ENABLE_AIEN 0x10 /* RGBC Interrupt Enable */
#define TCS34725_ENABLE_WEN 0x08 /* Wait enable - Writing 1 activates the wait timer */
#define TCS34725_ENABLE_AEN 0x02 /* RGBC Enable - Writing 1 actives the ADC, 0 disables it */
#define TCS34725_ENABLE_PON 0x01 /* Power on - Writing 1 activates the internal oscillator, 0 disables it */
#define TCS34725_ATIME 0x01 /* Integration time */
#define TCS34725_WTIME 0x03 /* Wait time (if TCS34725_ENABLE_WEN is asserted) */
#define TCS34725_WTIME_2_4MS 0xFF /* WLONG0 = 2.4ms WLONG1 = 0.029s */
#define TCS34725_WTIME_204MS 0xAB /* WLONG0 = 204ms WLONG1 = 2.45s */
#define TCS34725_WTIME_614MS 0x00 /* WLONG0 = 614ms WLONG1 = 7.4s */
#define TCS34725_AILTL 0x04 /* Clear channel lower interrupt threshold */
#define TCS34725_AILTH 0x05
#define TCS34725_AIHTL 0x06 /* Clear channel upper interrupt threshold */
#define TCS34725_AIHTH 0x07
#define TCS34725_PERS 0x0C /* Persistence register - basic SW filtering mechanism for interrupts */
#define TCS34725_PERS_NONE 0b0000 /* Every RGBC cycle generates an interrupt */
#define TCS34725_PERS_1_CYCLE 0b0001 /* 1 clean channel value outside threshold range generates an interrupt */
#define TCS34725_PERS_2_CYCLE 0b0010 /* 2 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_3_CYCLE 0b0011 /* 3 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_5_CYCLE 0b0100 /* 5 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_10_CYCLE 0b0101 /* 10 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_15_CYCLE 0b0110 /* 15 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_20_CYCLE 0b0111 /* 20 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_25_CYCLE 0b1000 /* 25 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_30_CYCLE 0b1001 /* 30 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_35_CYCLE 0b1010 /* 35 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_40_CYCLE 0b1011 /* 40 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_45_CYCLE 0b1100 /* 45 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_50_CYCLE 0b1101 /* 50 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_55_CYCLE 0b1110 /* 55 clean channel values outside threshold range generates an interrupt */
#define TCS34725_PERS_60_CYCLE 0b1111 /* 60 clean channel values outside threshold range generates an interrupt */
#define TCS34725_CONFIG 0x0D
#define TCS34725_CONFIG_WLONG 0x02 /* Choose between short and long (12x) wait times via TCS34725_WTIME */
#define TCS34725_CONTROL 0x0F /* Set the gain level for the sensor */
#define TCS34725_ID 0x12 /* 0x44 = TCS34721/TCS34725, 0x4D = TCS34723/TCS34727 */
#define TCS34725_STATUS 0x13
#define TCS34725_STATUS_AINT 0x10 /* RGBC Clean channel interrupt */
#define TCS34725_STATUS_AVALID 0x01 /* Indicates that the RGBC channels have completed an integration cycle */
#define TCS34725_CDATAL 0x14 /* Clear channel data_low8-bit byte */
#define TCS34725_CDATAH 0x15 /* Clear channel data_high 8-bit byte */
#define TCS34725_RDATAL 0x16 /* Red channel data */
#define TCS34725_RDATAH 0x17
#define TCS34725_GDATAL 0x18 /* Green channel data */
#define TCS34725_GDATAH 0x19
#define TCS34725_BDATAL 0x1A /* Blue channel data */
#define TCS34725_BDATAH 0x1B
// external function prototypes
extern void InitSysCtrl(void);
extern void InitPieCtrl(void);
extern void InitPieVectTable(void);
extern void InitCpuTimers(void);
extern void ConfigCpuTimer(struct CPUTIMER_VARS *, float, float);
// Prototype statements for functions found within this file.
void Gpio_select(void);
void I2CA_Init(void);
interrupt void cpu_timer0_isr(void);
int clear_light_low;
int red_light;
int green_light;
int blue_light;
//###########################################################################
// main code
//###########################################################################
void main(void)
{
InitSysCtrl(); // Basic Core Init from DSP2833x_SysCtrl.c
EALLOW;
SysCtrlRegs.WDCR= 0x00AF; // Re-enable the watchdog
EDIS; // 0x00AF to NOT disable the Watchdog, Prescaler = 64
DINT; // Disable all interrupts
Gpio_select(); // GPI031-LED2, GPIO34-LED3 as output
// to 2 LEDs on F28335 control-card
I2CA_Init(); // Initialize I2C device slave address is issued in I2CA_Init() 0x29
// step 1 : do the configuration:
//----------------------------------------------------//
// Send START, set pointer to Configuration register and set resolution to 12 bit
//hence it is master-transmitter mode to write register to the sensor
//step 1.1 set integration time to address 0x01+0xFF (2.4ms)
//step 1.2 set gain to address 0x0F + 0x00 (1*gain)
//step 1.3 Enable Device to address 0x00+0x03
I2caRegs.I2CCNT = 2; // means the DXR includes 2 byte including POINTER_CONFIGURATION and 0x60 for data bit setting
I2caRegs.I2CMDR.all = 0x6E20; //0x6E20 convert to binary is 0110111000100000
I2caRegs.I2CDXR = 0x80;
/*
Bit15 = 0; no NACK in receiver mode
Bit14 = 1; FREE on emulation halt
Bit13 = 1; STT generate START
Bit12 = 0; reserved
Bit11 = 1; STP generate STOP
Bit10 = 1; MST master mode
Bit9 = 1; TRX ****master - transmitter mode****
Bit8 = 0; XA 7 bit address mode
Bit7 = 0; RM nonrepeat mode, I2CCNT determines # of bytes
Bit6 = 1; DLB no loopback mode.it should be '0', from slide 12-12 corrected by Alex.J.
Bit5 = 1; IRS I2C module enabled
Bit4 = 0; STB no start byte mode
Bit3 = 0; FDF no free data format
Bit2-0: 0; BC **** 8 bit per data byte****
*/
while(I2caRegs.I2CSTR.bit.XRDY == 0); // wait until first byte is out
I2caRegs.I2CDXR = 0xE5 ; /*0x03 is '00000011',enable AEN and PON */
while(I2caRegs.I2CSTR.bit.SCD == 0); // wait for STOP condition
I2caRegs.I2CSTR.bit.SCD = 1; //clear stop condition flag
InitPieCtrl(); // basic setup of PIE table; from DSP2833x_PieCtrl.c
InitPieVectTable(); // default ISR's in PIE
EALLOW;
PieVectTable.TINT0 = &cpu_timer0_isr;
EDIS;
InitCpuTimers(); // basic setup CPU Timer0, 1 and 2
ConfigCpuTimer(&CpuTimer0,150,100000);
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
IER |=1;
EINT;
ERTM;
CpuTimer0Regs.TCR.bit.TSS = 0; // start timer0
//step 2 : start read the sensor data including 1 byte pointer register==>2 byte sensor data (upper 8bit) + (lower 8bit)
while(1)
{
while(CpuTimer0.InterruptCount == 0);
CpuTimer0.InterruptCount = 0;
EALLOW;
SysCtrlRegs.WDKEY = 0x55; // service WD #1
EDIS;
// Send START and set pointer to temperature - register
I2caRegs.I2CCNT = 1; // pointer to temperature register, count 1 bit only
I2caRegs.I2CDXR = 0x81;// set Pointer Address to pointer_temperature
// Send start as master transmitter
I2caRegs.I2CMDR.all = 0x6620; //only change stop to '0', do not generate stop. all others are the same as 6E20
/* Bit15 = 0; no NACK in receiver mode
Bit14 = 1; FREE on emulation halt
Bit13 = 1; STT generate START
Bit12 = 0; reserved
Bit11 = 0; STP not generate STOP
Bit10 = 1; MST master mode
Bit9 = 1; TRX master - transmitter mode
Bit8 = 0; XA 7 bit address mode
Bit7 = 0; RM nonrepeat mode, I2CCNT determines # of bytes
Bit6 = 1; DLB no loopback mode ,it should be '0', corrected by alex.J
Bit5 = 1; IRS I2C module enabled
Bit4 = 0; STB no start byte mode
Bit3 = 0; FDF no free data format
Bit2-0: 0; BC 8 bit per data byte,000 */
while(I2caRegs.I2CSTR.bit.ARDY == 0); // 0=previous cycle has not completed, wait for access ready condition
I2caRegs.I2CCNT = 1; // read 2 byte temperature
I2caRegs.I2CMDR.all = 0x6C20; //only change bit9 to 0, means master-receiver mode
/* Bit15 = 0; no NACK in receiver mode
Bit14 = 1; FREE on emulation halt
Bit13 = 1; STT generate START
Bit12 = 0; reserved
Bit11 = 1; STP generate STOP
Bit10 = 1; MST master mode
Bit9 = 0; TRX master - receiver mode
Bit8 = 0; XA 7 bit address mode
Bit7 = 0; RM nonrepeat mode, I2CCNT determines # of bytes
Bit6 = 0; DLB no loopback mode
Bit5 = 1; IRS I2C module enabled
Bit4 = 0; STB no start byte mode
Bit3 = 0; FDF no free data format
Bit2-0: 0; BC 8 bit per data byte */
while(I2caRegs.I2CSTR.bit.RRDY == 0); //0 means receive data NOT available in 12CDRR, wait for 1st byte
clear_light_low = I2caRegs.I2CDRR;
// read upper 8 Bit (integers)// read upper 8 Bit (integers)
// RRDY is automatically cleared by read of I2CDRR
GpioDataRegs.GPBTOGGLE.bit.GPIO34 = 0; // toggle red LED LD3 @ 28335CC
}
}
void Gpio_select(void)
{
EALLOW;
GpioCtrlRegs.GPAMUX1.all = 0; // GPIO15 ... GPIO0 = General Puropse I/O
GpioCtrlRegs.GPAMUX2.all = 0; // GPIO31 ... GPIO16 = General Purpose I/O
GpioCtrlRegs.GPBMUX1.all = 0; // GPIO47 ... GPIO32 = General Purpose I/O
GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1; // GPIO32 = I2C - SDA
GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1; // GPIO33 = I2C - SCL
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)
GpioCtrlRegs.GPBMUX2.all = 0; // GPIO63 ... GPIO48 = General Purpose I/O
GpioCtrlRegs.GPCMUX1.all = 0; // GPIO79 ... GPIO64 = General Purpose I/O
GpioCtrlRegs.GPCMUX2.all = 0; // GPIO87 ... GPIO80 = General Purpose I/O
GpioCtrlRegs.GPADIR.all = 0; // GPIO0 to 31 as inputs
GpioCtrlRegs.GPADIR.bit.GPIO9 = 1; // GPIO9 = LED LD1
GpioCtrlRegs.GPADIR.bit.GPIO11 = 1; // GpIO11 = LED LD2
GpioCtrlRegs.GPBDIR.all = 0; // GPIO63-32 as inputs
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // peripheral explorer: LED LD3 at GPIO34
GpioCtrlRegs.GPBDIR.bit.GPIO49 = 1; // peripheral explorer: LED LD4 at GPIO49
GpioCtrlRegs.GPCDIR.all = 0; // GPIO87-64 as inputs
EDIS;
}
void I2CA_Init(void)
{
I2caRegs.I2CMDR.bit.IRS = 0; // Reset the I2C module
// I2C slave address register
I2caRegs.I2CSAR = TCS24725_SLAVE;
// I2C Prescale Register
I2caRegs.I2CPSC.all = 14; // Internal I2C module clock = SYSCLK/(PSC +1)
// = 10 MHz
I2caRegs.I2CCLKL = 95; // Tmaster = (PSC +1)[ICCL + 5 + ICCH + 5] / 150MHz
I2caRegs.I2CCLKH = 95; // Tmaster = 10 [ICCL + ICCH + 10] / 150 MHz
// d = 5 for IPSC >1
// for I2C 50 kHz:
// Tmaster = 20 µs *150 MHz / 10 = 200 = (ICCL + ICCH +10)
// ICCL + ICCH = 190
// ICCL = ICH = 190/2 = 95
// I2caRegs.I2CCLKL = 45;
// I2caRegs.I2CCLKH = 45; // for I2C 100 kHz:
// Tmaster = 10 µs *150 MHz / 10 = 100 = (ICCL + ICCH + 10)
// ICCL + ICCH = 90
// ICCL = ICH = 90/2 = 45
I2caRegs.I2CMDR.bit.IRS = 1; // Take I2C out of reset
}
interrupt void cpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++;
EALLOW;
SysCtrlRegs.WDKEY = 0xAA; // service WD #2
EDIS;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
//===========================================================================
// End of SourceCode.
//===========================================================================






