cancel
Showing results for 
Search instead for 
Did you mean: 

ADC scan with DMA only pulls the first sample and then seems to stop and sets OVR if transfer set to CONT

DGoel.11
Associate

I am trying to set up the ADC to continuously scan a few channels in the background and store them in an array automatically using the DMA. I have been trying a vast number of things to get this work. If i don't set the the ADC to run in CONT then the OVR bit doesn't get set but I still only get one of my values in my array. I have been trying to figure this out for days now with no luck, any help would be appreciated

Here's my code:

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file           : main.c
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
 * All rights reserved.</center></h2>
 *
 * This software component is licensed by ST under BSD 3-Clause license,
 * the "License"; You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                        opensource.org/licenses/BSD-3-Clause
 *
 ******************************************************************************
 */
/* USER CODE END Header */
 
#define len(x) sizeof(x)/sizeof((x)[0])
 
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx.h"
#include <stdio.h>
#include <stdarg.h>
 
void SystemClock_Config(void);
void printfToSerial(char buf[], ...);
void printToSerial(char buf[], int length);
 
uint16_t sensorReadings[2] = {0, 0}, s2[2];
 
int main(void)
{
 
	SystemClock_Config();
 
	//ADC Setup
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
	GPIOA->MODER |= 0xF;
 
	RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;
	ADC->CCR |= ADC_CCR_ADCPRE_0 | ADC_CCR_ADCPRE_1;
	ADC1->CR2 |= ADC_CR2_ADON | ADC_CR2_CONT;
	ADC1->CR1 |= ADC_CR1_SCAN;
	ADC1->CR2 |= ADC_CR2_DMA | ADC_CR2_DDS;
	ADC1->SMPR2 |= ADC_SMPR2_SMP1_1 | ADC_SMPR2_SMP0_1;
	ADC1->SQR1 |= 1 << ADC_SQR1_L_Pos;
	ADC1->SQR3 |= 1 << 5;
 
	//USART Setup
	RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
	GPIOD->MODER |= 0xA << GPIO_MODER_MODER8_Pos;
	GPIOD->AFR[1] |= 0x77;
 
	RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
	USART3->CR1 |= USART_CR1_UE;
	USART3->BRR |= 22 << USART_BRR_DIV_Mantissa_Pos | 13; //5 + 12/16 = 5.75
 
	HAL_Delay(1);
 
	//DMA Enable
	RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;
 
	DMA2_Stream4->PAR = (uint32_t) (&(ADC1->DR));
	DMA2_Stream4->M0AR = (uint32_t) (sensorReadings);
//	DMA2_Stream4->M1AR = (uint32_t) (&s2);
	DMA2_Stream4->NDTR = 2;
	DMA2_Stream4->CR |= DMA_SxCR_MSIZE_0 |
						DMA_SxCR_PSIZE_0 |
						DMA_SxCR_MINC |
						DMA_SxCR_CIRC |
						DMA_SxCR_PL_Msk;
 
	DMA2_Stream4->CR = DMA_SxCR_EN;
	ADC1->CR2 |= ADC_CR2_SWSTART;
 
	while (1)
	{
		//printfToSerial("%d, %d\n", sensorReadings[0], sensorReadings[1]);
	}
 
}
 
/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
	RCC_OscInitTypeDef RCC_OscInitStruct =
	{ 0 };
	RCC_ClkInitTypeDef RCC_ClkInitStruct =
	{ 0 };
	RCC_PeriphCLKInitTypeDef PeriphClkInitStruct =
	{ 0 };
 
	/** Configure the main internal regulator output voltage
	 */
	__HAL_RCC_PWR_CLK_ENABLE();
	__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
	/** Initializes the CPU, AHB and APB busses clocks
	 */
	RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
	RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
	RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
	RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
	RCC_OscInitStruct.PLL.PLLM = 4;
	RCC_OscInitStruct.PLL.PLLN = 168;
	RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
	RCC_OscInitStruct.PLL.PLLQ = 7;
	RCC_OscInitStruct.PLL.PLLR = 2;
	if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
	{
//    Error_Handler();
	}
	/** Initializes the CPU, AHB and APB busses clocks
	 */
	RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
			| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
	RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
	RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
	RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
	RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
 
	if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
	{
//    Error_Handler();
	}
	PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CLK48;
	PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48CLKSOURCE_PLLQ;
	if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
	{
//    Error_Handler();
	}
}
 
void printToSerial(char buf[], int length)
{
	USART3->CR1 |= USART_CR1_TE;
	for (int i = 0; i < length; i++)
	{
		if (buf[i] == 0)
			return;
		while (!(USART3->SR & USART_SR_TXE))
			;
		USART3->DR = buf[i];
	}
}
 
void printfToSerial(char buf[], ...)
{
	char str[32];
	va_list args;
	va_start(args, buf);
	vsprintf(str, buf, args);
	printToSerial(str, len(str));
	va_end(args);
}

0 REPLIES 0