2023-05-29 04:34 AM
Hello everyone, I ve been trying to implement DMA ADC to ping-pong example for 5-6 days.
I made HAL_ADC_PollForConversion made without problem. When I try to implement dma + adc, it return 0.
I reviewed lorawan adc.c example for polling (there is no dma example).
I added these on sys_app.c
static void Gpio_PreInit(void)
{
/* USER CODE BEGIN Gpio_PreInit_1 */
/* USER CODE END Gpio_PreInit_1 */
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Configure all IOs in analog input */
/* Except PA143 and PA14 (SWCLK and SWD) for debug*/
/* PA13 and PA14 are configured in debug_init */
/* Configure all GPIO as analog to reduce current consumption on non used IOs */
/* Enable GPIOs clock */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
/* All GPIOs except debug pins (SWCLK and SWD) */
GPIO_InitStruct.Pin = GPIO_PIN_All & (~(GPIO_PIN_13 | GPIO_PIN_14));
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* All GPIOs */
GPIO_InitStruct.Pin = GPIO_PIN_All;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
HAL_GPIO_Init(GPIOH, &GPIO_InitStruct);
/* Disable GPIOs clock */
__HAL_RCC_GPIOA_CLK_DISABLE();
__HAL_RCC_GPIOB_CLK_DISABLE();
__HAL_RCC_GPIOC_CLK_DISABLE();
__HAL_RCC_GPIOH_CLK_DISABLE();
/* USER CODE BEGIN Gpio_PreInit_2 */
/* USER CODE END Gpio_PreInit_2 */
}
I add adc.c like this:
/* Includes ------------------------------------------------------------------*/
#include "adc.h"
ADC_HandleTypeDef hadc;
/* ADC init function */
void MX_ADC_Init(void)
{
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
ADC_ChannelConfTypeDef sConfig = {0};
hadc.Instance = ADC;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc.Init.Resolution = ADC_RESOLUTION_12B;
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
hadc.Init.LowPowerAutoWait = DISABLE;
hadc.Init.LowPowerAutoPowerOff = DISABLE;
hadc.Init.ContinuousConvMode = ENABLE;
hadc.Init.NbrOfConversion = 1;
hadc.Init.DiscontinuousConvMode = DISABLE;
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = ENABLE;
hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
hadc.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_39CYCLES_5;
hadc.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_160CYCLES_5;
hadc.Init.OversamplingMode = DISABLE;
hadc.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
/* Configure Regular Channel */
sConfig.Channel = ADC_CHANNEL_3;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
{
Error_Handler();
}
}
void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{
if(adcHandle->Instance==ADC)
{
/* USER CODE BEGIN ADC_MspInit 0 */
/* USER CODE END ADC_MspInit 0 */
/* ADC clock enable */
__HAL_RCC_ADC_CLK_ENABLE();
/* USER CODE BEGIN ADC_MspInit 1 */
/* USER CODE END ADC_MspInit 1 */
}
}
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{
if(adcHandle->Instance==ADC)
{
/* USER CODE BEGIN ADC_MspDeInit 0 */
/* USER CODE END ADC_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_ADC_CLK_DISABLE();
/* USER CODE BEGIN ADC_MspDeInit 1 */
/* USER CODE END ADC_MspDeInit 1 */
}
}
In my ping-pong example, in subghz_phy_app.c I added this function:
void SubghzApp_Init(void)
{
/* USER CODE BEGIN SubghzApp_Init_1 */
MX_DMA_Init();
MX_ADC_Init();
ADXL345_Init();
.
.
.
}
static void ADC_ReadChannels(void)
{
/* USER CODE BEGIN ADC_ReadChannels_1 */
/* USER CODE END ADC_ReadChannels_1 */
/* Start Calibration */
//if (HAL_ADCEx_Calibration_Start(&hadc) != HAL_OK)
//{
// Error_Handler();
// }
if (HAL_ADC_Start(&hadc) != HAL_OK)
{
/* Start Error */
Error_Handler();
}
/** Wait for end of conversion */
HAL_ADC_PollForConversion(&hadc, 1);
/** Wait for end of conversion */
HAL_ADC_Stop(&hadc) ; /* it calls also ADC_Disable() */
ADCxConvertedValues = HAL_ADC_GetValue(&hadc);
/* USER CODE BEGIN ADC_ReadChannels_2 */
/* USER CODE END ADC_ReadChannels_2 */
}
While doing these, when I call ADC_ReadChannels(); function in 10 ms timer, I can get ADC data with polling.
When I change ADC_ReadChannels like this:
void SubghzApp_Init(void)
{
MX_DMA_Init();
MX_ADC_Init();
ADXL345_Init();
ADC_ReadChannels();
}
static void ADC_ReadChannels(void)
{
HAL_ADC_Start_DMA(&hadc, (uint32_t*) rxBuf, 8192);
}
rxBuf returns 0. How can I get data with adc dma ? Can you please help, I couldn't find any example.
my dma settings on dma.c
#include "dma.h"
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMAMUX1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/* DMA1_Channel5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
}
2023-05-29 05:12 AM
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{
callback_state = 1;
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
callback_state = 2;
}
callback_state doesnt't change always 0.
2023-05-29 02:09 PM
I seem to remember that by default the sequencer is set up to send the stm32 into a deep power-saving mode when there are no tasks to run. That power-saving mode turns off HS oscillator as well as stopping the processor - killing any DMA or TIMER activity you have set up.
I don’t remember the details but there is a #define to disable deep sleep.
Hope this helps,
Danish