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.

TM4C123GH6PM: I2C Slave Mode, and SSI1 interference.

Part Number: TM4C123GH6PM

Hello,

I am using I2C slave mode on the TM4C123GH6PM, so an I2C master (a raspberry pi) can access an array of 32bytes, that is constantly calculated.

I noticed sometimes, that my slave devices returns all 255's. (an array of 32, containing all 255s)

I am using a number of timers, one of them updating at 10hz, the other 100hz, and a final led timer that updates at 2 to  5hz.

Not being able to debug the issue, I have started commenting out, different timers that I use, trying to find what causes it.

I finally found that it is the timer that I use for firing serial LED's, over SSI1. Namely:

I initialize with:

    // initialize led driver
    MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
    MAP_GPIOPinConfigure(GPIO_PF2_SSI1CLK);
    MAP_GPIOPinConfigure(GPIO_PF1_SSI1TX);
    MAP_GPIOPinTypeSSI(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2);
    MAP_SSIConfigSetExpClk(SSI1_BASE, ui32SysClkFreq, SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 2400000, 8);
    MAP_SSIEnable(SSI1_BASE);

And the timer fires up the part: (15 times in a row)

#define SPILONG    0xE0
#define SPISHORT   0x40

void send_byte(unsigned char b) {
    unsigned char bit;
    for(bit = 0; bit < 8; bit++) {
        if(b & 0x80) { MAP_SSIDataPut(SSI1_BASE, SPILONG); } else { MAP_SSIDataPut(SSI1_BASE, SPISHORT); }
        b <<= 1;
    }
}

Also, after calling the SSIDataPut(SS!_BASE, byte), to send the bytes I call:

while(MAP_SSIBusy(SSI1_BASE)) {}

So I have experimentally determined that, when the MAP_SSIDataPut(SSI1_BASE, SPILONG) is running, and if the tm4c123 slave device receives a read request, it will return all 255's.

I even changed the part I2CSlaveDataPut(I2C0_BASE, buffer[index++]) to I2CSlaveDataPut(I2C0_BASE, 1); - but when ever the 2 interrupts collide i2c slave device returns wrong data.

I

s there any way around this, or any reasons to why it is causing? They are different devices, I2C and SSI on the microcontroller, and even ports are different, so why could this be?

Best Regards,

Can A.

  • Hello Can,

    It's a bit hard to say for sure and you may want to look at the SPI and I2C bus lines during this clash with a logic analyzer to see what exactly is going on but I think perhaps what could be happening is that when your SPI is outputting data and the I2C slave receives a read request, it is ACK'ing the request and so the Master Module drives the I2C clock to receive the bytes and the slave would not drive the SDA line. But I would think the Master in that case would see an erroneous frame. So without seeing what is happening on the actual lines I don't think I can give a definitive answer.

    If that were the case however, then I think what we just reviewed before may be able to resolve this situation by making the I2C slave NACK anything received during SPI transmissions. Or alternatively, see if you can set the I2C interrupt to be a higher priority and monitor if the SSI bus is impacted by that.

    Those are my first thoughts but if you could get a capture of the four SPI lines & two I2C lines at the same time when this issue occurs, then I think that would allow us to better understand what is really going on.

    Best Regards,

    Ralph Jacobi

  • Hello, I will capture this data tomorrow if all else fails.

    However I noticed one thing: I am using a timer and within this timer interrupt I am driving the SSI. So moving the SSI data put out of the interrupt handler might help. This is one problem, being able to send NACK's is another, which I am looking at now.

    Thank you for your help, I will be posting more tomorrow.