Hello, I'm a generator of questions...:-)
anyway, the SDK example "evkmimxrt1010_sai_interrupt_record_playback" could be the solution of what I trying to do; anyone may help me to understand better in what way the code manage the SAI data transfer ?
I mean the type of transfer and the data structure; the code uses a data buffer -->
AT_NONCACHEABLE_SECTION_ALIGN(static uint8_t Buffer[BUFFER_NUMBER * BUFFER_SIZE], 4);
and a data structure to send dato to the SAI (and to receive)
xfer.data = Buffer + tx_index * BUFFER_SIZE;
xfer.dataSize = BUFFER_SIZE;
if (kStatus_Success == SAI_TransferSendNonBlocking(DEMO_SAI, &txHandle, &xfer))
I would like to understand better these parts of code.
Thank you.
Luigi
解決済! 解決策の投稿を見る。
Hi @LuigiV ,
Thanks for your interest in NXP MIMXRT series!
We can look at the main logic of this function together,while(1){...}:
An infinite loop is used here, constantly checking the status of the buffer and sending and receiving data.
- `emptyBlock` is an unsigned 8-bit integer that indicates how many sub-buffers in the buffer are empty, i.e., without data. Its initial value is `BUFFER_NUMBER`, which indicates that all sub-buffers are empty. Every time data is received from a sub-buffer, emptyBlock is decremented by one; every time data is sent from a sub-buffer, emptyBlock is incremented by one. This ensures that there is always data in the buffer to send without under or overflow.
- `if (emptyBlock > 0)` This judgment statement is used to check **<u> if there is an empty sub-buffer that can receive data </u>**. If there is, the `SAI_TransferReceiveNonBlocking` function is called to receive the data into the current sub-buffer. Then add one to rx_index to point to the next sub-buffer. If rx_index equals BUFFER_NUMBER, the end of the buffer has been reached, it is reset to 0, and reception starts from the beginning.
- `if (emptyBlock < BUFFER_NUMBER)` This judgment statement is used to check **<u> if there is a non-empty sub-buffer to which data can be sent </u>**. If there is, the `SAI_TransferSendNonBlocking` function is called to send the data to the SAI's transmitter. Then add one to tx_index to point to the next sub-buffer. If tx_index equals BUFFER_NUMBER, the end of the buffer has been reached, reset it to 0 and start sending from the beginning.
Then, we can look at the data structure:
`AT_NONCACHEABLE_SECTION_ALIGN(static uint8_t Buffer[BUFFER_NUMBER * BUFFER_SIZE], 4);`
- A macro is used here to define a static unsigned 8-bit array whose size is `BUFFER_NUMBER` times `BUFFER_SIZE`, both of which can be modified as needed. Each element of this array is a byte, which is used to **<u> store the sample values of the audio data </u>**. The alignment of this array is 4 bytes, this is to improve access speed and avoid alignment errors
The transmission structure is defined as follows:
`sai_transfer_t xfer;`
- A structure type sai_transfer_t is used here, which is defined in the SAI driver library and contains two member variables: `data` and `dataSize`. data is a pointer to the starting address of the data to be transferred. dataSize is an unsigned 32-bit integer representing the number of bytes of data to be transferred. dataSize is an unsigned 32-bit integer that indicates the number of bytes of data to be transferred.
The transfer structure is assigned as follows:
`xfer.data = Buffer + tx_index * BUFFER_SIZE;`
`xfer.dataSize = BUFFER_SIZE;`
- A variable `tx_index` is used here, which is an unsigned 8-bit integer that indicates the index of the current buffer to be transferred. Because the buffer is divided into `BUFFER_NUMBER` sub-buffers, and the size of each sub-buffer is `BUFFER_SIZE`, the starting address of the data to be transferred is the buffer plus tx_index multiplied by the BUFFER_SIZE, and the number of bytes of data to be transferred is the BUFFER_SIZE.
Also, there is some information you can refer to:
1. https://www.nxp.com/docs/en/application-note/AN12090.pdf
2. https://www.nxp.com/docs/en/application-note/AN12202.pdf
Best regards,
Gavin
Thank you Gavin for your support, I have a question: why does it use a 8 bit buffer instead of a 16 or 32 bit buffer ? Is it a requirement of the API function ?
Luigi
Hi @LuigiV ,
This is due to the reason that the Buffer stores the sample values of the audio data inside it, and each sample value occupies one byte, so the uint_8 type is used. This makes it easy to align and transfer with the data registers of the SAI module.
Best regards,
Gavin
Hi @LuigiV ,
Thanks for your interest in NXP MIMXRT series!
We can look at the main logic of this function together,while(1){...}:
An infinite loop is used here, constantly checking the status of the buffer and sending and receiving data.
- `emptyBlock` is an unsigned 8-bit integer that indicates how many sub-buffers in the buffer are empty, i.e., without data. Its initial value is `BUFFER_NUMBER`, which indicates that all sub-buffers are empty. Every time data is received from a sub-buffer, emptyBlock is decremented by one; every time data is sent from a sub-buffer, emptyBlock is incremented by one. This ensures that there is always data in the buffer to send without under or overflow.
- `if (emptyBlock > 0)` This judgment statement is used to check **<u> if there is an empty sub-buffer that can receive data </u>**. If there is, the `SAI_TransferReceiveNonBlocking` function is called to receive the data into the current sub-buffer. Then add one to rx_index to point to the next sub-buffer. If rx_index equals BUFFER_NUMBER, the end of the buffer has been reached, it is reset to 0, and reception starts from the beginning.
- `if (emptyBlock < BUFFER_NUMBER)` This judgment statement is used to check **<u> if there is a non-empty sub-buffer to which data can be sent </u>**. If there is, the `SAI_TransferSendNonBlocking` function is called to send the data to the SAI's transmitter. Then add one to tx_index to point to the next sub-buffer. If tx_index equals BUFFER_NUMBER, the end of the buffer has been reached, reset it to 0 and start sending from the beginning.
Then, we can look at the data structure:
`AT_NONCACHEABLE_SECTION_ALIGN(static uint8_t Buffer[BUFFER_NUMBER * BUFFER_SIZE], 4);`
- A macro is used here to define a static unsigned 8-bit array whose size is `BUFFER_NUMBER` times `BUFFER_SIZE`, both of which can be modified as needed. Each element of this array is a byte, which is used to **<u> store the sample values of the audio data </u>**. The alignment of this array is 4 bytes, this is to improve access speed and avoid alignment errors
The transmission structure is defined as follows:
`sai_transfer_t xfer;`
- A structure type sai_transfer_t is used here, which is defined in the SAI driver library and contains two member variables: `data` and `dataSize`. data is a pointer to the starting address of the data to be transferred. dataSize is an unsigned 32-bit integer representing the number of bytes of data to be transferred. dataSize is an unsigned 32-bit integer that indicates the number of bytes of data to be transferred.
The transfer structure is assigned as follows:
`xfer.data = Buffer + tx_index * BUFFER_SIZE;`
`xfer.dataSize = BUFFER_SIZE;`
- A variable `tx_index` is used here, which is an unsigned 8-bit integer that indicates the index of the current buffer to be transferred. Because the buffer is divided into `BUFFER_NUMBER` sub-buffers, and the size of each sub-buffer is `BUFFER_SIZE`, the starting address of the data to be transferred is the buffer plus tx_index multiplied by the BUFFER_SIZE, and the number of bytes of data to be transferred is the BUFFER_SIZE.
Also, there is some information you can refer to:
1. https://www.nxp.com/docs/en/application-note/AN12090.pdf
2. https://www.nxp.com/docs/en/application-note/AN12202.pdf
Best regards,
Gavin