// // 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(); gps_init(); wspr_init(); uint32_t led_timer = HAL_GetTick(); led_blink(4); uint16_t blink_rate = BLINK_FAST; uint8_t state = SYSTEM_GPSACQ; while (1) { 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; // TODO: probably don't power on all the time, just on state transition // gps_poweron(); // HAL_Delay(100); HAL_Delay(1000); // gps_update_position(); uint8_t fix_ok = 0; uint8_t numsats = 0; gps_check_lock(&fix_ok, &numsats); if(fix_ok) { // 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! state = SYSTEM_WSPRTX; } // else if(fix_timeout) // { // // Flash error code and go to idle probably? or just try forever? // } } break; // Wait for wspr timeslot and start transmitting case SYSTEM_WSPRTX: { // 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(); } } }