This is the code for the TM4C1294NCPDT I have, it's made for the current sensor INA226 that works with I2C, and I can't make it work,
the current variable is always in zero and I measured the signals in an oscilloscope and can't find why it's running at 400 kbps instead of 100 kbps.
#include <stdarg.h> #include <stdbool.h> #include <stdint.h> #include "inc/hw_i2c.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_gpio.h" #include "driverlib/i2c.h" #include "driverlib/sysctl.h" #include "driverlib/gpio.h" #include "driverlib/pin_map.h" #include "inc/tm4c1294ncpdt.h" #define ConfigReg 0x00 #define ShuntVolt 0x01 #define BusVolt 0x02 #define PowerReg 0x03 #define CurrentReg 0x04 #define CalReg 0x05 #define MaskEReg 0x06 #define AlertLReg 0x07 #define Med1ADDR_R 0x80>>1 //Slave Address #define MaxC 10 #define RShunt 1e-3 float Shunt,Bus,Power,Current; void InitI2C0(void) { //enable I2C module 0 SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0); //reset module SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0); //enable GPIO peripheral that contains I2C 0 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); // Configure the pin muxing for I2C0 functions on port B2 and B3. GPIOPinConfigure(GPIO_PB2_I2C0SCL); GPIOPinConfigure(GPIO_PB3_I2C0SDA); // Select the I2C function for these pins. GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2); GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3); //I2CSlaveEnable(I2C0_BASE); //I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, false); // Enable and initialize the I2C0 master module. Use the system clock for // the I2C0 module. The last parameter sets the I2C data transfer rate. // If false the data rate is set to 100kbps and if true the data rate will // be set to 400kbps. I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false); //clear I2C FIFOs HWREG(I2C0_BASE + I2C_O_FIFOCTL) = 80008000; } //sends an I2C command to the specified slave void I2CSend(uint8_t slave_addr, uint8_t num_of_args, ...){ uint8_t i; // Tell the master module what address it will place on the bus when // communicating with the slave. I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, false); //stores list of variable number of arguments va_list vargs; //specifies the va_list to "open" and the last fixed argument //so vargs knows where to start looking va_start(vargs, num_of_args); //put data to be sent into FIFO I2CMasterDataPut(I2C0_BASE, va_arg(vargs, uint32_t)); //if there is only one argument, we only need to use the single send I2C function if(num_of_args == 1) { //Initiate send of data from the MCU I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND); // Wait until MCU is done transferring. while(I2CMasterBusy(I2C0_BASE)); //"close" variable argument list va_end(vargs); } //otherwise, we start transmission of multiple bytes on the I2C bus else{ //Initiate send of data from the MCU I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START); // Wait until MCU is done transferring. while(I2CMasterBusy(I2C0_BASE)); //send num_of_args-2 pieces of data, using the //BURST_SEND_CONT command of the I2C module for(i = 1; i < (num_of_args - 1); i++) { //put next piece of data into I2C FIFO I2CMasterDataPut(I2C0_BASE, va_arg(vargs, uint32_t)); //send next data that was just placed into FIFO I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT); // Wait until MCU is done transferring. while (I2CMasterBusy(I2C0_BASE)); } //put last piece of data into I2C FIFO I2CMasterDataPut(I2C0_BASE, va_arg(vargs, uint32_t)); //send next data that was just placed into FIFO I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH); // Wait until MCU is done transferring. while(I2CMasterBusy(I2C0_BASE)); //"close" variable args list va_end(vargs); } I2CMasterSlaveAddrSet(I2C0_BASE, slave_addr, true); //specify data to be written to the above mentioned device_register I2CMasterDataPut(I2C0_BASE, va_arg(vargs, uint32_t)); //wait while checking for MCU to complete the transaction I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH); //wait for MCU & device to complete transaction while(I2CMasterBusy(I2C0_BASE)); } uint8_t readI2C0(uint16_t device_address, uint16_t device_register) { //specify that we want to communicate to device address with an intended write to bus I2CMasterSlaveAddrSet(I2C0_BASE, device_address, false); //the register to be read I2CMasterDataPut(I2C0_BASE, device_register); //send control byte and register address byte to slave device I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND); //wait for MCU to complete send transaction while(I2CMasterBusy(I2C0_BASE)); //read from the specified slave device I2CMasterSlaveAddrSet(I2C0_BASE, device_address, true); //send control byte and read from the register from the MCU I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE); //wait while checking for MCU to complete the transaction while(I2CMasterBusy(I2C0_BASE)); //Get the data from the MCU register and return to caller return( I2CMasterDataGet(I2C0_BASE)); } int CAL; float CLSB,PLSB;//Current Least Significant Bit void Calibration(float CLSB){ CAL=(int) (0.00512/(CLSB*RShunt)); I2CSend(Med1ADDR_W, 3,CalReg, CAL/256,CAL%256); } int main(void){ // Set the clocking to run directly from the external crystal/oscillator. SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_OSC_INT | SYSCTL_XTAL_16MHZ); // initialize I2C module 0 InitI2C0(); I2CSend(Med1ADDR_R, 3,ConfigReg, 0x41, 0x27);//Reset CLSB=MaxC/32768.;//2^15=32768 PLSB=CLSB*25; Calibration(CLSB);//Max Current=1 A, Shunt=1 mOhm while(1){ Shunt=readI2C0(Med1ADDR_R, ShuntVolt); Bus=readI2C0(Med1ADDR_R, BusVolt)*1.25E-3; Power=readI2C0(Med1ADDR_R, ShuntVolt)*PLSB; Current=readI2C0(Med1ADDR_R, CurrentReg)*CLSB; }; }