kopia lustrzana https://github.com/RPiks/pico-hf-oscillator
it is working up to ~30.5M freq. so far no tight tests though.
rodzic
3886eb4408
commit
cd9a90e24d
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
%}
|
|
@ -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.
|
||||
|
|
|
@ -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
23
test.c
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue