Mirror with some correction

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
mjr
Date:
Fri Feb 03 20:50:02 2017 +0000
Revision:
76:7f5912b6340e
Parent:
60:f38da020aa13
Child:
77:0b96f6867312
Rework flash driver to make it truly stable (hopefully to 100% reliability); host-loaded configuration; performance improvements; more performance diagnostics.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 76:7f5912b6340e 1 ; FreescaleIAP assembly functions
mjr 76:7f5912b6340e 2 ;
mjr 76:7f5912b6340e 3 ; Put all code here in READWRITE memory, to ensure that it goes in RAM
mjr 59:94eb9265b6d7 4 ; rather than flash.
mjr 59:94eb9265b6d7 5 AREA iapexec_asm_code, CODE, READWRITE
mjr 76:7f5912b6340e 6
mjr 76:7f5912b6340e 7 ;---------------------------------------------------------------------------
mjr 76:7f5912b6340e 8 ; iapEraseSector(FTFA_Type *FTFA, uint32_t address)
mjr 76:7f5912b6340e 9 ; R0 = FTFA pointer
mjr 76:7f5912b6340e 10 ; R1 = starting address
mjr 59:94eb9265b6d7 11
mjr 76:7f5912b6340e 12 EXPORT iapEraseSector
mjr 76:7f5912b6340e 13 iapEraseSector
mjr 76:7f5912b6340e 14 ; save registers
mjr 76:7f5912b6340e 15 STMFD R13!,{R1,R4,LR}
mjr 76:7f5912b6340e 16
mjr 76:7f5912b6340e 17 ; Ensure that no interrupts occur while we're erasing. This is
mjr 76:7f5912b6340e 18 ; vitally important, because the flash controller doesn't allow
mjr 76:7f5912b6340e 19 ; anyone to read from flash while an erase is in progress. Most
mjr 76:7f5912b6340e 20 ; of the program code is in flash, which means that any interrupt
mjr 76:7f5912b6340e 21 ; would invoke flash code, causing the CPU to fetch from flash,
mjr 76:7f5912b6340e 22 ; violating the no-read-during-erase rule. The CPU instruction
mjr 76:7f5912b6340e 23 ; fetch would fail, causing the CPU to lock up.
mjr 76:7f5912b6340e 24 CPSID I ; interrupts off
mjr 76:7f5912b6340e 25 DMB ; data memory barrier
mjr 76:7f5912b6340e 26 ISB ; instruction synchronization barrier
mjr 76:7f5912b6340e 27
mjr 76:7f5912b6340e 28 ; wait for any previous command to complete
mjr 76:7f5912b6340e 29 BL iapWait
mjr 60:f38da020aa13 30
mjr 76:7f5912b6340e 31 ; clear any errors
mjr 76:7f5912b6340e 32 BL iapClearErrors
mjr 76:7f5912b6340e 33
mjr 76:7f5912b6340e 34 ; set up the command parameters
mjr 76:7f5912b6340e 35 MOVS R4,#0
mjr 76:7f5912b6340e 36 STRB R4,[R0,#1] ; FTFA->FCNFG <- 0
mjr 76:7f5912b6340e 37 MOVS R4,#9 ; command = erase sector (9)
mjr 76:7f5912b6340e 38 STRB R4,[R0,#7] ; FTFA->FCCOB0 <- command
mjr 76:7f5912b6340e 39
mjr 76:7f5912b6340e 40 STRB R1,[R0,#4] ; FTFA->FCCOB3 <- address bits 16-23
mjr 59:94eb9265b6d7 41
mjr 76:7f5912b6340e 42 MOVS R1,R1,LSR #8 ; address >>= 8
mjr 76:7f5912b6340e 43 STRB R1,[R0,#5] ; FTFA->FCCOB2 <- address bits 8-15
mjr 76:7f5912b6340e 44
mjr 76:7f5912b6340e 45 MOVS R1,R1,LSR #8 ; address >>= 8
mjr 76:7f5912b6340e 46 STRB R1,[R0,#6] ; FTFA->FCCOB1 <- address bits 0-7
mjr 59:94eb9265b6d7 47
mjr 76:7f5912b6340e 48 ; execute and wait for completion
mjr 76:7f5912b6340e 49 BL iapExec
mjr 76:7f5912b6340e 50 BL iapWait
mjr 76:7f5912b6340e 51
mjr 76:7f5912b6340e 52 ; restore interrupts
mjr 76:7f5912b6340e 53 CPSIE I
mjr 59:94eb9265b6d7 54
mjr 59:94eb9265b6d7 55 ; pop registers and return
mjr 76:7f5912b6340e 56 LDMFD R13!,{R1,R4,PC}
mjr 76:7f5912b6340e 57
mjr 76:7f5912b6340e 58 ;---------------------------------------------------------------------------
mjr 76:7f5912b6340e 59 ; iapProgramBlock(TFA_Type *ftfa, uint32_t address, const void *src, uint32_t length)
mjr 76:7f5912b6340e 60 ; R0 = FTFA pointer
mjr 76:7f5912b6340e 61 ; R1 = flash address
mjr 76:7f5912b6340e 62 ; R2 = source data pointer
mjr 76:7f5912b6340e 63 ; R3 = data length in bytes
mjr 76:7f5912b6340e 64
mjr 76:7f5912b6340e 65 EXPORT iapProgramBlock
mjr 76:7f5912b6340e 66 iapProgramBlock
mjr 76:7f5912b6340e 67 ; save registers
mjr 76:7f5912b6340e 68 STMFD R13!, {R1,R2,R3,R4,LR}
mjr 76:7f5912b6340e 69
mjr 76:7f5912b6340e 70 ; Turn off interrupts while we're working. Flash reading
mjr 76:7f5912b6340e 71 ; while writing doesn't seem to be forbidden the way it is
mjr 76:7f5912b6340e 72 ; while erasing (see above), but even so, each longword
mjr 76:7f5912b6340e 73 ; transfer requires writing to 10 separate registers, so
mjr 76:7f5912b6340e 74 ; there's a lot of static state involved - we don't want
mjr 76:7f5912b6340e 75 ; any other code sneaking in and changing anything on us.
mjr 76:7f5912b6340e 76 CPSID I ; interrupts off
mjr 76:7f5912b6340e 77 DMB ; data memory barrier
mjr 76:7f5912b6340e 78 ISB ; instruction synchronization barrier
mjr 76:7f5912b6340e 79
mjr 76:7f5912b6340e 80 ; wait for any previous command to complete
mjr 76:7f5912b6340e 81 BL iapWait
mjr 76:7f5912b6340e 82
mjr 76:7f5912b6340e 83 ; iterate over the data
mjr 76:7f5912b6340e 84 LpLoop
mjr 76:7f5912b6340e 85 CMPS R3,#3 ; at least one longword left (>= 4 bytes)?
mjr 76:7f5912b6340e 86 BLS LpDone ; no, done
mjr 76:7f5912b6340e 87
mjr 76:7f5912b6340e 88 ; clear any errors from the previous command
mjr 76:7f5912b6340e 89 BL iapClearErrors
mjr 76:7f5912b6340e 90
mjr 76:7f5912b6340e 91 ; set up the command parameters
mjr 76:7f5912b6340e 92 MOVS R4,#0
mjr 76:7f5912b6340e 93 STRB R4,[R0,#1] ; FTFA->FCNFG <- 0
mjr 76:7f5912b6340e 94 MOVS R4,#6 ; command = program longword (6)
mjr 76:7f5912b6340e 95 STRB R4,[R0,#7] ; FTFA->FCCOB0 <- command
mjr 76:7f5912b6340e 96
mjr 76:7f5912b6340e 97 MOVS R4,R1 ; R4 <- current address
mjr 76:7f5912b6340e 98 STRB R4,[R0,#4] ; FTFA->FCCOB3 <- address bits 16-23
mjr 76:7f5912b6340e 99
mjr 76:7f5912b6340e 100 MOVS R4,R4,LSR #8 ; address >>= 8
mjr 76:7f5912b6340e 101 STRB R4,[R0,#5] ; FTFA->FCCOB2 <- address bits 8-15
mjr 76:7f5912b6340e 102
mjr 76:7f5912b6340e 103 MOVS R4,R4,LSR #8 ; address >>= 8
mjr 76:7f5912b6340e 104 STRB R4,[R0,#6] ; FTFA->FCCOB1 <- address bits 0-7
mjr 76:7f5912b6340e 105
mjr 76:7f5912b6340e 106 LDRB R4,[R2] ; R4 <- data[0]
mjr 76:7f5912b6340e 107 STRB R4,[R0,#8] ; FTFA->FCCOB7 <- data[0]
mjr 76:7f5912b6340e 108
mjr 76:7f5912b6340e 109 LDRB R4,[R2,#1] ; R4 <- data[1]
mjr 76:7f5912b6340e 110 STRB R4,[R0,#9] ; FTFA->FCCOB6 <- data[1]
mjr 76:7f5912b6340e 111
mjr 76:7f5912b6340e 112 LDRB R4,[R2,#2] ; R4 <- data[2]
mjr 76:7f5912b6340e 113 STRB R4,[R0,#0xA] ; FTFA->FCCOB5 <- data[2]
mjr 76:7f5912b6340e 114
mjr 76:7f5912b6340e 115 LDRB R4,[R2,#3] ; R4 <- data[3]
mjr 76:7f5912b6340e 116 STRB R4,[R0,#0xB] ; FTBA->FCCOB4 <- data[3]
mjr 76:7f5912b6340e 117
mjr 76:7f5912b6340e 118 ; execute the command
mjr 76:7f5912b6340e 119 BL iapExec
mjr 76:7f5912b6340e 120
mjr 76:7f5912b6340e 121 ; advance to the next longword
mjr 76:7f5912b6340e 122 ADDS R1,R1,#4 ; flash address += 4
mjr 76:7f5912b6340e 123 ADDS R2,R2,#4 ; source data pointer += 4
mjr 76:7f5912b6340e 124 SUBS R3,R3,#4 ; data length -= 4
mjr 76:7f5912b6340e 125 B LpLoop ; back for the next iteration
mjr 76:7f5912b6340e 126
mjr 76:7f5912b6340e 127 LpDone
mjr 76:7f5912b6340e 128 ; restore interrupts
mjr 76:7f5912b6340e 129 CPSIE I
mjr 76:7f5912b6340e 130
mjr 76:7f5912b6340e 131 ; pop registers and return
mjr 76:7f5912b6340e 132 LDMFD R13!, {R1,R2,R3,R4,PC}
mjr 76:7f5912b6340e 133
mjr 76:7f5912b6340e 134
mjr 76:7f5912b6340e 135 ;---------------------------------------------------------------------------
mjr 76:7f5912b6340e 136 ; iapClearErrors(FTFA_Type *FTFA) - clear errors from previous command
mjr 76:7f5912b6340e 137 ; R0 = FTFA pointer
mjr 76:7f5912b6340e 138
mjr 76:7f5912b6340e 139 iapClearErrors
mjr 76:7f5912b6340e 140 ; save registers
mjr 76:7f5912b6340e 141 STMFD R13!, {R2,R3,LR}
mjr 76:7f5912b6340e 142
mjr 76:7f5912b6340e 143 LDRB R2, [R0] ; R2 <- FTFA->FSTAT
mjr 76:7f5912b6340e 144 MOVS R3, #0x30 ; FPVIOL (0x10) | ACCERR (0x20)
mjr 76:7f5912b6340e 145 ANDS R2, R2, R3 ; R2 &= error bits
mjr 76:7f5912b6340e 146 BEQ Lc0 ; if all zeros, no need to reset anything
mjr 76:7f5912b6340e 147 STRB R2, [R0] ; write the 1 bits back to clear the error status
mjr 76:7f5912b6340e 148 Lc0
mjr 76:7f5912b6340e 149 ; restore registers and return
mjr 76:7f5912b6340e 150 LDMFD R13!, {R2,R3,PC}
mjr 76:7f5912b6340e 151
mjr 76:7f5912b6340e 152
mjr 76:7f5912b6340e 153 ;---------------------------------------------------------------------------
mjr 76:7f5912b6340e 154 ; iapWait(FTFA_Type *FTFA) - wait for command to complete
mjr 76:7f5912b6340e 155 ; R0 = FTFA pointer
mjr 76:7f5912b6340e 156
mjr 76:7f5912b6340e 157 iapWait
mjr 76:7f5912b6340e 158 ; save registers
mjr 76:7f5912b6340e 159 STMFD R13!, {R1,R2,LR}
mjr 76:7f5912b6340e 160
mjr 76:7f5912b6340e 161 ; the CCIF bit is SET when the command completes
mjr 76:7f5912b6340e 162 Lw0
mjr 76:7f5912b6340e 163 LDRB R1, [R0] ; R1 <- FTFA->FSTAT
mjr 76:7f5912b6340e 164 MOVS R2, #0x80 ; CCIF (0x80)
mjr 76:7f5912b6340e 165 TSTS R1, R2 ; test R1 & CCIF
mjr 76:7f5912b6340e 166 BEQ Lw0 ; if zero, the command is still running
mjr 76:7f5912b6340e 167
mjr 76:7f5912b6340e 168 LwDone
mjr 76:7f5912b6340e 169 ; pop registers and return
mjr 59:94eb9265b6d7 170 LDMFD R13!, {R1,R2,PC}
mjr 76:7f5912b6340e 171
mjr 76:7f5912b6340e 172
mjr 76:7f5912b6340e 173 ;---------------------------------------------------------------------------
mjr 76:7f5912b6340e 174 ; iapExec(FTFA_Type *FTFA)
mjr 76:7f5912b6340e 175 ; R0 = FTFA pointer
mjr 76:7f5912b6340e 176
mjr 76:7f5912b6340e 177 iapExec
mjr 76:7f5912b6340e 178 ; save registers
mjr 76:7f5912b6340e 179 STMFD R13!, {R1,LR}
mjr 76:7f5912b6340e 180
mjr 76:7f5912b6340e 181 ; write the CCIF bit to launch the command
mjr 76:7f5912b6340e 182 MOVS R1, #0x80 ; CCIF (0x80)
mjr 76:7f5912b6340e 183 STRB R1, [R0] ; FTFA->FSTAT = CCIF
mjr 76:7f5912b6340e 184
mjr 76:7f5912b6340e 185 ; wait until command completed
mjr 76:7f5912b6340e 186 BL iapWait
mjr 76:7f5912b6340e 187
mjr 76:7f5912b6340e 188 ; pop registers and return
mjr 76:7f5912b6340e 189 LDMFD R13!, {R1,PC}
mjr 59:94eb9265b6d7 190
mjr 59:94eb9265b6d7 191 END
mjr 59:94eb9265b6d7 192