diff --git a/include/si5351_driver.h b/include/si5351_driver.h index 0c5a88f..33e491a 100644 --- a/include/si5351_driver.h +++ b/include/si5351_driver.h @@ -32,123 +32,218 @@ typedef enum { }si5351_CLK_Disable_State; +typedef enum { + + SI5351_OUTPUT_DIVBY_1 = 0, + SI5351_OUTPUT_DIVBY_2 = 1, + SI5351_OUTPUT_DIVBY_4 = 2, + SI5351_OUTPUT_DIVBY_8 = 3, + SI5351_OUTPUT_DIVBY_16 = 4, + SI5351_OUTPUT_DIVBY_32 = 5, + SI5351_OUTPUT_DIVBY_64 = 6, + SI5351_OUTPUT_DIVBY_128 = 7, + + +}si5351_OutputDivide; + + +typedef enum { + + SI5351_CLK_SOURCE_XTAL = 0, + SI5351_CLK_SOURCE_CLOCKSOURCE = 1, + + + +}si5351_ClkSource; + +typedef enum { + + SI5351_REG_PLL_INPUT_SOURCE = 0xf0, // Reg 15 + + + + +}si5351_Registers; + + typedef int (*setGet_I2C_Event_fpt)(void *inst, uint8_t *data, uint32_t len, uint8_t set_get); typedef struct{ - uint8_t SYS_INIT : 1; // System Initialization Status - uint8_t LOL_A : 1; // PLLB Loss Of Lock Status. - uint8_t LOL_B : 1; // PLL A Loss Of Lock Status. - uint8_t LOS_CLKIN : 1; // CLKIN Loss Of Signal (Si5351C Only). - uint8_t LOS_XTAL : 1; // Crystal Loss of Signal - uint8_t RESERVED : 1; uint8_t REVID : 2; // Revision number of the device. - + uint8_t RESERVED : 1; + uint8_t LOS_XTAL : 1; // Crystal Loss of Signal + uint8_t LOS_CLKIN : 1; // CLKIN Loss Of Signal (Si5351C Only). + uint8_t LOL_B : 1; // PLL A Loss Of Lock Status. + uint8_t LOL_A : 1; // PLLB Loss Of Lock Status. + uint8_t SYS_INIT : 1; // System Initialization Status }__attribute__((packed)) si5351_deviceStat_t; typedef struct{ - uint8_t SYS_INIT_STKY : 1; // System Calibration Status Sticky Bit + uint8_t RESERVED : 3; + uint8_t LOS_XTAL_STKY : 1; // Crystal Loss of Signal Sticky Bit. + uint8_t LOS_CLKIN_STKY : 1; // CLKIN Loss Of Signal (Si5351C Only) Sticky Bit. uint8_t LOL_A_STKY : 1; // PLLB Loss Of Lock Status Sticky Bit uint8_t LOL_B_STKY : 1; // PLL A Loss Of Lock Status Sticky Bit. - uint8_t LOS_CLKIN_STKY : 1; // CLKIN Loss Of Signal (Si5351C Only) Sticky Bit. - uint8_t LOS_XTAL_STKY : 1; // Crystal Loss of Signal Sticky Bit. - uint8_t RESERVED : 3; - + uint8_t SYS_INIT_STKY : 1; // System Calibration Status Sticky Bit }__attribute__((packed)) si5351_interruptStatusSticky_t; typedef struct{ - uint8_t CLK7_OEB : 1; - uint8_t CLK6_OEB : 1; - uint8_t CLK5_OEB : 1; - uint8_t CLK4_OEB : 1; - uint8_t CLK3_OEB : 1; - uint8_t CLK2_OEB : 1; - uint8_t CLK1_OEB : 1; + uint8_t RESERVED : 3; + uint8_t LOS_XTAL_MASK : 1; // Crystal Loss of Signal Sticky Bit. + uint8_t LOS_CLKIN_MASK : 1; // CLKIN Loss Of Signal (Si5351C Only) Sticky Bit. + uint8_t LOL_A_MASK : 1; // PLLB Loss Of Lock Status Sticky Bit + uint8_t LOL_B_MASK : 1; // PLL A Loss Of Lock Status Sticky Bit. + uint8_t SYS_INIT_MASK : 1; // System Calibration Status Sticky Bit + +}__attribute__((packed)) si5351_interruptStatusMask_t; + +typedef struct{ + uint8_t CLK0_OEB : 1; - - + uint8_t CLK1_OEB : 1; + uint8_t CLK2_OEB : 1; + uint8_t CLK3_OEB : 1; + uint8_t CLK4_OEB : 1; + uint8_t CLK5_OEB : 1; + uint8_t CLK6_OEB : 1; + uint8_t CLK7_OEB : 1; }__attribute__((packed)) si5351_outputEnableControl_t; typedef struct{ - uint8_t CLKIN_DIV : 2; // ClKIN Input Divider + uint8_t CLK0_OEB_MSK : 1; + uint8_t CLK1_OEB_MSK : 1; + uint8_t CLK2_OEB_MSK : 1; + uint8_t CLK3_OEB_MSK : 1; + uint8_t CLK4_OEB_MSK : 1; + uint8_t CLK5_OEB_MSK : 1; + uint8_t CLK6_OEB_MSK : 1; + uint8_t CLK7_OEB_MSK : 1; + +}__attribute__((packed)) si5351_outputEnableControlMask_t; + +typedef struct{ + uint8_t RESERVED_0 : 2; - uint8_t PLLB_SRC : 1; // Input Source Select for PLLB. uint8_t PLLA_SRC : 1; // Input Source Select for PLLA. + uint8_t PLLB_SRC : 1; // Input Source Select for PLLB. uint8_t RESERVED_1 : 2; + uint8_t CLKIN_DIV : 2; // ClKIN Input Divider }__attribute__((packed)) si5351_PLLInputSource_t; typedef struct{ - uint8_t CLK_PDN: 1; // ClKIN Input Divider - uint8_t MS0_INT : 1; // MultiSynth 0 Integer Mode - uint8_t MS0_SRC : 1; // MultiSynth Source Select for CLK0. - uint8_t CLK_INV : 1; // Input Source Select for PLLB. - uint8_t CLK_SRC : 2; // Input Source Select for PLLA. si5351_DriveStrengthControl CLK_IDRV : 2; // CLK0 Output Rise and Fall time / Drive Strength Control + uint8_t CLK_SRC : 2; // Output Clock x Input Source. + uint8_t CLK_INV : 1; // Output Clock x Invert. + uint8_t MSx_SRC : 1; // MultiSynth Source Select for CLK0. + uint8_t MSx_INT : 1; // MultiSynth x Integer Mode + uint8_t CLK_PDN: 1; // Clock x Power Down. }__attribute__((packed)) si5351_CLK_Control_t; typedef struct{ - uint8_t CLK3_DIS_STATE: 1; // ClKIN Input Divider - uint8_t MS0_INT : 1; // MultiSynth 0 Integer Mode - uint8_t MS0_SRC : 1; // MultiSynth Source Select for CLK0. - uint8_t CLK_INV : 1; // Input Source Select for PLLB. - uint8_t CLK_SRC : 2; // Input Source Select for PLLA. - si5351_DriveStrengthControl CLK_IDRV : 2; // CLK0 Output Rise and Fall time / Drive Strength Control - -}__attribute__((packed)) si5351_CLK_Control_t; - -typedef struct{ - - si5351_CLK_Disable_State CLK3_DIS_STATE : 2; - si5351_CLK_Disable_State CLK2_DIS_STATE : 2; - si5351_CLK_Disable_State CLK1_DIS_STATE : 2; si5351_CLK_Disable_State CLK0_DIS_STATE : 2; + si5351_CLK_Disable_State CLK1_DIS_STATE : 2; + si5351_CLK_Disable_State CLK2_DIS_STATE : 2; + si5351_CLK_Disable_State CLK3_DIS_STATE : 2; // Clock x Disable State }__attribute__((packed)) si5351_CLK3_0_Control_t; typedef struct{ - si5351_CLK_Disable_State CLK7_DIS_STATE : 2; - si5351_CLK_Disable_State CLK6_DIS_STATE : 2; - si5351_CLK_Disable_State CLK5_DIS_STATE : 2; si5351_CLK_Disable_State CLK4_DIS_STATE : 2; + si5351_CLK_Disable_State CLK5_DIS_STATE : 2; + si5351_CLK_Disable_State CLK6_DIS_STATE : 2; + si5351_CLK_Disable_State CLK7_DIS_STATE : 2; }__attribute__((packed)) si5351_CLK7_4_Control_t; typedef struct{ + uint8_t MSNx_P3_15_8; // register 26 & 34 + uint8_t MSNx_P3_7_0; // 27 & 35 + uint8_t MSNx_P1_17_16 : 2; // (first) 28 & 36 + uint8_t Reserved : 6; // (rest of) 28 & 36 + uint8_t MSNx_P1_15_8; // 29 & 37 + uint8_t MSNx_P1_7_0; // 30 & 38 + uint8_t MSNx_P2_19_16 : 4; // (first) 31 & 39 + uint8_t MSNx_P3_19_16 : 4; // (rest of) 31 & 40 + uint8_t MSNx_P2_15_8; // 32 & 41 + uint8_t MSNx_P2_7_0; // 33 & 41 +}__attribute__((packed)) si5351_multiSynthNxParameters_t; +typedef struct{ + uint8_t MSx_P3_15_8; // register 42 + uint8_t MSx_P3_7_0; // 43 + uint8_t MSx_P1_17_16 : 2; // (first) 44 + uint8_t MSx_DIVBY4 : 2; // (rest of) 44 + si5351_OutputDivide Rx_DIV : 3; // (rest of) 44 + uint8_t Reserved_0 : 1; + uint8_t MSx_P1_15_8; // 46 + uint8_t MSx_P1_7_0; // 30 + uint8_t MSx_P2_19_16 : 4; // (first) 31 + uint8_t MSx_P3_19_16 : 4; // (rest of) 31 + uint8_t MSx_P2_15_8; // 32 + uint8_t MSx_P2_7_0; // 33 -}__attribute__((packed)) si5351_CLK7_4_Control_t; +}__attribute__((packed)) si5351_multiSynthxParameters_t; + +typedef struct { + uint8_t MS6_P1; +} __attribute__((packed))si5351_multiSynth6Parameters_t; + +typedef struct { + uint8_t MS7_P1; +} __attribute__((packed))si5351_multiSynth7Parameters_t; typedef struct{ - si5351_deviceStat_t deviceStatus; - si5351_interruptStatusSticky_t ISR_StatusSticky; - si5351_outputEnableControl_t outputEnableControl; - si5351_PLLInputSource_t pllInputSource; + si5351_deviceStat_t deviceStatus; // 0x00 + si5351_interruptStatusSticky_t ISR_StatusSticky; // 0x01 + si5351_interruptStatusMask_t ISR_StatusMask; // 0x02 + si5351_outputEnableControl_t outputEnableControl; // 0x03 + si5351_outputEnableControlMask_t outputEnableControlMask; // 0x09 + si5351_PLLInputSource_t pllInputSource; // 0x0F - si5351_CLK_Control_t CLK0_control; - si5351_CLK_Control_t CLK1_control; - si5351_CLK_Control_t CLK2_control; - si5351_CLK_Control_t CLK3_control; - si5351_CLK_Control_t CLK4_control; - si5351_CLK_Control_t CLK5_control; - si5351_CLK_Control_t CLK6_control; - si5351_CLK_Control_t CLK7_control; + si5351_CLK_Control_t CLK0_control; // 0x10 + si5351_CLK_Control_t CLK1_control; // 0x11 + si5351_CLK_Control_t CLK2_control; // 0x12 + si5351_CLK_Control_t CLK3_control; // 0x13 + si5351_CLK_Control_t CLK4_control; // 0x14 + si5351_CLK_Control_t CLK5_control; // 0x15 + si5351_CLK_Control_t CLK6_control; // 0x16 + si5351_CLK_Control_t CLK7_control; // 0x17 si5351_CLK3_0_Control_t clk_3_0_DisableState; si5351_CLK7_4_Control_t clk_7_4_DisableState; + si5351_multiSynthNxParameters_t multiSynthNAParam; + si5351_multiSynthNxParameters_t multiSynthNBParam; + + si5351_multiSynthxParameters_t multiSynth0Param; + si5351_multiSynthxParameters_t multiSynth1Param; + si5351_multiSynthxParameters_t multiSynth2Param; + si5351_multiSynthxParameters_t multiSynth3Param; + si5351_multiSynthxParameters_t multiSynth4Param; + si5351_multiSynthxParameters_t multiSynth5Param; + + si5351_multiSynth6Parameters_t multiSynth6Param; + si5351_multiSynth7Parameters_t multiSynth7Param; + + si5351_OutputDivide R6_DIV : 3; + uint8_t Reserved_0 : 1; + si5351_OutputDivide R7_DIV : 3; + uint8_t Reserved_1 : 1; + @@ -166,6 +261,7 @@ typedef struct{ int cm_si5351_init(si5351_driver *inst, void *i2c_transfer_inst, setGet_I2C_Event_fpt i2c_transfer_evt); uint8_t cm_si5351_getRevisionNumber(si5351_driver *inst); +int cm_setInputSource(si5351_driver *inst, si5351_ClkSource clk_source); #endif /* SI5351_DRIVER_INCLUDE_SI5351_DRIVER_H_ */ diff --git a/si5351_driver.c b/si5351_driver.c index b122b47..a18f264 100644 --- a/si5351_driver.c +++ b/si5351_driver.c @@ -12,11 +12,55 @@ enum{ }; +static int readRegister(si5351_driver *inst,uint8_t data_addr, uint8_t *data, uint32_t len){ + + // Write what kind of addr we would like to read from: + inst->i2c_transfer_evt(inst->i2c_transfer_inst,&data_addr,1, SI5351_I2C_SET); + + // Read data: + inst->i2c_transfer_evt(inst->i2c_transfer_inst,data,len, SI5351_I2C_GET); + + return 0; +} + +static int writeRegister(si5351_driver *inst,uint8_t data_addr, uint8_t *data, uint32_t len){ + + // Write what kind of addr we would like to read from: + inst->i2c_transfer_evt(inst->i2c_transfer_inst,&data_addr,1, SI5351_I2C_SET); + + // Write data: + inst->i2c_transfer_evt(inst->i2c_transfer_inst,data,len, SI5351_I2C_SET); + + return 0; +} + +int cm_setInputSource(si5351_driver *inst, si5351_ClkSource clk_source){ + + switch(clk_source){ + + case SI5351_CLK_SOURCE_XTAL: + inst->device_data.pllInputSource.PLLA_SRC = 1; + break; + + case SI5351_CLK_SOURCE_CLOCKSOURCE: + inst->device_data.pllInputSource.PLLA_SRC = 0; + break; + + default: + break; + + } + + // Write to register: + writeRegister(inst,SI5351_REG_PLL_INPUT_SOURCE, (uint8_t*) &inst->device_data.pllInputSource, sizeof(si5351_PLLInputSource_t)); + + return 0; +} + uint8_t cm_si5351_getRevisionNumber(si5351_driver *inst){ // Read Device Status register: - inst->i2c_transfer_evt(inst->i2c_transfer_inst,(uint8_t*) &(inst->device_data.deviceStatus),sizeof(inst->device_data.deviceStatus), SI5351_I2C_GET); - + readRegister(inst,0x00, (uint8_t *) &inst->device_data.deviceStatus, sizeof(si5351_deviceStat_t)); return inst->device_data.deviceStatus.REVID; }