Skip to content

Commit

Permalink
it is working up to ~30.5M freq. so far no tight tests though.
Browse files Browse the repository at this point in the history
  • Loading branch information
RPiks committed Dec 10, 2023
1 parent c92aa38 commit e0ca48a
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 13 deletions.
9 changes: 4 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.13)
set(CMAKE_BUILD_TYPE "Release")

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
# set(CMAKE_CXX_STANDARD 17)

# Initialise pico_sdk from installed location
# (note this can come from environment, CMake cache etc)
Expand All @@ -22,13 +22,13 @@ project(pico-hf-oscillator-test C CXX ASM)

# Initialise the Raspberry Pi Pico SDK
pico_sdk_init()

# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Og")
add_executable(pico-hf-oscillator-test)

pico_generate_pio_header(pico-hf-oscillator-test ${CMAKE_CURRENT_LIST_DIR}/piodco/dco.pio)
pico_generate_pio_header(pico-hf-oscillator-test ${CMAKE_CURRENT_LIST_DIR}/piodco/dco2.pio)

target_sources(pico-hf-oscillator-test PUBLIC
${CMAKE_CURRENT_LIST_DIR}/lib/assert.c
${CMAKE_CURRENT_LIST_DIR}/lib/assert.c
${CMAKE_CURRENT_LIST_DIR}/lib/thirdparty/strnstr.c
${CMAKE_CURRENT_LIST_DIR}/piodco/piodco.c
${CMAKE_CURRENT_LIST_DIR}/gpstime/GPStime.c
Expand Down Expand Up @@ -60,7 +60,6 @@ target_link_libraries(
hardware_timer
hardware_clocks
hardware_pio
#hardware_vreg
)

pico_add_extra_outputs(pico-hf-oscillator-test)
143 changes: 143 additions & 0 deletions piodco/dco2.pio
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
///////////////////////////////////////////////////////////////////////////////
//
// Roman Piksaykin [[email protected]], R2BDY
// https://www.qrz.com/db/r2bdy
//
///////////////////////////////////////////////////////////////////////////////
//
//
// dco2.pio Digital controlled radio freq oscillator based on PIO.
//
//
// DESCRIPTION
// -
//
// PLATFORM
// Raspberry Pi pico.
//
// REVISION HISTORY
//
// Rev 2.0 09 Dec 2023
// New algo devising.
//
// 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.
///////////////////////////////////////////////////////////////////////////////
.program dco

.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

mov x, y [1]
LOOP2:
jmp x-- LOOP2
set pins, 1

mov x, y [1]
LOOP3:
jmp x-- 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

static inline void dco_program_init(PIO pio, uint sm, uint offset, uint pin)
{
pio_sm_config c = dco_program_get_default_config(offset);

sm_config_set_out_shift(&c, true, true, 32); // Autopull.
sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX);

sm_config_set_out_pins(&c, pin, 1);
pio_gpio_init(pio, pin);

pio_sm_set_consecutive_pindirs(pio, sm, pin, 1, true);

sm_config_set_clkdiv_int_frac(&c, 1u, 0u);

pio_sm_init(pio, sm, offset, &c);
pio_sm_set_enabled(pio, sm, true);
}
//
static inline void dco_program_puts(PIO pio, uint sm, const uint32_t *s)
{
pio_sm_put_blocking(pio, sm, s[0]);
pio_sm_put_blocking(pio, sm, s[1]);
pio_sm_put_blocking(pio, sm, s[2]);
pio_sm_put_blocking(pio, sm, s[3]);
pio_sm_put_blocking(pio, sm, s[4]);
pio_sm_put_blocking(pio, sm, s[5]);
pio_sm_put_blocking(pio, sm, s[6]);
pio_sm_put_blocking(pio, sm, s[7]);
}

static inline void dco_program_puts1w(PIO pio, uint sm, const uint32_t val)
{
pio_sm_put_blocking(pio, sm, val);
}
%}
40 changes: 38 additions & 2 deletions piodco/piodco.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
#include <string.h>
#include "../lib/assert.h"

#include "build/dco.pio.h"
#include "build/dco2.pio.h"

int32_t si32precise_cycles; /* External in order to support ISR. */

Expand All @@ -89,11 +89,16 @@ int PioDCOInit(PioDco *pdco, int gpio, int cpuclkhz)
pdco->_offset = pio_add_program(pdco->_pio, &dco_program);
pdco->_ism = pio_claim_unused_sm(pdco->_pio, true);

gpio_init(pdco->_gpio);
pio_gpio_init(pdco->_pio, pdco->_gpio);

dco_program_init(pdco->_pio, pdco->_ism, pdco->_offset, pdco->_gpio);
pdco->_pio_sm = dco_program_get_default_config(pdco->_offset);

sm_config_set_out_shift(&pdco->_pio_sm, true, true, 32); // Autopull.
sm_config_set_fifo_join(&pdco->_pio_sm, PIO_FIFO_JOIN_TX);
sm_config_set_set_pins(&pdco->_pio_sm, pdco->_gpio, 1);
pio_gpio_init(pdco->_pio, pdco->_gpio);

pio_sm_init(pdco->_pio, pdco->_ism, pdco->_offset, &pdco->_pio_sm);

return 0;
Expand Down Expand Up @@ -169,6 +174,37 @@ void PioDCOStop(PioDco *pdco)
pio_sm_set_enabled(pdco->_pio, pdco->_ism, false);
}

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;
//const register uint32_t i23left = 8388608U;
LOOP:

i32wc = i32reg;
i32wc -= i32acc_error;
//i32wc += i23left;
i32wc >>= 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);

goto LOOP;
}

/// @brief Main worker task of DCO. It is time critical, so it ought to be run on
/// @brief the dedicated pi pico core.
/// @param pDCO Ptr to DCO context.
Expand Down
1 change: 1 addition & 0 deletions piodco/piodco.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,6 @@ void PioDCOStop(PioDco *pdco);
void PioDCOSetMode(PioDco *pdco, enum PioDcoMode emode);

void RAM (PioDCOWorker)(PioDco *pDCO);
void RAM (PioDCOWorker2)(PioDco *pDCO);

#endif
23 changes: 17 additions & 6 deletions test.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
#include "defines.h"

#include "piodco/piodco.h"
#include "build/dco.pio.h"
#include "build/dco2.pio.h"
#include "hardware/vreg.h"
#include "pico/multicore.h"
#include "pico/stdio/driver.h"
Expand All @@ -84,7 +84,7 @@

#include <GPStime.h>

#define GEN_FRQ_HZ 9400000L
#define GEN_FRQ_HZ 10000000L

PioDco DCO; /* External in order to access in both cores. */

Expand All @@ -93,7 +93,7 @@ PioDco DCO; /* External in order to access in both cores. */
void core1_entry()
{
const uint32_t clkhz = PLL_SYS_MHZ * 1000000L;
const uint32_t freq_hz = GEN_FRQ_HZ;
//const uint32_t freq_hz = GEN_FRQ_HZ;

/* Initialize DCO */
assert_(0 == PioDCOInit(&DCO, 6, clkhz));
Expand All @@ -102,10 +102,10 @@ void core1_entry()
PioDCOStart(&DCO);

/* Set initial freq. */
assert_(0 == PioDCOSetFreq(&DCO, freq_hz, 0u));
//assert_(0 == PioDCOSetFreq(&DCO, freq_hz, 0u));

/* Run the main DCO algorithm. It spins forever. */
PioDCOWorker(&DCO);
PioDCOWorker2(&DCO);
}

void RAM (SpinnerMFSKTest)(void)
Expand Down Expand Up @@ -251,6 +251,15 @@ 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;
Expand All @@ -265,11 +274,13 @@ int main()

multicore_launch_core1(core1_entry);

SpinnerDummyTest();

//SpinnerSweepTest();
//SpinnerMFSKTest();
//SpinnerRTTYTest();
//SpinnerMilliHertzTest();
//SpinnerWide4FSKTest();
SpinnerGPSreferenceTest();
//SpinnerGPSreferenceTest();
}

0 comments on commit e0ca48a

Please sign in to comment.