CHG programming further investigation
This commit is contained in:
@ -145,6 +145,7 @@ int main(void)
|
||||
|
||||
status = si5351_program(instance_si5351[1]);
|
||||
printf("Device #1 gets status %d\n", status);
|
||||
printf("Debug:\n%s", si5351_read_debug_msg(instance_si5351[1]));
|
||||
|
||||
for (int i=2; i>=0; i--) {
|
||||
si5351_deinit(instance_si5351[i]);
|
||||
@ -178,7 +179,7 @@ int main(void)
|
||||
terminalTaskHandle = osThreadNew(start_terminal_task, NULL, &terminalTask_attributes);
|
||||
|
||||
/* creation of idTask */
|
||||
idTaskHandle = osThreadNew(start_id_task, NULL, &idTask_attributes);
|
||||
// idTaskHandle = osThreadNew(start_id_task, NULL, &idTask_attributes);
|
||||
|
||||
/* USER CODE BEGIN RTOS_THREADS */
|
||||
/* add threads, ... */
|
||||
|
@ -10,14 +10,21 @@
|
||||
* adapted, idea and much information from Petr Polasek, created Feb 16, 2018
|
||||
******************************************************************************/
|
||||
|
||||
/* Defines for compilation ---------------------------------------------------*/
|
||||
#define DEBUG 1
|
||||
#define OPTIMIZED 1
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include <stdlib.h>
|
||||
// @TODO try to get rid off including the HAL here, using pointer to the specified functions
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
#include "stm32_si5351.h"
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
#define SI5351_VERSION 1
|
||||
|
||||
/* @brief Si5351 handle structure definition
|
||||
*/
|
||||
@ -26,12 +33,15 @@ typedef struct __SI5351_HandleTypeDef {
|
||||
uint32_t xtal_frequency; /*!< XTAL or CLKIN frequency */
|
||||
int si5351_num;
|
||||
struct __SI5351_HandleTypeDef *next;
|
||||
char debug_msg[1000];
|
||||
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 */
|
||||
} si5351_HandleTypeDef;
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
#define SI5351_VERSION 1
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
si5351_HandleTypeDef * first_handle = NULL; /* pointer to the first instancee */
|
||||
@ -111,6 +121,9 @@ si5351_HandleTypeDef *si5351_init(void * i2c_handle, uint32_t xtal_frequency, ui
|
||||
si5351_handle->i2c_handle = i2c_handle;
|
||||
si5351_handle->i2c_address = i2c_address;
|
||||
si5351_handle->xtal_frequency = xtal_frequency;
|
||||
/* disable all interrupts (Si5351C only) */
|
||||
si5351_handle->interrupt_status_mask = SI5351_SYS_INIT_MASK | SI5351_LOL_B_MASK |
|
||||
SI5351_LOL_A_MASK | SI5351_LOS_CLKIN_MASK | SI5351_LOS_XTAL_MASK;
|
||||
si5351_handle->initialized = 1;
|
||||
return si5351_handle;
|
||||
}
|
||||
@ -151,10 +164,11 @@ int si5351_deinit(si5351_HandleTypeDef * si5351_handle) {
|
||||
|
||||
/** @brief Check if there is any I2C device ready on the bus
|
||||
* @param si5351_instance Given si5351 device handle
|
||||
* @return 0 on success (HAL_StatusTypeDef)
|
||||
* @retval HAL_ERROR = 0x01
|
||||
* @retval HAL_BUSY = 0x02
|
||||
* @retval HAL_TIMEOUT = 0x03
|
||||
* @return 0 on success
|
||||
* @retval -EINVAL when given a NULL handle
|
||||
* @retval -ETIMEDOUT when HAL_TIMEOUT
|
||||
* @retval -EIO when HAL_ERROR
|
||||
* @retval -EBUSY when HAL_BUSY
|
||||
*/
|
||||
int si5351_isready(si5351_inst_t inst) {
|
||||
|
||||
@ -169,10 +183,20 @@ int si5351_isready(si5351_inst_t inst) {
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Program the si5351 with the already set values according to Figure 10 of the datasheet
|
||||
* @param si5351_instance Given si5351 device handle
|
||||
* @return 0 on success
|
||||
* @retval -EINVAL when given a NULL handle
|
||||
* @retval -ETIMEDOUT when HAL_TIMEOUT
|
||||
* @retval -EIO when HAL_ERROR
|
||||
* @retval -EBUSY when HAL_BUSY
|
||||
*/
|
||||
int si5351_program(si5351_inst_t inst) {
|
||||
|
||||
uint8_t data;
|
||||
int status = 0;
|
||||
int cx = 0;
|
||||
|
||||
if(!inst)
|
||||
return -EINVAL;
|
||||
@ -184,29 +208,82 @@ int si5351_program(si5351_inst_t inst) {
|
||||
|
||||
} while(data & SI5351_SYS_INIT);
|
||||
|
||||
/* Disable Outputs Set CLKx_DIS high, Reg. 3 = 0xFF */
|
||||
data = 0xff;
|
||||
status = si5351_write(inst, SI5351_OUTPUT_ENABLE_CONTROL, &data, 1);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
/* power down all output drivers reg 16 -- 23 */
|
||||
data = 0x80;
|
||||
for(int i = SI5351_CLK0_CONTROL; i <= SI5351_CLK7_CONTROL; i++) {
|
||||
status = si5351_write(inst, i, &data, 1);
|
||||
do {
|
||||
/* Disable Outputs Set CLKx_DIS high, Reg. 3 = 0xFF */
|
||||
data = SI5351_CLK7_OEB | SI5351_CLK6_OEB | SI5351_CLK5_OEB | SI5351_CLK4_OEB |
|
||||
SI5351_CLK3_OEB | SI5351_CLK2_OEB | SI5351_CLK1_OEB | SI5351_CLK0_OEB;
|
||||
status = si5351_write(inst, SI5351_OUTPUT_ENABLE_CONTROL, &data, 1);
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
|
||||
/* power down all output drivers reg 16 -- 23 */
|
||||
data = SI5351_CLKx_PDN; // 0x80
|
||||
#if OPTIMIZED
|
||||
status = si5351_write(inst, SI5351_CLK0_CONTROL, &data, SI5351_NUMBER_OF_OUTPUTS);
|
||||
if (status)
|
||||
break;
|
||||
#else
|
||||
for(int i = SI5351_CLK0_CONTROL; i <= SI5351_CLK7_CONTROL; i++) {
|
||||
status = si5351_write(inst, i, &data, 1);
|
||||
|
||||
if (status)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* set interrupt masks (see register 2 description) */
|
||||
status = si5351_write(inst, SI5351_INTERRUPT_STATUS_MASK, &inst->interrupt_status_mask, 1);
|
||||
if (status)
|
||||
break;
|
||||
|
||||
/* for debugging purpose, read out fanout enable register */
|
||||
#if DEBUG
|
||||
status = si5351_read(inst, SI5351_FANOUT_ENABLE, &data, 1);
|
||||
if (status)
|
||||
break;
|
||||
cx += snprintf(inst->debug_msg + cx, sizeof(inst->debug_msg) - cx, "(%d) FANOUT_ENABLE 0x%x\n", cx, data);
|
||||
cx += snprintf(inst->debug_msg + cx, sizeof(inst->debug_msg) - cx, "(%d) FANOUT_ENABLE %d\n", cx, data);
|
||||
#endif
|
||||
data = SI5351_CLKIN_FANOUT_EN | SI5351_XO_FANOUT_EN | SI5351_MS_FANOUT_EN; // set them to 1b
|
||||
status = si5351_write(inst, SI5351_FANOUT_ENABLE, &data, 1);
|
||||
if (status)
|
||||
break;
|
||||
#if DEBUG
|
||||
status = si5351_read(inst, SI5351_FANOUT_ENABLE, &data, 1);
|
||||
if (status)
|
||||
break;
|
||||
cx += snprintf(inst->debug_msg + cx, sizeof(inst->debug_msg) - cx, "(%d) FANOUT_ENABLE 0x%x\n", cx, data);
|
||||
cx += snprintf(inst->debug_msg + cx, sizeof(inst->debug_msg) - cx, "(%d) FANOUT_ENABLE %d\n", cx, data);
|
||||
#endif
|
||||
|
||||
/* Crystal Internal Load Capacitance */
|
||||
|
||||
#if DEBUG
|
||||
status = si5351_read(inst, SI5351_CRYSTAL_INTERNAL_LOAD_CAPACITANCE, &data, 1);
|
||||
if (status)
|
||||
break;
|
||||
cx += snprintf(inst->debug_msg + cx, sizeof(inst->debug_msg) - cx, "(%d) XTAL int. Load Cap: 0x%x (%dd)\n", cx, data, data);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
} while(0);
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
char * si5351_read_debug_msg(si5351_inst_t inst) {
|
||||
|
||||
if (!inst)
|
||||
return NULL;
|
||||
|
||||
return inst->debug_msg;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
int Si5351_WriteRegister(Si5351_ConfigTypeDef *Si5351_ConfigStruct, uint8_t reg_address, uint8_t reg_data)
|
||||
{
|
||||
uint32_t error_wait;
|
||||
|
Reference in New Issue
Block a user