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.

Handling NACK Errors

Part Number: TM4C123GH6PM
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.

  • Hi Matt,

      Is this your full main()? I don't see you configure the System Clock using SysCtlClockSet(). Please refer to the Tivaware I2C examples under <TivaWare_Installation>/examples/peripherals/i2c. Let me know after you add the SysCtlClockSet(...), does it fix your problem?

  • I'm using the default settings,  so my SysClock is 16MHz( see below). Sorry for the belated update but I think i have found the problem that was causing my address to get NACKd. I am working on fully defining what my assumptions were that led to the issue and defining what the issue was and then I will update the forum once I have fully resolved the issue in order to mark it resolved. Thank you for your suggestion Charles.

  • Hi Matt,

      Let us know your progress on your debug. Other than the System clock which you were correct by default was 16MHz using PIOSC, I don't really spot anything wrong with your code. You also stated you have proper pullup resistors on the SDA and SCL buses. So your hardware seems to be ok too. But to really know what happened and aid your debugging, you really need to have the scope or a logic analyzer.