Files
kunlun/dtest/sadc_test/hw/hw_sadc.c

451 lines
12 KiB
C
Raw Normal View History

2024-09-28 14:24:04 +08:00
/****************************************************************************
*
* 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.
*
* ****************************************************************************/
/* os shim includes */
#include "os_types.h"
#include "os_task.h"
#include "os_utils.h"
/* common includes */
#include "iot_io.h"
#include "iot_bitops.h"
#include "iot_pkt_api.h"
#include "iot_ipc.h"
#include "iot_plc_lib.h"
#include "iot_dbglog_api.h"
#include "iot_config.h"
/* driver includes */
#include "iot_clock.h"
#include "iot_uart.h"
#include "iot_led.h"
/* cli includes */
#include "iot_cli.h"
#include "iot_uart_h.h"
/* debug includes*/
#include "dbg_io.h"
#include "gpio_mtx.h"
#include "gpio_mtx_reg.h"
#include "apb_glb_reg.h"
#include "apb_dma.h"
#include "apb.h"
#include "ap_clk_core_rf.h"
#include "ahb_rf.h"
#include "phy_ana_glb.h"
#include "phy_bb.h"
#include "granite_reg.h"
#include "phy_dfe_reg.h"
#include "hw_reg_api.h"
#include "pin_rf.h"
#include "ana.h"
#include "dma_hw.h"
#include "i2s_reg.h"
#include "sadc_reg.h"
#include "sadc.h"
#include "sadc_hw.h"
#include "i2s_reg.h"
#include "i2s.h"
#include "dma_sw.h"
#include "hw_sadc.h"
#include "hal_sadc.h"
#include "iot_adc_api.h"
unsigned char buf[4][DMA_BUF_SIZE];
int phas_int_buf[4][1536]; //[1024];
desc_t descLs[4];
desc_t *pdesc_sadc_pool;
volatile int recieved_done = 1;
void sadc_i2s_data_buf_diff(volatile unsigned char in_buf[], int raw_buf_size, int *out_buf[])
{
int i = 0;
static int cnt_int[4] = {0, 0, 0, 0};
int tmp = 0;
for (i = 0; i < raw_buf_size; i = i + 4)
{
if (in_buf[i + 3] & 0x80)
{
tmp = ((in_buf[i + 3] << 8) | in_buf[i + 2]) & 0x7FFF;
if (tmp & (1 << 14))
{
tmp |= (1 << 15);
}
out_buf[3][cnt_int[3]++] = tmp;
tmp = (in_buf[i + 1] << 8) | in_buf[i];
out_buf[2][cnt_int[2]++] = tmp;
}
else
{
tmp = (in_buf[i + 3] << 8) | in_buf[i + 2];
if (tmp & (1 << 14))
{
tmp |= (1 << 15);
}
out_buf[1][cnt_int[1]++] = tmp;
tmp = (in_buf[i + 1] << 8) | in_buf[i];
out_buf[0][cnt_int[0]++] = tmp;
}
}
for(i=0; i<4; i++)
{
if (cnt_int[i]>=1024)
{
cnt_int[i] = 0;
}
}
}
void sadc_dma_data_buf_diff(volatile unsigned char in_buf[], int raw_buf_size, int *out_buf[])
{
int i = 0;
static int cnt[4] = {0, 0, 0, 0};
unsigned char phase = 0;
int tmp = 0;
for (i = 0; i < raw_buf_size;)
{
phase = (in_buf[i + 1] & 0xC0) >> 6;
tmp = ((in_buf[i + 1] << 8) | in_buf[i]) & 0x3FFF;
if (tmp & 0x2000)
{
tmp |= 0xC000;
}
out_buf[phase][cnt[phase]++] = tmp;
i = i + 2;
}
for(i=0; i<4; i++)
{
if (cnt[i]>=1024)
{
cnt[i] = 0;
}
}
}
void sadc_dma__handler(int vector, int status)
{
desc_t *pdesc1;
desc_t *pdesc2;
// int i = 0;
// Recycle out descroptors
if (status & DMA_INT_OUT_DONE)
{
pdesc1 = NULL;
if (pdesc1)
{
if (pdesc_sadc_pool)
{
pdesc2 = pdesc_sadc_pool;
while (pdesc2->n_ptr)
{
pdesc2 = pdesc2->n_ptr;
}
pdesc2->n_ptr = pdesc1;
}
else
{
pdesc_sadc_pool = pdesc1;
}
}
}
if (status & DMA_INT_IN_DONE)
{
if((0 == descLs[1].owner)
&&(0 == descLs[1].owner)
&&(0 == descLs[1].owner))
recieved_done = 1;
}
if (status & DMA_INT_ERROR_DEFAULT)
{
// TODO: Error handle.
}
return;
}
void sadc_dma_config(void)
{
int cnt;
dma_hw_open(DMA_DEV_I2S, (dma_int_handler)sadc_dma__handler, NULL);
#ifdef TEST_DMA_MODE
*(int *)0x44016000 |= 1 << 10; //enable sadc dev1
#endif
for (cnt = 0; cnt < DMA_BUF_SIZE; cnt++)
{
buf[1][cnt] = 0x0;
}
for (cnt = 1; cnt < 4; cnt++)
{
DMA_MAKE_DESC(&descLs[cnt], buf[cnt], DMA_BUF_SIZE, 0, 0, 0, 0, DESC_OWNER_DMA);
}
descLs[1].n_ptr = &descLs[2];
descLs[2].n_ptr = &descLs[3];
descLs[3].n_ptr = NULL;
dma_hw_start_recieve(DMA_DEV_I2S, &descLs[1]);
}
void sadc_i2s_cfg(void)
{
uint32_t tmp = 0;
tmp = I2S_READ_REG(CFG_PDM_CFG0_ADDR);
//REG_FIELD_SET(REG_PDM_SADC_DUMP, tmp, 1); //bypass the pdm filter, ignore 8 times down-sampling
// REG_FIELD_SET(REG_PDM_SADC_HP_BYPASS, tmp, 1); //bypass the high freqs
I2S_WRITE_REG(CFG_PDM_CFG0_ADDR, tmp);
tmp = AP_CLK_CORE_RF_READ_REG(CFG_CLK_IIS_CFG1_ADDR);
REG_FIELD_SET(IIS_DIV_M, tmp, 625); //set M=0x271
REG_FIELD_SET(IIS_DIV_N, tmp, 128); //set N=0x80
AP_CLK_CORE_RF_WRITE_REG(CFG_CLK_IIS_CFG1_ADDR, tmp);
// i2s_rx_eof_num_set(4096);
i2s_rx_eof_num_set(0, 65536);
// i2s_rx_eof_num_set(0xFFFFFFFF); //for sadc-i2s sine wave test
i2s_pdm_slave_mod_en(0, I2S_DIR_RX, ENABLE);
i2s_pdm_sadc_64bit_en(0, ENABLE);
i2s_pdm_sadc_en(ENABLE);
i2s_pdm_rx_tx_en(0, I2S_DIR_RX, ENABLE);
i2s_rx_start(0);
}
void sadc_reg_cfg(void)
{
uint8_t reg_id = 0;
uint8_t rodata = 0;
uint32_t rdata = 0;
uint32_t wdata = 0;
uint32_t wmask = 0;
uint32_t tmp = 0;
uint8_t channel[4] = {11, 13, 10, 11};
//uint8_t channel[4] = {8, 9, 12, 13}; //test single pad 0 1 4 5
//uint8_t channel[4] = {11, 12, 13, 10}; //test single pad 0 1 4 5
//uint8_t channel[4] = {10, 9, 12, 13};
//uint8_t channel[4] = {14, 10, 12, 13};
//uint8_t channel[4] = {10, 10, 12, 13};
//uint8_t channel[4] = {15, 8, 12, 13};
//uint8_t channel[4] = {14, 8, 12, 13};
//uint8_t channel[4] = {9, 9, 9, 9};//SADC1
//uint8_t channel[4] = {15, 15, 15, 15};//differential SADC0 & SADC1
//uint8_t gain[4] = {11, 11, 11, 11};
//uint8_t gain[4] = {15, 15, 15, 15};
//uint8_t gain[4] = {25, 25, 25, 25};
//uint8_t gain[4] = {25, 11, 11, 11};
uint8_t gain[4] = {9, 9, 9, 9}; //1001 for gain2
tmp = 0xFFFFFFFF;
AHB_RF_WRITE_REG(CFG_AHB_REG1_ADDR, tmp);
/* enable granite top reg */
reg_id = ANA_GRANITE_TOP_REG;
wdata = TOP_EN_SADC_MASK;
wmask = TOP_EN_SADC_MASK;
ana_i2c_write(reg_id, wdata, wmask);
tmp = APB_GLB_READ_REG(CFG_APB_GLB_GEN0_ADDR);
REG_FIELD_SET(SADC_EB, tmp, 1);
APB_GLB_WRITE_REG(CFG_APB_GLB_GEN0_ADDR, tmp);
tmp = PHY_DFE_READ_REG(CFG_BB_ADA_FORMAT_CFG_ADDR);
REG_FIELD_SET(SW_MON_ADC_SEL, tmp, 1);
PHY_DFE_WRITE_REG(CFG_BB_ADA_FORMAT_CFG_ADDR, tmp);
/* enable granite sadc reg */
reg_id = ANA_GRANITE_SADC_REG;
ana_i2c_read(reg_id, &rdata, &rodata);
REG_FIELD_SET(SADC_EN, rdata, 1); //sadc_en = 1
REG_FIELD_SET(SADC_TIMER_DLY, rdata, 14);
ana_i2c_write(reg_id, rdata, ~0);
#ifdef TEST_DMA_MODE
#error "stop support now"
sadc_data_num_set(ANA_SADC0, 0, 8);
#else
sadc_data_num_set(ANA_SADC0, 0, 8); //64 accumulation data
#endif
sadc_sum_data_clr(1);
sadc_discard_num_set(ANA_SADC0, 0, 2); //wait 1 clock cycle, then accumulate
sadc_phase_mode_set(ANA_SADC0, 0); //0:1 phase mode 1:4 phase mode
sadc_phase_sel(ANA_SADC0, 0); //for 1 phase mode, only 1 and 3 is valid!!
sadc_phase_sel_scl_mux(0, channel[0]); //select SADC0
sadc_phase_sel_scl_mux(1, channel[1]); //select SADC1
sadc_phase_sel_scl_mux(2, channel[2]); //select SADC4
sadc_phase_sel_scl_mux(3, channel[3]); //select SADC5
sadc_adc_gain_set(channel[0] & 0x07, gain[0]); //(channel, gain)
sadc_adc_gain_set(channel[1] & 0x07, gain[1]);
sadc_adc_gain_set(channel[2] & 0x07, gain[2]);
sadc_adc_gain_set(channel[3] & 0x07, gain[3]);
sadc_dc_thr_set(4); //for gain 1/2, the DC calibration is 4
//sadc_need_sub_dc_thr_set(I2S_MODE, 1);
sadc_start_en(ANA_SADC0, 1);
}
#if DT_SADC_POLLING_EN
void sadc_test_task()
{
uint32_t sample_data = 0;//, sample_tmp = 0;
uint8_t timeout = 0;
*(int *)0x44000004 |= 1 << 29; //enable sadc apb
*(int *)0x44000004 |= 1 << 28; //enable i2s apb
*(int *)0x44000004 |= 1 << 21; //enable dma apb
*(int *)0x44000008 |= 1 << 28; //i2s soft reset enable
*(int *)0x44000008 &= ~(1 << 28); //i2s soft reset enable
*(int *)0x44000008 |= 1 << 29; //sadc soft reset enable
*(int *)0x44000008 &= ~(1 << 29); //sadc soft reset enable
*(int *)0x44000008 |= 1 << 21; //dma4 soft reset enable
*(int *)0x44000008 &= ~(1 << 21); //dma4 soft reset enable
sadc_dma_config();
sadc_reg_cfg();
sadc_i2s_cfg();
iot_printf("sadc_i2s_data_buf_diff:\r\n");
/*
gain SADC_GAIN_CFG0
1/10 : 7
1/5 : 15
1/4 : 3
1/3 : 12
1/2 : 11
1 : 27
2 : 9
3 : 17
4 : 25
5 : 40
10 : 56
*/
while(1)
{
sample_data = sadc_poll_data_start(ADC_CHANNEL0_1, \
6,
9,
&timeout);
if (1 == timeout) {
iot_printf("sadc_sum_get time out!\n");
} else {
#if 0
if (sample_data & 0x8000) {
sample_tmp = sample_data - 0x10000;
} else {
sample_tmp = sample_data;
}
iot_printf("%d,\n", sample_tmp);
#else
iot_printf("%d,\n", sample_data);
#endif
}
}
}
#else
void sadc_test_task()
{
int i, j = 0;
//int i = 0;
*(int *)0x44000004 |= 1 << 29; //enable sadc apb
*(int *)0x44000004 |= 1 << 28; //enable i2s apb
*(int *)0x44000004 |= 1 << 21; //enable dma apb
*(int *)0x44000008 |= 1 << 28; //i2s soft reset enable
*(int *)0x44000008 &= ~(1 << 28); //i2s soft reset enable
*(int *)0x44000008 |= 1 << 29; //sadc soft reset enable
*(int *)0x44000008 &= ~(1 << 29); //sadc soft reset enable
*(int *)0x44000008 |= 1 << 21; //dma4 soft reset enable
*(int *)0x44000008 &= ~(1 << 21); //dma4 soft reset enable
int *pt[4];
for (i = 0; i < 4; i++)
{
pt[i] = phas_int_buf[i];
}
sadc_dma_config();
sadc_reg_cfg();
sadc_i2s_cfg();
iot_printf("sadc_i2s_data_buf_diff:\r\n");
while (1)
{
os_delay(500);
while(!recieved_done) __asm volatile("nop\n");
for(i=1; i<4; i++)
{
#ifdef TEST_DMA_MODE
sadc_dma_data_buf_diff(descLs[i].buf, DMA_BUF_SIZE, pt);
#else
sadc_i2s_data_buf_diff(descLs[i].buf, DMA_BUF_SIZE, pt);
#endif
}
for (j = 0; j < 4; j++)
{
// iot_printf("\r\n*******************************************************\r\n");
//iot_printf("\nPHASE%d_INT_data:\n", j);
iot_printf("\n");
for (i = 0; i < SDAC_BUF_SIZE / 2; i++)
{
//iot_printf("%hd, ", (short)pt[j][i]);
iot_printf("%x ", (short)pt[j][i]);
}
}
iot_printf("\n*******************************************************\n");
for (i = 1; i < 4; i++)
{
DMA_MAKE_DESC(&descLs[i], buf[i], DMA_BUF_SIZE, 0, 0, 0, 0, DESC_OWNER_DMA);
}
descLs[1].n_ptr = &descLs[2];
descLs[2].n_ptr = &descLs[3];
descLs[3].n_ptr = NULL;
dma_hw_start_recieve(DMA_DEV_I2S, &descLs[1]);
recieved_done = 0;
}
}
#endif