331 lines
12 KiB
C
331 lines
12 KiB
C
/**************************************************************************/
|
||
/*!
|
||
@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 let’s 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/
|
||
*/
|