diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml --- a/.settings/language.settings.xml +++ b/.settings/language.settings.xml @@ -11,7 +11,7 @@ - + diff --git a/inc/rtc.h b/inc/rtc.h --- a/inc/rtc.h +++ b/inc/rtc.h @@ -4,9 +4,11 @@ #include "stm32f0xx_hal.h" +void rtc_incseconds(void); void rtc_init(void); RTC_TimeTypeDef* rtc_time(void); uint64_t rtc_timestamp(void); +uint32_t rtc_timestamp_seconds(void); RTC_HandleTypeDef* rtc_gethandle(void); diff --git a/src/interrupts.c b/src/interrupts.c --- a/src/interrupts.c +++ b/src/interrupts.c @@ -38,12 +38,15 @@ void TIM1_BRK_UP_TRG_COM_IRQHandler(void void RTC_IRQHandler(void) { + HAL_RTC_AlarmIRQHandler(rtc_gethandle()); } void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) { + rtc_incseconds(); + // Do something awesome or not } diff --git a/src/main.c b/src/main.c --- a/src/main.c +++ b/src/main.c @@ -33,7 +33,7 @@ enum _state }; static void __calc_gridloc(char *dst, double lat, double lon); -static void ledpulse(void); +static void __ledpulse(void); static void __sleep_enter_stop(void); uint32_t statled_ontime = 0; @@ -61,8 +61,8 @@ int main(void) // state = SYSTEM_IDLE; uint32_t gps_polltimer = 0; - uint32_t fix_acq_starttime = 0; - uint32_t nextwspr_time = 0; + uint64_t fix_acq_starttime = 0; + uint64_t nextwspr_time = 0; uint8_t nextwspr_time_valid = 0; uint64_t last_wspr_tx_time = 0; uint64_t idle_blink_last = 0; @@ -78,18 +78,22 @@ int main(void) // __DBGMCU_CLK_ENABLE() ; // (RCC->APB2ENR |= (RCC_APB2ENR_DBGMCUEN)) // HAL_EnableDBGStopMode(); // SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_STOP); - +//////////////////////////////////////////// +///// TODO: MUST synchro RTC to start of 1PPS second to make sure we actually start wspr on time with 1s granularity +///////////////////////////////////////// while (1) { // Every 10 minutes, wake up and try to wspr - if(state == SYSTEM_IDLE && (rtc_timestamp() - last_wspr_tx_time > 60000 * 10)) + if(state == SYSTEM_IDLE && (rtc_timestamp_seconds() - last_wspr_tx_time >= 60 * 10)) { state = SYSTEM_GPSACQ; } // Update fix status every 2 seconds, only if the GPS is powered on - if(HAL_GetTick() - gps_polltimer > 2000) + if(rtc_timestamp_seconds() - gps_polltimer >= 3) { + gps_polltimer = rtc_timestamp_seconds(); + if(gps_ison()) { HAL_GPIO_WritePin(LED_BLUE, 1); @@ -103,7 +107,7 @@ int main(void) if(gps_getdata()->minute % 2) { // Wait until even minute plus one second, coming soon - nextwspr_time = HAL_GetTick() + (60000 - (gps_getdata()->second * 1000)); + nextwspr_time = rtc_timestamp_seconds() + (60 - (gps_getdata()->second * 1)); nextwspr_time_valid = 1; } @@ -111,11 +115,10 @@ int main(void) else { // Wait until odd minute, one minute and some change away - nextwspr_time = HAL_GetTick() + 60000 + (60000 - (gps_getdata()->second * 1000)); + nextwspr_time = rtc_timestamp_seconds() + 60 + (60 - (gps_getdata()->second * 1)); nextwspr_time_valid = 1; } } - gps_polltimer = HAL_GetTick(); } @@ -153,7 +156,7 @@ int main(void) if(!gps_ison()) { - fix_acq_starttime = HAL_GetTick(); + fix_acq_starttime = rtc_timestamp_seconds(); gps_poweron(); // power on and initialize GPS module } @@ -176,13 +179,13 @@ int main(void) adc_start(); } // If no decent fix in 3 minutes - else if(HAL_GetTick() - fix_acq_starttime > 60000 * 3) + else if(rtc_timestamp_seconds() - fix_acq_starttime >= 60 * 3) { // Flash error code and go to idle, try again next time led_blink(4); gps_poweroff(); fix_acq_starttime = 0; - last_wspr_tx_time = rtc_timestamp(); // repeat acq/tx cycle after big time delay + last_wspr_tx_time = rtc_timestamp_seconds(); // repeat acq/tx cycle after big time delay state = SYSTEM_IDLE; } else @@ -203,9 +206,9 @@ int main(void) // If we're after the minute but not more than 2s after the minute, start tx - if(HAL_GetTick() >= nextwspr_time) + if(rtc_timestamp_seconds() >= nextwspr_time) { - if(HAL_GetTick() < nextwspr_time + 2000) + if(rtc_timestamp_seconds() < nextwspr_time + 2) { volatile double latitude_flt = (double)gps_getdata()->latitude / 10000000.0; volatile double longitude_flt = (double)gps_getdata()->longitude / 10000000.0; @@ -216,14 +219,14 @@ int main(void) // TODO: Switch between alternate and standard packet wspr_transmit(grid_locator, packet_type); packet_type = !packet_type; // alternate packet type - last_wspr_tx_time = rtc_timestamp(); + last_wspr_tx_time = rtc_timestamp_seconds(); state = SYSTEM_IDLE; adc_stop(); } else { // Window was missed, go back to idle, and try again after time delay - last_wspr_tx_time = rtc_timestamp(); + last_wspr_tx_time = rtc_timestamp_seconds(); state = SYSTEM_IDLE; adc_stop(); } @@ -250,7 +253,7 @@ int main(void) #ifndef LED_DISABLE if((blink_rate != BLINK_DISABLE) && (HAL_GetTick() - led_timer > blink_rate)) { - ledpulse(); + __ledpulse(); led_timer = HAL_GetTick(); } @@ -285,7 +288,7 @@ static void __sleep_enter_stop(void) __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); } -static void ledpulse(void) +static void __ledpulse(void) { HAL_GPIO_WritePin(LED_BLUE, 1); statled_ontime = HAL_GetTick(); diff --git a/src/rtc.c b/src/rtc.c --- a/src/rtc.c +++ b/src/rtc.c @@ -7,7 +7,15 @@ #include "gpio.h" -RTC_HandleTypeDef hrtc; +static RTC_HandleTypeDef hrtc; +static volatile uint32_t seconds_ctr = 0; + + +void rtc_incseconds(void) +{ + //HAL_GPIO_TogglePin(LED_BLUE); + seconds_ctr += 1; +} static void Error_Handler(void) { @@ -94,14 +102,16 @@ void rtc_init(void) } -RTC_TimeTypeDef time_last = {0}; +static RTC_TimeTypeDef time_last = {0}; +// Get the time from the RTC RTC_TimeTypeDef* rtc_time(void) { HAL_RTC_GetTime(&hrtc, &time_last, RTC_FORMAT_BCD); return &time_last; } +// Calculate value in milliseconds from subseconds of the RTC uint16_t __rtc_millis(uint32_t sub_seconds) { // Subsecond counter counts down from SynchPrediv value to zero @@ -110,6 +120,7 @@ uint16_t __rtc_millis(uint32_t sub_secon #define JULIAN_DATE_BASE 2440588 // Unix epoch time in Julian calendar (UnixTime = 00:00:00 01.01.1970 => JDN = 2440588) +// Calculate timestamp in milliseconds since Unix epoch uint64_t rtc_timestamp(void) { RTC_TimeTypeDef time = {0}; @@ -154,12 +165,20 @@ uint64_t rtc_timestamp(void) } +uint32_t rtc_timestamp_seconds(void) +{ + return seconds_ctr; +} + +// Calibrate the RTC somehow void rtc_cal(void) { // Do something with hrtc.Instance->CALR; // this has a plus and minus component, see refman } + +// RTC accessor RTC_HandleTypeDef* rtc_gethandle(void) { return &hrtc;