From 1102fbd4d5faa50572af80ba0b9c6f3c48708a1d Mon Sep 17 00:00:00 2001 From: "Christian L. V. Madsen" Date: Sun, 13 Apr 2025 14:35:12 +0200 Subject: [PATCH] even more lightwheight --- si5351_driver.c | 246 ++++++++++++++++++------------------------------ si5351_driver.h | 21 +---- 2 files changed, 90 insertions(+), 177 deletions(-) diff --git a/si5351_driver.c b/si5351_driver.c index d59c9bf..2665987 100644 --- a/si5351_driver.c +++ b/si5351_driver.c @@ -27,45 +27,46 @@ static int readRegister(si5351_driver *inst,uint8_t data_addr, uint8_t *data, ui return 0; } -static int writeRegister(si5351_driver *inst,uint8_t data_addr, uint8_t *data, uint32_t len){ +static int writeRegister(si5351_driver *inst,uint8_t data_addr, uint32_t len){ - uint8_t *data_ptr = malloc(len+1); - - *data_ptr = data_addr; - - - // Copy data - memcpy(&data_ptr[1],data,len); - // Write data: - inst->i2c_transfer_evt(inst->i2c_transfer_inst,data_ptr,len+1, SI5351_I2C_SET); + // Set address + inst->device_data[0] = data_addr; + inst->i2c_transfer_evt(inst->i2c_transfer_inst,&inst->device_data[0],len+1, SI5351_I2C_SET); + return 0; +} - free(data_ptr); +static int writeRegisterbyte(si5351_driver *inst,uint8_t data_addr, uint8_t data){ + + // Set address + uint8_t buff[2] = {data_addr,data}; + inst->i2c_transfer_evt(inst->i2c_transfer_inst,&buff[0],2, SI5351_I2C_SET); return 0; } int cm_setPllParamRaw(si5351_driver *inst, si5351_PLLs sel_pll, uint32_t MSNx_P1, uint32_t MSNx_P2, uint32_t MSNx_P3){ + si5351_multiSynthNxParameters_t *multiSynthNxParam = (void*)&inst->device_data[1]; - inst->device_data.multiSynthNxParam.MSNx_P1_17_16 = (MSNx_P1 >> 16) & 0x2; - inst->device_data.multiSynthNxParam.MSNx_P1_15_8 = (MSNx_P1 >> 8) & 0xff; - inst->device_data.multiSynthNxParam.MSNx_P1_7_0 = MSNx_P1 & 0xff; + multiSynthNxParam->MSNx_P1_17_16 = (MSNx_P1 >> 16) & 0x3; + multiSynthNxParam->MSNx_P1_15_8 = (MSNx_P1 >> 8) & 0xff; + multiSynthNxParam->MSNx_P1_7_0 = MSNx_P1 & 0xff; - inst->device_data.multiSynthNxParam.MSNx_P2_19_16 = ((MSNx_P2 & 0x000F0000) >> 16); - inst->device_data.multiSynthNxParam.MSNx_P2_15_8 = (MSNx_P2 >> 8) & 0xff; - inst->device_data.multiSynthNxParam.MSNx_P2_7_0 = MSNx_P2 & 0xff; + multiSynthNxParam->MSNx_P2_19_16 = (MSNx_P2 >> 16) & 0xf; + multiSynthNxParam->MSNx_P2_15_8 = (MSNx_P2 >> 8) & 0xff; + multiSynthNxParam->MSNx_P2_7_0 = MSNx_P2 & 0xff; - inst->device_data.multiSynthNxParam.MSNx_P3_19_16 = ((MSNx_P3 & 0x000F0000) >> 12); - inst->device_data.multiSynthNxParam.MSNx_P3_15_8 = (MSNx_P3 >> 8) & 0xff; - inst->device_data.multiSynthNxParam.MSNx_P3_7_0 = MSNx_P3 & 0xff; + multiSynthNxParam->MSNx_P3_19_16 = (MSNx_P3 >> 16) & 0xf; + multiSynthNxParam->MSNx_P3_15_8 = (MSNx_P3 >> 8) & 0xff; + multiSynthNxParam->MSNx_P3_7_0 = MSNx_P3 & 0xff; switch(sel_pll){ case SI5351_PLL_A: - writeRegister(inst,SI5351_REG_MULTISYNTH_NA_0, (uint8_t*) &inst->device_data.multiSynthNxParam, sizeof(si5351_multiSynthNxParameters_t)); + writeRegister(inst,SI5351_REG_MULTISYNTH_NA_0, sizeof(si5351_multiSynthNxParameters_t)); break; case SI5351_PLL_B: - writeRegister(inst,SI5351_REG_MULTISYNTH_NB_0, (uint8_t*) &inst->device_data.multiSynthNxParam, sizeof(si5351_multiSynthNxParameters_t)); + writeRegister(inst,SI5351_REG_MULTISYNTH_NB_0, sizeof(si5351_multiSynthNxParameters_t)); break; default: @@ -81,33 +82,35 @@ int cm_setPllParamRaw(si5351_driver *inst, si5351_PLLs sel_pll, uint32_t MSNx_P1 int cm_setOutputMultiSynthRaw(si5351_driver *inst,si5351_Outputs clk_output, uint32_t MSx_P1, uint32_t MSx_P2, uint32_t MSx_P3){ - inst->device_data.multiSynthxParam.MSx_P1_17_16 = (MSx_P1 >> 16) & 0x3; // last division.. - inst->device_data.multiSynthxParam.MSx_P1_15_8 = (MSx_P1 >> 8) & 0xff; - inst->device_data.multiSynthxParam.MSx_P1_7_0 = MSx_P1 & 0xff; - inst->device_data.multiSynthxParam.MSx_P2_19_16 = (MSx_P2 >> 16) & 0x3; - inst->device_data.multiSynthxParam.MSx_P2_15_8 = (MSx_P2 >> 8) & 0xff; - inst->device_data.multiSynthxParam.MSx_P2_7_0 = MSx_P2 & 0xff; + si5351_multiSynthxParameters_t *multiSynthxParam = (void*)&inst->device_data[1]; + multiSynthxParam->MSx_P1_17_16 = (MSx_P1 >> 16) & 0x3; // last division.. + multiSynthxParam->MSx_P1_15_8 = (MSx_P1 >> 8) & 0xff; + multiSynthxParam->MSx_P1_7_0 = MSx_P1 & 0xff; - inst->device_data.multiSynthxParam.MSx_P3_19_16 = (MSx_P3 >> 12) & 0x3; - inst->device_data.multiSynthxParam.MSx_P3_15_8 = (MSx_P3 >> 8) & 0xff; - inst->device_data.multiSynthxParam.MSx_P3_7_0 = MSx_P3 & 0xff; + multiSynthxParam->MSx_P2_19_16 = (MSx_P2 >> 16) & 0xf; + multiSynthxParam->MSx_P2_15_8 = (MSx_P2 >> 8) & 0xff; + multiSynthxParam->MSx_P2_7_0 = MSx_P2 & 0xff; + + multiSynthxParam->MSx_P3_19_16 = (MSx_P3 >> 16) & 0xf; + multiSynthxParam->MSx_P3_15_8 = (MSx_P3 >> 8) & 0xff; + multiSynthxParam->MSx_P3_7_0 = MSx_P3 & 0xff; - inst->device_data.multiSynthxParam.MSx_DIVBY4 = 0; - inst->device_data.multiSynthxParam.Rx_DIV = 0; + multiSynthxParam->MSx_DIVBY4 = 0; + multiSynthxParam->Rx_DIV = 0; switch(clk_output){ case SI5351_OUTPUT_0: - writeRegister(inst,SI5351_REG_MULTISYNTH_OUT_0, (uint8_t*) &inst->device_data.multiSynthxParam, sizeof(si5351_multiSynthxParameters_t)); + writeRegister(inst,SI5351_REG_MULTISYNTH_OUT_0, sizeof(si5351_multiSynthxParameters_t)); break; case SI5351_OUTPUT_1: - writeRegister(inst,SI5351_REG_MULTISYNTH_OUT_1, (uint8_t*) &inst->device_data.multiSynthxParam, sizeof(si5351_multiSynthxParameters_t)); + writeRegister(inst,SI5351_REG_MULTISYNTH_OUT_1, sizeof(si5351_multiSynthxParameters_t)); break; case SI5351_OUTPUT_2: - writeRegister(inst,SI5351_REG_MULTISYNTH_OUT_2, (uint8_t*) &inst->device_data.multiSynthxParam, sizeof(si5351_multiSynthxParameters_t)); + writeRegister(inst,SI5351_REG_MULTISYNTH_OUT_2, sizeof(si5351_multiSynthxParameters_t)); break; default: @@ -118,119 +121,36 @@ int cm_setOutputMultiSynthRaw(si5351_driver *inst,si5351_Outputs clk_output, uin return 0; -} -/* -int cm_setPLLParameters(si5351_driver *inst,si5351_PLLs sel_pll, uint32_t a, uint32_t b, uint32_t c){ - - uint32_t temp_val = 0; - - temp_val = (float)128 * (float)a + ((float)128 * ((float)b/(float)c)) - (float)512; - - inst->device_data.multiSynthNxParam.MSNx_P1_17_16 = (temp_val >> 16) & 0x2; - inst->device_data.multiSynthNxParam.MSNx_P1_15_8 = (temp_val >> 8) & 0xff; - inst->device_data.multiSynthNxParam.MSNx_P1_7_0 = temp_val & 0xff; - - temp_val = 0; - - temp_val = (uint32_t)(128 * b - c * floor(128 * ((float)b / (float)c))); - - inst->device_data.multiSynthNxParam.MSNx_P2_19_16 = ((temp_val & 0x000F0000) >> 16); - inst->device_data.multiSynthNxParam.MSNx_P2_15_8 = (temp_val >> 8) & 0xff; - inst->device_data.multiSynthNxParam.MSNx_P2_7_0 = temp_val & 0xff; - - inst->device_data.multiSynthNxParam.MSNx_P3_19_16 = ((c & 0x000F0000) >> 12); - inst->device_data.multiSynthNxParam.MSNx_P3_15_8 = (c >> 8) & 0xff; - inst->device_data.multiSynthNxParam.MSNx_P3_7_0 = c & 0xff; - - switch(sel_pll){ - - case SI5351_PLL_A: - writeRegister(inst,SI5351_REG_MULTISYNTH_NA_0, (uint8_t*) &inst->device_data.multiSynthNxParam, sizeof(si5351_multiSynthNxParameters_t)); - break; - - case SI5351_PLL_B: - writeRegister(inst,SI5351_REG_MULTISYNTH_NB_0, (uint8_t*) &inst->device_data.multiSynthNxParam, sizeof(si5351_multiSynthNxParameters_t)); - break; - - } - - // reset PLL's - cm_resetPLLs(inst, 1,1); - - - return 0; -}*/ - -int cm_setOutputMultiSynth(si5351_driver *inst,si5351_Outputs clk_output, uint32_t d, uint32_t e, uint32_t f){ - - /* Integer mode */ - uint32_t P1 = 128 * d - 512; - uint32_t P2 = e; - uint32_t P3 = f; - - - inst->device_data.multiSynthxParam.MSx_P1_17_16 = (P1 >> 16) & 0x3; // last division.. - inst->device_data.multiSynthxParam.MSx_P1_15_8 = (P1 >> 8) & 0xff; - inst->device_data.multiSynthxParam.MSx_P1_7_0 = P1 & 0xff; - - inst->device_data.multiSynthxParam.MSx_P2_19_16 = (P2 >> 16) & 0x3; - inst->device_data.multiSynthxParam.MSx_P2_15_8 = (P2 >> 8) & 0xff; - inst->device_data.multiSynthxParam.MSx_P2_7_0 = P2 & 0xff; - - inst->device_data.multiSynthxParam.MSx_P3_19_16 = (P3 >> 12) & 0x3; - inst->device_data.multiSynthxParam.MSx_P3_15_8 = (P3 >> 8) & 0xff; - inst->device_data.multiSynthxParam.MSx_P3_7_0 = P3 & 0xff; - - switch(clk_output){ - - case SI5351_OUTPUT_0: - writeRegister(inst,SI5351_REG_MULTISYNTH_OUT_0, (uint8_t*) &inst->device_data.multiSynthxParam, sizeof(si5351_multiSynthxParameters_t)); - break; - - case SI5351_OUTPUT_1: - writeRegister(inst,SI5351_REG_MULTISYNTH_OUT_1, (uint8_t*) &inst->device_data.multiSynthxParam, sizeof(si5351_multiSynthxParameters_t)); - break; - - case SI5351_OUTPUT_2: - writeRegister(inst,SI5351_REG_MULTISYNTH_OUT_2, (uint8_t*) &inst->device_data.multiSynthxParam, sizeof(si5351_multiSynthxParameters_t)); - break; - - default: - break; - - - } - - return 0; - } int cm_setOutputEnable(si5351_driver *inst,si5351_Outputs clk_output, si5351_Outputs_state outputState){ - + si5351_outputEnableControl_t *outputEnableControl = (void*)&inst->device_data[1]; switch (clk_output) { case SI5351_OUTPUT_0: - inst->device_data.outputEnableControl.CLK0_OEB = outputState; + outputEnableControl->CLK0_OEB = outputState; break; case SI5351_OUTPUT_1: - inst->device_data.outputEnableControl.CLK1_OEB = outputState; + outputEnableControl->CLK1_OEB = outputState; break; case SI5351_OUTPUT_2: - inst->device_data.outputEnableControl.CLK2_OEB = outputState; + outputEnableControl->CLK2_OEB = outputState; break; default: break; } - - - writeRegister(inst,SI5351_REG_OUTPUT_ENABLE_CONTROL, (uint8_t*) &inst->device_data.outputEnableControl, sizeof(si5351_outputEnableControl_t)); + outputEnableControl->CLK0_OEB = 0; + outputEnableControl->CLK1_OEB = 0; + outputEnableControl->CLK2_OEB = 0; + + writeRegister(inst,SI5351_REG_OUTPUT_ENABLE_CONTROL, sizeof(si5351_outputEnableControl_t)); return 0; @@ -238,26 +158,34 @@ int cm_setOutputEnable(si5351_driver *inst,si5351_Outputs clk_output, si5351_Out int cm_setCLKControl(si5351_driver *inst, si5351_Outputs clk_output, si5351_CLK_PDN clk_pdn){ + si5351_CLK_Control_t *CLKx_control = (void*)&inst->device_data[1]; - inst->device_data.CLKx_control.CLK_PDN = clk_pdn; - inst->device_data.CLKx_control.MSx_INT = 1; - inst->device_data.CLKx_control.CLK_SRC = 0b11; - inst->device_data.CLKx_control.MSx_SRC = 0; - inst->device_data.CLKx_control.CLK_IDRV = SI5351_DRIVE_STRENGTH_8MA; + CLKx_control->CLK_PDN = clk_pdn; + + CLKx_control->CLK_IDRV = SI5351_DRIVE_STRENGTH_8MA; switch (clk_output) { case SI5351_OUTPUT_0: - writeRegister(inst,SI5351_REG_CLK_0_CONTROL, (uint8_t*) &inst->device_data.CLKx_control, sizeof(si5351_CLK_Control_t)); + CLKx_control->CLK_SRC = 0b11; + CLKx_control->MSx_SRC = 0; + CLKx_control->MSx_INT = 0; + writeRegister(inst,SI5351_REG_CLK_0_CONTROL, sizeof(si5351_CLK_Control_t)); break; case SI5351_OUTPUT_1: - writeRegister(inst,SI5351_REG_CLK_1_CONTROL, (uint8_t*) &inst->device_data.CLKx_control, sizeof(si5351_CLK_Control_t)); + CLKx_control->CLK_SRC = 0b11; + CLKx_control->MSx_SRC = 1; + CLKx_control->MSx_INT = 0; + writeRegister(inst,SI5351_REG_CLK_1_CONTROL, sizeof(si5351_CLK_Control_t)); break; case SI5351_OUTPUT_2: - writeRegister(inst,SI5351_REG_CLK_2_CONTROL, (uint8_t*) &inst->device_data.CLKx_control, sizeof(si5351_CLK_Control_t)); + CLKx_control->CLK_SRC = 0b00; + CLKx_control->MSx_SRC = 0; + CLKx_control->MSx_INT = 1; + writeRegister(inst,SI5351_REG_CLK_2_CONTROL, sizeof(si5351_CLK_Control_t)); break; default: @@ -274,15 +202,17 @@ int cm_setCLKControl(si5351_driver *inst, si5351_Outputs clk_output, si5351_CLK_ int cm_setInputSource(si5351_driver *inst, si5351_ClkSource clk_source){ + si5351_PLLInputSource_t *pllInputSource = (void*)&inst->device_data[1]; + switch(clk_source){ case SI5351_CLK_SOURCE_XTAL: - inst->device_data.pllInputSource.PLLA_SRC = 0; - inst->device_data.pllInputSource.PLLB_SRC = 0; + pllInputSource->PLLA_SRC = 0; + pllInputSource->PLLB_SRC = 0; break; case SI5351_CLK_SOURCE_CLOCKSOURCE: - inst->device_data.pllInputSource.PLLA_SRC = 1; + pllInputSource->PLLA_SRC = 1; break; default: @@ -291,30 +221,32 @@ int cm_setInputSource(si5351_driver *inst, si5351_ClkSource clk_source){ } // Write to register: - writeRegister(inst,SI5351_REG_PLL_INPUT_SOURCE, (uint8_t*) &inst->device_data.pllInputSource, sizeof(si5351_PLLInputSource_t)); + writeRegister(inst,SI5351_REG_PLL_INPUT_SOURCE, sizeof(si5351_PLLInputSource_t)); return 0; } int cm_resetPLLs(si5351_driver *inst, uint8_t reset_PLLA, uint8_t reset_PLLB){ - inst->device_data.PLL_Reset.PLLA_RST = (reset_PLLA != 0)? 1 : 0; - inst->device_data.PLL_Reset.PLLB_RST = (reset_PLLB != 0)? 1 : 0; + si5351_PLL_Reset_t *PLL_Reset = (void*)&inst->device_data[1]; + + PLL_Reset->PLLA_RST = (reset_PLLA != 0)? 1 : 0; + PLL_Reset->PLLB_RST = (reset_PLLB != 0)? 1 : 0; // Write to register: - writeRegister(inst,SI5351_REG_PLL_RESET, (uint8_t*) &inst->device_data.PLL_Reset, sizeof(si5351_PLL_Reset_t)); + writeRegister(inst,SI5351_REG_PLL_RESET, sizeof(si5351_PLL_Reset_t)); return 0; } - +/* uint8_t cm_si5351_getRevisionNumber(si5351_driver *inst){ // Read Device Status register: readRegister(inst,0x00, (uint8_t *) &inst->device_data.deviceStatus, sizeof(si5351_deviceStat_t)); return inst->device_data.deviceStatus.REVID; -} +}*/ int cm_si5351_init(si5351_driver *inst, void *i2c_transfer_inst, setGet_I2C_Event_fpt i2c_transfer_evt){ @@ -327,30 +259,30 @@ int cm_si5351_init(si5351_driver *inst, void *i2c_transfer_inst, setGet_I2C_Even int ret = 0; - memset(&(inst->device_data),0x00,sizeof(si5351_data)); + //memset(&(inst->device_data),0x00,sizeof(si5351_data)); /* Disable all outputs setting CLKx_DIS high */ uint8_t temp = 0xff; - writeRegister(inst,SI5351_REG_OUTPUT_ENABLE_CONTROL,&temp,1); + writeRegisterbyte(inst,SI5351_REG_OUTPUT_ENABLE_CONTROL,temp); /* Power down all output drivers */ temp = 0x80; - writeRegister(inst,SI5351_REG_CLK_0_CONTROL,&temp,1); - writeRegister(inst,SI5351_REG_CLK_1_CONTROL,&temp,1); - writeRegister(inst,SI5351_REG_CLK_2_CONTROL,&temp,1); - writeRegister(inst,SI5351_REG_CLK_3_CONTROL,&temp,1); - writeRegister(inst,SI5351_REG_CLK_4_CONTROL,&temp,1); - writeRegister(inst,SI5351_REG_CLK_5_CONTROL,&temp,1); - writeRegister(inst,SI5351_REG_CLK_6_CONTROL,&temp,1); - writeRegister(inst,SI5351_REG_CLK_7_CONTROL,&temp,1); + writeRegisterbyte(inst,SI5351_REG_CLK_0_CONTROL,temp); + writeRegisterbyte(inst,SI5351_REG_CLK_1_CONTROL,temp); + writeRegisterbyte(inst,SI5351_REG_CLK_2_CONTROL,temp); + writeRegisterbyte(inst,SI5351_REG_CLK_3_CONTROL,temp); + writeRegisterbyte(inst,SI5351_REG_CLK_4_CONTROL,temp); + writeRegisterbyte(inst,SI5351_REG_CLK_5_CONTROL,temp); + writeRegisterbyte(inst,SI5351_REG_CLK_6_CONTROL,temp); + writeRegisterbyte(inst,SI5351_REG_CLK_7_CONTROL,temp); temp = SI5351_CRYSTAL_LOAD_10PF; - writeRegister(inst,SI5351_REG_CRYSTAL_LOAD_CAPACITANCE,&temp,1); + writeRegisterbyte(inst,SI5351_REG_CRYSTAL_LOAD_CAPACITANCE,temp); // Enable xtal clk.. temp = 0b01000000; - writeRegister(inst,SI5351_REG_FANOUT_ENABLE,&temp,1); + writeRegisterbyte(inst,SI5351_REG_FANOUT_ENABLE,temp); return ret; diff --git a/si5351_driver.h b/si5351_driver.h index 29be302..457e1ae 100644 --- a/si5351_driver.h +++ b/si5351_driver.h @@ -261,30 +261,12 @@ typedef struct { } __attribute__((packed))si5351_PLL_Reset_t; -typedef struct{ - - 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 CLKx_control; // 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 - si5351_CLK_Dis_Control_t clk_DisableState; - si5351_multiSynthNxParameters_t multiSynthNxParam; - si5351_multiSynthxParameters_t multiSynthxParam; - si5351_multiSynth67Parameters_t multiSynth67Param; - si5351_OutputDivide Rx_DIV : 3; // R6 & R7 - si5351_PLL_Reset_t PLL_Reset; - -}__attribute__((packed)) si5351_data; - typedef struct{ void *i2c_transfer_inst; setGet_I2C_Event_fpt i2c_transfer_evt; - si5351_data device_data; + uint8_t device_data[15]; }__attribute__((packed)) si5351_driver; @@ -293,7 +275,6 @@ int cm_si5351_init(si5351_driver *inst, void *i2c_transfer_inst, setGet_I2C_Even uint8_t cm_si5351_getRevisionNumber(si5351_driver *inst); int cm_setInputSource(si5351_driver *inst, si5351_ClkSource clk_source); int cm_setPLLParameters(si5351_driver *inst,si5351_PLLs sel_pll, uint32_t a, uint32_t b, uint32_t c); -int cm_setOutputMultiSynth(si5351_driver *inst,si5351_Outputs clk_output, uint32_t d, uint32_t e, uint32_t f); int cm_setOutputMultiSynthRaw(si5351_driver *inst,si5351_Outputs clk_output, uint32_t MSx_P1, uint32_t MSx_P2, uint32_t MSx_P3); int cm_setOutputEnable(si5351_driver *inst,si5351_Outputs clk_output, si5351_Outputs_state outputState); int cm_setCLKControl(si5351_driver *inst, si5351_Outputs clk_output, si5351_CLK_PDN clk_pdn);