Recent

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

avra

  • Hero Member
  • *****
  • Posts: 1951
    • Additional info
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.    */
  59.   LL_DMA_SetMemoryAddress(DMAx, Channel, DMA_InitStruct->MemoryOrM2MDstAddress);
  60.  
  61.   /*-------------------------- DMAx CPAR Configuration -------------------------
  62.    * Configure the peripheral or source base address with parameter :
  63.    * - PeriphOrM2MSrcAddress: DMA_CPAR_PA[31:0] bits
  64.    */
  65.   LL_DMA_SetPeriphAddress(DMAx, Channel, DMA_InitStruct->PeriphOrM2MSrcAddress);
  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
    • J-Software
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

thanks for replys

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;
  25.   RCC_CFGR_ADCPRE_DIV4 = $00004000;
  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;
  73. contador: word;
  74. contador2,
  75. contador3: word;
  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;
  86. ADC1Buffer: Array[0..4] of word;
  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,
  97. Contador_tick_segundos: word;
  98. marca: Boolean;
  99. i: Longword;
  100. Usart_ini: TUSART_InitTypeDef;
  101. NVIC_Ini: TNVIC_InitTypeDef;
  102. ADC_Ini: TADC_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!!
  119. inc (contador3);
  120. If contador3 >= 100 then    //0.1 s
  121.   begin
  122.   marca:= true;
  123.   contador3:= 0;
  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.  
  170. procedure ADC1_and_ADC2_global_interrupt;  public name 'ADC1_and_ADC2_global_interrupt';  interrupt;
  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
  189.     //wait pll ready
  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);
  204.  RCC_ADCCLKConfig(RCC_HCLK_Div2);  //12 MHz
  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.  
  231.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_4; //ADC
  232.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AIN;
  233.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
  234.   GPIO_Init(PortA, GPIO_InitStruct);
  235.  
  236.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_5; //ADC
  237.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AIN;
  238.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
  239.   GPIO_Init(PortA, GPIO_InitStruct);
  240.  
  241.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_6; //ADC
  242.   GPIO_InitStruct.GPIO_Mode:= GPIO_Mode_AIN;
  243.   GPIO_InitStruct.GPIO_Speed:= GPIO_Speed_2MHz;
  244.   GPIO_Init(PortA, GPIO_InitStruct);
  245.  
  246.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_7; //ADC
  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.  
  276.   GPIO_InitStruct.GPIO_Pin:= GPIO_Pin_0; //ADC aux
  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.  
  417.   contador:= cuenta_max - 2;
  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;
  505.     Inc(Contador);
  506.     Inc(Contador_tick_Segundos);
  507.     If Contador_tick_segundos >= 10 then
  508.         begin
  509.         Contador_tick_segundos:= 0;
  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
  518.       contador := 0;
  519.       if subiendo then contador2 += 2 else contador2 -= 2;
  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
    • J-Software
Re: stm32f103 dma problem
« Reply #21 on: July 16, 2020, 04:02:38 pm »
Yeah it's probably stuck in a hardfault handler

Try adding:
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

Try adding:
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

again thanks for your time

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:

https://stm32f4-discovery.net/2017/07/stm32-tutorial-efficiently-receive-uart-data-using-dma/

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
  106.     USART1_SendBytesViaDMA(TXBuffer1);
  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
    • J-Software
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:

https://stm32f4-discovery.net/2017/07/stm32-tutorial-efficiently-receive-uart-data-using-dma/

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 »
Sorry, cannot read your mind, which code are you talking about, yours or mine?

What I remember from your code is that you enabled Hardware Handshake, no Handshake->no transmit.

You have now a fairly stripped down example from me, when having issues, please create a minimalistic example that only does what needs to be done. Then I (and very likely also others) are happy to help.

 

TinyPortal © 2005-2018