changeset 332:39f146ccdb1b

Merged in Ideenmodellierer/ostc4/I2C_Improvment (pull request #30) I2C Improvment
author heinrichsweikamp <bitbucket@heinrichsweikamp.com>
date Thu, 18 Jul 2019 14:26:56 +0000
parents 2559a3f0f1f2 (current diff) b4c578caaafb (diff)
children be1f74d5b3cb
files
diffstat 7 files changed, 175 insertions(+), 66 deletions(-) [+]
line wrap: on
line diff
--- a/Small_CPU/Inc/batteryGasGauge.h	Mon Jul 01 14:18:39 2019 +0000
+++ b/Small_CPU/Inc/batteryGasGauge.h	Thu Jul 18 14:26:56 2019 +0000
@@ -29,6 +29,8 @@
 
 /* Includes ------------------------------------------------------------------*/
 
+#include <stdint.h>
+
 void init_battery_gas_gauge(void);
 
 float get_voltage(void);
@@ -37,6 +39,7 @@
 void battery_gas_gauge_get_data(void);
 void battery_gas_gauge_set_charge_full(void);
 void battery_gas_gauge_set(float percentage);
+uint8_t battery_gas_gauge_CheckConfigOK(void);
 
 #ifdef __cplusplus
 }
--- a/Small_CPU/Src/baseCPU2.c	Mon Jul 01 14:18:39 2019 +0000
+++ b/Small_CPU/Src/baseCPU2.c	Thu Jul 18 14:26:56 2019 +0000
@@ -302,19 +302,25 @@
 
 /*	printf("CPU2-RTE running...\n"); */
 
+	HAL_Delay(100);
+
 	MX_I2C1_Init();
-	if (global.I2C_SystemStatus != HAL_OK) {
+	if (global.I2C_SystemStatus != HAL_OK)
+	{
 		if (MX_I2C1_TestAndClear() == GPIO_PIN_RESET) {
 			MX_I2C1_TestAndClear(); // do it a second time
 		}
 		MX_I2C1_Init();
 	}
 
+
+
 	//dangerous:	TM_OTP_Write(0,0, 0x01);
 #ifdef REGULAR_RUN
 	global.sensorError[SENSOR_PRESSURE_ID] = init_pressure();
 	global.I2C_SystemStatus = global.sensorError[SENSOR_PRESSURE_ID];
-	if (global.I2C_SystemStatus != HAL_OK) {
+	if (global.I2C_SystemStatus != HAL_OK)
+	{
 		if (MX_I2C1_TestAndClear() == GPIO_PIN_RESET) {
 			MX_I2C1_TestAndClear(); // do it a second time
 		}
@@ -325,7 +331,11 @@
 
 	global.dataSendToMaster.sensorErrors =
 			global.sensorError[SENSOR_PRESSURE_ID];
-	init_surface_ring();
+
+	if(is_init_pressure_done())
+	{
+		init_surface_ring();
+	}
 	init_battery_gas_gauge();
 	HAL_Delay(10);
 	battery_gas_gauge_get_data();
--- a/Small_CPU/Src/batteryGasGauge.c	Mon Jul 01 14:18:39 2019 +0000
+++ b/Small_CPU/Src/batteryGasGauge.c	Thu Jul 18 14:26:56 2019 +0000
@@ -22,6 +22,7 @@
   ******************************************************************************
   */ 
 /* Includes ------------------------------------------------------------------*/
+#include <string.h>	/* memset */
 #include "batteryGasGauge.h"
 #include "baseCPU2.h"
 #include "stm32f4xx_hal.h"
@@ -71,6 +72,25 @@
 	I2C_Master_Transmit(DEVICE_BATTERYGAUGE, buffer, 2);
 }
 
+uint8_t battery_gas_gauge_CheckConfigOK(void)
+{
+	#ifdef OSTC_ON_DISCOVERY_HARDWARE
+		return;
+	#endif
+
+	uint8_t retval = 0;
+	uint8_t bufferReceive[10];
+
+	memset(bufferReceive,0,sizeof(bufferReceive));
+
+	I2C_Master_Receive(DEVICE_BATTERYGAUGE, bufferReceive, 10);
+	if(bufferReceive[1] == 0xf8)
+	{
+		retval = 1;
+	}
+	return retval;
+}
+
 static void disable_adc(void)
 {
 	uint8_t buffer[2];
--- a/Small_CPU/Src/i2c.c	Mon Jul 01 14:18:39 2019 +0000
+++ b/Small_CPU/Src/i2c.c	Thu Jul 18 14:26:56 2019 +0000
@@ -31,39 +31,51 @@
 void HAL_I2C_Send_One_CLOCK(void)
 {
 	HAL_GPIO_WritePin(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_PIN, GPIO_PIN_RESET);
-	HAL_Delay(10);
+	HAL_Delay(1); 
 	HAL_GPIO_WritePin(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_PIN, GPIO_PIN_SET);
-	HAL_Delay(10);
+	HAL_Delay(1);
 }
 
 GPIO_PinState MX_I2C1_TestAndClear(void)
 {
+	GPIO_PinState retval;
+	uint8_t repeatcnt = 3;
+
 	I2C_DeInit();
 	HAL_I2C_ManualControl_MspInit();
-	for(int i=0; i<9;i++)
+	
+/* The SDA line is expected to be HIGH if no com is pending => send dummy clock signals if that is not the case */
+	do
 	{
-		if(HAL_I2C_Read_Data_PIN() == GPIO_PIN_RESET)
-			HAL_I2C_Send_One_CLOCK();
-		else
-			break;
-	}
-	return HAL_I2C_Read_Data_PIN();
+		for(int i=0; i<20;i++)
+		{
+			if(HAL_I2C_Read_Data_PIN() == GPIO_PIN_RESET)
+				HAL_I2C_Send_One_CLOCK();
+			else
+				break;
+		}
+		retval = HAL_I2C_Read_Data_PIN();
+	}while ((repeatcnt-- > 0) && (retval != GPIO_PIN_SET));
+
+	return retval;
 }
 
 HAL_StatusTypeDef MX_I2C1_Init(void)
 {
-	I2cHandle.Instance             = I2Cx;
+  I2cHandle.Instance             = I2Cx;
   I2cHandle.Init.AddressingMode  = I2C_ADDRESSINGMODE_7BIT;
-  I2cHandle.Init.ClockSpeed      = 100000;//400000; REDUCED for compatibility with  HMC5583L + MMA8452Q
-  I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLED;
-  I2cHandle.Init.DutyCycle       = I2C_DUTYCYCLE_2;
+  I2cHandle.Init.ClockSpeed      = 88000; /* Reduced to avoid behavior described in errata: Mismatch on the “Setup time for a repeated Start condition” */
+  I2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
+  I2cHandle.Init.DutyCycle       = I2C_DUTYCYCLE_2;				/* don't care if not in fast mode */
   I2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLED;
   I2cHandle.Init.NoStretchMode   = I2C_NOSTRETCH_DISABLED;
-  I2cHandle.Init.OwnAddress1     = 0x01;
+  I2cHandle.Init.OwnAddress1     = 0x01;						/* don't care because of master mode */
+
+/* According to documentation setting filters before I2C initialization is recommended */
+	/* HAL_I2CEx_AnalogFilter_Config(&I2cHandle, I2C_ANALOGFILTER_ENABLED); */
+	HAL_I2CEx_ConfigDigitalFilter(&I2cHandle,0x0F);
 
 	global.I2C_SystemStatus = HAL_I2C_Init(&I2cHandle);
-	HAL_I2CEx_AnalogFilter_Config(&I2cHandle, I2C_ANALOGFILTER_ENABLED);
-	HAL_I2CEx_ConfigDigitalFilter(&I2cHandle,0x0F);
 
 	if(global.dataSendToSlavePending)
 	{
@@ -85,12 +97,13 @@
 	i2c_errors++;
 }
 
+
 HAL_StatusTypeDef I2C_Master_Transmit(  uint16_t DevAddress, uint8_t *pData, uint16_t Size)
 {
 	if(global.I2C_SystemStatus != HAL_OK)
 		return global.I2C_SystemStatus;
 
-	global.I2C_SystemStatus = HAL_I2C_Master_Transmit(&I2cHandle, DevAddress,  pData, Size, 2);
+	global.I2C_SystemStatus = HAL_I2C_Master_Transmit(&I2cHandle, DevAddress,  pData, Size, 10);
 	if(global.I2C_SystemStatus != HAL_OK)
 	{
 		I2C_Error_count();
--- a/Small_CPU/Src/pressure.c	Mon Jul 01 14:18:39 2019 +0000
+++ b/Small_CPU/Src/pressure.c	Thu Jul 18 14:26:56 2019 +0000
@@ -28,7 +28,7 @@
  the last 30 minutes will be saved once per minute in a endless loop
  at the beginning of a dive the oldest value will be used
 */
-
+#include "math.h"
 #include "scheduler.h"
 #include "pressure.h"
 #include "i2c.h"
@@ -46,6 +46,9 @@
 #define CMD_ADC_4096 0x08 // ADC OSR=4096
 #define CMD_PROM_RD 0xA0 // Prom read command
 
+#define PRESSURE_HISTORY_SIZE			(8u)
+#define PRESSURE_JUMP_VALID_MBAR	    (500.0f)		/* values are measure several times a second => jumps > 5m very unlikely */
+
 static uint16_t get_ci_by_coef_num(uint8_t coef_num);
 //void pressure_calculation_new(void);
 //void pressure_calculation_old(void);
@@ -74,10 +77,12 @@
 */
 
 static float ambient_temperature = 0;
-static float ambient_pressure_mbar = 0;
-static float surface_pressure_mbar = 1000;
+static float ambient_pressure_mbar = 1000.0;
+static float surface_pressure_mbar = 1000.0;
 static float surface_ring_mbar[31] = { 0 };
 
+static float pressure_history_mbar[PRESSURE_HISTORY_SIZE];
+
 uint8_t secondCounterSurfaceRing = 0;
 
 float get_temperature(void)
@@ -104,6 +109,13 @@
 	surface_pressure_mbar = ambient_pressure_mbar;
 }
 
+void init_pressure_history(void)
+{
+	for(int i=0; i<PRESSURE_HISTORY_SIZE; i++)
+	{
+		pressure_history_mbar[i] = 1000.0;
+	}
+}
 
 /* the ring has one place with 0
  * after that comes the oldest value
@@ -119,17 +131,20 @@
 	
 	secondCounterSurfaceRing = 0;
 	
-	int hole;
-	for(hole=30;hole>0;hole--)
-		if(surface_ring_mbar[hole] == 0) { break; }
-
-	surface_ring_mbar[hole] = ambient_pressure_mbar;
+	if(is_init_pressure_done())
+	{
+		int hole;
+		for(hole=30;hole>0;hole--)
+			if(surface_ring_mbar[hole] == 0) { break; }
 
-	hole++;
-	if(hole > 30)
-		hole = 0;
-	surface_pressure_mbar = surface_ring_mbar[hole];
-	surface_ring_mbar[hole] = 0;
+		surface_ring_mbar[hole] = ambient_pressure_mbar;
+
+		hole++;
+		if(hole > 30)
+			hole = 0;
+		surface_pressure_mbar = surface_ring_mbar[hole];
+		surface_ring_mbar[hole] = 0;
+	}
 }
 
 #ifdef DEMOMODE
@@ -209,29 +224,6 @@
 }
 #endif
 
-
-/* called just once on power on */
-/* TBD old DR5 code? */
-void init_pressure_DRx(void)
-{
-	uint8_t resetCommand[1] = {0x1E};
-
-	I2C_Master_Transmit(  DEVICE_PRESSURE, resetCommand, 1);
-	HAL_Delay(3);
-
-	C[1] =	get_ci_by_coef_num(0x02);
-	C[2] =	get_ci_by_coef_num(0x04);
-	C[3] =	get_ci_by_coef_num(0x06);
-	C[4] =	get_ci_by_coef_num(0x08);
-	C[5] =	get_ci_by_coef_num(0x0A);
-	C[6] =	get_ci_by_coef_num(0x0C);
-	
-	C5_x_2p8  = C[5] * 256;
-	C2_x_2p16 = C[2] * 65536;
-	C1_x_2p15 = C[1] * 32768;
-	pressure_update();
-}
-
 uint8_t is_init_pressure_done(void)
 {
 	return pressureSensorInitSuccess;
@@ -243,7 +235,10 @@
 	buffer[0] = 0x1e;
 	uint8_t retValue = 0xFF;
 	
-	
+	pressureSensorInitSuccess = false;
+	init_pressure_history();
+
+/* Send reset request to pressure sensor */
 	retValue = I2C_Master_Transmit(  DEVICE_PRESSURE, buffer, 1);
 	if(retValue != HAL_OK)
 	{
@@ -264,8 +259,10 @@
 	if(global.I2C_SystemStatus == HAL_OK)
 	{
 		pressureSensorInitSuccess = 1;
+		retValue = pressure_update();
+
 	}
-	return pressure_update();
+	return retValue;
 }
 
 
@@ -416,6 +413,40 @@
 	pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015();
 }
 
+static uint8_t pressure_plausible(float pressurevalue)
+{
+	static uint8_t pressurewriteindex = 0;
+	uint8_t retval = 0;
+	uint8_t index;
+	float pressure_average = 0;
+
+	for(index = 0; index < PRESSURE_HISTORY_SIZE; index++)
+	{
+		pressure_average += pressure_history_mbar[index];
+	}
+	pressure_average /= PRESSURE_HISTORY_SIZE;
+	if(pressure_average == 1000.0) /* first pressure calculation */
+	{
+		if(fabs(pressurevalue - pressure_average) < 11000.0)  /* just in case a reset occure during dive assume value equal < 100m as valid */
+		{
+			for(index = 0; index < PRESSURE_HISTORY_SIZE; index++)
+			{
+				pressure_history_mbar[index] = pressurevalue;	/* set history to current value */
+				retval = 1;
+			}
+		}
+	}
+	else
+	{
+		if(fabs(pressurevalue - pressure_average) < PRESSURE_JUMP_VALID_MBAR)
+		pressure_history_mbar[pressurewriteindex++] = pressurevalue;
+		pressurewriteindex &= 0x7;	/* wrap around if necessary */
+		retval = 1;
+	}
+
+	return retval;
+}
+
 static void pressure_calculation_AN520_004_mod_MS5803_30BA__09_2015(void)
 {
 	uint32_t local_D1; // ADC value of the pressure conversion
@@ -426,6 +457,8 @@
 	int64_t local_OFF; // offset at actual temperature
 	int64_t local_SENS; // sensitivity at actual temperature
 
+	float calc_pressure;
+
 	int64_t T2;
 	int64_t OFF2;
 	int64_t SENS2;
@@ -479,7 +512,12 @@
 								/  8192 );//     )) / 10; // pow(2,21), pow(2,13)
 
 	ambient_temperature 	= ((float)local_Tx100) / 100;
-	ambient_pressure_mbar	= ((float)local_Px10) / 10;
+
+	calc_pressure = ((float)local_Px10) / 10;
+	if(pressure_plausible(calc_pressure))
+	{
+		ambient_pressure_mbar = calc_pressure;
+	}
 }
 
 
--- a/Small_CPU/Src/scheduler.c	Mon Jul 01 14:18:39 2019 +0000
+++ b/Small_CPU/Src/scheduler.c	Thu Jul 18 14:26:56 2019 +0000
@@ -617,10 +617,7 @@
 			{
 				MX_I2C1_TestAndClear();
 				MX_I2C1_Init();
-				if(!is_init_pressure_done())
-				{
-					init_pressure();
-				}
+				init_pressure();
 			}
 		}
 		if(ticksdiff >= 1000)
@@ -846,14 +843,23 @@
 			copyBatteryData();
 			copyDeviceData();
 
-			// new hw 170523
+/* check if I2C is not up an running and try to reactivate if necessary. Also do initialization if problem occured during startup */
 			if(global.I2C_SystemStatus != HAL_OK)
 			{
 				MX_I2C1_TestAndClear();
 				MX_I2C1_Init();
-				if(!is_init_pressure_done())
+				if(global.I2C_SystemStatus == HAL_OK)
 				{
 					init_pressure();
+					if(is_init_pressure_done())		/* Init surface data with initial measurement */
+					{
+						init_surface_ring();
+					}
+
+					if(!battery_gas_gauge_CheckConfigOK())
+					{
+						 init_battery_gas_gauge();
+					}
 				}
 			}
 		}
@@ -997,6 +1003,17 @@
 		MX_I2C1_Init();
 		pressure_sensor_get_pressure_raw();
 
+/* check if I2C is not up an running and try to reactivate if necessary. Also do initialization if problem occured during startup */
+		if(global.I2C_SystemStatus != HAL_OK)
+		{
+			MX_I2C1_TestAndClear();
+			MX_I2C1_Init();
+			if(global.I2C_SystemStatus == HAL_OK)
+			{
+				init_pressure();
+			}
+		}
+
 		if(secondsCount >= 30)
 		{
 			pressure_sensor_get_temperature_raw();
@@ -1562,6 +1579,10 @@
 /* same as in data_central.c */
 _Bool is_ambient_pressure_close_to_surface(SLifeData *lifeData)
 {
+	if(lifeData->pressure_ambient_bar == INVALID_PREASURE_VALUE)	/* as long as no valid data is available expect we are close to surface */
+	{
+		return true;
+	}
 	if (lifeData->pressure_ambient_bar > 1.16)
 		return false;
 	else if(lifeData->pressure_ambient_bar < (lifeData->pressure_surface_bar + 0.1f)) // hw 161121 now 1 mter, before 0.04f
--- a/Small_CPU/Src/stm32f4xx_hal_msp_v3.c	Mon Jul 01 14:18:39 2019 +0000
+++ b/Small_CPU/Src/stm32f4xx_hal_msp_v3.c	Thu Jul 18 14:26:56 2019 +0000
@@ -110,7 +110,7 @@
   /* I2C TX GPIO pin configuration  */
   GPIO_InitStruct.Pin       = I2Cx_SCL_PIN;
   GPIO_InitStruct.Mode      = GPIO_MODE_AF_OD;
-  GPIO_InitStruct.Pull      = GPIO_PULLUP;
+  GPIO_InitStruct.Pull      = GPIO_NOPULL;
   GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
   GPIO_InitStruct.Alternate = I2Cx_SCL_AF;
   
@@ -124,10 +124,14 @@
     
   /*##-3- Configure the NVIC for I2C #########################################*/   
   /* NVIC for I2C1 */
+
+ /* The callbacks are not used => no need to activate the interrupts */
+ /*
   HAL_NVIC_SetPriority(I2Cx_ER_IRQn, 1, 2);
   HAL_NVIC_EnableIRQ(I2Cx_ER_IRQn);
   HAL_NVIC_SetPriority(I2Cx_EV_IRQn, 1, 3);
   HAL_NVIC_EnableIRQ(I2Cx_EV_IRQn);
+*/
 }
 
 /**