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 Code stucks in master busy while loop

Other Parts Discussed in Thread: TM4C123GH6PM

Hi all,

I am writing a code to interface TM4C123GH6PM with RTC (PCF8563) over I2C. I have written a sample code for testing, to write to RTC registers and read back from them. When i execute the code it gets stuck in while loop (while(I2CMasterBusy(I2C0_BASE))) forever. I am using Tiva C series launch pad board and CCS 5.5.0 for development. Any help or suggestion would be appreciated. 

I have one more querry, do we really need to use this ( GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);) line in the code.

Code is below :

#define NUM_I2C_DATA 8
#define SLAVE_ADDRESS 0x51
#define SLAVE_ADDRESS 0x51

#define TIME_REGISTER_START_ADDR 0x02

#define SECONDS 0x01
#define MINUTES 0x50
#define HOURS 0x21
#define DAYS 0x21
#define WEEKDAYS 0x02
#define C_MONTHS 0x01
#define YEARS 0x14

int main()
{
uint32_t pui32DataTx[NUM_I2C_DATA];
uint32_t pui32DataRx[NUM_I2C_DATA];
uint32_t ui32Index;

//
// Initialize the receive buffer to NULL.
//
for(ui32Index = 0; ui32Index < NUM_I2C_DATA; ui32Index++)
{
pui32DataRx[ui32Index] = 0;
}

// Write TIME Registers data into RTC

//
// Set the clocking to run directly from the external crystal/oscillator.
// TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
// crystal on your board.
//
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
SYSCTL_XTAL_16MHZ);

//
// The I2C0 peripheral must be enabled before use.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);

//
// For this example I2C0 is used with PortB[3:2]. The actual port and
// pins used may be different on your part, consult the data sheet for
// more information. GPIO port B needs to be enabled so these pins can
// be used.
// TODO: change this to whichever GPIO port you are using.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

//
// Configure the pin muxing for I2C0 functions on port B2 and B3.
// 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_PB2_I2C0SCL);
GPIOPinConfigure(GPIO_PB3_I2C0SDA);


//I2CMasterEnable(GPIO_PORTB_BASE);
GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);

//
// Select the I2C function for these pins. This function will also
// configure the GPIO pins pins for I2C operation, setting them to
// open-drain operation with weak pull-ups. Consult the data sheet
// to see which functions are allocated per pin.
// TODO: change this to select the port/pin you are using.
//
GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);

//
// 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. For this example we will use a data rate of 100kbps.
//
I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);

//
// Tell the master module what address it will place on the bus when
// communicating with the slave. Set the address to SLAVE_ADDRESS
// (as set in the slave module). The receive parameter is set to false
// which indicates the I2C Master is initiating a writes to the slave. If
// true, that would indicate that the I2C Master is initiating reads from
// the slave.
//
//I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, false);
I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, false);


//
// Initalize the data to send.
//
pui32DataTx[0] = TIME_REGISTER_START_ADDR;
pui32DataTx[1] = SECONDS;
pui32DataTx[2] = MINUTES;
pui32DataTx[3] = HOURS;
pui32DataTx[4] = DAYS;
pui32DataTx[5] = WEEKDAYS;
pui32DataTx[5] = C_MONTHS;
pui32DataTx[6] = YEARS;

#if 1
//
// Send pieces of I2C data from the master to the slave.
//
for(ui32Index = 0; ui32Index < NUM_I2C_DATA; ui32Index++)
{
//
// Place the data to be sent in the data register
//
I2CMasterDataPut(I2C0_BASE, pui32DataTx[ui32Index]);

//
// Initiate send of data from the master. Since the loopback
// mode is enabled, the master and slave units are connected
// allowing us to receive the same data that we sent out.
//
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);

//
// Wait until master module is done transferring.
//
while(I2CMasterBusy(I2C0_BASE))
{
}

}
#endif


//
// Read TIME Registers data from RTC
//

//
// Modifiy the data direction to true, so that seeing the address will
// indicate that the I2C Master is initiating a read from the slave.
//
I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, true);


for(ui32Index = 0; ui32Index < NUM_I2C_DATA; ui32Index++)
{
//
// Tell the master to read data.
//
I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);

//
// Read the data from the master.
//
pui32DataRx[ui32Index] = I2CMasterDataGet(I2C0_BASE);
}

return (0);
}

Thanks & Regards