Arnaud VALLEY / Mbed 2 deprecated Pinscape_Controller_V2_arnoz

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
mjr
Date:
Fri May 13 21:28:41 2016 +0000
Revision:
60:f38da020aa13
Parent:
59:94eb9265b6d7
Child:
76:7f5912b6340e
Try to bulletproof the Flash programming procedure by using techniques recommended in ARM forums; enhanced comments in main routine

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 59:94eb9265b6d7 1 ; Put this in READWRITE memory, to ensure that it goes in RAM
mjr 59:94eb9265b6d7 2 ; rather than flash.
mjr 59:94eb9265b6d7 3 AREA iapexec_asm_code, CODE, READWRITE
mjr 59:94eb9265b6d7 4
mjr 59:94eb9265b6d7 5 ; iapExecAsm(FSTAT)
mjr 59:94eb9265b6d7 6 ; FSTAT = address of ftfa->FSTAT register
mjr 59:94eb9265b6d7 7 ;
mjr 59:94eb9265b6d7 8 ; Note: arguments passed in R0, R1...
mjr 59:94eb9265b6d7 9 EXPORT iapExecAsm
mjr 59:94eb9265b6d7 10 iapExecAsm
mjr 60:f38da020aa13 11 ; Do a layered call to our main handler routine. Advice on ARM
mjr 60:f38da020aa13 12 ; forums suggests that before we carry out the Flash write, we should
mjr 60:f38da020aa13 13 ; do an extra call layer from one RAM-resident code block to another
mjr 60:f38da020aa13 14 ; RAM-resident code block, with the inner block firing off the actual
mjr 60:f38da020aa13 15 ; FTFA execution. This supposedly will reduce the chances of core
mjr 60:f38da020aa13 16 ; lockup during the write. This strikes me as probably superstitious
mjr 60:f38da020aa13 17 ; in origin ("it was crashing and then I made some random changes to
mjr 60:f38da020aa13 18 ; the code that I can't remember and also knocked three times on the
mjr 60:f38da020aa13 19 ; desk and then it worked, so always knock three times on a desk").
mjr 60:f38da020aa13 20 ; But I have indeed seen random crashes, and this is only a few bytes
mjr 60:f38da020aa13 21 ; of extra code, so what the heck.
mjr 60:f38da020aa13 22 ;
mjr 60:f38da020aa13 23 ; If there's a real justification for this, it's probably that the
mjr 60:f38da020aa13 24 ; extra call fills up the CPU instruction fetch/pre-fetch mechanism
mjr 60:f38da020aa13 25 ; with RAM addresses, flushing out any remaining Flash addresses that
mjr 60:f38da020aa13 26 ; might trigger an asynchronous Flash read from the CPU instruction
mjr 60:f38da020aa13 27 ; fetch mechanism. The big hazard with programming Flash through the
mjr 60:f38da020aa13 28 ; FTFA is that any read access to the Flash will fail while a write
mjr 60:f38da020aa13 29 ; operation is in progress. This will cause a CPU lockup if such a
mjr 60:f38da020aa13 30 ; read comes from the instruction fetcher.
mjr 60:f38da020aa13 31 ;
mjr 60:f38da020aa13 32 ; Simply push the link register, call our main routine, and return.
mjr 60:f38da020aa13 33 ; Arguments are in registers (R0, R1, ...), so they'll just pass
mjr 60:f38da020aa13 34 ; through to the callee.
mjr 60:f38da020aa13 35 STMFD R13!, {LR}
mjr 60:f38da020aa13 36 BL iapExecMain
mjr 60:f38da020aa13 37 LDMFD R13!, {PC}
mjr 59:94eb9265b6d7 38
mjr 60:f38da020aa13 39 ;
mjr 60:f38da020aa13 40 ; Main routine
mjr 60:f38da020aa13 41 ;
mjr 60:f38da020aa13 42 iapExecMain
mjr 59:94eb9265b6d7 43 ; push R1, R2, link
mjr 59:94eb9265b6d7 44 STMFD R13!, {R1,R2,LR}
mjr 60:f38da020aa13 45
mjr 60:f38da020aa13 46 ; Advice on ARM forums suggests that we should add a little artificial
mjr 60:f38da020aa13 47 ; delay here to avoid core lockup. The point seems to be to reduce the
mjr 60:f38da020aa13 48 ; chances that a bus operation related to instruction fetching will hit
mjr 60:f38da020aa13 49 ; the Flash while the write operation is executing. This seems as
mjr 60:f38da020aa13 50 ; superstitious as the extra layered call (see above), but just in case...
mjr 60:f38da020aa13 51 MOVS R1, #100 ; loop counter
mjr 60:f38da020aa13 52 L0
mjr 60:f38da020aa13 53 SUBS R1, R1, #1 ; R1 = R1 - 1
mjr 60:f38da020aa13 54 BNE L0 ; loop until we reach 0
mjr 59:94eb9265b6d7 55
mjr 60:f38da020aa13 56 ; NB - caller is responsible for doing this
mjr 60:f38da020aa13 57 ; clear old errors from status bits
mjr 60:f38da020aa13 58 ;MOVS R1, #0x70 ; FPVIOL (0x10) | ACCERR (0x20) | RDCOLOERR (0x40)
mjr 60:f38da020aa13 59 ;STRB R1, [R0]
mjr 59:94eb9265b6d7 60
mjr 59:94eb9265b6d7 61 ; start command
mjr 59:94eb9265b6d7 62 MOVS R1, #0x80 ; CCIF (0x80)
mjr 59:94eb9265b6d7 63 STRB R1, [R0]
mjr 59:94eb9265b6d7 64
mjr 59:94eb9265b6d7 65 ; wait until command completed - the CCIF bit is SET when the command completes
mjr 59:94eb9265b6d7 66 MOVS R2, #0x80 ; CCIF (0x80)
mjr 59:94eb9265b6d7 67 L1
mjr 59:94eb9265b6d7 68 LDRB R1, [R0]
mjr 59:94eb9265b6d7 69 TSTS R1, R2 ; CCIF (0x80)
mjr 59:94eb9265b6d7 70 BEQ L1
mjr 59:94eb9265b6d7 71
mjr 59:94eb9265b6d7 72 ; pop registers and return
mjr 59:94eb9265b6d7 73 LDMFD R13!, {R1,R2,PC}
mjr 59:94eb9265b6d7 74
mjr 59:94eb9265b6d7 75 END
mjr 59:94eb9265b6d7 76