diff --git a/.cproject b/.cproject --- a/.cproject +++ b/.cproject @@ -11,12 +11,14 @@ + + - + - + @@ -153,4 +123,6 @@ + + diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml --- a/.settings/language.settings.xml +++ b/.settings/language.settings.xml @@ -5,7 +5,7 @@ - + diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ JTENCODE_INCLUDES = -Ilib/jtencode # USER_CFLAGS: user C flags (enable warnings, enable debug info) USER_CFLAGS = -Wall -g -ffunction-sections -fdata-sections -Os -fno-common --function-sections -fdata-sections -USER_CFLAGS += -flto +#USER_CFLAGS += -flto # USER_LDFLAGS: user LD flags USER_LDFLAGS = -fno-exceptions -ffunction-sections -fdata-sections -Wl,--gc-sections diff --git a/inc/config.h b/inc/config.h --- a/inc/config.h +++ b/inc/config.h @@ -6,13 +6,13 @@ // Transmitter config // -------------------------------------------------------------------------- - +//#define LED_DISABLE // -------------------------------------------------------------------------- // ADC config (adc.c) // -------------------------------------------------------------------------- -// Temperature sensor offset (die temperature from ambient, esimate, in Celcius) +// Temperature sensor offset (die temperature from ambient, estimate, in Celcius) #define ADC_TEMPERATURE_OFFSET -10 diff --git a/inc/wspr.h b/inc/wspr.h --- a/inc/wspr.h +++ b/inc/wspr.h @@ -6,6 +6,6 @@ void wspr_init(void); void wspr_sleep(void); void wspr_wakeup(void); void wspr_transmit(uint8_t* grid_locator, uint8_t send_alternate); - +void wspr_pilot_tone(void); #endif diff --git a/lib/si5351/si5351.h b/lib/si5351/si5351.h --- a/lib/si5351/si5351.h +++ b/lib/si5351/si5351.h @@ -35,7 +35,7 @@ /* Define definitions */ #define SI5351_BUS_BASE_ADDR ((0x60 & 0x7f) << 1) -#define SI5351_XTAL_FREQ 25000000 +#define SI5351_XTAL_FREQ 26000000 #define SI5351_PLL_FIXED 90000000000ULL #define SI5351_FREQ_MULT 100ULL #define SI5351_DEFAULT_CLK 1000000000ULL diff --git a/src/adc.c b/src/adc.c --- a/src/adc.c +++ b/src/adc.c @@ -72,6 +72,9 @@ void adc_init(void) void adc_start(void) { + // TODO: Is stopping the clocks enough? Might need to disable periph? + __ADC1_CLK_ENABLE(); + __DMA1_CLK_ENABLE(); HAL_ADC_Start_DMA(&hadc, adc_buffer, ADC_BUF_LEN); } @@ -79,6 +82,9 @@ void adc_start(void) void adc_stop(void) { HAL_ADC_Stop_DMA(&hadc); + __DMA1_CLK_DISABLE(); + __ADC1_CLK_DISABLE(); + } diff --git a/src/gpio.c b/src/gpio.c --- a/src/gpio.c +++ b/src/gpio.c @@ -1,5 +1,7 @@ #include "gpio.h" +#include "config.h" +// Initialize GPIOs void gpio_init(void) { @@ -67,11 +69,13 @@ void gpio_init(void) void led_blink(uint8_t n) { - for(int i = 0; i < n; i++) - { - HAL_GPIO_WritePin(LED_BLUE, 1); - HAL_Delay(100); - HAL_GPIO_WritePin(LED_BLUE, 0); - HAL_Delay(100); - } + #ifndef LED_DISABLE + for(int i = 0; i < n; i++) + { + HAL_GPIO_WritePin(LED_BLUE, 1); + HAL_Delay(100); + HAL_GPIO_WritePin(LED_BLUE, 0); + HAL_Delay(100); + } + #endif } diff --git a/src/main.c b/src/main.c --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,7 @@ #include "wspr.h" #include "rtc.h" #include "gps.h" +#include "config.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 @@ -63,16 +64,23 @@ int main(void) uint8_t packet_type = 0; + // Transmit pilot tone to test TX on bootup + HAL_Delay(1000); + wspr_pilot_tone(); + adc_stop(); + HAL_Delay(1000); + while (1) { + // TODO: Disable GPIO port clocking when not needed! // Every 10 minutes, wake up and try to wspr - if(state == SYSTEM_IDLE && (HAL_GetTick() - last_wspr_tx_time > 60000 * 10)) - { - state = SYSTEM_GPSACQ; - } +// if(state == SYSTEM_IDLE && (HAL_GetTick() - last_wspr_tx_time > 60000 * 10)) +// { +// state = SYSTEM_GPSACQ; +// } - // Update fix status every 2 seconds + // Update fix status every 2 seconds, only if the GPS is powered on if(HAL_GetTick() - gps_polltimer > 2000) { if(gps_ison()) @@ -142,6 +150,9 @@ int main(void) gps_poweron(); // power on and initialize GPS module } + // TODO: Move GPS processing into here from above! + + // If 3d fix with a decent enough precision if( ((gps_getdata()->fixtype == 2) || (gps_getdata()->fixtype == 3)) && gps_getdata()->pdop < 10 && nextwspr_time_valid == 1) { @@ -213,25 +224,26 @@ int main(void) HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI); } - // Schedule next wakeup (maybe 2mins prior ot timeslot if no osc trim) + // Schedule next wakeup (maybe 2mins prior to timeslot if no osc trim) // Next wakeup should enter SYSTEM_GPSACQ state... } break; } + #ifndef LED_DISABLE + if(HAL_GetTick() - led_timer > blink_rate) + { + ledpulse(); + led_timer = HAL_GetTick(); + } - if(HAL_GetTick() - led_timer > blink_rate) - { - ledpulse(); - led_timer = HAL_GetTick(); - } - - if(statled_ontime && HAL_GetTick() - statled_ontime > 10) - { - HAL_GPIO_WritePin(LED_BLUE, 0); - statled_ontime = 0; - } + if(statled_ontime && HAL_GetTick() - statled_ontime > 10) + { + HAL_GPIO_WritePin(LED_BLUE, 0); + statled_ontime = 0; + } + #endif } } diff --git a/src/rtc.c b/src/rtc.c --- a/src/rtc.c +++ b/src/rtc.c @@ -19,66 +19,66 @@ void rtc_init(void) __HAL_RCC_RTC_ENABLE(); - RTC_TimeTypeDef sTime; - RTC_DateTypeDef sDate; - RTC_AlarmTypeDef sAlarm; + RTC_TimeTypeDef sTime; + RTC_DateTypeDef sDate; + RTC_AlarmTypeDef sAlarm; - hrtc.Instance = RTC; - hrtc.Init.HourFormat = RTC_HOURFORMAT_24; - hrtc.Init.AsynchPrediv = 124; - hrtc.Init.SynchPrediv = 322; // if this has enough bits should be 1.0018Hz based on 40kHz LSI - hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; - hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; - hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; + hrtc.Instance = RTC; + hrtc.Init.HourFormat = RTC_HOURFORMAT_24; + hrtc.Init.AsynchPrediv = 124; + hrtc.Init.SynchPrediv = 322; // if this has enough bits should be 1.0018Hz based on 40kHz LSI + hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; + hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; + hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; - if (HAL_RTC_Init(&hrtc) != HAL_OK) - { - Error_Handler(); - } + if (HAL_RTC_Init(&hrtc) != HAL_OK) + { + Error_Handler(); + } - sTime.Hours = 0x0; - sTime.Minutes = 0x0; - sTime.Seconds = 0x0; - sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; - sTime.StoreOperation = RTC_STOREOPERATION_RESET; - if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) - { - Error_Handler(); - } + sTime.Hours = 0x0; + sTime.Minutes = 0x0; + sTime.Seconds = 0x0; + sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; + sTime.StoreOperation = RTC_STOREOPERATION_RESET; + if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) + { + Error_Handler(); + } - sDate.WeekDay = RTC_WEEKDAY_MONDAY; - sDate.Month = RTC_MONTH_JANUARY; - sDate.Date = 0x1; - sDate.Year = 0x0; + sDate.WeekDay = RTC_WEEKDAY_MONDAY; + sDate.Month = RTC_MONTH_JANUARY; + sDate.Date = 0x1; + sDate.Year = 0x0; - if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK) - { - Error_Handler(); - } + if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK) + { + Error_Handler(); + } - /**Enable the Alarm A - */ - sAlarm.AlarmTime.Hours = 0x0; - sAlarm.AlarmTime.Minutes = 0x0; - sAlarm.AlarmTime.Seconds = 0x0; - sAlarm.AlarmTime.SubSeconds = 0x0; - sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; - sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET; + /**Enable the Alarm A + */ + sAlarm.AlarmTime.Hours = 0x0; + sAlarm.AlarmTime.Minutes = 0x0; + sAlarm.AlarmTime.Seconds = 0x0; + sAlarm.AlarmTime.SubSeconds = 0x0; + sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; + sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET; - // Alarm will trigger on the Xth second of every minute - sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY | RTC_ALARMMASK_HOURS | RTC_ALARMMASK_MINUTES; - sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL; - sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE; - sAlarm.AlarmDateWeekDay = 0x1; - sAlarm.Alarm = RTC_ALARM_A; - if (HAL_RTC_SetAlarm(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK) - { - Error_Handler(); - } + // Alarm will trigger on the Xth second of every minute + sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY | RTC_ALARMMASK_HOURS | RTC_ALARMMASK_MINUTES; + sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL; + sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE; + sAlarm.AlarmDateWeekDay = 0x1; + sAlarm.Alarm = RTC_ALARM_A; + if (HAL_RTC_SetAlarm(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK) + { + Error_Handler(); + } - HAL_NVIC_SetPriority(RTC_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(RTC_IRQn); + HAL_NVIC_SetPriority(RTC_IRQn, 0, 0); + HAL_NVIC_EnableIRQ(RTC_IRQn); } void rtc_cal(void) diff --git a/src/system.c b/src/system.c --- a/src/system.c +++ b/src/system.c @@ -32,6 +32,7 @@ void sysclk_init(void) RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInit; + // TODO: Probably disable HSI14? This only drives the ADC RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSI14|RCC_OSCILLATORTYPE_LSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSI14State = RCC_HSI14_ON; diff --git a/src/wspr.c b/src/wspr.c --- a/src/wspr.c +++ b/src/wspr.c @@ -5,6 +5,7 @@ #include "wspr.h" #include "i2c.h" #include "gps.h" +#include "adc.h" #include "config.h" @@ -304,3 +305,58 @@ void wspr_transmit(uint8_t* grid_locator } + +// Transmit boot-up test tones to check tx +void wspr_pilot_tone(void) +{ + // Bring up TCXO + HAL_GPIO_WritePin(OSC_NOTEN, 0); + HAL_GPIO_WritePin(TCXO_EN, 1); + HAL_Delay(100); + + // Bring up the chip + i2c_init(); + si5351_init(i2c_get(), SI5351_CRYSTAL_LOAD_8PF, 0); + si5351_set_correction(0); + si5351_set_freq(WSPR_DEFAULT_FREQ * 100, 0, SI5351_CLK0); + si5351_drive_strength(SI5351_CLK0, SI5351_DRIVE_6MA); // Set for max power if desired (8ma max) + si5351_output_enable(SI5351_CLK0, 1); + + // Make sure the other outputs of the SI5351 are disabled + si5351_output_enable(SI5351_CLK1, 0); // Disable the clock initially + si5351_output_enable(SI5351_CLK2, 0); // Disable the clock initially + + // disable clock powers + si5351_set_clock_pwr(SI5351_CLK1, 0); + si5351_set_clock_pwr(SI5351_CLK2, 0); + + // Key transmitter + si5351_output_enable(SI5351_CLK0, 1); + + uint8_t tone_table[7] = {50, 100, 70, 50, 0, 10, 0}; + + // Boot-up pilot tones + for(uint8_t i=0; i<7; i++) + { + uint32_t freq2 = (WSPR_DEFAULT_FREQ + 10*tone_table[i]) * 100; + si5351_set_freq(freq2, 0, SI5351_CLK0); + #ifndef LED_DISABLE + HAL_GPIO_TogglePin(LED_BLUE); + #endif + HAL_Delay(500); + } + + + // Disable transmitter + si5351_output_enable(SI5351_CLK0, 0); + + HAL_GPIO_WritePin(OSC_NOTEN, 1); + HAL_GPIO_WritePin(TCXO_EN, 0); + + i2c_deinit(); + + // Make sure LED is off if we had an odd number of toggles above + HAL_GPIO_WritePin(LED_BLUE, 0); + +} +