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

📄 sport_interface.c

📁 IP04是一个使用Blackfin开源硬件结合Asterisk开源软件建立的IPPBX系统.
💻 C
字号:
/* * File:	sport_interface.c * * Author:	Alex Tao <wosttq@gmail.com> * * Based on:	bfsi.c    by David Rowe  *                  bfin_sport.c   by Roy Huang (roy.huang@analog.com) *  * Created:	Jun 3, 2007 * Description: This device driver enables SPORT1 on Blackfin532 interfacing  *              to Silicon Labs chips. *//* * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see the file COPYING, or write * to the Free Software Foundation, Inc., * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */#include <linux/kernel.h>#include <linux/interrupt.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/types.h>#include <linux/proc_fs.h>#include <linux/fcntl.h>#include <linux/delay.h>#include <asm/blackfin.h>#include <asm/system.h>#include <asm/uaccess.h>#include "sport_interface.h"//#define SPORT_INTERFACE_DEBUG#ifdef SPORT_INTERFACE_DEBUG#define PRINTK(args...) printk(args)#else#define PRINTK(args...)#endif#ifdef SPORT_INTERFACE_DEBUGstatic int txCnt = 0, rxCnt = 0;#endif#ifndef SPI_NCSB/* Use other PF signals */#define SPI_NCSA    8    /* Simulate SPORT interface as SPI */#define SPI_NCSB    9#endif#define SPORT_nPWR	12#ifndef SPORT1_REGBASE#define SPORT1_REGBASE 0xFFC00900#endif#define DEFINE_SPORT1_REG(reg, off) \static inline u16 sport1_read_##reg(void) \            { return *(volatile unsigned short*)(SPORT1_REGBASE + off); } \static inline void sport1_write_##reg(u16 v) \            {*(volatile unsigned short*)(SPORT1_REGBASE + off) = v;\             __builtin_bfin_ssync();}DEFINE_SPORT1_REG(TCR1,0x00)DEFINE_SPORT1_REG(TCR2,0x04)DEFINE_SPORT1_REG(TCLKDIV,0x08)DEFINE_SPORT1_REG(TFSDIV,0x0C)DEFINE_SPORT1_REG(RCR1, 0x20)DEFINE_SPORT1_REG(RCR2, 0x24)DEFINE_SPORT1_REG(RCLKDIV,0x28)DEFINE_SPORT1_REG(RFSDIV,0x2C)DEFINE_SPORT1_REG(STAT,0x30)static int sport_configure(int baud);/* When FX_MODE, we need not fill the struct of sport_config */static int sport_configure(int baud){	/* Register SPORTx_TCR1 ( relative details pls refer 12-12 of hardware reference ) 	        TCKFE ( Clock Falling Edge Select )   ( Bit14 )           	LTFS ( Bit11) :  0 - Active high TFS; 1 - Active low TFS		ITFS ( Bit9 ) :  0 - External TFS used; 1 - Internal TFS used 		TFSR: 0 - Dose not require TFS for every data word;  1 - Requires TFS for every data word		TLSBIT: 0 - Transmit MSB first ;  1 - Transmit LSB first		ITCLK: 0 - External transmit clock selected; 1 - Internal transmit clock selected	*/	sport1_write_TCR1(TCKFE | LATFS | LTFS | TFSR | ITFS | ITCLK);		/* 8 bit word length  */	sport1_write_TCR2(0x7);    	/* SPORTx_TCLK frequency = ( System Clock frequency ) / ( 2 * ( SPORTx_TCLKDIV + 1 ) )   */	sport1_write_TCLKDIV(baud);	sport1_write_TFSDIV(0x7);		/* Initialization of SPORT1_RCR1 and SPORT1_RCR2, similar to the Register SPORTx_TCR1  and SPORTx_TCR2 */	sport1_write_RCR1(RCKFE | LARFS | LRFS | RFSR);  	sport1_write_RCR2(0x7);      /* 8 bit word length      */		sport1_write_RCLKDIV(baud);	sport1_write_RFSDIV(0x7);		__builtin_bfin_ssync();	PRINTK("tcr1:0x%x, tcr2:0x%x, rcr1:0x%x, rcr2:0x%x\n",		sport1_read_TCR1(), sport1_read_TCR2(),		sport1_read_RCR1(), sport1_read_RCR2());	return 0;}void sport_tx_byte(u16 chip_select, u8 bits){	u16 tmp;	/* drop chip select */	if ( chip_select >7 )	{		/* Clear PFx used for chip_select */		bfin_write_FIO_FLAG_C( 1<<chip_select ); 		__builtin_bfin_ssync();		ndelay(25);	//tsu1 - Setup Time, /CS to SCLK fall	}		tmp = bits & 0x0ff;	bfin_write_SPORT1_TX16(tmp);	while (!(sport1_read_STAT() & TXHRE));	/*  Wait for the last byte sent out  */	udelay(2);	/* Raise chip select */	if ( chip_select >7 )	{		/* Raise PFx High*/		bfin_write_FIO_FLAG_S((1<<chip_select)); 		__builtin_bfin_ssync();	}#ifdef SPORT_INTERFACE_DEBUG	txCnt++;	PRINTK("Send the %d byte OK!\n", txCnt);#endif	return;}u8 sport_rx_byte(u16 chip_select){	u8 ret = 0;	PRINTK("Come into %s\n",__FUNCTION__);	/* Enable the receive operation */	sport1_write_RCR1( sport1_read_RCR1() | RSPEN ); 	while (!(sport1_read_RCR1() & RSPEN));		/* drop chip select */	if ( chip_select >7 )	{		/* Clear PFx used for chip_select */		bfin_write_FIO_FLAG_C( 1<<chip_select ); 		__builtin_bfin_ssync();	}	/* Write a dummy byte to generate a FSYNC */	bfin_write_SPORT1_TX16(0x00ff);	while (!(sport1_read_STAT() & RXNE))	{		PRINTK("%s Line%d:status:%x  %d \n", __FUNCTION__, __LINE__, sport1_read_STAT(), txCnt);	}	ret = (u8)bfin_read_SPORT1_RX16();	PRINTK("%s Line%d: tcr1:0x%x, tcr2:0x%x, rcr1:0x%x, rcr2:0x%x\n",		__FUNCTION__, __LINE__,		sport1_read_TCR1(), sport1_read_TCR2(),		sport1_read_RCR1(), sport1_read_RCR2());	/* Raise chip select */	if ( chip_select >7 )	{		/* Raise High of PFx */		bfin_write_FIO_FLAG_S((1<<chip_select)); 		__builtin_bfin_ssync();	}	sport1_write_RCR1( sport1_read_RCR1() & ~(RSPEN) ); 	ndelay(200);	__builtin_bfin_ssync();	PRINTK("%s Line%d receive byte OK!\n",__FUNCTION__, __LINE__ );	return ret;} void sport_interface_cleanup(void){	sport1_write_TCR1( sport1_read_TCR1() & ~(TSPEN) ); 	sport1_write_RCR1( sport1_read_RCR1() & ~(RSPEN) ); 	__builtin_bfin_ssync();}int sport_interface_init(int baud, u16 new_chip_select_mask){	sport_configure(baud); /* Default should be 0x1 */	PRINTK("Before setting, FIOD_DIR = 0x%04x\n", bfin_read_FIO_DIR());	PRINTK("Before setting, new_chip_select_mask = 0x%04x\n", new_chip_select_mask);	if (new_chip_select_mask & 0xff00) 	{		bfin_write_FIO_DIR(bfin_read_FIO_DIR() | 				   (new_chip_select_mask & 0xff00) |				   (1<<SPORT_nPWR)				   ); 		__builtin_bfin_ssync();	}	PRINTK("After setting, FIOD_DIR = 0x%04x\n", bfin_read_FIO_DIR());	bfin_write_FIO_FLAG_S( 1 << SPORT_nPWR );		//Enable SPORT1 interface	sport1_write_TCR1( sport1_read_TCR1() | TSPEN );	return 0; /* succeed */}void sport_interface_reset(int reset_bit){	/* Port from David! Thanks, David!*/  	PRINTK("set reset to PF%d\n",reset_bit);  	bfin_write_FIO_DIR(bfin_read_FIO_DIR() | (1<<reset_bit));   	__builtin_bfin_ssync();  	bfin_write_FIO_FLAG_C((1<<reset_bit));   	__builtin_bfin_ssync();  	udelay(100);  	bfin_write_FIO_FLAG_S((1<<reset_bit));  	__builtin_bfin_ssync();	  	/*  	p24 3050 data sheet, allow 1ms for PLL lock, with  	less than 1ms (1000us) register 2 would have  	a value of 0 rather than 3, indicating a bad reset.  	*/  	udelay(1000); }EXPORT_SYMBOL( sport_tx_byte );EXPORT_SYMBOL( sport_rx_byte );EXPORT_SYMBOL( sport_interface_init );EXPORT_SYMBOL( sport_interface_reset );EXPORT_SYMBOL( sport_interface_cleanup );MODULE_LICENSE("GPL");MODULE_AUTHOR("Alex Tao <wosttq@gmail.com>");

⌨️ 快捷键说明

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