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 mov.w r8, ISP_KEY_ADDRESS
00102 mov.w r9, AVR32_WDT_ADDRESS
00103 mov.w r10, ISP_CFG1_ADDRESS
00104 mov.w r11, AVR32_PM_ADDRESS
00105 ld.w r0, r8[0]
00106 mov.w r1, ISP_KEY_VALUE
00107
00108
00109 ld.w r2, r10[0]
00110 mov.w r3, ISP_CFG1_CRC8_POLYNOMIAL
00111 mov r4, r2
00112 rcall test_crc8_end
00113 brne start_loader
00114
00115
00116 bfextu r3, r2, ISP_CFG1_BOOT_KEY1_OFFSET, ISP_CFG1_BOOT_KEY1_SIZE
00117 cp.w r3, ISP_CFG1_BOOT_KEY1_VALUE
00118 brne start_loader
00119
00120
00121 test_isp_force:
00122 bld r2, ISP_CFG1_FORCE_OFFSET
00123 brcs start_loader
00124
00125
00126 ld.w r3, r11[AVR32_PM_RCAUSE]
00127 mov.w r4, AVR32_PM_RCAUSE_POR_MASK |\
00128 AVR32_PM_RCAUSE_EXT_MASK |\
00129 AVR32_PM_RCAUSE_JTAG_MASK |\
00130 AVR32_PM_RCAUSE_OCDRST_MASK |\
00131 AVR32_PM_RCAUSE_JTAGHARD_MASK
00132 tst r3, r4
00133 brne manage_io_cond
00134
00135
00136 bld r3, AVR32_PM_RCAUSE_WDT_OFFSET
00137 brcs start_program
00138
00139
00140 cp.w r0, r1
00141 brne start_program_no_isp_key
00142
00143
00144 start_loader:
00145 rcall disable_wdt
00146 st.w r8[0], r1
00147
00148
00149 mov sp, _estack
00150
00151
00152 ssrf AVR32_SR_EM_OFFSET
00153
00154
00155 mov r0, _evba
00156 mtsr AVR32_EVBA, r0
00157
00158
00159 mov r0, _data
00160 mov r1, _edata
00161 sub r2, pc, $ - _data_lma
00162 rcall load_idata
00163
00164
00165 mov r0, __bss_start
00166 mov r1, _end
00167 mov.w r2, 0
00168 mov.w r3, 0
00169 rjmp clear_udata
00170 clear_udata_loop:
00171 st.d r0++, r2
00172 clear_udata:
00173 cp.w r0, r1
00174 brlo clear_udata_loop
00175
00176
00177 mov r0, _const
00178 mov r1, _econst
00179 sub r2, pc, $ - _const_lma
00180 rcall load_idata
00181
00182
00183 call main
00184
00185
00186 manage_io_cond:
00187
00188 bld r2, ISP_CFG1_IO_COND_EN_OFFSET
00189 brcc start_program
00190
00191
00192 mov.w r10, ISP_CFG2_ADDRESS
00193 ld.w r2, r10[0]
00194 mov.w r3, ISP_CFG2_CRC8_POLYNOMIAL
00195 mov r4, r2
00196 rcall test_crc8_end
00197 brne start_loader
00198
00199
00200 bfextu r3, r2, ISP_CFG2_BOOT_KEY_OFFSET, ISP_CFG2_BOOT_KEY_SIZE
00201 cp.w r3, ISP_CFG2_BOOT_KEY_VALUE
00202 brne start_loader
00203
00204
00205 bfextu r3, r2, ISP_CFG2_IO_COND_PIN_OFFSET, ISP_CFG2_IO_COND_PIN_SIZE
00206 cp.w r3, AVR32_GPIO_NUMBER_OF_PINS
00207 brhs start_loader
00208
00209
00210 mov.w r10, AVR32_GPIO_ADDRESS
00211 lsr r4, r3, 5
00212 lsl r4, 8
00213 add r10, r4
00214 ld.w r4, r10[AVR32_GPIO_PVR]
00215 andl r3, 0x1F
00216 lsr r4, r4, r3
00217 bfextu r3, r2, ISP_CFG2_IO_COND_LEVEL_OFFSET, ISP_CFG2_IO_COND_LEVEL_SIZE
00218 eor r4, r3
00219 bld r4, 0
00220 brcc start_loader
00221
00222 start_program:
00223 cp.w r0, r1
00224 brne start_program_no_isp_key
00225 rcall disable_wdt
00226 .global boot_program
00227 .type boot_program, @function
00228 boot_program:
00229
00230 mov.w r8, ISP_KEY_ADDRESS
00231 mov.w r0, 0
00232 st.w r8[0], r0
00233 start_program_no_isp_key:
00234 mov.w r0, AVR32_SR_GM_MASK | AVR32_SR_EM_MASK | (AVR32_SR_M_SUP << AVR32_SR_M_OFFSET)
00235 mtsr AVR32_SR, r0
00236 .irp rd, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr
00237 mov.w \rd, 0
00238 .endr
00239 mtsr AVR32_EVBA, r0
00240 mtsr AVR32_COUNT, r0
00241 lddpc pc, program_start_address
00242
00243 disable_wdt:
00244 mov.w r2, AVR32_WDT_KEY_VALUE << AVR32_WDT_CTRL_KEY_OFFSET
00245 st.w r9[AVR32_WDT_CTRL], r2
00246 eor.w r2, AVR32_WDT_CTRL_KEY_MASK
00247 st.w r9[AVR32_WDT_CTRL], r2
00248 mov pc, lr
00249
00250 load_idata_loop:
00251 ld.d r4, r2++
00252 st.d r0++, r4
00253 load_idata:
00254 cp.w r0, r1
00255 brlo load_idata_loop
00256 mov pc, lr
00257
00258
00259 crc8:
00260 clz r5, r4
00261 rsub r5, r5, 32 - 9
00262 lsl r5, r3, r5
00263 eor r4, r5
00264 #if 0
00265 .global test_crc8_end
00266 .type test_crc8_end, @function
00267 #endif
00268 test_crc8_end:
00269 cp.w r4, 0xFF
00270 brhi crc8
00271 cp.w r4, 0
00272 retal r4
00273
00274
00275
00276
00277 .balign 4
00278
00279 program_start_address:
00280 .word PROGRAM_START_ADDRESS
00281
00282
00283 .section .evba, "ax", @progbits
00284
00285
00286 .balign 2
00287
00288
00289 .global _evba
00290 .type _evba, @function
00291 _evba:
00292 lda.w r8, _start
00293 mov.w r9, AVR32_SR_GM_MASK | AVR32_SR_EM_MASK | (AVR32_SR_M_SUP << AVR32_SR_M_OFFSET)
00294 mov sp, _estack - 6 * 4
00295 pushm r8-r9
00296 rete
00297
00298