| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840 |
- #define EXTMEM_FLASH_C
- #include "core/config.h"
- #include "drivers/flash/base/extmem_flash.h"
- #include "core/gpio.h"
- #include "core/main.h"
- #include "core/config_pins.h"
- #define pSPIHandle (&SPIHandle)
- #if AT45DBXXX_POWER_MANAGEMENT || W25QXXX_POWER_MANAGEMENT
- static void ExtMem_SetPinPowerOn();
- static void ExtMem_SetPinPowerOff();
- #endif
- #if AT45DBXXX_RESET_MANAGEMENT || W25QXXX_RESET_MANAGEMENT
- static void ExtMem_ResetPinAssert();
- static void ExtMem_ResetPinRelease();
- #endif
- #if AT45DBXXX_HW_WR_PROTECT || W25QXXX_HW_WR_PROTECT
- static void ExtMem_HwWrProtPinAssert();
- static void ExtMem_HwWrProtPinRelease();
- #endif
- static bool ExtMem_Write( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size );
- static bool ExtMem_Read( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size );
- static bool ExtMem_RangeCheck_Read( flash_address_t address, flash_address_t size );
- static bool ExtMem_RangeCheck_Write( flash_address_t address, flash_address_t size );
- static bool ExtMem_BankProtect( eExtMem_Bank_t bankId, bool protectStatus );
- static bool ExtMem_CheckBankProtect( eExtMem_Bank_t bankId, bool * pActualProtectStatus );
- static void ExtMem_Pins_Init();
- static void ExtMem_Pins_Deinit();
- static bool ExtMem_DeInit( bool bForce );
- static bool ExtMem_Init();
- // -----------------------------------------------------------------------------
- // Memory Banking Template
- // Divides the whole chip memory into the common banks
- // This structure describes the sectors mask included into the bank
- typedef struct
- {
- struct flash_sectors_st selectRegister;
- }
- sMemoryBankingTemplate_t;
- static void ExtMem_Internal_FillBankingTemplate( const ExtMem_Bank_Properties_t * pBankProperties, sMemoryBankingTemplate_t * pFactoryProtectionTemplate );
- // -----------------------------------------------------------------------------
- volatile bool bExtMemStatus = false;
- typedef struct
- {
- const flash_api_descriptor_t * api;
- }
- ExtMemDriver_t;
- // Supported flash-drivers
- static const ExtMemDriver_t flash_drivers[] =
- {
- { &W25Q16JV_API } // W25Q driver
- };
- static const ExtMemDriver_t * flashDriver = NULL; // active driver pointer
- #define EXTMEM_BANK0_SIZE (0x0E0000)
- #define EXTMEM_BANK1_SIZE (0x100000)
-
- // Dynamically filled Bank properties
- static ExtMem_Banks_Properties_t ActualBankProperties =
- {
- .factoryBank = { .bankSize = 0, .bankAddress = 0 },
- .userBank = { .bankSize = 0, .bankAddress = 0 },
- };
- #if AT45DBXXX_POWER_MANAGEMENT || AT45DBXXX_RESET_MANAGEMENT || AT45DBXXX_HW_WR_PROTECT
- const ExtMemPins_Handle_AT45_t ExtMemPinsHandle_AT45 =
- {
- #if AT45DBXXX_POWER_MANAGEMENT
- .SetPinPowerOn = ExtMem_SetPinPowerOn,
- .SetPinPowerOff = ExtMem_SetPinPowerOff,
- #endif
- #if AT45DBXXX_RESET_MANAGEMENT
- .ResetPinAssert = ExtMem_ResetPinAssert,
- .ResetPinRelease = ExtMem_ResetPinRelease,
- #endif
- #if AT45DBXXX_HW_WR_PROTECT
- .HwWrProtPinAssert = ExtMem_HwWrProtPinAssert,
- .HwWrProtPinRelease = ExtMem_HwWrProtPinRelease,
- #endif
- };
- #endif
- #if W25QXXX_POWER_MANAGEMENT || W25QXXX_RESET_MANAGEMENT || W25QXXX_HW_WR_PROTECT
- const ExtMemPins_Handle_W25Q_t ExtMemPinsHandle_W25Q =
- {
- #if W25QXXX_POWER_MANAGEMENT
- .SetPinPowerOn = ExtMem_SetPinPowerOn,
- .SetPinPowerOff = ExtMem_SetPinPowerOff,
- #endif
- #if W25QXXX_RESET_MANAGEMENT
- .ResetPinAssert = ExtMem_ResetPinAssert,
- .ResetPinRelease = ExtMem_ResetPinRelease,
- #endif
- #if W25QXXX_HW_WR_PROTECT
- .HwWrProtPinAssert = ExtMem_HwWrProtPinAssert,
- .HwWrProtPinRelease = ExtMem_HwWrProtPinRelease,
- #endif
- };
- #endif
- static const char Malfunction_FlashProperties_Description[] = "";
- static const flash_properties_t Malfunction_FlashProperties =
- {
- .minAddress = 0,
- .maxAddress = 0,
- .maxSectors = 0,
- .sectorSize = 0,
- .pChipDescription = Malfunction_FlashProperties_Description,
- };
- static const ExtMem_Banks_Properties_t Malfunction_BanksProperties =
- {
- .factoryBankSize = 0,
- .userBankSize = 0,
- .factoryBankAddress = 0,
- .userBankAddress = 0,
- };
- // Function stub
- static bool Malfunction_ExtMem_Write( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
- {
- return false;
- }
- // Function stub
- static bool Malfunction_ExtMem_Read( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
- {
- return false;
- }
- // Function stub
- static bool Malfunction_ExtMem_RangeCheck_Read( flash_address_t address, flash_address_t size )
- {
- return false;
- }
- // Function stub
- static bool Malfunction_ExtMem_RangeCheck_Write( flash_address_t address, flash_address_t size )
- {
- return false;
- }
- // Function stub
- static bool Malfunction_ExtMem_BankProtect( eExtMem_Bank_t bankId, bool protectStatus )
- {
- return false;
- }
- // Function stub
- static bool Malfunction_ExtMem_CheckBankProtect( eExtMem_Bank_t bankId, bool * pActualProtectStatus )
- {
- return false;
- }
- // Exporting External Memory descriptor
- ExtMem_Handle_t ExtMemHandle = {
- .Init = ExtMem_Init, // Always set to actual value
- .Write = Malfunction_ExtMem_Write, // will be set after Init()
- .Read = Malfunction_ExtMem_Read, // will be set after Init()
- .RangeCheck_Read = Malfunction_ExtMem_RangeCheck_Read, // will be set after Init()
- .RangeCheck_Write = Malfunction_ExtMem_RangeCheck_Write, // will be set after Init()
- .BankProtect = Malfunction_ExtMem_BankProtect, // will be set after Init()
- .CheckBankProtect = Malfunction_ExtMem_CheckBankProtect, // will be set after Init()
- .DeInit = ExtMem_DeInit, // Always set to actual value
- .pFlashProperties = &Malfunction_FlashProperties, // will be set after Init()
- .pBanksProperties = &Malfunction_BanksProperties // will be set after Init()
- };
- // // Current Model Memory Template: Bank 0 (Factory)
- // // [WRONG]
- // #warning Remove this line as soon as the following entity has been validated
- // const static sMemoryBankingTemplate_t ACMMemory_Bank0 = {
- //
- // .selectRegister = {
- // .loprotect = 0x000000FE, // First 4MBit (actually 7MBit, the bigger the better)
- // // First Sector 0 is skipped, and Sectors 1..7 is used as Bank0.
- // // Each sector = 128KBytes
- // .hiprotect = 0x00000000,
- // }
- //
- // };
- //
- // // 16MBit flash AT45DB161E is installed;
- // // But the application supposes that only 8MBit (4+4Mbits) is presents.
- // // So it adresses first 4MBit as a factory bank, and the second as
- // // a user bank. The rest part is useless.
- //
- // // Current Model Memory Template: Bank 1 (User)
- // // [WRONG]
- // #warning Remove this line as soon as the following entity has been validated
- // const static sMemoryBankingTemplate_t ACMMemory_Bank1 = {
- //
- // .selectRegister = {
- // .loprotect = 0x0000FF00, // Second 4MBit (actually 8MBit, the bigger the better)
- // // Sectors 8..15 is used as Bank1.
- // .hiprotect = 0x00000000,
- // }
- //
- // };
- // @ACMMemory_BankX: Dynamically filled template for sector protection operation
- static sMemoryBankingTemplate_t ACMMemory_BankX;
- // ExtMem_DeInit()
- // De-Initializes external memory driver.
- // Makes the chip fall asleep.
- // @bForce: if 'false' the function will detect if the chip
- // is busy and interrupt the operation with error.
- // If 'true', the function ignores current chip state and makes it
- // fall asleep instantly.
- // Returns 'true' in success case, and 'false' otherwise.
- bool ExtMem_DeInit( bool bForce )
- {
- // Clear status
- bExtMemStatus = false;
- // Check if the driver is loaded
- if( NULL != flashDriver )
- {
- #if EXTMEM_HIBERNATE_ENABLED
- // Make flash chip fall asleep
- if( FLASH_ERROR( flashDriver->api->routines.flashFinalize( true, bForce ) ) )
- #else
- // Deinitialize driver
- if( FLASH_ERROR( flashDriver->api->routines.flashFinalize( false, bForce ) ) )
- #endif
- {
- return false;
- }
- }
- // de-initialize SPI driver
- pSPIHandle->DeInit();
- // De-Initialize power- and reset- management pins
- ExtMem_Pins_Deinit();
- // clear routines and data
- ExtMemHandle.Write = Malfunction_ExtMem_Write;
- ExtMemHandle.Read = Malfunction_ExtMem_Read;
- ExtMemHandle.RangeCheck_Read = Malfunction_ExtMem_RangeCheck_Read;
- ExtMemHandle.RangeCheck_Write = Malfunction_ExtMem_RangeCheck_Write;
- ExtMemHandle.BankProtect = Malfunction_ExtMem_BankProtect;
- ExtMemHandle.CheckBankProtect = Malfunction_ExtMem_CheckBankProtect;
- ExtMemHandle.pFlashProperties = &Malfunction_FlashProperties;
- ExtMemHandle.pBanksProperties = &Malfunction_BanksProperties;
- // set status and return
- return true;
- }
- // ExtMem_DriverLoad
- // Detects the chip on the bus and returns the appropriate driver to control it
- static const ExtMemDriver_t * ExtMem_DriverLoad()
- {
- for( size_t flash_driver_active = 0; flash_driver_active < sizeof(flash_drivers)/sizeof(flash_drivers[0]); ++flash_driver_active )
- {
- if( FLASH_SUCCESS(flash_drivers[ flash_driver_active ].api->routines.flashInitialize( true ) ) )
- {
- return &flash_drivers[ flash_driver_active ];
- }
- }
- return NULL; // driver not found
- }
- // ExtMem_Init()
- // Initializes external memory driver.
- // Wakes the memory chip up if it is necessary.
- // Returns 'true' in success case, and 'false' otherwise.
- bool ExtMem_Init()
- {
- // Clear status
- bExtMemStatus = false;
- // Initialize power- and reset- management pins
- ExtMem_Pins_Init();
- // initialize SPI driver
- pSPIHandle->Init();
- // Detect chip and load driver
- flashDriver = ExtMem_DriverLoad();
- // Check if the driver is loaded
- if( NULL == flashDriver )
- {
- // deinitialize power- and reset- management pins
- ExtMem_Pins_Deinit();
- // de-initialize SPI driver
- pSPIHandle->DeInit();
- return false;
- }
- // Check boundaries
- if( flashDriver->api->flashProperties->minAddress >= flashDriver->api->flashProperties->maxAddress )
- return false;
- // Check sizes
- if( flashDriver->api->flashProperties->maxSectors == 0 || flashDriver->api->flashProperties->sectorSize == 0 )
- return false;
- // Update banks properties with actual values
- ActualBankProperties.factoryBankSize = EXTMEM_BANK0_SIZE;
- ActualBankProperties.userBankSize = EXTMEM_BANK1_SIZE;
- ActualBankProperties.factoryBankAddress = flashDriver->api->flashProperties->minAddress;
- ActualBankProperties.userBankAddress = flashDriver->api->flashProperties->minAddress + ActualBankProperties.factoryBankSize;
- // Check the Bank sizes:
- // the banks can not share one sector, the sector can be owned by only one bank.
- if( ((ActualBankProperties.factoryBankSize % flashDriver->api->flashProperties->sectorSize > 0 )?(flashDriver->api->flashProperties->sectorSize):(0))
- +((ActualBankProperties.userBankSize % flashDriver->api->flashProperties->sectorSize > 0 )?(flashDriver->api->flashProperties->sectorSize):(0))
- +( ActualBankProperties.factoryBankSize + ActualBankProperties.userBankSize)
- > flashDriver->api->flashProperties->maxSectors * flashDriver->api->flashProperties->sectorSize )
- {
- return false;
- }
- // initialize driver routines and data
- ExtMemHandle.Write = ExtMem_Write;
- ExtMemHandle.Read = ExtMem_Read;
- ExtMemHandle.RangeCheck_Read = ExtMem_RangeCheck_Read;
- ExtMemHandle.RangeCheck_Write = ExtMem_RangeCheck_Write;
- ExtMemHandle.BankProtect = ExtMem_BankProtect;
- ExtMemHandle.CheckBankProtect = ExtMem_CheckBankProtect;
- ExtMemHandle.pFlashProperties = flashDriver->api->flashProperties;
- ExtMemHandle.pBanksProperties = &ActualBankProperties;
- // Initialize flash driver
- if( FLASH_ERROR( flashDriver->api->routines.flashInitialize(false) ) )
- {
- // finalize after initialization fail
- flashDriver->api->routines.flashFinalize( false, true );
- // deinitialize power- and reset- management pins
- ExtMem_Pins_Deinit();
- // de-initialize SPI driver
- pSPIHandle->DeInit();
- // flash driver initialization error
- return false;
- }
- // set status and return
- return (bExtMemStatus = true);
- }
- // ExtMem_Internal_FillBankingTemplate
- // Calculates the sMemoryBankingTemplate_t structure during run-time.
- // Function relies on the bank properties passed in @pBankProperties.
- static void ExtMem_Internal_FillBankingTemplate( const ExtMem_Bank_Properties_t * pBankProperties, sMemoryBankingTemplate_t * pFactoryProtectionTemplate )
- {
- // The first bank's sector (including the sector)
- size_t factoryBankSectorBegin = __FLASH_ADDRESS2SECTOR_BEGIN(pBankProperties->bankAddress, ExtMemHandle.pFlashProperties->sectorSize);
-
- // The last bank's sector (including the sector)
- size_t factoryBankSectorEnd = __FLASH_ADDRESS2SECTOR_END(pBankProperties->bankAddress + pBankProperties->bankSize, ExtMemHandle.pFlashProperties->sectorSize);
-
- // Fill the structure with zeros before operation
- for( size_t nZero = 0; nZero < sizeof(pFactoryProtectionTemplate->selectRegister); ++nZero )
- {
- pFactoryProtectionTemplate->selectRegister.bytes[nZero] = 0;
- }
- // Mark the affected sectors in the output structure
- for( size_t nSector = factoryBankSectorBegin; nSector < factoryBankSectorEnd; ++nSector )
- {
- BITBUFFER_SET( pFactoryProtectionTemplate->selectRegister.bytes, nSector );
- }
- }
- // Initialize ExtMem power- and reset- management GPIO-pins
- static void ExtMem_Pins_Init()
- {
- #if W25QXXX_RESET_MANAGEMENT || AT45DBXXX_RESET_MANAGEMENT
- // Configure GPIO pins for AT45 IC : reset signal
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- // Configure as input to detect actual level:
- GPIO_InitStruct.Pin = CONFIG_PIN__EXTMEM__RST;
- GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(CONFIG_PORT__EXTMEM__RST, &GPIO_InitStruct);
- // read actual level
- GPIO_PinState xPreservedState = HAL_GPIO_ReadPin( CONFIG_PORT__EXTMEM__RST, CONFIG_PIN__EXTMEM__RST );
- // Configure as analog
- GPIO_InitStruct.Pin = CONFIG_PIN__EXTMEM__RST;
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(CONFIG_PORT__EXTMEM__RST, &GPIO_InitStruct);
- // prepare pin state:
- HAL_GPIO_WritePin( CONFIG_PORT__EXTMEM__RST, CONFIG_PIN__EXTMEM__RST, xPreservedState );
- // Configure as output:
- GPIO_InitStruct.Pin = CONFIG_PIN__EXTMEM__RST;
- GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
- GPIO_InitStruct.Pull = GPIO_PULLUP;
- HAL_GPIO_Init(CONFIG_PORT__EXTMEM__RST, &GPIO_InitStruct);
- #endif
- }
- // De-Initialize ExtMem power- and reset- management GPIO-pins
- static void ExtMem_Pins_Deinit()
- {
- #if W25QXXX_RESET_MANAGEMENT || AT45DBXXX_RESET_MANAGEMENT
- // Configure GPIO pins for AT45 IC : PB10=nWP (reset signal)
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- GPIO_InitStruct.Pin = CONFIG_PIN__EXTMEM__RST;
- GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- HAL_GPIO_Init(CONFIG_PORT__EXTMEM__RST, &GPIO_InitStruct);
- #endif
- }
-
- typedef struct
- {
- // Actual protection bits for all sectors:
- __FLASH_DWORD actual_protection_mask_lo;
- __FLASH_DWORD actual_protection_mask_hi;
- // Desired protection bits for selected sectors:
- __FLASH_DWORD desired_protection_mask_lo;
- __FLASH_DWORD desired_protection_mask_hi;
- union
- {
- bool globalProtectionStatus; // AT25
- bool anySectorProtectionStatus; // W25Q
- };
- bool individualProtectionStatus;
- }
- sProtectionEntry_t;
- // Queries actual protection information from the flash-memory and fills the [sProtectionEntry_t] structure.
- // If required, fills the protection register that can be used to set the protection information
- // @bankId = memory bank identifier;
- // @desiredProtectStatus = desired protecion state
- // @protEntry = pointer to the [sProtectionEntry_t] structure to fill, mandatory.
- // @setProtectRegister = pointer to the set-protection register to fill, optional, it then can be used by flash_protect_ex()
- // Returns the operaion status, true if succeded, false otherwise.
- // The actual protection state will be returned in @protEntry.
- static bool ExtMem_Internal_FillProtectionEntry( eExtMem_Bank_t bankId, bool desiredProtectStatus, sProtectionEntry_t * pProtEntry, flash_api_protect_t * setProtectRegister )
- {
- sMemoryBankingTemplate_t * pBankTemplate = NULL;
- flash_api_getprotect_t getProtectRegister;
- // Check if the driver is loaded
- if( NULL == flashDriver ) return false;
- if( NULL != pProtEntry )
- {
- // This function uses individual sector protecton
- //
- switch( bankId )
- {
- case extmem_bank_factory:
- {
- pBankTemplate = &ACMMemory_BankX;
- // use dynamic template for FACTORY bank
- ExtMem_Internal_FillBankingTemplate( &ExtMemHandle.pBanksProperties->factoryBank, pBankTemplate );
- }
- break;
- case extmem_bank_user:
- {
- pBankTemplate = &ACMMemory_BankX;
- // use dynamic template for USER bank
- ExtMem_Internal_FillBankingTemplate( &ExtMemHandle.pBanksProperties->userBank, pBankTemplate );
- }
- break;
- }
- if( NULL != pBankTemplate )
- {
- // Retrieve currect sector protection register:
- if( FLASH_SUCCESS( flashDriver->api->routines.flashGetProtect( &getProtectRegister ) ) )
- {
- // Get actual protection bits for all sectors:
- pProtEntry->actual_protection_mask_lo = getProtectRegister.sectors.loprotect;
- pProtEntry->actual_protection_mask_hi = getProtectRegister.sectors.hiprotect;
- // Initialize desired protection bits for selected sectors:
- pProtEntry->desired_protection_mask_lo = ((desiredProtectStatus)?0xFFFFFFFF:0x00000000);
- pProtEntry->desired_protection_mask_hi = ((desiredProtectStatus)?0xFFFFFFFF:0x00000000);
- // Filter only selected sectors (specified by selection register on memory bank template)
- pProtEntry->actual_protection_mask_lo &= pBankTemplate->selectRegister.loprotect;
- pProtEntry->actual_protection_mask_hi &= pBankTemplate->selectRegister.hiprotect;
- pProtEntry->desired_protection_mask_lo &= pBankTemplate->selectRegister.loprotect;
- pProtEntry->desired_protection_mask_hi &= pBankTemplate->selectRegister.hiprotect;
- // Compare actual and desired sector protection status:
- if( pProtEntry->actual_protection_mask_lo != pProtEntry->desired_protection_mask_lo
- ||
- pProtEntry->actual_protection_mask_hi != pProtEntry->desired_protection_mask_hi )
- {
- // PROTECTION STATUS: SOME SECTORS HAVE INCORRECT PROTECTION FLAGS
- pProtEntry->individualProtectionStatus = false;
- if( NULL != setProtectRegister )
- {
- // Do not change COMMON PROTECTION FLAG:
- setProtectRegister->protection_modify = flash_sector_protect_nomodify;
- // Mark selected sectors to be protected:
- setProtectRegister->protection_enabled = flash_sector_protect_pick;
- // Copy sectors selection mask:
- setProtectRegister->sectors.loprotect = pBankTemplate->selectRegister.loprotect;
- setProtectRegister->sectors.hiprotect = pBankTemplate->selectRegister.hiprotect;
- }
- }
- else
- {
- // PROTECTION STATUS: ALL SECTORS HAVE CORRECT PROTECTION FLAGS
- pProtEntry->individualProtectionStatus = true;
- }
- // QUERY GLOBAL PROTECTION FLAG
- switch( flashDriver->api->routines.flashGetProtect( NULL ) )
- {
- case FLERR_PROTECT_ENABLED:
- pProtEntry->globalProtectionStatus = true;
- return true;
- case FLERR_PROTECT_DISABLED:
- pProtEntry->globalProtectionStatus = false;
- return true;
- }
- }
- }
- }
- return false;
- }
- // ExtMem_BankProtect()
- // Implements external memory protection by Memory Bank Identifier
- // @bankId = memory bank identifier;
- // @desiredProtectStatus - protection status (true=protected, false=unprotected)
- // Returns the result of operation
- static bool ExtMem_BankProtect( eExtMem_Bank_t bankId, bool desiredProtectStatus )
- {
- sProtectionEntry_t protEntry_Bank0; // protection information for Bank0
- sProtectionEntry_t protEntry_Bank1; // protection information for Bank1
- // Check if the driver is loaded
- if( NULL == flashDriver ) return false;
- // --------------------
- if( extmem_bank_factory != bankId
- &&
- extmem_bank_user != bankId )
- {
- return false; // error
- }
- // --------------------
- // Query actual protection information for both banks
- // Argument ExtMem_Internal_FillProtectionEntry(... @desiredProtectStatus = true ...):
- // that ensures that all sectors are protected with individual protection flags.
- if( ExtMem_Internal_FillProtectionEntry( extmem_bank_factory, true, &protEntry_Bank0, NULL )
- &&
- ExtMem_Internal_FillProtectionEntry( extmem_bank_user, true, &protEntry_Bank1, NULL ) )
- {
- // Actual bank's protection state is depends on the global protection state and the individual protection state for bank
- bool stateBank0 = ( protEntry_Bank0.individualProtectionStatus && protEntry_Bank0.globalProtectionStatus );
- bool stateBank1 = ( protEntry_Bank1.individualProtectionStatus && protEntry_Bank1.globalProtectionStatus );
- // Check if current bank's protection state matchs to desired state
- if(
- (( extmem_bank_factory == bankId ) && ( desiredProtectStatus == stateBank0 ))
- ||
- (( extmem_bank_user == bankId ) && ( desiredProtectStatus == stateBank1 ))
- )
- {
- // All bank's protection statuses are correct, no operations are required
- return true; // success
- }
- else // Only if current state and the desired state mismatch:
- {
- // The global protection state must be set if at least one bank must be protected.
- bool requiredGlobalState = (( extmem_bank_factory == bankId )?desiredProtectStatus:stateBank0)
- ||
- (( extmem_bank_user == bankId )?desiredProtectStatus:stateBank1);
- if( requiredGlobalState )
- {
- // If global protection state will be set
- // Ensure that all banks have correct individual sector protection flags:
- // Remember: @requiredGlobalState is true
- if( protEntry_Bank0.individualProtectionStatus != (( extmem_bank_factory == bankId )?desiredProtectStatus:stateBank0) )
- {
- // @individualProtectionStatus does not match to the desired state
- flash_api_protect_t setProtectRegister; // set-protection register
- // new bank protection status
- stateBank0 = !protEntry_Bank0.individualProtectionStatus;
- // Query actual protection information for both banks
- // Specify argument ExtMem_Internal_FillProtectionEntry(... @desiredProtectStatus ...) to
- // the inverted @individualProtectionStatus state, because current @individualProtectionStatus value is wrong
- if( !ExtMem_Internal_FillProtectionEntry( extmem_bank_factory, stateBank0, &protEntry_Bank0, &setProtectRegister ) )
- {
- // query error
- return false;
- }
- // Execute operation: modify only individual sectors protection marks to the desired state
- if( FLASH_ERROR( flashDriver->api->routines.flashProtectEx( &setProtectRegister,
- (( stateBank0 )?(flash_sector_protected):(flash_sector_unprotected))
- ) ) )
- {
- // Error: can not modify individual sector protection flags
- return false;
- }
- }
- if( protEntry_Bank1.individualProtectionStatus != (( extmem_bank_user == bankId )?desiredProtectStatus:stateBank1) )
- {
- // @individualProtectionStatus does not match to the desired state
- flash_api_protect_t setProtectRegister; // set-protection register
- // new bank protection status
- stateBank1 = !protEntry_Bank1.individualProtectionStatus;
- // Query actual protection information for both banks
- // Specify argument ExtMem_Internal_FillProtectionEntry(... @desiredProtectStatus ...) to
- // the inverted @individualProtectionStatus state, because current @individualProtectionStatus value is wrong
- if( !ExtMem_Internal_FillProtectionEntry( extmem_bank_user, stateBank1, &protEntry_Bank1, &setProtectRegister ) )
- {
- // query error
- return false;
- }
- // Execute operation: modify only individual sectors protection marks to the desired state
- if( FLASH_ERROR( flashDriver->api->routines.flashProtectEx( &setProtectRegister,
- (( stateBank1 )?(flash_sector_protected):(flash_sector_unprotected))
- ) ) )
- {
- // Error: can not modify individual sector protection flags
- return false;
- }
- }
- // Modify global write-protection flag: protected
- // W25Q: stub call, always return FLERR_SUCCESS
- return FLASH_SUCCESS( flashDriver->api->routines.flashProtect( NULL ) );
- }
- else
- {
- // If global protection state will be reset: all banks must be unprotected
- // Modify global write-protection flag: unprotected
- return FLASH_SUCCESS( flashDriver->api->routines.flashUnprotect( NULL ) );
- }
- }
- }
- return false; // error
- }
- // ExtMem_CheckBankProtect()
- // Implements external memory protection by Memory Bank Identifier
- // @bankId = memory bank identifier;
- // @pActualProtectStatus - pointer to the boolean variable to receive actual protection status
- // Returns the result of operation
- static bool ExtMem_CheckBankProtect( eExtMem_Bank_t bankId, bool * pActualProtectStatus )
- {
- sProtectionEntry_t protEntry;
- if( NULL != pActualProtectStatus )
- {
- // Query current protection information
- if( ExtMem_Internal_FillProtectionEntry( bankId, true, &protEntry, NULL ) )
- {
- *pActualProtectStatus = (protEntry.globalProtectionStatus) && (protEntry.individualProtectionStatus);
- return true; // success, no operations are required
- }
- }
- return false; // error
- }
- #if AT45DBXXX_POWER_MANAGEMENT
- // Implement ExtMem power-management: set power enable pin
- static void ExtMem_SetPinPowerOn()
- {
- #error Not-implemented
- }
- // Implement ExtMem power-management: set power disable pin
- static void ExtMem_SetPinPowerOff()
- {
- #error Not-implemented
- }
- #endif
-
- #if AT45DBXXX_RESET_MANAGEMENT
- // Implement ExtMem reset-management: set reset enable pin
- static void ExtMem_ResetPinAssert()
- {
- HAL_GPIO_WritePin( CONFIG_PORT__EXTMEM__RST, CONFIG_PIN__EXTMEM__RST, GPIO_PIN_RESET );
- }
- // Implement ExtMem reset-management: set reset disable pin
- static void ExtMem_ResetPinRelease()
- {
- HAL_GPIO_WritePin( CONFIG_PORT__EXTMEM__RST, CONFIG_PIN__EXTMEM__RST, GPIO_PIN_SET );
- }
- #endif
- #if AT45DBXXX_HW_WR_PROTECT
- // Implement ExtMem hardware-write-protection: enable write protection
- static void ExtMem_HwWrProtPinAssert()
- {
- #error Not-implemented
- }
- // Implement ExtMem hardware-write-protection: disable write protection
- static void ExtMem_HwWrProtPinRelease()
- {
- #error Not-implemented
- }
- #endif
-
- #if CONFIG_EXTMEM_EMULATEWRITE
- static bool ExtMem_Write( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
- {
- return true;
- }
- #else
- static bool ExtMem_Write( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
- {
- // Check if the driver is loaded
- if( NULL == flashDriver ) return false;
- extern volatile bool bExtMemStatus;
- return bExtMemStatus && FLASH_SUCCESS( flashDriver->api->routines.flashWrite( flashDriver->api->flashProperties->minAddress + address, pBuffer, size, fwm_safewrite ) );
- }
- #endif
-
- #if CONFIG_EXTMEM_EMULATEREAD
- static bool ExtMem_Read( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
- {
- memset( pBuffer, 0xDE, size );
- return true;
- }
- #else
- static bool ExtMem_Read( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
- {
- // Check if the driver is loaded
- if( NULL == flashDriver ) return false;
- extern volatile bool bExtMemStatus;
- return bExtMemStatus && FLASH_SUCCESS( flashDriver->api->routines.flashRead( flashDriver->api->flashProperties->minAddress + address, pBuffer, size ) );
- }
- #endif
- static bool ExtMem_RangeCheck_Read( flash_address_t address, flash_address_t size )
- {
- // Check if the driver is loaded
- if( NULL == flashDriver ) return false;
- if( size <= (flashDriver->api->flashProperties->maxAddress - flashDriver->api->flashProperties->minAddress) )
- {
- if( address < flashDriver->api->flashProperties->maxAddress - flashDriver->api->flashProperties->minAddress - size )
- {
- return true;
- }
- }
- return false;
- }
- static bool ExtMem_RangeCheck_Write( flash_address_t address, flash_address_t size )
- {
- // Check if the driver is loaded
- if( NULL == flashDriver ) return false;
- if( size <= (flashDriver->api->flashProperties->maxAddress - flashDriver->api->flashProperties->minAddress) )
- {
- if( address < flashDriver->api->flashProperties->maxAddress - flashDriver->api->flashProperties->minAddress - size )
- {
- return true;
- }
- }
- return false;
- }
- // legacy compatibility
- flash_err_t flash_read( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
- {
- // Check if the driver is loaded
- if( NULL == flashDriver ) return FLERR_DEVICE_MALFUNCTION;
- extern volatile bool bExtMemStatus;
- if( bExtMemStatus )
- return flashDriver->api->routines.flashRead( address, pBuffer, size );
- return FLERR_DEVICE_MALFUNCTION; // !bExtMemStatus
- }
- // legacy compatibility
- flash_err_t flash_write( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size, flash_write_mode_t unused )
- {
- // Check if the driver is loaded
- if( NULL == flashDriver ) return FLERR_DEVICE_MALFUNCTION;
- extern volatile bool bExtMemStatus;
- (void)unused;
- if( bExtMemStatus )
- return flashDriver->api->routines.flashWrite( address, pBuffer, size, fwm_safewrite );
- return FLERR_DEVICE_MALFUNCTION; // !bExtMemStatus
- }
|