cancel
Showing results for 
Search instead for 
Did you mean: 

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

YSall.1
Senior

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

20 REPLIES 20

So work from that, and step through your original code to see where it differs ...

Allright thank you for your help

> // 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

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

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

OK so does it work now?

JW

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
Senior

1011b=0xB

It works now, but with HAL librairies using this function

HAL_TIM_DMABurst_MultiWriteStart(&htim2, TIM_DMABASE_ARR, TIM_DMA_UPDATE, (uint32_t*)aSRC_Buffer, TIM_DMABURSTLENGTH_4TRANSFERS, 6);

> 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