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-07-01 04:35 AM
Or step through the HAL code to see what it's doing - then do that in your own code.