cc26x2_cc13x2: add setup_trim_device function

This function trims the necessary registers for the device to operate
normally.

Signed-off-by: Jean Pierre Dudey <jeandudey@hotmail.com>
This commit is contained in:
Jean Pierre Dudey 2020-04-29 18:11:27 -05:00
parent dc1d2ace42
commit 951a99dba3
No known key found for this signature in database
GPG Key ID: 631A70D74E41F1AD
5 changed files with 325 additions and 0 deletions

View File

@ -33,6 +33,9 @@ void cpu_init(void)
/* initialize the Cortex-M core */ /* initialize the Cortex-M core */
cortexm_init(); cortexm_init();
/* trim device */
setup_trim_device();
/* initialize stdio prior to periph_init() to allow use of DEBUG() there */ /* initialize stdio prior to periph_init() to allow use of DEBUG() there */
stdio_init(); stdio_init();

View File

@ -0,0 +1,121 @@
/*
* Copyright (C) 2020 Locha Inc
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup cpu_cc26x2_cc13x2
* @{
*
* @file
* @brief CC26x2/CC13x2 Device setup functions
*/
#ifndef CC26X2_CC13X2_SETUP_H
#define CC26X2_CC13X2_SETUP_H
#include <cc26xx_cc13xx.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Setup API address
*/
#define ROM_API_SETUP ((uint32_t *) (ROM_API_TABLE[28]))
/**
* @brief Setup API ROM functions
* @{
*/
#define rom_setup_after_cold_reset_wakeup_from_shutdown_cfg1 \
((void (*)(uint32_t mode_conf))ROM_API_SETUP[0])
#define rom_setup_after_cold_reset_wakeup_from_shutdown_cfg2 \
((void (*)(uint32_t rev, uint32_t mode_conf))ROM_API_SETUP[1])
#define rom_setup_after_cold_reset_wakeup_from_shutdown_cfg3 \
((void (*)(uint32_t mode_conf))ROM_API_SETUP[2])
#define rom_setup_get_trim_for_adc_sh_mode_en \
((uint32_t (*)(uint32_t rev))ROM_API_SETUP[3])
#define rom_setup_get_trim_for_adc_sh_vbuf_en \
((uint32_t (*)(uint32_t rev))ROM_API_SETUP[4])
#define rom_setup_get_trim_for_ampcomp_ctrl \
((uint32_t (*)(uint32_t rev))ROM_API_SETUP[5])
#define rom_setup_get_trim_for_ampcomp_th1 \
((uint32_t (*)(void))ROM_API_SETUP[6])
#define rom_setup_get_trim_for_ampcomp_th2 \
((uint32_t (*)(void))ROM_API_SETUP[7])
#define rom_setup_get_trim_for_anabypass_value1 \
((uint32_t (*)(uint32_t mode_conf))ROM_API_SETUP[8])
#define rom_setup_get_trim_for_dblr_loop_filter_reset_voltage \
((uint32_t (*)(uint32_t rev))ROM_API_SETUP[9])
#define rom_setup_get_trim_for_radc_ext_cfg \
((uint32_t (*)(uint32_t rev))ROM_API_SETUP[10])
#define rom_setup_get_trim_for_rc_osc_lf_ibias_trim \
((uint32_t (*)(uint32_t rev))ROM_API_SETUP[11])
#define rom_setup_get_trim_for_rc_osc_lf_rtune_ctune_trim \
((uint32_t (*)(void))ROM_API_SETUP[12])
#define rom_setup_get_trim_for_xosc_hf_ctl \
((uint32_t (*)(uint32_t rev))ROM_API_SETUP[13])
#define rom_setup_get_trim_for_xosc_hf_fast_start \
((uint32_t (*)(void))ROM_API_SETUP[14])
#define rom_setup_get_trim_for_xosc_hf_ibiastherm \
((uint32_t (*)(void))ROM_API_SETUP[15])
#define rom_setup_get_trim_for_xosc_lf_regulator_and_cmirrwr_ratio \
((uint32_t (*)(uint32_t rev))ROM_API_SETUP[16])
#define rom_setup_set_aon_rtc_sub_sec_inc \
((void (*)(uint32_t subsecinc))ROM_API_SETUP[17])
#define rom_setup_set_cache_mode_according_to_ccfg_setting \
((void (*)(void))ROM_API_SETUP[18])
#define rom_setup_step_vddr_trim_to \
((void (*)(uint32_t tocode))ROM_API_SETUP[19])
/** @} */
/**
* @brief Performs the necessary trim of the device which is not done in ROM
* boot code.
*
* The following is handled by this function:
*
* - Checks if the driverlib variant used by the application is supported by the
* device. Execution is halted in case of unsupported driverlib variant.
* - Configures VIMS cache mode based on setting in CCFG.
* - Configures functionalities like DCDC and XOSC dependent on startup modes
* like cold reset, wakeup from shutdown and wakeup from from powerdown.
* - Configures VIMS power domain control.
* - Configures optimal wait time for flash FSM in cases where flash pump wakes
* up from sleep.
*
* @note It does no damage to execute this function again. It only consumes
* time.
*/
void setup_trim_device(void);
#ifdef __cplusplus
} /* end extern "C" */
#endif
#endif /* CC26X2_CC13X2_SETUP_H */
/** @} */

View File

@ -27,6 +27,7 @@
#include "cc26x2_cc13x2_aux.h" #include "cc26x2_cc13x2_aux.h"
#include "cc26x2_cc13x2_fcfg.h" #include "cc26x2_cc13x2_fcfg.h"
#include "cc26x2_cc13x2_prcm.h" #include "cc26x2_cc13x2_prcm.h"
#include "cc26x2_cc13x2_setup.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {

198
cpu/cc26x2_cc13x2/setup.c Normal file
View File

@ -0,0 +1,198 @@
/*
* Copyright (C) 2020 Locha Inc
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for more
* details.
*/
/**
* @ingroup cpu_cc26x2_cc13x2
* @{
*
* @file
* @brief CC26x2, CC13x2 Functions to setup the device
*
* @author Jean Pierre Dudey <jeandudey@hotmail.com>
* @}
*/
#include "cpu.h"
/**
* @brief Optimal wait time in cases where flash pump wakes up from sleep.
*/
#define FPAC1_OPTIMAL_PSLEEPTDIS (0x139)
/**
* @brief Trims to be applied when coming from PIN_RESET.
*/
__attribute__ ((weak)) void trim_after_cold_reset(void)
{
/* Currently no specific trim for Cold Reset */
}
/**
* @brief Trims to be applied when coming from POWER_DOWN (also called when
* coming from SHUTDOWN and PIN_RESET).
*/
__attribute__ ((weak)) void trim_after_cold_reset_wakeup_from_shutdown_wakeup_from_powerdown(void)
{
/* Currently no specific trim for Powerdown */
}
/**
* @brief Trims to be applied when coming from SHUTDOWN (also called when
* coming from PIN_RESET).
*
* @param[in] fcfg_rev FCFG1 revision
*/
void trim_after_cold_reset_wakeup_from_shutdown(uint32_t fcfg_rev)
{
uint32_t ccfg_mode_conf_reg;
/* Check in CCFG for alternative DCDC setting */
if ((CCFG->SIZE_AND_DIS_FLAGS & CCFG_SIZE_AND_DIS_FLAGS_DIS_ALT_DCDC_SETTING) == 0) {
/* ADI_3_REFSYS:DCDCCTL5[3] (=DITHER_EN) = CCFG_MODE_CONF_1[19] (=ALT_DCDC_DITHER_EN)
* ADI_3_REFSYS:DCDCCTL5[2:0](=IPEAK ) = CCFG_MODE_CONF_1[18:16](=ALT_DCDC_IPEAK )
*
* Using a single 4-bit masked write since layout is equal for both
* source and destination
*/
ADI3_M4->DCDCCTL5.LOW = 0xF0 | (CCFG->MODE_CONF_1 >>
CCFG_MODE_CONF_1_ALT_DCDC_IPEAK_s);
}
/* Force DCDC to use RCOSC before starting up XOSC.
* Clock loss detector does not use XOSC until SCLK_HF actually switches
* and thus DCDC is not protected from clock loss on XOSC in that time frame.
* The force must be released when the switch to XOSC has happened. */
DDI_0_OSC_M16->CTL0.HIGH = DDI_0_OSC_CTL0_CLK_DCDC_SRC_SEL_m |
(DDI_0_OSC_CTL0_CLK_DCDC_SRC_SEL_m >> 16);
/* Dummy read to ensure that the write has propagated */
DDI_0_OSC->CTL0;
/* Read the MODE_CONF register in CCFG */
ccfg_mode_conf_reg = CCFG->MODE_CONF;
/* First part of trim done after cold reset and wakeup from shutdown:
*
* - Adjust the VDDR_TRIM_SLEEP value.
* - Configure DCDC.
*/
rom_setup_after_cold_reset_wakeup_from_shutdown_cfg1(ccfg_mode_conf_reg);
/* Addition to the CC1352 boost mode for HWREV >= 2.0
* The combination VDDR_EXT_LOAD=0 and VDDS_BOD_LEVEL=1 is defined to select
* boost mode */
if (((ccfg_mode_conf_reg & CCFG_MODE_CONF_VDDR_EXT_LOAD) == 0) &&
((ccfg_mode_conf_reg & CCFG_MODE_CONF_VDDS_BOD_LEVEL) != 0)) {
ADI3->DCDCCTL3 = ADI_3_REFSYS_DCDCCTL3_VDDR_BOOST_COMP_BOOST;
}
/* Second part of trim done after cold reset and wakeup from shutdown:
*
* - Configure XOSC.
*/
rom_setup_after_cold_reset_wakeup_from_shutdown_cfg2(fcfg_rev, ccfg_mode_conf_reg);
{
uint32_t trim_reg;
uint32_t trim_value;
/* Propagate the LPM_BIAS trim */
trim_reg = FCFG->DAC_BIAS_CNF;
trim_value = (trim_reg & FCFG1_DAC_BIAS_CNF_LPM_TRIM_IOUT_m) >>
FCFG1_DAC_BIAS_CNF_LPM_TRIM_IOUT_s;
ADI_4_AUX->LPMBIAS = (trim_value << ADI_4_AUX_LPMBIAS_LPM_TRIM_IOUT_s) &
ADI_4_AUX_LPMBIAS_LPM_TRIM_IOUT_m;
/* Set LPM_BIAS_BACKUP_EN according to FCFG1 configuration */
if (trim_reg & FCFG1_DAC_BIAS_CNF_LPM_BIAS_BACKUP_EN) {
ADI3_SET->AUX_DEBUG = ADI_3_REFSYS_AUX_DEBUG_LPM_BIAS_BACKUP_EN;
}
else {
ADI3_CLR->AUX_DEBUG = ADI_3_REFSYS_AUX_DEBUG_LPM_BIAS_BACKUP_EN;
}
/* Set LPM_BIAS_WIDTH_TRIM according to FCFG1 configuration */
{
uint32_t width_trim = (trim_reg & FCFG1_DAC_BIAS_CNF_LPM_BIAS_WIDTH_TRIM_m) >>
FCFG1_DAC_BIAS_CNF_LPM_BIAS_WIDTH_TRIM_s;
/* Set LPM_BIAS_WIDTH_TRIM = 3
* Set mask (bits to be written) in [15:8]
* Set value (in correct bit pos) in [7:0]
*/
ADI_4_AUX_M8->COMP = (ADI_4_AUX_COMP_LPM_BIAS_WIDTH_TRIM_m << 8) |
(width_trim << ADI_4_AUX_COMP_LPM_BIAS_WIDTH_TRIM_s);
}
}
/* Third part of trim done after cold reset and wakeup from shutdown:
*
* - Configure HPOSC.
* - Setup the LF clock.
*/
rom_setup_after_cold_reset_wakeup_from_shutdown_cfg3(ccfg_mode_conf_reg);
/* Set AUX into power down active mode */
aux_sysif_opmode_change(AUX_SYSIF_OPMODEREQ_REQ_PDA);
/* Disable EFUSE clock */
FLASH->CFG |= FLASH_CFG_DIS_EFUSECLK;
}
void setup_trim_device(void)
{
/* Get factory configuration revision, treat undefined revision as 0 */
uint32_t fcfg_rev = FCFG->FCFG1_REVISION;
if (fcfg_rev == 0xFFFFFFFF) {
fcfg_rev = 0;
}
/* Enable standby in flash bank */
FLASH->CFG &= ~FLASH_CFG_DIS_STANDBY;
if (!(AON_IOC->IOCLATCH & AON_IOC_IOCLATCH_EN)) {
trim_after_cold_reset_wakeup_from_shutdown_wakeup_from_powerdown();
}
else if (!(AON_PMCTL->SLEEPCTL & AON_PMCTL_SLEEPCTL_IO_PAD_SLEEP_DIS)) {
trim_after_cold_reset_wakeup_from_shutdown(fcfg_rev);
trim_after_cold_reset_wakeup_from_shutdown_wakeup_from_powerdown();
}
else {
trim_after_cold_reset();
trim_after_cold_reset_wakeup_from_shutdown(fcfg_rev);
trim_after_cold_reset_wakeup_from_shutdown_wakeup_from_powerdown();
}
/* Set VIMS power domain */
PRCM->PDCTL1VIMS = 0;
/* Configure optimal wait time for flash FSM in cases where flash pump
* wakes up from sleep */
FLASH->FPAC1 = (FLASH->FPAC1 & ~FLASH_FPAC1_PSLEEPTDIS_m) |
(FPAC1_OPTIMAL_PSLEEPTDIS << FLASH_FPAC1_PSLEEPTDIS_s);
/* Set BOOT_DET bits in AON_PMCTL to 3 if already found to be 1.
* Note: The BOOT_DET_x_CLR/SET bits must be manually cleared */
uint32_t boot_det_m = AON_PMCTL_RESETCTL_BOOT_DET_1_m |
AON_PMCTL_RESETCTL_BOOT_DET_0_m;
uint32_t boot_det = (AON_PMCTL->RESETCTL & boot_det_m) >>
AON_PMCTL_RESETCTL_BOOT_DET_0_s;
if (boot_det == 1) {
uint32_t aon_sys_resetctl = AON_PMCTL->RESETCTL &
~(AON_PMCTL_RESETCTL_BOOT_DET_1_CLR_m |
AON_PMCTL_RESETCTL_BOOT_DET_0_CLR_m |
AON_PMCTL_RESETCTL_BOOT_DET_1_SET_m |
AON_PMCTL_RESETCTL_BOOT_DET_0_SET_m |
AON_PMCTL_RESETCTL_MCU_WARM_RESET_m);
AON_PMCTL->RESETCTL = aon_sys_resetctl |
AON_PMCTL_RESETCTL_BOOT_DET_1_SET_m;
AON_PMCTL->RESETCTL = aon_sys_resetctl;
}
/* Make sure there are no ongoing VIMS mode change when leaving (There
* should typically be no wait time here, but need to be sure) */
while (VIMS->STAT & VIMS_STAT_MODE_CHANGING) {}
}

View File

@ -144,6 +144,8 @@ typedef enum IRQn
#define FLASH_BASE 0x00000000 /**< FLASH base address */ #define FLASH_BASE 0x00000000 /**< FLASH base address */
#define PERIPH_BASE 0x40000000 /**< Peripheral base address */ #define PERIPH_BASE 0x40000000 /**< Peripheral base address */
#define PERIPH_BASE_NONBUF 0x60000000 /**< Peripheral base address (nonbuf) */ #define PERIPH_BASE_NONBUF 0x60000000 /**< Peripheral base address (nonbuf) */
#define ROM_API_TABLE ((uint32_t *) 0x10000180) /**< ROM API table */
/*@}*/ /*@}*/
/** /**