Skip to main content
YSall.1
Senior
June 27, 2022
Question

I tried the Arbitrary waveform generation using timer DMA-burst feature but it doesn't work, can someone help me? F446RE

  • June 27, 2022
  • 5 replies
  • 2710 views

I'm trying to generate an arbitrary waveform on PA_5 pin, tim2 channel1 in PMW output, using stream5 channel3 DMA

I tried to do exactly what is written on the application note AN4776 using a nucleo F446RE but it doesn't work here are all my code:

dma.C

 
#include "stm32f4xx.h"
#include "dma.h"
 
#define RCC_AHB1ENR_DMA1_EN 		(1<<21) // Enable clock access to DMA1
#define DMA_PRIORITY_HIGH			((1<<17)|(1<<16)) // Very high priority
#define DMA_CIRCULAR				(1<<8) // Circular mode
#define DMA_MEMORY_TO_PERIPH		(1<<6) // DMA de la mémoire au périph
#define DMA_MINC_ENABLE				(1<<10) //Incrémentation de la zone de mémoire
#define DMA_CHANNEL_3				((1<<26)|(1<<25)) // Selection channel 3
#define DMA_MSIZE					(1<<14) // Les données de mémoire sont de types word 32bits
#define DMA_PSIZE					(1<<12) // Les données périphériques sont de types word 32bits
#define TIM2_DMAR_ADDRESS 			0x4000004C
 
 
void dmaInit(uint32_t * src)
{
 RCC->AHB1ENR |= RCC_AHB1ENR_DMA1_EN; // Enable clock access to DMA1
 
 DMA1_Stream5->CR = 0;
 
 DMA1_Stream5->CR |= DMA_MEMORY_TO_PERIPH | DMA_MINC_ENABLE|DMA_CIRCULAR | DMA_PRIORITY_HIGH|DMA_CHANNEL_3|DMA_MSIZE|DMA_PSIZE;
 
 DMA1_Stream5->NDTR = 9;
 
 DMA1_Stream5->PAR = TIM2_DMAR_ADDRESS ; // ARR Adress
 
 DMA1_Stream5->M0AR = src;
 
 NVIC_EnableIRQ(DMA1_Stream5_IRQn);
 
 DMA1_Stream5->CR|= (1<<0);
 
 
 // Manque l'autorisation des interruptions?
 
}

tim.C

#include "stm32f4xx.h"
#include "tim.h"
 
#define PW1	((1<<6)|(1<<5))
#define Preload1 (1<<3)
#define autoReload (1<<7)
#define TIM2EN		(1U<<0)
#define CR1_CEN		(1U<<0)
#define TIM_DMA_UPDATE	(1U<<8)
#define TIM2_DCR_DBL (1<<9) // 3 DMA burst transfer and start from ARR register
#define TIM2_DCR_DBA ((1<<0)|(1<<1))
 
 
 
 
void timInit(void)
 
{
 
 
	RCC->APB1ENR |=TIM2EN;
 
	/*Set prescaler value*/
	TIM2->PSC = 1 - 1 ;
 
	TIM2->ARR = 90000000 - 1;
 
	TIM2->CCR1= 45000000-1;
 
	TIM2->CNT = 0;
 
	TIM2->CR1 |= autoReload;
 
	TIM2->CCMR1 |= PW1 | Preload1;
 
 
	TIM2-> DIER|= TIM_DMA_UPDATE;
 
	TIM2-> DCR|= (TIM2_DCR_DBL | TIM2_DCR_DBA);// 3 DMA burst transfer and start from ARR register
 
	TIM2-> EGR|= TIM_EGR_UG;
 
	while((TIM2->EGR & TIM_EGR_UG) == SET){}
 
	TIM2->EGR |= TIM_EGR_UG;
 
	TIM2->BDTR|=TIM_BDTR_MOE;
 
	TIM2->CCER |= TIM_CCER_CC1E;
 
	TIM1->CR1 |= TIM_CR1_CEN;
 
	TIM2->CR1 |=CR1_CEN;
 
}

rcc.C

/*
 * rcc.c
 *
 * Created on: Jun 22, 2022
 * Author: ysalliege
 */
#include "stm32f4xx.h"
#include "rcc.h"
 
#define PLL_M 	8
#define PLL_N 	360
#define PLL_P 	0 // PLLP = 2
 
void rccInit(void)
{
 
	RCC->CR |= 1<<16;
	while (!(RCC->CR & (1<<17)));
 
	RCC->APB1ENR |= 1<<28;
 
	PWR->CR |= 3<<14;
 
	FLASH->ACR = (1<<8) | (1<<9)| (1<<10)| (5<<0);
 
	// AHB PR
	RCC->CFGR &= ~(1<<4);
 
	// APB1 PR
	RCC->CFGR |= (5<<10);
 
	// APB2 PR
	RCC->CFGR |= (4<<13);
 
	RCC->PLLCFGR = (PLL_M <<0) | (PLL_N << 6) | (PLL_P <<16) | (1<<22);
 
	RCC->CR |= (1<<24);
	while (!(RCC->CR & (1<<25)));
 
	RCC->CFGR |= (2<<0);
	while (!(RCC->CFGR & (2<<2)));
}

main.c

#include "stm32f4xx.h"
#include "dma.h"
#include "rcc.h"
#include "tim.h"
 
 
 
#define GPIOAEN		(1U<<0)
#define PIN5		(1U<<5)
#define LED_PIN		PIN5
#define AFR5_TIM	(1U<<20)
 
int main (void)
{
 
	uint32_t buffer32b[9] = {90000000, 0, 45000000, 180000000, 0, 90000000,90000000, 0, 45000000};
	/*GPIO INIT*/
 
	RCC->AHB1ENR |=GPIOAEN;
	GPIOA->MODER |=(1U<<10);
	GPIOA->MODER &=~(1U<<11);
	GPIOA->PUPDR |=(1U<<10);
	GPIOA->OSPEEDR|= ((1U<<10)|(1U<<11)); // High speed
	GPIOA->AFR[0] |=AFR5_TIM;
 
 
	rccInit();
	timInit();
	dmaInit(buffer32b);
 
	while(1)
	{
 
	}
}

This topic has been closed for replies.

5 replies

Andrew Neil
Super User
June 27, 2022

"it doesn't work"

You need to give more information.

What is it doing, and how does that differ from what you were expecting?

What testing / investigation / debugging have you done to find what's going on? What did you find?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
YSall.1
YSall.1Author
Senior
June 28, 2022

I was expecting to have a PWM signal with this buffer that contains the folowing registers ARR RCR and CCR1

uint32_t buffer32b[9] = {90000000, 0, 45000000, 180000000, 0, 90000000,90000000, 0, 45000000};

But I had nothing on output

Andrew Neil
Super User
June 28, 2022

How are you observing the output?

Is the code actually running?

Is the hardware correct?

Have you done a basic test to see if you can just toggle the pin with a simple loop, setting it high & low?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
waclawek.jan
Super User
June 28, 2022

> // 3 DMA burst transfer and start from ARR register

> #define TIM2_DCR_DBA ((1<<0)|(1<<1))

This does not start from ARR.

But, as I've said in the other thread, read out and check/post the relevent registers' content. They may be different from what you think they are.

JW

YSall.1
YSall.1Author
Senior
June 28, 2022

Thank you I got confused by the description of this register, I will look into it

YSall.1
YSall.1Author
Senior
June 28, 2022

I wrote in in decimal instead of hexa, correct value is 0x0000000BU

waclawek.jan
Super User
June 28, 2022

OK so does it work now?

JW

YSall.1
YSall.1Author
Senior
June 28, 2022

No it doesn't work even though I re defined DBA

#define TIM2_DCR_DBL (1<<9) // 3 DMA burst transfer and start from ARR register
#define TIM2_DCR_DBA ((1<<3)|(1<<1)|(1<<0))

YSall.1
YSall.1Author
Senior
June 28, 2022

1011b=0xB

waclawek.jan
Super User
July 1, 2022

> It works now, but with HAL librairies using this function

So, you can read out and check/compare registers content between the HAL and non-HAL versions, to see why your non-HAL version does not work.

This

TIM_DMABURSTLENGTH_4TRANSFERS

and this

#define TIM2_DCR_DBL (1<<9) // 3 DMA burst transfer and start from ARR register

seem to be different, though.

JW

Andrew Neil
Super User
July 1, 2022

Or step through the HAL code to see what it's doing - then do that in your own code.

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.