]> rtime.felk.cvut.cz Git - arc.git/blob - memory/Fee/Fee.c
Updates to memory stack
[arc.git] / memory / Fee / Fee.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 \r
17 \r
18 \r
19 \r
20 \r
21 \r
22 \r
23 \r
24 #include <string.h>\r
25 #include "Fee.h"\r
26 #include "Fee_Cbk.h"\r
27 #include "NvM.h"\r
28 #include "Fls.h"\r
29 #include "Rte.h" // ???\r
30 #if defined(USE_DEM)\r
31 #include "Dem.h"\r
32 #endif\r
33 //#include "SchM_NvM.h"\r
34 #include "MemMap.h"\r
35 \r
36 /*\r
37  * Local definitions
38  */\r
39 \r
40 // Validation macros\r
41 #if  ( FEE_DEV_ERROR_DETECT == STD_ON )\r
42 #include "Det.h"\r
43 #define VALIDATE(_exp,_api,_err ) \\r
44         if( !(_exp) ) { \\r
45           Det_ReportError(MODULE_ID_FEE, 0, _api, _err); \\r
46         }\r
47 \r
48 #define VALIDATE_RV(_exp,_api,_err,_rv ) \\r
49         if( !(_exp) ) { \\r
50           Det_ReportError(MODULE_ID_FEE, 0, _api, _err); \\r
51           return _rv; \\r
52         }\r
53 \r
54 #define VALIDATE_NO_RV(_exp,_api,_err ) \\r
55   if( !(_exp) ) { \\r
56           Det_ReportError(MODULE_ID_FEE, 0, _api, _err); \\r
57           return; \\r
58         }\r
59 #define DET_REPORTERROR(_module,_instance,_api,_err) Det_ReportError(_module,_instance,_api,_err)\r
60 \r
61 #else\r
62 #define VALIDATE(_exp,_api,_err )\r
63 #define VALIDATE_RV(_exp,_api,_err,_rv )\r
64 #define VALIDATE_NO_RV(_exp,_api,_err )\r
65 #define DET_REPORTERROR(_module,_instance,_api,_err)\r
66 #endif\r
67 \r
68 // Block numbering recalculation macros\r
69 #define GET_BLOCK_INDEX_FROM_BLOCK_NUMBER(blocknr)      ((blocknr >> NVM_DATASET_SELECTION_BITS) - 1)\r
70 #define GET_DATASET_FROM_BLOCK_NUMBER(blocknr)  (blocknr & ((1 << NVM_DATASET_SELECTION_BITS) - 1))\r
71 \r
72 // Macro for checking if the flash is ready\r
73 #define FLASH_READY     (FlsAdmin.State == FEE_FLS_STATE_READY)\r
74 \r
75 // Macros and variables for flash block administration\r
76 #define BLOCK_ADMIN_STATUS_VALID        0x01\r
77 #define BLOCK_ADMIN_STATUS_EMPTY        0x02\r
78 \r
79 #define BLOCK_ADMIN_MAGIC_LEN           4\r
80 typedef struct {\r
81         uint8   Status;\r
82         uint8   Spare;\r
83         uint8   Magic[BLOCK_ADMIN_MAGIC_LEN];\r
84 } FlsBlockAdminType;\r
85 \r
86 static FlsBlockAdminType FlsBlockAdmin;\r
87 \r
88 #define BLOCK_ADMIN_LEN                         (sizeof(FlsBlockAdminType))\r
89 #define BLOCK_ADMIN_VALIDATE_POS        0\r
90 #define BLOCK_ADMIN_MAGIC_POS           2\r
91 \r
92 static const uint8 MagicMaster[BLOCK_ADMIN_MAGIC_LEN] = { 0xeb, 0xba, 0xba, 0xbe };\r
93 static const FlsBlockAdminType FlsBlockAdminMaster = {\r
94                 .Status = BLOCK_ADMIN_STATUS_VALID | ~BLOCK_ADMIN_STATUS_EMPTY,\r
95                 .Magic = { 0xeb, 0xba, 0xba, 0xbe }\r
96 };\r
97 \r
98 // Variables for keeping the state and status of the flash\r
99 typedef enum {\r
100         FEE_FLS_STATE_IDLE,\r
101         FEE_FLS_STATE_PENDING,\r
102         FEE_FLS_STATE_READY\r
103 } FlsStateType;\r
104 \r
105 typedef struct {\r
106         FlsStateType State;\r
107         Std_ReturnType ErrorStatus;\r
108         MemIf_JobResultType JobResult;\r
109 } FlsAdminType;\r
110 \r
111 static FlsAdminType FlsAdmin = {\r
112                 .State = FEE_FLS_STATE_IDLE,\r
113                 .ErrorStatus = E_OK,\r
114                 .JobResult = MEMIF_JOB_OK\r
115 };\r
116 \r
117 // Variables for quick reporting of status and job result\r
118 static MemIf_StatusType ModuleStatus = MEMIF_UNINIT;\r
119 static MemIf_JobResultType JobResult = MEMIF_JOB_OK;\r
120 \r
121 // Variables for the current job\r
122 typedef enum {\r
123   FEE_UNINITIALIZED = 0,\r
124   FEE_IDLE,\r
125   FEE_WRITE_REQUESTED,\r
126   FEE_WRITE_MAGIC_EREASE_PENDING,\r
127   FEE_WRITE_EREASE_PENDING,\r
128   FEE_WRITE_PENDING,\r
129   FEE_WRITE_BLOCK_ADMIN_PENDING,\r
130   FEE_READ_REQUESTED,\r
131   FEE_READ_BLOCK_ADMIN_PENDING,\r
132   FEE_READ_PENDING,\r
133   FEE_CANCEL_REQUESTED,\r
134   FEE_CANCEL_PENDING,\r
135   FEE_INVALIDATE_REQUESTED,\r
136   FEE_INVALIDATE_PENDING,\r
137   FEE_ERASE_IMMEDIATE_REQUESTED,\r
138   FEE_ERASE_IMMEDIATE_PENDING\r
139 } CurrentJobStateType;\r
140 \r
141 typedef struct {\r
142         CurrentJobStateType                     State;\r
143         const Fee_BlockConfigType       *BlockConfigPtr;\r
144         uint16                                          Length;\r
145         uint16                                          Offset;\r
146         Fls_AddressType                         FlsBlockAddr;           // Flash source/Dest depending of operation\r
147         Fls_AddressType                         FlsBlockAdminAddr;      // Startadress of admin block\r
148         uint8                                           *RamPtr;                        // RAM source/Dest depending of operation\r
149 } CurrentJobType;\r
150 \r
151 static CurrentJobType CurrentJob = {\r
152                 .State = FEE_IDLE\r
153 };\r
154 \r
155 \r
156 /*\r
157  * Local functions
158  */\r
159 #if (FEE_POLLING_MODE == STD_ON)\r
160 void PollFlsJobResult(void)\r
161 {\r
162         MemIf_JobResultType jobResult;\r
163 \r
164         if (FlsAdmin.State == FEE_FLS_STATE_PENDING) {\r
165                 jobResult = Fls_GetJobResult();\r
166 \r
167                 if (jobResult == MEMIF_JOB_OK) {\r
168                         FlsAdmin.ErrorStatus = E_OK;\r
169                         FlsAdmin.JobResult = jobResult;\r
170                         FlsAdmin.State = FEE_FLS_STATE_READY;\r
171                 } else if (jobResult != MEMIF_JOB_PENDING) {\r
172                         FlsAdmin.ErrorStatus = E_NOT_OK;\r
173                         FlsAdmin.JobResult = jobResult;\r
174                         FlsAdmin.State = FEE_FLS_STATE_READY;\r
175                 }\r
176         }\r
177 }\r
178 #else\r
179 #define PollFlsJobResult(...)\r
180 #endif\r
181 \r
182 \r
183 void FinnishJob(void)\r
184 {\r
185         FlsAdmin.State = FEE_FLS_STATE_IDLE;\r
186         CurrentJob.State = FEE_IDLE;\r
187 \r
188         ModuleStatus = MEMIF_IDLE;\r
189         JobResult = FlsAdmin.JobResult;\r
190 \r
191         if (FlsAdmin.ErrorStatus == E_OK) {\r
192                 if (Fee_Config.General.NvmJobEndCallbackNotificationCallback != NULL) {\r
193                         Fee_Config.General.NvmJobEndCallbackNotificationCallback();\r
194                 }\r
195         } else {\r
196                 if (Fee_Config.General.NvmJobErrorCallbackNotificationCallback != NULL) {\r
197                         Fee_Config.General.NvmJobErrorCallbackNotificationCallback();\r
198                 }\r
199         }\r
200 }\r
201 \r
202 \r
203 void ReadStartJob(void)\r
204 {\r
205         if (FlsAdmin.State == FEE_FLS_STATE_IDLE) {\r
206                 FlsAdmin.State = FEE_FLS_STATE_PENDING;\r
207                 CurrentJob.State = FEE_READ_BLOCK_ADMIN_PENDING;\r
208                 // Start by reading the admin block\r
209                 if (Fls_Read(CurrentJob.FlsBlockAdminAddr, (uint8*)&FlsBlockAdmin, BLOCK_ADMIN_LEN) != E_OK) {\r
210                         FlsAdmin.State = FEE_FLS_STATE_READY;\r
211                         FlsAdmin.ErrorStatus = E_NOT_OK;\r
212                         FlsAdmin.JobResult = Fls_GetJobResult();\r
213                         FinnishJob();\r
214                 }\r
215         }\r
216 }\r
217 \r
218 void ReadCheckBlockAdminJob(void)\r
219 {\r
220         if (FlsAdmin.ErrorStatus == E_OK) {\r
221                 if (memcmp(FlsBlockAdmin.Magic, MagicMaster, BLOCK_ADMIN_MAGIC_LEN) == 0) {\r
222                         if (FlsBlockAdmin.Status & BLOCK_ADMIN_STATUS_VALID) {\r
223                                 if (FlsAdmin.State != FEE_FLS_STATE_PENDING) {\r
224                                         FlsAdmin.State = FEE_FLS_STATE_PENDING;\r
225                                         CurrentJob.State = FEE_READ_PENDING;\r
226                                         // Read the actual data\r
227                                         if (Fls_Read(CurrentJob.FlsBlockAddr + CurrentJob.Offset, CurrentJob.RamPtr, CurrentJob.Length) != E_OK) {\r
228                                                 FlsAdmin.State = FEE_FLS_STATE_READY;\r
229                                                 FlsAdmin.ErrorStatus = E_NOT_OK;\r
230                                                 FlsAdmin.JobResult = Fls_GetJobResult();\r
231                                                 FinnishJob();\r
232                                         }\r
233                                 }\r
234                         } else {\r
235                                 FlsAdmin.ErrorStatus = E_NOT_OK;\r
236                                 FlsAdmin.JobResult = MEMIF_BLOCK_INVALID;\r
237                                 FinnishJob();\r
238                         }\r
239                 } else {\r
240                         FlsAdmin.ErrorStatus = E_NOT_OK;\r
241                         FlsAdmin.JobResult = MEMIF_BLOCK_INCONSISTENT;\r
242                         FinnishJob();\r
243                 }\r
244         } else {\r
245                 FinnishJob();\r
246         }\r
247 }\r
248 \r
249 \r
250 void WriteStartJob(void)\r
251 {\r
252         if (FlsAdmin.State == FEE_FLS_STATE_IDLE) {\r
253                 FlsAdmin.State = FEE_FLS_STATE_PENDING;\r
254                 CurrentJob.State = FEE_WRITE_MAGIC_EREASE_PENDING;\r
255                 // Start by erasing the magic\r
256                 if (Fls_Erase(CurrentJob.FlsBlockAdminAddr + BLOCK_ADMIN_MAGIC_POS, BLOCK_ADMIN_MAGIC_LEN) != E_OK) {\r
257                         FlsAdmin.State = FEE_FLS_STATE_READY;\r
258                         FlsAdmin.ErrorStatus = E_NOT_OK;\r
259                         FlsAdmin.JobResult = Fls_GetJobResult();\r
260                         FinnishJob();\r
261                 }\r
262         }\r
263 }\r
264 \r
265 \r
266 void WriteCheckMagicEraseJob(void)\r
267 {\r
268         if (FlsAdmin.ErrorStatus == E_OK) {\r
269                 if (FlsAdmin.State != FEE_FLS_STATE_PENDING) {\r
270                         FlsAdmin.State = FEE_FLS_STATE_PENDING;\r
271                         CurrentJob.State = FEE_WRITE_EREASE_PENDING;\r
272                         // Erase the rest of the block\r
273                         if (Fls_Erase(CurrentJob.FlsBlockAddr, CurrentJob.BlockConfigPtr->BlockSize + BLOCK_ADMIN_LEN - BLOCK_ADMIN_MAGIC_LEN) != E_OK) {\r
274                                 FlsAdmin.State = FEE_FLS_STATE_READY;\r
275                                 FlsAdmin.ErrorStatus = E_NOT_OK;\r
276                                 FlsAdmin.JobResult = Fls_GetJobResult();\r
277                                 FinnishJob();\r
278                         }\r
279                 }\r
280         } else {\r
281                 FinnishJob();\r
282         }\r
283 }\r
284 \r
285 \r
286 void WriteCheckEraseJob(void)\r
287 {\r
288         if (FlsAdmin.ErrorStatus == E_OK) {\r
289                 if (FlsAdmin.State != FEE_FLS_STATE_PENDING) {\r
290                         FlsAdmin.State = FEE_FLS_STATE_PENDING;\r
291                         CurrentJob.State = FEE_WRITE_PENDING;\r
292                         // Write the actual data\r
293                         if (Fls_Write(CurrentJob.FlsBlockAddr, CurrentJob.RamPtr, CurrentJob.Length) != E_OK) {\r
294                                 FlsAdmin.State = FEE_FLS_STATE_READY;\r
295                                 FlsAdmin.ErrorStatus = E_NOT_OK;\r
296                                 FlsAdmin.JobResult = Fls_GetJobResult();\r
297                                 FinnishJob();\r
298                         }\r
299                 }\r
300         } else {\r
301                 FinnishJob();\r
302         }\r
303 }\r
304 \r
305 \r
306 void WriteCheckWriteJob(void)\r
307 {\r
308         if (FlsAdmin.ErrorStatus == E_OK) {\r
309                 if (FlsAdmin.State != FEE_FLS_STATE_PENDING) {\r
310                         FlsAdmin.State = FEE_FLS_STATE_PENDING;\r
311                         CurrentJob.State = FEE_WRITE_BLOCK_ADMIN_PENDING;\r
312                         // Write the block admin (mark it as consistent, valid and not empty)\r
313                         if (Fls_Write(CurrentJob.FlsBlockAdminAddr, (uint8*)&FlsBlockAdminMaster, BLOCK_ADMIN_LEN) != E_OK) {\r
314                                 FlsAdmin.State = FEE_FLS_STATE_READY;\r
315                                 FlsAdmin.ErrorStatus = E_NOT_OK;\r
316                                 FlsAdmin.JobResult = Fls_GetJobResult();\r
317                                 FinnishJob();\r
318                         }\r
319                 }\r
320         } else {\r
321                 FinnishJob();\r
322         }\r
323 }\r
324 \r
325 \r
326 void InvalidateStartJob(void)\r
327 {\r
328         static const uint8 zero = 0;\r
329 \r
330         if (FlsAdmin.State == FEE_FLS_STATE_IDLE) {\r
331                 FlsAdmin.State = FEE_FLS_STATE_PENDING;\r
332                 CurrentJob.State = FEE_INVALIDATE_PENDING;\r
333                 // Write a zero to the Validate flag\r
334                 if (Fls_Write(CurrentJob.FlsBlockAdminAddr + BLOCK_ADMIN_VALIDATE_POS, &zero, 1) != E_OK) {\r
335                         FlsAdmin.State = FEE_FLS_STATE_READY;\r
336                         FlsAdmin.ErrorStatus = E_NOT_OK;\r
337                         FlsAdmin.JobResult = Fls_GetJobResult();\r
338                 }\r
339         }\r
340 }\r
341 \r
342 \r
343 /***************************************\r
344  *    External accessible functions    *
345  ***************************************/\r
346 /*\r
347  * Procedure:   Fee_Init\r
348  * Reentrant:   No\r
349  */\r
350 void Fee_Init(void)\r
351 {\r
352         // Reporting information\r
353         ModuleStatus = MEMIF_IDLE;\r
354         JobResult = MEMIF_JOB_OK;\r
355 \r
356         // State of device\r
357         CurrentJob.State = FEE_IDLE;\r
358         FlsAdmin.State = FEE_FLS_STATE_IDLE;\r
359         FlsAdmin.ErrorStatus = E_OK;\r
360         FlsAdmin.JobResult = MEMIF_JOB_OK;\r
361 }\r
362 \r
363 \r
364 /*\r
365  * Procedure:   Fee_SetMode\r
366  * Reentrant:   No\r
367  */\r
368 void Fee_SetMode(MemIf_ModeType mode)\r
369 {\r
370 #if ( FLS_SET_MODE_API == STD_ON )\r
371         Fls_SetMode(mode);\r
372 #else\r
373         DET_REPORTERROR(MODULE_ID_FEE, 0, FEE_SET_MODE_ID, FEE_E_NOT_SUPPORTED);\r
374 #endif\r
375 }\r
376 \r
377 /*\r
378  * Procedure:   Fee_Read\r
379  * Reentrant:   No\r
380  */\r
381 Std_ReturnType Fee_Read(uint16 blockNumber, uint16 blockOffset, uint8* dataBufferPtr, uint16 length)\r
382 {\r
383         uint16 blockIndex;\r
384 \r
385         VALIDATE_RV(ModuleStatus != MEMIF_UNINIT, FEE_READ_ID, FEE_E_UNINIT, E_NOT_OK);\r
386         VALIDATE_RV(ModuleStatus == MEMIF_IDLE, FEE_READ_ID, FEE_E_BUSY, E_NOT_OK);\r
387 \r
388         VALIDATE_RV(blockNumber >= (1 << NVM_DATASET_SELECTION_BITS), FEE_READ_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
389         blockIndex = GET_BLOCK_INDEX_FROM_BLOCK_NUMBER(blockNumber);\r
390         VALIDATE_RV(blockIndex < FEE_NUM_OF_BLOCKS, FEE_READ_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
391         VALIDATE_RV(dataBufferPtr != NULL, FEE_READ_ID, FEE_E_INVALID_DATA_PTR, E_NOT_OK);\r
392         VALIDATE_RV(blockOffset < Fee_Config.BlockConfig[blockIndex].BlockSize, FEE_READ_ID, FEE_E_INVALID_BLOCK_OFS, E_NOT_OK);\r
393         VALIDATE_RV(blockOffset + length <= Fee_Config.BlockConfig[blockIndex].BlockSize, FEE_READ_ID, FEE_E_INVALID_BLOCK_LEN, E_NOT_OK);\r
394 \r
395 \r
396         /** @req FEE022 */\r
397         ModuleStatus = MEMIF_BUSY;\r
398         JobResult = MEMIF_JOB_PENDING;\r
399 \r
400         CurrentJob.BlockConfigPtr = &Fee_Config.BlockConfig[blockIndex];\r
401         CurrentJob.Length = length;\r
402         CurrentJob.Offset = blockOffset;\r
403         CurrentJob.FlsBlockAddr = (CurrentJob.BlockConfigPtr->PhysBlockBaseNumber - 1) * FEE_VIRTUAL_PAGE_SIZE + GET_DATASET_FROM_BLOCK_NUMBER(blockNumber) * CurrentJob.BlockConfigPtr->BlockSize;             /** @req FEE021 */\r
404         CurrentJob.FlsBlockAdminAddr = CurrentJob.FlsBlockAddr + CurrentJob.BlockConfigPtr->BlockSize;\r
405         CurrentJob.RamPtr = dataBufferPtr;\r
406         CurrentJob.State = FEE_READ_REQUESTED;\r
407 \r
408         return E_OK;\r
409 }\r
410 \r
411 \r
412 /*\r
413  * Procedure:   Fee_Write\r
414  * Reentrant:   No\r
415  */\r
416 Std_ReturnType Fee_Write(uint16 blockNumber, uint8* dataBufferPtr)\r
417 {\r
418         uint16 blockIndex;\r
419 \r
420         VALIDATE_RV(ModuleStatus != MEMIF_UNINIT, FEE_WRITE_ID, FEE_E_UNINIT, E_NOT_OK);\r
421         VALIDATE_RV(ModuleStatus == MEMIF_IDLE, FEE_WRITE_ID, FEE_E_BUSY, E_NOT_OK);\r
422 \r
423         VALIDATE_RV(blockNumber >= (1 << NVM_DATASET_SELECTION_BITS), FEE_WRITE_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
424         blockIndex = GET_BLOCK_INDEX_FROM_BLOCK_NUMBER(blockNumber);\r
425         VALIDATE_RV(blockIndex < FEE_NUM_OF_BLOCKS, FEE_WRITE_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
426         VALIDATE_RV(dataBufferPtr != NULL, FEE_WRITE_ID, FEE_E_INVALID_DATA_PTR, E_NOT_OK);\r
427 \r
428 \r
429         /** @req FEE025 */\r
430         ModuleStatus = MEMIF_BUSY;\r
431         JobResult = MEMIF_JOB_PENDING;\r
432 \r
433         CurrentJob.BlockConfigPtr = &Fee_Config.BlockConfig[blockIndex];\r
434         CurrentJob.Length = CurrentJob.BlockConfigPtr->BlockSize;\r
435         CurrentJob.FlsBlockAddr = (CurrentJob.BlockConfigPtr->PhysBlockBaseNumber - 1) * FEE_VIRTUAL_PAGE_SIZE + GET_DATASET_FROM_BLOCK_NUMBER(blockNumber) * CurrentJob.BlockConfigPtr->BlockSize;             /** @req FEE024 */\r
436         CurrentJob.FlsBlockAdminAddr = CurrentJob.FlsBlockAddr + CurrentJob.BlockConfigPtr->BlockSize;\r
437         CurrentJob.RamPtr = dataBufferPtr;\r
438         CurrentJob.State = FEE_WRITE_REQUESTED;\r
439 \r
440         return E_OK;\r
441 }\r
442 \r
443 \r
444 /*\r
445  * Procedure:   Fee_Cancel\r
446  * Reentrant:   No\r
447  */\r
448 void Fee_Cancel(void)\r
449 {\r
450         DET_REPORTERROR(MODULE_ID_FEE, 0, FEE_CANCEL_ID, FEE_E_NOT_IMPLEMENTED_YET);\r
451 }\r
452 \r
453 \r
454 /*\r
455  * Procedure:   Fee_GetStatus\r
456  * Reentrant:   No\r
457  */\r
458 MemIf_StatusType Fee_GetStatus(void)\r
459 {\r
460         return ModuleStatus;\r
461 }\r
462 \r
463 \r
464 /*\r
465  * Procedure:   Fee_GetJobResult\r
466  * Reentrant:   No\r
467  */\r
468 MemIf_JobResultType Fee_GetJobResult(void)\r
469 {\r
470         return JobResult;\r
471 }\r
472 \r
473 \r
474 /*\r
475  * Procedure:   Fee_InvalidateBlock\r
476  * Reentrant:   No\r
477  */\r
478 Std_ReturnType Fee_InvalidateBlock(uint16 blockNumber)\r
479 {\r
480         uint16 blockIndex;\r
481 \r
482         VALIDATE_RV(ModuleStatus != MEMIF_UNINIT, FEE_INVALIDATE_BLOCK_ID, FEE_E_UNINIT, E_NOT_OK);\r
483         VALIDATE_RV(ModuleStatus == MEMIF_IDLE, FEE_INVALIDATE_BLOCK_ID, FEE_E_BUSY, E_NOT_OK);\r
484 \r
485         VALIDATE_RV(blockNumber >= (1 << NVM_DATASET_SELECTION_BITS), FEE_INVALIDATE_BLOCK_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
486         blockIndex = GET_BLOCK_INDEX_FROM_BLOCK_NUMBER(blockNumber);\r
487         VALIDATE_RV(blockIndex < FEE_NUM_OF_BLOCKS, FEE_INVALIDATE_BLOCK_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
488 \r
489 \r
490         ModuleStatus = MEMIF_BUSY;\r
491         JobResult = MEMIF_JOB_PENDING;\r
492 \r
493         CurrentJob.BlockConfigPtr = &Fee_Config.BlockConfig[blockIndex];\r
494         CurrentJob.Length = 0;\r
495         CurrentJob.FlsBlockAddr = (CurrentJob.BlockConfigPtr->PhysBlockBaseNumber - 1) * FEE_VIRTUAL_PAGE_SIZE + GET_DATASET_FROM_BLOCK_NUMBER(blockNumber) * CurrentJob.BlockConfigPtr->BlockSize;             /** @req FEE024 */\r
496         CurrentJob.FlsBlockAdminAddr = CurrentJob.FlsBlockAddr + CurrentJob.BlockConfigPtr->BlockSize;\r
497         CurrentJob.RamPtr = NULL;\r
498         CurrentJob.State = FEE_INVALIDATE_REQUESTED;\r
499 \r
500         return E_OK;\r
501 }\r
502 \r
503 \r
504 /*\r
505  * Procedure:   Fee_EraseImmediateBlock\r
506  * Reentrant:   No\r
507  */\r
508 Std_ReturnType Fee_EraseImmediateBlock(uint16 blockNumber)\r
509 {\r
510         DET_REPORTERROR(MODULE_ID_FEE, 0, FEE_ERASE_IMMEDIATE_ID, FEE_E_NOT_IMPLEMENTED_YET);\r
511 \r
512         return E_NOT_OK;\r
513 }\r
514 \r
515 \r
516 /***************************************\r
517  *         Scheduled functions         *
518  ***************************************/\r
519 /*\r
520  * Procedure:   Fee_MainFunction\r
521  * Reentrant:   No\r
522  */\r
523 void Fee_MainFunction(void)\r
524 {\r
525         switch (CurrentJob.State) {\r
526         case FEE_UNINITIALIZED:\r
527         case FEE_IDLE:\r
528                 break;\r
529 \r
530         // Read states\r
531         case FEE_READ_REQUESTED:\r
532                 ReadStartJob();\r
533                 break;\r
534 \r
535         case FEE_READ_BLOCK_ADMIN_PENDING:\r
536                 PollFlsJobResult();\r
537                 if (FLASH_READY) {\r
538                         ReadCheckBlockAdminJob();\r
539                 }\r
540                 break;\r
541 \r
542         case FEE_READ_PENDING:\r
543                 PollFlsJobResult();\r
544                 if (FLASH_READY) {\r
545                         FinnishJob();\r
546                 }\r
547                 break;\r
548 \r
549         // Write states\r
550         case FEE_WRITE_REQUESTED:\r
551                 WriteStartJob();\r
552                 break;\r
553 \r
554         case FEE_WRITE_MAGIC_EREASE_PENDING:\r
555                 PollFlsJobResult();\r
556                 if (FLASH_READY) {\r
557                         WriteCheckMagicEraseJob();\r
558                 }\r
559                 break;\r
560 \r
561         case FEE_WRITE_EREASE_PENDING:\r
562                 PollFlsJobResult();\r
563                 if (FLASH_READY) {\r
564                         WriteCheckEraseJob();\r
565                 }\r
566                 break;\r
567 \r
568         case FEE_WRITE_PENDING:\r
569                 PollFlsJobResult();\r
570                 if (FLASH_READY) {\r
571                         WriteCheckWriteJob();\r
572                 }\r
573                 break;\r
574 \r
575         case FEE_WRITE_BLOCK_ADMIN_PENDING:\r
576                 PollFlsJobResult();\r
577                 if (FLASH_READY) {\r
578                         FinnishJob();\r
579                 }\r
580                 break;\r
581 \r
582         // Invalidate states\r
583         case FEE_INVALIDATE_REQUESTED:\r
584                 InvalidateStartJob();\r
585                 break;\r
586 \r
587         case FEE_INVALIDATE_PENDING:\r
588                 PollFlsJobResult();\r
589                 if (FLASH_READY) {\r
590                         FinnishJob();\r
591                 }\r
592                 break;\r
593 \r
594         // Other\r
595         default:\r
596                 break;\r
597         }\r
598 }\r
599 \r
600 \r
601 /***************************************\r
602  *  Call-back notifications functions  *
603  ***************************************/\r
604 #if (FEE_POLLING_MODE == STD_OFF)\r
605 /*\r
606  * Procedure:   Fee_JobEndNotification\r
607  * Reentrant:   No\r
608  */\r
609 void Fee_JobEndNotification(void)\r
610 {\r
611         FlsAdmin.State = FEE_FLS_STATE_READY;\r
612         FlsAdmin.ErrorStatus = E_OK;\r
613         FlsAdmin.JobResult = Fls_GetJobResult();\r
614 }\r
615 \r
616 \r
617 /*\r
618  * Procedure:   Fee_JobErrorNotification\r
619  * Reentrant:   No\r
620  */\r
621 void Fee_JobErrorNotification(void)\r
622 {\r
623         FlsAdmin.State = FEE_FLS_STATE_READY;\r
624         FlsAdmin.ErrorStatus = E_NOT_OK;\r
625         FlsAdmin.JobResult = Fls_GetJobResult();\r
626 }\r
627 #endif\r
628 \r
629 \r