]> rtime.felk.cvut.cz Git - arc.git/blob - arch/ppc/mpc55xx/drivers/Fls.c
Fls ppc, removed code that should not be there.
[arc.git] / arch / ppc / mpc55xx / drivers / Fls.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 /* ----------------------------[information]----------------------------------*/\r
17 /*\r
18  * Author: mahi\r
19  *\r
20  * Part of Release:\r
21  *   3.0 (R3.0 V002)\r
22  *\r
23  * Description:\r
24  *   Implements the Fls module (flash driver)\r
25  *\r
26  * Support:\r
27  *   General                              Have Support\r
28  *   -------------------------------------------\r
29  *   FLS_AC_LOAD_ON_JOB_START    Y\r
30  *   FLS_BASE_ADDRESS                    Y, taken from FlashInfo\r
31  *   FLS_CANCEL_API                              N\r
32  *   FLS_COMPARE_API                     Y\r
33  *   FLS_DEV_ERROR_DETECT                Y\r
34  *   FLS_GET_JOB_RESULT_API              Y\r
35  *   FLS_GET_STATUS_API                  Y\r
36  *   FLS_SET_MODE_API            N\r
37  *   FLS_TOTAL_SIZE                              Y, taken from FlashInfo\r
38  *   FLS_USE_INTERRUPTS                  N, no hardware support\r
39  *   FLS_VERSION_INFO_API                Y\r
40  *\r
41  *   Device\r
42  *   - MPC5668  , No support for shadow flash\r
43  *   - MPC5606S , Support for dataflash only\r
44  *\r
45  * Implementation Notes:\r
46  *   Affected files:\r
47  *   - Fls.c\r
48  *   - Fls_Cfg.c/.h\r
49  *   - flash_h7f_c90.c     middle level driver\r
50  *   - flash_ll_h7f_c90.c  low level driver\r
51  *   - flash.h             interface for flash_xxx\r
52  *\r
53  *   Can't really tell if FlsMaxWriteFastMode, FlsMaxWriteNormalMode, etc is only\r
54  *   for SPI flashes or not. Is it?\r
55  *\r
56  * Things left:\r
57  *   - Virtual addresses, FLS209 is not done (code assumes FLS_BASE_ADDRESS is 0)\r
58  *\r
59  */\r
60 \r
61 /* ----------------------------[requirements]--------------------------------*/\r
62 \r
63 /* FlsGeneral, Complete for 3.0 */\r
64 /** @req FLS172 */\r
65 // TODO: #warning ENABLE THESE AGAIN\r
66 \r
67 /** !req FLS169 */\r
68 /** !req FLS285 */\r
69 /** !req FLS286 */\r
70 /** !req FLS287 */\r
71 /** !req FLS288 */\r
72 /** !req FLS289 */\r
73 /** !req FLS290 */\r
74 /** !req FLS291 */\r
75 /** !req FLS170 */\r
76 /** !req FLS292 */\r
77 /** !req FLS293 */\r
78 \r
79 /* FlsConfigSet, Complete for 3.0 */\r
80 /** !req FLS174 */\r
81 /** !req FLS270 */\r
82 /** !req FLS271 */\r
83 /** !req FLS272 */\r
84 /** @req FLS273 */\r
85 /** @req FLS274 */\r
86 /** !req FLS275 */\r
87 /** !req FLS276 */\r
88 /** @req FLS277 */\r
89 /** @req FLS278 */\r
90 /** !req FLS279  N/A in core */\r
91 \r
92 /* FlsPublishedInformation, Complete for 3.0 */\r
93 /** !req FLS294 */\r
94 /** !req FLS295 */\r
95 /** !req FLS296 */\r
96 /** !req FLS297 */\r
97 /** !req FLS298 */\r
98 /** !req FLS299 */\r
99 /** !req FLS300 */\r
100 /** !req FLS198 */\r
101 /** !req FLS301 */\r
102 \r
103 /* FlsSectorList and FlsSector , Complete for 3.0 */\r
104 /** !req FLS201 N/A in core since we use own format */\r
105 /** !req FLS202 N/A in core since we use own format */\r
106 /** !req FLS280 N/A in core since we use own format */\r
107 /** !req FLS281 N/A in core since we use own format */\r
108 /** !req FLS282 N/A in core since we use own format */\r
109 /** !req FLS283 N/A in core since we use own format */\r
110 \r
111 \r
112 /* ----------------------------[includes]------------------------------------*/\r
113 #include <stddef.h>\r
114 #include <stdlib.h>\r
115 #include <stdint.h>\r
116 #include <assert.h>\r
117 #include <string.h>\r
118 #include "Fls.h"\r
119 #include "flash.h"\r
120 #include "Det.h"\r
121 #if defined(USE_DEM)\r
122 #include "Dem.h"\r
123 #endif\r
124 #include "Cpu.h"\r
125 #include "mpc55xx.h"\r
126 \r
127 #if (FLS_BASE_ADDRESS != 0)\r
128 #error Virtual addresses not supported\r
129 #endif\r
130 \r
131 /* ----------------------------[private define]------------------------------*/\r
132 /* ----------------------------[private macro]-------------------------------*/\r
133 \r
134 \r
135 #if ( FLS_DEV_ERROR_DETECT == STD_ON )\r
136 #define DET_REPORTERROR(_x,_y,_z,_q) Det_ReportError(MODULE_ID_FLS, _y, _z, _q)\r
137 \r
138 #define FEE_JOB_END_NOTIFICATION() \\r
139   if( Fls_Global.config->FlsJobEndNotification != NULL ) { \\r
140     Fls_Global.config->FlsJobEndNotification(); \\r
141   }\r
142 \r
143 #define FEE_JOB_ERROR_NOTIFICATION() \\r
144   if( Fls_Global.config->FlsJobErrorNotification != NULL ) { \\r
145     Fls_Global.config->FlsJobErrorNotification(); \\r
146   }\r
147 \r
148 #define VALIDATE(_exp,_api,_err ) \\r
149         if( !(_exp) ) { \\r
150           Det_ReportError(MODULE_ID_FLS,0,_api,_err); \\r
151           return E_NOT_OK; \\r
152         }\r
153 \r
154 #define VALIDATE_NO_RV(_exp,_api,_err ) \\r
155         if( !(_exp) ) { \\r
156           Det_ReportError(MODULE_ID_FLS,0,_api,_err); \\r
157           return; \\r
158         }\r
159 \r
160 #define VALIDATE_W_RV(_exp,_api,_err,_rv ) \\r
161         if( !(_exp) ) { \\r
162           Det_ReportError(MODULE_ID_FLS,0,_api,_err); \\r
163           return (_rv); \\r
164         }\r
165 \r
166 \r
167 #else\r
168 #define DET_REPORTERROR(_x,_y,_z,_q)\r
169 #define FEE_JOB_END_NOTIFICATION()\r
170 #define FEE_JOB_ERROR_NOTIFICATION()\r
171 #define VALIDATE(_exp,_api,_err )\r
172 #define VALIDATE_NO_RV(_exp,_api,_err )\r
173 #define VALIDATE_W_RV(_exp,_api,_err,_rv )\r
174 #define DET_REPORTERROR(_x,_y,_z,_q)\r
175 #endif\r
176 \r
177 /* ----------------------------[private typedef]-----------------------------*/\r
178 \r
179 typedef enum {\r
180         FLS_JOB_NONE, FLS_JOB_COMPARE, FLS_JOB_ERASE, FLS_JOB_READ, FLS_JOB_WRITE,\r
181 } Fls_Arc_JobType;\r
182 \r
183 typedef struct {\r
184         uint32_t dest;\r
185 //      uint32_t size;\r
186         uint32_t source;\r
187         uint32_t left;\r
188 \r
189     uint32_t pDest;\r
190     uint32_t pLeft;\r
191 } Fls_ProgInfoType;\r
192 \r
193 \r
194 typedef struct {\r
195         const Fls_ConfigType * config;\r
196         MemIf_StatusType        status;\r
197         MemIf_JobResultType jobResultType;\r
198         Fls_Arc_JobType         jobType;\r
199         Fls_AddressType         flashAddr; //sourceAddr\r
200         uint8 *                         ramAddr;    // targetAddr\r
201         Fls_LengthType          length;\r
202         Fls_ProgInfoType        flashWriteInfo;\r
203         bool                            mustCheck;\r
204 } Fls_GlobalType;\r
205 \r
206 Fls_GlobalType Fls_Global = {\r
207         .status = MEMIF_UNINIT,\r
208         .jobResultType = MEMIF_JOB_OK,\r
209         .jobType = FLS_JOB_NONE,\r
210         .mustCheck = 0,\r
211 };\r
212 \r
213 \r
214 \r
215 /* ----------------------------[private function prototypes]-----------------*/\r
216 /* ----------------------------[private variables]---------------------------*/\r
217 static Std_VersionInfoType _Fls_VersionInfo = {\r
218                 .vendorID = (uint16) 1,\r
219                 .moduleID = (uint16) MODULE_ID_FLS,\r
220                 .instanceID = (uint8) 1,\r
221                 /* Vendor numbers */\r
222                 .sw_major_version = (uint8) FLS_SW_MAJOR_VERSION,\r
223                 .sw_minor_version = (uint8) FLS_SW_MINOR_VERSION,\r
224                 .sw_patch_version = (uint8) FLS_SW_PATCH_VERSION,\r
225                 .ar_major_version = (uint8) FLS_AR_MAJOR_VERSION,\r
226                 .ar_minor_version = (uint8) FLS_AR_MINOR_VERSION,\r
227                 .ar_patch_version = (uint8) FLS_AR_PATCH_VERSION, };\r
228 \r
229 /* ----------------------------[private functions]---------------------------*/\r
230 \r
231 static Std_ReturnType fls_SectorAligned( Fls_AddressType SourceAddress ) {\r
232         Std_ReturnType rv = E_NOT_OK;\r
233     const FlashType *bPtr;\r
234 \r
235     for (int bank = 0; bank < FLASH_BANK_CNT; bank++) {\r
236         bPtr = &Fls_Global.config->FlsInfo[bank];\r
237 \r
238         /* In range of bank */\r
239         if( (SourceAddress >= bPtr->sectAddr[0]) &&\r
240             (SourceAddress <= (bPtr->sectAddr[bPtr->sectCnt])) )\r
241         {\r
242             for (int sector = 0; sector < bPtr->sectCnt + 1; sector++)\r
243             {\r
244                 if( SourceAddress == bPtr->sectAddr[sector] ) {\r
245                     rv = E_OK;\r
246                     break;\r
247                 }\r
248             }\r
249             break;\r
250         }\r
251     }\r
252     return rv;\r
253 }\r
254 \r
255 static Std_ReturnType fls_CheckValidAddress( Fls_AddressType SourceAddress ) {\r
256         Std_ReturnType rv = E_NOT_OK;\r
257     const FlashType *bPtr;\r
258 \r
259     for (int bank = 0; bank < FLASH_BANK_CNT; bank++) {\r
260         bPtr = &Fls_Global.config->FlsInfo[bank];\r
261 \r
262                 for (int sector = 0; sector < bPtr->sectCnt; sector++)\r
263                 {\r
264                         if( (SourceAddress >= bPtr->sectAddr[sector]) &&\r
265                                 (SourceAddress < bPtr->sectAddr[sector+1]) )\r
266                         {\r
267                                 rv = E_OK;\r
268                                 break;\r
269                         }\r
270                 }\r
271     }\r
272     return rv;\r
273 }\r
274 \r
275 /**\r
276  * Get PC.\r
277  * Since you can't read the PC on PPC, do the next best thing.\r
278  * Ensure that the function is not inlined\r
279  */\r
280 #if 0\r
281 static uint32 fls_GetPc(void) __attribute__ ((noinline));\r
282 \r
283 static uint32 fls_GetPc(void) {\r
284         return get_spr(SPR_LR);\r
285 }\r
286 #endif\r
287 \r
288 static void fls_EraseFail( void ) {\r
289         Fls_Global.jobResultType = MEMIF_JOB_FAILED;\r
290         Fls_Global.jobType = FLS_JOB_NONE;\r
291         Fls_Global.status = MEMIF_IDLE;\r
292 #if defined(USE_DEM)\r
293         Dem_ReportErrorStatus(FLS_E_ERASE_FAILED, DEM_EVENT_STATUS_FAILED);\r
294 #endif\r
295         FEE_JOB_ERROR_NOTIFICATION();\r
296 }\r
297 \r
298 static void fls_WriteFail( void ) {\r
299         Fls_Global.jobResultType = MEMIF_JOB_FAILED;\r
300         Fls_Global.jobType = FLS_JOB_NONE;\r
301         Fls_Global.status = MEMIF_IDLE;\r
302 #if defined(USE_DEM)\r
303         Dem_ReportErrorStatus(FLS_E_WRITE_FAILED, DEM_EVENT_STATUS_FAILED);\r
304 #endif\r
305         FEE_JOB_ERROR_NOTIFICATION();\r
306 \r
307 }\r
308 \r
309 /* ----------------------------[public functions]----------------------------*/\r
310 \r
311 /**\r
312  *\r
313  * @param ConfigPtr\r
314  */\r
315 \r
316 void Fls_Init(const Fls_ConfigType *ConfigPtr) {\r
317         /** @req FLS249 3.0 */\r
318         /** @req FLS191 3.0 */\r
319         /** @req FLS014 3.0 */\r
320         /** @req FLS086 3.0 */\r
321         /** @req FLS015 3.0 */\r
322         /** !req FLS048 TODO, true?    */\r
323         /** !req FLS271 NO_SUPPORT 3.0 */\r
324         /** !req FLS325 NO_SUPPORT 4.0 */\r
325         /** !req FLS326 NO_SUPPORT 4.0 */\r
326 \r
327         /** @req FLS268 */\r
328         VALIDATE_NO_RV(Fls_Global.status!=MEMIF_BUSY,FLS_INIT_ID, FLS_E_BUSY );\r
329 \r
330         Fls_Global.status = MEMIF_UNINIT;\r
331         Fls_Global.jobResultType = MEMIF_JOB_PENDING;\r
332         // TODO: FLS_E_PARAM_CONFIG\r
333 \r
334         /** @req FLS191 */\r
335         Fls_Global.config = ConfigPtr;\r
336 \r
337         Flash_Init();\r
338 \r
339         /** @req FLS016 3.0 *//** @req FLS323 4.0 *//** @req FLS324 4.0*/\r
340         Fls_Global.status = MEMIF_IDLE;\r
341         Fls_Global.jobResultType = MEMIF_JOB_OK;\r
342         return;\r
343 }\r
344 \r
345 /**\r
346  * Erase flash sectors\r
347  *\r
348  * @param TargetAddress Always from 0 to FLS_TOTAL_SIZE\r
349  * @param Length\r
350  * @return\r
351  */\r
352 Std_ReturnType Fls_Erase(Fls_AddressType TargetAddress, Fls_LengthType Length) {\r
353         TargetAddress += FLS_BASE_ADDRESS;\r
354 \r
355         /** @req FLS250 3.0/4.0 */\r
356         /** @req FLS218 3.0/4.0 */\r
357         /** @req FLS220 3.0/4.0 */\r
358         /** @req FLS327 4.0     */\r
359 \r
360         /** @req FLS065 */\r
361         VALIDATE_W_RV( Fls_Global.status != MEMIF_UNINIT, FLS_ERASE_ID, FLS_E_UNINIT, E_NOT_OK );\r
362         /** @req FLS023 */\r
363         VALIDATE_W_RV( Fls_Global.status != MEMIF_BUSY, FLS_ERASE_ID, FLS_E_BUSY, E_NOT_OK );\r
364     /** @req FLS020 3.0/4.0 */\r
365         VALIDATE_W_RV( E_OK == fls_SectorAligned( TargetAddress ),\r
366                 FLS_ERASE_ID, FLS_E_PARAM_ADDRESS, E_NOT_OK );\r
367     /** @req FLS021 3.0/4.0 */\r
368     VALIDATE_W_RV( (Length != 0) && (EE_OK == fls_SectorAligned( TargetAddress + Length)),\r
369             FLS_ERASE_ID, FLS_E_PARAM_LENGTH, E_NOT_OK );\r
370 \r
371         // Check if we trying to erase a partition that we are executing in\r
372 #if 0\r
373         pc = fls_GetPc();\r
374 #endif\r
375 \r
376 \r
377         Fls_Global.status = MEMIF_BUSY;                             /** @req FLS219 3.0 */ /** @req FLS328 4.0 */\r
378         Fls_Global.jobResultType = MEMIF_JOB_PENDING;   /** @req FLS329 4.0 */\r
379         Fls_Global.jobType = FLS_JOB_ERASE;\r
380         Fls_Global.flashAddr = TargetAddress;\r
381         Fls_Global.length = Length;\r
382 \r
383         /* Unlock */\r
384         Flash_Lock(Fls_Global.config->FlsInfo,FLASH_OP_UNLOCK,TargetAddress, Length );\r
385 \r
386         /** @req FLS145 */\r
387         Flash_Erase(Fls_Global.config->FlsInfo,TargetAddress, Length, NULL );\r
388 \r
389         return E_OK;    /** @req FLS330 4.0 */\r
390 }\r
391 \r
392 \r
393 /**\r
394  * Programs flash sectors\r
395  *\r
396  * @param TargetAddress\r
397  * @param SourceAddressPtr\r
398  * @param Length\r
399  * @return\r
400  */\r
401 \r
402 Std_ReturnType Fls_Write(Fls_AddressType TargetAddress,\r
403                 const uint8 *SourceAddressPtr, Fls_LengthType Length) {\r
404         TargetAddress += FLS_BASE_ADDRESS;\r
405 \r
406         /** @req FLS251 3.0 */\r
407         /** @req FLS223 3.0 */\r
408         /** @req FLS225 3.0/4.0 */\r
409         /** @req FLS226 3.0/4.0 */\r
410 \r
411         /** @req FLS066 3.0/4.0 */\r
412         /** @req FLS030 3.0/4.0 */\r
413         /** @req FLS157 3.0/4.0 */\r
414         /** @req FLS026 3.0/4.0 */\r
415         /** @req FLS027 3.0/4.0 */\r
416         VALIDATE_W_RV(Fls_Global.status != MEMIF_UNINIT,FLS_WRITE_ID, FLS_E_UNINIT,E_NOT_OK );\r
417         VALIDATE_W_RV(Fls_Global.status != MEMIF_BUSY,FLS_WRITE_ID, FLS_E_BUSY,E_NOT_OK );\r
418         VALIDATE_W_RV(SourceAddressPtr != ((void *)0),FLS_WRITE_ID, FLS_E_PARAM_DATA,E_NOT_OK );\r
419         VALIDATE_W_RV( (TargetAddress % FLASH_PAGE_SIZE == 0) && (E_OK == fls_CheckValidAddress(TargetAddress)),\r
420                         FLS_WRITE_ID, FLS_E_PARAM_ADDRESS, E_NOT_OK );\r
421         VALIDATE_W_RV( (Length != 0) && (((TargetAddress + Length) % FLASH_PAGE_SIZE) == 0 && (E_OK == fls_CheckValidAddress(TargetAddress + Length))),\r
422                         FLS_WRITE_ID, FLS_E_PARAM_LENGTH, E_NOT_OK );\r
423 \r
424         // Destination is FLS_BASE_ADDRESS + TargetAddress\r
425         /** @req FLS224 3.0 */ /** @req FLS333 4.0 */\r
426         Fls_Global.jobResultType = MEMIF_JOB_PENDING;\r
427         /** @req FLS332 4.0 */\r
428         Fls_Global.status = MEMIF_BUSY;\r
429         Fls_Global.jobType = FLS_JOB_WRITE;\r
430 \r
431         // Fill in the required fields for programming...\r
432         /** @req FLS331 4.0 */\r
433         Fls_Global.flashWriteInfo.source = (uint32) SourceAddressPtr;\r
434         Fls_Global.flashWriteInfo.dest = TargetAddress;\r
435         Fls_Global.flashWriteInfo.left = Length;\r
436 \r
437 \r
438         // unlock flash for the entire range.\r
439         Flash_Lock(Fls_Global.config->FlsInfo,FLASH_OP_UNLOCK, TargetAddress, Length );\r
440 \r
441     /* Save to original request */\r
442     Fls_Global.flashWriteInfo.pDest = TargetAddress;\r
443     Fls_Global.flashWriteInfo.pLeft = Length;\r
444 \r
445     /** @req FLS146 3.0/4.0 */\r
446     Flash_ProgramPageStart(     Fls_Global.config->FlsInfo,\r
447                                                         &Fls_Global.flashWriteInfo.dest,\r
448                                                         &Fls_Global.flashWriteInfo.source,\r
449                                                         &Fls_Global.flashWriteInfo.left,\r
450                                                         NULL);\r
451 \r
452         return E_OK; /** @req FLS334 4.0 */\r
453 }\r
454 \r
455 #if ( FLS_CANCEL_API == STD_ON )\r
456 void Fls_Cancel( void )\r
457 {\r
458         /* API NOT SUPPORTED */\r
459 }\r
460 #endif\r
461 \r
462 #if ( FLS_GET_STATUS_API == STD_ON )\r
463 MemIf_StatusType Fls_GetStatus( void )\r
464 {\r
465         return Fls_Global.status;\r
466 }\r
467 #endif\r
468 \r
469 #if ( FLS_GET_JOB_RESULT_API == STD_ON )\r
470 MemIf_JobResultType Fls_GetJobResult( void )\r
471 {\r
472         return Fls_Global.jobResultType;\r
473 }\r
474 #endif\r
475 \r
476 void Fls_MainFunction(void) {\r
477         /** @req FLS255 */\r
478         /** @req FLS266 */\r
479         /** @req FLS038 */\r
480         /** !req FLS040  No support for Fls_ConfigSetType.FlsMaxXXXX */\r
481         /** !req FLS104 */\r
482         /** !req FLS105 */\r
483         /** !req FLS106 */\r
484         /** !req FLS154 */\r
485         /** !req FLS200 */\r
486         /** !req FLS022 */\r
487         /** !req FLS055 */\r
488         /** !req FLS056 */\r
489         /** !req FLS052 */\r
490         /** !req FLS232 */\r
491         /** !req FLS233 */\r
492         /** !req FLS234 */\r
493         /** !req FLS235 */\r
494         /** !req FLS272 */\r
495         /** !req FLS196 */\r
496 \r
497 \r
498 \r
499         uint32 flashStatus;\r
500         int result;\r
501 \r
502         /** @req FLS117 */\r
503         VALIDATE_NO_RV(Fls_Global.status != MEMIF_UNINIT,FLS_MAIN_FUNCTION_ID, FLS_E_UNINIT );\r
504 \r
505         /** @req FLS039 */\r
506         if ( Fls_Global.jobResultType == MEMIF_JOB_PENDING) {\r
507                 switch (Fls_Global.jobType) {\r
508                 case FLS_JOB_COMPARE:\r
509                     /** @req FLS243 */\r
510 \r
511                         // NOT implemented. Hardware error = FLS_E_COMPARE_FAILED\r
512                         // ( we are reading directly from flash so it makes no sense )\r
513 \r
514                     /** @req FLS244 */\r
515                         result = memcmp((void *)Fls_Global.ramAddr,\r
516                                                 (void *)Fls_Global.flashAddr, Fls_Global.length);\r
517                         if (result == 0) {\r
518                                 Fls_Global.jobResultType = MEMIF_JOB_OK;\r
519                         } else {\r
520                                 Fls_Global.jobResultType = MEMIF_BLOCK_INCONSISTENT;\r
521                         }\r
522                         Fls_Global.status = MEMIF_IDLE;\r
523                         Fls_Global.jobType = FLS_JOB_NONE;\r
524 \r
525                         break;\r
526                 case FLS_JOB_ERASE: {\r
527 \r
528                         flashStatus = Flash_CheckStatus(Fls_Global.config->FlsInfo, (uint32_t *)Fls_Global.flashAddr, Fls_Global.length );\r
529 \r
530                         if (flashStatus == EE_OK ) {\r
531                                 Fls_Global.jobResultType = MEMIF_JOB_OK;\r
532                                 Fls_Global.jobType = FLS_JOB_NONE;\r
533                                 Fls_Global.status = MEMIF_IDLE;\r
534                                 FEE_JOB_END_NOTIFICATION();\r
535                         } else if (flashStatus == EE_INFO_HVOP_INPROGRESS) {\r
536                                 /* Busy, Do nothing */\r
537                         } else {\r
538                                 // Error\r
539                                 fls_EraseFail();\r
540                         }\r
541             break;\r
542                 }\r
543                 case FLS_JOB_READ:\r
544                         /** @req FLS238 */\r
545                         /** @req FLS239 */\r
546 \r
547                         // NOT implemented. Hardware error = FLS_E_READ_FAILED\r
548                         // ( we are reading directly from flash so it makes no sense )\r
549                         memcpy( (void *)Fls_Global.ramAddr, (void *) Fls_Global.flashAddr,\r
550                                         Fls_Global.length);\r
551 \r
552                         Fls_Global.jobResultType = MEMIF_JOB_OK;\r
553                         Fls_Global.status = MEMIF_IDLE;\r
554                         Fls_Global.jobType = FLS_JOB_NONE;\r
555                         FEE_JOB_END_NOTIFICATION();\r
556                         break;\r
557 \r
558                 case FLS_JOB_WRITE:\r
559                 {\r
560 \r
561                     do {\r
562                                 flashStatus = Flash_CheckStatus(Fls_Global.config->FlsInfo,\r
563                                                                 (uint32_t *)Fls_Global.flashWriteInfo.pDest,\r
564                                                                 Fls_Global.flashWriteInfo.left -Fls_Global.flashWriteInfo.pLeft);\r
565 \r
566                                 if (flashStatus == EE_OK ) {\r
567 \r
568                                         if( Fls_Global.flashWriteInfo.left == 0 ) {\r
569                                                 Fls_Global.mustCheck = 0;\r
570                                                 /* Done! */\r
571                         Fls_Global.jobResultType = MEMIF_JOB_OK;\r
572                         Fls_Global.status = MEMIF_IDLE;\r
573                         Fls_Global.jobType = FLS_JOB_NONE;\r
574                         FEE_JOB_END_NOTIFICATION();\r
575                                                 break;\r
576                                         }\r
577                                     Fls_Global.flashWriteInfo.pDest = Fls_Global.flashWriteInfo.dest;\r
578                                     Fls_Global.flashWriteInfo.pLeft = Fls_Global.flashWriteInfo.left;\r
579 \r
580                                         flashStatus = Flash_ProgramPageStart(Fls_Global.config->FlsInfo,\r
581                                                                                         &Fls_Global.flashWriteInfo.dest,\r
582                                                                                         &Fls_Global.flashWriteInfo.source,\r
583                                                                                         &Fls_Global.flashWriteInfo.left,\r
584                                                                                         NULL);\r
585                                         Fls_Global.mustCheck = 1;\r
586                                         if( flashStatus != EE_OK ) {\r
587                                                 Fls_Global.mustCheck = 0;\r
588                                                 fls_WriteFail();\r
589                                                 break;\r
590                                         }\r
591                                 } else if( flashStatus == EE_INFO_HVOP_INPROGRESS ) {\r
592                                         /* Wait for it */\r
593                                 } else {\r
594                                         fls_WriteFail();\r
595                                         /* Nothing to do, quit loop */\r
596                                         break;\r
597                                 }\r
598                         } while(Fls_Global.flashWriteInfo.left && Fls_Global.mustCheck );\r
599 \r
600                         break;\r
601                 }\r
602                 case FLS_JOB_NONE:\r
603                         assert(0);\r
604                         break;\r
605 \r
606                 default:\r
607                     break;\r
608                 } /* switch */\r
609 \r
610         }   /* if */\r
611 }\r
612 \r
613 \r
614 /**\r
615  * Read from flash memory\r
616  *\r
617  * @param SourceAddress\r
618  * @param TargetAddressPtr\r
619  * @param Length\r
620  * @return\r
621  */\r
622 Std_ReturnType Fls_Read(        Fls_AddressType SourceAddress,\r
623                                                         uint8 *TargetAddressPtr,\r
624                                                         Fls_LengthType Length)\r
625 {\r
626         SourceAddress += FLS_BASE_ADDRESS;\r
627         /** @req FLS256 */\r
628         /** @req FLS236 */\r
629         /** !req FLS239 TODO */\r
630         /** !req FLS240 Have no idea what the requirement means*/\r
631 \r
632         /** @req FLS099 */\r
633         VALIDATE_W_RV(Fls_Global.status != MEMIF_UNINIT,FLS_READ_ID, FLS_E_UNINIT,E_NOT_OK );\r
634         /** @req FLS100 */\r
635         VALIDATE_W_RV( Fls_Global.status != MEMIF_BUSY, FLS_READ_ID, FLS_E_BUSY, E_NOT_OK );\r
636         /** @req FLS158 */\r
637         VALIDATE_W_RV( TargetAddressPtr != NULL , FLS_READ_ID, FLS_E_PARAM_DATA, E_NOT_OK );\r
638         /** @req FLS097  */\r
639         VALIDATE_W_RV( E_OK == fls_CheckValidAddress(SourceAddress), FLS_READ_ID, FLS_E_PARAM_ADDRESS, E_NOT_OK );\r
640         /** @req FLS098  */\r
641         VALIDATE_W_RV( (Length != 0) && (E_OK == fls_CheckValidAddress(SourceAddress + Length)), FLS_READ_ID, FLS_E_PARAM_LENGTH, E_NOT_OK );\r
642 \r
643         // Always check if status is not busy\r
644         if (Fls_Global.status == MEMIF_BUSY)\r
645                 return E_NOT_OK;\r
646 \r
647         Fls_Global.status = MEMIF_BUSY;\r
648         Fls_Global.jobResultType = MEMIF_JOB_PENDING;\r
649         Fls_Global.jobType = FLS_JOB_READ;\r
650 \r
651         /** @req FLS237 */\r
652         Fls_Global.flashAddr = SourceAddress;\r
653         Fls_Global.ramAddr = TargetAddressPtr;\r
654         Fls_Global.length = Length;\r
655 \r
656         return E_OK;\r
657 }\r
658 \r
659 #if ( FLS_COMPARE_API == STD_ON )\r
660 Std_ReturnType Fls_Compare( Fls_AddressType SourceAddress,\r
661                                                         uint8 *TargetAddressPtr,\r
662                                                         Fls_LengthType Length )\r
663 {\r
664         SourceAddress += FLS_BASE_ADDRESS;\r
665     /** @req FLS257 */\r
666     /** @req FLS241 */\r
667     /** @req FLS186 */\r
668 \r
669     /** @req FLS152 */\r
670     VALIDATE_W_RV(Fls_Global.status != MEMIF_UNINIT,FLS_COMPARE_ID, FLS_E_UNINIT,E_NOT_OK );\r
671     /** @req FLS153 */\r
672     VALIDATE_W_RV( Fls_Global.status != MEMIF_BUSY, FLS_COMPARE_ID, FLS_E_BUSY, E_NOT_OK );\r
673     /** @req FLS273 */\r
674     VALIDATE_W_RV( TargetAddressPtr != NULL , FLS_COMPARE_ID, FLS_E_PARAM_DATA, E_NOT_OK );\r
675         /** @req FLS150  */\r
676         VALIDATE_W_RV( E_OK == fls_CheckValidAddress(SourceAddress), FLS_COMPARE_ID, FLS_E_PARAM_ADDRESS, E_NOT_OK );\r
677         /** @req FLS151  */\r
678         VALIDATE_W_RV( (Length != 0) && (E_OK == fls_CheckValidAddress(SourceAddress + Length)),\r
679                         FLS_COMPARE_ID, FLS_E_PARAM_LENGTH, E_NOT_OK );\r
680 \r
681 \r
682         // Always check if status is not busy\r
683         if (Fls_Global.status == MEMIF_BUSY )\r
684             return E_NOT_OK;\r
685 \r
686         Fls_Global.status = MEMIF_BUSY;\r
687         Fls_Global.jobResultType = MEMIF_JOB_PENDING;\r
688         Fls_Global.jobType = FLS_JOB_COMPARE;\r
689         /* @req FLS242 */\r
690         Fls_Global.flashAddr = SourceAddress;\r
691         Fls_Global.ramAddr = TargetAddressPtr;\r
692         Fls_Global.length = Length;\r
693 \r
694         return E_OK;\r
695 }\r
696 #endif\r
697 \r
698 #if ( FLS_SET_MODE_API == STD_ON )\r
699 void Fls_SetMode( MemIf_ModeType Mode )\r
700 {\r
701     /** !req FLS258 */\r
702     /** !req FLS155 */\r
703     /** !req FLS187 */\r
704 \r
705     /* API NOT SUPPORTED */\r
706 }\r
707 #endif\r
708 \r
709 #if ( FLS_VERSION_INFO_API == STD_ON )\r
710 void Fls_GetVersionInfo( Std_VersionInfoType *VersioninfoPtr )\r
711 {\r
712     /** @req FLS259 */\r
713     /** @req FLS165 */\r
714     /** @req FLS166 */\r
715     /** !req FLS166 Change if moved to macro */\r
716 \r
717         memcpy(VersioninfoPtr, &_Fls_VersionInfo, sizeof(Std_VersionInfoType));\r
718 }\r
719 #endif\r
720 \r
721 #if 0\r
722 void Fls_Check(uint32 flsBaseAddress, uint32 flsTotalSize) {\r
723         // ECC checking is always on by default.\r
724         // If a non correctable error is discovered\r
725         // we will get an IVOR2 exception.\r
726 \r
727         // Enable Flash Non_Correctible Reporting,\r
728         // Not really necessary but makes more information\r
729         // available in the MCM registers if an error occurs.\r
730 #if defined(CFG_MPC560X) || defined(CFG_MPC5567)\r
731         ECSM.ECR.B.EFNCR = 1;\r
732 #elif defined (CFG_MPC5516)\r
733         MCM.ECR.B.EFNCR = 1;\r
734 #else\r
735 #warning "Non supported processor"\r
736 #endif\r
737 \r
738         // Read flash in 32bit chunks, it's most efficient.\r
739         uint32* memoryChunkPtr = (uint32*) flsBaseAddress;\r
740         uint32* flsTotalSizePtr = (uint32*) flsTotalSize;\r
741         uint32 memoryChunk = *memoryChunkPtr; // The first read\r
742 \r
743         // Read the rest of the flash, chunk by chunk\r
744         while (memoryChunkPtr < flsTotalSizePtr) {\r
745                 memoryChunk = *(memoryChunkPtr++);\r
746         }\r
747 }\r
748 #endif\r
749 \r