Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
FreescaleIAP/IAP.s
- Committer:
- arnoz
- Date:
- 2021-10-01
- Revision:
- 116:7a67265d7c19
- Parent:
- 101:755f44622abc
File content as of revision 116:7a67265d7c19:
; FreescaleIAP assembly functions ; ; The hardware manual warns that FTFA commands must be executed entirely ; from RAM code, since we can't have any flash reads occur while an erase ; or write operation is executing. If the code executing and waiting for ; the FTFA command were in flash, the CPU might have to fetch an instruction ; from flash in the course of the loop, which could freeze the CPU. ; Empirically, it seems that this isn't truly necessary, despite the manual's ; warnings. The M0+ instruction cache is big enough to hold the whole ; execute-and-wait loop instruction sequence, even when written in C++, so ; in practice this can run as flash-resident C++ code. We're implementing ; it as assembler anyway to follow the best practices as laid out in the ; hardware manual. ; ; Tell the linker to put our code in RAM by making it read-write. AREA iap_ram_asm_code, CODE, READWRITE ; iapExecAndWait() ; ; Launches the currently loaded FTFA command and waits for completion. ; Before calling, the caller must set up the FTFA command registers with ; the command code and any address and data parameters required. The ; caller should also disable interrupts, since an interrupt handler could ; cause a branch into code resident in flash memory, which would violate ; the rule against accessing flash while an FTFA command is running. EXPORT iapExecAndWait iapExecAndWait ; save registers STMFD R13!, {R1,R2,LR} ; disable interrupts CPSID I ; set the PRIMASK to disable interrupts DSB ; data synchronization barrier ISB ; instruction synchronization barrier ; Launch the command by writing the CCIF bit to FTFA_FSTAT LDR R0, FTFA_FSTAT MOVS R2, #0x80 ; CCIF (0x80) STRB R2, [R0] ; FTFA->FSTAT = CCIF ; Wait for the command to complete. The FTFA sets the CCIF ; bit in FTFA_FSTAT when the command is finished, so spin until ; the bit reads as set. Lew0 LDRB R1, [R0] ; R1 <- FTFA->FSTAT TSTS R1, R2 ; test R1 & CCIF BEQ Lew0 ; if zero, the command is still running ; re-enable interrupts CPSIE I ; pop registers and return LDMFD R13!, {R1,R2,PC} ALIGN FTFA_FSTAT DCD 0x40020000 END