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

📄 bfsi.c

📁 IP04是一个使用Blackfin开源硬件结合Asterisk开源软件建立的IPPBX系统.
💻 C
📖 第 1 页 / 共 3 页
字号:
                __builtin_bfin_ssync();		bfin_write_PORTFIO_DIR(bfin_read_PORTFIO_DIR() | 0x0010);		__builtin_bfin_ssync();		bfin_write_PORTFIO_CLEAR(1<<4);		__builtin_bfin_ssync();		udelay(100);		bfin_write_PORTFIO_SET(1<<4);		__builtin_bfin_ssync();        } else if (reset_bit == 7) {                PRINTK("Error: cannot set reset to PJ5\n");        }#endif	  /*      p24 3050 data sheet, allow 1ms for PLL lock, with     less than 1ms (1000us) I found register 2 would have     a value of 0 rather than 3, indicating a bad reset.  */  udelay(1000); }/*-------------------------- SPORT FUNCTIONS ----------------------------*//* Init serial port but dont enable just yet, we need to set up DMA first *//* Note SPORT0 is used for the BF533 STAMP and SPORT1 for the BF537 due to   the physical alignment of the 4fx cards on the STAMP boards. *//* Note a better way to write init code that works for both sports is   in uClinux-dist /linux-2.6.x/sound/blackfin/bf53x_sport.c.  A   structure is set up with the SPORT register addresses referenced to   the base ptr of the structure.  This means one function can be used   to init both SPORTs, just by changing the base addr of the ptr. */#if (defined(CONFIG_BF533) || defined(CONFIG_BF532))static void init_sport0(void){	/* set up FSYNC and optionally SCLK using Blackfin Serial port */  	/* Note: internalclock option not working at this stage - Tx side	   appears not to work, e.g. TFS pin never gets asserted. Not a 	   huge problem as the BF internal clock is not at quite the	   right frequency (re-crystal of STAMP probably required), so 	   we really need an external clock anyway.  However it would	   be nice to know why it doesnt work! */	if (internalclock) {		bfin_write_SPORT0_RCLKDIV(24);  /* approx 2.048MHz PCLK            */		bfin_write_SPORT0_RFSDIV(255);  /* 8 kHz FSYNC with 2.048MHz PCLK  */	}			else {		bfin_write_SPORT0_RFSDIV(255);  /* 8 kHz FSYNC with 2.048MHz PCLK  */	}	/* external tx clk, not data dependant, MSB first */	bfin_write_SPORT0_TCR2(7);      /* 8 bit word length      */	bfin_write_SPORT0_TCR1(0);	/* rx enabled, MSB first, internal frame sync     */	bfin_write_SPORT0_RCR2(7);      /* 8 bit word length      */	if (internalclock) {		bfin_write_SPORT0_RCR1(IRFS | IRCLK);	}	else {		bfin_write_SPORT0_RCR1(IRFS);	}	/* Enable MCM 8 transmit & receive channels       */	bfin_write_SPORT0_MTCS0(0x000000FF);	bfin_write_SPORT0_MRCS0(0x000000FF);		/* MCM window size of 8 with 0 offset             */	bfin_write_SPORT0_MCMC1(0x0000);	/* 0 bit delay between FS pulse and first data bit,	   multichannel frame mode enabled, 	   multichannel tx and rx DMA packing enabled */	bfin_write_SPORT0_MCMC2(0x001c);}#endif#if defined(CONFIG_BF537)static void init_sport1(void){        /* BF537 specific pin muxing configuration */        bfin_write_PORT_MUX(bfin_read_PORT_MUX() | PGTE|PGRE|PGSE);        __builtin_bfin_ssync();        bfin_write_PORTG_FER(bfin_read_PORTG_FER() | 0xFF00);        __builtin_bfin_ssync();	if (internalclock) {		bfin_write_SPORT1_RCLKDIV(24);  		bfin_write_SPORT1_RFSDIV(255); 	}			else {		bfin_write_SPORT1_RFSDIV(255); 	}	bfin_write_SPORT1_TCR2(7);      /* 8 bit word length      */	bfin_write_SPORT1_TCR1(0);	/* rx enabled, MSB first, internal frame sync     */	bfin_write_SPORT1_RCR2(7);      /* 8 bit word length      */	if (internalclock) {		bfin_write_SPORT1_RCR1(IRFS | IRCLK);	}	else {		bfin_write_SPORT1_RCR1(IRFS);	}	/* Enable MCM 8 transmit & receive channels       */	bfin_write_SPORT1_MTCS0(0x000000FF);	bfin_write_SPORT1_MRCS0(0x000000FF);		/* MCM window size of 8 with 0 offset             */	bfin_write_SPORT1_MCMC1(0x0000);	/* 0 bit delay between FS pulse and first data bit,	   multichannel frame mode enabled, 	   multichannel tx and rx DMA packing enabled */	bfin_write_SPORT1_MCMC2(0x001c);}#endif/* init DMA for autobuffer mode, but dont enable yet */static void init_dma_wc(void){#if (defined(CONFIG_BF533) || defined(CONFIG_BF532))  /* Set up DMA1 to receive, map DMA1 to Sport0 RX */  bfin_write_DMA1_PERIPHERAL_MAP(0x1000);  bfin_write_DMA1_IRQ_STATUS(bfin_read_DMA1_IRQ_STATUS() | 0x2);#endif#if defined(CONFIG_BF537)#if defined(BFSI_SPORT0)  /* Set up DMA3 to receive, map DMA3 to Sport0 RX */  bfin_write_DMA3_PERIPHERAL_MAP(0x3000);  bfin_write_DMA3_IRQ_STATUS(bfin_read_DMA3_IRQ_STATUS() | 0x2);#endif  #if defined(BFSI_SPORT1)  /* Set up DMA5 to receive, map DMA5 to Sport1 RX */  bfin_write_DMA5_PERIPHERAL_MAP(0x5000);  bfin_write_DMA5_IRQ_STATUS(bfin_read_DMA5_IRQ_STATUS() | 0x2);#endif  #endif    #if L1_DATA_A_LENGTH != 0  iRxBuffer1 = (char*)l1_data_A_sram_alloc(2*samples_per_chunk*8);#else	  {     dma_addr_t addr;    iRxBuffer1 = (char*)dma_alloc_coherent(NULL, 2*samples_per_chunk*8, &addr, 0);  }#endif  if (bfsi_debug)    printk("iRxBuffer1 = 0x%x\n", (int)iRxBuffer1);#if (defined(CONFIG_BF533) || defined(CONFIG_BF532))  /* Start address of data buffer */  bfin_write_DMA1_START_ADDR(iRxBuffer1);  /* DMA inner loop count */  bfin_write_DMA1_X_COUNT(samples_per_chunk*8);  /* Inner loop address increment */  bfin_write_DMA1_X_MODIFY(1);  bfin_write_DMA1_Y_MODIFY(1);  bfin_write_DMA1_Y_COUNT(2);		  /* Configure DMA1     8-bit transfers, Interrupt on completion, Autobuffer mode */  bfin_write_DMA1_CONFIG(WNR | WDSIZE_8 | DI_EN | 0x1000 | DI_SEL | DMA2D);   /* Set up DMA2 to transmit, map DMA2 to Sport0 TX */  bfin_write_DMA2_PERIPHERAL_MAP(0x2000);  /* Configure DMA2 8-bit transfers, Autobuffer mode */  bfin_write_DMA2_CONFIG(WDSIZE_8 | 0x1000 | DMA2D);#endif#if defined(CONFIG_BF537)#if defined(BFSI_SPORT0)  /* Start address of data buffer */  bfin_write_DMA3_START_ADDR(iRxBuffer1);  /* DMA inner loop count */  bfin_write_DMA3_X_COUNT(samples_per_chunk*8);  /* Inner loop address increment */  bfin_write_DMA3_X_MODIFY(1);  bfin_write_DMA3_Y_MODIFY(1);  bfin_write_DMA3_Y_COUNT(2);		  /* Configure DMA3     8-bit transfers, Interrupt on completion, Autobuffer mode */  bfin_write_DMA3_CONFIG(WNR | WDSIZE_8 | DI_EN | 0x1000 | DI_SEL | DMA2D);   /* Set up DMA4 to transmit, map DMA4 to Sport0 TX */  bfin_write_DMA4_PERIPHERAL_MAP(0x4000);  /* Configure DMA4 8-bit transfers, Autobuffer mode */  bfin_write_DMA4_CONFIG(WDSIZE_8 | 0x1000 | DMA2D);#endif  #if defined(BFSI_SPORT1)  /* Start address of data buffer */  bfin_write_DMA5_START_ADDR(iRxBuffer1);  /* DMA inner loop count */  bfin_write_DMA5_X_COUNT(samples_per_chunk*8);  /* Inner loop address increment */  bfin_write_DMA5_X_MODIFY(1);  bfin_write_DMA5_Y_MODIFY(1);  bfin_write_DMA5_Y_COUNT(2);		  /* Configure DMA5     8-bit transfers, Interrupt on completion, Autobuffer mode */  bfin_write_DMA5_CONFIG(WNR | WDSIZE_8 | DI_EN | 0x1000 | DI_SEL | DMA2D);   /* Set up DMA6 to transmit, map DMA6 to Sport1 TX */  bfin_write_DMA6_PERIPHERAL_MAP(0x6000);  /* Configure DMA2 8-bit transfers, Autobuffer mode */  bfin_write_DMA6_CONFIG(WDSIZE_8 | 0x1000 | DMA2D);#endif  #endif  #if L1_DATA_A_LENGTH != 0  iTxBuffer1 = (char*)l1_data_A_sram_alloc(2*samples_per_chunk*8);#else	  {     dma_addr_t addr;    iTxBuffer1 = (char*)dma_alloc_coherent(NULL, 2*samples_per_chunk*8, &addr, 0);  }#endif  if (bfsi_debug)    printk("iTxBuffer1 = 0x%x\n", (int)iTxBuffer1);#if (defined(CONFIG_BF533) || defined(CONFIG_BF532))  /* Start address of data buffer */  bfin_write_DMA2_START_ADDR(iTxBuffer1);  /* DMA inner loop count */  bfin_write_DMA2_X_COUNT(samples_per_chunk*8);  /* Inner loop address increment */  bfin_write_DMA2_X_MODIFY(1);  bfin_write_DMA2_Y_MODIFY(1);  bfin_write_DMA2_Y_COUNT(2);#endif#if defined(CONFIG_BF537)#if defined(BFSI_SPORT0)  /* Start address of data buffer */  bfin_write_DMA4_START_ADDR(iTxBuffer1);  /* DMA inner loop count */  bfin_write_DMA4_X_COUNT(samples_per_chunk*8);  /* Inner loop address increment */  bfin_write_DMA4_X_MODIFY(1);  bfin_write_DMA4_Y_MODIFY(1);  bfin_write_DMA4_Y_COUNT(2);#endif#if defined(BFSI_SPORT1)  /* Start address of data buffer */  bfin_write_DMA6_START_ADDR(iTxBuffer1);  /* DMA inner loop count */  bfin_write_DMA6_X_COUNT(samples_per_chunk*8);  /* Inner loop address increment */  bfin_write_DMA6_X_MODIFY(1);  bfin_write_DMA6_Y_MODIFY(1);  bfin_write_DMA6_Y_COUNT(2);#endif#endif}/* works out which write buffer is available for writing */static u8 *isr_write_processing(void) {        u8  *writechunk;	int  writepingpong;	int  x;	/* select which ping-pong buffer to write to */#if (defined(CONFIG_BF533) || defined(CONFIG_BF532))	x = (int)(bfin_read_DMA2_CURR_ADDR()) - (int)iTxBuffer1;#endif#if defined(CONFIG_BF537)#if defined(BFSI_SPORT0)	x = (int)(bfin_read_DMA4_CURR_ADDR()) - (int)iTxBuffer1;#endif#if defined(BFSI_SPORT1)	x = (int)(bfin_read_DMA6_CURR_ADDR()) - (int)iTxBuffer1;#endif#endif	/* for some reason x for tx tends to be 0xe and 0x4e, whereas	   x for rx is 0x40 and 0x80.  Not sure why they would be	   different.  We could perhaps consider having	   different interrupts for tx and rx side.  Hope this	   offset doesn't kill the echo cancellation, e.g. if we	   get echo samples in rx before tx has sent them!	*/	if (x >= 8*samples_per_chunk) {		writechunk = (unsigned char*)iTxBuffer1;		writechunk_first++;		writepingpong = PING;	}	else {		writechunk = (unsigned char*)iTxBuffer1 + samples_per_chunk*8;		writechunk_second++;		writepingpong = PONG;	}	/* make sure writechunk actually ping pongs */	if (writepingpong == lastwritepingpong) {		writechunk_didntswap++;	}	lastwritepingpong = writepingpong;	return writechunk;}/* works out which read buffer is available for reading */static u8 *isr_read_processing(void) {        u8 *readchunk;	int readpingpong;	int x,i;	/* select which ping-pong buffer to write to */#if (defined(CONFIG_BF533) || defined(CONFIG_BF532))	x = (int)bfin_read_DMA1_CURR_ADDR() - (int)iRxBuffer1;#endif#if defined(CONFIG_BF537)#if defined(BFSI_SPORT0)	x = (int)bfin_read_DMA3_CURR_ADDR() - (int)iRxBuffer1;#endif#if defined(BFSI_SPORT1)	x = (int)bfin_read_DMA5_CURR_ADDR() - (int)iRxBuffer1;#endif#endif	/* possible values for x are 8*samples_per_chunk=0x40 at the	   end of the first row and 2*8*samples_per_chunk=0x80 at the	   end of the second row */	if ((x & 0x7f) >= 8*samples_per_chunk) {		readchunk = iRxBuffer1;		readchunk_first++;		readpingpong = PING;	}	else {		readchunk = iRxBuffer1 + samples_per_chunk*8;		readchunk_second++;		readpingpong = PONG;	}	log_readchunk = readchunk;	/* memory of x for debug */	for(i=0; i<4; i++)	    last_x[i] = last_x[i+1];	last_x[4] = x;	/* make sure readchunk actually ping pongs */	if (readpingpong == lastreadpingpong) {		readchunk_didntswap++;		memcpy(bad_x, last_x, sizeof(bad_x));	}	lastreadpingpong = readpingpong;	return readchunk;}/* called each time the DMA finishes one "line" */static irqreturn_t sport_rx_isr(int irq, void *dev_id, struct pt_regs * regs){  unsigned int  start_cycles = cycles();  u8           *read_samples;  u8           *write_samples;  /* confirm interrupt handling, write 1 to DMA_DONE bit */#if (defined(CONFIG_BF533) || defined(CONFIG_BF532))  bfin_write_DMA1_IRQ_STATUS(0x0001);#endif#if defined(CONFIG_BF537)#if defined(BFSI_SPORT0)  bfin_write_DMA3_IRQ_STATUS(0x0001);#endif#if defined(BFSI_SPORT1)  bfin_write_DMA5_IRQ_STATUS(0x0001);#endif#endif  __builtin_bfin_ssync();   __builtin_bfin_ssync();    /* Measure clock cycles since last interrupt.  This should always be less     than 1ms.  */    isr_between_diff = start_cycles - isr_between_prev;  isr_between_prev = start_cycles;  if (isr_between_diff > isr_between_worst)      isr_between_worst = isr_between_diff;  /* note hard coded for 400MHz clock, 400000 cycles between ISRs, so     800000 means we didnt process within 2ms */

⌨️ 快捷键说明

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