1 /* -------------------------------- Arctic Core ------------------------------
\r
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\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
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
14 * -------------------------------- Arctic Core ------------------------------*/
\r
16 /* ----------------------------[information]----------------------------------*/
\r
24 * Implements the Fls module (flash driver)
\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
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
42 * - MPC5668 , No support for shadow flash
\r
43 * - MPC5606S , Support for dataflash only
\r
45 * Implementation Notes:
\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
53 * Can't really tell if FlsMaxWriteFastMode, FlsMaxWriteNormalMode, etc is only
\r
54 * for SPI flashes or not. Is it?
\r
57 * - Virtual addresses, FLS209 is not done (code assumes FLS_BASE_ADDRESS is 0)
\r
61 /* ----------------------------[requirements]--------------------------------*/
\r
63 /* FlsGeneral, Complete for 3.0 */
\r
65 // TODO: #warning ENABLE THESE AGAIN
\r
79 /* FlsConfigSet, Complete for 3.0 */
\r
90 /** !req FLS279 N/A in core */
\r
92 /* FlsPublishedInformation, Complete for 3.0 */
\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
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
121 #if defined(USE_DEM)
\r
125 #include "mpc55xx.h"
\r
127 #if (FLS_BASE_ADDRESS != 0)
\r
128 #error Virtual addresses not supported
\r
131 /* ----------------------------[private define]------------------------------*/
\r
132 /* ----------------------------[private macro]-------------------------------*/
\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
138 #define FEE_JOB_END_NOTIFICATION() \
\r
139 if( Fls_Global.config->FlsJobEndNotification != NULL ) { \
\r
140 Fls_Global.config->FlsJobEndNotification(); \
\r
143 #define FEE_JOB_ERROR_NOTIFICATION() \
\r
144 if( Fls_Global.config->FlsJobErrorNotification != NULL ) { \
\r
145 Fls_Global.config->FlsJobErrorNotification(); \
\r
148 #define VALIDATE(_exp,_api,_err ) \
\r
150 Det_ReportError(MODULE_ID_FLS,0,_api,_err); \
\r
154 #define VALIDATE_NO_RV(_exp,_api,_err ) \
\r
156 Det_ReportError(MODULE_ID_FLS,0,_api,_err); \
\r
160 #define VALIDATE_W_RV(_exp,_api,_err,_rv ) \
\r
162 Det_ReportError(MODULE_ID_FLS,0,_api,_err); \
\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
177 /* ----------------------------[private typedef]-----------------------------*/
\r
180 FLS_JOB_NONE, FLS_JOB_COMPARE, FLS_JOB_ERASE, FLS_JOB_READ, FLS_JOB_WRITE,
\r
191 } Fls_ProgInfoType;
\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
206 Fls_GlobalType Fls_Global = {
\r
207 .status = MEMIF_UNINIT,
\r
208 .jobResultType = MEMIF_JOB_OK,
\r
209 .jobType = FLS_JOB_NONE,
\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
229 /* ----------------------------[private functions]---------------------------*/
\r
231 static Std_ReturnType fls_SectorAligned( Fls_AddressType SourceAddress ) {
\r
232 Std_ReturnType rv = E_NOT_OK;
\r
233 const FlashType *bPtr;
\r
235 for (int bank = 0; bank < FLASH_BANK_CNT; bank++) {
\r
236 bPtr = &Fls_Global.config->FlsInfo[bank];
\r
238 /* In range of bank */
\r
239 if( (SourceAddress >= bPtr->sectAddr[0]) &&
\r
240 (SourceAddress <= (bPtr->sectAddr[bPtr->sectCnt])) )
\r
242 for (int sector = 0; sector < bPtr->sectCnt + 1; sector++)
\r
244 if( SourceAddress == bPtr->sectAddr[sector] ) {
\r
255 static Std_ReturnType fls_CheckValidAddress( Fls_AddressType SourceAddress ) {
\r
256 Std_ReturnType rv = E_NOT_OK;
\r
257 const FlashType *bPtr;
\r
259 for (int bank = 0; bank < FLASH_BANK_CNT; bank++) {
\r
260 bPtr = &Fls_Global.config->FlsInfo[bank];
\r
262 for (int sector = 0; sector < bPtr->sectCnt; sector++)
\r
264 if( (SourceAddress >= bPtr->sectAddr[sector]) &&
\r
265 (SourceAddress < bPtr->sectAddr[sector+1]) )
\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
281 static uint32 fls_GetPc(void) __attribute__ ((noinline));
\r
283 static uint32 fls_GetPc(void) {
\r
284 return get_spr(SPR_LR);
\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
295 FEE_JOB_ERROR_NOTIFICATION();
\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
305 FEE_JOB_ERROR_NOTIFICATION();
\r
309 /* ----------------------------[public functions]----------------------------*/
\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
328 VALIDATE_NO_RV(Fls_Global.status!=MEMIF_BUSY,FLS_INIT_ID, FLS_E_BUSY );
\r
330 Fls_Global.status = MEMIF_UNINIT;
\r
331 Fls_Global.jobResultType = MEMIF_JOB_PENDING;
\r
332 // TODO: FLS_E_PARAM_CONFIG
\r
335 Fls_Global.config = ConfigPtr;
\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
346 * Erase flash sectors
\r
348 * @param TargetAddress Always from 0 to FLS_TOTAL_SIZE
\r
352 Std_ReturnType Fls_Erase(Fls_AddressType TargetAddress, Fls_LengthType Length) {
\r
353 TargetAddress += FLS_BASE_ADDRESS;
\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
361 VALIDATE_W_RV( Fls_Global.status != MEMIF_UNINIT, FLS_ERASE_ID, FLS_E_UNINIT, E_NOT_OK );
\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
371 // Check if we trying to erase a partition that we are executing in
\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
384 Flash_Lock(Fls_Global.config->FlsInfo,FLASH_OP_UNLOCK,TargetAddress, Length );
\r
387 Flash_Erase(Fls_Global.config->FlsInfo,TargetAddress, Length, NULL );
\r
389 return E_OK; /** @req FLS330 4.0 */
\r
394 * Programs flash sectors
\r
396 * @param TargetAddress
\r
397 * @param SourceAddressPtr
\r
402 Std_ReturnType Fls_Write(Fls_AddressType TargetAddress,
\r
403 const uint8 *SourceAddressPtr, Fls_LengthType Length) {
\r
404 TargetAddress += FLS_BASE_ADDRESS;
\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
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
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
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
438 // unlock flash for the entire range.
\r
439 Flash_Lock(Fls_Global.config->FlsInfo,FLASH_OP_UNLOCK, TargetAddress, Length );
\r
441 /* Save to original request */
\r
442 Fls_Global.flashWriteInfo.pDest = TargetAddress;
\r
443 Fls_Global.flashWriteInfo.pLeft = Length;
\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
452 return E_OK; /** @req FLS334 4.0 */
\r
455 #if ( FLS_CANCEL_API == STD_ON )
\r
456 void Fls_Cancel( void )
\r
458 /* API NOT SUPPORTED */
\r
462 #if ( FLS_GET_STATUS_API == STD_ON )
\r
463 MemIf_StatusType Fls_GetStatus( void )
\r
465 return Fls_Global.status;
\r
469 #if ( FLS_GET_JOB_RESULT_API == STD_ON )
\r
470 MemIf_JobResultType Fls_GetJobResult( void )
\r
472 return Fls_Global.jobResultType;
\r
476 void Fls_MainFunction(void) {
\r
480 /** !req FLS040 No support for Fls_ConfigSetType.FlsMaxXXXX */
\r
499 uint32 flashStatus;
\r
503 VALIDATE_NO_RV(Fls_Global.status != MEMIF_UNINIT,FLS_MAIN_FUNCTION_ID, FLS_E_UNINIT );
\r
506 if ( Fls_Global.jobResultType == MEMIF_JOB_PENDING) {
\r
507 switch (Fls_Global.jobType) {
\r
508 case FLS_JOB_COMPARE:
\r
511 // NOT implemented. Hardware error = FLS_E_COMPARE_FAILED
\r
512 // ( we are reading directly from flash so it makes no sense )
\r
515 result = memcmp((void *)Fls_Global.ramAddr,
\r
516 (void *)Fls_Global.flashAddr, Fls_Global.length);
\r
518 Fls_Global.jobResultType = MEMIF_JOB_OK;
\r
520 Fls_Global.jobResultType = MEMIF_BLOCK_INCONSISTENT;
\r
522 Fls_Global.status = MEMIF_IDLE;
\r
523 Fls_Global.jobType = FLS_JOB_NONE;
\r
526 case FLS_JOB_ERASE: {
\r
528 flashStatus = Flash_CheckStatus(Fls_Global.config->FlsInfo, (uint32_t *)Fls_Global.flashAddr, Fls_Global.length );
\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
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 if( Os_EccError ) {
\r
555 Fls_Global.jobResultType = MEMIF_JOB_OK;
\r
556 Fls_Global.status = MEMIF_IDLE;
\r
557 Fls_Global.jobType = FLS_JOB_NONE;
\r
558 FEE_JOB_END_NOTIFICATION();
\r
561 case FLS_JOB_WRITE:
\r
565 flashStatus = Flash_CheckStatus(Fls_Global.config->FlsInfo,
\r
566 (uint32_t *)Fls_Global.flashWriteInfo.pDest,
\r
567 Fls_Global.flashWriteInfo.left -Fls_Global.flashWriteInfo.pLeft);
\r
569 if (flashStatus == EE_OK ) {
\r
571 if( Fls_Global.flashWriteInfo.left == 0 ) {
\r
572 Fls_Global.mustCheck = 0;
\r
574 Fls_Global.jobResultType = MEMIF_JOB_OK;
\r
575 Fls_Global.status = MEMIF_IDLE;
\r
576 Fls_Global.jobType = FLS_JOB_NONE;
\r
577 FEE_JOB_END_NOTIFICATION();
\r
580 Fls_Global.flashWriteInfo.pDest = Fls_Global.flashWriteInfo.dest;
\r
581 Fls_Global.flashWriteInfo.pLeft = Fls_Global.flashWriteInfo.left;
\r
583 flashStatus = Flash_ProgramPageStart(Fls_Global.config->FlsInfo,
\r
584 &Fls_Global.flashWriteInfo.dest,
\r
585 &Fls_Global.flashWriteInfo.source,
\r
586 &Fls_Global.flashWriteInfo.left,
\r
588 Fls_Global.mustCheck = 1;
\r
589 if( flashStatus != EE_OK ) {
\r
590 Fls_Global.mustCheck = 0;
\r
594 } else if( flashStatus == EE_INFO_HVOP_INPROGRESS ) {
\r
598 /* Nothing to do, quit loop */
\r
601 } while(Fls_Global.flashWriteInfo.left && Fls_Global.mustCheck );
\r
618 * Read from flash memory
\r
620 * @param SourceAddress
\r
621 * @param TargetAddressPtr
\r
625 Std_ReturnType Fls_Read( Fls_AddressType SourceAddress,
\r
626 uint8 *TargetAddressPtr,
\r
627 Fls_LengthType Length)
\r
629 SourceAddress += FLS_BASE_ADDRESS;
\r
632 /** !req FLS239 TODO */
\r
633 /** !req FLS240 Have no idea what the requirement means*/
\r
636 VALIDATE_W_RV(Fls_Global.status != MEMIF_UNINIT,FLS_READ_ID, FLS_E_UNINIT,E_NOT_OK );
\r
638 VALIDATE_W_RV( Fls_Global.status != MEMIF_BUSY, FLS_READ_ID, FLS_E_BUSY, E_NOT_OK );
\r
640 VALIDATE_W_RV( TargetAddressPtr != NULL , FLS_READ_ID, FLS_E_PARAM_DATA, E_NOT_OK );
\r
642 VALIDATE_W_RV( E_OK == fls_CheckValidAddress(SourceAddress), FLS_READ_ID, FLS_E_PARAM_ADDRESS, E_NOT_OK );
\r
644 VALIDATE_W_RV( (Length != 0) && (E_OK == fls_CheckValidAddress(SourceAddress + Length)), FLS_READ_ID, FLS_E_PARAM_LENGTH, E_NOT_OK );
\r
646 // Always check if status is not busy
\r
647 if (Fls_Global.status == MEMIF_BUSY)
\r
650 Fls_Global.status = MEMIF_BUSY;
\r
651 Fls_Global.jobResultType = MEMIF_JOB_PENDING;
\r
652 Fls_Global.jobType = FLS_JOB_READ;
\r
655 Fls_Global.flashAddr = SourceAddress;
\r
656 Fls_Global.ramAddr = TargetAddressPtr;
\r
657 Fls_Global.length = Length;
\r
662 #if ( FLS_COMPARE_API == STD_ON )
\r
663 Std_ReturnType Fls_Compare( Fls_AddressType SourceAddress,
\r
664 uint8 *TargetAddressPtr,
\r
665 Fls_LengthType Length )
\r
667 SourceAddress += FLS_BASE_ADDRESS;
\r
673 VALIDATE_W_RV(Fls_Global.status != MEMIF_UNINIT,FLS_COMPARE_ID, FLS_E_UNINIT,E_NOT_OK );
\r
675 VALIDATE_W_RV( Fls_Global.status != MEMIF_BUSY, FLS_COMPARE_ID, FLS_E_BUSY, E_NOT_OK );
\r
677 VALIDATE_W_RV( TargetAddressPtr != NULL , FLS_COMPARE_ID, FLS_E_PARAM_DATA, E_NOT_OK );
\r
679 VALIDATE_W_RV( E_OK == fls_CheckValidAddress(SourceAddress), FLS_COMPARE_ID, FLS_E_PARAM_ADDRESS, E_NOT_OK );
\r
681 VALIDATE_W_RV( (Length != 0) && (E_OK == fls_CheckValidAddress(SourceAddress + Length)),
\r
682 FLS_COMPARE_ID, FLS_E_PARAM_LENGTH, E_NOT_OK );
\r
685 // Always check if status is not busy
\r
686 if (Fls_Global.status == MEMIF_BUSY )
\r
689 Fls_Global.status = MEMIF_BUSY;
\r
690 Fls_Global.jobResultType = MEMIF_JOB_PENDING;
\r
691 Fls_Global.jobType = FLS_JOB_COMPARE;
\r
693 Fls_Global.flashAddr = SourceAddress;
\r
694 Fls_Global.ramAddr = TargetAddressPtr;
\r
695 Fls_Global.length = Length;
\r
701 #if ( FLS_SET_MODE_API == STD_ON )
\r
702 void Fls_SetMode( MemIf_ModeType Mode )
\r
708 /* API NOT SUPPORTED */
\r
712 #if ( FLS_VERSION_INFO_API == STD_ON )
\r
713 void Fls_GetVersionInfo( Std_VersionInfoType *VersioninfoPtr )
\r
718 /** !req FLS166 Change if moved to macro */
\r
720 memcpy(VersioninfoPtr, &_Fls_VersionInfo, sizeof(Std_VersionInfoType));
\r
725 void Fls_Check(uint32 flsBaseAddress, uint32 flsTotalSize) {
\r
726 // ECC checking is always on by default.
\r
727 // If a non correctable error is discovered
\r
728 // we will get an IVOR2 exception.
\r
730 // Enable Flash Non_Correctible Reporting,
\r
731 // Not really necessary but makes more information
\r
732 // available in the MCM registers if an error occurs.
\r
733 #if defined(CFG_MPC560X) || defined(CFG_MPC5567)
\r
734 ECSM.ECR.B.EFNCR = 1;
\r
735 #elif defined (CFG_MPC5516)
\r
736 MCM.ECR.B.EFNCR = 1;
\r
738 #warning "Non supported processor"
\r
741 // Read flash in 32bit chunks, it's most efficient.
\r
742 uint32* memoryChunkPtr = (uint32*) flsBaseAddress;
\r
743 uint32* flsTotalSizePtr = (uint32*) flsTotalSize;
\r
744 uint32 memoryChunk = *memoryChunkPtr; // The first read
\r
746 // Read the rest of the flash, chunk by chunk
\r
747 while (memoryChunkPtr < flsTotalSizePtr) {
\r
748 memoryChunk = *(memoryChunkPtr++);
\r