s3c2440的USB主机控制器

发布者:SereneWanderer最新更新时间:2016-05-30 来源: eefocus关键字:s3c2440  USB  主机控制器 手机看文章 扫描二维码
随时随地手机看文章
s3c2440提供了USB主机接口,它与OHCI v1.0完全兼容。要使用该功能,就必须熟悉OHCI v1.0规范;而要熟悉OHCI v1.0规范,那么还必须先熟悉USB v1.1协议。因此涉及到该部分的内容较多,要想正确使用s3c2440所提供的USB主机接口也不是一件容易的事情。在这里,我主要介绍USB设备枚举过程中所涉及到的一些知识,并给出具体的实现程序。
 
       OHCI(Open HCI)是目前使用比较广泛的三种USB主机控制器规范之一。USB体系结构是由四个主要部分组成:客户软件/USB驱动,主机控制器驱动(HCD),主机控制器(HC)和USB驱动。前两者由软件实现,后两者由硬件实现。而OHCI就是规范了主机控制器驱动和主机控制器之间的接口,以及它们的基本操作。在主机控制器驱动和主机控制器之间,有两个通信通道,第一个是应用位于HC的一套可操作寄存器,它们包括控制寄存器、状态寄存器和列表指针寄存器;另一个通道是应用称为主机控制器通信域(HCCA)的共享内存。
 
       USB定义了四种数据传输类型:控制传输、批量传输、中断传输和同步传输。在OHCI规范中把数据传输类型分为两类:周期传输和非周期传输。同步传输和中断传输属于周期传输,控制传输和批量传输属于非周期传输。USB定义了每帧的周期为1.0毫秒,为了保证每一帧都能发生周期传输和非周期传输,一般地,OHCI把每一帧的带宽分为四个部分,首先是发送SOF,然后是非周期传输,紧接着是周期传输,如果周期传输完毕后,还有时间,则剩余的时间仍然留给非周期传输。
 
       端点描述符(ED)和传输描述符(TD)是两个最基本的通信模块。ED包含了一个端点的信息,它被HC用来管理使用端点。ED的典型参数包括端点地址、传输速度、最大数据包大小,另外ED还提供了TD链表的停靠地(锚点)。TD是一个依赖于ED的内存缓存区,用于与端点之间进行数据传输。当HC存取一个ED,并且找到一个有效的TD地址时,则HC就完成了一个简单的与端点之间的传输任务,这个端点是由ED确定,而所存取的数据内存地址由TD指定。当所有的被TD所定义的数据传输完毕后,TD就从ED中解链出来,并链接到完成列表中。这个完成列表能够被HCD所处理,以提供一些完成信息。
 
       ED的数据结构长度为16字节,它的数据域有:
FA:USB的功能地址;
EN:USB功能内的端点地址;
D:数据流的传输方向,是IN,OUT,还是有TD来决定传输方向;
S:速度,全速还是低速;
K:用于设置跳过当前ED;
F:链接于ED的TD的形式,是通用TD格式还是同步TD格式;
MPS:数据传输的最大字节大小;
TailP:TD列表的尾指针;
H:用于停止当前TD列表的处理;
C:数据翻转进位位;
HeadP:TD列表的头指针;
NextED:下一个要处理的ED指针。
 
根据上述说明,我们可以定义ED为下面的数据类型:
typedef struct _ED {
       volatile unsigned int Control;
       volatile unsigned int TailP;
       volatile unsigned int HeadP;
       volatile unsigned int NextEd;
} ED, *P_ED;
 
       由于ED必须是16字节地址对齐形式,因此我们必须用下面的形式来声明它的变量:
__align(16) ED ed;
 
       我们可以用下面的函数来创建一个ED:
__inline void CreateEd(
       unsigned int EDAddr,                  //ED地址指针
       unsigned int MaxPacket,                     //MPS
       unsigned int TDFormat,               //F
       unsigned int Skip,                       //K
       unsigned int Speed,                            //S
       unsigned int Direction,                 //D
       unsigned int EndPt,                            //EN
       unsigned int FuncAddress,            //FA
       unsigned int TDQTailPntr,            //TailP
       unsigned int TDQHeadPntr,          //HeadP
       unsigned int ToggleCarry,             //C
       unsigned int NextED)                  //NextED
{
       P_ED pED = (P_ED) EDAddr;
pED->Control = (MaxPacket << 16) | (TDFormat << 15) |(Skip << 14) | (Speed << 13)
| Direction << 11) | (EndPt << 7) | FuncAddress;
       pED->TailP = (TDQTailPntr & 0xFFFFFFF0);
       pED->HeadP = (TDQHeadPntr & 0xFFFFFFF0) | (ToggleCarry << 1);
       pED->NextEd = (NextED & 0xFFFFFFF0);
}
 
TD共有两种类型:通用TD和同步TD。通用TD用于中断、控制和批量端点,同步TD用于同步传输。在这里,我们只给出通用TD的数据结构和定义。
 
通用TD的数据结构长度也是16字节,它的数据域有:
R:缓存凑整,用于设置是否需要最后一个数据包的长度与所定义的长度一致;
DP:方向,是IN,OUT,还是SETUP;
DI:延时中断;
T:数据翻转;
EC:传输错误计数;
CC:条件码,为上一次企图传输的状态;
CBP:将要被传输的数据内存物理地址;
NextTD:下一个TD;
BE:将要被传输的数据内存物理末字节地址;
 
根据上述说明,我们可以定义通用TD为下面的数据类型:
typedef struct _TD {
       volatile unsigned int Control;
       volatile unsigned int CBP;
       volatile unsigned int NextTD;
       volatile unsigned int BE;
} TD, *P_TD;
 
由于通用TD必须是16字节地址对齐形式,因此我们必须用下面的形式来声明它的变量:
__align(16) TD td[4];
 
我们可以用下面的函数来创建一个通用TD:
__inline void CreateGenTd(
       unsigned int GenTdAddr,                    //TD地址指针
       unsigned int DataToggle,                     //T
       unsigned int DelayInterrupt,                //DI
       unsigned int Direction,                        //DP
       unsigned int BufRnding,                            //R
       unsigned int CurBufPtr,                      //CBP
       unsigned int NextTD,                          //NextTD
       unsigned int BuffLen)                         //被传输的数据长度,由该变量可以得到BE
{
       P_TD pTD = (P_TD) GenTdAddr;
       pTD->Control = (DataToggle << 24) | (DelayInterrupt << 21)
| (Direction << 19) | (BufRnding << 18);
       pTD->CBP = CurBufPtr;
       pTD->NextTD = (NextTD & 0xFFFFFFF0);
       pTD->BE = (BuffLen) ? CurBufPtr + BuffLen - 1 : CurBufPtr;
}
 
       下面我们给出HCCA的数据结构,它的长度为256字节,包括128字节的HCCA中断表,2字节的HCCA帧数,2字节的HCCA便签(表示HC是否正在更新HCCA帧数),4字节的HCCA完成队列头指针,以及116字节的保留区。根据上述说明,我们可以定义HCCA为下面的数据类型:
typedef struct _HCCA {
       volatile unsigned int HccaInterruptTable[32];
       volatile unsigned short HccaFrameNumber;
       volatile unsigned short HccaPad1;
       volatile unsigned int HccaDoneHead;
       volatile unsigned char reserved[116];
} HCCA, *P_HCCA;
 
由于HCCA必须是256字节地址对齐形式,因此我们必须用下面的形式来声明它的变量:
__align(256) HCCA hcca;
 
       OHCI是基于寄存器层描述的USB主机控制器的规范,因此HC包含了一些片内可操作寄存器,这些寄存器同样可以被HCD所使用。下面我们就简单介绍OHCI中的寄存器。
HcRevision:HCI规范版本;
HcControl:HC的操作模式,CBSR——在非周期队列中,被服务的控制ED与批量ED之间的比例;CLE——下一帧控制队列处理使能;HCFS——USB主机控制器功能状态,包括复位、重新开始、操作和中止;
HcCommandStatus:HC接收来至HCD的命令,也可反映HC的当前状态,HCR——软件复位HC;CLF——确定是否有控制队列TD;
HcInterruptStatus:提供各种能够触发硬件中断事件的状态;
HcInterruptEnable:使能用于控制产生硬件中断事件的位;
HcInterruptDisable:无效用于控制产生硬件中断事件的位
HcHCCA:HCCA的物理地址;
HcPeriodCurrentED:当前同步或中断ED的物理地址;
HcControlHeadED:控制队列的第一个ED的物理地址;
HcControlCurrentED:当前控制对立ED的物理地址;
HcBulkHeadED:批量队列的第一个ED的物理地址;
HcBulkCurrentED:当前批量对立ED的物理地址;
HcDoneHead:被添加在完成队列中的最近一个TD的物理地址;
HcFmInterval:包含一个14位的FI——用于表示一帧之内所占用的比特时间,2个连续的SOFs,和一个15位PSMPS——用于表示在没有引发调度溢出下可发送或接收全速最大包大小,FI,PSMPS的推荐值为 0x2EDF和0x2778。
HcFmRemaining:14位的倒计数器,以表示当前帧所剩时间;
HcFmNumber:16位计数器,以提供时序参考;
HcPeriodicStart:14位可编程数值,以确定HC在什么时间开始执行周期队列;
HcLSThreshold:11位数值,用于确定是否在EOF之前执行最大8位LS包传输;
HcRhDescriptorA:第一个对跟集线器进行描述的寄存器;
HcRhDescriptorB:第二个对跟集线器进行描述的寄存器;
HcRhStatus:包括集线器状态域和集线器状态更改域;
HcRhPortStstus[1:NDP]:用于控制和报告每个端口上的事件,在s3c2440中,NDP为2
 
       下面给出OHCI的初始化,它都是基于寄存器的。根据OHCI规范,HCD应该完成下列初始化步骤:
● 初始化HCCA数据内存单元
● 初始化可操作寄存器,以匹配当前设备数据状态
● 设置HcHCCA
● 设置HcInterruptEnable
● 设置HcControl
● 设置HcPeriodicStart
      
       结合本文所介绍的实际内容,OHCI的初始化函数为:
void OHCIInit( )
{
       unsigned int fminterval;
 
       //复位
rHcControl = 0;
       //写HCCA
       rHcHCCA = (volatile unsigned )&hcca;
      
       //设置帧间隔
       fminterval = 0x2edf;
       rHcFmInterval =((((fminterval - 210) * 6) / 7) << 16)| fminterval;
       rHcPeriodicStart= (fminterval * 9) / 10;
 
       //初始化HcDoneHead
       rHcDoneHead = 0x00;
       hcca.HccaDoneHead = 0x0000;
   
//设置HC为运行状态
       rHcControl = 0x80;
}
 
       主机对USB设备的识别过程称为设备枚举,因此枚举对于USB至关重要。在本文,只进行下列简单的5步枚举过程:
1、主机要求得到设备描述符,SETUP数据包为:0x80, 0x06,0x00,0x01,0x00,0x00,0x40,0x00,得到的数据长度最大为0x40;
2、第二个SETUP包是为设备分配一个地址,内容一般为:0x00,0x05,0x02,0x00,0x00,0x00,0x00,0x00。其中的02表示为设备分配的地址为0x02,以后我们再对该设备操作时,就只能使用0x02这个地址值;
3、主机用新的地址再次获取设备描述符,SETUP包为:0x80,0x06,0x00,0x01,0x00,0x00,0x12,0x00,与上次不同,这次得到数据长度时实际的数据长度0x12;
4、主机读取设备全部配置描述符,SETUP包为:0x80,0x06,0x00,0x02,0x00,0x00,0x40,0x00,由于主机不知道设备描述符的长度,因此这里只要求得到0x40个字节;
5、主机发送SETUP数据包:0x00,0x09,0x01,0x00,0x00,0x00,0x00,0x00,用以设置配置,允许所有端点进入工作状态。
对USB设备枚举我们只做了简单的介绍,关于枚举的其他步骤以及SETUP数据包各个字节的具体含义,请阅读USB协议的第9章。
 
       下面我们就主要介绍OHCI规范是如何完成USB设备枚举的。前面我们已经介绍过了,OHCI数据传输主要依靠ED和TD,其中TD是挂靠在ED上的。ED主要用来设置传输的各种参数,TD则主要负责具体的数据传输。根据USB协议,USB的设备枚举只涉及控制传输。控制传输最少有两个事务阶段:建立和状态,控制传输可以有选择性地包括建立和状态阶段之间的数据阶段。在这里,控制写传输不需要数据阶段,而控制读需要在建立和状态之间添加主机要读取到的数据。一般来说,完成一次控制写传输需要3个TD:第一个发送Setup包,第二个用于接收握手或零长度的数据包,第三个用于发送状态;而完成一次控制读传输需要4个TD:第一个发送Setup包,第二个用于接收数据,第三个用于发送一个零长度的数据包,,第四个用于接收状态。
 
       下面给出具体的USB设备枚举的函数。在进行枚举之前,主机一定要确认有USB设备的存在。正确情况下,在确认过程中,如果在一段给定时间没有检测到设备,则主机认为没有USB设备。“一段给定的时间”应该由定时器来完成。在这里,为了简化程序,我们只用计数来代替定时。
int USB_Enum()
{
       int i;
       //判断有无USB设备
       for(i=0;i<100000;i++)
       {
              if (rHcRhPortStatus1 & 0x01)
              {
                     rHcRhPortStatus1 = (1 << 4);      // 端口复位
                     while (rHcRhPortStatus1 & (1 << 4))
                            ;            // 等待复位结束
                     rHcRhPortStatus1 = (1 << 1);      // 使能该端口
                     break;
              }
              else if (rHcRhPortStatus2 & 0x01)
              {
                     rHcRhPortStatus2 = (1 << 4);      // 端口复位
                     while (rHcRhPortStatus2 & (1 << 4))
                            ;            // 等待复位结束
                     rHcRhPortStatus2 = (1 << 1);      // 使能该端口
                     break;
              }           
       }
      
       if (i>90000)
              return 0x44;
      
       //第一步,主机得到设备描述符
       CreateEd(
              (unsigned int) &ed,       // ED Address
              64,                        // Max packet
              0,                         // TD format
              0,                         // Skip
              0,                         // Speed
              0x0,                      // Direction
              0x0,                      // Endpoint
              0x0,                      // Func Address,初始为0
              (unsigned int) &td[3],                  // TDQTailPointer
              (unsigned int) &td[0],                  // TDQHeadPointer
              0,                         // ToggleCarry
              0x0);                     // NextED
 
       // 建立PID
       CreateGenTd(
              (unsigned int) &td[0],                  // TD Address
              2,                         // Data Toggle
              0x2,                      // DelayInterrupt
              0x0,                      // Direction
              1,                         // Buffer Rounding
              (unsigned int) pSetup1,         // Current Buffer Pointer,定义的全局变量数组
                                                        //const char pSetup1[8] = {0x80,0x06,0x00,0x01,0x00,0x00,0x40,0x00};
              (unsigned int) &td[1],           // Next TD
              8);                        // Buffer Length
 
       // 接收数据
       CreateGenTd(
              (unsigned int) &td[1],           // TD Address
              0,                         // Data Toggle
              0x2,                      // DelayInterrupt
              0x2,                      // Direction
              1,                         // Buffer Rounding
              (unsigned int) pData1,          // Current Buffer Pointer,定义的全局变量数组
                                                        // char pData1[0x40]; 通过读取该数组,可以获知设备描述符
              (unsigned int) &td[2],           // Next TD
              0x40);                   // Buffer Length
 
       // 零长度数据包
       CreateGenTd(
              (unsigned int) &td[2],                  // TD Address
              3,                         // Data Toggle
              0x2,                      // DelayInterrupt
              0x1,                      // Direction
              1,                         // Buffer Rounding
              0x0,                      // Current Buffer Pointer
              (unsigned int) &td[3],                  // Next TD
              0x0);                     // Buffer Length
      
//接收状态
       CreateGenTd(
              (unsigned int) &td[3],           // TD Address
              3,                         // Data Toggle
              0x2,                      // DelayInterrupt
              0x2,                      // Direction
              1,                         // Buffer Rounding
              0x0,                      // Current Buffer Pointer
              (unsigned int) 0,                   // Next TD
              0x0);                     // Buffer Length
             
       //设置寄存器
       rHcControlHeadED = (unsigned int )& ed;
       rHcControlCurrentED = (unsigned int )& ed;
 
       // 控制列表处理使能,开始工作
       rHcControl = 0x90;
      
       //通知HC控制列表已填充
       rHcCommandStatus = 0x02;
      
 
       //第二步 为设备分配地址
       CreateEd(
(unsigned int) &ed,                     // ED Address
64,                        // Max packet
0,                         // TD format
0,                         // Skip
0,                         // Speed
0x0,                      // Direction
0,                         // Endpoint
0,                         // Func Address
(unsigned int) &td[2],           // TDQTailPointer
(unsigned int) &td[0],           // TDQHeadPointer
0,                         // ToggleCarry
0x0);                     // NextED
   
//建立PID
CreateGenTd(
(unsigned int) &td[0],           // TD Address
2,                         // Data Toggle
2,                         // DelayInterrupt
0,                         // Direction
1,                         // Buffer Rounding
(unsigned int) pSetup2,               // Current Buffer Pointer,定义的全局变量数组
                                                        //const char pSetup2[8] = {0x00,0x05,0x02,0x00,0x00,0x00,0x00,0x00};
(unsigned int) &td[1],           // Next TD
8);                        // Buffer Length
 
//接收零长度数据包
CreateGenTd(
(unsigned int) &td[1],           // TD Address
0,                         // Data Toggle
2,                         // DelayInterrupt
2,                         // Direction
1,                         // Buffer Rounding
(unsigned int) 0,                   // Current Buffer Pointer
(unsigned int) &td[2],           // Next TD
0);                        // Buffer Length
 
//发送状态
CreateGenTd(
(unsigned int) &td[2],           // TD Address
3,                         // Data Toggle
2,                         // DelayInterrupt
1,                         // Direction
1,                         // Buffer Rounding
0x0,                      // Current Buffer Pointer
(unsigned int) 0,            // Next TD
0x0);                     // Buffer Length
 
       rHcControlHeadED = (unsigned int )& ed;
       rHcControlCurrentED = (unsigned int )& ed;
       rHcControl = 0x90;
       rHcCommandStatus = 0x02;
 
       //第三步,主机用新的地址再次获取设备描述符
       CreateEd(
              (unsigned int) &ed, // ED Address
              64,      // Max packet
              0,      // TD format
              0,      // Skip
              0,      // Speed
              0x0,    // Direction
              0x0,    // Endpoint
              0x2,    // Func Address,新的地址
              (unsigned int) &td[3],    // TDQTailPointer
              (unsigned int) &td[0],    // TDQHeadPointer
              0,      // ToggleCarry
              0x0);   // NextED
 
       CreateGenTd(
              (unsigned int) &td[0],    // TD Address
              2,      // Data Toggle
              0x2,    // DelayInterrupt
              0x0,    // Direction
              1,      // Buffer Rounding
              (unsigned int) pSetup3,               // Current Buffer Pointer,定义的全局变量数组
                                                        //const char pSetup3[8] = {0x80,0x06,0x00,0x01,0x00,0x00,0x12,0x00};
              (unsigned int) &td[1],    // Next TD
              8);     // Buffer Length
 
       CreateGenTd(
              (unsigned int) &td[1],    // TD Address
              0,      // Data Toggle
              0x2,    // DelayInterrupt
              0x2,    // Direction
              1,      // Buffer Rounding
              (unsigned int) pData3,          // Current Buffer Pointer,定义的全局变量数组
                                                        // char pData3[0x12]; 通过读取该数组,可以获知设备描述符
              (unsigned int) &td[2],    // Next TD
              0x12);  // Buffer Length
 
       CreateGenTd(
              (unsigned int) &td[2],    // TD Address
              3,      // Data Toggle
              0x2,    // DelayInterrupt
              0x1,    // Direction
              1,      // Buffer Rounding
              0x0,    // Current Buffer Pointer
              (unsigned int) &td[3],   // Next TD
              0x0);   // Buffer Length
      
       CreateGenTd(
              (unsigned int) &td[3],    // TD Address
              3,      // Data Toggle
              0x2,    // DelayInterrupt
              0x2,    // Direction
              1,      // Buffer Rounding
              0x0,    // Current Buffer Pointer
              (unsigned int) 0,   // Next TD
              0x0);   // Buffer Length
             
       rHcControlHeadED = (unsigned int )& ed;
       rHcControlCurrentED = (unsigned int )& ed;
       rHcControl = 0x90;
       rHcCommandStatus = 0x02;
      
       //第四步,主机读取设备全部配置描述符
       CreateEd(
              (unsigned int) &ed, // ED Address
              64,      // Max packet
              0,      // TD format
              0,      // Skip
              0,      // Speed
              0x0,    // Direction
              0x0,    // Endpoint
              0x2,    // Func Address
              (unsigned int) &td[3],    // TDQTailPointer
              (unsigned int) &td[0],    // TDQHeadPointer
              0,      // ToggleCarry
              0x0);   // NextED
 
       CreateGenTd(
              (unsigned int) &td[0],    // TD Address
              2,      // Data Toggle
              0x2,    // DelayInterrupt
              0x0,    // Direction
              1,      // Buffer Rounding
              (unsigned int) pSetup4,               // Current Buffer Pointer,定义的全局变量数组
                                                        //const char pSetup4[8] = {0x80,0x06,0x00,0x02,0x00,0x00,0x40,0x00};
              (unsigned int) &td[1],    // Next TD
              8);     // Buffer Length
 
 
       CreateGenTd(
              (unsigned int) &td[1],    // TD Address
              0,      // Data Toggle
              0x2,    // DelayInterrupt
              0x2,    // Direction
              1,      // Buffer Rounding
              (unsigned int) pData4,          // Current Buffer Pointer,定义的全局变量数组
                                                        // char pData4[0x40];  通过读取该数组,可以获知配置描述符
              (unsigned int) &td[2],    // Next TD
              0x40);  // Buffer Length
 
       CreateGenTd(
              (unsigned int) &td[2],    // TD Address
              3,      // Data Toggle
              0x2,    // DelayInterrupt
              0x1,    // Direction
              1,      // Buffer Rounding
              0x0,    // Current Buffer Pointer
              (unsigned int) &td[3],   // Next TD
              0x0);   // Buffer Length
      
       CreateGenTd(
              (unsigned int) &td[3],    // TD Address
              3,      // Data Toggle
              0x2,    // DelayInterrupt
              0x2,    // Direction
              1,      // Buffer Rounding
              0x0,    // Current Buffer Pointer
              (unsigned int) 0,   // Next TD
              0x0);   // Buffer Length
             
       rHcControlHeadED = (unsigned int )& ed;
       rHcControlCurrentED = (unsigned int )& ed;
       rHcControl = 0x90;
       rHcCommandStatus = 0x02;
      
      
       //第五步,主机发送SETUP数据包,用以设置配置,允许所有端点进入工作状态。
       CreateEd(
(unsigned int) &ed, // ED Address
64,                           // Max packet
0,                         // TD format
0,                         // Skip
0,                         // Speed
0x0,                          // Direction
0,                           // Endpoint
2,             // Func Address
(unsigned int) &td[2],    // TDQTailPointer
(unsigned int) &td[0],    // TDQHeadPointer
0,                         // ToggleCarry
0x0);                        // NextED
 
CreateGenTd(
(unsigned int) &td[0],    // TD Address
2,                        // Data Toggle
2,                // DelayInterrupt
0,                    // Direction
1,                        // Buffer Rounding
(unsigned int) pSetup5,               // Current Buffer Pointer,定义的全局变量数组
                                                        //const char pSetup5[8] = {0x00,0x09,0x01,0x00,0x00,0x00,0x00,0x00};
(unsigned int) &td[1],    // Next TD
8);                       // Buffer Length
 
CreateGenTd(
(unsigned int) &td[1],    // TD Address
0,                       // Data Toggle
2,               // DelayInterrupt
2,                     // Direction
1,                        // Buffer Rounding
(unsigned int) 0,       // Current Buffer Pointer
(unsigned int) &td[2],    // Next TD
0);                          // Buffer Length
 
CreateGenTd(
(unsigned int) &td[2],    // TD Address
3,                         // Data Toggle
2,                 // DelayInterrupt
1,                    // Direction
1,                         // Buffer Rounding
0x0,                          // Current Buffer Pointer
(unsigned int) 0,            // Next TD
0x0);                        // Buffer Length
 
       rHcControlHeadED = (unsigned int )& ed;
       rHcControlCurrentED = (unsigned int )& ed;
       rHcControl = 0x90;
       rHcCommandStatus = 0x02;
      
       return 0x88;
}
关键字:s3c2440  USB  主机控制器 引用地址:s3c2440的USB主机控制器

上一篇:s3c2440外部中断
下一篇:s3c2440的nandflash启动

推荐阅读最新更新时间:2024-03-16 14:55

USB描述符详解
一、基本概念     1、USB协议本身很复杂,但方便在提供了统一的接口方式,使得驱动程序在使用设备的时候,工作简化到了类似操作串行接口。   2、USB设备可以看作提供了多个串口的设备,依据USB的规范,我们将每个串口称作端点(Endpoint),要和这个端点通信,我们就要打开到这个端点的连接,这个连接就是管道(Pipe)。   3、打开端点之后,就可以像串口一样进行数据传输了。USB有4种不同类型的传输方式:控制传输(Control Transfer),批量传输(Bulk Transfer),中断传输(Interrupt Transfer)和实时传输(IsochTransfer)。   4、由于一个设备可能要适应多种
[嵌入式]
ARM9_S3C2440学习(三)FCLK/HCLK和PCLK
ADS1.2中关于时钟的C代码 ChangeMPllValue((mpll_val 12)&0xff, (mpll_val 4)&0x3f, mpll_val&3); ChangeClockDivider(key, 12); 1)FLCK、HCLK和PCLK的关系 S3C2440有三个时钟FLCK、HCLK和PCLK s3c2440官方手册上说P7-8写到: FCLK is used by ARM920T,内核时钟,主频。 HCLK is used for AHB bus, which is used by the ARM920T, the memory controller, the interrupt controlle
[单片机]
USB电池充电电路
  USB标准其中一个特性是从主机为插入的USB外设供电。从过去的串行和并行端口变化到USB,这种进步可使连接到PC的各种器件数大大增加。   除直接供电USB器件外,USB更有用的一个功能是用USB电源进行电池充电。由于很多便携装置(如MP3播放机,PDA)与PC交换信息,所以,电池充电和数据交换同时在一条缆线上进行将会使装置方便性大大增强。把USB和电池供电功能结合起来,扩大了“非受限”装置(如移动web相机连接PC或不连接PC工作)的工作范围。在很多情况下,不必携带不方便的AC适配器。   从USB对电池充电可以复杂也可以简单,这取决于USB设备要求。对设计有影响的因素通常是“成本”、“大小”和“重量”。其它重要的考虑包括:
[电源管理]
<font color='red'>USB</font>电池充电电路
无需功率计即可进行功率测量 安捷伦推基于USB传感器
(北京,2007年7月17日)— 安捷伦科技(NYSE:A)最新发布的 Agilent U2000 系列基于USB的功率传感器,与典型功率计和类似的功率探测解决方案相比,重量更轻,并有更高的性价比。由于使用这种功率传感器进行测量可不需要功率计或额外的硬件模块,因此能节省工作台空间,也使现场测试工作更简单、更容易。 U2000系列功率传感器可与各种 Agilent 信号源、频谱分析仪和网络分析仪配合使用,从而使这些仪器具有更精确的平均功率测试能力。除了USB设备即插即用的连通性所提供的简便、快速的设置外,U2000系列功率传感器还通过与组合众多功能特性的N1918A 功率分析管理器软件配合使用,提供便捷的监测和分析。 由于 Ag
[新品]
意法半导体(ST)发布USB Type-C和电力传输接口
中国,2016年1月14日 横跨多重电子应用领域、全球领先的半导体供应商意法半导体(STMicroelectronics,简称ST;纽约证券交易所代码:STM)发布了一款新的USB Type-C和电力传输接口芯片解决方案。目前,电脑、手机、平板电脑、电视机、机顶盒、游戏机、各种消费电子产品、工控设备以及物联网装置在办公室和家庭里随处可见,然而不同类型的充电器、电源线、数据线相互缠绕,往往使得办公室和居室显得很凌乱,而意法半导体的接口芯片则有助于解决这一困扰。 USB Type-C接口和新电力传输标准(Power Delivery)修改了USB子系统,将其从一个供电能力有限的数据接口,变成一个主要的供电接口、同
[嵌入式]
意法半导体(ST)发布<font color='red'>USB</font> Type-C和电力传输接口
基于S3C2440的嵌入式Linux驱动——SPI子系统解读(三)
该系列文章将分为四个部分: 第一部分,将对SPI子系统整体进行描述,同时给出SPI的相关数据结构,最后描述SPI总线的注册。 基于S3C2440的嵌入式Linux驱动——SPI子系统解读(一) 第二部分,该文将对SPI的主控制器(master)驱动进行描述。 基于S3C2440的嵌入式Linux驱动——SPI子系统解读(二) 第三部分,即本篇文章,该文将对SPI设备驱动,也称protocol 驱动,进行讲解。 第四部分,通过SPI设备驱动留给用户层的API,我们将从上到下描述数据是如何通过SPI的protocol 驱动,由bitbang中转,最后由master驱动将数据传输出 去。 基于S3C
[单片机]
代码重定位(S3C2440)
nand启动,需要重定位 S3C2440的CPU可以直接给SDRAM发送命令、给Nor Flash发送命令、给4K的片上SDRAM发送命令,但是不能直接给Nand Flash发送命令,CPU无法直接访问Nand Flash,因为之间还隔了个Nand Flash控制器。 问:那为什么还可以nand启动? 答:1.nand启动时,前4k代码由硬件自动复制到SRAM。2.此时SRAM的基地址为0地址,CPU从SRAM的0地址开始运行。 问:那么问题来了,烧录至Nand Flash的bin文件大于4k怎么办? 答:前4k代码需要把整个程序读出,复制到SDRAM。然后去SDRAM执行程序。 把程序从nand读出复制到SDRAM的
[单片机]
代码重定位(<font color='red'>S3C2440</font>)
创建USB-PD源设备创建项目与配置系统
USB供电源入门 1创建项目 打开 STM32CubeIDE 并创建一个新的 STM32 项目。作为目标选择,从Board Selector选项卡中选择 NUCLEO-G0B1RE 单击“下一步”,然后输入您的项目名称。将其他字段保留为默认值,然后单击“完成”。 当提示使用默认模式初始化外围设备时,单击否。 2配置系统↑ 此时,您的项目已创建,您只剩下 STM32CubeMX 视图。在接下来的步骤中,我们将配置项目所需的外围设备和选项。 2.1清除引出线↑ 要从空白配置开始,请单击Pinout菜单并选择Clear Pinouts。这将重置引脚布局视图中的引脚布局。 2.2配置系统时基↑ 对于这个简单的例子,我们将使用 Sy
[单片机]
创建<font color='red'>USB</font>-PD源设备创建项目与配置系统
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved