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