Changeset - 38f0f2457409
[Not reviewed]
default
0 3 0
Ethan Zonca - 9 years ago 2016-10-13 20:21:04
ez@ethanzonca.com
Fix issue where code would constantly enter gpsacq state because of last wspr timeout expiring
3 files changed with 18 insertions and 0 deletions:
0 comments (0 inline, 0 general)
src/gps.c
Show inline comments
 
@@ -141,112 +141,126 @@ static uint8_t _gps_verify_checksum(uint
 
        return 0;
 
    else
 
        return 1;
 
}
 

	
 

	
 
// Calculate a UBX checksum using 8-bit Fletcher (RFC1145)
 
static void gps_ubx_checksum(uint8_t* data, uint8_t len, uint8_t* cka, uint8_t* ckb)
 
{
 
    *cka = 0;
 
    *ckb = 0;
 
    for( uint8_t i = 0; i < len; i++ )
 
    {
 
        *cka += *data;
 
        *ckb += *cka;
 
        data++;
 
    }
 
}
 

	
 

	
 
// Power on GPS module and initialize UART
 
void gps_poweron(void)
 
{
 
    // NOTE: pchannel
 
    HAL_GPIO_WritePin(GPS_NOTEN, 0);
 
    uart_init();
 

	
 

	
 

	
 
	// Disable messages
 
	uint8_t setGGA[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0XFF, 0X23};
 
	HAL_UART_Transmit(uart_gethandle(), setGGA, sizeof(setGGA)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 
	uint8_t ackbuffer[10];
 
	for(uint8_t i=0; i<10; i++)
 
		ackbuffer[i] = 0xaa;
 
	HAL_UART_Receive(uart_gethandle(), ackbuffer, 10, 100);
 

	
 
	uint8_t setZDA[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X08, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X07, 0X5B};
 
	HAL_UART_Transmit(uart_gethandle(), setZDA, sizeof(setZDA)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 
	uint8_t setGLL[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X01, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X2A};
 
	HAL_UART_Transmit(uart_gethandle(), setGLL, sizeof(setGLL)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 
	uint8_t setGSA[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X02, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X01, 0X31};
 
	HAL_UART_Transmit(uart_gethandle(), setGSA, sizeof(setGSA)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 
	uint8_t setGSV[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X03, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X02, 0X38};
 
	HAL_UART_Transmit(uart_gethandle(), setGSV, sizeof(setGSV)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 
	uint8_t setRMC[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X04, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X03, 0X3F};
 
	HAL_UART_Transmit(uart_gethandle(), setRMC, sizeof(setRMC)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 
	uint8_t setVTG[] = {0XB5, 0X62, 0X06, 0X01, 0X08, 0X00, 0XF0, 0X05, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X04, 0X46};
 
	HAL_UART_Transmit(uart_gethandle(), setVTG, sizeof(setRMC)/sizeof(uint8_t), 100);
 
	HAL_Delay(100);
 

	
 

	
 
//    // 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);
 
//    volatile HAL_StatusTypeDef res = HAL_UART_Transmit(uart_gethandle(), disable_glonass, 20, 100);
 
//
 
//    // Enable power saving
 
//    uint8_t enable_powersave[10] = {0xB5, 0x62, 0x06, 0x11, 0x02, 0x00, 0x08, 0x01, 0x22, 0x92};
 
//    //gps_sendubx(enable_powersave, 10);
 
//    res = HAL_UART_Transmit(uart_gethandle(), enable_powersave, 10, 100);
 
//
 
//
 
//    // 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 };
 
//    //gps_sendubx(airborne_model, sizeof(airborne_model)/sizeof(uint8_t));
 
//    res = HAL_UART_Transmit(uart_gethandle(), airborne_model, sizeof(airborne_model)/sizeof(uint8_t), 100);
 

	
 

	
 

	
 

	
 

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

	
 
    gpson = 1;
 
}
 

	
 

	
 
// Power off GPS module
 
void gps_poweroff(void)
 
{
 
    // NOTE: pchannel
 
	position.hour = 0;
 
	position.minute = 0;
 
	position.second = 0;
 
	position.altitude = 0;
 
	position.latitude = 0;
 
	position.longitude = 0;
 
	position.day = 0;
 
	position.month = 0;
 
	position.fixtype = 0;
 
	position.valid = 0;
 
	position.pdop = 0;
 
	position.sats_in_solution = 0;
 
	position.speed = 0;
 

	
 
    uart_deinit();
 
    HAL_GPIO_WritePin(GPS_NOTEN, 1);
 
    gpson = 0;
 
}
 

	
 
gps_data_t* gps_getdata(void)
 
{
 
    return &position;
 
}
 

	
 
uint8_t gps_ison(void)
 
{
 
    return gpson;
 
}
 

	
 
// vim:softtabstop=4 shiftwidth=4 expandtab 
src/main.c
Show inline comments
 
@@ -47,190 +47,192 @@ int main(void)
 
 
    uint16_t blink_rate = BLINK_FAST;
 
    uint8_t state = SYSTEM_GPSACQ;
 
 
    uint32_t gps_polltimer = 0;
 
    uint32_t fix_acq_starttime = 0;
 
    uint32_t nextwspr_time = 0;
 
    uint32_t last_wspr_tx_time = 0;
 
 
    uint8_t fix_ok = 0;
 
    uint8_t numsats = 0;
 
 
 
    while (1)
 
    {
 
 
    	// Every 10 minutes, wake up and try to wspr
 
    	if(HAL_GetTick() - last_wspr_tx_time > 60000 * 10)
 
    	{
 
    		state = SYSTEM_GPSACQ;
 
    	}
 
 
        // Update fix status every 2 seconds
 
        if(HAL_GetTick() - gps_polltimer > 2000)
 
        {
 
            if(gps_ison())
 
            {
 
            	gps_update_data();
 
 
            	// If odd minute
 
            	if(gps_getdata()->minute % 2)
 
            	{
 
            		// Wait until even minute, coming soon
 
            		nextwspr_time = HAL_GetTick() + (60000 - (gps_getdata()->second * 1000));
 
 
            	}
 
            	// If even minute
 
            	else
 
            	{
 
            		// Wait until odd minute, one minute and some change away
 
            		nextwspr_time = HAL_GetTick() + 60000 + (60000 - (gps_getdata()->second * 1000));
 
            	}
 
            }
 
            gps_polltimer = HAL_GetTick();
 
        }
 
 
 
 
        switch(state)
 
        {
 
 
            // Idling: sleep and wait for RTC timeslot trigger
 
            case SYSTEM_IDLE:
 
            {
 
                blink_rate = BLINK_SLOW;
 
                HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);
 
                // 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;
 
 
                if(!gps_ison())
 
                {
 
                	fix_acq_starttime = HAL_GetTick();
 
                    gps_poweron(); // power on and initialize GPS module
 
                }
 
 
                // If 3d fix with a decent enough precision
 
                if( ((gps_getdata()->fixtype == 2) || (gps_getdata()->fixtype == 3)) && gps_getdata()->pdop < 10)
 
                {
 
                    // 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!
 
                    fix_acq_starttime = 0;
 
                    state = SYSTEM_WSPRTX;
 
                }
 
                // If no decent fix in 3 minutes
 
                else if(HAL_GetTick() - fix_acq_starttime > 60000 * 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 = HAL_GetTick(); // repeat acq/tx cycle after big time delay
 
                	state = SYSTEM_IDLE;
 
                }
 
            } break;
 
 
            
 
            // Wait for wspr timeslot and start transmitting
 
            case SYSTEM_WSPRTX:
 
            {
 
            	blink_rate = BLINK_SLOW;
 
                // Wait for wspr countdown timer to expire and go to tx
 
//                if(timeout_expired)
 
//                {
 
 
            	// If we're after the minute but not more than 2s after the minute, start tx
 
            	if(HAL_GetTick() >= nextwspr_time)
 
            	{
 
            		if(HAL_GetTick() < nextwspr_time + 2000)
 
            		{
 
            			volatile double latitude_flt = (double)gps_getdata()->latitude / 10000000.0;
 
            			volatile double longitude_flt = (double)gps_getdata()->longitude / 10000000.0;
 
            			volatile uint8_t grid_locator[7];
 
 
            			__calc_gridloc(grid_locator, latitude_flt, longitude_flt);
 
 
						wspr_transmit(grid_locator);
 
						last_wspr_tx_time = HAL_GetTick();
 
						state = SYSTEM_IDLE;
 
            		}
 
            		else
 
            		{
 
            			// Window was missed, go back to idle, and try again after time delay
 
						last_wspr_tx_time = HAL_GetTick();
 
            			state = SYSTEM_IDLE;
 
            		}
 
                }
 
 
                // Schedule next wakeup (maybe 2mins prior ot timeslot if no osc trim)
 
                // Next wakeup should enter SYSTEM_GPSACQ state...
 
 
            } break;
 
 
        }
 
 
 
        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;
 
        }
 
 
    }
 
}
 
 
static void ledpulse(void)
 
{
 
    HAL_GPIO_WritePin(LED_BLUE, 1);
 
	statled_ontime = HAL_GetTick();
 
}
 
 
static void __calc_gridloc(char *dst, double lat, double lon)
 
{
 
	int o1, o2, o3;
 
	int a1, a2, a3;
 
	double remainder;
 
	// longitude
 
	remainder = lon + 180.0;
 
	o1 = (int)(remainder / 20.0);
 
	remainder = remainder - (double)o1 * 20.0;
 
	o2 = (int)(remainder / 2.0);
 
	remainder = remainder - 2.0 * (double)o2;
 
	o3 = (int)(12.0 * remainder);
 
 
	// latitude
 
	remainder = lat + 90.0;
 
	a1 = (int)(remainder / 10.0);
 
	remainder = remainder - (double)a1 * 10.0;
 
	a2 = (int)(remainder);
 
	remainder = remainder - (double)a2;
 
	a3 = (int)(24.0 * remainder);
 
	dst[0] = (char)o1 + 'A';
 
	dst[1] = (char)a1 + 'A';
 
	dst[2] = (char)o2 + '0';
 
	dst[3] = (char)a2 + '0';
 
	dst[4] = (char)o3 + 'A';
 
	dst[5] = (char)a3 + 'A';
 
	dst[6] = (char)0;
 
}
 
src/uart.c
Show inline comments
 
#include "stm32f0xx_hal.h"
 
 
#include "uart.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;
 
    GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
 
    GPIO_InitStruct.Alternate = GPIO_AF0_USART1;
 
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
 
    // Init UART periph
 
    huart1.Instance = USART1;
 
    huart1.Init.BaudRate = 9600;
 
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
 
    huart1.Init.StopBits = UART_STOPBITS_1;
 
    huart1.Init.Parity = UART_PARITY_NONE;
 
    huart1.Init.Mode = UART_MODE_TX_RX;
 
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
 
    huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 
    huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_RXOVERRUNDISABLE_INIT|UART_ADVFEATURE_DMADISABLEONERROR_INIT;
 
    huart1.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;
 
    huart1.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;
 
    HAL_UART_Init(&huart1);
 
 
    HAL_Delay(100);
 
	uint8_t switch_baud[] = "$PUBX,41,1,0003,0001,115200,0*1E\r\n";
 
	HAL_UART_Transmit(uart_gethandle(), switch_baud, sizeof(switch_baud)/sizeof(uint8_t), 1000);
 
 
    HAL_UART_DeInit(&huart1);
 
    huart1.Init.BaudRate = 115200;
 
    HAL_UART_Init(&huart1);
 
 
 
//
 
//    __DMA1_CLK_ENABLE();
 
//
 
//  // Init UART DMA
 
//    hdma_usart1_rx.Instance = DMA1_Channel3;
 
//    hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
 
//    hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
 
//    hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
 
//    hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 
//    hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 
//    hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
 
//    hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW;
 
//    HAL_DMA_Init(&hdma_usart1_rx);
 
//
 
//    __HAL_LINKDMA(&huart1,hdmarx,hdma_usart1_rx);
 
//
 
//    hdma_usart1_tx.Instance = DMA1_Channel2;
 
//    hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
 
//    hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
 
//    hdma_usart1_tx.Init.MemInc = DMA_MINC_DISABLE;
 
//    hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
 
//    hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 
//    hdma_usart1_tx.Init.Mode = DMA_NORMAL;
 
//    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);
 
        __HAL_RCC_USART1_CLK_DISABLE();
 
 
        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)
 
{
 
    return &hdma_usart1_rx;
 
}
 
0 comments (0 inline, 0 general)