Other Parts Discussed in Thread: IO-EXPANDER-EVM, TCA9535, TCA6424A
Hello I am using the TM4C123GH6PM on the TIVA C Launchpad TM4C123GXL to interface via I2C with the IO-Expander-EVM, populated with the TCA6242A and TCA9535 chips. I am connecting to the board using jumper wires bringing the 3.3v/GND from the TivaC to the IO-Expander-EVM as the IO-Expander-EVM is meant to interface with the MSP430 Launchpad and the breakout headers/connectors do not allow for using any of the TM4C123GH6PMs GPIO pins with I2C functionality with a stacked connection. My issue is that when I try to send my I2C frame, the ADDRESS BYTE and the DATA BYTE are nacked. I can see this by stepping through my code in CCS and monitoring the I2C1_MCS register in the debug register window. Here is my code and the register window in the CCS debug I am referencing.
#include "TM4C123GH6PM.h"
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <inc/hw_i2c.h>
#include <inc/hw_memmap.h>
#include <inc/hw_types.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>
int main(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
//// Wait for the I2C0 module to be ready.//
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C1)){}
//enable GPIO peripheral that contains I2C
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
// Configure the pin muxing for I2C3 functions on port A6 and A7.
GPIOPinConfigure(GPIO_PA6_I2C1SCL);
GPIOPinConfigure(GPIO_PA7_I2C1SDA);
// Select the I2C function for these pins.
GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);
//// Initialize Master and Slave//
I2CMasterInitExpClk(I2C1_BASE, SysCtlClockGet(), false);
//// Specify slave address//
I2CMasterSlaveAddrSet(I2C1_BASE, 0x23, false);
//// Place the character to be sent in the data register//
I2CMasterDataPut(I2C1_BASE, 0x08);
//// Initiate send of character from Master to Slave//
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND);
while(I2CMasterBusy(I2C1_BASE)){}
return 0;
}
The I2C1_MCS register asserts these bits after this function call has completed:
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND);
I believe my problem is because of noise in the channel. I believe this because of these reasons:
1) I have tried the MSP430 eval. board with the GUI driver and the IO expanders can be controlled, toggling LEDs for verification. Though the MSP430 eval board works with the IO Expander Eval board when they are connected via the breakout headers/connectors, the communication does not work when using the jumper wires. I have verified the pins are connected correctly on all set ups via schematics, layout files and digital multimeter tests. Since there is a known working set up with a shorter signal path vs the jumper wires (6 inches) not working connection, this indicates to me that the difference is a noisy channel which would be the same on both the MSP430/TIVAC when implemented with jumper wires.
2) I have verified the address that is getting NACKED on the TCA6424A through the data sheet and the source code for the MSP430 Eval meant to be used with the GUI IO EXPANDER Eval. executable is supposed to have a value 0x23 when passed as an argument to the address set function.
I've also tried communicating with the TCA9535 on the eval. module and had no success.
Right now because I am getting NACKED on the ADDRESS I am not worried about the rest of the frame as much. But I have tried sending an entire frame and did not have success.
I do not have an available Oscilloscope to verify my noisy channel theory, or bit streams.
I've often seen simple I2C implementations like this with jumper wire. I saw one in one of these ti forums where someone connected to the io Eval. board in question with jumper wires and a RPI. So I believe it is possible.
Is there anything from my description and the code posted that you guys can see as a potential problem that needs ameliorating outside of the poor physical I2C channel?
Is it inadvisable or possible, to handle the noisy channel by detecting the NACK and basically resetting the message and sending again until it isn't NACK'd?
I've been trying to develop error handling code for this program where I detect the AddressNACK and stop the communication and resend the message. Currently I am trying something like this to no success, it seems that both the STOP AND START bits in the I2C_MCS remain enabled no matter what. I checked the bus monitor register and the SCL is not being held low by the slave.
Also there are 4.7k pull up resistors on the i2c eval board for the SDA/SCL lines.
uint32_t ERROR_STATUS = 0x01;
while(ERROR_STATUS|I2CMasterBusy(I2C1_BASE)){
I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND);
if(I2CMasterErr(I2C1_BASE))
{
I2CMasterIntClear(I2C1_BASE);
while (I2CMasterIntStatus(I2C1_BASE, true)){}
I2CMasterControl(I2C1_BASE,I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
}
else
{
ERROR_STATUS ==0x00;
}
}
I used the I2CMasterIntClear() outside of an interrupt handler because I figured on a simple program like this a busy/wait implementation would be easier for me and more sensible then trying to implement an ISR.
Thank you very much for taking the time to help me out here, I appreciate it.

