Wikia

CHDK Wiki

Srsa 4c/S1IS DMA

Talk0
575pages on
this wiki

< User:Srsa 4c

Revision as of 23:58, April 23, 2012 by Srsa 4c (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This is a nice clean routine found in the S1 IS firmware (DIGIC I !). For some reason (like the used slow ARM CPU) they decided to use DMA to copy the "start of data" data into RAM. This happens very early in the boot process, no operating system is present yet. The special 0xc0xxxxxx addresses and their use bear a great resemblance to the later DIGIC equivalents, as documented by the Magic Lantern hackers http://magiclantern.wikia.com/wiki/Register_Map

The code is utterly unoptimized.

 sub_FF01017C
             MOV     R12, SP
             STMFD   SP!, {R11,R12,LR,PC}
             SUB     R11, R12, #4
             SUB     SP, SP, #0x10
             STR     R0, [R11,#-0x10]  ; "start of data"-4
             STR     R1, [R11,#-0x14]  ; 0x1000    (destination)
             STR     R2, [R11,#-0x18]  ; 0x124e7 (length in words)
             MOV     R3, #0
             STR     R3, [R11,#-0x1C]
             MOV     R3, #0xC0000004
             ADD     R3, R3, #0x400000 ; 0xc0400004: clock selection (speed?)
             LDR     R2, [R3]          ; read...
             STR     R2, [R11,#-0x1C]  ; ...and store current value
             MOV     R3, #0xC0000004
             ADD     R3, R3, #0x400000 ; 0xc0400004
             LDR     R2, [R11,#-0x1C]
             ORR     R1, R2, #0x2000   ; this additional clock is needed
             STR     R1, [R3]          ; value written back
             MOV     R3, #0xC0000008
             ADD     R3, R3, #0x400000 ; 0xc0400008: clock control
             LDR     R2, [R3]
             STR     R2, [R11,#-0x1C]  ; ...saved
             MOV     R3, #0xC0000008
             ADD     R3, R3, #0x400000
             LDR     R2, [R11,#-0x1C]
             ORR     R1, R2, #0x1000000    ; dma module 0
             STR     R1, [R3]          ; clock control updated
             MOV     R3, #0xC0000000
             ADD     R3, R3, #0xA10000 ; 0xc0a10000: dma1 base reg.
             MOV     R2, #1
             STR     R2, [R3]          ; dma1 enabled
             MOV     R3, #0xC0000018
             ADD     R3, R3, #0xA10000 ; 0xc0a10018: src address
             LDR     R2, [R11,#-0x10]  ; indeed this is the source
             STR     R2, [R3]
             MOV     R3, #0xC000001C
             ADD     R3, R3, #0xA10000 ; 0xc0a1001c: dest. address
             LDR     R2, [R11,#-0x14]  ; destination indeed
             STR     R2, [R3]
             MOV     R3, #0xC0000020
             ADD     R3, R3, #0xA10000 ; 0xc0a10020: transfer count (32bit aligned)
             LDR     R2, [R11,#-0x18]  ; length (given in words, not bytes here)
             MOV     R1, R2
             MOV     R2, R1,LSL#2      ; length*4 (count of bytes)
             STR     R2, [R3]
             MOV     R3, #0xC0000008
             ADD     R3, R3, #0xA10000 ; 0xc0a10008: control bits
             MOV     R2, #1            ; control bit0: start the transfer
             STR     R2, [R3]
 loc_FF010240
             B       loc_FF010248
             B       loc_FF010288
 loc_FF010248
             MOV     R3, #0xC0000010
             ADD     R3, R3, #0xA10000 ; 0xc0a10010, some status
             LDR     R2, [R3]          ; load status
             STR     R2, [R11,#-0x1C]
             LDR     R2, [R11,#-0x1C]
             AND     R3, R2, #1
             CMP     R3, #0
             BEQ     loc_FF010270      ; jump if bit0=0
             B       loc_FF010288      ; jump if bit0=1
             B       loc_FF010284
 loc_FF010270
             LDR     R2, [R11,#-0x1C]  ; status saved previously
             AND     R3, R2, #2
             CMP     R3, #0
             BEQ     loc_FF010284      ; jump if bit1 = 0
             B       loc_FF010288      ; jump if bit1 = 1 (finished)
 loc_FF010284
             B       loc_FF010240      ; loop back, let's wait
 loc_FF010288                          ; finished, switch off related hardware
             MOV     R3, #0xC0000004
             ADD     R3, R3, #0x400000 ; 0xc0400004
             LDR     R2, [R3]          ; value read
             STR     R2, [R11,#-0x1C]  ; ... and stored
             MOV     R3, #0xC0000004
             ADD     R3, R3, #0x400000 ; 0xc0400004
             LDR     R2, [R11,#-0x1C]  ; load previous value
             BIC     R1, R2, #0x2000   ; clear a bit
             STR     R1, [R3]          ; write it back
             MOV     R3, #0xC0000008   ; 0xc0400008
             ADD     R3, R3, #0x400000
             LDR     R2, [R3]          ; value read
             STR     R2, [R11,#-0x1C]  ; ... and stored
             MOV     R3, #0xC0000008
             ADD     R3, R3, #0x400000 ; 0xc0400008
             LDR     R2, [R11,#-0x1C]  ; load previous value
             BIC     R1, R2, #0x1000000    ; clear a bit
             STR     R1, [R3]          ; write it back
             LDMDB   R11, {R11,SP,PC}


This camera only uses this DMA, maybe there are no more DMA channels in DIGIC I.

On the other hand, on DIGIC II+ p&s models all DMA channels are potentially in use (haven't noticed this before)

typical code snippet:

ldr	r1, =0xc0a10000
mov	r0, #1
str	r0, [r1, r4, lsl #16] ; r4 = channel (0..3)

Around Wikia's network

Random Wiki