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) {
341  }
342 
343  return (error);
344 }
345 //@}
346 
347 //! \endcond