STMicroelectronics / STM32CubeH7

STM32Cube MCU Full Package for the STM32H7 series - (HAL + LL Drivers, CMSIS Core, CMSIS Device, MW libraries plus a set of Projects running on all boards provided by ST (Nucleo, Evaluation and Discovery Kits))
https://www.st.com/en/embedded-software/stm32cubeh7.html
Other
479 stars 298 forks source link

Fix DMA overflow in ADCDualModeInterleaved example #282

Closed dwalkes closed 6 months ago

dwalkes commented 7 months ago

With DMA_MDATAALIGN_WORD the HAL_ADCEx_MultiModeStart_DMA call expects the length parameter to be in words, not half words.

Without this change, the DMA interrupt overwrites the aADCxConvertedValues buffer located immediately behind the, DMA buffer, which isn't a problem for this example since it's immediately overwritten with the correct values in the HAL_ADC_ConvCpltCallback.

However, for those using this reference example this bug is likely to cause memory corruption in their application.

I have signed the CLA.

RJMSTM commented 6 months ago

Hello @dwalkes,

Following your request, we have tried to reproduce the issue. the HAL_ADCEx_MultiModeStart_DMA call aADCDualConvertedValuesas the pData Destination Buffer address parameter and not aADCxConvertedValues

  /* Start ADCx and ADCy multimode conversion on regular group with transfer by DMA */
  if (HAL_ADCEx_MultiModeStart_DMA(&AdcHandle_master,
                                   (uint32_t *)aADCDualConvertedValues,
                                    ADCCONVERTEDVALUES_BUFFER_SIZE
                                  ) != HAL_OK)

Before callbacks functions aADCxConvertedValues and aADCyConvertedValues both tables are set to zero image and aADCDualConvertedValues it is fully stocked.

image but if I implement the solution, that you have proposed, the aADCDualConvertedValues table is half filled.

image

Can you clarify more your problem because the callbacks functions write in aADCxConvertedValues and aADCyConvertedValues through(uint16_t) COMPUTATION_DUALMODEINTERLEAVED_ADCMASTER_RESULT(aADCDualConvertedValues[tmp_index]);and (uint16_t) COMPUTATION_DUALMODEINTERLEAVED_ADCSLAVE_RESULT(aADCDualConvertedValues[tmp_index]);

which are implement like the description of the reference manual. image

First 16 bits ->Master (LSB) next 16 bits -> slave (MSB)

/**
  * @brief  Computation of ADC master conversion result
  *         from ADC dual mode conversion result (ADC master and ADC slave
  *         results concatenated on data register of ADC master).
  * @param  DATA: ADC dual mode conversion result
  * @retval None
  */
#define COMPUTATION_DUALMODEINTERLEAVED_ADCMASTER_RESULT(DATA)                 \
  ((DATA) & 0x0000FFFF)

/**
  * @brief  Computation of ADC slave conversion result
  *         from ADC dual mode conversion result (ADC master and ADC slave
  *         results concatenated on data register of ADC master).
  * @param  DATA: ADC dual mode conversion result
  * @retval None
  */
#define COMPUTATION_DUALMODEINTERLEAVED_ADCSLAVE_RESULT(DATA)                  \
  ((DATA) >> 16)

With regards, Rania

dwalkes commented 6 months ago

HAL_ADCEx_MultiModeStart_DMA call aADCDualConvertedValues as the pData Destination Buffer address parameter and not aADCxConvertedValues

Sorry, my mistake, I missed that the aADCDualConvertedValues was uint32_t