This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C I2C Problem



Hello everyone,

I have a problem that i couldn't init the I2C on TM4C. Here is the my code. I guess that i2c send function is ok but I thought that my problem is about to initialize the i2c3_base. I searched on some other codes (examples or other ones) but i couldn't make it true. Help please.


#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#include "inc/hw_i2c.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/gpio.h"
#include "driverlib/i2c.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"


typedef enum I2CResultTypes
{
ACK_RECEIVED,
ACK_ERROR
}I2CResultType;

typedef enum I2CTypes
{
I2C0,
I2C1,
I2C2,
I2C3
}I2CType;

typedef enum I2cRegisters
{
VREG_A = 0x11,
VREG_B,
NVREG_A = 0x21,
NVREG_B,
}I2cRegister;

typedef enum I2cAddresses
{
ADDRESS0 = 0x28,
ADDRESS1 = 0x29,
ADDRESS2 = 0x2A,
ADDRESS3 = 0x2B,
ADDRESS4 = 0x2C,
ADDRESS5 = 0x2D,
ADDRESS6 = 0x2E,
ADDRESS7 = 0x2F
}I2cAddress;

I2CResultType I2C_Send(I2CType i2cPort, unsigned char slaveAddress, unsigned char regAddress, unsigned char data)
{
int result;
I2CMasterIntClear(i2cPort);
I2CMasterSlaveAddrSet(i2cPort, slaveAddress, 0);
I2CMasterDataPut(i2cPort, regAddress);
I2CMasterControl(i2cPort, I2C_MASTER_CMD_BURST_SEND_FINISH);
while (I2CMasterBusy(i2cPort));
result = I2CMasterErr(i2cPort);

if (result != I2C_MASTER_ERR_NONE)
{
return ACK_ERROR;
}
I2CMasterDataPut(i2cPort, data);
I2CMasterControl(i2cPort, I2C_MASTER_CMD_BURST_SEND_FINISH);
while (I2CMasterBusy(i2cPort));
result = I2CMasterErr(i2cPort);

if (result != I2C_MASTER_ERR_NONE)
{
return ACK_ERROR;
}

return ACK_RECEIVED;
}

void MAX5479_SetValue2( unsigned char value)
{
I2CResultType result = ACK_ERROR;
I2CType I2c = I2C3;
I2cAddress address = 0x29;
I2cRegister regAddress =0x11 ;

result = I2C_Send(I2C3, 0x29, 0x11, value);

if (result == ACK_RECEIVED)
{
asm("NOP");
}
else
{
asm("NOP");
}
}

void I2CInit (void)
{


SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3);

SysCtlPeripheralReset(SYSCTL_PERIPH_I2C3);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
//SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOG);


GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_0);
GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_1);


GPIOPinConfigure(GPIO_PG0_I2C3SCL);
GPIOPinConfigure(GPIO_PG1_I2C3SDA);


I2CMasterInitExpClk(I2C3_BASE, SysCtlClockGet(), false);

}

int
main(void)
{
volatile uint32_t ui32Loop;

SysCtlClockSet(SYSCTL_SYSDIV_3 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_25MHZ);
I2CInit();
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);

//
// Check if the peripheral access is enabled.
//
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOK))
{
}
GPIOPinTypeGPIOOutput(GPIO_PORTK_BASE, GPIO_PIN_3);

while(1)
{
MAX5479_SetValue2(20);

}
}

  • There are TWO versions of the TM4C family (123 & 129) and they require different code treatment.
    Editing your "Subject/Title" (TM4C) - to include your actual MCU version (i.e. TM4C123) - will prove to your advantage.

  • Mine is TM4C123.
  • Thank you - appreciated - questions/comments follow:

    Questions:

    halo_rmz said:
    I couldn't init the I2C on TM4C123

    How have you reached that conclusion?     (No support/justification appears.    Is it not possible that "init" proved correct - and (other) issues arose?)

    halo_rmz said:
    I guess that i2c send function is ok

    How do you move (beyond) "guess?"     Have you access to test gear - ideally a scope?     And deployed (more proper) External pull-up resistors?     (MCU's are too high in value to prove robust!)    Proper Diagnostics depends upon/demands, "facts."

    Comments:

    Your code is (spectacularly) inclusive - reveals much understanding & good effort.      Yet - the presentation of, "multi-conditions" and "great flexibility" - as your code displays - may NOT prove "ideal" for "quick & eased" (i.e. uneventful) project success!      The exhaustive, multi-conditional code strays FAR (very far) from "KISS."    (KISS = Simple, Strategic, Highly Focused, ESSENTIALS ONLY - aimed at the creation of, "Easily Measurable, NARROW GOALS!")    

    Such (KISS) offers the "best & shortest" path towards, "Project Success."     The "extent" of your code "invites issues" - and from MULTIPLE SOURCES - greatly complicating any Debug!     Usually - one must (selectively) disable (many) portions of,  "Such exhaustive code" - to have (ANY) chance of  "detecting faults."      Would it not be far simpler - to "START w/a far more limited code base" - get (THAT) working - and (only then) add the (many) extra "bits/pieces?"      Note too - those extra "bits/pieces" do (little) to aid your initial Debug...    

    And - most importantly - w/SO MANY  (camouflaging/intruding)  "Non-Essentials" ...  Where (and How) ...  do you (even) begin?

    Firm/I are "wed" to "KISS" - (from years of experience) I much believe - "KISS"  will, "Speed, Ease & Enhance" your SUCCESS - as well.    

    You note your issue as,  "TM4C  I2C Problem"  -  yet is it not (more) likely - that your issue proves MORE,  "Your "too broad" Method and/or Approach?"

  • Have you checked SCL and SDA with an oscilloscope?
  • cb1_mobile said:
    Have you access to test gear - ideally a scope?     And deployed (more proper) External pull-up resistors?

    Perhaps (reasonably) great minds - do - (sometimes) think alike.     Neglect of pull-ups often derails - yet poster's "off to the races EXCESS" stands out - at least to this reporter...

  • Hello everyone,
    I tried to make it true. And here is my code. I also checked with osciloscope. But there is a problem about slave address. When i send (slave address 0x52) i saw 2xslave_address = 0xA4. I everytime saw that. Where is my problem ? My code is below;

    #include <stdint.h>
    #include <stdbool.h>
    #include <stdarg.h>
    #include "inc/hw_i2c.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_gpio.h"
    #include "driverlib/gpio.h"
    #include "driverlib/i2c.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/uart.h"
    #include "utils/uartstdio.h"

    void I2CInit (void)
    {

    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3);

    //SysCtlPeripheralReset(SYSCTL_PERIPH_I2C3);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
    //SysCtlPeripheralReset(SYSCTL_PERIPH_GPIOG);


    GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_0);
    GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_1);


    GPIOPinConfigure(GPIO_PG0_I2C3SCL);
    GPIOPinConfigure(GPIO_PG1_I2C3SDA);


    I2CMasterInitExpClk(I2C3_BASE, SysCtlClockGet(), false);

    }

    int
    main(void)
    {
    volatile uint32_t ui32Loop, data_byte = 0;
    SysCtlClockSet(SYSCTL_SYSDIV_3 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_25MHZ);
    I2CInit();


    while(1)
    {
    if(data_byte <= 255)
    {

    I2CMasterSlaveAddrSet(I2C3_BASE, 0x52, 0);
    I2CMasterDataPut(I2C3_BASE, 0x13);
    I2CMasterControl(I2C3_BASE,I2C_MASTER_CMD_BURST_SEND_START);
    while(I2CMasterBusy(I2C3_BASE));

    I2CMasterDataPut(I2C3_BASE, data_byte);
    while(I2CMasterBusy(I2C3_BASE));
    I2CMasterControl(I2C3_BASE,I2C_MASTER_CMD_BURST_SEND_FINISH);
    data_byte= data_byte + 10;
    }
    else
    {
    data_byte = 0;
    }
    for(ui32Loop = 0; ui32Loop < 2000000; ui32Loop++)
    {
    }

    }
    }