| Xmega IEC60730 Class B Library 1.0 |

All Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
classb_cpu_gcc.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 AVR GCC.
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) 2012 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 GCC
57
58 /*!
59 * \brief CPU register self-diagnostic routine for AVR GCC.
60 *
61 * This function tests the CPU registers, preserving those registers specified
62 * in the AVR GCC compiler documentation. Note that if there should be a fault
63 * in a register that needs preservation, its value would not be restored.
64 *
65 * Registers are tested in this order:
66 * -# Critical registers
67 * -# Return value register: R24
68 * -# stack pointer: SPL/SPH
69 * -# register %file: R31 -- R30
70 * -# Non-critical registers
71 * -# register %file: R29 -- R25, R23 -- R0
72 * -# extended addressing registers: RAMPD/X/Y/Z, EIND
73 * -# status register: SREG (except interrupt flag)
74 *
75 * \retval false No register fault detected.
76 * \retval true Register fault detected.
77 *
78 * \note Interrupts must be disabled during this test.
79 */
80 bool classb_register_test(void)
81 {
82
83 // The error flag used locally
84 register bool error asm("r24") = true;
85
86 // Test R24 first because it is the return register!
87 CLASSB_RegSet_R_HI(R24,0x55);
88 CLASSB_RegTest_R_HI(R24,0xAA,CLASSB_ERROR_CRIT);
89 CLASSB_RegTest_R_HI(R24,0x55,CLASSB_ERROR_CRIT);
90
91 // Then test R31 and R30 because they are used in the rest of the tests.
92 CLASSB_RegSet_R_HI(R31,0x55);
93 CLASSB_RegTest_R_HI(R31,0xAA,CLASSB_ERROR_CRIT);
94 CLASSB_RegTest_R_HI(R31,0x55,CLASSB_ERROR_CRIT);
95
96 CLASSB_RegSet_R_HI(R30,0x55);
97 CLASSB_RegTest_R_HI(R30,0xAA,CLASSB_ERROR_CRIT);
98 CLASSB_RegTest_R_HI(R30,0x55,CLASSB_ERROR_CRIT);
99
100 // SPH
101 CLASSB_RegStore_IO(0x3D);
102 CLASSB_RegSet_IO(0x3D,0x55);
103 CLASSB_RegTest_IO(0x3D,0xAA,CLASSB_ERROR_CRIT);
104 CLASSB_RegTest_IO(0x3D,0x55,CLASSB_ERROR_CRIT);
105 CLASSB_RegRestore_IO(0x3D);
106
107 // SPL
108 CLASSB_RegStore_IO(0x3E);
109 CLASSB_RegSet_IO(0x3E,0x55);
110 CLASSB_RegTest_IO(0x3E,0xAA,CLASSB_ERROR_CRIT);
111 CLASSB_RegTest_IO(0x3E,0x55,CLASSB_ERROR_CRIT);
112 CLASSB_RegRestore_IO(0x3E);
113
114 // Test R29-R28 non-destructively.
115 CLASSB_RegStore_R(R29);
116 CLASSB_RegSet_R_HI(R29,0x55);
117 CLASSB_RegTest_R_HI(R29,0xAA,CLASSB_ERROR_NON_CRIT);
118 CLASSB_RegTest_R_HI(R29,0x55,CLASSB_ERROR_NON_CRIT);
119 CLASSB_RegRestore_R(R29);
120
121 CLASSB_RegStore_R(R28);
122 CLASSB_RegSet_R_HI(R28,0x55);
123 CLASSB_RegTest_R_HI(R28,0xAA,CLASSB_ERROR_NON_CRIT);
124 CLASSB_RegTest_R_HI(R28,0x55,CLASSB_ERROR_NON_CRIT);
125 CLASSB_RegRestore_R(R28);
126
127 // Test R27-R25, R23-R18 destructively.
128 CLASSB_RegSet_R_HI(R27,0x55);
129 CLASSB_RegTest_R_HI(R27,0xAA,CLASSB_ERROR_NON_CRIT);
130 CLASSB_RegTest_R_HI(R27,0x55,CLASSB_ERROR_NON_CRIT);
131
132 CLASSB_RegSet_R_HI(R26,0x55);
133 CLASSB_RegTest_R_HI(R26,0xAA,CLASSB_ERROR_NON_CRIT);
134 CLASSB_RegTest_R_HI(R26,0x55,CLASSB_ERROR_NON_CRIT);
135
136 CLASSB_RegSet_R_HI(R25,0x55);
137 CLASSB_RegTest_R_HI(R25,0xAA,CLASSB_ERROR_NON_CRIT);
138 CLASSB_RegTest_R_HI(R25,0x55,CLASSB_ERROR_NON_CRIT);
139
140 CLASSB_RegSet_R_HI(R23,0x55);
141 CLASSB_RegTest_R_HI(R23,0xAA,CLASSB_ERROR_NON_CRIT);
142 CLASSB_RegTest_R_HI(R23,0x55,CLASSB_ERROR_NON_CRIT);
143
144 CLASSB_RegSet_R_HI(R22,0x55);
145 CLASSB_RegTest_R_HI(R22,0xAA,CLASSB_ERROR_NON_CRIT);
146 CLASSB_RegTest_R_HI(R22,0x55,CLASSB_ERROR_NON_CRIT);
147
148 CLASSB_RegSet_R_HI(R21,0x55);
149 CLASSB_RegTest_R_HI(R21,0xAA,CLASSB_ERROR_NON_CRIT);
150 CLASSB_RegTest_R_HI(R21,0x55,CLASSB_ERROR_NON_CRIT);
151
152 CLASSB_RegSet_R_HI(R20,0x55);
153 CLASSB_RegTest_R_HI(R20,0xAA,CLASSB_ERROR_NON_CRIT);
154 CLASSB_RegTest_R_HI(R20,0x55,CLASSB_ERROR_NON_CRIT);
155
156 CLASSB_RegSet_R_HI(R19,0x55);
157 CLASSB_RegTest_R_HI(R19,0xAA,CLASSB_ERROR_NON_CRIT);
158 CLASSB_RegTest_R_HI(R19,0x55,CLASSB_ERROR_NON_CRIT);
159
160 CLASSB_RegSet_R_HI(R18,0x55);
161 CLASSB_RegTest_R_HI(R18,0xAA,CLASSB_ERROR_NON_CRIT);
162 CLASSB_RegTest_R_HI(R18,0x55,CLASSB_ERROR_NON_CRIT);
163
164 // Test R17-R0 non-destructively.
165 CLASSB_RegStore_R(R17);
166 CLASSB_RegSet_R_HI(R17,0x55);
167 CLASSB_RegTest_R_HI(R17,0xAA,CLASSB_ERROR_NON_CRIT);
168 CLASSB_RegTest_R_HI(R17,0x55,CLASSB_ERROR_NON_CRIT);
169 CLASSB_RegRestore_R(R17);
170
171 CLASSB_RegStore_R(R16);
172 CLASSB_RegSet_R_HI(R16,0x55);
173 CLASSB_RegTest_R_HI(R16,0xAA,CLASSB_ERROR_NON_CRIT);
174 CLASSB_RegTest_R_HI(R16,0x55,CLASSB_ERROR_NON_CRIT);
175 CLASSB_RegRestore_R(R16);
176
177 CLASSB_RegStore_R(R15);
178 CLASSB_RegSet_R_LO(R15,0x55);
179 CLASSB_RegTest_R_LO(R15,0xAA,CLASSB_ERROR_NON_CRIT);
180 CLASSB_RegTest_R_LO(R15,0x55,CLASSB_ERROR_NON_CRIT);
181 CLASSB_RegRestore_R(R15);
182
183 CLASSB_RegStore_R(R14);
184 CLASSB_RegSet_R_LO(R14,0x55);
185 CLASSB_RegTest_R_LO(R14,0xAA,CLASSB_ERROR_NON_CRIT);
186 CLASSB_RegTest_R_LO(R14,0x55,CLASSB_ERROR_NON_CRIT);
187 CLASSB_RegRestore_R(R14);
188
189 CLASSB_RegStore_R(R13);
190 CLASSB_RegSet_R_LO(R13,0x55);
191 CLASSB_RegTest_R_LO(R13,0xAA,CLASSB_ERROR_NON_CRIT);
192 CLASSB_RegTest_R_LO(R13,0x55,CLASSB_ERROR_NON_CRIT);
193 CLASSB_RegRestore_R(R13);
194
195 CLASSB_RegStore_R(R12);
196 CLASSB_RegSet_R_LO(R12,0x55);
197 CLASSB_RegTest_R_LO(R12,0xAA,CLASSB_ERROR_NON_CRIT);
198 CLASSB_RegTest_R_LO(R12,0x55,CLASSB_ERROR_NON_CRIT);
199 CLASSB_RegRestore_R(R12);
200
201 CLASSB_RegStore_R(R11);
202 CLASSB_RegSet_R_LO(R11,0x55);
203 CLASSB_RegTest_R_LO(R11,0xAA,CLASSB_ERROR_NON_CRIT);
204 CLASSB_RegTest_R_LO(R11,0x55,CLASSB_ERROR_NON_CRIT);
205 CLASSB_RegRestore_R(R11);
206
207 CLASSB_RegStore_R(R10);
208 CLASSB_RegSet_R_LO(R10,0x55);
209 CLASSB_RegTest_R_LO(R10,0xAA,CLASSB_ERROR_NON_CRIT);
210 CLASSB_RegTest_R_LO(R10,0x55,CLASSB_ERROR_NON_CRIT);
211 CLASSB_RegRestore_R(R10);
212
213 CLASSB_RegStore_R(R9);
214 CLASSB_RegSet_R_LO(R9,0x55);
215 CLASSB_RegTest_R_LO(R9,0xAA,CLASSB_ERROR_NON_CRIT);
216 CLASSB_RegTest_R_LO(R9,0x55,CLASSB_ERROR_NON_CRIT);
217 CLASSB_RegRestore_R(R9);
218
219 CLASSB_RegStore_R(R8);
220 CLASSB_RegSet_R_LO(R8,0x55);
221 CLASSB_RegTest_R_LO(R8,0xAA,CLASSB_ERROR_NON_CRIT);
222 CLASSB_RegTest_R_LO(R8,0x55,CLASSB_ERROR_NON_CRIT);
223 CLASSB_RegRestore_R(R8);
224
225 CLASSB_RegStore_R(R7);
226 CLASSB_RegSet_R_LO(R7,0x55);
227 CLASSB_RegTest_R_LO(R7,0xAA,CLASSB_ERROR_NON_CRIT);
228 CLASSB_RegTest_R_LO(R7,0x55,CLASSB_ERROR_NON_CRIT);
229 CLASSB_RegRestore_R(R7);
230
231 CLASSB_RegStore_R(R6);
232 CLASSB_RegSet_R_LO(R6,0x55);
233 CLASSB_RegTest_R_LO(R6,0xAA,CLASSB_ERROR_NON_CRIT);
234 CLASSB_RegTest_R_LO(R6,0x55,CLASSB_ERROR_NON_CRIT);
235 CLASSB_RegRestore_R(R6);
236
237 CLASSB_RegStore_R(R5);
238 CLASSB_RegSet_R_LO(R5,0x55);
239 CLASSB_RegTest_R_LO(R5,0xAA,CLASSB_ERROR_NON_CRIT);
240 CLASSB_RegTest_R_LO(R5,0x55,CLASSB_ERROR_NON_CRIT);
241 CLASSB_RegRestore_R(R5);
242
243 CLASSB_RegStore_R(R4);
244 CLASSB_RegSet_R_LO(R4,0x55);
245 CLASSB_RegTest_R_LO(R4,0xAA,CLASSB_ERROR_NON_CRIT);
246 CLASSB_RegTest_R_LO(R4,0x55,CLASSB_ERROR_NON_CRIT);
247 CLASSB_RegRestore_R(R4);
248
249 CLASSB_RegStore_R(R3);
250 CLASSB_RegSet_R_LO(R3,0x55);
251 CLASSB_RegTest_R_LO(R3,0xAA,CLASSB_ERROR_NON_CRIT);
252 CLASSB_RegTest_R_LO(R3,0x55,CLASSB_ERROR_NON_CRIT);
253 CLASSB_RegRestore_R(R3);
254
255 CLASSB_RegStore_R(R2);
256 CLASSB_RegSet_R_LO(R2,0x55);
257 CLASSB_RegTest_R_LO(R2,0xAA,CLASSB_ERROR_NON_CRIT);
258 CLASSB_RegTest_R_LO(R2,0x55,CLASSB_ERROR_NON_CRIT);
259 CLASSB_RegRestore_R(R2);
260
261 CLASSB_RegStore_R(R1);
262 CLASSB_RegSet_R_LO(R1,0x55);
263 CLASSB_RegTest_R_LO(R1,0xAA,CLASSB_ERROR_NON_CRIT);
264 CLASSB_RegTest_R_LO(R1,0x55,CLASSB_ERROR_NON_CRIT);
265 CLASSB_RegRestore_R(R1);
266
267 CLASSB_RegStore_R(R0);
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 CLASSB_RegRestore_R(R0);
272
273 // Test IO registers non-destructively.
274 // RAMPD
275 #ifdef CLASSB_HAS_BIGMEM
276 CLASSB_RegStore_IO(0x38);
277 CLASSB_RegSet_IO(0x38,0x55);
278 CLASSB_RegTest_IO(0x38,0xAA,CLASSB_ERROR_NON_CRIT);
279 CLASSB_RegTest_IO(0x38,0x55,CLASSB_ERROR_NON_CRIT);
280 CLASSB_RegRestore_IO(0x38);
281 #endif
282
283 // RAMPX
284 #ifdef CLASSB_HAS_BIGMEM
285 CLASSB_RegStore_IO(0x39);
286 CLASSB_RegSet_IO(0x39,0x55);
287 CLASSB_RegTest_IO(0x39,0xAA,CLASSB_ERROR_NON_CRIT);
288 CLASSB_RegTest_IO(0x39,0x55,CLASSB_ERROR_NON_CRIT);
289 CLASSB_RegRestore_IO(0x39);
290 #endif
291
292 // RAMPY
293 #ifdef CLASSB_HAS_BIGMEM
294 CLASSB_RegStore_IO(0x3A);
295 CLASSB_RegSet_IO(0x3A,0x55);
296 CLASSB_RegTest_IO(0x3A,0xAA,CLASSB_ERROR_NON_CRIT);
297 CLASSB_RegTest_IO(0x3A,0x55,CLASSB_ERROR_NON_CRIT);
298 CLASSB_RegRestore_IO(0x3A);
299 #endif
300
301 // RAMPZ
302 #if defined(CLASSB_HAS_BIGMEM) || defined(CLASSB_HAS_BIGFLASH)
303 CLASSB_RegStore_IO(0x3B);
304 CLASSB_RegSet_IO(0x3B,0x55);
305 CLASSB_RegTest_IO(0x3B,0xAA,CLASSB_ERROR_NON_CRIT);
306 CLASSB_RegTest_IO(0x3B,0x55,CLASSB_ERROR_NON_CRIT);
307 CLASSB_RegRestore_IO(0x3B);
308 #endif
309
310 // EIND
311 #ifdef CLASSB_HAS_BIGFLASH
312 CLASSB_RegStore_IO(0x3C);
313 CLASSB_RegSet_IO(0x3C,0x55);
314 CLASSB_RegTest_IO(0x3C,0xAA,CLASSB_ERROR_NON_CRIT);
315 CLASSB_RegTest_IO(0x3C,0x55,CLASSB_ERROR_NON_CRIT);
316 CLASSB_RegRestore_IO(0x3C);
317 #endif
318
319 // SREG (Not interrupt flag!)
320 CLASSB_RegStore_IO(0x3F);
321 CLASSB_RegSet_IO(0x3F,0x55);
322 CLASSB_RegTest_IO(0x3F,0x2A,CLASSB_ERROR_NON_CRIT);
323 CLASSB_RegTest_IO(0x3F,0x55,CLASSB_ERROR_NON_CRIT);
324 CLASSB_RegRestore_IO(0x3F);
325
326 ASSEMBLY(
327 // Continue here if test was successful: Clear return register and return.
328 "clr %0 \n\t"
329 "jmp END \n\t"
330 "CLASSB_LABEL1: jmp CLASSB_LABEL1 \n\t"
331 // If a fault was detected, set return register.
332 "CLASSB_LABEL2: ldi %0, 0x01 \n\t"
333 "END: \n\t"
334 :"=r" (error) // Output value
335 : // No inputs
336 );
337
338 // Handle global error. This will not be reached if there was a fault in
339 // a) critical registers and CLASSB_ERROR_CRIT was defined as CLASSB_LABEL1.
340 // b) non-critical registers and CLASSB_ERROR_NON_CRIT was defined as CLASSB_LABEL1.
341 if (error == true)
342 {
343 CLASSB_ERROR_HANDLER_REGISTERS();
344 }
345
346 return (error);
347 }
348
349 //! \endcond