2023-01-03 11:27 AM
I have read quite a few posts, reference, and KBs trying to get this to work - but I'm stuck.
Challenge: Trying to get STM32H745 working with ADC1 (and eventually ADC3) with DMA.
What I am experiencing: All my results are coming back as "65535" (even when there is not a 3.3V on the input)
What I've done/read:
I've referred to this KB quite a bit:
https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices
So I have an understanding of some of the challenges. I am using "Solution example 3: Use Cache maintenance functions" as my guide. However, it's unclear to me if I need to make an effort to move the memory locations as in "Solution example 1" and "Solution example 2".
Relevant code:
main.c
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
And further:
MX_GPIO_Init();
MX_ADC1_Init();
MX_ADC3_Init();
MX_BDMA_Init();
MX_DMA_Init();
MX_FDCAN1_Init();
MX_FDCAN2_Init();
MX_USART3_UART_Init();
ADC:
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
hadc1.Init.Resolution = ADC_RESOLUTION_16B;
hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
hadc1.Init.LowPowerAutoWait = DISABLE;
hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.NbrOfConversion = 4;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;
hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
[ channels are configured ]
sConfig.Channel = ADC_CHANNEL_7;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE;
[DMA is configured]
hdma_adc1.Instance = DMA1_Stream0;
hdma_adc1.Init.Request = DMA_REQUEST_ADC1;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
hdma_adc1.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(adcHandle,DMA_Handle,hdma_adc1);
/* ADC1 interrupt Init */
HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC_IRQn);
User code:
#define ADC1_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) 32) /* Size of array aADCxConvertedData[] */
#define ADC3_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) 32) /* Size of array aADCxConvertedData[] */
ALIGN_32BYTES (static uint16_t aADC1ConvertedData[ADC1_CONVERTED_DATA_BUFFER_SIZE]);
ALIGN_32BYTES (static uint16_t aADC3ConvertedData[ADC3_CONVERTED_DATA_BUFFER_SIZE]);
void calibrate_adc() {
if (HAL_ADCEx_LinearCalibration_FactorLoad(&hadc1) != HAL_OK) {
serprintf("Could not load linear calibration for adc1.");
}
if (HAL_ADCEx_LinearCalibration_FactorLoad(&hadc3) != HAL_OK) {
serprintf("Could not load linear calibration for adc3.");
}
/* Run the ADC calibration in single-ended mode */
if (HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK) {
/* Calibration Error */
serprintf("ADC1 calibration error.");
Error_Handler();
}
HAL_Delay(50);
/* Run the ADC calibration in single-ended mode */
if (HAL_ADCEx_Calibration_Start(&hadc3, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK) {
/* Calibration Error */
serprintf("ADC3 calibration error.");
Error_Handler();
}
HAL_Delay(50);
HAL_ADC_Start_DMA(&hadc1, (uint32_t*) aADC1ConvertedData, ADC1_CONVERTED_DATA_BUFFER_SIZE);
//HAL_ADC_Start_DMA(&hadc3, (uint32_t*) aADC3ConvertedData, ADC3_CONVERTED_DATA_BUFFER_SIZE);
}
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{
/* Invalidate Data Cache to get the updated content of the SRAM on the first half of the ADC converted data buffer: 32 bytes */
SCB_InvalidateDCache_by_Addr((uint32_t*)((uint32_t)aADC1ConvertedData), ADC1_CONVERTED_DATA_BUFFER_SIZE);
SCB_InvalidateDCache_by_Addr((uint32_t*)((uint32_t)aADC3ConvertedData), ADC3_CONVERTED_DATA_BUFFER_SIZE);
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
/* Invalidate Data Cache to get the updated content of the SRAM on the second half of the ADC converted data buffer: 32 bytes */
SCB_InvalidateDCache_by_Addr((uint32_t*)((uint32_t)aADC1ConvertedData), ADC1_CONVERTED_DATA_BUFFER_SIZE);
SCB_InvalidateDCache_by_Addr((uint32_t*)((uint32_t)aADC3ConvertedData), ADC3_CONVERTED_DATA_BUFFER_SIZE);
}
Linker script:
MEMORY
{
RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K /* Memory is divided. Actual start is 0x08000000 and actual length is 2048K */
DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
}
Solved! Go to Solution.
2023-01-05 11:10 AM
Wanted to come back and indicate I solved this. This is a custom board and the designer used an analog reference IC (MCP1501) and I discovered that the shutdown pin was wired incorrectly, thus shutting it down.
2023-01-04 02:09 AM
Hello @Community member ,
When DMA is used, the MX_DMA_Init shall always be called before any other HAL_***_Init (where *** is any peripheral with a HW dependency on DMA init code).
So try to initiate DMA before the ADC :
MX_GPIO_Init();
MX_DMA_Init();
MX_BDMA_Init();
MX_ADC1_Init();
MX_ADC3_Init();
MX_FDCAN1_Init();
MX_FDCAN2_Init();
MX_USART3_UART_Init();
Foued
To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2023-01-04 04:54 AM
The code was generated by CubeMX, and I have read about the problem where they are initialized in the wrong order. I have manually swapped them but the problem still exists.
2023-01-05 11:10 AM
Wanted to come back and indicate I solved this. This is a custom board and the designer used an analog reference IC (MCP1501) and I discovered that the shutdown pin was wired incorrectly, thus shutting it down.