diff --git a/CMakeLists.txt b/CMakeLists.txt index 87d5dc2..09c57a8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,8 +9,6 @@ set(CMAKE_CXX_STANDARD 17) # Initialise pico_sdk from installed location # (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") # Pull in Raspberry Pi Pico SDK (must be before project) @@ -22,13 +20,8 @@ endif() project(pico-wspr-tx C CXX ASM) -# Initialise the Raspberry Pi Pico SDK pico_sdk_init() - -# Add executable. Default name is the project name, version 0.1 - add_executable(pico-wspr-tx) - pico_generate_pio_header(pico-wspr-tx ${CMAKE_CURRENT_LIST_DIR}/pico-hf-oscillator/piodco/dco.pio) 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_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_usb(pico-wspr-tx 1) @@ -62,16 +55,13 @@ target_include_directories(pico-wspr-tx PRIVATE ${CMAKE_CURRENT_LIST_DIR}/.. ) -# Add any user requested libraries -target_link_libraries( - pico-wspr-tx - pico_stdlib - pico_sync - pico_multicore - hardware_timer - hardware_clocks - hardware_pio - hardware_vreg - ) +target_link_libraries(pico-wspr-tx + pico_stdlib + pico_sync + pico_multicore + hardware_timer + hardware_clocks + hardware_pio + ) pico_add_extra_outputs(pico-wspr-tx) diff --git a/TxChannel/TxChannel.c b/TxChannel/TxChannel.c index 7020a1a..c35b607 100644 --- a/TxChannel/TxChannel.c +++ b/TxChannel/TxChannel.c @@ -58,8 +58,12 @@ static void __not_in_flash_func (TxChannelISR)(void) const int n2send = TxChannelPop(spTX, &byte); if(n2send) { + const int32_t i32_compensation_millis = + PioDCOGetFreqShiftMilliHertz(spTX->_p_oscillator, + (uint64_t)(spTX->_u32_dialfreqhz * 1000LL)); + 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; diff --git a/TxChannel/TxChannel.h b/TxChannel/TxChannel.h index eec5ba5..f9b5aef 100644 --- a/TxChannel/TxChannel.h +++ b/TxChannel/TxChannel.h @@ -63,7 +63,6 @@ typedef struct uint32_t _bit_period_us; uint8_t _timer_alarm_num; - //uint8_t _b_allowtx; uint8_t _ix_input, _ix_output; uint8_t _pbyte_buffer[256]; @@ -81,7 +80,5 @@ uint8_t TxChannelPending(TxChannelContext *pctx); int TxChannelPush(TxChannelContext *pctx, uint8_t *psrc, int n); int TxChannelPop(TxChannelContext *pctx, uint8_t *pdst); void TxChannelClear(TxChannelContext *pctx); -//void TxChannelStart(TxChannelContext *pctx); -//void TxChannelStop(TxChannelContext *pctx); #endif diff --git a/WSPRbeacon/WSPRbeacon.c b/WSPRbeacon/WSPRbeacon.c index bcdd63b..445de6d 100644 --- a/WSPRbeacon/WSPRbeacon.c +++ b/WSPRbeacon/WSPRbeacon.c @@ -50,7 +50,6 @@ // THE SOFTWARE. /////////////////////////////////////////////////////////////////////////////// #include "WSPRbeacon.h" - #include /// @brief Initializes a new WSPR beacon context. @@ -123,6 +122,11 @@ int WSPRbeaconSendPacket(const WSPRbeaconContext *pctx) 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) { assert_(pctx); @@ -137,12 +141,12 @@ int WSPRbeaconTxScheduler(WSPRbeaconContext *pctx, int verbose) if(!is_GPS_available) { - StampPrintf("Waiting for GPS receiver..."); + if(verbose) StampPrintf("WSPR> Waiting for GPS receiver..."); return -1; } 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 = 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; static int itx_trigger = 0; - //StampPrintf("Slot: %d %d %d", islot_number, islot_modulo, itx_trigger); if(ZERO == islot_modulo) { if(!itx_trigger) { itx_trigger = 1; - StampPrintf("WSPR> Start TX."); + if(verbose) StampPrintf("WSPR> Start TX."); PioDCOStart(pctx->_pTX->_p_oscillator); WSPRbeaconCreatePacket(pctx); @@ -169,7 +172,7 @@ int WSPRbeaconTxScheduler(WSPRbeaconContext *pctx, int verbose) else { itx_trigger = 0; - StampPrintf("WSPR> Passive TX slot."); + if(verbose) StampPrintf("WSPR> Passive TX slot."); PioDCOStop(pctx->_pTX->_p_oscillator); } } @@ -177,6 +180,8 @@ int WSPRbeaconTxScheduler(WSPRbeaconContext *pctx, int verbose) return 0; } +/// @brief Dumps the beacon context to stdio. +/// @param pctx Ptr to Context. void WSPRbeaconDumpContext(const WSPRbeaconContext *pctx) { assert_(pctx); diff --git a/core1.c b/core1.c index 178e71e..ea14363 100644 --- a/core1.c +++ b/core1.c @@ -54,8 +54,7 @@ #include "pico-hf-oscillator/lib/assert.h" #include -#include "defines.h" - +#include #include extern WSPRbeaconContext *pWSPR; @@ -74,9 +73,6 @@ void Core1Entry() /* Initialize DCO */ assert_(0 == PioDCOInit(p, pWSPR->_pTX->_i_tx_gpio, clkhz)); - /* Run DCO. */ - //PioDCOStart(p); - /* Set initial freq. */ assert_(0 == PioDCOSetFreq(p, freq_hz, 0U)); diff --git a/defines.h b/defines.h index 9a72ff5..fc3dd4c 100644 --- a/defines.h +++ b/defines.h @@ -81,21 +81,18 @@ /* A macro of multiplication guarantees of doing so using 1 ASM command. */ #define iMUL32ASM(a,b) __mul_instruction((int32_t)(a), (int32_t)(b)) - /* Performing the square by ASM. */ -#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 SECOND 1 /* Time. */ #define MINUTE (60 * SECOND) #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 diff --git a/init.c b/init.c index 819870b..411acbc 100644 --- a/init.c +++ b/init.c @@ -55,8 +55,7 @@ #include "pico/stdlib.h" #include "hardware/clocks.h" - -#include "defines.h" +#include /// @brief Initializes Pi pico low level hardware. void InitPicoHW(void) diff --git a/main.c b/main.c index 16b591b..8d12bed 100644 --- a/main.c +++ b/main.c @@ -11,21 +11,25 @@ // DESCRIPTION // The pico-WSPR-tx project provides WSPR beacon function using only // 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 -// . +// ./build.sh; cp ./build/*.uf2 /media/Pico_Board/ // // PLATFORM // Raspberry Pi pico. // // REVISION HISTORY -// // Rev 0.1 18 Nov 2023 -// Initial release. +// Rev 0.5 02 Dec 2023 // // PROJECT PAGE // https://github.com/RPiks/pico-WSPR-tx // +// SUBMODULE PAGE +// https://github.com/RPiks/pico-hf-oscillator +// // LICENCE // MIT License (http://www.opensource.org/licenses/mit-license.php) // @@ -56,13 +60,11 @@ #include "pico/multicore.h" #include "pico-hf-oscillator/lib/assert.h" #include "pico-hf-oscillator/defines.h" -#include "defines.h" +#include #include #include -#include "debug/logutils.h" - -void InitPicoHW(void); -void Core1Entry(void); +#include +#include WSPRbeaconContext *pWSPR; @@ -105,10 +107,14 @@ int main() for(;;) { WSPRbeaconTxScheduler(pWB, YES); + + gpio_put(PICO_DEFAULT_LED_PIN, 1); + sleep_ms(100); + gpio_put(PICO_DEFAULT_LED_PIN, 0); - if(0 == ++tick % 10) + if(0 == ++tick % 60) WSPRbeaconDumpContext(pWB); - sleep_ms(1000); + sleep_ms(900); } } diff --git a/protos.h b/protos.h new file mode 100644 index 0000000..98f666f --- /dev/null +++ b/protos.h @@ -0,0 +1,7 @@ +#ifndef PROTOS_H_ +#define PROTOS_H_ + +void InitPicoHW(void); +void Core1Entry(void); + +#endif diff --git a/util/flashmem.h b/util/flashmem.h new file mode 100644 index 0000000..16a0702 --- /dev/null +++ b/util/flashmem.h @@ -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