|
用Holtek USB MCU实现USB Device McuPlayer 发表于 2006-9-9 13:16 资料 文集 短消息
一直想在论坛写个帖子,介绍Holtek USB MCU单片机的实际应用。无奈时间缘故, 上班忙公司的事,下班忙着在各个论坛灌水。忽然想通了,何不把自己的摸索经历写 下来与大家分享。于人,帮助初学者,于我,知识的总结与提升。 我将在这个帖子里面把我用Holtek 82K系列MCU开发USB Device的经验跟大家 分享,包括固件(也叫做韧件、单片机软件)、PC软件。主要局限在Low Speed 和HID,这样我们就不用开发Driver了,而是直接是有能够M$的HID Driver。至于 硬件,如果你跟我一样懒,直接抄Datasheet好了,保证可以跑。 虽然说包括Firmware和Software,但是以Firmware为主。因为Firmware最能 体现USB spec的内容,Driver也在很大程度上体现USB spec,但是不是这个帖子 讨论的主题。 我首先做个假设,参与讨论的朋友都可以: 1、熟练使用Holtek MCU的汇编指令集 2、熟练使用IDE3000来开发单片机应用 3、对USB有一定的了解,曾经浏览过USB spec,哪个版本都算数 4、对C++和Windows API有一定的了解(如果你不写Software就可不要求这个学分啦) 做USB Device,一定要对USB spec的chapter9熟悉。看看名字是“CHAPTER 9 USB DEVICE FRAMEWORK”就知道这章是我们写Firmware的参考重点了。这里我们先来 温习一下Chapter9的内容。
先来看看USB Device的state machine,这个状态机使USB设备知道自己处于何种状态。 我的USB spec是V1.1版本的,在176页。USB Device所处的几个状态分别是: attached(连接)、Powered(上电)、Default(缺省状态)、Address(可寻址)、 configured(已配置),在外加一个suspend状态。 Attached状态,就是我们手工把Device和Host连接的过程,Plug而已,用Firmwre的角 度说就是“不关我的事”。 Powered这个状态的命名来自于总线供电的设备。但是也有设备是自供电的,这就设计一 些对我们讨论Firmware关系不大的细节,我们先跳过不谈(我是不是太懒惰了)。 Default缺省状态,USB Device在加电后并不立刻对总线发出响应,而是在USB的总线 Reset后才进入Default状态,可以在缺省地址相应USB的token。至于Default状态都会 发生什么USB request,我也说不清楚,但是有一点是明确的,Set Address是这个阶段 的很重要的任务。 Address状态就是在Default状态响应Set Address后进入的。按说,现在就可以工作了吧, 为什么还要再安排个Configured状态呢。这是因为USB的设计者想USB Device可以support N个设置,到时候可以根据需要N选一(皇帝临幸妃子不都如此吗)。 Configured就是最终的工作状态了(不要再想上面的话了啊),这时候大量数据传输,所 有的USB Device都是在这个状态工作的。 至于那个suspend状态,把它当成休假好了,省电了。
说完了状态机,就该说枚举过程了。Enumerate过程,我有个朋友一直翻译为总线标示过程, 如果你也如此,肯定是看那份翻译的还算不错但是又很蹩脚的中文USB spec了。 我们先看看USB Device被Plug到Host的socket后发生了什么: 1、那个口对应的HUB会报告主机,此时你只是见到了媒婆而已,相亲还得等会 2、HUB这个媒婆就跟HOST窃窃私语,讨论你长得帅不帅之类的,而且故意搞些delay保证 你不会立马拍屁股走人。 3、HUB会Reset Device个10ms,然后Device总算到了Default状态了,可以对0地址相应了。 4、HOST跟Device见面后,通过一系列的USB request,吧Device从几个状态转来转去,最 终目标是Configured。Default状态就只能用0地址,configured之前只能用Default pipe,也 只能使用control传输。
打字有点累了,USB Requeset的回顾放到下次吧。 GET_STATUS------问你话呢,忙什么呢?HOST就是这样去了解DEVICE的 CLEAR_FEATURE----那个不用的功能暂时关闭吧。 SET_FEATURE------打开某个功能,现在需要。 SET_ADDRESS------你转正了,你的正式地址是N(1~127) GET_DESCRIPTOR----想知道你的自我描述, SET_DESCRIPTOR----试试能否改变你 GET_CONFIGURATION--你用的是哪个配置啊 SET_CONFIGURATION--你用我告诉你的这个配置,号码 GET_INTERFACE-----你用的是哪个接口啊 SET_INTERFACE-----用这个配置吧 SYNCH_FRAME------这个是同步传输用的
关于这几个Request的细节,我们会在讨论Firmware的时候,再细细叙来。
HOLTEK单片机的USB SIE承担USB通讯的很多协议层及其以下层次()的细节, 也就是说电气和协议层等USB spec的内容,只需粗略读一下即可。 而Firmware处理的多是Device Frame(spec ch9)的内容。
详细如下(其实很费话,因为几乎所有的USB MCU都如此,或者很类似)
USB SIE处理下面的工作: 1、转换接受到的编码数据,编码准备在USB总线上传输的数据。 2、硬件CRC检查和CRC产生。如果CRC错误,硬件不会ACK给HOST,并且设置FLAG 3、硬件自动更新、发送数据反转位,(Data1/0) 4、自动发送ACK或者NAK 5、SETUP/IN/OUT的Token自动识别,并设置对应的寄存器 6、把收到的数据保存到对应的FIFO 7、位填充、去填充 8、地址检查,只有与自己Address对应的数据才接受 9、端点检查,根据HOST的要求,设置对应的寄存器
Firmware需要做余下的工作: 1、通过响应来自的HOST的USB Request完成枚举 2、填充或者清空FIFO,完成数据的读写 3、挂起/恢复 USB Device 状态,通过USB SIE控制器存取 4、完成Remote wake up,如果需要的话 5、透过USB中断,依据各个Register的状态,branch到各个不同的处理路径
下面会介绍HOLTEK单片机的USB所对应的寄存器 以HT82K96为例,介绍USB相关的Register 这些Register主要分布在BANK0和BANK1 BANK0: USC, USR, SCC BANK1: AWR, STALL, PIPE, SIES, MISC, FIFO0~FIFO3
1、USC只有bit0-bit3是跟USB相关的。 SUSP和RESUME,是USB总线状态表现的地方 RMWK,通知HOST进行WakeUp的,相当于Device这个秘书唤醒HOST URST:USB Reset标示
2、SCC中跟USB相关的只有2个bit SYSCLK:说明现在用的是6M还是12M,千万别添错,否则HOST不理你 USBCKEN:USB时钟允许,正常用的时候一定置1,置0的相当于USB关了,不给发薪怎么干活呢
3、USR跟USB相关的bit多了 EP0IF-EP3IF: Endpoint Interrupt flag,就是引起USB中断的来头,Firmware看这几个bit, 用完了还要记得清除,去大号当然要自己擦屁股了 SPS2:PS2使能,当然置0了,对待敌人要象秋风扫落叶一样..... SUSB: USB使能,当然置1了,对待..... ADREF: AD转换用的,跟我们的话题无关,自己看去 FIFO-cntl: 专门跟仿真器用的,操作FIFO时候,0读1写,我想烧OTP也不碍事吧,就一直用吧
下面是住在BANK1的寄存器介绍,写Firmware的时候记着用间接寻址来访问喔
1、AWR USB地址(7个bit)+Remote Wake使能(1个bit),注意这7个bit的地址,是bit1-bit7,所以经常要shift 1个bit
2、STALL STALL,死到死到,确实是负责各个端点死活的,不过不是死了拉到,1就死0就活,每个ENDPOINT一个bit
3、FIFO0~FIFO3 各个PIPE的FIFO了,各管各家,各养各妈
4、PIPE 这里就告诉你刚才哪个王妃(PIPE)被国王(HOST)临幸过,仍然是各管各家,每个PIPE一个bit
5、MISC 终于轮到这个最杂货的Register了,这可以PIPE访问的法官啊,它仲裁SIE和Firmware谁可以访问FIFO 因为Firmware是通过FIFO跟USB SIE联络的,于是FIFO就是临界区(不明白概念者,去看OS课本) SELP0+SELP1:两个bit表示4个FIFO,别告诉我你想不通 TX:发送还是接受,也就是你要读还是写FIFO,1表示其中哪个,1当然表示发送了,人家名字叫TX啊 REQ和READY:分别用来提交申请和查看申请是否通过,大家最讨厌的罗嗦估计也跟它俩有关,不过人家也尽责了 剩下的几个bit估计比较独立了 Cleare:不管FIFO有没有READY,强制清除FIFO,说好听的叫做进入特别状态,不好听就叫做独裁 SCMD:告诉Firmware说FIFO里面的数据是Setup,它怎么有先见之明呢,人家SIE不是看过Token了吗 LEN0:告诉Firmware说HOST送来个长度为0的数据包,有这样送礼的吗?USB spec确实定义了这种流氓做法,这是后话
6、SIES 这个寄存器啊,新版的IC才有(详见官方datasheet) Adr_set:这个有用啊,增加它Firmware可简化了不少,这是后话。 F0_Err: FIFO0专用的Error寄存器,作用呢,您仔细瞅吧,一出错标志而已,无非想证明FIFO0最重要 dengdalong
我正在用82K96 能否提供相关C代码! USB
万分感谢 ddlav478@sohu.com
谢谢鼓励
很多东西,还在酝酿。打算写点东西,才知道掌握太少了,而此之前有些自以为是啊,哈哈。 我用的是汇编,在HOLTEK官方的demo基础上修改的。
|