2021-12-10 04:41 AM
Hi,
I am trying to use the ADC with DMA but the values on the buffer are not being updated.
Next i detail the steps that i have done:
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct;
/* Disable the MPU */
HAL_MPU_Disable();
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x30000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_128KB;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.SubRegionDisable = 0x00;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enable the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
While running the ADC handler does not show any error, but the buffer remains empty, only updating the first index with trash values.
ADC Config:
static void MX_ADC1_Init(void)
{
/* USER CODE BEGIN ADC1_Init 0 */
/* USER CODE END ADC1_Init 0 */
ADC_MultiModeTypeDef multimode = {0};
ADC_ChannelConfTypeDef sConfig = {0};
/* USER CODE BEGIN ADC1_Init 1 */
/* USER CODE END ADC1_Init 1 */
/** Common config
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4;
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 = DISABLE;
hadc1.Init.NbrOfConversion = 3;
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;
hadc1.Init.OversamplingMode = DISABLE;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure the ADC multi-mode
*/
multimode.Mode = ADC_MODE_INDEPENDENT;
if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_16;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_32CYCLES_5;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
sConfig.OffsetSignedSaturation = DISABLE;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_17;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_18;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN ADC1_Init 2 */
/* USER CODE END ADC1_Init 2 */
}
ADC functions:
#define NADC_CH ((uint32_t) 3)
#define NADC_SAMPLES 30
#define ADC_VUSB_CH 0
#define ADC_5V_CH 1
#define ADC_AUX_CH 2
#if defined( __ICCARM__ )
#define DMA_BUFFER \
_Pragma("location=\".dma_buffer\"")
#else
#define DMA_BUFFER \
__attribute__((section(".dma_buffer")))
#endif
DMA_BUFFER uint16_t aADCxConvertedData[NADC_CH];
void adc_TimInt(TIM_HandleTypeDef *htim) {
if (htim->Instance == _TIMER_ADC.Instance)
{
if (HAL_ADC_GetState(&_ADC) & HAL_ADC_STATE_READY) {
if (HAL_ADC_Start_DMA(&_ADC, (uint32_t *)aADCxConvertedData, NADC_CH) != HAL_OK)
{
/* ADC conversion start error */
Error_Hand();
}
}
}
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *AdcHandle)
{
/* 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 *) &aADCxConvertedData[NADC_CH/2], NADC_CH);
ubDmaTransferStatus = 1;
adc_samples[ADC_VUSB_CH][ptr_adc_sample] = aADCxConvertedData[0];
adc_samples[ADC_5V_CH][ptr_adc_sample] = aADCxConvertedData[1];
adc_samples[ADC_AUX_CH][ptr_adc_sample] = aADCxConvertedData[2];
}
Any help would be really appreciated!
2021-12-10 05:23 AM
YOU CAN ALSO USE ADC WITHOUT MPU,why did you use mpu
2021-12-12 10:48 PM
I have also tried wihtout MPU but it did not work
2021-12-13 08:44 PM
Hi, Change MPU access in D2 RAM to sharable ...
BR
2021-12-23 12:26 AM
finally i changed it in order not to work with DMA... thanks for the help anyway
2022-04-17 08:13 PM
Hello all.
We have developed in the past some devices using the STM32F4 and F7 families, with no issues using ADC+DMA+Timer Triggering with no effort (mostly tweaking the examples provided by ST and using the ioc Cube files).
However, we are trying to do the same, but we are finding big issues with the H7 family, in specific when we use more than one ADC (to my knowledge this example is not provided by ST yet). There are also problems with the DMA (we have reader and moved the data buffers to RAM D2 area) and we do not see the triggering of the DMA interrupt with the Timer trigger.
Maybe somebody in the forum knows one repository or is able to share a simple example of this structure (if it is based on STM32Cubemx ioc file the better, since for it will be easier to add things).
Thank you in advance.