By BearCat696
#1587
Gday there,  Im looking for help programming the I2C protocol between my dspic and the 10dof sensor.  My problem is that I don't receive any data from the sensor.  I have coded the protocol to what is detailed in the datasheet for the pic chip.  I have verified that the program runs through properly, so my best guess is that either the sensor chip is broken somehow, or Im not using the I2C protocol properly.  Or maybe its a really stupid mistake that's right under my nose haha.  Im hoping somebody can shed some light.

Any help would be appreciated, thanks for taking the time to look through my code.


#include <p33fj64mc802.h>
#include <libpic30.h>

void PORT_init(void);
void I2C_init(void);
void readI2C(void);
void INT_init(void);

unsigned char sensorData = 0x00;

unsigned char gyrAddWrite = 0x68;
unsigned char gyrAddRead  = 0x69;
unsigned char accAddWrite = 0xA6;
unsigned char accAddRead  = 0xA7;
unsigned char magAddWrite = 0x3C;
unsigned char magAddRead  = 0x3D;
unsigned char preAddWrite = 0xEE;
unsigned char preAddRead  = 0xEF;

unsigned char gyrXH = 0x1D;
unsigned char gyrXL = 0x1E;
unsigned char gyrYH = 0x1F;
unsigned char gyrYL = 0x20;
unsigned char gyrZH = 0x21;
unsigned char gyrZL = 0x22;


// INTERRUPT SUB-ROUTINE

void __attribute__ ((interrupt, no_auto_psv)) _MI2C1Interrupt(void)
{
__delay32(1);
}



int main()
{
PORT_init();
__delay32(1);
I2C_init();
__delay32(1);
INT_init();
__delay32(1);

while (1)
{
readI2C();

if ((sensorData & 0x01) == 0x01)
{
__delay32(1);
PORTBbits.RB0 = 1;
__delay32(1);
}
else
{
__delay32(1);
PORTBbits.RB0 = 0;
__delay32(1);
}

__delay32(1);

if ((sensorData & 0x02) == 0x02)
{
__delay32(1);
PORTBbits.RB1 = 1;
__delay32(1);
}
else
{
__delay32(1);
PORTBbits.RB1 = 0;
__delay32(1);
}

__delay32(1);

if ((sensorData & 0x04) == 0x04)
{
__delay32(1);
PORTBbits.RB2 = 1;
__delay32(1);
}
else
{
__delay32(1);
PORTBbits.RB2 = 0;
__delay32(1);
}

__delay32(1);

if ((sensorData & 0x08) == 0x08)
{
__delay32(1);
PORTBbits.RB3 = 1;
__delay32(1);
}
else
{
__delay32(1);
PORTBbits.RB3 = 0;
__delay32(1);
}

__delay32(1);

if ((sensorData & 0x10) == 0x10)
{
__delay32(1);
PORTBbits.RB4 = 1;
__delay32(1);
}
else
{
__delay32(1);
PORTBbits.RB4 = 0;
__delay32(1);
}

__delay32(1);

if ((sensorData & 0x20) == 0x20)
{
__delay32(1);
PORTBbits.RB5 = 1;
__delay32(1);
}
else
{
__delay32(1);
PORTBbits.RB5 = 0;
__delay32(1);
}

__delay32(1);

if ((sensorData & 0x40) == 0x40)
{
__delay32(1);
PORTBbits.RB6 = 1;
__delay32(1);
}
else
{
__delay32(1);
PORTBbits.RB6 = 0;
__delay32(1);
}

__delay32(1);

if ((sensorData & 0x80) == 0x80)
{
__delay32(1);
PORTBbits.RB7 = 1;
__delay32(1);
}
else
{
__delay32(1);
PORTBbits.RB7 = 0;
__delay32(1);
}

__delay32(5000000);
}
}


void PORT_init()
{
ADPCFG = 0XFFFF;
__delay32(1);

TRISBbits.TRISB0 = 0;
__delay32(1);
TRISBbits.TRISB1 = 0; 
__delay32(1);
TRISBbits.TRISB2 = 0; 
__delay32(1);
TRISBbits.TRISB3 = 0;
__delay32(1);
TRISBbits.TRISB4 = 0; 
__delay32(1);
TRISBbits.TRISB5 = 0;
__delay32(1);
TRISBbits.TRISB6 = 0; 
__delay32(1);
TRISBbits.TRISB7 = 0; 
__delay32(1);


PORTBbits.RB0 = 0;
__delay32(1);
PORTBbits.RB1 = 0;
__delay32(1);
PORTBbits.RB2 = 0;
__delay32(1);
PORTBbits.RB3 = 0;
__delay32(1);
PORTBbits.RB4 = 0;
__delay32(1);
PORTBbits.RB5 = 0;
__delay32(1);
PORTBbits.RB6 = 0;
__delay32(1);
PORTBbits.RB7 = 0;
__delay32(1);
}


void INT_init(void)
{
    IEC1bits.MI2C1IE = 1;
    __delay32(1);
    IPC4bits.MI2C1IP = 3;
    __delay32(1);
    IFS1bits.MI2C1IF = 0;
    __delay32(1);
}



void I2C_init(void)
{
I2C1CONbits.I2CEN = 1; // enable the I2C module
__delay32(1);
I2C1CONbits.DISSLW = 1;
__delay32(1);
I2C1BRG = 0X0188; // enable baud rate to 100kHz
__delay32(1);
I2C1CONbits.ACKDT = 1;  // set acknowldge data bit to send NACK
__delay32(1);
}

void readI2C()
{


if (I2C1STATbits.P == 1)
{

// Assert a start condition on SDA1 and SCL1

I2C1CONbits.SEN = 1;

while (!IFS1bits.MI2C1IF);
__delay32(1);
IFS1bits.MI2C1IF = 0;


// Send the I2C device address byte to the slave with a write indication

I2C1TRN = accAddWrite; 

while (!IFS1bits.MI2C1IF);
__delay32(1);
IFS1bits.MI2C1IF = 0;


// Send the serial memory address high byte to the slave

I2C1TRN = 0x00; // register of accel device id , should return 0xE5

while (!IFS1bits.MI2C1IF);
__delay32(1);
IFS1bits.MI2C1IF = 0;


// Assert a repeated Start condition on SDA1 and SCL1

I2C1CONbits.RSEN = 1;

while (!IFS1bits.MI2C1IF);
__delay32(1);
IFS1bits.MI2C1IF = 0;


// Send the device address byte to the slave with a read indication

I2C1TRN = preAddRead;

while (!IFS1bits.MI2C1IF);
__delay32(1);
IFS1bits.MI2C1IF = 0;


// Enable master reception to receive serial memory data

I2C1CONbits.RCEN = 1; // start receiving data

while (!IFS1bits.MI2C1IF);
__delay32(1);
IFS1bits.MI2C1IF = 0;


__delay32(1);
sensorData = I2C1RCV;
__delay32(1);


// Generate an ACK(LOW) or NACK condition at the end of a received byte of data
// ACK(LOW) to receive a second byte a data, or NACK to finish receiving data


I2C1CONbits.ACKEN = 1; // send NACK

while (!IFS1bits.MI2C1IF);
__delay32(1);
IFS1bits.MI2C1IF = 0;


// Generate a Stop condition on SDA1 and SCL1

I2C1CONbits.PEN = 1; // send stop condition

while (!IFS1bits.MI2C1IF);
__delay32(1);
IFS1bits.MI2C1IF = 0;
}
}