651 lines
21 KiB
C
651 lines
21 KiB
C
/****************************************************************************
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
be copied by any method or incorporated into another program without
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
liability for its use in any way and conveys no license or title under
|
|
any patent or copyright and makes no representation or warranty that this
|
|
Information is free from patent or copyright infringement.
|
|
|
|
****************************************************************************/
|
|
#include "rf_phy_tx.h"
|
|
#include "iot_config.h"
|
|
#include "mpdu_frame.h"
|
|
#include "iot_io.h"
|
|
#include "phy_rf_init.h"
|
|
#include "bb_rf_cfg.h"
|
|
#include "rf_hw_tonemap.h"
|
|
#include "bb_rf_hw_tbl.h"
|
|
#include "bb_cpu_mac_isr.h"
|
|
#include "bb_cpu_fsm.h"
|
|
#include "bb_init.h"
|
|
#include "phy_rf_init.h"
|
|
#include "hw_reg_api.h"
|
|
#include "rfplc_reg_base.h"
|
|
#include "rfplc_general_reg.h"
|
|
#include "wphy_reg.h"
|
|
#include "mac_sys_reg.h"
|
|
#include "rf_mac_reg.h"
|
|
#include "ahb.h"
|
|
#include "iot_irq.h"
|
|
#include "rf_spi_api.h"
|
|
#include "iot_clock.h"
|
|
#include "rf_mac_common.h"
|
|
#include "dma_reg.h"
|
|
#include "dma_hw.h"
|
|
#include "dma.h"
|
|
#include "phy_rf_chn.h"
|
|
#include "mac_rf_common_hw.h"
|
|
#include "apb_dma_hw.h"
|
|
#include "apb_dma.h"
|
|
#include "chip_irq_vector.h"
|
|
|
|
#include "os_types.h"
|
|
#include "os_utils.h"
|
|
#include "os_types.h"
|
|
#include "os_task.h"
|
|
#include "os_utils.h"
|
|
#include "gpio_mtx.h"
|
|
#include "iot_board_api.h"
|
|
|
|
uint8_t rf_tx_pb_buf[520] = { 0 };
|
|
uint32_t tx_print_period_s = (4 * 25000000); /*receive 25*4 packets in 4s*/
|
|
uint32_t tx_period_ms = (6 * 25000);
|
|
uint32_t tx_done_is_happen = 0;
|
|
iot_irq_t isr_rf_phy;
|
|
|
|
uint32_t rf_phy_tx_isr(uint32_t vector, iot_addrword_t data)
|
|
{
|
|
// TODO: debug isr interrupt.
|
|
(void)vector;
|
|
(void)data;
|
|
uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_COMMON_INT_REG_6_ADDR);
|
|
if (tmp & 0x400) {
|
|
// tx_done_is_happen = 1;
|
|
tmp = RF_MAC_READ_REG(CFG_RF_MAC_COMMON_INT_REG_4_ADDR);
|
|
tmp |= 1 << 10;
|
|
RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_4_ADDR, tmp);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void rf_phy_isr_start()
|
|
{
|
|
RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_4_ADDR, 0);
|
|
|
|
uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_COMMON_INT_REG_0_ADDR);
|
|
tmp |= 1 << 10;
|
|
RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_0_ADDR, tmp);
|
|
|
|
tmp = RF_MAC_READ_REG(CFG_RF_MAC_COMMON_INT_REG_8_ADDR);
|
|
tmp |= 1 << 10;
|
|
RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_8_ADDR, tmp);
|
|
}
|
|
|
|
void rf_phy_interrupt_init()
|
|
{
|
|
#if 0
|
|
// TODO: debug isr interrupt.
|
|
isr_rf_phy = iot_interrupt_create(HAL_VECTOR_RFMAC,
|
|
HAL_INTR_PRI_7, (iot_addrword_t)NULL, rf_phy_tx_isr);
|
|
iot_interrupt_attach(isr_rf_phy);
|
|
iot_interrupt_unmask(isr_rf_phy);
|
|
#endif
|
|
|
|
rf_phy_isr_start();
|
|
}
|
|
|
|
void rf_phy_init(uint32_t option)
|
|
{
|
|
bb_rf_init(option, 0);
|
|
}
|
|
|
|
static uint32_t wait_tx_done_interrupt()
|
|
{
|
|
uint32_t tmp = RF_MAC_READ_REG(CFG_RF_MAC_COMMON_INT_REG_6_ADDR);
|
|
if (tmp & 0x400) {
|
|
tx_done_is_happen = 1;
|
|
tmp = RF_MAC_READ_REG(CFG_RF_MAC_COMMON_INT_REG_4_ADDR);
|
|
tmp |= 1 << 10;
|
|
RF_MAC_WRITE_REG(CFG_RF_MAC_COMMON_INT_REG_4_ADDR, tmp);
|
|
}
|
|
return tx_done_is_happen;
|
|
}
|
|
|
|
extern void board_fixed_signal_mtx_binding(void);
|
|
|
|
uint32_t rf_phy_tx_init(PHY_RF_BAND_T band_sel, uint32_t option)
|
|
{
|
|
uint8_t rf_ver = RF_VER_INVAILD;
|
|
/* disable rf phy bb cpu */
|
|
phy_rf_deinit();
|
|
ahb_mac_enable();
|
|
ahb_mac_reg_enable();
|
|
if (phy_rf_check_rf_version(mac_rf_get_rf_ver())) {
|
|
rf_ver = mac_rf_get_rf_ver();
|
|
}
|
|
|
|
/* ahb init and reset */
|
|
ahb_rfmac_disable();
|
|
ahb_rfmac_reg_disable();
|
|
ahb_rfmac_enable();
|
|
ahb_rfmac_reg_enable();
|
|
ahb_rfmac_reset();
|
|
ahb_rfmac_reg_reset();
|
|
|
|
ahb_rfplc_phy_disable();
|
|
ahb_rfplc_phy_reg_disable();
|
|
ahb_rfplc_ana_disable();
|
|
ahb_rfplc_phy_enable();
|
|
ahb_rfplc_phy_reg_enable();
|
|
ahb_rfplc_ana_enable();
|
|
|
|
ahb_rfplc_phy_reset();
|
|
ahb_rfplc_phy_reg_reset();
|
|
ahb_rfplc_ana_reset();
|
|
#if (IOT_DTEST_ONLY_SUPPORT != 1)
|
|
/* get rf spi */
|
|
uint8_t clk = iot_board_get_gpio(GPIO_SPI_RF_CLK);
|
|
uint8_t cs = iot_board_get_gpio(GPIO_SPI_RF_CS);
|
|
uint8_t miso = iot_board_get_gpio(GPIO_SPI_RF_MISO);
|
|
uint8_t mosi = iot_board_get_gpio(GPIO_SPI_RF_MOSI);
|
|
#else
|
|
/* rf mac dtest */
|
|
#if HW_PLATFORM == HW_PLATFORM_FPGA
|
|
uint8_t clk = 9;
|
|
uint8_t cs = 12;
|
|
uint8_t miso = 11;
|
|
uint8_t mosi = 10;
|
|
#else
|
|
uint8_t clk = 12;
|
|
uint8_t cs = 9;
|
|
uint8_t miso = 10;
|
|
uint8_t mosi = 11;
|
|
for (uint32_t wphy_gpio = 42; wphy_gpio < 60; wphy_gpio++) {
|
|
gpio_pin_select(wphy_gpio, 1);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
/* init rf spi gpio */
|
|
mac_rf_set_spi_gpio(clk, cs, mosi, miso);
|
|
phy_rf_in_check();
|
|
phy_rf_load_cal_cfg();
|
|
|
|
/* spi init */
|
|
rf_spi_init();
|
|
if (!phy_rf_check_rf_version(mac_rf_get_rf_ver()) &&
|
|
rf_ver != RF_VER_INVAILD) {
|
|
mac_rf_set_rf_ver(rf_ver);
|
|
}
|
|
mac_rf_to_wphy_interface_init(1);
|
|
bb_rf_init_ver();
|
|
rf_phy_init(option);
|
|
rf_phy_interrupt_init();
|
|
return 0;
|
|
}
|
|
|
|
void rf_phy_option_test(rf_mac_cfg_info_t *rf_tx_cfg)
|
|
{
|
|
iot_printf("%s\n", __FUNCTION__);
|
|
|
|
/* just test config */
|
|
mac_rf_to_wphy_interface_init(1);
|
|
rf_phy_init(rf_tx_cfg->option);
|
|
}
|
|
|
|
uint32_t rf_phy_get_pbsz(uint8_t blkz)
|
|
{
|
|
switch (blkz) {
|
|
case 0:
|
|
return 16;
|
|
case 1:
|
|
return 40;
|
|
case 2:
|
|
return 72;
|
|
case 3:
|
|
return 136;
|
|
case 4:
|
|
return 264;
|
|
case 5:
|
|
return 520;
|
|
default:
|
|
IOT_ASSERT(0);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void rf_phy_tx_start(rf_mac_cfg_info_t *rf_tx_cfg)
|
|
{
|
|
iot_printf("%s\n", __FUNCTION__);
|
|
bb_rf_hw_info_t *phr_info = NULL;
|
|
bb_rf_hw_info_t *pld_info = NULL;
|
|
uint32_t pb_size = rf_phy_get_pbsz(rf_tx_cfg->pld_blkz);
|
|
frame_control_t phr = { 0 };
|
|
uint32_t pb_num = 1, record_tx_cnt = 0, tx_done;
|
|
uint32_t end_time = 0, en_time, cur_time;
|
|
int64_t time_span = 0;
|
|
uint32_t start_time = rf_mac_get_ntb();
|
|
|
|
tx_start:
|
|
tx_done_is_happen = 0;
|
|
en_time = rf_mac_get_ntb();/*for tx*/
|
|
phr.delimiter_type = rf_tx_cfg->delimiter;
|
|
phr.network_type = 0;
|
|
phr.nid = rf_tx_cfg->nid;
|
|
switch (rf_tx_cfg->delimiter) {
|
|
case FC_DELIM_BEACON:
|
|
{
|
|
phr.vf.rf_bcn.src_tei = 1;
|
|
phr.vf.rf_bcn.mcs = rf_tx_cfg->pld_mcs;
|
|
phr.vf.rf_bcn.pb_sz_idx = rf_tx_cfg->pld_blkz;
|
|
phr.vf.rf_bcn.resv0 = 0;
|
|
phr.vf.rf_bcn.version = 0;
|
|
phr.vf.rf_bcn.fccs = 0;
|
|
break;
|
|
}
|
|
case FC_DELIM_SOF:
|
|
{
|
|
phr.vf.rf_sof.src_tei = 1;
|
|
phr.vf.rf_sof.dst_tei = 2;
|
|
phr.vf.rf_sof.lid = 0;
|
|
phr.vf.rf_sof.frame_len = 0;
|
|
phr.vf.rf_sof.pb_sz_idx = rf_tx_cfg->pld_blkz;
|
|
phr.vf.rf_sof.resv0 = 0;
|
|
phr.vf.rf_sof.bcast = rf_tx_cfg->is_bcast& 0x1;
|
|
phr.vf.rf_sof.retry = 0;
|
|
phr.vf.rf_sof.encry = 0;
|
|
phr.vf.rf_sof.mcs = rf_tx_cfg->pld_mcs;
|
|
phr.vf.rf_sof.resv1 = 0;
|
|
phr.vf.rf_sof.version = 0;
|
|
phr.vf.rf_sof.fccs = 0;
|
|
break;
|
|
}
|
|
default:
|
|
IOT_ASSERT(0);
|
|
}
|
|
/* tx config */
|
|
bb_rf_tx_cfg(rf_tx_cfg->option, RF_CHANNEL_DEF_FREQ_HZ);
|
|
|
|
phr_info = bb_rf_get_phr_hw_info(rf_tx_cfg->option, rf_tx_cfg->phr_mcs);
|
|
pld_info = bb_rf_get_pld_hw_info(rf_tx_cfg->option,
|
|
rf_tx_cfg->pld_blkz, rf_tx_cfg->pld_mcs);
|
|
|
|
#if SUPPORT_SMART_GRID
|
|
sg_sof_pb_hdr_t *hdr =
|
|
(sg_sof_pb_hdr_t *)&rf_tx_pb_buf;
|
|
hdr->mac_frame_end = 1 & 0x1;
|
|
hdr->mac_frame_start = 1 & 0x1;
|
|
hdr->seq = 0 & 0x3f;
|
|
#endif
|
|
|
|
/* clear tx info */
|
|
bb_rf_clear_tx_info();
|
|
|
|
/* start dma */
|
|
//bb_cpu_dma_start(RF_PHY_TX_DMA_BASEADDR, pb_size * pb_num);
|
|
//os_mem_cpy((void *)RF_PHY_TX_DMA_BASEADDR, rf_tx_pb_buf, pb_size * pb_num);
|
|
|
|
/* beacon need calcualte crc32 */
|
|
if (rf_tx_cfg->delimiter == FC_DELIM_BEACON) {
|
|
bb_rf_set_crc32_en(1);
|
|
} else {
|
|
bb_rf_set_crc32_en(0);
|
|
}
|
|
|
|
/* set tx phy header */
|
|
bb_rf_set_tx_phr((uint32_t *)&phr);
|
|
/* config tx phy header info */
|
|
bb_rf_cfg_tx_phr_info(phr_info);
|
|
/* config tx payload info */
|
|
bb_rf_cfg_tx_pld_info(pld_info, pb_num);
|
|
|
|
/* bb cpu trigger bb to tx */
|
|
//bb_cpu_trigger_bb(BB_CPU_TRIGGER_BB_TX);
|
|
|
|
/* use debug tx */
|
|
bb_rf_debug_tx_immd();
|
|
|
|
/* use copy replace dma */
|
|
bb_rf_write_data_to_bb(pb_size, rf_tx_pb_buf);
|
|
|
|
/* wait for tx done */
|
|
do {
|
|
cur_time = rf_mac_get_ntb();
|
|
time_span = cur_time - en_time;
|
|
if (time_span < 0) { // wrap around
|
|
time_span = (0x100000000LL) - en_time + cur_time;
|
|
}
|
|
tx_done = wait_tx_done_interrupt();
|
|
} while (!tx_done || ((uint64_t)time_span < tx_period_ms));
|
|
|
|
record_tx_cnt++;
|
|
|
|
/* tx cnt print */
|
|
end_time = rf_mac_get_ntb();
|
|
time_span = end_time - start_time;
|
|
if (time_span < 0) { // wrap around
|
|
time_span = (0x100000000LL) - start_time + end_time;
|
|
}
|
|
if((uint64_t)time_span > tx_print_period_s) {
|
|
iot_printf("tx ok cnt:%d/4s, fchz:%lu\n",
|
|
record_tx_cnt, bb_rf_get_fchz());
|
|
record_tx_cnt = 0;
|
|
start_time = end_time;
|
|
}
|
|
|
|
if (rf_tx_cfg->tx_cnt) {
|
|
rf_tx_cfg->tx_cnt--;
|
|
goto tx_start;
|
|
}
|
|
}
|
|
|
|
void rf_phy_tx_tone_hw(uint8_t option, uint32_t lo_freq, uint32_t on_off,
|
|
int8_t tone0_num, int8_t tone1_num, uint8_t att0, uint8_t att1)
|
|
{
|
|
uint32_t tmp;
|
|
tmp = RFPLC_GENERAL_READ_REG(CFG_RFPLC_DBG_CFG0_ADDR);
|
|
|
|
if (on_off && REG_FIELD_GET(SW_RFPLC_TONE_CFG_EN, tmp)) {
|
|
REG_FIELD_SET(SW_RFPLC_TONE_CFG_EN, tmp, on_off);
|
|
REG_FIELD_SET(SW_RFPLC_TONE_0_ATTEN, tmp, att0);
|
|
REG_FIELD_SET(SW_RFPLC_TONE_1_ATTEN, tmp, att1);
|
|
REG_FIELD_SET(SW_RFPLC_TONE_0_CFG_NUM, tmp, tone0_num);
|
|
REG_FIELD_SET(SW_RFPLC_TONE_1_CFG_NUM, tmp, tone1_num);
|
|
RFPLC_GENERAL_WRITE_REG(CFG_RFPLC_DBG_CFG0_ADDR, tmp);
|
|
return;
|
|
}
|
|
|
|
if (on_off) {
|
|
bb_rf_rx_reset();
|
|
bb_rf_tx_reset();
|
|
bb_rf_jesd_reset();
|
|
rf_spi_write(30, 0x101);
|
|
/* tx config */
|
|
bb_rf_tx_cfg(option, lo_freq);
|
|
}
|
|
|
|
/* clear rfplc contrl */
|
|
RFPLC_GENERAL_WRITE_REG(CFG_RFPLC_DBG_CFG0_ADDR, 0);
|
|
|
|
REG_FIELD_SET(SW_RFPLC_TONE_CFG_EN, tmp, on_off);
|
|
REG_FIELD_SET(SW_RFPLC_TONE_0_ATTEN, tmp, on_off ? att0 : 0);
|
|
REG_FIELD_SET(SW_RFPLC_TONE_1_ATTEN, tmp, on_off ? att1 : 0);
|
|
REG_FIELD_SET(SW_RFPLC_TONE_0_CFG_NUM, tmp, on_off ? tone0_num : 0);
|
|
REG_FIELD_SET(SW_RFPLC_TONE_1_CFG_NUM, tmp, on_off ? tone1_num : 0);
|
|
RFPLC_GENERAL_WRITE_REG(CFG_RFPLC_DBG_CFG0_ADDR, tmp);
|
|
|
|
tmp = RFPLC_GENERAL_READ_REG(CFG_RFPLC_DBG_CFG0_ADDR);
|
|
REG_FIELD_SET(SW_RFPLC_FORCE_TX, tmp, on_off);
|
|
RFPLC_GENERAL_WRITE_REG(CFG_RFPLC_DBG_CFG0_ADDR, tmp);
|
|
|
|
tmp = RFPLC_GENERAL_READ_REG(CFG_RFPLC_DBG_CFG2_ADDR);
|
|
REG_FIELD_SET(SW_RFPLC_TX_TXNRX, tmp, on_off);
|
|
REG_FIELD_SET(SW_RFPLC_TX_ENABLE, tmp, on_off);
|
|
RFPLC_GENERAL_WRITE_REG(CFG_RFPLC_DBG_CFG2_ADDR, tmp);
|
|
}
|
|
|
|
void rf_phy_tx_dc_test()
|
|
{
|
|
/* clear rfplc contrl */
|
|
RFPLC_GENERAL_WRITE_REG(CFG_RFPLC_DBG_CFG0_ADDR, 0);
|
|
RFPLC_GENERAL_WRITE_REG(CFG_RFPLC_DBG_CFG1_ADDR, 0);
|
|
|
|
uint32_t tmp;
|
|
|
|
/* tx config */
|
|
bb_rf_tx_cfg(PHY_RF_OPTION1_1M, RF_CHANNEL_DEF_FREQ_HZ);
|
|
|
|
//bb_rf_debug_tx_immd();
|
|
|
|
tmp = RFPLC_GENERAL_READ_REG(CFG_RFPLC_DBG_CFG0_ADDR);
|
|
REG_FIELD_SET(SW_RFPLC_FORCE_TX, tmp, 0);
|
|
REG_FIELD_SET(SW_RFPLC_TONE_CFG_EN, tmp, 0);
|
|
RFPLC_GENERAL_WRITE_REG(CFG_RFPLC_DBG_CFG0_ADDR, tmp);
|
|
|
|
tmp = RFPLC_GENERAL_READ_REG(CFG_RFPLC_DBG_CFG1_ADDR);
|
|
REG_FIELD_SET(SW_RFPLC_TX_DC_I, tmp, 100);
|
|
REG_FIELD_SET(SW_RFPLC_TX_DC_Q, tmp, 100);
|
|
REG_FIELD_SET(SW_RFPLC_TX_DC, tmp, 1);
|
|
RFPLC_GENERAL_WRITE_REG(CFG_RFPLC_DBG_CFG1_ADDR, tmp);
|
|
|
|
tmp = RFPLC_GENERAL_READ_REG(CFG_RFPLC_DBG_CFG0_ADDR);
|
|
REG_FIELD_SET(SW_RFPLC_FORCE_TX, tmp, 1);
|
|
RFPLC_GENERAL_WRITE_REG(CFG_RFPLC_DBG_CFG0_ADDR, tmp);
|
|
|
|
tmp = RFPLC_GENERAL_READ_REG(CFG_RFPLC_DBG_CFG2_ADDR);
|
|
REG_FIELD_SET(SW_RFPLC_TX_TXNRX, tmp, 1);
|
|
REG_FIELD_SET(SW_RFPLC_TX_ENABLE, tmp, 1);
|
|
RFPLC_GENERAL_WRITE_REG(CFG_RFPLC_DBG_CFG2_ADDR, tmp);
|
|
|
|
while(1);
|
|
}
|
|
|
|
double my_floor(double x)
|
|
{
|
|
if(x < 0) {
|
|
return (float)(x - 0.5);
|
|
} else {
|
|
return (float)(x + 0.5);
|
|
}
|
|
}
|
|
|
|
typedef struct _iq_data {
|
|
int16_t i_data;
|
|
int16_t q_data;
|
|
} iq_data_t;
|
|
|
|
double my_mod(double _X, double _Y)
|
|
{
|
|
return _X - (int)(_X / _Y) * _Y;
|
|
}
|
|
|
|
double my_sin( double x )
|
|
{
|
|
#define XPI (3.1415926535897932384626433832795)
|
|
#define XENTRY (100)
|
|
#define XINCL (XPI/2/XENTRY)
|
|
static const double XSinTbl[] = {
|
|
0.00000000000000000 , 0.015707317311820675 , 0.031410759078128292 , 0.047106450709642665 , 0.062790519529313374 ,
|
|
0.078459095727844944 , 0.094108313318514325 , 0.10973431109104528 , 0.12533323356430426 , 0.14090123193758267 ,
|
|
0.15643446504023087 , 0.17192910027940955 , 0.18738131458572463 , 0.20278729535651249 , 0.21814324139654256 ,
|
|
0.23344536385590542 , 0.24868988716485479 , 0.26387304996537292 , 0.27899110603922928 , 0.29404032523230400 ,
|
|
0.30901699437494740 , 0.32391741819814940 , 0.33873792024529142 , 0.35347484377925714 , 0.36812455268467797 ,
|
|
0.38268343236508978 , 0.39714789063478062 , 0.41151435860510882 , 0.42577929156507272 , 0.43993916985591514 ,
|
|
0.45399049973954680 , 0.46792981426057340 , 0.48175367410171532 , 0.49545866843240760 , 0.50904141575037132 ,
|
|
0.52249856471594880 , 0.53582679497899666 , 0.54902281799813180 , 0.56208337785213058 , 0.57500525204327857 ,
|
|
0.58778525229247314 , 0.60042022532588402 , 0.61290705365297649 , 0.62524265633570519 , 0.63742398974868975 ,
|
|
0.64944804833018377 , 0.66131186532365183 , 0.67301251350977331 , 0.68454710592868873 , 0.69591279659231442 ,
|
|
0.70710678118654757 , 0.71812629776318881 , 0.72896862742141155 , 0.73963109497860968 , 0.75011106963045959 ,
|
|
0.76040596560003104 , 0.77051324277578925 , 0.78043040733832969 , 0.79015501237569041 , 0.79968465848709058 ,
|
|
0.80901699437494745 , 0.81814971742502351 , 0.82708057427456183 , 0.83580736136827027 , 0.84432792550201508 ,
|
|
0.85264016435409218 , 0.86074202700394364 , 0.86863151443819120 , 0.87630668004386369 , 0.88376563008869347 ,
|
|
0.89100652418836779 , 0.89802757576061565 , 0.90482705246601958 , 0.91140327663544529 , 0.91775462568398114 ,
|
|
0.92387953251128674 , 0.92977648588825146 , 0.93544403082986738 , 0.94088076895422557 , 0.94608535882754530 ,
|
|
0.95105651629515353 , 0.95579301479833012 , 0.96029368567694307 , 0.96455741845779808 , 0.96858316112863108 ,
|
|
0.97236992039767667 , 0.97591676193874743 , 0.97922281062176575 , 0.98228725072868872 , 0.98510932615477398 ,
|
|
0.98768834059513777 , 0.99002365771655754 , 0.99211470131447788 , 0.99396095545517971 , 0.99556196460308000 ,
|
|
0.99691733373312796 , 0.99802672842827156 , 0.99888987496197001 , 0.99950656036573160 , 0.99987663248166059 ,
|
|
1.00000000000000000 };
|
|
int s = 0 , n;
|
|
double dx , sx , cx;
|
|
if( x < 0 )
|
|
s = 1 , x = -x;
|
|
x = my_mod(x, 2 * XPI);
|
|
if (x > XPI)
|
|
s = !s , x -= XPI;
|
|
if (x > XPI / 2)
|
|
x = XPI - x;
|
|
n = (int)(x / XINCL);
|
|
dx = x - n * XINCL;
|
|
if (dx > XINCL / 2) {
|
|
++n;
|
|
dx -= XINCL;
|
|
}
|
|
sx = XSinTbl[n];
|
|
cx = XSinTbl[XENTRY-n];
|
|
x = sx + dx*cx - (dx*dx)*sx/2 - (dx*dx*dx)*cx/6 + (dx*dx*dx*dx)*sx/24;
|
|
|
|
return s ? -x : x;
|
|
}
|
|
|
|
double my_cos( double x )
|
|
{
|
|
const float Q = 1.5707963268;
|
|
const float PI =3.1415926536;
|
|
x += Q;
|
|
|
|
if(x > PI)
|
|
x -= 2 * PI;
|
|
|
|
return my_sin(x);
|
|
}
|
|
|
|
static iot_irq_t dma_interrupt_irq = 0;
|
|
static desc_t g_tone_dma_desc[16] = { 0 };
|
|
static iq_data_t tone_data_buf[128] = { 0 };
|
|
|
|
static void IRAM_ATTR dma_local_interrupt_isr(int vector, int data)
|
|
{
|
|
DMA_CHANNEL_ID tx_ch = 0;
|
|
DMA_CONTROLLER controller = (DMA_CONTROLLER)data;
|
|
desc_t *pdesc = g_tone_dma_desc;
|
|
uint8_t desc_cnt = IOT_ARRAY_CNT(g_tone_dma_desc);
|
|
uint32_t tmp;
|
|
uint8_t i;
|
|
|
|
/* out */
|
|
if (tx_ch != DMA_CHANNEL_NONE) {
|
|
if (dma_get_ch_int_status(controller, tx_ch) &
|
|
(1 << DMA_INT_CURR_DECR)) {
|
|
dma_channel_int_clear(controller, tx_ch, DMA_INT_CURR_DECR);
|
|
}
|
|
if (dma_get_ch_int_status(controller, tx_ch) &
|
|
(1 << DMA_INT_ALL_DECR)) {
|
|
dma_channel_int_clear(controller, tx_ch, DMA_INT_ALL_DECR);
|
|
for (i = 0; i < desc_cnt; i++) {
|
|
pdesc[i].owner = DESC_OWNER_DMA;
|
|
}
|
|
DMA2_WRITE_REG(CFG_DMA_CHN0_CFG0_ADDR, (uint32_t)pdesc);
|
|
tmp = DMA2_READ_REG(CFG_DMA_CHN0_CFG2_ADDR);
|
|
REG_FIELD_SET(CH0_START, tmp, 1);
|
|
DMA2_WRITE_REG(CFG_DMA_CHN0_CFG2_ADDR, tmp);
|
|
}
|
|
if (dma_get_ch_int_status(controller, tx_ch) & (1 << DMA_INT_STOP)) {
|
|
dma_channel_int_clear(controller, tx_ch, DMA_INT_STOP);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void rf_phy_tx_tone_raw_test(int8_t tone_num, uint8_t option, uint32_t fchz)
|
|
{
|
|
uint32_t i, tmp;
|
|
double pi = 3.1415926;
|
|
double tmp_cos = 0, tmp_sin = 0;
|
|
desc_t *pdesc = g_tone_dma_desc;
|
|
uint8_t desc_cnt = IOT_ARRAY_CNT(g_tone_dma_desc);
|
|
iq_data_t *tone_data = tone_data_buf;
|
|
|
|
tmp = RFPLC_GENERAL_READ_REG(CFG_RFPLC_DBG_CTRL_ADDR);
|
|
REG_FIELD_SET(SW_WPHY_DMA_STX_DISABLE, tmp, 0);
|
|
REG_FIELD_SET(SW_WPHY_DMA_RX_DISABLE, tmp, 1);
|
|
REG_FIELD_SET(SW_WPHY_DMA_TX_DISABLE, tmp, 1);
|
|
RFPLC_GENERAL_WRITE_REG(CFG_RFPLC_DBG_CTRL_ADDR, tmp);
|
|
|
|
for (i = 0; i < 128; i++) {
|
|
if (tone_num != 0) {
|
|
tmp_cos = my_floor(my_cos(2 * pi * i * tone_num / 128) *
|
|
((1 << 9) - 1));
|
|
tmp_sin = my_floor(my_sin(2 * pi * i * tone_num / 128) *
|
|
((1 << 9) - 1));
|
|
}
|
|
tone_data[i].i_data = (int16_t)tmp_cos;
|
|
tone_data[i].q_data = (int16_t)tmp_sin;
|
|
#if 0
|
|
iot_printf("i:%d, i_data:%d, q_data:%d\n", i,
|
|
tone_data[i].i_data, tone_data[i].q_data);
|
|
#endif
|
|
}
|
|
|
|
dma_hw_deinit(DMA_DEV_WPHY_RTX);
|
|
dma_clk_enable(DMA_CONTROLLER2);
|
|
// Reset channel
|
|
dma_channel_reset(DMA_CONTROLLER2, DMA_CHANNEL_0);
|
|
// Clear all int
|
|
dma_channel_int_clear_all(DMA_CONTROLLER2, DMA_CHANNEL_0);
|
|
// Default to set channel int to dma_int0
|
|
dma_channel_int_select(DMA_CONTROLLER2, DMA_CHANNEL_0, DMA_INT_0);
|
|
if (dma_interrupt_irq == 0) {
|
|
dma_interrupt_irq = iot_interrupt_create(DMA2_INT0, HAL_INTR_PRI_6,
|
|
(iot_addrword_t)2, (iot_isr_t*)dma_local_interrupt_isr);
|
|
iot_interrupt_attach(dma_interrupt_irq);
|
|
}
|
|
iot_interrupt_unmask(dma_interrupt_irq);
|
|
|
|
for (i = 0; i < desc_cnt; i++) {
|
|
DMA_INIT_DESC(pdesc);
|
|
DMA_MAKE_DESC(pdesc, tone_data, sizeof(tone_data_buf),
|
|
sizeof(tone_data_buf), 0, 0, 0, DESC_OWNER_DMA);
|
|
DMA_SET_DESC_ADDR(pdesc, tone_data, 0x52a00000);
|
|
if (i != desc_cnt - 1) {
|
|
pdesc->n_ptr = &pdesc[i + 1];
|
|
} else {
|
|
pdesc->n_ptr = NULL;
|
|
}
|
|
DMA_INTR_DIS(pdesc);
|
|
pdesc++;
|
|
}
|
|
|
|
dma_set_channel_request(DMA_CONTROLLER2, DMA_CHANNEL_0, DMA2_PERI_WPHY_STX);
|
|
dma_set_channel_descriptor(DMA_CONTROLLER2, DMA_CHANNEL_0,
|
|
(dma_descriptor_t *)g_tone_dma_desc);
|
|
|
|
tmp = DMA2_READ_REG(CFG_DMA_CHN0_CFG2_ADDR);
|
|
REG_FIELD_SET(CH0_TX_ADDR_INC_MODE, tmp, 1);
|
|
REG_FIELD_SET(CH0_RX_ADDR_INC_MODE, tmp, 1);
|
|
REG_FIELD_SET(CH0_TRANS_TYPE, tmp, 1);
|
|
REG_FIELD_SET(CH0_TX_BURST_LEN, tmp, 7);
|
|
REG_FIELD_SET(CH0_RX_BURST_LEN, tmp, 7);
|
|
DMA2_WRITE_REG(CFG_DMA_CHN0_CFG2_ADDR, tmp);
|
|
|
|
tmp = DMA2_READ_REG(CFG_DMA_CHN0_CFG4_ADDR);
|
|
REG_FIELD_SET(CH0_TX_WRAP_BURST_TYPE, tmp, 0);
|
|
REG_FIELD_SET(CH0_RX_WRAP_BURST_TYPE, tmp, 0);
|
|
DMA2_WRITE_REG(CFG_DMA_CHN0_CFG4_ADDR, tmp);
|
|
|
|
tmp = DMA2_READ_REG(CFG_DMA_CHN0_INT_ENA_ADDR);
|
|
//REG_FIELD_SET(CH0_CURR_DECR_INT_ENA, tmp, 1);
|
|
REG_FIELD_SET( CH0_ALL_DECR_INT_ENA, tmp, 1);
|
|
REG_FIELD_SET( CH0_STOP_INT_ENA, tmp, 1);
|
|
DMA2_WRITE_REG(CFG_DMA_CHN0_INT_ENA_ADDR, tmp);
|
|
|
|
/* wphy init and config tx tone */
|
|
WPHY_INIT_WRITE_REG(0xf01008, 0x120);
|
|
WPHY_INIT_WRITE_REG(0xf01000, 0x3);
|
|
|
|
/* tx config */
|
|
bb_rf_tx_cfg(option, fchz);
|
|
bb_rf_debug_tx_immd();
|
|
|
|
/* dma start */
|
|
tmp = DMA2_READ_REG(CFG_DMA_CHN0_CFG2_ADDR);
|
|
REG_FIELD_SET(CH0_START, tmp, 1);
|
|
DMA2_WRITE_REG(CFG_DMA_CHN0_CFG2_ADDR, tmp);
|
|
}
|
|
|
|
void rf_phy_tx_tone_raw_test_stop(void)
|
|
{
|
|
if (dma_interrupt_irq) {
|
|
dma_channel_stop(DMA_CONTROLLER2, DMA_CHANNEL_0);
|
|
os_delay(100);
|
|
iot_interrupt_mask(dma_interrupt_irq);
|
|
}
|
|
}
|