### Bookstore

 Computer Math and Games in Pascal (preview) Lazarus Handbook

### Author Topic: stm32f103 dma problem [SOLVED]  (Read 1764 times)

#### avra

• Hero Member
• Posts: 1951
##### Re: stm32f103 dma problem
« Reply #15 on: July 16, 2020, 09:13:38 am »
This is from one of the stm32f103*.h files at https://github.com/stm32duino/Arduino_Core_STM32:
Code: C  [Select][+][-]
1. typedef struct
2. {
3.   __IO uint32_t CCR;
4.   __IO uint32_t CNDTR;
5.   __IO uint32_t CPAR;
6.   __IO uint32_t CMAR;
7. } DMA_Channel_TypeDef;
8.
9. typedef struct
10. {
11.   __IO uint32_t ISR;
12.   __IO uint32_t IFCR;
13. } DMA_TypeDef;

Code: C  [Select][+][-]
1. #define PERIPH_BASE           0x40000000UL /*!< Peripheral base address in the alias region */
2.
3. #define APB1PERIPH_BASE       PERIPH_BASE
4. #define APB2PERIPH_BASE       (PERIPH_BASE + 0x00010000UL)
5. #define AHBPERIPH_BASE        (PERIPH_BASE + 0x00020000UL)
6.
7. #define DMA1_BASE             (AHBPERIPH_BASE + 0x00000000UL)
8. #define DMA1_Channel1_BASE    (AHBPERIPH_BASE + 0x00000008UL)
9. #define DMA1_Channel2_BASE    (AHBPERIPH_BASE + 0x0000001CUL)
10. #define DMA1_Channel3_BASE    (AHBPERIPH_BASE + 0x00000030UL)
11. #define DMA1_Channel4_BASE    (AHBPERIPH_BASE + 0x00000044UL)
12. #define DMA1_Channel5_BASE    (AHBPERIPH_BASE + 0x00000058UL)
13. #define DMA1_Channel6_BASE    (AHBPERIPH_BASE + 0x0000006CUL)
14. #define DMA1_Channel7_BASE    (AHBPERIPH_BASE + 0x00000080UL)

Code: C  [Select][+][-]
1. #define DMA1                ((DMA_TypeDef *)DMA1_BASE)
2. #define DMA1_Channel1       ((DMA_Channel_TypeDef *)DMA1_Channel1_BASE)
3. #define DMA1_Channel2       ((DMA_Channel_TypeDef *)DMA1_Channel2_BASE)
4. #define DMA1_Channel3       ((DMA_Channel_TypeDef *)DMA1_Channel3_BASE)
5. #define DMA1_Channel4       ((DMA_Channel_TypeDef *)DMA1_Channel4_BASE)
6. #define DMA1_Channel5       ((DMA_Channel_TypeDef *)DMA1_Channel5_BASE)
7. #define DMA1_Channel6       ((DMA_Channel_TypeDef *)DMA1_Channel6_BASE)
8. #define DMA1_Channel7       ((DMA_Channel_TypeDef *)DMA1_Channel7_BASE)

and here is relevant HAL driver code from stm32f1xx_ll_dma.c:
Code: C  [Select][+][-]
1. /**
2.   * @brief  De-initialize the DMA registers to their default reset values.
3.   * @param  DMAx DMAx Instance
4.   * @param  Channel This parameter can be one of the following values:
5.   *         @arg @ref LL_DMA_CHANNEL_1
6.   *         @arg @ref LL_DMA_CHANNEL_2
7.   *         @arg @ref LL_DMA_CHANNEL_3
8.   *         @arg @ref LL_DMA_CHANNEL_4
9.   *         @arg @ref LL_DMA_CHANNEL_5
10.   *         @arg @ref LL_DMA_CHANNEL_6
11.   *         @arg @ref LL_DMA_CHANNEL_7
12.   * @retval An ErrorStatus enumeration value:
13.   *          - SUCCESS: DMA registers are de-initialized
14.   *          - ERROR: DMA registers are not de-initialized
15.   */
16. uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel)
17. {
18.   DMA_Channel_TypeDef *tmp = (DMA_Channel_TypeDef *)DMA1_Channel1;
19.   ErrorStatus status = SUCCESS;
20.
21.   /* Check the DMA Instance DMAx and Channel parameters*/
22.   assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
23.
24.   tmp = (DMA_Channel_TypeDef *)(__LL_DMA_GET_CHANNEL_INSTANCE(DMAx, Channel));
25.
26.   /* Disable the selected DMAx_Channely */
27.   CLEAR_BIT(tmp->CCR, DMA_CCR_EN);
28.
29.   /* Reset DMAx_Channely control register */
30.   LL_DMA_WriteReg(tmp, CCR, 0U);
31.
32.   /* Reset DMAx_Channely remaining bytes register */
33.   LL_DMA_WriteReg(tmp, CNDTR, 0U);
34.
35.   /* Reset DMAx_Channely peripheral address register */
36.   LL_DMA_WriteReg(tmp, CPAR, 0U);
37.
38.   /* Reset DMAx_Channely memory address register */
39.   LL_DMA_WriteReg(tmp, CMAR, 0U);
40.
41.   if (Channel == LL_DMA_CHANNEL_1)
42.   {
43.     /* Reset interrupt pending bits for DMAx Channel1 */
44.     LL_DMA_ClearFlag_GI1(DMAx);
45.   }
46.   else if (Channel == LL_DMA_CHANNEL_2)
47.   {
48.     /* Reset interrupt pending bits for DMAx Channel2 */
49.     LL_DMA_ClearFlag_GI2(DMAx);
50.   }
51.   else if (Channel == LL_DMA_CHANNEL_3)
52.   {
53.     /* Reset interrupt pending bits for DMAx Channel3 */
54.     LL_DMA_ClearFlag_GI3(DMAx);
55.   }
56.   else if (Channel == LL_DMA_CHANNEL_4)
57.   {
58.     /* Reset interrupt pending bits for DMAx Channel4 */
59.     LL_DMA_ClearFlag_GI4(DMAx);
60.   }
61.   else if (Channel == LL_DMA_CHANNEL_5)
62.   {
63.     /* Reset interrupt pending bits for DMAx Channel5 */
64.     LL_DMA_ClearFlag_GI5(DMAx);
65.   }
66.
67.   else if (Channel == LL_DMA_CHANNEL_6)
68.   {
69.     /* Reset interrupt pending bits for DMAx Channel6 */
70.     LL_DMA_ClearFlag_GI6(DMAx);
71.   }
72.   else if (Channel == LL_DMA_CHANNEL_7)
73.   {
74.     /* Reset interrupt pending bits for DMAx Channel7 */
75.     LL_DMA_ClearFlag_GI7(DMAx);
76.   }
77.   else
78.   {
79.     status = ERROR;
80.   }
81.
82.   return status;
83. }

Code: C  [Select][+][-]
1. /**
2.   * @brief  Initialize the DMA registers according to the specified parameters in DMA_InitStruct.
3.   * @note   To convert DMAx_Channely Instance to DMAx Instance and Channely, use helper macros :
4.   *         @arg @ref __LL_DMA_GET_INSTANCE
5.   *         @arg @ref __LL_DMA_GET_CHANNEL
6.   * @param  DMAx DMAx Instance
7.   * @param  Channel This parameter can be one of the following values:
8.   *         @arg @ref LL_DMA_CHANNEL_1
9.   *         @arg @ref LL_DMA_CHANNEL_2
10.   *         @arg @ref LL_DMA_CHANNEL_3
11.   *         @arg @ref LL_DMA_CHANNEL_4
12.   *         @arg @ref LL_DMA_CHANNEL_5
13.   *         @arg @ref LL_DMA_CHANNEL_6
14.   *         @arg @ref LL_DMA_CHANNEL_7
15.   * @param  DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
16.   * @retval An ErrorStatus enumeration value:
17.   *          - SUCCESS: DMA registers are initialized
18.   *          - ERROR: Not applicable
19.   */
20. uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct)
21. {
22.   /* Check the DMA Instance DMAx and Channel parameters*/
23.   assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel));
24.
25.   /* Check the DMA parameters from DMA_InitStruct */
26.   assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
27.   assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
28.   assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode));
29.   assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode));
30.   assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize));
31.   assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize));
32.   assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData));
33.   assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
34.
35.   /*---------------------------- DMAx CCR Configuration ------------------------
36.    * Configure DMAx_Channely: data transfer direction, data transfer mode,
37.    *                          peripheral and memory increment mode,
38.    *                          data size alignment and  priority level with parameters :
39.    * - Direction:      DMA_CCR_DIR and DMA_CCR_MEM2MEM bits
40.    * - Mode:           DMA_CCR_CIRC bit
41.    * - PeriphOrM2MSrcIncMode:  DMA_CCR_PINC bit
42.    * - MemoryOrM2MDstIncMode:  DMA_CCR_MINC bit
43.    * - PeriphOrM2MSrcDataSize: DMA_CCR_PSIZE[1:0] bits
44.    * - MemoryOrM2MDstDataSize: DMA_CCR_MSIZE[1:0] bits
45.    * - Priority:               DMA_CCR_PL[1:0] bits
46.    */
47.   LL_DMA_ConfigTransfer(DMAx, Channel, DMA_InitStruct->Direction | \
48.                         DMA_InitStruct->Mode                   | \
49.                         DMA_InitStruct->PeriphOrM2MSrcIncMode  | \
50.                         DMA_InitStruct->MemoryOrM2MDstIncMode  | \
51.                         DMA_InitStruct->PeriphOrM2MSrcDataSize | \
52.                         DMA_InitStruct->MemoryOrM2MDstDataSize | \
53.                         DMA_InitStruct->Priority);
54.
55.   /*-------------------------- DMAx CMAR Configuration -------------------------
56.    * Configure the memory or destination base address with parameter :
57.    * - MemoryOrM2MDstAddress: DMA_CMAR_MA[31:0] bits
58.    */
60.
61.   /*-------------------------- DMAx CPAR Configuration -------------------------
62.    * Configure the peripheral or source base address with parameter :
63.    * - PeriphOrM2MSrcAddress: DMA_CPAR_PA[31:0] bits
64.    */
66.
67.   /*--------------------------- DMAx CNDTR Configuration -----------------------
68.    * Configure the peripheral base address with parameter :
69.    * - NbData: DMA_CNDTR_NDT[15:0] bits
70.    */
71.   LL_DMA_SetDataLength(DMAx, Channel, DMA_InitStruct->NbData);
72.
73.   return SUCCESS;
74. }
« Last Edit: July 16, 2020, 09:46:03 am by avra »
ct2laz - Conversion between Lazarus and CodeTyphon
bithelpers - Bit manipulation for standard types
pasettimino - Siemens S7 PLC lib

#### MiR

• Full Member
• Posts: 115
##### Re: stm32f103 dma problem
« Reply #16 on: July 16, 2020, 10:52:41 am »
Can you please send complete code for the working example that sends Hello via DMA?

What I am missing (for example) is your ISR routine for DMA, you enable DMA Interrupts, so you also need to handle the interrupts.

As Addresses match perfectly and (as assumed) word/longword access is also not the root cause it must be somewhere else, and disabling the DMA by writing to CCR cannot be it. Also Errata Sheet for STM32F103 says nothing about DMA, so I guess we are save there.

When I have complete code for a simple example I am willing to run that code through the debugger, but it does not make sense when bits and peaces are missing. And please keep the code simple, include the minimum code needed to successfully do the job.
« Last Edit: July 16, 2020, 01:13:47 pm by MiR »

#### kupferstecher

• Sr. Member
• Posts: 401
##### Re: stm32f103 dma problem
« Reply #17 on: July 16, 2020, 12:05:29 pm »
Code: Pascal  [Select][+][-]
1.  Usart1.CR1:= 0; //disable usart1
2.  Usart1.CR1:= Usart1.CR1 or %00000000001100;
3.  Usart1.CR2:= 0;
4.  Usart1.CR2:= Usart1.CR2 or %000000000000000;
5.  Usart1.CR3:= 0;
6.  Usart1.CR3:= Usart1.CR3 or %00010000000;
7.

Offtopic, but may be helpful: Once I translated the bit definitions to pascal, see attached file.

#### Laksen

• Hero Member
• Posts: 652
##### Re: stm32f103 dma problem
« Reply #18 on: July 16, 2020, 01:05:45 pm »
With the original code, when you say that it hangs how do you mean? Have you tried installing fault handlers?

Also what compiler version are you using? Trunk?

#### diego bertotti

• Jr. Member
• Posts: 61
##### Re: stm32f103 dma problem
« Reply #19 on: July 16, 2020, 02:59:06 pm »
hi

lazarus 2.1.0 fpc 3.3.1 on win10 64

this is the code

Code: Pascal  [Select][+][-]
1.
2. program torque_vfd_comm;
3.
4. uses cortexm3, stm32f103fw;
5.
6. const
7.   TIM_CR1_CEN : uInt16 = \$0001;            // Counter enable
8.   RCC_APB1ENR_TIM2EN : uInt32 = \$00000001; // TIM2 clock enabled
9.
10.   TIM_DIER_CC1IE : uInt16 = \$0002;         // Capture / Compare 1 interrupt enable
11.   TIM_SR_CC1IF : uInt16 = \$0002;           // Capture / Compare 1 interrupt flag
12.   TIM2_IRQn = 28;                          // TIM2 global interrupt
13.
14.   systick_counter_enable = 1;
15.   CTRL_TICKINT_Set = 2;
16.   Systick_IRQn = -1;
17.
18.   RCC_CR_PLLON = \$01000000;
19.   RCC_CR_CSSON = \$00080000;
20.   RCC_CR_HSEON = \$00010000;
21.   RCC_CR_HSION = \$00000001;
22.   RCC_CFGR_USBPRE = \$00400000;
23.   RCC_CFGR_PLLMULL6 = \$00100000;
24.   RCC_CFGR_PLLSRC = \$00010000;
26.   RCC_CFGR_HPRE_DIV2 = \$0000008;
27.   RCC_CFGR_SWS_PLL = \$00000008;
28.   RCC_CFGR_SW_PLL = \$00000002;
29.   RCC_CR_HSERDY = \$00020000;
30.   RCC_CR_HSIRDY = \$00000002;
31.   RCC_CR_PLLRDY = \$02000000;
32.   USART_RE =    \$00000004;
33.   USART_TE =    \$00000008;
34.   USART_IDLEIE = \$00000010;
35.   USART_RXNEIE = \$00000020;
36.   USART_TCIE =   \$00000040;
37.   USART_TXIE =   \$00000080;
38.   USART_PEIE =   \$00000100;
39.   USART_UE =     \$00002000;
40.   USART_DMAT =   \$00000080;
41.   USART_DMAR =   \$00000040;
42.
43.   Marcha_OUT =      \$0001;
44.   Para_OUT =        \$0002;
45.   Sentido_OUT =     \$0004;
46.   Marcha_local =    \$0010;
47.   Para_Local =      \$0020;
48.   Sentido_Local =   \$0040;
49.   Marcha_Remoto =   \$0100;
50.   Para_Remoto =     \$0200;
51.   Sentido_Remoto =  \$0400;
52.   Remoto_Local =    \$8000; //1= remoto
53.   Serial_buffer_size = 64;
54.
55.
56.
57.
58.
59. {\$O-}
60.
61.
62. Type
63.   TLed = bitpacked array[0..15] of boolean;
64.
65.
66.
67. var
68. PuertoA : TLed absolute PortA.ODR;
69. PuertoB : TLed absolute PortB.ODR;
70. PuertoC : TLed absolute PortC.ODR;
71. PuertoD : TLed absolute PortD.ODR;
72. LedC : TLed absolute PortC.ODR;
76. cuenta_max: word = 20;
77. subiendo: boolean = true;
78. PUsart: ^TUSARTRegisters;
79. PDMARegisters : ^LongWord;
80. RXBuffer1: Array [0..Serial_buffer_size-1] of byte;
81. TXBuffer1: Array [0..Serial_buffer_size-1] of byte;
82. RXBuffer2: Array [0..Serial_buffer_size-1] of byte;
83. TXBuffer2: Array [0..Serial_buffer_size-1] of byte;
84. RXBuffer3: Array [0..Serial_buffer_size-1] of byte;
85. TXBuffer3: Array [0..Serial_buffer_size-1] of byte;
87. RPM : word;
88. RPM_1,
89. RPM_2,
90. Presion_1,
91. Presion_2,
92. Temperatura_1,
93. Temperatura_2,
94. Caudal_1,
95. Caudal_2,
96. IO_Bits,
98. marca: Boolean;
99. i: Longword;
100. Usart_ini: TUSART_InitTypeDef;
101. NVIC_Ini: TNVIC_InitTypeDef;
103. I2C_Ini: TI2CRegisters;
104. TIMER_Ini: TIM_TimeBaseInitTypeDef;
105. Timer_OC_INI: TIM_OCInitTypeDef;
106. Timer_IC_INI: TIM_ICInitTypeDef;
107. GPIOx: TPortRegisters;
108. GPIO_InitStruct: TGPIO_InitTypeDef;
109. DMAChannel: TDMAChannel;
110. DMA_InitTypeDef: TDMA_InitTypeDef;
111. DMARegisters: TDMARegisters;
112. tmpreg: longword;
113. RCC_Clocks: TRCC_ClocksTypeDef;
114. PByte: ^Byte;
115. AUX_B: Byte;
116.
117. procedure SysTick_interrupt; public name 'SysTick_interrupt';  interrupt;
118. begin       // 1 ms!!
120. If contador3 >= 100 then    //0.1 s
121.   begin
122.   marca:= true;
124.   end;
125. end;
126.
127. procedure Timer2_Interrupt; public name 'TIM2_global_interrupt';  interrupt;
128.   begin
129.     TIMER2.SR  := TIMER2.SR and not TIM_SR_CC1IF; // Clear CC1IF
130.
131.   end;
132.
133.
134. procedure DMA1_Channel1_global_interrupt; public name 'DMA1_Channel1_global_interrupt';  interrupt;
135. Begin
136.     dmaregisters.ifcr:= \$0FFFFFFF;
137.
138. end;
139.
140. procedure DMA1_Channel2_global_interrupt; public name 'DMA1_Channel2_global_interrupt';  interrupt;
141. Begin
142.       dmaregisters.ifcr:= \$0FFFFFFF;
143. end;
144.
145. procedure DMA1_Channel3_global_interrupt; public name 'DMA3_Channel1_global_interrupt';  interrupt;
146. Begin
147.        dmaregisters.ifcr:= \$0FFFFFFF;
148. end;
149.
150. procedure DMA1_Channel4_global_interrupt;  public name 'DMA4_Channel1_global_interrupt';  interrupt;
151. Begin
152.     dmaregisters.ifcr:= \$0FFFFFFF;
153. end;
154.
155. procedure DMA1_Channel5_global_interrupt; public name 'DMA5_Channel1_global_interrupt';  interrupt;
156. Begin
157.     dmaregisters.ifcr:= \$0FFFFFFF;
158. end;
159.
160. procedure DMA1_Channel6_global_interrupt; public name 'DMA6_Channel1_global_interrupt';  interrupt;
161. Begin
162.       dmaregisters.ifcr:= \$0FFFFFFF;
163. end;
164.
165. procedure DMA1_Channel7_global_interrupt;  public name 'DMA7_Channel1_global_interrupt';  interrupt;
166. Begin
167.     dmaregisters.ifcr:= \$0FFFFFFF;
168. end;
169.
171. Begin
172.    dmaregisters.ifcr:= \$0FFFFFFF;
173. end;
174.
175. begin
176.
177.  //************************************************
178.  //**************** RCC  *************************
179.  //FLASH_SetLatency(1);
180.  RCC_HSICmd(Enabled);
181.  RCC_DeInit;
182.  RCC_HSICmd(Enabled);
183.  RCC_HSEConfig(RCC_HSE_On);
184.  RCC_WaitForHSEStartUp;
185.  RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_6); //48MHz
186.  RCC_PLLCmd(Enabled);
187.    while rcc.cr and  RCC_CR_PLLRDY = 0 do
188.     begin
190.     end;
191.  RCC_HCLKConfig(RCC_SYSCLK_Div1);
192.  RCC_PCLK1Config(RCC_HCLK_Div2); //24MHz
193.  RCC_PCLK2Config(RCC_HCLK_Div1); //48MHz
194.  RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
195.  while RCC_GetSYSCLKSource <> %1000 do //(RCC_SYSCLKSource_PLLCLK shl 2)
196.    begin
197.    //wait pll source
198.    end;
199.  RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1 or RCC_AHBPeriph_DMA2 or RCC_AHBPeriph_SRAM or RCC_AHBPeriph_FLITF, Enabled);
200.  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ALL, Enabled);
201.  //RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, Disabled);
202.  RCC_APB1PeriphClockCmd(RCC_APB1Periph_ALL, Enabled);
203.  //RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 or RCC_APB1Periph_I2C2 or RCC_APB1Periph_CAN, Disabled);
205.  RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); //48MHz
206.  RCC_ClockSecuritySystemCmd(Enabled);
207.  RCC_GetClocksFreq(RCC_Clocks);
208.
209. //************************************************
210. //**************** GPIO  *************************
211.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_0;  //RPM TIM2_1 input1
212.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_IPU;
213.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
214.   GPIO_Init(PortA, GPIO_InitStruct);
215.
216.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_1; //RTS USART2
217.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AF_PP;
218.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
219.   GPIO_Init(PortA, GPIO_InitStruct);
220.
221.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_2; //TX USART2
222.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AF_PP;
223.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
224.   GPIO_Init(PortA, GPIO_InitStruct);
225.
226.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_3; //RX USART2
227.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_IPU;
228.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
229.   GPIO_Init(PortA, GPIO_InitStruct);
230.
232.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AIN;
233.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
234.   GPIO_Init(PortA, GPIO_InitStruct);
235.
237.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AIN;
238.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
239.   GPIO_Init(PortA, GPIO_InitStruct);
240.
242.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AIN;
243.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
244.   GPIO_Init(PortA, GPIO_InitStruct);
245.
247.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AIN;
248.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
249.   GPIO_Init(PortA, GPIO_InitStruct);
250.
251.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_8;//para_local_in
252.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_IPU;
253.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
254.   GPIO_Init(PortA, GPIO_InitStruct);
255.
256.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_9; //TX USART1
257.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AF_PP;
258.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
259.   GPIO_Init(PortA, GPIO_InitStruct);
260.
261.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_10; //RX USART1
262.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_IPU;
263.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
264.   GPIO_Init(PortA, GPIO_InitStruct);
265.
266.   //11 usb
267.   //12 usb
268.   //13 swdio
269.   //14 swclk
270.
271.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_15; //marcha_local_in
272.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_IPU;
273.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
274.   GPIO_Init(PortA, GPIO_InitStruct);
275.
277.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AIN;
278.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
279.   GPIO_Init(PortB, GPIO_InitStruct);
280.
281.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_1; //rpm timer3_4
282.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_IPU;
283.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
284.   GPIO_Init(PortB, GPIO_InitStruct);
285.
286.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_2;//BOOT1
287.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_IPU;
288.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
289.   GPIO_Init(PortB, GPIO_InitStruct);
290.
291.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_3;//Sentido_local_in
292.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_IPU;
293.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
294.   GPIO_Init(PortB, GPIO_InitStruct);
295.
296.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_4;//Marcha_OUT
297.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_Out_PP;
298.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
299.   GPIO_Init(PortB, GPIO_InitStruct);
300.
301.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_5;//Para_OUT
302.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_Out_PP;
303.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
304.   GPIO_Init(PortB, GPIO_InitStruct);
305.
306.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_6;//RPM TIMER4_1
307.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_IPU;
308.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
309.   GPIO_Init(PortB, GPIO_InitStruct);
310.
311.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_7;//Sentido_OUT
312.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_Out_PP;
313.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
314.   GPIO_Init(PortB, GPIO_InitStruct);
315.
316.   GPIO_PinRemapConfig(GPIO_Remap_I2C1, enabled);
317.
318.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_8;//I2C1 SCL
319.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AF_OD;
320.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
321.   GPIO_Init(PortB, GPIO_InitStruct);
322.
323.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_9;//I2C1 SDA
324.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AF_OD;
325.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
326.   GPIO_Init(PortB, GPIO_InitStruct);
327.
328.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_10; //TX USART3
329.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AF_PP;
330.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
331.   GPIO_Init(PortB, GPIO_InitStruct);
332.
333.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_11; //RX USART3
334.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_IPU;
335.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
336.   GPIO_Init(PortB, GPIO_InitStruct);
337.
338.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_12;//Aux_OUT
339.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AF_PP;
340.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
341.   GPIO_Init(PortB, GPIO_InitStruct);
342.
343.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_13; //PWM OUT 1
344.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AF_PP;
345.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
346.   GPIO_Init(PortB, GPIO_InitStruct);
347.
348.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_14; //PWM OUT 2
349.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AF_PP;
350.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
351.   GPIO_Init(PortB, GPIO_InitStruct);
352.
353.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_15; //PWM OUT 3
354.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AF_PP;
355.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
356.   GPIO_Init(PortB, GPIO_InitStruct);
357.
358.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_13; //led interno
359.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_Out_PP;
360.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
361.   GPIO_Init(PortC, GPIO_InitStruct);
362.
363. //************************************************
364. //**************** USART *************************
365.
366.  Usart_ini.USART_BaudRate:= 9600;
367.  Usart_ini.USART_WordLength:= USART_WordLength_8b;
368.  Usart_ini.USART_StopBits:= USART_StopBits_1;
369.  Usart_ini.USART_Parity:= USART_Parity_No ;
370.  Usart_ini.USART_Mode:= USART_Mode_Rx or USART_Mode_Tx;
371.  Usart_ini.USART_HardwareFlowControl:= USART_HardwareFlowControl_None;
372.  Usart_ini.USART_Clock:= USART_Clock_Disable;
373.  Usart_ini.USART_CPOL:= USART_CPOL_Low;
374.  Usart_ini.USART_CPHA:= USART_CPHA_1Edge;
375.  Usart_ini.USART_LastBit:= USART_LastBit_Disable;
376.  USART_Init(USart1, Usart_ini);
377.  USART_Init(USart3, Usart_ini);
378.  Usart_ini.USART_HardwareFlowControl:= USART_HardwareFlowControl_RTS;
379.  USART_Init(USart2, Usart_ini);
380.
381.  USART_DMACmd(Usart1,USART_DMAReq_Tx  or USART_DMAReq_Rx ,Enabled);
382.  USART_DMACmd(Usart2,USART_DMAReq_Tx  or USART_DMAReq_Rx ,Enabled);
383.  USART_DMACmd(Usart3,USART_DMAReq_Tx  or USART_DMAReq_Rx ,Enabled);
384.  USART_ITConfig(Usart1, USART_IT_TC , enabled);
385.  USART_ITConfig(Usart2, USART_IT_TC , enabled);
386.  USART_ITConfig(Usart3, USART_IT_TC , enabled);
387.  Usart_Cmd(Usart1, ENABLED);
388.  Usart_Cmd(Usart2, ENABLED);
389.  Usart_Cmd(Usart3, ENABLED);
390.
391. //************************************************
392.  //**************** NVIC **************************
393.   NVIC_Ini.NVIC_IRQChannelPreemptionPriority:= 0;
394.   NVIC_Ini.NVIC_IRQChannelSubPriority:= 0;
395.   NVIC_Ini.NVIC_IRQChannel:= DMAChannel1_IRQChannel;
396.   NVIC_Init(NVIC_Ini);
397.   NVIC_Ini.NVIC_IRQChannel:= DMAChannel2_IRQChannel;
398.   NVIC_Init(NVIC_Ini);
399.   NVIC_Ini.NVIC_IRQChannel:= DMAChannel3_IRQChannel;
400.   NVIC_Init(NVIC_Ini);
401.   NVIC_Ini.NVIC_IRQChannel:= DMAChannel4_IRQChannel;
402.   NVIC_Init(NVIC_Ini);
403.   NVIC_Ini.NVIC_IRQChannel:= DMAChannel5_IRQChannel;
404.   NVIC_Init(NVIC_Ini);
405.   NVIC_Ini.NVIC_IRQChannel:= DMAChannel6_IRQChannel;
406.   NVIC_Init(NVIC_Ini);
407.   NVIC_Ini.NVIC_IRQChannel:= DMAChannel7_IRQChannel;
408.   NVIC_Init(NVIC_Ini);
409.   NVIC_Ini.NVIC_IRQChannelCmd:= Enabled;
410.
411. //***************************************************
412.   //******************** Systick **********************
413.   Systick.LOAD:= 6000;   // 1ms main loop
414.   SysTick.CTRL := SysTick.CTRL or CTRL_TICKINT_Set AND (not 4);// interrupt, AHB/8
415.   SysTick.CTRL := SysTick.CTRL or systick_counter_enable ; //enabled
416.
418.
419.   TXBuffer1[0]:= byte('h');
420.   TXBuffer1[1]:= byte('e');
421.   TXBuffer1[2]:= byte('l');
422.   TXBuffer1[3]:= byte('l');
423.   TXBuffer1[4]:= byte('o');
424.
425.
426.  tmpreg:= longWord(@DMA1.Channel[2].CCR);
427.    AUX_B:= Byte((tmpreg AND \$000000FF));
428.    TXBuffer1[5]:= AUX_B;
429.    AUX_B:= Byte((tmpreg  AND \$0000FF00) shr 8);
430.    TXBuffer1[6]:= AUX_B;
431.    AUX_B:= Byte((tmpreg  AND \$00FF0000) shr 16);
432.    TXBuffer1[7]:= AUX_B;
433.    AUX_B:= Byte((tmpreg  AND \$FF000000) shr 24);
434.    TXBuffer1[8]:= AUX_B;
435.    tmpreg:= longWord(@DMA1.Channel[2].res1);
436.    AUX_B:= Byte((tmpreg AND \$000000FF));
437.    TXBuffer1[9]:= AUX_B;
438.    AUX_B:= Byte((tmpreg  AND \$0000FF00) shr 8);
439.    TXBuffer1[10]:= AUX_B;
440.    AUX_B:= Byte((tmpreg  AND \$00FF0000) shr 16);
441.    TXBuffer1[11]:= AUX_B;
442.    AUX_B:= Byte((tmpreg  AND \$FF000000) shr 24);
443.    TXBuffer1[12]:= AUX_B;
444.    tmpreg:= longWord(@DMA1.Channel[2].CNDTR);
445.    AUX_B:= Byte((tmpreg AND \$000000FF));
446.    TXBuffer1[13]:= AUX_B;
447.    AUX_B:= Byte((tmpreg  AND \$0000FF00) shr 8);
448.    TXBuffer1[14]:= AUX_B;
449.    AUX_B:= Byte((tmpreg  AND \$00FF0000) shr 16);
450.    TXBuffer1[15]:= AUX_B;
451.    AUX_B:= Byte((tmpreg  AND \$FF000000) shr 24);
452.    TXBuffer1[16]:= AUX_B;
453.    tmpreg:= longWord(@DMA1.Channel[2].res2);
454.    AUX_B:= Byte((tmpreg AND \$000000FF));
455.    TXBuffer1[17]:= AUX_B;
456.    AUX_B:= Byte((tmpreg  AND \$0000FF00) shr 8);
457.    TXBuffer1[18]:= AUX_B;
458.    AUX_B:= Byte((tmpreg  AND \$00FF0000) shr 16);
459.    TXBuffer1[19]:= AUX_B;
460.    AUX_B:= Byte((tmpreg  AND \$FF000000) shr 24);
461.    TXBuffer1[20]:= AUX_B;
462.
463.  PDMARegisters := @DMA1 + \$44;   //CCR4
464.  PDMARegisters^:= %000000010110110;
465.  PDMARegisters := @DMA1 + \$48;   //CNDTR4
466.  PDMARegisters^:= 22;
467.  PDMARegisters := @DMA1 + \$4C;   //CPAR4
468.  PDMARegisters^:= LongWord(@Usart1.DR);
469.  PDMARegisters := @DMA1 + \$50;   //CMAR4
470.  PDMARegisters^:= LongWord(@TXBuffer1);
471.  Usart1.SR:= Usart1.SR and not %1000000;
472.  PDMARegisters := @DMA1 + \$44;   //CCR4
473.  PDMARegisters^:= PDMARegisters^ or %1;   //enable
474.
475.  PDMARegisters := @DMA1 + \$80;   //CCR7
476.  PDMARegisters^:= %000000010110110;
477.  PDMARegisters := @DMA1 + \$84;   //CNDTR7
478.  PDMARegisters^:= 5;
479.  PDMARegisters := @DMA1 + \$88;   //CPAR7
480.  PDMARegisters^:= LongWord(@Usart2.DR);
481.  PDMARegisters := @DMA1 + \$8c;   //CMAR7
482.  PDMARegisters^:= LongWord(@TXBuffer2);
483.  Usart2.SR:= Usart2.SR and not %1000000;
484.  PDMARegisters := @DMA1 + \$80;   //CCR7
485.  PDMARegisters^:= PDMARegisters^ or %1;   //enable
486.
487.  PDMARegisters := @DMA1 + \$1C;   //CCR2
488.  PDMARegisters^:= %000000010110110;
489.  PDMARegisters := @DMA1 + \$20;   //CNDTR2
490.  PDMARegisters^:= 5;
491.  PDMARegisters := @DMA1 + \$24;   //CPAR2
492.  PDMARegisters^:= LongWord(@Usart3.DR);
493.  PDMARegisters := @DMA1 + \$28;   //CMAR2
494.  PDMARegisters^:= LongWord(@TXBuffer3);
495.  Usart3.SR:= Usart3.SR and not %1000000;
496.  PDMARegisters := @DMA1 + \$1C;   //CCR2
497.  PDMARegisters^:= PDMARegisters^ or %1;   //enable
498.
499.  while true do
500.     begin
501.   //RPM:= 60000 div Usart2.BRR;
502.   If marca then
503.     begin
504.     marca:= False;
507.     If Contador_tick_segundos >= 10 then
508.         begin
510.         PuertoB[4]:= Not PuertoB[4];
511.         PuertoB[5]:= Not PuertoB[5];
512.         PuertoB[7]:= Not PuertoB[7];
513.         end;
514.     //if contador and 01 = 0 then LedC[13] := not LedC[13] else LedC[13] := true;
515.     if contador <= contador2 then LedC[13] := not LedC[13] else LedC[13] := true;
516.     if contador >= cuenta_Max then
517.       begin
520.       if contador2 > Cuenta_max then subiendo:= false;
521.       if contador2 = 0 then subiendo:= true;
522.       end;
523.     end;
524.
525.
526.     end;
527.  end.
528.
529.

but i think enabling, isr and all these are ok, because it work when i use bare metal code, then all the rest of code must be ok

look the attached image in previous post, was captured using logic analizer on usart1 output pin

again, thanks
« Last Edit: July 16, 2020, 03:01:22 pm by diego bertotti »

#### diego bertotti

• Jr. Member
• Posts: 61
##### Re: stm32f103 dma problem
« Reply #20 on: July 16, 2020, 03:06:22 pm »
With the original code, when you say that it hangs how do you mean? Have you tried installing fault handlers?

Also what compiler version are you using? Trunk?

my code make a blink in the internal led, but in a increasin and decreasing amount of blink fashion.

when i said it hangs, i mean led is allways on!!

Have you tried installing fault handlers? -> i thinking about it. not yet

Also what compiler version are you using? Trunk?-> 2.1.0 fpc 3.3.1 win10 64
« Last Edit: July 16, 2020, 03:33:59 pm by diego bertotti »

#### Laksen

• Hero Member
• Posts: 652
##### Re: stm32f103 dma problem
« Reply #21 on: July 16, 2020, 04:02:38 pm »
Yeah it's probably stuck in a hardfault handler

Code: Pascal  [Select][+][-]
1. SCB.SHCSR := SCB.SHCSR or (7 shl \$10);

and

Code: Pascal  [Select][+][-]
1. procedure hard_fault_handler_c(p: plongword; lr: longword);
2. begin
3.   writeln('Hardfault');
4.   writeln(' R0:  ', hexstr(p[0], 8));
5.   writeln(' R1:  ', hexstr(p[1], 8));
6.   writeln(' R2:  ', hexstr(p[2], 8));
7.   writeln(' R3:  ', hexstr(p[3], 8));
8.
9.   writeln(' R12: ', hexstr(p[4], 8));
10.   writeln(' LR:  ', hexstr(p[5], 8));
11.   writeln(' PC:  ', hexstr(p[6], 8));
12.   writeln(' PSR: ', hexstr(p[7], 8));
13.
14.   writeln(' LR:  ', hexstr(lr, 8));
15.   while true do;
16. end;
17.
18. procedure Hardfault_interrupt; assembler; nostackframe; [public, alias: 'Hardfault_interrupt'];
19. asm
20.   tst lr, #4
21.   mov r1, lr
22.   ite eq
23.   mrseq r0, msp
24.   mrsne r0, psp
25.   b hard_fault_handler_c
26. end;
27.
28. procedure MemManage_interrupt_C(p: plongword; ALR: longword);
29. begin
30.   writeln('MemManage_interrupt');
31.   writeln(' LR:  ', hexstr(p[5], 8));
32.   writeln(' PC:  ', hexstr(p[6], 8));
33.
34.   writeln(' MMFSR: ', hexstr(scb.CFSR and \$FF, 8));
35.   writeln(' MMFAR: ', hexstr(scb.MMFAR, 8));
36.
37.   while true do;
38. end;
39.
40. procedure MemManage_interrupt; assembler; nostackframe; [public, alias: 'MemManage_interrupt'];
41. asm
42.   tst lr, #4
43.   mov r1, lr
44.   ite eq
45.   mrseq r0, msp
46.   mrsne r0, psp
47.   b MemManage_interrupt_c
48. end;
49.
50. procedure BusFault_interrupt_C(p: plongword; ALR: longword);
51. begin
52.   writeln('BusFault');
53.   writeln(' LR:  ', hexstr(p[5], 8));
54.   writeln(' PC:  ', hexstr(p[6], 8));
55.
56.   writeln(' BFAR: ', hexstr(scb.BFAR, 8));
57.   while true do;
58. end;
59.
60. procedure BusFault_interrupt; assembler; nostackframe; [public, alias: 'BusFault_interrupt'];
61. asm
62.   tst lr, #4
63.   mov r1, lr
64.   ite eq
65.   mrseq r0, msp
66.   mrsne r0, psp
67.   b BusFault_interrupt_C
68. end;
69.
70. procedure UsageFault_interrupt_C(p: plongword; ALR: longword);
71. begin
72.   writeln('UsageFault');
73.   writeln(' LR:  ', hexstr(p[5], 8));
74.   writeln(' PC:  ', hexstr(p[6], 8));
75.   writeln(' UFSR: ', hexstr(SCB.CFSR shr 16, 4));
76.   while true do;
77. end;
78.
79. procedure UsageFault_interrupt; assembler; nostackframe; [public, alias: 'UsageFault_interrupt'];
80. asm
81.   tst lr, #4
82.   mov r1, lr
83.   ite eq
84.   mrseq r0, msp
85.   mrsne r0, psp
86.   b UsageFault_interrupt_C
87. end;
88.

That should give you a good idea about what's going on.

#### diego bertotti

• Jr. Member
• Posts: 61
##### Re: stm32f103 dma problem
« Reply #22 on: July 16, 2020, 05:01:50 pm »
Yeah it's probably stuck in a hardfault handler

Code: Pascal  [Select][+][-]
1. SCB.SHCSR := SCB.SHCSR or (7 shl \$10);

and

Code: Pascal  [Select][+][-]
1. procedure hard_fault_handler_c(p: plongword; lr: longword);
2. begin
3.   writeln('Hardfault');
4.   writeln(' R0:  ', hexstr(p[0], 8));
5.   writeln(' R1:  ', hexstr(p[1], 8));
6.   writeln(' R2:  ', hexstr(p[2], 8));
7.   writeln(' R3:  ', hexstr(p[3], 8));
8.
9.   writeln(' R12: ', hexstr(p[4], 8));
10.   writeln(' LR:  ', hexstr(p[5], 8));
11.   writeln(' PC:  ', hexstr(p[6], 8));
12.   writeln(' PSR: ', hexstr(p[7], 8));
13.
14.   writeln(' LR:  ', hexstr(lr, 8));
15.   while true do;
16. end;
17.
18. procedure Hardfault_interrupt; assembler; nostackframe; [public, alias: 'Hardfault_interrupt'];
19. asm
20.   tst lr, #4
21.   mov r1, lr
22.   ite eq
23.   mrseq r0, msp
24.   mrsne r0, psp
25.   b hard_fault_handler_c
26. end;
27.
28. procedure MemManage_interrupt_C(p: plongword; ALR: longword);
29. begin
30.   writeln('MemManage_interrupt');
31.   writeln(' LR:  ', hexstr(p[5], 8));
32.   writeln(' PC:  ', hexstr(p[6], 8));
33.
34.   writeln(' MMFSR: ', hexstr(scb.CFSR and \$FF, 8));
35.   writeln(' MMFAR: ', hexstr(scb.MMFAR, 8));
36.
37.   while true do;
38. end;
39.
40. procedure MemManage_interrupt; assembler; nostackframe; [public, alias: 'MemManage_interrupt'];
41. asm
42.   tst lr, #4
43.   mov r1, lr
44.   ite eq
45.   mrseq r0, msp
46.   mrsne r0, psp
47.   b MemManage_interrupt_c
48. end;
49.
50. procedure BusFault_interrupt_C(p: plongword; ALR: longword);
51. begin
52.   writeln('BusFault');
53.   writeln(' LR:  ', hexstr(p[5], 8));
54.   writeln(' PC:  ', hexstr(p[6], 8));
55.
56.   writeln(' BFAR: ', hexstr(scb.BFAR, 8));
57.   while true do;
58. end;
59.
60. procedure BusFault_interrupt; assembler; nostackframe; [public, alias: 'BusFault_interrupt'];
61. asm
62.   tst lr, #4
63.   mov r1, lr
64.   ite eq
65.   mrseq r0, msp
66.   mrsne r0, psp
67.   b BusFault_interrupt_C
68. end;
69.
70. procedure UsageFault_interrupt_C(p: plongword; ALR: longword);
71. begin
72.   writeln('UsageFault');
73.   writeln(' LR:  ', hexstr(p[5], 8));
74.   writeln(' PC:  ', hexstr(p[6], 8));
75.   writeln(' UFSR: ', hexstr(SCB.CFSR shr 16, 4));
76.   while true do;
77. end;
78.
79. procedure UsageFault_interrupt; assembler; nostackframe; [public, alias: 'UsageFault_interrupt'];
80. asm
81.   tst lr, #4
82.   mov r1, lr
83.   ite eq
84.   mrseq r0, msp
85.   mrsne r0, psp
86.   b UsageFault_interrupt_C
87. end;
88.

That should give you a good idea about what's going on.

thank you! ill try

but i must assign writeln to the usart1  or stdout or something like that

#### MiR

• Full Member
• Posts: 115
##### Re: stm32f103 dma problem
« Reply #23 on: July 17, 2020, 09:55:15 am »
I checked your code this morning, here's what I found:

You activate far more peripherals than you actually need which is bad for power consumption and can cause nice side effects when you experiment in different places. Tons of boilerplate code distract and you easily miss something important which I guess you did:

The thing that is wrong is that you have enabled transmission complete interrupts for uart and have no interrupt handlers for uart, this is the likely cause that your app crashes, has very little to do with DMA.

When using DMA then interrupts for serial should be turned off as the DMA controller takes over to handle the peripheral.

There is one exception which has to do with receiving in DMA Mode when you do not know how much data you actually will receive, please look at this very good article:

What I absolutely not understand is why you put on the burden of using DMA at all for communication with a VFD at 9600 Baud.

Sending data via DMA is one thing, it is elegant and uses close to no CPU but receiving (unknown length) results via DMA is a real pain.

For Baudrates as low as 9600 using interrupts for Serial is a lot more straightforward and good enough to get the job done.

Michael

#### MiR

• Full Member
• Posts: 115
##### Re: stm32f103 dma problem
« Reply #24 on: July 17, 2020, 01:47:29 pm »
I forgot in my last post that when an interrupt is not configured in nvic it does not fire....

The problem was indeed the 16-bit alignment of the fields, the processor creates an exception when the CNDTR field is accessed as HalfWord (16 Bits).

@Jeppe: Do you think you can patch this in the unit code @Trunk?
While at it, how do you think about changing the array index for dma from [0..6] to [1..7], that creates perhaps less confusion

So I stripped down your code and created this working example:

Code: Pascal  [Select][+][-]
1. program torque_vfd_comm;
2.
3. uses cortexm3, stm32f103fw;
4. {\$O-}
5.
6. const
7.   Serial_buffer_size = 7;
8.   DMA_CHANNEL4 = 3;
9.   PERIPH_BASE   = \$40000000;
10.   AHBPERIPH_BASE= PERIPH_BASE + \$00020000;
11.   DMA1_Channel4_BASE= AHBPERIPH_BASE + \$00000044;
12.
13. type
14.   TDMA_Channel_Registers = record
15.     CCR         : longword;
16.     CNDTR       : longword;
17.     CPAR        : longword;
18.     CMAR        : longword;
19.   end;
20.
21. var
22.   TXBuffer1: Array [0..Serial_buffer_size-1] of byte;
23.   Usart_ini: TUSART_InitTypeDef;
24.   NVIC_Ini: TNVIC_InitTypeDef;
25.   GPIO_InitStruct: TGPIO_InitTypeDef;
26.   RCC_Clocks: TRCC_ClocksTypeDef;
27.   DMA1_Channel4 : TDMA_Channel_Registers absolute DMA1_Channel4_BASE;
28.   i : integer;
29.
30. procedure DMA1_Channel4_global_interrupt;  public name 'DMA4_Channel1_global_interrupt';  interrupt;
31. Begin
32.   dma1.ifcr:= \$0FFFFFFF;
33. end;
34.
35. procedure USART1_SendBytesViaDMA(var Data : array of byte; const count : integer = -1);
36. begin
37.   //Disable DMA, Transfer Complete IRQ Read from Memory No Circular Mode No Periph Inc Memory Inc 8bit periph 8bit mem prio0
38.   DMA1_Channel4.CCR := %000000010010010;
39.   if count=-1 then
40.     DMA1_Channel4.CNDTR := High(Data)+1
41.   else
42.     DMA1_Channel4.CNDTR := Count;
43.   DMA1_Channel4.CPAR :=  LongWord(@Usart1.DR);
44.   DMA1_Channel4.CMAR := LongWord(@Data);
45.   DMA1_Channel4.CCR := DMA1_Channel4.CCR or %1;   //enable
46. end;
47.
48. begin
49.   //************************************************
50.   //**************** RCC  *************************
51.   //FLASH_SetLatency(1);
52.   RCC_HSICmd(Enabled);
53.   RCC_DeInit;
54.   RCC_HSICmd(Enabled);
55.   //For simplicity run on 8MHz internal Clock
56.   RCC_HCLKConfig(RCC_SYSCLK_Div1);
57.   RCC_PCLK1Config(RCC_HCLK_Div2); //24MHz
58.   RCC_PCLK2Config(RCC_HCLK_Div1); //48MHz
59.   RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1 or RCC_AHBPeriph_SRAM or RCC_AHBPeriph_FLITF, Enabled);
60.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_ALL, Enabled);
61.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_ALL, Enabled);
62.   RCC_GetClocksFreq(RCC_Clocks);
63.
64.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_9; //TX USART1
65.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AF_PP;
66.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
67.   GPIO_Init(PortA, GPIO_InitStruct);
68.
69.   //************************************************
70.   //**************** USART *************************
71.
72.   Usart_ini.USART_BaudRate:= 9600;
73.   Usart_ini.USART_WordLength:= USART_WordLength_8b;
74.   Usart_ini.USART_StopBits:= USART_StopBits_1;
75.   Usart_ini.USART_Parity:= USART_Parity_No;
76.   Usart_ini.USART_Mode:= USART_Mode_Tx;
77.   Usart_ini.USART_HardwareFlowControl:= USART_HardwareFlowControl_None;
78.   Usart_ini.USART_Clock:= USART_Clock_Disable;
79.   Usart_ini.USART_CPOL:= USART_CPOL_Low;
80.   Usart_ini.USART_CPHA:= USART_CPHA_1Edge;
81.   Usart_ini.USART_LastBit:= USART_LastBit_Disable;
82.   USART_Init(USart1, Usart_ini);
83.
84.   USART_DMACmd(Usart1,USART_DMAReq_Tx,Enabled);
85.
86.   Usart_Cmd(Usart1, ENABLED);
87.
88.   //************************************************
89.   //**************** NVIC **************************
90.   NVIC_Ini.NVIC_IRQChannelPreemptionPriority:= 0;
91.   NVIC_Ini.NVIC_IRQChannelSubPriority:= 0;
92.   NVIC_Ini.NVIC_IRQChannel:= DMAChannel4_IRQChannel;
93.   NVIC_Init(NVIC_Ini);
94.   NVIC_Ini.NVIC_IRQChannelCmd := Enabled;
95.
96.   TXBuffer1[0] := byte('h');
97.   TXBuffer1[1] := byte('e');
98.   TXBuffer1[2] := byte('l');
99.   TXBuffer1[3] := byte('l');
100.   TXBuffer1[4] := byte('o');
101.   TXBuffer1[5] := byte(#13);
102.   TXBuffer1[6] := byte(#10);
103.
104.   while true do
105.   begin
107.     //Quick hack, wait for tramsfer done....
108.     repeat
109.     until DMA1_Channel4.CNDTR = 0;
110.     //now waste some time so that we better see when transfer starts again
111.     for i := 1 to 100000 do
112.       ;
113.
114.   end;
115. end.
116.
« Last Edit: July 17, 2020, 01:52:48 pm by MiR »

#### Laksen

• Hero Member
• Posts: 652
##### Re: stm32f103 dma problem
« Reply #25 on: July 17, 2020, 02:00:28 pm »
What's the difference in the generated assembly with longword vs word access? The reference manual explicitly states that all the registers can be accessed with either byte, halfword or word accesses.

#### MiR

• Full Member
• Posts: 115
##### Re: stm32f103 dma problem
« Reply #26 on: July 17, 2020, 02:08:20 pm »
An STRH was created, after changing to 32bit an STR was created which then worked without creating an exception.

What I found strange was that the 16bit write to CCR actually worked with the original headers, only CNDTR had the issue.

By the way, for testing I used a Nucleo-F103RB Board, so my cpu is 100% geniue

Michael
« Last Edit: July 17, 2020, 02:12:16 pm by MiR »

#### diego bertotti

• Jr. Member
• Posts: 61
##### Re: stm32f103 dma problem
« Reply #27 on: July 17, 2020, 02:49:24 pm »
I checked your code this morning, here's what I found:

You activate far more peripherals than you actually need which is bad for power consumption and can cause nice side effects when you experiment in different places. Tons of boilerplate code distract and you easily miss something important which I guess you did:

The thing that is wrong is that you have enabled transmission complete interrupts for uart and have no interrupt handlers for uart, this is the likely cause that your app crashes, has very little to do with DMA.

When using DMA then interrupts for serial should be turned off as the DMA controller takes over to handle the peripheral.

There is one exception which has to do with receiving in DMA Mode when you do not know how much data you actually will receive, please look at this very good article:

What I absolutely not understand is why you put on the burden of using DMA at all for communication with a VFD at 9600 Baud.

Sending data via DMA is one thing, it is elegant and uses close to no CPU but receiving (unknown length) results via DMA is a real pain.

For Baudrates as low as 9600 using interrupts for Serial is a lot more straightforward and good enough to get the job done.

Michael

You activate far more peripherals than you actually need which is bad for power consumption and can cause nice side effects when you experiment in different places. Tons of boilerplate code distract and you easily miss something important which I guess you did: -> first i activate only needed peripheral, but after i see the problem, then i activate all, just in case....

What I absolutely not understand is why you put on the burden of using DMA at all for communication with a VFD at 9600 Baud.-> because is my first time with stm32 and just starting to know it. Really i need 3 usart and 1 i2c, at differents speeds and settings. Is just to learn.

now i'll try disabling transmission complete interrupts. but this must not be a problem in the deinit code...i guess,

again a lot of thanks!!!

#### diego bertotti

• Jr. Member
• Posts: 61
##### Re: stm32f103 dma problem
« Reply #28 on: July 17, 2020, 02:57:13 pm »
hi

me again!!

thaks for the support

now i found another problem.

using the bare metal working code posted before, i see nothing on usart3 tx pin (PB10). Usart1 and USART2 works fine!!

#### MiR

• Full Member
• Posts: 115
##### Re: stm32f103 dma problem
« Reply #29 on: July 17, 2020, 03:07:09 pm »