2023-09-14 09:40 PM - edited 2023-09-14 09:47 PM
Hi everyone,
I'm running into issues with setting up my STM32F746g-discovery board to pass 4 values from its ADC to the DMA. I've debugged this for hours and have been unable to find a solution. All of the pins I'm using (and their corresponding ADC ports) work fine on their own without scan mode and DMA enabled, but as soon as I enable scan mode, no values are printed to my adcValues[4] array. I've attached my main.c file for anyone who would be kind enough to have a look and tell me what (likely obvious) mistake I have made. I've got some other stuff in there, but I'm assuming it's simply an initialization error (although after debugging for so long, I'm not so sure). Clock is at 200Mhz. GPIO pins are configured for analog read and correspond to PA0, PF10, PF9 and PF8.
If downloading the main.c is too much, here are some snippets of my main loop to give an idea:
#include "main.h"
ADC_HandleTypeDef hadc3;
DMA_HandleTypeDef hdma_adc3;
CRC_HandleTypeDef hcrc;
DMA2D_HandleTypeDef hdma2d;
LTDC_HandleTypeDef hltdc;
TIM_HandleTypeDef htim4;
UART_HandleTypeDef huart4;
SDRAM_HandleTypeDef hsdram1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_TIM4_Init(void);
static void MX_LTDC_Init(void);
static void MX_UART4_Init(void);
static void MX_CRC_Init(void);
static void MX_DMA2D_Init(void);
static void MX_FMC_Init(void);
static void MX_ADC3_Init(void);
float rotationmain;
float rotationfactor;
float mixfactormain;
int countermain;
uint32_t adcValues[4] = {0}; // To store ADC values of channels 0-3
float adcvalue = 0;
float32_t* renderedModel;
TS_StateTypeDef ts;
char xTouchStr[10];
int main(void)
{
SCB_EnableICache();
SCB_EnableDCache();
HAL_Init();
SystemClock_Config();
BSP_SDRAM_Init();
MX_DMA_Init();
MX_GPIO_Init();
MX_TIM4_Init();
MX_LTDC_Init();
MX_UART4_Init();
MX_CRC_Init();
MX_DMA2D_Init();
MX_FMC_Init();
MX_ADC3_Init();
BSP_TS_Init(480, 272);
__HAL_RCC_CRC_CLK_ENABLE();
dsp3D_init();
HAL_ADC_Start_DMA(&hadc3, (uint32_t*)adcValues, 4);
SwitchState currentState = SWITCH_STATE_INVALID;
SwitchState previousState = SWITCH_STATE_INVALID;
and my initialization functions:
static void MX_ADC3_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
hadc3.Instance = ADC3;
hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV6;
hadc3.Init.Resolution = ADC_RESOLUTION_12B;
hadc3.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc3.Init.ContinuousConvMode = ENABLE;
hadc3.Init.DiscontinuousConvMode = DISABLE;
hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc3.Init.NbrOfConversion = 4;
hadc3.Init.DMAContinuousRequests = ENABLE;
hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = ADC_REGULAR_RANK_2;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfig.Channel = ADC_CHANNEL_7;
sConfig.Rank = ADC_REGULAR_RANK_3;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = ADC_REGULAR_RANK_4;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
}
Solved! Go to Solution.
2023-09-15 08:51 AM
@elib123 Have you tried using different external trigger conversion?
hadc3.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
ADC_SOFTWARE_START is a software parameter used for compatibility with other STM32 devices.
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-09-15 12:37 AM
Hello @elib123
The external trigger conversion ADC_SOFTWARE_START is discarded.
What is the start external event used to trigger the start of conversion?
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-09-15 07:21 AM
Thank you for your response! I thought that HAL_ADC_Start_DMA(&hadc3,(uint32_t*)adcValues, 4); would start the initial conversion and then would fill the adcValues buffer constantly using dma, overwriting the old data when new adc data is ready? Am I wrong about the way that works or perhaps just implementing it incorrectly?
2023-09-15 08:51 AM
@elib123 Have you tried using different external trigger conversion?
hadc3.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
ADC_SOFTWARE_START is a software parameter used for compatibility with other STM32 devices.
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-09-15 11:09 AM - edited 2023-09-16 02:44 PM
@FBL That did something, but there still seem to be some issues with the scan mode.
Now I get the first value recorded through to the adcValues[0] array, but then something breaks and everything stops. I get no values recorded to the other indexes of the array, and the value doesn't update. Also quite strangely, the pin that the value is recorded from seems to be mismatched. I checked the rankings though, and everything is ranked as expected, and I have tested the GPIO pins before in non-scan mode, and each of them worked.
So to summarize, only one value is converted right now, and it is to adcValues[0], but for some reason the input is from A2 instead of the expected A0.