STM32F103 USART1 + DMA1

General discussion on mikroPascal PRO for ARM.
Post Reply
Author
Message
Vit2
Posts: 77
Joined: 15 Apr 2015 10:00

STM32F103 USART1 + DMA1

#1 Post by Vit2 » 18 Oct 2023 11:48

Hey, everybody!
I can't figure out why it's not working. What am I doing wrong? I'm so confused.

Code: Select all

// DMA initialization procedure
procedure InitDMA;
begin
  // 1. Enable DMA1 clock
  RCC_AHBENR := EN_DMA1_CCR4_bit;

  // 2. Configure DMA interrupts: TCIE (Transfer Complete), HTIE (Half Transfer), TEIE (Transfer Error)
  TCIE_DMA1_CCR4_bit := 0;
  HTIE_DMA1_CCR4_bit := 0;
  TEIE_DMA1_CCR4_bit := 0;

  // 3. Configure the source data transfer direction
  // For example, if you're transmitting data from the memory to USART (TX), then:
  DIR_DMA1_CCR4_bit := 1;
  // Configure memory increment (memory address increment mode)
  MINC_DMA1_CCR4_bit := 1;

  // 4. Configure the channel priority
  DMA1_CCR4 := (DMA1_CCR4 and not $00030000); // Set the priority (PL Bits 19:18) to 00 (Low priority)

  // 5. Enable circular mode
  CIRC_DMA1_CCR4_bit := 1;
  PINC_DMA1_CCR4_bit := 0;

  // 6. Configure memory and peripheral data sizes
  PSIZE0_DMA1_CCR4_bit := 1; // Memory and peripheral data size: 8-bit
  MEM2MEM_DMA1_CCR4_bit := 0;

  // 7. Configure memory data size (MSIZE)
  MSIZE0_DMA1_CCR4_bit := 1; // Memory data size: 8-bit

  // 8. Configure the channel priority level
  PL0_DMA1_CCR4_bit := 1;

  // Enable the DMA channel
  DMA1_CCR4 := DMA1_CCR4 or EN_DMA1_CCR4_bit;
end;

procedure SendTextWithDMA(var Text: string);
begin
  // Copy the string to the buffer for transmission
  CopyStringToBuffer(Text, TextBuffer);

  // Enable DMA1 clock
  RCC_AHBENR := RCC_AHBENR or DMA1EN_bit;

  // Activate the DMA channel by setting the ENABLE bit in DMA1_CCR4
  DMA1_CCR4 := DMA1_CCR4 or EN_DMA1_CCR4_bit;

  // Configure DMA for USART1 data transmission (channel 4)
  DMA1_CNDTR4 := Length(Text); // Set the number of data items to be transferred
  DMA1_CMAR4 := dword(@TextBuffer[1]); // Set the memory address with data
  DMA1_CPAR4 := dword(@USART1_DR); // Set the peripheral address (USART1_DR)

  // Configure CCR (Control Register) for DMA1 channel 4
  MINC_DMA1_CCR4_bit := 1;
  PINC_DMA1_CCR4_bit := 1;
  DIR_DMA1_CCR4_bit := 1;

  // Enable the DMA channel
  DMA1_CCR4 := DMA1_CCR4 or EN_DMA1_CCR4_bit;

  // Wait for DMA to complete
  while DMA1EN_bit <> 0 do;

  // Disable USART1 transmission (if needed)
  USART1_CR1 := USART1_CR1 and not TE;
end;
          UART1_Init(115200);
    InitDMA;

AntiMember
Posts: 136
Joined: 02 Jan 2020 19:00

Re: STM32F103 USART1 + DMA1

#2 Post by AntiMember » 18 Oct 2023 20:52

DMAT_bit at USART1_CR3.B7;

Vit2
Posts: 77
Joined: 15 Apr 2015 10:00

Re: STM32F103 USART1 + DMA1

#3 Post by Vit2 » 20 Oct 2023 09:09

Thank you!
I can't figure out why it's not working! Without interrupts, should it work?
Thank you!

Code: Select all

procedure InitDMA;
begin
  RCC_AHBENR := RCC_AHBENR or EN_DMA1_CCR4_bit;

  DMA1_CCR4 := MEM2MEM_DMA1_CCR4_bit or
               PL0_DMA1_CCR4_bit or
               CIRC_DMA1_CCR4_bit or
               PINC_DMA1_CCR4_bit or
               MINC_DMA1_CCR4_bit or DIR_DMA1_CCR4_bit or
               PSIZE1_DMA1_CCR4_bit or PSIZE0_DMA1_CCR4_bit or
               MSIZE1_DMA1_CCR4_bit or MSIZE0_DMA1_CCR4_bit;
                 DMA1_CPAR4 := dword(@USART1_DR);
  DMA1_CMAR4 := dword(@TextBuffer[1]);
  DMA1_CNDTR4 := TextBuffer[1];//Length(Text);
  DMAT_bit:= 1;
end;

procedure SendTextWithDMA(var Text: string);
begin
  CopyStringToBuffer(Text, TextBuffer);
  while DMA1EN_bit <> 0 do;
  USART1_CR1 := USART1_CR1 and not TE;
end; 

Code: Select all

 UART1_Init_Advanced(115200, _UART_8_BIT_DATA, _UART_NOPARITY, _UART_ONE_STOPBIT, @_GPIO_MODULE_USART1_PA9_10);
  // UART1_Init(115200);
    InitDMA;

AntiMember
Posts: 136
Joined: 02 Jan 2020 19:00

Re: STM32F103 USART1 + DMA1

#4 Post by AntiMember » 20 Oct 2023 21:16

It should work without interrupts.
I didn't understand the design:

Code: Select all

  DMA1_CCR4 := MEM2MEM_DMA1_CCR4_bit or
               PL0_DMA1_CCR4_bit or
               CIRC_DMA1_CCR4_bit or
               PINC_DMA1_CCR4_bit or
               MINC_DMA1_CCR4_bit or DIR_DMA1_CCR4_bit or
               PSIZE1_DMA1_CCR4_bit or PSIZE0_DMA1_CCR4_bit or
               MSIZE1_DMA1_CCR4_bit or MSIZE0_DMA1_CCR4_bit;
Easier:

Code: Select all

    sbit  EN_DMA1_CCR4_bit at DMA1_CCR4.B0;            1
    sbit  TCIE_DMA1_CCR4_bit at DMA1_CCR4.B1;
    sbit  HTIE_DMA1_CCR4_bit at DMA1_CCR4.B2;
    sbit  TEIE_DMA1_CCR4_bit at DMA1_CCR4.B3;
    sbit  DIR_DMA1_CCR4_bit at DMA1_CCR4.B4;           1
    sbit  CIRC_DMA1_CCR4_bit at DMA1_CCR4.B5;         1
    sbit  PINC_DMA1_CCR4_bit at DMA1_CCR4.B6;
    sbit  MINC_DMA1_CCR4_bit at DMA1_CCR4.B7;         1
    sbit  PSIZE0_DMA1_CCR4_bit at DMA1_CCR4.B8;
    sbit  PSIZE1_DMA1_CCR4_bit at DMA1_CCR4.B9;
    sbit  MSIZE0_DMA1_CCR4_bit at DMA1_CCR4.B10;
    sbit  MSIZE1_DMA1_CCR4_bit at DMA1_CCR4.B11;
    sbit  PL0_DMA1_CCR4_bit at DMA1_CCR4.B12;
    sbit  PL1_DMA1_CCR4_bit at DMA1_CCR4.B13;
    sbit  MEM2MEM_DMA1_CCR4_bit at DMA1_CCR4.B14;
DMA1_CCR4 := 0x000000B1;

Vit2
Posts: 77
Joined: 15 Apr 2015 10:00

Re: STM32F103 USART1 + DMA1

#5 Post by Vit2 » 21 Oct 2023 11:30

Thank you, AntiMember!

I still can't figure out why it's not working!

Code: Select all

procedure InitDMA;
begin
  RCC_AHBENR := RCC_AHBENR or EN_DMA1_CCR4_bit;
  DMA1_CCR4:= 0x000000B1;
  DMA1_CPAR4 := dword(@USART1_DR);
  DMA1_CMAR4 := dword(@TextBuffer[TBuff]);
  DMA1_CNDTR4 := TextBuffer[1];//Length(Text);
  USART1_CR3:= USART1_CR3 or DMAT_bit;
  // USART1_CR3 := USART1_CR3 or DMAR_bit;
end;

procedure SendTextWithDMA(var Text: string);
begin
  CopyStringToBuffer(Text, TextBuffer);
  while DMA1EN_bit <> 0 do;
 USART1_CR1 := USART1_CR1 and not TE;
end;

Code: Select all

 Const TBuff = 254;
var
  TextBuffer: array[0..TBuff] of char;

AntiMember
Posts: 136
Joined: 02 Jan 2020 19:00

Re: STM32F103 USART1 + DMA1

#6 Post by AntiMember » 21 Oct 2023 17:52

procedure InitDMA;
begin
RCC_AHBENR := RCC_AHBENR or EN_DMA1_CCR4_bit;
DMA1_CPAR4 := dword(@USART1_DR);
DMA1_CMAR4 := dword(@TextBuffer[TBuff]);
DMA1_CNDTR4 := TextBuffer[1];//Length(Text);

DMA1_CCR4:= 0x000000B1;
end;
...................................................
bla-bla-bla main
begin
UART1_Init(115200);
USART1_CR3:= USART1_CR3 or DMAT_bit; //Does this really work? I'm too lazy to download pascal...
// USART1_CR3 := USART1_CR3 or DMAR_bit;
InitDMA;
while 1 do;
end;

Vit2
Posts: 77
Joined: 15 Apr 2015 10:00

Re: STM32F103 USART1 + DMA1

#7 Post by Vit2 » 22 Oct 2023 08:36

Hi!
It's not working! I don't know anymore.

AntiMember
Posts: 136
Joined: 02 Jan 2020 19:00

Re: STM32F103 USART1 + DMA1

#8 Post by AntiMember » 22 Oct 2023 16:30

Maybe it will work like this: test out "555555555555555......."

Code: Select all

program DMA_USART1;
 Const TBuff = 128;
var
  TextBuffer: array[0..TBuff] of char;
  i: integer;

procedure InitDMA;
begin
RCC_AHBENR.B0 := 1;
DMA1_CPAR4 := dword(@USART1_DR);
DMA1_CMAR4 := dword(@TextBuffer[0]);
DMA1_CNDTR4 := dword(sizeof(TextBuffer));
USART1_CR3.B7 := 1;
DMA1_CCR4:= 0x000000B1;
end;

begin
  for i :=  0 to  TBuff-1 do
  begin
    TextBuffer[i] := 0x35;
  end;
  UART1_Init(115200);
  InitDMA;
  while 1 do;
end.

Vit2
Posts: 77
Joined: 15 Apr 2015 10:00

Re: STM32F103 USART1 + DMA1

#9 Post by Vit2 » 22 Oct 2023 18:20

Thank you so much!
It worked!

Post Reply

Return to “mikroPascal PRO for ARM General”