⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rf_io.c

📁 软件无线电的平台
💻 C
字号:
/***************************************************************************             rf_io.c  - IO-functions for the rf                            -------------------    begin                :  2002    authors              :  Linus Gasser    emails               :  linus.gasser@epfl.ch ***************************************************************************//***************************************************************************                                 Changes                                 ------- date - name - description 02-10-01 - ineiti - create 02-12-11 - ineiti - changed the name from daq_io.c, adjusted daq to rf  **************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************//** * The hardware-interface for the rf-cards */#include "debugging.h"#include "channel_rf.h"#include "rf_io.h"#include "rf_dev.h"#include "memory.h"#define DBG_LVL 0void setup_regs( device_t *dev_rf ) {  unsigned int baseptr, ioptr;  unsigned int rx_pci_address;  unsigned int tx_pci_address;  unsigned int mbox_pci_address;  baseptr = dev_rf->data_base;  ioptr = dev_rf->addr[1];  PR_DBG( 2, "baseptr: %x, ioptr: %x\n", baseptr, ioptr );  rx_pci_address = (unsigned int) virt_to_bus(dev_rf->rx_buffer);  tx_pci_address = (unsigned int) virt_to_bus(dev_rf->tx_buffer);  mbox_pci_address = (unsigned int) virt_to_bus(dev_rf->mboxes);  PR_DBG( 2, "rx: %p-%p\n", dev_rf->rx_buffer, dev_rf->rx_buffer +          dev_rf->blocks_in_frame * DAQ_DMA_BLOCK_SIZE_BYTES );  PR_DBG( 2, "tx: %p-%p\n", dev_rf->tx_buffer, dev_rf->tx_buffer +          dev_rf->blocks_in_frame * DAQ_DMA_BLOCK_SIZE_BYTES );  // Program DMA0 mode reg 80h  // 0000000000000000000 0 0 1 0 1 1 0 0000 11 = 0x583  // width 32 bits  // 0 wait state  // BTERM enable (burst forever)  // Burst enable  outl(0x00000183,ioptr + DMA0_MODE_REG);  // Program DMA0 descriptor pointer register 90h  // 0000000000000000000000000000 1 0 0 0 = 0x8  // Direction: Local to PCI  outl(0x00000008,ioptr + DMA0_DESC_REG);  // Program DMA LOCAL DMA address  // Top of ADC Buffer  outl(ADC_BUFFER,ioptr + DMA0_LOCAL_START);  // Program DMA Block Size  outl(ADC_LOCAL_SIZE, ioptr + DMA0_BYTE_COUNT);  // Program DMA FIFO Thresholds (to be tuned)  outl(0x00000770, ioptr + DMA_THRESHOLD);  // Program Direct Master Range register  // Needed for write to mailbox  outl(DMA_RANGE, ioptr + DIR_MAST_RANGE);  // Program Local Base Address for Direct Master write  // Needed for write to mailbox  outl(MBOX_LOCAL_MAP, ioptr + DIR_MAST_ADD);  // Program Remap for Direct Master write  // Map 1 Mbyte area on local bus + enable Direct Master Memory Access  outl(((unsigned int) 0x00000001) | (mbox_pci_address & 0xFFF00000),       ioptr + DIR_MAST_REMAP);  // Program DMA1 mode reg 94h  // 0000000000000000000 0 0 0 0 1 1 0 0000 11 = 0x183  // width 32 bits  // 0 wait states  // BTERM enable (burst forever)  // Burst enable  outl(0x00000183,ioptr+DMA1_MODE_REG);  // Program DMA1 descriptor pointer register A4h  // 0000000000000000000000000000 0 0 0 0 = 0x0  // Direction: Local to PCI  outl(0x00000000,ioptr+DMA1_DESC_REG);  // Program DMA LOCAL DMA address  // Top of ADC Buffer  outl(DAC_BUFFER,ioptr + DMA1_LOCAL_START);  // Program DMA Block Size  outl(DAC_LOCAL_SIZE, ioptr + DMA1_BYTE_COUNT);  // Program Direct Master Range register  // Needed for write to mailbox  outl(DMA_RANGE, ioptr + DIR_MAST_RANGE);  // Program Local Base Address for Direct Master write  // Needed for write to mailbox  outl(MBOX_LOCAL_MAP, ioptr + DIR_MAST_ADD);  // Program Remap for Direct Master write  // Map 1 Mbyte area on local bus + enable Direct Master Memory Access  outl(((unsigned int) 0x00000001) | (mbox_pci_address & 0xFFF00000),       ioptr + DIR_MAST_REMAP);  // Write PCI address of top of DMA buffer to FPGA  rf_writel(rx_pci_address, baseptr + PCI_BASE_REG_RD);  // Write PCI address of bottom of DMA buffer  rf_writel(rx_pci_address + dev_rf->blocks_in_frame * DAQ_DMA_BLOCK_SIZE_BYTES,            baseptr + PCI_LIMIT_REG_RD);  // Write Local Bus address of PCI Mailbox  rf_writel(MBOX_LOCAL_MAP | (mbox_pci_address & 0x000FFFFF),            baseptr+PCI_MBOX_REG_RD);  // Write PCI address of top of DMA buffer to FPGA  rf_writel(tx_pci_address , baseptr + PCI_BASE_REG_WR);  //0  // Write PCI address of bottom of DMA buffer  rf_writel(tx_pci_address + dev_rf->blocks_in_frame * DAQ_DMA_BLOCK_SIZE_BYTES,            baseptr + PCI_LIMIT_REG_WR);  // Write Local Bus address of PCI Mailbox  rf_writel(MBOX_LOCAL_MAP | ((mbox_pci_address + 4)& 0x000FFFFF),            baseptr + PCI_MBOX_REG_WR);}/** * @short Sets the gains * * This is a special function that is only available with the rf-antenna. * It should be packed in the general interface, but for the moment (dec02) * no certainity exists on how to set a certain gain in dbm. * * There are four gain-controllers on the RF-board. All four can * be set at the same time through this function. * * @param nbr_daq The index of the DAQ [0..MAX_ANTENNAS - 1] * @param tx_pa The transmission power-amplifier gain * @param tx_med The transmission DAC-gain * @param tx_if The transmission intermediate-frequency gain * @param rx_if The reception intermediate-frequency gain * @return 0 for success or -1 for error */int swr_rf_set_gains( device_t *dev_rf,                      int tx_pa, int tx_med, int tx_if, int rx_if ) {  dev_rf->tx_pa_gain = tx_pa;  dev_rf->tx_med_gain = tx_med;  dev_rf->tx_if_gain = tx_if;  dev_rf->rx_if_gain = rx_if;  writegain( dev_rf, TX_PA_GAIN, dev_rf->tx_pa_gain );  writegain( dev_rf, TX_MED_GAIN, dev_rf->tx_med_gain );  writegain( dev_rf, TX_IF_GAIN, dev_rf->tx_if_gain );  writegain( dev_rf, RX_IF_GAIN, dev_rf->rx_if_gain );  PR_DBG( 3, "Wrote gains... if:%i\n", dev_rf->rx_if_gain );  return 0;}/** * @short Reads the gains * * @return 0 for success or -1 for error */int swr_rf_get_gains( device_t *dev_rf,                      int *tx_pa, int *tx_med, int *tx_if, int *rx_if ) {  *tx_pa = dev_rf->tx_pa_gain;  *tx_med = dev_rf->tx_med_gain;  *tx_if = dev_rf->tx_if_gain;  *rx_if = dev_rf->rx_if_gain;  return 0;}// sets particular qdac channel to some levelvoid writegain ( device_t *dev_rf, int channel, int level ) {  unsigned int baseptr=dev_rf->data_base;  unsigned int  qdacword, intlevel;  const unsigned long  // system control wakeup, offset coding  // Vdd/2 for A, B, C, D :  qdacctrl[5] = {                  0x0060, 0x4010, 0x4410, 0x4810, 0x4C10                },                qdacdata[4] = {0x2000, 0x2400, 0x2800, 0x2C00};  intlevel = min(0x3ff,level);  qdacword = qdacdata[channel-1] | intlevel;  // write the control and data word  rf_writel(qdacctrl[0],            baseptr + ODAC);  rtl_delay(10000);  rf_writel(qdacctrl[channel],            baseptr + ODAC);  rtl_delay(10000);  rf_writel(qdacword,            baseptr + ODAC);  rtl_delay(10000);}#define LDAC (1<<13) // Load DAC A#define PDB (1<<12)  // Power down DAC Bvoid write_sdac( device_t *dev_rf, int level ) {  unsigned int baseptr=dev_rf->data_base;  unsigned int qdacword, intlevel;  intlevel = min(0xff,level);  qdacword =  LDAC | PDB | intlevel;  // write the control and data word  rf_writel(qdacword,            baseptr + SDAC);}void setmode( device_t *dev_rf, unsigned int mode ) {  unsigned int baseptr=dev_rf->data_base;  unsigned int oldval,newval;  PR_DBG( 4, "Setting mode to %d\n",mode);  mode&=0xf;  oldval = rf_readl(baseptr + ODAC) & 0xff;  newval = (mode<<12)|oldval;  rf_writel(newval, baseptr + ODAC);}#define Fosc 16e6                  // Reference frequency#define Xmax 32767#define RF_CP_WORD ((1<<1) | 1)     // Charge Pump = 200 uA, +ve VCO polarity#define V2_EN 0                     // Voltage doubled#define DLL_MODE 1                  // Fast#define RF_CNTL_WORD 1              // Normal Operation, Powered up, 32/33void write_lo( device_t *dev_rf, unsigned int freq ) {  unsigned int baseptr=dev_rf->data_base;  int PBA,F,R,RF_N,RF_R;  DEBDIV( freq, "rf_printf::write_lo div0\n" );  R = (int)(((double)Xmax * Fosc)/ (double)freq);  PBA = (int)(((double)freq * R) / (double)Fosc);  F = ((int)(((((double)freq * R )*16))/Fosc))%16;  RF_R = (R<<2) | 2 | (RF_CP_WORD<<17) | (V2_EN<<22) | (DLL_MODE<<23);  RF_N = (RF_CNTL_WORD << 21) | (PBA<<6) | (F<<2) | 3;  rf_writel((1<<23) | (1<<22),baseptr + FSYN); // OSC = 1, Frac = 16  PR_DBG( 4, "IF_R = %x\n",(1<<23) | (1<<22));  rtl_delay((long)3000);  rf_writel(RF_R,baseptr + FSYN);  PR_DBG( 4, "RF_R = %x\n",RF_R);  rtl_delay((long)3000);  rf_writel(RF_N,baseptr + FSYN);  PR_DBG( 4, "RF_N = %x\n",RF_N);  rtl_delay((long) 3000);}int dump_config( device_t *dev_rf, unsigned char bus, unsigned char func ) {  int res;  int i;  unsigned int mask;  unsigned char  b;  unsigned short w;  unsigned int   dw;  struct pci_dev *pdev;  unsigned int addr[] = {                          PCI_BASE_ADDRESS_0,                          PCI_BASE_ADDRESS_1,                          PCI_BASE_ADDRESS_2,                          PCI_BASE_ADDRESS_3,                          PCI_BASE_ADDRESS_4,                          PCI_BASE_ADDRESS_5                        };  res = pcibios_read_config_word(bus, func, PCI_VENDOR_ID, &w);  PR_DBG( 4, "vendor: 0x%04X\n", (int)w);  res = pcibios_read_config_word(bus, func, PCI_DEVICE_ID, &w);  PR_DBG( 4, "device: 0x%04X\n", (int)w);  res = pcibios_read_config_word(bus, func, PCI_COMMAND, &w);  PR_DBG( 4, "command: 0x%04X\n", (int)w);  res = pcibios_read_config_word(bus, func, PCI_STATUS, &w);  PR_DBG( 4, "status: 0x%04X\n", (int)w);  res = pcibios_read_config_dword(bus, func, PCI_CLASS_REVISION, &dw);  PR_DBG( 4, "Class & revision: 0x%08X\n", (int)dw);  res = pcibios_read_config_byte(bus, func, PCI_REVISION_ID, &b);  PR_DBG( 4, "revision: %d\n", (int)b);  res = pcibios_read_config_byte(bus, func, PCI_CACHE_LINE_SIZE, &b);  PR_DBG( 4, "cache line size: %d\n", (int)b);  res = pcibios_read_config_byte(bus, func, PCI_LATENCY_TIMER, &b);  PR_DBG( 4, "latency timer: %d\n", (int)b);  res = pcibios_read_config_byte(bus, func, PCI_HEADER_TYPE, &b);  PR_DBG( 4, "header type: %d\n", (int)b);  res = pcibios_read_config_byte(bus, func, PCI_BIST, &b);  PR_DBG( 4, "burst ist: %d\n", (int)b);  for(i = 0; i <= 5; ++i) {    res = pcibios_read_config_dword(bus,  func, addr[i], &dw);    res = pcibios_write_config_dword(bus, func, addr[i], ~0);    res = pcibios_read_config_dword(bus,  func, addr[i], &mask);    res = pcibios_write_config_dword(bus, func, addr[i], dw);    if(dw != 0) {      PR_DBG( 4, "----------------\n");      if(dw & PCI_BASE_ADDRESS_SPACE_IO) {        PR_DBG( 4, "I/O\n");        dev_rf->addr[i] = dw & PCI_BASE_ADDRESS_IO_MASK;        dw ^= PCI_BASE_ADDRESS_SPACE_IO; /* Clean the last bit */        mask ^= PCI_BASE_ADDRESS_SPACE_IO; /* Clean the last bit */      } else {        PR_DBG( 4, "memory\n");        dev_rf->addr[i] = dw & PCI_BASE_ADDRESS_MEM_MASK;        switch(dw & PCI_BASE_ADDRESS_MEM_TYPE_MASK) {        case PCI_BASE_ADDRESS_MEM_TYPE_32:          PR_DBG( 4, "32 bits address\n");          break;        case PCI_BASE_ADDRESS_MEM_TYPE_1M:          PR_DBG( 4, "below 1M address\n");          break;        case PCI_BASE_ADDRESS_MEM_TYPE_64:          PR_DBG( 4, "64 bits address\n");          break;        default:          PR_DBG( 4, "ERROR: unkown address type\n");          break;        }        if(dw & PCI_BASE_ADDRESS_MEM_PREFETCH) {          PR_DBG( 4, "prefetchable\n");        } else {          PR_DBG( 4, "not prefetchable\n");        }      }      PR_DBG( 4, "Base address %d: 0x%08x\n", i, dev_rf->addr[i]);      PR_DBG( 4, "size: 0x%08X\n", (unsigned int)~mask + 1);    }  }  PR_DBG( 4, "----------------\n");  pdev = pci_find_slot(bus, func);  dev_rf->irq = pdev->irq;  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -