📄 ics_554.c
字号:
0x00, 0x00, 0x00, 0x50 }, }; u8 offset; for ( offset=0x10; offset<=0x17; offset++ ){ wr_ddc_page( 0x40, offset, data40[index][ offset - 0x10 ] ); } for ( offset=0x10; offset<=0x1f; offset++ ){ wr_ddc_page( 0x41, offset, data41[index][ offset - 0x10 ] ); } ics554_ddc_set_res( board, res_empty );}void ics554_ddc_set_output( struct ics_dev *board, u8 index ){ // first try u8 data62[][13] = { { 0xff, 0x40, 0x6c, 0x80, 0xe8, 0x01, 0xe4, 0x10, 0x32, 0x54, 0x76, 0x00, 0x02 }, // umts example { 0xff, 0x40, 0x6c, 0x80, 0x29, 0x01, 0x00, 0x10, 0x32, 0x54, 0x76, 0x02, 0x02 }, // umts example 2 { 0xff, 0x40, 0x6c, 0x80, 0xe8, 0x01, 0xe4, 0x10, 0x32, 0x54, 0x76, 0x02, 0x02 }, // simple { 0xff, 0x40, 0x6c, 0x80, 0xe8, 0x01, 0xe4, 0x10, 0x32, 0x54, 0x76, 0x02, 0x02 } }; u8 offset; for ( offset=0x10; offset<=0x1c; offset++ ){ wr_ddc_page( 0x62, offset, data62[index][ offset - 0x10 ] ); }}void ics554_ddc_set_fir( struct ics_dev *board, u16 page, u16 size, u8 *data ){ u16 offset = 0x10, index; PR_DBG_CL( 4, "[%2x]: ", page ); for ( index=0; index<size; index++ ){ PR_DBG_CL( 4, "[%2x]=%2x, ", offset, *data ); wr_ddc_page( page, offset++, *data++ ); if ( offset > 0x1f ){ offset = 0x10; page++; PR_DBG_CL( 4, "\n[%2x]: ", page ); } } PR_DBG_CL( 4, "\n" );}void ics554_ddc_set_phase( struct ics_dev *board, u8 channel, u16 phase ){ wr_ddc_page( channel * 8 + 6, 16, phase & 0xff ); wr_ddc_page( channel * 8 + 6, 17, phase >> 8 ); rtl_udelay( 10000 );}/* // Work for 10kHz BW *//* void ics554_ddc_set_cic( struct ics_dev *board, u8 channel, u16 dec_ratio, u16 dec_gain ){ *//* u16 N; *//* N=dec_ratio-1; *//* //wr_ddc_page( channel * 8 + 7, 16, N & 0xff ); *//* wr_ddc_page( channel * 8 + 7, 21, N & 0xff ); *//* wr_ddc_page( channel * 8 + 7, 22, 0x70 | ( N >> 8 ) ); *//* wr_ddc_page( channel * 8 + 7, 23, 0x51 ); // SCALE and BIG_SCALE to be changed, default value for N=8... 0x51 worked with the homemade modulation *//* wr_ddc_page( channel * 8 + 7, 30, 0x00 ); //Fine gain [0:7] default value for N=8... *//* wr_ddc_page( channel * 8 + 7, 31, 0x04 ); //Fine gain [8:13]default value for N=8... */ /* rtl_udelay( 10000 ); *//* } */void ics554_ddc_set_cic( struct ics_dev *board, u8 channel, u16 dec_ratio, u16 dec_gain ){ u16 N; N=dec_ratio-1; //wr_ddc_page( channel * 8 + 7, 16, N & 0xff ); wr_ddc_page( channel * 8 + 7, 21, N & 0xff ); wr_ddc_page( channel * 8 + 7, 22, 0x70 | ( N >> 8 ) ); wr_ddc_page( channel * 8 + 7, 23, 0x32); // SCALE and BIG_SCALE to be changed, default value for N=8... 0x51 worked with the homemade modulation wr_ddc_page( channel * 8 + 7, 30, 0x00 ); //Fine gain [0:7] default value for N=8... wr_ddc_page( channel * 8 + 7, 31, 0x04 ); //Fine gain [8:13]default value for N=8... rtl_udelay( 10000 );}void ics554_ddc_set_freq( struct ics_dev *board, u8 channel, u32 freq ){ u8 offset, page = channel * 8 + 6; PR_DBG( 4, "Page: %2x ", page ); for ( offset=18; offset<=21; offset++ ){ PR_DBG_CL( 4, "%2x=%2x ", offset, freq & 0xff ); wr_ddc_page( page, offset, freq & 0xff ); freq >>= 8; } PR_DBG_CL( 4, "\n" );}void ics554_ddc_set_channel( struct ics_dev *board, u8 channel, u8 input, u8 ccp, u8 *cfir, u8 *pfir, u16 phase, double freq , u16 dec_ratio, u16 dec_gain ){ ics554_ddc_set_ccp( board, channel, ccp ); ics554_ddc_set_cfir( board, channel, cfir ); ics554_ddc_set_pfir( board, channel, pfir ); ics554_ddc_set_phase( board, channel, phase ); ics554_ddc_set_freq_d( board, channel, freq, 100 ); // was 81.84 instead of 100... ics554_ddc_set_cic( board, channel, dec_ratio, dec_gain ); wr_ddc_page( channel * 8 + 7, 0x1b, input & 3 );}void ics554_ddc_finalize( struct ics_dev *board, u8 res_index, u8 *res, u8 out_index ){ ics554_ddc_set_resampler( board, res_index ); if ( res ){ ics554_ddc_set_res( board, res ); } ics554_ddc_set_output( board, out_index ); wr_ddc( 0, 0x08 ); wr_ddc( 5, 0x5c ); ics554_ddc_deselect( board ); rtl_udelay( 10000 );}unsigned int ics554_interrupt ( unsigned int irq, struct pt_regs *r){ u64 intRegister, tmp; struct ics_dev *board = &board_rx; static u64 t_last, t_now; static int dma_fifo = 0; /* Read the Interrupt status Register */ intRegister = READ_QL5064_U64(board,IRQ_STAT); t_now = gethrtime(); PR_DBG( 2, "INTR: 0x%16.16llx, count=%i, time=%i\n", intRegister, (u32)board->block_count, ( t_now - t_last ) / 1000 ); t_last = t_now; /* Check if the interrupt was caused by our device */ if( !(intRegister & ( QL_5064_INT_STAT_XMT0 | QL_5064_INT_STAT_RCV0 | QL_5064_INT_STAT_CHN | QL_5064_INT_STAT_USR ) ) ) { return 0; } /* Now Acknowledge the interrupt on the device */ WRITE_QL5064_U64(board,IRQ_STAT,intRegister); /* wait bus to stabilize (QL user manual - ISR 3.11.2.0) */ tmp = READ_QL5064_U64(board, WAIT); if ( board->flags & ICS554_NO_INT ){ PR_DBG( 1, "No interrupt\n" ); return 0; } if ( intRegister & QL_5064_INT_STAT_USR ){ PR_DBG( 3, "usr-interrupt: %x\n", ics554_status( board ) ); WRITE_ICS554_U32( board, IRQ_MASK, 0 ); if ( board->flags & ICS554_INT_DMA ){ int block = board->block_count % board->blocks_per_frame; u64 *d = board->params[0]->addr_rx; PR_DBG( 1, "Doing dma for user\n" ); adc_start_dma(board, 0, d + block * board->block_size, board->block_size * sizeof( u64 ) ); if ( ( board->flags & ICS554_TEST ) && ( board->block_count % 120 ) == 2 ){ pthread_cond_broadcast( &int_554_cond ); } dma_fifo = 1; } } if ( intRegister & QL_5064_INT_STAT_XMT0 ){ int dma_started = 0; PR_DBG( 3, "dma-interrupt: %x\n", ics554_status( board ) ); if ( board->flags & ICS554_INT_DMA ){ if ( dma_fifo == 1 && ( number_channels > 2 ) ){ int block = board->block_count % board->blocks_per_frame; adc_start_dma(board, 1, (u64*)board->params[2]->addr_rx + block * board->block_size, board->block_size * sizeof( u64 ) ); dma_fifo = 0; dma_started = 1; } if ( !dma_started ){ WRITE_ICS554_U32( board, IRQ_MASK, 1 ); board->block_count++; } } } // Re-enable the ira (not necessary in pure linux-kernel-mode) rtl_hard_enable_irq( board->irq ); // Notify that something happened if ( board->flags & ICS554_INT_BROADCAST ){ pthread_cond_broadcast( &int_554_cond ); } return 0;}void ics554_reset( struct ics_dev *board ){ /* Reset QL5064 */ WRITE_QL5064_U64(board, RESET, 1); rtl_udelay(1000); /* Reset QL5064 Dma Interrupt */ WRITE_QL5064_U64( board, IRQ_MASK, ( QL_5064_INT_STAT_XMT0 | QL_5064_INT_STAT_RCV0 | QL_5064_INT_STAT_CHN | QL_5064_INT_STAT_USR) ); rtl_udelay(1000); WRITE_QL5064_U64( board, FIFO, 0x800200020001B ); rtl_udelay(1000); WRITE_ICS554_U32(board, IRQ_MASK, 0x0); rtl_udelay(1000); PR_DBG( 2,"QL_MASK(0x%2.2x)=0x%16.16llx\n", QL_5064_IRQ_MASK, READ_QL5064_U64(board, IRQ_MASK ) ); PR_DBG( 2,"QL_FIFO(0x%2.2x)=0x%16.16llx\n", QL_5064_FIFO, READ_QL5064_U64(board, FIFO) ); //Set Channel mode CONTROL1<08> and CONTROL1<09> WRITE_ICS554_U32( board, CONTROL1, 0x0 | CLOCK_INPUT ); // Two channel mode // rtl_udelay( 10000 ); //Board Reset; clears CR's except set above WRITE_ICS554_U32( board, SOFT_BOARD_RESET, 1); // rtl_udelay( 10000 ); WRITE_GC4016( board, 2, 0 ); ddc_act_page = 0;}void ics554_setup( struct ics_dev *board ){ int ddc, channel; // Setting up the basic board board->block_size = DAQ_DMA_BLOCK_SIZE_QI_SAMPLES * 2 * BOARD_BLOCK_SIZE; board->blocks_per_frame = 20; board->block_count = 0; ics554_board_reset( board, 0, 0x3 ); ics554_fifo_size( board, 0, 65536 - board->block_size - 2 ); ics554_fifo_size( board, 1, 65536 - board->block_size - 2 ); ics554_decimation( board, 32 ); // Setup the DDCs ics554_channel_count( board, 15, 15 ); ics554_ddc_enable( board, 3 ); for ( ddc=3; ddc>=0; ddc-- ){ ics554_ddc_select( board, ddc ); // Setup the channels of the DDC // for ( channel = 0; channel < 4; channel++ ){ // ics554_ddc_set_channel( board, channel, ddc, //4, cfir_17, pfir_17, // channel%2 ? 0xc000:0, CARRIER_MHZ ); //This works for the GPS signal storage don't touch /* for ( channel = 0; channel < 4; channel++ ){ */ /* ics554_ddc_set_channel( board, channel, ddc, */ /* 5, cfir_150, pfir_150, */ /* channel%2 ? 0xc000:0, CARRIER_MHZ ); */ // This work for 10 kHz BW AM /* for ( channel = 0; channel < 4; channel++ ){ */ /* ics554_ddc_set_channel( board, channel, ddc, */ /* 5, cfir_17, pfir_17, */ /* channel%2 ? 0xc000:0, CARRIER_MHZ, 1250, 0 ); */ /* } */ //Testos for ( channel = 0; channel < 4; channel++ ){ ics554_ddc_set_channel( board, channel, ddc, 5, cfir_80, pfir_80, channel%2 ? 0xc000:0, CARRIER_MHZ, 12, 0 ); } //GPS by PHiL changed second param from 6 to 8// 9=5x=0x4 8=0x16 4=1x //9 is used for GPS //ics554_ddc_finalize( board, 9, res_9x32_30, 2 ); //ics554_ddc_finalize( board, 8, res_9x32_60, 2 ); AM 10 kHZ BW ics554_ddc_finalize( board, 9, res_8x64_80, 2 ); //testos // Clean the DDC-selection ics554_ddc_deselect( board ); } ics554_adc_reset( board ); ics554_enable( board, 3, 1 ); rtl_udelay( 10000 );}int ics554_stop(struct ics_dev *board){ PR_DBG( 1, "Starting to exit\n" ); board->flags &= ~ICS554_RUN; adc_cancel_dma( board ); PR_DBG( 1, "Freed thread and memory\n" ); WRITE_QL5064_U64(board, RESET, 1); rtl_udelay(10000);/* if(board->irq >= 0) { *//* rtl_free_irq(board->irq); *//* PR_DBG( 1, "Freed IRQ %i\n", board->irq ); *//* } */ board->flags &= ~ICS554_STARTED; PR_DBG( 1, "Finished 554\n" ); return 0;}int ics554_init(){ if ( ics_get_board( &board_rx, ICS_SUB_DEV_554, ics554_interrupt ) == 0 ){ PR_DBG( 0, "Couldn't find ICS 564 board!\n" ); return -1; } PR_DBG( 0, "Found ICS 554 ADC board\n" ); ics554_reset( &board_rx ); ics554_setup( &board_rx ); board_rx.flags = ICS554_INITIALIZED | ICS554_INT_DMA; return 0;}int ics554_free( struct ics_dev *board ){ int j; if(board->flags & ICS554_INITIALIZED) { if(board->flags & ICS554_STARTED){ ics554_stop(board); } if(board->irq >= 0) { rtl_free_irq(board->irq); PR_DBG( 1, "Freed IRQ %i\n", board->irq ); } for(j=0; j < 3; j++) { iounmap(board->iobase[j]); } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -