| Xmega IEC60730 Class B Library 1.0 |

All Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
classb_cpu_iar.c
Go to the documentation of this file.
1 /* This file has been prepared for Doxygen automatic documentation generation.*/
2 /**
3 * \file
4 *
5 * \brief This file contains the function definition for a CPU register test
6 * that is compatible with IAR.
7 *
8 * \par Application note:
9 * AVR1610: Guide to IEC60730 Class B compliance with XMEGA
10 *
11 * \par Documentation
12 * For comprehensive code documentation, supported compilers, compiler
13 * settings and supported devices see readme.html
14 *
15 * \author
16 * Atmel Corporation: http://www.atmel.com \n
17 * Support email: avr@atmel.com
18 *
19 *
20 * Copyright (C) 2011 Atmel Corporation. All rights reserved.
21 *
22 * \page License
23 *
24 * Redistribution and use in source and binary forms, with or without
25 * modification, are permitted provided that the following conditions are met:
26 *
27 * 1. Redistributions of source code must retain the above copyright notice,
28 * this list of conditions and the following disclaimer.
29 *
30 * 2. Redistributions in binary form must reproduce the above copyright notice,
31 * this list of conditions and the following disclaimer in the documentation
32 * and/or other materials provided with the distribution.
33 *
34 * 3. The name of Atmel may not be used to endorse or promote products derived
35 * from this software without specific prior written permission.
36 *
37 * 4. This software may only be redistributed and used in connection with an
38 * Atmel AVR product.
39 *
40 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
41 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
42 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
43 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
44 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
46 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
47 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
50 * DAMAGE.
51 */
52
53 #include "avr_compiler.h"
54 #include "classb_cpu.h"
55
56 //! \cond IAR
57
58 //! \addtogroup classb_cpu_registers
59 //@{
60
61 /*!
62 * \brief CPU register self-diagnostic routine for IAR.
63 *
64 * This function tests the CPU registers, preserving those registers specified
65 * in the AVR GCC compiler documentation. Note that if there should be a fault
66 * in a register that needs preservation, its value would not be restored.
67 *
68 * Registers are tested in this order:
69 * -# Critical registers
70 * -# Return value register: R16
71 * -# stack pointer: SPL/SPH
72 * -# register %file: R31 -- R30
73 * -# Non-critical registers
74 * -# register %file: R29 -- R17, R15 -- R0
75 * -# extended addressing registers: RAMPD/X/Y/Z, EIND
76 * -# status register: SREG (except interrupt flag)
77 *
78 * \retval false No register fault detected.
79 * \retval true Register fault detected.
80 *
81 * \note Interrupts must be disabled during this test.
82 */
83 bool classb_register_test (void)
84 {
85 // IAR should use R16 for this variable.
86 bool error = true;
87
88 // Test R16 first because it is the return register! FAIL -> hang device.
89 CLASSB_RegSet_R_HI(R16,0x55);
90 CLASSB_RegTest_R_HI(R16,0xAA,CLASSB_ERROR_CRIT);
91 CLASSB_RegTest_R_HI(R16,0x55,CLASSB_ERROR_CRIT);
92
93 // Then test R31 and R30 because they are used in the rest of the tests.
94 CLASSB_RegSet_R_HI(R31,0x55);
95 CLASSB_RegTest_R_HI(R31,0xAA,CLASSB_ERROR_CRIT);
96 CLASSB_RegTest_R_HI(R31,0x55,CLASSB_ERROR_CRIT);
97
98 CLASSB_RegSet_R_HI(R30,0x55);
99 CLASSB_RegTest_R_HI(R30,0xAA,CLASSB_ERROR_CRIT);
100 CLASSB_RegTest_R_HI(R30,0x55,CLASSB_ERROR_CRIT);
101
102 // SPH
103 CLASSB_RegStore_IO(0x3D);
104 CLASSB_RegSet_IO(0x3D,0x55);
105 CLASSB_RegTest_IO(0x3D,0xAA,CLASSB_ERROR_CRIT);
106 CLASSB_RegTest_IO(0x3D,0x55,CLASSB_ERROR_CRIT);
107 CLASSB_RegRestore_IO(0x3D);
108
109 // SPL
110 CLASSB_RegStore_IO(0x3E);
111 CLASSB_RegSet_IO(0x3E,0x55);
112 CLASSB_RegTest_IO(0x3E,0xAA,CLASSB_ERROR_CRIT);
113 CLASSB_RegTest_IO(0x3E,0x55,CLASSB_ERROR_CRIT);
114 CLASSB_RegRestore_IO(0x3E);
115
116 // Test R29-R24 non-destructively.
117 CLASSB_RegStore_R(R29);
118 CLASSB_RegSet_R_HI(R29,0x55);
119 CLASSB_RegTest_R_HI(R29,0xAA,CLASSB_ERROR_NON_CRIT);
120 CLASSB_RegTest_R_HI(R29,0x55,CLASSB_ERROR_NON_CRIT);
121 CLASSB_RegRestore_R(R29);
122
123 CLASSB_RegStore_R(R28);
124 CLASSB_RegSet_R_HI(R28,0x55);
125 CLASSB_RegTest_R_HI(R28,0xAA,CLASSB_ERROR_NON_CRIT);
126 CLASSB_RegTest_R_HI(R28,0x55,CLASSB_ERROR_NON_CRIT);
127 CLASSB_RegRestore_R(R28);
128
129 CLASSB_RegStore_R(R27);
130 CLASSB_RegSet_R_HI(R27,0x55);
131 CLASSB_RegTest_R_HI(R27,0xAA,CLASSB_ERROR_NON_CRIT);
132 CLASSB_RegTest_R_HI(R27,0x55,CLASSB_ERROR_NON_CRIT);
133 CLASSB_RegRestore_R(R27);
134
135 CLASSB_RegStore_R(R26);
136 CLASSB_RegSet_R_HI(R26,0x55);
137 CLASSB_RegTest_R_HI(R26,0xAA,CLASSB_ERROR_NON_CRIT);
138 CLASSB_RegTest_R_HI(R26,0x55,CLASSB_ERROR_NON_CRIT);
139 CLASSB_RegRestore_R(R26);
140
141 CLASSB_RegStore_R(R25);
142 CLASSB_RegSet_R_HI(R25,0x55);
143 CLASSB_RegTest_R_HI(R25,0xAA,CLASSB_ERROR_NON_CRIT);
144 CLASSB_RegTest_R_HI(R25,0x55,CLASSB_ERROR_NON_CRIT);
145 CLASSB_RegRestore_R(R25);
146
147 CLASSB_RegStore_R(R24);
148 CLASSB_RegSet_R_HI(R24,0x55);
149 CLASSB_RegTest_R_HI(R24,0xAA,CLASSB_ERROR_NON_CRIT);
150 CLASSB_RegTest_R_HI(R24,0x55,CLASSB_ERROR_NON_CRIT);
151 CLASSB_RegRestore_R(R24);
152
153 // Test R23-R17 destructively.
154 CLASSB_RegSet_R_HI(R23,0x55);
155 CLASSB_RegTest_R_HI(R23,0xAA,CLASSB_ERROR_NON_CRIT);
156 CLASSB_RegTest_R_HI(R23,0x55,CLASSB_ERROR_NON_CRIT);
157
158 CLASSB_RegSet_R_HI(R22,0x55);
159 CLASSB_RegTest_R_HI(R22,0xAA,CLASSB_ERROR_NON_CRIT);
160 CLASSB_RegTest_R_HI(R22,0x55,CLASSB_ERROR_NON_CRIT);
161
162 CLASSB_RegSet_R_HI(R21,0x55);
163 CLASSB_RegTest_R_HI(R21,0xAA,CLASSB_ERROR_NON_CRIT);
164 CLASSB_RegTest_R_HI(R21,0x55,CLASSB_ERROR_NON_CRIT);
165
166 CLASSB_RegSet_R_HI(R20,0x55);
167 CLASSB_RegTest_R_HI(R20,0xAA,CLASSB_ERROR_NON_CRIT);
168 CLASSB_RegTest_R_HI(R20,0x55,CLASSB_ERROR_NON_CRIT);
169
170 CLASSB_RegSet_R_HI(R19,0x55);
171 CLASSB_RegTest_R_HI(R19,0xAA,CLASSB_ERROR_NON_CRIT);
172 CLASSB_RegTest_R_HI(R19,0x55,CLASSB_ERROR_NON_CRIT);
173
174 CLASSB_RegSet_R_HI(R18,0x55);
175 CLASSB_RegTest_R_HI(R18,0xAA,CLASSB_ERROR_NON_CRIT);
176 CLASSB_RegTest_R_HI(R18,0x55,CLASSB_ERROR_NON_CRIT);
177
178 CLASSB_RegSet_R_HI(R17,0x55);
179 CLASSB_RegTest_R_HI(R17,0xAA,CLASSB_ERROR_NON_CRIT);
180 CLASSB_RegTest_R_HI(R17,0x55,CLASSB_ERROR_NON_CRIT);
181
182 // Test R15-R4 non-destructively.
183 CLASSB_RegStore_R(R15);
184 CLASSB_RegSet_R_LO(R15,0x55);
185 CLASSB_RegTest_R_LO(R15,0xAA,CLASSB_ERROR_NON_CRIT);
186 CLASSB_RegTest_R_LO(R15,0x55,CLASSB_ERROR_NON_CRIT);
187 CLASSB_RegRestore_R(R15);
188
189 CLASSB_RegStore_R(R14);
190 CLASSB_RegSet_R_LO(R14,0x55);
191 CLASSB_RegTest_R_LO(R14,0xAA,CLASSB_ERROR_NON_CRIT);
192 CLASSB_RegTest_R_LO(R14,0x55,CLASSB_ERROR_NON_CRIT);
193 CLASSB_RegRestore_R(R14);
194
195 CLASSB_RegStore_R(R13);
196 CLASSB_RegSet_R_LO(R13,0x55);
197 CLASSB_RegTest_R_LO(R13,0xAA,CLASSB_ERROR_NON_CRIT);
198 CLASSB_RegTest_R_LO(R13,0x55,CLASSB_ERROR_NON_CRIT);
199 CLASSB_RegRestore_R(R13);
200
201 CLASSB_RegStore_R(R12);
202 CLASSB_RegSet_R_LO(R12,0x55);
203 CLASSB_RegTest_R_LO(R12,0xAA,CLASSB_ERROR_NON_CRIT);
204 CLASSB_RegTest_R_LO(R12,0x55,CLASSB_ERROR_NON_CRIT);
205 CLASSB_RegRestore_R(R12);
206
207 CLASSB_RegStore_R(R11);
208 CLASSB_RegSet_R_LO(R11,0x55);
209 CLASSB_RegTest_R_LO(R11,0xAA,CLASSB_ERROR_NON_CRIT);
210 CLASSB_RegTest_R_LO(R11,0x55,CLASSB_ERROR_NON_CRIT);
211 CLASSB_RegRestore_R(R11);
212
213 CLASSB_RegStore_R(R10);
214 CLASSB_RegSet_R_LO(R10,0x55);
215 CLASSB_RegTest_R_LO(R10,0xAA,CLASSB_ERROR_NON_CRIT);
216 CLASSB_RegTest_R_LO(R10,0x55,CLASSB_ERROR_NON_CRIT);
217 CLASSB_RegRestore_R(R10);
218
219 CLASSB_RegStore_R(R9);
220 CLASSB_RegSet_R_LO(R9,0x55);
221 CLASSB_RegTest_R_LO(R9,0xAA,CLASSB_ERROR_NON_CRIT);
222 CLASSB_RegTest_R_LO(R9,0x55,CLASSB_ERROR_NON_CRIT);
223 CLASSB_RegRestore_R(R9);
224
225 CLASSB_RegStore_R(R8);
226 CLASSB_RegSet_R_LO(R8,0x55);
227 CLASSB_RegTest_R_LO(R8,0xAA,CLASSB_ERROR_NON_CRIT);
228 CLASSB_RegTest_R_LO(R8,0x55,CLASSB_ERROR_NON_CRIT);
229 CLASSB_RegRestore_R(R8);
230
231 CLASSB_RegStore_R(R7);
232 CLASSB_RegSet_R_LO(R7,0x55);
233 CLASSB_RegTest_R_LO(R7,0xAA,CLASSB_ERROR_NON_CRIT);
234 CLASSB_RegTest_R_LO(R7,0x55,CLASSB_ERROR_NON_CRIT);
235 CLASSB_RegRestore_R(R7);
236
237 CLASSB_RegStore_R(R6);
238 CLASSB_RegSet_R_LO(R6,0x55);
239 CLASSB_RegTest_R_LO(R6,0xAA,CLASSB_ERROR_NON_CRIT);
240 CLASSB_RegTest_R_LO(R6,0x55,CLASSB_ERROR_NON_CRIT);
241 CLASSB_RegRestore_R(R6);
242
243 CLASSB_RegStore_R(R5);
244 CLASSB_RegSet_R_LO(R5,0x55);
245 CLASSB_RegTest_R_LO(R5,0xAA,CLASSB_ERROR_NON_CRIT);
246 CLASSB_RegTest_R_LO(R5,0x55,CLASSB_ERROR_NON_CRIT);
247 CLASSB_RegRestore_R(R5);
248
249 CLASSB_RegStore_R(R4);
250 CLASSB_RegSet_R_LO(R4,0x55);
251 CLASSB_RegTest_R_LO(R4,0xAA,CLASSB_ERROR_NON_CRIT);
252 CLASSB_RegTest_R_LO(R4,0x55,CLASSB_ERROR_NON_CRIT);
253 CLASSB_RegRestore_R(R4);
254
255 // Test R3-R0 destructively.
256 CLASSB_RegSet_R_LO(R3,0x55);
257 CLASSB_RegTest_R_LO(R3,0xAA,CLASSB_ERROR_NON_CRIT);
258 CLASSB_RegTest_R_LO(R3,0x55,CLASSB_ERROR_NON_CRIT);
259
260 CLASSB_RegSet_R_LO(R2,0x55);
261 CLASSB_RegTest_R_LO(R2,0xAA,CLASSB_ERROR_NON_CRIT);
262 CLASSB_RegTest_R_LO(R2,0x55,CLASSB_ERROR_NON_CRIT);
263
264 CLASSB_RegSet_R_LO(R1,0x55);
265 CLASSB_RegTest_R_LO(R1,0xAA,CLASSB_ERROR_NON_CRIT);
266 CLASSB_RegTest_R_LO(R1,0x55,CLASSB_ERROR_NON_CRIT);
267
268 CLASSB_RegSet_R_LO(R0,0x55);
269 CLASSB_RegTest_R_LO(R0,0xAA,CLASSB_ERROR_NON_CRIT);
270 CLASSB_RegTest_R_LO(R0,0x55,CLASSB_ERROR_NON_CRIT);
271
272 // Test IO registers non-destructively.
273 // RAMPD
274 #ifdef CLASSB_HAS_BIGMEM
275 CLASSB_RegStore_IO(0x38);
276 CLASSB_RegSet_IO(0x38,0x55);
277 CLASSB_RegTest_IO(0x38,0xAA,CLASSB_ERROR_NON_CRIT);
278 CLASSB_RegTest_IO(0x38,0x55,CLASSB_ERROR_NON_CRIT);
279 CLASSB_RegRestore_IO(0x38);
280 #endif
281
282 // RAMPX
283 #ifdef CLASSB_HAS_BIGMEM
284 CLASSB_RegStore_IO(0x39);
285 CLASSB_RegSet_IO(0x39,0x55);
286 CLASSB_RegTest_IO(0x39,0xAA,CLASSB_ERROR_NON_CRIT);
287 CLASSB_RegTest_IO(0x39,0x55,CLASSB_ERROR_NON_CRIT);
288 CLASSB_RegRestore_IO(0x39);
289 #endif
290
291 // RAMPY
292 #ifdef CLASSB_HAS_BIGMEM
293 CLASSB_RegStore_IO(0x3A);
294 CLASSB_RegSet_IO(0x3A,0x55);
295 CLASSB_RegTest_IO(0x3A,0xAA,CLASSB_ERROR_NON_CRIT);
296 CLASSB_RegTest_IO(0x3A,0x55,CLASSB_ERROR_NON_CRIT);
297 CLASSB_RegRestore_IO(0x3A);
298 #endif
299
300 // RAMPZ
301 #if defined(CLASSB_HAS_BIGMEM) || defined(CLASSB_HAS_BIGFLASH)
302 CLASSB_RegStore_IO(0x3B);
303 CLASSB_RegSet_IO(0x3B,0x55);
304 CLASSB_RegTest_IO(0x3B,0xAA,CLASSB_ERROR_NON_CRIT);
305 CLASSB_RegTest_IO(0x3B,0x55,CLASSB_ERROR_NON_CRIT);
306 CLASSB_RegRestore_IO(0x3B);
307 #endif
308
309 // EIND
310 #ifdef CLASSB_HAS_BIGFLASH
311 CLASSB_RegStore_IO(0x3C);
312 CLASSB_RegSet_IO(0x3C,0x55);
313 CLASSB_RegTest_IO(0x3C,0xAA,CLASSB_ERROR_NON_CRIT);
314 CLASSB_RegTest_IO(0x3C,0x55,CLASSB_ERROR_NON_CRIT);
315 CLASSB_RegRestore_IO(0x3C);
316 #endif
317
318 // SREG (Not interrupt flag!)
319 CLASSB_RegStore_IO(0x3F);
320 CLASSB_RegSet_IO(0x3F,0x55);
321 CLASSB_RegTest_IO(0x3F,0x2A,CLASSB_ERROR_NON_CRIT);
322 CLASSB_RegTest_IO(0x3F,0x55,CLASSB_ERROR_NON_CRIT);
323 CLASSB_RegRestore_IO(0x3F);
324
325 ASSEMBLY(
326 // Continue here if test was successful: clear return register and return.
327 "clr R16 \n"
328 "jmp END \n"
329 // If a fault in return value or stack registers was detected, hang the device.
330 "CLASSB_LABEL1: jmp CLASSB_LABEL1 \n"
331 // If a fault was detected, set return register.
332 "CLASSB_LABEL2: ldi R16, 0x01 \n"
333 "END: \n"
334 );
335
336 // Handle global error. This will not be reached if there was a fault in
337 // a) critical registers and CLASSB_ERROR_CRIT was defined as CLASSB_LABEL1.
338 // b) non-critical registers and CLASSB_ERROR_NON_CRIT was defined as CLASSB_LABEL1.
339 if (error == true) {
340 CLASSB_ERROR_HANDLER_REGISTERS();
341 }
342
343 return (error);
344 }
345 //@}
346
347 //! \endcond