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.

TM4C1294NCPDT: TMC4C1294 master and TM4C123 SPI slave with notification interrupts back to master

Part Number: TM4C1294NCPDT

Hello,

I'm using TI-RTOS with a TM4C1294 acting as a master via SPI to a slave TM4C123 slave device. The master can send various command to the slave to configure or perform other actions on the slave, this all works fine.

However, the slave also needs to generate an interrupt notification (via gpio pin) back to the master whenever it decodes a smpte timecode packet. These interrupts will stream at a rate of around 2kHz as the slave decodes packets and notifies the master to read the data from the slave and clear the interrupt. The The master must read the timecode packet data and acknowledge each interrupt to the slave via a SPI status command read to the slave. 

However, other RTOS threads in my applicaiton will need to communicate with the slave via the same SPI bus to control functions provided by the slave. The slave will also be busy decoding timecode packets and notifying the master via gpio pin interrupt. The problem is my Hwi INT handler in the master will need to read over the same SPI bus to acknowledge interrupts from the slave. Since the same SPI bus can also be accessed from other threads in my application synchronously, how do I synchronize the asynch Hwi SPI reads with other tasks performing synchronous SPI reads over the same SPI port. 

Should my INT notifcation handler post to a Swi and then use a global mutex or semaphore between the swi and other tasks making spi calls?

If this is not possible, perhaps it would be easier to setup another SPI channel to process just the interrupt data stream? Unfortunately, expensive hardware changes would be required to setup a second comm channel to a slave processor device.

Thanks in advance for any suggestions.

Regards

Bob Starr

  • Hi,

    Should my INT notifcation handler post to a Swi and then use a global mutex or semaphore between the swi and other tasks making spi calls?

    Your idea is worth trying. Will you consider disabling other tasks when the master is accessing the slave? The interrupt should have higher priority over other tasks so preemption should not happen in the first place. Using a queue to queue up all the data before sending to the slave is also possible. Not sure if my ideas are worth trying though. 

  • Hi Charles, thanks for the reply. I'll try having my Hwi post to a Swi. Best I recall, the Swi should have higher priority over tasks, but lower than the Hwi posting to it. I've created my own driver layer similar to other drivers in TI-RTOS.  I create a Gate Mutex in the handle construct, then all the SMPTE_Read(), SMPTE_Write() functions in my driver layer are protected by this mutex. My idea was to have the Hwi INT handler post to a Swi, that in turn makes the SPI call (using the same Mutex wrapped by the object handle) to reads the async data from the SPI slave. The act of reading the slave INT data will reset it's "interrupt" internal logic state. 

    Currently I'm using a mailbox to pass data between the Hwi and a SPI reader task, but I considered using the queue_elem constructs and mechanisms initially for this. Maybe I should change my driver to use a sempahore, rather than gate mutex, for all the synchronization. Then the slave read/write functions could then have a timeout in case something fails internally and gets confused with the Swi accessing the SPI stream as well.

    I need to go back and read the documentation on Swi's again, and first make sure the default SPI lib layer calls are valid within a Swi context. My current implementation calls Mailbox_post() from the Hwi handler, so I would think the Swi can do the same as tto handle the Hwi calls.

    Regards,

    Bob

    MPTE_Handle SMPTE_construct(SMPTE_Object *obj, SMPTE_Params *params)
    {
    /* Initialize the object's fields */
    obj->spiHandle = params->spiHandle;
    obj->gpioCS = params->gpioCS;

    GateMutex_construct(&(obj->gate), NULL);

    return (SMPTE_Handle)obj;
    }

    SMPTE_Handle SMPTE_create(SMPTE_Params *params)
    {
    SMPTE_Handle handle;
    Error_Block eb;

    Error_init(&eb);

    handle = Memory_alloc(NULL, sizeof(SMPTE_Object), NULL, &eb);

    if (handle == NULL)
    return NULL;

    handle = SMPTE_construct(handle, params);

    return handle;
    }

  • Hi Robert,

      I have not heard back from you. I hope you are able to find the best solution (e.g. mailbox, semaphore, queue or others) for your problem.  I will close the thread for now. If you have an update, you can write back to this thread and it will change the status to OPEN. 

  • HI Charles,
    I tried the SWI and found that SPI_read only works in non-blocking mode from a SWI. But, this created other problems when trying to use this method with a GateMutex in the SPI callback. So, I ended up going back to mailbox from the hwi and a reader task to read the SPI in response to the interrupt. Maybe not the best in terms of speed responding to the interrupt, but it seems to be working for now at least. Trying to share the same SPI channel with other tasks and interrupt handlers is not so clean, I'll change my hardware design next time. Thanks for the help.