// // WSPRHAB: Minimal high-altitude balloon tracker with WSPR telemetry // #include "stm32f0xx_hal.h" #include "adc.h" #include "system.h" #include "i2c.h" #include "uart.h" #include "gpio.h" #include "wspr.h" #include "gps.h" // We have access to the 1PPS pin of the gps... could have trim routine for internal oscillator based on this when we have a fix // Probabl wake up 1 minute early -- 0.45min possible +/- on wakeup time with 15min sync intervals enum _state { SYSTEM_POWERUP_SYNC = 0, // on powerup, get a GPS fix and set the RTC SYSTEM_IDLE, // awaiting RTC interrupt for wakeup TODO wake up before scheduled time to get fix? SYSTEM_GPSACQ, // RTC interrupted SYSTEM_WSPRTX, // Wait for timeslot and actually transmit the message }; int main(void) { HAL_Init(); sysclk_init(); gpio_init(); adc_init(); i2c_init(); wspr_init(); uint32_t led_timer = HAL_GetTick(); led_blink(4); uint16_t blink_rate = BLINK_FAST; uint8_t state = SYSTEM_GPSACQ; uint32_t gps_polltimer = 0; uint32_t fix_acq_starttime = 0; uint8_t fix_ok = 0; uint8_t numsats = 0; while (1) { // Update fix status every 2 seconds if(HAL_GetTick() - gps_polltimer > 2000) { if(gps_ison()) gps_update_data(); gps_polltimer = HAL_GetTick(); } switch(state) { // Idling: sleep and wait for RTC timeslot trigger case SYSTEM_IDLE: { blink_rate = BLINK_SLOW; // Wait for RTC wakeup interrupt //wfi(); //enter_sleep(); // Somehow go to another state when we get an interrupt // state = SYSTEM_GPSACQ; } break; // Attempt to acquire GPS fix case SYSTEM_GPSACQ: { blink_rate = BLINK_FAST; if(!gps_ison()) { fix_starttime = HAL_GetTick(); gps_poweron(); // power on and initialize GPS module } if(gps_getdata()->fixtype > 0 && gps_getdata()->pdop < 5) { // Disable GPS module gps_poweroff(); // TODO: Set RTC from GPS time // TODO: Set RTC for countdown to next transmission timeslot! // TODO: Set wspr countdown timer for this transmission! fix_acq_starttime = 0; state = SYSTEM_WSPRTX; } else if(HAL_GetTick() - fix_acq_starttime > 60000) { // Flash error code and go to idle probably? or just try forever? led_blink(4); } } break; // Wait for wspr timeslot and start transmitting case SYSTEM_WSPRTX: { blink_rate = BLINK_SLOW; // Wait for wspr countdown timer to expire and go to tx // if(timeout_expired) // { // wspr_transmit(); // } // Schedule next wakeup (maybe 2mins prior ot timeslot if no osc trim) // Next wakeup should enter SYSTEM_GPSACQ state... // state = SYSTEM_IDLE; } break; } if(HAL_GetTick() - led_timer > blink_rate) { HAL_GPIO_TogglePin(LED_BLUE); led_timer = HAL_GetTick(); } } }