/***************************************************************************//** * @brief dac_datasel *******************************************************************************/ int dac_datasel(int32_t chan, enum dds_data_select sel) { if (PCORE_VERSION_MAJOR(dds_st.pcore_version) > 7) { if (chan < 0) { /* ALL */ int i; for (i = 0; i < dds_st.num_dds_channels; i++) { dac_write(ADI_REG_CHAN_CNTRL_7(i), sel); } } else { dac_write(ADI_REG_CHAN_CNTRL_7(chan), sel); } } else { uint32_t reg; switch(sel) { case DATA_SEL_DDS: case DATA_SEL_SED: case DATA_SEL_DMA: dac_read(ADI_REG_CNTRL_2, ®); reg &= ~ADI_DATA_SEL(~0); reg |= ADI_DATA_SEL(sel); dac_write(ADI_REG_CNTRL_2, reg); break; default: return -EINVAL; } } return 0; }
/***************************************************************************//** * @brief dac_init *******************************************************************************/ void dac_init(uint8_t data_sel) { uint32_t status; uint32_t tx_count; uint32_t index; uint32_t index_i1; uint32_t index_q1; uint32_t index_i2; uint32_t index_q2; uint32_t data_i1; uint32_t data_q1; uint32_t data_i2; uint32_t data_q2; dac_write(ADI_REG_RSTN, 0x0); dac_write(ADI_REG_RSTN, ADI_RSTN); dac_write(ADI_REG_RATECNTRL, ADI_RATE(3)); dds_st.dac_clk = &ad9361_phy->clks[TX_SAMPL_CLK]->rate; dac_write(ADI_REG_CNTRL_1, 0); switch (data_sel) { case DATA_SEL_DDS: dds_default_setup(DDS_CHAN_TX1_I_F1, 90000, 1000000, 4); dds_default_setup(DDS_CHAN_TX1_I_F2, 90000, 1000000, 4); dds_default_setup(DDS_CHAN_TX1_Q_F1, 0, 1000000, 4); dds_default_setup(DDS_CHAN_TX1_Q_F2, 0, 1000000, 4); dds_default_setup(DDS_CHAN_TX2_I_F1, 90000, 1000000, 4); dds_default_setup(DDS_CHAN_TX2_I_F2, 90000, 1000000, 4); dds_default_setup(DDS_CHAN_TX2_Q_F1, 0, 1000000, 4); dds_default_setup(DDS_CHAN_TX2_Q_F2, 0, 1000000, 4); dac_write(ADI_REG_CNTRL_2, ADI_DATA_SEL(DATA_SEL_DDS)); break; case DATA_SEL_DMA: tx_count = sizeof(sine_lut) / sizeof(uint16_t); dac_write(ADI_REG_VDMA_FRMCNT, tx_count * 8); for(index = 0; index < (tx_count * 2); index+=2) { index_i1 = index; index_q1 = index + (tx_count / 4); if(index_q1 >= (tx_count * 2)) index_q1 -= (tx_count * 2); data_i1 = (sine_lut[index_i1 / 2] << 20); data_q1 = (sine_lut[index_q1 / 2] << 4); Xil_Out32(DAC_DDR_BASEADDR + index * 4, data_i1 | data_q1); index_i2 = index_i1 + (tx_count / 2); index_q2 = index_q1 + (tx_count / 2); if(index_i2 >= (tx_count * 2)) index_i2 -= (tx_count * 2); if(index_q2 >= (tx_count * 2)) index_q2 -= (tx_count * 2); data_i2 = (sine_lut[index_i2 / 2] << 20); data_q2 = (sine_lut[index_q2 / 2] << 4); Xil_Out32(DAC_DDR_BASEADDR + (index + 1) * 4, data_i2 | data_q2); } Xil_DCacheFlush(); vdma_write(XAXIVDMA_CR_OFFSET, 0x0); vdma_write(XAXIVDMA_CR_OFFSET, XAXIVDMA_CR_TAIL_EN_MASK | XAXIVDMA_CR_RUNSTOP_MASK); do { vdma_read(XAXIVDMA_SR_OFFSET, &status); } while((status & 0x01) == 0x01); vdma_write(XAXIVDMA_FRMSTORE_OFFSET, 0x01); vdma_write(XAXIVDMA_MM2S_ADDR_OFFSET | XAXIVDMA_START_ADDR_OFFSET, DAC_DDR_BASEADDR); vdma_write(XAXIVDMA_MM2S_ADDR_OFFSET | XAXIVDMA_STRD_FRMDLY_OFFSET, tx_count * 8); vdma_write(XAXIVDMA_MM2S_ADDR_OFFSET | XAXIVDMA_HSIZE_OFFSET, tx_count * 8); vdma_write(XAXIVDMA_MM2S_ADDR_OFFSET | XAXIVDMA_VSIZE_OFFSET, 1); dac_write(ADI_REG_CNTRL_2, ADI_DATA_SEL(DATA_SEL_DMA)); break; default: break; } dac_write(ADI_REG_CNTRL_1, ADI_ENABLE); }