ADSP—BF561 的SPORT口是全双工的,可以同时发送和接收数据。本驱动主要通过软件设置和处理,利用SPORT口的发送功能,发送16位的串行数据字。其中有效数据位8位,最低位在前,拥有与 UART异步数据相同的数据格式,在主机端可用超级终端等软件接收。
驱动中需在file_operations结构里实现的主要接口函数有open(),write()和ioetl()。
(1)open() 函数
在open()函数中,需初始化SPORTl口相应的寄存器。以下是几个重要的寄存器设置。
①SPORTl_TCLKDIV:SPORTl口发送时钟频率设置。
SPORTl_TCLKDIV=(SYS_CLOCK_FREQUENCY/2*MO—DEM_BAUD_RATE))一 1;/*SYS_CLOCK_FREQUENCY为系统时钟频率,通过测试,此处应取值为98 390 000。MODEM_BAUD_RATE为波特率,用户可通过调用iootl()进行设置*/
②SPORTl_TFSDIV:SPORTl口的发送帧同步频率设置,确定在TFS脉冲前要计数的发送时钟周期数。 SPORTl_TFSDIV=0x000f;
③SPORTl_TCR2:设置串行通信字长。SPORTl_TCR2=0x000f; //设置串行通信字长为16位
④SPORTl_TCRl:SPORTl口的主要控制寄存器。SPORTl_TCRl=0x0613; /*传输使能。发送数据时,设置低位优先,设置串口为内部时钟,内部产生帧同步信号,传送时可按照实际的波特率发送数据*/
(2)write() 函数
write()函数的主要功能是将应用程序中写入SPORT口的数据转换成UART的数据格式输出,主要实现流程如下:
①分配缓冲区以存放转换后的数据(用kmalloc实现)。
②数据格式的转换。要用SPORT口模拟UART口,就要使从SPORT口发出的数据与从UART口发出的数据具有相同的数据格式。在驱动中将从 SPORT口发出的数据设置为1位起始位、8位数据位、1位停止位,即“O DO D1 D2 D3 D4 D5 D6 D7 l”。停止位与起始位之间可有多个1,但一旦停止位后有O,便认为是下一个字符的开始。应用程序中传入的数据要经过相应转换才能写入SPORT的发送寄存器。具体转换过程为:
[!--empirenews.page--]
③数据的发送。SPORT1_STAT中的TXF位指示发送FIFO中是否有空位,其值为1表示FIFO已满,为0表示FIFO中仍有空位。
(3)ioctl() 函数
ioctl()是设备驱动程序中对设备I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口传输波特率的选择。驱动程序中ioctl()通过传入的参数cmd设置SPORTl口的发送时钟频率。cmd在用户程序端由一些宏进行定义,该整数通过系统调用传递到内核中的驱动程序,再由驱动程序利用解码宏从这个整数中得到用户要设置的波特率,然后通过switch{case)结构进行相应的操作。
主要实现流程如下:
只要保证应用程序中由locil()的参数cmd的宏定义值与核心驱动中相应的解码宏定义相符,便可在应用程序中通过ioctl()函数实现任意有效波特率的设置。
结语
在SPORT口驱动程序中,通过对数据帧结构进行转换,输出与UART异步数据相同的帧格式,用软件实现UART,有效地解决了DSP的异步串口扩展问题。