Contiki 2.6

mfg-token.c

Go to the documentation of this file.
00001 /** @file hal/micro/cortexm3/mfg-token.c
00002  * @brief Cortex-M3 Manufacturing-Token system
00003  *
00004  * <!--(C) COPYRIGHT 2010 STMicroelectronics. All rights reserved.        -->
00005  */
00006 #include PLATFORM_HEADER
00007 #include "error.h"
00008 #include "hal/micro/cortexm3/flash.h"
00009 #include "mfg-token.h"
00010 
00011 
00012 
00013 
00014 #define DEFINETOKENS
00015 #define TOKEN_MFG(name,creator,iscnt,isidx,type,arraysize,...) \
00016   const int16u TOKEN_##name = TOKEN_##name##_ADDRESS;
00017   #include "hal/micro/cortexm3/token-manufacturing.h"
00018 #undef TOKEN_DEF
00019 #undef TOKEN_MFG
00020 #undef DEFINETOKENS
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 static const int8u nullEui[] = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF };
00030 
00031 
00032 void halInternalGetMfgTokenData(void *data, int16u ID, int8u index, int8u len)
00033 {
00034   int8u *ram = (int8u*)data;
00035   
00036   //0x7F is a non-indexed token.  Remap to 0 for the address calculation
00037   index = (index==0x7F) ? 0 : index;
00038   
00039   if(ID == MFG_EUI_64_LOCATION) {
00040     //There are two EUI64's stored in the Info Blocks, St and Custom.
00041     //0x0A00 is the address used by the generic EUI64 token, and it is
00042     //token.c's responbility to pick the returned EUI64 from either St
00043     //or Custom.  Return the Custom EUI64 if it is not all FF's, otherwise
00044     //return the St EUI64.
00045     tokTypeMfgEui64 eui64;
00046     halCommonGetMfgToken(&eui64, TOKEN_MFG_CUSTOM_EUI_64);
00047     if(MEMCOMPARE(eui64,nullEui, 8 /*EUI64_SIZE*/) == 0) {
00048       halCommonGetMfgToken(&eui64, TOKEN_MFG_ST_EUI_64);
00049     }
00050     MEMCOPY(ram, eui64, 8 /*EUI64_SIZE*/);
00051   } else {
00052     //read from the Information Blocks.  The token ID is only the
00053     //bottom 16bits of the token's actual address.  Since the info blocks
00054     //exist in the range DATA_BIG_INFO_BASE-DATA_BIG_INFO_END, we need
00055     //to OR the ID with DATA_BIG_INFO_BASE to get the real address.
00056     int32u realAddress = (DATA_BIG_INFO_BASE|ID) + (len*index);
00057     int8u *flash = (int8u *)realAddress;
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072     MEMCOPY(ram, flash, len);
00073   }
00074 }
00075 
00076 
00077 void halInternalSetMfgTokenData(int16u token, void *data, int8u len)
00078 {
00079   StStatus flashStatus;
00080   int32u realAddress = (DATA_BIG_INFO_BASE|token);
00081   int8u * flash = (int8u *)realAddress;
00082   int32u i;
00083   
00084   //The flash library (and hardware) requires the address and length to both
00085   //be multiples of 16bits.  Since this API is only valid for writing to
00086   //the CIB, verify that the token+len falls within the CIB.
00087   assert((token&1) != 1);
00088   assert((len&1) != 1);
00089   assert((realAddress>=CIB_BOTTOM) && ((realAddress+len-1)<=CIB_TOP));
00090   
00091   //CIB manufacturing tokens can only be written by on-chip code if the token
00092   //is currently unprogrammed.  Verify the entire token is unwritten.  The
00093   //flash library performs a similar check, but verifying here ensures that
00094   //the entire token is unprogrammed and will prevent partial writes.
00095   for(i=0;i<len;i++) {
00096     assert(flash[i] == 0xFF);
00097   }
00098   
00099   //Remember, the flash library operates in 16bit quantities, but the
00100   //token system operates in 8bit quantities.  Hence the divide by 2.
00101   flashStatus = halInternalFlashWrite(realAddress, data, (len/2));
00102   assert(flashStatus == ST_SUCCESS);
00103 }
00104