Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
Diff: FreescaleIAP/IAP.s
- Revision:
- 60:f38da020aa13
- Parent:
- 59:94eb9265b6d7
- Child:
- 76:7f5912b6340e
--- a/FreescaleIAP/IAP.s Thu May 12 05:57:53 2016 +0000 +++ b/FreescaleIAP/IAP.s Fri May 13 21:28:41 2016 +0000 @@ -8,13 +8,55 @@ ; Note: arguments passed in R0, R1... EXPORT iapExecAsm iapExecAsm + ; Do a layered call to our main handler routine. Advice on ARM + ; forums suggests that before we carry out the Flash write, we should + ; do an extra call layer from one RAM-resident code block to another + ; RAM-resident code block, with the inner block firing off the actual + ; FTFA execution. This supposedly will reduce the chances of core + ; lockup during the write. This strikes me as probably superstitious + ; in origin ("it was crashing and then I made some random changes to + ; the code that I can't remember and also knocked three times on the + ; desk and then it worked, so always knock three times on a desk"). + ; But I have indeed seen random crashes, and this is only a few bytes + ; of extra code, so what the heck. + ; + ; If there's a real justification for this, it's probably that the + ; extra call fills up the CPU instruction fetch/pre-fetch mechanism + ; with RAM addresses, flushing out any remaining Flash addresses that + ; might trigger an asynchronous Flash read from the CPU instruction + ; fetch mechanism. The big hazard with programming Flash through the + ; FTFA is that any read access to the Flash will fail while a write + ; operation is in progress. This will cause a CPU lockup if such a + ; read comes from the instruction fetcher. + ; + ; Simply push the link register, call our main routine, and return. + ; Arguments are in registers (R0, R1, ...), so they'll just pass + ; through to the callee. + STMFD R13!, {LR} + BL iapExecMain + LDMFD R13!, {PC} +; +; Main routine +; +iapExecMain ; push R1, R2, link STMFD R13!, {R1,R2,LR} + + ; Advice on ARM forums suggests that we should add a little artificial + ; delay here to avoid core lockup. The point seems to be to reduce the + ; chances that a bus operation related to instruction fetching will hit + ; the Flash while the write operation is executing. This seems as + ; superstitious as the extra layered call (see above), but just in case... + MOVS R1, #100 ; loop counter +L0 + SUBS R1, R1, #1 ; R1 = R1 - 1 + BNE L0 ; loop until we reach 0 - ; clear old errors from status bits - MOVS R1, #0x70 ; FPVIOL (0x10) | ACCERR (0x20) | RDCOLOERR (0x40) - STRB R1, [R0] + ; NB - caller is responsible for doing this + ; clear old errors from status bits + ;MOVS R1, #0x70 ; FPVIOL (0x10) | ACCERR (0x20) | RDCOLOERR (0x40) + ;STRB R1, [R0] ; start command MOVS R1, #0x80 ; CCIF (0x80)