cancel
Showing results for 
Search instead for 
Did you mean: 

Refinement about DMA

Roman K
Associate II
Posted on February 28, 2018 at 12:55

I have a few misunderstandings about DMA, so I need some help. 

I setup DMA to copy from GPIO IDR (without inc) to sram (with inc), it triggered from Timer (Free Running, Overflow event).

In the case of algorithm like following:

   1. DMA setup

   2. Timer Start

   3. Infinite Loop

   4. Breakpoint in DMA Interrupt handler

All works fine, program jumps into interrupt handler, the sram buffer is filled up with some data from IDR. But when I change an 

algorithm like that:

   1.

DMA setup

   2. Timer Start

   3.1. WFI (I'm using an assembler)

   3.2. Infinite Loop

   4.

Breakpoint in DMA Interrupt handler

The 

interrupt 

wakes core up, but the buffer is empty (not changed). DMA CNDTR register is 0 and there are no error flags. In Reference Manual I have this about WFI: 'CPU clock OFF, no effect on other clocks or analog clock sources', so, what did I miss? And how should I 'wait' for DMA interrupt without entering in checking loop?

Another

misunderstanding

: I want to read least significant byte of IDR, so, I setup PSIZE = 16bits (as it said in 

Reference Manual 'IDR 

can be accessed in Word mode only'), MSIZE = 8bits (like in

 Table 76 in 

Reference Manual). But sram is filled with halfwords anyway (doesn't matter what values of PSIZE (16bits/8bits) and MSIZE (16bits/8bits) are).

And some stupid misunderstanding

:

 why can't I use source address of DMA in peripheral bit-band region as peripheral (to read specified GPIO bit)?

10 REPLIES 10
Posted on February 28, 2018 at 13:53

Bit banding is done by the core it is not actually in the memory space for DMA to use.

For bit level writes to GPIO use BSRR. For reads you'll need to mask when you process the capture buffer. 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on February 28, 2018 at 13:56

Another

misunderstanding

: I want to read least significant byte of IDR, so, I setup PSIZE = 16bits (as it said in 

Reference Manual 'IDR 

can be accessed in Word mode only'),

Which STM32? Where did you see this in RM? Why if 'Word only' you set 16-bits?

MSIZE = 8bits (like in

 Table 76 in Reference Manual). But sram is filled with halfwords anyway (doesn't matter what values of PSIZE (16bits/8bits) and MSIZE (16bits/8bits) are).

Show code, explain expected and observed behaviour.

And some stupid misunderstanding

:

 why can't I use source address of DMA in peripheral bit-band region as peripheral (to read specified GPIO bit)?

Bit-banding is the property of the processor, and is performed by an attachment on the S-port of the processor.

JW

Posted on February 28, 2018 at 14:09

Which STM32? Where did you see this in RM?

Oh, my bad. I have STM32F

Show code, explain expected and observed behaviour.

 ; LDI is a macro that loads an address in R0 and value in R1 and then STR R1, [R0]
; ================= RCC Setup ============== ;
 ; Some Setup ;
 ; Timer 3 ;
LDITIM3_PSC,0
LDITIM3_ARR,9; 128 MHz / 9 ~ 14 MHz ;
LDITIM3_DIER,TIM_DIER_UDE; Overflow DMA Request ;
; DMA ch 3 : TIM3_UP ;
LDIDMA1_Channel3_CPAR,GPIOA_IDR ; Address of IDR ;
LDIDMA1_Channel3_CMAR,SOME_ARRAY_ADDRESS; Address of SomeArray ;
MOVWR2,#(DMA_IFCR_CTCIF3 :OR: DMA_IFCR_CTCIF4)
MOVWR3,#2048
MOVWR4,#(DMA_CCR_PL_VeryHigh :OR: DMA_CCR_MSIZE_16Bits :OR: DMA_CCR_PSIZE_16Bits :OR: DMA_CCR_MINC :OR: DMA_CCR_TCIE :OR: DMA_CCR_EN)
LDRR5,=TIM3_CR1
LDRR7,=DMA1_IFCR
LDRR8,=DMA1_Channel3_CNDTR
LDRR9,=DMA1_Channel4_CNDTR
Begin_Oscill
STRR3,[R8]; 4096 samples ; ;
LDRparam0,=DMA1_Channel3_CCR ; Enable DMA ;
STRR4,[param0]
Start_Oscill
STRconst_1,[R5]; Starts TMR3 ;
 ; WFI
Mainloop
BMainloop
 ENDP; ========================================================================================= /RAM PROGRAM

ALIGN
DMA1_Channel3_IRQHandlerPROC; =============================================================================== DMA Transfer Complete
STRconst_0,[R5]; Stops TMR3 ;
LDITIM3_SR,0; ;
STRR2,[R7] ; Clear Interrupt ;
LDIDMA1_Channel3_CCR,0; Disable DMA ;
BXLR
ENDP; ========================================================================================= /DMA Transfer Complete�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

So with WFI commented I reads at SOME_ARRAY_ADDRESS proper data. With WFI executed no data changed, but DMA interrupt handled.

And with DMA_CCR_M(P)SIZE 8 or 16 data in

SOME_ARRAY_ADDRESSare 16 bit wide anyway.

Posted on February 28, 2018 at 15:15

Hmm, WFI enters a low power state. Are you sure that DMA keeps running in this state?

-- pa

Posted on February 28, 2018 at 15:52

Well, I am sure that CNDTR (Data Count) is zero after interrupt and DMA flags set. So my conclusion is that DMA keeps running.

Posted on February 28, 2018 at 16:04

Can you please show disasm of the same code?

There are too many macros I don't see, in there.

JW

Posted on February 28, 2018 at 16:04

and DMA flags set

Which flags?

JW

Posted on March 01, 2018 at 10:54

Yes I can.

 209: ; Timer 3 ; 
0x200004C6 4837 LDR r0,[pc,#220] ; @0x200005A4
0x200004C8 F8C0B000 STR r11,[r0,#0x00]
 210: LDI TIM3_PSC, 0 
0x200004CC 4836 LDR r0,[pc,#216] ; @0x200005A8
0x200004CE F8C0A000 STR r10,[r0,#0x00]
 211: LDI TIM3_ARR, 9 ; ; 
0x200004D2 4836 LDR r0,[pc,#216] ; @0x200005AC
0x200004D4 F04F0109 MOV r1,#0x09
0x200004D8 6001 STR r1,[r0,#0x00]
 212: LDI TIM3_DIER, TIM_DIER_UDE ; Overflow DMA Request ; 
 213: 
 214: ; íàñòðàèâàåì DMA ; 
 215: ; Êàíàë 3 : TIM3_UP ; 
0x200004DA 4835 LDR r0,[pc,#212] ; @0x200005B0
0x200004DC F2401100 MOVW r1,#0x100
0x200004E0 6001 STR r1,[r0,#0x00]
 216: LDI DMA1_Channel3_CPAR, GPIOA_IDR ; Address of IDR ; 
0x200004E2 4834 LDR r0,[pc,#208] ; @0x200005B4
0x200004E4 4934 LDR r1,[pc,#208] ; @0x200005B8
0x200004E6 6001 STR r1,[r0,#0x00]
 217: LDI DMA1_Channel3_CMAR, SOME_ARRAY_ADDRESS; Address of SomeArray ; 
 218: 
 219: ; �?åêîòîðûå êîíñòàíòû ; 
0x200004E8 4834 LDR r0,[pc,#208] ; @0x200005BC
0x200004EA 4935 LDR r1,[pc,#212] ; @0x200005C0
0x200004EC 6001 STR r1,[r0,#0x00]
 220: MOVW R2, #(DMA_IFCR_CTCIF3 :OR: DMA_IFCR_CTCIF4) 
0x200004EE F2422200 MOVW r2,#0x2200
 221: MOVW R3, #2048 
0x200004F2 F6400300 MOVW r3,#0x800
 222: MOVW R4, #(DMA_CCR_PL_VeryHigh :OR: DMA_CCR_MSIZE_16Bits :OR: DMA_CCR_PSIZE_16Bits :OR: DMA_CCR_MINC :OR: DMA_CCR_TCIE :OR: DMA_CCR_EN) 
0x200004F6 F2435483 MOVW r4,#0x3583
 223: LDR R5, =TIM3_CR1 
0x200004FA 4D0E LDR r5,[pc,#56] ; @0x20000534
 224: LDR R6, =(PERIPH_BB_BASE :OR: (GPIOA_IDR << 5) :OR: (10 << 2)) ; Address of IDR Bit-Band ; 
0x200004FC 4E31 LDR r6,[pc,#196] ; @0x200005C4
 225: LDR R7, =DMA1_IFCR 
0x200004FE 4F32 LDR r7,[pc,#200] ; @0x200005C8
 226: LDR R8, =DMA1_Channel3_CNDTR 
0x20000500 F8DF80C8 LDR.W r8,[pc,#200] ; @0x200005CC
 227: LDR R9, =DMA1_Channel4_CNDTR 
 228: Begin_Oscill 
0x20000504 F8DF90C8 LDR.W r9,[pc,#200] ; @0x200005D0
 229: STR R3, [R8] ; 4096 samples ; ; 
0x20000508 F8C83000 STR r3,[r8,#0x00]
 230: LDR param0, =DMA1_Channel3_CCR ; Enable DMA ; 
0x2000050C 4831 LDR r0,[pc,#196] ; @0x200005D4
 231: STR R4, [param0] 
 232: 
 233: Wait_For_Pin 
0x2000050E 6004 STR r4,[r0,#0x00]
 234: LDR param0, [R6] ; Ñ÷èòûâàåì ïèí ; 1 Òàêò ; 
0x20000510 6830 LDR r0,[r6,#0x00]
 235: CBZ param0, Start_Oscill ; Îñöèë åñëè íóëü ; 2 Òàêòà ; 
0x20000512 B100 CBZ r0,0x20000516
 236: B Wait_For_Pin ; Èíà÷å æäåì ; 
 237: 
 238: Start_Oscill 
0x20000514 E7FC B 0x20000510
 239: STR const_1, [R5] ; �?óñê òàéìåðà 3 (DMA) ; 
 240: 
 241: 
0x20000516 F8C5B000 STR r11,[r5,#0x00]
 242: WFI 
 243: 
 244: Mainloop 
 245: 
 246: 
0x2000051A BF30 WFI 
 247: B Mainloop 
 248: 
 249: 
 250: 
 251: 
 252: ENDP ; ========================================================================================= /RAM PROGRAM 
 253: 
 254: 
 255: ALIGN 
 256: DMA1_Channel3_IRQHandler PROC ; =============================================================================== DMA Transfer Complete 
0x2000051C E7FE B 0x2000051C
0x2000051E 0000 DCW 0x0000
 257: STR const_0, [R5] ; Ñòîï òàéìåðà ; 
0x20000520 F8C5A000 STR r10,[r5,#0x00]
 258: LDI TIM3_SR, 0 ; Î÷èñòêà ôëàãîâ ; 
0x20000524 482C LDR r0,[pc,#176] ; @0x200005D8
0x20000526 F8C0A000 STR r10,[r0,#0x00]
 259: STR R2, [R7] ; Clear Interrupt ; 
0x2000052A 603A STR r2,[r7,#0x00]
 260: LDI DMA1_Channel3_CCR, 0 ; Disable DMA ; 
0x2000052C 4829 LDR r0,[pc,#164] ; @0x200005D4
0x2000052E F8C0A000 STR r10,[r0,#0x00]
 261: BX LR 
0x20000532 4770 BX lr�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Some conditions: R10 contains zero, R11 contains 0x01 (never change - constants). This is the way how Keil disassembly.

So, here's some screen shots:

SOME_ARRAY after power off then on.

0690X00000609mJQAQ.png

SOME_ARRAY after DMA interrupts program flow (without WFI).

0690X00000609qgQAA.png

SOME_ARRAY after DMA interrupts program flow (with WFI)

.

0690X00000608WjQAI.png

All flags are set (GIF, TCIF, HTIF), data counter is zero. But there's no data in SOME_ARRAY.

I just comment and uncomment WFI command.

Posted on March 01, 2018 at 23:12

We are no clairvoyants here. You showed the portion of disassembly without the constants.

I am not really interested in the program, I am interested in the content of registers. Although, honestly, I am not intersted at all - you should be.

Isn't it suspicious that the DMA control register is all zero?

JW