Contiki 2.6
|
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