IMXRT1010 SAI transfer

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

IMXRT1010 SAI transfer

Jump to solution
229 Views
LuigiV
Contributor III

I'm developing a project that convolve an IR with the data acquired by the codec; I use the IMXRT1010 board.

I take the SDK example and I modify it to get what I need to do the convolution.

The example use this function to receive the data:

* @brief Performs an interrupt non-blocking receive transfer on SAI.

* @note This API returns immediately after the transfer initiates.

* Call the SAI_RxGetTransferStatusIRQ to poll the transfer status and check whether

* the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer

* is finished.

*

* @param base SAI base pointer

* @param handle Pointer to the sai_handle_t structure which stores the transfer state.

* @param xfer Pointer to the sai_transfer_t structure.

* @retval kStatus_Success Successfully started the data receive.

* @retval kStatus_SAI_RxBusy Previous receive still not finished.

* @retval kStatus_InvalidArgument The input parameter is invalid.

*/

 

status_t SAI_TransferReceiveNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer);

and the function:

SAI_TransferSendNonBlocking(....)

 

to send the data.

 

Both need to check the status:

---> Call the SAI_RxGetTransferStatusIRQ 

---> Call the SAI_TxGetTransferStatusIRQ

 

The problem is that I don't find the status check routines; may you help me ?

 

Thanks.

 

Luigi

 

0 Kudos
Reply
1 Solution
200 Views
LuigiV
Contributor III

Thank you Sam, great !!

View solution in original post

0 Kudos
Reply
2 Replies
206 Views
Sam_Gao
NXP Employee
NXP Employee

Hi @LuigiV 

Certainly! Thanks for your questions, plz see my comments below, please correct me if my understanding is wrong.

To perform non-blocking data transfer using the SAI (Serial Audio Interface) module on the IMXRT1010 board, you need to use the provided functions and check the transfer status properly. The functions you mentioned (`SAI_TransferReceiveNonBlocking` and `SAI_TransferSendNonBlocking`) initiate the transfer, and you need to check the status using the appropriate status functions.

 The functions like `SAI_RxGetTransferStatusIRQ` and `SAI_TxGetTransferStatusIRQ` are used to check the status of the receive and transmit transfers, respectively. These functions might not be directly named as such, but they are part of the SAI driver in the SDK.

Here's how you typically use them:

### Receiving Data
To receive data non-blocking, you need to initialize the SAI module, create a transfer handle, and initiate the receive transfer. Then, you periodically check the status to see if the transfer is complete.

#include "fsl_sai.h"
#include "fsl_debug_console.h"
#include "board.h"

#define EXAMPLE_SAI SAI1
#define EXAMPLE_SAI_CHANNEL (0)
#define BUFFER_SIZE (1024U)

sai_handle_t rxHandle;
uint8_t rxBuffer[BUFFER_SIZE];
volatile bool isRxFinished = false;

// Callback function for receive
void SAI_UserRxIRQHandler(I2S_Type *base, sai_handle_t *handle, status_t status, void *userData)
{
if (status == kStatus_SAI_RxIdle)
{
isRxFinished = true;
}
}

void InitSAI(void)
{
sai_config_t config;
SAI_TxGetDefaultConfig(&config);
SAI_Init(EXAMPLE_SAI);

SAI_TransferRxCreateHandle(EXAMPLE_SAI, &rxHandle, SAI_UserRxIRQHandler, NULL);
SAI_TransferRxSetConfig(EXAMPLE_SAI, &rxHandle, &config);
}

void StartReceive(void)
{
sai_transfer_t xfer;
xfer.data = rxBuffer;
xfer.dataSize = BUFFER_SIZE;

if (SAI_TransferReceiveNonBlocking(EXAMPLE_SAI, &rxHandle, &xfer) != kStatus_Success)
{
PRINTF("Failed to start receive transfer.\r\n");
}
}

int main(void)
{
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();

InitSAI();
StartReceive();

while (!isRxFinished)
{
// Poll the transfer status
status_t status = SAI_TransferGetReceiveCount(EXAMPLE_SAI, &rxHandle);
if (status == kStatus_SAI_RxError)
{
PRINTF("Receive error occurred.\r\n");
break;
}
}

PRINTF("Receive finished.\r\n");

while (1)
{
}
}
```

 

 

### Transmitting Data
Similarly, for transmitting data, you initialize the SAI module, create a transfer handle, and initiate the transmit transfer. Then, you periodically check the status to see if the transfer is complete.

```c
#include "fsl_sai.h"
#include "fsl_debug_console.h"
#include "board.h"

#define EXAMPLE_SAI SAI1
#define EXAMPLE_SAI_CHANNEL (0)
#define BUFFER_SIZE (1024U)

sai_handle_t txHandle;
uint8_t txBuffer[BUFFER_SIZE];
volatile bool isTxFinished = false;

// Callback function for transmit
void SAI_UserTxIRQHandler(I2S_Type *base, sai_handle_t *handle, status_t status, void *userData)
{
if (status == kStatus_SAI_TxIdle)
{
isTxFinished = true;
}
}

void InitSAI(void)
{
sai_config_t config;
SAI_TxGetDefaultConfig(&config);
SAI_Init(EXAMPLE_SAI);

SAI_TransferTxCreateHandle(EXAMPLE_SAI, &txHandle, SAI_UserTxIRQHandler, NULL);
SAI_TransferTxSetConfig(EXAMPLE_SAI, &txHandle, &config);
}

void StartTransmit(void)
{
sai_transfer_t xfer;
xfer.data = txBuffer;
xfer.dataSize = BUFFER_SIZE;

if (SAI_TransferSendNonBlocking(EXAMPLE_SAI, &txHandle, &xfer) != kStatus_Success)
{
PRINTF("Failed to start transmit transfer.\r\n");
}
}

int main(void)
{
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();

InitSAI();
StartTransmit();

while (!isTxFinished)
{
// Poll the transfer status
status_t status = SAI_TransferGetSendCount(EXAMPLE_SAI, &txHandle);
if (status == kStatus_SAI_TxError)
{
PRINTF("Transmit error occurred.\r\n");
break;
}
}

PRINTF("Transmit finished.\r\n");

while (1)
{
}
}
```

### Notes
1. Interrupt Handler: The callback functions `SAI_UserRxIRQHandler` and `SAI_UserTxIRQHandler` handle the interrupt service routines. They set a flag when the transfer is finished.
2. Polling Status: In the main loop, the status is periodically checked using `SAI_TransferGetReceiveCount` and `SAI_TransferGetSendCount` functions to determine if the transfer is complete.
3. SDK Documentation: Ensure to refer to the specific SDK documentation for your board and SAI driver functions as there might be slight variations in function names or parameters.

By following the above examples, you should be able to perform non-blocking transfers with status checks on the IMXRT1010 board.

 

Have a nice day!

Sam

0 Kudos
Reply
201 Views
LuigiV
Contributor III

Thank you Sam, great !!

0 Kudos
Reply