rework of si5351 driver
This commit is contained in:
parent
f3682d7103
commit
2c8881338d
@ -82,8 +82,8 @@
|
|||||||
</folderInfo>
|
</folderInfo>
|
||||||
<sourceEntries>
|
<sourceEntries>
|
||||||
<entry excluding="external_sources" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
|
<entry excluding="external_sources" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
|
||||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
|
|
||||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Middlewares"/>
|
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Middlewares"/>
|
||||||
|
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
|
||||||
</sourceEntries>
|
</sourceEntries>
|
||||||
</configuration>
|
</configuration>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
@ -165,8 +165,8 @@
|
|||||||
</folderInfo>
|
</folderInfo>
|
||||||
<sourceEntries>
|
<sourceEntries>
|
||||||
<entry excluding="external_sources" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
|
<entry excluding="external_sources" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
|
||||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
|
|
||||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Middlewares"/>
|
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Middlewares"/>
|
||||||
|
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
|
||||||
</sourceEntries>
|
</sourceEntries>
|
||||||
</configuration>
|
</configuration>
|
||||||
</storageModule>
|
</storageModule>
|
||||||
|
@ -70,8 +70,6 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include <stdint.h>
|
|
||||||
#include <si5351_reg.h> /* register map of the Si5351 */
|
|
||||||
/* #include <errno.h> could also be included */
|
/* #include <errno.h> could also be included */
|
||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
|
|
||||||
@ -105,7 +103,7 @@ typedef enum {
|
|||||||
|
|
||||||
/* Exported macros -----------------------------------------------------------*/
|
/* Exported macros -----------------------------------------------------------*/
|
||||||
#define __SI5351__ 1
|
#define __SI5351__ 1
|
||||||
#define __SI5351_MINOR__ 1
|
#define __SI5351_MINOR__ 2
|
||||||
#define __SI5351_PATCHLEVEL__ 0
|
#define __SI5351_PATCHLEVEL__ 0
|
||||||
|
|
||||||
#define SI5351_VERSION (__SI5351__ * 10000 \
|
#define SI5351_VERSION (__SI5351__ * 10000 \
|
||||||
@ -127,7 +125,6 @@ int si5351_deinitialize(void);
|
|||||||
si5351_inst_t si5351_init(void * i2c_handle, uint8_t i2c_address, uint32_t xtal_frequency);
|
si5351_inst_t si5351_init(void * i2c_handle, uint8_t i2c_address, uint32_t xtal_frequency);
|
||||||
int si5351_deinit(si5351_inst_t si5351_handle);
|
int si5351_deinit(si5351_inst_t si5351_handle);
|
||||||
int si5351_i2c_ready(si5351_inst_t inst);
|
int si5351_i2c_ready(si5351_inst_t inst);
|
||||||
int si5351_program(si5351_inst_t inst);
|
|
||||||
int si5351_enable_output(si5351_inst_t inst, uint8_t clk);
|
int si5351_enable_output(si5351_inst_t inst, uint8_t clk);
|
||||||
int si5351_disable_output(si5351_inst_t inst, uint8_t clk);
|
int si5351_disable_output(si5351_inst_t inst, uint8_t clk);
|
||||||
int si5351_set_clk0(si5351_inst_t inst, uint32_t frequency);
|
int si5351_set_clk0(si5351_inst_t inst, uint32_t frequency);
|
||||||
@ -136,7 +133,10 @@ int si5351_set_clk(si5351_inst_t inst, uint8_t clk, uint32_t frequency, si5351_p
|
|||||||
char * si5351_read_debug_msg(si5351_inst_t inst);
|
char * si5351_read_debug_msg(si5351_inst_t inst);
|
||||||
char * si5351_read_register_debug(si5351_inst_t inst, char *buf, size_t bufsize, uint8_t regaddr);
|
char * si5351_read_register_debug(si5351_inst_t inst, char *buf, size_t bufsize, uint8_t regaddr);
|
||||||
|
|
||||||
|
/* some functions for getting information */
|
||||||
int si5351_get_instance(si5351_inst_t *inst);
|
int si5351_get_instance(si5351_inst_t *inst);
|
||||||
|
int si5351_get_i2c_address(si5351_inst_t inst);
|
||||||
|
void* si5351_get_i2c_handle(si5351_inst_t inst);
|
||||||
|
|
||||||
/* under development */
|
/* under development */
|
||||||
int si5351_set_clk_phase(si5351_inst_t inst, uint8_t clk, uint32_t frequency, double phase, si5351_pll_t pll);
|
int si5351_set_clk_phase(si5351_inst_t inst, uint8_t clk, uint32_t frequency, double phase, si5351_pll_t pll);
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
#include <string.h> //strchr
|
#include <string.h> //strchr
|
||||||
#include <stdlib.h> //bsearch
|
#include <stdlib.h> //bsearch
|
||||||
#include "helper.h" //ltrim
|
#include "helper.h" //ltrim
|
||||||
#include "stm32_si5351.h"
|
#include "si5351.h"
|
||||||
|
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "at1_defines.h"
|
#include "at1_defines.h"
|
||||||
#include "stm32_si5351.h"
|
#include "si5351.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "ringbuf.h"
|
#include "ringbuf.h"
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @file stm32_si5351.c
|
* @file si5351.c
|
||||||
* @brief STM32 library/driver for the Si5351 clock chip
|
* @brief STM32 library/driver for the Si5351 clock chip
|
||||||
from Skyworks Solutions, Inc. (former SiLabs)
|
* from Skyworks Solutions, Inc. (former SiLabs)
|
||||||
******************************************************************************
|
*******************************************************************************
|
||||||
* @author: Thomas Kuschel KW4NZ
|
* @author: Thomas Kuschel KW4NZ
|
||||||
* created 2022-05-11
|
* created 2022-05-11
|
||||||
*
|
*
|
||||||
@ -16,11 +16,13 @@
|
|||||||
|
|
||||||
/* Defines for compilation ---------------------------------------------------*/
|
/* Defines for compilation ---------------------------------------------------*/
|
||||||
/* if you want to automatically enable the clk output after setting synthesis */
|
/* if you want to automatically enable the clk output after setting synthesis */
|
||||||
|
/* you can set the AUTOMATICALLY_ENALBE_OUTPUT to 1 (not recommended) */
|
||||||
#define AUTOMATICALLY_ENABLE_OUTPUT 0
|
#define AUTOMATICALLY_ENABLE_OUTPUT 0
|
||||||
/* enable some optimizing, usually set to 1 */
|
/* enable some optimizing, usually set to 1 */
|
||||||
#define OPTIMIZED 1
|
#define OPTIMIZED 1
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes -----------------------------------------------------------------*/
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -31,7 +33,8 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
/* including the HAL here */
|
/* including the HAL here */
|
||||||
#include "stm32l4xx_hal.h"
|
#include "stm32l4xx_hal.h"
|
||||||
/* Include the header file */
|
/* register map of the Si5351 */
|
||||||
|
#include "si5351_reg.h"
|
||||||
#include "si5351.h"
|
#include "si5351.h"
|
||||||
|
|
||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
@ -40,29 +43,29 @@
|
|||||||
*/
|
*/
|
||||||
typedef struct __SI5351_HandleTypeDef {
|
typedef struct __SI5351_HandleTypeDef {
|
||||||
void *i2c_handle; /*!< the I2C handle, must not be unique */
|
void *i2c_handle; /*!< the I2C handle, must not be unique */
|
||||||
struct __SI5351_HandleTypeDef *next; /*!< next pointer to the following structure when there are several instances */
|
struct __SI5351_HandleTypeDef *next; /*!< used for several instances */
|
||||||
uint32_t xtal_frequency; /*!< XTAL or CLKIN frequency */
|
uint32_t xtal_frequency; /*!< XTAL or CLKIN frequency */
|
||||||
#if SI5351_DEBUG
|
#if SI5351_DEBUG
|
||||||
char debug_msg[1000]; /*!< debugging messages for extensive tests of the Si5351 chip, not required */
|
char debug_msg[1000]; /*!< for debugging msgs, extensive tests, N/A */
|
||||||
#endif
|
#endif
|
||||||
uint8_t clk_is_pllb; /*!< assignment of PLLA or PLLB per CLK #, if bit set to 1 ...PLLB */
|
uint8_t clk_is_pllb; /*!< assignment of PLLA or PLLB per CLK #, if bit set to 1 ...PLLB */
|
||||||
uint8_t clk_is_disabled; /*!< assignment of Output Enable Control, app. Register 3 */
|
uint8_t clk_is_disabled; /*!< assignment of Output Enable Control, app. Register 3 */
|
||||||
uint8_t clk_has_phase_shift;/*!< assignment of an output with a phase shift offset */
|
uint8_t clk_has_phase_shift;/*!< assignment of an output with a phase shift offset */
|
||||||
uint8_t i2c_address; /*!< I2C address of the datasheet */
|
uint8_t i2c_address; /*!< I2C address of the datasheet */
|
||||||
uint8_t interrupt_status_mask; /*!< Reg 2: Interrupt Status Mask */
|
uint8_t interrupt_status_mask; /*!< Reg 2: Interrupt Status Mask */
|
||||||
uint8_t initialized :1; /*!< mark the driver initialized */
|
uint8_t initialized :1; /*!< mark the driver initialized */
|
||||||
uint8_t programmed :1; /*!< mark the chip is programmed */
|
uint8_t programmed :1; /*!< mark the chip is programmed */
|
||||||
} si5351_HandleTypeDef;
|
} si5351_HandleTypeDef;
|
||||||
|
|
||||||
/* @brief SI5351 synthesis settings */
|
/* @brief SI5351 synthesis settings */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t pll_multiplier; /*!< in datasheet this value corresponds to feedback multisynth (N) a */
|
uint32_t pll_multiplier; /*!< corresponds to feedback multisynth (N) a */
|
||||||
uint32_t pll_numerator; /*!< in datasheet this value corresponds to feedback multisynth (N) b */
|
uint32_t pll_numerator; /*!< corresponds to feedback multisynth (N) b */
|
||||||
uint32_t pll_denominator; /*!< in datasheet this value corresponds to feedback multisynth (N) c */
|
uint32_t pll_denominator; /*!< corresponds to feedback multisynth (N) c */
|
||||||
uint32_t out_multiplier; /*!< in datasheet this value corresponds to multisynth (M) a */
|
uint32_t out_multiplier; /*!< corresponds to multisynth (M) a */
|
||||||
uint32_t out_numerator; /*!< in datasheet this value corresponds to multisynth (M) b */
|
uint32_t out_numerator; /*!< corresponds to multisynth (M) b */
|
||||||
uint32_t out_denominator; /*!< in datasheet this value corresponds to multisynth (M) c */
|
uint32_t out_denominator; /*!< corresponds to multisynth (M) c */
|
||||||
uint8_t out_r_divider; /*!< R divider, log2 value bit set to 1; 2,4,8,...,128; for frequencies < 500 kHz, otherwise set to 1 i.e. bit 0 */
|
uint8_t out_r_divider; /*!< R divider, log2 value bit set to 1; 2,4,8,...,128; for frequencies < 500 kHz, otherwise set to 1 i.e. bit 0 */
|
||||||
} synthesis_t;
|
} synthesis_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -108,32 +111,33 @@ typedef struct {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Private variables ---------------------------------------------------------*/
|
/* Private variables ---------------------------------------------------------*/
|
||||||
si5351_HandleTypeDef *first_handle = NULL; /* pointer to the first instance */
|
si5351_HandleTypeDef *first_handle = NULL; /* pointer to the first instance */
|
||||||
int si5351_errno = 0; /* error_number for functions with return == NULL */
|
int si5351_errno = 0; /* error_number for functions with return == NULL */
|
||||||
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
int __fprintb(FILE *stream, void *value, size_t size);
|
int __fprintb(FILE *stream, void *value, size_t size);
|
||||||
#endif
|
#endif
|
||||||
int calculation(uint32_t frequency, uint32_t xtal, synthesis_t *synth);
|
static int si5351_set_synthesis(si5351_inst_t inst, synthesis_t *synth, uint8_t clk);
|
||||||
int si5351_set_pll(si5351_inst_t inst, synthesis_t *synth);
|
static int si5351_program(si5351_inst_t inst);
|
||||||
int si5351_set_output(si5351_inst_t inst, synthesis_t *synth);
|
static int si5351_error_status_i2c(HAL_StatusTypeDef status);
|
||||||
int si5351_set_synthesis(si5351_inst_t inst, synthesis_t *synth, uint8_t clk);
|
static int si5351_read(si5351_inst_t inst, uint8_t regaddr, uint8_t *data, uint16_t size);
|
||||||
|
static int si5351_write(si5351_inst_t inst, uint8_t regaddr, uint8_t *data, uint16_t size);
|
||||||
|
static int band_select(uint32_t frequency, band_t *band);
|
||||||
|
static int calculation(uint32_t frequency, uint32_t xtal, synthesis_t *synth);
|
||||||
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
/** Wrapper functions for receiving/transceiving bytes from I2C bus (HAL function set)
|
/** Wrapper functions for receiving/transceiving bytes from I2C bus
|
||||||
|
* (HAL function set)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** @brief Give better error numbers based on the Linux error_no.h
|
/** @brief Give better error numbers based on the Linux error_no.h
|
||||||
* @param i2c_handle the handle of the I2C bus from HAL function, e.g. hi2c1
|
* @param status based on HAL library in HAL_StatusTypeDef
|
||||||
* @param xtal_frequency either the XTAL frequency (25/27 MHz) or CLock-In
|
* @return error number see si5351_errno
|
||||||
* from 10 MHz to 100 MHz entered in Hz
|
|
||||||
* @param i2c_address I2C bus address of the device from datasheet typically 0x60 (or 0x61)
|
|
||||||
* @param datasize reserve an extra area of data space in bytes, access with function si5351_read_data() and si5351_write_data()
|
|
||||||
* @return si5351_handle Pointer to the si5351 handle, NULL if error, see si5351_errno
|
|
||||||
*/
|
*/
|
||||||
static int si5351_error_status_i2c(HAL_StatusTypeDef status) {
|
static int si5351_error_status_i2c(HAL_StatusTypeDef status) {
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case HAL_TIMEOUT:
|
case HAL_TIMEOUT:
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
@ -150,32 +154,35 @@ static int si5351_error_status_i2c(HAL_StatusTypeDef status) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Read (blocking mode) one ore more data bytes from the I2C bus starting at the regaddr register address
|
/** @brief Read (blocking mode) one ore more data bytes from the I2C bus
|
||||||
* @param instance instance (handle) of the SI5351 driver
|
* starting at the regaddr register address
|
||||||
|
* @param inst instance (handle) of the SI5351 driver
|
||||||
* @param regaddr starting register address of the SI5351
|
* @param regaddr starting register address of the SI5351
|
||||||
* @param data pointer to the first byte of data
|
* @param data pointer to the first byte of data
|
||||||
* @param datasize datasize of the reading data, sizeof (data), when reading only one register (byte), set to 1
|
* @param datasize datasize of the reading data, sizeof (data),
|
||||||
|
* when reading only one register (byte), set to 1
|
||||||
* @return errno 0 on success, see si5351_errno_t
|
* @return errno 0 on success, see si5351_errno_t
|
||||||
* @retval -EINVAL when given a NULL handle
|
* @retval -EINVAL when given a NULL handle
|
||||||
* @retval -ETIMEDOUT when HAL_TIMEOUT
|
* @retval -ETIMEDOUT when HAL_TIMEOUT
|
||||||
* @retval -EIO when HAL_ERROR
|
* @retval -EIO when HAL_ERROR
|
||||||
* @retval -EBUSY when HAL_BUSY
|
* @retval -EBUSY when HAL_BUSY
|
||||||
* if applicable use interrupt controlled HAL functions
|
* if applicable use interrupt controlled HAL functions
|
||||||
*/
|
*/
|
||||||
int si5351_read(si5351_inst_t instance, uint8_t regaddr, uint8_t *data,
|
static int si5351_read(si5351_inst_t inst, uint8_t regaddr, uint8_t *data, uint16_t size) {
|
||||||
uint16_t size) {
|
|
||||||
|
|
||||||
HAL_StatusTypeDef status;
|
HAL_StatusTypeDef status;
|
||||||
status = HAL_I2C_Mem_Read(instance->i2c_handle, instance->i2c_address,
|
status = HAL_I2C_Mem_Read(inst->i2c_handle, inst->i2c_address,
|
||||||
(uint16_t) regaddr, I2C_MEMADD_SIZE_8BIT, data, size, 0xffff);
|
(uint16_t) regaddr, I2C_MEMADD_SIZE_8BIT, data, size, 0xffff);
|
||||||
return si5351_error_status_i2c(status);
|
return si5351_error_status_i2c(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Write (blocking mode) one ore more data bytes to the I2C bus starting at the regaddr register address
|
/** @brief Write (blocking mode) one ore more data bytes to the I2C bus
|
||||||
* @param instance instance (handle) of the SI5351 driver
|
* starting at the regaddr register address
|
||||||
|
* @param inst instance (handle) of the SI5351 driver
|
||||||
* @param regaddr starting register address of the SI5351
|
* @param regaddr starting register address of the SI5351
|
||||||
* @param data pointer to the first byte of data
|
* @param data pointer to the first byte of data
|
||||||
* @param datasize datasize of the writing data, sizeof (data), when writing to one register (byte), set to 1
|
* @param datasize datasize of the writing data, sizeof (data),
|
||||||
|
* when writing to one register (byte), set to 1
|
||||||
* @return errno 0 on success, see si5351_errno_t
|
* @return errno 0 on success, see si5351_errno_t
|
||||||
* @retval -EINVAL when given a NULL handle
|
* @retval -EINVAL when given a NULL handle
|
||||||
* @retval -ETIMEDOUT when HAL_TIMEOUT
|
* @retval -ETIMEDOUT when HAL_TIMEOUT
|
||||||
@ -183,11 +190,10 @@ int si5351_read(si5351_inst_t instance, uint8_t regaddr, uint8_t *data,
|
|||||||
* @retval -EBUSY when HAL_BUSY
|
* @retval -EBUSY when HAL_BUSY
|
||||||
* if applicable use interrupt controlled HAL functions
|
* if applicable use interrupt controlled HAL functions
|
||||||
*/
|
*/
|
||||||
int si5351_write(si5351_inst_t instance, uint8_t regaddr, uint8_t *data,
|
static int si5351_write(si5351_inst_t inst, uint8_t regaddr, uint8_t *data, uint16_t size) {
|
||||||
uint16_t size) {
|
|
||||||
|
|
||||||
HAL_StatusTypeDef status;
|
HAL_StatusTypeDef status;
|
||||||
status = HAL_I2C_Mem_Write(instance->i2c_handle, instance->i2c_address,
|
status = HAL_I2C_Mem_Write(inst->i2c_handle, inst->i2c_address,
|
||||||
(uint16_t) regaddr, I2C_MEMADD_SIZE_8BIT, data, size, 0xffff);
|
(uint16_t) regaddr, I2C_MEMADD_SIZE_8BIT, data, size, 0xffff);
|
||||||
return si5351_error_status_i2c(status);
|
return si5351_error_status_i2c(status);
|
||||||
}
|
}
|
||||||
@ -336,7 +342,7 @@ int si5351_deinitialize(void) {
|
|||||||
* @retval -EIO when HAL_ERROR
|
* @retval -EIO when HAL_ERROR
|
||||||
* @retval -EBUSY when HAL_BUSY
|
* @retval -EBUSY when HAL_BUSY
|
||||||
*/
|
*/
|
||||||
int si5351_program(si5351_inst_t inst) {
|
static int si5351_program(si5351_inst_t inst) {
|
||||||
|
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
@ -388,8 +394,12 @@ int si5351_program(si5351_inst_t inst) {
|
|||||||
status = si5351_read(inst, SI5351_FANOUT_ENABLE, &data, 1);
|
status = si5351_read(inst, SI5351_FANOUT_ENABLE, &data, 1);
|
||||||
if (status)
|
if (status)
|
||||||
break;
|
break;
|
||||||
cx += snprintf(inst->debug_msg + cx, sizeof(inst->debug_msg) - (size_t)cx, "(%d) FANOUT_ENABLE 0x%x\n", cx, data);
|
cx += snprintf(inst->debug_msg + cx,
|
||||||
cx += snprintf(inst->debug_msg + cx, sizeof(inst->debug_msg) - (size_t)cx, "(%d) FANOUT_ENABLE %d\n", cx, data);
|
sizeof(inst->debug_msg) - (size_t)cx,
|
||||||
|
"(%d) FANOUT_ENABLE 0x%x\n", cx, data);
|
||||||
|
cx += snprintf(inst->debug_msg + cx,
|
||||||
|
sizeof(inst->debug_msg) - (size_t)cx,
|
||||||
|
"(%d) FANOUT_ENABLE %d\n", cx, data);
|
||||||
#endif
|
#endif
|
||||||
data = SI5351_CLKIN_FANOUT_EN | SI5351_XO_FANOUT_EN
|
data = SI5351_CLKIN_FANOUT_EN | SI5351_XO_FANOUT_EN
|
||||||
| SI5351_MS_FANOUT_EN; // set them to 1b
|
| SI5351_MS_FANOUT_EN; // set them to 1b
|
||||||
@ -400,8 +410,12 @@ int si5351_program(si5351_inst_t inst) {
|
|||||||
status = si5351_read(inst, SI5351_FANOUT_ENABLE, &data, 1);
|
status = si5351_read(inst, SI5351_FANOUT_ENABLE, &data, 1);
|
||||||
if (status)
|
if (status)
|
||||||
break;
|
break;
|
||||||
cx += snprintf(inst->debug_msg + cx, sizeof(inst->debug_msg) - (size_t)cx, "(%d) FANOUT_ENABLE 0x%x\n", cx, data);
|
cx += snprintf(inst->debug_msg + cx,
|
||||||
cx += snprintf(inst->debug_msg + cx, sizeof(inst->debug_msg) - (size_t)cx, "(%d) FANOUT_ENABLE %d\n", cx, data);
|
sizeof(inst->debug_msg) - (size_t)cx,
|
||||||
|
"(%d) FANOUT_ENABLE 0x%x\n", cx, data);
|
||||||
|
cx += snprintf(inst->debug_msg + cx,
|
||||||
|
sizeof(inst->debug_msg) - (size_t)cx,
|
||||||
|
"(%d) FANOUT_ENABLE %d\n", cx, data);
|
||||||
#endif
|
#endif
|
||||||
/* Crystal Internal Load Capacitance */
|
/* Crystal Internal Load Capacitance */
|
||||||
|
|
||||||
@ -410,7 +424,9 @@ int si5351_program(si5351_inst_t inst) {
|
|||||||
status = si5351_write(inst, SI5351_CRYSTAL_INTERNAL_LOAD_CAPACITANCE, &data, 1);
|
status = si5351_write(inst, SI5351_CRYSTAL_INTERNAL_LOAD_CAPACITANCE, &data, 1);
|
||||||
if (status)
|
if (status)
|
||||||
break;
|
break;
|
||||||
cx += snprintf(inst->debug_msg + cx, sizeof(inst->debug_msg) - (size_t)cx, "(%d) XTAL int. Load Cap: 0x%x (%dd)\n", cx, data, data);
|
cx += snprintf(inst->debug_msg + cx,
|
||||||
|
sizeof(inst->debug_msg) - (size_t)cx,
|
||||||
|
"(%d) XTAL int. Load Cap: 0x%x (%dd)\n", cx, data, data);
|
||||||
#endif
|
#endif
|
||||||
inst->programmed = 1; /* the device is programmed */
|
inst->programmed = 1; /* the device is programmed */
|
||||||
} while (0);
|
} while (0);
|
||||||
@ -419,24 +435,31 @@ int si5351_program(si5351_inst_t inst) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Select the right band to calculate even divisors for the output
|
/** @brief Select the right band to calculate even divisors for the output
|
||||||
* @param frequency
|
* @param frequency
|
||||||
* @param band pointer of band_t return parameters as a structure min, max, divisor for each band
|
* @param band pointer of band_t return parameters as a structure min,
|
||||||
|
* max, divisor for each band
|
||||||
* @return 1 on success, when a frequency band is found
|
* @return 1 on success, when a frequency band is found
|
||||||
* @retval 0 when frequency not found
|
* @retval 0 when frequency not found
|
||||||
*/
|
*/
|
||||||
int band_select(uint32_t frequency, band_t *band) {
|
static int band_select(uint32_t frequency, band_t *band) {
|
||||||
|
|
||||||
static const band_t sband[] = { /* band in meters, frequ_lo, frequ_hi, multiplier, divider_bit */
|
static const band_t sband[] = { /* band in meters, frequ_lo, frequ_hi, multiplier, divider_bit */
|
||||||
{ "80", 3000000, 4500000, 200, 0 }, { "40", 5625000, 7500000, 120, 0 }, {
|
{ "80", 3000000, 4500000, 200, 0 },
|
||||||
"30", 7500000, 11250000, 80, 0 },
|
{ "40", 5625000, 7500000, 120, 0 },
|
||||||
{ "20", 11250000, 15000000, 60, 0 }, { "15", 15000000, 22500000, 40,
|
{ "30", 7500000, 11250000, 80, 0 },
|
||||||
0 }, { "10", 22500000, 32142000, 28, 0 }, { "8", 32142000,
|
{ "20", 11250000, 15000000, 60, 0 },
|
||||||
45000000, 20, 0 }, { "6", 45000000, 64285000, 14, 0 }, {
|
{ "15", 15000000, 22500000, 40, 0 },
|
||||||
"4", 64285000, 76000000, 10, 0 }, { "3", 76000000, 11250000,
|
{ "10", 22500000, 32142000, 28, 0 },
|
||||||
8, 0 }, { "2", 11250000, 15000000, 6, 0 }, { "180", 1500000,
|
{ "8", 32142000, 45000000, 20, 0 },
|
||||||
2250000, 400, 0 }, { "120", 2250000, 3000000, 300, 0 }, {
|
{ "6", 45000000, 64285000, 14, 0 },
|
||||||
"60", 4500000, 5625000, 160, 0 }, };
|
{ "4", 64285000, 76000000, 10, 0 },
|
||||||
|
{ "3", 76000000, 11250000, 8, 0 },
|
||||||
|
{ "2", 11250000, 15000000, 6, 0 },
|
||||||
|
{"180", 1500000, 2250000, 400, 0 },
|
||||||
|
{"120", 2250000, 3000000, 300, 0 },
|
||||||
|
{ "60", 4500000, 5625000, 160, 0 },
|
||||||
|
};
|
||||||
|
/* possibly this could be improved with a bsearch algorithm: */
|
||||||
for (uint32_t i = 0; i < (sizeof(sband) / sizeof(sband[0])); i++) {
|
for (uint32_t i = 0; i < (sizeof(sband) / sizeof(sband[0])); i++) {
|
||||||
if (frequency > sband[i].qrg_min && frequency <= sband[i].qrg_max) {
|
if (frequency > sband[i].qrg_min && frequency <= sband[i].qrg_max) {
|
||||||
memcpy(band, &sband[i], sizeof(*band));
|
memcpy(band, &sband[i], sizeof(*band));
|
||||||
@ -452,7 +475,7 @@ int band_select(uint32_t frequency, band_t *band) {
|
|||||||
* @param synth pointer to a structure snythesis_t will be set with the calculated values
|
* @param synth pointer to a structure snythesis_t will be set with the calculated values
|
||||||
* @return 0 on success
|
* @return 0 on success
|
||||||
*/
|
*/
|
||||||
int calculation(uint32_t frequency, uint32_t xtal, synthesis_t *synth) {
|
static int calculation(uint32_t frequency, uint32_t xtal, synthesis_t *synth) {
|
||||||
|
|
||||||
uint32_t t;
|
uint32_t t;
|
||||||
band_t band;
|
band_t band;
|
||||||
@ -689,7 +712,7 @@ int si5351_set_clk_phase(si5351_inst_t inst, uint8_t clk, uint32_t frequency,
|
|||||||
* @retval -EIO when HAL_ERROR
|
* @retval -EIO when HAL_ERROR
|
||||||
* @retval -EBUSY when HAL_BUSY
|
* @retval -EBUSY when HAL_BUSY
|
||||||
*/
|
*/
|
||||||
int si5351_reset_pll(si5351_inst_t inst, uint8_t clk) {
|
static int si5351_reset_pll(si5351_inst_t inst, uint8_t clk) {
|
||||||
|
|
||||||
/* internal function, no need to check inst nor clk */
|
/* internal function, no need to check inst nor clk */
|
||||||
|
|
||||||
@ -707,8 +730,8 @@ int si5351_reset_pll(si5351_inst_t inst, uint8_t clk) {
|
|||||||
|
|
||||||
/** @brief Sets the CLK_x output phase of the si5351 (direct access to register)
|
/** @brief Sets the CLK_x output phase of the si5351 (direct access to register)
|
||||||
* @param si5351_instance Given si5351 device handle
|
* @param si5351_instance Given si5351 device handle
|
||||||
* @param phase in uint8_t type value
|
|
||||||
* @param clk The CLK ouput to drive and disable 0...CLK0, 1...CLK1, 2...CLK2, ...
|
* @param clk The CLK ouput to drive and disable 0...CLK0, 1...CLK1, 2...CLK2, ...
|
||||||
|
* @param phase in uint8_t type value
|
||||||
* @return 0 on success
|
* @return 0 on success
|
||||||
* @retval -EINVAL when given a NULL handle
|
* @retval -EINVAL when given a NULL handle
|
||||||
* @retval -ETIMEDOUT when HAL_TIMEOUT
|
* @retval -ETIMEDOUT when HAL_TIMEOUT
|
||||||
@ -743,7 +766,7 @@ int si5351_set_phase(si5351_inst_t inst, uint8_t clk, uint8_t phase) {
|
|||||||
* @retval -EIO when HAL_ERROR
|
* @retval -EIO when HAL_ERROR
|
||||||
* @retval -EBUSY when HAL_BUSY
|
* @retval -EBUSY when HAL_BUSY
|
||||||
*/
|
*/
|
||||||
int si5351_set_synthesis(si5351_inst_t inst, synthesis_t *synth, uint8_t clk) {
|
static int si5351_set_synthesis(si5351_inst_t inst, synthesis_t *synth, uint8_t clk) {
|
||||||
|
|
||||||
uint32_t MSNx_P1, MSNx_P2, MSNx_P3;
|
uint32_t MSNx_P1, MSNx_P2, MSNx_P3;
|
||||||
uint32_t MSx_P1, MSx_P2, MSx_P3;
|
uint32_t MSx_P1, MSx_P2, MSx_P3;
|
||||||
|
@ -511,4 +511,4 @@ VP_RTC_VS_RTC_Calendar.Signal=RTC_VS_RTC_Calendar
|
|||||||
VP_SYS_VS_tim6.Mode=TIM6
|
VP_SYS_VS_tim6.Mode=TIM6
|
||||||
VP_SYS_VS_tim6.Signal=SYS_VS_tim6
|
VP_SYS_VS_tim6.Signal=SYS_VS_tim6
|
||||||
board=NUCLEO-L4A6ZG
|
board=NUCLEO-L4A6ZG
|
||||||
isbadioc=true
|
isbadioc=false
|
||||||
|
Loading…
Reference in New Issue
Block a user