comparison Small_CPU/Src/scheduler.c @ 981:c6c781a2e85b default

Merge into default
author heinrichsweikamp
date Tue, 11 Feb 2025 18:12:00 +0100
parents 9b29995d6619
children d9290c76b840
comparison
equal deleted inserted replaced
871:f7318457df4d 981:c6c781a2e85b
19 * 19 *
20 ****************************************************************************** 20 ******************************************************************************
21 */ 21 */
22 22
23 23
24 //#define DEBUGMODE
25
26 /* Includes ------------------------------------------------------------------*/ 24 /* Includes ------------------------------------------------------------------*/
27 #include <string.h> 25 #include <string.h>
28 #include "baseCPU2.h" 26 #include "baseCPU2.h"
29 #include "stm32f4xx_hal.h" 27 #include "stm32f4xx_hal.h"
30 #include "i2c.h" 28 #include "i2c.h"
35 #include "batteryCharger.h" 33 #include "batteryCharger.h"
36 #include "spi.h" 34 #include "spi.h"
37 #include "rtc.h" 35 #include "rtc.h"
38 #include "dma.h" 36 #include "dma.h"
39 #include "adc.h" 37 #include "adc.h"
38 #include "gpio.h"
40 #include "calc_crush.h" 39 #include "calc_crush.h"
41 #include "stm32f4xx_hal_rtc_ex.h" 40 #include "stm32f4xx_hal_rtc_ex.h"
42 #include "decom.h" 41 #include "decom.h"
43 #include "tm_stm32f4_otp.h" 42 #include "tm_stm32f4_otp.h"
44 #include "externalInterface.h" 43 #include "externalInterface.h"
45 #include "uart.h" 44 #include "uart.h"
45 #include "uart_Internal.h"
46 #include "GNSS.h"
47 #include "uartProtocol_GNSS.h"
48 #include "math.h"
49 #include "configuration.h"
46 50
47 /* uncomment to enable restoting of last known date in case of a power loss (RTC looses timing data) */ 51 /* uncomment to enable restoting of last known date in case of a power loss (RTC looses timing data) */
48 /* #define RESTORE_LAST_KNOWN_DATE */ 52 /* #define RESTORE_LAST_KNOWN_DATE */
49 53
50 #define INVALID_PREASURE_VALUE (0.0f) 54 #define INVALID_PREASURE_VALUE (0.0f)
51 #define START_DIVE_MOUNTAIN_MODE_BAR (0.88f) 55 #define START_DIVE_MOUNTAIN_MODE_BAR (0.88f)
52 #define START_DIVE_IMMEDIATLY_BAR (1.16f) 56 #define START_DIVE_IMMEDIATLY_BAR (1.16f)
57
58 /* Ascent rate calculation */
59 typedef enum
60 {
61 ASCENT_NONE = 0,
62 ASCENT_RISING,
63 ASCENT_FALLING,
64 } AscentStates_t;
53 65
54 /* Private types -------------------------------------------------------------*/ 66 /* Private types -------------------------------------------------------------*/
55 const SGas Air = {79,0,0,0,0}; 67 const SGas Air = {79,0,0,0,0};
56 68
57 /* Exported variables --------------------------------------------------------*/ 69 /* Exported variables --------------------------------------------------------*/
90 void copyVpmCrushingData(void); 102 void copyVpmCrushingData(void);
91 void copyDeviceData(void); 103 void copyDeviceData(void);
92 void copyPICdata(void); 104 void copyPICdata(void);
93 void copyExtADCdata(); 105 void copyExtADCdata();
94 void copyExtCO2data(); 106 void copyExtCO2data();
107 void copyGNSSdata(void);
95 static void schedule_update_timer_helper(int8_t thisSeconds); 108 static void schedule_update_timer_helper(int8_t thisSeconds);
109 static void evaluateAscentSpeed(void);
96 uint32_t time_elapsed_ms(uint32_t ticksstart,uint32_t ticksnow); 110 uint32_t time_elapsed_ms(uint32_t ticksstart,uint32_t ticksnow);
97 111
98 void scheduleSetDate(SDeviceLine *line); 112 void scheduleSetDate(SDeviceLine *line);
99 113
100 /* Exported functions --------------------------------------------------------*/ 114 /* Exported functions --------------------------------------------------------*/
140 global.sensorError[i] = HAL_OK; // HAL_OK = 0; 154 global.sensorError[i] = HAL_OK; // HAL_OK = 0;
141 } 155 }
142 156
143 global.dataSendToMaster.RTE_VERSION_high = firmwareVersionHigh();//RTE_VERSION_HIGH;; 157 global.dataSendToMaster.RTE_VERSION_high = firmwareVersionHigh();//RTE_VERSION_HIGH;;
144 global.dataSendToMaster.RTE_VERSION_low = firmwareVersionLow();//RTE_VERSION_LOW;; 158 global.dataSendToMaster.RTE_VERSION_low = firmwareVersionLow();//RTE_VERSION_LOW;;
145 global.dataSendToMaster.chargeStatus = 0; 159 global.dataSendToMaster.chargeStatus = CHARGER_off;
146 160
147 global.dataSendToMaster.power_on_reset = 0; 161 global.dataSendToMaster.power_on_reset = 0;
148 global.dataSendToMaster.header.checkCode[0] = 0xA1; 162 global.dataSendToMaster.header.checkCode[0] = 0xA1;
149 global.dataSendToMaster.header.checkCode[1] = SPI_RX_STATE_OFFLINE; 163 global.dataSendToMaster.header.checkCode[1] = SPI_RX_STATE_OFFLINE;
150 global.dataSendToMaster.header.checkCode[2] = 0xA3; 164 global.dataSendToMaster.header.checkCode[2] = 0xA3;
153 global.dataSendToMaster.footer.checkCode[2] = 0xE3; 167 global.dataSendToMaster.footer.checkCode[2] = 0xE3;
154 global.dataSendToMaster.footer.checkCode[1] = 0xE2; 168 global.dataSendToMaster.footer.checkCode[1] = 0xE2;
155 global.dataSendToMaster.footer.checkCode[0] = 0xE1; 169 global.dataSendToMaster.footer.checkCode[0] = 0xE1;
156 global.dataSendToMaster.sensorErrors = 0; 170 global.dataSendToMaster.sensorErrors = 0;
157 171
172 global.dataSendToMaster.data[0].gnssInfo.coord.fLat = 0.0;
173 global.dataSendToMaster.data[0].gnssInfo.coord.fLon = 0.0;
174 global.dataSendToMaster.data[0].gnssInfo.fixType = 0;
175 global.dataSendToMaster.data[0].gnssInfo.numSat = 0;
176
158 global.sync_error_count = 0; 177 global.sync_error_count = 0;
159 global.check_sync_not_running = 0; 178 global.check_sync_not_running = 0;
160 179
161 global.deviceDataSendToMaster.RTE_VERSION_high = firmwareVersionHigh();//RTE_VERSION_HIGH; 180 global.deviceDataSendToMaster.RTE_VERSION_high = firmwareVersionHigh();//RTE_VERSION_HIGH;
162 global.deviceDataSendToMaster.RTE_VERSION_low = firmwareVersionLow();//RTE_VERSION_LOW; 181 global.deviceDataSendToMaster.RTE_VERSION_low = firmwareVersionLow();//RTE_VERSION_LOW;
163 global.deviceDataSendToMaster.chargeStatus = 0; 182 global.deviceDataSendToMaster.chargeStatus = CHARGER_off;
164 183
165 global.deviceDataSendToMaster.power_on_reset = 0; 184 global.deviceDataSendToMaster.power_on_reset = 0;
166 global.deviceDataSendToMaster.header.checkCode[0] = 0xDF; 185 global.deviceDataSendToMaster.header.checkCode[0] = 0xDF;
167 global.deviceDataSendToMaster.header.checkCode[1] = 0xDE; 186 global.deviceDataSendToMaster.header.checkCode[1] = 0xDE;
168 global.deviceDataSendToMaster.header.checkCode[2] = 0xDD; 187 global.deviceDataSendToMaster.header.checkCode[2] = 0xDD;
321 externalInface_SetSensorMap(global.dataSendToSlave.data.externalInterface_SensorMap); 340 externalInface_SetSensorMap(global.dataSendToSlave.data.externalInterface_SensorMap);
322 if(global.dataSendToSlave.data.externalInterface_Cmd & 0x00FF) /* lowest nibble for commands */ 341 if(global.dataSendToSlave.data.externalInterface_Cmd & 0x00FF) /* lowest nibble for commands */
323 { 342 {
324 externalInterface_ExecuteCmd(global.dataSendToSlave.data.externalInterface_Cmd); 343 externalInterface_ExecuteCmd(global.dataSendToSlave.data.externalInterface_Cmd);
325 } 344 }
345 #ifdef ENABLE_GPIO_V2
346 GPIO_HandleBuzzer();
347 #endif
326 348
327 349
328 #if 0 350 #if 0
329 //TODO: Temporary placed here. Duration ~210 ms. 351 //TODO: Temporary placed here. Duration ~210 ms.
330 if (global.I2C_SystemStatus != HAL_OK) { 352 if (global.I2C_SystemStatus != HAL_OK) {
480 { 502 {
481 uint32_t ticksdiff = 0; 503 uint32_t ticksdiff = 0;
482 uint32_t lasttick = 0; 504 uint32_t lasttick = 0;
483 uint8_t extAdcChannel = 0; 505 uint8_t extAdcChannel = 0;
484 uint8_t counterAscentRate = 0; 506 uint8_t counterAscentRate = 0;
485 float lastPressure_bar = 0.0f;
486 global.dataSendToMaster.mode = MODE_DIVE; 507 global.dataSendToMaster.mode = MODE_DIVE;
487 global.deviceDataSendToMaster.mode = MODE_DIVE; 508 global.deviceDataSendToMaster.mode = MODE_DIVE;
488 uint8_t counter_exit = 0; 509 uint8_t counter_exit = 0;
489 510
490 Scheduler.counterSPIdata100msec = 0; 511 Scheduler.counterSPIdata100msec = 0;
510 { 531 {
511 lasttick = HAL_GetTick(); 532 lasttick = HAL_GetTick();
512 ticksdiff = time_elapsed_ms(Scheduler.tickstart,lasttick); 533 ticksdiff = time_elapsed_ms(Scheduler.tickstart,lasttick);
513 534
514 externalInterface_HandleUART(); 535 externalInterface_HandleUART();
536 #ifdef ENABLE_GPIO_V2
537 UART6_HandleUART();
538 #endif
515 if(ticksdiff >= Scheduler.counterSPIdata100msec * 100 + 10) 539 if(ticksdiff >= Scheduler.counterSPIdata100msec * 100 + 10)
516 { 540 {
517 if(SPI_Evaluate_RX_Data()!=0) /* did we receive something ? */ 541 if(SPI_Evaluate_RX_Data()!=0) /* did we receive something ? */
518 { 542 {
519 Scheduler.counterSPIdata100msec++; 543 Scheduler.counterSPIdata100msec++;
550 } 574 }
551 if((global.lifeData.counterSecondsShallowDepth > 1) && (global.lifeData.counterSecondsShallowDepth < (global.settings.timeoutDiveReachedZeroDepth - 10))) 575 if((global.lifeData.counterSecondsShallowDepth > 1) && (global.lifeData.counterSecondsShallowDepth < (global.settings.timeoutDiveReachedZeroDepth - 10)))
552 global.lifeData.counterSecondsShallowDepth = (global.settings.timeoutDiveReachedZeroDepth - 10); 576 global.lifeData.counterSecondsShallowDepth = (global.settings.timeoutDiveReachedZeroDepth - 10);
553 } 577 }
554 #endif 578 #endif
555 579
556 //Calc ascentrate every two second (20 * 100 ms)
557 counterAscentRate++; 580 counterAscentRate++;
558 if(counterAscentRate == 20) 581 if(counterAscentRate == 4)
559 { 582 {
560 global.lifeData.pressure_ambient_bar = get_pressure_mbar() / 1000.0f; 583 global.lifeData.pressure_ambient_bar = get_pressure_mbar() / 1000.0f;
561 if(lastPressure_bar >= 0) 584 evaluateAscentSpeed();
562 {
563 //2 seconds * 30 == 1 minute, bar * 10 = meter
564 global.lifeData.ascent_rate_meter_per_min = (lastPressure_bar - global.lifeData.pressure_ambient_bar) * 30 * 10;
565 }
566 lastPressure_bar = global.lifeData.pressure_ambient_bar;
567 counterAscentRate = 0; 585 counterAscentRate = 0;
568 } 586 }
569 copyPressureData(); 587 copyPressureData();
570 Scheduler.counterPressure100msec++; 588 Scheduler.counterPressure100msec++;
571 } 589 }
599 decom_oxygen_calculate_otu(&global.lifeData.otu,global.lifeData.ppO2); 617 decom_oxygen_calculate_otu(&global.lifeData.otu,global.lifeData.ppO2);
600 battery_gas_gauge_get_data(); 618 battery_gas_gauge_get_data();
601 619
602 620
603 /** counter_exit allows safe exit via button for testing 621 /** counter_exit allows safe exit via button for testing
604 * and demo_mode is exited too if aplicable. 622 * and demo_mode is exited too if applicable.
605 */ 623 */
606 if(global.dataSendToMaster.mode == MODE_ENDDIVE) 624 if(global.dataSendToMaster.mode == MODE_ENDDIVE)
607 { 625 {
608 counter_exit++; 626 counter_exit++;
609 if(counter_exit >= 2) 627 if(counter_exit >= 2)
613 } 631 }
614 } 632 }
615 633
616 if(is_ambient_pressure_close_to_surface(&global.lifeData)) 634 if(is_ambient_pressure_close_to_surface(&global.lifeData))
617 { 635 {
636
618 global.lifeData.counterSecondsShallowDepth++; 637 global.lifeData.counterSecondsShallowDepth++;
619 if((global.lifeData.counterSecondsShallowDepth >= global.settings.timeoutDiveReachedZeroDepth) || ((global.lifeData.dive_time_seconds < 60) && (global.demo_mode == 0)) 638 if((global.lifeData.counterSecondsShallowDepth >= global.settings.timeoutDiveReachedZeroDepth) || ((global.lifeData.dive_time_seconds < 60) && (global.demo_mode == 0))
620 || (ManualExitDiveCounter)) 639 || (ManualExitDiveCounter))
621 { 640 {
622 global.seconds_since_last_dive = 1; // start counter 641 global.seconds_since_last_dive = 1; // start counter
650 } 669 }
651 670
652 // surface break 671 // surface break
653 if(is_ambient_pressure_close_to_surface(&global.lifeData)) 672 if(is_ambient_pressure_close_to_surface(&global.lifeData))
654 { 673 {
674 global.lifeData.ascent_rate_meter_per_min = 0;
655 global.lifeData.counterSecondsShallowDepth++; 675 global.lifeData.counterSecondsShallowDepth++;
656 if(global.lifeData.counterSecondsShallowDepth > 3) // time for main cpu to copy to apnea_last_dive_time_seconds 676 if(global.lifeData.counterSecondsShallowDepth > 3) // time for main cpu to copy to apnea_last_dive_time_seconds
657 { 677 {
658 global.lifeData.dive_time_seconds = 0; // this apnea dive ends here 678 global.lifeData.dive_time_seconds = 0; // this apnea dive ends here
659 } 679 }
816 if(scheduleSetButtonResponsiveness()) 836 if(scheduleSetButtonResponsiveness())
817 setButtonsNow = 0; 837 setButtonsNow = 0;
818 } 838 }
819 839
820 externalInterface_HandleUART(); 840 externalInterface_HandleUART();
841 #ifdef ENABLE_GPIO_V2
842 UART6_HandleUART();
843 #endif
821 844
822 /* Evaluate received data at 10 ms, 110 ms, 210 ms,... duration ~<1ms */ 845 /* Evaluate received data at 10 ms, 110 ms, 210 ms,... duration ~<1ms */
823 if(ticksdiff >= Scheduler.counterSPIdata100msec * 100 + 10) 846 if(ticksdiff >= Scheduler.counterSPIdata100msec * 100 + 10)
824 { 847 {
825 if(SPI_Evaluate_RX_Data()!=0) /* did we receive something ? */ 848 if(SPI_Evaluate_RX_Data()!=0) /* did we receive something ? */
867 /* evaluate compass data at 70 ms, 170 ms, 270 ms,... duration <1ms */ 890 /* evaluate compass data at 70 ms, 170 ms, 270 ms,... duration <1ms */
868 if(ticksdiff >= Scheduler.counterAmbientLight100msec * 100 + 70) 891 if(ticksdiff >= Scheduler.counterAmbientLight100msec * 100 + 70)
869 { 892 {
870 adc_ambient_light_sensor_get_data(); 893 adc_ambient_light_sensor_get_data();
871 copyAmbientLightData(); 894 copyAmbientLightData();
895
896 #if defined ENABLE_GNSS_SUPPORT || defined ENABLE_GPIO_V2
897 copyGNSSdata();
898 #endif
872 Scheduler.counterAmbientLight100msec++; 899 Scheduler.counterAmbientLight100msec++;
873 } 900 }
874 901
875 902
876 903
1081 void scheduleSleepMode(void) 1108 void scheduleSleepMode(void)
1082 { 1109 {
1083 global.dataSendToMaster.mode = 0; 1110 global.dataSendToMaster.mode = 0;
1084 global.deviceDataSendToMaster.mode = 0; 1111 global.deviceDataSendToMaster.mode = 0;
1085 secondsCount = 0; 1112 secondsCount = 0;
1086 1113 #ifdef ENABLE_GPIO_V2
1114 uint16_t deepSleepCntDwn = 21600; /* 12 hours in 2 second steps */
1115 uint8_t deepSleep = 0;
1116 GPIO_InitTypeDef GPIO_InitStruct;
1117 #endif
1087 /* prevent button wake up problem while in sleep_prepare 1118 /* prevent button wake up problem while in sleep_prepare
1088 * sleep prepare does I2C_DeInit() 1119 * sleep prepare does I2C_DeInit()
1089 */ 1120 */
1090 if(global.mode != MODE_SLEEP) 1121 if(global.mode != MODE_SLEEP)
1091 MX_I2C1_Init(); 1122 MX_I2C1_Init();
1092 else 1123 else
1093 do 1124 do
1094 { 1125 {
1095 I2C_DeInit(); 1126 I2C_DeInit();
1096 1127
1097 #ifdef DEBUGMODE 1128 #ifdef ENABLE_SLEEP_DEBUG
1098 HAL_Delay(2000); 1129 HAL_Delay(2000);
1099 #else 1130 #else
1100 RTC_StopMode_2seconds(); 1131 RTC_StopMode_2seconds();
1101 #endif 1132 #endif
1102
1103
1104 1133
1105 if(global.mode == MODE_SLEEP) 1134 if(global.mode == MODE_SLEEP)
1106 secondsCount += 2; 1135 secondsCount += 2;
1107 1136
1108 externalInterface_InitPower33(); 1137 externalInterface_InitPower33();
1160 || (global.lifeData.pressure_ambient_bar > START_DIVE_IMMEDIATLY_BAR)) 1189 || (global.lifeData.pressure_ambient_bar > START_DIVE_IMMEDIATLY_BAR))
1161 { 1190 {
1162 global.mode = MODE_BOOT; 1191 global.mode = MODE_BOOT;
1163 } 1192 }
1164 scheduleUpdateLifeData(2000); 1193 scheduleUpdateLifeData(2000);
1194 #ifdef ENABLE_GPIO_V2
1195 if(deepSleepCntDwn)
1196 {
1197 deepSleepCntDwn--;
1198 if(deepSleepCntDwn == 0)
1199 {
1200 deepSleep = 1;
1201 GPIO_GPS_OFF();
1202 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
1203 GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
1204 GPIO_InitStruct.Pull = GPIO_NOPULL;
1205 GPIO_InitStruct.Pin = GPIO_PIN_All ^ (GPS_POWER_CONTROL_PIN);
1206 HAL_GPIO_Init( GPIOB, &GPIO_InitStruct);
1207 uartGnss_SetState(UART_GNSS_INIT);
1208 }
1209 }
1210 else
1211 {
1212 if((deepSleep = 1) && (global.lifeData.battery_voltage < 3.5)) /* switch off backup voltage if battery gets low */
1213 {
1214 deepSleep = 2;
1215 GPIO_GPS_BCKP_OFF();
1216 GPIO_InitStruct.Pin = GPIO_PIN_All ^ (GPS_BCKP_CONTROL_PIN);
1217 HAL_GPIO_Init( GPIOB, &GPIO_InitStruct);
1218 __HAL_RCC_GPIOB_CLK_DISABLE();
1219 }
1220 }
1221 #endif
1165 } 1222 }
1166 while(global.mode == MODE_SLEEP); 1223 while(global.mode == MODE_SLEEP);
1167 /* new section for system after Standby */ 1224 /* new section for system after Standby */
1168 scheduleUpdateLifeData(-1); 1225 scheduleUpdateLifeData(-1);
1169 clearDecoNow = 0; 1226 clearDecoNow = 0;
1170 setButtonsNow = 0; 1227 setButtonsNow = 0;
1171 reinitGlobals(); 1228 reinitGlobals();
1172 ReInit_battery_charger_status_pins(); 1229 ReInit_battery_charger_status_pins();
1230 #ifdef ENABLE_GPIO_V2
1231 if(deepSleep != 0)
1232 {
1233 GPIO_GNSS_Init();
1234 }
1235 #endif
1173 } 1236 }
1174 1237
1175 1238
1176 1239
1177 /* Private functions ---------------------------------------------------------*/ 1240 /* Private functions ---------------------------------------------------------*/
1727 global.dataSendToMaster.data[(boolCO2Buffer && DATA_BUFFER_CO2)].externalInterface_CmdAnswer = 0; 1790 global.dataSendToMaster.data[(boolCO2Buffer && DATA_BUFFER_CO2)].externalInterface_CmdAnswer = 0;
1728 } 1791 }
1729 global.dataSendToMaster.boolADCO2Data |= boolCO2Buffer; 1792 global.dataSendToMaster.boolADCO2Data |= boolCO2Buffer;
1730 } 1793 }
1731 1794
1795 void copyGNSSdata(void)
1796 {
1797 RTC_TimeTypeDef sTimeNow;
1798
1799 global.dataSendToMaster.data[0].gnssInfo.coord.fLat = GNSS_Handle.fLat;
1800 global.dataSendToMaster.data[0].gnssInfo.coord.fLon = GNSS_Handle.fLon;
1801 global.dataSendToMaster.data[0].gnssInfo.fixType = GNSS_Handle.fixType;
1802 global.dataSendToMaster.data[0].gnssInfo.numSat = GNSS_Handle.numSat;
1803 global.dataSendToMaster.data[0].gnssInfo.DateTime.year = (uint8_t) (GNSS_Handle.year - 2000);
1804 global.dataSendToMaster.data[0].gnssInfo.DateTime.month = GNSS_Handle.month;
1805 global.dataSendToMaster.data[0].gnssInfo.DateTime.day = GNSS_Handle.day;
1806 global.dataSendToMaster.data[0].gnssInfo.DateTime.hour = GNSS_Handle.hour;
1807 global.dataSendToMaster.data[0].gnssInfo.DateTime.min = GNSS_Handle.min;
1808 global.dataSendToMaster.data[0].gnssInfo.DateTime.sec = GNSS_Handle.sec;
1809
1810 global.dataSendToMaster.data[0].gnssInfo.alive = GNSS_Handle.alive;
1811
1812 if(( GNSS_Handle.fixType < 2) && (GNSS_Handle.alive & GNSS_ALIVE_BACKUP_POS)) /* fallback to last known position ? */
1813 {
1814 RTC_GetTime(&sTimeNow);
1815 if(GNSS_Handle.last_hour > sTimeNow.Hours)
1816 {
1817 sTimeNow.Hours += 24; /* compensate date change */
1818 }
1819 if(sTimeNow.Hours - GNSS_Handle.last_hour > 2)
1820 {
1821 GNSS_Handle.alive &= ~GNSS_ALIVE_BACKUP_POS; /* position outdated */
1822 }
1823 else
1824 {
1825 global.dataSendToMaster.data[0].gnssInfo.coord.fLat = GNSS_Handle.last_fLat;
1826 global.dataSendToMaster.data[0].gnssInfo.coord.fLon = GNSS_Handle.last_fLon;
1827 }
1828 }
1829 memcpy(&global.dataSendToMaster.data[0].gnssInfo.signalQual,&GNSS_Handle.statSat, sizeof(GNSS_Handle.statSat));
1830 }
1831
1832
1732 typedef enum 1833 typedef enum
1733 { 1834 {
1734 SPI3_OK = 0x00, 1835 SPI3_OK = 0x00,
1735 SPI3_DEINIT = 0x01, 1836 SPI3_DEINIT = 0x01,
1736 } SPI3_StatusTypeDef; 1837 } SPI3_StatusTypeDef;
1807 } 1908 }
1808 } 1909 }
1809 return retval; 1910 return retval;
1810 } 1911 }
1811 1912
1913 void evaluateAscentSpeed()
1914 {
1915 static uint32_t lastPressureTick = 0;
1916 static float lastPressure_bar = 0.0f;
1917 static AscentStates_t ascentState = ASCENT_NONE;
1918 static uint8_t ascentStableCnt = 0;
1919 uint32_t tickPressureDiff = 0;
1920 uint32_t lasttick = HAL_GetTick();
1921 float localAscentRate = 0.0;
1922
1923 tickPressureDiff = time_elapsed_ms(lastPressureTick,lasttick); /* Calculate ascent rate every 400ms use timer to take care for small time shifts */
1924 if(tickPressureDiff != 0)
1925 {
1926 if(lastPressure_bar >= 0)
1927 {
1928 localAscentRate = (lastPressure_bar - global.lifeData.pressure_ambient_bar) * (60000.0 / tickPressureDiff) * 10; /* bar * 10 = meter */
1929 if((fabs(localAscentRate) < 1.0) || (global.lifeData.pressure_ambient_bar < START_DIVE_IMMEDIATLY_BAR))
1930 {
1931 ascentState = ASCENT_NONE;
1932 ascentStableCnt = 0;
1933 }
1934 else if(localAscentRate > 0.0)
1935 {
1936 if(ascentState != ASCENT_FALLING)
1937 {
1938 if(ascentStableCnt < 5)
1939 {
1940 ascentStableCnt++;
1941 }
1942 else
1943 {
1944 ascentState = ASCENT_RISING;
1945 }
1946 }
1947 else
1948 {
1949 ascentState = ASCENT_NONE;
1950 ascentStableCnt = 0;
1951 }
1952 }
1953 else /* must be falling */
1954 {
1955 if(ascentState != ASCENT_RISING)
1956 {
1957 if(ascentStableCnt < 5)
1958 {
1959 ascentStableCnt++;
1960 }
1961 else
1962 {
1963 ascentState = ASCENT_FALLING;
1964 }
1965 }
1966 else
1967 {
1968 ascentState = ASCENT_NONE;
1969 ascentStableCnt = 0;
1970 }
1971 }
1972 if(ascentState != ASCENT_NONE)
1973 {
1974 global.lifeData.ascent_rate_meter_per_min = localAscentRate;
1975 }
1976 else
1977 {
1978 global.lifeData.ascent_rate_meter_per_min = 0;
1979 }
1980 }
1981 }
1982 lastPressure_bar = global.lifeData.pressure_ambient_bar;
1983 lastPressureTick = lasttick;
1984 }
1812 1985
1813 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/ 1986 /************************ (C) COPYRIGHT heinrichs weikamp *****END OF FILE****/
1814 1987