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

📄 ics_564.c

📁 软件无线电的平台
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************             ics_564.c  -  ICS-564 driver                            -------------------    begin                :  2003    authors              :  Linus Gasser    emails               :  linus.gasser@epfl.ch ***************************************************************************//***************************************************************************                                 Changes                                 ------- date - name - description 03-09-16 - ineiti - create **************************************************************************//*************************************************************************** *                                                                         * *    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.                                   * *                                                                         * ***************************************************************************/#include "system.h"#include "ics_564.h"#include "ics_564_test.h"#include "ql_5064.h"#include <linux/pci.h>#include "debugging.h"#include <math.h>#include "std.h"#include "rtl_time.h"#include "rf_ics.h"#define DBG_LVL 0u16 old_regout;void ics564_dac_write( struct ics_dev *board, u8 dac, u8 addr, u8 data ){  u32 val;  dac &= 3;  addr &= 0x1f;  val = (u32)data + ( (u32)addr << 8 ) + ( (u32)dac << 13 );  PR_DBG( 4,"Setting dac(%hi) at %hi to %hx\n", dac, addr, data );  WRITE_ICS564_U32(board, DAC_INSTR, val);  rtl_udelay(1000);}u8 ics564_dac_read( struct ics_dev *board, u8 dac, u8 addr ){  u32 val;  u32 data;  dac &= 3;  addr &= 0x1f;  val = ( (u32)addr << 8 ) + ( (u32)dac << 13 ) + DAC_INSTRUCTION_RW;  WRITE_ICS564_U32(board, DAC_INSTR, val);  rtl_udelay(1000);  data = READ_ICS564_U32( board, DAC_INSTR );  PR_DBG( 4,"Reading dac(%i) at %i: %x\n", dac, addr, data );    return (u8)data;}void ics564_freq( struct ics_dev *board, int dac, u32 freq ){  int i;  for ( i=2; i<=5; i++ ){    ics564_dac_write( board, dac, i, freq & 0xff );    freq >>= 8;  }  WRITE_ICS564_U32( board, DAC_CONFIG, 0x10000 );  WRITE_ICS564_U32( board, DAC_CONFIG, 0x11000 );  WRITE_ICS564_U32( board, DAC_CONFIG, 0x01000 );  WRITE_ICS564_U32( board, DAC_CONFIG, 0x00000 );}/** * updates the frequency and goes into the 'other' profile */void ics564_freq_quad( struct ics_dev *board, int dac, 		       int profile, u32 freq ){  int i;  u32 dac_config = READ_ICS564_U32( board, DAC_CONFIG );  profile = max( profile, 0 );  profile = min( profile, 3 );  for ( i=2; i<=5; i++ ){    ics564_dac_write( board, dac, i + profile * 6, freq & 0xff );    freq >>= 8;  }    dac_config &= ~( 3 << ( dac * 2 ) );  dac_config |= profile << ( dac * 2 );  WRITE_ICS564_U32( board, DAC_CONFIG, dac_config );  PR_DBG( 4, "Wrote %x to dac %i and profile %i\n",	  dac_config, dac, profile );}void ics564_set_imr( struct ics_dev *board, u8 dac ){  u32 old, mask;  old = READ_ICS564_U32( board, IRQ_MASK );  mask = ( (1<<(u32)dac) << 4 );  WRITE_ICS564_U32( board, IRQ_MASK, old | mask );  //  rtl_udelay( 1000 );}void ics564_clear_imr( struct ics_dev *board, u8 dac ){  u32 old, mask;  old = READ_ICS564_U32( board, IRQ_MASK );  mask = ( (1<<(u32)dac) << 4 );  WRITE_ICS564_U32( board, IRQ_MASK, old & ~mask );  //  rtl_udelay( 1000 );}void ics564_dac_set_base( struct ics_dev *board, int dac, u16 config ){  ics564_dac_write( board, dac, 0, config & 0xff );  ics564_dac_write( board, dac, 1, config >> 8 );  PR_DBG( 1, "Setting dac %i to %2x/%2x\n", dac, 	  config & 0xff, config >> 8 );}u16 ics564_dac_config_base( u16 refclk, u16 pll_lock, u16 lsb_first, u16 sdio,		     u16 mode, u16 auto_power, u16 sleep,		     u16 bypass_inv_sinc, u16 cic_clear ){//  u16 temp;  // Set all parameters to good values  refclk = min( refclk, (u16)0x14 );  if ( refclk < 4 ) refclk = 1;    mode = min( (u16)2, mode );  #if 1  return refclk + ( !!pll_lock << 5 ) + ( !!lsb_first << 6 ) + ( !! sdio << 7 )+   ( mode << 8 ) + ( !!auto_power << 10 ) + ( !! sleep << 11 ) +   ( !!bypass_inv_sinc << 14 ) + ( !!cic_clear << 15 );#else  return temp;  temp = refclk + ( !!pll_lock << 5 ) + ( !!lsb_first << 6 ) + ( !! sdio << 7 );  temp += ( mode << 8 ) + ( !!auto_power << 10 ) + ( !! sleep << 11 );  temp += ( !!bypass_inv_sinc << 14 ) + ( !!cic_clear << 15 );  return temp;#endif}void ics564_dac_set_profile( struct ics_dev *board, int dac, int profile, u64 config ){  int i;  profile = min( profile, 3 );  profile = max( profile, 0 );  PR_DBG( 1, "Setting dac %i/%i to %8.8x-%4.4x\n", dac, profile, 	  (u32)( config & 0xffffffff ), (u32)( config >> 32 ) );  for ( i = 0; i < 6; i++ ){    ics564_dac_write( board, dac, i + profile * 6 + 2, config & 0xff );    config >>= 8;  }}u64 ics564_dac_config_profile( u64 frequency, 			u64 bypass_inv_cic, u64 inv_spect, u64 cic_interp,			u64 scaling ){  cic_interp = min( cic_interp, (u64)0x3f );  cic_interp = max( cic_interp, (u64)1 );  return frequency + ( (u64)!!bypass_inv_cic << 32 ) +     ( (u64)!!inv_spect << 33 ) + ( (u64)cic_interp << 34 ) +     ( (u64)scaling << 40 );}void ics564_fifo_setup( struct ics_dev *board, int size ){  u32 x;  int ld, sel;  ld = size / 4;  sel = size & 3;  // Set LD-flags ( + PCI LD flag )  x = ld * ( 0x1f << 5 );  // Set select-flags  x += sel * ( 0x55 << 10 );  PR_DBG( 1, "FIFO-setup: %x\n", x );  WRITE_ICS564_U32( board, FIFO, x );  WRITE_ICS564_U32( board, FIFO, x + ( 1 << 3 ) );  WRITE_ICS564_U32( board, FIFO, x );  }void ics564_setup_control( struct ics_dev *board, u32 m1, u32 m2, u32 m3, u32 m4,			u32 enable, u32 ext_trig, u32 ext_clock ){  u32 val;  val = m1 + (m2<<2) + (m3<<4) + (m4<<6) + (!!enable << 15 );  val += (!!ext_trig << 8) + (!!ext_clock << 17);  WRITE_ICS564_U32( board, CONTROL, val );  rtl_udelay( 10000 );  /*  #define ics564_dac_setup_control(board,d1,d2,d3,d4,enable) WRITE_ICS564_U32( board,\  CONTROL, (u32)DAC_MODE_##d1 + ((u32)DAC_MODE_##d2<<2) + ((u32)DAC_MODE_##d3<<4) + \           ((u32)DAC_MODE_##d4<<6) + (!!((u32)enable) << 15 ) )  */}void ics564_load( struct ics_dev *board, u32 dacs ){  u32 fifo;    // Mask all four dacs  dacs &= 0xf;  fifo = READ_ICS564_U32( board, FIFO );  fifo &= ~( 0xf << 5 );  PR_DBG( 1, "Loading fifos: %x, dacs: %x\n", fifo, dacs );  WRITE_ICS564_U32( board, FIFO, fifo );  // Enable triggering  rtl_udelay( 10000 );  WRITE_ICS564_U32( board, LOAD, dacs );  rtl_udelay( 10000 );  // Enable PCI for sure  dacs += 0x10;  // And enable writing to the fifos  fifo |= dacs << 5;  WRITE_ICS564_U32( board, FIFO, fifo );  PR_DBG( 4, "Finished\n" );}void ics564_setup_datapath( struct ics_dev *board, u32 dacs, u32 enable ){  //  WRITE_ICS564_U32( board, USER_CONTROL, ( dacs & 0xf ) << 1 );  WRITE_ICS564_U32( board, USER_CONTROL, ( ( dacs & 0xf ) << 1 ) + !!enable );}void ics564_start_dma( struct ics_dev *board, u64 dac, 		    void *from, u64 count ){  WRITE_QL5064_U64( board, TOICS_PCI_ADDR, virt_to_bus( from ) );  WRITE_QL5064_U64( board, TOICS_COUNT, count );  WRITE_QL5064_U64( board, LOC_RCV0_CNT_ADDR, ( count << 32 ) + 		    0x80000 * 0 );  WRITE_QL5064_U64( board, DMA_CONTROL, DMA_START_TOICS );}void ics564_cancel_dma( struct ics_dev *board ){  WRITE_QL5064_U8( board, LOC_DMA_CANCEL, 1 );}void ics564_send_serial( struct ics_dev *board,u8 w_size, u32 word, 			 u8 chip, u16 tx, u16 adr){  int i;  u16 reg_out; // 8bits: ADR1,ADR2,SYN_CE,SYN_Data,SYN_Clk,ATT_CE,ATT_Data,ATT_Clk  int shift=0;  u32 orig_word=word;  u8 dir=0;  /* reg_out = 0;     WRITE_ICS564_U16( board, USER_IO,  reg_out);     usleep( 10 );  */  switch( chip ){  case ICS_564_ATT_CHIP:    shift=0;    dir=0; //clock'in LSB first    break;  case ICS_564_SYNTH_CHIP:    shift=3;    dir=1; //clock'in MSB first    break;  }  tx=tx<<8; // an extra nine'th bit for the rx/tx commutation  adr=adr<<6;  reg_out = 4;  WRITE_ICS564_U16( board, USER_IO,  adr + tx + ( reg_out << shift ));  usleep( 10 );    reg_out = 5;  WRITE_ICS564_U16( board, USER_IO, adr + tx + ( reg_out << shift ));  usleep( 10 );      for ( i=0; i<w_size; i++ ){    word=orig_word>>(dir*(w_size-i-1)+(1-dir)*i);    reg_out = ( 0 << 2 )+( ( word & 0x1 ) << 1 ) + 0;    PR_DBG( 4, "%2i: reg_out is %x\n", i, reg_out );    WRITE_ICS564_U16( board, USER_IO, adr + tx + ( reg_out << shift ));    usleep( 10 );    reg_out = ( 0 << 2 ) + ( ( word & 0x1 ) << 1 ) + 1;    WRITE_ICS564_U16( board, USER_IO, adr + tx + ( reg_out << shift ));    usleep( 10 );  }    reg_out = 4;  WRITE_ICS564_U16( board, USER_IO, adr + tx + ( reg_out << shift ));  usleep( 10 );    reg_out = 4;  WRITE_ICS564_U16( board, USER_IO, adr + tx + ( reg_out << shift ));  usleep( 10 );  }u32 last_time, old_time, past_time;#define TIME_PAST old_time = last_time; last_time = gethrtime() / 1000; \                  past_time = last_time - old_time#define DMA_PRELOAD 9#define TIME_SHOW ((DMA_PRELOAD + 10)*board->number_channels)void ics564_dma_next_block( struct ics_dev *board ){  int block_offset, ch, bc, ch_inv;  bc = board->block_count;  ch = bc % board->number_channels;  //  ch_inv = ( ch + 2 ) % 4;  ch_inv = ch;  block_offset = bc / board->number_channels;  block_offset %= board->blocks_per_frame;  if ( ( bc % 1000 ) < TIME_SHOW ){

⌨️ 快捷键说明

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