Mercurial > public > ostc4
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); +*/ } /**