From 2ccc91e98d33dc5f6d169e7c5bff5e36262af8cf Mon Sep 17 00:00:00 2001 From: Benjamin Valentin Date: Tue, 29 Sep 2020 17:25:49 +0200 Subject: [PATCH] driver/at86rf215: add functions to set trim & clock output at run-time To calibrate the at86rf215 radio, trim value has to be set at run-time during board production. Add two helper functions to control the trim value and clock output register. --- drivers/at86rf215/at86rf215.c | 2 +- drivers/at86rf215/at86rf215_getset.c | 12 ++++++ drivers/include/at86rf215.h | 63 ++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/drivers/at86rf215/at86rf215.c b/drivers/at86rf215/at86rf215.c index b8c1cf84fb82..24a6ce091eab 100644 --- a/drivers/at86rf215/at86rf215.c +++ b/drivers/at86rf215/at86rf215.c @@ -125,7 +125,7 @@ if (!IS_ACTIVE(CONFIG_AT86RF215_USE_CLOCK_OUTPUT)){ } /* allow to configure board-specific trim */ #ifdef CONFIG_AT86RF215_TRIM_VAL - at86rf215_reg_write(dev, RG_RF_XOC, CONFIG_AT86RF215_TRIM_VAL | XOC_FS_MASK); + at86rf215_set_trim(dev, CONFIG_AT86RF215_TRIM_VAL); #endif /* enable TXFE & RXFE IRQ */ diff --git a/drivers/at86rf215/at86rf215_getset.c b/drivers/at86rf215/at86rf215_getset.c index 473139a72c9e..7a1f65f13a6e 100644 --- a/drivers/at86rf215/at86rf215_getset.c +++ b/drivers/at86rf215/at86rf215_getset.c @@ -89,6 +89,18 @@ uint8_t at86rf215_get_chan(const at86rf215_t *dev) return at86rf215_reg_read16(dev, dev->RF->RG_CNL); } +void at86rf215_set_trim(at86rf215_t *dev, uint8_t trim) +{ + assert(trim <= 0xF); + at86rf215_reg_write(dev, RG_RF_XOC, trim | XOC_FS_MASK); +} + +void at86rf215_set_clock_output(at86rf215_t *dev, + at86rf215_clko_cur_t cur, at86rf215_clko_freq_t freq) +{ + at86rf215_reg_write(dev, RG_RF_CLKO, cur | freq); +} + void at86rf215_set_chan(at86rf215_t *dev, uint16_t channel) { at86rf215_await_state_end(dev, RF_STATE_TX); diff --git a/drivers/include/at86rf215.h b/drivers/include/at86rf215.h index 022d23cdbac0..d9ef609a4db0 100644 --- a/drivers/include/at86rf215.h +++ b/drivers/include/at86rf215.h @@ -272,6 +272,33 @@ enum { AT86RF215_MODE_MR_FSK }; +/** + * @name Clock Output Driver Strength + * @{ + */ +typedef enum { + AT86RF215_CLKO_2mA = 0 << 3, /**< 2 mA */ + AT86RF215_CLKO_4mA = 1 << 3, /**< 4 mA */ + AT86RF215_CLKO_6mA = 2 << 3, /**< 6 mA */ + AT86RF215_CLKO_8mA = 3 << 3, /**< 8 mA */ +} at86rf215_clko_cur_t; +/** @} */ + +/** + * @name Clock Output Frequency + * @{ + */ +typedef enum { + AT86RF215_CLKO_OFF = 0, /**< Clock Output Disabled */ + AT86RF215_CLKO_26_MHz, /**< 26 MHz */ + AT86RF215_CLKO_32_MHz, /**< 32 MHz */ + AT86RF215_CLKO_16_MHz, /**< 16 MHz */ + AT86RF215_CLKO_8_MHz, /**< 8 MHz */ + AT86RF215_CLKO_4_MHz, /**< 4 MHz */ + AT86RF215_CLKO_2_MHz, /**< 2 MHz */ + AT86RF215_CLKO_1_MHz, /**< 1 MHz */ +} at86rf215_clko_freq_t; + /** * @name Internal device option flags * @{ @@ -526,6 +553,42 @@ int8_t at86rf215_get_ed_level(at86rf215_t *dev); */ void at86rf215_set_option(at86rf215_t *dev, uint16_t option, bool state); +/** + * @brief Set crystal oscillator trim value. + * + * An internal capacitance array is connected to the + * crystal oscillator pins TCXO and XTAL2. + * + * Each increment of the trim value adds 0.3pF capacitance + * to the oscillator circuit. + * + * To trim a board, enable the clock output with + * @ref at86rf215_set_clock_output and connect a frequency + * counter to the clock output pin. + * Then adjust the trim value until it the measured frequency + * closely matches the configured output frequency. + * + * It is recommended to use a 26 MHz output frequency for the + * test as this is the raw frequency of the external oscillator. + * + * The resulting trim value must then be stored in a persistent + * memory area of the board to be set via @ref CONFIG_AT86RF215_TRIM_VAL + * + * @param[in] dev device to configure + * @param[in] trim trim value + */ +void at86rf215_set_trim(at86rf215_t *dev, uint8_t trim); + +/** + * @brief Configure the Clock Output pin + * + * @param[in] dev device to configure + * @param[in] cur Clock output current + * @param[in] freq Clock output frequency + */ +void at86rf215_set_clock_output(at86rf215_t *dev, + at86rf215_clko_cur_t cur, at86rf215_clko_freq_t freq); + /** * @brief Convenience function for simply sending data *