kopia lustrzana https://github.com/RPiks/pico-hf-oscillator
				
				
				
			it is working up to ~30.5M freq. so far no tight tests though.
							rodzic
							
								
									c92aa38f99
								
							
						
					
					
						commit
						e0ca48aacb
					
				| 
						 | 
				
			
			@ -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