Skip to main content
DGoel.11
Visitor II
March 19, 2020
Question

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

  • March 19, 2020
  • 0 replies
  • 466 views

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);
}

This topic has been closed for replies.