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.

I2C communication problem on TM4C123G launchpad

Other Parts Discussed in Thread: ENERGIA, BQ76920

Hello All,

I am trying to write some data on EEPROM using I2C. For this i am using i2c0 (pb2, pb3 pins).

i am using Energia IDE and  written below code. 

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

#define address 0x50

void setup()
{
  // put your setup code here, to run once:
  SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC |   SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
  GPIOPinConfigure(/*GPIO_PB2_I2C0SCL*/0x00010803);
  GPIOPinConfigure(/*GPIO_PB3_I2C0SDA*/0x00010C03);

  GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
  GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
  
  I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);
  
   I2CMasterSlaveAddrSet(I2C0_BASE,address, false);
   
   while(I2CMasterBusBusy(I2C0_BASE) != false)
  {
    ;
  }
  I2CMasterDataPut(I2C0_BASE, 0x400);
  I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
  while(I2CMasterBusBusy(I2C0_BASE) != false)
  {
    ;
  }
  if(I2CMasterErr(I2C0_BASE) == I2C_MASTER_ERR_NONE)
  {
     I2CMasterDataPut(I2C0_BASE, 'B');
     I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
     while(I2CMasterBusBusy(I2C0_BASE) != false)
     {
        ;
     }
     I2CMasterDataPut(I2C0_BASE, 'I');
     I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
  }
  else
  {
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
  }
}

void loop()
{
  // put your main code here, to run repeatedly:

  
}

But problem is that nothing is appering on I2C SCL line.  i mean SCL line always stay HIGH, i am watching SCL line using oscilloscope.

As far As i know when we start data transmission  SCL line stay low until data transmission stops(correct me if i am wrong).

so, kindly suggest how can i solve this issue.

 

  • Hi Bijendra,

    That the SCL line stays high would suggest you have pull-up resistors installed on the I2C bus - but please confirm this is the case. Also, the first thing you should do if you suspect pin malfunctioning is to turn that pin to a regular GPIO and toggle it "manually" - verifying operation with your scope. Or, it might be that your code actually never gets to the first I2CMasterControl line - have you checked with the debugger?

    Also, a couple of notes:

    1. The parameters for GPIOPinConfigure - you have the macro names commented out and replaced with values - why? The macro names should be just fine. If the compiler complains they're undefined, you need to ensure pin_map.h is correctly included
    2. Your first call to I2CMasterDataPut - you give 0x400 as the value. I assume your intention is to send the two-byte EEPROM memory address there. Do understand that (if the code worked) what would get sent would be 0x00 only - you need two subsequent calls, one with 0x00 and one with 0x04. Check the EEPROM datasheet for the proper order of those bytes.

    Regards,

    Veikko

  • Hi Veikko,

    thanks for quick reply,

    Also, the first thing you should do if you suspect pin malfunctioning is to turn that pin to a regular GPIO and toggle it "manually" - verifying operation with your scope. Or, it might be that your code actually never gets to the first I2CMasterControl line - have you checked with the debugger?

    GPIO pin is toggling properly and tested with Scope.

    it might be that your code actually never gets to the first I2CMasterControl line - have you checked with the debugger?

     I haven't tested it because Energia IDE don't have any debugger. is there any other way to test it?

     The parameters for GPIOPinConfigure - you have the macro names commented out and replaced with values - why? The macro names should be just fine. If the compiler complains they're undefined, you need to ensure pin_map.h is correctly included

    i already included pin_map.h but still i got same error. so instead of solving it, i simply tried replace macro name with macro value  to get work done.

    Your first call to I2CMasterDataPut - you give 0x400 as the value. I assume your intention is to send the two-byte EEPROM memory address there. Do understand that (if the code worked) what would get sent would be 0x00 only - you need two subsequent calls, one with 0x00 and one with 0x04. Check the EEPROM datasheet for the proper order of those bytes.

    thank you for pointing this.

    But still problem is same, nothing on i2c scl line bus never goes low.

  • Bijendra Singh said:

    it might be that your code actually never gets to the first I2CMasterControl line - have you checked with the debugger?

     I haven't tested it because Energia IDE don't have any debugger. is there any other way to test it?

    You could switch on the onboard LED's - one colour just before the call, another just after, for example.


    Bijendra Singh said:

    you need to ensure pin_map.h is correctly included

    i already included pin_map.h but still i got same error. so instead of solving it, i simply tried replace macro name with macro value  to get work done.

    I would suggest you stop work until you've resolved this - things like this usually mean there's something more fundamental wrong with your project and can cause unexpected, nasty side effects. Always ensure a stable foundation before you start laying bricks on top! I have not worked on Energia so I can't unfortunately guide you there.

  • i2c scl line bus never goes low.
  • sorry for just above post.. it is cross posted.
    i will first solve pin_map.h problem.
    is there any problem in code ?
  • Bijendra Singh said:
    is there any problem in code ?

    Not anything that I spot outright - but I didn't compare to a known-good code, and it's been a while since I've last fiddled with plain I2C. A good suggestion would be to look at the I2C examples included in the TivaWare package.

  • Hello Bijendra,
    here is the code I use to configure two I2Cs, I hope it helps. I am using two I2C ports one to a master Tiva and one to the BQ.

    void initI2C0(void)
    {
    //enable I2C module
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
    //reset I2C module
    SysCtlPeripheralReset(SYSCTL_PERIPH_I2C0);
    //enable GPIO peripheral that contains I2C , done in Main see below
    // Configure the pin muxing for I2C0 functions on port B2 and B3.
    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);
    // SDA open drail
    GPIOPadConfigSet(GPIO_PORTB_BASE, GPIO_PIN_3, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_OD);
    // Select the I2C function for these pins.
    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
    // Enable and initialize the I2C0 master module. Use the system clock for
    // the I2C0 module.
    I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);

    // init second I2C to BQ76920 ============
    //
    // Enable Peripheral Clocks
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    // SDA open drail
    GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_7, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_OD);
    //
    // Enable pin PA7 for I2C1 I2C1SDA
    //
    GPIOPinConfigure(GPIO_PA7_I2C1SDA);
    GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);

    //
    // Enable pin PA6 for I2C1 I2C1SCL
    //
    GPIOPinConfigure(GPIO_PA6_I2C1SCL);
    GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);

    I2CMasterInitExpClk(I2C1_BASE, SysCtlClockGet(), false);
    }
    //===================================




    In the main code: make sure your GPIOs are enabled, I use A, B,C,D,E and F, you may not need all of these.

    // Enable Peripheral Clocks

    //SysCtlPeripheralEnable(SYSCTL_PERIPH_UART6);
    //SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
    //SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    // call init to init the I2C
    initI2C0(); // the I2C0 module.

    // read and write to the slave
    etc...
  • Hello Bijendra

    The issue could be the fact that you are using I2CMasterBusBusy for polling instead of I2CMasterBusy when sending the I2C Commands.

    Regards
    Amit
  • thank you.

    little bit of success achieved.

    but current is problem is that i2c scl and  line is keeping low.

    kindly suggest how can i solve this.

    below is current code.

    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_gpio.h"
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    //#include "driverlib/pin_map.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pwm.h"
    #include "driverlib/i2c.h"
    #include "driverlib/uart.h"
    
    #define address 0x50
    
    void sendDataTOPC(unsigned int qeiposition);
    void delay(unsigned int ms)
    {
    	SysCtlDelay( (SysCtlClockGet()/(3*1000))*ms ) ;
    }
    
    
    int main(void)
    {
      //pinMode(30, OUTPUT);
      //delay(200);
      // put your setup code here, to run once:
      SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC |   SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
      SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
      delay(10);
        SysCtlPeripheralEnable(SYSCTL_PERIPH_UART7/*SYSCTL_PERIPH_UART0*/); // Enable UART hardware
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE/*SYSCTL_PERIPH_GPIOA*/); // Enable Pin hardware
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD); // Enable Pin hardware
    
      GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
      GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
    
      GPIOPinConfigure(/*GPIO_PB2_I2C0SCL*/0x00010803);
      GPIOPinConfigure(/*GPIO_PB3_I2C0SDA*/0x00010C03);
    
      GPIOPinConfigure(0x00040001/*GPIO_PC4_U4RX*/);
      GPIOPinConfigure(0x00040401/*GPIO_PC4_U4TX*/);
    
      GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_3);
      GPIOPinWrite(GPIO_PORTD_BASE,GPIO_PIN_3,0);
    
    
       GPIOPinTypeUART(GPIO_PORTE_BASE, GPIO_PIN_0 | GPIO_PIN_1); // Set Pins for UART
    
      UARTConfigSetExpClk(UART7_BASE, SysCtlClockGet(), 115200, // Configure UART to 8N1 at 115200bps
      (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
    
      //GPIOPadConfigSet(GPIO_PORTB_BASE,GPIO_PIN_2,0x00000001,0x0000000A);
    
    
      //GPIOPadConfigGet(GPIO_PORTB_BASE, GPIO_PIN_2, &pui32Strength, &pui32PinType);
      UARTCharPut(UART7_BASE, 'E');
      //sendDataTOPC(pui32Strength);
      //sendDataTOPC(pui32PinType);
     GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
     GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
    
      I2CMasterInitExpClk(I2C0_BASE, 16000000, false);
      I2CMasterEnable(I2C0_BASE);
       I2CMasterSlaveAddrSet(I2C0_BASE, address, false);
       //I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
    
    //   while(I2CMasterBusy(I2C0_BASE) != false)
    //  {
    // //   digitalWrite(30, HIGH);
    // //   delay(500);
    // //   digitalWrite(30, LOW);
    //  }
    
      I2CMasterDataPut(I2C0_BASE, 0x30);
     // I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);
    
      while(I2CMasterBusy(I2C0_BASE))
      {
      }
      I2CMasterDataPut(I2C0_BASE, 'B');
      I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
      if(I2CMasterErr(I2C0_BASE) == I2C_MASTER_ERR_NONE)
      {
         I2CMasterDataPut(I2C0_BASE, 'B');
         I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
         while(I2CMasterBusy(I2C0_BASE))
                {
                }
         I2CMasterDataPut(I2C0_BASE, 'I');
         I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
      }
      else
      {
        I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
      }
      return 0;
    }
    

  • Hello Bijendra,

    1. Are there Pull Up on the SCL and SDA external to chip?
    2. The Start Command for I2C frame is missing.
    3. Can you add SysCtlPeripheralReset before enabling the peripheral to ensure that there are no stale states during debug rerun's.

    Regards
    Amit
  • I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);

     is uncommented in the code,  and at the place of

    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);

    i again replaces it with

    I2CMasterControl(I2C0_BASE,I2C_MASTER_CMD_BURST_SEND_CONT); 

    but still no success. i am clueless now....

  • Hello Bijendra,

    Did you check my other recommendations? Also it is time to bring in a scope and LA to see what is happening on the SCL and SDA when the device is in IIdle state and when it processing a command.

    Regards
    Amit
  • Can you check if the line 

    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP)
    is being executed.

    I have had problems with this command and replaced it with BURST_SEND_FINISH
    The ERROR_STOP caused both lines to go low I believe it was the slave that held the lines low.

    Good luck
    Claude
  • Hello Claude,

    Poster has yet not clarified a lot of details required. Also the code post seems to be different from the code being executed... In this variable environment we are lagging.

    Regards
    Amit