2024-10-16 04:46 PM - edited 2024-10-17 07:46 AM
/* USER CODE BEGIN PV */
int adcEnd = 0;
#define ADC_BUF_LEN 2000
uint16_t adc_buf[ADC_BUF_LEN];
/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
if (hadc == &hadc1)
{
adcEnd = 1;
}
}
void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
{
int errorCode = hadc->ErrorCode;
}
uint16_t* process_request_adc()
{
adcEnd = 0;
memset(adc_buf, 0x00, sizeof(adc_buf));
// Trigger the ADC.
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buf, sizeof(adc_buf));
// Wait for the ADC collection to complete.
while(!adcEnd)
{
HAL_Delay(10);
}
return adc_buf;
}
2024-10-17 02:56 AM
Hello @JohnPeterson ,
welcome to the ST community.
I have some question that and information I need to know to help you with your investigation.
could you share the .IOC file used to generate the code are you sure there are no conflicting pins used by ZDC and Ethernet.
also check the following article which can give you good tips on usage of ADC alongside Ethernet.
ADC value affected by ETH PHY 50 MHz from RMII int... - STMicroelectronics Community
Regards
2024-10-17 09:16 AM
Dear STea,
Thanks for the response! I've shared my ADC_Test.ioc file. How will you identify whether there are conflicting pins or not?
When hovering over the three ADC options, I *do* note that they claim to potentially be in conflict with ETH RMII:
Yet it's not clear WHAT might be in conflict. I am not using PB0 (as far as I know).
With my board, my ONLY option for the ETH mode is RMII:
If the ADCs are really in conflict with the ETH RMII...does this mean this board is not suitable to run both components simultaneously?
Thanks for the provided link. I feel like my situation is a bit different, as I'm not getting "noise" in the ADC buffer (at least, I don't think so), but rather the buffer isn't being populated at all.
I'm eager to learn what you can glean from the .ioc file!
Thanks in advance for any help you can provide!
2024-10-22 06:10 AM
Hello @JohnPeterson ,
sorry for the delayed response but I have some questions as a follow-up .seems like there is no conlicts betwwen ADC pin PF11 and the RMII pins used.
after seeing the configuration that you are using i would like to see if you can get values of ADV conversions in polling mode instead of DMA mode.
also, I would like to know what the behavior with another ADC instance and maybe another line.
Regards
2024-10-24 04:43 PM
Dear STea,
Thanks for the reply. I'd like to share some additional findings regarding this issue. I believe that maybe my ADC/DMA problem is less related to ETH/LWIP, but instead related to enabling the I/DCache (which I enable as part of the ETH/LWIP configuration).
Consider the following steps to create a brand new project from the CubeIDE:
When the IDE loads the new IOC file:
Under Pinout & Configuration:
Switch to Clock Configuration:
Back under Pinout & Configuration.
Under the ADC1 Parameter Settings, it should look like:
Save the IOC file and click Yes to generate code.
In main.c, add the following code before the main(void) function in the USER CODE 0 section:
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#define ADC_BUF_LEN 2000
int adcEnd = 0;
uint16_t adc_buf[ADC_BUF_LEN];
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
if (hadc == &hadc1)
{
adcEnd = 1;
}
}
void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
{
int errorCode = hadc->ErrorCode;
}
void process_request_adc()
{
adcEnd = 0;
memset(adc_buf, 0x0F, sizeof(adc_buf)); // Decimal 3855 - just some arbitrary value to see if the buffer changes.
// Trigger the ADC.
HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adc_buf, sizeof(adc_buf));
while(!adcEnd)
{
HAL_Delay(10);
}
uint32_t* test = adc_buf;
}
/* USER CODE END 0 */
In the main(void) function, within the USER CODE 2 section, add the following:
/* USER CODE BEGIN 2 */
process_request_adc();
/* USER CODE END 2 */
Save and debug the application, placing a breakpoint at the last line of the process_request_adc() function to be able to view the contents of adc_buf (or set it up as a Watch variable). You'll note that the 3885 values have been overwritten to some random values, which indicates a successful ADC/DMA action.
Stop debugging.
Under the IOC Pinout & Configuration:
Save the IOC file and click Yes to generate code.
Debug again. Note that the contents of adc_buf now remain unchanged from their initialized values of 3855. The ADC callback is being invoked, but the contents of the buffer we're using for the DMA are not being overwritten.
Why?!?
2024-11-03 10:38 PM
Hello @JohnPeterson ,
The issue you are experiencing is likely due to data coherency problems between the CPU cache and the DMA controller. When the cache is enabled, the CPU may be reading stale data from the cache instead of the updated data from the SRAM, where the DMA controller writes the converted ADC values
you should either try to disable cache for this region of memory where you buffer resides (Use the Memory Protection Unit (MPU) to change the DMA buffers to non-cacheable (device mode)) via MPU configuration or implement Before enabling DMA, perform a cache clean operation to ensure that any data in the cache is written to SRAM. Before reading the data, perform a cache clean and invalidate operation to ensure that the CPU reads the updated data from SRAM.
Regards