PXA255具有丰富的外设接口,如LCD控制器、I2S控制器和UART控制器等,可以实现丰富的人机接口以及数据输入输出。
LCD控制器的功能是产生显示驱动信号,驱动LCD显示器,不同的控制器可以支持无源阵列显示屏(STN)和有源阵列显示屏(TFT)的显示,包括单色和彩色,单向刷新模式和双向刷新模式等不同显示的需求。用户只需要读写一系列的寄存器,完成配置和显示控制。
由处理器产生的显示数据先被存放在外部存储器的帧缓冲中,这些数据由LCD DMA控制器按顺序加载到一个先入先出(FIFO)的缓冲队列中。当采用单向刷新模式时,只有一个DMA通道在工作,同时对应一个FIFO缓冲队列。当采用双向刷新模式,两个DMA通道都会工作,同时对应两个FIFO缓冲队列。
帧缓冲中的数据称为帧缓冲数据,它们对应屏幕上一个个像素点的色彩值。帧缓冲数据可以是压缩编码后的色彩值,也可以是原始的色彩值,这要取决与LCD控制器选定的显示模式。在彩色模式中,原始的色彩值是16位的RGB色彩值,其中Red 5位、Green 6位、Blue 5位(因为人眼对绿色比较敏感,所以Green多占用了1位),一个16位的数据描述了屏幕上一个像素点的色彩。压缩编码的色彩值可以用比较少的位描述一定的色彩值,减少了每像素点的色彩数据量可以相应地提高显示的刷新速率,减少数据的传输量。但是压缩编码的色彩值需要由色彩描述板(Palette)解释后才能描述像素点真正的色彩值。
当使用原始色彩值,即16位描述一个像素点时不使用色彩描述板。单色色彩描述板是一个256入口的8位宽的数据结构,相当于UInt8 palette[256],可以表示256级灰度。彩色色彩描述板是一个256入口的16位宽的数据结构,相当于UInt16 palette[256],可以表示256色的伪彩。压缩编码后的每像素色彩描述位数决定了可描述色彩的数量:每像素1位可以访问色彩描述板中2种色彩,每像素2位可以访问色彩描述板中4种色彩,每像素4位可以访问色彩描述板中16种色彩,每像素8位可以访问色彩描述板中256种色彩。
STN显示屏采用的是被动(Passive)刷新模式,有时为了提高LCD色彩的表现,可以通过使每屏图像的像素刷新多次,使用时间混合色度的方法。这个方法叫做暂时调节能量分配算法(TMED),也被称为瞬时抖动。
TFT显示屏采用的是主动(Active)刷新模式,不采用瞬时抖动的方法。
不同的显示模式最终使用的LCD数据输出引脚数也是不同的,而且双向刷新模式所使用的数据引脚数一定是对应单向刷新模式的一倍,这是因为双向刷新模式是同时刷新屏幕的上半部分和下半部分。
(1)像素时钟(Pixel Clock)
对应片上引脚L_PCLK,LCD显示器用来控制显示数据进入行显示位移寄存器(Line Shift Register)的控制时钟信号。一个时钟周期刷新屏幕上几个像素点,频率越高,行分辨率越高。在被动刷新模式中只有当有效的显示数据到来了时钟才开始翻转。在主动刷新模式中时钟是连续翻转的,数据的有效信是靠AC Bias信号来判断的。
(2)行时钟(Line Clock)
对应片上引脚L_LCLK,LCD显示器用来表示屏幕上一行像素刷新完毕的时钟信号。当行时钟信号生时就表示显示器要开始刷新下一行的像素,控制器会把存放在行显示位移寄存器中下一行的显示数据转移到显示屏,并且将行位置计数器加1。在主动刷新模式中,行时钟信号也称为水平同步信号。
(3)帧时钟(Frame Clock)
对应片上引脚L_FCLK,LCD显示器用来表示整个屏幕刷新完毕,又有新的帧等待显示时产生的时钟信号。当信号到来时显示器将行位置计数器重置到屏幕的第一行(最靠近屏幕顶端)。在主动刷新模式中,帧时钟信号也称为垂直同步信号。
LCD控制器拥有以下几点特性。
n 显示模式:
Ø 支持单向刷新或双向刷新;
Ø 在被动单色模式中最多可以显示256级灰度(8位压缩编码);
Ø 在主动彩色模式中最多可以显示65536种色彩(16位瞬时抖动);
Ø 在主动彩色模式中最多可以显示65536种色彩(16位不采用瞬时抖动);
Ø 支持被动256色伪彩单向刷新模式;
Ø 支持被动256色伪彩双向刷新模式。
n 最大分辨率可达1024×1024像素,建议最大分辨率640×480像素;
n 支持外部RAM彩色色彩描述板,256入口16位宽数据(能够在每帧开始时自动加载);
n 压缩编码像素支持1位、2位、4位和8位;
n 可编程的像素时钟,频率范围195kHz~83MHz(100MHz/512至166MHz/2);
n 具有双DMA通道(一个通道用来传输色彩描述板和单向刷新的数据,另一个通道用来在双向刷新模式中传输下半屏幕刷新的数据)。
LCD控制器有4个控制寄存器,10个DMA寄存器,1个状态寄存器,还有1个RAM色彩描述板。所有的寄存器都必须由32位的地址来访问,并且不应该尝试对未定义的寄存器地址空间进行读写的操作,这会产生不可预料的错误。
设置这些寄存器的对应位可以有以下功能:
n 启动和停止LCD控制器;
n 设置LCD屏幕的高度和宽度;
n 指定使用单向还是双向的屏幕刷新方式;
n 指定使用彩色还是灰度或纯黑白显示方式;
n 设置控制引脚的电平有效值;
n 设置帧时钟、行时钟、像素时钟和AC Bias引脚信号的频率;
n 设置在屏幕显示数据(行数据、帧数据)前后插入的空数据量(协调屏幕尺寸最小数据传输量);
n 可以启用多种中断屏蔽。
(1)零号控制寄存器(LCCR0)
LCCR0的使能位(ENB)被置1时,LCD控制器启动。在控制器启动后其他的控制位就不能做任何的更改了,这点在编程时要特别注意,并且LCD控制器的停止也是依靠控制寄存器来控制的。
n LCD输出队列下溢中断屏蔽控制位(OUM)
OUM=0时,下溢中断被启用,这时当LCSR中的OU状态位被置1时,一个下溢中断请求产生,中断控制器响应,完成相应的出错处理。OUM=1时,下溢中断被屏蔽。
n 快速关闭中断屏蔽控制位(QDM)
QDM=0时快速停止中断被启用,这时当LCSR中的QD状态位被置1时,一个LCD快速关闭中断请求产生,中断控制器响应请求。QDM=1时被屏蔽。快速关闭一般用于休眠模式。
n LCD关闭控制位(DIS)
DIS=1时,LCD控制器在读取完当前帧的数据后会停止从缓存中读取新的帧数据,在当前帧显示完成后,关闭LCD控制器。
n 主动/被动显示模式选择位(PAS)
这一位是用来控制显示模式,主动还是被动显示模式。PAS=0时,被动模式被选中。PAS=1时,主动模式被选中。
n 单向/双向刷新模式选择位(SDS)
SDS=0时表示单向刷新,SDS=1时表示双向刷新。在主动模式下SDS一定为0。
Table7-2考虑加入
n 彩色/单色模式选择位(CMS)
CMS=0时,选中了彩色模式,相应的色彩描述板的的色彩数据是16位宽。CMS=1时,选中了单色模式,相应的色彩描述板的色彩数据是8位宽(最多256级灰度)。
n LCD启动控制位(ENB)
ENB=0时,所有的LCD引脚都被作为通用IO口使用;ENB=1时,LCD控制器启用。
(2)一号控制寄存器(LCCR1)
这个寄存器中的4个域的值是用来控制LCD行显示相关时钟信号的时序,它们分别是对应计数器的默认计数值。
n 行前置空像素时钟节拍数(BLW)
表示在开始显示一行像素前所需要等待的空像素时钟节拍数。BLW可以产生的1~256个像素时钟的等待周期,对应BLW值0~255。
n 行后置空像素时钟节拍数(ELW)
和BLW类似,是在一行像素显示结束后需要等待的空像素时钟节拍数。
n 水平同步信号脉冲宽度(HSW)
HSW的值指定了在主动或被动模式下行时钟信号的脉冲宽度。每次行时钟信号有效时,HSW的值被赋给一个6位的计数器,每一个像素时钟到来时计数器减1,当计数器为0时行时钟信号失效。HSW值的范围是0~63,可以表示1~64之间的脉冲宽度。
n 行像素数(PPL)
PPL可以描述0~1023范围的值,它指定了屏幕中一行上像素点的数量(1~1024个像素)。建议最大不要超过640个像素。在不同的像素描述模式下PPL的值也有不同的要求:每像素1位描述时PPL+1必须是32的倍数,每像素2位描述时PPL+1必须是16的倍数,每像素4位描述时PPL+1必须是8的倍数,每像素8位描述时PPL+1必须是4的倍数,每像素16位描述时PPL+1必须是2的倍数。当PPL与实际屏幕的行像素值不能对应时,空像素就会被引入,BLW或ELW就会被使用。
(3)二号控制寄存器(LCCR2)
和LCCR1类似,这个寄存器中的4个域的值是用来控制LCD上帧显示相关时钟信号的时序的。
(4)帧前置空行时钟节拍数(BFW)
只在主动显示模式下使用,表示在开始显示新的一帧前所需要等待的空行时钟节拍数。BLW可以产生的0~255个行时钟的等待周期,BLW=0时不等待。
(5)帧后置空行时钟节拍数(EFW)
只在主动显示模式下使用,和BFW类似,是在一帧像素显示结束后需要等待的空行时钟节拍数。
(6)垂直同步信号脉冲宽度(VSW)
VSW的值指定了在主动或被动模式下帧时钟信号的脉冲宽度。主动模式下,每次帧时钟信号有效时,VSW的值被赋给一个6位的计数器,每一个行时钟到来时计数器减1,当计数器为0时,行时帧信号失效。被动模式下,VSW则用来提供额外的空行时钟,当前一帧显示结束,VSW的值被赋给一个6位的计数器,用来计数空时钟信号,当计数器为0时,下一帧才开始(BFW、EFW还是存在)。VSW值的范围是0~63,可以表示1~64之间的脉冲宽度或额外空时钟数。
(7)屏幕行数(LPP)
LPP可以描述0~1023范围的值,它指定了屏幕中行的数量(1~1024行)。
(8)每像素位描述数(BPP)
描述了一个像素色彩值在内存中所占的位数。在每像素1、2、4、8位的压缩编码模式在,这些像素在被显示前,它们的色彩描述板必须被加载,以得到真正的色彩值。BPP=0b000时,每像素1位描述。BPP=0b001时,每像素2位描述。BPP=0b010时,每像素4位描述。BPP=0b011时,每像素8位描述。BPP=0b100时,每像素16位描述。其他保留用于将来扩展。
(9)像素时钟边沿有效性选择(PCP)
PCP=0时,在L_PCLK上升沿有效,采样LCD数据引脚的数据。PCP=1时,在L_PCLK下降沿有效,采样LCDLCD数据引脚的数据。
(10)水平同步信号电平有效性选择(HSP)
HSP=0时,L_LCLK高电平有效,HSP=1时,L_LCLK低电平有效。在被动模式下水平同步信号就是行时钟信号。
(11)垂直同步信号电平有效性选择(VSP)
VSP=0时,L_FCLK高电平有效,VSP=1时,L_FCLK低电平有效。
(12)像素时钟分频选择(PCD)
PCD的值在0~255之间,代表1~256的分频参数(分频时要乘以2)。最后得到的像素时钟的频率在LCLK/2到LCLK/512之间。LCLK频率等于LCD内存控制器的时钟频率,一般在100MHz~166MHz之间。
状态寄存器的状态位可以标示:
n FIFO缓冲队列的上溢与下溢错误;
n DMA总线错误;
n DMA控制器何时开始和结束一个帧数据的传输;
n LCD关闭前最后一个帧显示在何时结束。
(1)帧结束状态位(EOF)
当DMA控制器从存储器中取得一帧的显示数据,并且数据中的帧描述符中包含表示帧结束的标示位,那么EOF=1,如果LCCR0中的EFM屏蔽位没有被设置,那么将产生一个EOF中断请求。
(2)LCD快速关闭状态位(QD)
当QD=1,QDM=0时,会产生一个快速关闭的中断,这个中断会强制停止LCD控制器,并且马上停止LCD的引脚的驱动。快速关闭可用于LCD休眠模式。
(3)输出FIFO下溢状态位(OU)
如果输出FIFO为空,LCD的数据引脚还继续尝试从FIFO中获取显示数据时,OU=1。若OUM=0时,这将产生一个输出FIFO下溢中断。
(4)上屏幕输入FIFO下溢状态位(IUU)
如果上屏幕的输入FIFO为空,LCD控制器的像素解码器还继续尝试从FIFO中获取压缩编码的数据时,IUU=1。若IUM=0时,这将产生一个输入FIFO下溢中断。
(5)下屏幕输入FIFO下溢状态位(IUL)
当选中了双向刷新模式时才使用(SDS=1),如果下屏幕的输入FIFO为空,LCD控制器的像素解码器还继续尝试从FIFO中获取压缩编码的数据时,IUL=1。若IUM=0时,这将产生一个输入FIFO下溢中断。
(6)总线错误状态位(BER)
当DMA传输控制器发生了一个系统总线的错误时,BER=1。例如,当DMA控制器试图访问保留的或不存在的存储空间。错误发生后,DMA控制器会停止工作,直到有效的地址空间被加载到FDADRx寄存器。
(7)帧开始状态位(SOF)
当DMA控制器获取到新的帧描述符,并且它包含表示帧开始的标示位,那么SOF=1,如果LCCR0中的SFM屏蔽位没有被设置,那么将产生一个SOF中断请求。
(8)LCD关闭完成状态位(LDD)
当DIS=1,LCD控制器读取完当前帧的所有数据时,在当前帧的最后一个像素数据被发送到LCD数据引脚后,LCD控制器被关闭,LDD被置1。若LDM=0,还将产生一个关闭完成中断请求。这个状态位是由硬件设置的,但它的清除工作是由软件来完成的。
(9)其他寄存器
除了以上介绍几个主要寄存器外还有一些将会用到的寄存器。例如,LCD DMA命令寄存器(LDCMDx),LCD控制器中断ID寄存器(LIIDR),瞬时抖动RGB色彩偏移寄存器(TRGBR),瞬时抖动控制寄存器(TCR)等。
存放一个显示帧数据所须的缓存大小可以用以下公式来计算:
FrameBufferSize=(BitPerPixel´Lines´(Pixels + n))/8 (单位是byte)
其中BitPerPixel表示描述一个像素所需要多少个bit位,例如256级灰度的BitPerPixel=8,64K彩色的BitPerPixel=16。Lines等于显示屏幕的行数。Pixels是显示屏幕中一行上的像素点的个数,n是插入的空像素点的个数(为了显示的控制)。
在双向刷新模式中,两个DMA管道的帧缓冲大小是一样的,所以在计算这个模式下一个管道中的帧缓冲时,Lines是屏幕大小的一半。
为了满足显示数据的传输,LCD控制器的数据传输总线带宽可以用以下公式计算得到:
n 单向
BusBandwidth=(FrameBufferSize+PaletteSize)´RefreshRate
n 双向
BusBandwidth=(FrameBufferSize*2+PaletteSize)´RefreshRate
其中PaletteSize是色彩描述板的大小,单色色彩描述板的大小是256´8bit=256byte,彩色色彩描述板是256´16=512byte。RefreshRate是屏幕的刷新率。
在双向模式中,负责上半屏幕的DMA管道负责传输Palette和上半屏幕的显示数据,而负责下半屏幕的DMA管道只下半屏幕的显示数据,所以双向模式的公式中PaleteSize没有乘以2。
初动模式的时序如图4-1至图4-3所示。
ENB – LCD使能信号 |
HSP – 水平同步极性设置 |
0 – LCD禁止 |
0 – 行时钟高有效,低无效 |
1 – LCD使能 |
1 – 行时钟低有效,高无效 |
VSP – 垂直同步极性设置 |
PCP – 像素时钟极性设置 |
0 – 帧时钟高有效,低无效 |
0 – 在时钟的上升沿采样像素数据 |
1 – 帧时钟低有效,高无效 |
1 – 在时钟的下降沿采样像素数据 |
当PCP=0时,L_PCLK的波形是反向的,但时序是相同的。 |
|
VSW = 垂直同步信号脉冲宽度 – 1 |
|
HSW = 水平同步信号(行时钟)脉冲宽度 – 1 |
|
BLW = 开始行像素时钟等待个数 – 1 |
|
ELW = 结束行像素时钟等待个数 – 1 |
图4-1 被动模式帧启动时序
ENB – LCD使能信号 |
HSP – 水平同步极性设置 |
0 – LCD禁止 |
0 – 行时钟高有效,低无效 |
1 – LCD使能 |
1 – 行时钟低有效,高无效 |
|
|
VSP – 垂直同步极性设置 |
PCP – 像素时钟极性设置 |
0 – 帧时钟高有效,低无效 |
0 – 在时钟的上升沿采样像素数据 |
1 – 帧时钟低有效,高无效 |
1 – 在时钟的下降沿采样像素数据 |
|
|
当PCP=0时,L_PCLK的波形是反向的,但时序是相同的。 |
|
|
|
VSW = 垂直同步信号脉冲宽度 – 1 |
|
HSW = 水平同步信号(行时钟)脉冲宽度 – 1 |
|
BLW = 开始行像素时钟等待个数 – 1 |
|
ELW = 结束行像素时钟等待个数 – 1 |
|
PPL = 每行像素 – 1 |
|
LPP = 每屏幕行数 – 1 |
图4-2 被动模式帧结束时序
PCP – 像素时钟极性设置 |
0 – 在时钟的上升沿采样像素数据 |
1 – 在时钟的下降沿采样像素数据 |
当PCP=0时,L_PCLK的波形是反向的,但时序是相同的。 |
图4-3 被动模式像素时钟和数据引脚时序
主动模式的时序如图4-4与图4-5所示。
将对应的通用I/O引脚配置给LCD控制器,设置了正确的色彩描述板、帧描述符的内存地址和LCCR0以外的一些必要寄存器的设置后,置位LCCR0的ENB控制位后LCD控制器就会启动了。
ENB – LCD使能信号 |
HSP – 水平同步极性设置 |
0 – LCD禁止 |
0 – 行时钟高有效,低无效 |
1 – LCD使能 |
1 – 行时钟低有效,高无效 |
|
|
VSP – 垂直同步极性设置 |
PCP – 像素时钟极性设置 |
0 – 帧时钟高有效,低无效 |
0 – 在时钟的上升沿采样像素数据 |
1 – 帧时钟低有效,高无效 |
1 – 在时钟的下降沿采样像素数据 |
|
|
当PCP=0时,L_PCLK的波形是反向的,但时序是相同的。 |
|
|
|
VSW = 垂直同步信号脉冲宽度 – 1 |
|
HSW = 水平同步信号(行时钟)脉冲宽度 – 1 |
|
BFW = 开始帧水平同步时钟等待个数 |
|
BLW = 开始行像素时钟等待个数 – 1 |
|
ELW = 结束行像素时钟等待个数 – 1 |
|
PPL = 每行像素 – 1 |
图4-4 主动模式的时序
PCP – 像素时钟极性设置 |
0 – 在时钟的上升沿采样像素数据 |
1 – 在时钟的下降沿采样像素数据 |
当PCP=0时,L_PCLK的波形是反向的,但时序是相同的。 |
图4-5 主动模式像数时钟和数据引脚时序
伪代码如下:
#define LCCR0_ADDRESS 0x44000000 // LCCR0的地址
#define LCCR0 ( * ( (volatile unsigned int * ) LCCR0_ADDRESS ) )
#define LCD_ENB 0x00000001 // ENB在LCCR0中的位置
LCCR0 = LCCR0 | LCD_ENB; // 置位ENB
(1)正常停止
一般建议使用这个方式停止LCD控制器。这个操作是由设置LCCR0的DIS控制位来完成的。并且在LCD控制器加载了最后要显示的帧数据后,LCSR的LDD状态位会被硬件自动置位,同时LCCR0中的ENB位也会被硬件清零。
伪代码如下:
#define LCCR0_ADDRESS 0x44000000 // LCCR0的地址
#define LCCR0 ( * ( (volatile unsigned int * ) LCCR0_ADDRESS ) )
#define LCSR_ADDRESS 0x44000038 //LCSR的地址
#define LCSR ( * ( (volatile unsigned int * ) LCSR_ADDRESS ) )
#define LCD_DIS 0x00000400 //DIS在LCCR0中的位置
#define LCD_LDD 0x00000001 //LDD在LCSR中的位置
LCCR0 = LCCR0 | LCD_DIS; //LCCR0中的LCD_DIS位置位
while(!(LCSR & LCD_LDD)); //等待硬件置位LDD
LCSR = LCSR & (~LCD_LDD); //软件清除LCD_LDD位,以便下次使用
(2)快速停止
直接清除LCCR0的ENB控制位可以实现快速停止的操作。清除了ENB位后LCSR的QD状态位会被置位,产生一个中断,中断响应后LCD控制器会马上停止加载了一切的帧数据,停止LCD控制器对LCD引脚的驱动。在电池电量不足时,CPU为了保存重要的数据,快速停止模式被采用。
伪代码如下:
#define LCCR0_ADDRESS 0x44000000 // LCCR0的地址
#define LCCR0 ( * ( (volatile unsigned int * ) LCCR0_ADDRESS ) )
#define LCD_ENB 0x00000001 // ENB在LCCR0中的位置
LCCR0 = LCCR0 & (~LCD_ENB); //清除ENB位
I2S是数字立体声音频协议。PXA255的I2S控制器如图4-6所示(I2SC)控制了I2S链接,I2S链接是低功耗的4线立体声串行接口。I2S接口和Audio解码器'97(AC'97)接口可以同时使用。
I2SC由数据缓冲、状态和控制寄存器、记数器组成。它们将系统内存和外设的I2S解码器连接,产生同步音频。I2SC通过I2SLINK连接将系统内存中数字化的声音样本发送到外设的I2S解码器中。然后由外设的数模转换器将数字信号转换成模拟信号。对于录音来说,I2SC从外部I2S解码器接收到数字信号,然后将它们存储在系统内存中。I2S控制器提供了普通I2S和MSB-Justified-I2S格式,可以通过4~5根引脚将外部的解码器连接到本控制。I2SC必需的信号主要有如下几个:
n 一个码率时钟,它可以引用外部或者内部时钟源;
n 一个控制信号提供“左/右”声道控制信息;
n 两个串行音频引脚,一个输出一个输入;
n 码率时钟,I2SC会将可选的系统时钟信号也发送到外部解码器中。
I2S的数据可以通过两种方式和系统内存交互:DMA和普通的I/O操作。对于I2S系统来说,还需要额外的引脚来控制外部解码器。有些解码器使用L3控制总线(需要3根引脚信号L3_CLK、L3_DATA和L3_MODE)。通过程序控制I/O引脚,I2SC可以支持L3总线。I2SC没有提供LS总线的硬件支持(必须通过软件控制)。
可以通过两种方式将数字化的音频信号通过串行通道进行传输:普通的I2S和MSB- Justified-I2S。它们都能够在不同的时钟频率下进行工作。
图4-6 PXA255 I2S控制器
SYSCLK是I2S单元中所有其他时钟信号的基础。通过使用可编程分频器分频PLL,SYSCLK可以产生频率从2MHz~12.2MHz的时钟频率。它的频率应当始终为音频采样率的256倍。
只有当BITCLK被配置成输出的时候,SYSCLK才由处理器驱动。BITCLK提供了串行音频比特率,它作为外部解码器采样率的基础。BITCLK的频率是SYSCLK的四分之一,并且是音频采样率的64倍。在每个BITCLK周期里,都会有一个位的音频数据被传送或者接收。单一的串行音频样本由左右声道的数据组成,每组数据可以包含8、16或者32位。SYNC信号的频率是BITCLK的1/64,它的范围是8~48kHz。SYNC的状态是用来标记当前的数据是左声道还是右声道的。SDATA_IN和SDATA_OUT数据引脚用来向外部解码器发送/接收串行音频数据。
面向外部解码器的接口信息如表4-1所示。
表4-1 外部解码器接口
名 字 |
方 向 |
描 述 |
GP32/SYSCLK |
输出 |
SYSCLK = BITCLK´4,仅用于解码器 |
GP28/BITCLK |
输入/输出 |
BITCLK = SYNC´64 |
GP31/SYNC |
输出 |
左右声道标记信号 |
GP30/SDATA_OUT |
输出 |
到CODEC的串行音频数据 |
GP29/SDATA_IN |
输入 |
来自于CODEC的串行音频数据 |
BITCLK可以被配置成输入或者输出模式。编程可以按照以下步骤。
① 设置SYSUNIT的GPIO方向寄存器(GPDR)。
② 设置SYSUNIT的GPIO候选功能选择寄存器(GAFR)。
③ 设置I2SC的串行音频控制寄存器中的BCKD位。
如果BITCLK被配置成输出方向,SYSCLK也必须被配置成相同的方向。如果BITCLK是由解码器提供的,那么GPIO引脚GP32可以选用候选功能。
n 设置SYSUNIT的GPIO方向寄存器(GPDR)。
n 设置SYSUNIT的GPIO候选功能选择寄存器(GAFR)。
要将SYNC和SDATA_OUT配置成输出方向,按照以下步骤操作:
n 设置SYSUNIT的GPIO方向寄存器(GPDR)。
n 设置SYSUNIT的GPIO候选功能选择寄存器(GAFR)。
处理器和DMA控制器都可以操作I2S控制器(I2SC)。处理器可以通过I/O指令来控制I2SC。并且可以得到以下类型的数据。
n I2SC寄存器数据:所有寄存器都是32位宽,并且按字对齐。
n I2SC FIFO数据:向I2SC串行音频数据寄存器(SADR)写入值,会占用发送FIFO的一个入口。而读一次(SADR)会引起FIFO的刷新,并且腾出一个空闲的接收FIFO入口。
n I2S解码器数据:解码器寄存器可以通过L3总线进行访问。L3总线操作应当由软件控制的3个GPIO引脚进行模拟。
初始化的步骤如下。
① 设置BITCLK的传输方向。
② 选择运行模式、普通I2S或者MSB-Justified模式。这可以通过向SACR1寄存器的第0个位编程实现。
③ 额外的可编程I/O可以用来为发送FIFO准备一些数据,从1个字节到16个字节。如果I2SLINK被建立后,发送FIFO中并没有任何数据,这将引发一个Under-Run错误,并在状态寄存器中置位。这是一个可选的步骤,仅仅是为了防止状态寄存器中被置位。如果该步骤不做,那么软件必须清除这个错误位。
④ 以下的操作可以同时在I2SC串行音频控制器全局控制寄存器上执行(SACR0):
n 通过设置SACR0来使能I2SLINK链接;
n 通过填充SACR0寄存器的TFTH和RFTH位,确定发送/接收的水位值。
一旦I2SLINK被使能,如果发送FIFO仍然为空,则会发送用0填充的数据帧。上述第③步可以避免这种情况发生。当发送FIFO中有至少一个有效样本后,实际数据就会开始传送。一个样本包含32位值,2个16字节分别代表左右声道的数据。
当I2SC被使能后,音频的传送就被自动使能。可以通过设置SACR1中的DRPL位,来关闭音频的传送和回放功能。
当I2SC被使能后,录音功能就被自动使能。可以通过设置SACR1中的DREC位,来关闭录音功能。
当解码器完成有效数据的传送后,I2SC会将数据0填充到录音数据中,直到关闭录音功能。如果总的接收到的数据数量小于接收水位值,剩下的就会用0填充。当达到水位值后,会触发一个DMA请求。
数据进入和离开I2SLINK时,使用了BITCLK的频率。如果BITCLK为输出,解码器就使用SYSCLK运行delta sigma ADC操作。BITCLK可以引用解码器或者内部PLL的时钟源头。如果BITCLK引用内部PLL,则BITCLK和SYSCLK都被配置成输出引脚,并且提供给解码器。如果BITCLK信号由解码器提供,那么它将被配置成输入引脚,这种情况下,SYSCLK的GPIO引脚可以用作其他后备用途。
BITCLK信号如表4-2所示,与采样频率是不一样的。如果BITCLK为输出,则音频时钟分频寄存器会将147.46MHz的PLL分频产生SYSCLK信号,然后SYSCLK被进一步4分频产生BITCLK。采样频率为SYNC信号的频率,它有BITCLK信号64分频产生。48kHz的采样频率可以支持MPEG-2和MPEG-4协议,44.1kHz采样频率可以支持MP3协议。
表4-2 BITCLK信号
Audio Clock Divider Register(31:0) |
SYSCLK = (147.6MHz / SADIV) |
BITCLK = SYSCLK / 4 |
SYNC or Sampling frequency = BITCLK / 64 |
0x0000_ 000C |
12.288MHz |
3.072MHz |
48.000kHz(closest std = 48kHz) |
0x0000_000D |
11.343MHz |
2.836MHz |
44.308kHz(closest std = 44.1kHz) |
0x0000_ 001A |
5.671MHz |
1.418MHz |
22.154kHz(closest std = 22.05kHz) |
0x0000_0024 |
4.096MHz |
1.024MHz |
16.000kHz(closest std = 16.00kHz) |
0x0000_0034 |
2.836MHz |
708.92kHz |
11.077kHz(closest std = 11.025kHz) |
0x0000_0048 |
2.048MHz |
512.00kHz |
8.000kHz(closest std = 8.00kHz) |
FIFO缓冲有16个数据存放入口,每个数据入口为32位宽。音频数据按照左右声道各16字节存储在32位的空间里。即便数据不满16位,也一样会占用16位,不满16位的用0填充,有效字节从左部开始存放。左声道数据占用了[15:0]位,剩余为右声道。
I2S和MSB-Justified是两种类似的串行音频数据传输协议。图4-7和图4-8显示了I2S和MSB-justified的数据格式。
图4-8 MSB-Justified数据格式(16位)
所有的I2S寄存器都是32位宽的,因此地址的递增是以0x0000_0004为增量的,所有的寄存器简要描述见表4-3。
表4-3 寄存器列表
Address |
寄存器名字 |
描 述 |
0x4040_0000 |
SACR0 |
全局控制寄存器 |
0x4040_0004 |
SACR1 |
串行音频数据控制寄存器 |
0x4040_0008 |
– |
保留 |
0x4040_ 000C |
SASR0 |
串行音频数据接口和FIFO状态寄存器 |
0x4040_0014 |
SAIMR |
串行音频中断掩码寄存器 |
0x4040_0018 |
SAICR |
串行音频中断清除寄存器 |
0x4040_ 001C 至0x4040_ 005C |
– |
保留 |
0x4040_0060 |
SADIV |
音频时钟除数寄存器 |
0x4040_0064至0x4040_ 007C |
– |
保留 |
0x4040_0080 |
SADR |
串行音频数据寄存器(接收和发送FIFO访问寄存器) |
PXA255处理器包含了4种UART接口:Full Function UART(FFUART)、Bluetooth UART(BTUART)、Standard UART(STUART)和Hardware UART(HWUART)。这些UART接口都支持以下功能:
n 兼容16550标准;
n 能动态指定串口通信中的标志位,如增加启始位、奇偶校验位等;
n 支持可编程的波特率产生器,将时钟分频至1到(216–1)分之一,产生内部时钟;
n 可控制Modem;
n 具备串口通信的接口能力:
n 5、6、7或者8位数据位;
n 产生1、1.5或者2位的停止位;
n 对于BTUART和HWUART波特率可以达到921kbit/s,其他接口可以达到230kbit/s;
n 64字节的FIFO发送数据队列;
n 64字节的FIFO接收数据队列;
n 可以通过寄存器获得接口运行状态;
n 中断运行模式;
n DMA运行模式;
n 慢速红外异步接口。
在本书中,我们仅讨论标准UART(STUART)的功能。标准UART支持上述列举的除Moderm控制以外的所有功能。在标准串口中,波特率的最高值可以达到230.4kbit/s,而分频器的值必须等于或者大于4。
表4-4描述了在串口通信中需要使用到的信号。和这些信号相对应的引脚被直接连接到PXA255的GPIO上。
表4-4 接口信号描述
信 号 |
类 型 |
功 能 |
RXD |
输入 |
串口输入信号:输入的数据将被储存到接受移位寄存器。在红外模式下,这个信号直接和红外的输入器相连接 |
TXD |
输出 |
串口输出信号。在系统复位后,TXD被置成1 |
先来看一下通常串口数据帧的组成结构,如图4-9所示。
图4-9 串口数据帧组成结构
可以看出一个数据帧是由一个起始位标志开始的。在起始位后面紧跟着5~8位的数据位,这些数据的首位被称为Least Significant Bit(LSB)。在数据位后是奇偶校验位。数据帧的最后是停止位,停止位的位数是由寄存器设定的。在PXA255中可以是1位、1.5位或者2位。
每个UART有两个FIFO队列:输出队列和输入队列。输出队列有64个8位的空间;而输入队列有64字节的空间,每个单元由11位组成,多余的3位用来存放错误信息。
在系统复位后,串口的功能是被关闭的。在启动串口功能之前,必须先正确设置GPIO。然后再设置IER[UUE]。当串口被启动后,接收器和发送器都等待数据的到来。在串口功能被启动前,也可以将数据写入输出寄存器,这样数据也会被锁存。在FIFO模式下,数据先进入队列然后在被锁存到输出寄存器。当串口被关闭时,将在完成当前帧传输后停止接收、发送数据。当时队列中的数据仍然有效,将在下一次串口被启动时继续处理队列中的数据。
每个UART都有13个寄存器,其中12个为UART操作控制寄存器,另外一个寄存器是留给慢速红外传输模式的。所有的寄存器都为32位宽,但是只有低8位数据有效。
每个UART的12个寄存器都有如表4-5所示的分布。
表4‑5 UART寄存器
UART寄存器地址(基地址+偏移) |
DLAB位值 |
被访问的寄存器 |
基地址 |
0 |
接收缓冲寄存器(只读) |
基地址 |
0 |
发送缓冲寄存器(只写) |
基地址+0x04 |
0 |
中断使能寄存器(读/写) |
基地址+0x08 |
X |
中断识别寄存器(只读) |
基地址+0x08 |
X |
FIFO控制寄存器(只写) |
基地址+0x 0C |
X |
电话线控制寄存器(读/写) |
基地址+0x10 |
X |
调制解调器控制寄存器(读/写) |
基地址+0x14 |
X |
电话线状态寄存器(只读) |
基地址+0x18 |
X |
调制解调器状态寄存器(只读) |
基地址+0x 1C |
X |
暂时寄存器(读/写) |
基地址+0x20 |
X |
红外选择寄存器(读/写) |
基地址 |
1 |
分频寄存器低字节(读/写) |
基地址+0x04 |
1 |
分频寄存器高字节(读/写) |
表4-6描述了接收数据寄存器(RBR),在非FIFO模式下RBR寄存器保存了从接收移位寄存器(Receive Shift Register)接收到的数据,由于接收移位寄存器的宽度为8,如果RBR的宽度被设置成小于8位,那么只有右边的数据会被保留。MSB将被用0填充。对这个寄存器的读操作将使寄存器被清空,并且Line Status Register(LSR)也将被置0。
在FIFO模式下,RBR将取接收队列的头一个元素。
表4-6 接收数据寄存器(RBR)
位 号 |
名 字 |
描 述 |
31:8 |
- |
保留 |
7:0 |
RBR[7:0] |
接收的字节(最低位先入) |
表4-7描述了发送数据寄存器(THR),在非FIFO模式下THR中的数据将被传送到发送移位寄存器(TSR)中。当TSR中的数据被发送后,THR中的数据将被传送到TSR中,并且LSR[TDRQ]被设置成1。
在FIFO模式下,向THR中写入数据将把数据存放到发送队列头部,此前的数据将被装载到TSR中。
表4-7 发送数据寄存器(THR)
位 号 |
名 字 |
描 述 |
31:8 |
- |
保留 |
7:0 |
THR[7:0] |
发送的字节(最低位先出) |
每个UART接口都能编程控制波特率,它以14.7456MHz输入时钟为基础进行分频。分频值可以从1到(216–1)。对于FFUART和STUART分频值为4到(216–1)。
波特率产生器产生的频率,是波特率的16倍。DLL和DLH两个8位寄存器一共存储了16位的分频值。如果这两个寄存器都为0,则分频器停止工作。它们的描述如表4-8和表4-9所示。
表4-8 分频寄存器(DLL)
位 号 |
名 字 |
描 述 |
31:8 |
- |
保留 |
7:0 |
DLL[7:0] |
用于产生波特率的分频寄存器低8位 |
表4-9 分频寄存器(DLH)
位 号 |
名 字 |
描 述 |
31:8 |
- |
保留 |
7:0 |
DLH[7:0] |
用于产生波特率的分频寄存器高8位 |
FCR是一个只写寄存器如表4-10所示。FCR决定了串口是否一FIFO队列的模式运行。如表4-10所示。
表4‑10 FIFO控制寄存器(FCR)
位 号 |
名 字 |
描 述 |
|
|||
|
31:8 |
- |
保留 |
|||
|
7:6 |
ITL |
中断触发级别:当接收器FIFO中的字节数目达到了ITL中的数目,并且通过IER寄存器允许触发中断,一个中断信号将被产生,同时会产生一个接收的DMA请求 |
|||
|
5:3 |
- |
保留 |
|||
续表
位 号 |
名 字 |
描 述 |
|
|||
|
2 |
RESETTF |
发送器FIFO清零:当RESETTF被设置成1,在发送器FIFO中的数据都将被清除。如果IER中的TIE位被置位,LSR中的TDRQ位将被置位,IIR显示了发送器请求数据的中断。发送器移位寄存器不会被清除,UART会完成当前的发送 |
|||
|
1 |
RESETRF |
接收器FIFO清零:当RESETRF被设置成1,在接收器FIFO中的数据都将被清除。LSR中的DR位被清零。FIFO中的所有错误位和FIFOE位都将被清除。LSR中已经设置的错误位,如OE,PE,FE或者BI都仍然保留。接收移位寄存器不会被清零。如果IIR已经被设置成接收数据可用信号,此信号就会被清除 |
|||
|
0 |
TRFIFOE |
发送器和接收器FIFO使能:TRFIFOE使能/禁止发送器和接收器的FIFO。当TRFIFOE=1,两个FIFO都会被使能(进入FIFO模式)。当TRFIFOE=0,两个FIFO都会被禁止(进入非FIFO模式)。将此位写0将会清除两个FIFO中的所有的数据。当从FIFO模式转变成非FIFO模式或者相反,FIFO中的数据会被自动清除。当此寄存器中其他位被写入时,此位必须为1,或者其他位没有被编程 |
|||
将STUART寄存器信息总结如表4-11所示。
表4-11 STUART寄存器总结
寄存器地址 |
DLAB位值 |
名 字 |
描 述 |
0x4070_0000 |
0 |
STRBR |
接收缓冲寄存器(只读) |
0x4070_0000 |
0 |
STTHR |
发送保持寄存器(只写) |
0x4070_0004 |
0 |
STIER |
IER(读/写) |
0x4070_0008 |
X |
STIIR |
中断ID寄存器(只读) |
0x4070_0008 |
X |
STFCR |
FCR(只写) |
0x4070_ 000C |
X |
STLCR |
LCR(读/写) |
0x4070_0010 |
X |
STMCR |
MCR(读/写) |
0x4070_0014 |
X |
STLSR |
LSR(只读) |
0x4070_0018 |
X |
STMSR |
保留(无Modem控制脚) |
0x4070_ 001C |
X |
STSPR |
暂时寄存器 |
续表
寄存器地址 |
DLAB位值 |
名 字 |
描 述 |
0x4070_0020 |
X |
STISR |
红外选择寄存器(读/写) |
0x4070_0000 |
1 |
STDLL |
分频器低8位寄存器(读/写) |
0x4070_0004 |
1 |
STDLH |
分频器高8位寄存器(读/写) |
PXA255具有一个快速红外端口(Fast Infrared Communication Port,简称FICP),该端口与STUART(标准UART)的引脚复用,在半双工模式下能直接与IrDA协会兼容的红外收发器连接,实现4Mbps速率的红外通信。
FICP遵从以下标准。
n 4Mbit/s IrDA标准;
n 4相位脉冲调制Fourposition pulse modulation(4PPM);
n 专为IRDA传输而开发的串行通信数据包。
FICP包含以下组件。
n 一个位编码器/解码器;
n 一个串行转并行模块;
n FIFO 128入口、8位宽的传输器;
n FIFO 128入口、11位宽的接收器。
FICP和标准UART共用GPIO引脚。
FICP使用了IRRXD和IRTXD信号。表4-12描述了这两个信号的功能。大多数IrDA传输器都有自己的使能和传输速率配置GPIO引脚。
表4‑12 信号描述
信 号 |
输入/输出 |
描 述 |
IRRXD |
输入 |
FICP的接收数据引脚 |
IRTXD |
输出 |
FICP的发送数据引脚 |
在系统复位后,FICP处于无效状态。在软件使用FICP进行高速通信前,必须先将控制寄存器设置成需要的操作模式。在控制寄存器被设置后,程序可以用数据填充FICP的FIFO传输寄存器至128字节,或者将FIFO传输寄存器清空,使用DMA来进行填充。在FICP被使能后,收发数据寄存器中的数据将通过收发引脚发送。
收发数据寄存器中的数据将按照4PPM IrDA标准进行调制,然后转换成串行或者并行数据格式。
4相位脉冲(Four-position pulse modulation,4PPM)用在4.0Mbps高速率数据传输场合。数据编码和传输过程如下:
一次编码(Bytes->4PPM data)处理两位,总共花费4个Timeslots,这4个Timeslots组成一个Chip时间片。每个Chip传输两位,为4种组合中的一种,即00,01,11,10,在一个Chip中4个Timeslots中产生的脉冲和这4个组合相对应。每个Timeslots维持时间为125ns。如图4-10所示。
图4-10 4PPM Modulation Encodings
图4-11说明了对数据0b10110001进行编码并且传送的实例。编码时一次对一个字节编
图4‑11 4PPM Modulation Example
码,传输一个字节将花费4个Chip的时间。每个Chip传输的数据是2个bit,称为一个Nibble,因此一个字节由4个Nibble组成,由高位到低位依次为Nibble3至Nibble0(如图中的Original Order所示)。传送时,低位的Nibble先传送,高位的在后面,即Nibble0第一个传送,Nibble3最后一个传送。图中Reordered Nibbles说明了这种顺序的转化。
图4-12显示了4Mbit/s传输中使用到的帧格式。
图4-12 4Mbit/s传输中使用到的帧格式
一个数据帧被分成前导域(Preamble)、启动域(Start Flag)、数据域(Data)、校验域(CRC)和停止域(Stop Flag)部分。Preamble、Start Flag、Stop Flag中任何一个Chip时间片中都可能含有0,1或者2个脉冲,因为它们含有“1000”、“1100”等数据。而这几种数据容易导致一个Chip中不含有脉冲或者含有2个脉冲,因为一个Chip中不含有脉冲或者含有2个脉冲都是错误的,因此,利用这种数据比较容易区分Chip的构成,适合于组成前导域、启动域和停止域的数据。前导域部分包含了16个重复的“1000 0000 1010 1000 ” ,启动域由“0000 1100 0000 1100 0110 0000 0110 0000 ” 组成,停止域由“0000 1100 0000 1100 0000 0110 0000 0110 ” 组成。地址域(Address)、控制域(Control)、数据域(Data)、校验域(CRC-32)在下面有详细介绍。
发送器使用8位地址域来识别接收方,这样在当有多达255个站点连接到同一组串行线时,仍然能够识别接受方(0x00~0xFE)。发送方使用0xFF作为广播地址来发送消息。在FICP Control Register 1(ICCR1)中应当指明接收方的地址。
控制域是一个可选的8位域,它由软件定义。FICP并没有为控制域提供硬件的解码支持,它将地址域和CRC域之间的所有位都视为数据。
数据域的长度可以从0~2045字节,具体有软件指定。当接收到的数据长度不是8位的倍数时,会产生abort信号。
FICP使用了32位的CRC校验码来确保数据传输时的正确性。CRC校验码从每个数据帧的地址域、控制域和数据域中产生。发送器在数据被发送时,CRC计算单元计算出32位的CRC码,并且以逆序存储到数据帧中,直到Stop Flag被发送为止。接收器同样在接收数据的同时也计算CRC码,然后和接受到的CRC码进行比较。如果两个CRC码不相同,则会设置CRC错误码。
需要注意的是,与地址、控制、数据域相反,CRC域是以最高位Nibble首先发送的。CRC的计算公式如下:
CRC(X)=(X32+X26+X23+X22+X16+X12+X11+X10+X8+X7+X5+X4+X2+X+1)
IrDA标准定义了所有传输都以半双工模式进行。这样一来,程序在给定的时间里只能使能一个传输方向,或者使能发送器或者接收器。然而PXA255的FICP硬件并没有完全按照标准协议,而是允许全双工模式传输数据,因此程序可以同时使能发送器和接收器。这个功能使用在FICP Loopback模式下,在这个模式下传输器的输出将会和输入相连接。
在FICP被使能后,接收逻辑单元就开始工作,并且使用串行接收器从输入数据引脚接收4PPM chip,每次处理一个chip。如果在这些chip的数据中无法找到对应的Preamble域,那么timeslot记数器的时钟就会延迟一个8MHz周期,同时计数器也延缓自增。这可以视为寻找数据帧,被称为Hunt Mode。这种探测将被重复,直到chip组成了对应的Preamble域,这样计数器才能进入同步自增阶段。Preamble中的chip至少要重复16次来表明数据传输的间隔,也可以通过不断地重复来表明数据链路的空闲状态。
在重复16次Preamble chip后,应当接收到Start Flag。Start Flag为8chip长。如果Start Flag中的数据不符合校验码,那么接收逻辑单元将宣告一个错误,然后再次进入Hunt Mode。
当正确的Start Flag被接收到后,后续的chip将按照每4chip对应一个字节的规则进行解码。然后将字节存放到临时的5字节的FIFO寄存器中,这个临时寄存器是为了将数据和CRC校验码隔离,以防止CRC校验码混入接收FIFO寄存器中。当临时寄存器放满时,数据就被存放进接收FIFO寄存器中。在一个数据帧数据域的开始字节为地址域,如果接收逻辑单元的地址匹配功能被使能,那么存储在ICCR1中的地址就会被用来和接收到的地址进行匹配。如果地址值和接收到的地址相同或者为广播数据,则后续数据将被存储到FIFO寄存器中。如果地址值并不匹配,则数据就不被存储进FIFO寄存器。并且随后就进入Hunting Mode,寻找下一个Preamble。如果地址匹配功能没有被使能,则数据域将会被视为普通数据被存储。数据帧的第二个字节可以是控制域,它所代表的意义必须由程序按照自己的协议进行判别。
IrDA标准规定了所有的数据帧不得超过2047字节(包括地址和控制字节),而在PXA255中并没有限制数据帧的大小。数据帧的大小必须有软件确保。
当接收FIFO中的数据量达到规定值后,FICP就会引发一次中断请求DMA传输。如果数据没有足够快地被清除,造成后续数据无法进入接收FIFO,则后续数据将被存放到full FIFO中,同时FICP会宣告一个overrun错误。当full FIFO也已经填满时,后续数据将被全部丢弃。
如果在数据域中发现无效chip,如0011、1010、1110等,数据帧的接收就会停止。临时FIFO中的旧数据将被转移到接收FIFO中,而没有被转移的数据将被丢弃。
接收逻辑单元将持续寻找8chip的Stop Flag。当确认接收到Stop Flag后,接收FIFO中的最后一个字节被当作这个数据帧的结尾数据,而临时FIFO中的数据将被丢弃,作为CRC校验数据。这里需要注意,接收逻辑单元在判别接收数据是Stop Flag时,最后的一个字节并没有进入临时FIFO,临时FIFO中的内容为4字节的CRC校验码和1字节的Stop Flag。接受逻辑单元将接收到的CRC校验码和自己统计的校验码相比较,如果不匹配的话,接收FIFO中最后的字节会被打上CRC错误标记。如果没有接收到Stop Flag,那么将产生一个abort信号。
如果程序在FICP运行时停止接收逻辑单元的工作,接收中的数据将被立即停止,接收FIFO被清空。然后由System Integration Unit(SIU)接管GPIO的控制。FICP使用的时钟也被关闭,已达到节省功耗的目的。
在使能FICP之前,软件可以用数据预先填充发送FIFO,或者在使能FICP之后请求CPU或者DMA填充发送FIFO。在发送真正的数据之前将先发送至少16个Preamble,如果在16个Preamble后数据仍然没有准备完毕(至少发送FIFO中有一个字节的数据),则发送逻辑单元将继续发送Preamble。在发送完Preamble后,紧接着就是Start Flag和其他发送FIFO中的数据。4个chips(一个字节)将被一次填充入串行移位寄存器。串行移位寄存器中的数据随后被发送到输出引脚,该输出引脚由8MHz时钟驱动。
当发送FIFO中的空闲入口多于32个时,将产生一个DMA服务的中断请求。软件可以决定当数据的填充速度不能满足发送要求时,该帧是作为正常终止还是异常终止。
当软件将其视为正常终止的情况下,发送逻辑单元会正常计算CRC校验码,然后发送数据。然后进入下一帧的处理。
当软件将此视为帧异常终止的情况下,发送逻辑单元将产生一个abort信号,并且产生一个中断。发送单元将持续不断地发送abort信号,直到发送FIFO中出现可发送数据。当出现可发送数据时发送单元仍然将先发送16个Preamble,然后再进入数据发送阶段。
在帧传输的末尾,FICP产生一个脉冲,这被成为串行红外交互脉冲(Serial Infrared Interaction Pulse,SIP)。最长每隔500ms必须产生一个SIP来确保低速设备(115.2Kbit/s或者更低)不会影响高速设备的通信。一次SIP将迫使输出引脚处于高电平1.625µs低电平7.375µs(SIP周期为9.0µs)。
发送FIFO有128个存储入口,每个入口8位宽度;发送FIFO有128个入口,11位宽度。
接收FIFO使用每个入口的3位作为状态记录位。发送FIFO和接收FIFO使用两个独立的但是功能相同的DMA请求。
当发送FIFO中的空闲区域大于32字节时,将产生一个DMA请求中断。这时,处理器可以向FIFO发送后续的数据。当发送FIFO满时,任何处理器发送过来的数据都将丢失。当接收FIFO达到它的触发值时(ICCR2中设置),会产生一个接收中断和DMA服务请求,以通知处理器处理缓冲区中的数据。
每次DMA传输的字节数在DMAC中设置,可以是8、16或者32字节。而发送FIFO没有DMA触发条件,只要空闲区域大于32字节就随时可能发生中断。
FICP中包含的关键寄存器如表4-13所示。
表4‑13 FICP寄存器
物 理 地 址 |
名 称 |
描 述 |
0x4080_0000 |
ICCR0 |
FICP控制寄存器0 |
0x4080_0004 |
ICCR1 |
FICP控制寄存器1 |
0x4080_0008 |
ICCR2 |
FICP控制寄存器2 |
0x4080_ 000C |
ICDR |
FICP数据寄存器 |
0x4080_0010 |
— |
保留 |
0x4080_0014 |
ICSR0 |
FICP状态寄存器0 |
0x4080_0018 |
ICSR1 |
FICP状态寄存器1 |
PXA255的USB设备控制器可以实现符合USB 1.1规格的USB客户端,能支持多达16个端点,并提供了FIFO和DMA来实现与存储器的数据交换。
UDC支持16个端点,作为从设备可以以半双工模式12Mbps的速度进行传输。UDC支持四种设备配置模式(关于配置模式的详细解释,请参考USB协议)。
一种USB设备的配置(configuration)可以认为是一组USB资源的组合。一种配置下有多个接口(interface),接口是指一组数据传输端点(endpoint)的集合,这些端点代表了设备的一种功能特性。
配置1、2和3都支持两个接口。多种配置和接口的支持使得USB主控制器可以根据总线动态变化来调整从设备的工作模式。UDC在的数据包都有层次结构。域,是通信最基本的协议。UDC包括:sync、包标识(PID)、地址、通信端点、帧序列号、数据和CRC校验码。域和数据包被捆绑在一起。一个数据包的功能决定了有多少个域和包捆绑在一起。包类型包括:token、帧开始包、数据包和协议握手包。USB协议的数据传输方式有以下四种:块传输、控制传输、中断传输和同步传输。端点0只用来传输控制信息来配置UDC。端点0的职责有以下几种:建立连接、分配地址、其他端点配置、总线自举和断开链接。每个块传输和同步传输端点都采用了双缓冲来支持FIFO功能,双缓冲的优点在于处理一个缓冲区传输的同时,可以进行另一个缓冲区的数据填充。当收到一个数据包时,就会产生一个中断或者DMA服务请求。DMA处理器每次处理32字节的UDC FIFO接收区的数据。端点0拥有一个16个入口的8位宽度的FIFO,它只能有CPU进行读写。对于1~15号端点,UDC都使用Dual-Ported Memory来保存块传输发送的数据,这样可以在传输的同时校验数据的正确性。如果块传输发送的数据是无效的,则UDC将发送一个NAK协议数据包,通知主控制器重新发送这个数据包(注意,这里所说的发送,是从主控制器的角度来看的)。在块传输发送的数据包被完整接收和校验之前,软件不会被通知数据的到来。如果UDC接收到NAK协议包,则它自己将重新发送数据包。由于FIFO保存了缓冲区的备份数据,因此在重新发送数据时,软件不需要重新加载数据。UDC的外部引脚为UDC+和UDC-信号线。一个1.5千欧的上拉电阻必须和USB Cable的D+信号线连接,以使UDC+信号线在设备没有被驱动的情况下能够拉高。在设备没有被驱动的时候将UDC+引脚拉高将使UDC被认为是一个告诉传输设备(12Mbit/s)。
USB设备配置信息如表4-14所示。
表4‑14 USB设备配置
端 点 号 |
类 型 |
功 能 |
FIFO大小(bytes)×FIFO数量 |
0 |
控制 |
N/OUT |
16 |
1 |
块 |
IN |
64×2 |
2 |
块 |
OUT |
64×2 |
3 |
同步 |
IN |
256×2 |
4 |
同步 |
OUT |
256×2 |
5 |
中断 |
IN |
8 |
6 |
块 |
IN |
64×2 |
7 |
块 |
OUT |
64×2 |
8 |
同步 |
IN |
256×2 |
续表
端 点 号 |
类 型 |
功 能 |
FIFO大小(bytes)×FIFO数量 |
9 |
同步 |
OUT |
256×2 |
10 |
中断 |
IN |
8 |
11 |
块 |
IN |
64×2 |
12 |
块 |
OUT |
64×2 |
13 |
同步 |
IN |
256×2 |
14 |
同步 |
OUT |
256×2 |
15 |
中断 |
IN |
8 |
其中IN数据包代表从UDC发送到主控制器的数据,OUT数据包代表从主控制器到UDC的数据。
本节将讨论如何为各种设备连接USB接口。
图4-13显示了如何为自供电设备连接USB接口。0欧的电阻是可选的,如果它们没有被提供,那么USB D+信号线必须和设备的UDC D+线直接连接,同样USB D-信号线也必须和UDC D-信号线连接。UDC D+和UDC D-引脚被设计来匹配USB Cable的阻抗(90欧姆)。
图4‑13 自供电设备USB连接
在5v电源和CPU引脚之间必须插入“5V转3.3V”设备,因为CPU引脚只能接受3.3V电压。设备能用各种途径来实现,最强壮和可扩展的解决方案是诸如Power-On-Reset设备。
(1)当GPIOn和GPIOx为不同引脚的场合
GPIOn和GPIOx引脚可以是任何的GPIO引脚。GPIOn必须是能将设备从睡眠状态唤醒的引脚。在系统复位后,GPIOx被配置成输入引脚。这就引起UDC+的信号无法到达主控制器。GPIOn被配置成输入引脚,并且在上升沿或者下降沿产生中断。当中断产生时,软件必须查询GPIOn引脚以确定USB Cable是否被连接。当USB Cable被连接时,GPIOn引脚被设置成1,否则为0。当USB物理连接被探测到的时候,软件必须使能UDC外设,而且将GPIOx引脚设置成1,以此向主控制器表明一个高速的USB设备已经被连接。当USB连接被断开,软件必须将GPIOx引脚配置成输入引脚。然后将GPIOn引脚配置成等待唤醒信号,使被断开的设备进入睡眠状态。如果软件必须将设备设置成睡眠状态,则需要将GPIOx引脚设置成输入模式。这将引起UDC+的信号无法到达主控制器。当设备被唤醒时,软件必须向GPIOx引脚写入1,标识高速设备的物理连接。
(2)当GPIOn和GPIOx为相同引脚的场合
在系统复位后,GPIOn被配置成输入引脚并且在上升沿或者下降沿的时候产生中断。当中断产生后,软件必须查询GPIOn引脚来决定USB Cable是否已经被连接。当USB Cable被连接时,GPIOn引脚被设置成1,否则为0。如果USB连接被探测到,软件必须在主控制器向从设备发送第一个USB命令前使能设备。当USB连接被断开时,软件必须将GPIOn引脚配置成等待唤醒信号,然后将设备设置成睡眠模式。当GPIOn和GPIOx为相同引脚时,并且USB Cable仍然连接着设备,那就不需要将设备设置成睡眠模式。在睡眠的时候,UDC始终处于复位模式并且不响应主控制器的任何信号。当它从睡眠模式恢复时,也不会对已经分配的地址作出响应。
处理器不支持总线供电设备,因为它的设计要求本身在睡眠状态下消耗小于500µA。处理器如果不进入睡眠状态,则无法确保其自身功耗在500µA以下。当处理器进入睡眠状态后,它会复位USB的寄存器,这样就不能主控制器分配的地址上的信息进行响应。
当USB中断被探测到后,软件将处理中断。USIR中断是电平触发的,中断处理程序应该确保在退出中断之前清除USIR中的中断标志(在此之前应当清除中断源的位)。在上电或者复位的时候,软件在初始化时只使能EP0中断。其他中断必须在SET_CONFIG命令后再被使能。关于USB协议的命令,请参考USB协议。
EP0控制读操作过程如下。
① 当程序开始执行的时候,先进入EP0_IDLE状态。
② 主控制器发送SETUP命令。
③ UDC产生EP0中断。
④ 程序检测UDCCS0[SA]和UDCCS0[OPR]位是否被设置。这代表一个EP0的缓冲区中存在一个新的OUT数据包,标记一个SETUP阶段的数据传输。
⑤ 如果UDCCS0[RNE](receiver not empty)位为1时,软件将数据读如程序的缓冲区。
⑥ 程序分析缓冲区中的数据,分析这是否是一个控制传输的读操作。
⑦ 软件开始向UDDR0寄存器中加载第一个数据包并且将程序内部的状态标志设置为EP0_IN_DATA_PHASE。
⑧ 在UDC读取接收到的数据后,程序清除UDCCS0[SA]和UDCCS0[OPR]位,并且设置UDCCS0[IPR]的位。在UDCCS0[IPR]位被设置成1之前,任何对本端点的操作请求都会得到NAK的返回。
⑨ 程序清除UDC的中断标志,然后从中断服务中返回。
⑩ UDC发送一个IN包,其中包含了主控制器需要的数据,在主控制器发送ACK确认信号后,UDC清除UDDCS0[IPR]位,然后产生一个中断。
程序进入ISR例子,检测内部状态标记。如果处于EP0_IN_DATA_PHASE状态,这代表它需要传输更多的数据,然后加载更多的数据。内部状态标记不受影响。
重复⑩和 步骤,直到所有数据都被传输。
如果最近一次传输的数据包长度小于标准,则程序将内部状态标记设置为EP0_END _XFER。如果数据长度正好为16字节的倍数,那么UDC将发送一个0字节长度的IN包,然后将内部状态设置为EP0_END_XFER。
然后主控制器发送一个0字节长度的STATUS OUT包,UDC设置UDDCS0[OPR]位,产生中断。
程序进入ISR例程,检查UDCCS0[OPR]是否被设置,UDCCS0[SA]是否被清空,内部状态标记是否为EP0_END_XFER。如果满足这些条件,程序将状态设置为EP0_ IDLE。
① 当程序开始执行的时候,先进入EP0_IDLE状态。
② 主控制器发送SETUP命令。
③ UDC产生EP0中断。
④ 软件检测UDCCS0[SA]和UDCCS0[OPR]位是否被设置。这代表一个EP0的缓冲区中存在一个新的OUT数据包,标记一个SETUP阶段的数据传输。
⑤ 如果UDCCS0[RNE](receiver not empty)位为1时,软件将数据读如程序的缓冲区。
⑥ 程序分析缓冲区中的数据,分析这是否是一个控制传输的写操作。
⑦ 程序清除UDCCS0[OPR]和UDCCS0[SA]位并且将程序内部的状态标志设置为EP0_OUT_DATA_PHASE。
⑧ 程序设置UDCCS0[IPR]位并且向发送FIFO中加载0字节长度的数据包。
⑨ 程序清除UDC中断位并且返回。
⑩ 主控制器发送一个OUT包,UDC产生中断。
程序进入ISR例程并且检查自身是否处于EP0_OUT_DATA_PHASE状态。如果UDCCS0[OPR]位被设置并且UDCCS0[SA]位被清除,则这代表有更多的数据需要接收。
在UDCCS0[RNE]为1时,程序将数据转移到程序缓冲区,清除UDDCCS0[OPR]位。
程序设置UDCCS0[IPR]位,允许premature STATUS IN包。
程序清除UDC中断位并且返回。
重复 ~ 步骤,直到所有数据都被正确接收。
在发送完控制命令后,主控制器发送STATUS IN包,标明控制端将不会发送任何数据。
UDC接收到STATUS IN包后,会返回0字节长的数据包。这会产生一个中断。
程序进入ISR服务例程,查看自身是否处于EP0_OUT_DATA_PHASE状态而且eUD CCS0[OPR]和UDCCS0[IPR]位是否被清除,这标记一个STATUS IN包的接收。
程序比较接收到的包中标记的字节数和SETUP包中标记需要发送的字节数。如果已经发送了正确的数据则程序设置内部状态为EP0_IDLE,否则丢弃所有剩余数据和指针。
程序清除UDC中断位并且返回。
注意,如果在一次发送期间,主控制器又发送了一个SETUP命令,那么UDC必须立即终止当前的传输过程。
当程序接收到来自主控制器的SETUP VENDOR命令,建立端点1的传输时,UDC可以选择以下两种方式中的一种来作为传输模式:
n 关闭端点1的中断功能,使能DMA控制器,由DMA处理数据传输;
n 打开端点1的中断功能,直接处理数据传输。
(1)DMA控制器处理数据传输
如果程序使能了DMA控制器,则按照下列步骤进行数据传输。
① 在接收到SETUP VENDOR命令后,软件使能DMA控制器并且屏蔽端点1的中断。DMA开始地址必须是16字节对齐的。
n 如果包大小为64字节,程序可以将所有数据通过一个DMA描述符进行传输。
n 如果包大小小于64字节,程序应当建立DMA描述符队列,其中奇数序列的描述符指向数据,偶数序列的描述符中的数据被写入UDCCS1[TSP]。
② 主控制器发送BULK-IN请求,UDC回送一个数据包。
③ UDC产生DMA中断。
④ DMA控制器填充端点1的FIFO(UDDR1)。如果数据包长度小于标准数据包的长度,则设置UDCCS1[TSP]。
⑤ 重复②~④步骤,直到所有数据被发送。
(2)通过中断处理数据传输
如果软件使能端点1的中断允许Megacell直接处理数据,则按照下列步骤进行数据传输:
① 在接收到SETUP VENDOR命令后,程序用数据填充端点1的FIFO(UDDR1),清除UDCCS1[TPC]。如果数据包为短数据包(大小小于标准数据包),还要清除UDCCS1[TSP]。
② 主控制器发送BULK-IN包,UDC回送一个数据包,并且产生一次中断。
③ 程序填充端点1的数据FIFO(UDDR1),清除UDCCS1[TPC]。如果数据包为短数据包(大小小于标准数据包),还要清除UDCCS1[TSP]。
④ 从中断返回。
⑤ 重复②~④步骤,直到所有数据被发送。
在端点7和12上同样也有本操作类型。当UDC接收到SETUP VENDOR命令建立端点2块数据传输(BULK OUT),程序可以选择以下两种模式中的一种:
n 关闭端点1的中断功能,使能DMA控制器,由DMA处理数据传输;
n 打开端点1的中断功能,直接处理数据传输。
以上两种模式的具体操作步骤和“EP1块数据传输(BULK-IN)”章节中描述的类似。
本节描述的传输方式同样也适用在端点8和13上。在本节描述的传输方式中,只有当数据包大小小于256个字节时,才会被认为是短数据包。同样,同步数据发送也可以采用多种方式:
n DMA处理数据;
n 使能端点3的中断功能,由Megacell直接处理数据;
n 使能SOF(Start of Frame)中断来处理数据(有关SOF,请参考USB协议)。
(1)DMA处理数据
如果程序使能了DMA控制器,则按照下列步骤进行数据传输:
① 在接收到SETUP VENDOR命令后,程序使能DMA控制器屏蔽端点3的中断。DMA开始地址必须是16字节对齐的。.
n 如果包大小为256字节,则程序可以通过一个DMA描述符来发送所有数据(256字节)。
n 如果包大小小于256字节,如果包大小小于256字节,程序应当建立DMA描述符队列,其中奇数序列的描述符指向数据,偶数序列的描述符中的数据被写入UDCCS1[TSP]。
② 主控制器发送ISOC-IN包,UDC回送一个数据包。
③ UDC产生DMA中断。
④ DMA控制器填充端点3的数据FIFO(UDDR3),如果是短数据包,还要设置UDCCS3[TSP]。
⑤ 重复②~④步骤,直到所有的数据被发送到主控制器。
(2)通过中断处理数据传输
如果程序使能端点1的中断允许Megacell直接处理数据,则按照下列步骤进行数据传输:
① 在接收到SETUP VENDOR命令后,程序用数据填充端点3的FIFO(UDDR3),清除UDCCS3[TPC]。如果数据包为短数据包,还要清除UDCCS3[TSP]。
② 主控制器发送ISOC-IN包,UDC回送一个数据包,并且产生一次中断。
③ 程序填充端点3的数据FIFO(UDDR3),清除UDCCS3[TPC]。如果数据包为短数据包(大小小于标准数据包),还要清除UDCCS3[TSP]。
④ 从中断返回。
⑤ 重复②~④步骤,直到所有数据被发送。
(3)由SOF中断处理数据传输
如果程序使能端点3的SOF中断,则按照下列步骤进行数据传输:
① 程序通过设置UICR0[IM3]禁止UDCCS3中断,清除UFNHR[SIM]位来使能SOF中断。
② 当主控制器发送SOF后,UDC设置UFNHR[SIR]位,这将产生一次SOF中断。
③ 程序检查UDCCS3[TFS]位来判断是否有空间留给数据包。如果有空间,则程序填充端点3的数据FIFO(UDDR3),清除[TPC]位。如果数据包是一个短数据包,则程序设置UDCCS3[TSP]位。
④ 程序清除UFNHR[SIR]位。
⑤ 从中断返回。
⑥ 重复②~⑤步骤,直到所有数据被发送到主控制器。
本操作模式同样也可适用于端点9和14。当程序接收到SETUP VENDOR命令建立端点4同步接收连接时,可以采用多种方式传输数据:
n DMA处理数据;
n 使能端点4的中断功能,由Megacell直接处理数据;
n 使能SOF(Start of Frame)中断来处理数据。
具体操作方式和同步发送数据过程类似。
① 在系统复位后,程序应当按照需要向各寄存器中加载数据。
② 程序设置UDCCR[UDE]位来使能UDC,然后立即读取UDCCR[UDA]位来判断总线上是否有USB复位信号。
n 如果UDCCR[UDA]为0,表明总线上有USB复位信号,程序应当设置UDCCR [RSTIR]来清除中断,然后清除UDCCR[REM]位来允许将来的复位中断。
n 如果UDCCR[UDA]为1,总线上没有USB复位信号,程序通过清除UDCCR[REM]位来允许将来的复位中断。
③ 从中断返回。
④ 主控制器可以断言一个Assertions Reset USB中断或者Reset Negation USB中断。
⑤ UDC产生一个复位中断。
⑥ 软件判断UDCCR[RSTIR]位是否被设置,然后清除中断(设置UDCCR[RSTIR])。接着程序检查UDCCR[UDA]位,来确定已经产生的复位的类型。
n 如果UDCCR[UDA]为0,代表断言的复位。程序从中断返回,等待Reset Negation中断。
n 如果UDDCR[UDA]为1,则产生的是Reset Negation。程序做必要的初始化。
⑦ 从中断返回。
① 程序开始运行时,清除UDCCR[SRM]位来允许USB suspend中断。
② 主控制器通过截断UDC+和UDC-上的信号,断言一个USB suspend。
③ UDC产生Suspend中断。
④ 中断程序检查UDCCR[SUSIR]位是否被设置。这代表了是否产生了一个USB suspend。如果的确产生了一个USB suspend中断,则UDC关闭外设,清除内部数据缓冲区,切换电源状态等。
① 在程序开始运行时,清除UDCCR[SRM]位,允许产生USB resume中断。
② 主控制器通过恢复UDC+和UDC-上被截断的信号,断言一个USB resume。
③ UDC产生一个RESUME中断。
④ 中断服务程序判断UDCCR[RESIR]位是否被设置。这代表是否已经产生了一个USB resume命令,然后后续程序可以恢复设备供电、初始化数据缓冲区等操作。
表4-15显示了UDC寄存器以及它们的地址和功能。
表4‑15 UDC寄存器一览
地 址 |
寄存器名字 |
描 述 |
0x4060_0000 |
UDCCR |
UDC控制寄存器 |
0x4060_0004 |
- |
保留 |
0x4060_0008 |
UDCCFR |
UDC功能寄存器 |
0x4060_ 000C |
- |
保留 |
0x4060_0010 |
UDCCS0 |
UDC端点0控制/状态寄存器 |
续表
地 址 |
寄存器名字 |
描 述 |
0x4060_0014 |
UDCCS1 |
UDC端点1(IN)控制/状态寄存器 |
0x4060_0018 |
UDCCS2 |
UDC端点2(OUT)控制/状态寄存器 |
0x4060_ 001C |
UDCCS3 |
UDC端点3(IN)控制/状态寄存器 |
0x4060_0020 |
UDCCS4 |
UDC端点4(OUT)控制/状态寄存器 |
0x4060_0024 |
UDCCS5 |
UDC端点5(中断)控制/状态寄存器 |
0x4060_0028 |
UDCCS6 |
UDC端点6(IN)控制/状态寄存器 |
0x4060_ 002C |
UDCCS7 |
UDC端点7(OUT)控制/状态寄存器 |
0x4060_0030 |
UDCCS8 |
UDC端点8(IN)控制/状态寄存器 |
0x4060_0034 |
UDCCS9 |
UDC端点9(OUT)控制/状态寄存器 |
0x4060_0038 |
UDCCS10 |
UDC端点10(中断)控制/状态寄存器 |
0x4060_ 003C |
UDCCS11 |
UDC端点11(IN)控制/状态寄存器 |
0x4060_0040 |
UDCCS12 |
UDC端点12(OUT)控制/状态寄存器 |
0x4060_0044 |
UDCCS13 |
UDC端点13(IN)控制/状态寄存器 |
0x4060_0048 |
UDCCS14 |
UDC端点14(OUT)控制/状态寄存器 |
0x4060_ 004C |
UDCCS15 |
UDC端点15(中断)控制/状态寄存器 |
0x4060_0050 |
UICR0 |
UDC中断控制寄存器0 |
0x4060_0054 |
UICR1 |
UDC中断控制寄存器1 |
0x4060_0058 |
USIR0 |
UDC状态中断寄存器0 |
0x4060_ 005C |
USIR1 |
UDC状态中断寄存器1 |
0x4060_0060 |
UFNHR |
UDC帧数目高位寄存器 |
0x4060_0064 |
UFNLR |
UDC帧数目低位寄存器 |
0x4060_0068 |
UBCR2 |
UDC字节计数寄存器2 |
0x4060_ 006C |
UBCR4 |
UDC字节计数寄存器4 |
0x4060_0070 |
UBCR7 |
UDC字节计数寄存器7 |
0x4060_0074 |
UBCR9 |
UDC字节计数寄存器9 |
0x4060_0078 |
UBCR12 |
UDC字节计数寄存器12 |
0x4060_ 007C |
UBCR14 |
UDC字节计数寄存器14 |
0x4060_0080 |
UDDR0 |
UDC端点0数据寄存器 |
0x4060_0100 |
UDDR1 |
UDC端点1数据寄存器 |
0x4060_0180 |
UDDR2 |
UDC端点2数据寄存器 |
0x4060_0200 |
UDDR3 |
UDC端点3数据寄存器 |
0x4060_0400 |
UDDR4 |
UDC端点4 |