2022-06-27 07:47 AM
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)
{
}
}
2022-06-28 03:18 AM
So work from that, and step through your original code to see where it differs ...
2022-06-28 03:30 AM
Allright thank you for your help
2022-06-28 03:47 AM
> // 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
2022-06-28 04:48 AM
Thank you I got confused by the description of this register, I will look into it
2022-06-28 04:52 AM
I wrote in in decimal instead of hexa, correct value is 0x0000000BU
2022-06-28 05:33 AM
OK so does it work now?
JW
2022-06-28 05:39 AM
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))
2022-06-28 05:39 AM
1011b=0xB
2022-07-01 01:14 AM
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);
2022-07-01 04:28 AM
> 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