Files
squero/squero/Core/Inc/si5351.h
nzasch 5219b4bfbe init
2022-01-03 17:56:55 +01:00

331 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**************************************************************************/
/*!
@file Adafruit_SI5351.h
@author K. Townsend (Adafruit Industries)
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2014, Adafruit Industries
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**************************************************************************/
#ifndef _SI5351_H_
#define _SI5351_H_
extern I2C_HandleTypeDef hi2c2;
#include "si5351_errors.h"
#include "si5351_asserts.h"
#define SI5351_ADDRESS (0x60) // Assumes ADDR pin = low
#define SI5351_READBIT (0x01)
#define USE_FULL_ASSERT (0x01)
/* Test setup from SI5351 ClockBuilder
* -----------------------------------
* XTAL: 25 MHz
* Channel 0: 120.00 MHz
* Channel 1: 12.00 MHz
* Channel 2: 13.56 MHz
*/
static const uint8_t m_si5351_regs_15to92_149to170[100][2] =
{
{ 15, 0x00 }, /* Input source = crystal for PLLA and PLLB */
{ 16, 0x4F }, /* CLK0 Control: 8mA drive, Multisynth 0 as CLK0 source, Clock not inverted, Source = PLLA, Multisynth 0 in integer mode, clock powered up */
{ 17, 0x4F }, /* CLK1 Control: 8mA drive, Multisynth 1 as CLK1 source, Clock not inverted, Source = PLLA, Multisynth 1 in integer mode, clock powered up */
{ 18, 0x6F }, /* CLK2 Control: 8mA drive, Multisynth 2 as CLK2 source, Clock not inverted, Source = PLLB, Multisynth 2 in integer mode, clock powered up */
{ 19, 0x80 }, /* CLK3 Control: Not used ... clock powered down */
{ 20, 0x80 }, /* CLK4 Control: Not used ... clock powered down */
{ 21, 0x80 }, /* CLK5 Control: Not used ... clock powered down */
{ 22, 0x80 }, /* CLK6 Control: Not used ... clock powered down */
{ 23, 0x80 }, /* CLK7 Control: Not used ... clock powered down */
{ 24, 0x00 }, /* Clock disable state 0..3 (low when disabled) */
{ 25, 0x00 }, /* Clock disable state 4..7 (low when disabled) */
/* PLL_A Setup */
{ 26, 0x00 },
{ 27, 0x05 },
{ 28, 0x00 },
{ 29, 0x0C },
{ 30, 0x66 },
{ 31, 0x00 },
{ 32, 0x00 },
{ 33, 0x02 },
/* PLL_B Setup */
{ 34, 0x02 },
{ 35, 0x71 },
{ 36, 0x00 },
{ 37, 0x0C },
{ 38, 0x1A },
{ 39, 0x00 },
{ 40, 0x00 },
{ 41, 0x86 },
/* Multisynth Setup */
{ 42, 0x00 },
{ 43, 0x01 },
{ 44, 0x00 },
{ 45, 0x01 },
{ 46, 0x00 },
{ 47, 0x00 },
{ 48, 0x00 },
{ 49, 0x00 },
{ 50, 0x00 },
{ 51, 0x01 },
{ 52, 0x00 },
{ 53, 0x1C },
{ 54, 0x00 },
{ 55, 0x00 },
{ 56, 0x00 },
{ 57, 0x00 },
{ 58, 0x00 },
{ 59, 0x01 },
{ 60, 0x00 },
{ 61, 0x18 },
{ 62, 0x00 },
{ 63, 0x00 },
{ 64, 0x00 },
{ 65, 0x00 },
{ 66, 0x00 },
{ 67, 0x00 },
{ 68, 0x00 },
{ 69, 0x00 },
{ 70, 0x00 },
{ 71, 0x00 },
{ 72, 0x00 },
{ 73, 0x00 },
{ 74, 0x00 },
{ 75, 0x00 },
{ 76, 0x00 },
{ 77, 0x00 },
{ 78, 0x00 },
{ 79, 0x00 },
{ 80, 0x00 },
{ 81, 0x00 },
{ 82, 0x00 },
{ 83, 0x00 },
{ 84, 0x00 },
{ 85, 0x00 },
{ 86, 0x00 },
{ 87, 0x00 },
{ 88, 0x00 },
{ 89, 0x00 },
{ 90, 0x00 },
{ 91, 0x00 },
{ 92, 0x00 },
/* Misc Config Register */
{ 149, 0x00 },
{ 150, 0x00 },
{ 151, 0x00 },
{ 152, 0x00 },
{ 153, 0x00 },
{ 154, 0x00 },
{ 155, 0x00 },
{ 156, 0x00 },
{ 157, 0x00 },
{ 158, 0x00 },
{ 159, 0x00 },
{ 160, 0x00 },
{ 161, 0x00 },
{ 162, 0x00 },
{ 163, 0x00 },
{ 164, 0x00 },
{ 165, 0x00 },
{ 166, 0x00 },
{ 167, 0x00 },
{ 168, 0x00 },
{ 169, 0x00 },
{ 170, 0x00 }
};
/* See http://www.silabs.com/Support%20Documents/TechnicalDocs/AN619.pdf for registers 26..41 */
enum
{
SI5351_REGISTER_0_DEVICE_STATUS = 0,
SI5351_REGISTER_1_INTERRUPT_STATUS_STICKY = 1,
SI5351_REGISTER_2_INTERRUPT_STATUS_MASK = 2,
SI5351_REGISTER_3_OUTPUT_ENABLE_CONTROL = 3,
SI5351_REGISTER_9_OEB_PIN_ENABLE_CONTROL = 9,
SI5351_REGISTER_15_PLL_INPUT_SOURCE = 15,
SI5351_REGISTER_16_CLK0_CONTROL = 16,
SI5351_REGISTER_17_CLK1_CONTROL = 17,
SI5351_REGISTER_18_CLK2_CONTROL = 18,
SI5351_REGISTER_19_CLK3_CONTROL = 19,
SI5351_REGISTER_20_CLK4_CONTROL = 20,
SI5351_REGISTER_21_CLK5_CONTROL = 21,
SI5351_REGISTER_22_CLK6_CONTROL = 22,
SI5351_REGISTER_23_CLK7_CONTROL = 23,
SI5351_REGISTER_24_CLK3_0_DISABLE_STATE = 24,
SI5351_REGISTER_25_CLK7_4_DISABLE_STATE = 25,
SI5351_REGISTER_42_MULTISYNTH0_PARAMETERS_1 = 42,
SI5351_REGISTER_43_MULTISYNTH0_PARAMETERS_2 = 43,
SI5351_REGISTER_44_MULTISYNTH0_PARAMETERS_3 = 44,
SI5351_REGISTER_45_MULTISYNTH0_PARAMETERS_4 = 45,
SI5351_REGISTER_46_MULTISYNTH0_PARAMETERS_5 = 46,
SI5351_REGISTER_47_MULTISYNTH0_PARAMETERS_6 = 47,
SI5351_REGISTER_48_MULTISYNTH0_PARAMETERS_7 = 48,
SI5351_REGISTER_49_MULTISYNTH0_PARAMETERS_8 = 49,
SI5351_REGISTER_50_MULTISYNTH1_PARAMETERS_1 = 50,
SI5351_REGISTER_51_MULTISYNTH1_PARAMETERS_2 = 51,
SI5351_REGISTER_52_MULTISYNTH1_PARAMETERS_3 = 52,
SI5351_REGISTER_53_MULTISYNTH1_PARAMETERS_4 = 53,
SI5351_REGISTER_54_MULTISYNTH1_PARAMETERS_5 = 54,
SI5351_REGISTER_55_MULTISYNTH1_PARAMETERS_6 = 55,
SI5351_REGISTER_56_MULTISYNTH1_PARAMETERS_7 = 56,
SI5351_REGISTER_57_MULTISYNTH1_PARAMETERS_8 = 57,
SI5351_REGISTER_58_MULTISYNTH2_PARAMETERS_1 = 58,
SI5351_REGISTER_59_MULTISYNTH2_PARAMETERS_2 = 59,
SI5351_REGISTER_60_MULTISYNTH2_PARAMETERS_3 = 60,
SI5351_REGISTER_61_MULTISYNTH2_PARAMETERS_4 = 61,
SI5351_REGISTER_62_MULTISYNTH2_PARAMETERS_5 = 62,
SI5351_REGISTER_63_MULTISYNTH2_PARAMETERS_6 = 63,
SI5351_REGISTER_64_MULTISYNTH2_PARAMETERS_7 = 64,
SI5351_REGISTER_65_MULTISYNTH2_PARAMETERS_8 = 65,
SI5351_REGISTER_66_MULTISYNTH3_PARAMETERS_1 = 66,
SI5351_REGISTER_67_MULTISYNTH3_PARAMETERS_2 = 67,
SI5351_REGISTER_68_MULTISYNTH3_PARAMETERS_3 = 68,
SI5351_REGISTER_69_MULTISYNTH3_PARAMETERS_4 = 69,
SI5351_REGISTER_70_MULTISYNTH3_PARAMETERS_5 = 70,
SI5351_REGISTER_71_MULTISYNTH3_PARAMETERS_6 = 71,
SI5351_REGISTER_72_MULTISYNTH3_PARAMETERS_7 = 72,
SI5351_REGISTER_73_MULTISYNTH3_PARAMETERS_8 = 73,
SI5351_REGISTER_74_MULTISYNTH4_PARAMETERS_1 = 74,
SI5351_REGISTER_75_MULTISYNTH4_PARAMETERS_2 = 75,
SI5351_REGISTER_76_MULTISYNTH4_PARAMETERS_3 = 76,
SI5351_REGISTER_77_MULTISYNTH4_PARAMETERS_4 = 77,
SI5351_REGISTER_78_MULTISYNTH4_PARAMETERS_5 = 78,
SI5351_REGISTER_79_MULTISYNTH4_PARAMETERS_6 = 79,
SI5351_REGISTER_80_MULTISYNTH4_PARAMETERS_7 = 80,
SI5351_REGISTER_81_MULTISYNTH4_PARAMETERS_8 = 81,
SI5351_REGISTER_82_MULTISYNTH5_PARAMETERS_1 = 82,
SI5351_REGISTER_83_MULTISYNTH5_PARAMETERS_2 = 83,
SI5351_REGISTER_84_MULTISYNTH5_PARAMETERS_3 = 84,
SI5351_REGISTER_85_MULTISYNTH5_PARAMETERS_4 = 85,
SI5351_REGISTER_86_MULTISYNTH5_PARAMETERS_5 = 86,
SI5351_REGISTER_87_MULTISYNTH5_PARAMETERS_6 = 87,
SI5351_REGISTER_88_MULTISYNTH5_PARAMETERS_7 = 88,
SI5351_REGISTER_89_MULTISYNTH5_PARAMETERS_8 = 89,
SI5351_REGISTER_90_MULTISYNTH6_PARAMETERS = 90,
SI5351_REGISTER_91_MULTISYNTH7_PARAMETERS = 91,
SI5351_REGISTER_092_CLOCK_6_7_OUTPUT_DIVIDER = 92,
SI5351_REGISTER_165_CLK0_INITIAL_PHASE_OFFSET = 165,
SI5351_REGISTER_166_CLK1_INITIAL_PHASE_OFFSET = 166,
SI5351_REGISTER_167_CLK2_INITIAL_PHASE_OFFSET = 167,
SI5351_REGISTER_168_CLK3_INITIAL_PHASE_OFFSET = 168,
SI5351_REGISTER_169_CLK4_INITIAL_PHASE_OFFSET = 169,
SI5351_REGISTER_170_CLK5_INITIAL_PHASE_OFFSET = 170,
SI5351_REGISTER_177_PLL_RESET = 177,
SI5351_REGISTER_183_CRYSTAL_INTERNAL_LOAD_CAPACITANCE = 183
};
typedef enum
{
SI5351_PLL_A = 0,
SI5351_PLL_B,
} si5351PLL_t;
typedef enum
{
SI5351_CRYSTAL_LOAD_6PF = (1<<6),
SI5351_CRYSTAL_LOAD_8PF = (2<<6),
SI5351_CRYSTAL_LOAD_10PF = (3<<6)
} si5351CrystalLoad_t;
typedef enum
{
SI5351_CRYSTAL_FREQ_24MHZ = (24000000),
SI5351_CRYSTAL_FREQ_25MHZ = (25000000),
SI5351_CRYSTAL_FREQ_27MHZ = (27000000)
} si5351CrystalFreq_t;
typedef enum
{
SI5351_MULTISYNTH_DIV_4 = 4,
SI5351_MULTISYNTH_DIV_6 = 6,
SI5351_MULTISYNTH_DIV_8 = 8
} si5351MultisynthDiv_t;
typedef enum
{
SI5351_R_DIV_1 = 0,
SI5351_R_DIV_2 = 1,
SI5351_R_DIV_4 = 2,
SI5351_R_DIV_8 = 3,
SI5351_R_DIV_16 = 4,
SI5351_R_DIV_32 = 5,
SI5351_R_DIV_64 = 6,
SI5351_R_DIV_128 = 7,
} si5351RDiv_t;
typedef struct
{
uint8_t initialised;
si5351CrystalFreq_t crystalFreq;
si5351CrystalLoad_t crystalLoad;
uint32_t crystalPPM;
uint8_t plla_configured;
uint32_t plla_freq;
uint8_t pllb_configured;
uint32_t pllb_freq;
uint32_t ms0_freq;
uint32_t ms1_freq;
uint32_t ms2_freq;
uint32_t ms0_r_div;
uint32_t ms1_r_div;
uint32_t ms2_r_div;
} si5351Config_t;
err_t si5351_Init(void);
err_t si5351_setupPLL(si5351PLL_t pll, uint8_t mult, uint32_t num, uint32_t denom);
err_t si5351_setupPLLInt(si5351PLL_t pll, uint8_t mult);
err_t si5351_setupMultisynth(uint8_t output, si5351PLL_t pllSource, uint32_t div, uint32_t num, uint32_t denom);
err_t si5351_setupMultisynthInt(uint8_t output, si5351PLL_t pllSource, si5351MultisynthDiv_t div);
err_t si5351_enableOutputs(uint8_t enabled);
err_t si5351_setupRdiv(uint8_t output, si5351RDiv_t div);
extern si5351Config_t m_si5351Config;
err_t si5351_write8(uint8_t reg, uint8_t value);
err_t si5351_read8(uint8_t reg, uint8_t *value);
#endif
/*
The VCO frequency can only be from 600 MHz to 900 MHz. Yes, over-clocking is possible, and so in under-clocking, to extend the output frequency range beyond 2,3 kHz to 200 MHz. But lets leave this for now.
The FMD ratio can be from 15 + 0/1 048 575 and to 90 + 0/1 048 575, i.e. a = 15, b = 0 and c = 1 048 575 to a = 90, b = 0 and c = 1 048 575. Please remember that c can never be zero (0), as this will violate fundamental math principles.
The OMD ratio can be 4 and from 6 to 2048. Please remember that f can never be zero (0), as this will violate fundamental math principles.
The R divider can only be 1, 2, 4, 8, 16, 32, 64 or 128.
If the output frequency is above 150 MHz d is always 4.
If the output frequency is below 500 kHz R should be used, i.e. higher than 1.
https://www.rfzero.net/documentation/tools/si5351a-frequency-tool/
*/