![]() |
Energy Micro IEC60355 Library Example Project 1.0 (internal use only!) GCC-Version
Example project demonstrating POST and BIST library functions
|
00001 /***************************************************************************/ 00029 #include "efm32.h" 00030 #include "iec60335_class_b.h" 00031 00037 #if (defined (__CC_ARM)) 00038 /*------------------RealView Compiler -----------------*/ 00039 FlashCRC_t const IEC60335_Flash_CRC_REF __attribute__ ((at(FLASH_CRC_ADDR))) = ENTRY_FLASH_CRC; 00040 /* FlashCRC_t const IEC60335_Flash_CRC_REF = ENTRY_FLASH_CRC; */ 00043 #elif (defined (__ICCARM__)) 00044 00045 /*------------------ ICC Compiler -------------------*/ 00046 #pragma section = "_CRC_area" 00047 const FlashCRC_t IEC60335_Flash_CRC_REF @ "_CRC_area" = ENTRY_FLASH_CRC; 00050 #elif (defined (__GNUC__)) 00051 00052 /*------------------ GNU Compiler ---------------------*/ 00053 const FlashCRC_t IEC60335_Flash_CRC_REF __attribute__ ((section("_CRC_area"))) = ENTRY_FLASH_CRC; 00055 #else 00056 #error "iec60355_class_b_flash_test.c: undefined compiler" 00057 #endif 00058 00059 00061 #if (dynamic_CRC_table == 0) 00062 /* ======================================================================== 00063 * Table of CRC-32's of all single-byte values (made by make_crc_table) 00064 */ 00065 00066 /* const table for CRC32 byte references */ 00067 static const uint32_t crc_table[256] = { 00068 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, 00069 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, 00070 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, 00071 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, 00072 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, 00073 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, 00074 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, 00075 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, 00076 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, 00077 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, 00078 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, 00079 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, 00080 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, 00081 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, 00082 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, 00083 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, 00084 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, 00085 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, 00086 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, 00087 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, 00088 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, 00089 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, 00090 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, 00091 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, 00092 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, 00093 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, 00094 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, 00095 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, 00096 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, 00097 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, 00098 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, 00099 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, 00100 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, 00101 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, 00102 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, 00103 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, 00104 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, 00105 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, 00106 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, 00107 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, 00108 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, 00109 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, 00110 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, 00111 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, 00112 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, 00113 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, 00114 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, 00115 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, 00116 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, 00117 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, 00118 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, 00119 0x2d02ef8dL 00120 }; 00122 #else 00123 00124 static int32_t crc_table_empty = 1; 00125 static uint32_t crc_table[256]; 00126 static void make_crc_table(void); 00127 /* 00128 * Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: 00129 * x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. 00130 * 00131 * Polynomials over GF(2) are represented in binary, one bit per coefficient, 00132 * with the lowest powers in the most significant bit. Then adding polynomials 00133 * is just exclusive-or, and multiplying a polynomial by x is a right shift by 00134 * one. If we call the above polynomial p, and represent a byte as the 00135 * polynomial q, also with the lowest power in the most significant bit (so the 00136 * byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, 00137 * where a mod b means the remainder after dividing a by b. 00138 * 00139 * This calculation is done using the shift-register method of multiplying and 00140 * taking the remainder. The register is initialized to zero, and for each 00141 * incoming bit, x^32 is added mod p to the register if the bit is a one (where 00142 * x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by 00143 * x (which is shifting right by one and adding x^32 mod p if the bit shifted 00144 * out is a one). We start with the highest power (least significant bit) of 00145 * q and repeat for all eight bits of q. 00146 * 00147 * The table is simply the CRC of all possible eight bit values. This is all 00148 * the information needed to generate CRC's on data a byte at a time for all 00149 * combinations of CRC register values and incoming bytes. 00150 */ 00151 static void make_crc_table(void) 00152 { 00153 uint32_t c; 00154 int n, k; 00155 uint32_t poly; /* polynomial exclusive-or pattern */ 00156 /* terms of polynomial defining this crc (except x^32): */ 00157 static const uint8_t p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 }; 00158 00159 /* make exclusive-or pattern from polynomial (0xedb88320L) */ 00160 poly = 0L; 00161 for (n = 0; n < sizeof(p) / sizeof(uint8_t); n++) 00162 { 00163 poly |= 1L << (31 - p[n]); 00164 } 00165 00166 for (n = 0; n < 256; n++) 00167 { 00168 c = (uint32_t) n; 00169 for (k = 0; k < 8; k++) 00170 { 00171 c = c & 1 ? poly ^ (c >> 1) : c >> 1; 00172 } 00173 crc_table[n] = c; 00174 } 00175 crc_table_empty = 0; 00176 } 00177 #endif 00178 00180 /* ========================================================================= */ 00181 #define DO1(src) crc = crc_table[((uint32_t) crc ^ (*src++)) & 0xff] ^ (crc >> 8); 00182 #define DO2(src) DO1(src); DO1(src); 00183 #define DO4(src) DO2(src); DO2(src); 00184 #define DO8(src) DO4(src); DO4(src); 00185 00186 /* ========================================================================= */ 00187 uint32_t crc32(uint32_t crc, uint8_t ** const pp_src, uint32_t len) 00188 { 00189 uint8_t * src = (*pp_src); 00190 #if (dynamic_CRC_table == 1) 00191 if (crc_table_empty) 00192 make_crc_table(); 00193 #endif 00194 crc = crc ^ 0xffffffffL; 00195 while (len > 7) 00196 { 00197 DO8(src); 00198 len -= 8; 00199 } 00200 if (len) do 00201 { 00202 DO1(src); 00203 } while (--len); 00204 00205 *pp_src = src; 00206 return(crc ^ 0xffffffffL); 00207 } 00208 00209 testResult_t IEC60335_ClassB_FLASHtest_POST(void) 00210 { 00211 FlashCRC_t TestCRC; 00212 uint32_t TestAddr = (uint32_t)__STEXT; 00213 testResult_t Result = IEC60335_testFailed; 00214 00215 /* Do the POST signature generation according to the various flash sizes */ 00216 /* check the complete Flash memory */ 00217 TestCRC.CRC32Val = crc32(0, (uint8_t ** )&TestAddr, FLASHSIZE - (int32_t) __STEXT); 00218 TestCRC.Status = FLASH_CRC_Done; 00219 00220 /* check status flag and CRC value */ 00221 if (IEC60335_Flash_CRC_REF.Status == FLASH_CRC_Valid) 00222 { 00223 if (TestCRC.CRC32Val == IEC60335_Flash_CRC_REF.CRC32Val) 00224 { 00225 Result = IEC60335_testPassed; 00226 } 00227 } 00228 00229 return(Result); 00230 } 00231 00232 testResult_t IEC60335_ClassB_FLASHtest_BIST(uint8_t StartMode) 00233 { 00234 testResult_t Result = IEC60335_testFailed; 00235 /* CRC32Val,MemLenght,NextAddress,BlockSize,Status; */ 00236 static FlashCRC_t bistFlashCRC = { 0, FLASH_SIZE, 0, CRC_block_size, FLASH_CRC_Restart }; 00237 00238 if (StartMode >= FLASH_CRC_Restart) 00239 { 00240 bistFlashCRC.Status = FLASH_CRC_Restart; 00241 Result = IEC60335_testInProgress; 00242 } 00243 if (StartMode == FLASH_CRC_Missing) 00244 { 00245 return(Result); 00246 } 00247 /* consecutive addressing based on the struct content */ 00248 00249 /* check parts of the Flash memory */ 00250 /* determine restart condition of FlashTest */ 00251 if (bistFlashCRC.NextAddress <= (uint32_t) __STEXT) 00252 { 00253 bistFlashCRC.Status = FLASH_CRC_Restart; 00254 } 00255 /* determine failure condition of FlashTest */ 00256 if (bistFlashCRC.NextAddress > FLASHSIZE) 00257 { 00258 bistFlashCRC.Status = FLASH_CRC_Restart; 00259 } 00260 if (bistFlashCRC.Status == FLASH_CRC_Restart) 00261 { 00262 bistFlashCRC.CRC32Val = 0; 00263 bistFlashCRC.NextAddress = (uint32_t) __STEXT; 00264 bistFlashCRC.BlockSize = CRC_block_size; 00265 } 00266 00267 /* determine next length exceeding FlasSize */ 00268 if ((bistFlashCRC.NextAddress + bistFlashCRC.BlockSize) > FLASHSIZE) 00269 { 00270 bistFlashCRC.BlockSize = FLASHSIZE - bistFlashCRC.NextAddress; 00271 } 00272 /* calculate next part */ 00273 bistFlashCRC.CRC32Val = crc32(bistFlashCRC.CRC32Val, (uint8_t ** )&bistFlashCRC.NextAddress, bistFlashCRC.BlockSize); 00274 00275 bistFlashCRC.Status = FLASH_CRC_InProg; 00276 if (bistFlashCRC.NextAddress == FLASHSIZE) 00277 { 00278 bistFlashCRC.Status = FLASH_CRC_Done; 00279 } 00280 00281 /* state when memory block is processed completely */ 00282 if (bistFlashCRC.Status == FLASH_CRC_Done) 00283 { 00284 if (bistFlashCRC.CRC32Val == IEC60335_Flash_CRC_REF.CRC32Val) 00285 { 00286 Result = IEC60335_testPassed; 00287 } 00288 } 00289 if (bistFlashCRC.Status == FLASH_CRC_InProg) 00290 { 00291 Result = IEC60335_testInProgress; 00292 } 00293 00294 /* return value if the part or all is done */ 00295 return(Result); 00296 } 00297 00302 /************************************** EOF *********************************/