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.

Compiler/TM4C123GH6PZ: Issue with I2C Burst data back and forth communication between two Tiva board

Part Number: TM4C123GH6PZ

Tool/software: TI C/C++ Compiler

Hi sir,

 I was facing some issue while communicating between two Tiva board using I2C. What I am doing is sending some burst data from one Tiva board(master) to the other tiva board(slave) back and forth. The master will send some burst data and slave will read and send it back to master and display it using UART.

I am attaching my master and slave code below.

Master Code

#include "stdio.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "hw_memmap.h"
#include "inc/hw_ints.h"
#include "driverlib/pin_map.h"
#include "inc/hw_types.h"
#include "driverlib/interrupt.h"
#include "driverlib/systick.h"
#include "driverlib/timer.h"
#include "inc/hw_nvic.h"
#include "driverlib/timer.c"
#include "driverlib/systick.c"
#include "driverlib/adc.h"
#include "driverlib/debug.h"
#include "driverlib/uart.h"
#include "driverlib/rom.h"
#include "inc/hw_ints.h"
#include "driverlib/ssi.h"
#include "driverlib/i2c.h"
void delay(int a);
volatile uint32_t count=0;//Counter to count the number of interrupts that have been called

#define SLAVE_ADDRESS 0x20

//void InitConsole(void);
unsigned long k=0;
int I2C_SEND_CHAR(void);
void I2C_RECV_CHAR(void);
void InitConsole(void);
uint32_t data_read;
uint32_t n=3,i;
  int main()
  {
  
 // char char_tx[]="abcd",data;
  
  SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_OSC |SYSCTL_XTAL_8MHZ|SYSCTL_OSC_MAIN); //seting system clock as 8Mhz
  //void InitConsole(void);
  // Enable the I2C0 peripheral
  //
  SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
  while(!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C0));
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
  while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB));
  //configure the muxing and GPIO settings to bring the SSI functions out to the pins
  GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
  GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
  GPIOPinConfigure(GPIO_PB2_I2C0SCL);
  GPIOPinConfigure(GPIO_PB3_I2C0SDA);
  I2CMasterEnable(I2C0_BASE);
  //
  //This function initializes operation of the I2C Master block by configuring the bus speed for the
  //master and enabling the I2C Master block.false-100kbps/true-400kbps
  //
  I2CMasterInitExpClk(I2C0_BASE,SysCtlClockGet(),false);
  InitConsole();
  while(1)
  {
  
  I2C_SEND_CHAR();
  I2C_RECV_CHAR(); 
  //put data to be sent into FIFO
 
  
  }
 }  
   
   
int I2C_SEND_CHAR(void)
{
 I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, false);//Send data to the slave
              
 I2CMasterDataPut(I2C0_BASE, 'A');
 I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
// while(!I2CMasterBusBusy(I2C0_BASE));
 while(I2CMasterBusBusy(I2C0_BASE));
 //
    // Check for errors.
    //
    if( I2CMasterErr(I2C0_BASE) != I2C_MASTER_ERR_NONE)
    {
        return 0;
    }
 I2CMasterDataPut(I2C0_BASE, 'Q');
 I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
// while(!I2CMasterBusBusy(I2C0_BASE));
 while(I2CMasterBusBusy(I2C0_BASE));
   //
    // Check for errors.
    //
    if( I2CMasterErr(I2C0_BASE) != I2C_MASTER_ERR_NONE)
    {
        return 0;
    }
 I2CMasterDataPut(I2C0_BASE, 'D');
 I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
// while(!I2CMasterBusBusy(I2C0_BASE));
 while(I2CMasterBusBusy(I2C0_BASE));
  
}
void I2C_RECV_CHAR(void)
{
 data_read = I2CMasterDataGet(I2C0_BASE);
 I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, true);
 for(i=0; i<=n; i++)
 {
 data_read = I2CMasterDataGet(I2C0_BASE);     // data_read declared as ungined int 32 bit before
 I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
 UARTCharPut(UART0_BASE, data_read);
 while(I2CMasterBusBusy(I2C0_BASE));
 }
}
  void InitConsole(void)
 {
   //
// Enable the UART0 module.
//
 SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
  //
// Wait for the UART0 module to be ready.
//
 while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART0));
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
  while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA));
  GPIOPinConfigure(GPIO_PA0_U0RX);
 GPIOPinConfigure(GPIO_PA1_U0TX);
  //UARTClockSourceSet(SYSCTL_PERIPH_UART0,UART_CLOCK_SYSTEM);
 // UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
  GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
 UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,(UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE));
 //UARTCharPut(UART0_BASE, 'J');
 
 }

Slave code

#include "stdio.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "hw_memmap.h"
#include "inc/hw_ints.h"
#include "driverlib/pin_map.h"
#include "inc/hw_types.h"
#include "driverlib/interrupt.h"
#include "driverlib/systick.h"
#include "driverlib/timer.h"
#include "inc/hw_nvic.h"
#include "driverlib/timer.c"
#include "driverlib/systick.c"
#include "driverlib/adc.h"
#include "driverlib/debug.h"
#include "driverlib/uart.h"
#include "driverlib/rom.h"
#include "inc/hw_ints.h"
#include "driverlib/ssi.h"
#include "driverlib/i2c.h"
void delay(int a);
volatile uint32_t count=0;//Counter to count the number of interrupts that have been called
void TimerBegin(void);
uint32_t ui32ADC0Value[1];
float ui32ADCvalue;
#define SLAVE_ADDRESS 0x20

#define DEBUG true
//void InitConsole(void);
unsigned long k=0;
void I2C_SEND_CHAR(void);
void I2C_RECV_CHAR(void);
void InitConsole(void);
uint32_t char_rx;
uint32_t n=3,i;
  int main()
  {
  
  //char char_tx[]="abcd",data;
  
  SysCtlClockSet(SYSCTL_SYSDIV_1|SYSCTL_USE_OSC |SYSCTL_XTAL_8MHZ|SYSCTL_OSC_MAIN); //seting system clock as 8Mhz
  //void InitConsole(void);
  // Enable the I2C0 peripheral
  //
  SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
  while(!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C0));
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
  while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOB));
  //configure the muxing and GPIO settings to bring the SSI functions out to the pins
  GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
  GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);
  GPIOPinConfigure(GPIO_PB2_I2C0SCL);
  GPIOPinConfigure(GPIO_PB3_I2C0SDA);
  I2CMasterEnable(I2C0_BASE);
  //
  //This function initializes operation of the I2C Master block by configuring the bus speed for the
  //master and enabling the I2C Master block.false-100kbps/true-400kbps
  //
  I2CMasterInitExpClk(I2C0_BASE,SysCtlClockGet(),false);
  InitConsole();
  
  while(1)
  {
  
  I2C_RECV_CHAR(); 
  I2C_SEND_CHAR();
   
  }
 }  
   
   
void I2C_SEND_CHAR(void)
{
for(i=0; i<=n; i++)
 {
while(!(I2CSlaveStatus(I2C0_BASE) & I2C_SLAVE_ACT_TREQ));
  I2CSlaveDataPut(I2C0_BASE,char_rx);
  
}
 }
void I2C_RECV_CHAR(void)
{
  SysCtlDelay(1000);

 for(i=0; i<=n; i++)
 {
 while(!(I2CSlaveStatus(I2C0_BASE) & I2C_SLAVE_ACT_RREQ));
  char_rx=I2CSlaveDataGet(I2C0_BASE);
  UARTCharPut(UART0_BASE, char_rx);
}
 }
#if DEBUG
void
InitConsole(void)
{
 //
 // Enable GPIO port A which is used for UART0 pins.
 // TODO: change this to whichever GPIO port you are using.
 //
 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
 //
 // Configure the pin muxing for UART0 functions on port A0 and A1.
 // This step is not necessary if your part does not support pin muxing.
 // TODO: change this to select the port/pin you are using.
 //
 GPIOPinConfigure(GPIO_PA0_U0RX);
 GPIOPinConfigure(GPIO_PA1_U0TX);
 //
 // Enable UART0 so that we can configure the clock.
 //
 SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
 //
 // Use the internal 8MHz oscillator as the UART clock source.
 //
 //UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
 //
 // Select the alternate (UART) function for these pins.
 // TODO: change this to select the port/pin you are using.
 //
 GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
 //
 // Initialize the UART for console I/O.
 //
 UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,(UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE));
}
#endif

Doubt

1. when I am keeping in debug section the program is stoping at the highlighted section in master code. Please let me know why it is happening.

2. I am confused about burst data is the program what I wrote is correct or not for burst data send. If the code is not correct for burst data then please explain how I can do it. 

I am a student  and learning I2C communication. So please help me to solve the issues.

Thank you,

Mariya

  • Hi,
    Sorry I did a mistake in the previous code. Instead of while(I2CMasterBusy(I2C0_BASE)); I put while(I2CMasterBusBusy(I2C0_BASE)); Because of that it is stopped there. Now I changed my code and kept in debug mode and checked now it is sending only first character 'A' after that it is returning to main doing receive function.In the UART terminal I am receiving null characters(ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ).
    Slave code also put in debug mode and the program is stacking at while(!(I2CSlaveStatus(I2C0_BASE) & I2C_SLAVE_ACT_RREQ)); this section.

    Please let me know what will be the issue and how I can resolve it.
    Thank you,
    Mariya
  • Hello Mariya,

    I had seen a similar issue not long ago when working with another customer, and it had gotten resolved with the code I provided on this post: e2e.ti.com/.../2817634

    Can you review what I provided there and work to implement it on your example and see if that resolves your issue?
  • Hi sir,

    I checked my code with the link you provided that is for sending single byte data. I am able to send single byte of data, but the issue is when I am trying to send burst amount of data. I am little bit confused about burst data sending, and I am not sure the way I am following is correct or not for burst data send. Please let me know sir how I can send burst data back and forth.

    Thank  you,

    Mariya

  • Hello Mariya,

    We have a very helpful app note for how to do I2C transactions including burst transactions, I think if you give it a good read through, you'll get all the information you need! The app note link is: www.ti.com/.../spma073.pdf