]> rtime.felk.cvut.cz Git - arc.git/blob - memory/Fee/Fee.c
Added more to Fee
[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 "Fee.h"\r
25 #include "Fee_Cbk.h"\r
26 #include "NvM.h"\r
27 #include "Fls.h"\r
28 #include "Rte.h" // ???\r
29 #if defined(USE_DEM)\r
30 #include "Dem.h"\r
31 #endif\r
32 //#include "SchM_NvM.h"\r
33 #include "MemMap.h"\r
34 \r
35 /*\r
36  * Local definitions
37  */\r
38 #if  ( FEE_DEV_ERROR_DETECT == STD_ON )\r
39 #include "Det.h"\r
40 #define VALIDATE(_exp,_api,_err ) \\r
41         if( !(_exp) ) { \\r
42           Det_ReportError(MODULE_ID_FEE, 0, _api, _err); \\r
43         }\r
44 \r
45 #define VALIDATE_RV(_exp,_api,_err,_rv ) \\r
46         if( !(_exp) ) { \\r
47           Det_ReportError(MODULE_ID_FEE, 0, _api, _err); \\r
48           return _rv; \\r
49         }\r
50 \r
51 #define VALIDATE_NO_RV(_exp,_api,_err ) \\r
52   if( !(_exp) ) { \\r
53           Det_ReportError(MODULE_ID_FEE, 0, _api, _err); \\r
54           return; \\r
55         }\r
56 #define DET_REPORTERROR(_module,_instance,_api,_err) Det_ReportError(_module,_instance,_api,_err)\r
57 \r
58 #else\r
59 #define VALIDATE(_exp,_api,_err )\r
60 #define VALIDATE_RV(_exp,_api,_err,_rv )\r
61 #define VALIDATE_NO_RV(_exp,_api,_err )\r
62 #define DET_REPORTERROR(_module,_instance,_api,_err)\r
63 #endif\r
64 \r
65 \r
66 #define GET_BLOCK_INDEX_FROM_BLOCK_NUMBER(blocknr)      ((blocknr >> NVM_DATASET_SELECTION_BITS) - 1)\r
67 #define GET_DATASET_FROM_BLOCK_NUMBER(blocknr)  (blocknr & ~((1 << NVM_DATASET_SELECTION_BITS) - 1))\r
68 \r
69 \r
70 // Variables for quick reporting of status and job result\r
71 static MemIf_StatusType ModuleStatus = MEMIF_UNINIT;\r
72 static MemIf_JobResultType JobResult = MEMIF_JOB_OK;\r
73 \r
74 typedef enum {\r
75   FEE_UNINITIALIZED = 0,\r
76   FEE_IDLE,\r
77   FEE_JOB_REQUESTED,\r
78   FEE_JOB_PROCESSING,\r
79   FEE_JOB_PENDING,\r
80 } FeeStateType;\r
81 \r
82 // Variables holding state of Fee.\r
83 static FeeStateType FeeState = FEE_UNINITIALIZED;\r
84 \r
85 typedef enum {\r
86         FEE_JOB_TYPE_NONE,\r
87         FEE_JOB_TYPE_READ,\r
88         FEE_JOB_TYPE_WRITE,\r
89         FEE_JOB_TYPE_CANCEL,\r
90         FEE_JOB_TYPE_INVALIDATE,\r
91         FEE_JOB_TYPE_ERASE_IMMEDIATE_BLOCK\r
92 } CurrentJobTypeType;\r
93 \r
94 typedef enum {\r
95         FEE_FLS_STATE_IDLE,\r
96         FEE_FLS_STATE_PENDING,\r
97         FEE_FLS_STATE_READY\r
98 } FlsStateType;\r
99 \r
100 typedef struct {\r
101         FlsStateType State;\r
102         Std_ReturnType ErrorStatus;\r
103         MemIf_JobResultType JobResult;\r
104 } FlsAdminType;\r
105 \r
106 static FlsAdminType FlsAdmin = {\r
107                 .State = FEE_FLS_STATE_IDLE,\r
108                 .ErrorStatus = E_OK,\r
109                 .JobResult = MEMIF_JOB_OK\r
110 };\r
111 \r
112 typedef struct {\r
113         boolean         Consistant;\r
114 } BlockAdminType;\r
115 \r
116 static BlockAdminType BlockAdminList[FEE_NUM_OF_BLOCKS];\r
117 \r
118 typedef struct {\r
119         CurrentJobTypeType                      Type;\r
120         const Fee_BlockConfigType       *BlockConfigPtr;\r
121         BlockAdminType                          *BlockAdminPtr;\r
122         uint16                                          Length;\r
123         uint8                                           FlsAddr;                // Flash source/Dest depending of operation\r
124         uint8                                           *RamPtr;                // RAM source/Dest depending of operation\r
125 } CurrentJobType;\r
126 \r
127 static CurrentJobType CurrentJob = {\r
128                 .Type = FEE_JOB_TYPE_NONE,\r
129 };\r
130 \r
131 void Fee_Init(void)\r
132 {\r
133         // Reporting information\r
134         ModuleStatus = MEMIF_IDLE;\r
135         JobResult = MEMIF_JOB_OK;\r
136 \r
137         // State of device\r
138         FeeState = FEE_IDLE;\r
139         FlsAdmin.State = FEE_FLS_STATE_IDLE;\r
140         FlsAdmin.ErrorStatus = E_OK;\r
141         FlsAdmin.JobResult = MEMIF_JOB_OK;\r
142 }\r
143 \r
144 \r
145 void Fee_SetMode(MemIf_ModeType mode)\r
146 {\r
147 #if ( FLS_SET_MODE_API == STD_ON )\r
148         Fls_SetMode(mode);\r
149 #else\r
150         DET_REPORTERROR(MODULE_ID_FEE, 0, FEE_SET_MODE_ID, FEE_E_NOT_SUPPORTED);\r
151 #endif\r
152 }\r
153 \r
154 \r
155 Std_ReturnType Fee_Read(uint16 blockNumber, uint16 blockOffset, uint8* dataBufferPtr, uint16 length)\r
156 {\r
157         uint16 blockIndex;\r
158 \r
159         VALIDATE_RV(ModuleStatus != MEMIF_UNINIT, FEE_READ_ID, FEE_E_UNINIT, E_NOT_OK);\r
160         VALIDATE_RV(ModuleStatus == MEMIF_IDLE, FEE_READ_ID, FEE_E_BUSY, E_NOT_OK);\r
161 \r
162         VALIDATE_RV(blockNumber >= (1 << NVM_DATASET_SELECTION_BITS), FEE_READ_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
163         blockIndex = GET_BLOCK_INDEX_FROM_BLOCK_NUMBER(blockNumber);\r
164         VALIDATE_RV(blockIndex < FEE_NUM_OF_BLOCKS, FEE_READ_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
165         VALIDATE_RV(dataBufferPtr != NULL, FEE_READ_ID, FEE_E_INVALID_DATA_PTR, E_NOT_OK);\r
166         VALIDATE_RV(blockOffset < Fee_Config.BlockConfig[blockIndex].BlockSize, FEE_READ_ID, FEE_E_INVALID_BLOCK_OFS, E_NOT_OK);\r
167         VALIDATE_RV(blockOffset + length < Fee_Config.BlockConfig[blockIndex].BlockSize, FEE_READ_ID, FEE_E_INVALID_BLOCK_LEN, E_NOT_OK);\r
168 \r
169 \r
170         /** @req FEE022 */\r
171         ModuleStatus = MEMIF_BUSY;\r
172         JobResult = MEMIF_JOB_PENDING;\r
173 \r
174         CurrentJob.Type = FEE_JOB_TYPE_READ;\r
175         CurrentJob.BlockConfigPtr = &Fee_Config.BlockConfig[blockIndex];\r
176         CurrentJob.BlockAdminPtr = &BlockAdminList[blockIndex];\r
177         CurrentJob.Length = length;\r
178         CurrentJob.FlsAddr = CurrentJob.BlockConfigPtr->PhysBaseAddress + GET_DATASET_FROM_BLOCK_NUMBER(blockNumber) * CurrentJob.BlockConfigPtr->BlockSize + blockOffset;              /** @req FEE021 */\r
179         CurrentJob.RamPtr = dataBufferPtr;\r
180 \r
181         FeeState = FEE_JOB_REQUESTED;\r
182 \r
183         return E_OK;\r
184 }\r
185 \r
186 \r
187 Std_ReturnType Fee_Write(uint16 blockNumber, uint8* dataBufferPtr)\r
188 {\r
189         uint16 blockIndex;\r
190 \r
191         VALIDATE_RV(ModuleStatus != MEMIF_UNINIT, FEE_WRITE_ID, FEE_E_UNINIT, E_NOT_OK);\r
192         VALIDATE_RV(ModuleStatus == MEMIF_IDLE, FEE_WRITE_ID, FEE_E_BUSY, E_NOT_OK);\r
193 \r
194         VALIDATE_RV(blockNumber >= (1 << NVM_DATASET_SELECTION_BITS), FEE_WRITE_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
195         blockIndex = GET_BLOCK_INDEX_FROM_BLOCK_NUMBER(blockNumber);\r
196         VALIDATE_RV(blockIndex < FEE_NUM_OF_BLOCKS, FEE_WRITE_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
197         VALIDATE_RV(dataBufferPtr != NULL, FEE_WRITE_ID, FEE_E_INVALID_DATA_PTR, E_NOT_OK);\r
198 \r
199 \r
200         /** @req FEE025 */\r
201         ModuleStatus = MEMIF_BUSY;\r
202         JobResult = MEMIF_JOB_PENDING;\r
203 \r
204         CurrentJob.Type = FEE_JOB_TYPE_WRITE;\r
205         CurrentJob.BlockConfigPtr = &Fee_Config.BlockConfig[blockIndex];\r
206         CurrentJob.BlockAdminPtr = &BlockAdminList[blockIndex];\r
207         CurrentJob.Length = CurrentJob.BlockConfigPtr->BlockSize;\r
208         CurrentJob.FlsAddr = CurrentJob.BlockConfigPtr->PhysBaseAddress + GET_DATASET_FROM_BLOCK_NUMBER(blockNumber) * CurrentJob.BlockConfigPtr->BlockSize;            /** @req FEE024 */\r
209         CurrentJob.RamPtr = dataBufferPtr;\r
210 \r
211         FeeState = FEE_JOB_REQUESTED;\r
212 \r
213         return E_OK;\r
214 }\r
215 \r
216 \r
217 void Fee_Cancel(void)\r
218 {\r
219 \r
220 }\r
221 \r
222 \r
223 MemIf_StatusType Fee_GetStatus(void)\r
224 {\r
225         return ModuleStatus;\r
226 }\r
227 \r
228 \r
229 MemIf_JobResultType Fee_GetJobResult(void)\r
230 {\r
231         return JobResult;\r
232 }\r
233 \r
234 \r
235 Std_ReturnType Fee_InvalidateBlock(uint16 blockNumber)\r
236 {\r
237         VALIDATE_RV(blockNumber < FEE_NUM_OF_BLOCKS, FEE_INVALIDATE_BLOCK_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
238 \r
239         ModuleStatus = MEMIF_BUSY;\r
240         JobResult = MEMIF_JOB_PENDING;\r
241 \r
242         CurrentJob.Type = FEE_JOB_TYPE_INVALIDATE;\r
243 \r
244         FeeState = FEE_JOB_REQUESTED;\r
245 \r
246         return E_OK;\r
247 }\r
248 \r
249 \r
250 Std_ReturnType Fee_EraseImmediateBlock(uint16 blockNumber)\r
251 {\r
252         VALIDATE_RV(blockNumber < FEE_NUM_OF_BLOCKS, FEE_ERASE_IMMEDIATE_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
253         VALIDATE_RV(Fee_Config.BlockConfig[blockNumber].ImmediateData, FEE_ERASE_IMMEDIATE_ID, FEE_E_INVALID_BLOCK_NO, E_NOT_OK);\r
254 \r
255         ModuleStatus = MEMIF_BUSY;\r
256         JobResult = MEMIF_JOB_PENDING;\r
257         CurrentJob.Type = FEE_JOB_TYPE_ERASE_IMMEDIATE_BLOCK;\r
258 \r
259         FeeState = FEE_JOB_REQUESTED;\r
260 \r
261         return E_OK;\r
262 }\r
263 \r
264 void StartJob(void)\r
265 {\r
266         if (FlsAdmin.State == FEE_FLS_STATE_IDLE) {\r
267                 switch (CurrentJob.Type) {\r
268                 case FEE_JOB_TYPE_READ:\r
269                         FlsAdmin.State = FEE_FLS_STATE_PENDING;\r
270                         FeeState = FEE_JOB_PENDING;\r
271                         if (Fls_Read(CurrentJob.FlsAddr, CurrentJob.RamPtr, CurrentJob.Length) != E_OK) {\r
272                                 FlsAdmin.State = FEE_FLS_STATE_READY;\r
273                                 FlsAdmin.ErrorStatus = E_NOT_OK;\r
274                                 FlsAdmin.JobResult = Fls_GetJobResult();\r
275                         }\r
276                         break;\r
277 \r
278                 case FEE_JOB_TYPE_WRITE:\r
279                         FlsAdmin.State = FEE_FLS_STATE_PENDING;\r
280                         FeeState = FEE_JOB_PENDING;\r
281                         if (Fls_Write(CurrentJob.FlsAddr, CurrentJob.RamPtr, CurrentJob.Length) != E_OK) {\r
282                                 FlsAdmin.State = FEE_FLS_STATE_READY;\r
283                                 FlsAdmin.ErrorStatus = E_NOT_OK;\r
284                                 FlsAdmin.JobResult = Fls_GetJobResult();\r
285                         }\r
286                         break;\r
287 \r
288                 case FEE_JOB_TYPE_CANCEL:\r
289                         break;\r
290 \r
291                 case FEE_JOB_TYPE_INVALIDATE:\r
292                         break;\r
293 \r
294                 case FEE_JOB_TYPE_ERASE_IMMEDIATE_BLOCK:\r
295                         break;\r
296 \r
297                 default:\r
298                         break;\r
299                 }\r
300         } // if FEE_FLSH_STATE_IDLE\r
301 }\r
302 \r
303 \r
304 #if (FEE_POLLING_MODE == STD_ON)\r
305 void PollFlsJobResult(void)\r
306 {\r
307         MemIf_JobResultType jobResult;\r
308 \r
309         FlsAdmin.State = FEE_FLS_STATE_READY;\r
310         jobResult = Fls_GetJobResult();\r
311 \r
312         if (jobResult == MEMIF_JOB_OK) {\r
313                 FlsAdmin.ErrorStatus = E_OK;\r
314                 FlsAdmin.JobResult = jobResult;\r
315         } else if (jobResult != MEMIF_JOB_PENDING) {\r
316                 FlsAdmin.ErrorStatus = E_NOT_OK;\r
317                 FlsAdmin.JobResult = jobResult;\r
318         }\r
319 \r
320 }\r
321 #else\r
322 void Fee_JobEndNotification(void)\r
323 {\r
324         FlsAdmin.State = FEE_FLS_STATE_READY;\r
325         FlsAdmin.ErrorStatus = E_OK;\r
326         FlsAdmin.JobResult = Fls_GetJobResult();\r
327 }\r
328 \r
329 void Fee_JobErrorNotification(void)\r
330 {\r
331         FlsAdmin.State = FEE_FLS_STATE_READY;\r
332         FlsAdmin.ErrorStatus = E_NOT_OK;\r
333         FlsAdmin.JobResult = Fls_GetJobResult();\r
334 }\r
335 #endif\r
336 \r
337 void CheckFlsResult(void)\r
338 {\r
339         FlsAdmin.State = FEE_FLS_STATE_IDLE;\r
340         FeeState = FEE_IDLE;\r
341 \r
342         ModuleStatus = MEMIF_IDLE;\r
343         JobResult = FlsAdmin.JobResult;\r
344 \r
345         if (FlsAdmin.ErrorStatus == E_OK) {\r
346                 if (Fee_Config.General.NvmJobEndCallbackNotificationCallback != NULL) {\r
347                         Fee_Config.General.NvmJobEndCallbackNotificationCallback();\r
348                 }\r
349         } else {\r
350                 if (Fee_Config.General.NvmJobErrorCallbackNotificationCallback != NULL) {\r
351                         Fee_Config.General.NvmJobErrorCallbackNotificationCallback();\r
352                 }\r
353         }\r
354 }\r
355 \r
356 \r
357 void Fee_MainFunction(void)\r
358 {\r
359         switch (FeeState) {\r
360         case FEE_UNINITIALIZED:\r
361         case FEE_IDLE:\r
362                 break;\r
363 \r
364         case FEE_JOB_REQUESTED:\r
365                 StartJob();\r
366                 break;\r
367 \r
368         case FEE_JOB_PENDING:\r
369 #if (FEE_POLLING_MODE == STD_ON)\r
370                 PollFlsJobResult();\r
371 #endif\r
372                 CheckFlsResult();\r
373                 break;\r
374 \r
375         default:\r
376                 break;\r
377         }\r
378 }\r
379 \r