Changeset - dd3b59fcb7a7
[Not reviewed]
default
0 5 0
Ethan Zonca - 10 years ago 2016-04-06 23:10:46
ez@ethanzonca.com
Added code to handle GPS fix acquisition. Hot reaq time is around 3-4s. WSPR currently disabled.
5 files changed with 141 insertions and 39 deletions:
0 comments (0 inline, 0 general)
inc/gps.h
Show inline comments
 
@@ -20,53 +20,52 @@
 
 * Matthew Kanning
 
 * Kyle Ripperger
 
 * Matthew Kroening
 
 *
 
 */
 

	
 

	
 
#ifndef GPS_H_
 
#define GPS_H_
 

	
 
#include <stdint.h>
 

	
 
// Hardware config
 
/*#define GPS_USART USART1
 
#define GPS_IRQ NVIC_USART1_IRQ
 

	
 
#define GPS_TX_PORT GPIOB
 
#define GPS_TX_PIN GPIO6
 
#define GPS_TX_AF GPIO_AF0
 
// Duration before GPS fix is declared stale
 
#define GPS_STALEFIX_MS 60000
 

	
 
#define GPS_RX_PORT GPIOB
 
#define GPS_RX_PIN GPIO7
 
#define GPS_RX_AF GPIO_AF0
 
enum gps_state
 
{
 
    GPS_STATE_ACQUIRING = 0,
 
    GPS_STATE_FRESHFIX,
 
    GPS_STATE_STALEFIX,
 
    GPS_STATE_NOFIX
 
};
 

	
 
#define GPS_ONOFF_PORT GPIOA
 
#define GPS_ONOFF_PIN GPIO1
 
#define GPS_ONOFF GPS_ONOFF_PORT, GPS_ONOFF_PIN
 
*/
 
// Messages (REMOVEME?)
 
#define GGA_MESSAGE
 
#define RMC_MESSAGE
 
#define UKN_MESSAGE
 

	
 
void gps_poweron(void);
 
void gps_poweroff(void);
 
void gps_init(void);
 
void gps_sendubx(uint8_t* data, uint8_t size);
 
char* get_longitudeTrimmed(void);
 
char* get_longitudeLSBs(void);
 
char* get_latitudeTrimmed(void);
 
char* get_latitudeLSBs(void);
 
char* get_timestamp(void);
 
char* get_gpsaltitude(void);
 
char* get_speedKnots(void);
 
char* get_course(void);
 
char* get_hdop(void);
 
uint16_t get_hdop_int_tenths(void);
 
char* get_sv(void);
 
char* get_dayofmonth(void);
 
uint8_t gps_hasfix(void);
 
void gps_process(void);
 
uint8_t gps_getstate(void);
 
void gps_acquirefix(void);
 
void parse_gps_transmission(void);
 
void XORbyteWithChecksum(uint8_t byte);
 

	
 
#endif /* GPS_H_ */
inc/usart.h
Show inline comments
 
#ifndef __usart_H
 
#define __usart_H
 
 
#include "stm32f0xx_hal.h"
 
 
void uart_init(void);
 
void uart_deinit(void);
 
UART_HandleTypeDef* uart_gethandle(void);
 
DMA_HandleTypeDef* uart_get_txdma_handle(void);
 
DMA_HandleTypeDef* uart_get_rxdma_handle(void);
 
 
#endif 
src/gps.c
Show inline comments
 
// TODO: Transition to using https://github.com/cuspaceflight/joey-m/blob/master/firmware/gps.c requesting UBX data
 

	
 
#include "stm32f0xx_hal.h"
 

	
 
#include "config.h"
 
#include "gpio.h"
 
#include "usart.h"
 
#include "gps.h"
 

	
 
// Circular buffer for incoming data
 
uint8_t nmeaBuffer[NMEABUFFER_SIZE];
 

	
 
// Location of parser in the buffer
 
uint8_t nmeaBufferParsePosition = 0;
 

	
 
uint8_t skipBytes = 0;
 

	
 
//used to index data arrays during data collection
 
uint32_t numBytes = 0;
 

	
 
//variables to store data from transmission
 
//least significant digit is stored at location 0 of arrays
 
char tramsmissionType[7];
 

	
 

	
 
void gps_poweron(void)
 
{
 
    // NOTE: pchannel
 
    //gpio_clear(GPS_ONOFF);
 
    HAL_GPIO_WritePin(GPS_NOTEN, 0);
 
    uart_init();
 

	
 
    // Begin DMA reception
 
    HAL_UART_Receive_DMA(uart_gethandle(), nmeaBuffer, NMEABUFFER_SIZE);
 

	
 
}
 

	
 
void gps_poweroff(void)
 
{
 
    // NOTE: pchannel
 
    //gpio_set(GPS_ONOFF);
 
    uart_deinit();
 
    HAL_GPIO_WritePin(GPS_NOTEN, 1);
 
}
 

	
 
char timestamp[12];	//hhmmss.ss
 
char* get_timestamp() 
 
{
 
	return timestamp;
 
}
 
	
 
char latitude[14];	//lllll.lla
 
char latitudeTmpTRIM[8];
 
char latitudeTmpLSB[4];
 
char* get_latitudeTrimmed() 
 
@@ -77,24 +84,36 @@ char quality;		//quality for GGA and val
 
char numSatellites[4];
 
char* get_sv() 
 
{
 
	return numSatellites;
 
}
 

	
 
char hdop[6];		//xx.x
 
char* get_hdop() 
 
{
 
	return hdop;
 
}
 

	
 
uint16_t get_hdop_int_tenths(void)
 
{
 
    // If only one digit before decimal
 
    if(hdop[1] == '.')
 
    {
 
        return (hdop[0]-0x30)*10 + (hdop[2]-0x30);
 
    }
 

	
 
    // Return normal hdop
 
    return (hdop[0]-0x30)*100 + (hdop[1]-0x30)*10 + (hdop[2]-0x30);
 
}
 

	
 
char altitude[10];	//xxxxxx.x
 
char* get_gpsaltitude()
 
{
 
	return altitude;
 
}
 

	
 
//char wgs84Height[8];	//sxxx.x
 
//char lastUpdated[8];	//blank - included for testing
 
//char stationID[8];	//blank - included for testing
 
char checksum[3];	//xx
 

	
 
char knots[8];		//xxx.xx
 
@@ -161,41 +180,36 @@ enum decodeState {
 
//
 
//void usart1_isr(void)
 
//{
 
//	uint8_t recv = 0;// usart_recv(GPS_USART);
 
//	//ECHO debug: usart_send_blocking(GPS_USART, recv);
 
//	nmeaBuffer[nmeaBufferDataPosition % NMEABUFFER_SIZE] = recv;
 
//	nmeaBufferDataPosition = (nmeaBufferDataPosition + 1) % NMEABUFFER_SIZE;
 
//}
 

	
 
void gps_init() 
 
{
 
    // Initialize serial port
 
    uart_init();
 
   // done in poweron uart_init();
 

	
 
    // Begin DMA reception
 
    HAL_UART_Receive_DMA(uart_gethandle(), nmeaBuffer, NMEABUFFER_SIZE);
 

	
 
    timestamp[0] = 0x00;
 
    latitude[0] = 0x00;
 
    longitude[0] = 0x00;
 
    numSatellites[0] = 0x00;
 
    hdop[0] = 0x00;
 
    knots[0] = 0x00;
 
    course[0] = 0x00;
 
    dayofmonth[0] = 0x00;
 

	
 
    gps_poweron();
 
    HAL_Delay(100); // Make sure GPS is awake and alive
 

	
 
//    // Disable GLONASS mode
 
//    uint8_t disable_glonass[20] = {0xB5, 0x62, 0x06, 0x3E, 0x0C, 0x00, 0x00, 0x00, 0x20, 0x01, 0x06, 0x08, 0x0E, 0x00, 0x00, 0x00, 0x01, 0x01, 0x8F, 0xB2};
 
//
 
//    gps_sendubx(disable_glonass, 20);
 
//
 
//    // Enable power saving
 
//    uint8_t enable_powersave[10] = {0xB5, 0x62, 0x06, 0x11, 0x02, 0x00, 0x08, 0x01, 0x22, 0x92};
 
//    gps_sendubx(enable_powersave, 10);
 
//
 
//
 
//    // Set dynamic model 6 (<1g airborne platform)
 
//    uint8_t airborne_model[] = { 0xB5, 0x62, 0x06, 0x24, 0x24, 0x00, 0xFF, 0xFF, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10, 0x27, 0x00, 0x00, 0x05, 0x00, 0xFA, 0x00, 0xFA, 0x00, 0x64, 0x00, 0x2C, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xDC };
 
@@ -219,26 +233,87 @@ static void setParserState(uint8_t state
 

	
 
	// If resetting, clear vars
 
	if(state == INITIALIZE)
 
	{
 
		calculatedChecksum = 0;
 
	}
 
	
 
	// Every time we change state, we have parsed a byte
 
	nmeaBufferParsePosition = (nmeaBufferParsePosition + 1) % NMEABUFFER_SIZE;
 
}
 

	
 

	
 
static uint8_t gps_acquiring = 0;
 
static uint32_t gps_lastfix_time = 0;
 

	
 
//// MKa GPS transmission parser START
 

	
 

	
 
void gps_process(void)
 
{
 
    // If we're trying to acquire a GPS fix
 
    if(gps_acquiring)
 
    {
 
        // Process incoming bytes
 
        parse_gps_transmission();
 

	
 
        // If fix acquired
 
        uint16_t hdop_int = get_hdop_int_tenths();
 
        if(hdop_int < 50 && hdop_int > 0)
 
        {
 
            // Set RTC to GPS time
 

	
 
            // Record time of fix (TODO: don't use ticks if sleeping... use RTC time)
 
            gps_lastfix_time = HAL_GetTick();
 

	
 
            // Turn off GPS module
 
            gps_poweroff();
 

	
 
            // Invalidate HDOP
 
            hdop[0] = '9';
 

	
 
            // Go to idle state
 
            gps_acquiring = 0;
 
        }
 
        else
 
        {
 
            // if too much time has elapsed, set an error flag and go idle
 
            //gps_acquiring = 0;
 
        }
 
    }
 
}
 

	
 
void gps_acquirefix(void)
 
{
 
    gps_poweron();
 

	
 
    // Wait for fix
 
    gps_acquiring = 1;
 
}
 

	
 

	
 

	
 
uint8_t gps_getstate(void)
 
{
 
    if(gps_acquiring)
 
        return GPS_STATE_ACQUIRING;
 
    else if(gps_lastfix_time == 0)
 
        return GPS_STATE_NOFIX;
 
    else if(HAL_GetTick() - gps_lastfix_time < GPS_STALEFIX_MS)
 
        return GPS_STATE_FRESHFIX;
 
    else
 
        return GPS_STATE_STALEFIX;
 

	
 
}
 

	
 
// MKa GPS transmission parser START
 
void parse_gps_transmission(void)
 
{
 
    uint16_t nmeaBufferDataPosition = NMEABUFFER_SIZE - uart_get_rxdma_handle()->Instance->CNDTR;
 

	
 
	char byte;
 

	
 
	while(nmeaBufferDataPosition != nmeaBufferParsePosition)
 
	{
 
	    // Pull byte off of the buffer
 
	    byte = nmeaBuffer[nmeaBufferParsePosition];
 

	
 
		if(decodeState == INITIALIZE) //start of transmission sentence
src/main.c
Show inline comments
 
@@ -76,42 +76,43 @@ void encode_wspr(void)
 
        proceed = 0;
 
        while(!proceed);
 
    }
 
 
    // Disable transmitter
 
    si5351_output_enable(SI5351_CLK0, 0);
 
 
    HAL_GPIO_WritePin(OSC_NOTEN, 1);
 
    HAL_GPIO_WritePin(TCXO_EN, 0);
 
}
 
 
 
 
 
TIM_HandleTypeDef htim1;
 
 
int main(void)
 
{
 
    HAL_Init();
 
 
    sysclk_init();
 
    gpio_init();
 
    adc_init();
 
    i2c_init();
 
    gps_init();
 
 
    //jtencode_init();
 
 
    HAL_Delay(300);
 
 
    // Turn GPS on
 
    HAL_GPIO_WritePin(GPS_NOTEN, 0);
 
    //gps_poweroff();
 
 
    // Disable ICs
 
    HAL_GPIO_WritePin(OSC_NOTEN, 1);
 
    HAL_GPIO_WritePin(TCXO_EN, 0);
 
 
    HAL_GPIO_TogglePin(LED_BLUE);
 
 
    // 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;
 
@@ -131,55 +132,68 @@ int main(void)
 
    HAL_GPIO_TogglePin(LED_BLUE);
 
    HAL_Delay(100);
 
    HAL_GPIO_TogglePin(LED_BLUE);
 
    HAL_Delay(100);
 
    HAL_GPIO_TogglePin(LED_BLUE);
 
    HAL_Delay(100);
 
    HAL_GPIO_TogglePin(LED_BLUE);
 
    HAL_Delay(100);
 
 
    uint8_t lastMinute = 0;
 
    uint16_t blink_rate = 250;
 
 
 
    while (1)
 
    {
 
        // TODO: Trigger this when RTC thinks its time to go
 
        if(HAL_GetTick() - last_wspr > 500)
 
        {
 
            if(get_hdop()[0] == '9' && get_hdop()[1] == '9')
 
                blink_rate = 250;
 
            else
 
                blink_rate = 100;
 
 
            volatile uint8_t minute = get_timestamp()[3] - 0x30;
 
 
            // If last minute was odd and this minute is even (transition)
 
            if(lastMinute%2 == 1 && minute%2 == 0)
 
            switch(gps_getstate())
 
            {
 
                // Wait until the first second of the minute
 
                HAL_Delay(1000);
 
                encode_wspr();
 
                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;
 
            }
 
 
            lastMinute = minute;
 
            // EMZ TODO: this needs to trigger off of RTC minute, not GPS minute
 
//            volatile uint8_t minute = get_timestamp()[3] - 0x30;
 
//
 
//            // 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);
 
//                encode_wspr();
 
//            }
 
 
//            lastMinute = minute;
 
            last_wspr = HAL_GetTick();
 
        }
 
 
        if(HAL_GetTick() - led_timer > blink_rate)
 
        {
 
            HAL_GPIO_TogglePin(LED_BLUE);
 
            led_timer = HAL_GetTick();
 
        }
 
        if(HAL_GetTick() - last_gps > 10)
 
        {
 
            parse_gps_transmission();
 
            gps_process();
 
            last_gps = HAL_GetTick();
 
        }
 
 
        //enter_sleep();
 
    }
 
}
 
 
 
void enter_sleep(void)
 
{
 
    //HAL_SuspendTick();
 
    HAL_TIM_Base_Stop_IT(&htim1);
src/usart.c
Show inline comments
 
#include "stm32f0xx_hal.h"
 
 
#include "usart.h"
 
#include "config.h"
 
#include "gpio.h"
 
 
UART_HandleTypeDef huart1;
 
DMA_HandleTypeDef hdma_usart1_rx;
 
DMA_HandleTypeDef hdma_usart1_tx;
 
uint8_t uart_initted = 0;
 
 
void uart_init(void)
 
{
 
    __GPIOB_CLK_ENABLE();
 
    __HAL_RCC_USART1_CLK_ENABLE();
 
 
    GPIO_InitTypeDef GPIO_InitStruct;
 
 
    // Init gpio pins for uart
 
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
 
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 
    GPIO_InitStruct.Pull = GPIO_NOPULL; //GPIO_PULLUP;
 
@@ -64,24 +65,36 @@ void uart_init(void)
 
    hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
 
    HAL_DMA_Init(&hdma_usart1_tx);
 
 
    __HAL_LINKDMA(&huart1,hdmatx,hdma_usart1_tx);
 
 
//    HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
 
//    HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
 
 
    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
 
    //HAL_NVIC_EnableIRQ(USART1_IRQn);
 
    HAL_NVIC_DisableIRQ(USART1_IRQn);
 
 
    uart_initted = 1;
 
}
 
 
void uart_deinit(void)
 
{
 
    if(uart_initted == 1)
 
    {
 
        HAL_DMA_DeInit(&hdma_usart1_rx);
 
        HAL_DMA_DeInit(&hdma_usart1_tx);
 
        HAL_UART_DeInit(&huart1);
 
        uart_initted = 0;
 
    }
 
}
 
 
UART_HandleTypeDef* uart_gethandle(void)
 
{
 
    return &huart1;
 
} 
 
 
DMA_HandleTypeDef* uart_get_txdma_handle(void)
 
{
 
    return &hdma_usart1_tx;
 
}
 
DMA_HandleTypeDef* uart_get_rxdma_handle(void)
0 comments (0 inline, 0 general)