Energy Micro IEC60355 Library Example Project 1.0 (internal use only!) GCC-Version
Example project demonstrating POST and BIST library functions

iec60335_class_b_flash_test.c

Go to the documentation of this file.
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 *********************************/