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.

TM4C123AE6PM: SPI_Transaction use as Slave

Part Number: TM4C123AE6PM

I'm having problems getting reply data from a Tiva acting as a slave device. I've configured the SPI port for blocking 16-bit word size. I'm not sure how the slave select line is handle in slave mode. Basically, i need to send a 16-bit command word to the slave device to control things. However some commands need to respond back with data requested from the slave. The code in my slave looks as follows:

for(;;)
    {
        ulReply = ulRequest = ulDummy = 0;

        transaction1.count = 1;
        transaction1.txBuf = (Ptr)&ulDummy;
        transaction1.rxBuf = (Ptr)&ulRequest;

        /* Send the SPI transaction */
        success = SPI_transfer(hSlave, &transaction1);

        if (!success)
        {
            System_printf("SPI slave rx failed\n");
            System_flush();
            /* Loop if error reading SPI! */
            continue;
        }

        uint8_t opcode = (ulRequest & SMPTE_REG_MASK) >> 8;

        if (opcode == SMPTE_REG_REVID)
        {
            /* ====================================================
             * SMPTE CARD REV/ID REGISTER (RO)
             * ====================================================
             */

            ulReply = SMPTE_REVID;

            /* Send the reply word back */
            transaction2.count = 1;
            transaction2.txBuf = (Ptr)&ulReply;
            transaction2.rxBuf = (Ptr)&ulDummy;

            /* Send the SPI transaction */
            success = SPI_transfer(hSlave, &transaction2);

            if (!success)
            {
                System_printf("SMPTE slave reply failed!\n");
                System_flush();
            }
        }
        else if (opcode == SMPTE_REG_GENCTL)

The master side is controlling the FSS manually on the main board. The slave card has the FSS configured for control by the SPI module.

static bool SMPTE_Read(uint16_t opcode, uint16_t *result)
{
    bool success;
    uint16_t txbuf[2];
    uint16_t rxbuf[2];
    SPI_Transaction transaction;

    /* Set the read flag to send response */
    txbuf[0] = opcode | SMPTE_F_READ;
    rxbuf[0] = 0;

    /* Send the command */
    transaction.count = 1;
    transaction.txBuf = (Ptr)&txbuf[0];
    transaction.rxBuf = (Ptr)&rxbuf[0];

    /* Send the SPI transaction */
    GPIO_write(Board_SMPTE_FS, PIN_LOW);
    success = SPI_transfer(handle, &transaction);
    GPIO_write(Board_SMPTE_FS, PIN_HIGH);

    /* Set the read flag to send response */
    txbuf[1] = opcode;
    rxbuf[1] = 0;

    /* Send the command */
    transaction.count = 1;
    transaction.txBuf = (Ptr)&txbuf[1];
    transaction.rxBuf = (Ptr)&rxbuf[1];

    Task_sleep(3);

    /* Send the SPI transaction */
    GPIO_write(Board_SMPTE_FS, PIN_LOW);
    success = SPI_transfer(handle, &transaction);
    GPIO_write(Board_SMPTE_FS, PIN_HIGH);

    if (success)
        *result = rxbuf[1];

    return success;
}

When the master sends a command that expects a reply, it immediately issues another read with dummy byte to get the data returned. However, the second SPI_transfer call returns zero from the transaction operation unless I added the Task_sleep() call between the two transaction on the master side. Any help would be greatly appreciated.

Bob

  • It looks like you are using the TI-RTOS SPI driver. If the master sends the command and immediately sends the dummy byte to generate the read, the slave has not had time to detect the command and then fill the transmit buffer with the response before the master sends the dummy byte. The FSS line selects the slave. It does not hold off the master until the slave is ready. You need to either add a delay, or implement an additional GPIO signal that tells the master when the slave is ready.

  • Thanks, yes using TI-RTOS. I was wondering if another GPIO for flow control would be needed. I think I have another GPIO line mapped between the two processors that I can use as a slave busy indicator and will look into this.