Changeset - 659774b354b1
[Not reviewed]
default
0 3 0
Ethan Zonca - 9 years ago 2016-09-18 19:40:52
ez@ethanzonca.com
Add a bunch of nonworking state machine code
3 files changed with 85 insertions and 52 deletions:
0 comments (0 inline, 0 general)
inc/gpio.h
Show inline comments
 
#ifndef __gpio_H
 
#define __gpio_H
 
 
#include "stm32f0xx_hal.h"
 
 
 
enum _blinkrate
 
{
 
    BLINK_FAST = 50,
 
    BLINK_MED = 250, 
 
    BLINK_SLOW = 500
 
}
 
 
 
#define OSC_EN_Pin GPIO_PIN_1
 
#define OSC_EN_GPIO_Port GPIOF
 
#define OSC_NOTEN OSC_EN_GPIO_Port , OSC_EN_Pin
 
 
#define GPS_NEN_Pin GPIO_PIN_0
 
#define GPS_NEN_GPIO_Port GPIOF
 
#define GPS_NOTEN GPS_NEN_GPIO_Port , GPS_NEN_Pin
 
 
#define VBATT_SENSE_Pin GPIO_PIN_6
 
#define VBATT_SENSE_GPIO_Port GPIOA
 
 
#define LED_BLUE_Pin GPIO_PIN_0
 
#define LED_BLUE_GPIO_Port GPIOB
 
#define LED_BLUE LED_BLUE_GPIO_Port , LED_BLUE_Pin
 
 
#define TCXO_EN_Pin GPIO_PIN_8
 
#define TCXO_EN_GPIO_Port GPIOA
 
#define TCXO_EN TCXO_EN_GPIO_Port  , TCXO_EN_Pin
 
 
 
void gpio_init(void);
 
void led_blink(uint8_t n);
 
 
#endif 
src/main.c
Show inline comments
 
//
 
// 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();
 
 
    //jtencode_init();
 
 
    HAL_Delay(300);
 
 
    //gps_poweroff();
 
 
    // Disable ICs
 
    HAL_GPIO_WritePin(OSC_NOTEN, 1);
 
    HAL_GPIO_WritePin(TCXO_EN, 0);
 
    wspr_init();
 
 
    uint32_t led_timer = HAL_GetTick();
 
    uint32_t last_gps  = HAL_GetTick();
 
    uint32_t last_wspr  = HAL_GetTick(); //0xfffff; // start immediately.
 
 
 
    led_blink(4);
 
 
    uint8_t lastMinute = 0;
 
    uint16_t blink_rate = 250;
 
    uint16_t blink_rate = BLINK_FAST;
 
    uint8_t state = SYSTEM_GPSACQ;
 
 
    gps_poweron();
 
    HAL_Delay(500);
 
    gps_update_position();
 
 
    while (1)
 
    {
 
        // TODO: Trigger this when RTC thinks its time to go
 
        if(HAL_GetTick() - last_wspr > 500)
 
        switch(state)
 
        {
 
            switch(gps_getstate())
 
 
            // 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:
 
            {
 
                case GPS_STATE_ACQUIRING:
 
                    blink_rate = 250;
 
                    break;
 
                case GPS_STATE_FRESHFIX:
 
                    blink_rate = 50;
 
                    break;
 
                case GPS_STATE_STALEFIX:
 
                case GPS_STATE_NOFIX:
 
                    gps_acquirefix();
 
                    blink_rate = 500;
 
                    break;
 
            }
 
                blink_rate = BLINK_FAST;
 
 
                // TODO: probably don't power on all the time, just on state transition
 
                gps_poweron();
 
                HAL_Delay(500);
 
                gps_update_position();
 
 
                if(fix_ok)
 
                {
 
                    // Disable GPS module
 
                    gps_poweroff();
 
 
                    // TODO: Set RTC from GPS time
 
 
                    // TODO: Set RTC for countdown to next transmission timeslot!
 
 
            uint8_t hour, minute, second;
 
            gps_update_time(&hour, &minute, &second);
 
                    // 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;
 
 
            // EMZ TODO: this needs to trigger off of RTC minute, not GPS minute
 
            // If last minute was odd and this minute is even (transition)
 
//            if(lastMinute%2 == 1 && minute%2 == 0)
 
//            {
 
//                // Wait until the first second of the minute
 
//                HAL_Delay(1000);
 
//                wspr_transmit();
 
//            }
 
            
 
            // 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();
 
                }
 
 
            lastMinute = minute;
 
            last_wspr = HAL_GetTick();
 
                // 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();
 
        }
 
        if(HAL_GetTick() - last_gps > 10)
 
        {
 
            //gps_process();
 
        	gps_update_position();
 
            last_gps = HAL_GetTick();
 
        }
 
 
        //enter_sleep();
 
    }
 
}
 
 
 
 
src/wspr.c
Show inline comments
 
@@ -22,48 +22,51 @@ uint32_t freq = WSPR_DEFAULT_FREQ;
 
uint8_t symbol_count = WSPR_SYMBOL_COUNT;
 
uint16_t ctc = WSPR_CTC;
 
uint16_t tone_spacing = WSPR_TONE_SPACING;
 
volatile uint8_t proceed = 0;
 

	
 
TIM_HandleTypeDef htim1;
 

	
 

	
 

	
 
void wspr_init(void)
 
{
 
    // Start timer for WSPR
 
    __TIM1_CLK_ENABLE();
 
    htim1.Instance = TIM1;
 
    htim1.Init.Prescaler = 512; // gives 64uS ticks from 8MHz ahbclk
 
    htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
 
    htim1.Init.Period = ctc; // Count up to this value (how many 64uS ticks per symbol)
 
    htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 
    htim1.Init.RepetitionCounter = 0;
 
    HAL_TIM_Base_Init(&htim1);
 
    HAL_TIM_Base_Start_IT(&htim1);
 
    HAL_NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn, 0, 0);
 
    HAL_NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);
 

	
 
    // Turn off ICs
 
    HAL_GPIO_WritePin(OSC_NOTEN, 1);
 
    HAL_GPIO_WritePin(TCXO_EN, 0);
 
}
 

	
 
// Do anything needed to prepare for sleep
 
void wspr_sleep(void)
 
{
 
    HAL_TIM_Base_Stop_IT(&htim1);
 
}
 

	
 
void wspr_wakeup(void)
 
{
 
    HAL_TIM_Base_Start_IT(&htim1);
 
}
 

	
 

	
 
// Bring up TCXO and oscillator IC
 
void wspr_transmit(void)
 
{
 
    HAL_GPIO_WritePin(OSC_NOTEN, 0);
 
    HAL_GPIO_WritePin(TCXO_EN, 1);
 
    HAL_Delay(100);
 

	
 
    // Bring up the chip
 
    si5351_init(i2c_get(), SI5351_CRYSTAL_LOAD_8PF, 0);
 
    si5351_set_correction(0);
0 comments (0 inline, 0 general)