FPC Embedded DMA with STM32?

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

FPC Embedded DMA with STM32?

turro75
This post was updated on .
Hi All,

more or less I'm getting everything working in lazarus, I made a full working RC transmitter with PPM encoder, nrf24l01 and Nokia LCD, Timers, USART, SPI, interrupts, and (sorry for that) an Arduino compatibility unit to use most of the freely available libraries. When ready I'll publish the project template and some units for everyone who wants to play with this.
Now the problem:
when trying to write or read
DMA1_Channel1.CCR:=0;
DMA1_Channel1.CNDTR:=0;
I get a window_watchdog_interrupt() in gdb and program stops running
 
while accessing these it's fine:
DMA1_Channel1.CPAR:=0;
DMA1_Channel1.CMAR:=0;

I modified the TDMA_Registers by removing the channel array and moved to the same implementation as stm stdlib do respecting the same absolute address but no way to get it working.

any suggestion?
Reply | Threaded
Open this post in threaded view
|

Re: FPC Embedded DMA with STM32?

turro75
Update:

I solved by declaring individual registers as absolute.
I need the help of some fpc guru to understand why I got the problem.

According to stm32 manual I declared the same register in two ways:
 
TDMAChannel = record
  CCR,
  CNDTR,
  CPAR,
  CMAR :longword;
 end;        


DMA1_Channel1 : TDMAChannel                         absolute ($40020008);
dma1_ccr1 : longword   absolute($40020008);
dma1_cndtr1 : longword   absolute($4002000C);
dma1_cpar1 : longword   absolute($40020010);
dma1_cmar1 : longword   absolute($40020014);    


I put some values to the serial port to understand what is happening:

Serial1.println;
  Serial1.print('0x'+hexstr(longword(@DMA1_Channel1.CCR),8));
  Serial1.print(' 0x'+hexstr(longword(@DMA1_CCR1),8));
  Serial1.print(' 0x'+hexstr(longword(@DMA1_Channel1.CNDTR),8));
  Serial1.print(' 0x'+hexstr(longword(@DMA1_CNDTR1),8));
  Serial1.print(' 0x'+hexstr(longword(@DMA1_Channel1.CPAR),8));
  Serial1.print(' 0x'+hexstr(longword(@DMA1_CPAR1),8));
  Serial1.print(' 0x'+hexstr(longword(@DMA1_Channel1.CMAR),8));
  Serial1.print(' 0x'+hexstr(longword(@DMA1_CMAR1),8));
  Serial1.println;  
             

this is the output:
0x40020008 0x40020008 0x4002000C 0x4002000C 0x40020010 0x40020010 0x40020014 0x40020014

so address are exactly the same

if I remove the @ I should get the value of the register:

  Serial1.println;
  Serial1.print('0x'+hexstr(longword(@DMA1_Channel1.CCR),8));
  Serial1.print(' 0x'+hexstr(longword(DMA1_CCR1),8));
  Serial1.print(' 0x'+hexstr(longword(@DMA1_Channel1.CNDTR),8));
  Serial1.print(' 0x'+hexstr(longword(DMA1_CNDTR1),8));
  Serial1.print(' 0x'+hexstr(longword(DMA1_Channel1.CPAR),8));
  Serial1.print(' 0x'+hexstr(longword(DMA1_CPAR1),8));
  Serial1.print(' 0x'+hexstr(longword(DMA1_Channel1.CMAR),8));
  Serial1.print(' 0x'+hexstr(longword(DMA1_CMAR1),8));
  Serial1.println;  
   

this is the output:
0x40020008 0x00005A61 0x4002000C 0x0000000D 0x200002F4 0x200002F4 0x40010810 0x40010810

If I remove also the @ from Serial1.print(' 0x'+hexstr(longword(@DMA1_Channel1.CNDTR),8));

this is the output:
0x40020008 0x00005A61

the program stops running when trying to access this register, it does the same with DMA1_Channel1.CCR.
what makes me mad is that the other 2 registers are well working and in the stm32f103fw unit there are a lot of registers which work fine with the record declaration.

Any idea?
Reply | Threaded
Open this post in threaded view
|

Re: FPC Embedded DMA with STM32?

Jeppe Johansen-3
Are you using 2.6.4? This sounds like something that was fixed some time
ago in trunk.

Either way I cannot reproduce any problems with SVN trunk.

On 05/10/2015 02:21 AM, turro75 wrote:

> Update:
>
> I solved by declaring individual registers as absolute.
> I need the help of some fpc guru to understand why I got the problem.
>
> According to stm32 manual I declared the same register in two ways:
> /
> TDMAChannel = record
>    CCR,
>    CNDTR,
>    CPAR,
>    CMAR :longword;
>   end;
>
>
> DMA1_Channel1 : TDMAChannel                         absolute ($40020008);
> dma1_ccr1 : longword   absolute($40020008);
> dma1_cndtr1 : longword   absolute($4002000C);
> dma1_cpar1 : longword   absolute($40020010);
> dma1_cmar1 : longword   absolute($40020014);    /
>
> I put some values to the serial port to understand what is happening:
>
> /Serial1.println;
>    Serial1.print('0x'+hexstr(longword(@DMA1_Channel1.CCR),8));
>    Serial1.print(' 0x'+hexstr(longword(@DMA1_CCR1),8));
>    Serial1.print(' 0x'+hexstr(longword(@DMA1_Channel1.CNDTR),8));
>    Serial1.print(' 0x'+hexstr(longword(@DMA1_CNDTR1),8));
>    Serial1.print(' 0x'+hexstr(longword(@DMA1_Channel1.CPAR),8));
>    Serial1.print(' 0x'+hexstr(longword(@DMA1_CPAR1),8));
>    Serial1.print(' 0x'+hexstr(longword(@DMA1_Channel1.CMAR),8));
>    Serial1.print(' 0x'+hexstr(longword(@DMA1_CMAR1),8));
>    Serial1.println;   /
>
> this is the output:
> 0x40020008 0x40020008 0x4002000C 0x4002000C 0x40020010 0x40020010 0x40020014
> 0x40020014
>
> so address are exactly the same
>
> if I remove the @ I should get the value of the register:
>
>   / Serial1.println;
>    Serial1.print('0x'+hexstr(longword(@DMA1_Channel1.CCR),8));
>    Serial1.print(' 0x'+hexstr(longword(DMA1_CCR1),8));
>    Serial1.print(' 0x'+hexstr(longword(@DMA1_Channel1.CNDTR),8));
>    Serial1.print(' 0x'+hexstr(longword(DMA1_CNDTR1),8));
>    Serial1.print(' 0x'+hexstr(longword(DMA1_Channel1.CPAR),8));
>    Serial1.print(' 0x'+hexstr(longword(DMA1_CPAR1),8));
>    Serial1.print(' 0x'+hexstr(longword(DMA1_Channel1.CMAR),8));
>    Serial1.print(' 0x'+hexstr(longword(DMA1_CMAR1),8));
>    Serial1.println;  /
>
> this is the output:
> 0x40020008 0x00005A61 0x4002000C 0x0000000D 0x200002F4 0x200002F4 0x40010810
> 0x40010810
>
> If I remove also the @ from /Serial1.print('
> 0x'+hexstr(longword(@DMA1_Channel1.CNDTR),8));/
>
> this is the output:
> 0x40020008 0x00005A61
>
> the program stops running when trying to access this register, it does the
> same with DMA1_Channel1.CCR.
> what makes me mad is that the other 2 registers are well working and in the
> stm32f103fw unit there are a lot of registers which work fine with the
> record declaration.
>
> Any idea?
>
>
>
> --
> View this message in context: http://free-pascal-general.1045716.n5.nabble.com/FPC-Embedded-DMA-with-STM32-tp5721684p5721685.html
> Sent from the Free Pascal - General mailing list archive at Nabble.com.
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
>

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: FPC Embedded DMA with STM32?

turro75
Thanks Jeppe,  Solved!

it was a problem in the TDMAChannel declaration which I modified without rebuilding the fpc

here the produced asm code:

# [39] Serial1.print(' 0x'+hexstr(longword(DMA1_Channel1.CNDTR),8));
        ldr r0,.Lj98
        ldrh r1,[r0]
        mov r2,#0
        sub r0,r11,#560
        mov r3,#8
        bl SYSTEM_$$_HEXSTR$QWORD$BYTE$$SHORTSTRING
        sub r3,r11,#560
        ldr r2,.Lj84
        sub r0,r11,#304
        mov r1,#255
        bl fpc_shortstr_concat
        sub r1,r11,#304
        ldr r0,.Lj25
        ldr r0,[r0]
        bl HWSERIAL$_$TSTM32SERIAL_$__$$_PRINT$SHORTSTRING
# [40] Serial1.print(' 0x'+hexstr(longword(DMA1_CNDTR1),8));
        ldr r0,.Lj98
        ldr r1,[r0]
        mov r2,#0
        sub r0,r11,#560
        mov r3,#8
        bl SYSTEM_$$_HEXSTR$QWORD$BYTE$$SHORTSTRING
        sub r3,r11,#560
        ldr r2,.Lj84
        sub r0,r11,#304
        mov r1,#255
        bl fpc_shortstr_concat
        sub r1,r11,#304
        ldr r0,.Lj25
        ldr r0,[r0]
        bl HWSERIAL$_$TSTM32SERIAL_$__$$_PRINT$SHORTSTRING


the only difference is the ldrh instruction which means halfword, in fact the original TDMAChannel declares CCR and CDNTR as word, changing them to longword and after rebuilding the fpc everything is working with channel array!