diff --git a/gpstime/GPStime.c b/gpstime/GPStime.c index 8e452e2..96b12a1 100644 --- a/gpstime/GPStime.c +++ b/gpstime/GPStime.c @@ -11,19 +11,19 @@ // // DESCRIPTION // -// GPS time utilities for PioDco oscillator calculates a precise frequency +// GPS time utilities for pico-hf-oscillator calculate a precise frequency // shift between the local Pico oscillator and reference oscill. of GPS system. -// The value of the shift is used to correct PioDco generated frequency. The -// practical precision of this solution within tenths millihertz range. -// The value of this accuracy depends on quality of navigation solution of GPS -// receiver. This quality can be estimated by GDOP and TDOP parameters received +// The value of the shift is used to correct generated frequency. The practical +// precision of this solution depends on GPS receiver's time pulse stability, +// as well as on quality of navigation solution of GPS receiver. +// This quality can be estimated by GDOP and TDOP parameters received // in NMEA-0183 message packet from GPS receiver. -// Owing to the meager PioDco frequency step in millihertz range, we obtain -// a quasi-analog precision frequency source (if the GPS navigation works ok). +// Owing to the meager frequency step in millihertz range, we obtain +// a quasi-analog precision frequency source (if the GPS navigation works OK). // This is an experimental project of amateur radio class and it is devised // by me on the free will base in order to experiment with QRP narrowband // digital modes including extremely ones such as QRSS. -// I gracefully appreciate any thoughts or comments on that matter. +// I appreciate any thoughts or comments on that matter. // // PLATFORM // Raspberry Pi pico. diff --git a/gpstime/GPStime.h b/gpstime/GPStime.h index aecb82f..301ae24 100644 --- a/gpstime/GPStime.h +++ b/gpstime/GPStime.h @@ -11,19 +11,19 @@ // // DESCRIPTION // -// GPS time utilities for PioDco oscillator calculates a precise frequency +// GPS time utilities for pico-hf-oscillator calculate a precise frequency // shift between the local Pico oscillator and reference oscill. of GPS system. -// The value of the shift is used to correct PioDco generated frequency. The -// practical precision of this solution within tenths millihertz range. -// The value of this accuracy depends on quality of navigation solution of GPS -// receiver. This quality can be estimated by GDOP and TDOP parameters received +// The value of the shift is used to correct generated frequency. The practical +// precision of this solution depends on GPS receiver's time pulse stability, +// as well as on quality of navigation solution of GPS receiver. +// This quality can be estimated by GDOP and TDOP parameters received // in NMEA-0183 message packet from GPS receiver. -// Owing to the meager PioDco frequency step in millihertz range, we obtain -// a quasi-analog precision frequency source (if the GPS navigation works ok). +// Owing to the meager frequency step in millihertz range, we obtain +// a quasi-analog precision frequency source (if the GPS navigation works OK). // This is an experimental project of amateur radio class and it is devised // by me on the free will base in order to experiment with QRP narrowband // digital modes including extremely ones such as QRSS. -// I gracefully appreciate any thoughts or comments on that matter. +// I appreciate any thoughts or comments on that matter. // // PLATFORM // Raspberry Pi pico. diff --git a/lib/utility.h b/lib/utility.h index b5edcb4..8f01882 100644 --- a/lib/utility.h +++ b/lib/utility.h @@ -1,3 +1,49 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// Roman Piksaykin [piksaykin@gmail.com], R2BDY, PhD +// https://www.qrz.com/db/r2bdy +// +/////////////////////////////////////////////////////////////////////////////// +// +// +// utility.h - Utilities for RPiks' projects. +// +// DESCRIPTION +// - +// +// PLATFORM +// Raspberry Pi pico. +// +// REVISION HISTORY +// +// Rev 0.1 25 Nov 2023 Initial release +// +// PROJECT PAGE +// https://github.com/RPiks/pico-hf-oscillator +// +// 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 UTILITY_H_ #define UTILITY_H_ diff --git a/piodco/dco2.pio b/piodco/dco2.pio index 68b5914..e1cf89c 100644 --- a/piodco/dco2.pio +++ b/piodco/dco2.pio @@ -6,19 +6,43 @@ /////////////////////////////////////////////////////////////////////////////// // // -// dco2.pio Digital controlled radio freq oscillator based on PIO. +// dco2.pio - Digital controlled radio freq oscillator based on PIO. // // // DESCRIPTION -// - +// +// The oscillator provides precise generation of any frequency ranging +// from 1 Hz to 33.333 MHz with tenth's of millihertz resolution (please note that +// this is relative resolution owing to the fact that the absolute accuracy of +// onboard crystal of pi pico is limited; the absoulte accuracy can be provided +// when using GPS reference option included). +// The DCO uses phase locked loop principle programmed in C and PIO asm. +// The DCO does *NOT* use any floating point operations - all time-critical +// instructions run in 1 CPU cycle. +// Currently the upper freq. limit is about 33.333 MHz and it is achieved only +// using pi pico overclocking to 270 MHz. +// Owing to the meager frequency step, it is possible to use 3, 5, or 7th +// harmonics of generated frequency. Such solution completely cover all HF and +// a portion of VHF band up to about 233 MHz. +// Unfortunately due to pure digital freq.synthesis principle the jitter may +// be a problem on higher frequencies. You should assess the quality of generated +// signal if you want to emit a noticeable power. +// This is an experimental project of amateur radio class and it is devised +// by me on the free will base in order to experiment with QRP narrowband +// digital modes. +// I appreciate any thoughts or comments on that matter. // // PLATFORM // Raspberry Pi pico. // // REVISION HISTORY // -// Rev 2.0 09 Dec 2023 -// New algo devising. +// Rev 0.1 05 Nov 2023 Initial release +// Rev 0.2 18 Nov 2023 +// Rev 1.0 10 Dec 2023 Improved frequency range (to ~33.333 MHz). +// +// PROJECT PAGE +// https://github.com/RPiks/pico-hf-oscillator // // LICENCE // MIT License (http://www.opensource.org/licenses/mit-license.php) @@ -68,40 +92,6 @@ LOOP3: set pins, 0 .wrap -/* -// it is OK for ~20.5M -.wrap_target - out y, 32 - mov x, y -LOOP0: - jmp x-- LOOP0 - set pins, 1 - - mov x, y [1] -LOOP1: - jmp x-- LOOP1 - set pins, 0 -.wrap -*/ -/* -.wrap_target - // CYCLES COUNT - out y, 8 // 1. -LOOP0: - jmp y-- LOOP0 // 2 + y0. - set pins, 1 // 1 * PI 3 + y0. - - out y, 8 // 4 + y0. -LOOP1: - jmp y-- LOOP1 // 5 + y0 + y1. - set pins, 0 // 2 * PI 6 + y0 + y1. - // 6 cycles min.=> 270MHz / 6 = 45MHz (VHF low-band). - // 3rd harmonic is 135M. - // 5th is 225M. - // 7th is 315M. -.wrap -*/ - % c-sdk { #define PIOASM_DELAY_CYCLES 4 diff --git a/piodco/piodco.c b/piodco/piodco.c index a8560cd..1a13e45 100644 --- a/piodco/piodco.c +++ b/piodco/piodco.c @@ -12,21 +12,25 @@ // DESCRIPTION // // The oscillator provides precise generation of any frequency ranging -// from 1.1 to 9.4 MHz with tenth's of millihertz resolution (please note that +// from 1 Hz to 33.333 MHz with tenth's of millihertz resolution (please note that // this is relative resolution owing to the fact that the absolute accuracy of -// onboard crystal of pi pico is limited). -// The DCO uses phase locked loop principle programmed in C. +// onboard crystal of pi pico is limited; the absoulte accuracy can be provided +// when using GPS reference option included). +// The DCO uses phase locked loop principle programmed in C and PIO asm. // The DCO does *NOT* use any floating point operations - all time-critical // instructions run in 1 CPU cycle. -// Currently the upper freq. limit is about 9.8 MHz and it is achieved only -// using pi pico overclocking to 270MHz. +// Currently the upper freq. limit is about 33.333 MHz and it is achieved only +// using pi pico overclocking to 270 MHz. // Owing to the meager frequency step, it is possible to use 3, 5, or 7th // harmonics of generated frequency. Such solution completely cover all HF and -// low band up to about 66 MHz. +// a portion of VHF band up to about 233 MHz. +// Unfortunately due to pure digital freq.synthesis principle the jitter may +// be a problem on higher frequencies. You should assess the quality of generated +// signal if you want to emit a noticeable power. // This is an experimental project of amateur radio class and it is devised // by me on the free will base in order to experiment with QRP narrowband // digital modes. -// I gracefully appreciate any thoughts or comments on that matter. +// I appreciate any thoughts or comments on that matter. // // PLATFORM // Raspberry Pi pico. @@ -35,6 +39,7 @@ // // Rev 0.1 05 Nov 2023 Initial release // Rev 0.2 18 Nov 2023 +// Rev 1.0 10 Dec 2023 Improved frequency range (to ~33.333 MHz). // // PROJECT PAGE // https://github.com/RPiks/pico-hf-oscillator @@ -69,7 +74,7 @@ #include "build/dco2.pio.h" -int32_t si32precise_cycles; /* External in order to support ISR. */ +volatile int32_t si32precise_cycles; /// @brief Initializes DCO context and prepares PIO hardware. /// @param pdco Ptr to DCO context. @@ -121,7 +126,7 @@ int PioDCOSetFreq(PioDco *pdco, uint32_t ui32_frq_hz, int32_t ui32_frq_millihz) pdco->_frq_cycles_per_pi = (int32_t)(((int64_t)pdco->_clkfreq_hz * (int64_t)(1<<24) * 1000LL +(i64denominator>>1)) / i64denominator); - si32precise_cycles = pdco->_frq_cycles_per_pi; + si32precise_cycles = pdco->_frq_cycles_per_pi - (PIOASM_DELAY_CYCLES<<24); return 0; } @@ -174,33 +179,22 @@ void PioDCOStop(PioDco *pdco) pio_sm_set_enabled(pdco->_pio, pdco->_ism, false); } +/// @brief Main worker task of DCO V.2. It is time critical, so it ought to be run on +/// @brief the dedicated pi pico core. +/// @param pDCO Ptr to DCO context. +/// @return No return. It spins forever. void RAM (PioDCOWorker2)(PioDco *pDCO) { register PIO pio = pDCO->_pio; register uint sm = pDCO->_ism; register int32_t i32acc_error = 0; - const int32_t ui32_frq_hz = 30455133; - const int64_t i64denominator = 2000LL * (int64_t)ui32_frq_hz; - pDCO->_frq_cycles_per_pi = (int32_t)(((int64_t)pDCO->_clkfreq_hz * (int64_t)(1<<24) * 1000LL - +(i64denominator>>1)) / i64denominator); - const register uint32_t i32reg = pDCO->_frq_cycles_per_pi - (4<<24); + register uint32_t i32wc, i32reg; - register uint32_t i32wc; - //const register uint32_t i23left = 8388608U; LOOP: - - i32wc = i32reg; - i32wc -= i32acc_error; - //i32wc += i23left; - i32wc >>= 24U; + i32reg = si32precise_cycles; + i32wc = (i32reg - i32acc_error) >> 24U; pio_sm_put_blocking(pio, sm, i32wc); - i32wc <<= 24U; - i32acc_error += i32wc - i32reg; - - //const int32_t i32wc2 = iSAR32(i32reg - i32acc_error + (1<<23), 24); - //i32acc_error += (i32wc2<<24) - i32reg; - - //pio_sm_put_blocking(pio, sm, i32wc - 4); + i32acc_error += (i32wc << 24U) - i32reg; goto LOOP; } diff --git a/piodco/piodco.h b/piodco/piodco.h index 6f967c9..5a31800 100644 --- a/piodco/piodco.h +++ b/piodco/piodco.h @@ -12,21 +12,25 @@ // DESCRIPTION // // The oscillator provides precise generation of any frequency ranging -// from 1.1 to 9.4 MHz with tenth's of millihertz resolution (please note that +// from 1 Hz to 33.333 MHz with tenth's of millihertz resolution (please note that // this is relative resolution owing to the fact that the absolute accuracy of -// onboard crystal of pi pico is limited). -// The DCO uses phase locked loop principle programmed in C. +// onboard crystal of pi pico is limited; the absoulte accuracy can be provided +// when using GPS reference option included). +// The DCO uses phase locked loop principle programmed in C and PIO asm. // The DCO does *NOT* use any floating point operations - all time-critical // instructions run in 1 CPU cycle. -// Currently the upper freq. limit is about 9.8 MHz and it is achieved only -// using pi pico overclocking to 270MHz. +// Currently the upper freq. limit is about 33.333 MHz and it is achieved only +// using pi pico overclocking to 270 MHz. // Owing to the meager frequency step, it is possible to use 3, 5, or 7th // harmonics of generated frequency. Such solution completely cover all HF and -// low band up to about 66 MHz. +// a portion of VHF band up to about 233 MHz. +// Unfortunately due to pure digital freq.synthesis principle the jitter may +// be a problem on higher frequencies. You should assess the quality of generated +// signal if you want to emit a noticeable power. // This is an experimental project of amateur radio class and it is devised // by me on the free will base in order to experiment with QRP narrowband // digital modes. -// I gracefully appreciate any thoughts or comments on that matter. +// I appreciate any thoughts or comments on that matter. // // PLATFORM // Raspberry Pi pico. @@ -35,6 +39,7 @@ // // Rev 0.1 05 Nov 2023 Initial release // Rev 0.2 18 Nov 2023 +// Rev 1.0 10 Dec 2023 Improved frequency range (to ~33.333 MHz). // // PROJECT PAGE // https://github.com/RPiks/pico-hf-oscillator diff --git a/test.c b/test.c index d8e462b..e9efb45 100644 --- a/test.c +++ b/test.c @@ -6,31 +6,40 @@ /////////////////////////////////////////////////////////////////////////////// // // -// test.c - Simple test of digital controlled radio freq oscillator based on PIO. +// test.c - Simple tests of digital controlled radio freq oscillator. // // // DESCRIPTION // // The oscillator provides precise generation of any frequency ranging -// from 1.1 to 9.4 MHz with tenth's of millihertz resolution (please note that +// from 1 Hz to 33.333 MHz with tenth's of millihertz resolution (please note that // this is relative resolution owing to the fact that the absolute accuracy of -// onboard crystal of pi pico is limited). -// The DCO uses phase locked loop principle programmed in C. +// onboard crystal of pi pico is limited; the absoulte accuracy can be provided +// when using GPS reference option included). +// The DCO uses phase locked loop principle programmed in C and PIO asm. // The DCO does *NOT* use any floating point operations - all time-critical // instructions run in 1 CPU cycle. -// Currently the upper freq. limit is about 9.8 MHz and it is achieved only -// using pi pico overclocking to 270MHz. +// Currently the upper freq. limit is about 33.333 MHz and it is achieved only +// using pi pico overclocking to 270 MHz. // Owing to the meager frequency step, it is possible to use 3, 5, or 7th // harmonics of generated frequency. Such solution completely cover all HF and -// low band up to about 66 MHz. +// a portion of VHF band up to about 233 MHz. +// Unfortunately due to pure digital freq.synthesis principle the jitter may +// be a problem on higher frequencies. You should assess the quality of generated +// signal if you want to emit a noticeable power. // This is an experimental project of amateur radio class and it is devised // by me on the free will base in order to experiment with QRP narrowband // digital modes. -// I gracefully appreciate any thoughts or comments on that matter. +// I appreciate any thoughts or comments on this matter. // -// HOWTOSTART -// Set frequency by #define GEN_FRQ_HZ and build the project. The default -// output pin is GPIO6. +// TESTS LIST +// +// SpinnerMFSKTest - It generates a random sequence of 2-FSK stream. +// SpinnerSweepTest - Frequency sweep test of 5 Hz step. +// SpinnerRTTYTest - Random RTTY sequence test (170 Hz). +// SpinnerMilliHertzTest - A test of millihertz resolution of freq.setting. +// SpinnerWide4FSKTest - Some `wide` 4-FSK test (100 Hz per step, 400 Hz overall). +// SpinnerGPSreferenceTest - GPS receiver connection and working test. // // PLATFORM // Raspberry Pi pico. @@ -39,6 +48,7 @@ // // Rev 0.1 05 Nov 2023 Initial release // Rev 0.2 18 Nov 2023 +// Rev 1.0 10 Dec 2023 Improved frequency range (to ~33.333 MHz). // // PROJECT PAGE // https://github.com/RPiks/pico-hf-oscillator @@ -84,16 +94,48 @@ #include -#define GEN_FRQ_HZ 10000000L +//#define GEN_FRQ_HZ 32333333L +#define GEN_FRQ_HZ 29977777L PioDco DCO; /* External in order to access in both cores. */ +void RAM (SpinnerMFSKTest)(void); +void RAM (SpinnerSweepTest)(void); +void RAM (SpinnerRTTYTest)(void); +void RAM (SpinnerMilliHertzTest)(void); +void RAM (SpinnerWide4FSKTest)(void); +void RAM (SpinnerGPSreferenceTest)(void); + +void core1_entry(); + +int main() +{ + const uint32_t clkhz = PLL_SYS_MHZ * 1000000L; + set_sys_clock_khz(clkhz / 1000L, true); + + stdio_init_all(); + sleep_ms(1000); + printf("Start\n"); + + gpio_init(PICO_DEFAULT_LED_PIN); + gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); + + multicore_launch_core1(core1_entry); + + //SpinnerDummyTest(); + //SpinnerSweepTest(); + //SpinnerMFSKTest(); + SpinnerRTTYTest(); + //SpinnerMilliHertzTest(); + //SpinnerWide4FSKTest(); + //SpinnerGPSreferenceTest(); +} + /* This is the code of dedicated core. We deal with extremely precise real-time task. */ void core1_entry() { const uint32_t clkhz = PLL_SYS_MHZ * 1000000L; - //const uint32_t freq_hz = GEN_FRQ_HZ; /* Initialize DCO */ assert_(0 == PioDCOInit(&DCO, 6, clkhz)); @@ -102,7 +144,7 @@ void core1_entry() PioDCOStart(&DCO); /* Set initial freq. */ - //assert_(0 == PioDCOSetFreq(&DCO, freq_hz, 0u)); + assert_(0 == PioDCOSetFreq(&DCO, GEN_FRQ_HZ, 0u)); /* Run the main DCO algorithm. It spins forever. */ PioDCOWorker2(&DCO); @@ -140,9 +182,9 @@ void RAM (SpinnerSweepTest)(void) /* LED signal */ gpio_put(PICO_DEFAULT_LED_PIN, 1); - sleep_ms(250); + sleep_ms(500); gpio_put(PICO_DEFAULT_LED_PIN, 0); - sleep_ms(250); + sleep_ms(500); /* Return to initial freq after 20 steps (100 Hz). */ if(++i == 20) @@ -250,37 +292,3 @@ void RAM (SpinnerGPSreferenceTest)(void) } } } - -void RAM (SpinnerDummyTest)(void) -{ - for(;;) - { - tight_loop_contents(); - //PioDCOSetFreq(&DCO, GEN_FRQ_HZ, 0u); - } -} - -int main() -{ - const uint32_t clkhz = PLL_SYS_MHZ * 1000000L; - set_sys_clock_khz(clkhz / 1000L, true); - - stdio_init_all(); - sleep_ms(1000); - printf("Start\n"); - - gpio_init(PICO_DEFAULT_LED_PIN); - gpio_set_dir(PICO_DEFAULT_LED_PIN, GPIO_OUT); - - multicore_launch_core1(core1_entry); - - SpinnerDummyTest(); - - //SpinnerSweepTest(); - //SpinnerMFSKTest(); - //SpinnerRTTYTest(); - //SpinnerMilliHertzTest(); - //SpinnerWide4FSKTest(); - //SpinnerGPSreferenceTest(); -} - diff --git a/test/pico-MFSK-9M4-test.uf2 b/test/pico-MFSK-9M4-test.uf2 deleted file mode 100644 index e6aa8e4..0000000 Binary files a/test/pico-MFSK-9M4-test.uf2 and /dev/null differ diff --git a/test/pico-MilliHertz-9M4-test.uf2 b/test/pico-MilliHertz-9M4-test.uf2 deleted file mode 100644 index a63d5e6..0000000 Binary files a/test/pico-MilliHertz-9M4-test.uf2 and /dev/null differ diff --git a/test/pico-RTTY-9M4-test.uf2 b/test/pico-RTTY-9M4-test.uf2 deleted file mode 100644 index d4546ad..0000000 Binary files a/test/pico-RTTY-9M4-test.uf2 and /dev/null differ diff --git a/test/pico-Wide4FSK-9M4-test.uf2 b/test/pico-Wide4FSK-9M4-test.uf2 deleted file mode 100644 index b18503e..0000000 Binary files a/test/pico-Wide4FSK-9M4-test.uf2 and /dev/null differ diff --git a/test/pico-sweep-9M4-test.uf2 b/test/pico-sweep-9M4-test.uf2 deleted file mode 100644 index 7aded8a..0000000 Binary files a/test/pico-sweep-9M4-test.uf2 and /dev/null differ