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
 | |
| 
 |