2024-09-10 02:16 PM
Hi Folks,
I'm working on pattern generation on GPIO pins and I've done it successfully using bare-metal programming approach. I used TIM1 to trigger DMA2 to take data from a buffer and send it GPIOA->BSRR.
But when I try to change the timer from TIM1 to TIM2 and change the respective DMA stream, the same code does not work.
code:
uint32_t signal1[6]; //pattern no included
// Enable clocks for GPIOA, TIM2, and DMA1
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
// Configure GPIOA Pins 0-5 as output
GPIOA->MODER &= ~0x00000FFF; // Clear mode for PA0-PA5
GPIOA->MODER |= 0x00000555; // Set PA0-PA5 as General Purpose Output
// Configure TIM2 for DMA requests on update event
TIM2->PSC = 0; // Set prescaler to 0
TIM2->ARR = 999; // Set auto-reload value (adjust for timing)
TIM2->DIER |= TIM_DIER_UDE; // Enable update DMA request
TIM2->CR1 |= TIM_CR1_CEN; // Enable TIM2
// Configure DMA1 Stream 5 for TIM2 Update
DMA1_Stream5->CR &= ~DMA_SxCR_EN; // Disable stream to configure
DMA1_Stream5->PAR = (uint32_t)&GPIOA->ODR; // Peripheral address (GPIOA ODR)
DMA1_Stream5->M0AR = (uint32_t)signal1; // Memory address (signal1 array)
DMA1_Stream5->NDTR = 6; // Number of data items
// Configure DMA control register
DMA1_Stream5->CR = (3 << DMA_SxCR_CHSEL_Pos) | // Channel 3 for TIM2_UP
(0 << DMA_SxCR_DIR_Pos) | // Memory-to-Peripheral
(2 << DMA_SxCR_MSIZE_Pos) | // Memory size: 32-bit
(2 << DMA_SxCR_PSIZE_Pos) | // Peripheral size: 32-bit
DMA_SxCR_MINC | // Memory increment mode
DMA_SxCR_CIRC; // Circular mode
// Enable DMA1 Stream 5
DMA1_Stream5->CR |= DMA_SxCR_EN;
// TIM2 will now trigger DMA transfers to output the pattern on GPIOA pins 0-5
This code does not work but if you change it to TIM1 and respective DMA stream it works. I checked and i get transfer error interrupt flag. Any help or direction is appreciated.