kopia lustrzana https://github.com/RPiks/pico-WSPR-tx
Ongiong work, debug beginning.
rodzic
70073d00ed
commit
402d61ec4f
|
@ -34,6 +34,7 @@ pico_generate_pio_header(pico-wspr-tx ${CMAKE_CURRENT_LIST_DIR}/pico-hf-oscillat
|
|||
target_sources(pico-wspr-tx PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-hf-oscillator/lib/assert.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-hf-oscillator/piodco/piodco.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-hf-oscillator/gpstime/GPStime.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/TxChannel/TxChannel.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/WSPRbeacon/thirdparty/WSPRutility.c
|
||||
${CMAKE_CURRENT_LIST_DIR}/WSPRbeacon/thirdparty/nhash.c
|
||||
|
@ -47,13 +48,14 @@ 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_enable_stdio_uart(pico-wspr-tx 0)
|
||||
pico_enable_stdio_uart(pico-wspr-tx 1)
|
||||
pico_enable_stdio_usb(pico-wspr-tx 1)
|
||||
|
||||
# Add the standard include files to the build
|
||||
target_include_directories(pico-wspr-tx PRIVATE
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-hf-oscillator/piodco
|
||||
${CMAKE_CURRENT_LIST_DIR}/pico-hf-oscillator/debug
|
||||
${CMAKE_CURRENT_LIST_DIR}/TxChannel
|
||||
${CMAKE_CURRENT_LIST_DIR}/WSPRbeacon
|
||||
${CMAKE_CURRENT_LIST_DIR}/WSPRbeacon/thirdparty
|
||||
|
|
|
@ -70,6 +70,7 @@ typedef struct
|
|||
|
||||
PioDco *_p_oscillator;
|
||||
uint32_t _u32_dialfreqhz;
|
||||
int _i_tx_gpio;
|
||||
|
||||
} TxChannelContext;
|
||||
|
||||
|
|
|
@ -58,9 +58,13 @@
|
|||
/// @param pgridsquare Maidenhead locator, 7 chr max.
|
||||
/// @param txpow_dbm TX power, db`mW.
|
||||
/// @param pdco Ptr to working DCO.
|
||||
/// @return the context.
|
||||
/// @param dial_freq_hz The begin of working WSPR passband.
|
||||
/// @param shift_freq_hz The shift of tx freq. relative to dial_freq_hz.
|
||||
/// @param gpio Pico's GPIO pin of RF output.
|
||||
/// @return Ptr to the new context.
|
||||
WSPRbeaconContext *WSPRbeaconInit(const char *pcallsign, const char *pgridsquare, int txpow_dbm,
|
||||
PioDco *pdco)
|
||||
PioDco *pdco, uint32_t dial_freq_hz, uint32_t shift_freq_hz,
|
||||
int gpio)
|
||||
{
|
||||
assert_(pdco);
|
||||
|
||||
|
@ -70,9 +74,12 @@ WSPRbeaconContext *WSPRbeaconInit(const char *pcallsign, const char *pgridsquare
|
|||
strncpy(p->_pu8_callsign, pcallsign, sizeof(p->_pu8_callsign));
|
||||
strncpy(p->_pu8_locator, pgridsquare, sizeof(p->_pu8_locator));
|
||||
p->_u8_txpower = txpow_dbm;
|
||||
|
||||
|
||||
p->_pTX = TxChannelInit(682667, 0, pdco);
|
||||
assert_(p->_pTX);
|
||||
p->_pTX->_u32_dialfreqhz = dial_freq_hz + shift_freq_hz;
|
||||
p->_pTX->_i_tx_gpio = gpio;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
@ -112,3 +119,62 @@ int WSPRbeaconSendPacket(const WSPRbeaconContext *pctx)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int WSPRbeaconTxScheduler(WSPRbeaconContext *pctx, int verbose)
|
||||
{
|
||||
assert_(pctx);
|
||||
|
||||
const uint64_t u64tmnow = GetUptime64();
|
||||
const uint32_t is_GPS_available = pctx->_pTX->_p_oscillator->_pGPStime->_time_data._u32_nmea_gprmc_count;
|
||||
const uint32_t is_GPS_active = pctx->_pTX->_p_oscillator->_pGPStime->_time_data._u8_is_solution_active;
|
||||
const uint32_t is_GPS_override = pctx->_txSched._u8_tx_GPS_past_time == YES;
|
||||
|
||||
const uint64_t u64_GPS_last_age_sec
|
||||
= (u64tmnow - pctx->_pTX->_p_oscillator->_pGPStime->_time_data._u64_sysclk_nmea_last) / 1000000ULL;
|
||||
|
||||
#if 1
|
||||
StampPrintf("%llu %lu %lu %lu %llu", u64tmnow, is_GPS_available, is_GPS_active, is_GPS_override, u64_GPS_last_age_sec);
|
||||
//return 0;
|
||||
#endif
|
||||
|
||||
if(!is_GPS_available)
|
||||
{
|
||||
StampPrintf("Waiting for GPS receiver...");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(is_GPS_active || (is_GPS_override && u64_GPS_last_age_sec < 2 * HOUR))
|
||||
{
|
||||
const uint32_t u32_unixtime_now
|
||||
= pctx->_pTX->_p_oscillator->_pGPStime->_time_data._u32_utime_nmea_last + u64_GPS_last_age_sec;
|
||||
|
||||
const int isec_of_hour = u32_unixtime_now % HOUR;
|
||||
const int islot_number = isec_of_hour / (2 * MINUTE);
|
||||
const int islot_modulo = islot_number % pctx->_txSched._u8_tx_slot_skip;
|
||||
|
||||
static int itx_trigger = 0;
|
||||
if(ZERO == islot_modulo)
|
||||
{
|
||||
if(!itx_trigger)
|
||||
{
|
||||
itx_trigger = 1;
|
||||
StampPrintf("Start transmission.");
|
||||
|
||||
//WSPRbeaconSetDialFreq(pWB, WSPR_DIAL_FREQ_HZ + WSPR_SHIFT_FREQ_HZ);
|
||||
WSPRbeaconCreatePacket(pctx);
|
||||
|
||||
PioDCOStart(pctx->_pTX->_p_oscillator);
|
||||
sleep_ms(100);
|
||||
WSPRbeaconSendPacket(pctx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
itx_trigger = 0;
|
||||
StampPrintf("NO transmission slot.");
|
||||
PioDCOStop(pctx->_pTX->_p_oscillator);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,17 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <TxChannel.h>
|
||||
#include <logutils.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t _u8_tx_slot_skip; /* 0=1tx0skip, 1=1tx1skip, 2=1tx2skip, ... */
|
||||
uint8_t _u8_tx_GPS_mandatory; /* No tx when no active GPS solution. */
|
||||
uint8_t _u8_tx_GPS_past_time; /* Override _u8_tx_GPS_mandatory if there
|
||||
was solution in the past. */
|
||||
uint8_t _u8_tx_heating_pause_min; /* No tx during this interval from start. */
|
||||
|
||||
} WSPRbeaconSchedule;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -66,12 +77,17 @@ typedef struct
|
|||
|
||||
TxChannelContext *_pTX;
|
||||
|
||||
WSPRbeaconSchedule _txSched;
|
||||
|
||||
} WSPRbeaconContext;
|
||||
|
||||
WSPRbeaconContext *WSPRbeaconInit(const char *pcallsign, const char *pgridsquare, int txpow_dbm,
|
||||
PioDco *pdco);
|
||||
PioDco *pdco, uint32_t dial_freq_hz, uint32_t shift_freq_hz,
|
||||
int gpio);
|
||||
void WSPRbeaconSetDialFreq(WSPRbeaconContext *pctx, uint32_t freq_hz);
|
||||
int WSPRbeaconCreatePacket(WSPRbeaconContext *pctx);
|
||||
int WSPRbeaconSendPacket(const WSPRbeaconContext *pctx);
|
||||
|
||||
int WSPRbeaconTxScheduler(WSPRbeaconContext *pctx, int verbose);
|
||||
|
||||
#endif
|
||||
|
|
19
core1.c
19
core1.c
|
@ -56,23 +56,30 @@
|
|||
#include <piodco.h>
|
||||
#include "defines.h"
|
||||
|
||||
extern PioDco DCO;
|
||||
#include <WSPRbeacon.h>
|
||||
|
||||
extern WSPRbeaconContext *pWSPR;
|
||||
|
||||
/// @brief The code of dedicated core' program running HF oscillator.
|
||||
void Core1Entry()
|
||||
{
|
||||
assert_(pWSPR);
|
||||
|
||||
const uint32_t clkhz = PLL_SYS_MHZ * MHz;
|
||||
const uint32_t freq_hz = WSPR_DIAL_FREQ_HZ + WSPR_SHIFT_FREQ_HZ;
|
||||
const uint32_t freq_hz = pWSPR->_pTX->_u32_dialfreqhz;
|
||||
|
||||
PioDco *p = pWSPR->_pTX->_p_oscillator;
|
||||
assert_(p);
|
||||
|
||||
/* Initialize DCO */
|
||||
assert_(0 == PioDCOInit(&DCO, 6, clkhz));
|
||||
assert_(0 == PioDCOInit(p, pWSPR->_pTX->_i_tx_gpio, clkhz));
|
||||
|
||||
/* Run DCO. */
|
||||
PioDCOStart(&DCO);
|
||||
//PioDCOStart(p);
|
||||
|
||||
/* Set initial freq. */
|
||||
assert_(0 == PioDCOSetFreq(&DCO, freq_hz, 0u));
|
||||
assert_(0 == PioDCOSetFreq(p, freq_hz, 0U));
|
||||
|
||||
/* Run the main DCO algorithm. It spins forever. */
|
||||
PioDCOWorker(&DCO);
|
||||
PioDCOWorker(p);
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ void StampPrintf(const char* pformat, ...)
|
|||
const uint32_t tm_sec = (uint32_t)(tm_us / 1000000ULL);
|
||||
tm_us -= (uint64_t)tm_sec * 1000000ULL;
|
||||
|
||||
stdio_set_driver_enabled(&stdio_uart, false);
|
||||
printf("%02lud%02lu:%02lu:%02lu.%06llu [%04lu] ", tm_day, tm_hour, tm_min, tm_sec, tm_us, sTick++);
|
||||
|
||||
va_list argptr;
|
||||
|
@ -84,4 +85,5 @@ void StampPrintf(const char* pformat, ...)
|
|||
va_end(argptr);
|
||||
|
||||
printf("\n");
|
||||
stdio_set_driver_enabled(&stdio_uart, true);
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#define YES 1 /* The answer is yes. */
|
||||
#define OFF 0 /* Turn something off. */
|
||||
#define ON 1 /* Turn something on. */
|
||||
#define ZERO 0 /* Something in zero state. */
|
||||
|
||||
#define RAM __not_in_flash_func /* Place time-critical func in RAM */
|
||||
#define RAM_A __not_in_flash("A") /* Place time-critical var in RAM */
|
||||
|
@ -92,4 +93,9 @@
|
|||
//#define WSPR_FREQ_STEP_MILHZ 1465UL
|
||||
#define WSPR_FREQ_STEP_MILHZ 2930UL
|
||||
|
||||
#define MINUTE 60
|
||||
#define HOUR (60 * MINUTE)
|
||||
|
||||
#define GPS_PPS_PIN 2
|
||||
|
||||
#endif
|
||||
|
|
57
main.c
57
main.c
|
@ -53,32 +53,66 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "defines.h"
|
||||
|
||||
#include "pico/multicore.h"
|
||||
#include "pico-hf-oscillator/lib/assert.h"
|
||||
#include "pico-hf-oscillator/defines.h"
|
||||
#include "defines.h"
|
||||
#include <piodco.h>
|
||||
|
||||
#include <WSPRbeacon.h>
|
||||
|
||||
#include "debug/logutils.h"
|
||||
|
||||
PioDco DCO;
|
||||
|
||||
void InitPicoHW(void);
|
||||
void Core1Entry(void);
|
||||
|
||||
WSPRbeaconContext *pWSPR;
|
||||
|
||||
int main()
|
||||
{
|
||||
DEBUGPRINTF("\n");
|
||||
sleep_ms(1000);
|
||||
DEBUGPRINTF("Pico-WSPR-tx start.");
|
||||
StampPrintf("\n");
|
||||
sleep_ms(5000);
|
||||
StampPrintf("R2BDY Pico-WSPR-tx start.");
|
||||
|
||||
InitPicoHW();
|
||||
|
||||
DEBUGPRINTF("WSPR beacon init...");
|
||||
WSPRbeaconContext *pWB = WSPRbeaconInit("R2BDY", "KO85", 6, &DCO);
|
||||
StampPrintf("WSPR beacon init...");
|
||||
|
||||
PioDco DCO;
|
||||
GPStimeContext *pGPS = GPStimeInit(0, 9600, GPS_PPS_PIN);
|
||||
assert_(pGPS);
|
||||
DCO._pGPStime = pGPS;
|
||||
|
||||
WSPRbeaconContext *pWB = WSPRbeaconInit(
|
||||
"R2BDY", /* the Callsign. */
|
||||
"KO85", /* the QTH locator. */
|
||||
10, /* Tx power, dbm. */
|
||||
&DCO, /* the PioDCO object. */
|
||||
7040000UL, /* the dial frequency. */
|
||||
55UL, /* the carrier freq. shift relative to dial freq. */
|
||||
6 /* RF output GPIO pin. */
|
||||
);
|
||||
assert_(pWB);
|
||||
pWSPR = pWB;
|
||||
|
||||
pWB->_txSched._u8_tx_GPS_mandatory = YES; /* Send WSPR signals only when GPS solution is active. */
|
||||
pWB->_txSched._u8_tx_GPS_past_time = NO; /* No relying on GPS sp;ution in the past. */
|
||||
pWB->_txSched._u8_tx_slot_skip = 1; /* 1 slot tx, 1 slot idle, etc. */
|
||||
pWB->_txSched._u8_tx_heating_pause_min = 1; /* Give 1 minute pre-heating ere first transmition. */
|
||||
|
||||
StampPrintf("PioDco ADDR: %p", pWSPR->_pTX->_p_oscillator);
|
||||
|
||||
StampPrintf("RF oscillator start...");
|
||||
sleep_ms(500);
|
||||
multicore_launch_core1(Core1Entry);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
WSPRbeaconTxScheduler(pWB, YES);
|
||||
|
||||
StampPrintf(".");
|
||||
|
||||
sleep_ms(1000);
|
||||
}
|
||||
/*
|
||||
WSPRbeaconSetDialFreq(pWB, WSPR_DIAL_FREQ_HZ + WSPR_SHIFT_FREQ_HZ);
|
||||
DEBUGPRINTF("OK");
|
||||
|
||||
|
@ -99,4 +133,5 @@ int main()
|
|||
DEBUGPRINTF("tick.");
|
||||
sleep_ms(1000);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue