mbed library sources. Supersedes mbed-src.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_RDA/TARGET_UNO_91H/rda_ccfg_api.c
- Committer:
- AnnaBridge
- Date:
- 2019-02-20
- Revision:
- 189:f392fc9709a3
File content as of revision 189:f392fc9709a3:
/* * Copyright (c) 2018, Arm Limited and affiliates. * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "rda_ccfg_api.h" #include "RDA5991H.h" #define CLK_FREQ_40M (0x00U) #define CLK_FREQ_80M (0x01U) #define CLK_FREQ_160M (0x02U) #define ADDR2REG(addr) (*((volatile unsigned int *)(addr))) #define RF_SPI_REG ADDR2REG(0x4001301CUL) #define TRAP_CTRL_REG ADDR2REG(0x40011000UL) #define TRAP0_SRC_REG ADDR2REG(0x40011004UL) #define TRAP0_DST_REG ADDR2REG(0x40011024UL) #define TRAP1_SRC_REG ADDR2REG(0x40011008UL) #define TRAP1_DST_REG ADDR2REG(0x40011028UL) #define SPIF_CFG_REG ADDR2REG(0x17FFF014UL) #define SYS_CPU_CLK CLK_FREQ_160M #define AHB_BUS_CLK CLK_FREQ_80M extern void core_util_critical_section_enter(void); extern void core_util_critical_section_exit(void); static int ChipHwVersion = 0; static inline void wr_rf_usb_reg(unsigned char a, unsigned short d, int isusb) { core_util_critical_section_enter(); while(RF_SPI_REG & (0x01UL << 31)); while(RF_SPI_REG & (0x01UL << 31)); RF_SPI_REG = (unsigned int)d | ((unsigned int)a << 16) | (0x01UL << 25) | ((isusb) ? (0x01UL << 27) : 0x00UL); core_util_critical_section_exit(); } static inline void rd_rf_usb_reg(unsigned char a, unsigned short *d, int isusb) { core_util_critical_section_enter(); while(RF_SPI_REG & (0x01UL << 31)); while(RF_SPI_REG & (0x01UL << 31)); RF_SPI_REG = ((unsigned int)a << 16) | (0x01UL << 24) | (0x01UL << 25) | ((isusb) ? (0x01UL << 27) : 0x00UL); __asm volatile ("nop"); while(RF_SPI_REG & (0x01UL << 31)); while(RF_SPI_REG & (0x01UL << 31)); *d = (unsigned short)(RF_SPI_REG & 0xFFFFUL); core_util_critical_section_exit(); } /* Power down the debug-usage I2C */ static inline void rda_ccfg_pdi2c(void) { unsigned int val = RDA_PINCFG->MUX2; if(0x00UL == (val & 0x3FUL)) { RDA_PINCFG->MUX2 = val | 0x09UL; } wr_rf_usb_reg(0xA1, 0x0000, 0); } /* Config CPU & Bus clock */ static inline void rda_ccfg_ck(void) { unsigned short val = 0U, cfg = 0U; cfg = (RDA_SCU->CORECFG >> 11) & 0x07U; rd_rf_usb_reg(0xA4, &val, 0); #if ((SYS_CPU_CLK == CLK_FREQ_160M) && (AHB_BUS_CLK == CLK_FREQ_80M)) /* HCLK inv */ if(((CLK_FREQ_40M << 1) | CLK_FREQ_40M) == cfg) { val |= (0x01U << 12); } #endif /* CLK_FREQ_160M && CLK_FREQ_80M */ /* Config CPU & BUS clock */ cfg ^= (((SYS_CPU_CLK << 1) | AHB_BUS_CLK) & 0x07U); val &= ~(0x07U << 9); /* bit[11:10] = 2'b00:40M, 2'b01:80M, 2'b1x:160M */ val |= (cfg << 9); /* bit[9] = 1'b0:40M, 1'b1:80M */ val &= ~(0x01U); /* i2c_wakeup_en */ wr_rf_usb_reg(0xA4, val, 0); } /* Config SPI flash clock */ static inline void rda_ccfg_spifck(void) { unsigned int val; __DSB(); val = SPIF_CFG_REG & ~(0x00FFUL << 8); SPIF_CFG_REG = val | (0x0004UL << 8); // divider __DSB(); } /* Handle abort booting */ static inline int rda_ccfg_abort_hdlr(void) { int ret = 0; unsigned short val = 0U; rd_rf_usb_reg(0xA1, &val, 0); ret = (int)((val >> 2) & 0x01U); if(ret) { unsigned short val2 = 0U; rd_rf_usb_reg(0xB2, &val2, 0); wr_rf_usb_reg(0xB2, (val2 | (0x01U << 11)), 0); RDA_GPIO->PCCTRL |= (0x01UL << 31); // set abort flag for(val = 0; val < 0x00FFU; val++) { // delay ; } wr_rf_usb_reg(0xB2, (val2 & ~(0x01U << 11)), 0); } return ret; } /* Power up the always-on timer */ void rda_ccfg_aontmr(void) { unsigned short val = 0U; rd_rf_usb_reg(0xA3, &val, 0); if (0x00U == (val & (0x01U << 12))) { wr_rf_usb_reg(0xA3, (val | (0x01U << 12)), 0); } } /* Config clock source of always-on timer */ void rda_ccfg_aontmr_cksrc(int cksrc) { unsigned short val; if(0 == cksrc) { // use lpo 32K clk, hw default wr_rf_usb_reg(0xDD, 0x5100U, 0); rd_rf_usb_reg(0xD8, &val, 0); wr_rf_usb_reg(0xD8, (val & ~(0x03U << 14)), 0); rd_rf_usb_reg(0xA8, &val, 0); val |= ((0x01U << 10) | (0x01U << 14)); wr_rf_usb_reg(0xA8, (val & ~(0x01U << 12)), 0); } else { // use 6m5xtal 32K clk, more accurate int idx; wr_rf_usb_reg(0xDD, 0x8100U, 0); rd_rf_usb_reg(0xD8, &val, 0); wr_rf_usb_reg(0xD8, (val | (0x01U << 15)), 0); for(idx = 0; idx < 5; idx++) { // for dealy rd_rf_usb_reg(0x00, &val, 0); } wr_rf_usb_reg(0xDD, 0x9100U, 0); rd_rf_usb_reg(0xD8, &val, 0); wr_rf_usb_reg(0xD8, (val | (0x01U << 15) | (0x01U << 14)), 0); rd_rf_usb_reg(0xA8, &val, 0); val &= ~((0x01U << 10) | (0x01U << 14)); wr_rf_usb_reg(0xA8, (val | (0x01U << 12)), 0); } } /* Config GPIO6 to dig core */ void rda_ccfg_gp6(unsigned short cfg) { unsigned short val = 0U; rd_rf_usb_reg(0xCD, &val, 0); val &= ~(0x01U << 11); wr_rf_usb_reg(0xCD, (val | ((cfg & 0x01U) << 11)), 0); } /* Config GPIO7 to dig core */ void rda_ccfg_gp7(unsigned short cfg) { unsigned short val = 0U; rd_rf_usb_reg(0xB0, &val, 0); val &= ~(0x01U << 14); wr_rf_usb_reg(0xB0, (val | ((cfg & 0x01U) << 14)), 0); } /* Config GPIO6/7/8/9 to pmu intf or dig core */ void rda_ccfg_gp(unsigned char gp, unsigned short cfg) { unsigned short val = 0U; unsigned char reg = 0xCDU; const int ofs_lst[4] = {11, 14, 10, 9}; if((6 > gp) || (9 < gp)) { return; } if(7 == gp) { reg = 0xB0U; } rd_rf_usb_reg(reg, &val, 0); val &= ~(0x01U << ofs_lst[gp - 6]); wr_rf_usb_reg(reg, (val | ((cfg & 0x01U) << ofs_lst[gp - 6])), 0); } /* Set some core config when booting */ int rda_ccfg_boot(void) { int ret = 1; int abort_flag = rda_ccfg_abort_hdlr(); if(!abort_flag) { rda_ccfg_pdi2c(); } /*close usb polling*/ RDA_GPIO->CTRL &= ~(0x01UL << 12); rda_ccfg_ck(); /* Set flash clock */ rda_ccfg_spifck(); /* Set aon timer clock source */ rda_ccfg_aontmr_cksrc(1); return ret; } /* Reset CPU & Bus clock config */ void rda_ccfg_ckrst(void) { unsigned short val = 0U; rd_rf_usb_reg(0xA4, &val, 0); /* HCLK inv */ val &= ~(0x01U << 12); /* Config CPU clock */ val &= ~(0x03U << 10); val |= (0x00U << 10); /* 2'b00:40M, 2'b01:80M, 2'b1x:160M */ /* Config BUS clock */ val &= ~(0x01U << 9); val |= (0x00U << 9); /* 1'b0:40M, 1'b1:80M */ wr_rf_usb_reg(0xA4, val, 0); } /* Reset peripheral module */ void rda_ccfg_perrst(void) { unsigned int idx = 0x0FUL; RDA_SCU->RESETCTRL &= ~(0x01UL << 11); // soft_resetn_bb for (; idx>0; idx--); RDA_SCU->RESETCTRL |= (0x01UL << 11); } /* Init ADC module */ void rda_ccfg_adc_init(void) { unsigned short val = 0U; rd_rf_usb_reg(0xA3, &val, 0); /* adc en */ wr_rf_usb_reg(0xA3, (val | (0x01U << 3)), 0); rd_rf_usb_reg(0xD8, &val, 0); /* clk 6p5m en */ wr_rf_usb_reg(0xD8, (val | (0x01U << 15)), 0); rd_rf_usb_reg(0xB7, &val, 0); /* clk 26m en */ wr_rf_usb_reg(0xB7, (val | (0x01U << 14)), 0); } /* Config GPIO6/7/8 pdn or pup for ADC usage */ void rda_ccfg_adc_gp(unsigned char gp, unsigned short cfg) { unsigned short val = 0U; const int ofs_lst[3] = {8, 9, 7}; if((6 > gp) || (8 < gp)) { return; } rd_rf_usb_reg(0xB2, &val, 0); val &= ~(0x01U << ofs_lst[gp - 6]); wr_rf_usb_reg(0xB2, (val | ((cfg & 0x01U) << ofs_lst[gp - 6])), 0); } /* Config GPADC oenb, use be config to 1 in either Normal mode or GPADC mode */ void rda_ccfg_adc_oenb(unsigned char ch, unsigned short cfg) { unsigned short val = 0U; unsigned char offset = 0U; int ver = rda_ccfg_hwver(); if ((ch > 1) || (cfg > 1)) return; if (0 == ch) { offset = 2; } else { if (ver <= 2) offset = 3; else if (ver >= 4) offset = 1; } rd_rf_usb_reg(0xB0, &val, 0); val &= ~(0x01U << offset); val |= (cfg << offset); wr_rf_usb_reg(0xB0, val, 0); } /* Read ADC value */ unsigned short rda_ccfg_adc_read(unsigned char ch) { unsigned short val = 0U; rd_rf_usb_reg(0xB7, &val, 0); /* set vref */ val &= ~((0x03U) << 12); /* verf 1.7V */ if(!((2U == ch) && (rda_ccfg_hwver() <= 4))) { val |= ((0x02U) << 12); /* verf 2.0V */ } wr_rf_usb_reg(0xB7, val, 0); rd_rf_usb_reg(0xB6, &val, 0); /* channel select */ val &= ~((0x03U) << 12); wr_rf_usb_reg(0xB6, (val | ((ch & 0x03U) << 12)), 0); rd_rf_usb_reg(0xB6, &val, 0); /* set read en */ wr_rf_usb_reg(0xB6, (val | (0x01U << 2)), 0); for(val = 0; val < 0x0FFU; val++) { // delay ; } rd_rf_usb_reg(0xB6, &val, 0); /* clr read en */ wr_rf_usb_reg(0xB6, (val & ~(0x01U << 2)), 0); do { rd_rf_usb_reg(0xB7, &val, 0); /* finish loop flag */ } while(0x00U == (val & (0x01U << 10))); return (val & 0x03FFU); } /* Free ADC module */ void rda_ccfg_adc_free(void) { unsigned short val = 0U; rd_rf_usb_reg(0xA3, &val, 0); /* adc disable */ wr_rf_usb_reg(0xA3, (val & ~(0x01U << 3)), 0); rd_rf_usb_reg(0xB7, &val, 0); /* clk 26m disable */ wr_rf_usb_reg(0xB7, (val & ~(0x01U << 14)), 0); } /* Get abort flag */ int rda_ccfg_abort_flag(void) { int ret = 0; if(0x00UL != (RDA_GPIO->PCCTRL & (0x01UL << 31))) { ret = 1; } return ret; } /* Set wdt en */ void rda_ccfg_wdt_en(void) { unsigned short val = 0U; rd_rf_usb_reg(0xC8, &val, 0); wr_rf_usb_reg(0xC8, (val | (0x01U << 13)), 0); } unsigned short rf_reg_read(unsigned short addr) { unsigned short val = 0U; if(addr <= 0x1FF) { if((((addr & 0xFFU) >= 0xA0) && ((addr & 0xFFU) <= 0xDF)) || (addr == 0x30U) || (addr == 0x34U) || (addr == 0x35U)) { /* PMU & RF_30H/34H/35H */ rd_rf_usb_reg((unsigned char)(addr & 0xFFU), &val, 0); } else { /* RF */ char isrun = 0; rd_rf_usb_reg(0x30U, &val, 0); isrun = (val & 0x01U) ? 1 : 0; if(isrun) { wr_rf_usb_reg(0x02U, (0x5000U | addr), 0); rd_rf_usb_reg(0x34U, &val, 0); } else { if(addr & (0x01U << 8)) { wr_rf_usb_reg(0x3FU, 1, 0); } rd_rf_usb_reg((unsigned char)(addr & 0xFFU), &val, 0); if(addr & (0x01U << 8)) { wr_rf_usb_reg(0x3FU, 0, 0); } } } } return val; } void rf_reg_write(unsigned short addr, unsigned short val) { if(addr <= 0x1FF) { if((((addr & 0xFFU) >= 0xA0) && ((addr & 0xFFU) <= 0xDF)) || (addr == 0x30U) || (addr == 0x34U) || (addr == 0x35U)) { /* PMU & RF_30H/34H/35H */ wr_rf_usb_reg((unsigned char)(addr & 0xFFU), val, 0); } else { /* RF */ char isrun = 0; rd_rf_usb_reg(0x30U, &val, 0); isrun = (val & 0x01U) ? 1 : 0; if(isrun) { wr_rf_usb_reg(0x32U, val, 0); wr_rf_usb_reg(0x02U, (0x4000U | addr), 0); } else { if(addr & (0x01U << 8)) { wr_rf_usb_reg(0x3FU, 1, 0); } wr_rf_usb_reg((unsigned char)(addr & 0xFFU), val, 0); if(addr & (0x01U << 8)) { wr_rf_usb_reg(0x3FU, 0, 0); } } } } } /* Get chip hw version */ int rda_ccfg_hwver(void) { if(0 == ChipHwVersion) { ChipHwVersion = (int)((RDA_GPIO->REVID >> 16) & 0xFFUL) + 1; } return ChipHwVersion; }