| /** |
| * \addtogroup BSP |
| * \{ |
| * \addtogroup DEVICES |
| * \{ |
| * \addtogroup RF |
| * \{ |
| */ |
| |
| /** |
| ***************************************************************************************** |
| * |
| * @file |
| * |
| * @brief Radio module (RF) Low Level Driver API definition. |
| * |
| * Copyright (c) 2016, Dialog Semiconductor |
| * All rights reserved. |
| * Redistribution and use in source and binary forms, with or without modification, |
| * are permitted provided that the following conditions are met: |
| * 1. Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * 3. Neither the name of the copyright holder nor the names of its contributors |
| * may be used to endorse or promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
| * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
| * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, |
| * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
| * OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| * |
| ***************************************************************************************** |
| */ |
| |
| #if dg_configUSE_HW_RF |
| |
| |
| #include "hw_rf.h" |
| #include "sdk_defs.h" |
| #include "hw_cpm.h" |
| #include "hw_gpio.h" |
| |
| #if (dg_configSYSTEMVIEW) |
| # include "SEGGER_SYSVIEW_FreeRTOS.h" |
| #else |
| # define SEGGER_SYSTEMVIEW_ISR_ENTER() |
| # define SEGGER_SYSTEMVIEW_ISR_EXIT() |
| #endif |
| |
| #if dg_configUSE_HW_COEX == 1 |
| #include "hw_coex.h" |
| #endif |
| |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| #define KMODE_ALPHA_ACAD_PREF 0x0410 |
| #define KMODE_ALPHA_AA_PREF 0x0416 |
| |
| #define DF1_DAC_CHECK_VALUE 32 |
| #define DF1_DGAIN_THR0 16 |
| #define DF1_DGAIN_THR1 24 |
| #define DF1_DGAIN_THR2 32 |
| #endif |
| |
| /* User callbacks (defined as weak functions) definitions */ |
| bool hw_rf_preoff_cb(void) __attribute__((weak)); |
| void hw_rf_postconf_cb(void) __attribute__((weak)); |
| void hw_rf_precalib_cb(void) __attribute__((weak)); |
| void hw_rf_postcalib_cb(void) __attribute__((weak)); |
| void hw_rf_apply_tcs_cb(void) __attribute__((weak)); |
| uint64_t hw_rf_get_start_iff_time(void) __attribute__((weak)); |
| bool hw_rf_check_iff_timeout(uint64_t start_time) __attribute__((weak)); |
| |
| #if dg_configFEM == FEM_SKY66112_11 |
| #include "hw_fem_sky66112-11.h" |
| #endif |
| |
| typedef enum rf_states_e |
| { |
| RF_ST_OFF = 0, |
| RF_ST_ON, |
| RF_ST_CONFIG, |
| RF_ST_WAIT_NEXT1, |
| RF_ST_WAIT_NEXT2 |
| } rf_states_e; |
| |
| #if dg_configBLACK_ORCA_IC_REV != BLACK_ORCA_IC_REV_A |
| typedef enum |
| { |
| IFF_MODE_CTRL_BLE = 0, |
| IFF_MODE_CTRL_FTDF = 1, |
| IFF_MODE_CTRL_COMBO = 2 |
| } iff_mode_ctrl_e; |
| |
| typedef enum |
| { |
| IFF_MODE_OVR_BLE = 1, |
| IFF_MODE_OVR_FTDF = 2 |
| } iff_mode_ovr_e; |
| |
| typedef enum |
| { |
| MGC_MODE_CTRL_BLE_GAUSSDAC = 0, |
| MGC_MODE_CTRL_BLE_TXDAC = 1, |
| MGC_MODE_CTRL_FTDF = 2 |
| } mgc_mode_ctrl_e; |
| |
| #endif |
| |
| /** RF status bitmap. */ |
| typedef uint8_t rf_request_t; |
| |
| /** Indicates whether FTDF MAC has turned RF on. */ |
| #define RF_REQUEST_FTDF_ON (1 << 0) |
| |
| /** Indicates whether BLE MAC has turned RF on. */ |
| #define RF_REQUEST_BLE_ON (1 << 1) |
| |
| |
| |
| static rf_request_t rf_request __RETAINED; |
| static rf_states_e rf_state __RETAINED; |
| hw_rf_tx_power_luts_t rf_tx_power_luts __RETAINED; |
| |
| /* Variables used for holding previous reg values during gain calib */ |
| static uint32_t rf_cntrl_timer14_reg_set_offset; |
| static uint32_t rf_cntrl_timer_7_reg_value; |
| static uint32_t rf_cal_ctrl_reg_value; |
| static uint32_t rf_mgain_ctrl_reg_value; |
| static uint32_t rf_mgain_ctrl2_reg_value; |
| static uint16_t rf_synth_ctrl2_ble_reg_value; |
| static uint16_t rf_synth_ctrl2_ftdf_reg_value; |
| |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| static uint8_t kmoda_cal __RETAINED; |
| __RETAINED_RW static uint32_t gg_cal_modified = 128; |
| static uint32_t rf_enable_config14_ble_reg_value; |
| static uint32_t rf_enable_config15_ble_reg_value; |
| static uint32_t rf_enable_config14_ftdf_reg_value; |
| static uint32_t rf_enable_config15_ftdf_reg_value; |
| static uint16_t rf_bmcw_reg_value; |
| static uint16_t rf_vcocal_ctrl_reg_value; |
| #else |
| static uint16_t rf_enable_config14_reg_value; |
| static uint16_t rf_enable_config15_reg_value; |
| static uint16_t rf_overrule_reg_value; |
| static uint16_t rf_enable_config23_ble_reg_value; |
| static uint16_t rf_enable_config23_ftdf_reg_value; |
| static uint16_t rf_enable_config45_ble_reg_value; |
| static uint16_t rf_enable_config45_ftdf_reg_value; |
| #endif |
| bool hw_rf_system_init(void) |
| { |
| bool calib_succeeded; |
| |
| rf_state = RF_ST_OFF; |
| rf_request = 0; |
| |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| |
| /* Initially set kmoda_cal to its preferred settings value */ |
| if ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) |
| || ((dg_configUSE_AUTO_CHIP_DETECTION == 1) |
| && (CHIP_IS_AE))) |
| { |
| kmoda_cal = KMODE_ALPHA_ACAD_PREF & REG_MSK(PLLDIG, RF_KMOD_ALPHA_REG, |
| KMOD_ALPHA_BLE); |
| } |
| |
| #endif |
| |
| #if dg_configCOEX_ENABLE_CONFIG == 1 |
| hw_coex_init(); |
| #endif |
| /* Apply tcs and preferred settings */ |
| hw_rf_apply_tcs_cb(); |
| hw_rf_set_recommended_settings(); |
| |
| /* Perform calibration */ |
| calib_succeeded = hw_rf_calibration(); |
| |
| #ifndef CONFIG_USE_BLE |
| /* Force disable the ble, making the ftdf the only requester */ |
| REG_SET_BIT(CRG_TOP, FORCE_SLEEP_REG, FORCE_BLE_SLEEP); |
| #endif |
| #ifndef CONFIG_USE_FTDF |
| /* Force disable the ftdf, making the ble the only requester */ |
| REG_SET_BIT(CRG_TOP, FORCE_SLEEP_REG, FORCE_FTDF_SLEEP); |
| #endif |
| |
| /* System is ready to be used */ |
| return calib_succeeded; |
| } |
| |
| /** |
| * \brief Preferred settings 680 radio |
| * |
| */ |
| void hw_rf_set_recommended_settings(void) |
| { |
| |
| // Preferred Settings File for DCTMON |
| // Device : DA14680AA |
| // Package : All packages, no dependency on package. |
| // Last change date : June 18, 2015 - 18:00:48 |
| // Last change item : Register: RF_KMOD_ALPHA_REG, Field: KMOD_ALPHA_FTDF, Value: 0x10 |
| // File date : June 18, 2015 - 19:16:16 |
| |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| if (((dg_configUSE_AUTO_CHIP_DETECTION == 1) && (CHIP_IS_AE)) |
| || (BLACK_ORCA_TARGET_IC == BLACK_ORCA_IC_VERSION(A, E))) |
| { |
| REG_SET_MASKED(DEM, RF_AFC_CTRL_REG, 0x0030, 0x00F5); |
| REG_SET_MASKED(DEM, RF_AGC_CTRL2_REG, 0x003F, 0x0049); |
| |
| // MP |
| REG_SET_MASKED(DEM, RF_AGC_CTRL1_REG, 0x007F, 0x950A); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_10_REG, 0xFF00, 0x182E); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_11_REG, 0xFF00, 0x1830); |
| RFCU_POWER->RF_CNTRL_TIMER_12_REG = 0x3C; |
| RFCU_POWER->RF_CNTRL_TIMER_13_REG = 0x163C; |
| RFCU_POWER->RF_CNTRL_TIMER_15_REG = 0x183C; |
| RFCU_POWER->RF_CNTRL_TIMER_16_REG = 0x2207; |
| RFCU_POWER->RF_CNTRL_TIMER_17_REG = 0x410; |
| RFCU_POWER->RF_CNTRL_TIMER_18_REG = 0x218; |
| RFCU_POWER->RF_CNTRL_TIMER_19_REG = 0x218; |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_1_REG, 0xFF00, 0x1E00); |
| RFCU_POWER->RF_CNTRL_TIMER_20_REG = 0x508; |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_21_REG, 0x00FF, 0x44); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_22_REG, 0x00FF, 0x40); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_23_REG, 0x00FF, 0x52); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_2_REG, 0xFF00, 0x1B08); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_3_REG, 0xFF00, 0x1A10); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_5_REG, 0xFF00, 0x1818); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_7_REG, 0xFF00, 0x1818); |
| REG_SET_MASKED(RFCU, RF_CP_CTRL_BLE_REG, 0x0F0F, 0x7575); |
| REG_SET_MASKED(RFCU, RF_CP_CTRL_FTDF_REG, 0x0F0F, 0x7575); |
| REG_SET_MASKED(DEM, RF_DC_OFFSET_CTRL2_REG, 0x0202, 0x01D0); |
| REG_SET_MASKED(DEM, RF_DC_OFFSET_CTRL3_REG, 0x00FF, 0xDCE4); |
| REG_SET_MASKED(RFCU, RF_DIV_IQ_TX_REG, 0x00FF, 0x00A1); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG11_BLE_REG, 0x001F, 0x0054); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG11_FTDF_REG, 0x001F, 0x0054); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG12_BLE_REG, 0x001F, 0x0071); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG12_FTDF_REG, 0x001F, 0x0071); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG15_BLE_REG, 0x03E0, 0x01E0); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG15_FTDF_REG, 0x03E0, 0x01E0); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG19_BLE_REG, 0x001F, 0x0054); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG19_FTDF_REG, 0x001F, 0x0054); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG20_BLE_REG, 0x001F, 0x0071); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG20_FTDF_REG, 0x001F, 0x0071); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG21_BLE_REG, 0x001F, 0x0071); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG21_FTDF_REG, 0x001F, 0x0071); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG22_BLE_REG, 0x001F, 0x0071); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG22_FTDF_REG, 0x001F, 0x0071); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG24_FTDF_REG, 0x03E0, 0x01A0); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG25_FTDF_REG, 0x03E0, 0x0060); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG27_BLE_REG, 0x001F, 0x0071); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG27_FTDF_REG, 0x001F, 0x0071); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG28_BLE_REG, 0x001F, 0x00B2); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG28_FTDF_REG, 0x001F, 0x00B2); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG29_BLE_REG, 0x001F, 0x00B2); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG29_FTDF_REG, 0x001F, 0x00B2); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG33_BLE_REG, 0x001F, 0x0071); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG33_FTDF_REG, 0x001F, 0x0071); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG34_BLE_REG, 0x001F, 0x00F3); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG34_FTDF_REG, 0x001F, 0x00F3); |
| RFCU_POWER->RF_ENABLE_CONFIG42_BLE_REG = 0x210; |
| RFCU_POWER->RF_ENABLE_CONFIG42_FTDF_REG = 0x210; |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG46_BLE_REG, 0x001F, 0x0015); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG46_FTDF_REG, 0x001F, 0x0015); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG47_BLE_REG, 0x001F, 0x0016); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG47_FTDF_REG, 0x001F, 0x0016); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG48_BLE_REG, 0x001F, 0x0017); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG48_FTDF_REG, 0x001F, 0x0017); |
| REG_SET_MASKED(DEM, RF_FTDF_CTRL1_REG, 0xC000, 0x87C0); |
| REG_SET_MASKED(DEM, RF_FTDF_CTRL2_REG, 0x0700, 0x6810); |
| REG_SET_MASKED(DEM, RF_FTDF_CTRL5_REG, 0x1FFF, 0x4708); |
| REG_SET_MASKED(DEM, RF_FTDF_LOOP_GAIN_DS_REG, 0x00FF, 0x0060); |
| REG_SET_MASKED(DEM, RF_FTDF_LOOP_GAIN_PD_REG, 0x00FF, 0x0060); |
| PLLDIG->RF_KMOD_ALPHA_REG = KMODE_ALPHA_ACAD_PREF; |
| REG_SET_MASKED(RFCU, RF_LF_CTRL_REG, 0x001F, 0x00C0); |
| REG_SET_MASKED(RFCU, RF_LF_RES_CTRL_BLE_REG, 0x0F0F, 0x7474); |
| REG_SET_MASKED(RFCU, RF_LF_RES_CTRL_FTDF_REG, 0x0F0F, 0x7474); |
| |
| |
| PLLDIG->RF_MGAIN_CTRL2_REG = 0x0006; |
| REG_SET_MASKED(PLLDIG, RF_MGAIN_CTRL_BLE_REG, 0x1C00, 0x1403); |
| |
| |
| REG_SET_MASKED(RFCU, RF_MIXER_CTRL1_BLE_REG, 0x000F, 0x0031); |
| REG_SET_MASKED(RFCU, RF_MIXER_CTRL1_FTDF_REG, 0x000F, 0x0031); |
| REG_SET_MASKED(RFCU, RF_MIXER_CTRL2_REG, 0x001F, 0x0000); |
| REG_SET_MASKED(PLLDIG, RF_MSKMOD_CTRL1_REG, 0x0003, 0x0003); |
| REG_SET_MASKED(RFCU, RF_REF_OSC_BLE_REG, 0x7FC0, 0x302C); |
| REG_SET_MASKED(RFCU, RF_REF_OSC_FTDF_REG, 0x7FC0, 0x302C); |
| REG_SET_MASKED(DEM, RF_RSSI_COMP_CTRL_REG, 0xF000, 0x9777); |
| |
| REG_SET_MASKED(RFCU, RF_SPARE1_FTDF_REG, 0x4800, 0x4000); |
| REG_SET_MASKED(PLLDIG, RF_SYNTH_CTRL2_BLE_REG, 0x14C0, 0x108B); |
| REG_SET_MASKED(PLLDIG, RF_SYNTH_CTRL2_FTDF_REG, 0x00C0, 0x009B); |
| REG_SET_MASKED(RFCU, RF_TX_PWR_LUT_1_REG, 0x003F, 0x003B); |
| REG_SET_MASKED(RFCU, RF_TX_PWR_LUT_2_REG, 0x003F, 0x0037); |
| RFCU->RF_TX_PWR_LUT_3_REG = 0x01F6; |
| REG_SET_MASKED(RFCU, RF_TX_PWR_LUT_4_REG, 0x003F, 0x0036); |
| PLLDIG->RF_VCO_CALCAP_BIT14_REG = 0xD59D; |
| |
| /* FTDF specific */ |
| REG_SETF(DEM, RF_FTDF_CTRL5_REG, RSSITH, 1800); |
| } |
| |
| REG_SETF(PLLDIG, RF_KMOD_ALPHA_REG, KMOD_ALPHA_BLE, kmoda_cal); |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL_BLE_REG, GAUSS_GAIN_WR, gg_cal_modified); |
| REG_SET_BIT(PLLDIG, RF_MGAIN_CTRL_BLE_REG, GAUSS_GAIN_SEL); |
| #else |
| REG_SET_MASKED(DEM, RF_AFC_CTRL_REG, 0x0330, 0x01F5); |
| REG_SET_MASKED(DEM, RF_AGC_CTRL1_REG, 0x007F, 0x950A); |
| REG_SET_MASKED(DEM, RF_AGC_CTRL2_REG, 0x003F, 0x0049); |
| REG_SET_MASKED(DEM, RF_CCA_RSSITH_REG, 0xE000, 0xE708); |
| |
| RFCU_POWER->RF_CNTRL_TIMER_10_REG = 0x0A42; |
| RFCU_POWER->RF_CNTRL_TIMER_11_REG = 0x0A44; |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_12_REG, 0x00FF, 0x0050); |
| RFCU_POWER->RF_CNTRL_TIMER_13_REG = 0x0850; |
| RFCU_POWER->RF_CNTRL_TIMER_14_REG = 0x1858; |
| RFCU_POWER->RF_CNTRL_TIMER_15_REG = 0x0A50; |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_16_REG, 0xFF00, 0x1207); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_1_REG, 0xFF00, 0x0F00); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_21_REG, 0x00FF, 0x0044); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_22_REG, 0x00FF, 0x0040); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_23_REG, 0x00FF, 0x0052); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_2_REG, 0xFF00, 0x0D08); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_3_REG, 0xFF00, 0x0C10); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_5_REG, 0xFF00, 0x0A18); |
| REG_SET_MASKED(RFCU_POWER, RF_CNTRL_TIMER_7_REG, 0xFF00, 0x0A18); |
| RFCU->RF_CP_CTRL_BLE_REG = 0x3535; |
| REG_SET_MASKED(RFCU, RF_CP_CTRL_FTDF_REG, 0x0F0F, 0x7575); |
| REG_SET_MASKED(DEM, RF_DC_OFFSET_CTRL2_REG, 0x0402, 0x05D0); |
| REG_SET_MASKED(RFCU, RF_DIV_IQ_TX_REG, 0x00FF, 0x00A1); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG16_REG, 0x001F, 0x0014); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG23_BLE_REG, 0x03E0, 0x0000); |
| RFCU_POWER->RF_ENABLE_CONFIG42_REG = 0x0210; |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG45_BLE_REG, 0x03E0, 0x0060); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG46_BLE_REG, 0x001F, 0x0015); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG46_FTDF_REG, 0x001F, 0x0015); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG47_BLE_REG, 0x001F, 0x0016); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG47_FTDF_REG, 0x001F, 0x0016); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG48_BLE_REG, 0x001F, 0x0017); |
| REG_SET_MASKED(RFCU_POWER, RF_ENABLE_CONFIG48_FTDF_REG, 0x001F, 0x0017); |
| REG_SET_MASKED(DEM, RF_FTDF_CTRL1_REG, 0xC000, 0x47C0); |
| REG_SET_MASKED(DEM, RF_FTDF_SIGDET_CTRL_REG, 0x1FFF, 0x0B6A); |
| REG_SET_MASKED(PLLDIG, RF_KMOD_ALPHA_BLE_REG, 0x0FC0, 0x030C); |
| PLLDIG->RF_KMOD_ALPHA_FTDF_REG = 0x000D; |
| RFCU->RF_LF_RES_CTRL_BLE_REG = 0x3434; |
| REG_SET_MASKED(RFCU, RF_LF_CTRL_REG, 0x0040, 0x0080); |
| REG_SET_MASKED(RFCU, RF_LF_RES_CTRL_FTDF_REG, 0x0F0F, 0x7474); |
| RFCU->RF_LO_IQ_TRIM_REG = 0x0001; |
| PLLDIG->RF_MGAIN_CTRL3_REG = 0x0050; |
| REG_SET_MASKED(PLLDIG, RF_MGAIN_CTRL_FTDF_REG, 0xFF00, 0x5000); |
| REG_SET_MASKED(RFCU, RF_MIXER_CTRL1_BLE_REG, 0x000F, 0x0031); |
| REG_SET_MASKED(RFCU, RF_MIXER_CTRL1_FTDF_REG, 0x000F, 0x0031); |
| REG_SET_MASKED(RFCU, RF_OVERRULE_REG, 0x3C00, 0x5800); |
| REG_SET_MASKED(DEM, RF_RSSI_COMP_CTRL_REG, 0xF000, 0x9777); |
| REG_SET_MASKED(RFCU, RF_SPARE1_BLE_REG, 0x0038, 0x0018); |
| REG_SET_MASKED(RFCU, RF_SPARE1_FTDF_REG, 0x0008, 0x0008); |
| REG_SET_MASKED(PLLDIG, RF_SYNTH_CTRL2_BLE_REG, 0x20C0, 0x304B); |
| REG_SET_MASKED(PLLDIG, RF_SYNTH_CTRL2_FTDF_REG, 0x0040, 0x004B); |
| RFCU->RF_TX_PWR_LUT_5_REG = 0x09FF; |
| REG_SET_MASKED(RFCU, RF_TXDAC_CTRL_REG, 0x0040, 0x0000); |
| #endif |
| } |
| |
| |
| |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| /** |
| * \brief Modulation gain calibration |
| * |
| * \param[in] bool, true for BLE, false for FTDF |
| * \param[in] bool, true to enable RFCAL IRQ, false to poll |
| * |
| */ |
| static void hw_rf_modulation_gain_calibration_start(bool mode_ble) |
| { |
| |
| uint32_t calcap_mid; // MP-12-02-2016 |
| |
| // Store all the registers that will be changed in this function |
| rf_cntrl_timer14_reg_set_offset = REG_GETF(RFCU_POWER, RF_CNTRL_TIMER_14_REG, |
| SET_OFFSET); |
| rf_cntrl_timer_7_reg_value = RFCU_POWER->RF_CNTRL_TIMER_7_REG; |
| rf_enable_config14_ble_reg_value = RFCU_POWER->RF_ENABLE_CONFIG14_BLE_REG; |
| rf_enable_config15_ble_reg_value = RFCU_POWER->RF_ENABLE_CONFIG15_BLE_REG; |
| rf_enable_config14_ftdf_reg_value = RFCU_POWER->RF_ENABLE_CONFIG14_FTDF_REG; |
| rf_enable_config15_ftdf_reg_value = RFCU_POWER->RF_ENABLE_CONFIG15_FTDF_REG; |
| rf_cal_ctrl_reg_value = RFCU->RF_CAL_CTRL_REG; |
| rf_mgain_ctrl_reg_value = PLLDIG->RF_MGAIN_CTRL_BLE_REG; |
| rf_mgain_ctrl2_reg_value = PLLDIG->RF_MGAIN_CTRL2_REG; |
| rf_synth_ctrl2_ble_reg_value = PLLDIG->RF_SYNTH_CTRL2_BLE_REG; |
| rf_synth_ctrl2_ftdf_reg_value = PLLDIG->RF_SYNTH_CTRL2_FTDF_REG; |
| rf_bmcw_reg_value = PLLDIG->RF_BMCW_REG; |
| rf_vcocal_ctrl_reg_value = PLLDIG->RF_VCOCAL_CTRL_REG; |
| |
| // move PLLCLOSED_EN to after PLL is in lock |
| REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_7_REG, SET_OFFSET, |
| rf_cntrl_timer14_reg_set_offset + 150); |
| |
| // Disable PA and PA ramp. |
| RFCU_POWER->RF_ENABLE_CONFIG14_BLE_REG = 0x0000; |
| RFCU_POWER->RF_ENABLE_CONFIG15_BLE_REG = 0x0000; |
| |
| RFCU_POWER->RF_ENABLE_CONFIG14_FTDF_REG = 0x0000; |
| RFCU_POWER->RF_ENABLE_CONFIG15_FTDF_REG = 0x0000; |
| |
| // Disable end-of-packet detection (not needed for the MGC) |
| REG_SET_BIT(PLLDIG, RF_SYNTH_CTRL2_BLE_REG, EO_PACKET_DIS); |
| |
| //Set modulator inversion |
| // REG_CLR_BIT(PLLDIG, RF_MSKMOD_CTRL1_REG, INV_SDM_POL); // Normal SDM polarity |
| // REG_SET_BIT(PLLDIG, RF_MSKMOD_CTRL1_REG, INV_DAC_POL); // Inverted DAC polarity |
| |
| //Make sure that normal operation is selected. |
| REG_CLR_BIT(PLLDIG, RF_MGAIN_CTRL_BLE_REG, GAUSS_GAIN_SEL); |
| |
| // Settings for modulation gain calibration |
| REG_SET_BIT(RFCU, RF_MGC_CTRL_REG, MGC_GAIN_SET); |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL_BLE_REG, MGAIN_AVER, 0x2); |
| |
| // invert the comparator value if mode bit is set to true. |
| if (!mode_ble) |
| { |
| REG_SETF(RFCU, RF_OVERRULE_REG, RF_MODE_OVR, 0x2); // Set radio in FTDF mode |
| REG_SET_BIT(PLLDIG, RF_MGAIN_CTRL_BLE_REG, MGAIN_CMP_INV); |
| // Set length dependent on mode , JH-09-11-2015 |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL2_REG, MGAIN_TRANSMIT_LENGTH, 12); |
| // Need to set ModIndex value to 0x3F. |
| REG_SETF(PLLDIG, RF_SYNTH_CTRL2_FTDF_REG, FTDF_MODINDEX, 0x3F); |
| } |
| else |
| { |
| REG_SETF(RFCU, RF_OVERRULE_REG, RF_MODE_OVR, 0x1); // Set radio in BLE mode |
| REG_SET_BIT(PLLDIG, RF_MGAIN_CTRL_BLE_REG, MGAIN_CMP_INV); |
| // Set length dependent on mode , JH-09-11-2015 |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL2_REG, MGAIN_TRANSMIT_LENGTH, 8); |
| // Set modindex to 266kHz to improve df2/df1 , JH-09-17-2015 |
| REG_SETF(PLLDIG, RF_SYNTH_CTRL2_BLE_REG, MODINDEX, 0x2); |
| |
| // Start with a VCO coarse cal to find the calcap for mid channel |
| REG_SETF(PLLDIG, RF_BMCW_REG, CN_SEL, 1); |
| REG_SETF(PLLDIG, RF_BMCW_REG, CN_WR, 18); |
| |
| // Disable all calibrations except the VCO coarse cal. |
| RFCU->RF_CAL_CTRL_REG = 0x001C; |
| |
| // Clear eo-cal interrupt, such that new calibration can be stared |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| // Wait until the VCO coarse calibration can be started |
| while ((RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, EO_CAL))) {} |
| |
| // Start the VCO coarse calibration |
| REG_SET_BIT(RFCU, RF_CAL_CTRL_REG, SO_CAL); |
| |
| // Wait until the VCO coarse calibration has started |
| while (!(RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL))) {} |
| |
| // Wait until the VCO coarse calibration is completed |
| while ((RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL))) {} |
| |
| // Clear eo_cal interrupt, so that new calibration can be started |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| calcap_mid = REG_GETF(PLLDIG, RF_SYNTH_RESULT_BLE_REG, VCO_FREQTRIM_RD); |
| REG_SETF(PLLDIG, RF_VCOCAL_CTRL_REG, VCO_FREQTRIM_WR, |
| calcap_mid - REG_GETF(PLLDIG, RF_VCOCAL_CTRL_REG, VCO_FREQTRIM_SEL)); |
| |
| REG_SETF(PLLDIG, RF_VCOCAL_CTRL_REG, VCO_FREQTRIM_SEL, 2); // manual calcap |
| |
| } |
| |
| // Disable all calibrations except the modulation gain cal. |
| RFCU->RF_CAL_CTRL_REG = 0x0038; |
| |
| // Clear eo-cal interrupt, such that new calibration can be started |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| // Wait until next calibration can be started |
| while (RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, EO_CAL)) {} |
| |
| NVIC_ClearPendingIRQ(RFCAL_IRQn); |
| |
| // Start the modulation gain calibration |
| REG_SET_BIT(RFCU, RF_CAL_CTRL_REG, SO_CAL); |
| |
| // Wait until the modulation gain calibration has started |
| while (!(RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL))) {} |
| } |
| #else /* dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B */ |
| static void hw_rf_modulation_gain_calibration_generic_start(mgc_mode_ctrl_e mode_ctrl, |
| int16_t average, int16_t mgain_mode, int16_t force, int16_t length) |
| { |
| |
| // Store all the registers that will be changed in this function |
| rf_cntrl_timer14_reg_set_offset = REG_GETF(RFCU_POWER, RF_CNTRL_TIMER_14_REG, |
| SET_OFFSET); |
| rf_cntrl_timer_7_reg_value = RFCU_POWER->RF_CNTRL_TIMER_7_REG; |
| rf_enable_config14_reg_value = RFCU_POWER->RF_ENABLE_CONFIG14_REG; |
| rf_enable_config15_reg_value = RFCU_POWER->RF_ENABLE_CONFIG15_REG; |
| rf_cal_ctrl_reg_value = RFCU->RF_CAL_CTRL_REG; |
| rf_mgain_ctrl_reg_value = PLLDIG->RF_MGAIN_CTRL_BLE_REG; |
| rf_mgain_ctrl2_reg_value = PLLDIG->RF_MGAIN_CTRL2_REG; |
| rf_synth_ctrl2_ble_reg_value = PLLDIG->RF_SYNTH_CTRL2_BLE_REG; |
| rf_synth_ctrl2_ftdf_reg_value = PLLDIG->RF_SYNTH_CTRL2_FTDF_REG; |
| rf_overrule_reg_value = RFCU->RF_OVERRULE_REG; |
| rf_enable_config23_ble_reg_value = RFCU_POWER->RF_ENABLE_CONFIG23_BLE_REG; |
| rf_enable_config23_ftdf_reg_value = RFCU_POWER->RF_ENABLE_CONFIG23_FTDF_REG; |
| rf_enable_config45_ble_reg_value = RFCU_POWER->RF_ENABLE_CONFIG45_BLE_REG; |
| rf_enable_config45_ftdf_reg_value = RFCU_POWER->RF_ENABLE_CONFIG45_FTDF_REG; |
| |
| // move PLLCLOSED_EN to after PLL is in lock |
| REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_7_REG, SET_OFFSET, |
| rf_cntrl_timer14_reg_set_offset + 150); |
| |
| // Disable PA and PA ramp. |
| RFCU_POWER->RF_ENABLE_CONFIG14_REG = 0x0000; |
| RFCU_POWER->RF_ENABLE_CONFIG15_REG = 0x0000; |
| |
| // Disable end-of-packet detection (not needed for the MGC) |
| REG_SET_BIT(PLLDIG, RF_SYNTH_CTRL2_BLE_REG, EO_PACKET_DIS); |
| |
| // Set Gain in Analog comparator to 1 |
| REG_SET_BIT(RFCU, RF_MGC_CTRL_REG, MGC_GAIN_SET); |
| |
| |
| /* Set mode specific settings for BLE mode with GaussDAC */ |
| if (mode_ctrl == MGC_MODE_CTRL_BLE_GAUSSDAC) |
| { |
| /* Set radio in BLE mode */ |
| REG_SETF(RFCU, RF_OVERRULE_REG, RF_MODE_OVR, 0x1); |
| /* Inversion of analog comparator signal */ |
| REG_SET_BIT(PLLDIG, RF_MGAIN_CTRL_BLE_REG, MGAIN_CMP_INV); |
| |
| if (force != -1) |
| { |
| /* Disable Gauss Gain override */ |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL_BLE_REG, GAUSS_GAIN_SEL, force & 0x1); |
| } |
| |
| if (average != -1) |
| { |
| /* Set number of averaging */ |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL_BLE_REG, MGAIN_AVER, average & 0x3); |
| } |
| |
| /* Setting number of zeros and ones */ |
| if (length == -1) |
| { |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL2_REG, MGAIN_TRANSMIT_LENGTH, 8); |
| } |
| else |
| { |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL2_REG, MGAIN_TRANSMIT_LENGTH, |
| length & 0x7f); |
| } |
| |
| /* Set modindex to 266kHz */ |
| REG_SETF(PLLDIG, RF_SYNTH_CTRL2_BLE_REG, MODINDEX, 0x2); |
| /* Select the GaussDac in BLE mode */ |
| REG_SETF(PLLDIG, RF_SYNTH_CTRL2_BLE_REG, BLE_DAC_SEL, 0x0); |
| |
| if (mgain_mode != -1) |
| { |
| /* Use the new algorithm */ |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL2_REG, MGAIN_MODE_SEL, mgain_mode & 0x1); |
| } |
| |
| /* Disable TXDAC in BLE mode */ |
| REG_SETF(RFCU_POWER, RF_ENABLE_CONFIG45_BLE_REG, txdac_en_ble_dcf_tx, 0x0); |
| /* Enable GaussDAC in BLE mode */ |
| REG_SETF(RFCU_POWER, RF_ENABLE_CONFIG23_BLE_REG, gauss_en_ble_dcf_tx, 0x3); |
| /* Disable TX-DAC output selection */ |
| REG_SETF(RFCU, RF_OVERRULE_REG, TXDAC_SEL, 0x0); |
| /* Enable GaussDAC output selection switch */ |
| REG_SETF(RFCU, RF_OVERRULE_REG, GAUSS_DAC_SEL, 0x0); |
| } |
| |
| /* Set mode specific settings for BLE mode with TXDAC */ |
| if (mode_ctrl == MGC_MODE_CTRL_BLE_TXDAC) |
| { |
| /* Set radio in BLE mode */ |
| REG_SETF(RFCU, RF_OVERRULE_REG, RF_MODE_OVR, 0x1); |
| /* Inversion of analog comparator signal */ |
| REG_SET_BIT(PLLDIG, RF_MGAIN_CTRL_BLE_REG, MGAIN_CMP_INV); |
| |
| if (force != -1) |
| { |
| /* Disable Gauss Gain override */ |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL_BLE_REG, GAUSS_GAIN_SEL, force & 0x1); |
| } |
| |
| if (average != -1) |
| { |
| /* Set number of averaging */ |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL_BLE_REG, MGAIN_AVER, average & 0x3); |
| } |
| |
| /* Setting number of zeros and ones */ |
| if (length == -1) |
| { |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL2_REG, MGAIN_TRANSMIT_LENGTH, 8); |
| } |
| else |
| { |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL2_REG, MGAIN_TRANSMIT_LENGTH, |
| length & 0x7f); |
| } |
| |
| /* Set modindex to 250kHz */ |
| REG_SETF(PLLDIG, RF_SYNTH_CTRL2_BLE_REG, MODINDEX, 0x0); |
| /* Select the TXDAC in BLE mode */ |
| REG_SETF(PLLDIG, RF_SYNTH_CTRL2_BLE_REG, BLE_DAC_SEL, 0x1); |
| |
| if (mgain_mode != -1) |
| { |
| /* Use the new algorithm */ |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL2_REG, MGAIN_MODE_SEL, mgain_mode & 0x1); |
| } |
| |
| /* Enable TXDAC in BLE mode */ |
| REG_SETF(RFCU_POWER, RF_ENABLE_CONFIG45_BLE_REG, txdac_en_ble_dcf_tx, 0x3); |
| /* Disable GaussDAC in BLE mode */ |
| REG_SETF(RFCU_POWER, RF_ENABLE_CONFIG23_BLE_REG, gauss_en_ble_dcf_tx, 0x0); |
| /* Select TX-DAC output selection */ |
| REG_SETF(RFCU, RF_OVERRULE_REG, TXDAC_SEL, 0x2); |
| /* Unselect GaussDAC output selection switch */ |
| REG_SETF(RFCU, RF_OVERRULE_REG, GAUSS_DAC_SEL, 0x1); |
| } |
| |
| /* Set mode specific settings for FTDF mode */ |
| if (mode_ctrl == MGC_MODE_CTRL_FTDF) |
| { |
| /* Set radio in FTDF mode */ |
| REG_SETF(RFCU, RF_OVERRULE_REG, RF_MODE_OVR, 0x2); |
| /* Inversion of analog comparator signal */ |
| REG_SET_BIT(PLLDIG, RF_MGAIN_CTRL_BLE_REG, MGAIN_CMP_INV); |
| |
| if (force != -1) |
| { |
| /* Disable Gauss Gain override */ |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL_BLE_REG, GAUSS_GAIN_SEL, force & 0x1); |
| } |
| |
| if (average != -1) |
| { |
| /* Set number of averaging */ |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL_BLE_REG, MGAIN_AVER, average & 0x3); |
| } |
| |
| /* Setting number of zeros and ones */ |
| if (length == -1) |
| { |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL2_REG, MGAIN_TRANSMIT_LENGTH, 16); |
| } |
| else |
| { |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL2_REG, MGAIN_TRANSMIT_LENGTH, |
| length & 0x7f); |
| } |
| |
| if (mgain_mode != -1) |
| { |
| /* Use the new algorithm */ |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL2_REG, MGAIN_MODE_SEL, mgain_mode & 0x1); |
| } |
| |
| /* Enable TXDAC in FTDF mode */ |
| REG_SETF(RFCU_POWER, RF_ENABLE_CONFIG45_FTDF_REG, txdac_en_ftdf_dcf_tx, 0x3); |
| /* Disable GaussDAC in FTDF mode */ |
| REG_SETF(RFCU_POWER, RF_ENABLE_CONFIG23_FTDF_REG, gauss_en_ftdf_dcf_tx, 0x0); |
| /* Select TX-DAC output selection */ |
| REG_SETF(RFCU, RF_OVERRULE_REG, TXDAC_SEL, 0x0); |
| /* Unselect GaussDAC output selection switch */ |
| REG_SETF(RFCU, RF_OVERRULE_REG, GAUSS_DAC_SEL, 0x0); |
| } |
| |
| // Disable all calibrations except the modulation gain cal. |
| RFCU->RF_CAL_CTRL_REG = 0x0038; |
| |
| // Clear eo-cal interrupt, such that new calibration can be started |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| // Wait until next calibration can be started |
| while (RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, EO_CAL)) {} |
| |
| NVIC_ClearPendingIRQ(RFCAL_IRQn); |
| |
| // Start the modulation gain calibration |
| REG_SET_BIT(RFCU, RF_CAL_CTRL_REG, SO_CAL); |
| |
| // Wait until the modulation gain calibration has started |
| while (!(RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL))) {} |
| } |
| |
| static inline void hw_rf_modulation_gain_calibration_start(bool mode_ble) |
| { |
| if (mode_ble) |
| { |
| hw_rf_modulation_gain_calibration_generic_start(MGC_MODE_CTRL_BLE_TXDAC, 2, 1, 0, 8); |
| } |
| else |
| { |
| hw_rf_modulation_gain_calibration_generic_start(MGC_MODE_CTRL_FTDF, 2, 1, 0, 8); |
| } |
| } |
| #endif |
| |
| static void hw_rf_modulation_gain_calibration_end(void) |
| { |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| uint32_t ch_cal, gg_cal, gg_ch_prod, kmoda_max, gg0, gg_th1, gg_th2; // MP-12-02-2016 |
| uint32_t kmoda_base; |
| uint32_t Y; |
| uint32_t tmp; |
| uint32_t dgain_kill_second_jump; |
| uint32_t dgain; |
| |
| if ((dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A) |
| || ((dg_configUSE_AUTO_CHIP_DETECTION == 1) |
| && (CHIP_IS_AE))) |
| { |
| kmoda_base = KMODE_ALPHA_ACAD_PREF & REG_MSK(PLLDIG, RF_KMOD_ALPHA_REG, |
| KMOD_ALPHA_BLE); |
| } |
| |
| // Clear eo_cal interrupt, so that new calibration can be started |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| ch_cal = REG_GETF(PLLDIG, RF_SYNTH_RESULT2_BLE_REG, CN_CAL_RD); |
| gg_cal = REG_GETF(PLLDIG, RF_SYNTH_RESULT_BLE_REG, GAUSS_GAIN_CAL_RD); |
| |
| gg0 = gg_cal + ((gg_cal * kmoda_base * ch_cal + 1024) >> 11); |
| gg_th1 = (gg_cal & 0xE0) + DF1_DAC_CHECK_VALUE; // gg_th1 = (gg_cal&0xE0)+32; |
| gg_th2 = (gg_th1 + DF1_DAC_CHECK_VALUE); // gg_th2 = (gg_th1+32); |
| |
| if (gg0 >= gg_th2) //so 2 jumps are on the left of the cal. channel |
| { |
| /* |
| Formula (MP): |
| Y = 1 + ((kmoda_base*ch_cal)/2048); |
| dgain_kill_second_jump = gg_cal - (gg_th2-1)/Y; |
| |
| Improve the resolution, |
| Y = 2048* + (kmoda_base*ch_cal); |
| dgain_kill_second_jump = gg_cal - (gg_th2-1)*2048/Y; |
| */ |
| |
| Y = 2048 + (kmoda_base * ch_cal); |
| tmp = (((gg_th2 - 1) << 11) / Y); |
| |
| if (gg_cal > tmp) //check to prevent negative value for dgain_kill_second_jump |
| { |
| dgain_kill_second_jump = gg_cal - tmp; |
| |
| if (dgain_kill_second_jump <= DF1_DGAIN_THR1) |
| { |
| dgain = DF1_DGAIN_THR1; |
| } |
| else if (dgain_kill_second_jump >= DF1_DGAIN_THR2) |
| { |
| dgain = DF1_DGAIN_THR2; // Should never end up here � but better to be safe than sorry. dgain_thr2 is default 16 |
| } |
| else |
| { |
| dgain = dgain_kill_second_jump; |
| } |
| } |
| else |
| { |
| dgain = 0; // End up here because something went wrong with the calculation of tmp! |
| } |
| |
| } |
| else if (gg0 >= gg_th1) |
| { |
| dgain = DF1_DGAIN_THR1; |
| } |
| else |
| { |
| dgain = DF1_DGAIN_THR0; |
| } |
| |
| if (gg_cal > dgain) |
| { |
| gg_cal_modified = gg_cal - dgain; |
| } |
| else |
| { |
| gg_cal_modified = gg_cal; |
| } |
| |
| gg_ch_prod = (uint32_t)(gg_cal_modified * ch_cal); |
| |
| if (gg_ch_prod == 0) // Avoid HardFault due to division by 0 (not likely) |
| { |
| kmoda_cal = kmoda_base; |
| } |
| else |
| { |
| |
| kmoda_max = (255 * 2048 - 2048 * gg_cal_modified) / gg_ch_prod ; |
| |
| if (kmoda_max >= kmoda_base) |
| { |
| kmoda_cal = kmoda_base; |
| } |
| else |
| { |
| kmoda_cal = kmoda_max; |
| } |
| } |
| |
| // This should be done both here (to take effect after calib) AND after preferred settings |
| REG_SETF(PLLDIG, RF_KMOD_ALPHA_REG, KMOD_ALPHA_BLE, kmoda_cal); |
| |
| //Restore the values of the registers that were changed in the function |
| //REG_SET_BIT(PLLDIG, RF_MSKMOD_CTRL1_REG, INV_SDM_POL); // Inverted SDM polarity |
| //REG_CLR_BIT(PLLDIG, RF_MSKMOD_CTRL1_REG, INV_DAC_POL); // Normal DAC polarity |
| RFCU_POWER->RF_CNTRL_TIMER_7_REG = rf_cntrl_timer_7_reg_value; |
| RFCU->RF_CAL_CTRL_REG = rf_cal_ctrl_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG14_BLE_REG = rf_enable_config14_ble_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG14_FTDF_REG = rf_enable_config14_ftdf_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG15_BLE_REG = rf_enable_config15_ble_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG15_FTDF_REG = rf_enable_config15_ftdf_reg_value; |
| |
| PLLDIG->RF_MGAIN_CTRL_BLE_REG = rf_mgain_ctrl_reg_value; |
| PLLDIG->RF_MGAIN_CTRL2_REG = rf_mgain_ctrl2_reg_value; |
| PLLDIG->RF_SYNTH_CTRL2_BLE_REG = rf_synth_ctrl2_ble_reg_value; |
| PLLDIG->RF_SYNTH_CTRL2_FTDF_REG = rf_synth_ctrl2_ftdf_reg_value; |
| |
| PLLDIG->RF_BMCW_REG = rf_bmcw_reg_value; // MP-12-02-2016 |
| PLLDIG->RF_VCOCAL_CTRL_REG = rf_vcocal_ctrl_reg_value; // MP-12-02-2016 |
| |
| REG_SETF(PLLDIG, RF_MGAIN_CTRL_BLE_REG, GAUSS_GAIN_WR, gg_cal_modified); |
| REG_SET_BIT(PLLDIG, RF_MGAIN_CTRL_BLE_REG, GAUSS_GAIN_SEL); |
| |
| // Disable overrule mode |
| RFCU->RF_OVERRULE_REG &= ~REG_MSK(RFCU, RF_OVERRULE_REG, RF_MODE_OVR); |
| #else |
| // Clear eo_cal interrupt, so that new calibration can be started |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| //Restore the values of the registers that were changed in the function |
| RFCU_POWER->RF_CNTRL_TIMER_7_REG = rf_cntrl_timer_7_reg_value; |
| RFCU->RF_CAL_CTRL_REG = rf_cal_ctrl_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG14_REG = rf_enable_config14_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG15_REG = rf_enable_config15_reg_value; |
| PLLDIG->RF_MGAIN_CTRL_BLE_REG = rf_mgain_ctrl_reg_value; |
| PLLDIG->RF_MGAIN_CTRL2_REG = rf_mgain_ctrl2_reg_value; |
| PLLDIG->RF_SYNTH_CTRL2_BLE_REG = rf_synth_ctrl2_ble_reg_value; |
| PLLDIG->RF_SYNTH_CTRL2_FTDF_REG = rf_synth_ctrl2_ftdf_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG23_BLE_REG = rf_enable_config23_ble_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG23_FTDF_REG = rf_enable_config23_ftdf_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG45_BLE_REG = rf_enable_config45_ble_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG45_FTDF_REG = rf_enable_config45_ftdf_reg_value; |
| |
| // Disable overrule mode |
| RFCU->RF_OVERRULE_REG = rf_overrule_reg_value; |
| |
| #endif |
| } |
| |
| /** |
| * \brief Modulation gain calibration - Wrapper function |
| * |
| * Used on boot, and generally whenever the interrupt-based approach is not |
| * needed |
| * |
| * \param[in] bool, true for FTDF, false for BLE |
| * |
| */ |
| void hw_rf_modulation_gain_calibration(bool mode_ble) |
| { |
| /* Start the gain calibration */ |
| hw_rf_modulation_gain_calibration_start(mode_ble); |
| |
| // Wait until the modulation gain calibration is completed |
| while (RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL)) {} |
| |
| hw_rf_modulation_gain_calibration_end(); |
| } |
| |
| |
| void hw_rf_dc_offset_calibration(void) |
| { |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| // Save the values of registers that will be changed in the function |
| uint32_t RF_ENABLE_CONFIG0_BLE_REG_value = RFCU_POWER->RF_ENABLE_CONFIG0_BLE_REG; |
| uint32_t RF_ENABLE_CONFIG1_BLE_REG_value = RFCU_POWER->RF_ENABLE_CONFIG1_BLE_REG; |
| uint32_t RF_ENABLE_CONFIG2_BLE_REG_value = RFCU_POWER->RF_ENABLE_CONFIG2_BLE_REG; |
| uint32_t RF_ENABLE_CONFIG46_BLE_REG_value = RFCU_POWER->RF_ENABLE_CONFIG46_BLE_REG; |
| |
| uint32_t RF_DC_OFFSET_CTRL2_REG_value = DEM->RF_DC_OFFSET_CTRL2_REG; |
| uint32_t rf_cal_ctrl_reg_value_local = RFCU->RF_CAL_CTRL_REG; |
| uint32_t rf_overrule_reg_value_local = RFCU->RF_OVERRULE_REG; |
| |
| // Required setting for the DC-offset calibration |
| RFCU_POWER->RF_ENABLE_CONFIG0_BLE_REG = 0x0000; // Disable LNA_LDO |
| RFCU_POWER->RF_ENABLE_CONFIG1_BLE_REG = 0x0000; // Disable LNA_CORE |
| RFCU_POWER->RF_ENABLE_CONFIG2_BLE_REG = 0x0000; // Disable LNA_CGM |
| RFCU_POWER->RF_ENABLE_CONFIG46_BLE_REG = 0x0000; // Disable the DCF triggered Partial DCOC |
| |
| // DCNGAIN = 3, DCNSTEP = 5, DCPARCAL_EN = 0, DCOFFSET_SEL = 0 |
| DEM->RF_DC_OFFSET_CTRL2_REG = 0x01D0; |
| // Disable all calibrations except the DC-offset cal. |
| RFCU->RF_CAL_CTRL_REG = 0x002C; |
| |
| REG_SETF(RFCU, RF_OVERRULE_REG, RF_MODE_OVR, 0x1); // Overrule RF_MODE <- BLE_MODE |
| |
| // Clear eo-cal interrupt, so that new calibration can be stared |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| // Wait until the DC-offset calibration can be started |
| while (RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, EO_CAL)) {} |
| |
| // Start the modulation gain calibration |
| REG_SET_BIT(RFCU, RF_CAL_CTRL_REG, SO_CAL); |
| |
| // Wait until the modulation gain calibration has started |
| while (!(RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL))) {} |
| |
| // Wait until the modulation gain calibration is completed |
| while (RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL)) {} |
| |
| // Clear eo-cal interrupt, so that new calibration can be started |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| // Restore the values of registers that were changed in the function |
| RFCU_POWER->RF_ENABLE_CONFIG0_BLE_REG = RF_ENABLE_CONFIG0_BLE_REG_value; |
| RFCU_POWER->RF_ENABLE_CONFIG1_BLE_REG = RF_ENABLE_CONFIG1_BLE_REG_value; |
| RFCU_POWER->RF_ENABLE_CONFIG2_BLE_REG = RF_ENABLE_CONFIG2_BLE_REG_value; |
| RFCU_POWER->RF_ENABLE_CONFIG46_BLE_REG = RF_ENABLE_CONFIG46_BLE_REG_value; |
| |
| DEM->RF_DC_OFFSET_CTRL2_REG = RF_DC_OFFSET_CTRL2_REG_value; |
| RFCU->RF_CAL_CTRL_REG = rf_cal_ctrl_reg_value_local; |
| RFCU->RF_OVERRULE_REG = rf_overrule_reg_value_local; |
| #else /* REV_B */ |
| // Save the values of registers that will be changed in the function |
| uint32_t RF_ENABLE_CONFIG0_REG_value = RFCU_POWER->RF_ENABLE_CONFIG0_REG; |
| uint32_t RF_ENABLE_CONFIG1_REG_value = RFCU_POWER->RF_ENABLE_CONFIG1_REG; |
| uint32_t RF_ENABLE_CONFIG2_REG_value = RFCU_POWER->RF_ENABLE_CONFIG2_REG; |
| |
| uint32_t RF_DC_OFFSET_CTRL2_REG_value = DEM->RF_DC_OFFSET_CTRL2_REG; |
| uint32_t rf_cal_ctrl_reg_value_local = RFCU->RF_CAL_CTRL_REG; |
| uint32_t rf_overrule_reg_value_local = RFCU->RF_OVERRULE_REG; |
| |
| // Required setting for the DC-offset calibration |
| RFCU_POWER->RF_ENABLE_CONFIG0_REG = 0x0000; // Disable LNA_LDO |
| RFCU_POWER->RF_ENABLE_CONFIG1_REG = 0x0000; // Disable LNA_CORE |
| RFCU_POWER->RF_ENABLE_CONFIG2_REG = 0x0000; // Disable LNA_CGM |
| |
| // DCNGAIN = 3, DCNSTEP = 5, DCPARCAL_EN = 0, DCOFFSET_SEL = 0 |
| DEM->RF_DC_OFFSET_CTRL2_REG = 0x01D0; |
| // Disable all calibrations except the DC-offset cal. |
| RFCU->RF_CAL_CTRL_REG = 0x002C; |
| |
| REG_SETF(RFCU, RF_OVERRULE_REG, RF_MODE_OVR, 0x1); // Overrule RF_MODE <- BLE_MODE |
| |
| // Clear eo-cal interrupt, so that new calibration can be stared |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| // Wait until the DC-offset calibration can be started |
| while (RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, EO_CAL)) {} |
| |
| // Start the modulation gain calibration |
| REG_SET_BIT(RFCU, RF_CAL_CTRL_REG, SO_CAL); |
| |
| // Wait until the modulation gain calibration has started |
| while (!(RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL))) {} |
| |
| // Wait until the modulation gain calibration is completed |
| while (RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL)) {} |
| |
| // Clear eo-cal interrupt, so that new calibration can be started |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| // Restore the values of registers that were changed in the function |
| RFCU_POWER->RF_ENABLE_CONFIG0_REG = RF_ENABLE_CONFIG0_REG_value; |
| RFCU_POWER->RF_ENABLE_CONFIG1_REG = RF_ENABLE_CONFIG1_REG_value; |
| RFCU_POWER->RF_ENABLE_CONFIG2_REG = RF_ENABLE_CONFIG2_REG_value; |
| |
| DEM->RF_DC_OFFSET_CTRL2_REG = RF_DC_OFFSET_CTRL2_REG_value; |
| RFCU->RF_CAL_CTRL_REG = rf_cal_ctrl_reg_value_local; |
| RFCU->RF_OVERRULE_REG = rf_overrule_reg_value_local; |
| #endif |
| } |
| |
| |
| |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| bool hw_rf_iff_calibration(void) |
| { |
| uint64_t start_time; |
| |
| uint16_t calcap_result; |
| |
| // Save the values of registers that will be changed in the function |
| uint32_t rf_cal_ctrl_reg_value_local = RFCU->RF_CAL_CTRL_REG; |
| |
| // Configure the reference oscillator for the calibration |
| // 21-04-2015 : JH - Removed to use preferred settings instead |
| //uint16_t reg = RFCU->RF_REF_OSC_BLE_REG; |
| //REG_SET_FIELD(RFCU, RF_REF_OSC_BLE_REG, CNT_CLK, reg, 0xA6); |
| //REG_SET_FIELD(RFCU, RF_REF_OSC_BLE_REG, CNT_RO, reg, 0x2C); |
| //RFCU->RF_REF_OSC_BLE_REG = reg; |
| //reg = RFCU->RF_REF_OSC_FTDF_REG; |
| //REG_SET_FIELD(RFCU, RF_REF_OSC_FTDF_REG, CNT_CLK, reg, 0xA6); |
| //REG_SET_FIELD(RFCU, RF_REF_OSC_FTDF_REG, CNT_RO, reg, 0x2C); |
| //RFCU->RF_REF_OSC_FTDF_REG = reg; |
| |
| // Save the values of registers that will be changed in the function |
| uint32_t RF_ENABLE_CONFIG0_BLE_REG_value = RFCU_POWER->RF_ENABLE_CONFIG0_BLE_REG; |
| uint32_t RF_ENABLE_CONFIG1_BLE_REG_value = RFCU_POWER->RF_ENABLE_CONFIG1_BLE_REG; |
| uint32_t RF_ENABLE_CONFIG2_BLE_REG_value = RFCU_POWER->RF_ENABLE_CONFIG2_BLE_REG; |
| uint32_t RF_ENABLE_CONFIG46_BLE_REG_value = RFCU_POWER->RF_ENABLE_CONFIG46_BLE_REG; |
| |
| // Required setting for the DC-offset calibration |
| RFCU_POWER->RF_ENABLE_CONFIG0_BLE_REG = 0x0000; // Disable LNA_LDO |
| RFCU_POWER->RF_ENABLE_CONFIG1_BLE_REG = 0x0000; // Disable LNA_CORE |
| RFCU_POWER->RF_ENABLE_CONFIG2_BLE_REG = 0x0000; // Disable LNA_CGM |
| RFCU_POWER->RF_ENABLE_CONFIG46_BLE_REG = 0x0000; // Disable the DCF triggered Partial DCOC |
| |
| // Disable all calibrations except the Iff cal. |
| RFCU->RF_CAL_CTRL_REG = 0x0034; |
| // Select the IF calcap to use the FSM value |
| REG_SET_BIT(RFCU, RF_IFF_CTRL1_REG, IF_SELECT_FSM); |
| |
| // Clear eo-cal interrupt, so that new calibration can be stared |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| |
| start_time = hw_rf_get_start_iff_time(); |
| |
| // Wait until the IFF calibration can be started |
| while (RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, EO_CAL)) |
| { |
| if (hw_rf_check_iff_timeout(start_time)) |
| { |
| /* IFF lockup detected. Abort */ |
| return false; |
| } |
| } |
| |
| /* |
| * New code by SR 3/23/2016 |
| * (Disable partial calibration before IFF calibrations starts) |
| * |
| * Save current content of RF_DC_OFFSET_CTRl2_REG and set DCPARCAL_EN = 0 |
| * |
| */ |
| uint16_t rf_dc_offset_ctrl2_reg = DEM->RF_DC_OFFSET_CTRL2_REG; //GetWord16(RF_DC_OFFSET_CTRL2_REG); |
| REG_CLR_BIT(DEM, RF_DC_OFFSET_CTRL2_REG, DCPARCAL_EN); |
| |
| // Start the IFF calibration |
| REG_SET_BIT(RFCU, RF_CAL_CTRL_REG, SO_CAL); |
| |
| // Wait until the IFF calibration has started |
| while (!(RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL))) |
| { |
| if (hw_rf_check_iff_timeout(start_time)) |
| { |
| /* IFF lockup detected. Abort */ |
| return false; |
| } |
| } |
| |
| // Wait until the IFF calibration is completed |
| while (RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL)) |
| { |
| if (hw_rf_check_iff_timeout(start_time)) |
| { |
| /* IFF lockup detected. Abort */ |
| return false; |
| } |
| } |
| |
| // Clear eo-cal interrupt, so that new calibration can be started |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| // Store the result to all IFF CC registers |
| calcap_result = RFCU->RF_IFF_CAL_CAP_STAT_REG; |
| RFCU->RF_IFF_CC_BLE_SET1_REG = calcap_result; |
| RFCU->RF_IFF_CC_BLE_SET2_REG = calcap_result; |
| RFCU->RF_IFF_CC_FTDF_SET1_REG = calcap_result; |
| RFCU->RF_IFF_CC_FTDF_SET2_REG = calcap_result; |
| |
| // Restore the values of registers that were changed in the function |
| RFCU->RF_CAL_CTRL_REG = rf_cal_ctrl_reg_value_local; |
| // De-select the IF calcap to use the FSM value |
| REG_CLR_BIT(RFCU, RF_IFF_CTRL1_REG, IF_SELECT_FSM); |
| |
| |
| /* |
| * New code by SR 3/23/2016 |
| * (Disable partial calibration before IFF calibrations starts) |
| * |
| * Restore RF_DC_OFFSET_CTRl2_REG |
| * |
| */ |
| DEM->RF_DC_OFFSET_CTRL2_REG = rf_dc_offset_ctrl2_reg; |
| |
| // Restore the values of registers that were changed in the function |
| RFCU_POWER->RF_ENABLE_CONFIG0_BLE_REG = RF_ENABLE_CONFIG0_BLE_REG_value; |
| RFCU_POWER->RF_ENABLE_CONFIG1_BLE_REG = RF_ENABLE_CONFIG1_BLE_REG_value; |
| RFCU_POWER->RF_ENABLE_CONFIG2_BLE_REG = RF_ENABLE_CONFIG2_BLE_REG_value; |
| RFCU_POWER->RF_ENABLE_CONFIG46_BLE_REG = RF_ENABLE_CONFIG46_BLE_REG_value; |
| return true; |
| } |
| #else /* dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_B */ |
| static bool iff_calib_internal(iff_mode_ovr_e rf_mode_ovr, iff_mode_ctrl_e mode_ctrl) |
| { |
| uint16_t calcap_result; |
| uint64_t start_time; |
| |
| // Set mode |
| REG_SETF(RFCU, RF_OVERRULE_REG, RF_MODE_OVR, rf_mode_ovr); |
| |
| // Disable all calibrations except the Iff cal. |
| RFCU->RF_CAL_CTRL_REG = 0x0034; |
| |
| // Select the IF calcap to use the FSM value |
| REG_SET_BIT(RFCU, RF_IFF_CTRL1_REG, IF_SELECT_FSM); |
| |
| // Clear eo-cal interrupt, so that new calibration can be stared |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| start_time = hw_rf_get_start_iff_time(); |
| |
| // Wait until the IFF calibration can be started |
| while (RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, EO_CAL)) |
| { |
| if (hw_rf_check_iff_timeout(start_time)) |
| { |
| /* IFF lockup detected. Abort */ |
| return false; |
| } |
| } |
| |
| // Start the IFF calibration |
| REG_SET_BIT(RFCU, RF_CAL_CTRL_REG, SO_CAL); |
| |
| // Wait until the IFF calibration has started |
| while (!(RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL))) |
| { |
| if (hw_rf_check_iff_timeout(start_time)) |
| { |
| /* IFF lockup detected. Abort */ |
| return false; |
| } |
| } |
| |
| // Wait until the IFF calibration is completed |
| while (RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL)) |
| { |
| if (hw_rf_check_iff_timeout(start_time)) |
| { |
| /* IFF lockup detected. Abort */ |
| return false; |
| } |
| } |
| |
| // Clear eo-cal interrupt, so that new calibration can be started |
| RFCU->RF_IRQ_CTRL_REG = 0x0000; |
| |
| // Store the result to all IFF CC BLE registers |
| calcap_result = RFCU->RF_IFF_CAL_CAP_STAT_REG; |
| |
| if (mode_ctrl != IFF_MODE_CTRL_COMBO || rf_mode_ovr == IFF_MODE_OVR_BLE) |
| { |
| RFCU->RF_IFF_CC_BLE_SET1_REG = calcap_result; |
| RFCU->RF_IFF_CC_BLE_SET2_REG = calcap_result; |
| } |
| |
| switch (mode_ctrl) |
| { |
| case IFF_MODE_CTRL_BLE: // BLE |
| RFCU->RF_IFF_CC_FTDF_SET1_REG = calcap_result - 2; |
| RFCU->RF_IFF_CC_FTDF_SET2_REG = calcap_result - 2; |
| break; |
| |
| case IFF_MODE_CTRL_FTDF: // FTDF |
| RFCU->RF_IFF_CC_FTDF_SET1_REG = calcap_result + 2; |
| RFCU->RF_IFF_CC_FTDF_SET2_REG = calcap_result + 2; |
| break; |
| |
| case IFF_MODE_CTRL_COMBO: // COMBO |
| if (rf_mode_ovr == IFF_MODE_OVR_FTDF) |
| { |
| RFCU->RF_IFF_CC_FTDF_SET1_REG = calcap_result; |
| RFCU->RF_IFF_CC_FTDF_SET2_REG = calcap_result; |
| } |
| |
| break; |
| } |
| |
| return true; |
| } |
| |
| static bool hw_rf_iff_calibration(iff_mode_ctrl_e mode_ctrl) |
| { |
| bool ret; |
| |
| ////////////////////////////////////////////////////////////// |
| /// Capacitance calibration for different modes |
| /// mode_ctrl=0 : Calibration in BLE mode, use offsetted values in FTDF |
| /// mode_ctrl=1 : Calibration in FTDF mode, use offsetted values in BLE |
| /// mode_ctrl=2 : Calibration done in BLE mode and FTDF mode |
| ////////////////////////////////////////////////////////////// |
| |
| |
| // Save the values of registers that will be changed in the function |
| uint16_t rf_cal_ctrl_reg_value_local = RFCU->RF_CAL_CTRL_REG; |
| uint16_t rf_overrule_reg_value_local = RFCU->RF_OVERRULE_REG; |
| uint16_t rf_enable_config0_reg_value = RFCU_POWER->RF_ENABLE_CONFIG0_REG; |
| uint16_t rf_enable_config1_reg_value = RFCU_POWER->RF_ENABLE_CONFIG1_REG; |
| uint16_t rf_enable_config2_reg_value = RFCU_POWER->RF_ENABLE_CONFIG2_REG; |
| uint16_t rf_enable_config46_ble_reg_value = RFCU_POWER->RF_ENABLE_CONFIG46_BLE_REG; |
| uint16_t rf_enable_config46_ftdf_reg_value = RFCU_POWER->RF_ENABLE_CONFIG46_FTDF_REG; |
| uint16_t rf_dc_offset_ctrl2_reg_value = DEM->RF_DC_OFFSET_CTRL2_REG; |
| |
| // Required setting for the DC-offset calibration |
| RFCU_POWER->RF_ENABLE_CONFIG0_REG = 0x0000; // Disable LNA_LDO |
| RFCU_POWER->RF_ENABLE_CONFIG1_REG = 0x0000; // Disable LNA_CORE |
| RFCU_POWER->RF_ENABLE_CONFIG2_REG = 0x0000; // Disable LNA_CGM |
| RFCU_POWER->RF_ENABLE_CONFIG46_BLE_REG = 0x0000; // Disable the DCF triggered Partial DCOC |
| RFCU_POWER->RF_ENABLE_CONFIG46_FTDF_REG = 0x0000; // Disable the DCF triggered Partial DCOC |
| REG_SETF(DEM, RF_DC_OFFSET_CTRL2_REG, DCPARCAL_EN, 0x0); |
| |
| |
| switch (mode_ctrl) |
| { |
| case IFF_MODE_CTRL_BLE: // BLE |
| ret = iff_calib_internal(IFF_MODE_OVR_BLE, IFF_MODE_CTRL_BLE); |
| break; |
| |
| case IFF_MODE_CTRL_FTDF: // FTDF |
| ret = iff_calib_internal(IFF_MODE_OVR_FTDF, IFF_MODE_CTRL_FTDF); |
| break; |
| |
| case IFF_MODE_CTRL_COMBO: // COMBO |
| ret = iff_calib_internal(IFF_MODE_OVR_BLE, IFF_MODE_CTRL_COMBO); |
| |
| if (!ret) |
| { |
| ret = iff_calib_internal(IFF_MODE_OVR_FTDF, IFF_MODE_CTRL_COMBO); |
| } |
| |
| break; |
| } |
| |
| if (!ret) |
| { |
| return false; |
| } |
| |
| // Restore the values of registers that were changed in the function |
| RFCU->RF_CAL_CTRL_REG = rf_cal_ctrl_reg_value_local; |
| RFCU->RF_OVERRULE_REG = rf_overrule_reg_value_local; |
| RFCU_POWER->RF_ENABLE_CONFIG0_REG = rf_enable_config0_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG1_REG = rf_enable_config1_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG2_REG = rf_enable_config2_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG46_BLE_REG = rf_enable_config46_ble_reg_value; |
| RFCU_POWER->RF_ENABLE_CONFIG46_FTDF_REG = rf_enable_config46_ftdf_reg_value; |
| DEM->RF_DC_OFFSET_CTRL2_REG = rf_dc_offset_ctrl2_reg_value; |
| |
| // De-select the IF calcap to use the FSM value |
| REG_CLR_BIT(RFCU, RF_IFF_CTRL1_REG, IF_SELECT_FSM); |
| |
| return true; |
| } |
| #endif |
| |
| bool hw_rf_calibration(void) |
| { |
| bool iff_result; |
| |
| GLOBAL_INT_DISABLE(); |
| hw_rf_dc_offset_calibration(); |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| iff_result = hw_rf_iff_calibration(); |
| #else |
| #if defined(CONFIG_USE_FTDF) && defined(CONFIG_USE_BLE) |
| iff_result = hw_rf_iff_calibration(0x2); |
| #elif defined(CONFIG_USE_BLE) |
| iff_result = hw_rf_iff_calibration(0x0); |
| #elif defined(CONFIG_USE_FTDF) |
| iff_result = hw_rf_iff_calibration(0x1); |
| #endif |
| #endif |
| |
| if (iff_result) |
| { |
| #ifdef CONFIG_USE_FTDF |
| hw_rf_modulation_gain_calibration(0); |
| #endif |
| #ifdef CONFIG_USE_BLE |
| hw_rf_modulation_gain_calibration(1); |
| #endif |
| } |
| |
| GLOBAL_INT_RESTORE(); |
| |
| return iff_result; |
| } |
| |
| void hw_rf_request_on(bool mode_ble) |
| { |
| /* First RF requester. Switch it on */ |
| if (rf_request == 0) |
| { |
| if (rf_state == RF_ST_OFF) |
| { |
| hw_rf_poweron(); |
| rf_state = RF_ST_ON; |
| #if dg_configCOEX_ENABLE_CONFIG == 1 |
| hw_coex_apply_config(); |
| #endif |
| } |
| } |
| |
| if (mode_ble) |
| { |
| rf_request |= RF_REQUEST_BLE_ON; |
| } |
| else |
| { |
| rf_request |= RF_REQUEST_FTDF_ON; |
| } |
| |
| } |
| |
| |
| void hw_rf_request_off(bool mode_ble) |
| { |
| if (mode_ble) |
| { |
| rf_request &= ~RF_REQUEST_BLE_ON; |
| } |
| else |
| { |
| rf_request &= ~RF_REQUEST_FTDF_ON; |
| } |
| |
| /* If not already off or during recalibration... */ |
| if (rf_state == RF_ST_ON || rf_state == RF_ST_CONFIG) |
| { |
| /* If not RF requesters remain, switch it off */ |
| if (rf_request == 0) |
| { |
| /* If user pre-off cb returns true, don't shutdown */ |
| if (hw_rf_preoff_cb() == false) |
| { |
| hw_rf_poweroff(); |
| rf_state = RF_ST_OFF; |
| } |
| } |
| } |
| } |
| |
| |
| bool hw_rf_start_calibration() |
| { |
| bool iff_result; |
| |
| if (rf_state == RF_ST_CONFIG) |
| { |
| /* Call pre-calibration user cb */ |
| hw_rf_precalib_cb(); |
| |
| /* force RADIO_BUSY to BLE to 0 */ |
| REG_SETF(COEX, COEX_CTRL_REG, SEL_BLE_RADIO_BUSY, 1); |
| /* Ignore BLE/FTDF TX/RX_EN */ |
| REG_SET_BIT(COEX, COEX_CTRL_REG, IGNORE_BLE); |
| REG_SET_BIT(COEX, COEX_CTRL_REG, IGNORE_FTDF); |
| |
| /* Wait until DCFs have settled */ |
| while (REG_GETF(COEX, COEX_STAT_REG, COEX_RADIO_BUSY)); |
| |
| /* Perform DC offset calibration */ |
| hw_rf_dc_offset_calibration(); |
| |
| /* Perform IFF calibration */ |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| iff_result = hw_rf_iff_calibration(); |
| #else /* BLACK_ORCA_IC_REV_B */ |
| #if defined(CONFIG_USE_FTDF) && defined(CONFIG_USE_BLE) |
| iff_result = hw_rf_iff_calibration(0x2); |
| #elif defined(CONFIG_USE_BLE) |
| iff_result = hw_rf_iff_calibration(0x0); |
| #elif defined(CONFIG_USE_FTDF) |
| iff_result = hw_rf_iff_calibration(0x1); |
| #endif |
| #endif |
| |
| if (iff_result == false) |
| { |
| return false; |
| } |
| |
| NVIC_EnableIRQ(RFCAL_IRQn); |
| |
| #if defined(CONFIG_USE_FTDF) && defined(CONFIG_USE_BLE) |
| /* Start the gain calibration, on ftdf mode */ |
| hw_rf_modulation_gain_calibration_start(0); |
| rf_state = RF_ST_WAIT_NEXT1; |
| #elif defined(CONFIG_USE_FTDF) |
| /* Start the gain calibration, on ftdf mode */ |
| hw_rf_modulation_gain_calibration_start(0); |
| rf_state = RF_ST_WAIT_NEXT2; |
| #elif defined(CONFIG_USE_BLE) |
| /* Start the gain calibration, on ble mode */ |
| hw_rf_modulation_gain_calibration_start(1); |
| rf_state = RF_ST_WAIT_NEXT2; |
| #endif |
| |
| } |
| |
| return true; |
| } |
| |
| void RFCAL_Handler(void) |
| { |
| SEGGER_SYSTEMVIEW_ISR_ENTER(); |
| |
| uint32_t iser; |
| |
| /* Interrupts must be disabled. However, some callbacks actually |
| * use FreeRTOS critical sections. To overcome this problem. use |
| * ISER/ICER to enable/disable interrupts |
| */ |
| GLOBAL_INT_DISABLE(); |
| iser = NVIC->ISER[0];; |
| NVIC->ICER[0] = iser; |
| GLOBAL_INT_RESTORE(); |
| |
| switch (rf_state) |
| { |
| case RF_ST_WAIT_NEXT1: |
| |
| /* FTDF gain calib (boot) completed. Proceed with ble gain |
| * calib |
| */ |
| while (RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL)) {} |
| |
| hw_rf_modulation_gain_calibration_end(); |
| |
| /* Make sure RFCAL IRQ will be enabled when interrupts are enabled */ |
| iser |= ((uint32_t)(1 << RFCAL_IRQn)); |
| |
| /* Start the gain calibration, on ble mode */ |
| hw_rf_modulation_gain_calibration_start(1); |
| |
| rf_state = RF_ST_WAIT_NEXT2; |
| break; |
| |
| case RF_ST_WAIT_NEXT2: |
| |
| /* BLE (or ftdf) gain calib (boot) completed. |
| */ |
| while (RFCU->RF_CAL_CTRL_REG & REG_MSK(RFCU, RF_CAL_CTRL_REG, SO_CAL)) {} |
| |
| hw_rf_modulation_gain_calibration_end(); |
| |
| /* Make sure RFCAL IRQ will be disabled when interrupts are enabled */ |
| iser &= ~((uint32_t)(1 << RFCAL_IRQn)); |
| |
| /* Restore state to normal BLE/FTDF MAC operation */ |
| REG_CLR_BIT(COEX, COEX_CTRL_REG, IGNORE_BLE); |
| REG_CLR_BIT(COEX, COEX_CTRL_REG, IGNORE_FTDF); |
| REG_SETF(COEX, COEX_CTRL_REG, SEL_BLE_RADIO_BUSY, 0); |
| |
| /* Calibration complete. */ |
| /* Call post-calibration user cb */ |
| hw_rf_postcalib_cb(); |
| |
| /* Check if RF is still needed on, |
| * otherwise, switch it off |
| */ |
| if (rf_request == 0) |
| { |
| hw_rf_poweroff(); |
| rf_state = RF_ST_OFF; |
| } |
| else |
| { |
| rf_state = RF_ST_CONFIG; |
| hw_rf_postconf_cb(); |
| } |
| |
| break; |
| |
| default: |
| break; |
| } |
| |
| /* Re-enable interrupts */ |
| NVIC->ISER[0] = iser; |
| |
| SEGGER_SYSTEMVIEW_ISR_EXIT(); |
| } |
| |
| void hw_rf_request_recommended_settings(void) |
| { |
| if (rf_state == RF_ST_ON) |
| { |
| hw_rf_apply_tcs_cb(); |
| hw_rf_set_recommended_settings(); |
| |
| /* Initialize TX Power LUTs */ |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| hw_rf_set_tx_power(rf_tx_power_luts.tx_power_ble); |
| #else |
| #ifdef CONFIG_USE_BLE |
| hw_rf_set_tx_power_ble(rf_tx_power_luts.tx_power_ble); |
| #endif |
| #ifdef CONFIG_USE_FTDF |
| hw_rf_set_tx_power_ftdf(rf_tx_power_luts.tx_power_ftdf); |
| #endif |
| #endif |
| |
| rf_state = RF_ST_CONFIG; |
| hw_rf_postconf_cb(); |
| } |
| } |
| |
| bool __attribute__((weak)) hw_rf_preoff_cb(void) |
| { |
| return false; |
| } |
| |
| void hw_rf_start_continuous_wave(uint8_t mode, uint8_t ch) |
| { |
| REG_SETF(RFCU, RF_OVERRULE_REG, TX_EN_OVR, 1); // disable TX overrule |
| REG_SETF(RFCU, RF_OVERRULE_REG, TX_EN_OVR, 0); // NORMAL TX |
| |
| REG_SETF(PLLDIG, RF_BMCW_REG, CN_SEL, 1); |
| REG_SETF(PLLDIG, RF_BMCW_REG, CN_WR, ch); |
| |
| REG_SETF(RFCU, RF_OVERRULE_REG, RF_MODE_OVR, mode); |
| REG_SETF(RFCU, RF_OVERRULE_REG, TX_EN_OVR, 2); // OVERRULE TX ENABLED |
| } |
| |
| void hw_rf_stop_continuous_wave(void) |
| { |
| REG_SETF(PLLDIG, RF_BMCW_REG, CN_SEL, 0); |
| REG_SETF(PLLDIG, RF_BMCW_REG, CN_WR, 0); |
| |
| REG_SETF(RFCU, RF_OVERRULE_REG, TX_EN_OVR, 1); // disable TX overrule |
| REG_SETF(RFCU, RF_OVERRULE_REG, TX_EN_OVR, 0); // NORMAL TX |
| REG_SETF(RFCU, RF_OVERRULE_REG, RF_MODE_OVR, 0); // NORMAL RF mode, so disable BLE mode |
| } |
| |
| #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A |
| void hw_rf_set_tx_power(HW_RF_PWR_LUT_SETTING lut) |
| { |
| RFCU->RF_TX_PWR_REG = lut; |
| rf_tx_power_luts.tx_power_ble = lut; |
| } |
| #else |
| |
| #ifdef CONFIG_USE_BLE |
| void hw_rf_set_tx_power_ble(HW_RF_PWR_LUT_SETTING lut) |
| { |
| RFCU->RF_TX_PWR_BLE_REG = lut; |
| rf_tx_power_luts.tx_power_ble = lut; |
| } |
| #endif |
| |
| #ifdef CONFIG_USE_FTDF |
| void hw_rf_set_tx_power_ftdf(HW_RF_PWR_LUT_SETTING lut) |
| { |
| RFCU->RF_TX_PWR_FTDF_REG = lut; |
| rf_tx_power_luts.tx_power_ftdf = lut; |
| } |
| #endif |
| |
| #endif /* dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A */ |
| #endif /* dg_configUSE_HW_RF */ |
| /** |
| * \} |
| * \} |
| * \} |
| */ |