451 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			451 lines
		
	
	
		
			12 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.
 | 
						|
 *
 | 
						|
 * ****************************************************************************/
 | 
						|
 | 
						|
/* 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
 | 
						|
 |