changeset 571:91a8f9893e68

Reactivate compass parameter stored in NVM: The calibration parameters are stored in NVM but the automatic restore function during startup was no longer active. As result the compass needed to be calibration after every RTE update. In addition compass HW was detected at every startup causing some i2c "trouble" because of adressing not available devices. The compass HW info is now stored together with the calibration parameters to avoid i2C problems.
author Ideenmodellierer
date Wed, 25 Nov 2020 20:16:20 +0100
parents 701ead8dddab
children f3463c06b2d3
files Small_CPU/Inc/RTE_FlashAccess.h Small_CPU/Inc/i2c.h Small_CPU/Src/RTE_FlashAccess.c Small_CPU/Src/compass.c
diffstat 4 files changed, 98 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- a/Small_CPU/Inc/RTE_FlashAccess.h	Mon Nov 30 20:55:23 2020 +0100
+++ b/Small_CPU/Inc/RTE_FlashAccess.h	Wed Nov 25 20:16:20 2020 +0100
@@ -43,10 +43,43 @@
 	BFA_EMPTY,
 };
 
+/// split word to 2 bytes
+typedef struct{
+uint8_t low; ///< split word to 2 bytes
+uint8_t hi; ///< split word to 2 bytes
+} two_byte;
+
+
+/// split word to 2 bytes
+typedef union{
+two_byte Byte; ///< split word to 2 bytes
+uint16_t Word; ///< split word to 2 bytes
+} tword;
+
+
+/// split signed word to 2 bytes
+typedef union{
+two_byte Byte; ///< split signed word to 2 bytes
+int16_t Word; ///< split signed word to 2 bytes
+} signed_tword;
+
+
+/// split full32 to 2 words
+typedef struct{
+uint16_t low16; ///< split word to 2 bytes
+uint16_t hi16; ///< split word to 2 bytes
+} two_word;
+
+typedef union{
+two_word Word16; ///< split word to 2 bytes
+uint32_t Full32; ///< split word to 2 bytes
+} tfull32;
+
 	 /* Exported functions --------------------------------------------------------*/
 
-uint8_t BFA_readLastDataBlock(uint32_t *dataArray4);
-uint8_t BFA_writeDataBlock(const uint32_t *dataArray4);
+uint8_t BFA_readLastDataBlock(tfull32 *dataArray4);
+uint8_t BFA_writeDataBlock(const tfull32 *dataArray4);
+uint16_t BFA_calc_Block_Checksum(const tfull32 *dataArray4);
 
 #ifdef __cplusplus
 }
--- a/Small_CPU/Inc/i2c.h	Mon Nov 30 20:55:23 2020 +0100
+++ b/Small_CPU/Inc/i2c.h	Wed Nov 25 20:16:20 2020 +0100
@@ -8,9 +8,15 @@
 
 /* Compass/Accelerometer */
 #define COMPASS_NOT_RECOGNIZED  		0xAA	///< id used with hardwareCompass
-#define	compass_generation1				0x01	// Hardware gen 1 (Two chip solution with MMA8452Q and HMC5883L)
-#define	compass_generation2				0x02	// Hardware gen 2 (Single chip solution LSM303D)
-#define	compass_generation3				0x03	// Hardware gen 3 (Single chip solution LSM303AGR)
+
+typedef enum
+{
+	compass_generation_undef =			0x00,
+	compass_generation1,						// Hardware gen 1 (Two chip solution with MMA8452Q and HMC5883L)
+	compass_generation2,						// Hardware gen 2 (Single chip solution LSM303D)
+	compass_generation3,						// Hardware gen 3 (Single chip solution LSM303AGR)
+	compass_generation_future
+} compass_generation_t;
 
 #define DEVICE_ACCELARATOR_MMA8452Q 	0x38	// Hardware gen 1 (Two chip solution with MMA8452Q and HMC5883L)
 #define DEVICE_COMPASS_HMC5883L			0x3C	// Hardware gen 1 (Two chip solution with MMA8452Q and HMC5883L)
--- a/Small_CPU/Src/RTE_FlashAccess.c	Mon Nov 30 20:55:23 2020 +0100
+++ b/Small_CPU/Src/RTE_FlashAccess.c	Wed Nov 25 20:16:20 2020 +0100
@@ -75,7 +75,7 @@
 
 /* Exported functions --------------------------------------------------------*/
 
-uint8_t BFA_readLastDataBlock(uint32_t *dataArray4)
+uint8_t BFA_readLastDataBlock(tfull32 *dataArray4)
 {
 	uint8_t answer;
 	
@@ -83,15 +83,15 @@
 	if(answer != BFA_OK)
 		return answer;
 
-	dataArray4[0] = *(__IO uint32_t*)(Address +  0);
-	dataArray4[1] = *(__IO uint32_t*)(Address +  4);
-	dataArray4[2] = *(__IO uint32_t*)(Address +  8);
-	dataArray4[3] = *(__IO uint32_t*)(Address + 12);
+	dataArray4[0].Full32 = *(__IO uint32_t*)(Address +  0);
+	dataArray4[1].Full32 = *(__IO uint32_t*)(Address +  4);
+	dataArray4[2].Full32 = *(__IO uint32_t*)(Address +  8);
+	dataArray4[3].Full32 = *(__IO uint32_t*)(Address + 12);
 	return BFA_OK;
 }
 
 
-uint8_t BFA_writeDataBlock(const uint32_t *dataArray4)
+uint8_t BFA_writeDataBlock(const tfull32 *dataArray4)
 {
 	uint8_t answer;
 	uint32_t dataTest[4];
@@ -128,14 +128,25 @@
 	HAL_FLASH_Unlock();
 	for(int i=0;i<4;i++)
 	{
-		answer = HAL_FLASH_Program(TYPEPROGRAM_WORD, Address, dataArray4[i]);
+		answer = HAL_FLASH_Program(TYPEPROGRAM_WORD, Address, dataArray4[i].Full32);
 		Address = Address + 4;
 	}
 	HAL_FLASH_Lock();
 	Address = StartAddress; // back to start of this data set (for reading etc.)
 	return answer;
 }
+uint16_t BFA_calc_Block_Checksum(const tfull32 *dataArray4)
+{
+	uint16_t checksum = 0;
+	uint8_t loop = 0;
+	uint16_t* p_data = (uint16_t*)dataArray4;
 
+	for (loop = 0; loop < 6; loop++) // calc checksum across first 6 words */
+	{
+		checksum += *p_data;
+	}
+	return checksum;
+}
 
 /* Private functions ---------------------------------------------------------*/
 /*
--- a/Small_CPU/Src/compass.c	Mon Nov 30 20:55:23 2020 +0100
+++ b/Small_CPU/Src/compass.c	Wed Nov 25 20:16:20 2020 +0100
@@ -43,38 +43,6 @@
 extern uint32_t time_elapsed_ms(uint32_t ticksstart,uint32_t ticksnow);
 extern SGlobal global;
 
-/// split word to 2 bytes
-typedef struct{
-uint8_t low; ///< split word to 2 bytes
-uint8_t hi; ///< split word to 2 bytes
-} two_byte; 
-	
-
-/// split word to 2 bytes
-typedef union{
-two_byte Byte; ///< split word to 2 bytes
-uint16_t Word; ///< split word to 2 bytes
-} tword; 
-
-
-/// split signed word to 2 bytes
-typedef union{
-two_byte Byte; ///< split signed word to 2 bytes
-int16_t Word; ///< split signed word to 2 bytes
-} signed_tword; 
-
-
-/// split full32 to 2 words
-typedef struct{
-uint16_t low16; ///< split word to 2 bytes
-uint16_t hi16; ///< split word to 2 bytes
-} two_word; 
-
-typedef union{
-two_word Word16; ///< split word to 2 bytes
-uint32_t Full32; ///< split word to 2 bytes
-} tfull32; 
-
 
 /// crazy compass calibration stuff
 typedef struct
@@ -132,7 +100,7 @@
 
 uint8_t compass_gain; ///< 7 on start, can be reduced during calibration
 
-uint8_t  hardwareCompass = 0;	///< either HMC5883L (=1) or LSM303D (=2) or LSM303AGR (=3) or not defined yet (=0)
+uint8_t  hardwareCompass = compass_generation_undef;	///< either HMC5883L (=1) or LSM303D (=2) or LSM303AGR (=3) or not defined yet (=0)
 
 /// LSM303D variables
 uint8_t magDataBuffer[6];	///< here raw data from LSM303D is stored, can be local
@@ -224,8 +192,27 @@
 		return;
 	}
 	
+	if(hardwareCompass == compass_generation_undef)					/* check if compass had been detected before */
+	{
+		tfull32 dataBlock[4];
+		if(BFA_readLastDataBlock(dataBlock) == BFA_OK)
+		{
+			if(dataBlock[3].Word16.hi16 == BFA_calc_Block_Checksum(dataBlock))
+			{
+				compass_CX_f = dataBlock[0].Word16.low16;
+				compass_CY_f = dataBlock[0].Word16.hi16;
+				compass_CZ_f = dataBlock[1].Word16.low16;
+				hardwareCompass = dataBlock[1].Word16.hi16;
+				if(hardwareCompass >= compass_generation_future)		/* no generation stored (including COMPASS_NOT_RECOGNIZED) */
+				{
+					hardwareCompass = compass_generation_undef;
+				}
+			}
+		}
+	}
+
 // old code but without else
-	if(hardwareCompass == 0)
+	if(hardwareCompass == compass_generation_undef)
 	{
 		uint8_t data = WHO_AM_I;
 		I2C_Master_Transmit( DEVICE_COMPASS_303D, &data, 1);
@@ -240,7 +227,7 @@
 	}
 
 /* No compass identified => Retry */
-	if(hardwareCompass == 0)
+	if(hardwareCompass == compass_generation_undef)
 	{
 		I2C_DeInit();
 		HAL_Delay(100);
@@ -259,7 +246,7 @@
 	}
 
 /* Assume that a HMC5883L is equipped by default if detection still failed */
-	if(hardwareCompass == 0)
+	if(hardwareCompass == compass_generation_undef)
 		hardwareCompass = compass_generation1;				//HMC5883L;
 	
 	HAL_StatusTypeDef resultOfOperationHMC_MMA = HAL_TIMEOUT;
@@ -296,14 +283,6 @@
 		global.deviceDataSendToMaster.hw_Info.compass = hardwareCompass;
 		global.deviceDataSendToMaster.hw_Info.checkCompass = 1;
 	}
-	tfull32 dataBlock[4];
-	if(BFA_readLastDataBlock((uint32_t *)dataBlock) == BFA_OK)
-		{
-			compass_CX_f = dataBlock[0].Word16.low16;
-			compass_CY_f = dataBlock[0].Word16.hi16;
-			compass_CZ_f = dataBlock[1].Word16.low16;
-		}
-
 }
 
 
@@ -1382,15 +1361,19 @@
         
     compass_solve_calibration(&g);
 		
-	tfull32 dataBlock[4];
-	dataBlock[0].Word16.low16 = compass_CX_f;
-	dataBlock[0].Word16.hi16 = compass_CY_f;
-	dataBlock[1].Word16.low16 = compass_CZ_f;
-	dataBlock[1].Word16.hi16 = 0xFFFF;
-	dataBlock[2].Full32 = 0x7FFFFFFF;
-	dataBlock[3].Full32 = 0x7FFFFFFF;
-	BFA_writeDataBlock((uint32_t *)dataBlock);
-	
+    if((hardwareCompass != compass_generation_undef)		/* if compass is not know at this point in time storing data makes no sense */
+    	&& (hardwareCompass != COMPASS_NOT_RECOGNIZED))
+    {
+		tfull32 dataBlock[4];
+		dataBlock[0].Word16.low16 = compass_CX_f;
+		dataBlock[0].Word16.hi16 = compass_CY_f;
+		dataBlock[1].Word16.low16 = compass_CZ_f;
+		dataBlock[1].Word16.hi16 = hardwareCompass;
+		dataBlock[2].Full32 = 0x7FFFFFFF;
+		dataBlock[3].Word16.low16 = 0xFFFF;
+		dataBlock[3].Word16.hi16 = BFA_calc_Block_Checksum(dataBlock);
+		BFA_writeDataBlock(dataBlock);
+    }
 	return 0;
 }