/***************************************************************************//** * @brief dds_set_phase *******************************************************************************/ int32_t dds_set_phase(uint32_t chan, uint32_t phase) { uint32_t pcore_version; uint64_t val64; uint32_t reg; dac_read(DAC_REG_VERSION, &pcore_version); if(DAC_PCORE_VERSION_MAJOR(pcore_version) < 8) { dac_write(DAC_REG_CNTRL_1, 0); } dac_read(DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), ®); reg &= ~DAC_DDS_INIT(~0); val64 = (uint64_t) phase * 0x10000ULL + (360000 / 2); val64 = val64 / 360000; reg |= DAC_DDS_INIT(val64); dac_write(DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), reg); if(DAC_PCORE_VERSION_MAJOR(pcore_version) < 8) { dac_write(DAC_REG_CNTRL_1, DAC_ENABLE); } else { dac_write(DAC_REG_CNTRL_1, DAC_SYNC); } return 0; }
int32_t dac_data_src_sel(dac_core *core, int32_t chan, dac_data_src src) { uint32_t pcore_version; uint32_t reg; int32_t i; dac_read(core, DAC_REG_VERSION, &pcore_version); // single core control for all channels if (DAC_PCORE_VERSION_MAJOR(pcore_version) < 7) { dac_read(core, DAC_REG_DATA_CONTROL, ®); reg = (reg & ~DAC_DATA_SEL(~0)) | DAC_DATA_SEL(src); dac_write(core, DAC_REG_DATA_CONTROL, reg); return(0); } // per channel source select for (i = 0; i < (core->no_of_channels * 2); i++) { if ((chan < 0) || (chan == i)) dac_write(core, DAC_REG_DATA_SELECT(i), src); } dac_write(core, DAC_REG_SYNC_CONTROL, DAC_SYNC); return(0); }
/***************************************************************************//** * @brief dds_set_calib_scale_phase *******************************************************************************/ int32_t dds_set_calib_scale_phase(struct ad9361_rf_phy *phy, uint32_t phase, uint32_t chan, int32_t val, int32_t val2) { uint32_t reg; uint32_t i; if (PCORE_VERSION_MAJOR(dds_st[phy->id_no].pcore_version) < 8) { return -1; } i = dds_to_signed_mag_fmt(val, val2); dac_read(phy, DAC_REG_CHAN_CNTRL_8(chan), ®); if (!((chan + phase) % 2)) { reg &= ~DAC_IQCOR_COEFF_1(~0); reg |= DAC_IQCOR_COEFF_1(i); } else { reg &= ~DAC_IQCOR_COEFF_2(~0); reg |= DAC_IQCOR_COEFF_2(i); } dac_write(phy, DAC_REG_CHAN_CNTRL_8(chan), reg); dac_write(phy, DAC_REG_CHAN_CNTRL_6(chan), DAC_IQCOR_ENB); return 0; }
/***************************************************************************//** * @brief dac_datasel *******************************************************************************/ int dac_datasel(struct ad9361_rf_phy *phy, int32_t chan, enum dds_data_select sel) { if (PCORE_VERSION_MAJOR(dds_st[phy->id_no].pcore_version) > 7) { if (chan < 0) { /* ALL */ uint32_t i; for (i = 0; i < dds_st[phy->id_no].num_dds_channels; i++) { dac_write(phy, DAC_REG_CHAN_CNTRL_7(i), sel); } } else { dac_write(phy, DAC_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(phy, DAC_REG_CNTRL_2, ®); reg &= ~DAC_DATA_SEL(~0); reg |= DAC_DATA_SEL(sel); dac_write(phy, DAC_REG_CNTRL_2, reg); break; default: return -EINVAL; } } return 0; }
/***************************************************************************//** * @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_setup *******************************************************************************/ int32_t dac_setup(uint32_t baseaddr) { uint32_t status; dac_baseaddr = baseaddr; dac_write(DAC_REG_RSTN, 0x00); dac_write(DAC_REG_RSTN, 0x03); mdelay(100); dac_read(DAC_REG_STATUS, &status); if(status == 0x0) { xil_printf("DAC Core Status errors.\n\r"); return -1; } else { xil_printf("DAC Core successfully initialized.\n"); return 0; } }
/***************************************************************************//** * @brief dds_set_frequency *******************************************************************************/ void dds_set_frequency(uint32_t chan, uint32_t freq) { uint64_t val64; uint32_t ctrl_reg, reg; dac_read(ADI_REG_CNTRL_1, &ctrl_reg); dds_st.cached_freq[chan] = freq; dac_write(ADI_REG_CNTRL_1, 0); dac_read(ADI_REG_CHAN_CNTRL_2_IIOCHAN(chan), ®); reg &= ~ADI_DDS_INCR(~0); val64 = (u64) freq * 0xFFFFULL; do_div(val64, *dds_st.dac_clk); reg |= ADI_DDS_INCR(val64) | 1; dac_write(ADI_REG_CHAN_CNTRL_2_IIOCHAN(chan), reg); dac_write(ADI_REG_CNTRL_1, ctrl_reg); }
/***************************************************************************//** * @brief dds_set_phase *******************************************************************************/ void dds_set_phase(uint32_t chan, uint32_t phase) { uint64_t val64; uint32_t ctrl_reg, reg; dac_read(ADI_REG_CNTRL_1, &ctrl_reg); dds_st.cached_phase[chan] = phase; dac_write(ADI_REG_CNTRL_1, 0); dac_read(ADI_REG_CHAN_CNTRL_2_IIOCHAN(chan), ®); reg &= ~ADI_DDS_INIT(~0); val64 = (u64) phase * 0x10000ULL + (360000 / 2); do_div(val64, 360000); reg |= ADI_DDS_INIT(val64); dac_write(ADI_REG_CHAN_CNTRL_2_IIOCHAN(chan), reg); dac_write(ADI_REG_CNTRL_1, ctrl_reg); }
/***************************************************************************//** * @brief dac_setup *******************************************************************************/ int32_t dac_setup(mykonosDevice_t *myk_dev, dac_core *core) { uint32_t reg_data; if (core->plddr_bypass_gpio) { /* * The default HDL design features a optional high bandwidth DDR FIFO, * it can be bypassed using this fabric internal GPIO */ gpio_direction_output(core->plddr_bypass_gpio, !(core->dma_type == DMA_PLDDR_FIFO)); } dac_write(core, DAC_REG_RSTN, 0x00); dac_write(core, DAC_REG_RSTN, 0x03); mdelay(100); dac_read(core, DAC_REG_STATUS, ®_data); if (reg_data == 0x0) { printf("%s DAC Core Status errors.\n", __func__); return -1; } core->clock = myk_dev->tx->txProfile->iqRate_kHz * 1000; dac_write(core, DAC_REG_RATECNTRL, DAC_RATE(3)); printf("%s dac core initialized (%"PRIu64" MHz).\n", __func__, core->clock / 1000000); dac_data_setup(core); return 0; }
int32_t dds_set_scale(dac_core *core, uint32_t chan, int32_t scale_micro_units) { uint32_t pcore_version; uint32_t scale_reg; dac_read(core, DAC_REG_VERSION, &pcore_version); // only ise projects support binary shift scaling, if you think you need // this supported in this driver, let us know. if (DAC_PCORE_VERSION_MAJOR(pcore_version) < 6) { printf("%s ERROR: Sorry, binary scale is NOT supported!\n", __func__); return(-1); } scale_reg = scale_micro_units; if (scale_micro_units < 0) scale_reg = scale_micro_units * -1; if (scale_reg >= 1999000) scale_reg = 1999000; scale_reg = (uint32_t)(((uint64_t)scale_reg * 0x4000) / 1000000); if (scale_micro_units < 0) scale_reg = scale_reg | 0x8000; dac_write(core, DAC_REG_SYNC_CONTROL, 0); dac_write(core, DAC_REG_DDS_SCALE(chan), DAC_DDS_SCALE(scale_reg)); dac_write(core, DAC_REG_SYNC_CONTROL, DAC_SYNC); return(0); }
/***************************************************************************//** * @brief dds_get_calib_scale_phase *******************************************************************************/ int32_t dds_get_calib_scale_phase(struct ad9361_rf_phy *phy, uint32_t phase, uint32_t chan, int32_t *val, int32_t *val2) { uint32_t reg; if (PCORE_VERSION_MAJOR(dds_st[phy->id_no].pcore_version) < 8) { return -1; } dac_read(phy, DAC_REG_CHAN_CNTRL_8(chan), ®); /* format is 1.1.14 (sign, integer and fractional bits) */ if (!((phase + chan) % 2)) { reg = DAC_TO_IQCOR_COEFF_1(reg); } else { reg = DAC_TO_IQCOR_COEFF_2(reg); } dds_from_signed_mag_fmt(reg, val, val2); return 0; }
/***************************************************************************//** * @brief dds_set_phase *******************************************************************************/ void dds_set_scale(uint32_t chan, uint32_t scale) { uint32_t ctrl_reg; dac_read(ADI_REG_CNTRL_1, &ctrl_reg); dds_st.cached_scale[chan] = scale; dac_write(ADI_REG_CNTRL_1, 0); dac_write(ADI_REG_CHAN_CNTRL_1_IIOCHAN(chan), ADI_DDS_SCALE(scale)); dac_write(ADI_REG_CNTRL_1, ctrl_reg); }
/***************************************************************************//** * @brief dds_set_frequency *******************************************************************************/ int32_t dds_set_frequency(uint32_t chan, uint32_t freq) { uint32_t pcore_version; uint32_t val; uint64_t val64; uint32_t reg; uint64_t dac_clk; dac_read(DAC_REG_CLK_FREQ, &val); dac_clk = val; dac_read(DAC_REG_CLK_RATIO, &val); dac_clk *= val * 1525; dac_read(DAC_REG_VERSION, &pcore_version); if(DAC_PCORE_VERSION_MAJOR(pcore_version) < 8) { dac_write(DAC_REG_CNTRL_1, 0); } dac_read(DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), ®); reg &= ~DAC_DDS_INCR(~0); val64 = (uint64_t) freq * 0xFFFFULL; val64 = val64 / dac_clk; reg |= DAC_DDS_INCR(val64) | 1; dac_write(DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), reg); if(DAC_PCORE_VERSION_MAJOR(pcore_version) < 8) { dac_write(DAC_REG_CNTRL_1, DAC_ENABLE); } else { dac_write(DAC_REG_CNTRL_1, DAC_SYNC); } return 0; }
/***************************************************************************//** * @brief dds_set_frequency *******************************************************************************/ void dds_set_frequency(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t freq) { uint64_t val64; uint32_t reg; dds_st[phy->id_no].cached_freq[chan] = freq; dac_stop(phy); dac_read(phy, DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), ®); reg &= ~DAC_DDS_INCR(~0); val64 = (uint64_t) freq * 0xFFFFULL; do_div(&val64, *dds_st[phy->id_no].dac_clk); reg |= DAC_DDS_INCR(val64) | 1; dac_write(phy, DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), reg); dac_start_sync(phy, 0); }
/***************************************************************************//** * @brief dds_set_phase *******************************************************************************/ void dds_set_phase(struct ad9361_rf_phy *phy, uint32_t chan, uint32_t phase) { uint64_t val64; uint32_t reg; dds_st[phy->id_no].cached_phase[chan] = phase; dac_stop(phy); dac_read(phy, DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), ®); reg &= ~DAC_DDS_INIT(~0); val64 = (uint64_t) phase * 0x10000ULL + (360000 / 2); do_div(&val64, 360000); reg |= DAC_DDS_INIT(val64); dac_write(phy, DAC_REG_CHAN_CNTRL_2_IIOCHAN(chan), reg); dac_start_sync(phy, 0); }
int32_t dds_set_phase(dac_core *core, uint32_t chan, uint32_t phase) { uint64_t val64; uint32_t reg; dac_write(core, DAC_REG_SYNC_CONTROL, 0); dac_read(core, DAC_REG_DDS_INIT_INCR(chan), ®); val64 = (uint64_t) phase * 0x10000ULL + (360000 / 2); val64 = val64 / 360000; reg = (reg & ~DAC_DDS_INIT(~0)) | DAC_DDS_INIT(val64); dac_write(core, DAC_REG_DDS_INIT_INCR(chan), reg); dac_write(core, DAC_REG_SYNC_CONTROL, DAC_SYNC); return 0; }
int32_t dds_set_frequency(dac_core *core, uint32_t chan, uint32_t freq) { uint64_t val64; uint32_t reg; dac_write(core, DAC_REG_SYNC_CONTROL, 0); dac_read(core, DAC_REG_DDS_INIT_INCR(chan), ®); val64 = (uint64_t) freq * 0xFFFFULL; val64 = val64 / core->clock; reg = (reg & ~DAC_DDS_INCR(~0)) | DAC_DDS_INCR(val64) | 1; dac_write(core, DAC_REG_DDS_INIT_INCR(chan), reg); dac_write(core, DAC_REG_SYNC_CONTROL, DAC_SYNC); return 0; }
float analogout_read(dac_t *obj) { uint32_t value = dac_read(obj); return (float)((float)value * (1.0f / (float)DAC_RANGE)); }
uint16_t analogout_read_u16(dac_t *obj) { return (uint16_t)dac_read(obj); }
float analogout_read(dac_t *obj) { uint32_t value = dac_read(obj); return (float)value * (1.0f / (float)RANGE_12BIT); }
float analogout_read(dac_t *obj) { uint32_t value = dac_read(); return (float)value * (1.0f / (float)0xFFF); }
/***************************************************************************//** * @brief dds_set_phase *******************************************************************************/ void dds_set_scale(uint32_t chan, double scale) { uint32_t ctrl_reg; uint32_t scale_reg; uint32_t sign_part; uint32_t int_part; uint32_t fract_part; if (PCORE_VERSION_MAJOR(dds_st.pcore_version) > 6) { if(scale >= 1.0) { sign_part = 0; int_part = 1; fract_part = 0; dds_st.cached_scale[chan] = 1.0; goto set_scale_reg; } if(scale <= -1.0) { sign_part = 1; int_part = 1; fract_part = 0; dds_st.cached_scale[chan] = -1.0; goto set_scale_reg; } if(scale < 0) { sign_part = 1; int_part = 0; dds_st.cached_scale[chan] = scale; scale *= -1; goto set_scale_reg; } sign_part = 0; int_part = 0; dds_st.cached_scale[chan] = scale; fract_part = (uint32_t)(scale * 0x4000); set_scale_reg: scale_reg = (sign_part << 15) | (int_part << 14) | fract_part; } else { if(scale >= 1.0) { scale_reg = 0; scale = 1.0; } if(scale <= 0.0) { scale_reg = 0; scale = 0.0; } dds_st.cached_scale[chan] = scale; fract_part = (uint32_t)(scale * 1000000); scale_reg = 500000 / fract_part; } dac_read(ADI_REG_CNTRL_1, &ctrl_reg); dac_write(ADI_REG_CNTRL_1, 0); dac_write(ADI_REG_CHAN_CNTRL_1_IIOCHAN(chan), ADI_DDS_SCALE(scale_reg)); dac_write(ADI_REG_CNTRL_1, ctrl_reg); }
/***************************************************************************//** * @brief dac_init *******************************************************************************/ void dac_init(struct ad9361_rf_phy *phy, uint8_t data_sel, uint8_t config_dma) { 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 index_mem; uint32_t data_i1; uint32_t data_q1; uint32_t data_i2; uint32_t data_q2; uint32_t length; dac_write(phy, DAC_REG_RSTN, 0x0); dac_write(phy, DAC_REG_RSTN, DAC_RSTN | DAC_MMCM_RSTN); dds_st[phy->id_no].dac_clk = &phy->clks[TX_SAMPL_CLK]->rate; dds_st[phy->id_no].rx2tx2 = phy->pdata->rx2tx2; if(dds_st[phy->id_no].rx2tx2) { dds_st[phy->id_no].num_buf_channels = 4; dac_write(phy, DAC_REG_RATECNTRL, DAC_RATE(3)); } else { dds_st[phy->id_no].num_buf_channels = 2; dac_write(phy, DAC_REG_RATECNTRL, DAC_RATE(1)); } dac_read(phy, DAC_REG_VERSION, &dds_st[phy->id_no].pcore_version); dac_stop(phy); switch (data_sel) { case DATA_SEL_DDS: dds_default_setup(phy, DDS_CHAN_TX1_I_F1, 90000, 1000000, 250000); dds_default_setup(phy, DDS_CHAN_TX1_I_F2, 90000, 1000000, 250000); dds_default_setup(phy, DDS_CHAN_TX1_Q_F1, 0, 1000000, 250000); dds_default_setup(phy, DDS_CHAN_TX1_Q_F2, 0, 1000000, 250000); if(dds_st[phy->id_no].rx2tx2) { dds_default_setup(phy, DDS_CHAN_TX2_I_F1, 90000, 1000000, 250000); dds_default_setup(phy, DDS_CHAN_TX2_I_F2, 90000, 1000000, 250000); dds_default_setup(phy, DDS_CHAN_TX2_Q_F1, 0, 1000000, 250000); dds_default_setup(phy, DDS_CHAN_TX2_Q_F2, 0, 1000000, 250000); } dac_write(phy, DAC_REG_CNTRL_2, 0); dac_datasel(phy, -1, DATA_SEL_DDS); break; case DATA_SEL_DMA: if(config_dma) { tx_count = sizeof(sine_lut) / sizeof(uint16_t); if(dds_st[phy->id_no].rx2tx2) { #ifdef FMCOMMS5 for(index = 0, index_mem = 0; index < (tx_count * 2); index += 2, index_mem += 4) #else for(index = 0, index_mem = 0; index < (tx_count * 2); index += 2, index_mem += 2) #endif { 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); Xil_Out32(DAC_DDR_BASEADDR + index_mem * 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); Xil_Out32(DAC_DDR_BASEADDR + (index_mem + 1) * 4, data_i2 | data_q2); #ifdef FMCOMMS5 Xil_Out32(DAC_DDR_BASEADDR + (index_mem + 2) * 4, data_i1 | data_q1); Xil_Out32(DAC_DDR_BASEADDR + (index_mem + 3) * 4, data_i2 | data_q2); #endif } } 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] << 20); data_q1 = (sine_lut[index_q1] << 4); Xil_Out32(DAC_DDR_BASEADDR + index * 4, data_i1 | data_q1); } } Xil_DCacheFlush(); if(dds_st[phy->id_no].rx2tx2) { length = (tx_count * 8); } else { length = (tx_count * 4); } #ifdef FMCOMMS5 length = (tx_count * 16); #endif 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, DAC_DDR_BASEADDR); 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); } dac_write(phy, DAC_REG_CNTRL_2, 0); dac_datasel(phy, -1, DATA_SEL_DMA); break; default: break; } dds_st[phy->id_no].enable = true; dac_start_sync(phy, 0); }
/***************************************************************************//** * @brief dds_set_scale *******************************************************************************/ int32_t dds_set_scale(uint32_t chan, int32_t scale_micro_units) { uint32_t pcore_version; uint32_t scale_reg; uint32_t sign_part; uint32_t int_part; uint32_t fract_part; dac_read(DAC_REG_VERSION, &pcore_version); if(DAC_PCORE_VERSION_MAJOR(pcore_version) > 6) { if(scale_micro_units >= 1000000) { sign_part = 0; int_part = 1; fract_part = 0; goto set_scale_reg; } if(scale_micro_units <= -1000000) { sign_part = 1; int_part = 1; fract_part = 0; goto set_scale_reg; } if(scale_micro_units < 0) { sign_part = 1; int_part = 0; scale_micro_units *= -1; } else { sign_part = 0; int_part = 0; } fract_part = (uint32_t)(((uint64_t)scale_micro_units * 0x4000) / 1000000); set_scale_reg: scale_reg = (sign_part << 15) | (int_part << 14) | fract_part; } else { if(scale_micro_units >= 1000000) { scale_reg = 0; scale_micro_units = 1000000; } if(scale_micro_units <= 0) { scale_reg = 0; scale_micro_units = 0; } fract_part = (uint32_t)(scale_micro_units); scale_reg = 500000 / fract_part; } if(DAC_PCORE_VERSION_MAJOR(pcore_version) < 8) { dac_write(DAC_REG_CNTRL_1, 0); } dac_write(DAC_REG_CHAN_CNTRL_1_IIOCHAN(chan), DAC_DDS_SCALE(scale_reg)); if(DAC_PCORE_VERSION_MAJOR(pcore_version) < 8) { dac_write(DAC_REG_CNTRL_1, DAC_ENABLE); } else { dac_write(DAC_REG_CNTRL_1, DAC_SYNC); } return 0; }
/***************************************************************************//** * @brief dac_init *******************************************************************************/ void dac_init(struct ad9361_rf_phy *phy, uint8_t data_sel, uint8_t config_dma) { #ifdef DMA_UIO uint32_t tx_count; uint32_t index, index_i1, index_q1, index_i2, index_q2; uint32_t index_mem; 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; tx_dma_uio_fd = open(TX_DMA_UIO_DEV, O_RDWR); if(tx_dma_uio_fd < 1) { printf("%s: Can't open tx_dma_uio device\n\r", __func__); return; } tx_dma_uio_addr = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, tx_dma_uio_fd, 0); #endif dac_write(phy, DAC_REG_RSTN, 0x0); dac_write(phy, DAC_REG_RSTN, DAC_RSTN); dac_write(phy, DAC_REG_RATECNTRL, DAC_RATE(3)); dds_st[phy->id_no].dac_clk = &phy->clks[TX_SAMPL_CLK]->rate; dds_st[phy->id_no].rx2tx2 = phy->pdata->rx2tx2; if(dds_st[phy->id_no].rx2tx2) { dds_st[phy->id_no].num_dds_channels = 8; } else { dds_st[phy->id_no].num_dds_channels = 4; } dac_read(phy, DAC_REG_VERSION, &dds_st[phy->id_no].pcore_version); dac_write(phy, DAC_REG_CNTRL_1, 0); switch (data_sel) { case DATA_SEL_DDS: dds_default_setup(phy, DDS_CHAN_TX1_I_F1, 90000, 1000000, 250000); dds_default_setup(phy, DDS_CHAN_TX1_I_F2, 90000, 1000000, 250000); dds_default_setup(phy, DDS_CHAN_TX1_Q_F1, 0, 1000000, 250000); dds_default_setup(phy, DDS_CHAN_TX1_Q_F2, 0, 1000000, 250000); if(dds_st[phy->id_no].rx2tx2) { dds_default_setup(phy, DDS_CHAN_TX2_I_F1, 90000, 1000000, 250000); dds_default_setup(phy, DDS_CHAN_TX2_I_F2, 90000, 1000000, 250000); dds_default_setup(phy, DDS_CHAN_TX2_Q_F1, 0, 1000000, 250000); dds_default_setup(phy, DDS_CHAN_TX2_Q_F2, 0, 1000000, 250000); } dac_write(phy, DAC_REG_CNTRL_2, 0); dac_datasel(phy, -1, DATA_SEL_DDS); break; case DATA_SEL_DMA: if(config_dma) { #ifdef DMA_UIO get_file_info(TX_BUFF_MEM_SIZE, &tx_buff_mem_size); get_file_info(TX_BUFF_MEM_ADDR, &tx_buff_mem_addr); 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[phy->id_no].rx2tx2) { #ifdef FMCOMMS5 for(index = 0, index_mem = 0; index < (tx_count * 2); index += 2, index_mem += 4) #else for(index = 0, index_mem = 0; index < (tx_count * 2); index += 2, index_mem += 2) #endif { 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_mem* 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_mem+ 1) * 4))) = data_i2 | data_q2; #ifdef FMCOMMS5 *((unsigned *) (tx_buff_virt_addr + ((index_mem+ 2) * 4))) = data_i1 | data_q1; *((unsigned *) (tx_buff_virt_addr + ((index_mem+ 3) * 4))) = data_i2 | data_q2; #endif } } 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[phy->id_no].rx2tx2) { length = (tx_count * 8); } else { length = (tx_count * 4); } #ifdef FMCOMMS5 length = (tx_count * 16); #endif 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(phy, DAC_REG_CNTRL_2, 0); dac_datasel(phy, -1, DATA_SEL_DMA); break; default: break; } dds_st[phy->id_no].enable = true; dac_start_sync(phy, 0); }
/***************************************************************************//** * @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); }