【译】s3c2410中的irda红外驱动数据手册和原理图

一、S3c2410UART提供三种独立异步的串口

 provides three independent asynchronous serial I/O (SIO) ports

每一个串口都可以工作在DMA方式或者是中断模式,换句话说,这三个串口能够产生中断,或者是DMA请求来在我们的CPU和Uart来传送数据,并且可以通过外扩的串口时钟来提升数据传速率。

receive  和transmit都是分别拥有两个FIFO通道.

Each UART contains a baud-rate generator, a transmitter, a receiver and a control unit


波特率可以由PCLK or UEXTCLK(外部扩展时钟)来产生,数据在发送之前会被放到transmitterFIFO里面做一个缓存The data  is then shifted out by the transmit data pin (TxDn).数据被我们硬件上的的数据引脚TxDn发送出去。Meanwhile, received data is shifted from the receive data pin (RxDn), and then copied to FIFO from the shifter.同时我们的数据引脚RxDn会在这个时候接收数据并放到FIFO里面。

这三个串口的一些属性:

Uart的操作有这些:

The following sections describe the UART operations that include data transmission, data reception, interrupt generation, baud-rate generation, Loopback mode, Infra-red mode, and auto flow control.

其中在Infra-red Mode下:即设置ULCONnnfra-red-mode bit(红外模式位)下面这个图阐述了这个红外模式下uart是如何工作的:

红外的数据传送Data Transmission

一个数据传送帧是可编程的,它由一下几个部分组成:1个开始位,58个数据位,一个奇偶校验位和12个结束位。这些可以被一个叫做 线控制器line control register(ULCONn)的寄存器来指定,这种传送方式可以产生中断条件,来强制在一个传输数据帧里面有连续的0状态。在当前这个transmission word被传送完毕后,这个传送块会产生一个中断信号,然后,如果是FIFO模式的话,就会连续的往Tx  FIFO里面写入数据。

数据的接受Data Reception

和传送方式一样的,数据接收帧也是可编程的,它由1start位,5个数据位,也是一个奇偶校验位和12个结束位,同样在ULCONn寄存器里面得到设置。

接收的时候可以发现两种“数据帧”错误。

— The overrun error indicates that new data has overwritten the old data before the old data has been read.

— The frame error indicates that the received data does not have a valid stop bit.

但是接收是有超时检测的,当它在3word time (this interval(间隔) follows the setting of Word Length bit) ,或者是在FIFO模式,Rx FIFO不为空的时候会产生超时。

自动流量控制Auto Flow Control (AFC)

S3C2410UART 0 UART 1串口支持通过nRTS  nCTS信号来达到自动流量控制的功能,这个是设置寄存器UMCONn的相应位置来达到目的的

红外的数据传送Data Transmission

一个数据传送帧是可编程的,它由一下几个部分组成:1个开始位,58个数据位,一个奇偶校验位和12个结束位。这些可以被一个叫做 线控制器line control register(ULCONn)的寄存器来指定,这种传送方式可以产生中断条件,来强制在一个传输数据帧里面有连续的0状态。在当前这个transmission word被传送完毕后,这个传送块会产生一个中断信号,然后,如果是FIFO模式的话,就会连续的往Tx  FIFO里面写入数据。

数据的接受Data Reception

和传送方式一样的,数据接收帧也是可编程的,它由1start位,5个数据位,也是一个奇偶校验位和12个结束位,同样在ULCONn寄存器里面得到设置。

接收的时候可以发现两种“数据帧”错误。

— The overrun error indicates that new data has overwritten the old data before the old data has been read.

— The frame error indicates that the received data does not have a valid stop bit.

但是接收是有超时检测的,当它在3word time (this interval(间隔) follows the setting of Word Length bit) ,或者是在FIFO模式,Rx FIFO不为空的时候会产生超时。

自动流量控制Auto Flow Control (AFC)

S3C2410UART 0 UART 1串口支持通过nRTS  nCTS信号来达到自动流量控制的功能,这个是设置寄存器UMCONn的相应位置来达到目的的。我们可以连上一个额外的串口,例如,用户可以通过串口来来连接调制解调器(Modem)的时候,通常需要通过软件将寄存器UMCONn的自动流控制位disable

In AFC, nRTS depends on the condition of the receiver and nCTS signals control the operation of the transmitter.

在自动流量控制机制中,nRTS 依赖的条件是nCTS 信号被触发。

UART's transmitter transfers the data in FIFO only when nCTS signals are activated (in AFC, nCTS means that other UART's FIFO is ready to receive data). 

仅当nCTS 信号被触发(即串口的FIFO已经准备好接收数据的准备了),串口的传送区在通过FIFO来传送这个数据。

/*------------------------------------------------------------------------------------------------------------------*/

总结一下:在发送模块中,会以字的方式发送数据帧,发送完成之后又会发送一个nCTS 信号。在接受模块这边,通过AFC(自动流量控制)捕获到这个nCTS 信号,然后会向发送模块递交一个nRTS 信号,他们的对话是这样的

【T:我可以向你发送数据么?

  R:等等,我看看

(AFC) ... 

  R:哦,我看了我的缓冲区一下,是闲着的,你现在可以发送数据了 

  T:OK,发送数据...】。

在完成一次数据传输前的握手后,这个发送模块就可以连续不断的往我们的FIFObuffer中发送数据。

图的意思是发送的时候,要问问是否可以发送;在接受后要问问是否可以接受。UART 0 和 UART 1是支持AFC功能的,但是UART即我们的这个红外的串口是不支持的,因为它没有nRTS2 nCTS2

/*------------------------------------------------------------------------------------------------------------------*/

Example of Non Auto-Flow control (controlling nRTS and nCTS by software)

Rx operation with FIFO

1. Select receive mode (Interrupt or DMA mode).

选择接收模式是中断还是DMA

2. Check the value of Rx FIFO count in UFSTATn register. If the value is less than 15, users have to set the value of UMCONn[0] to '1' (activating nRTS), and if it is equal or larger than 15 users have to set the value to '0'(inactivating nRTS).

检查接受FIFO缓冲区的大小(UFSTATn也计算在内 ),假如大小小于15的话,用户就不得不去设置寄存器UMCONn[0]位为1,即激活nRTS;假如大于或者是等于15的话,用户好药设置这个寄存器的0号位为1,表示不激活nRTS

3. Repeat the Step 2.

Tx operation with FIFO

1. Select transmit mode (Interrupt or DMA mode).

和发送还是一样,选择接收模式是中断还是DMA

2. Check the value of UMSTATn[0]. If the value is '1' (activating nCTS), users write the data to Tx FIFO register.

不同的是他需要检查这个UMSTATn寄存器的0号位,若是1的话,就 表示激活nCTS,然后用户就写数据到Tx FIFO 寄存器中。

/*------------------------------------UART SPECIAL REGISTERS-------------------------------------*/

UART FIFO STATUS REGISTER UFSTAT0

UART MODEM STATUS REGISTER    UMSTAT0  UMSTAT1 没有UMSTAT2

UART MODEM CONTROL REGISTER UMCON0  UMCON1 没有UMCON2 

UART FIFO CONTROL REGISTER   UFCONn

UART CONTROL REGISTER UCONn

UART LINE CONTROL REGISTER ULCONn

UART TRANSMIT BUFFER REGISTER    UTXHn

UART RECEIVE BUFFER REGISTER   URXHn 

UART BAUD RATE DIVISOR REGISTER   UBRDIVn

UART ERROR STATUS REGISTER  UERSTATn

UART TX/RX STATUS REGISTER UTRSTATn

/*------------------------------------------------------------------------------------------------------------------*/

(1)ULCONn 设置是否红外模式、数据帧的位数、停止位是几位

Infra-Red mode. [6] |  0 = Normal mode operation 1 = Infra-Red Tx/Rx mode

Word Length.   [2] | 0 = One stop bit per frame 1 = Two stop bit per frame

Number of Stop Bit. [1:0] | 00 = 5-bit      01 = 6-bit 10 = 7-bit      11 = 8-bit

(2)UCONn

Clock Selection [10]

0=PCLK : UBRDIVn = (int)(PCLK / (bps x 16) ) -1

1=UEXTCLK(@GPH8) : UBRDIVn = (int)(UEXTCLK / (bps x 16) ) -1

Tx Interrupt Type[9]/ Rx Interrupt Type [8]

0 = Pulse (Interrupt is requested as soon as the Tx buffer becomes empty in Non-FIFO  mode or reaches Tx FIFO Trigger Level in FIFO mode.)

1 = Level (Interrupt is requested while Tx buffer is empty in Non-FIFO mode or  reaches Tx FIFO Trigger Level in FIFO mode.)

Rx Time Out Enable [7]  0 = Disable            1 = Enable

... .... 剩下的这些寄存器的可以用类似的方法总结几个,然后就熟悉这些寄存器的用法了,这样比我们看老师给我们讲数据手册有意思多了,绝对不会瞌睡哦。

现在写到这里我们要明白,我们这样罗列寄存器的目的是什么?因为在前边翻译Uart的一些操作的时候,里面的寄存器很相似,而且还有一定的数量。所以我先把寄存器这部分先看看,有助于前边那些操作的理解。我们接着分析。

看得出来红外对于这两个寄存器UMSTAT2UMCON2 是没有的。

我们对于红外的驱动开发的知识的累积也已经差不多了,那么我们就开始试着写吧。

说实话,学了驱动这么久,我一直都是用vim来查看老师给的实例驱动程序。然后分析,后来觉得,vim还是有它的一些局限性,然后才知道source  insight这个工具的强大,然后就对它产生了兴趣,接下来的这个irda红外驱动源程序,就是用source insight 修改的,这里特别强调一下修改两字,如果你的理解和这有出入,那你以为呢,自己动手写写就能知道这里面的奥妙了。

驱动也是程序,所以我们提前分析一些重要的学习内容。

(1)我们用模块的方式来开发一个驱动程序,这个没什么争议吧(至少对于初学的我们)

MODULE_LICENSE("GPL");

MODULE_AUTHOR("janec <[email protected]>");

MODULE_DESCRIPTION("The Linux IrDA Driver");

module_init(irda_init);

module_exit(irda_cleanup);

这样一个模块搭建好了

(2)设备操作的函数集合file_operation得定义好

static const struct file_operations irda_fops = {

.owner  = THIS_MODULE,

.open     = irda_open,

.read     = irda_read,

.lseek     = irda_lseek,

.release   = irda_release,

};

/*------------------------------------------------------------------------------------------------------------------*/

写到这里遇到了问题:

一、【用红外来进行数据的通行,那么irda是不是网络设备呢?

我估计,irda也是Uart,串口驱动是一种字符设备驱动。所以这里应该用file_operations

而不是net_device_ops这个结构体,我在查看内核中<drivers/net/irda>目录下的文件 时,看见这个irda-usb.c就是用的net_device_ops,所有不禁怀疑irda又是网络驱动】

正解:百度一阵后,发现这么一句话“仅使用标准字符驱动设计方法来设计红外驱动是无法保证系统服务质量的因此需要为红外驱动加入有效的内核机制 ”,看来还真是用字符设备驱动来设计的。初略的看了一下,关键字等待队列read被调用时应该是被阻塞的即不能从内核空间获得数据 ,因此在这种情况下我们的驱动程序应该默认阻塞该进程将其置入休眠状态直到请求可继续 .当一个进程被置入休眠时它会被标记为一种特殊状态并从调度器的运行队列中移走。直到某些情况下修改了这个状态进程才会在CPU上调度也即运行该进程。休眠中的进程被搁置在一边等待将来的某个事件发生--被唤醒。完成唤醒任务的代码必须能够找到我们的进程这样才能唤醒休眠的进程。为确保唤醒发生需清楚06 9期 周海泉等:基于嵌入式Linux的红外遥控驱动程序设计地直到对每个休眠而言哪些事件序列会结束休眠。能够找到休眠的进程意味着需要维护一个称为等待队列的数据结构。等待队列是以双循环链表为基础数据结构与进程调度机制紧密结合能够用于实现核心的异步事件通知机制它包含了等待某个特定事件的所有进程。一个等待队列通过一个“等待队列头waitqueuehead”来管理等待队列头是一个类型为wait_queue_head_t的结构体定义在中。可通过如下方法定义并初始化一个等待队列头:DECLARE_WAIT_QUEUE_HEADname当进程休眠时它将期待某个条件会在未来成真。当一个休眠进程被唤醒时它将再次检查它所等待的条件的确为真。Linux内核中最简单的休眠方式是称为wait_event的宏以及它的几个变种在实现休眠的同时它也检查进程等待的条件。wait_event的形式是:wait_eventqueueconditionqueue是等待队列头condition是任意一个布尔表达式上面的宏在休眠前后都要对该表达式求职在条件为真之前进程会保持休眠。在我们的程序里选择使用wait_event_interruptibleinterruptible表示可被信号中断。返回值为整型非零值表示休眠被某个信号中断这时候将不能被用户read。整个过程的另外一半是唤醒。其他的某个执行进程可能是另一个进程或者中断处理例程必须为我们执行唤醒因为我们的进程正在休眠中。用来唤醒休眠进程的基本函数是wake_up它也有多种形式对应wait_event_interruptible的是wake_up_interruptible。 

等待队列的举例:等待队列的应用涉及两个进程假设为A和B。A是资源的消费者B是资源的生产者。A在消费的时候必须确保资源已经生产出来为此定义一个资源等待队列。这个队列同时要被进程A和进程B使用在LIRC程序里A就是应用程序需要的红外码值是read调用B就是驱动程序得到的硬件信息是interrupt处理 。 你可以百度一下这些文段的出处:“基于嵌入式Linux的红外遥控驱动程序设计”其中tasklet通常是底半部处理的优选机制因为这种机制非常快通常用于减少中断处理的时间将本应该是在中断服务程序中完成的任务转化成软中断完成是一个可以由系统决定的安全时刻在软件中断上下文被调度运行的特殊函数。tasklet以数据结构的形式存在并在使用前必须初始化。可以使用特定的宏来声明该结构即可完成tasklet的初始化:DECLARE_TASKLETnamefunctiondataname是给tasklet起的名字function是执行tasklet时调用的函数实际上就是底半部处理data是一个用来传递给tasklet函数的unsignedlong类型的值。函数tasklet_schedule用来调度一个tasklet运行。 

/*------------------------------------------------------------------------------------------------------------------*/

问题二、这些都是个人问题,写到这里是为了防止自己又忘记了,我对个Uart的传输和接收得时候,发送的消息,是一种中断,因为前边着重了翻译,而是体会不深,待会还得看看前边翻译的那些。

还有就是“手机上的红外传输”和“我们电视遥控器的传输”的差异,当然这个遥控器的这个可以查阅上面推荐的这篇文章“基于嵌入式Linux的红外遥控驱动程序设计”这篇文章提供了一些思路。


原文:

 UART
OVERVIEW

The S3C2410A UART (Universal Asynchronous Receiver and Transmitter) provides three independent asynchronous
serial I/O (SIO) ports, each of which can operate in Interrupt-based or DMA-based mode. In other words, the UART
can generate an interrupt or a DMA request to transfer data between CPU and the UART. The UART can support bit
rates of up to 230.4K bps using system clock. If an external device provides the UART with UEXTCLK, then the
UART can operate at higher speed. Each UART channel contains two 16-byte FIFOs for receive and transmit.
The S3C2410A UART includes programmable baud rates, infra-red (IR) transmit/receive, one or two stop bit insertion,
5-bit, 6-bit, 7-bit or 8-bit data width and parity checking.
Each UART contains a baud-rate generator, a transmitter, a receiver and a control unit, as shown in Figure11-1. The
baud-rate generator can be clocked by PCLK or UEXTCLK. The transmitter and the receiver contain 16-byte FIFOs
and data shifters. Data  is written to FIFO and then copied to the transmit shifter before being transmitted. The data
is then shifted out by the transmit data pin (TxDn). Meanwhile, received data is shifted from the receive data pin
(RxDn), and then copied to FIFO from the shifter.
FEATURES
— RxD0, TxD0, RxD1, TxD1, RxD2, and TxD2 with DMA-based or interrupt-based operation
— UART Ch 0, 1, and 2 with IrDA 1.0 & 16-byte FIFO
— UART Ch 0 and 1 with nRTS0, nCTS0, nRTS1, and nCTS1
— Supports handshake transmit/receive

UART OPERATION
The following sections describe the UART operations that include data transmission, data reception, interrupt
generation, baud-rate generation, Loopback mode, Infra-red mode, and auto flow control.
Data Transmission
The data frame for transmission is programmable. It consists of a start bit, 5 to 8 data bits, an optional parity bit and
1 to 2 stop bits, which can be specified by the line control register (ULCONn). The transmitter can also produce the
break condition, which forces the serial output to logic 0 state for one frame transmission time. This block transmits
break signals after the present transmission word is transmitted completely. After the break signal transmission, it
continuously transmits data into the Tx FIFO (Tx holding register in the case of Non-FIFO mode).
Data Reception
Like the transmission, the data frame for reception is also programmable. It consists of a start bit, 5 to 8 data bits,
an optional parity bit and 1 to 2 stop bits in the line control register (ULCONn). The receiver can detect overrun error
and frame error.
— The overrun error indicates that new data has overwritten the old data before the old data has been read.
— The frame error indicates that the received data does not have a valid stop bit.
Receive time-out condition occurs when it does not receive any data during the 3 word time (this interval follows the
setting of Word Length bit) and the Rx FIFO is not empty in the FIFO mode.


你可能感兴趣的:(【译】s3c2410中的irda红外驱动数据手册和原理图)