RT1021 SDK2.11 HTTP and SAI simultaneous use will cause the interrupt to stop

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

RT1021 SDK2.11 HTTP and SAI simultaneous use will cause the interrupt to stop

1,185 Views
jarman_zhou
Contributor I

My application is HTTP+SAI scenario. When I run the SAI alone, there is no problem. However, when I open the HTTP and send messages to the board, the callback of the SAI does not enter.

1.SAI captures the play using EDMA and uses the semaphore in the callback to synchronize the task so that it runs alone without a problem.

NVIC_SetPriority(DMA1_DMA17_IRQn, 2);//Set the priority to 2, otherwise the semaphore cannot be used
static void rx_callback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData)
{
     portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
    if (kStatus_SAI_RxError == status)
    {
        /* Handle the error. */
    }
    else 
    {
        emptyBlock--;
        xSemaphoreGiveFromISR(xSemaphoreSai, &xHigherPriorityTaskWoken);
        portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    }
}

static void tx_callback(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData)
{
    if (kStatus_SAI_TxError == status)
    {
        /* Handle the error. */
    }
    else 
    {
        emptyBlock++;
    }
}

...
...
...
void sai_task()
{
while (1) 
{
        if(emptyBlock > 0)
        {
            xfer.data     = Buffer + rx_index * BUFFER_SIZE;
            xfer.dataSize = BUFFER_SIZE;
            if (kStatus_Success == SAI_TransferReceiveEDMA(DEMO_SAI, &rxHandle, &xfer))
            {
                rx_index++;
            }
            if (rx_index == BUFFER_NUMBER)
            {
                rx_index = 0U;
            }
        }

        if(emptyBlock < BUFFER_NUMBER)
        {
            xSemaphoreTake(xSemaphoreSai, portMAX_DELAY);
            xfer.data     = Buffer + tx_index * BUFFER_SIZE;
            xfer.dataSize = BUFFER_SIZE;
            if (kStatus_Success == SAI_TransferSendEDMA(DEMO_SAI, &txHandle, &xfer))
            {
                 tx_index++;
            }

           if (tx_index == BUFFER_NUMBER)
           {
                 tx_index = 0U;
           }
        }
}
}

2.Add http service and send test data to board,Have a probability of causing rx_callback/tx_callback no call. I suspect it has something to do with semaphore

0 Kudos
Reply
6 Replies

1,147 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @jarman_zhou ,

Will xSemaphoreSai full when the problem appear?

 

Regards,

Jing

0 Kudos
Reply

1,139 Views
jarman_zhou
Contributor I

Hi,@jingpan

The block is because xSemaphoreTake(xSemaphoreSai, portMAX_DELAY);

If you set a timeout, When refreshing http, an error occurs causing SAI_TransferSendEDMA to return 1904,Cause audio distortion

0 Kudos
Reply

1,116 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @jarman_zhou ,

Do you mean ISR is keeping receiving data but xSemaphoreTake() can't get semaphore?

 

Regards,

Jing

0 Kudos
Reply

1,112 Views
jarman_zhou
Contributor I

Hi,@jingpan

No, the block is because portMAX_DELAY is set.Setting a specific value will work.

However, if there is any other interruption, it will cause the audio data to become abnormal

 

0 Kudos
Reply

1,100 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi @jarman_zhou ,

If xSemaphoreTake() doesn't get semaphore,  it will return errQUEUE_EMPTY. But you do not care about it because (emptyBlock < BUFFER_NUMBER). It will still copy data and process. The delay is useless here because new data is received. But if (emptyBlock < BUFFER_NUMBER) while queue still empty, something is wrong.

 

Regards,

0 Kudos
Reply

1,082 Views
jarman_zhou
Contributor I

Hi,@jingpan

The way it's written in the example, when I write if(emptyBlock < BUFFER_NUMBER), when processing data after sending, the ring buffer pointing to has been received to change, resulting in data distortion, how to avoid this problem?

if(emptyBlock > 0)
{
    Recv_Req_Num++;
 
    xfer.data   = Buffer + rx_index * BUFFER_SIZE;
    xfer.dataSize = BUFFER_SIZE;
    xfer_status = SAI_TransferReceiveEDMA(DEMO_SAI, &rxHandle, &xfer);
    if (kStatus_Success == xfer_status)
    {
         rx_index++;
    }
 
    if (rx_index == BUFFER_NUMBER)
    {
        rx_index = 0U;
    }
}
 
if(emptyBlock < BUFFER_NUMBER)
{
    //xSemaphoreTake(xSemaphoreSai, 1);
    xfer.data     = Buffer + tx_index * BUFFER_SIZE;
    xfer.dataSize = BUFFER_SIZE;
 
    //-----------------------------------------------------------
    /*This is where I'm going to process the data*/
    //-----------------------------------------------------------
 
    memset(xfer.data, 0, BUFFER_SIZE);//Run a test. Clear the buffer
    for(int i=0; i<BUFFER_SIZE; i++)
    {
        if(xfer.data[i] != 0)
            PRINTF("%d ", i);//Some of the data printed here has been changed
    }
 
    xfer_status = SAI_TransferSendEDMA(DEMO_SAI, &txHandle, &xfer);
    if (kStatus_Success == xfer_status)
    {
          tx_index++;
    }
 
    if (tx_index == BUFFER_NUMBER)
    {
          tx_index = 0U;
    }
}
0 Kudos
Reply