00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <avr32/io.h>
00046 #include "conf_isp.h"
00047
00048
00051
00052
00053
00054
00055
00056 .macro eor.w rd, imm
00057 .if \imm & 0x0000FFFF
00058 eorl \rd, LO(\imm)
00059 .endif
00060 .if \imm & 0xFFFF0000
00061 eorh \rd, HI(\imm)
00062 .endif
00063 .endm
00064
00065
00066 .macro mov.w rd, imm
00067 .if ((-(1 << (21 - 1))) <= \imm) && (\imm <= ((1 << (21 - 1)) - 1))
00068 mov \rd, \imm
00069 #if __AVR32_UC__ >= 2
00070 .elseif !(\imm & 0x0000FFFF)
00071 movh \rd, HI(\imm)
00072 #endif
00073 .else
00074 mov \rd, LO(\imm)
00075 orh \rd, HI(\imm)
00076 .endif
00077 .endm
00078
00079
00080
00081
00082 .macro or.w rd, imm
00083 .if \imm & 0x0000FFFF
00084 orl \rd, LO(\imm)
00085 .endif
00086 .if \imm & 0xFFFF0000
00087 orh \rd, HI(\imm)
00088 .endif
00089 .endm
00090
00091
00092 .section .reset, "ax", @progbits
00093
00094
00095 .balign 2
00096
00097
00098 .global _start
00099 .type _start, @function
00100 _start:
00101
00102 add r0, r0
00103 add r0, r0
00104 add r0, r0
00105 add r0, r0
00106 add r0, r0
00107 add r0, r0
00108 add r0, r0
00109 add r0, r0
00110 add r0, r0
00111 add r0, r0
00112 add r0, r0
00113 add r0, r0
00114 add r0, r0
00115 add r0, r0
00116 add r0, r0
00117 add r0, r0
00118 mov.w r8, ISP_KEY_ADDRESS
00119 mov.w r9, AVR32_WDT_ADDRESS
00120 mov.w r10, AVR32_FLASHC_ADDRESS
00121 mov.w r11, AVR32_PM_ADDRESS
00122 ld.w r0, r8[0]
00123 mov.w r1, ISP_KEY_VALUE
00124 ld.w r2, r10[AVR32_FLASHC_FGPFRLO]
00125 bld r2, ISP_GPFB_BOD_EN_OFFSET
00126 brcc test_isp_gpfb_force
00127 ld.w r3, r11[AVR32_PM_BOD]
00128 mov.w r4, AVR32_BOD_KEY << AVR32_PM_BOD_KEY_OFFSET
00129 or.w r3, AVR32_PM_BOD_FCD_MASK |\
00130 ((~AVR32_BOD_KEY << AVR32_PM_BOD_KEY_OFFSET) & AVR32_PM_BOD_KEY_MASK)
00131 mov.w r5, AVR32_PM_BOD_CTRL_ENABLED_NORESET
00132 bfins r3, r5, AVR32_PM_BOD_CTRL_OFFSET, AVR32_PM_BOD_CTRL_SIZE
00133 st.w r11[AVR32_PM_BOD], r4
00134 st.w r11[AVR32_PM_BOD], r3
00135 mov.w r5, AVR32_PM_BOD_CTRL_ENABLED
00136 bfins r3, r5, AVR32_PM_BOD_CTRL_OFFSET, AVR32_PM_BOD_CTRL_SIZE
00137 st.w r11[AVR32_PM_BOD], r4
00138 st.w r11[AVR32_PM_BOD], r3
00139 test_isp_gpfb_force:
00140 bld r2, ISP_GPFB_FORCE_OFFSET
00141 brcs start_loader
00142 ld.w r3, r11[AVR32_PM_RCAUSE]
00143 mov.w r4, AVR32_PM_RCAUSE_POR_MASK |\
00144 AVR32_PM_RCAUSE_EXT_MASK |\
00145 AVR32_PM_RCAUSE_JTAG_MASK |\
00146 AVR32_PM_RCAUSE_OCDRST_MASK |\
00147 AVR32_PM_RCAUSE_JTAGHARD_MASK
00148 tst r3, r4
00149 brne manage_io_cond
00150 bld r3, AVR32_PM_RCAUSE_WDT_OFFSET
00151 brcs start_program
00152 cp.w r0, r1
00153 brne start_program_no_isp_key
00154
00155 start_loader:
00156 rcall disable_wdt
00157 st.w r8[0], r1
00158
00159
00160 mov sp, _estack
00161
00162
00163 ssrf AVR32_SR_EM_OFFSET
00164
00165
00166 mov r0, _evba
00167 mtsr AVR32_EVBA, r0
00168
00169
00170 mov r0, _data
00171 mov r1, _edata
00172 sub r2, pc, $ - _data_lma
00173 rcall load_idata
00174
00175
00176 mov r0, __bss_start
00177 mov r1, _end
00178 mov.w r2, 0
00179 mov.w r3, 0
00180 rjmp clear_udata
00181 clear_udata_loop:
00182 st.d r0++, r2
00183 clear_udata:
00184 cp.w r0, r1
00185 brlo clear_udata_loop
00186
00187
00188 mov r0, _const
00189 mov r1, _econst
00190 sub r2, pc, $ - _const_lma
00191 rcall load_idata
00192
00193
00194 call main
00195
00196 manage_io_cond:
00197 bld r2, ISP_GPFB_IO_COND_EN_OFFSET
00198 brcc start_program
00199 mov.w r10, ISP_CFG_ADDRESS
00200 ld.w r2, r10[0]
00201 mov.w r3, ISP_CFG_CRC8_POLYNOMIAL
00202 mov r4, r2
00203 rjmp test_crc8_end
00204 crc8:
00205 clz r5, r4
00206 rsub r5, r5, 32 - 9
00207 lsl r5, r3, r5
00208 eor r4, r5
00209 test_crc8_end:
00210 cp.w r4, 0xFF
00211 brhi crc8
00212 cp.w r4, 0
00213 brne start_loader
00214 bfextu r3, r2, ISP_CFG_BOOT_KEY_OFFSET, ISP_CFG_BOOT_KEY_SIZE
00215 cp.w r3, ISP_CFG_BOOT_KEY_VALUE
00216 brne start_loader
00217 bfextu r3, r2, ISP_CFG_IO_COND_PIN_OFFSET, ISP_CFG_IO_COND_PIN_SIZE
00218 cp.w r3, AVR32_GPIO_NUMBER_OF_PINS
00219 brhs start_loader
00220 mov.w r10, AVR32_GPIO_ADDRESS
00221 lsr r4, r3, 5
00222 lsl r4, 8
00223 add r10, r4
00224 ld.w r4, r10[AVR32_GPIO_PVR]
00225 andl r3, 0x1F
00226 lsr r4, r4, r3
00227 bfextu r3, r2, ISP_CFG_IO_COND_LEVEL_OFFSET, ISP_CFG_IO_COND_LEVEL_SIZE
00228 eor r4, r3
00229 bld r4, 0
00230 brcc start_loader
00231
00232 start_program:
00233 cp.w r0, r1
00234 brne start_program_no_isp_key
00235 rcall disable_wdt
00236 .global boot_program
00237 .type boot_program, @function
00238 boot_program:
00239 mov.w r8, ISP_KEY_ADDRESS
00240 mov.w r0, 0
00241 st.w r8[0], r0
00242 start_program_no_isp_key:
00243 mov.w r0, AVR32_SR_GM_MASK | AVR32_SR_EM_MASK | (AVR32_SR_M_SUP << AVR32_SR_M_OFFSET)
00244 mtsr AVR32_SR, r0
00245 .irp rd, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr
00246 mov.w \rd, 0
00247 .endr
00248 mtsr AVR32_EVBA, r0
00249 mtsr AVR32_COUNT, r0
00250 lddpc pc, program_start_address
00251
00252 disable_wdt:
00253 mov.w r2, AVR32_WDT_KEY_VALUE << AVR32_WDT_CTRL_KEY_OFFSET
00254 st.w r9[AVR32_WDT_CTRL], r2
00255 eor.w r2, AVR32_WDT_CTRL_KEY_MASK
00256 st.w r9[AVR32_WDT_CTRL], r2
00257 mov pc, lr
00258
00259 load_idata_loop:
00260 ld.d r4, r2++
00261 st.d r0++, r4
00262 load_idata:
00263 cp.w r0, r1
00264 brlo load_idata_loop
00265 mov pc, lr
00266
00267
00268
00269
00270 .balign 4
00271
00272 program_start_address:
00273 .word PROGRAM_START_ADDRESS
00274
00275
00276 .section .evba, "ax", @progbits
00277
00278
00279 .balign 2
00280
00281
00282 .global _evba
00283 .type _evba, @function
00284 _evba:
00285 lda.w r8, _start
00286 mov.w r9, AVR32_SR_GM_MASK | AVR32_SR_EM_MASK | (AVR32_SR_M_SUP << AVR32_SR_M_OFFSET)
00287 mov sp, _estack - 6 * 4
00288 pushm r8-r9
00289 rete
00290
00291