Hi,
I am learning the I2C module with F28069 and
I use the F28069 as the master to communicate with MPU6050.
Now I have successfully driven the MPU6050 and get correct data with functions that can only write/read one byte.
I tried to write a function that can read multiple bytes but it did't work.
I use the GPIO32 and GPIO33 as the SDA and SCL ports.
Here is my I2C initialization codes:
void I2CA_Init(void) { // Initialize I2C I2caRegs.I2CMDR.all = 0x0000; I2caRegs.I2CSAR = 0; // Slave address I2caRegs.I2CPSC.all = 8; // 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 0010 0100 I2caRegs.I2CIER.bit.AAS = 0; // Addressed as slave interrupt enable bit I2caRegs.I2CIER.bit.SCD = 1; // Stop condition detected interrupt enable bit I2caRegs.I2CIER.bit.XRDY = 1; // Transmit-data-ready interrupt enable bit I2caRegs.I2CIER.bit.XRDY = 1; // Receive-data-ready interrupt enable bit I2caRegs.I2CIER.bit.ARDY = 1; // Register-access-ready interrupt enable bit I2caRegs.I2CIER.bit.NACK = 0; // No-acknowledgment interrupt enable bit I2caRegs.I2CIER.bit.ARBL = 0; // Arbitration-lost interrupt enable bit //I2caRegs.I2CMDR.all = 0x0020; // Take I2C out of reset,Stop I2C when suspended I2caRegs.I2CMDR.bit.NACKMOD = 0; // NACK mode bit I2caRegs.I2CMDR.bit.FREE = 0; // Stop I2C when suspended I2caRegs.I2CMDR.bit.STT = 0; // START condition bit I2caRegs.I2CMDR.bit.STP = 0; // STOP condition bit I2caRegs.I2CMDR.bit.MST = 0; // Slave mode I2caRegs.I2CMDR.bit.TRX = 0; // Receiver mode I2caRegs.I2CMDR.bit.XA = 0; // 7-bit addressing mode I2caRegs.I2CMDR.bit.RM = 0; // Nonrepeat mode I2caRegs.I2CMDR.bit.DLB = 0; // Digital loopback mode is disabled I2caRegs.I2CMDR.bit.IRS = 1; // The I2C module is enabled I2caRegs.I2CMDR.bit.STB = 0; // The I2C module is not in the START byte mode I2caRegs.I2CMDR.bit.FDF = 0; // Free data format mode is disabled I2caRegs.I2CMDR.bit.BC = 0; // 8 bits per data byte // FIFO not used return; }
The writing one byte function:
uint16 I2CA_WriteData(uint16 addr, uint16 reg, uint16 data) { I2caRegs.I2CMDR.bit.IRS = 1; // reset I2C // Make sure I2C is not busy and has stopped while (I2caRegs.I2CSTR.bit.BB == 1); // busy loop I2caRegs.I2CSTR.bit.SCD = 1; // Clear the SCD bit (stop condition bit) while(I2caRegs.I2CMDR.bit.STP == 1); // stop bit loop I2caRegs.I2CSAR = addr; // I2C slave address while (I2caRegs.I2CSTR.bit.BB == 1); // still busy? I2caRegs.I2CCNT = 2; // assume register address = 1 byte, and data is 1 byte //I2caRegs.I2CMDR.all = 0x6E20; // start, stop, no rm, reset i2c 01101110 00100000 I2caRegs.I2CMDR.bit.NACKMOD = 0; // NACK mode bit I2caRegs.I2CMDR.bit.FREE = 1; // Run free I2C when suspended I2caRegs.I2CMDR.bit.STT = 1; // START condition bit I2caRegs.I2CMDR.bit.STP = 1; // STOP condition bit I2caRegs.I2CMDR.bit.MST = 1; // Master mode I2caRegs.I2CMDR.bit.TRX = 1; // Transmitter mode I2caRegs.I2CMDR.bit.XA = 0; // 7-bit addressing mode I2caRegs.I2CMDR.bit.RM = 0; // Nonrepeat mode I2caRegs.I2CMDR.bit.DLB = 0; // Digital loopback mode is disabled I2caRegs.I2CMDR.bit.IRS = 1; // The I2C module is enabled I2caRegs.I2CMDR.bit.STB = 0; // The I2C module is not in the START byte mode I2caRegs.I2CMDR.bit.FDF = 0; // Free data format mode is disabled I2caRegs.I2CMDR.bit.BC = 0; // 8 bits per data byte while(I2caRegs.I2CSTR.bit.XRDY == 0); // Do nothing till bus is free I2caRegs.I2CDXR = reg; // register address of the sensor (1 byte) while(I2caRegs.I2CSTR.bit.XRDY == 0); // Do nothing till bus is free I2caRegs.I2CDXR = data; // data to be sent (1 byte) I2caRegs.I2CMDR.bit.STP = 1; // stop bit when CNT=0 while(!I2caRegs.I2CSTR.bit.SCD); // wait for STOP condition return I2C_SUCCESS; }
The reading one byte function:
uint16 I2CA_ReadData(uint16 addr, uint16 reg) { Uint16 tempdata; I2caRegs.I2CMDR.bit.IRS = 1; // reset I2C // Make sure I2C is not busy and has stopped while (I2caRegs.I2CSTR.bit.BB == 1); // busy loop I2caRegs.I2CSTR.bit.SCD = 1; // Clear the SCD bit (stop condition bit) while(I2caRegs.I2CMDR.bit.STP == 1); // stop bit loop I2caRegs.I2CSAR = addr; // I2C slave address while (I2caRegs.I2CSTR.bit.BB == 1); // still busy? //I2caRegs.I2CMDR.all = 0x2620; // start, no stop bit, master, tx, reset I2C 00100110 I2caRegs.I2CMDR.bit.NACKMOD = 0; // NACK mode bit I2caRegs.I2CMDR.bit.FREE = 0; // Stop I2C when suspended I2caRegs.I2CMDR.bit.STT = 1; // START condition bit I2caRegs.I2CMDR.bit.STP = 0; // STOP condition bit I2caRegs.I2CMDR.bit.MST = 1; // Master mode I2caRegs.I2CMDR.bit.TRX = 1; // Transmitter mode I2caRegs.I2CMDR.bit.XA = 0; // 7-bit addressing mode I2caRegs.I2CMDR.bit.RM = 0; // Nonrepeat mode I2caRegs.I2CMDR.bit.DLB = 0; // Digital loopback mode is disabled I2caRegs.I2CMDR.bit.IRS = 1; // The I2C module is enabled I2caRegs.I2CMDR.bit.STB = 0; // The I2C module is not in the START byte mode I2caRegs.I2CMDR.bit.FDF = 0; // Free data format mode is disabled I2caRegs.I2CMDR.bit.BC = 0; // 8 bits per data byte I2caRegs.I2CCNT = 1; // assume register address is one byte while(I2caRegs.I2CSTR.bit.XRDY == 0); // Do nothing till bus is free I2caRegs.I2CDXR = reg; // register address of the sensor (1 byte) while(!I2caRegs.I2CSTR.bit.ARDY); // all ready? //I2caRegs.I2CMDR.all = 0x2C20; // start, stop bit when CNT =0, master, rx, reset I2C 00101100 I2caRegs.I2CMDR.bit.NACKMOD = 0; // NACK mode bit I2caRegs.I2CMDR.bit.FREE = 0; // Stop I2C when suspended I2caRegs.I2CMDR.bit.STT = 1; // START condition bit I2caRegs.I2CMDR.bit.STP = 1; // STOP condition bit I2caRegs.I2CMDR.bit.MST = 1; // Master mode I2caRegs.I2CMDR.bit.TRX = 0; // Receiver mode I2caRegs.I2CMDR.bit.XA = 0; // 7-bit addressing mode I2caRegs.I2CMDR.bit.RM = 0; // Nonrepeat mode I2caRegs.I2CMDR.bit.DLB = 0; // Digital loopback mode is disabled I2caRegs.I2CMDR.bit.IRS = 1; // The I2C module is enabled I2caRegs.I2CMDR.bit.STB = 0; // The I2C module is not in the START byte mode I2caRegs.I2CMDR.bit.FDF = 0; // Free data format mode is disabled I2caRegs.I2CMDR.bit.BC = 0; // 8 bits per data byte I2caRegs.I2CCNT = 1; // only read one byte data if(I2caRegs.I2CSTR.bit.NACK == 1) { I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT; // 0x0002 } I2caRegs.I2CMDR.bit.STP = 1; // stop bit when CNT=0 while(!I2caRegs.I2CSTR.bit.SCD); // stop bit detected? tempdata = I2caRegs.I2CDRR; // read one byte data return(1); }
The multi-read function I have tried:
uint16 I2CA_ReadDataN(uint16 addr, uint16 reg, uint16 len, uint16 *buf) { uint8 i; I2caRegs.I2CMDR.bit.IRS = 1; // reset I2C // Make sure I2C is not busy and has stopped while (I2caRegs.I2CSTR.bit.BB == 1); // busy loop I2caRegs.I2CSTR.bit.SCD = 1; // Clear the SCD bit (stop condition bit) while(I2caRegs.I2CMDR.bit.STP == 1); // stop bit loop I2caRegs.I2CSAR = addr; // I2C slave address while (I2caRegs.I2CSTR.bit.BB == 1); // still busy? //I2caRegs.I2CMDR.all = 0x2620; // start, no stop bit, master, tx, reset I2C 00100110 I2caRegs.I2CMDR.bit.NACKMOD = 0; // NACK mode bit I2caRegs.I2CMDR.bit.FREE = 0; // Stop I2C when suspended I2caRegs.I2CMDR.bit.STT = 1; // START condition bit I2caRegs.I2CMDR.bit.STP = 0; // STOP condition bit I2caRegs.I2CMDR.bit.MST = 1; // Master mode I2caRegs.I2CMDR.bit.TRX = 1; // Transmitter mode I2caRegs.I2CMDR.bit.XA = 0; // 7-bit addressing mode I2caRegs.I2CMDR.bit.RM = 0; // Nonrepeat mode I2caRegs.I2CMDR.bit.DLB = 0; // Digital loopback mode is disabled I2caRegs.I2CMDR.bit.IRS = 1; // The I2C module is enabled I2caRegs.I2CMDR.bit.STB = 0; // The I2C module is not in the START byte mode I2caRegs.I2CMDR.bit.FDF = 0; // Free data format mode is disabled I2caRegs.I2CMDR.bit.BC = 0; // 8 bits per data byte I2caRegs.I2CCNT = 1; // assume register address is one byte while(I2caRegs.I2CSTR.bit.XRDY == 0); // Do nothing till bus is free I2caRegs.I2CDXR = reg; // register address of the sensor (1 byte) while(!I2caRegs.I2CSTR.bit.ARDY); // all ready? //I2caRegs.I2CMDR.all = 0x2C20; // start, stop bit when CNT =0, master, rx, reset I2C 00101100 I2caRegs.I2CMDR.bit.NACKMOD = 0; // NACK mode bit I2caRegs.I2CMDR.bit.FREE = 0; // Stop I2C when suspended I2caRegs.I2CMDR.bit.STT = 1; // START condition bit I2caRegs.I2CMDR.bit.STP = 1; // STOP condition bit I2caRegs.I2CMDR.bit.MST = 1; // Master mode I2caRegs.I2CMDR.bit.TRX = 0; // Receiver mode I2caRegs.I2CMDR.bit.XA = 0; // 7-bit addressing mode I2caRegs.I2CMDR.bit.RM = 0; // Nonrepeat mode I2caRegs.I2CMDR.bit.DLB = 0; // Digital loopback mode is disabled I2caRegs.I2CMDR.bit.IRS = 1; // The I2C module is enabled I2caRegs.I2CMDR.bit.STB = 0; // The I2C module is not in the START byte mode I2caRegs.I2CMDR.bit.FDF = 0; // Free data format mode is disabled I2caRegs.I2CMDR.bit.BC = 0; // 8 bits per data byte I2caRegs.I2CCNT = len; // only read one byte data // if(I2caRegs.I2CSTR.bit.NACK == 1) // { // I2caRegs.I2CSTR.all = I2C_CLR_NACK_BIT; // 0x0002 // } // I2caRegs.I2CMDR.bit.STP = 1; // stop bit when CNT=0 // // while(!I2caRegs.I2CSTR.bit.SCD); // stop bit detected? for (i = 0; i < len; i++) { while(I2caRegs.I2CSTR.bit.RRDY == 0); // Do nothing till bus is free buf[i] = I2caRegs.I2CDRR; I2caRegs.I2CMDR.all = 0x2C20; } return 1; }
Thanks for your help!
:)
-Di