From 5177f954ae7b570e7842a69793baf83a5ab80478 Mon Sep 17 00:00:00 2001 From: Bruce MacKinnon Date: Sat, 10 Oct 2020 13:46:19 -0400 Subject: [PATCH 1/5] Small refactoring to allow other I2C interfaces --- src/ArduinoInterface.h | 72 +++++++++++++++++++++++++++++++++++++++ src/I2CInterface.h | 49 ++++++++++++++++++++++++++ src/STM32_HAL_Interface.h | 46 +++++++++++++++++++++++++ src/si5351.cpp | 55 +++++++++++------------------- src/si5351.h | 4 +-- 5 files changed, 188 insertions(+), 38 deletions(-) create mode 100644 src/ArduinoInterface.h create mode 100644 src/I2CInterface.h create mode 100644 src/STM32_HAL_Interface.h diff --git a/src/ArduinoInterface.h b/src/ArduinoInterface.h new file mode 100644 index 0000000..fb974f8 --- /dev/null +++ b/src/ArduinoInterface.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2020 Bruce MacKinnon KC1FSZ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef _ArduinoInterface_h +#define _ArduinoInterface_h + +#include "Arduino.h" +#include "Wire.h" +#include "I2CInterface.h" + +class ArduinoInterface : public I2CInterface { +public: + + ArduinoInterface() { + Wire.begin(); + } + + uint8_t check_address(uint8_t i2c_bus_addr) { + Wire.beginTransmission(i2c_bus_addr); + return Wire.endTransmission(); + } + + uint8_t read(uint8_t i2c_bus_addr, uint8_t addr) { + + uint8_t reg_val = 0; + + Wire.beginTransmission(i2c_bus_addr); + Wire.write(addr); + Wire.endTransmission(); + + Wire.requestFrom(i2c_bus_addr, (uint8_t)1, (uint8_t)false); + + while(Wire.available()) + { + reg_val = Wire.read(); + } + + return reg_val; + } + + uint8_t write(uint8_t i2c_bus_addr, uint8_t addr, uint8_t data) { + Wire.beginTransmission(i2c_bus_addr); + Wire.write(addr); + Wire.write(data); + return Wire.endTransmission(); + } + + uint8_t write_bulk(uint8_t i2c_bus_addr, uint8_t addr, uint8_t bytes, uint8_t *data) { + Wire.beginTransmission(i2c_bus_addr); + Wire.write(addr); + for(int i = 0; i < bytes; i++) + { + Wire.write(data[i]); + } + return Wire.endTransmission(); + } +}; + +#endif diff --git a/src/I2CInterface.h b/src/I2CInterface.h new file mode 100644 index 0000000..8dc0055 --- /dev/null +++ b/src/I2CInterface.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 Bruce MacKinnon KC1FSZ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef _I2CInterface_h +#define _I2CInterface_h + +#include + +/** + * A generic interface for interacting with an I2C bus + */ +class I2CInterface { +public: + + /** + * Determmines whether a device is connected at the specified address. + */ + virtual uint8_t check_address(uint8_t i2c_bus_addr) = 0; + + /** + * Standard read operation. + */ + virtual uint8_t read(uint8_t i2c_bus_addr, uint8_t addr) = 0; + + /** + * Standard write operation. + */ + virtual uint8_t write(uint8_t i2c_bus_addr, uint8_t addr, uint8_t data) = 0; + + /** + * Multi-byte write operation + */ + virtual uint8_t write_bulk(uint8_t i2c_bus_addr, uint8_t addr, uint8_t bytes, uint8_t *data) = 0; +}; + +#endif diff --git a/src/STM32_HAL_Interface.h b/src/STM32_HAL_Interface.h new file mode 100644 index 0000000..0e09451 --- /dev/null +++ b/src/STM32_HAL_Interface.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2020 Bruce MacKinnon KC1FSZ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef _STM32_HAL_Interface_h +#define _STM32_HAL_Interface_h + +#include +#include "I2CInterface.h" + +// An STM32/HAL based implementation of the I2CInterface. +// +// NOT IMPLEMENTED YET!! +// +class STM32_HAL_Interface : public I2C_Interface { +public: + // TODO: WILL PASS THE HAL I2C STRUCTURE HERE + STM32_HAL_Interface() { + } + uint8_t check_address(uint8_t i2c_bus_addr) { + return 0; + } + uint8_t read(uint8_t i2c_bus_addr, uint8_t addr) { + return 0; + } + uint8_t write(uint8_t i2c_bus_addr, uint8_t addr, uint8_t data) { + return 0; + } + uint8_t write_bulk(uint8_t i2c_bus_addr, uint8_t addr, uint8_t bytes, uint8_t *data) { + return 0; + } +}; + +#endif diff --git a/src/si5351.cpp b/src/si5351.cpp index e140d65..97dd99b 100644 --- a/src/si5351.cpp +++ b/src/si5351.cpp @@ -24,10 +24,18 @@ #include +// Bring in the relevant interface to the I2C bus +#ifndef STM32 +#include "STM32_HAL_Interface.h" +static STM32_HAL_Interface I2C_Interface_Instance; +#else #include "Arduino.h" #include "Wire.h" -#include "si5351.h" +#include "ArduinoInterface.h" +static ArduinoInterface I2C_Interface_Instance; +#endif +#include "si5351.h" /********************/ /* Public functions */ @@ -36,6 +44,9 @@ Si5351::Si5351(uint8_t i2c_addr): i2c_bus_addr(i2c_addr) { + // Connect to the appropriate I2C interface + i2c_interface = &I2C_Interface_Instance; + xtal_freq[0] = SI5351_XTAL_FREQ; // Start by using XO ref osc as default for each PLL @@ -62,13 +73,8 @@ Si5351::Si5351(uint8_t i2c_addr): */ bool Si5351::init(uint8_t xtal_load_c, uint32_t xo_freq, int32_t corr) { - // Start I2C comms - Wire.begin(); - // Check for a device on the bus, bail out if it is not there - Wire.beginTransmission(i2c_bus_addr); - uint8_t reg_val; - reg_val = Wire.endTransmission(); + uint8_t reg_val = i2c_interface->check_address(i2c_bus_addr); if(reg_val == 0) { @@ -565,7 +571,7 @@ void Si5351::set_pll(uint64_t pll_freq, enum si5351_pll target_pll) pllb_freq = pll_freq; } - delete params; + delete [] params; } /* @@ -672,7 +678,7 @@ void Si5351::set_ms(enum si5351_clock clk, struct Si5351RegSet ms_reg, uint8_t i break; } - delete params; + delete [] params; } /* @@ -1240,7 +1246,7 @@ void Si5351::set_vcxo(uint64_t pll_freq, uint8_t ppm) // Write the parameters si5351_write_bulk(SI5351_PLLB_PARAMETERS, i, params); - delete params; + delete [] params; // Write the VCXO parameters vcxo_param = ((vcxo_param * ppm * SI5351_VCXO_MARGIN) / 100ULL) / 1000000ULL; @@ -1309,40 +1315,17 @@ void Si5351::set_ref_freq(uint32_t ref_freq, enum si5351_pll_input ref_osc) uint8_t Si5351::si5351_write_bulk(uint8_t addr, uint8_t bytes, uint8_t *data) { - Wire.beginTransmission(i2c_bus_addr); - Wire.write(addr); - for(int i = 0; i < bytes; i++) - { - Wire.write(data[i]); - } - return Wire.endTransmission(); - + return i2c_interface->write_bulk(i2c_bus_addr, addr, bytes, data); } uint8_t Si5351::si5351_write(uint8_t addr, uint8_t data) { - Wire.beginTransmission(i2c_bus_addr); - Wire.write(addr); - Wire.write(data); - return Wire.endTransmission(); + return i2c_interface->write(i2c_bus_addr, addr, data); } uint8_t Si5351::si5351_read(uint8_t addr) { - uint8_t reg_val = 0; - - Wire.beginTransmission(i2c_bus_addr); - Wire.write(addr); - Wire.endTransmission(); - - Wire.requestFrom(i2c_bus_addr, (uint8_t)1, (uint8_t)false); - - while(Wire.available()) - { - reg_val = Wire.read(); - } - - return reg_val; + return i2c_interface->read(i2c_bus_addr, addr); } /*********************/ diff --git a/src/si5351.h b/src/si5351.h index 59c16e9..0092ebc 100644 --- a/src/si5351.h +++ b/src/si5351.h @@ -29,9 +29,8 @@ #ifndef SI5351_H_ #define SI5351_H_ -#include "Arduino.h" -#include "Wire.h" #include +#include "I2CInterface.h" /* Define definitions */ @@ -330,6 +329,7 @@ class Si5351 uint8_t clkin_div; uint8_t i2c_bus_addr; bool clk_first_set[8]; + I2CInterface* i2c_interface; }; #endif /* SI5351_H_ */ From e392bbc85e06dd9c12b23534757f9b040e4f24ee Mon Sep 17 00:00:00 2001 From: Bruce MacKinnon Date: Sat, 10 Oct 2020 13:55:14 -0400 Subject: [PATCH 2/5] Improved comments --- src/ArduinoInterface.h | 4 ++++ src/si5351.cpp | 4 +++- src/si5351.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ArduinoInterface.h b/src/ArduinoInterface.h index fb974f8..b13a305 100644 --- a/src/ArduinoInterface.h +++ b/src/ArduinoInterface.h @@ -21,6 +21,10 @@ #include "Wire.h" #include "I2CInterface.h" +/** + * The standard Ardiuno way of talking to I2C + * via the Wire.h library. + */ class ArduinoInterface : public I2CInterface { public: diff --git a/src/si5351.cpp b/src/si5351.cpp index 97dd99b..e8c8323 100644 --- a/src/si5351.cpp +++ b/src/si5351.cpp @@ -24,7 +24,9 @@ #include -// Bring in the relevant interface to the I2C bus +// Bring in the relevant interface to the I2C bus. This has been +// abstracted to allow the library to be used in differnet +// hardware environments. #ifndef STM32 #include "STM32_HAL_Interface.h" static STM32_HAL_Interface I2C_Interface_Instance; diff --git a/src/si5351.h b/src/si5351.h index 0092ebc..7579dd0 100644 --- a/src/si5351.h +++ b/src/si5351.h @@ -329,6 +329,7 @@ class Si5351 uint8_t clkin_div; uint8_t i2c_bus_addr; bool clk_first_set[8]; + // This is a connection to the I2C bus I2CInterface* i2c_interface; }; From 8a2ad1219a0ec2bd2d0a7ca2949248389333ee0f Mon Sep 17 00:00:00 2001 From: Bruce MacKinnon Date: Sat, 10 Oct 2020 14:57:39 -0400 Subject: [PATCH 3/5] Corrected some typos, added TTestInterface for debug --- src/STM32_HAL_Interface.h | 2 +- src/TestInterface.h | 53 +++++++++++++++++++++++++++++++++++++++ src/si5351.cpp | 19 ++++++++------ 3 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 src/TestInterface.h diff --git a/src/STM32_HAL_Interface.h b/src/STM32_HAL_Interface.h index 0e09451..1df9597 100644 --- a/src/STM32_HAL_Interface.h +++ b/src/STM32_HAL_Interface.h @@ -24,7 +24,7 @@ // // NOT IMPLEMENTED YET!! // -class STM32_HAL_Interface : public I2C_Interface { +class STM32_HAL_Interface : public I2CInterface { public: // TODO: WILL PASS THE HAL I2C STRUCTURE HERE STM32_HAL_Interface() { diff --git a/src/TestInterface.h b/src/TestInterface.h new file mode 100644 index 0000000..5d05179 --- /dev/null +++ b/src/TestInterface.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2020 Bruce MacKinnon KC1FSZ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef _Test_Interface_h +#define _Test_Interface_h + +#include +#include +#include "I2CInterface.h" + +// A dummy interface for testing. +// +class TestInterface : public I2CInterface { +public: + TestInterface() { + printf("TestInterface initialized\n"); + } + uint8_t check_address(uint8_t i2c_bus_addr) { + printf("check_address\n"); + return 0; + } + uint8_t read(uint8_t i2c_bus_addr, uint8_t addr) { + printf("read(%x,%x)\n", i2c_bus_addr, addr); + return 0; + } + uint8_t write(uint8_t i2c_bus_addr, uint8_t addr, uint8_t data) { + printf("write(%x, %x, %x)\n", i2c_bus_addr, addr, data); + return 0; + } + uint8_t write_bulk(uint8_t i2c_bus_addr, uint8_t addr, uint8_t bytes, uint8_t *data) { + printf("write_bulk(%x, %x, ", i2c_bus_addr, addr); + for (int i = 0; i < bytes; i++) { + printf("%x ", data[i]); + } + printf(")\n"); + return 0; + } +}; + +#endif diff --git a/src/si5351.cpp b/src/si5351.cpp index e8c8323..7b4ffaf 100644 --- a/src/si5351.cpp +++ b/src/si5351.cpp @@ -24,17 +24,22 @@ #include +#define SI5351_DEMO + // Bring in the relevant interface to the I2C bus. This has been // abstracted to allow the library to be used in differnet // hardware environments. -#ifndef STM32 -#include "STM32_HAL_Interface.h" -static STM32_HAL_Interface I2C_Interface_Instance; +#if defined(SI5351_STM32) + #include "STM32_HAL_Interface.h" + static STM32_HAL_Interface I2C_Interface_Instance; +#elif defined(SI5351_DEMO) + #include "TestInterface.h" + static TestInterface I2C_Interface_Instance; #else -#include "Arduino.h" -#include "Wire.h" -#include "ArduinoInterface.h" -static ArduinoInterface I2C_Interface_Instance; + #include "Arduino.h" + #include "Wire.h" + #include "ArduinoInterface.h" + static ArduinoInterface I2C_Interface_Instance; #endif #include "si5351.h" From 3bb7651bc86d75eb50fc666ca84172756644692b Mon Sep 17 00:00:00 2001 From: Bruce MacKinnon Date: Sat, 10 Oct 2020 16:03:29 -0400 Subject: [PATCH 4/5] Initial implementation of STM32 interface --- src/I2CInterface.h | 4 ++++ src/STM32_HAL_Interface.h | 49 ++++++++++++++++++++++++++++++++++----- src/si5351.cpp | 8 +++++-- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/I2CInterface.h b/src/I2CInterface.h index 8dc0055..65aa2fa 100644 --- a/src/I2CInterface.h +++ b/src/I2CInterface.h @@ -27,21 +27,25 @@ class I2CInterface { /** * Determmines whether a device is connected at the specified address. + * @return 0 if things are good, -1 if there is a problem. */ virtual uint8_t check_address(uint8_t i2c_bus_addr) = 0; /** * Standard read operation. + * @return The received byte */ virtual uint8_t read(uint8_t i2c_bus_addr, uint8_t addr) = 0; /** * Standard write operation. + * @return Then number of bytes written */ virtual uint8_t write(uint8_t i2c_bus_addr, uint8_t addr, uint8_t data) = 0; /** * Multi-byte write operation + * @return The number of bytes written */ virtual uint8_t write_bulk(uint8_t i2c_bus_addr, uint8_t addr, uint8_t bytes, uint8_t *data) = 0; }; diff --git a/src/STM32_HAL_Interface.h b/src/STM32_HAL_Interface.h index 1df9597..a0d744a 100644 --- a/src/STM32_HAL_Interface.h +++ b/src/STM32_HAL_Interface.h @@ -26,21 +26,58 @@ // class STM32_HAL_Interface : public I2CInterface { public: - // TODO: WILL PASS THE HAL I2C STRUCTURE HERE - STM32_HAL_Interface() { + + STM32_HAL_Interface(I2C_HandleTypeDef* hi2c) + : _hi2c(hi2c), + _errorCount(0), + _timeoutMs(10) { } + uint8_t check_address(uint8_t i2c_bus_addr) { - return 0; + HAL_StatusTypeDef status = HAL_I2C_IsDeviceReady(_hi2c, (uint16_t)(i2c_bus_addr << 1), 1, _timeoutMs); + if (status == HAL_OK) { + return 0; + } else { + return -1; + } } + uint8_t read(uint8_t i2c_bus_addr, uint8_t addr) { - return 0; + uint8_t reg_val = 0; + // NOTE: PER HAL DOCUMENTATION, ADDRESS NEEDS TO BE SHIFTED LEFT + HAL_StatusTypeDef status = HAL_I2C_Mem_Read(_hi2c, (uint16_t)(i2c_bus_addr << 1), (uint16_t)(addr), 1, + ®_val, 1, _timeoutMs); + if (status != HAL_OK) { + _errorCount++; + } + return reg_val; } + uint8_t write(uint8_t i2c_bus_addr, uint8_t addr, uint8_t data) { - return 0; + // NOTE: PER HAL DOCUMENTATION, ADDRESS NEEDS TO BE SHIFTED LEFT + HAL_StatusTypeDef status = HAL_I2C_Mem_Write(_hi2c, (uint16_t)(i2c_bus_addr << 1), addr, 1, + &data, 1, _timeoutMs); + if (status != HAL_OK) { + _errorCount++; + } + return 1; } + uint8_t write_bulk(uint8_t i2c_bus_addr, uint8_t addr, uint8_t bytes, uint8_t *data) { - return 0; + // NOTE: PER HAL DOCUMENTATION, ADDRESS NEEDS TO BE SHIFTED LEFT + HAL_StatusTypeDef status = HAL_I2C_Mem_Write(_hi2c, (uint16_t)(i2c_bus_addr << 1), addr, 1, + data, bytes, _timeoutMs); + if (status != HAL_OK) { + _errorCount++; + } + return bytes; } + +private: + + I2C_HandleTypeDef* _hi2c; + int _errorCount; + uint32_t _timeoutMs; }; #endif diff --git a/src/si5351.cpp b/src/si5351.cpp index 7b4ffaf..9ba9851 100644 --- a/src/si5351.cpp +++ b/src/si5351.cpp @@ -24,7 +24,11 @@ #include -#define SI5351_DEMO +// Uncomment the relevant hardware environment. Arduino +// is the default +//#define SI5351_DEMO +#define SI5351_STM32 +//#define SI5351_ARDINO // Bring in the relevant interface to the I2C bus. This has been // abstracted to allow the library to be used in differnet @@ -35,7 +39,7 @@ #elif defined(SI5351_DEMO) #include "TestInterface.h" static TestInterface I2C_Interface_Instance; -#else +#elif defined(SI5351_ARDUINO) #include "Arduino.h" #include "Wire.h" #include "ArduinoInterface.h" From 7fcbe068d46552e022ad49e86216c92c46f1be1d Mon Sep 17 00:00:00 2001 From: Bruce MacKinnon Date: Sat, 10 Oct 2020 17:07:29 -0400 Subject: [PATCH 5/5] Test successfully on STM32 --- src/STM32_HAL_Interface.h | 3 +++ src/si5351.cpp | 43 +++++++++++++++++++++++---------------- src/si5351.h | 13 ++++++++++++ 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/STM32_HAL_Interface.h b/src/STM32_HAL_Interface.h index a0d744a..f2d5f73 100644 --- a/src/STM32_HAL_Interface.h +++ b/src/STM32_HAL_Interface.h @@ -18,6 +18,9 @@ #define _STM32_HAL_Interface_h #include +// NOTE: Add the appropriate HAL include here: +#include "stm32f4xx_hal.h" + #include "I2CInterface.h" // An STM32/HAL based implementation of the I2CInterface. diff --git a/src/si5351.cpp b/src/si5351.cpp index 9ba9851..dd62d17 100644 --- a/src/si5351.cpp +++ b/src/si5351.cpp @@ -24,26 +24,18 @@ #include -// Uncomment the relevant hardware environment. Arduino -// is the default -//#define SI5351_DEMO -#define SI5351_STM32 -//#define SI5351_ARDINO - -// Bring in the relevant interface to the I2C bus. This has been -// abstracted to allow the library to be used in differnet -// hardware environments. -#if defined(SI5351_STM32) - #include "STM32_HAL_Interface.h" - static STM32_HAL_Interface I2C_Interface_Instance; -#elif defined(SI5351_DEMO) - #include "TestInterface.h" - static TestInterface I2C_Interface_Instance; -#elif defined(SI5351_ARDUINO) +// Remove this to turn off the Arduino hardware environment. Arduino +// is the default. +#define SI5351_ARDUINO + +#if defined(SI5351_ARDUINO) #include "Arduino.h" #include "Wire.h" #include "ArduinoInterface.h" static ArduinoInterface I2C_Interface_Instance; +#else + #include "TestInterface.h" + static TestInterface I2C_Interface_Instance; #endif #include "si5351.h" @@ -55,9 +47,24 @@ Si5351::Si5351(uint8_t i2c_addr): i2c_bus_addr(i2c_addr) { - // Connect to the appropriate I2C interface + // Connect to the default I2C interface i2c_interface = &I2C_Interface_Instance; - + + setup(); +} + +Si5351::Si5351(uint8_t i2c_addr, I2CInterface* i2c): + i2c_bus_addr(i2c_addr), + i2c_interface(i2c) +{ + setup(); +} + +/* + * Common setup code + */ +void Si5351::setup() { + xtal_freq[0] = SI5351_XTAL_FREQ; // Start by using XO ref osc as default for each PLL diff --git a/src/si5351.h b/src/si5351.h index 7579dd0..c407f92 100644 --- a/src/si5351.h +++ b/src/si5351.h @@ -278,7 +278,19 @@ struct Si5351IntStatus class Si5351 { public: + + /** + * Use this constructor when using the (default) Arduino + * I2C interface. + */ Si5351(uint8_t i2c_addr = SI5351_BUS_BASE_ADDR); + + /** + * Use this constructor when explicitly passing the I2CInterface + * object. + */ + Si5351(uint8_t i2c_addr, I2CInterface* i2c); + bool init(uint8_t, uint32_t, int32_t); void reset(void); uint8_t set_freq(uint64_t, enum si5351_clock); @@ -317,6 +329,7 @@ class Si5351 enum si5351_pll_input pllb_ref_osc; uint32_t xtal_freq[2]; private: + void setup(); uint64_t pll_calc(enum si5351_pll, uint64_t, struct Si5351RegSet *, int32_t, uint8_t); uint64_t multisynth_calc(uint64_t, uint64_t, struct Si5351RegSet *); uint64_t multisynth67_calc(uint64_t, uint64_t, struct Si5351RegSet *);