//================================================================================================= // // Company: Paul Scherrer Institut // 5232 Villigen PSI // Switzerland // //------------------------------------------------------------------------------------------------- // // Project: Peltier Controller V2 // Author: Noah Piqué (noah.pique@psi.ch) // //------------------------------------------------------------------------------------------------- // // Module: User Flash // Filename: USFL_UserFlash.c // Date: Handled by Subversion (version control system) // Revision: Handled by Subversion (version control system) // History: Handled by Subversion (version control system) // //------------------------------------------------------------------------------------------------- // // Description: This source file contains all functions dealing with internal flash for User Settings // // STM32L432KBUX_FLASH.ld // // DATA (rwx) : ORIGIN = 0x801F800, LENGTH = 2K // // /* Sections */ // SECTIONS // { // /* NOLOAD is required for not ereasing this block */ // .user_data (NOLOAD) : // { // . = ALIGN(4); // *(.user_data) // . = ALIGN(4); // } > DATA*/ // ... //================================================================================================= //================================================================================================= // Section: INCLUDES // Description: List of required include files. //================================================================================================= #include "USFL_UserFlash.h" // Toolbox #include "../Application/VARH_VariableHandler.h" // include STM32 drivers #include "stm32l4xx_hal.h" #include "cmsis_os2.h" //================================================================================================= // Section: DEFINITIONS // Description: Definition of local constants (visible by this module only). //================================================================================================= #define USERFLASHSIZE (2000/4) // Bytes -> 64 Bits #define USERFLASHPAGE (63) #define VARDEF 0xABCDEF #define STARTDEF (((U64)0xAA01F055 << 32) + (VARDEF << 2)) //================================================================================================= // Section: MACROS // Description: Definition of local macros (visible by this module only). //================================================================================================= //================================================================================================= // Section: ENUMERATIONS // Description: Definition of local enumerations (visible by this module only). //================================================================================================= //================================================================================================= // Section: STRUCTURES // Description: Definition of local Structures (visible by this module only). //================================================================================================= FLASH_EraseInitTypeDef stEreaseInit = { FLASH_TYPEERASE_PAGES, FLASH_BANK_1, USERFLASHPAGE, 1 }; //================================================================================================= // Section: LOCAL VARIABLES // Description: Definition of local variables (visible by this module only). //================================================================================================= U32 u32VarPointer = 0; //================================================================================================= // Section: LOCAL CONSTANTS // Description: Definition of local constants (visible by this module only). //================================================================================================= __attribute__((__section__(".user_data"))) const U64 UserFlash[USERFLASHSIZE]; //================================================================================================= // Section: LOCAL FUNCTIONS (PROTOTYPES) // Description: Definition of local functions (visible by this module only). //================================================================================================= BOOL vEreaseUserFlash( void ); U32 vFindNextFreePointer( void ); U32 u32FindLastPointer( void ); U8 u8ConvertWordsToDoubleWords( U8 u8Words ); //================================================================================================= // Section: GLOBAL FUNCTIONS // Description: Definition (implementation) of global functions. //================================================================================================= //------------------------------------------------------------------------------------------------- // Function: USFL_boInitializeModule // Description: Initializes the module. Function must be called once immediately after power-up. // Parameters: None // Returns: Boolean TRUE if successful //------------------------------------------------------------------------------------------------- BOOL USFL_boInitializeModule( VOID ) { BOOL boOK = TRUE; if( UserFlash[0] != STARTDEF ){ boOK &= vEreaseUserFlash(); } return( boOK ); } VARH_UVariable USFL_uGetVariable ( void ){ if( u32VarPointer == 0 ) u32VarPointer = u32FindLastPointer(); } //================================================================================================= // Section: LOCAL FUNCTIONS // Descriptionn: Definition (implementation) of local functions. //================================================================================================= //------------------------------------------------------------------------------------------------- // Function: u32FindNextFreePointer // Description: Finds the next free sector in the flash for saving variables // Parameters: None // Returns: U32 next free pointer //------------------------------------------------------------------------------------------------- U32 u32FindNextFreePointer( void ){ BOOL boFound = FALSE; U32 u32Pointer = u32VarPointer; while(!boFound){ if( ( ( UserFlash[u32Pointer] >> 8 ) & 0xFFFFFF ) == VARDEF ){ U8 u8Size = UserFlash[u32Pointer] & 0xFF; if( u8Size == 0 ){ boFound = TRUE; } else { u32Pointer += u8ConvertWordsToDoubleWords(u8Size); } } else { u32Pointer += 1; } if( u32Pointer >= USERFLASHSIZE ){ u32Pointer = 1; break; } } return u32Pointer; } //------------------------------------------------------------------------------------------------- // Function: u32FindLastPointer // Description: Finds the next free sector in the flash for saving variables // Parameters: None // Returns: U32 next free pointer //------------------------------------------------------------------------------------------------- U32 u32FindLastPointer( void ){ BOOL boFound = FALSE; U32 u32Pointer = 0; U8 u8LastSize = 0; while(!boFound){ if( ( UserFlash[u32Pointer] >> 40) == VARDEF ){ U8 u8Size = UserFlash[u32Pointer] & 0xFF; if( u8Size == 0 ){ boFound = TRUE; u32Pointer -= u8ConvertWordsToDoubleWords(u8LastSize); } else { u32Pointer += u8ConvertWordsToDoubleWords(u8Size); u8LastSize = u8Size; } } else { u32Pointer += 1; } if( u32Pointer >= USERFLASHSIZE ){ u32Pointer = 1; break; } } return u32Pointer; } //------------------------------------------------------------------------------------------------- // Function: u8ConvertWordsToDoubleWords // Description: Converts 32Bit Word size to 64 Bit Double Word size for saving Vars // Parameters: U8 u8Words // Returns: U8 Double Words //------------------------------------------------------------------------------------------------- U8 u8ConvertWordsToDoubleWords( U8 u8Words ) { U8 u8DWords; u8Words += 1; // + VARDEF u8DWords = u8Words / 2; u8DWords += u8Words % 2; return u8DWords; } //------------------------------------------------------------------------------------------------- // Function: vEreaseUserFlash // Description: Ereases the User Flash Sector // Parameters: None // Returns: Boolean TRUE if successful //------------------------------------------------------------------------------------------------- BOOL vEreaseUserFlash( void ){ uint32_t u32PageError = 0; BOOL boOK = TRUE; HAL_FLASH_Unlock(); boOK &= HAL_FLASHEx_Erase(&stEreaseInit, &u32PageError) == HAL_OK ? TRUE : FALSE; if( !boOK ){ return FALSE; } HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (U32) &UserFlash[0], STARTDEF); HAL_FLASH_Lock(); return TRUE; }