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