2024-02-18 10:10 PM - edited 2024-02-18 10:13 PM
I have a B-L475E-IOT01A2 board. I'm trying to use the onboard microphones to record audio, using the DFSDM peripheral, and then send the data over UART to my PC to play it back. The thing is, the data I get is basically just static.
Here is how I configured the DFSDM peripheral in CubeMX, based on the "DFSDM_AudioRecord" example for the eval boards
Now, for the code:
#define DFSDM_RECORDING_SIZE 2048
static bool left_dma_half_complete = false;
static bool left_dma_full_complete = false;
static bool right_dma_half_complete = false;
static bool right_dma_full_complete = false;
static int32_t left_rec_buf[DFSDM_RECORDING_SIZE];
static int32_t right_rec_buf[DFSDM_RECORDING_SIZE];
static int16_t output_buf[DFSDM_RECORDING_SIZE * 2];
static HAL_StatusTypeDef status;
// ...
// in main():
if (HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter0, left_rec_buf,
DFSDM_RECORDING_SIZE) != HAL_OK) {
Error_Handler();
}
if (HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter1, right_rec_buf,
DFSDM_RECORDING_SIZE) != HAL_OK) {
Error_Handler();
}
while (1) {
if (left_dma_half_complete && right_dma_half_complete) {
for (int i = 0; i < DFSDM_RECORDING_SIZE; i++) {
output_buf[i * 2] = clamp(left_rec_buf[i] / 256, -32768, 32767);
output_buf[i * 2 + 1] = clamp(right_rec_buf[i] / 256, -32768, 32767);
}
status = HAL_UART_Transmit(&huart1, (uint8_t *)output_buf,
DFSDM_RECORDING_SIZE * 4, 1000);
if (status != HAL_OK) {
Error_Handler();
}
left_dma_half_complete = false;
right_dma_half_complete = false;
}
if (left_dma_full_complete && right_dma_full_complete) {
for (int i = 0; i < DFSDM_RECORDING_SIZE; i++) {
output_buf[i * 2] = clamp(left_rec_buf[i] / 256, -32768, 32767);
output_buf[i * 2 + 1] = clamp(right_rec_buf[i] / 256, -32768, 32767);
}
status = HAL_UART_Transmit(&huart1, (uint8_t *)output_buf,
DFSDM_RECORDING_SIZE * 4, 1000);
if (status != HAL_OK) {
Error_Handler();
}
left_dma_full_complete = false;
right_dma_full_complete = false;
}
}
void HAL_DFSDM_FilterRegConvHalfCpltCallback(
DFSDM_Filter_HandleTypeDef *hdfsdm_filter) {
if (hdfsdm_filter == &hdfsdm1_filter0) {
left_dma_half_complete = true;
} else if (hdfsdm_filter == &hdfsdm1_filter1) {
right_dma_half_complete = true;
}
}
void HAL_DFSDM_FilterRegConvCpltCallback(
DFSDM_Filter_HandleTypeDef *hdfsdm_filter) {
if (hdfsdm_filter == &hdfsdm1_filter0) {
left_dma_full_complete = true;
} else if (hdfsdm_filter == &hdfsdm1_filter1) {
right_dma_full_complete = true;
}
}
Solved! Go to Solution.
2024-02-19 12:14 AM - edited 2024-02-19 12:31 AM
>> Basically i dont see, what you do with the data in real time, that you generate: 42,8KHz x 2 ch x 16b = 13,7 Mbit data rate .
I don't understand this sentence. Can you rephrase?
I made complex sentence - just to say : sooo much data - where do you store it ?
But i calculate wrong (decimal point...) , i edit. its 1,37Mbit --- and thats possible on usb or on uart .
+
> At > 1,4 Mbit ?
I guess that's where my issue comes from. I didn't think about that. My test is indeed at a very low speed. Do you have any suggestions on how to get the data fast enough to the PC?
Yes, so much data - you have to store it , or make USB audio device (= sound card) , to send over USB audio; here i see the best way to get 48kHz (this is the standard speed) 16b stereo to a pc.
On uart : what speed you set ? You need 2 Mbit (minimum) and send with DMA; blocking/polling probably too slow.
+
> can you show the circuit,
> what and how you make the data stream for input ?
You didnt tell, you use a B-L475E-IOT01 board . No its clear to me : onboard dig. mics -> DFSDM ... ok.
+
So first decide, how to do with that data in real time - sending to pc could work on USB or UART .
Then test with a small and fixed data block, with no real data, but something like a sawtooth pattern, thats easy to see : good or not.
2024-02-18 11:45 PM - edited 2024-02-19 12:15 AM
Basically i dont see, what you do with the data in real time, that you generate: 42,8KHz x 2 ch x 16b = 13,7 1,37 Mbit data rate .
>My receiver program on the PC can get data properly
At > 14 Mbit ?? how you do this magic speed on UART ? You proved with a test ?
+
Can you show the circuit, what and how you make the data stream for input ?
2024-02-18 11:51 PM - edited 2024-02-18 11:53 PM
> Basically i dont see, what you do with the data in real time, that you generate: 42,8KHz x 2 ch x 16b = 13,7 Mbit data rate .
I don't understand this sentence. Can you rephrase?
> At > 14 Mbit ?? how you do this magic speed on UART ?
I guess that's where my issue comes from. I didn't think about that. My test is indeed at a very low speed. Do you have any suggestions on how to get the data fast enough to the PC?
> can you show the circuit,
There is no "circuit", the board is just connected to my PC via USB and the integrated ST-Link. As I said, it's a B-L475E-IOT01, so I guess the circuit you might want is the one in the datasheet: https://www.st.com/resource/en/data_brief/b-l475e-iot01a.pdf
> what and how you make the data stream for input ?
I don't understand your question - what do you mean by "make the data stream for input"?
2024-02-19 12:14 AM - edited 2024-02-19 12:31 AM
>> Basically i dont see, what you do with the data in real time, that you generate: 42,8KHz x 2 ch x 16b = 13,7 Mbit data rate .
I don't understand this sentence. Can you rephrase?
I made complex sentence - just to say : sooo much data - where do you store it ?
But i calculate wrong (decimal point...) , i edit. its 1,37Mbit --- and thats possible on usb or on uart .
+
> At > 1,4 Mbit ?
I guess that's where my issue comes from. I didn't think about that. My test is indeed at a very low speed. Do you have any suggestions on how to get the data fast enough to the PC?
Yes, so much data - you have to store it , or make USB audio device (= sound card) , to send over USB audio; here i see the best way to get 48kHz (this is the standard speed) 16b stereo to a pc.
On uart : what speed you set ? You need 2 Mbit (minimum) and send with DMA; blocking/polling probably too slow.
+
> can you show the circuit,
> what and how you make the data stream for input ?
You didnt tell, you use a B-L475E-IOT01 board . No its clear to me : onboard dig. mics -> DFSDM ... ok.
+
So first decide, how to do with that data in real time - sending to pc could work on USB or UART .
Then test with a small and fixed data block, with no real data, but something like a sawtooth pattern, thats easy to see : good or not.
2024-02-19 04:34 AM - edited 2024-02-19 04:37 AM
> You didnt tell, you use a B-L475E-IOT01 board
Well, that was the first sentence of my post. Anyway.
After some testing, the problem is indeed with the UART speed. Even if:
the UART is still too slow for the audio. I monitored the callbacks using ITM_Send, and it shows that my DFSDM DMA buffer gets full four times during the period it takes for the UART to finish transmitting.
> Yes, so much data - you have to store it ,
Where could I store it? I read that flash is not good for large writes at runtime, it will wear out too quickly.
> or make USB audio device (= sound card) , to send over USB audio; here i see the best way to get 48kHz (this is the standard speed) 16b stereo to a pc.
Is this possible with an STM MCU or do I need a specialized module?
Thanks for your help!
2024-02-19 05:30 AM
>Well, that was the first sentence of my post. Anyway.
Right. Bad eyes...sorry. :)
>the UART is still too slow for the audio.
First (always!) calculate : i want read data here->transfer->receive ; is speed possible at all ?
-> so 42kHz x 2ch x 16b = about 1,4Mbit . = your needed minimum transfer speed .
>Where could I store it?
If sd-card or USB stick there, should be possible. (But no easy game.)
> USB audio device >Is this possible with an STM MCU ..
Yes. Your card has (from manual):
-> need library/driver for USB audio device , also no easy game. But will work.
2024-02-19 06:29 AM - edited 2024-02-19 06:30 AM
I was able to get real sound data by increasing the UART transfer rate way up (1843200 bps). Thanks!