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

📄 bfsi.c

📁 IP04是一个使用Blackfin开源硬件结合Asterisk开源软件建立的IPPBX系统.
💻 C
📖 第 1 页 / 共 3 页
字号:
  if (isr_between_diff > 800000) {      isr_between_skip++;      isr_between_difflastskip = isr_between_diff;  }  /* read and write sample callbacks */  read_samples = isr_read_processing();  write_samples = isr_write_processing();  if ((bfsi_isr_callback != NULL) && !bfsi_freeze) {    bfsi_isr_callback(read_samples, write_samples);  }  __builtin_bfin_ssync();  /* some stats to help monitor the cycles used by ISR processing */  /*      Simple IIR averager:        y(n) = (1 - 1/TC)*y(n) + (1/TC)*x(n)     After conversion to fixed point:       2*y(n) = ((TC-1)*2*y(n) + 2*x(n) + half_lsb ) >> LTC   */  isr_cycles_average = ( (u32)(TC-1)*isr_cycles_average + 			 (((u32)isr_cycles_last)<<1) + TC) >> LTC;  if (isr_cycles_last > isr_cycles_worst)    isr_cycles_worst = isr_cycles_last;  /* we sample right at the end to make sure we count cycles used to      measure cycles! */  isr_cycles_last = cycles() - start_cycles;    return IRQ_HANDLED;}static int init_sport_interrupts(void){	//unsigned int data32;	#if (defined(CONFIG_BF533) || defined(CONFIG_BF532))	if(request_irq(IRQ_SPORT0_RX, sport_rx_isr,                       SA_INTERRUPT, "sport rx", NULL) != 0) {                return -EBUSY;        }#endif#if defined(CONFIG_BF537)#if defined(BFSI_SPORT0)  	if(request_irq(IRQ_SPORT0_RX, sport_rx_isr, 		       SA_INTERRUPT, "sport rx", NULL) != 0) {    		return -EBUSY;	}#endif#if defined(BFSI_SPORT1)  	if(request_irq(IRQ_SPORT1_RX, sport_rx_isr, 		       SA_INTERRUPT, "sport rx", NULL) != 0) {    		return -EBUSY;	}#endif#endif	if (bfsi_debug) {		printk("ISR installed OK\n");	}#if (defined(CONFIG_BF533) || defined(CONFIG_BF532))	/* enable DMA1 sport0 Rx interrupt */	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 0x00000200);	__builtin_bfin_ssync();#endif#if defined(CONFIG_BF537)#if defined(BFSI_SPORT0)	/* enable DMA3 sport0 Rx interrupt */	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 0x00000020);	__builtin_bfin_ssync();#endif#if defined(BFSI_SPORT1)	/* enable DMA5 sport1 Rx interrupt */	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() | 0x00000080);	__builtin_bfin_ssync();#endif#endif	return 0;}static void enable_dma_sport(void){	/* enable DMAs */#if (defined(CONFIG_BF533) || defined(CONFIG_BF532))	bfin_write_DMA2_CONFIG(bfin_read_DMA2_CONFIG() | DMAEN);	bfin_write_DMA1_CONFIG(bfin_read_DMA1_CONFIG() | DMAEN);	__builtin_bfin_ssync();	/* enable sport0 Tx and Rx */	bfin_write_SPORT0_TCR1(bfin_read_SPORT0_TCR1() | TSPEN);	bfin_write_SPORT0_RCR1(bfin_read_SPORT0_RCR1() | RSPEN);	__builtin_bfin_ssync();#endif#if defined(CONFIG_BF537)#if defined(BFSI_SPORT0)	bfin_write_DMA4_CONFIG(bfin_read_DMA4_CONFIG() | DMAEN);	bfin_write_DMA3_CONFIG(bfin_read_DMA3_CONFIG() | DMAEN);	__builtin_bfin_ssync();	/* enable sport0 Tx and Rx */	bfin_write_SPORT0_TCR1(bfin_read_SPORT0_TCR1() | TSPEN);	bfin_write_SPORT0_RCR1(bfin_read_SPORT0_RCR1() | RSPEN);	__builtin_bfin_ssync();#endif#if defined(BFSI_SPORT1)	bfin_write_DMA6_CONFIG(bfin_read_DMA6_CONFIG() | DMAEN);	bfin_write_DMA5_CONFIG(bfin_read_DMA5_CONFIG() | DMAEN);	__builtin_bfin_ssync();	/* enable sport1 Tx and Rx */	bfin_write_SPORT1_TCR1(bfin_read_SPORT1_TCR1() | TSPEN);	bfin_write_SPORT1_RCR1(bfin_read_SPORT1_RCR1() | RSPEN);	__builtin_bfin_ssync();#endif#endif}static void disable_sport(void){#if (defined(CONFIG_BF533) || defined(CONFIG_BF532))	/* disable sport0 Tx and Rx */	bfin_write_SPORT0_TCR1(bfin_read_SPORT0_TCR1() & (~TSPEN));	bfin_write_SPORT0_RCR1(bfin_read_SPORT0_RCR1() & (~RSPEN));	__builtin_bfin_ssync();	/* disable DMA1 and DMA2 */	bfin_write_DMA2_CONFIG(bfin_read_DMA2_CONFIG() & (~DMAEN));	bfin_write_DMA1_CONFIG(bfin_read_DMA1_CONFIG() & (~DMAEN));	__builtin_bfin_ssync();	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & (~0x00000200));	__builtin_bfin_ssync();#endif#if defined(CONFIG_BF537)#if defined(BFSI_SPORT0)	/* disable sport0 Tx and Rx */	bfin_write_SPORT0_TCR1(bfin_read_SPORT0_TCR1() & (~TSPEN));	bfin_write_SPORT0_RCR1(bfin_read_SPORT0_RCR1() & (~RSPEN));	__builtin_bfin_ssync();	/* disable DMA3 and DMA4 */	bfin_write_DMA4_CONFIG(bfin_read_DMA4_CONFIG() & (~DMAEN));	bfin_write_DMA3_CONFIG(bfin_read_DMA3_CONFIG() & (~DMAEN));	__builtin_bfin_ssync();	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & (~0x00000020));	__builtin_bfin_ssync();#endif#if defined(BFSI_SPORT1)	/* disable sport1 Tx and Rx */	bfin_write_SPORT1_TCR1(bfin_read_SPORT1_TCR1() & (~TSPEN));	bfin_write_SPORT1_RCR1(bfin_read_SPORT1_RCR1() & (~RSPEN));	__builtin_bfin_ssync();	/* disable DMA3 and DMA4 */	bfin_write_DMA6_CONFIG(bfin_read_DMA6_CONFIG() & (~DMAEN));	bfin_write_DMA5_CONFIG(bfin_read_DMA5_CONFIG() & (~DMAEN));	__builtin_bfin_ssync();	bfin_write_SIC_IMASK(bfin_read_SIC_IMASK() & (~0x00000080));	__builtin_bfin_ssync();#endif#endif}int bfsi_proc_read(char *buf, char **start, off_t offset, 		    int count, int *eof, void *data){	int len;	len = sprintf(buf, 		      "readchunk_first.........: %d\n"		      "readchunk_second........: %d\n"		      "readchunk_didntswap.....: %d\n"		      "bad_x...................: %d %d %d %d %d\n"		      "log_readchunk...........: 0x%08x\n"		      "writechunk_first........: %d\n"		      "writechunk_second.......: %d\n"		      "writechunk_didntswap....: %d\n"		      "isr_cycles_last.........: %d\n"		      "isr_cycles_worst........: %d\n"		      "isr_cycles_average......: %d\n"		      "echo_sams...............: %d\n"		      "isr_between_diff........: %d\n"		      "isr_between_worst.......: %d\n"		      "isr_between_skip........: %d\n"		      "isr_between_difflastskip: %d\n",		      readchunk_first,		      readchunk_second,		      readchunk_didntswap,		      bad_x[0],bad_x[1],bad_x[2],bad_x[3],bad_x[4],		      log_readchunk,		      writechunk_first,		      writechunk_second,		      writechunk_didntswap,		      isr_cycles_last,		      isr_cycles_worst,		      isr_cycles_average>>1,		      echo_sams,		      isr_between_diff,		      isr_between_worst,		      isr_between_skip,		      isr_between_difflastskip);	*eof=1;	return len;}static int proc_read_bfsi_freeze(char *buf, char **start, off_t offset,                                 int count, int *eof, void *data){  int len;  unsigned int flags;  *eof = 1;  len = sprintf(buf, "%d\n", bfsi_freeze);  return len;}static int proc_write_bfsi_freeze(struct file *file, const char *buffer,                                  unsigned long count, void *data){  int   new_freeze;  char *endbuffer;  unsigned int flags;  new_freeze = simple_strtol (buffer, &endbuffer, 10);  bfsi_freeze = new_freeze;  return count;}static int proc_write_bfsi_reset(struct file *file, const char *buffer,                                  unsigned long count, void *data){    int i;    isr_cycles_worst = 0;    isr_between_worst = 0;    isr_between_skip = 0;    isr_between_difflastskip = 0;    readchunk_first = 0;    readchunk_second = 0;    readchunk_didntswap = 0;    writechunk_first = 0;    writechunk_second = 0;    writechunk_didntswap = 0;    for(i=0; i<5; i++)	bad_x[i] = 0;    return count;}/*    Wrapper for entire SPORT setup, returns 1 for success, 0 for failure.   The SPORT code is designed to deliver small arrays of size samples   every (125us * samples).  A ping-pong arrangement is used, so the   address of the buffer will alternate every call between two possible   values.   The callback functions privide to the address of the current buffer   for the read and write channels.  Read means the data was just   read from the SPORT, so this is the "receive" PCM samples.  Write   is the PCM data to be written to the SPORT.      The callbacks are called in the context of an interrupt service   routine, so treat any code them like an ISR.   Once this function returns successfully the SPORT/DMA will be up   and running, and calls to the isr callback will start.  For testing   it is OK to set the callback function pointer to NULL, say if you   just want to look at the debug information.      If debug==1 then "cat /proc/bfsi" will display some debug   information, something like:     readchunk_first.....: 9264     readchunk_second....: 9264     readchunk_didntswap.: 0     writechunk_first....: 9264     writechunk_second...: 9264     writechunk_didntswap: 0   If all is well then "readchunk_didntswap" and "writechunk_didntswap"   will be static and some very small number.  The first and second   values should be at most one value different.  These variables   indicate sucessful ping-pong operation.   The numbers are incremented ever interrupt, for example if samples=8   (typical for zaptel), then we get one interrupt every ms, or 1000   interrupts per second.  This means the values for each first/second   entry should go up 500 times per second.   8 channels are sampled at once, so the size of the samples buffers   is 8*samples (typically 64 bytes for zaptel).   TODO:   1/ It might be nice to modify this function allow user defined      SPORT control reg settings, for example to change clock      dividers and frame sync sources.  Or posible provide      a bfsi_sport_set() function.   2/ Modify the callbacks to provide user-dfine context information.   3/ Modify init to define max number of channels, it is currently      hard coded at 8.*/int bfsi_sport_init(  void (*isr_callback)(u8 *read_samples, u8 *write_samples),   int samples,  int debug){  struct proc_dir_entry *freeze, *reset;  if (debug) {    create_proc_read_entry("bfsi", 0, NULL, bfsi_proc_read, NULL);    bfsi_debug = debug;    freeze = create_proc_read_entry("bfsi_freeze", 0, NULL, proc_read_bfsi_freeze, NULL);    freeze->write_proc = proc_write_bfsi_freeze;    reset = create_proc_read_entry("bfsi_reset", 0, NULL, NULL, NULL);    reset->write_proc = proc_write_bfsi_reset;  }  bfsi_isr_callback = isr_callback;  samples_per_chunk = samples;#if (defined(CONFIG_BF533) || defined(CONFIG_BF532))  init_sport0();#endif#if defined(CONFIG_BF537)#if defined(BFSI_SPORT0)  init_sport0();#endif#if defined(BFSI_SPORT1)  init_sport1();#endif#endif  init_dma_wc();  enable_dma_sport();  if (init_sport_interrupts())    init_ok = 0;  else    init_ok = 1;  return init_ok;}/* shut down SPORT operation cleanly */void bfsi_sport_close(void){  disable_sport();  if (init_ok) {#if (defined(CONFIG_BF533) || defined(CONFIG_BF532))    free_irq(IRQ_SPORT0_RX, NULL);#endif#if defined(CONFIG_BF537)#if defined(BFSI_SPORT0)    free_irq(IRQ_SPORT0_RX, NULL);#endif#if defined(BFSI_SPORT1)    free_irq(IRQ_SPORT1_RX, NULL);#endif#endif  }#if L1_DATA_A_LENGTH != 0  l1_data_A_sram_free(iTxBuffer1);  l1_data_A_sram_free(iRxBuffer1);#else  dma_free_coherent(NULL, 2*samples_per_chunk*8, iTxBuffer1, 0);  dma_free_coherent(NULL, 2*samples_per_chunk*8, iRxBuffer1, 0);#endif  remove_proc_entry("bfsi", NULL);  remove_proc_entry("bfsi_freeze", NULL);  remove_proc_entry("bfsi_reset", NULL);}MODULE_LICENSE("GPL");EXPORT_SYMBOL(bfsi_spi_write_8_bits);EXPORT_SYMBOL(bfsi_spi_read_8_bits);EXPORT_SYMBOL(bfsi_spi_init);EXPORT_SYMBOL(bfsi_sport_init);EXPORT_SYMBOL(bfsi_reset);EXPORT_SYMBOL(bfsi_sport_close);

⌨️ 快捷键说明

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