STM32F407 ADC Problem with sample rate above 8 kHz
I am using the STM32F407G-DISC1 board in hopes of using ADC to send audio via UDP to a remote client. Before I actually test the UDP process, I am using ADC to encode the audio and pass it to the onboard DAC. So far I have not been very successful. The Discovery board is running at 168 MHz.
I am using ADC1 in the interrupt mode with Timer 3 as the trigger. DAC is triggered by software in the ADC complete callback function. As long as I keep the ADC running at 8 kHz, everything works well. The DAC output sine wave looks on the scope as what you would expect to see, more or less a sine wave. However, I would like to sample at 16 kHz to get a cleaner signal.
I have Ethernet up and running and have a UDP client running on my desktop. UDP sends the signal and the desktop client receives the packets. So that process appears to be working. My ultimate goal is to use another STM32F407G-DISC1 board as the client. I will receive the UDP data on that board and pass it off to the DAC. So I should end up with the same audio out of the DAC on the second board.
However, if I set the ADC to anything above 8 kHz, it messes with the MX_LWIP_Process() call on the first board. If I set it to 10 kHz I usually get 3 good replies when I ping the board. If I set the ADC to 16 kHz, most of the time I only get 2 good replies. At 8 kHz I get all 4 replies with less than 1 ms turn around time. The problem appears that the ADC interrupt happens too quickly for the main loop to reliably run the MX_LWIP_Process() code.
Is there any way to work around that problem by somehow using DMA to process the ADC packets and hand them off to the Ethernet send process? I did setup an ADC to DAC DMA test program and it runs fine without blocking the MX_LWIP_Process() call. However, there appears to be no way to let DMA send the ADC conversions to the Ethernet transmit process.
ADC code is shown here:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
adcvalue = HAL_ADC_GetValue(&hadc1); // adcvalue is uint16_t global variable
// adcbuff is uint16_t global array, buffcount is uint16_t global variable
adcbuff[buffcount] = adcvalue; // place value read in current buffer position
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_8B_R, adcbuff[buffcount]);
HAL_GPIO_TogglePin(CLK_GPIO_Port, CLK_Pin); // so O'scope can measure ADC update frequency
udp_test_send(); // send adcbuff[buffcount] out as UDP packet
}Any suggestions would be appreciated.