Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed FastIO FastPWM USBDevice
Fork of Pinscape_Controller by
FreescaleIAP/IAP.s@78:1e00b3fa11af, 2017-03-19 (annotated)
- Committer:
- mjr
- Date:
- Sun Mar 19 05:30:53 2017 +0000
- Revision:
- 78:1e00b3fa11af
- Parent:
- 77:0b96f6867312
- Child:
- 79:682ae3171a08
Ad hoc IR command send; Shift button 'AND' and 'OR' modes; new accelerometer auto centering options
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| mjr | 76:7f5912b6340e | 1 | ; FreescaleIAP assembly functions |
| mjr | 76:7f5912b6340e | 2 | ; |
| mjr | 77:0b96f6867312 | 3 | AREA iap_main_asm_code, CODE, READONLY |
| mjr | 76:7f5912b6340e | 4 | |
| mjr | 76:7f5912b6340e | 5 | ;--------------------------------------------------------------------------- |
| mjr | 76:7f5912b6340e | 6 | ; iapEraseSector(FTFA_Type *FTFA, uint32_t address) |
| mjr | 76:7f5912b6340e | 7 | ; R0 = FTFA pointer |
| mjr | 76:7f5912b6340e | 8 | ; R1 = starting address |
| mjr | 59:94eb9265b6d7 | 9 | |
| mjr | 76:7f5912b6340e | 10 | EXPORT iapEraseSector |
| mjr | 76:7f5912b6340e | 11 | iapEraseSector |
| mjr | 76:7f5912b6340e | 12 | ; save registers |
| mjr | 76:7f5912b6340e | 13 | STMFD R13!,{R1,R4,LR} |
| mjr | 76:7f5912b6340e | 14 | |
| mjr | 76:7f5912b6340e | 15 | ; wait for any previous command to complete |
| mjr | 76:7f5912b6340e | 16 | BL iapWait |
| mjr | 60:f38da020aa13 | 17 | |
| mjr | 76:7f5912b6340e | 18 | ; clear any errors |
| mjr | 76:7f5912b6340e | 19 | BL iapClearErrors |
| mjr | 76:7f5912b6340e | 20 | |
| mjr | 76:7f5912b6340e | 21 | ; set up the command parameters |
| mjr | 76:7f5912b6340e | 22 | MOVS R4,#0 |
| mjr | 76:7f5912b6340e | 23 | STRB R4,[R0,#1] ; FTFA->FCNFG <- 0 |
| mjr | 76:7f5912b6340e | 24 | MOVS R4,#9 ; command = erase sector (9) |
| mjr | 76:7f5912b6340e | 25 | STRB R4,[R0,#7] ; FTFA->FCCOB0 <- command |
| mjr | 76:7f5912b6340e | 26 | |
| mjr | 76:7f5912b6340e | 27 | STRB R1,[R0,#4] ; FTFA->FCCOB3 <- address bits 16-23 |
| mjr | 59:94eb9265b6d7 | 28 | |
| mjr | 76:7f5912b6340e | 29 | MOVS R1,R1,LSR #8 ; address >>= 8 |
| mjr | 76:7f5912b6340e | 30 | STRB R1,[R0,#5] ; FTFA->FCCOB2 <- address bits 8-15 |
| mjr | 76:7f5912b6340e | 31 | |
| mjr | 76:7f5912b6340e | 32 | MOVS R1,R1,LSR #8 ; address >>= 8 |
| mjr | 76:7f5912b6340e | 33 | STRB R1,[R0,#6] ; FTFA->FCCOB1 <- address bits 0-7 |
| mjr | 59:94eb9265b6d7 | 34 | |
| mjr | 77:0b96f6867312 | 35 | ; execute (and wait for completion) |
| mjr | 77:0b96f6867312 | 36 | BL iapExecAndWait |
| mjr | 76:7f5912b6340e | 37 | |
| mjr | 59:94eb9265b6d7 | 38 | ; pop registers and return |
| mjr | 76:7f5912b6340e | 39 | LDMFD R13!,{R1,R4,PC} |
| mjr | 76:7f5912b6340e | 40 | |
| mjr | 76:7f5912b6340e | 41 | ;--------------------------------------------------------------------------- |
| mjr | 76:7f5912b6340e | 42 | ; iapProgramBlock(TFA_Type *ftfa, uint32_t address, const void *src, uint32_t length) |
| mjr | 76:7f5912b6340e | 43 | ; R0 = FTFA pointer |
| mjr | 76:7f5912b6340e | 44 | ; R1 = flash address |
| mjr | 76:7f5912b6340e | 45 | ; R2 = source data pointer |
| mjr | 76:7f5912b6340e | 46 | ; R3 = data length in bytes |
| mjr | 76:7f5912b6340e | 47 | |
| mjr | 76:7f5912b6340e | 48 | EXPORT iapProgramBlock |
| mjr | 76:7f5912b6340e | 49 | iapProgramBlock |
| mjr | 76:7f5912b6340e | 50 | ; save registers |
| mjr | 76:7f5912b6340e | 51 | STMFD R13!, {R1,R2,R3,R4,LR} |
| mjr | 76:7f5912b6340e | 52 | |
| mjr | 76:7f5912b6340e | 53 | ; wait for any previous command to complete |
| mjr | 76:7f5912b6340e | 54 | BL iapWait |
| mjr | 76:7f5912b6340e | 55 | |
| mjr | 76:7f5912b6340e | 56 | ; iterate over the data |
| mjr | 76:7f5912b6340e | 57 | LpLoop |
| mjr | 76:7f5912b6340e | 58 | CMPS R3,#3 ; at least one longword left (>= 4 bytes)? |
| mjr | 76:7f5912b6340e | 59 | BLS LpDone ; no, done |
| mjr | 76:7f5912b6340e | 60 | |
| mjr | 76:7f5912b6340e | 61 | ; clear any errors from the previous command |
| mjr | 76:7f5912b6340e | 62 | BL iapClearErrors |
| mjr | 76:7f5912b6340e | 63 | |
| mjr | 76:7f5912b6340e | 64 | ; set up the command parameters |
| mjr | 76:7f5912b6340e | 65 | MOVS R4,#0 |
| mjr | 76:7f5912b6340e | 66 | STRB R4,[R0,#1] ; FTFA->FCNFG <- 0 |
| mjr | 76:7f5912b6340e | 67 | MOVS R4,#6 ; command = program longword (6) |
| mjr | 76:7f5912b6340e | 68 | STRB R4,[R0,#7] ; FTFA->FCCOB0 <- command |
| mjr | 76:7f5912b6340e | 69 | |
| mjr | 76:7f5912b6340e | 70 | MOVS R4,R1 ; R4 <- current address |
| mjr | 76:7f5912b6340e | 71 | STRB R4,[R0,#4] ; FTFA->FCCOB3 <- address bits 16-23 |
| mjr | 76:7f5912b6340e | 72 | |
| mjr | 76:7f5912b6340e | 73 | MOVS R4,R4,LSR #8 ; address >>= 8 |
| mjr | 76:7f5912b6340e | 74 | STRB R4,[R0,#5] ; FTFA->FCCOB2 <- address bits 8-15 |
| mjr | 76:7f5912b6340e | 75 | |
| mjr | 76:7f5912b6340e | 76 | MOVS R4,R4,LSR #8 ; address >>= 8 |
| mjr | 76:7f5912b6340e | 77 | STRB R4,[R0,#6] ; FTFA->FCCOB1 <- address bits 0-7 |
| mjr | 76:7f5912b6340e | 78 | |
| mjr | 76:7f5912b6340e | 79 | LDRB R4,[R2] ; R4 <- data[0] |
| mjr | 76:7f5912b6340e | 80 | STRB R4,[R0,#8] ; FTFA->FCCOB7 <- data[0] |
| mjr | 76:7f5912b6340e | 81 | |
| mjr | 76:7f5912b6340e | 82 | LDRB R4,[R2,#1] ; R4 <- data[1] |
| mjr | 76:7f5912b6340e | 83 | STRB R4,[R0,#9] ; FTFA->FCCOB6 <- data[1] |
| mjr | 76:7f5912b6340e | 84 | |
| mjr | 76:7f5912b6340e | 85 | LDRB R4,[R2,#2] ; R4 <- data[2] |
| mjr | 76:7f5912b6340e | 86 | STRB R4,[R0,#0xA] ; FTFA->FCCOB5 <- data[2] |
| mjr | 76:7f5912b6340e | 87 | |
| mjr | 76:7f5912b6340e | 88 | LDRB R4,[R2,#3] ; R4 <- data[3] |
| mjr | 76:7f5912b6340e | 89 | STRB R4,[R0,#0xB] ; FTBA->FCCOB4 <- data[3] |
| mjr | 76:7f5912b6340e | 90 | |
| mjr | 76:7f5912b6340e | 91 | ; execute the command |
| mjr | 77:0b96f6867312 | 92 | BL iapExecAndWait |
| mjr | 76:7f5912b6340e | 93 | |
| mjr | 76:7f5912b6340e | 94 | ; advance to the next longword |
| mjr | 76:7f5912b6340e | 95 | ADDS R1,R1,#4 ; flash address += 4 |
| mjr | 76:7f5912b6340e | 96 | ADDS R2,R2,#4 ; source data pointer += 4 |
| mjr | 76:7f5912b6340e | 97 | SUBS R3,R3,#4 ; data length -= 4 |
| mjr | 76:7f5912b6340e | 98 | B LpLoop ; back for the next iteration |
| mjr | 76:7f5912b6340e | 99 | |
| mjr | 76:7f5912b6340e | 100 | LpDone |
| mjr | 76:7f5912b6340e | 101 | ; pop registers and return |
| mjr | 76:7f5912b6340e | 102 | LDMFD R13!, {R1,R2,R3,R4,PC} |
| mjr | 76:7f5912b6340e | 103 | |
| mjr | 76:7f5912b6340e | 104 | |
| mjr | 76:7f5912b6340e | 105 | ;--------------------------------------------------------------------------- |
| mjr | 76:7f5912b6340e | 106 | ; iapClearErrors(FTFA_Type *FTFA) - clear errors from previous command |
| mjr | 76:7f5912b6340e | 107 | ; R0 = FTFA pointer |
| mjr | 76:7f5912b6340e | 108 | |
| mjr | 76:7f5912b6340e | 109 | iapClearErrors |
| mjr | 76:7f5912b6340e | 110 | ; save registers |
| mjr | 76:7f5912b6340e | 111 | STMFD R13!, {R2,R3,LR} |
| mjr | 76:7f5912b6340e | 112 | |
| mjr | 76:7f5912b6340e | 113 | LDRB R2, [R0] ; R2 <- FTFA->FSTAT |
| mjr | 76:7f5912b6340e | 114 | MOVS R3, #0x30 ; FPVIOL (0x10) | ACCERR (0x20) |
| mjr | 76:7f5912b6340e | 115 | ANDS R2, R2, R3 ; R2 &= error bits |
| mjr | 76:7f5912b6340e | 116 | BEQ Lc0 ; if all zeros, no need to reset anything |
| mjr | 76:7f5912b6340e | 117 | STRB R2, [R0] ; write the 1 bits back to clear the error status |
| mjr | 76:7f5912b6340e | 118 | Lc0 |
| mjr | 76:7f5912b6340e | 119 | ; restore registers and return |
| mjr | 76:7f5912b6340e | 120 | LDMFD R13!, {R2,R3,PC} |
| mjr | 76:7f5912b6340e | 121 | |
| mjr | 76:7f5912b6340e | 122 | |
| mjr | 76:7f5912b6340e | 123 | ;--------------------------------------------------------------------------- |
| mjr | 76:7f5912b6340e | 124 | ; iapWait(FTFA_Type *FTFA) - wait for command to complete |
| mjr | 76:7f5912b6340e | 125 | ; R0 = FTFA pointer |
| mjr | 76:7f5912b6340e | 126 | |
| mjr | 76:7f5912b6340e | 127 | iapWait |
| mjr | 76:7f5912b6340e | 128 | ; save registers |
| mjr | 76:7f5912b6340e | 129 | STMFD R13!, {R1,R2,LR} |
| mjr | 76:7f5912b6340e | 130 | |
| mjr | 76:7f5912b6340e | 131 | ; the CCIF bit is SET when the command completes |
| mjr | 76:7f5912b6340e | 132 | Lw0 |
| mjr | 76:7f5912b6340e | 133 | LDRB R1, [R0] ; R1 <- FTFA->FSTAT |
| mjr | 76:7f5912b6340e | 134 | MOVS R2, #0x80 ; CCIF (0x80) |
| mjr | 76:7f5912b6340e | 135 | TSTS R1, R2 ; test R1 & CCIF |
| mjr | 76:7f5912b6340e | 136 | BEQ Lw0 ; if zero, the command is still running |
| mjr | 76:7f5912b6340e | 137 | |
| mjr | 76:7f5912b6340e | 138 | ; pop registers and return |
| mjr | 59:94eb9265b6d7 | 139 | LDMFD R13!, {R1,R2,PC} |
| mjr | 76:7f5912b6340e | 140 | |
| mjr | 76:7f5912b6340e | 141 | |
| mjr | 76:7f5912b6340e | 142 | ;--------------------------------------------------------------------------- |
| mjr | 77:0b96f6867312 | 143 | ; |
| mjr | 77:0b96f6867312 | 144 | ; The iapExecAndWait function MUST NOT BE IN FLASH, since we can't have |
| mjr | 78:1e00b3fa11af | 145 | ; any flash reads occur while an erase or write operation is executing. If |
| mjr | 78:1e00b3fa11af | 146 | ; the code were in flash, the CPU might have to fetch an instruction from |
| mjr | 78:1e00b3fa11af | 147 | ; flash in the course of the loop, which could freeze the CPU. Force the |
| mjr | 78:1e00b3fa11af | 148 | ; linker to put this section in RAM by making it read-write. |
| mjr | 77:0b96f6867312 | 149 | |
| mjr | 77:0b96f6867312 | 150 | AREA iap_ram_asm_code, CODE, READWRITE |
| mjr | 76:7f5912b6340e | 151 | |
| mjr | 77:0b96f6867312 | 152 | ;--------------------------------------------------------------------------- |
| mjr | 77:0b96f6867312 | 153 | ; |
| mjr | 77:0b96f6867312 | 154 | ; iapExecAndWait(FTFA_Type *FTFA) |
| mjr | 77:0b96f6867312 | 155 | ; R0 = FTFA pointer |
| mjr | 77:0b96f6867312 | 156 | ; |
| mjr | 77:0b96f6867312 | 157 | ; This sets the bit in the FTFA status register to launch execution |
| mjr | 77:0b96f6867312 | 158 | ; of the command currently configured in the control registers. The |
| mjr | 77:0b96f6867312 | 159 | ; caller must set up the control registers with the command code, and |
| mjr | 77:0b96f6867312 | 160 | ; any address data parameters requied for the command. After launching |
| mjr | 77:0b96f6867312 | 161 | ; the command, we loop until the FTFA signals command completion. |
| mjr | 77:0b96f6867312 | 162 | ; |
| mjr | 77:0b96f6867312 | 163 | ; This routine turns off CPU interrupts and disables all peripheral |
| mjr | 77:0b96f6867312 | 164 | ; interrupts through the NVIC while the command is executing. That |
| mjr | 77:0b96f6867312 | 165 | ; should eliminate any possibility of a hardware interrupt triggering |
| mjr | 77:0b96f6867312 | 166 | ; a flash fetch during a programming operation. We restore interrupts |
| mjr | 77:0b96f6867312 | 167 | ; on return. The caller doesn't need to (and shouldn't) do its own |
| mjr | 77:0b96f6867312 | 168 | ; interrupt manipulation. In testing, it seems problematic to leave |
| mjr | 77:0b96f6867312 | 169 | ; interrupts disabled for long periods, so the safest approach seems |
| mjr | 77:0b96f6867312 | 170 | ; to be to disable the interrupts only for the actual command execution. |
| mjr | 77:0b96f6867312 | 171 | |
| mjr | 77:0b96f6867312 | 172 | EXPORT iapExecAndWait |
| mjr | 77:0b96f6867312 | 173 | iapExecAndWait |
| mjr | 76:7f5912b6340e | 174 | ; save registers |
| mjr | 77:0b96f6867312 | 175 | STMFD R13!, {R1,R2,R3,R4,LR} |
| mjr | 77:0b96f6867312 | 176 | |
| mjr | 77:0b96f6867312 | 177 | ; disable all interrupts in the NVIC |
| mjr | 77:0b96f6867312 | 178 | LDR R3, =NVIC_ICER ; R3 <- NVIC_ICER |
| mjr | 77:0b96f6867312 | 179 | LDR R4, [R3] ; R4 <- current interrupt status |
| mjr | 77:0b96f6867312 | 180 | MOVS R2, #0 ; R2 <- 0 |
| mjr | 78:1e00b3fa11af | 181 | SUBS R2,R2,#1 ; R2 <- 0 - 1 = 0xFFFFFFFF |
| mjr | 77:0b96f6867312 | 182 | STR R2, [R3] ; [NVIC_ICER] <- 0xFFFFFFFF (disable all interrupts) |
| mjr | 77:0b96f6867312 | 183 | |
| mjr | 77:0b96f6867312 | 184 | ; disable CPU interrupts |
| mjr | 77:0b96f6867312 | 185 | CPSID I ; interrupts off |
| mjr | 77:0b96f6867312 | 186 | DMB ; data memory barrier |
| mjr | 78:1e00b3fa11af | 187 | DSB ; data synchronization barrier |
| mjr | 77:0b96f6867312 | 188 | ISB ; instruction synchronization barrier |
| mjr | 77:0b96f6867312 | 189 | |
| mjr | 77:0b96f6867312 | 190 | ; Launch the command by writing the CCIF bit to FTFA_FSTAT |
| mjr | 76:7f5912b6340e | 191 | MOVS R1, #0x80 ; CCIF (0x80) |
| mjr | 76:7f5912b6340e | 192 | STRB R1, [R0] ; FTFA->FSTAT = CCIF |
| mjr | 76:7f5912b6340e | 193 | |
| mjr | 77:0b96f6867312 | 194 | ; Wait for the command to complete. The FTFA sets the CCIF |
| mjr | 77:0b96f6867312 | 195 | ; bit in FTFA_FSTAT when the command is finished, so spin until |
| mjr | 77:0b96f6867312 | 196 | ; the bit reads as set. |
| mjr | 77:0b96f6867312 | 197 | Lew0 |
| mjr | 77:0b96f6867312 | 198 | LDRB R1, [R0] ; R1 <- FTFA->FSTAT |
| mjr | 77:0b96f6867312 | 199 | MOVS R2, #0x80 ; CCIF (0x80) |
| mjr | 77:0b96f6867312 | 200 | TSTS R1, R2 ; test R1 & CCIF |
| mjr | 77:0b96f6867312 | 201 | BEQ Lew0 ; if zero, the command is still running |
| mjr | 77:0b96f6867312 | 202 | |
| mjr | 77:0b96f6867312 | 203 | ; restore CPU interrupts |
| mjr | 77:0b96f6867312 | 204 | CPSIE I |
| mjr | 76:7f5912b6340e | 205 | |
| mjr | 77:0b96f6867312 | 206 | ; re-enable NVIC interrupts |
| mjr | 77:0b96f6867312 | 207 | LDR R3, =NVIC_ISER ; R3 <- NVIC_ISER |
| mjr | 77:0b96f6867312 | 208 | STR R4, [R3] ; NVIC_ISER = old interrupt enable vector |
| mjr | 77:0b96f6867312 | 209 | |
| mjr | 76:7f5912b6340e | 210 | ; pop registers and return |
| mjr | 77:0b96f6867312 | 211 | LDMFD R13!, {R1,R2,R3,R4,PC} |
| mjr | 77:0b96f6867312 | 212 | |
| mjr | 78:1e00b3fa11af | 213 | ALIGN |
| mjr | 78:1e00b3fa11af | 214 | NVIC_ISER DCD 0xE000E100 |
| mjr | 78:1e00b3fa11af | 215 | NVIC_ICER DCD 0xE000E180 |
| mjr | 78:1e00b3fa11af | 216 | |
| mjr | 59:94eb9265b6d7 | 217 | END |
