Early implementation of new GPS watchdog, some code cleanup

develop
sq2ips 2025-07-31 20:12:19 +02:00
rodzic 91de72ae76
commit d0051d1dec
4 zmienionych plików z 188 dodań i 100 usunięć

Wyświetl plik

@ -16,9 +16,9 @@ const static float QRG_FSK4[] = {435100000}; // Transmitted frequencies array, s
#define TIME_PERIOD 6 // Time betwen starts of transmissions (in seconds) (must be more than 3)
#define GPS_TYPE 1 // Type of GPS module: 1 - u-blox | 2 - XM1110
#define GPS_TYPE 2 // Type of GPS module: 1 - u-blox | 2 - XM1110
#define GPS_WATCHDOG 3 // number of frames without gps fix to trigger restart
#define GPS_WATCHDOG // Enable GPS watchdog
#define PA_FSK4 10 // RF power setting for horus transmission values 0-63
#define RF_BOOST_ACTIVE 1 // RF booster enabled for transmissions about 15dB gain, but more power consumed - normally should be ON(1).
@ -32,6 +32,10 @@ const static float QRG_FSK4[] = {435100000}; // Transmitted frequencies array, s
/*-----------------------------------------------------------------*/
// the rest of parameters should not be changed normally
#define GPS_WATCHDOG_ARC 180 // Time of GPS watchdog after restart counter, how much time (in s) the module has for getting a fix after a restart before next one
//#define GPS_WATCHDOG_MAX_D_TIME 10 // Max GPS time deviation (in s) from last frame
//#define GPS_WATCHDOG_ASCENTRATE 100 // Ascent rate value triggering restart
#define FSK4_BAUD 100 // Baudrate for horus 4FSK
#define FSK4_SPACE_MULTIPLIER 1 // Tone spacing multiplier - 1 for 244Hz, 2 for 488, etc.

Wyświetl plik

@ -21,7 +21,8 @@ typedef struct TBinaryPacket {
int16_t ExtTemp;
uint8_t Hum;
uint16_t Press;
uint16_t Unused;
uint8_t GpsResetCount; // counter of GPS watchdog resets
uint8_t Unused;
// End of custom data
uint16_t Checksum;
} __attribute__((packed)) HorusBinaryPacket;

Wyświetl plik

@ -60,8 +60,16 @@ XMDATA GpsData;
#endif
#ifdef GPS_WATCHDOG
uint8_t GpsWatchdogCounter = 0;
bool GpsPreviousFix = false;
struct GpsWatchdogStruct {
bool PreviousFix;
bool AfterRestart;
uint8_t AfterRestartCounter;
bool TriggerRestart;
#if GPS_TYPE == 2
uint32_t LastTime;
#endif
} GpsWatchdog;
#endif
uint8_t lps_init;
@ -87,6 +95,8 @@ static void MX_TIM6_Init(void);
void GPS_Handler(void);
void LED_Handler(void);
void main_loop(void);
void DelayWithIWDG(uint16_t time);
void GpsAirborne(void);
#ifdef DEBUG
#ifdef __GNUC__
@ -183,6 +193,11 @@ void main_loop(void) {
LL_ADC_REG_StartConversion(ADC1);
while (LL_ADC_IsActiveFlag_EOC(ADC1) == 0) {
}
// ADC voltage: 3.3V, divided by ADC max value 4095 (2^12-1). That gives a
// range between 0 for 0V and 1 for 3.3V. Than it's multiplied by max
// variable value: 255, and divided by corresponding voltage: 5V, simplified
// gives 187/4550 Note: this value will not go higher than 168 corresponding
// to 3.3V max value of ADC
HorusPacket.BatVoltage = (LL_ADC_REG_ReadConversionData12(ADC1) * 187) / 4550;
LL_ADC_ClearFlag_EOS(ADC1);
@ -221,9 +236,94 @@ void main_loop(void) {
(unsigned char *)&HorusPacket,
sizeof(HorusPacket));
#ifdef GPS_WATCHDOG
// Set a flag if we have initial fix.
#if GPS_TYPE == 1
if (NmeaData.Fix > 1 && NmeaData.Sats > 0) {
GpsWatchdog.PreviousFix = true;
GpsWatchdog.AfterRestart = false;
}
#elif GPS_TYPE == 2
if (GpsData.Fix > 1 && GpsData.Sats > 0) {
GpsWatchdog.PreviousFix = true;
GpsWatchdog.AfterRestart = false;
}
#endif
// Check GPS reset conditions only if there was initial fix.
if (GpsWatchdog.PreviousFix) {
#if GPS_TYPE == 1
if (NmeaData.Fix > 1 && NmeaData.Sats > 0) {
if (NmeaData.AscentRate >= GPS_WATCHDOG_ASCENTRATE) {
GpsWatchdog.TriggerRestart = true;
}
}
#elif GPS_TYPE == 2
if (GpsData.Fix > 1 && GpsData.Sats > 0) {
// If there is fix check spoofing specific conditions.
// Ascent rate
//printf("%d %d\r\n",(int32_t)GpsData.Time - TIME_PERIOD, GpsWatchdog.LastTime);
/*if ((int32_t)GpsData.AscentRate >= GPS_WATCHDOG_ASCENTRATE
|| (int32_t)GpsData.AscentRate <= (-1*GPS_WATCHDOG_ASCENTRATE)
// Time deviation
|| (GpsWatchdog.LastTime != 0 &&
(((int32_t)GpsData.Time - TIME_PERIOD) - GpsWatchdog.LastTime > GPS_WATCHDOG_MAX_D_TIME
|| GpsWatchdog.LastTime - ((int32_t)GpsData.Time - TIME_PERIOD) < GPS_WATCHDOG_MAX_D_TIME))) {
// If conditions match trigger a restart
GpsWatchdog.TriggerRestart = true;
}*/
GpsWatchdog.LastTime = GpsData.Time;
// if (GpsData.AscentRate >= GPS_WATCHDOG_ASCENTRATE ||
//(GpsWatchdog.LastTime != 0 &&
// (GpsData.Time-TIME_PERIOD-GpsWatchdog.LastTime>GPS_WATCHDOG_MAX_TIME ||
// GpsData.Time-TIME_PERIOD-GpsWatchdog.LastTime<(-1*GPS_WATCHDOG_MAX_TIME))))
// /
}
#endif
else if (GpsWatchdog.AfterRestart) {
// If there is no fix and gps after a restart give it some time before next restart
GpsWatchdog.AfterRestartCounter++;
if (GpsWatchdog.AfterRestartCounter >= GPS_WATCHDOG_ARC/TIME_PERIOD) {
GpsWatchdog.TriggerRestart = true;
}
} else {
GpsWatchdog.TriggerRestart = true;
}
}
//printf("%d %d %d %d\r\n", GpsWatchdog.PreviousFix,
// GpsWatchdog.AfterRestart, GpsWatchdog.AfterRestartCounter,
// GpsWatchdog.TriggerRestart);
if (GpsWatchdog.TriggerRestart) {
LL_GPIO_ResetOutputPin(GPS_ON_GPIO_Port, GPS_ON_Pin); // disable GPS
DelayWithIWDG(1000);
LL_GPIO_SetOutputPin(GPS_ON_GPIO_Port, GPS_ON_Pin); // enable GPS
}
#endif
// Transmit
FSK4_start_TX(HorusCodedBuffer, HorusCodedLen);
#ifdef GPS_WATCHDOG
if (GpsWatchdog.TriggerRestart) {
#if GPS_TYPE == 1
while (FSK4_is_active()) {
LL_IWDG_ReloadCounter(IWDG);
LL_mDelay(100);
} // Wait for end of transmission (and for GPS module to start).
GpsAirborne(); // Send a command to GPS module to change to airborne mode.
#endif
// Reset variables to after restart state
GpsWatchdog.TriggerRestart = false;
GpsWatchdog.AfterRestart = true;
GpsWatchdog.AfterRestartCounter = 0;
GpsWatchdog.LastTime = 0;
HorusPacket.GpsResetCount++;
}
#endif
// Packet counter
HorusPacket.PacketCount++;
@ -231,78 +331,6 @@ void main_loop(void) {
#if LED_MODE == 1
LL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
#endif
#ifdef GPS_WATCHDOG
#if GPS_TYPE == 1
if (NmeaData.Fix >= 1 && NmeaData.Sats>0)
GpsPreviousFix = true;
if (GpsPreviousFix && (NmeaData.Fix <= 1 || NmeaData.Sats == 0)) {
GpsWatchdogCounter++;
} else {
GpsWatchdogCounter = 0;
}
#elif GPS_TYPE == 2
if (GpsData.Fix >= 1 && GpsData.Sats>0)
GpsPreviousFix = true;
if (GpsPreviousFix && (GpsData.Fix <= 1 || GpsData.Sats == 0)) {
GpsWatchdogCounter++;
} else {
GpsWatchdogCounter = 0;
}
#endif
if (GpsWatchdogCounter >= GPS_WATCHDOG) {
LL_GPIO_ResetOutputPin(GPS_ON_GPIO_Port, GPS_ON_Pin); // disable GPS
for(uint8_t i = 0; i<10; i++){
LL_mDelay(100);
LL_IWDG_ReloadCounter(IWDG);
}
LL_GPIO_SetOutputPin(GPS_ON_GPIO_Port, GPS_ON_Pin); // enable GPS
GpsWatchdogCounter = 0;
}
#endif
}
void GPS_Handler(void) {
if (LL_LPUART_IsEnabledIT_RXNE(LPUART1) &&
LL_LPUART_IsActiveFlag_RXNE(LPUART1)) {
if (GpsBufferCounter >= GpsRxBuffer_SIZE) {
GpsBufferCounter = 0;
GpsBufferReady = true;
}
GpsRxBuffer[GpsBufferCounter] = LL_LPUART_ReceiveData8(LPUART1);
GpsBufferCounter++;
} else if (LL_LPUART_IsActiveFlag_ORE(LPUART1)) {
LL_LPUART_ClearFlag_ORE(LPUART1);
#ifdef DEBUG
printf("ORE!\r\n");
#endif
}
}
void LED_Handler(void) {
#if LED_MODE == 2
#if GPS_TYPE == 1
uint8_t fix = NmeaData.Fix;
if (LED_DISABLE_ALT != 0) {
if (NmeaData.Alt >= LED_DISABLE_ALT) {
LL_TIM_DisableCounter(TIM6);
LL_TIM_DisableIT_UPDATE(TIM6);
}
}
#elif GPS_TYPE == 2
uint8_t fix = GpsData.Fix;
if (LED_DISABLE_ALT != 0) {
if (GpsData.Alt >= LED_DISABLE_ALT) {
LL_TIM_DisableCounter(TIM6);
LL_TIM_DisableIT_UPDATE(TIM6);
}
}
#endif
for (; fix > 0; fix--) {
LL_GPIO_SetOutputPin(LED_GPIO_Port, LED_Pin);
LL_mDelay(50);
LL_GPIO_ResetOutputPin(LED_GPIO_Port, LED_Pin);
LL_mDelay(100);
}
#endif
}
/* USER CODE END 0 */
@ -316,9 +344,11 @@ int main(void) {
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* MCU
* Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick.
/* Reset of all peripherals, Initializes the Flash interface and the
* Systick.
*/
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
@ -345,7 +375,7 @@ int main(void) {
MX_TIM2_Init();
MX_TIM22_Init();
MX_ADC_Init();
// MX_IWDG_Init(); // IWDG implementation after GPS
MX_IWDG_Init();
MX_TIM6_Init();
/* USER CODE BEGIN 2 */
@ -359,6 +389,7 @@ int main(void) {
HorusPacket.PayloadID = PAYLOAD_ID;
// Init of LPS22 sensor, try 5 times
for (uint8_t i = 0; i < 5; i++) {
lps_init = LPS22_Init();
if (lps_init == 0)
@ -380,27 +411,14 @@ int main(void) {
#if GPS_TYPE == 1
// u-blox change mode to airborne
LL_mDelay(2000);
for (uint8_t ih = 0; ih < 2; ih++) {
for (uint8_t ig = 0; ig < 44; ig++) {
while (!LL_LPUART_IsActiveFlag_TXE(LPUART1)) {
}
LL_LPUART_TransmitData8(LPUART1, GPS_airborne[ig]);
}
while (!LL_LPUART_IsActiveFlag_TC(LPUART1)) {
}
if (ih == 0)
LL_mDelay(900);
LL_mDelay(100);
}
DelayWithIWDG(2000); // Wait for full GPS start
GpsAirborne(); // Send a command to GPS module to change to airborne mode.
DelayWithIWDG(100);
#endif
LL_GPIO_ResetOutputPin(LED_GPIO_Port, LED_Pin);
// watchdog timer
MX_IWDG_Init();
// main loop timer
LL_TIM_EnableCounter(TIM22);
LL_TIM_EnableIT_UPDATE(TIM22);
@ -1112,6 +1130,70 @@ static void MX_GPIO_Init(void) {
}
/* USER CODE BEGIN 4 */
void GPS_Handler(void) {
if (LL_LPUART_IsEnabledIT_RXNE(LPUART1) &&
LL_LPUART_IsActiveFlag_RXNE(LPUART1)) {
if (GpsBufferCounter >= GpsRxBuffer_SIZE) {
GpsBufferCounter = 0;
GpsBufferReady = true;
}
GpsRxBuffer[GpsBufferCounter] = LL_LPUART_ReceiveData8(LPUART1);
GpsBufferCounter++;
} else if (LL_LPUART_IsActiveFlag_ORE(LPUART1)) {
LL_LPUART_ClearFlag_ORE(LPUART1);
#ifdef DEBUG
printf("ORE!\r\n");
#endif
}
}
void LED_Handler(void) {
#if LED_MODE == 2
#if GPS_TYPE == 1
uint8_t fix = NmeaData.Fix;
if (LED_DISABLE_ALT != 0) {
if (NmeaData.Alt >= LED_DISABLE_ALT) {
LL_TIM_DisableCounter(TIM6);
LL_TIM_DisableIT_UPDATE(TIM6);
}
}
#elif GPS_TYPE == 2
uint8_t fix = GpsData.Fix;
if (LED_DISABLE_ALT != 0) {
if (GpsData.Alt >= LED_DISABLE_ALT) {
LL_TIM_DisableCounter(TIM6);
LL_TIM_DisableIT_UPDATE(TIM6);
}
}
#endif
for (; fix > 0; fix--) {
LL_GPIO_SetOutputPin(LED_GPIO_Port, LED_Pin);
LL_mDelay(50);
LL_GPIO_ResetOutputPin(LED_GPIO_Port, LED_Pin);
LL_mDelay(100);
}
#endif
}
void DelayWithIWDG(uint16_t time) {
for (uint8_t i = 0; i < time / 100; i++) {
LL_IWDG_ReloadCounter(IWDG);
LL_mDelay(100);
}
}
#if GPS_TYPE == 1
void GpsAirborne(void) {
for (uint8_t ih = 0; ih < 2; ih++) {
for (uint8_t ig = 0; ig < 44; ig++) {
while (!LL_LPUART_IsActiveFlag_TXE(LPUART1)) {
}
LL_LPUART_TransmitData8(LPUART1, GPS_airborne[ig]);
}
while (!LL_LPUART_IsActiveFlag_TC(LPUART1)) {
}
if (ih == 0)
DelayWithIWDG(900);
}
}
#endif
/* USER CODE END 4 */
/**
@ -1120,7 +1202,8 @@ static void MX_GPIO_Init(void) {
*/
void Error_Handler(void) {
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
/* User can add his own implementation to report the HAL error return state
*/
__disable_irq();
while (1) {
}
@ -1138,8 +1221,8 @@ void Error_Handler(void) {
void assert_failed(uint8_t *file, uint32_t line) {
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line
number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file,
line) */
number, ex: printf("Wrong parameters value: file %s on line %d\r\n",
file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

Wyświetl plik

@ -42,7 +42,7 @@ void ParseXM(XMDATA *GpsData, uint8_t *buffer, uint8_t position) {
((GpsData->Time & 0x00FF0000) >> 8) |
((GpsData->Time & 0x0000FF00) << 8);
if (GpsData->Fix > 1 && GpsData->Alt != 0) {
if (GpsData->Fix == 3 && GpsData->Alt != 0) {
if (GpsData->Time != 0) {
if (oldTime == 0) {
oldAlt = GpsData->Alt;