Hi,
I have been playing with my DK-TM4C129X board and wanted to try the I2C. I used the example provided in TivaWare peripheral folder. It seems it is a common issue in both stellaris and Tiva devices to get this example to work. I have done the following, which is almost identical to the posted example. However, It doesnt seem to receive any ack from the slave and gets stuck in the bolded line. Have there been any solutions to this issue yet?
int
main(void)
{
uint32_t pui32DataTx[NUM_I2C_DATA];
uint32_t pui32DataRx[NUM_I2C_DATA];
uint32_t ui32Index;
//
// 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.
//
ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
SYSCTL_OSC_MAIN |
SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480), 120000000);
//
// The I2C6 peripheral must be enabled before use.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C6);
//
// For this example I2C6 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 I2C6 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_PB6_I2C6SCL);
GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_6);
GPIOPinConfigure(GPIO_PB7_I2C6SDA);
GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_7);
//
// 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_6 | GPIO_PIN_7);
//
// Enable loopback mode. Loopback mode is a built in feature that is
// useful for debugging I2C operations. It internally connects the I2C
// master and slave terminals, which effectively let's you send data as
// a master and receive data as a slave.
// NOTE: For external I2C operation you will need to use external pullups
// that are stronger than the internal pullups. Refer to the datasheet for
// more information.
//
HWREG(I2C6_BASE + I2C_O_MCR) |= I2C_MCR_LPBK;
//
// Enable and initialize the I2C6 master module. Use the system clock for
// the I2C6 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(I2C6_BASE, ui32SysClock, false);
I2CMasterEnable(I2C6_BASE);
//
// Enable the I2C6 slave module. This module is enabled only for testing
// purposes. It does not need to be enabled for proper operation of the
// I2Cx master module.
//
I2CSlaveEnable(I2C6_BASE);
//
// Set the slave address to SLAVE_ADDRESS. In loopback mode, it's an
// arbitrary 7-bit number (set in a macro above) that is sent to the
// I2CMasterSlaveAddrSet function.
//
I2CSlaveInit(I2C6_BASE, SLAVE_ADDRESS);
I2CMasterSlaveAddrSet(I2C6_BASE, SLAVE_ADDRESS, false);
InitConsole();
UARTprintf("I2C Loopback Example ->");
UARTprintf("\n Module = I2C6");
UARTprintf("\n Mode = Single Send/Receive");
UARTprintf("\n Rate = 100kbps\n\n");
pui32DataTx[0] = 'I';
pui32DataTx[1] = '2';
pui32DataTx[2] = 'C';
for(ui32Index = 0; ui32Index < NUM_I2C_DATA; ui32Index++)
{
pui32DataRx[ui32Index] = 0;
}
UARTprintf("Tranferring from: Master -> Slave\n");
for(ui32Index = 0; ui32Index < NUM_I2C_DATA; ui32Index++)
{
//
// Display the data that the I2C6 master is transferring.
//
UARTprintf(" Sending: '%c' . . . ", pui32DataTx[ui32Index]);
I2CMasterDataPut(I2C6_BASE, pui32DataTx[ui32Index]);
I2CMasterControl(I2C6_BASE, I2C_MASTER_CMD_SINGLE_SEND);
while(!(I2CSlaveStatus(I2C6_BASE) & I2C_SLAVE_ACT_RREQ))
{
}
pui32DataRx[ui32Index] = I2CSlaveDataGet(I2C6_BASE);
while(I2CMasterBusy(I2C6_BASE))
{
}
//
// Display the data that the slave has received.
//
UARTprintf("Received: '%c'\n", pui32DataRx[ui32Index]);
}
//
// Reset receive buffer.
//
for(ui32Index = 0; ui32Index < NUM_I2C_DATA; ui32Index++)
{
pui32DataRx[ui32Index] = 0;
}
//
// Indicate the direction of the data.
//
UARTprintf("\n\nTranferring from: Slave -> Master\n");
I2CMasterSlaveAddrSet(I2C6_BASE, SLAVE_ADDRESS, true);
//
// Do a dummy receive to make sure you don't get junk on the first receive.
//
I2CMasterControl(I2C6_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
while(!(I2CSlaveStatus(I2C6_BASE) & I2C_SLAVE_ACT_TREQ))
{
}
for(ui32Index = 0; ui32Index < NUM_I2C_DATA; ui32Index++)
{
//
// Display the data that I2C6 slave module is transferring.
//
UARTprintf(" Sending: '%c' . . . ", pui32DataTx[ui32Index]);
//
// Place the data to be sent in the data register
//
I2CSlaveDataPut(I2C6_BASE, pui32DataTx[ui32Index]);
//
// Tell the master to read data.
//
I2CMasterControl(I2C6_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE);
//
// Wait until the slave is done sending data.
//
while(!(I2CSlaveStatus(I2C6_BASE) & I2C_SLAVE_ACT_TREQ))
{
}
//
// Read the data from the master.
//
pui32DataRx[ui32Index] = I2CMasterDataGet(I2C6_BASE);
//
// Display the data that the slave has received.
//
UARTprintf("Received: '%c'\n", pui32DataRx[ui32Index]);
}
//
// Tell the user that the test is done.
//
UARTprintf("\nDone.\n\n");
//
// Return no errors
//
return(0);
}