it is working up to ~30.5M freq. so far no tight tests though.

wip4speed
roman 2023-12-10 03:56:26 +03:00
rodzic 3886eb4408
commit cd9a90e24d
5 zmienionych plików z 203 dodań i 13 usunięć

Wyświetl plik

@ -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)
@ -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
@ -60,7 +60,6 @@ target_link_libraries(
hardware_timer
hardware_clocks
hardware_pio
#hardware_vreg
)
pico_add_extra_outputs(pico-hf-oscillator-test)

143
piodco/dco2.pio 100644
Wyświetl plik

@ -0,0 +1,143 @@
///////////////////////////////////////////////////////////////////////////////
//
// Roman Piksaykin [piksaykin@gmail.com], 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);
}
%}

Wyświetl plik

@ -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. */
@ -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;
@ -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.

Wyświetl plik

@ -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
test.c
Wyświetl plik

@ -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"
@ -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. */
@ -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));
@ -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)
@ -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;
@ -265,11 +274,13 @@ int main()
multicore_launch_core1(core1_entry);
SpinnerDummyTest();
//SpinnerSweepTest();
//SpinnerMFSKTest();
//SpinnerRTTYTest();
//SpinnerMilliHertzTest();
//SpinnerWide4FSKTest();
SpinnerGPSreferenceTest();
//SpinnerGPSreferenceTest();
}