Xmega IEC60730 Class B Library  1.0
 All Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
classb_cpu.h
Go to the documentation of this file.
1 /* This file has been prepared for Doxygen automatic documentation generation.*/
2 /**
3  * \file
4  *
5  * \brief
6  * Settings and definitions for the CPU registers test.
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  * Copyright (C) 2012 Atmel Corporation. All rights reserved.
20  *
21  * \page License
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions are met:
25  *
26  * 1. Redistributions of source code must retain the above copyright notice,
27  * this list of conditions and the following disclaimer.
28  *
29  * 2. Redistributions in binary form must reproduce the above copyright notice,
30  * this list of conditions and the following disclaimer in the documentation
31  * and/or other materials provided with the distribution.
32  *
33  * 3. The name of Atmel may not be used to endorse or promote products derived
34  * from this software without specific prior written permission.
35  *
36  * 4. This software may only be redistributed and used in connection with an
37  * Atmel AVR product.
38  *
39  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
40  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
41  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
42  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
43  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
44  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
45  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
46  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
47  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
48  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
49  * DAMAGE.
50  */
51 
52 
53 #ifndef CLASSB_CPU_H_
54 #define CLASSB_CPU_H_
55 
56 #include "error_handler.h"
57 
58 
59 //! \defgroup classb_registers CPU Register test
60 //!
61 //! \brief This is the self-test module for the registers in the CPU.
62 //!
63 //! The CPU registers are tested for stuck bits and some coupling faults.
64 //! The test is executed by calling \ref classb_register_test(). The test procedure
65 //! consists of five steps per register:
66 //! -# Write 0x55 to register
67 //! -# Write 0xAA to register
68 //! -# Verify content (0xAA) of register
69 //! -# Write 0x55 to register
70 //! -# Verify content (0x55) of register
71 //!
72 //! Non-destructive testing is done on the R-registers that are stated to
73 //! need preservation in the compiler documentation and on all IO registers.
74 //! Further, this test returns its result using a register. Therefore, the
75 //! register used to return the value, the stack pointer registers or those
76 //! used within the test (e.g. to save values) are critical in the sense
77 //! that the test cannot be executed correctly unless these registers are
78 //! working.
79 //!
80 //! The error handler for the test is \ref CLASSB_ERROR_HANDLER_REGISTERS().
81 //! It is possible to configure independently the behavior of the test with
82 //! respect to failure in critical and non-critical registers (see \ref CLASSB_ERROR_CRIT
83 //! and \ref CLASSB_ERROR_NON_CRIT).
84 //!
85 //! Given that GCC and IAR make use of the CPU registers in a different manner,
86 //! we have included a compiler-specific function. This reduces execution time
87 //! and simplifies the code.
88 //!
89 //! \note Interrupts must be disabled during this test.
90 //!
91 
92 
93 
94 //! \addtogroup classb_registers
95 //@{
96 
97 //! \defgroup settings_cpu Settings related to error handling
98 //! \brief In principle, any error in critical registers would mean that the system
99 //! cannot verify whether the registers are working correctly. Since registers are
100 //! vital to most applications, the microcontroller should probably hang. However,
101 //! this behavior can be modified so that failure in critical registers is handled by
102 //! \ref CLASSB_ERROR_HANDLER_REGISTERS(). The behavior for failure in non-critical
103 //! registers can also be configured: the microcontroller can call the error handler
104 //! or hang.
105 //@{
106 /*! \brief Error handling in critical registers.
107  * If this constant is defined as \c CLASSB_LABEL1, critical register faults
108  * will hang the device. However, if this was defined as \c CLASSB_LABEL2,
109  * errors in critical registers would be processed by the error handler.
110  */
111 #define CLASSB_ERROR_CRIT CLASSB_LABEL1
112 
113 /*! \brief Error handling in non-critical registers.
114  * If this constant is defined as \c CLASSB_LABEL2, errors in non-critical registers
115  * will be processed by the error handler. However, it was defined as \c CLASSB_LABEL1,
116  * non-critical register faults would hang the device.
117  */
118 #define CLASSB_ERROR_NON_CRIT CLASSB_LABEL2
119 //@}
120 
121 
122 //! \internal \defgroup reg_check Symbols used to check whether some registers are present.
123 //!
124 //! \brief These symbols are used to check indirectly whether RAMPx and EIND
125 //! registers are present.
126 //!
127 //! RAMPx and EIND registers are present if the memory sizes are large enough.
128 //! It seems like the register constants are defined in the header file even
129 //! if those registers are not present in the device. Therefore, it is
130 //! necessary to check it indirectly through the memory size.
131 //@{
132 #ifdef __DOXYGEN__
133 
134  //! \internal \brief Automatically defined for devices with data memory larger than 64KB.
135  #define CLASSB_HAS_BIGMEM
136 
137  //! \internal \brief Automatically defined for devices with program memory larger than 64KB.
138  #define CLASSB_HAS_BIGFLASH
139 
140 #else
141  #if (DATAMEM_SIZE > 65536)
142  #define CLASSB_HAS_BIGMEM
143  #endif
144  #if (PROGMEM_SIZE > 65536)
145  #define CLASSB_HAS_BIGFLASH
146  #endif
147 #endif
148 //@}
149 
150 
151 //! \internal \defgroup reg_macros Macros for reading, writing and testing registers
152 //! \brief In order to simplify the code, the assembly code is interfaced through macros.
153 //@{
154 
155 /*! \internal \brief Save R register content to R31.
156  *
157  * \param reg R-register to store in R31.
158  */
159 #define CLASSB_RegStore_R(reg) \
160  ASSEMBLY( \
161  "mov r31, " #reg " \n" \
162  )
163 
164 /*! \internal \brief Load R register content from R31.
165  *
166  * \param reg R-register to restore from R31.
167  */
168 #define CLASSB_RegRestore_R(reg) \
169  ASSEMBLY( \
170  "mov " #reg ", r31 \n" \
171  )
172 
173 /*! \internal \brief Set high R-register to specified value.
174  *
175  * \param reg R-register to set (R16-R31).
176  * \param value Value to set R-register to.
177  */
178 #define CLASSB_RegSet_R_HI(reg,value) \
179  ASSEMBLY( \
180  "ldi " #reg ", " #value " \n" \
181  )
182 
183 /*! \internal \brief Set low R-register to specified value.
184  *
185  * \param reg R-register to set (R0-R15).
186  * \param value Value to set R-register to.
187  *
188  * \note The value is copied into the specified register via R30.
189  */
190 #define CLASSB_RegSet_R_LO(reg,value) \
191  ASSEMBLY( \
192  "ldi r30, " #value " \n" \
193  "mov " #reg ", r30 \n" \
194  )
195 
196 /*! \internal \brief Set IO-register to specified value.
197  *
198  * \param reg IO-address of register to set.
199  * \param value Value to set register to.
200  *
201  * \note The value is copied into the specified register via R30.
202  */
203 #define CLASSB_RegSet_IO(reg,value) \
204  ASSEMBLY( \
205  "ldi r30, " #value " \n" \
206  "out " #reg ", r30 \n" \
207  )
208 
209 /*! \internal \brief Clear R register.
210  *
211  * \param reg R-register to clear.
212  *
213  * \note This macro works for any R-register (R0-R31).
214  */
215 #define CLASSB_RegClear_R(reg) \
216  ASSEMBLY( \
217  "clr " #reg " \n" \
218  )
219 
220 /*! \internal \brief Clear IO-register.
221  *
222  * \param reg IO-address of register to clear.
223  *
224  * \note The IO-register is cleared via R30.
225  */
226 #define CLASSB_RegClear_IO(reg) \
227  ASSEMBLY( \
228  "clr r30 \n" \
229  "out " #reg ", r30 \n" \
230  )
231 
232 /*! \internal \brief Store IO-register content.
233  *
234  * \param reg IO-address of register to store.
235  *
236  * \note The value of the IO-register is stored in R31.
237  */
238 #define CLASSB_RegStore_IO(reg) \
239  ASSEMBLY( \
240  "in r31, " #reg " \n" \
241  )
242 
243 /*! \internal \brief Restore IO-register content.
244  *
245  * \param reg IO-address of register to restore.
246  *
247  * \note The value of the IO-register is restored from R31.
248  */
249 #define CLASSB_RegRestore_IO(reg) \
250  ASSEMBLY( \
251  "out " #reg ", r31 \n" \
252  )
253 
254 /*! \internal \brief Test R16-31 with specified value, jump to specified label on fault
255  *
256  * \param reg Register to test (R16..R31).
257  * \param value Value to test register with.
258  * \param label Label to jump to if test fails.
259  */
260 #define CLASSB_RegTest_R_HI(reg,value,label) \
261  ASSEMBLY( \
262  "ldi " #reg ", " #value " \n" \
263  "cpi " #reg ", " #value " \n" \
264  "breq A_" STRINGIZE(LABEL(reg,value,__LINE__)) " \n" \
265  "jmp " STRINGIZE(label) " \n" \
266  "A_" STRINGIZE(LABEL(reg,value,__LINE__)) ": \n" \
267  )
268 
269 /*! \internal \brief Test R0-15 with specified value, jump to specified label on fault
270  *
271  * \note R30 is used in the copying values to the register.
272  *
273  * \param reg Register to test (R0..R15).
274  * \param value Value to test register with.
275  * \param label Label to jump to if test fails.
276  */
277 #define CLASSB_RegTest_R_LO(reg,value,label) \
278  ASSEMBLY( \
279  "ldi r30, " #value " \n" \
280  "mov " #reg ", r30 \n" \
281  "mov r30, " #reg " \n" \
282  "cpi r30, " #value " \n" \
283  "breq A_" STRINGIZE(LABEL(reg,value,__LINE__)) " \n" \
284  "jmp " STRINGIZE(label) " \n" \
285  "A_" STRINGIZE(LABEL(reg,value,__LINE__)) ": \n" \
286  )
287 
288 /*! \internal \brief Test IO register with specified value, jump to specified label on fault
289  *
290  * \note R30 is used in the copying of values to the register.
291  *
292  * \param reg Address of IO register to test.
293  * \param value Value to test register with.
294  * \param label Label to jump to if test fails.
295  */
296 #define CLASSB_RegTest_IO(reg,value,label) \
297  ASSEMBLY( \
298  "ldi r30, " #value " \n" \
299  "out " #reg ", r30 \n" \
300  "in r30, " #reg " \n" \
301  "cpi r30, " #value " \n" \
302  "breq A_" STRINGIZE(LABEL(reg,value,__LINE__)) " \n" \
303  "jmp " STRINGIZE(label) " \n" \
304  "A_" STRINGIZE(LABEL(reg,value,__LINE__)) ": \n" \
305  )
306 //@}
307 
308 //! \defgroup reg_func Functions
309 //! \brief This is the self-test for CPU registers.
310 //@{
311 bool classb_register_test (void);
312 //@}
313 
314 //@}
315 
316 #endif /* CLASSB_CPU_H_ */