Hi, I have problems reading the contents of the registers from a sensor conected to the I2C bus in the C2000 Peripheral Explorer Kit. The sensor is the ADXL345, an accelerometer that stores the readings in 8-bit registers (2 registers per reading, one with higher byte and the other with lower byte). The configuration of the sensor should be correct because the debugger goes on step by step.
The program works, but the values read make no sense, because I am obtaining always the same value from those registers, no matter which register I am reading or the position of the sensor. Please find attached the code, I really don't know what is it that I'm doing wrong.
Also, is there anyway to monitor the state of the signals SCL and SDA to understand better if something is being done wrong?
Thank you very much.
//########################################################################### // // FILE: ADXL345.c // // TITLE: DSP28335 I2C test // Accelerometer ADXL345 connected to GPIO33 (SCL) and GPIO32(SDA) // LED LD1 as life indicator 100 ms toggle // //########################################################################### #include "DSP2833x_Device.h" // Define register addresses #define ACCEL 0x53 // slave address #define ACCEL_WRITE 0xA6 // slave address for writing #define ACCEL_READ 0xA7 // slave address for reading #define POWER_CTL 0x2D // POWER_CTL register at sensor #define DATAX0 0x32 // LS byte for X measurement #define DATAX1 0x33 // MS byte for X measurement #define DATAY0 0x34 // LS byte for Y measurement #define DATAY1 0x35 // MS byte for Y measurement #define DATAZ0 0x36 // LS byte for Z measurement #define DATAZ1 0x37 // MS byte for Z measurement // external function prototypes extern void InitSysCtrl(void); extern void InitPieCtrl(void); extern void InitPieVectTable(void); // Prototype statements for functions found within this file. void Gpio_select(void); void I2CA_Init(void); int xaccel = 0; int yaccel; int zaccel; //########################################################################### // 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(); // Initialize I2C I2CA_Init(); // Initialize and configure ADXL345 I2caRegs.I2CCNT = 3; //Send 3 bytes I2caRegs.I2CDXR = ACCEL_WRITE; //Select POWER_CTL register in sensor I2caRegs.I2CMDR.all = 0x6E20; //Generate start and stop, master transmitter while(I2caRegs.I2CSTR.bit.XRDY == 0); // wait until first byte is out I2caRegs.I2CDXR = POWER_CTL; //Select POWER_CTL register in sensor while(I2caRegs.I2CSTR.bit.XRDY == 0); // wait until second byte is out I2caRegs.I2CDXR = 0x08; //Activate measurement mode in sensor while(I2caRegs.I2CSTR.bit.SCD == 0); // wait for STOP condition I2caRegs.I2CSTR.bit.SCD = 1; InitPieCtrl(); // basic setup of PIE table; from DSP2833x_PieCtrl.c InitPieVectTable(); // default ISR's in PIE InitCpuTimers(); // basic setup CPU Timer0, 1 and 2 PieCtrlRegs.PIEIER1.bit.INTx7 = 1; IER |=1; EINT; ERTM; EALLOW; SysCtrlRegs.WDKEY = 0x55; // service WD #1 EDIS; //Read acceleration on X axis //Higher 8 bits (DATAX1 register) I2caRegs.I2CCNT = 2; //Write 1 byte (register address) I2caRegs.I2CDXR = ACCEL_WRITE; //Select higher byte register in sensor I2caRegs.I2CMDR.all = 0x6E20; //Generate start and stop, master transmitter while(I2caRegs.I2CSTR.bit.XRDY == 0); // wait until first byte is out I2caRegs.I2CDXR = DATAX1; //Select higher byte register in sensor while(I2caRegs.I2CSTR.bit.SCD == 0); // wait for STOP condition I2caRegs.I2CSTR.bit.SCD = 1; I2caRegs.I2CCNT = 1; //Write 1 byte (register address) I2caRegs.I2CDXR = ACCEL_READ; //Select higher byte register in sensor I2caRegs.I2CMDR.all = 0x6620; //Generate start but not stop, master transmitter while(I2caRegs.I2CSTR.bit.XRDY == 0); // wait until first byte is out while(I2caRegs.I2CSTR.bit.ARDY == 0); // wait for access ready condition I2caRegs.I2CCNT = 1; //Read 1 byte (register address) I2caRegs.I2CMDR.all = 0xEC20; //Generate stop but not start, master receiver, generate NACK while(I2caRegs.I2CSTR.bit.RRDY == 0); // wait for byte xaccel = I2caRegs.I2CDRR<<8; // read upper 8 Bit (integers) //Lower 8 bits (DATAX0 register) I2caRegs.I2CCNT = 2; //Write 1 byte (register address) I2caRegs.I2CDXR = ACCEL_WRITE; //Select higher byte register in sensor I2caRegs.I2CMDR.all = 0x6E20; //Generate start and stop, master transmitter while(I2caRegs.I2CSTR.bit.XRDY == 0); // wait until first byte is out I2caRegs.I2CDXR = DATAX0; //Select higher byte register in sensor while(I2caRegs.I2CSTR.bit.SCD == 0); // wait for STOP condition I2caRegs.I2CSTR.bit.SCD = 1; I2caRegs.I2CCNT = 1; //Write 1 byte (register address) I2caRegs.I2CDXR = ACCEL_READ; //Select higher byte register in sensor I2caRegs.I2CMDR.all = 0x6620; //Generate start but not stop, master transmitter while(I2caRegs.I2CSTR.bit.XRDY == 0); // wait until first byte is out while(I2caRegs.I2CSTR.bit.ARDY == 0); // wait for access ready condition I2caRegs.I2CCNT = 1; //Read 1 byte (register address) I2caRegs.I2CMDR.all = 0xEC20; //Generate stop but not start, master receiver, generate NACK while(I2caRegs.I2CSTR.bit.RRDY == 0); // wait for byte xaccel += I2caRegs.I2CDRR; // read lower 8 Bit (integers) EALLOW; SysCtrlRegs.WDKEY = 0xAA; // service WD #2 EDIS; } 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 I2caRegs.I2CSAR = ACCEL; //Select write address for sensor // 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 = 15 [ICCL + ICCH + 10] / 150 MHz // d = 5 for IPSC >1 // for I2C 50 kHz: // Tmaster = 20 µs * 150 MHz / 15 = 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 / 15 = 100 = (ICCL + ICCH + 10) // ICCL + ICCH = 90 // ICCL = ICH = 90/2 = 45 I2caRegs.I2CMDR.bit.IRS = 1; // Take I2C out of reset } //=========================================================================== // End of SourceCode. //===========================================================================