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.

CC3235MODSF: cc3235 - i2c slave - no TX_FIFO_EMPTY IRQ happens when flag is set.

Part Number: CC3235MODSF

I'm trying to use the CC3235 as an I2C slave and fill up my TX FIFO (attached to the slave module) with 4 bytes (0x1,0x2,0x3,0x4).
Proceedure:

- disable the TX FIFO EMPTY IRQ,

- Flush the TX FIFO, 

- clear the IRQ

- fill up the TX FIFO with 4 bytes

- enable TX FIFO EMPTY IRQ

- signal to master (GPIO) that I have bytes to send (readout from CC3235 on I2c).

On logic analyzer I see that bytes 0x1,0x2,0x3,0x4 are shifted out and 0x4 is "NACK"-ed.

Afterwards. I see no interrupts whatsoever.

I2CSRIS shows 0x00000027 -> TXRIS | STOPRIS  | STARTRIS | DATARIS

FIFOSTATUS shows 0x00010005 -> TXBLWTRIG | TXFE

Any idea how that could happen that FIFOSTATUS shows TxFifoEmpty but I have no I2CSRIS TFFEIC? (Note that I do not clear anywhere else this flag, neither I get an interrupt).

  • Just to avoid any SIMR related answers: of course I2CSIMR = 0x000000C0 (TXFEIM | RXIM)

  • Could it be that FIFO EMPTY IRQ is not generated properly when 4 bytes are added to the FIFO and 4 bytes are transmitted with a STOPRIS?

    When I add only 3 bytes to the FIFO and master tries to fetch 4 bytes I get the FIFO EMPTY IRQ.

  • Hi,

    There is a note in the description of TXFERIS in the register map of I2CSRIS that indicates "Note that if the TXFERIS interrupt is cleared (by setting the TXFEIC bit) when the TX FIFO is empty, the TXFERIS interrupt does not reassert even though the TX FIFO remains empty in this situation." Perhaps that might be a reason why you are observing this issue.

    As for the thought that 4 bytes causes the IRQ to not function correctly, do you see the same behavior if you provide 3 bytes into the FIFO but the master only reads 3 bytes (and not 4) from the CC3235?

    Regards,
    Michael

  • "Note that if the TXFERIS interrupt is cleared (by setting the TXFEIC bit) when the TX FIFO is empty, the TXFERIS interrupt does not reassert even though the TX FIFO remains empty in this situation." 

    This to me means: When the FIFO gets emptied the bit is SET and an interrupt should assert. When YOU CLEAR it it will be  not be reasserted. This means I need to clear it first. But I do not clear it.

    Why would be the 3 byte case different than the 4 byte case? HW FIFO is 8 byte deep.

    Has anyone tested the integration of the Slave I2C silicon module to the CC3235 M4 core? Could someone from TI send a piece of code/initialization sequence that works?

  • Hi,

    I have not tested out the I2C slave feature on the CC3235, but I can work on developing an init sequence for i2c slave. This might take a while, as there doesn't exist any internal TI code of using the CC32xx I2C peripheral in slave mode. This will probably take a few days to a week to complete, and I'll update you on the status of my work.

    On another note, what is the impetus behind needing i2c slave functionality? As I2C is often used by MCUs to control simple devices, needing an MCU to function as a slave to a different MCU is typically not done as interfaces such as SPI and UART are more often used.

    Regards,
    Michael

  •     /*
         *  Take I2C hardware semaphore to prevent NWP from accessing I2C.
         *
         *  This is done in initHw() instead of postNotify(), so the
         *  hardware sempahore is also taken during open().
         */
        ulRegVal = HWREG(COMMON_REG_BASE + COMMON_REG_O_I2C_Properties_Register);
        ulRegVal = (ulRegVal & ~0x3) | 0x1;
        HWREG(0x400F7000) = ulRegVal;
    
        Power_setDependency(PowerCC32XX_PERIPH_I2CA0);
        Power_setDependency(PowerCC32XX_PERIPH_GPIOA1);
    
        PinTypeGPIO(I2CCC32XX_PIN_03_I2C_SCL & 0xFF, (I2CCC32XX_PIN_03_I2C_SCL >> 8), true);
        PinTypeGPIO(I2CCC32XX_PIN_04_I2C_SDA & 0xFF, (I2CCC32XX_PIN_04_I2C_SDA >> 8), true);
    
        PRCMPeripheralReset(PRCM_I2CA0);
    
        HwiP_clearInterrupt(INT_I2CA0);
    
        HwiP_Params_init(&hwiParams);
        hwiParams.arg = (uintptr_t)0;
        hwiParams.priority = ~0;
        hwiHandle = HwiP_create(INT_I2CA0, I2CCC32XX_hwiFxn2, &hwiParams);
    
        // In case of app restart: disable I2C module, clear interrupt at NVIC
        MAP_I2CMasterDisable(I2CA0_BASE);
        MAP_I2CSlaveDisable(I2CA0_BASE);
    
        // HwiP_clearInterrupt(hwAttrs->intNum);
        // Power_registerNotify(&(object->notifyObj), PowerCC32XX_AWAKE_LPDS, I2CCC32XX_postNotify, (uint32_t)handle);
    
        // Flush the FIFOs. They must be empty before re-assignment
        MAP_I2CTxFIFOFlush(I2CA0_BASE);
        MAP_I2CRxFIFOFlush(I2CA0_BASE);
    
        // Set TX and RX FIFOs to master mode
        MAP_I2CTxFIFOConfigSet(I2CA0_BASE, I2C_FIFO_CFG_TX_SLAVE | I2C_FIFO_CFG_TX_TRIG_1 );
        MAP_I2CRxFIFOConfigSet(I2CA0_BASE, I2C_FIFO_CFG_RX_SLAVE | I2C_FIFO_CFG_RX_TRIG_4 );
    
        // Clear any pending interrupts
        MAP_I2CSlaveIntClear(I2CA0_BASE);
        MAP_I2CSlaveIntClearEx(I2CA0_BASE, 0xFFFFFFFF);
    
        // Don't change the sequence of these 2 function calls. They operate on SCSR and it is write only!
        MAP_I2CSlaveInit(I2CA0_BASE, SLAVE_I2C_ADDR);
        MAP_I2CSlaveFIFOEnable(I2CA0_BASE, I2C_SCSR_TREQ | I2C_SCSR_FBR);
    
        //MAP_I2CSlaveIntEnable(I2CA0_BASE);
        MAP_I2CSlaveIntEnableEx(I2CA0_BASE, I2C_SLAVE_INT_RX_FIFO_REQ);

    Here is the init code I'm using. Did not clean up some comments, just take what you need. At the moment I had to switch to 1 byte trigger (I2C_FIFO_CFG_TX_TRIG_1) for the "TX FIFO empty" signal.

    We are integrating the CC3235 into an existing multi-cpu design where the modules are already communicating over i2c. SPI is dedicated for communicating with one CPU and I2C slave needed as there is a master already on the bus (legacy design).
    We could change the role allocation but it seemed to be easier to just use the CC3235 in slave mode as it should support it, at least theoretically.