S3C2440 之USB设备篇

发布者:SparkleMagic最新更新时间:2018-06-04 来源: eefocus关键字:S3C2440  USB设备 手机看文章 扫描二维码
随时随地手机看文章

S3C2440 有2 个USB 主机接口和1 个USB 设备接口, 本篇讲述USB 设备接口。

1 USB 的分类及主机接口和设备接口的区别

1.1USB2.0 按照速度分为以下三类

High-speed USB2.0 :理论速度480Mbps ,对应之前的USB2.0 ; 
Full-speed USB2.0 :理论速度12Mbps ,也就是过去的USB1.1 ; 
Low-speed USB2.0 :理论速度1.5Mbps ,这个一般用于鼠标、键盘等对速度要求不高的外部设备。

 

1.2 低速USB  全速USB 硬件设备接口的区别

USB 通过D-,D+ 信号的状态判断设备的插入,如下图所示,D+ 接上拉电阻为全速设备,D- 接下拉为低速设备。

 

1.3 MINI2440USB 设备接口的区别

      Mini2440 开发板只有一个USB 主机接口和一个USB 设备接口,均为USB 全速接口。Mini2440 USB 设备的D+ 是由GPC5 来控制的,如果GPC5 输出高电平,则D+ 上相当于通过上拉电阻接到+5V ,则设备启用;如果GPC5 输出低电平,则D+ 上相当于通过下拉电阻接到GND ,则设备禁用。

 


2 S3C2440USB 设备的固件枚举过程分析

2.1 S3C2440 USB 设备的端点

   2440 有5 个端点,EP0 ,EP1 ,EP2 ,EP3 ,EP4, 。

   EP0 是用于USB 设备枚举,传输方式为control 方式。EP1 到 EP4 用于数据传输。端点的传输方向有两种,IN 和OUT ,这个由 IN_CSR2_REG 来配置。

  端点的传输方式,批量(bulk ),中断(interrupt )也是由 IN_CSR2_REG 来配置。



由上图看到,BIT6 用于配置是 批量模式,BIT5 用于配置传输方向。

 

2.2 S3C2440 USB 程序分析

      整个USB 枚举过程其实是很简单的,首先进行USB 时钟的初始化,设置为48MHz ;然后GPC5 使能,表示全速设备,然后设置USBD1 为USB 设备,禁止USB 挂起,这样调用 UsbdMain(); 进行必要的初始化,这样就准备完成了。

当我们把2440 的USB 口插入到电脑主机的时候,会产生USB 设备复位中断,我们在设备复位中断中进行一些初始化,整个枚举就进入到一个状态机中,一步一步直到枚举完成。

 

// 初始化USB 设备时钟 48MHZ

       ChangeUPllValue(0x38,2,2); // UCLK=48Mhz

 

       // GPC5 使能, 输出为高电平, 表示全速设备

       rGPCCON &= ~(3<<10);

       rGPCCON |=  (1<<10); // output

       rGPCUP  |=  (1<<5);  // pullup disable

       rGPCDAT |=  (1<<5);  // ourtput 

 

       rMISCCR=rMISCCR&~(1<<3);  // USBD1 设置为设备( 不是主机)

       rMISCCR=rMISCCR&~(1<<13); // USBD1 设置为普通模式( 不是挂起模式)

       UsbdMain();

    while(1)

       {

delay();

}

 

我们看下函数UsbdMain 的定义

void UsbdMain(void)

{

    InitDescriptorTable();   // 初始化设备描述符

 

    ConfigUsbd();          // USB 配置

 

    PrepareEp1Fifo();       // 端点1 初始化

}

 

我们看下函数ConfigUsbd

void ConfigUsbd(void)

{

    ReconfigUsbd();       // 重新配置USB

 

    pISR_USBD =(unsigned)IsrUsbd;  // 安装中断函数

    ClearPending(BIT_USBD);        // 清除USB 中断挂起标记

    rINTMSK&=~(BIT_USBD);       // 允许USB 中断

}

 

void ReconfigUsbd(void)

{

// *** End point information ***

//   EP0: control

//   EP1: bulk in end point

//   EP2: not used

//   EP3: bulk out end point

//   EP4: not used

 

// 禁止设备进入挂起模式( 正常模式)

rPWR_REG=PWR_REG_DEFAULT_VALUE;   

 

    rINDEX_REG=0;

//EP0 max packit size = 8         最大数据包

    rMAXP_REG=FIFO_SIZE_8;       

//EP0:clear OUT_PKT_RDY & SETUP_END

rEP0_CSR=EP0_SERVICED_OUT_PKT_RDY|EP0_SERVICED_SETUP_END;  

     

    rINDEX_REG=1;

    #if (EP1_PKT_SIZE==32)

//EP1:max packit size = 32

        rMAXP_REG=FIFO_SIZE_32;

    #else

//EP1:max packit size = 64

      rMAXP_REG=FIFO_SIZE_64;  

    #endif

 

    rIN_CSR1_REG=EPI_FIFO_FLUSH|EPI_CDT;

//IN mode, IN_DMA_INT=masked, 端点方向为IN, 批量传输模式, 中断禁止.

    rIN_CSR2_REG=EPI_MODE_IN|EPI_IN_DMA_INT_MASK|EPI_BULK;

 

    rOUT_CSR1_REG=EPO_CDT;    

    rOUT_CSR2_REG=EPO_BULK|EPO_OUT_DMA_INT_MASK;    

 

    rINDEX_REG=2;

//EP2:max packit size = 64

    rMAXP_REG=FIFO_SIZE_64; 

    rIN_CSR1_REG=EPI_FIFO_FLUSH|EPI_CDT|EPI_BULK;

//IN mode, IN_DMA_INT=masked   

    rIN_CSR2_REG=EPI_MODE_IN|EPI_IN_DMA_INT_MASK;

    rOUT_CSR1_REG=EPO_CDT;    

    rOUT_CSR2_REG=EPO_BULK|EPO_OUT_DMA_INT_MASK;    

                                                                                    

    rINDEX_REG=3;

     #if (EP3_PKT_SIZE==32)

//EP3:max packit size = 32

        rMAXP_REG=FIFO_SIZE_32;

     #else

//EP3:max packit size = 64

       rMAXP_REG=FIFO_SIZE_64;   

    #endif

       //OUT mode, IN_DMA_INT=masked   

    rIN_CSR1_REG=EPI_FIFO_FLUSH|EPI_CDT|EPI_BULK;

 

    rIN_CSR2_REG=EPI_MODE_OUT|EPI_IN_DMA_INT_MASK;

    rOUT_CSR1_REG=EPO_CDT;    

     //clear OUT_PKT_RDY, data_toggle_bit.

        //The data toggle bit should be cleared when initialization.

    rOUT_CSR2_REG=EPO_BULK|EPO_OUT_DMA_INT_MASK;    

 

    rINDEX_REG=4;

    rMAXP_REG=FIFO_SIZE_64;  //EP4:max packit size = 64

    rIN_CSR1_REG=EPI_FIFO_FLUSH|EPI_CDT|EPI_BULK;

//OUT mode, IN_DMA_INT=masked    

    rIN_CSR2_REG=EPI_MODE_OUT|EPI_IN_DMA_INT_MASK;

//clear OUT_PKT_RDY, data_toggle_bit.

    rOUT_CSR1_REG=EPO_CDT;    

        

        //The data toggle bit should be cleared when initialization.

    rOUT_CSR2_REG=EPO_BULK|EPO_OUT_DMA_INT_MASK;    

   

// 清除中断标记位

    rEP_INT_REG=EP0_INT|EP1_INT|EP2_INT|EP3_INT|EP4_INT;

//Clear all usbd pending bits

    rUSB_INT_REG=RESET_INT|SUSPEND_INT|RESUME_INT;        

        

        

    //EP0,1,3 & reset interrupt are enabled

// 中断使能寄存器

    rEP_INT_EN_REG=EP0_INT|EP1_INT|EP3_INT;      

// USB 复位中断使能

    rUSB_INT_EN_REG=RESET_INT;                               

// 端点0 状态设置为初始化

    ep0State=EP0_STATE_INIT;                                

}

 

void IsrUsbd(void)

{

    U8 usbdIntpnd,epIntpnd;

    U8 saveIndexReg=rINDEX_REG;

    usbdIntpnd=rUSB_INT_REG;   // 读取USB 中断寄存器

    epIntpnd=rEP_INT_REG;       // 读取断点中断寄存器

    //DbgPrintf( "[INT:EP_I=%x,USBI=%x]",epIntpnd,usbIntpnd );

 

    if(usbdIntpnd&SUSPEND_INT)

    {

           rUSB_INT_REG=SUSPEND_INT;

           DbgPrintf( "

    }

    if(usbdIntpnd&RESUME_INT)

    {

           rUSB_INT_REG=RESUME_INT;

           DbgPrintf("

    }

    if(usbdIntpnd&RESET_INT)   // 收到复位信号, 重新配置USB 设备配置

    {

           DbgPrintf( "

          

              // 中断标记清零

           rUSB_INT_REG = RESET_INT;  //RESET_INT should be cleared after ResetUsbd().     

 

              //ResetUsbd();

           ReconfigUsbd();

 

              Test();  //PrepareEp1Fifo();

       

    }

 

    if(epIntpnd&EP0_INT)

    {

           rEP_INT_REG=EP0_INT; 

           Ep0Handler();

    }

    if(epIntpnd&EP1_INT)

    {

          rEP_INT_REG=EP1_INT; 

           Ep1Handler();

    }

 

    if(epIntpnd&EP2_INT)

    {

           rEP_INT_REG=EP2_INT; 

           DbgPrintf("<2:TBD]");   //not implemented yet      

           //Ep2Handler();

    }

 

    if(epIntpnd&EP3_INT)

    {

           rEP_INT_REG=EP3_INT;

           Ep3Handler();

    }

 

    if(epIntpnd&EP4_INT)

    {

           rEP_INT_REG=EP4_INT;

           DbgPrintf("<4:TBD]");   //not implemented yet      

           //Ep4Handler();

    }

 

    ClearPending(BIT_USBD);   

   

    rINDEX_REG=saveIndexReg;

}

 

void Test()

{

    U8 in_csr1;

    rINDEX_REG=1;

    in_csr1=rIN_CSR1_REG;

    SET_EP1_IN_PKT_READY();

}


关键字:S3C2440  USB设备 引用地址:S3C2440 之USB设备篇

上一篇:s3c2440启动过程分析
下一篇:谈谈和S3C2440的对比

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

S3C2440在MDK4.22下使用printf向串口打印调试
背景知识: 串口的基本知识已经在上一篇讲过了。这里重点讲解如何在MDK4.22下使用printf函数,这样的话就可以很方便的打印调试信息,追踪。 这个知识来源于MDK自带的帮助手册。有现成的代码提供。 实现方式有2种,使用标准C库下裁剪合适的函数,使用微库C下裁剪合适的函数。 微库下的情况,在魔术棒那里要勾选上使用微库。然后需要定义如下结构和改写如下函数--FILE stdout fputc ferror。 标准库的情况,也是需要关注FILE stdout fputc ferror。注意网上很多文章说,在标准库下,需要关掉半主机模式,我尝试过,关掉后,需要定义_sys_exit函数,可以达到效果,但是如果不关掉半主机模式,和
[单片机]
ARM9_S3C2440学习(四)FIQ和IRQ区别
ARM 处理器有 FIQ和 IRQ 两级外部中断,它们都是由对电平敏感的低电平(LOW)信号激活进入处理器的。为了产生中断,CPSR 中的相应禁用位必须清零。 快速中断请求(Fast Interrupt Request,FIQ),IRQ全称为Interrupt Request,即是“中断请求”的意思。 FIQ 的优先级比 IRQ高,具体表现如下: (1)当发生多个中断时,首先处理 FIQ。 (2)处理 FIQ会导致禁用 IRQ 和后续 FIQ,在 FIQ处理程序启用之前,不会处理 IRQ 和后续 FIQ。这通常是通过在处理程序结束时从 SPSR恢复 CPSR来完成的。 FIQ 向量是向量表的最后一个入口,因此
[单片机]
USB设备控制器端点缓冲区的优化技术设计
  这里首先简要介绍USB中端点的概念,并给出一款异步FIFO的设计方案。然后根据USB四种传输类型的特点,提出基于该FIFO结构的不同类型的端点缓冲区的设计方案。特别是对于控制端点提出了一种新型的双向异步FIFO结构,在保证控制传输的前提下,减小了将近1/2的电路面积。最后给出在Synopsys平台下电路的VLSL实现结果。   USB 2.0规范将USB接口的传输速度提高了40倍。传输速度的提升使得USB设备控制器的设计指标也随之提高,虽然协议中对于缓冲区的设计要求并没有本质上的改变,但是由于总线带宽与传输速度的提高,各个芯片供应商均推出了自己的缓冲区设计方案。为了提高USB接口的数据存取速度,通常使用异步FIFO来设计端点缓冲
[嵌入式]
关于S3C2440时钟设置的理解
关于S3C2440时钟设置的理解 1)FLCK、HCLK和PCLK的关系 S3C2440有三个时钟FLCK、HCLK和PCLK 手册上说P7-8写到: FCLK is used by ARM920T,内核时钟,主频。 HCLK is used for AHB bus, which is used by the ARM920T, the memory controller, the interrupt controller, the LCD controller, the DMA and USB host block. 也就是总线时钟,包括USB时钟。 PCLK is used for APB bus, which is u
[单片机]
关于<font color='red'>S3C2440</font>时钟设置的理解
s3c2440 iic eeprom
1、使用2440 iic 模块控制 #include 2440addr.h #include uart.h volatile int ackFlag = 0; void delay() { int i,j; for(i = 0; i 500;i++) for(j = 0; j 500; j++) ; } /*********************************************** Function name : Iic_ISR Description : iic 中断处理函数 Input parameter : none Return : none
[单片机]
S3C2440—7.存储控制器访问外设
一.内存接口的概念 S3C2440是SOC,所以会有很多外设,一般驱动外设的方法可以分为: 通过CPU访问相应的的寄存器,然后通过控制器驱动外设 CPU直接访问外设地址,驱动外设 后一种访问方式是CPU直接对内存地址的访问,即通过内存接口访问外设,CPU通过片选线选定外设,通过地址线先选定地址,通过数据线进行控制。 我们称这种外设为内存类设备,通常有:NOR FLASH、网卡、SDRAM…… 那CPU是如何通过这些总线来驱动内存类设备呢?这就涉及到存储控制器了,下面就来介绍一下存储控制器的原理。 二.存储控制器(内存控制器) 2.1 什么是存储控制器? 存储控制器是按照一定的时序规则对存储器的访问进行必要控制的
[单片机]
<font color='red'>S3C2440</font>—7.存储控制器访问外设
内嵌USB设备的ARM微控制器
  爱特梅尔推出基于ARM9 的微控制器AT91SAM9R64,目标市场为高性能的、具有USB接口的嵌入式控制应用。AT91SAM9R64可通过USB、SD卡或外接NAND闪存启动,从而减少保存程序和批量数据的存储器的数量。芯片采用球间距为0.8mm的10x10 mm BGA封装。    高速USB   传输速率高达480 Mbits/sec的高速USB正迅速成为连接设备与PC的标准。SAM9R64可以将现有的全速USB (速率为12 Mbits/sec)产品升级到高速USB,而无需对连接器进行任何物理改动。    可编程的存储器总线电压   除了支持传统的静态存储器外,SAM9R64的存储器总线接口还支持SDRAM和NA
[单片机]
S3C2440之ADC
S3C2440包含一个8通道A/D转换器,有10位分辨率下面简要介绍一下S3C2440中ADC的用法: 用到的寄存器: ADCCON:ADC控制寄存器 ADCDAT0:ADC转换数据寄存器 SUBSRCPND:次级源挂起寄存器 INTSUBMSK:中断次级屏蔽寄存器 SRCPND:源挂起寄存器 INTPND:中断挂起寄存器 INTMSK:中断屏蔽寄存器 ADCCON:AD控制寄存器 ADCDAT0:AD转换数据寄存器 1,首先设置控制寄存器ADCCON的相应位来选择频率和通道: view plain copy rADCCON = (1 14)|(preScale
[单片机]
<font color='red'>S3C2440</font>之ADC
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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