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.

LAUNCHXL-CC1312R1: I2S Blocking

Part Number: LAUNCHXL-CC1312R1

Hi

I have a function writeCallbackFxn (below) from the I2S, it states that I should not you the I2S_stopwrite() function, is this correct and if so what's the best way to handle the call back.

static void writeCallbackFxn(I2S_Handle handle, int_fast16_t status, I2S_Transaction *transactionPtr) {
    // Nothing to do here: the buffer(s) are queued in a ring list, the transfers are
    // executed without any action from the application.
    // We must consider the previous transaction (ok, when you have only one transaction it's the same)
    I2S_Transaction *transactionFinished = (I2S_Transaction*)List_prev(&transactionPtr->queueElement);

    if(transactionFinished != NULL){
            // After an arbitrary number of completion of the transaction, we will stop writting
        if(no_of_repetition == NULL){

        }
        else if(no_of_repetition != NULL){
            if(transactionFinished->numberOfCompletions >= no_of_repetition) {
               
			   // Note: You cannot use I2S_stopRead() / I2S_stopWrite() in the callback.
                // The execution of these functions is potentially blocking and can mess up the
                // system.
				
                writeFinished = (bool)true;
                I2S_stopWrite(i2sHandle);
                I2S_stopClocks(i2sHandle);
            }
        }
    }

Kind Regards

David

  • Hi David,

    Could you specify which SK version are you using?

    Regards,

    Fausto

  • Hi Fausto

    The SDK version is CC13xx CC26xx SDK (6.10.00.29)

    Regards

    David

  • Hi David,

    As stated in the code example, any use of blocking call is illegal from a Hw interrupt callback context. This because when handling an interrupt, a blocked called can potentially block the system inside a callback and not allow any other task to run. The best way to signal an event from a callback is to:

    1) create a semaphore in your main application

    2) Post the semaphore from the callback to unblock a task pending on that semaphore

    3) the task will be unblocked and will execute the potentially blocking call from a task context instead of interrupt context

    Regards,

    Fausto

  • Hi Fausto

    I don't have a lot of experience in RTOS7 can you please show me a small example.

    Regards

    David

  • Hi David,

    you can use either the TIRTOS7 semaphores (documentation here) or the  Posix-semaphores (documentation here) which are a OS-independent wrapper of both freertos and TIRTOS7 semaphores and can make your code more portable across OSes.

    Here is a simple example on how to use the SemaphoreP Posix-semaphores in binary mode (the semaphore can only count up to 1, use the regular type of semaphore instead if you want it to be able to count to higher number):

    #include <ti/drivers/dpl/SemaphoreP.h>
    
    static SemaphoreP_Struct mySemaphore;
    
    void myCallback (void) {
    
        // Post semaphore and unblock the blocked task
        SemaphoreP_post(&mySemaphore);
    }
    
    
    void myTask(void) {
    
        // Create a binary seamphore and initialize it to 0
        SemaphoreP_constructBinary(&mySemaphore, 0);
        
        while(1) {
            // Pend for the semaphore to be unblocked by the callback
            SemaphoreP_pend(&mySempahore);
        
            // Finally execute potentially blocking call here
            // ex. I2S_stopRead() or I2S_stopWrite()
        }
        
    }

    Regards,

    Fausto

  • Hi Fausto

    Thank you for your excellent help.

    Regards

    David