Changeset - f40195400941
[Not reviewed]
default
0 5 0
Ethan Zonca - 8 years ago 2017-09-21 22:34:15
ez@ethanzonca.com
Initial non-compiling implementation of secondary wspr encoding modes
5 files changed with 163 insertions and 9 deletions:
0 comments (0 inline, 0 general)
.settings/language.settings.xml
Show inline comments
 
@@ -2,13 +2,13 @@
 
<project>
 
	<configuration id="ilg.gnuarmeclipse.managedbuild.cross.toolchain.base.1766192373" name="Default">
 
		<extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
 
			<provider copy-of="extension" id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
 
			<provider-reference id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider" ref="shared-provider"/>
 
			<provider copy-of="extension" id="org.eclipse.cdt.managedbuilder.core.GCCBuildCommandParser"/>
 
			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1355837167222073652" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
 
			<provider class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector" console="false" env-hash="1836845659980131172" id="ilg.gnuarmeclipse.managedbuild.cross.GCCBuiltinSpecsDetector" keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings Cross ARM" parameter="${COMMAND} ${FLAGS} ${cross_toolchain_flags} -E -P -v -dD &quot;${INPUTS}&quot;" prefer-non-shared="true">
 
				<language-scope id="org.eclipse.cdt.core.gcc"/>
 
				<language-scope id="org.eclipse.cdt.core.g++"/>
 
			</provider>
 
			<provider-reference id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider" ref="shared-provider"/>
 
		</extension>
 
	</configuration>
inc/i2c.h
Show inline comments
 
#ifndef __i2c_H
 
#define __i2c_H
 
 
#include "stm32f0xx_hal.h"
 
 
void i2c_init(void);
 
void i2c_deinit(void);
 
I2C_HandleTypeDef* i2c_get(void);
 
 
#endif 
 
inc/wspr.h
Show inline comments
 
@@ -2,10 +2,10 @@
 
#define _WSPR_H
 

	
 
// Prototypes
 
void wspr_init(void);
 
void wspr_sleep(void);
 
void wspr_wakeup(void);
 
void wspr_transmit(uint8_t* grid_locator);
 
void wspr_transmit(uint8_t* grid_locator, uint8_t send_alternate);
 

	
 

	
 
#endif
src/main.c
Show inline comments
 
@@ -11,13 +11,13 @@
 
#include "wspr.h"
 
#include "rtc.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
 
// Probable wake up 1 minute early -- 0.45min possible +/- on wakeup time with 15min sync intervals
 
 
 
// TODO: Add JT9 message with more grid locator digits + altitude + vbatt + temp
 
// MSG13charmax:
 
// 	X: gridloc
 
//  Y: altitude
 
@@ -37,13 +37,13 @@ static void ledpulse(void);
 
uint32_t statled_ontime = 0;
 
 
 
int main(void)
 
{
 
    HAL_Init();
 
    HAL_Delay(2000); // startup delay before infinisleep
 
    HAL_Delay(1000); // startup delay before infinisleep
 
 
    sysclk_init();
 
    rtc_init();
 
    gpio_init();
 
    adc_init();
 
    wspr_init();
 
@@ -61,18 +61,19 @@ int main(void)
 
    uint8_t nextwspr_time_valid = 0;
 
    uint32_t last_wspr_tx_time = 0;
 
 
    uint8_t fix_ok = 0;
 
    uint8_t numsats = 0;
 
 
    uint8_t packet_type = 0;
 
 
    while (1)
 
    {
 
 
    	// Every 10 minutes, wake up and try to wspr
 
    	if(state == SYSTEM_IDLE && (HAL_GetTick() - last_wspr_tx_time > 60000))// * 10))
 
    	if(state == SYSTEM_IDLE && (HAL_GetTick() - last_wspr_tx_time > 60000 /* * 10 */))
 
    	{
 
    		state = SYSTEM_GPSACQ;
 
    	}
 
 
        // Update fix status every 2 seconds
 
        if(HAL_GetTick() - gps_polltimer > 2000)
 
@@ -81,13 +82,13 @@ int main(void)
 
            {
 
            	gps_update_data();
 
 
            	// If odd minute
 
            	if(gps_getdata()->minute % 2)
 
            	{
 
            		// Wait until even minute, coming soon
 
            		// Wait until even minute plus one second, coming soon
 
            		nextwspr_time = HAL_GetTick() + (60000 - (gps_getdata()->second * 1000));
 
                    nextwspr_time_valid = 1;
 
 
            	}
 
            	// If even minute
 
            	else
 
@@ -187,13 +188,15 @@ int main(void)
 
            			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);
 
                        // TODO: Switch between alternate and standard packet
 
						wspr_transmit(grid_locator, packet_type);
 
                        //packet_type = !packet_type; // alternate packet type
 
						last_wspr_tx_time = HAL_GetTick();
 
						state = SYSTEM_IDLE;
 
            		}
 
            		else
 
            		{
 
            			// Window was missed, go back to idle, and try again after time delay
src/wspr.c
Show inline comments
 
#include "stm32f0xx_hal.h"
 
#include "si5351.h"
 
#include "jtencode.h"
 
#include "gpio.h"
 
#include "wspr.h"
 
#include "i2c.h"
 
#include "gps.h"
 
#include "config.h"
 

	
 

	
 
#define WSPR_DEFAULT_FREQ 10140100UL
 
#define WSPR_TONE_SPACING 146 // ~1.46 Hz
 
#define WSPR_CTC 10672 // CTC value for WSPR
 

	
 
char call_orig[7] = "KD8TDF";
 
#define DBM_ORIG 10
 

	
 

	
 
// Test stuff
 
char call[7] = "KD8TDF";
 
char loc[5] = "EN72";
 
char loc[5] = "EN82";
 
uint8_t dbm = 10;
 
uint8_t tx_buffer[255];
 

	
 
// Frequencies and channel info
 
uint32_t freq = WSPR_DEFAULT_FREQ;
 
uint8_t symbol_count = WSPR_SYMBOL_COUNT;
 
@@ -45,19 +50,164 @@ void wspr_wakeup(void)
 
{
 
    HAL_TIM_Base_Start_IT(&htim1);
 
}
 

	
 

	
 
// Bring up TCXO and oscillator IC
 
void wspr_transmit(uint8_t* grid_locator)
 
void wspr_transmit(uint8_t* grid_locator, uint8_t send_alternate)
 
{
 
	// Copy 4 digit grid locator to local buffer; null terminate
 
	for(uint8_t i=0; i<4; i++)
 
		loc[i] = grid_locator[i];
 
	loc[4] = '\0';
 

	
 
    // Set power to altitude in m / 150
 
    uint8_t altscaled = gps_getdata()->altitude / 150;
 
    if(altscaled > 60)
 
        altscaled = 60;
 

	
 

	
 
    // If alternate packet, send 0XFXXEN82XX
 
    if(send_alternate)
 
    {
 

	
 

	
 

	
 
        /////////////////////////////////////////////////
 
        // Composite altitude and sub-maidenhead locator
 
        ///////////////////////////////////////////////// 
 
        uint16_t maiden_ext = (loc[4] - 'A') + ((loc[5] - 'A') * 24); // 0-575
 
        uint16_t altitude_mod = gps_getdata()->altitude / 20;   
 

	
 
        // Ciel at 21,340 meters
 
        if(altitude_mod > 1067)
 
            altitude_mod = 1067; // Don't overflow into maidenhead!
 
    
 
        // Compose composite altitude (lsbs) with maidenhead locator (msbs)
 
        uint32_t subalt = (1068 * maiden_ext) + (gps_getdata()->altitude / 20);
 

	
 

	
 

	
 
        ////////////////////////////////////////////
 
        // Encode extended maidenhead and altitude
 
        ////////////////////////////////////////////
 
        call[0] = '0';
 

	
 
        // Split into chunks of valmax 36, 26, 26, 26
 

	
 
        // Mask off following 3 26valmax fields
 
        uint32_t chunk = subalt / 26 / 26 / 26; 
 

	
 
        // Encode to callsign
 
        if(chunk < 10)
 
            call[1] = '0' + chunk
 
        else
 
            call[1] = chunk - 10 + 'A';
 

	
 
        // Subtract off previous portion
 
        subalt -= (chunk * 26 * 26 * 26);
 

	
 
        // Mask off following 2 26bit values
 
        chunk = (subalt / 26 / 26);
 

	
 
        call[3] = 'A' + chunk;
 

	
 
        // Subtract off previous portion
 
        subalt -= (chunk * 26 * 26)
 

	
 
        // Mask off following 1 26bit values
 
        chunk = (subalt / 26);
 

	
 
        call[4] = 'A' + chunk;
 

	
 
        // Subtract off previous portion
 
        subalt -= (chunk * 26);
 

	
 
        // Remainder is the last call char
 
        call[5] = 'A' + subalt;
 
 
 

	
 
        ////////////////////////////////////////
 
        // Composite temp/batt/speed/gps 
 
        ////////////////////////////////////////
 

	
 
        // Encode value from -50C to 39C => 0-89. TODO: Bounds!
 
        uint8_t temp_enc = 0 + 50;
 

	
 
        // Encode value from 0-39 with some scalar/offset/etc
 
        uint8_t batt_enc = 0; 
 

	
 
        // Encode speed in knots from 0-82 to 0-41
 
        uint8_t speed_enc = gpsdata()->speed / 2;
 
        if(speed_enc > 41)
 
            speed_enc = 41;
 

	
 
        // Encode GPS status
 
        uint8_t gps_status = 0b00; // MSB is valid fix, lsb is sats > 8
 

	
 
        uint32_t engdata = gps_status + 2 * (speed_enc + 42 * (batt_enc + 40 * temp_enc));
 

	
 
        ////////////////////////////////////////////
 
        // Encode temp/batt/speed/gps
 
        ////////////////////////////////////////////
 

	
 
        // Mask off fields
 
        chunk = engdata / 18 / 10 / 10 / 19;  
 

	
 
        // Encode to grid locator
 
        grid_locator[0] = 'A' + chunk;
 

	
 
        // Subtract off previous portion 
 
        engdata -= (chunk * 18 * 10 * 10 * 19);  
 

	
 
        // Mask of fields
 
        chunk = engdata / 10 / 10 / 19;  
 

	
 
        // Encode to grid locator
 
        grid_locator[1] = 'A' + chunk;
 

	
 
        // Subtract off previous portion
 
        engdata -= (chunk * 10 * 10 * 19);  
 

	
 
        // Mask off fields
 
        chunk = engdata / 10 / 19;  
 

	
 
        // Encode
 
        grid_locater[2] = '0' + chunk;
 

	
 
        // Subtract
 
        engdata -= (chunk * 10 * 19);  
 

	
 
        // Mask off
 
        chunk = engdata / 19;  
 

	
 
        // Encode
 
        grid_locator[3] = chunk;
 

	
 
        // Subtract
 
        engdata -= (chunk * 19);  
 

	
 
        // Mask off
 
        chunk = engdata;  
 

	
 
        // Encode
 
        uint8_t powers[] = {0, 3, 7, 10, 13, 17, 20, 23, 27, 30, 33, 37, 40, 43, 47, 50, 53, 57, 60}
 
        dbm = powers[chunk];
 
    }
 
    else
 
    {
 
        call[0] = call_orig[0];
 
        call[1] = call_orig[1];
 
        call[2] = call_orig[2];
 
        call[3] = call_orig[3];
 
        call[4] = call_orig[4];
 
        call[5] = call_orig[5];
 
        call[6] = call_orig[6];
 

	
 
        dbm = DBM_ORIG; 
 
    }
 

	
 
    // Start timer for WSPR
 
    __TIM1_CLK_ENABLE();
 
    htim1.Instance = TIM1;
 
    htim1.Init.Prescaler = 512 / 4; // FIXED gives 64us ticks from 2mhz clock // gives 64uS ticks from 8MHz ahbclk
 
    htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
0 comments (0 inline, 0 general)