AnsweredAssumed Answered

dma issue when writing to TIM1->BDTR

Question asked by hage.mike on May 23, 2014
Latest reply on May 23, 2014 by hage.mike
whenever i perform the dma transfer, I always get a transfer error on the write to TIM1->BDTR.  If I write to a different peripheral register, such as TIM3->ARR, it succeeds.  Any thoughts?

001.TIM_TimeBaseInitTypeDef                                 TIM1_TimeBaseStructure;
002.TIM_OCInitTypeDef                               TIM1_OCInitStructure;
003.TIM_BDTRInitTypeDef                                         TIM1_BDTRInitStruct;
004.TIM_TimeBaseInitTypeDef                                 TIM3_TimeBaseStructure;
005.TIM_OCInitTypeDef                               TIM3_OCInitStructure;
006.GPIO_InitTypeDef                                GPIO_InitStructure;
007.RCC_ClocksTypeDef                                           RCC_Clocks;
008.uint16_t                                period;
009.uint8_t                                                                 dc = 30;
010.uint16_t                                pulse1;
011.uint16_t                                pulse2;
012.TIM_TypeDef const * tim1;
013.TIM_TypeDef const * tim3;
014.TIM_TypeDef const * tim8;
015.DMA_InitTypeDef sDMAInitStructureTx;
016. 
017. 
018.tim1 = (TIM_TypeDef*)TIM1_BASE;
019.tim3 = (TIM_TypeDef*)TIM3_BASE;
020.tim8 = (TIM_TypeDef*)TIM8_BASE;
021. 
022. 
023.RCC_GetClocksFreq(&RCC_Clocks);
024. 
025. 
026./* Compute the value for the ARR register to have a period of 350 KHz */
027.period = (RCC_Clocks.HCLK_Frequency / 350000 ) - 1;     
028. 
029. 
030./* Compute the CCR2 value */
031.pulse1 = (uint16_t) (((uint32_t) (100 - dc) * (period - 1)) / 100);
032. 
033. 
034./* Compute the CCR3 value */
035.pulse2 = (uint16_t) (((uint32_t) (dc) * (period - 1)) / 100);
036. 
037. 
038./* TIM3 clock enable */
039.RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 , ENABLE);
040. 
041. 
042./* GPIOB clock enable */
043.RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
044. 
045. 
046./* TIM1 clock enable */
047.RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 , ENABLE);
048. 
049. 
050./* DMA1 clock enable */
051.RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
052. 
053. 
054./* Initialize PB0, Alternative Function, 100Mhz, Output, Push-pull */
055.GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
056.GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
057.GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
058.GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
059.GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
060.GPIO_Init(GPIOB, &GPIO_InitStructure);
061.GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_TIM1);        
062.GPIO_PinAFConfig(GPIOB, GPIO_PinSource1, GPIO_AF_TIM1); 
063. 
064. 
065./* Timer Base configuration */
066.TIM_TimeBaseStructInit(&TIM1_TimeBaseStructure);
067.TIM1_TimeBaseStructure.TIM_Prescaler = 0;
068.TIM1_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
069.TIM1_TimeBaseStructure.TIM_Period = period;
070.TIM1_TimeBaseStructure.TIM_ClockDivision = 0;
071.TIM1_TimeBaseStructure.TIM_RepetitionCounter = 0;
072.TIM_TimeBaseInit(TIM1, &TIM1_TimeBaseStructure);
073. 
074. 
075./* Channel 2 output configuration */
076.TIM_OCStructInit(&TIM1_OCInitStructure);
077.TIM1_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
078.TIM1_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
079.TIM1_OCInitStructure.TIM_Pulse = pulse2;
080.TIM1_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
081.TIM1_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
082.TIM_OC2Init(TIM1, &TIM1_OCInitStructure);
083. 
084. 
085./* Enable Preload register on CCR2. */
086.TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
087. 
088. 
089./* Channel 3 output configuration */
090.TIM1_OCInitStructure.TIM_Pulse = pulse1;
091.TIM1_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
092.TIM1_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
093.TIM_OC3Init(TIM1, &TIM1_OCInitStructure);
094. 
095. 
096./* Enable Preload register on CCR3. */
097.TIM_OC3PreloadConfig(TIM1, TIM_OCPreload_Enable);
098. 
099. 
100.// Setup dead time register (p-fet delay)
101.TIM_BDTRStructInit(&TIM1_BDTRInitStruct);
102.TIM1_BDTRInitStruct.TIM_DeadTime = 0U;
103.TIM_BDTRConfig(TIM1, &TIM1_BDTRInitStruct);
104. 
105. 
106.// Setup Timer 1 output compare Ch1     (Used for timer 3 clock source)
107.TIM1_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;     // Timing mode only(no I/O output)
108.TIM1_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;    // don't care
109.TIM1_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;  // don't care
110.TIM1_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;       // don't care
111.TIM1_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;     // don't care
112.TIM1_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
113.TIM1_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
114.TIM1_OCInitStructure.TIM_Pulse = 1;
115.TIM_OC1Init(TIM1, &TIM1_OCInitStructure);
116.TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
117.TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_Update);       // Used to clock timer 3
118. 
119. 
120.// Setup Timer 3 to gate H-Bridge drive signals
121.TIM_TimeBaseStructInit(&TIM3_TimeBaseStructure);
122.TIM3_TimeBaseStructure.TIM_ClockDivision = 0;
123.TIM3_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
124.TIM3_TimeBaseStructure.TIM_Period = 1;           
125.TIM3_TimeBaseStructure.TIM_Prescaler = 0;
126.TIM_TimeBaseInit(TIM3, &TIM3_TimeBaseStructure);
127.TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_External1); // Clock timer 3 via timer 1
128.TIM_ITRxExternalClockConfig(TIM3, TIM_TS_ITR0);    // drive timer 3 via timer 1
129.TIM_ARRPreloadConfig(TIM3, ENABLE);             // Enable pre-load
130.TIM_SetAutoreload(TIM3, 1);
131. 
132. 
133.// Setup Timer 3 output compare 1 to load burst duration
134.TIM3_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
135.TIM3_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
136.TIM3_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
137.TIM3_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
138.TIM3_OCInitStructure.TIM_Pulse = 1;
139.TIM_OC1Init(TIM3, &TIM3_OCInitStructure);
140. 
141. 
142./* Enable Preload register on CCR1. */
143.TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
144. 
145. 
146.// Enable DMA channel 2
147.DMA_Cmd(DMA1_Stream2, DISABLE);
148. 
149. 
150.// Enable DMA channel 4
151.DMA_Cmd(DMA1_Stream4, DISABLE);
152. 
153. 
154.// Setup DMA 1 stream 4 to modulate fet drive on/off
155.DMA_StructInit(&sDMAInitStructureTx);
156.sDMAInitStructureTx.DMA_Channel = DMA_Channel_5;
157.sDMAInitStructureTx.DMA_PeripheralBaseAddr = (uint32_t)&(tim1->BDTR);
158.sDMAInitStructureTx.DMA_BufferSize = 2;
159.sDMAInitStructureTx.DMA_DIR = DMA_DIR_MemoryToPeripheral;
160.sDMAInitStructureTx.DMA_Memory0BaseAddr = (uint32_t)gBurstEnable;
161.sDMAInitStructureTx.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
162.sDMAInitStructureTx.DMA_MemoryInc = DMA_MemoryInc_Enable;
163.sDMAInitStructureTx.DMA_Mode = DMA_Mode_Circular;
164. 
165. 
166.sDMAInitStructureTx.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
167.sDMAInitStructureTx.DMA_PeripheralInc = DMA_PeripheralInc_Disable;      
168.sDMAInitStructureTx.DMA_Priority = DMA_Priority_VeryHigh;
169. 
170. 
171.// Initialize DMA
172.DMA_DeInit(DMA1_Stream4);
173.DMA_Init(DMA1_Stream4, &sDMAInitStructureTx);
174. 
175. 
176.// Setup DMA 1 stream 2 to update burst table
177.DMA_StructInit(&sDMAInitStructureTx);
178.sDMAInitStructureTx.DMA_Channel = DMA_Channel_5;
179.sDMAInitStructureTx.DMA_PeripheralBaseAddr = (uint32_t)&(tim3->ARR);
180.sDMAInitStructureTx.DMA_BufferSize = 8;
181.sDMAInitStructureTx.DMA_DIR = DMA_DIR_MemoryToPeripheral;
182.sDMAInitStructureTx.DMA_Memory0BaseAddr = (uint32_t)TimeData;
183.sDMAInitStructureTx.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
184.sDMAInitStructureTx.DMA_MemoryInc = DMA_MemoryInc_Enable;
185.sDMAInitStructureTx.DMA_Mode = DMA_Mode_Circular;
186.sDMAInitStructureTx.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
187.sDMAInitStructureTx.DMA_PeripheralInc = DMA_PeripheralInc_Disable;      
188.sDMAInitStructureTx.DMA_Priority = DMA_Priority_VeryHigh;
189. 
190. 
191.// Initialize DMA
192.DMA_DeInit(DMA1_Stream2);
193.DMA_Init(DMA1_Stream2, &sDMAInitStructureTx);
194. 
195. 
196.// Enable Timer DMA request on update
197.TIM_DMACmd(TIM3, TIM_DMA_CC1, ENABLE);
198.TIM_DMACmd(TIM3, TIM_DMA_Update, ENABLE);
199. 
200. 
201./* TIM1 Main Output Enable */
202.TIM_CtrlPWMOutputs(TIM1, ENABLE);
203. 
204. 
205./* TIM3 counter enable */
206.TIM_Cmd(TIM3, ENABLE);
207. 
208. 
209./* TIM1 counter enable */
210.TIM_Cmd(TIM1, ENABLE);
211. 
212. 
213.// Enable DMA channel 2
214.DMA_Cmd(DMA1_Stream2, ENABLE);
215. 
216. 
217.// Enable DMA channel 4
218.DMA_Cmd(DMA1_Stream4, ENABLE);
219.         
220./* forever... */
221.while (1) {
222.__asm("nop");
223.}

Outcomes