ADD read and write wrapper function for i2c bus, start programming
procedure for si5351
This commit is contained in:
parent
8f5cdc1f54
commit
acc0f0a5da
@ -81,7 +81,7 @@ extern "C" {
|
|||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stm32_si5351_reg.h> /* register map of the Si5351 */
|
||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
/* Exported types ------------------------------------------------------------*/
|
||||||
@ -89,14 +89,17 @@ extern "C" {
|
|||||||
typedef struct __SI5351_HandleTypeDef *si5351_inst_t;
|
typedef struct __SI5351_HandleTypeDef *si5351_inst_t;
|
||||||
|
|
||||||
/* Exported constants --------------------------------------------------------*/
|
/* Exported constants --------------------------------------------------------*/
|
||||||
/** @enum errno_t Error Number Constants
|
/** @enum errno_t Error Number Constants, @TODO could also errno.h included!!
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EPERM = 1, /*!< Operation not permitted */
|
EPERM = 1, /*!< Operation not permitted */
|
||||||
|
EIO = 5, /*!< I/O error */
|
||||||
ENOMEM = 12, /*!< Out of memory */
|
ENOMEM = 12, /*!< Out of memory */
|
||||||
ENODEV = 19, /*!< No such device */
|
ENODEV = 19, /*!< No such device */
|
||||||
|
EBUSY = 16, /*!< Device or resource busy */
|
||||||
EINVAL = 22, /*!< Invalid argument */
|
EINVAL = 22, /*!< Invalid argument */
|
||||||
EADDRINUSE = 98 /*!< Address already in use */
|
EADDRINUSE = 98,/*!< Address already in use */
|
||||||
|
ETIMEDOUT = 116 /*!< Connection timed out */
|
||||||
} si5351_errno_t;
|
} si5351_errno_t;
|
||||||
|
|
||||||
/* Exported variables --------------------------------------------------------*/
|
/* Exported variables --------------------------------------------------------*/
|
||||||
@ -107,6 +110,7 @@ typedef enum {
|
|||||||
si5351_inst_t si5351_init(void * i2c_handle, uint32_t xtal_frequency, uint8_t i2c_address);
|
si5351_inst_t si5351_init(void * i2c_handle, uint32_t xtal_frequency, uint8_t i2c_address);
|
||||||
int si5351_deinit(si5351_inst_t si5351_handle);
|
int si5351_deinit(si5351_inst_t si5351_handle);
|
||||||
int si5351_isready(si5351_inst_t inst);
|
int si5351_isready(si5351_inst_t inst);
|
||||||
|
int si5351_program(si5351_inst_t inst);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
|
1081
Core/Inc/stm32_si5351_reg.h
Normal file
1081
Core/Inc/stm32_si5351_reg.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -101,7 +101,7 @@ void start_id_task(void *argument);
|
|||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
/* USER CODE BEGIN 1 */
|
/* USER CODE BEGIN 1 */
|
||||||
|
int status = 0;
|
||||||
/* USER CODE END 1 */
|
/* USER CODE END 1 */
|
||||||
|
|
||||||
/* MCU Configuration--------------------------------------------------------*/
|
/* MCU Configuration--------------------------------------------------------*/
|
||||||
@ -142,6 +142,10 @@ int main(void)
|
|||||||
printf("Device No. %d (Instance No: 0x%x) is %s\n", i, (unsigned int) instance_si5351[i], (ready==0) ? "ready" : "N/A");
|
printf("Device No. %d (Instance No: 0x%x) is %s\n", i, (unsigned int) instance_si5351[i], (ready==0) ? "ready" : "N/A");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status = si5351_program(instance_si5351[1]);
|
||||||
|
printf("Device #1 gets status %d\n", status);
|
||||||
|
|
||||||
for (int i=2; i>=0; i--) {
|
for (int i=2; i>=0; i--) {
|
||||||
si5351_deinit(instance_si5351[i]);
|
si5351_deinit(instance_si5351[i]);
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,12 @@
|
|||||||
*/
|
*/
|
||||||
typedef struct __SI5351_HandleTypeDef {
|
typedef struct __SI5351_HandleTypeDef {
|
||||||
void * i2c_handle;
|
void * i2c_handle;
|
||||||
|
uint32_t xtal_frequency; /*!< XTAL or CLKIN frequency */
|
||||||
uint32_t xtal_frequency;
|
|
||||||
int si5351_num;
|
int si5351_num;
|
||||||
struct __SI5351_HandleTypeDef *next;
|
struct __SI5351_HandleTypeDef *next;
|
||||||
uint8_t i2c_address;
|
uint8_t i2c_address; /*!< I2C address of the datasheet */
|
||||||
uint8_t initialized:1;
|
// uint8_t interrupt_status_mask; /*!< Reg 2: Interrupt Status Mask */
|
||||||
|
uint8_t initialized:1; /*!< mark the driver initialized */
|
||||||
} si5351_HandleTypeDef;
|
} si5351_HandleTypeDef;
|
||||||
|
|
||||||
/* Private define ------------------------------------------------------------*/
|
/* Private define ------------------------------------------------------------*/
|
||||||
@ -39,6 +39,34 @@ int si5351_errno = 0; /* error_number for functions whith return == NULL */
|
|||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
/* Private functions ---------------------------------------------------------*/
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* wrapper function for receiving bytes from I2C bus
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int si5351_error_status_i2c(HAL_StatusTypeDef status) {
|
||||||
|
switch (status) {
|
||||||
|
case HAL_TIMEOUT: return -ETIMEDOUT; break;
|
||||||
|
case HAL_ERROR: return -EIO; break;
|
||||||
|
case HAL_BUSY: return -EBUSY; break;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int si5351_read(si5351_inst_t instance, uint8_t regaddr, uint8_t *data, uint16_t size) {
|
||||||
|
|
||||||
|
HAL_StatusTypeDef status;
|
||||||
|
status = HAL_I2C_Mem_Read(instance->i2c_handle, instance->i2c_address<<1,
|
||||||
|
(uint16_t)regaddr, I2C_MEMADD_SIZE_8BIT, data, size, 0xffff);
|
||||||
|
return si5351_error_status_i2c(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
int si5351_write(si5351_inst_t instance, uint8_t regaddr, uint8_t *data, uint16_t size) {
|
||||||
|
|
||||||
|
HAL_StatusTypeDef status;
|
||||||
|
status = HAL_I2C_Mem_Write(instance->i2c_handle, instance->i2c_address<<1,
|
||||||
|
(uint16_t)regaddr, I2C_MEMADD_SIZE_8BIT, data, size, 0xffff);
|
||||||
|
return si5351_error_status_i2c(status);
|
||||||
|
}
|
||||||
|
|
||||||
/** @brief Initialize the device Si5351 with the main parameters
|
/** @brief Initialize the device Si5351 with the main parameters
|
||||||
* @param i2c_handle the handle of the I2C bus from HAL function, e.g. hi2c1
|
* @param i2c_handle the handle of the I2C bus from HAL function, e.g. hi2c1
|
||||||
* @param xtal_frequency either the XTAL frequency (25/27 MHz) or CLock-In
|
* @param xtal_frequency either the XTAL frequency (25/27 MHz) or CLock-In
|
||||||
@ -56,10 +84,6 @@ si5351_HandleTypeDef *si5351_init(void * i2c_handle, uint32_t xtal_frequency, ui
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAL_I2C_MODULE_ENABLED
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
si5351_handle = calloc(1, sizeof(*si5351_handle));
|
si5351_handle = calloc(1, sizeof(*si5351_handle));
|
||||||
if (si5351_handle == NULL) {
|
if (si5351_handle == NULL) {
|
||||||
si5351_errno = ENOMEM; // cannot allocate any memory
|
si5351_errno = ENOMEM; // cannot allocate any memory
|
||||||
@ -125,7 +149,7 @@ int si5351_deinit(si5351_HandleTypeDef * si5351_handle) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Check if there is the I2C device ready on the bus
|
/** @brief Check if there is any I2C device ready on the bus
|
||||||
* @param si5351_instance Given si5351 device handle
|
* @param si5351_instance Given si5351 device handle
|
||||||
* @return 0 on success (HAL_StatusTypeDef)
|
* @return 0 on success (HAL_StatusTypeDef)
|
||||||
* @retval HAL_ERROR = 0x01
|
* @retval HAL_ERROR = 0x01
|
||||||
@ -144,6 +168,42 @@ int si5351_isready(si5351_inst_t inst) {
|
|||||||
/* @TODO: create a pointer to that function for more flexiblity using other tools as HAL */
|
/* @TODO: create a pointer to that function for more flexiblity using other tools as HAL */
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int si5351_program(si5351_inst_t inst) {
|
||||||
|
|
||||||
|
uint8_t data;
|
||||||
|
int status = 0;
|
||||||
|
|
||||||
|
if(!inst)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
do {
|
||||||
|
status = si5351_read(inst, SI5351_DEVICE_STATUS, &data, 1);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
} 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);
|
||||||
|
if (status)
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user