extmem_flash.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. #include "core/config.h"
  2. #include "drivers/extmem_flash/extmem_flash.h"
  3. #include "core/gpio.h"
  4. #include "core/main.h"
  5. #include "core/config_pins.h"
  6. #if AT45DB321D_POWER_MANAGEMENT
  7. static void ExtMem_SetPinPowerOn();
  8. static void ExtMem_SetPinPowerOff();
  9. #endif
  10. #if AT45DB321D_RESET_MANAGEMENT
  11. static void ExtMem_ResetPinAssert();
  12. static void ExtMem_ResetPinRelease();
  13. #endif
  14. #if AT45DB321D_HW_WR_PROTECT
  15. static void ExtMem_HwWrProtPinAssert();
  16. static void ExtMem_HwWrProtPinRelease();
  17. #endif
  18. static bool ExtMem_Write( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size );
  19. static bool ExtMem_Read( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size );
  20. static bool ExtMem_RangeCheck_Read( flash_address_t address, flash_address_t size );
  21. static bool ExtMem_RangeCheck_Write( flash_address_t address, flash_address_t size );
  22. static bool ExtMem_BankProtect( eExtMem_Bank_t bankId, bool protectStatus );
  23. static bool ExtMem_CheckBankProtect( eExtMem_Bank_t bankId, bool * pActualProtectStatus );
  24. static void ExtMem_Pins_Init();
  25. static void ExtMem_Pins_Deinit();
  26. static bool ExtMem_DeInit( bool bForce );
  27. static bool ExtMem_Init();
  28. volatile bool bExtMemStatus = false;
  29. #define EXTMEM_BANK0_SIZE (0x100000) // do not forget to change ACMMemory_Bank0
  30. #define EXTMEM_BANK1_SIZE (0x100000) // do not forget to change ACMMemory_Bank1
  31. static const ExtMem_Bank_Properties_t BanksProperties =
  32. {
  33. .factoryBankSize = EXTMEM_BANK0_SIZE,
  34. .userBankSize = EXTMEM_BANK1_SIZE
  35. };
  36. const ExtMemPins_Handle_t ExtMemPinsHandle =
  37. {
  38. #if AT45DB321D_POWER_MANAGEMENT
  39. .SetPinPowerOn = ExtMem_SetPinPowerOn,
  40. .SetPinPowerOff = ExtMem_SetPinPowerOff,
  41. #endif
  42. #if AT45DB321D_RESET_MANAGEMENT
  43. .ResetPinAssert = ExtMem_ResetPinAssert,
  44. .ResetPinRelease = ExtMem_ResetPinRelease,
  45. #endif
  46. #if AT45DB321D_HW_WR_PROTECT
  47. .HwWrProtPinAssert = ExtMem_HwWrProtPinAssert,
  48. .HwWrProtPinRelease = ExtMem_HwWrProtPinRelease,
  49. #endif
  50. };
  51. const ExtMem_Handle_t ExtMemHandle = {
  52. .Init = ExtMem_Init,
  53. .Write = ExtMem_Write,
  54. .Read = ExtMem_Read,
  55. .RangeCheck_Read = ExtMem_RangeCheck_Read,
  56. .RangeCheck_Write = ExtMem_RangeCheck_Write,
  57. .BankProtect = ExtMem_BankProtect,
  58. .CheckBankProtect = ExtMem_CheckBankProtect,
  59. .DeInit = ExtMem_DeInit,
  60. .pFlashProperties = &FlashProperties,
  61. .pBanksProperties = &BanksProperties
  62. };
  63. // Memory Banking Template
  64. // Divides the whole chip memory into the common banks
  65. // This structure describes the sectors mask included into the bank
  66. typedef struct
  67. {
  68. struct flash_sectors_st selectRegister;
  69. }
  70. sMemoryBankingTemplate_t;
  71. //
  72. // Current Model Memory Template: Bank 0 (Factory)
  73. const static sMemoryBankingTemplate_t ACMMemory_Bank0 = {
  74. .selectRegister = {
  75. .loprotect = 0x0001FFFE,
  76. //.loprotect = 0x000001FE, // "First" 8MBit --- bug found 29.05.19, each bit represent only 512kbit, not 1Mbit.
  77. .hiprotect = 0x00000000,
  78. }
  79. };
  80. // 32MBit flash AT45DB321D is installed;
  81. // But the application supposes that only first 8MBit is presents
  82. // So it adresses first 4MBit as a factory bank, and the second as
  83. // a user bank. The rest part is useless.
  84. // Current Model Memory Template: Bank 1 (User)
  85. const static sMemoryBankingTemplate_t ACMMemory_Bank1 = {
  86. .selectRegister = {
  87. .loprotect = 0xFFFE0000, // "Second" 8MBit
  88. //.loprotect = 0x0001FE00, // "Second" 8MBit --- bug found 29.05.19, each bit represent only 512kbit, not 1Mbit.
  89. .hiprotect = 0x00000001,
  90. //.hiprotect = 0x00000000, --- bug found 29.05.19, each bit represent only 512kbit, not 1Mbit.
  91. }
  92. };
  93. #define pBankTemplate_Bank0 (&ACMMemory_Bank0)
  94. #define pBankTemplate_Bank1 (&ACMMemory_Bank1)
  95. #define pSPIHandle (&SPIHandle)
  96. // ExtMem_DeInit()
  97. // De-Initializes external memory driver.
  98. // Makes the chip fall asleep.
  99. // @bForce: if 'false' the function will detect if the chip
  100. // is busy and interrupt the operation with error.
  101. // If 'true', the function ignores current chip state and makes it
  102. // fall asleep instantly.
  103. // Returns 'true' in success case, and 'false' otherwise.
  104. bool ExtMem_DeInit( bool bForce )
  105. {
  106. // Clear status
  107. bExtMemStatus = false;
  108. #if EXTMEM_HIBERNATE_ENABLED
  109. // Make flash chip fall asleep
  110. if( FLASH_ERROR( flash_finalize( true, bForce ) ) )
  111. #else
  112. // Deinitialize driver
  113. if( FLASH_ERROR( flash_finalize( false, bForce ) ) )
  114. #endif
  115. {
  116. return false;
  117. }
  118. // de-initialize SPI driver
  119. pSPIHandle->DeInit();
  120. // De-Initialize power- and reset- management pins
  121. ExtMem_Pins_Deinit();
  122. // set status and return
  123. return true;
  124. }
  125. // ExtMem_Init()
  126. // Initializes external memory driver.
  127. // Wakes the memory chip up if it is necessary.
  128. // Returns 'true' in success case, and 'false' otherwise.
  129. bool ExtMem_Init()
  130. {
  131. // Clear status
  132. bExtMemStatus = false;
  133. if( ExtMemHandle.pFlashProperties->minAddress >= ExtMemHandle.pFlashProperties->maxAddress )
  134. return false;
  135. if( ExtMemHandle.pFlashProperties->maxSectors == 0 || ExtMemHandle.pFlashProperties->sectorSize == 0 )
  136. return false;
  137. // Check the Bank sizes:
  138. // the banks can not share one sector, the sector can be owned by only one bank.
  139. if( ((ExtMemHandle.pBanksProperties->factoryBankSize % ExtMemHandle.pFlashProperties->sectorSize > 0 )?(ExtMemHandle.pFlashProperties->sectorSize):(0))
  140. +((ExtMemHandle.pBanksProperties->userBankSize % ExtMemHandle.pFlashProperties->sectorSize > 0 )?(ExtMemHandle.pFlashProperties->sectorSize):(0))
  141. > ExtMemHandle.pFlashProperties->maxSectors * ExtMemHandle.pFlashProperties->sectorSize )
  142. {
  143. return false;
  144. }
  145. // Initialize power- and reset- management pins
  146. ExtMem_Pins_Init();
  147. // initialize SPI driver
  148. pSPIHandle->Init();
  149. // Initialize flash driver
  150. if( FLASH_ERROR( flash_initialize() ) )
  151. {
  152. // de-initialize SPI driver
  153. pSPIHandle->DeInit();
  154. // flash driver initialization error
  155. return false;
  156. }
  157. // set status and return
  158. return (bExtMemStatus = true);
  159. }
  160. // Initialize ExtMem power- and reset- management GPIO-pins
  161. static void ExtMem_Pins_Init()
  162. {
  163. // Configure GPIO pins for AT45 IC : PB10=nWP (reset signal)
  164. GPIO_InitTypeDef GPIO_InitStruct = {0};
  165. // Configure as input to detect actual level:
  166. GPIO_InitStruct.Pin = CONFIG_PIN__EXTMEM__RST;
  167. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  168. GPIO_InitStruct.Pull = GPIO_NOPULL;
  169. HAL_GPIO_Init(CONFIG_PORT__EXTMEM__RST, &GPIO_InitStruct);
  170. // read actual level
  171. GPIO_PinState xPreservedState = HAL_GPIO_ReadPin( CONFIG_PORT__EXTMEM__RST, CONFIG_PIN__EXTMEM__RST );
  172. // Configure as analog
  173. GPIO_InitStruct.Pin = CONFIG_PIN__EXTMEM__RST;
  174. GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  175. GPIO_InitStruct.Pull = GPIO_NOPULL;
  176. HAL_GPIO_Init(CONFIG_PORT__EXTMEM__RST, &GPIO_InitStruct);
  177. // prepare pin state:
  178. HAL_GPIO_WritePin( CONFIG_PORT__EXTMEM__RST, CONFIG_PIN__EXTMEM__RST, xPreservedState );
  179. // Configure as output:
  180. GPIO_InitStruct.Pin = CONFIG_PIN__EXTMEM__RST;
  181. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  182. GPIO_InitStruct.Pull = GPIO_PULLUP;
  183. HAL_GPIO_Init(CONFIG_PORT__EXTMEM__RST, &GPIO_InitStruct);
  184. }
  185. // De-Initialize ExtMem power- and reset- management GPIO-pins
  186. static void ExtMem_Pins_Deinit()
  187. {
  188. // Configure GPIO pins for AT45 IC : PB10=nWP (reset signal)
  189. GPIO_InitTypeDef GPIO_InitStruct = {0};
  190. GPIO_InitStruct.Pin = CONFIG_PIN__EXTMEM__RST;
  191. GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  192. GPIO_InitStruct.Pull = GPIO_NOPULL;
  193. HAL_GPIO_Init(CONFIG_PORT__EXTMEM__RST, &GPIO_InitStruct);
  194. }
  195. typedef struct
  196. {
  197. // Actual protection bits for all sectors:
  198. __FLASH_DWORD actual_protection_mask_lo;
  199. __FLASH_DWORD actual_protection_mask_hi;
  200. // Desired protection bits for selected sectors:
  201. __FLASH_DWORD desired_protection_mask_lo;
  202. __FLASH_DWORD desired_protection_mask_hi;
  203. bool globalProtectionStatus;
  204. bool individualProtectionStatus;
  205. }
  206. sProtectionEntry_t;
  207. // Queries actual protection information from the flash-memory and fills the [sProtectionEntry_t] structure.
  208. // If required, fills the protection register that can be used to set the protection information
  209. // @bankId = memory bank identifier;
  210. // @desiredProtectStatus = desired protecion state
  211. // @protEntry = pointer to the [sProtectionEntry_t] structure to fill, mandatory.
  212. // @setProtectRegister = pointer to the set-protection register to fill, optional, it then can be used by flash_protect_ex()
  213. // Returns the operaion status, true if succeded, false otherwise.
  214. // The actual protection state will be returned in @protEntry.
  215. static bool ExtMem_Internal_FillProtectionEntry( eExtMem_Bank_t bankId, bool desiredProtectStatus, sProtectionEntry_t * pProtEntry, flash_api_protect_t * setProtectRegister )
  216. {
  217. const sMemoryBankingTemplate_t * pBankTemplate = NULL;
  218. flash_api_getprotect_t getProtectRegister;
  219. if( NULL != pProtEntry )
  220. {
  221. // This function uses individual sector protecton
  222. //
  223. switch( bankId )
  224. {
  225. case extmem_bank_factory:
  226. {
  227. pBankTemplate = pBankTemplate_Bank0;
  228. }
  229. break;
  230. case extmem_bank_user:
  231. {
  232. pBankTemplate = pBankTemplate_Bank1;
  233. }
  234. break;
  235. }
  236. if( NULL != pBankTemplate )
  237. {
  238. // Retrieve currect sector protection register:
  239. if( FLASH_SUCCESS( flash_getprotect( &getProtectRegister ) ) )
  240. {
  241. // Get actual protection bits for all sectors:
  242. pProtEntry->actual_protection_mask_lo = getProtectRegister.sectors.loprotect;
  243. pProtEntry->actual_protection_mask_hi = getProtectRegister.sectors.hiprotect;
  244. // Initialize desired protection bits for selected sectors:
  245. pProtEntry->desired_protection_mask_lo = ((desiredProtectStatus)?0xFFFFFFFF:0x00000000);
  246. pProtEntry->desired_protection_mask_hi = ((desiredProtectStatus)?0xFFFFFFFF:0x00000000);
  247. // Filter only selected sectors (specified by selection register on memory bank template)
  248. pProtEntry->actual_protection_mask_lo &= pBankTemplate->selectRegister.loprotect;
  249. pProtEntry->actual_protection_mask_hi &= pBankTemplate->selectRegister.hiprotect;
  250. pProtEntry->desired_protection_mask_lo &= pBankTemplate->selectRegister.loprotect;
  251. pProtEntry->desired_protection_mask_hi &= pBankTemplate->selectRegister.hiprotect;
  252. // Compare actual and desired sector protection status:
  253. if( pProtEntry->actual_protection_mask_lo != pProtEntry->desired_protection_mask_lo
  254. ||
  255. pProtEntry->actual_protection_mask_hi != pProtEntry->desired_protection_mask_hi )
  256. {
  257. // PROTECTION STATUS: SOME SECTORS HAVE INCORRECT PROTECTION FLAGS
  258. pProtEntry->individualProtectionStatus = false;
  259. if( NULL != setProtectRegister )
  260. {
  261. // Do not change COMMON PROTECTION FLAG:
  262. setProtectRegister->protection_modify = flash_sector_protect_nomodify;
  263. // Mark selected sectors to be protected:
  264. setProtectRegister->protection_enabled = flash_sector_protect_pick;
  265. // Copy sectors selection mask:
  266. setProtectRegister->sectors.loprotect = pBankTemplate->selectRegister.loprotect;
  267. setProtectRegister->sectors.hiprotect = pBankTemplate->selectRegister.hiprotect;
  268. }
  269. }
  270. else
  271. {
  272. // PROTECTION STATUS: ALL SECTORS HAVE CORRECT PROTECTION FLAGS
  273. pProtEntry->individualProtectionStatus = true;
  274. }
  275. // QUERY GLOBAL PROTECTION FLAG
  276. switch( flash_getprotect( NULL ) )
  277. {
  278. case FLERR_PROTECT_ENABLED:
  279. pProtEntry->globalProtectionStatus = true;
  280. return true;
  281. case FLERR_PROTECT_DISABLED:
  282. pProtEntry->globalProtectionStatus = false;
  283. return true;
  284. }
  285. }
  286. }
  287. }
  288. return false;
  289. }
  290. // ExtMem_BankProtect()
  291. // Implements external memory protection by Memory Bank Identifier
  292. // @bankId = memory bank identifier;
  293. // @desiredProtectStatus - protection status (true=protected, false=unprotected)
  294. // Returns the result of operation
  295. static bool ExtMem_BankProtect( eExtMem_Bank_t bankId, bool desiredProtectStatus )
  296. {
  297. #warning 31/05/19 Áûëà èçìåíåíà ýòà ôóíêöèÿ, ïîâåðõíîñòíûå òåñòû ïðîøëà. Òðåáóåòñÿ òùàòåëüíàÿ ïðîâåðêà
  298. #warning 02/07/19 error->warning, áóäåì ïðîâåðÿòü
  299. sProtectionEntry_t protEntry_Bank0; // protection information for Bank0
  300. sProtectionEntry_t protEntry_Bank1; // protection information for Bank1
  301. // --------------------
  302. if( extmem_bank_factory != bankId
  303. &&
  304. extmem_bank_user != bankId )
  305. {
  306. return false; // error
  307. }
  308. // --------------------
  309. // Query actual protection information for both banks
  310. // Argument ExtMem_Internal_FillProtectionEntry(... @desiredProtectStatus = true ...):
  311. // that ensures that all sectors are protected with individual protection flags.
  312. if( ExtMem_Internal_FillProtectionEntry( extmem_bank_factory, true, &protEntry_Bank0, NULL )
  313. &&
  314. ExtMem_Internal_FillProtectionEntry( extmem_bank_user, true, &protEntry_Bank1, NULL ) )
  315. {
  316. // Actual bank's protection state is depends on the global protection state and the individual protection state for bank
  317. bool stateBank0 = ( protEntry_Bank0.individualProtectionStatus && protEntry_Bank0.globalProtectionStatus );
  318. bool stateBank1 = ( protEntry_Bank1.individualProtectionStatus && protEntry_Bank1.globalProtectionStatus );
  319. // Check if current bank's protection state matchs to desired state
  320. if(
  321. (( extmem_bank_factory == bankId ) && ( desiredProtectStatus == stateBank0 ))
  322. ||
  323. (( extmem_bank_user == bankId ) && ( desiredProtectStatus == stateBank1 ))
  324. )
  325. {
  326. // All bank's protection statuses are correct, no operations are required
  327. return true; // success
  328. }
  329. else // Only if current state and the desired state mismatch:
  330. {
  331. // The global protection state must be set if at least one bank must be protected.
  332. bool requiredGlobalState = (( extmem_bank_factory == bankId )?desiredProtectStatus:stateBank0)
  333. ||
  334. (( extmem_bank_user == bankId )?desiredProtectStatus:stateBank1);
  335. if( requiredGlobalState )
  336. {
  337. // If global protection state will be set
  338. // Ensure that all banks have correct individual sector protection flags:
  339. // Remember: @requiredGlobalState is true
  340. if( protEntry_Bank0.individualProtectionStatus != (( extmem_bank_factory == bankId )?desiredProtectStatus:stateBank0) )
  341. {
  342. // @individualProtectionStatus does not match to the desired state
  343. flash_api_protect_t setProtectRegister; // set-protection register
  344. // new bank protection status
  345. stateBank0 = !protEntry_Bank0.individualProtectionStatus;
  346. // Query actual protection information for both banks
  347. // Specify argument ExtMem_Internal_FillProtectionEntry(... @desiredProtectStatus ...) to
  348. // the inverted @individualProtectionStatus state, because current @individualProtectionStatus value is wrong
  349. if( !ExtMem_Internal_FillProtectionEntry( extmem_bank_factory, stateBank0, &protEntry_Bank0, &setProtectRegister ) )
  350. {
  351. // query error
  352. return false;
  353. }
  354. // Execute operation: modify only individual sectors protection marks to the desired state
  355. if( FLASH_ERROR( flash_protect_ex( &setProtectRegister,
  356. (( stateBank0 )?(flash_sector_protected):(flash_sector_unprotected))
  357. ) ) )
  358. {
  359. // Error: can not modify individual sector protection flags
  360. return false;
  361. }
  362. }
  363. if( protEntry_Bank1.individualProtectionStatus != (( extmem_bank_user == bankId )?desiredProtectStatus:stateBank1) )
  364. {
  365. // @individualProtectionStatus does not match to the desired state
  366. flash_api_protect_t setProtectRegister; // set-protection register
  367. // new bank protection status
  368. stateBank1 = !protEntry_Bank1.individualProtectionStatus;
  369. // Query actual protection information for both banks
  370. // Specify argument ExtMem_Internal_FillProtectionEntry(... @desiredProtectStatus ...) to
  371. // the inverted @individualProtectionStatus state, because current @individualProtectionStatus value is wrong
  372. if( !ExtMem_Internal_FillProtectionEntry( extmem_bank_user, stateBank1, &protEntry_Bank1, &setProtectRegister ) )
  373. {
  374. // query error
  375. return false;
  376. }
  377. // Execute operation: modify only individual sectors protection marks to the desired state
  378. if( FLASH_ERROR( flash_protect_ex( &setProtectRegister,
  379. (( stateBank1 )?(flash_sector_protected):(flash_sector_unprotected))
  380. ) ) )
  381. {
  382. // Error: can not modify individual sector protection flags
  383. return false;
  384. }
  385. }
  386. // Modify global write-protection flag: protected
  387. return FLASH_SUCCESS( flash_protect( NULL ) );
  388. }
  389. else
  390. {
  391. // If global protection state will be reset: all banks must be unprotected
  392. // Modify global write-protection flag: unprotected
  393. return FLASH_SUCCESS( flash_unprotect( NULL ) );
  394. }
  395. }
  396. }
  397. return false; // error
  398. }
  399. // ExtMem_CheckBankProtect()
  400. // Implements external memory protection by Memory Bank Identifier
  401. // @bankId = memory bank identifier;
  402. // @pActualProtectStatus - pointer to the boolean variable to receive actual protection status
  403. // Returns the result of operation
  404. static bool ExtMem_CheckBankProtect( eExtMem_Bank_t bankId, bool * pActualProtectStatus )
  405. {
  406. sProtectionEntry_t protEntry;
  407. if( NULL != pActualProtectStatus )
  408. {
  409. // Query current protection information
  410. if( ExtMem_Internal_FillProtectionEntry( bankId, true, &protEntry, NULL ) )
  411. {
  412. *pActualProtectStatus = (protEntry.globalProtectionStatus) && (protEntry.individualProtectionStatus);
  413. return true; // success, no operations are required
  414. }
  415. }
  416. return false; // error
  417. }
  418. /*
  419. // ExtMem_BankProtect()
  420. // Implements external memory protection by Memory Bank Identifier
  421. // @bankId = memory bank identifier;
  422. // @protectStatus - protection status (true=protected, false=unprotected)
  423. // Returns the result of operation
  424. static bool ExtMem_BankProtect0( eExtMem_Bank_t bankId, bool protectStatus )
  425. {
  426. flash_api_getprotect_t getProtectRegister;
  427. flash_api_protect_t setProtectRegister;
  428. flash_api_protect_bits mode = (( protectStatus )?(flash_sector_protected):(flash_sector_unprotected));
  429. const sMemoryBankingTemplate_t * pBankTemplate = NULL;
  430. // This function uses individual sector protecton
  431. //
  432. switch( bankId )
  433. {
  434. case extmem_bank_factory:
  435. {
  436. pBankTemplate = pBankTemplate_Bank0;
  437. }
  438. break;
  439. case extmem_bank_user:
  440. {
  441. pBankTemplate = pBankTemplate_Bank1;
  442. }
  443. break;
  444. }
  445. if( NULL != pBankTemplate )
  446. {
  447. // Retrieve currect sector protection register:
  448. if( FLASH_SUCCESS( flash_getprotect( &getProtectRegister ) ) )
  449. {
  450. // Get actual protection bits for all sectors:
  451. __FLASH_DWORD actual_protection_mask_lo = getProtectRegister.sectors.loprotect;
  452. __FLASH_DWORD actual_protection_mask_hi = getProtectRegister.sectors.hiprotect;
  453. // Initialize desired protection bits for selected sectors:
  454. __FLASH_DWORD desired_protection_mask_lo = ((protectStatus)?0xFFFFFFFF:0x00000000);
  455. __FLASH_DWORD desired_protection_mask_hi = ((protectStatus)?0xFFFFFFFF:0x00000000);
  456. // Filter only selected sectors (specified by selection register on memory bank template)
  457. actual_protection_mask_lo &= pBankTemplate->selectRegister.loprotect;
  458. actual_protection_mask_hi &= pBankTemplate->selectRegister.hiprotect;
  459. desired_protection_mask_lo &= pBankTemplate->selectRegister.loprotect;
  460. desired_protection_mask_hi &= pBankTemplate->selectRegister.hiprotect;
  461. // Compare actual and desired sector protection status:
  462. if( actual_protection_mask_lo != desired_protection_mask_lo
  463. ||
  464. actual_protection_mask_hi != desired_protection_mask_hi )
  465. {
  466. // Do not change COMMON PROTECTION FLAG:
  467. setProtectRegister.protection_modify = flash_sector_protect_nomodify;
  468. // Mark selected sectors to be protected:
  469. setProtectRegister.protection_enabled = flash_sector_protect_pick;
  470. // Copy sectors selection mask:
  471. setProtectRegister.sectors.loprotect = pBankTemplate->selectRegister.loprotect;
  472. setProtectRegister.sectors.hiprotect = pBankTemplate->selectRegister.hiprotect;
  473. // Execute operation: modify only individual sectors protection marks to the desired state
  474. if( FLASH_SUCCESS( flash_protect_ex( &setProtectRegister, mode ) ) )
  475. {
  476. // Modify global write-protection flag: protected (for only selected sectors)
  477. return FLASH_SUCCESS( flash_protect( NULL ) );
  478. }
  479. }
  480. else
  481. {
  482. // Modify global write-protection flag: protected (for only selected sectors)
  483. return FLASH_SUCCESS( flash_protect( NULL ) );
  484. }
  485. }
  486. }
  487. return false;
  488. }
  489. */
  490. #if AT45DB321D_POWER_MANAGEMENT
  491. // Implement ExtMem power-management: set power enable pin
  492. static void ExtMem_SetPinPowerOn()
  493. {
  494. #error Not-implemented
  495. }
  496. // Implement ExtMem power-management: set power disable pin
  497. static void ExtMem_SetPinPowerOff()
  498. {
  499. #error Not-implemented
  500. }
  501. #endif
  502. #if AT45DB321D_RESET_MANAGEMENT
  503. // Implement ExtMem reset-management: set reset enable pin
  504. static void ExtMem_ResetPinAssert()
  505. {
  506. HAL_GPIO_WritePin( CONFIG_PORT__EXTMEM__RST, CONFIG_PIN__EXTMEM__RST, GPIO_PIN_RESET );
  507. }
  508. // Implement ExtMem reset-management: set reset disable pin
  509. static void ExtMem_ResetPinRelease()
  510. {
  511. HAL_GPIO_WritePin( CONFIG_PORT__EXTMEM__RST, CONFIG_PIN__EXTMEM__RST, GPIO_PIN_SET );
  512. }
  513. #endif
  514. #if AT45DB321D_HW_WR_PROTECT
  515. // Implement ExtMem hardware-write-protection: enable write protection
  516. static void ExtMem_HwWrProtPinAssert()
  517. {
  518. #error Not-implemented
  519. }
  520. // Implement ExtMem hardware-write-protection: disable write protection
  521. static void ExtMem_HwWrProtPinRelease()
  522. {
  523. #error Not-implemented
  524. }
  525. #endif
  526. #if CONFIG_EXTMEM_EMULATEWRITE
  527. static bool ExtMem_Write( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
  528. {
  529. return true;
  530. }
  531. #else
  532. static bool ExtMem_Write( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
  533. {
  534. extern volatile bool bExtMemStatus;
  535. return bExtMemStatus && FLASH_SUCCESS( flash_write( ExtMemHandle.pFlashProperties->minAddress + address, pBuffer, size, fwm_safewrite ) );
  536. }
  537. #endif
  538. #if CONFIG_EXTMEM_EMULATEREAD
  539. static bool ExtMem_Read( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
  540. {
  541. memset( pBuffer, 0xDE, size );
  542. return true;
  543. }
  544. #else
  545. static bool ExtMem_Read( flash_address_t address, __FLASH_BYTE * pBuffer, flash_address_t size )
  546. {
  547. extern volatile bool bExtMemStatus;
  548. return bExtMemStatus && FLASH_SUCCESS( flash_read( ExtMemHandle.pFlashProperties->minAddress + address, pBuffer, size ) );
  549. }
  550. #endif
  551. static bool ExtMem_RangeCheck_Read( flash_address_t address, flash_address_t size )
  552. {
  553. if( size <= (ExtMemHandle.pFlashProperties->maxAddress - ExtMemHandle.pFlashProperties->minAddress) )
  554. {
  555. if( address < ExtMemHandle.pFlashProperties->maxAddress - ExtMemHandle.pFlashProperties->minAddress - size )
  556. {
  557. return true;
  558. }
  559. }
  560. return false;
  561. }
  562. static bool ExtMem_RangeCheck_Write( flash_address_t address, flash_address_t size )
  563. {
  564. if( size <= (ExtMemHandle.pFlashProperties->maxAddress - ExtMemHandle.pFlashProperties->minAddress) )
  565. {
  566. if( address < ExtMemHandle.pFlashProperties->maxAddress - ExtMemHandle.pFlashProperties->minAddress - size )
  567. {
  568. return true;
  569. }
  570. }
  571. return false;
  572. }