This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Does the SPIS clear its END interrupt when a new transaction starts?

Dear all,

I have written some code that controls the SPIS and allows it to transfer data as if it were a master. I am generating the SPIS clock from one timer, and I am looping back a pin to control the CSN line for the SPIS. The CSN is controlled by a high priority interrupt source, and my SPIS interrupt is a low priority interrupt. In the high priority interrupt source I am deasserting the CSN line, grabbing the read data and putting it in a FIFO and then reasserting the CSN pin. I know in this interrupt that all the data will be transferred.

In doing this I do not get an SPIS interrupt being generated. I do see it if the CSN pin is not toggled quite so fast n other sections of my code. I do get repeating transfers of data using this method.

Is this a known issue? I was expecting the END interrupt to be latching, not dependent on whether a new transaction had been started. Similarly, I am releasing the semaphore in this high level interrupt too.

Interested in your response,

Peter

  • Hi Peter

    Thanks for you question

    Where are you acquiring the semaphore? Do you have the END_ACQUIRE shortcut enabled? Are you not waiting for the ACQUIRED event before proceeding with the buffer operation?

  • Stefan,

    1. I am not 'actively' checking/acquiring the interrupt, but...
    2. I do have the END_ACQUIRE shortcut enabled, and in the high priority interrupt handler I am releasing the semaphore.
    3. I am not changing the buffers because I am reusing all the buffer locations. I am performing an SPI read operation that the external device requires a single byte command to start. I am setting the TXDPTR to point to a buffer holding this command, as well as writing the byte to the ORC and DEF registers.

    The read data is being copied from the buffer the SPIS points to, into a FIFO, but the pointer in the SPIS is not changed.

    Peter

  • Hi Peter

    The way it is performed in the SPIS driver in the SDK:

    • The SPI master sets CSN line high which ends the transaction and generates the SPIS->END event
    • The END_ACQUIRE shortcut is set, making the semaphore to be acquired immediately after the SPIS->END event is received
    • The SPIS->END event is cleared in SPIS->END interrupt handler
    • The ACQUIRED event is cleared in the SPIS->ACQUIRED interrupt handler and the buffer operations are performed
    • Semaphore is released when buffer operations are completed, which will allow the SPIS to send/receive more data

    The state machine for the above sequence is shown here.

    I have the following understanding of your case, correct me as necessary:

    • When you receive the high priority interrupt, you manually set the CSN high, which ends the transaction and generates the SPIS->END event
    • The END_ACQUIRE shortcut is set so the semaphore is requested as soon as the END event is generated by SPIS.
    • You clear the END event in the END event handler
    • You do not wait for the ACQUIRED event, but instead read buffer data and release the ACQUIRED event in a high priority interrupt, without knowing if the ACKUIRED event has been received or not.
    • You end the high priority interrupt with setting CSN low, allowing SPIS to operate if CLK signal is generated with your TIMER
    • In the ACQUIRED event handler, you release the semaphore again with calling SPIS->RELEASE task, since there are no buffers to relocate.

    If this high priority interrupt is generated with high frequency, I suspect that one of the following may happen:

    • The high frequency interrupt starves the SPIS->END low priority interrupt, because as soon as one high frequency interrupt ends, another one begins. Processing time of the high priority interrupt may take a long time if considerable amount of data has to be copied from the SPIS RX buffer to the FIFO buffer.
    • The ACQUIRED event handler has not been executed before starting SPIS transmission, therefore the semophore has not been released. In this case all incoming data is ignored by SPIS, and you will probably not receive SPIS->END event when CSN goes high again, since this would not be a valid transaction.
    • You release the semaphore in your high priority interrupt before it has been acquired, which has no effect. When you set the CSN low again, the semaphore has been acquired by the CPU, so the SPIS can not acquire it, making the SPIS to ignore the following transaction and not generate any SPIS->END event.

    The above is just speculation in order to give you ideas of possible failure scenarios. I feel I do not understand your scenario or sequence sufficiently yet do draw any conclusions.

  • It appears it may have simply been a starvation issue, as you suggest. I placed a simple LED toggle function in the spi handler and it toggles infrequently. I am also running in debug mode, so optimisations would not have reduced my code.

    Sorry for the noise, and thank you for the help,

    Peter

  • Any time. I am glad that you figured out the issue

    PS. If you do not have enough CPU time for your scenario, nRF52 has an Cortex M4, which is much faster ;)

Related