cancel
Showing results for 
Search instead for 
Did you mean: 

DMA to TIM3 CCR1 problem!

mikael239955_stm1_st
Associate III
Posted on August 08, 2015 at 05:21

Hi! Device is STM32F103C8

A update event from TIM4 is used to trigger DMA channel7 who then is supposed to transfer 9 values in circular mode

to TIM3 CCR1. However the DMA transfers only one value and that one is set to 0 and the rest is set to 127!?

So what i get is narrow pulse on CCR1 going round at the speed of TIM4 update event.

1.

#include ''stm32f10x.h''

2.

uint8_t buffer[9] = {0,16,32,48,64,80,96,112,127};

void tim4(void)

{

/************************* Tim4 ****************************************************/

TIM4->CCMR1 |= 0b0110000001100000; //OCM1 is set to PWM1 mode and OCM2 is set to PWM1 mode

TIM4->CCMR2 |= 0b0110000001100000; //OCM3 is set to PWM1 mode and OCM4 is set to PWM1 mode

TIM4->CCER |= TIM_CCER_CC1E; //Capture/Compare 1 output enable

TIM4->CCER |= TIM_CCER_CC2E; //Capture/Compare 2 output enable

TIM4->CCER |= TIM_CCER_CC3E; //Capture/Compare 1 output enable

TIM4->CCER |= TIM_CCER_CC4E; //Capture/Compare 2 output enable

TIM4->PSC = 8192;

TIM4->ARR = 1;

TIM4->CCR1 = 1; //CCR1 register set to initial PWM1 value

TIM4->CCR2 = 1; //CCR2 register set to initial PWM2 value

TIM4->CCR3 = 1;

TIM4->CCR4 = 1;

TIM4->DIER |= TIM_DIER_UDE; //DMA request on tim4 Update event

TIM4->BDTR |= TIM_BDTR_MOE; //Enable output stage

//TIM4->CR2 |= TIM_CR2_CCDS; //DMA request on Update event

TIM4->CR1 |= TIM_CR1_CEN; //Enable Timer4

}

void

tim3(

void

)

{

/************ Tim3 ********************************************************************/

TIM3->CCMR1 |= 0b0110000001100000;

//OCM1 is set to PWM1 mode and OCM2 is set to PWM1 mode

TIM3->CCMR2 |= 0b0110000001100000;

//OCM3 is set to PWM1 mode and OCM4 is set to PMW1 mode

TIM3->CCER |= TIM_CCER_CC1E;

//Capture/Compare 1 output enable

TIM3->CCER |= TIM_CCER_CC2E;

//Capture/Compare 2 output enable

TIM3->CCER |= TIM_CCER_CC3E;

//Capture/Compare 3 output enable

TIM3->CCER |= TIM_CCER_CC4E;

//Capture/Compare 4 output enable

TIM3->PSC = 0;

TIM3->ARR = 127;

TIM3->CCR1 = 64;

//CCR1 register set to initial PWM1 value

TIM3->CCR2 = 64;

//CCR2 register set to initial PWM2 value

TIM3->CCR3 = 64;<br>

TIM3->CCR4 = 64;<br>

TIM3->BDTR |= TIM_BDTR_MOE;

//Enable output stage

TIM3->CR1 |= TIM_CR1_CEN;

//Enable Timer3

}

void

dma1(

void

)

{

/**************** DMA configuration......DMA ch7 triggered by TIM4 UD ***********************************/

DMA1_Channel7->CCR = 0;

//Reset CCR

DMA1->IFCR = 0;

//Clear all pending (old) DMA1 Stream's interrupts

DMA1_Channel7->CNDTR = 9;

//Number of DMA transfers

DMA1_Channel7->CMAR |= (uint32_t)&buffer;

//Source, should fetch data from buffer!??!

DMA1_Channel7->CPAR |= (uint32_t)&(TIM3->CCR1);

//Destination, TIM3 CCR1

//DMA1_Channel7->CCR |= DMA_CCR7_PSIZE_0; //Set peripheral size to 16bits

//DMA1_Channel7->CCR |= DMA_CCR7_MSIZE_0; //Set memory size to 16bits

DMA1_Channel7->CCR |= DMA_CCR7_DIR;

//Read from memory to peripheral

DMA1_Channel7->CCR |= DMA_CCR7_MINC;

//Memory increment enabled

//DMA1_Channel7->CCR |= DMA_CCR7_MEM2MEM; //Memory to memory enabled

//DMA1_Channel7->CCR |= DMA_CCR7_PINC; //Peripheral increment enabled

DMA1_Channel7->CCR |= DMA_CCR7_CIRC;

//DMA set to circular mode

DMA1_Channel7->CCR |= DMA_CCR7_PL;

//Channel Priority level set to very high

DMA1_Channel7->CCR |= DMA_CCR7_EN;

//DMA channel7 enabled

}

2 REPLIES 2
Posted on August 08, 2015 at 22:35

Check the DMA channel - NDTR should change as TIM4 updates happen. Check also the DMA error flags.

Maybe the following kicked in: RM0008, 4: The peripheral registers can be accessed by half-words (16-bit) or words (32-bit). Minor remarks:

DMA1_Channel7->CMAR |= (uint32_t)&buffer; 
//Source, should fetch data from buffer!??!


DMA1_Channel7->CPAR |= (uint32_t)&(TIM3->CCR1); 
//Destination,

I wouldn't |=. Also , TIM4 does not have _BDTR. JW
mikael239955_stm1_st
Associate III
Posted on August 09, 2015 at 02:11

Yes your right Jan, removed TIM4_BDTR and TIM3_BDTR and |

When i change CCR7_PSIZE and CCR7_MSIZE from 8 to , 16 or 32 all i get is a change of number of high and low states on TIM3 CCR1 pin , no actual fetch of values from the array seams to happen.

But the number of transactions correlates with the number of update events when i look on the oscilloscope.

In 13.3.5 Error management it says:

>When a DMA transfer error occurs during a DMA read or a write access, the faulty channel is automatically disabled through a hardware clear of its EN

So since CCR1 emits signals in sync with TIM4 update events DMA ch7 is not disabled and is working, if not the channel would be disabled and TEIF7 be set and no signals on CCR1 would be seen.