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
|
target_sources(pico-wspr-tx PUBLIC
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-hf-oscillator/lib/assert.c
|
${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/piodco/piodco.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/pico-hf-oscillator/gpstime/GPStime.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/TxChannel/TxChannel.c
|
${CMAKE_CURRENT_LIST_DIR}/TxChannel/TxChannel.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/WSPRbeacon/thirdparty/WSPRutility.c
|
${CMAKE_CURRENT_LIST_DIR}/WSPRbeacon/thirdparty/WSPRutility.c
|
||||||
${CMAKE_CURRENT_LIST_DIR}/WSPRbeacon/thirdparty/nhash.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_name(pico-wspr-tx "pico-wspr-tx")
|
||||||
pico_set_program_version(pico-wspr-tx "0.1")
|
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)
|
pico_enable_stdio_usb(pico-wspr-tx 1)
|
||||||
|
|
||||||
# Add the standard include files to the build
|
# Add the standard include files to the build
|
||||||
target_include_directories(pico-wspr-tx PRIVATE
|
target_include_directories(pico-wspr-tx PRIVATE
|
||||||
${CMAKE_CURRENT_LIST_DIR}
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
${CMAKE_CURRENT_LIST_DIR}/pico-hf-oscillator/piodco
|
${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}/TxChannel
|
||||||
${CMAKE_CURRENT_LIST_DIR}/WSPRbeacon
|
${CMAKE_CURRENT_LIST_DIR}/WSPRbeacon
|
||||||
${CMAKE_CURRENT_LIST_DIR}/WSPRbeacon/thirdparty
|
${CMAKE_CURRENT_LIST_DIR}/WSPRbeacon/thirdparty
|
||||||
|
|
|
@ -70,6 +70,7 @@ typedef struct
|
||||||
|
|
||||||
PioDco *_p_oscillator;
|
PioDco *_p_oscillator;
|
||||||
uint32_t _u32_dialfreqhz;
|
uint32_t _u32_dialfreqhz;
|
||||||
|
int _i_tx_gpio;
|
||||||
|
|
||||||
} TxChannelContext;
|
} TxChannelContext;
|
||||||
|
|
||||||
|
|
|
@ -58,9 +58,13 @@
|
||||||
/// @param pgridsquare Maidenhead locator, 7 chr max.
|
/// @param pgridsquare Maidenhead locator, 7 chr max.
|
||||||
/// @param txpow_dbm TX power, db`mW.
|
/// @param txpow_dbm TX power, db`mW.
|
||||||
/// @param pdco Ptr to working DCO.
|
/// @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,
|
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);
|
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_callsign, pcallsign, sizeof(p->_pu8_callsign));
|
||||||
strncpy(p->_pu8_locator, pgridsquare, sizeof(p->_pu8_locator));
|
strncpy(p->_pu8_locator, pgridsquare, sizeof(p->_pu8_locator));
|
||||||
p->_u8_txpower = txpow_dbm;
|
p->_u8_txpower = txpow_dbm;
|
||||||
|
|
||||||
|
|
||||||
p->_pTX = TxChannelInit(682667, 0, pdco);
|
p->_pTX = TxChannelInit(682667, 0, pdco);
|
||||||
assert_(p->_pTX);
|
assert_(p->_pTX);
|
||||||
|
p->_pTX->_u32_dialfreqhz = dial_freq_hz + shift_freq_hz;
|
||||||
|
p->_pTX->_i_tx_gpio = gpio;
|
||||||
|
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -112,3 +119,62 @@ int WSPRbeaconSendPacket(const WSPRbeaconContext *pctx)
|
||||||
|
|
||||||
return 0;
|
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 <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <TxChannel.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
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -66,12 +77,17 @@ typedef struct
|
||||||
|
|
||||||
TxChannelContext *_pTX;
|
TxChannelContext *_pTX;
|
||||||
|
|
||||||
|
WSPRbeaconSchedule _txSched;
|
||||||
|
|
||||||
} WSPRbeaconContext;
|
} WSPRbeaconContext;
|
||||||
|
|
||||||
WSPRbeaconContext *WSPRbeaconInit(const char *pcallsign, const char *pgridsquare, int txpow_dbm,
|
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);
|
void WSPRbeaconSetDialFreq(WSPRbeaconContext *pctx, uint32_t freq_hz);
|
||||||
int WSPRbeaconCreatePacket(WSPRbeaconContext *pctx);
|
int WSPRbeaconCreatePacket(WSPRbeaconContext *pctx);
|
||||||
int WSPRbeaconSendPacket(const WSPRbeaconContext *pctx);
|
int WSPRbeaconSendPacket(const WSPRbeaconContext *pctx);
|
||||||
|
|
||||||
|
int WSPRbeaconTxScheduler(WSPRbeaconContext *pctx, int verbose);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
19
core1.c
19
core1.c
|
@ -56,23 +56,30 @@
|
||||||
#include <piodco.h>
|
#include <piodco.h>
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
|
|
||||||
extern PioDco DCO;
|
#include <WSPRbeacon.h>
|
||||||
|
|
||||||
|
extern WSPRbeaconContext *pWSPR;
|
||||||
|
|
||||||
/// @brief The code of dedicated core' program running HF oscillator.
|
/// @brief The code of dedicated core' program running HF oscillator.
|
||||||
void Core1Entry()
|
void Core1Entry()
|
||||||
{
|
{
|
||||||
|
assert_(pWSPR);
|
||||||
|
|
||||||
const uint32_t clkhz = PLL_SYS_MHZ * MHz;
|
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 */
|
/* Initialize DCO */
|
||||||
assert_(0 == PioDCOInit(&DCO, 6, clkhz));
|
assert_(0 == PioDCOInit(p, pWSPR->_pTX->_i_tx_gpio, clkhz));
|
||||||
|
|
||||||
/* Run DCO. */
|
/* Run DCO. */
|
||||||
PioDCOStart(&DCO);
|
//PioDCOStart(p);
|
||||||
|
|
||||||
/* Set initial freq. */
|
/* 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. */
|
/* 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);
|
const uint32_t tm_sec = (uint32_t)(tm_us / 1000000ULL);
|
||||||
tm_us -= (uint64_t)tm_sec * 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++);
|
printf("%02lud%02lu:%02lu:%02lu.%06llu [%04lu] ", tm_day, tm_hour, tm_min, tm_sec, tm_us, sTick++);
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
|
@ -84,4 +85,5 @@ void StampPrintf(const char* pformat, ...)
|
||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
stdio_set_driver_enabled(&stdio_uart, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
#define YES 1 /* The answer is yes. */
|
#define YES 1 /* The answer is yes. */
|
||||||
#define OFF 0 /* Turn something off. */
|
#define OFF 0 /* Turn something off. */
|
||||||
#define ON 1 /* Turn something on. */
|
#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 __not_in_flash_func /* Place time-critical func in RAM */
|
||||||
#define RAM_A __not_in_flash("A") /* Place time-critical var 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 1465UL
|
||||||
#define WSPR_FREQ_STEP_MILHZ 2930UL
|
#define WSPR_FREQ_STEP_MILHZ 2930UL
|
||||||
|
|
||||||
|
#define MINUTE 60
|
||||||
|
#define HOUR (60 * MINUTE)
|
||||||
|
|
||||||
|
#define GPS_PPS_PIN 2
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
57
main.c
57
main.c
|
@ -53,32 +53,66 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "defines.h"
|
|
||||||
|
|
||||||
#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 <piodco.h>
|
#include <piodco.h>
|
||||||
|
|
||||||
#include <WSPRbeacon.h>
|
#include <WSPRbeacon.h>
|
||||||
|
|
||||||
#include "debug/logutils.h"
|
#include "debug/logutils.h"
|
||||||
|
|
||||||
PioDco DCO;
|
|
||||||
|
|
||||||
void InitPicoHW(void);
|
void InitPicoHW(void);
|
||||||
void Core1Entry(void);
|
void Core1Entry(void);
|
||||||
|
|
||||||
|
WSPRbeaconContext *pWSPR;
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
DEBUGPRINTF("\n");
|
StampPrintf("\n");
|
||||||
sleep_ms(1000);
|
sleep_ms(5000);
|
||||||
DEBUGPRINTF("Pico-WSPR-tx start.");
|
StampPrintf("R2BDY Pico-WSPR-tx start.");
|
||||||
|
|
||||||
InitPicoHW();
|
InitPicoHW();
|
||||||
|
|
||||||
DEBUGPRINTF("WSPR beacon init...");
|
StampPrintf("WSPR beacon init...");
|
||||||
WSPRbeaconContext *pWB = WSPRbeaconInit("R2BDY", "KO85", 6, &DCO);
|
|
||||||
|
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);
|
WSPRbeaconSetDialFreq(pWB, WSPR_DIAL_FREQ_HZ + WSPR_SHIFT_FREQ_HZ);
|
||||||
DEBUGPRINTF("OK");
|
DEBUGPRINTF("OK");
|
||||||
|
|
||||||
|
@ -99,4 +133,5 @@ int main()
|
||||||
DEBUGPRINTF("tick.");
|
DEBUGPRINTF("tick.");
|
||||||
sleep_ms(1000);
|
sleep_ms(1000);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue