/** **************************************************************************************** * @brief Read single series of bytes from I2C EEPROM (for driver's internal use) * * @param[in] p Memory address to read the series of bytes from (all in the same page) * @param[in] size count of bytes to read (must not cross page) **************************************************************************************** */ static void read_data_single(uint8_t **p, uint32_t address, uint32_t size) { int j; i2c_send_address(address); for (j = 0; j < size; j++) { WAIT_WHILE_I2C_FIFO_IS_FULL(); // Wait if Tx FIFO is full SEND_I2C_COMMAND(0x0100); // Set read access for <size> times } // Critical section GLOBAL_INT_DISABLE(); // Get the received data for (j = 0; j < size; j++) { WAIT_FOR_RECEIVED_BYTE(); // Wait for received data **p =(0xFF & GetWord16(I2C_DATA_CMD_REG)); // Get the received byte (*p)++; } // End of critical section GLOBAL_INT_RESTORE(); }
void hw_fem_stop(void) { GLOBAL_INT_DISABLE(); fem_config.started = false; /* Stop DCF Timers */ #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A RFCU_POWER->RF_PORT_EN_REG = 0x0; #else RFCU_POWER->RF_PORT_EN_BLE_REG = 0x0; RFCU_POWER->RF_PORT_EN_FTDF_REG = 0x0; #endif /* Set all FEM interface outputs to GPIO mode, and value 0, in order to get the minimum * possible power consumption from FEM */ #if defined(dg_configFEM_SKY66112_11_CSD_PORT) && defined(dg_configFEM_SKY66112_11_CSD_PIN) hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CSD_PORT, dg_configFEM_SKY66112_11_CSD_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false); #endif hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CTX_PORT, dg_configFEM_SKY66112_11_CTX_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false); #if defined(dg_configFEM_SKY66112_11_CHL_PORT) && defined(dg_configFEM_SKY66112_11_CHL_PIN) hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CHL_PORT, dg_configFEM_SKY66112_11_CHL_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false); #endif hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CRX_PORT, dg_configFEM_SKY66112_11_CRX_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false); #if defined(dg_configFEM_SKY66112_11_CPS_PORT) && defined(dg_configFEM_SKY66112_11_CPS_PIN) hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CPS_PORT, dg_configFEM_SKY66112_11_CPS_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false); #endif #if defined(dg_configFEM_SKY66112_11_ANTSEL_PORT) && defined(dg_configFEM_SKY66112_11_ANTSEL_PIN) hw_gpio_configure_pin(dg_configFEM_SKY66112_11_ANTSEL_PORT, dg_configFEM_SKY66112_11_ANTSEL_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false); #endif #if defined(dg_configFEM_SKY66112_11_ANT_TRIM_0_PORT) && defined(dg_configFEM_SKY66112_11_ANT_TRIM_0_PIN) hw_gpio_configure_pin(dg_configFEM_SKY66112_11_ANT_TRIM_0_PORT, dg_configFEM_SKY66112_11_ANT_TRIM_0_PORT, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false); #endif #if defined(dg_configFEM_SKY66112_11_ANT_TRIM_1_PORT) && defined(dg_configFEM_SKY66112_11_ANT_TRIM_1_PIN) hw_gpio_configure_pin(dg_configFEM_SKY66112_11_ANT_TRIM_1_PORT, dg_configFEM_SKY66112_11_ANT_TRIM_1_PORT, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false); #endif #if defined(dg_configFEM_SKY66112_11_ANT_TRIM_2_PORT) && defined(dg_configFEM_SKY66112_11_ANT_TRIM_2_PIN) hw_gpio_configure_pin(dg_configFEM_SKY66112_11_ANT_TRIM_2_PORT, dg_configFEM_SKY66112_11_ANT_TRIM_2_PORT, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false); #endif GLOBAL_INT_RESTORE(); }
void hw_fem_set_txpower_ftdf(bool high) { #if defined(dg_configFEM_SKY66112_11_CHL_PORT) && defined(dg_configFEM_SKY66112_11_CHL_PIN) GLOBAL_INT_DISABLE(); fem_config.tx_power_ftdf = high; set_txpower(); GLOBAL_INT_RESTORE(); #endif }
void hw_aes_hash_disable(const bool waitOnFinish) { if (waitOnFinish) hw_aes_hash_wait_on_inactive(); REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN); GLOBAL_INT_DISABLE(); REG_CLR_BIT(CRG_TOP, CLK_AMBA_REG, AES_CLK_ENABLE); GLOBAL_INT_RESTORE(); NVIC_DisableIRQ(CRYPTO_IRQn); }
void hw_aes_hash_disable(const bool waitOnFinish) { if (waitOnFinish) hw_aes_hash_wait_on_inactive(); hw_aes_hash_disable_interrupt_source(); AES_HASH->CRYPTO_CLRIRQ_REG = 1; GLOBAL_INT_DISABLE(); REG_CLR_BIT(CRG_TOP, CLK_AMBA_REG, AES_CLK_ENABLE); GLOBAL_INT_RESTORE(); REG_CLR_BIT(AES_HASH, CRYPTO_CTRL_REG, CRYPTO_MORE_IN); }
void hw_trng_enable(hw_trng_cb callback) { if (callback != NULL) { trng_cb = callback; hw_trng_clear_pending(); NVIC_EnableIRQ(TRNG_IRQn); } GLOBAL_INT_DISABLE(); REG_SET_BIT(CRG_TOP, CLK_AMBA_REG, TRNG_CLK_ENABLE); GLOBAL_INT_RESTORE(); REG_SET_BIT(TRNG, TRNG_CTRL_REG, TRNG_ENABLE); }
void hw_fem_set_rx_bypass_ftdf(bool enable) { #if defined(dg_configFEM_SKY66112_11_CPS_PORT) && defined(dg_configFEM_SKY66112_11_CPS_PIN) GLOBAL_INT_DISABLE(); fem_config.rx_bypass_ftdf = enable; if (fem_config.started) { set_bypass(); } GLOBAL_INT_RESTORE(); #endif }
void hw_fem_set_antenna(bool one) { #if defined(dg_configFEM_SKY66112_11_ANTSEL_PORT) && defined(dg_configFEM_SKY66112_11_ANTSEL_PIN) GLOBAL_INT_DISABLE(); fem_config.antsel = one; if (fem_config.started) { /* Antenna selection */ hw_gpio_configure_pin(dg_configFEM_SKY66112_11_ANTSEL_PORT, dg_configFEM_SKY66112_11_ANTSEL_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, fem_config.antsel); } GLOBAL_INT_RESTORE(); #endif }
void hw_timer0_init(const timer0_config *cfg) { /* Enable clock for peripheral */ GLOBAL_INT_DISABLE(); uint32_t clk_tmr_reg = CRG_TOP->CLK_TMR_REG; clk_tmr_reg &= ~CRG_TOP_CLK_TMR_REG_TMR0_DIV_Msk; clk_tmr_reg &= ~CRG_TOP_CLK_TMR_REG_TMR0_CLK_SEL_Msk; clk_tmr_reg |= CRG_TOP_CLK_TMR_REG_TMR0_ENABLE_Msk; CRG_TOP->CLK_TMR_REG = clk_tmr_reg ; GLOBAL_INT_RESTORE(); /* Reset control register, i.e. disable timer */ GP_TIMERS->TIMER0_CTRL_REG = 0x0; /* Disable NVIC interrupt */ NVIC_DisableIRQ(SWTIM0_IRQn); intr_cb = NULL; hw_timer0_configure(cfg); }
/** **************************************************************************************** * @brief Writes page to I2C EEPROM. * * @param[in] address Starting address of memory page. * @param[in] wr_data_ptr Pointer to the first of bytes to be written. * @param[in] size Size of the data to be written (MUST BE LESS OR EQUAL TO I2C_EEPROM_PAGE). * * @return Count of bytes that were actually written **************************************************************************************** */ uint16_t i2c_eeprom_write_page(uint8_t *wr_data_ptr, uint32_t address, uint16_t size) { uint16_t feasible_size; uint16_t bytes_written = 0; if (address < I2C_EEPROM_SIZE) { // max possible write size without crossing page boundary feasible_size = I2C_EEPROM_PAGE - (address % I2C_EEPROM_PAGE); if (size < feasible_size) feasible_size = size; // adjust limit accordingly i2c_wait_until_eeprom_ready(); // Critical section GLOBAL_INT_DISABLE(); i2c_send_address(address); do { WAIT_WHILE_I2C_FIFO_IS_FULL(); // Wait if I2c Tx FIFO is full SEND_I2C_COMMAND(*wr_data_ptr & 0xFF); // Send write data wr_data_ptr++; feasible_size--; bytes_written++; } while (feasible_size != 0); // End of critical section GLOBAL_INT_RESTORE(); WAIT_UNTIL_I2C_FIFO_IS_EMPTY(); // Wait until Tx FIFO is empty WAIT_UNTIL_NO_MASTER_ACTIVITY(); // Wait until no master activity } return bytes_written; }
void hw_i2c_init(HW_I2C_ID id, const i2c_config *cfg) { IRQn_Type irq_type = I2C_IRQn; int enable_loop_cnt = 0; if (id == HW_I2C2) { irq_type = I2C2_IRQn; } else if (id != HW_I2C1) { /* Requested ID must be one of HW_I2C1 or HW_I2C2 */ ASSERT_ERROR(0); } struct i2c *i2c = get_i2c(id); memset(i2c, 0, sizeof(*i2c)); GLOBAL_INT_DISABLE(); uint32_t clk_per_reg_local = CRG_PER->CLK_PER_REG; REG_SET_FIELD(CRG_PER, CLK_PER_REG, I2C_CLK_SEL, clk_per_reg_local, 0); REG_SET_FIELD(CRG_PER, CLK_PER_REG, I2C_ENABLE, clk_per_reg_local, 1); CRG_PER->CLK_PER_REG = clk_per_reg_local; GLOBAL_INT_RESTORE(); hw_i2c_disable(id); while (hw_i2c_get_enable_status(id) & I2C_I2C_ENABLE_STATUS_REG_IC_EN_Msk) { hw_cpm_delay_usec(500); enable_loop_cnt++; /* we shouldn't get stuck here, the HW I2C block should eventually be enabled */ ASSERT_ERROR(enable_loop_cnt < I2C_ENABLE_LOOP_LIMIT); } IBA(id)->I2C_INTR_MASK_REG = 0x0000; hw_i2c_configure(id, cfg); NVIC_EnableIRQ(irq_type); }
static __RETAINED_CODE void configure_cache(void) { bool flush = false; GLOBAL_INT_DISABLE(); if (dg_configCACHEABLE_QSPI_AREA_LEN != -1) { uint32_t cache_len; /* dg_configCACHEABLE_QSPI_AREA_LEN must be 64KB-aligned */ ASSERT_WARNING((dg_configCACHEABLE_QSPI_AREA_LEN & 0xFFFF) == 0); /* * dg_configCACHEABLE_QSPI_AREA_LEN shouldn't set any bits that do not fit in * CACHE_CTRL2_REG.CACHE_LEN (9 bits wide) after shifting out the lower 16 bits */ ASSERT_WARNING((dg_configCACHEABLE_QSPI_AREA_LEN & 0x1FF0000) == dg_configCACHEABLE_QSPI_AREA_LEN); /* * set cacheable area * * setting CACHE_CTRL2_REG.CACHE_LEN to N, actually sets the size of the cacheable * area to (N + 1) * 64KB * special cases: * N == 0 --> no caching * N == 1 --> 128KB are cached, i.e. no way to cache only 64KB */ cache_len = dg_configCACHEABLE_QSPI_AREA_LEN >> 16; /* cannot cache only 64KB! */ ASSERT_WARNING(cache_len != 1); if (cache_len > 1) { cache_len--; } REG_SETF(CACHE, CACHE_CTRL2_REG, CACHE_LEN, cache_len); }
void hw_fem_set_txpower(bool high) { #if defined(dg_configFEM_SKY66112_11_CHL_PORT) && defined(dg_configFEM_SKY66112_11_CHL_PIN) GLOBAL_INT_DISABLE(); fem_config.tx_power = high; if (fem_config.started) { if (high == false) { /* TX Power low. Stop DCF, set GPIO to low */ hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CHL_PORT, dg_configFEM_SKY66112_11_CHL_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, false); REG_SET_MASKED(RFCU_POWER, RF_PORT_EN_REG, RFCU_POWER_RF_PORT_EN_REG_RF_PORT4_RX_Msk | RFCU_POWER_RF_PORT_EN_REG_RF_PORT4_TX_Msk, 0); } else { /* TX Power high. Configure GPIO for DCF. Enable DCF on TX. */ hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_CHL_PORT, dg_configFEM_SKY66112_11_CHL_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_PORT4_DCF); REG_SET_MASKED(RFCU_POWER, RF_PORT_EN_REG, RFCU_POWER_RF_PORT_EN_REG_RF_PORT4_RX_Msk | RFCU_POWER_RF_PORT_EN_REG_RF_PORT4_TX_Msk, RFCU_POWER_RF_PORT_EN_REG_RF_PORT4_TX_Msk); } } GLOBAL_INT_RESTORE(); #endif }
/** **************************************************************************************** * @brief Enable sleep mode * @param[in] mode sleep mode * @param[in] iconfig wakeup interrupt config * @param[in] callback callback after wakeup * @description * This function is used to set MCU into sleep mode, before enter sleep, wakeup source should be set. ***************************************************************************************** */ void enter_sleep(enum SLEEP_MODE mode, uint32_t iconfig, void (*callback)(void)) { if (mode == SLEEP_CPU_CLK_OFF) { // -------------------------------------------- // cpu clock disable // -------------------------------------------- // Ensure we use deep SLEEP - SLEEPDEEP should be set // SCR[2] = SLEEPDEEP SCB->SCR |= (1UL << 2); // set pd state to deep gating syscon_SetPGCR2WithMask(QN_SYSCON, SYSCON_MASK_PD_STATE|SYSCON_MASK_PMUENABLE, MASK_DISABLE); GLOBAL_INT_DISABLE(); #if SLEEP_CONFIG_EN == TRUE NVIC->ISER[0] = iconfig; #endif // Wait For Interrupt __WFI(); // Enter sleep mode // Wakeup when interrupt is triggered GLOBAL_INT_RESTORE(); // TODO } else if ((mode == SLEEP_NORMAL) || (mode == SLEEP_DEEP)) { #if QN_LOW_POWER_MODE_EN==TRUE enter_low_power_mode(0); // -------------------------------------------- // cpu clock disable // -------------------------------------------- // Ensure we use deep SLEEP - SLEEPDEEP should be set // SCR[2] = SLEEPDEEP SCB->SCR |= (1UL << 2); #else // -------------------------------------------- // sleep or deep sleep // -------------------------------------------- #ifdef BLE_PRJ // Save configuration before power down save_ble_setting(); #endif #if (defined(QN_9020_B1) && QN_PMU_VOLTAGE) // Switch off REF PLL power syscon_SetPGCR1WithMask(QN_SYSCON, SYSCON_MASK_DIS_REF_PLL, MASK_ENABLE); #endif // switch to internal 20MHz syscon_SetCMDCRWithMask(QN_SYSCON, SYSCON_MASK_CLK_MUX, CLK_INT_20M<<SYSCON_POS_CLK_MUX); if(mode == SLEEP_NORMAL) { #if (QN_DEEP_SLEEP_EN) sleep_env.deep_sleep = false; #endif // power down all module in sleep except 32K and retention memory syscon_SetPGCR0WithMask(QN_SYSCON, sleep_env.retention_modules|0x00000001, 0x00000001); } else { #if (QN_DEEP_SLEEP_EN) sleep_env.deep_sleep = true; #endif // power down all module in deep sleep except retention memory #if (defined(QN_9020_B2) || defined(QN_9020_B1)) syscon_SetPGCR0WithMask(QN_SYSCON, 0xF7FFFCFF, 0xFFFFFC01|~sleep_env.retention_modules); #elif defined(QN_9020_B0) syscon_SetPGCR0WithMask(QN_SYSCON, 0xFFFFFCFF, 0xFFFFFC01|~sleep_env.retention_modules); #endif } #if (defined(QN_9020_B0) && QN_PMU_VOLTAGE) syscon_SetCMDCRWithMask(QN_SYSCON, SYSCON_MASK_AHB_DIV_BYPASS|SYSCON_MASK_AHB_DIVIDER, (0xf<<SYSCON_POS_AHB_DIVIDER)); #endif // Ensure we use deep SLEEP - SLEEPDEEP should be set // SCR[2] = SLEEPDEEP SCB->SCR |= (1UL << 2); // set pd state to sleep #if !QN_PMU_VOLTAGE syscon_SetPGCR2WithMask(QN_SYSCON, SYSCON_MASK_PD_STATE|SYSCON_MASK_DVDD12_PMU_SET|SYSCON_MASK_PMUENABLE, MASK_ENABLE); #else syscon_SetPGCR2WithMask(QN_SYSCON, SYSCON_MASK_PD_STATE|SYSCON_MASK_PMUENABLE, MASK_ENABLE); #endif syscon_SetIvrefX32WithMask(QN_SYSCON, SYSCON_MASK_VREG12_A|SYSCON_MASK_VREG12_D|SYSCON_MASK_DVDD12_SW_EN, (0x0 << SYSCON_POS_VREG12_A)|(0x0 << SYSCON_POS_VREG12_D)); #endif // QN_LOW_POWER_MODE_EN==TRUE #if SLEEP_CONFIG_EN == TRUE NVIC->ICPR[0] = 0x00000020; // clear OSC_EN pending flag NVIC->ISER[0] = iconfig; #endif // Wait For Interrupt __WFI(); // Enter sleep mode // Wakeup when sleep timer, comparator or gpio is triggered // Disable interrupt in the wakeup procedure. NVIC->ICER[0] = iconfig; #if QN_LOW_POWER_MODE_EN==TRUE #ifdef BLE_PRJ restore_from_low_power_mode(NULL); #else restore_from_low_power_mode(callback); #endif #else // 1.2V syscon_SetIvrefX32WithMask(QN_SYSCON, SYSCON_MASK_VREG12_A|SYSCON_MASK_VREG12_D|SYSCON_MASK_DVDD12_SW_EN, (0x1 << SYSCON_POS_VREG12_A)|(0x0 << SYSCON_POS_VREG12_D)|SYSCON_MASK_DVDD12_SW_EN); #if (defined(QN_9020_B0) && QN_PMU_VOLTAGE) syscon_SetCMDCRWithMask(QN_SYSCON, SYSCON_MASK_AHB_DIV_BYPASS, MASK_ENABLE); #endif syscon_SetPGCR2WithMask(QN_SYSCON, SYSCON_MASK_PD_STATE|SYSCON_MASK_DVDD12_PMU_SET, MASK_DISABLE); #if SLEEP_CALLBACK_EN == TRUE if (callback != NULL) { callback(); } #endif #if (defined(QN_9020_B0) && QN_PMU_VOLTAGE) syscon_set_ahb_clk(__AHB_CLK); #endif // 16MHz/32MHz XTAL is ready while (!(syscon_GetBLESR(QN_SYSCON) & SYSCON_MASK_CLK_RDY)) { // XTAL shall be ready before BLE wakeup if(check_ble_wakeup()) { // In this case XTAL wakeup duration is larger than setting. // The parameter 'Oscillator wake-up time' in the NVDS should be revised. #if (QN_DBG_INFO) set_dbg_info(QN_DBG_INFO_XTAL_WAKEUP_DURATION); #endif } } syscon_SetCMDCRWithMask(QN_SYSCON, SYSCON_MASK_CLK_MUX, CLK_XTAL<<SYSCON_POS_CLK_MUX); #endif // QN_LOW_POWER_MODE_EN==TRUE #if ((defined(QN_9020_B2) || defined(QN_9020_B1)) && defined(BLE_PRJ)) sleep_post_process(); #endif } }
void fsm_scan_update(void) { switch(current_scan_state) { case KEY_SCAN_INACTIVE: if (DEVELOPMENT_DEBUG && (systick_hit || wkup_hit)) { ASSERT_ERROR(0); } if (HAS_DELAYED_WAKEUP) { app_kbd_enable_delayed_scanning(true); } else { app_kbd_enable_scanning(); } current_scan_state = KEY_SCAN_IDLE; // Transition from KEY_SCAN_INACTIVE -> KEY_SCAN_IDLE break; case KEY_SCAN_IDLE: if (DEVELOPMENT_DEBUG && systick_hit) { ASSERT_ERROR(0); } if (wkup_hit) { // dbg_puts(DBG_SCAN_LVL, "KEY_SCAN_IDLE -> Wakeup! -> KEY_SCANNING\r\n"); scanning_substate = 0; GLOBAL_INT_DISABLE(); current_scan_state = KEY_SCANNING; // Transition from KEY_SCAN_IDLE -> KEY_SCANNING app_kbd_start_scanning(); wkup_hit = false; GLOBAL_INT_RESTORE(); } break; case KEY_STATUS_UPD: if (DEVELOPMENT_DEBUG && wkup_hit) { ASSERT_ERROR(0); } if (systick_hit) { systick_hit = false; if (app_kbd_update_status()) { scanning_substate = 0; current_scan_state = KEY_SCANNING; // Transition from KEY_STATUS_UPD -> KEY_SCANNING // scan once to save time! if (app_kbd_scan_matrix(&scanning_substate)) { current_scan_state = KEY_STATUS_UPD; // Transition from KEY_SCANNING -> KEY_STATUS_UPD } } else { GLOBAL_INT_DISABLE(); app_kbd_enable_scanning(); current_scan_state = KEY_SCAN_IDLE; // Transition from KEY_STATUS_UPD -> KEY_SCAN_IDLE GLOBAL_INT_RESTORE(); } } break; case KEY_SCANNING: if (DEVELOPMENT_DEBUG && wkup_hit) { ASSERT_ERROR(0); } if (systick_hit) { systick_hit = false; if (app_kbd_scan_matrix(&scanning_substate)) { current_scan_state = KEY_STATUS_UPD; // Transition from KEY_SCANNING -> KEY_STATUS_UPD } // else the state remains unchanged and next time we will scan the next row } break; default: break; } }
void hw_fem_start(void) { GLOBAL_INT_DISABLE(); fem_config.started = true; uint8_t set_delay; uint8_t reset_delay; uint16_t rf_port_en; /****************************************************** * Setup GPIOs */ /* CSD GPIO Config */ #if defined(dg_configFEM_SKY66112_11_CSD_PORT) && defined(dg_configFEM_SKY66112_11_CSD_PIN) # if dg_configFEM_SKY66112_11_CSD_USE_DCF == 0 /* Manually set CSD (Enable FEM) */ hw_gpio_configure_pin(dg_configFEM_SKY66112_11_CSD_PORT, dg_configFEM_SKY66112_11_CSD_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, true); # else /* Use DCF for CSD */ hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_CSD_PORT, dg_configFEM_SKY66112_11_CSD_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_PORT2_DCF); # endif #endif /* Timer 27 GPIO (DCF Port 0). Used for TX EN */ hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_CTX_PORT, dg_configFEM_SKY66112_11_CTX_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_PORT0_DCF); /* Timer 28 (DCF Port 1). Used for RX EN */ hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_CRX_PORT, dg_configFEM_SKY66112_11_CRX_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_PORT1_DCF); /* Antenna selection */ #if defined(dg_configFEM_SKY66112_11_ANTSEL_PORT) && defined(dg_configFEM_SKY66112_11_ANTSEL_PIN) hw_gpio_configure_pin(dg_configFEM_SKY66112_11_ANTSEL_PORT, dg_configFEM_SKY66112_11_ANTSEL_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, fem_config.antsel); #endif /****************************************************** * Setup RF_ANT_TRIM GPIOs */ /* RF_ANT_TRIM_0 Config */ #if defined(dg_configFEM_SKY66112_11_ANT_TRIM_0_PORT) && defined(dg_configFEM_SKY66112_11_ANT_TRIM_0_PIN) hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_ANT_TRIM_0_PORT, dg_configFEM_SKY66112_11_ANT_TRIM_0_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_RF_ANT_TRIM0); #endif /* RF_ANT_TRIM_1 Config */ #if defined(dg_configFEM_SKY66112_11_ANT_TRIM_1_PORT) && defined(dg_configFEM_SKY66112_11_ANT_TRIM_1_PIN) hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_ANT_TRIM_1_PORT, dg_configFEM_SKY66112_11_ANT_TRIM_1_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_RF_ANT_TRIM1); #endif /* RF_ANT_TRIM_2 Config */ #if defined(dg_configFEM_SKY66112_11_ANT_TRIM_2_PORT) && defined(dg_configFEM_SKY66112_11_ANT_TRIM_2_PIN) hw_gpio_set_pin_function(dg_configFEM_SKY66112_11_ANT_TRIM_2_PORT, dg_configFEM_SKY66112_11_ANT_TRIM_2_PIN, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_RF_ANT_TRIM2); #endif /****************************************************** * Setup DCFs */ /* assign values to the timer registers for CTX/CRX (in usec) */ REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_27_REG, SET_OFFSET, dg_configFEM_SKY66112_11_TXSET_DCF); REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_27_REG, RESET_OFFSET, dg_configFEM_SKY66112_11_TXRESET_DCF); REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_28_REG, SET_OFFSET, dg_configFEM_SKY66112_11_RXSET_DCF); REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_28_REG, RESET_OFFSET, dg_configFEM_SKY66112_11_RXRESET_DCF); rf_port_en = 0x6; /* Start with Port 0: TX, Port 1: RX */ /* Compute set/reset delays to use for CSD, CPS, CHL DCFs: For setting delay, * smaller of TXSET, RXSET, and for resetting delay, larger of TXSET, RXSET */ #if dg_configFEM_SKY66112_11_RXSET_DCF > dg_configFEM_SKY66112_11_TXSET_DCF set_delay = dg_configFEM_SKY66112_11_TXSET_DCF; #else set_delay = dg_configFEM_SKY66112_11_RXSET_DCF; #endif #if dg_configFEM_SKY66112_11_RXRESET_DCF > dg_configFEM_SKY66112_11_TXRESET_DCF reset_delay = dg_configFEM_SKY66112_11_RXRESET_DCF; #else reset_delay = dg_configFEM_SKY66112_11_TXRESET_DCF; #endif /* CSD DCF (if enabled) configuration */ #if defined(dg_configFEM_SKY66112_11_CSD_PORT) && defined(dg_configFEM_SKY66112_11_CSD_PIN) # if dg_configFEM_SKY66112_11_CSD_USE_DCF != 0 REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_29_REG, SET_OFFSET, set_delay); REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_29_REG, RESET_OFFSET, reset_delay); /* enable DCF Signals for Port 2 (CSD) for both rx/tx */ rf_port_en |= 0x30; # endif /* dg_configFEM_SKY66112_11_CSD_USE_DCF != 0 */ #endif /* Set bypass (CPS) DCF timers (but don't enable yet) */ REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_30_REG, SET_OFFSET, set_delay); REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_30_REG, RESET_OFFSET, reset_delay); /* Set TX Power (CHL) DCF timers (but don't enable yet) */ REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_31_REG, SET_OFFSET, dg_configFEM_SKY66112_11_TXSET_DCF); REG_SETF(RFCU_POWER, RF_CNTRL_TIMER_31_REG, RESET_OFFSET, dg_configFEM_SKY66112_11_TXRESET_DCF); /* Enable DCFs */ #if dg_configBLACK_ORCA_IC_REV == BLACK_ORCA_IC_REV_A RFCU_POWER->RF_PORT_EN_REG = rf_port_en; hw_fem_set_txpower(fem_config.tx_power); #else RFCU_POWER->RF_PORT_EN_BLE_REG = rf_port_en; RFCU_POWER->RF_PORT_EN_FTDF_REG = rf_port_en; set_txpower(); #endif set_bypass(); GLOBAL_INT_RESTORE(); }
void hw_trng_disable_clk(void) { GLOBAL_INT_DISABLE(); REG_CLR_BIT(CRG_TOP, CLK_AMBA_REG, TRNG_CLK_ENABLE); GLOBAL_INT_RESTORE(); }