/***************************************************************************//** * @brief dac_init *******************************************************************************/ void dac_init(struct ad9361_rf_phy *phy, uint8_t data_sel) { 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 | ADI_MMCM_RSTN); dac_write(ADI_REG_RATECNTRL, ADI_RATE(3)); dds_st.dac_clk = &phy->clks[TX_SAMPL_CLK]->rate; dds_st.num_dds_channels = 8; // FIXME dac_read(ADI_REG_VERSION, &dds_st.pcore_version); dac_stop(); switch (data_sel) { case DATA_SEL_DDS: dds_default_setup(DDS_CHAN_TX1_I_F1, 90000, 1000000, 0.25); dds_default_setup(DDS_CHAN_TX1_I_F2, 90000, 1000000, 0.25); dds_default_setup(DDS_CHAN_TX1_Q_F1, 0, 1000000, 0.25); dds_default_setup(DDS_CHAN_TX1_Q_F2, 0, 1000000, 0.25); dds_default_setup(DDS_CHAN_TX2_I_F1, 90000, 1000000, 0.25); dds_default_setup(DDS_CHAN_TX2_I_F2, 90000, 1000000, 0.25); dds_default_setup(DDS_CHAN_TX2_Q_F1, 0, 1000000, 0.25); dds_default_setup(DDS_CHAN_TX2_Q_F2, 0, 1000000, 0.25); dac_write(ADI_REG_CNTRL_2, 0); dac_datasel(-1, DATA_SEL_DDS); break; case DATA_SEL_DMA: tx_count = sizeof(sine_lut) / sizeof(uint16_t); for(index = 0; index < (tx_count * 2); index += 2) { index_i1 = index; index_q1 = index + (tx_count / 2); 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); // FIXME index_i2 = index_i1; index_q2 = index_q1; 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); // FIXME } dac_dma_write(AXI_DMAC_REG_CTRL, 0); dac_dma_write(AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_ENABLE); // FIXME dac_dma_write(AXI_DMAC_REG_SRC_ADDRESS, DAC_DDR_BASEADDR); dac_dma_write(AXI_DMAC_REG_SRC_STRIDE, 0x0); dac_dma_write(AXI_DMAC_REG_X_LENGTH, (tx_count * 8) - 1); dac_dma_write(AXI_DMAC_REG_Y_LENGTH, 0x0); dac_dma_write(AXI_DMAC_REG_START_TRANSFER, 0x1); dac_write(ADI_REG_CNTRL_2, 0); dac_datasel(-1, DATA_SEL_DMA); break; default: break; } dds_st.enable = true; dac_start_sync(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); }
/***************************************************************************//** * @brief dac_init *******************************************************************************/ void dac_init(struct ad9361_rf_phy *phy, uint8_t data_sel) { uint32_t tx_count; uint32_t index, index_i1, index_q1, index_i2, index_q2; uint32_t data_i1, data_q1, data_i2, data_q2; uint32_t length; int dev_mem_fd; uint32_t mapping_length, page_mask, page_size; void *mapping_addr, *tx_buff_virt_addr; #ifdef DMA_UIO printf("%s: Open txdma_uio device\n\r", __func__); txdma_uio_fd = open(TXDMA_UIO_DEV, O_RDWR); if(txdma_uio_fd < 1) { printf("%s: Can't open txdma_uio device\n\r", __func__); return; } txdma_uio_addr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, txdma_uio_fd, 0); #endif 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 = &phy->clks[TX_SAMPL_CLK]->rate; dds_st.rx2tx2 = phy->pdata->rx2tx2; if(dds_st.rx2tx2) { dds_st.num_dds_channels = 8; } else { dds_st.num_dds_channels = 4; } dac_read(ADI_REG_VERSION, &dds_st.pcore_version); dac_write(ADI_REG_CNTRL_1, 0); switch (data_sel) { case DATA_SEL_DDS: dds_default_setup(DDS_CHAN_TX1_I_F1, 90000, 1000000, 0.25); dds_default_setup(DDS_CHAN_TX1_I_F2, 90000, 1000000, 0.25); dds_default_setup(DDS_CHAN_TX1_Q_F1, 0, 1000000, 0.25); dds_default_setup(DDS_CHAN_TX1_Q_F2, 0, 1000000, 0.25); if(dds_st.rx2tx2) { dds_default_setup(DDS_CHAN_TX2_I_F1, 90000, 1000000, 0.25); dds_default_setup(DDS_CHAN_TX2_I_F2, 90000, 1000000, 0.25); dds_default_setup(DDS_CHAN_TX2_Q_F1, 0, 1000000, 0.25); dds_default_setup(DDS_CHAN_TX2_Q_F2, 0, 1000000, 0.25); } dac_write(ADI_REG_CNTRL_2, 0); dac_datasel(-1, DATA_SEL_DDS); break; case DATA_SEL_DMA: #ifdef DMA_UIO dev_mem_fd = open("/dev/mem", O_RDWR | O_SYNC); if(dev_mem_fd == -1) { printf("%s: Can't open /dev/mem device\n\r", __func__); return; } page_size = sysconf(_SC_PAGESIZE); mapping_length = (((TX_BUFF_MEM_SIZE / page_size) + 1) * page_size); page_mask = (page_size - 1); mapping_addr = mmap(NULL, mapping_length, PROT_READ | PROT_WRITE, MAP_SHARED, dev_mem_fd, (TX_BUFF_MEM_ADDR & ~page_mask)); if(mapping_addr == MAP_FAILED) { printf("%s: mmap error\n\r", __func__); return; } tx_buff_virt_addr = (mapping_addr + (TX_BUFF_MEM_ADDR & page_mask)); tx_count = sizeof(sine_lut) / sizeof(uint16_t); if(dds_st.rx2tx2) { for(index = 0; index < (tx_count * 2); index += 2) { index_i1 = index; index_q1 = index + (tx_count / 2); 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); *((unsigned *) (tx_buff_virt_addr + (index * 4))) = data_i1 | data_q1; index_i2 = index_i1; index_q2 = index_q1; 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); *((unsigned *) (tx_buff_virt_addr + ((index + 1) * 4))) = data_i2 | data_q2; } } else { for(index = 0; index < tx_count; index += 1) { index_i1 = index; index_q1 = index + (tx_count / 4); if(index_q1 >= tx_count) index_q1 -= tx_count; data_i1 = (sine_lut[index_i1 / 2] << 20); data_q1 = (sine_lut[index_q1 / 2] << 4); *((unsigned *) (tx_buff_virt_addr + (index * 4))) = data_i1 | data_q1; } } munmap(mapping_addr, mapping_length); close(dev_mem_fd); if(dds_st.rx2tx2) { length = (tx_count * 8); } else { length = (tx_count * 4); } dac_dma_write(AXI_DMAC_REG_CTRL, 0); dac_dma_write(AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_ENABLE); dac_dma_write(AXI_DMAC_REG_SRC_ADDRESS, TX_BUFF_MEM_ADDR); dac_dma_write(AXI_DMAC_REG_SRC_STRIDE, 0x0); dac_dma_write(AXI_DMAC_REG_X_LENGTH, length - 1); dac_dma_write(AXI_DMAC_REG_Y_LENGTH, 0x0); dac_dma_write(AXI_DMAC_REG_START_TRANSFER, 0x1); #endif dac_write(ADI_REG_CNTRL_2, 0); dac_datasel(-1, DATA_SEL_DMA); break; default: break; } dds_st.enable = true; dac_start_sync(0); }