*\r
* So how much data should be read from MemIf if a CRC checksum is used. Assuming that we use a physical layout where the CRC is located\r
* after the NV Block it would be BALIGN(NvNvmBlockLength,4) + 4 bytes. The same applies to the RAM block (ROM block to not have CRC, NVM127)\r
+ *\r
+ * SPEED\r
+ * To get some speed into this multiple thing must be done in the same MainFunction loop.\r
+ *\r
*/\r
\r
\r
#define NVM_BLOCK_ALIGNMENT 4\r
#define NVM_CHECKSUM_LENGTH 4\r
\r
+#define NVM_BLOCK_OFFSET 0\r
+\r
+\r
//#define NVM_SERVICE_ID 0x00 // TODO: What number shall this ID have?\r
\r
#if ( NVM_DEV_ERROR_DETECT == STD_ON )\r
\r
// State variable\r
typedef enum {\r
- NVM_UNINITIALIZED = 0, //!< NVM_UNINITIALIZED\r
- NVM_IDLE, //!< NVM_IDLE\r
- NVM_READ_ALL_REQUESTED, //!< NVM_READ_ALL_REQUESTED\r
- NVM_READ_ALL_PROCESSING, //!< NVM_READ_ALL_PROCESSING\r
- NVM_READ_ALL_PENDING, //!< NVM_READ_ALL_PENDING\r
- NVM_WRITE_ALL_REQUESTED, //!< NVM_WRITE_ALL_REQUESTED\r
- NVM_WRITE_ALL_PROCESSING,//!< NVM_WRITE_ALL_PROCESSING\r
- NVM_WRITE_ALL_PENDING, //!< NVM_WRITE_ALL_PENDING\r
-\r
+ NVM_UNINITIALIZED = 0,\r
+ NVM_IDLE,\r
+ NVM_READ_ALL,\r
+ NVM_WRITE_ALL,\r
NVM_READ_BLOCK,\r
+ NVM_WRITE_BLOCK,\r
} NvmStateType;\r
\r
typedef enum {\r
BLOCK_STATE_IDLE,\r
- BLOCK_STATE_RECALC_CRC,\r
- BLOCK_STATE_RECALC_CRC_DONE,\r
- BLOCK_STATE_POSTCALC_CRC,\r
- BLOCK_STATE_POSTCALC_CRC_DONE,\r
-\r
- BLOCK_STATE_LOAD_FROM_NV,\r
-// BLOCK_STATE_LOAD_FROM_NV_DONE,\r
-// BLOCK_STATE_LOAD_FROM_NV_REDUNDANT,\r
-// BLOCK_STATE_LOAD_FROM_ROM,\r
-\r
- BLOCK_STATE_WRITE_TO_NV\r
-// BLOCK_STATE_WRITE_TO_NV_DONE\r
+ BLOCK_STATE_START,\r
+ BLOCK_STATE_PROCESS,\r
+ BLOCK_STATE_CALC_CRC,\r
} BlockStateType;\r
\r
+\r
+\r
+\r
typedef struct {\r
NvM_RequestResultType ErrorStatus; // Status from multi block requests i.e. Read/Write/CancelWrite-all\r
} AdministrativeMultiBlockType;\r
\r
static int nvmSubState = 0;\r
static int nvmSetNr;\r
-static AdministrativeBlockType AdminBlock[NVM_NUM_OF_NVRAM_BLOCKS];\r
+static AdministrativeBlockType AdminBlock[NVM_NUM_OF_NVRAM_BLOCKS+NVM_BLOCK_OFFSET];\r
static AdministrativeMultiBlockType AdminMultiBlock;\r
\r
\r
};\r
\r
typedef struct {\r
- uint16 NextBlockIndex; // Keeps track of next unfinished block\r
+ uint16 currBlockIndex; // Keeps track of next unfinished block\r
NvM_RequestResultType PendingErrorStatus; // Status from multi block requests i.e. Read/Write/CancelWrite-all\r
} AdminMultiReqType;\r
\r
AdministrativeBlockType *AdminBlockTable = AdminBlock;\r
uint16 i;\r
\r
- nvmState = NVM_READ_ALL_PROCESSING;\r
AdminMultiReq.PendingErrorStatus = NVM_REQ_OK;\r
- AdminMultiReq.NextBlockIndex = 0;\r
+ AdminMultiReq.currBlockIndex = 0;\r
\r
- for (i = 0; i < NVM_NUM_OF_NVRAM_BLOCKS; i++) {\r
+ for (i = NVM_BLOCK_OFFSET; i < ( NVM_NUM_OF_NVRAM_BLOCKS + NVM_BLOCK_OFFSET); i++) {\r
if ((BlockDescriptorList->SelectBlockForReadall)\r
#if (NVM_SET_RAM_BLOCK_STATUS_API == STD_ON) /** @req NVM345 */\r
&& ((!AdminBlockTable->BlockValid) // TODO: Check if this is to be done like this\r
AdminBlockTable->BlockState = BLOCK_STATE_LOAD_FROM_NV;\r
}\r
} else {\r
- AdminBlockTable->ErrorStatus = NVM_REQ_BLOCK_SKIPPED;\r
+ AdminBlockTable->ErrorStatus = NVM_REQ_BLOCK_SKIPPED; /* @req 3.1.5/NVM287 */\r
}\r
\r
AdminBlockTable++;\r
*/\r
static void ReadAllMain(void)\r
{\r
- const NvM_BlockDescriptorType *BlockDescriptorList = NvM_Config.BlockDescriptor;\r
- AdministrativeBlockType *AdminBlockTable = AdminBlock;\r
- uint16 i;\r
+ const NvM_BlockDescriptorType *bPtr = &NvM_Config.BlockDescriptor[AdminMultiReq.currBlockIndex];\r
+ AdministrativeBlockType *admPtr = &AdminBlock[AdminMultiReq.currBlockIndex];\r
+\r
+ /* Cases:\r
+ * 1. We process each block until it's finished\r
+ * 2. We start to process a lot of blocks. The blocks may use different devices\r
+ * and should be able to read a lot of them. This includes CRC.\r
+ *\r
+ * 1) is much simpler and 2) probably much faster.\r
+ * This implementation will use 1) since it's simpler and maximum time that is\r
+ * spent in MainFunction() can be controlled much better.\r
+ */\r
+ bool blockDone = 0;\r
\r
- // Search forward to first unfinished block\r
- while ((AdminMultiReq.NextBlockIndex < NVM_NUM_OF_NVRAM_BLOCKS) && (AdminBlockTable[AdminMultiReq.NextBlockIndex].ErrorStatus != NVM_REQ_PENDING)) {\r
- AdminMultiReq.NextBlockIndex++;\r
- }\r
+ /* This block pending? */\r
+ assert( admPtr->ErrorStatus == NVM_REQ_PENDING );\r
\r
- if (AdminMultiReq.NextBlockIndex == NVM_NUM_OF_NVRAM_BLOCKS) {\r
- // All block processed\r
- if (AdminMultiReq.PendingErrorStatus == NVM_REQ_OK) {\r
- AdminMultiBlock.ErrorStatus = NVM_REQ_OK;\r
- } else {\r
- AdminMultiBlock.ErrorStatus = NVM_REQ_NOT_OK;\r
- }\r
+ switch (admPtr->BlockState) {\r
+ case BLOCK_STATE_IDLE:\r
+ /* Read block from NV */\r
+ ReadBlock(&bPtr[i], &admPtr[i], 0, bPtr->RamBlockDataAddress);\r
+ admPtr->BlockState = BLOCK_STATE_PROCESS;\r
+ break;\r
\r
- nvmState = NVM_IDLE;\r
+ case BLOCK_STATE_PROCESS:\r
+ /* Check read */\r
+ MemIf_JobResultType jobResult = MemIf_GetJobResult();\r
\r
- if (NvM_Config.Common.MultiBlockCallback != NULL) {\r
- NvM_Config.Common.MultiBlockCallback(NVM_SERVICE_ID, AdminMultiBlock.ErrorStatus);\r
- }\r
+ if( MEMIF_JOB_PENDING == jobResult ) {\r
+ /* Keep on waiting */\r
+ } else if( MEMIF_JOB_PENDING == jobResult ) {\r
+ /* We are done */\r
+ if( bPtr->CalcRamBlockCrc ) { /* @req 3.1.5/NVM362 */\r
+ admPtr->BlockState = BLOCK_STATE_CALC_CRC;\r
+ } else {\r
+ admPtr->BlockState = BLOCK_STATE_IDLE;\r
+ blockDone = 1;\r
+ }\r
+ break;\r
+ } else {\r
+ /* Something failed */\r
+ AdminMultiReq.PendingErrorStatus = NVM_REQ_NOT_OK;\r
+ blockDone = 1;\r
+ admPtr->BlockState = BLOCK_STATE_IDLE; /* TODO, this really true for all result below */\r
\r
- } else {\r
- for (i = AdminMultiReq.NextBlockIndex; (i < NVM_NUM_OF_NVRAM_BLOCKS) && (nvmState == NVM_READ_ALL_PROCESSING); i++) {\r
- switch (AdminBlockTable[i].BlockState) {\r
- case BLOCK_STATE_POSTCALC_CRC_DONE:\r
- // TODO: Check CRC\r
- break;\r
+ switch( jobResult ) {\r
+ case MEMIF_BLOCK_INVALID:\r
+ /* @req 3.1.5/NVM342 */\r
+ admPtr->ErrorStatus = NVM_REQ_NV_INVALIDATED;\r
\r
- case BLOCK_STATE_RECALC_CRC_DONE:\r
- // TODO: If CRC is ok do not reload from NVRAM\r
- // TODO: else reload\r
break;\r
-\r
- case BLOCK_STATE_LOAD_FROM_NV:\r
- nvmState = NVM_READ_ALL_PENDING;\r
- ReadBlock(&BlockDescriptorList[i], &AdminBlockTable[i], 0, BlockDescriptorList[i].RamBlockDataAddress);\r
+ case MEMIF_BLOCK_INCONSISTENT:\r
+ /* @req 3.1.5/NVM360 */\r
+ admPtr->ErrorStatus = NVM_REQ_INTEGRITY_FAILED;\r
+ DEM_REPORTERRORSTATUS(NVM_E_REQ_INTEGRITY_FAILED,DEM_EVENT_STATUS_FAILED);\r
+ blockDone = 1;\r
break;\r
-\r
+ case MEMIF_JOB_FAILED:\r
+ /* @req 3.1.5/NVM361 */\r
+ admPtr->ErrorStatus = NVM_REQ_NOT_OK;\r
+ DEM_REPORTERRORSTATUS(NVM_E_REQ_FAILED,DEM_EVENT_STATUS_FAILED);\r
+ blockDone = 1;\r
default:\r
+ assert(0);\r
break;\r
- } // Switch\r
- } // for\r
- } // else\r
+ }\r
+ }\r
+\r
+ case BLOCK_STATE_CALC_CRC:\r
+ /* TODO: */\r
+ break;\r
+ }\r
+\r
+ if( blockDone ) {\r
+\r
+ /* @req 3.1.5/NVM281 */\r
+ if( bPtr->SingleBlockCallback() != NULL ) {\r
+ bPtr->SingleBlockCallback();\r
+ }\r
+\r
+ AdminMultiReq.currBlockIndex++;\r
+ if( AdminMultiReq.currBlockIndex >= NVM_NUM_OF_NVRAM_BLOCKS ) {\r
+ AdminMultiReq.currBlockIndex = 0;\r
+\r
+ /* @req 3.1.5/NVM301 */\r
+ if( NVM_REQ_NOT_OK == AdminMultiReq.PendingErrorStatus ) {\r
+ AdminMultiBlock.ErrorStatus = NVM_REQ_NOT_OK;\r
+ } else {\r
+ AdminMultiBlock.ErrorStatus = NVM_REQ_OK;\r
+ }\r
+ nvmState = NVM_IDLE;\r
+ }\r
+ }\r
}\r
\r
\r
\r
nvmState = NVM_WRITE_ALL_PROCESSING;\r
AdminMultiReq.PendingErrorStatus = NVM_REQ_OK;\r
- AdminMultiReq.NextBlockIndex = 0;\r
+ AdminMultiReq.currBlockIndex = 0;\r
\r
for (i = 0; i < NVM_NUM_OF_NVRAM_BLOCKS; i++) {\r
if ((BlockDescriptorList->RamBlockDataAddress != NULL)\r
uint16 i;\r
\r
// Search forward to first unfinished block\r
- while ((AdminMultiReq.NextBlockIndex < NVM_NUM_OF_NVRAM_BLOCKS) && (AdminBlockTable[AdminMultiReq.NextBlockIndex].ErrorStatus != NVM_REQ_PENDING)) {\r
- AdminMultiReq.NextBlockIndex++;\r
+ while ((AdminMultiReq.currBlockIndex < NVM_NUM_OF_NVRAM_BLOCKS) && (AdminBlockTable[AdminMultiReq.currBlockIndex].ErrorStatus != NVM_REQ_PENDING)) {\r
+ AdminMultiReq.currBlockIndex++;\r
}\r
\r
- if (AdminMultiReq.NextBlockIndex == NVM_NUM_OF_NVRAM_BLOCKS) {\r
+ if (AdminMultiReq.currBlockIndex == NVM_NUM_OF_NVRAM_BLOCKS) {\r
// All block processed\r
if (AdminMultiReq.PendingErrorStatus == NVM_REQ_OK) {\r
AdminMultiBlock.ErrorStatus = NVM_REQ_OK;\r
}\r
\r
} else {\r
- for (i = AdminMultiReq.NextBlockIndex; (i < NVM_NUM_OF_NVRAM_BLOCKS) && (nvmState == NVM_WRITE_ALL_PROCESSING); i++) {\r
+ for (i = AdminMultiReq.currBlockIndex; (i < NVM_NUM_OF_NVRAM_BLOCKS) && (nvmState == NVM_WRITE_ALL_PROCESSING); i++) {\r
switch (AdminBlockTable[i].BlockState) {\r
case BLOCK_STATE_POSTCALC_CRC_DONE:\r
// TODO: Check CRC\r
*/\r
void NvM_ReadAll(void)\r
{\r
- AdministrativeBlockType *AdminBlockTable = AdminBlock;\r
uint16 i;\r
\r
VALIDATE_NO_RV(nvmState != NVM_UNINITIALIZED, NVM_READ_ALL_ID, NVM_E_NOT_INITIALIZED);\r
\r
// Check state\r
if (nvmState == NVM_IDLE) {\r
- nvmState = NVM_READ_ALL_REQUESTED; /** @req NVM243 */\r
+\r
+ /** !req 3.1.5/NVM243 TODO: Must check that queue is empty */\r
+ nvmState = NVM_READ_ALL;\r
\r
// Set status to pending in the administration blocks\r
- AdminMultiBlock.ErrorStatus = NVM_REQ_PENDING;\r
+ AdminMultiBlock.ErrorStatus = NVM_REQ_PENDING; /** @req 3.1.5/NVM304 */\r
\r
- for (i = 0; i < NVM_NUM_OF_NVRAM_BLOCKS; i++) {\r
- AdminBlockTable->ErrorStatus = NVM_REQ_PENDING;\r
- AdminBlockTable++;\r
+ /** @req 3.1.5/NVM244 */\r
+ for (i = NVM_BLOCK_OFFSET; i < (NVM_NUM_OF_NVRAM_BLOCKS+NVM_BLOCK_OFFSET); i++) {\r
+ AdminBlock[i].ErrorStatus = NVM_REQ_PENDING;\r
}\r
+\r
+ ReadAllInit();\r
}\r
}\r
\r
if (blockId == 0) {\r
// Multiblock ID\r
*requestResultPtr = AdminMultiBlock.ErrorStatus;\r
+ } else if (blockId == 1) {\r
+ /* TODO */\r
} else {\r
- *requestResultPtr = AdminBlock[blockId-1].ErrorStatus;\r
+ *requestResultPtr = AdminBlock[blockId-NVM_BLOCK_OFFSET].ErrorStatus;\r
}\r
\r
}\r
CalcCrc();\r
break;\r
}\r
- case NVM_READ_ALL_REQUESTED:\r
- ReadAllInit();\r
+ case NVM_READ_ALL:\r
+ ReadAllMain();\r
break;\r
\r
case NVM_READ_ALL_PROCESSING:\r