/////////////////////////////////////////////////////////////////////////////// // // Roman Piksaykin [piksaykin@gmail.com], R2BDY // https://www.qrz.com/db/r2bdy // /////////////////////////////////////////////////////////////////////////////// // // // dco.pio Digital controlled radio freq oscillator based on PIO. // // // DESCRIPTION // - // // PLATFORM // Raspberry Pi pico. // // REVISION HISTORY // // Rev 0.1 05 Nov 2023 // Initial release. // // 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 set x, 0 set y, 0 .wrap_target // CYCLES pull // load full 32-bit register. 1c out y, 8 // load 8-bit delay value. 2c mov x, y // copy value in order to do next PI cycle. 3c LOOP0: jmp x-- LOOP0 // do exactly X*CPU CLK delay. 4c+x set pins, 1 [3] // set output high. 5c+x LOOP1: jmp y-- LOOP1 // do exactly X*CPU CLK delay. 8c+x set pins, 0 // set output high. 9c+x // RPix: The next sections repeat aforementioned algo 3 times. out y, 8 mov x, y [1] LOOP2: jmp x-- LOOP2 set pins, 1 [3] LOOP3: jmp y-- LOOP3 set pins, 0 out y, 8 mov x, y [1] LOOP4: jmp x-- LOOP4 set pins, 1 [3] LOOP5: jmp y-- LOOP5 set pins, 0 out y, 8 mov x, y [1] LOOP6: jmp x-- LOOP6 set pins, 1 [3] LOOP7: jmp y-- LOOP7 set pins, 0 .wrap % c-sdk { #define PIOASM_DELAY_CYCLES 5 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_pins(&c, pin, 1); pio_gpio_init(pio, pin); sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); //sm_config_set_out_shift(&c, true, true, 32); // Autopull. 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); } %}