changeset 1017:5924a2d1d3ba GasConsumption

Prepare custom block update function: In the flash area of the font lib some sectors may be used for custom data or a boot updater image. With this change a flash option is added to the maintainance menu. IMPORTANT: The fimwareEraseProgram.c is needed for compiling the firmware now => Add it e.g. by adding a link from the OtherSources location to your source folder.
author Ideenmodellierer
date Thu, 29 May 2025 22:04:46 +0200 (2 months ago)
parents 8c0134a287da
children 808153ba3fec
files Common/Inc/settings.h Discovery/Inc/firmwareEraseProgram.h Discovery/Inc/tMenuSystem.h Discovery/Inc/tStructure.h Discovery/Src/data_central.c Discovery/Src/settings.c Discovery/Src/tComm.c Discovery/Src/tMenuEditSystem.c OtherSources/firmwareEraseProgram.c
diffstat 9 files changed, 249 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/Common/Inc/settings.h	Sun May 11 16:18:20 2025 +0200
+++ b/Common/Inc/settings.h	Thu May 29 22:04:46 2025 +0200
@@ -32,8 +32,7 @@
 
 // From Common/Inc:
 #include "FirmwareData.h"
-
-//#include "data_central.h"
+#include "firmwareEraseProgram.h"
 
 #include "global_constants.h"
 // From Common/Drivers/
@@ -332,33 +331,6 @@
 	uint8_t warningBuzzer;
 } SSettings;
 
-typedef struct
-{
-	// 8 bytes
-	uint16_t primarySerial;
-	uint8_t primaryLicence;
-	uint8_t revision8bit;
-	uint8_t production_year;
-	uint8_t production_month;
-	uint8_t production_day;
-	uint8_t production_bluetooth_name_set;
-
-	// 44 bytes
-	char production_info[44];
-
-	// 8 bytes
-	uint16_t secondarySerial;
-	uint8_t secondaryLicence;
-	uint8_t secondaryReason8bit;
-	uint8_t secondary_year;
-	uint8_t secondary_month;
-	uint8_t secondary_day;
-	uint8_t secondary_bluetooth_name_set;
-
-	// 4 bytes
-	char secondary_info[4];
-} SHardwareData;
-
 uint8_t writeData(uint8_t *);
 uint8_t readData(uint8_t what,uint8_t *);
 uint8_t readDataLimits__8and16BitValues_4and7BytesOutput(uint8_t what, uint8_t * data);
--- a/Discovery/Inc/firmwareEraseProgram.h	Sun May 11 16:18:20 2025 +0200
+++ b/Discovery/Inc/firmwareEraseProgram.h	Thu May 29 22:04:46 2025 +0200
@@ -41,11 +41,42 @@
 #define HARDWAREDATA_ADDRESS	(0x08000000 + 0x0000A040)
 /* Exported functions --------------------------------------------------------*/
 
+ typedef struct
+ {
+ 	// 8 bytes
+ 	uint16_t primarySerial;
+ 	uint8_t primaryLicence;
+ 	uint8_t revision8bit;
+ 	uint8_t production_year;
+ 	uint8_t production_month;
+ 	uint8_t production_day;
+ 	uint8_t production_bluetooth_name_set;
 
+ 	// 44 bytes
+ 	char production_info[44];
+
+ 	// 8 bytes
+ 	uint16_t secondarySerial;
+ 	uint8_t secondaryLicence;
+ 	uint8_t secondaryReason8bit;
+ 	uint8_t secondary_year;
+ 	uint8_t secondary_month;
+ 	uint8_t secondary_day;
+ 	uint8_t secondary_bluetooth_name_set;
+
+ 	// 4 bytes
+ 	char secondary_info[4];
+ } SHardwareData;
+
+
+uint32_t CalcFletcher32(uint32_t startAddr, uint32_t endAddr);
 
 uint8_t firmware_eraseFlashMemory(void);
 uint8_t firmware_programFlashMemory(uint8_t *pBuffer1, uint32_t length1);//, uint8_t *pBuffer2, uint32_t length2)
 
+uint8_t bootloader_eraseFlashMemory(void);
+uint8_t bootloader_programFlashMemory(uint8_t *pBuffer1, uint32_t length1, SHardwareData* pHwInfo);
+
 uint8_t firmware2_variable_upperpart_eraseFlashMemory(uint32_t length, uint32_t offset);
 uint8_t firmware2_variable_upperpart_programFlashMemory(uint32_t length, uint32_t offset, uint8_t *pBuffer1, uint32_t pBuffer1Size, uint8_t *pBuffer2);
 
--- a/Discovery/Inc/tMenuSystem.h	Sun May 11 16:18:20 2025 +0200
+++ b/Discovery/Inc/tMenuSystem.h	Thu May 29 22:04:46 2025 +0200
@@ -36,6 +36,16 @@
 	* @{
 	*/
 
+#define CUSTOM_BLOCK_INFO_ADDR	(0x0811FFF0)
+
+typedef struct
+{
+    uint32_t Reserved;		/* for future use */
+    uint32_t Type;			/* type => block purpose */
+    uint32_t fletcher;		/* fletcher check sum */
+    uint32_t length;		/* length of block starting from 0x08100000 */
+} customBlockInfo_t;
+
 void set_CustomsviewsSubpage(uint8_t page);
 
 /* Exported variables --------------------------------------------------------*/
--- a/Discovery/Inc/tStructure.h	Sun May 11 16:18:20 2025 +0200
+++ b/Discovery/Inc/tStructure.h	Thu May 29 22:04:46 2025 +0200
@@ -340,6 +340,7 @@
 #define StMSYS5_ResetBluetooth	_MB(2,8,5,12,0)
 #define StMSYS5_SetSampleIndx   _MB(2,8,5,13,0)
 #define StMSYS5_AdjustSurfPres  _MB(2,8,5,14,0)
+#define StMSYS5_FlashBoot		_MB(2,8,5,15,0)
 
 #define StMSYS_Custom0			_MB(2,8,1,0,0)
 #define StMSYS_Custom1			_MB(2,8,2,0,0)
--- a/Discovery/Src/data_central.c	Sun May 11 16:18:20 2025 +0200
+++ b/Discovery/Src/data_central.c	Thu May 29 22:04:46 2025 +0200
@@ -717,10 +717,12 @@
 
 uint32_t	CRC_CalcBlockCRC_moreThan768000(uint32_t *buffer1, uint32_t *buffer2, uint32_t words)
 {
- cm_t        crc_model;
- uint32_t      word_to_do;
- uint8_t       byte_to_do;
- int         i;
+	 cm_t        crc_model;
+	 uint32_t      word_to_do;
+	 uint8_t       byte_to_do;
+	 int         i;
+
+	 uint32_t wordCnt = 0;
  
      // Values for the STM32F generator.
  
@@ -733,10 +735,10 @@
  
      cm_ini(&crc_model);
  
-     while (words--)
+     do
      {
          // The STM32F10x hardware does 32-bit words at a time!!!
-				if(words > (768000/4))
+				if(wordCnt >= (768000/4))
 					word_to_do = *buffer2++;
 				else
 					word_to_do = *buffer1++;
@@ -765,7 +767,8 @@
  
              cm_nxt(&crc_model, byte_to_do);
          }
-     }
+         wordCnt++;
+     } while (wordCnt != words);
  
      // Return the final result.
  
--- a/Discovery/Src/settings.c	Sun May 11 16:18:20 2025 +0200
+++ b/Discovery/Src/settings.c	Thu May 29 22:04:46 2025 +0200
@@ -1914,6 +1914,7 @@
 }
 
 
+#if 0
 #ifndef SPECIALPROGRAMM
 const SHardwareData* hardwareDataGetPointer(void)
 {
@@ -1921,6 +1922,7 @@
 }
 #endif
 #endif
+#endif
 const SSettings* settingsGetPointerStandard(void)
 {
     return &SettingsStandard;
--- a/Discovery/Src/tComm.c	Sun May 11 16:18:20 2025 +0200
+++ b/Discovery/Src/tComm.c	Thu May 29 22:04:46 2025 +0200
@@ -1572,7 +1572,10 @@
 
     // neu 110212
     if(id == id_FONT)
+    {
         offsetTotal = 256 * 256 * 256 * (uint32_t)sBuffer[1] +  256 * 256 * (uint32_t)sBuffer[2] + 256 * (uint32_t)sBuffer[3];
+       /* todo set offset depending on font version offsetTotal = 0; */
+    }
     else
         offsetTotal = 256 * 256 * 256 * (uint32_t)sBuffer[0] +  256 * 256 * (uint32_t)sBuffer[1] + 256 * (uint32_t)sBuffer[2] + sBuffer[3];
 
--- a/Discovery/Src/tMenuEditSystem.c	Sun May 11 16:18:20 2025 +0200
+++ b/Discovery/Src/tMenuEditSystem.c	Thu May 29 22:04:46 2025 +0200
@@ -58,6 +58,19 @@
 //void openEdit_ShowDebugInfo(void);
 //void openEdit_Salinity(void);
 
+static uint32_t swapBytes(uint32_t source)
+{
+	uint32_t ret = 0;
+
+	ret =  		((source & 0x000000FF) << 24)
+			| 	((source & 0x0000FF00) <<  8)
+			| 	((source & 0x00FF0000) >>  8)
+			| 	((source & 0xFF000000) >> 24);
+
+	return ret;
+}
+
+
 /* Announced function prototypes -----------------------------------------------*/
 uint8_t OnAction_Date					(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_Time					(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
@@ -101,7 +114,9 @@
 #ifdef SCREENTEST
 uint8_t OnAction_ScreenTest		(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 #endif
-uint8_t OnAction_Information	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+uint8_t OnAction_Information	 (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+uint8_t OnAction_FlashBootloader (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
+
 /*
 uint8_t OnAction_Salinity			(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
 uint8_t OnAction_TestCLog			(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action);
@@ -1383,6 +1398,8 @@
     write_buttonTextline(TXT2BYTE_ButtonBack,TXT2BYTE_ButtonEnter,TXT2BYTE_ButtonNext);
 }
 
+customBlockInfo_t blockInfo;
+
 void openEdit_Maintenance(void)
 {
     char text[32];
@@ -1390,6 +1407,12 @@
     SSettings *pSettings = settingsGetPointer();
     SSensorDataDiveO2* pDiveO2Data = NULL;
 
+    customBlockInfo_t* pCustumBlockInfo = (customBlockInfo_t *) CUSTOM_BLOCK_INFO_ADDR;
+
+    blockInfo.Type = swapBytes(pCustumBlockInfo->Type);
+    blockInfo.fletcher = swapBytes(pCustumBlockInfo->fletcher);
+    blockInfo.length = swapBytes(pCustumBlockInfo->length);
+
     resetMenuEdit(CLUT_MenuPageSystem);
 
     text[0] = '\001';
@@ -1432,6 +1455,12 @@
     	}
     }
 
+    if((blockInfo.Type & 0x0000FF00)== 0x0100)
+    {
+    	snprintf(text,32,"Flash Bootloader");
+		write_field_button(StMSYS5_FlashBoot,			30, 800, ME_Y_LINE4,  &FontT48, text);
+    }
+
 #ifdef ENABLE_ANALYSE_SAMPLES
     text[0] = TXT_2BYTE;
     text[1] = TXT2BYTE_SetSampleIndex;
@@ -1455,6 +1484,12 @@
     setEvent(StMSYS5_SetSampleIndx, (uint32_t)OnAction_RecoverSampleIdx);
 #endif
 
+    if((blockInfo.Type & 0x0000FF00)== 0x0100)
+    {
+    	setEvent(StMSYS5_FlashBoot, (uint32_t)OnAction_FlashBootloader);
+    }
+
+
 
     text[0] = TXT_2BYTE;
     text[1] = TXT2BYTE_WarnBatteryLow;
@@ -1670,6 +1705,31 @@
     FrameCount++;
 }
 #endif
+
+uint8_t OnAction_FlashBootloader (uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
+{
+	SHardwareData HwInfo;
+    customBlockInfo_t* pCustumBlockInfo = (customBlockInfo_t *) CUSTOM_BLOCK_INFO_ADDR;
+    customBlockInfo_t blockInfo;
+    uint32_t checksum;
+    uint8_t* pSource = (uint8_t *) 0x08100000;
+
+    checksum = CalcFletcher32(0x08100000,0x0811FFEF);	/* last nibble contains block info => exclude */
+
+    blockInfo.Type = swapBytes(pCustumBlockInfo->Type);
+    blockInfo.fletcher = swapBytes(pCustumBlockInfo->fletcher);
+    blockInfo.length = swapBytes(pCustumBlockInfo->length);
+
+    if(checksum == blockInfo.fletcher)
+    {
+		memcpy (&HwInfo, hardwareDataGetPointer(), sizeof(SHardwareData)); /* create backup copy because data will be overwritten during flash erase */
+
+		bootloader_eraseFlashMemory();
+		bootloader_programFlashMemory(pSource, blockInfo.length, &HwInfo);
+    }
+	return UNSPECIFIC_RETURN;
+}
+
 /*
 uint8_t OnAction_TestCLog	(uint32_t editId, uint8_t blockNumber, uint8_t digitNumber, uint8_t digitContent, uint8_t action)
 {
--- a/OtherSources/firmwareEraseProgram.c	Sun May 11 16:18:20 2025 +0200
+++ b/OtherSources/firmwareEraseProgram.c	Thu May 29 22:04:46 2025 +0200
@@ -83,6 +83,9 @@
 
 #define SECTOR_SIZE_128KB     ((uint32_t)0x00020000) 
 
+#define FLASH_BOOT_START_ADDR   ADDR_FLASH_SECTOR_0
+#define FLASH_BOOT_END_ADDR     (ADDR_FLASH_SECTOR_5 - 1)
+
 #define FLASH_FW_START_ADDR   ADDR_FLASH_SECTOR_6
 #define FLASH_FW_END_ADDR     (ADDR_FLASH_SECTOR_12 - 1)
 
@@ -447,6 +450,133 @@
 	
 }
 
+
+uint8_t bootloader_eraseFlashMemory(void)
+{
+//	HAL_StatusTypeDef answer;
+  /* Unlock the Flash to enable the flash control register access *************/
+  HAL_FLASH_Unlock();
+
+  /* Erase the user Flash area
+    (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
+
+  /* Get the 1st sector to erase */
+  FirstSector = GetSector(FLASH_BOOT_START_ADDR);
+  /* Get the number of sector to erase from 1st sector*/
+  NbOfSectors = GetSector(FLASH_BOOT_END_ADDR) - FirstSector + 1;
+
+  /* Fill EraseInit structure*/
+  EraseInitStruct.TypeErase = FLASH_TYPEERASE_SECTORS;
+  EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_1;
+  EraseInitStruct.Sector = FirstSector;
+  EraseInitStruct.NbSectors = NbOfSectors;
+
+  /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
+     you have to make sure that these data are rewritten before they are accessed during code
+     execution. If this cannot be done safely, it is recommended to flush the caches by setting the
+     DCRST and ICRST bits in the FLASH_CR register. */
+	return HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
+}
+
+uint8_t bootloader_programFlashMemory(uint8_t *pBuffer1, uint32_t length1, SHardwareData* pHwInfo)
+{
+	HAL_StatusTypeDef answer;
+
+  /* Program the user Flash area word by word
+    (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
+
+	uint32_t index = 0;
+	Address = FLASH_BOOT_START_ADDR;
+
+	uint8_t* pHardwareInfo = (uint8_t*) pHwInfo;
+	uint8_t tmp = 0;
+
+	index = 0;
+	while ((Address <= FLASH_FW_END_ADDR) && (index < length1))
+	{
+		if((Address >= HARDWAREDATA_ADDRESS) && (Address < HARDWAREDATA_ADDRESS + sizeof(SHardwareData)))
+		{
+			answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, *pHardwareInfo++);
+		}
+		else
+		{
+			answer = HAL_FLASH_Program(FLASH_TYPEPROGRAM_BYTE, Address, pBuffer1[index]);
+		}
+		if (answer == HAL_OK)
+		{
+			Address = Address + 1;
+			index++;
+		}
+		else
+		{
+				return answer;
+		}
+	}
+  /* Lock the Flash to disable the flash control register access (recommended
+     to protect the FLASH memory against possible unwanted operation) *********/
+	HAL_FLASH_Lock();
+
+  /* Check if the programmed data is OK
+      MemoryProgramStatus = 0: data programmed correctly
+      MemoryProgramStatus != 0: number of words not programmed correctly ******/
+	Address = FLASH_BOOT_START_ADDR;
+	MemoryProgramStatus = 0x0;
+
+	index = 0;
+	pHardwareInfo = (uint8_t*) pHwInfo;
+
+	while ((Address <= FLASH_FW_END_ADDR) && (index < length1))
+	{
+		if((Address >= HARDWAREDATA_ADDRESS) && (Address < HARDWAREDATA_ADDRESS + sizeof(SHardwareData)))
+		{
+			tmp = *pHardwareInfo++;
+		}
+		else
+		{
+			tmp = pBuffer1[index];
+		}
+
+		data32 = *(__IO uint8_t*)Address;
+		if (data32 != tmp)
+		{
+			MemoryProgramStatus++;
+		}
+
+		Address = Address + 1;
+		index++;
+	}
+  /* Check if there is an issue to program data */
+	if (MemoryProgramStatus == 0)
+	{
+		return HAL_OK;
+    /* No error detected. Switch on LED3 */
+	}
+	else
+	{
+		return 0xEE;
+	}
+}
+
+
+uint32_t CalcFletcher32(uint32_t startAddr, uint32_t endAddr)
+{
+	uint32_t fletcher = 0;
+	uint16_t* pData = (uint16_t*) startAddr;
+	uint32_t index = 0;
+
+	uint16_t sum1 = 0;
+	uint16_t sum2 = 0;
+	for(index = startAddr; index <= endAddr; index +=2)
+	{
+		sum1 = sum1 + *pData++;
+	    sum2 = (sum2 + sum1);
+	}
+	fletcher = (sum2 << 16) | sum1;
+
+	return fletcher;
+}
+
+
 /* Private functions ---------------------------------------------------------*/
 
 /**