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
	
	 roman
						roman