kopia lustrzana https://github.com/RPiks/pico-WSPR-tx
Pre-release GPS build.
rodzic
5a9f1cc01b
commit
f5c6f5b2cd
|
@ -9,8 +9,6 @@ set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
# Initialise pico_sdk from installed location
|
# Initialise pico_sdk from installed location
|
||||||
# (note this can come from environment, CMake cache etc)
|
# (note this can come from environment, CMake cache etc)
|
||||||
# set(PICO_SDK_PATH "/home/jabba/pico-sdk")
|
|
||||||
|
|
||||||
set(PICO_BOARD pico CACHE STRING "Board type")
|
set(PICO_BOARD pico CACHE STRING "Board type")
|
||||||
|
|
||||||
# Pull in Raspberry Pi Pico SDK (must be before project)
|
# Pull in Raspberry Pi Pico SDK (must be before project)
|
||||||
|
@ -22,13 +20,8 @@ endif()
|
||||||
|
|
||||||
project(pico-wspr-tx C CXX ASM)
|
project(pico-wspr-tx C CXX ASM)
|
||||||
|
|
||||||
# Initialise the Raspberry Pi Pico SDK
|
|
||||||
pico_sdk_init()
|
pico_sdk_init()
|
||||||
|
|
||||||
# Add executable. Default name is the project name, version 0.1
|
|
||||||
|
|
||||||
add_executable(pico-wspr-tx)
|
add_executable(pico-wspr-tx)
|
||||||
|
|
||||||
pico_generate_pio_header(pico-wspr-tx ${CMAKE_CURRENT_LIST_DIR}/pico-hf-oscillator/piodco/dco.pio)
|
pico_generate_pio_header(pico-wspr-tx ${CMAKE_CURRENT_LIST_DIR}/pico-hf-oscillator/piodco/dco.pio)
|
||||||
|
|
||||||
target_sources(pico-wspr-tx PUBLIC
|
target_sources(pico-wspr-tx PUBLIC
|
||||||
|
@ -46,7 +39,7 @@ target_sources(pico-wspr-tx PUBLIC
|
||||||
)
|
)
|
||||||
|
|
||||||
pico_set_program_name(pico-wspr-tx "pico-wspr-tx")
|
pico_set_program_name(pico-wspr-tx "pico-wspr-tx")
|
||||||
pico_set_program_version(pico-wspr-tx "0.1")
|
pico_set_program_version(pico-wspr-tx "0.5")
|
||||||
|
|
||||||
pico_enable_stdio_uart(pico-wspr-tx 1)
|
pico_enable_stdio_uart(pico-wspr-tx 1)
|
||||||
pico_enable_stdio_usb(pico-wspr-tx 1)
|
pico_enable_stdio_usb(pico-wspr-tx 1)
|
||||||
|
@ -62,16 +55,13 @@ target_include_directories(pico-wspr-tx PRIVATE
|
||||||
${CMAKE_CURRENT_LIST_DIR}/..
|
${CMAKE_CURRENT_LIST_DIR}/..
|
||||||
)
|
)
|
||||||
|
|
||||||
# Add any user requested libraries
|
target_link_libraries(pico-wspr-tx
|
||||||
target_link_libraries(
|
|
||||||
pico-wspr-tx
|
|
||||||
pico_stdlib
|
pico_stdlib
|
||||||
pico_sync
|
pico_sync
|
||||||
pico_multicore
|
pico_multicore
|
||||||
hardware_timer
|
hardware_timer
|
||||||
hardware_clocks
|
hardware_clocks
|
||||||
hardware_pio
|
hardware_pio
|
||||||
hardware_vreg
|
|
||||||
)
|
)
|
||||||
|
|
||||||
pico_add_extra_outputs(pico-wspr-tx)
|
pico_add_extra_outputs(pico-wspr-tx)
|
||||||
|
|
|
@ -58,8 +58,12 @@ static void __not_in_flash_func (TxChannelISR)(void)
|
||||||
const int n2send = TxChannelPop(spTX, &byte);
|
const int n2send = TxChannelPop(spTX, &byte);
|
||||||
if(n2send)
|
if(n2send)
|
||||||
{
|
{
|
||||||
|
const int32_t i32_compensation_millis =
|
||||||
|
PioDCOGetFreqShiftMilliHertz(spTX->_p_oscillator,
|
||||||
|
(uint64_t)(spTX->_u32_dialfreqhz * 1000LL));
|
||||||
|
|
||||||
PioDCOSetFreq(pDCO, spTX->_u32_dialfreqhz,
|
PioDCOSetFreq(pDCO, spTX->_u32_dialfreqhz,
|
||||||
(uint32_t)byte * WSPR_FREQ_STEP_MILHZ);
|
(uint32_t)byte * WSPR_FREQ_STEP_MILHZ - 2 * i32_compensation_millis);
|
||||||
}
|
}
|
||||||
|
|
||||||
spTX->_tm_future_call += spTX->_bit_period_us;
|
spTX->_tm_future_call += spTX->_bit_period_us;
|
||||||
|
|
|
@ -63,7 +63,6 @@ typedef struct
|
||||||
uint32_t _bit_period_us;
|
uint32_t _bit_period_us;
|
||||||
|
|
||||||
uint8_t _timer_alarm_num;
|
uint8_t _timer_alarm_num;
|
||||||
//uint8_t _b_allowtx;
|
|
||||||
|
|
||||||
uint8_t _ix_input, _ix_output;
|
uint8_t _ix_input, _ix_output;
|
||||||
uint8_t _pbyte_buffer[256];
|
uint8_t _pbyte_buffer[256];
|
||||||
|
@ -81,7 +80,5 @@ uint8_t TxChannelPending(TxChannelContext *pctx);
|
||||||
int TxChannelPush(TxChannelContext *pctx, uint8_t *psrc, int n);
|
int TxChannelPush(TxChannelContext *pctx, uint8_t *psrc, int n);
|
||||||
int TxChannelPop(TxChannelContext *pctx, uint8_t *pdst);
|
int TxChannelPop(TxChannelContext *pctx, uint8_t *pdst);
|
||||||
void TxChannelClear(TxChannelContext *pctx);
|
void TxChannelClear(TxChannelContext *pctx);
|
||||||
//void TxChannelStart(TxChannelContext *pctx);
|
|
||||||
//void TxChannelStop(TxChannelContext *pctx);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
// THE SOFTWARE.
|
// THE SOFTWARE.
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
#include "WSPRbeacon.h"
|
#include "WSPRbeacon.h"
|
||||||
|
|
||||||
#include <WSPRutility.h>
|
#include <WSPRutility.h>
|
||||||
|
|
||||||
/// @brief Initializes a new WSPR beacon context.
|
/// @brief Initializes a new WSPR beacon context.
|
||||||
|
@ -123,6 +122,11 @@ int WSPRbeaconSendPacket(const WSPRbeaconContext *pctx)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Arranges WSPR sending in accordance with pre-defined schedule.
|
||||||
|
/// @brief It works only if GPS receiver available (for now).
|
||||||
|
/// @param pctx Ptr to Context.
|
||||||
|
/// @param verbose Whether stdio output is needed.
|
||||||
|
/// @return 0 if OK, -1 if NO GPS received available
|
||||||
int WSPRbeaconTxScheduler(WSPRbeaconContext *pctx, int verbose)
|
int WSPRbeaconTxScheduler(WSPRbeaconContext *pctx, int verbose)
|
||||||
{
|
{
|
||||||
assert_(pctx);
|
assert_(pctx);
|
||||||
|
@ -137,12 +141,12 @@ int WSPRbeaconTxScheduler(WSPRbeaconContext *pctx, int verbose)
|
||||||
|
|
||||||
if(!is_GPS_available)
|
if(!is_GPS_available)
|
||||||
{
|
{
|
||||||
StampPrintf("Waiting for GPS receiver...");
|
if(verbose) StampPrintf("WSPR> Waiting for GPS receiver...");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_GPS_active || (pctx->_pTX->_p_oscillator->_pGPStime->_time_data._u32_utime_nmea_last &&
|
if(is_GPS_active || (pctx->_pTX->_p_oscillator->_pGPStime->_time_data._u32_utime_nmea_last &&
|
||||||
is_GPS_override && u64_GPS_last_age_sec < 2 * HOUR))
|
is_GPS_override && u64_GPS_last_age_sec < WSPR_MAX_GPS_DISCONNECT_TM))
|
||||||
{
|
{
|
||||||
const uint32_t u32_unixtime_now
|
const uint32_t u32_unixtime_now
|
||||||
= pctx->_pTX->_p_oscillator->_pGPStime->_time_data._u32_utime_nmea_last + u64_GPS_last_age_sec;
|
= pctx->_pTX->_p_oscillator->_pGPStime->_time_data._u32_utime_nmea_last + u64_GPS_last_age_sec;
|
||||||
|
@ -152,13 +156,12 @@ int WSPRbeaconTxScheduler(WSPRbeaconContext *pctx, int verbose)
|
||||||
const int islot_modulo = islot_number % pctx->_txSched._u8_tx_slot_skip;
|
const int islot_modulo = islot_number % pctx->_txSched._u8_tx_slot_skip;
|
||||||
|
|
||||||
static int itx_trigger = 0;
|
static int itx_trigger = 0;
|
||||||
//StampPrintf("Slot: %d %d %d", islot_number, islot_modulo, itx_trigger);
|
|
||||||
if(ZERO == islot_modulo)
|
if(ZERO == islot_modulo)
|
||||||
{
|
{
|
||||||
if(!itx_trigger)
|
if(!itx_trigger)
|
||||||
{
|
{
|
||||||
itx_trigger = 1;
|
itx_trigger = 1;
|
||||||
StampPrintf("WSPR> Start TX.");
|
if(verbose) StampPrintf("WSPR> Start TX.");
|
||||||
|
|
||||||
PioDCOStart(pctx->_pTX->_p_oscillator);
|
PioDCOStart(pctx->_pTX->_p_oscillator);
|
||||||
WSPRbeaconCreatePacket(pctx);
|
WSPRbeaconCreatePacket(pctx);
|
||||||
|
@ -169,7 +172,7 @@ int WSPRbeaconTxScheduler(WSPRbeaconContext *pctx, int verbose)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
itx_trigger = 0;
|
itx_trigger = 0;
|
||||||
StampPrintf("WSPR> Passive TX slot.");
|
if(verbose) StampPrintf("WSPR> Passive TX slot.");
|
||||||
PioDCOStop(pctx->_pTX->_p_oscillator);
|
PioDCOStop(pctx->_pTX->_p_oscillator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,6 +180,8 @@ int WSPRbeaconTxScheduler(WSPRbeaconContext *pctx, int verbose)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Dumps the beacon context to stdio.
|
||||||
|
/// @param pctx Ptr to Context.
|
||||||
void WSPRbeaconDumpContext(const WSPRbeaconContext *pctx)
|
void WSPRbeaconDumpContext(const WSPRbeaconContext *pctx)
|
||||||
{
|
{
|
||||||
assert_(pctx);
|
assert_(pctx);
|
||||||
|
|
6
core1.c
6
core1.c
|
@ -54,8 +54,7 @@
|
||||||
|
|
||||||
#include "pico-hf-oscillator/lib/assert.h"
|
#include "pico-hf-oscillator/lib/assert.h"
|
||||||
#include <piodco.h>
|
#include <piodco.h>
|
||||||
#include "defines.h"
|
#include <defines.h>
|
||||||
|
|
||||||
#include <WSPRbeacon.h>
|
#include <WSPRbeacon.h>
|
||||||
|
|
||||||
extern WSPRbeaconContext *pWSPR;
|
extern WSPRbeaconContext *pWSPR;
|
||||||
|
@ -74,9 +73,6 @@ void Core1Entry()
|
||||||
/* Initialize DCO */
|
/* Initialize DCO */
|
||||||
assert_(0 == PioDCOInit(p, pWSPR->_pTX->_i_tx_gpio, clkhz));
|
assert_(0 == PioDCOInit(p, pWSPR->_pTX->_i_tx_gpio, clkhz));
|
||||||
|
|
||||||
/* Run DCO. */
|
|
||||||
//PioDCOStart(p);
|
|
||||||
|
|
||||||
/* Set initial freq. */
|
/* Set initial freq. */
|
||||||
assert_(0 == PioDCOSetFreq(p, freq_hz, 0U));
|
assert_(0 == PioDCOSetFreq(p, freq_hz, 0U));
|
||||||
|
|
||||||
|
|
23
defines.h
23
defines.h
|
@ -81,21 +81,18 @@
|
||||||
/* A macro of multiplication guarantees of doing so using 1 ASM command. */
|
/* A macro of multiplication guarantees of doing so using 1 ASM command. */
|
||||||
#define iMUL32ASM(a,b) __mul_instruction((int32_t)(a), (int32_t)(b))
|
#define iMUL32ASM(a,b) __mul_instruction((int32_t)(a), (int32_t)(b))
|
||||||
|
|
||||||
/* Performing the square by ASM. */
|
#define SECOND 1 /* Time. */
|
||||||
#define iSquare32ASM(x) (iMUL32ASM((x), (x)))
|
|
||||||
/* Hardware defs. */
|
|
||||||
#define kHz 1000UL
|
|
||||||
#define MHz 1000000UL
|
|
||||||
#define PLL_SYS_MHZ 270UL
|
|
||||||
/* WSPR defs. */
|
|
||||||
//#define WSPR_DIAL_FREQ_HZ 7040000UL
|
|
||||||
//#define WSPR_SHIFT_FREQ_HZ 50UL
|
|
||||||
#define WSPR_FREQ_STEP_MILHZ 2930UL
|
|
||||||
|
|
||||||
#define SECOND 1
|
|
||||||
#define MINUTE (60 * SECOND)
|
#define MINUTE (60 * SECOND)
|
||||||
#define HOUR (60 * MINUTE)
|
#define HOUR (60 * MINUTE)
|
||||||
|
|
||||||
#define GPS_PPS_PIN 2
|
#define kHz 1000UL /* Freq. */
|
||||||
|
#define MHz 1000000UL
|
||||||
|
#define PLL_SYS_MHZ 270UL
|
||||||
|
/* WSPR defs. */
|
||||||
|
#define WSPR_FREQ_STEP_MILHZ 2930UL /* FSK freq.bin (*2 this time). */
|
||||||
|
#define WSPR_MAX_GPS_DISCONNECT_TM \
|
||||||
|
(6 * HOUR) /* How long is active without GPS. */
|
||||||
|
|
||||||
|
#define GPS_PPS_PIN 2 /* GPS time mark PIN. */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
3
init.c
3
init.c
|
@ -55,8 +55,7 @@
|
||||||
|
|
||||||
#include "pico/stdlib.h"
|
#include "pico/stdlib.h"
|
||||||
#include "hardware/clocks.h"
|
#include "hardware/clocks.h"
|
||||||
|
#include <defines.h>
|
||||||
#include "defines.h"
|
|
||||||
|
|
||||||
/// @brief Initializes Pi pico low level hardware.
|
/// @brief Initializes Pi pico low level hardware.
|
||||||
void InitPicoHW(void)
|
void InitPicoHW(void)
|
||||||
|
|
26
main.c
26
main.c
|
@ -11,21 +11,25 @@
|
||||||
// DESCRIPTION
|
// DESCRIPTION
|
||||||
// The pico-WSPR-tx project provides WSPR beacon function using only
|
// The pico-WSPR-tx project provides WSPR beacon function using only
|
||||||
// Pi Pico board. *NO* additional hardware such as freq.synth required.
|
// Pi Pico board. *NO* additional hardware such as freq.synth required.
|
||||||
|
// External GPS receiver is optional and serves a purpose of holding
|
||||||
|
// WSPR time window order and accurate frequancy drift compensation.
|
||||||
//
|
//
|
||||||
// HOWTOSTART
|
// HOWTOSTART
|
||||||
// .
|
// ./build.sh; cp ./build/*.uf2 /media/Pico_Board/
|
||||||
//
|
//
|
||||||
// PLATFORM
|
// PLATFORM
|
||||||
// Raspberry Pi pico.
|
// Raspberry Pi pico.
|
||||||
//
|
//
|
||||||
// REVISION HISTORY
|
// REVISION HISTORY
|
||||||
//
|
|
||||||
// Rev 0.1 18 Nov 2023
|
// Rev 0.1 18 Nov 2023
|
||||||
// Initial release.
|
// Rev 0.5 02 Dec 2023
|
||||||
//
|
//
|
||||||
// PROJECT PAGE
|
// PROJECT PAGE
|
||||||
// https://github.com/RPiks/pico-WSPR-tx
|
// https://github.com/RPiks/pico-WSPR-tx
|
||||||
//
|
//
|
||||||
|
// SUBMODULE PAGE
|
||||||
|
// https://github.com/RPiks/pico-hf-oscillator
|
||||||
|
//
|
||||||
// LICENCE
|
// LICENCE
|
||||||
// MIT License (http://www.opensource.org/licenses/mit-license.php)
|
// MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||||
//
|
//
|
||||||
|
@ -56,13 +60,11 @@
|
||||||
#include "pico/multicore.h"
|
#include "pico/multicore.h"
|
||||||
#include "pico-hf-oscillator/lib/assert.h"
|
#include "pico-hf-oscillator/lib/assert.h"
|
||||||
#include "pico-hf-oscillator/defines.h"
|
#include "pico-hf-oscillator/defines.h"
|
||||||
#include "defines.h"
|
#include <defines.h>
|
||||||
#include <piodco.h>
|
#include <piodco.h>
|
||||||
#include <WSPRbeacon.h>
|
#include <WSPRbeacon.h>
|
||||||
#include "debug/logutils.h"
|
#include <logutils.h>
|
||||||
|
#include <protos.h>
|
||||||
void InitPicoHW(void);
|
|
||||||
void Core1Entry(void);
|
|
||||||
|
|
||||||
WSPRbeaconContext *pWSPR;
|
WSPRbeaconContext *pWSPR;
|
||||||
|
|
||||||
|
@ -106,9 +108,13 @@ int main()
|
||||||
{
|
{
|
||||||
WSPRbeaconTxScheduler(pWB, YES);
|
WSPRbeaconTxScheduler(pWB, YES);
|
||||||
|
|
||||||
if(0 == ++tick % 10)
|
gpio_put(PICO_DEFAULT_LED_PIN, 1);
|
||||||
|
sleep_ms(100);
|
||||||
|
gpio_put(PICO_DEFAULT_LED_PIN, 0);
|
||||||
|
|
||||||
|
if(0 == ++tick % 60)
|
||||||
WSPRbeaconDumpContext(pWB);
|
WSPRbeaconDumpContext(pWB);
|
||||||
|
|
||||||
sleep_ms(1000);
|
sleep_ms(900);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef PROTOS_H_
|
||||||
|
#define PROTOS_H_
|
||||||
|
|
||||||
|
void InitPicoHW(void);
|
||||||
|
void Core1Entry(void);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,64 @@
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Roman Piksaykin [piksaykin@gmail.com], R2BDY
|
||||||
|
// https://www.qrz.com/db/r2bdy
|
||||||
|
//
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// flashmem.h - Utility of writing & reading a data from/to Pico's flash mem.
|
||||||
|
//
|
||||||
|
// DESCRIPTION
|
||||||
|
// .
|
||||||
|
//
|
||||||
|
// HOWTOSTART
|
||||||
|
// .
|
||||||
|
//
|
||||||
|
// PLATFORM
|
||||||
|
// Raspberry Pi pico.
|
||||||
|
//
|
||||||
|
// REVISION HISTORY
|
||||||
|
//
|
||||||
|
// Rev 0.1 02 Dec 2023
|
||||||
|
// Initial release.
|
||||||
|
//
|
||||||
|
// PROJECT PAGE
|
||||||
|
// https://github.com/RPiks/pico-WSPR-tx
|
||||||
|
//
|
||||||
|
// LICENCE
|
||||||
|
// MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||||
|
//
|
||||||
|
// Copyright (c) 2023 by Roman Piksaykin
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge,to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the Software), to deal
|
||||||
|
// in the Software without restriction,including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY,WHETHER IN AN ACTION OF CONTRACT,TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#ifndef FLASHMEM_H_
|
||||||
|
#define FLASHMEM_H_
|
||||||
|
|
||||||
|
#include "hardware/flash.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
void *_pFlashTargetOffset;
|
||||||
|
|
||||||
|
} FlashMemContext;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
Ładowanie…
Reference in New Issue