打印

笙泉USB系列芯片硬件说明,及USB鼠标代码,连载中........

[复制链接]
10890|29
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
David_ming|  楼主 | 2011-4-15 23:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 David_ming 于 2011-5-3 18:01 编辑

不用去读规格书了,大家可以直接跟帖

84系列是Megawin的USB芯片,抗干扰不错,而且也特别适合学习,带有USB
的引导程序,开发的时候可以不用任何工具,只用笙泉的DFU软件即可,特
此发点学习资料,不正确的地方请斑竹指正,欢迎跟帖纠正

1. 硬件自动做的事情有:
   1.编解码,CRC,PID令牌解码,总线事件等最底层的事情;
   2.ACK,NAK信号的回复;
   3.DATA0/1自动切换;
   4.错误重试;
2. 发STALL信号命令:(EPCON |= RXSTL | TXSTL)
   置位RXSTL和TXSTL就把硬件端点给挂起了,下一次主机问的时候就会自动
   回复STALL信号。注意,这个STALL信号只会有效一次。
3. FIFO特性
   每个端点都是FIFO特性(先进先出),对于IN端点,可以通过RXCNT判断接收
   到了多少个字节,当然,虽然每次收到的数据个数都是已知的.在每次读完
   FIFO后记得清零一下,即 RXCLR 位置一。
4. 当想往上位机发送数据的时候,要写数据到FIFO,然后再写入包的大小到
   TXCNT中以告诉硬件要发送多少byte数据,当然也可以写0到该寄存器,以
   发送状态信息。
5. 对于中断OUT型端点,记得收到数据后清一下 RXFFRC 位以使能下一次的
   接收,不然,会一直回复NAK。

想到了这么多,知道上面的这些,应该可以做不少东东了




贴个能工作的工程,注意这个工程只是能工作,省略了很多东西,下载进去后能看见鼠标向右下角移动

Project.rar

50.79 KB

沙发
zhaor| | 2011-4-19 08:17 | 只看该作者
谢谢了啊!哪有出售的啊?

使用特权

评论回复
板凳
David_ming|  楼主 | 2011-4-19 18:32 | 只看该作者
本帖最后由 David_ming 于 2011-4-19 18:34 编辑

联系代理商吧,路必康


下面是 WIN7 键盘的枚举过程:

  0:Suspend!
  1:Reset!
  2:EP0 Event->80 6 0 1 0 0 40 0 Standard->GetDescr->Device->length:18
  3:Reset!
  4:EP0 Event->0 5 3 0 0 0 0 0 Standard->SetAdd=3.
  5:SetAddressAck.
  6:EP0 Event->80 6 0 1 0 0 12 0 Standard->GetDescr->Device->length:18
  7:SendOvf.
  8:EP0 Event->80 6 0 2 0 0 ff 0 Standard->GetDescr->Config->length:34
  9:SendOvf.
10:EP0 Event->80 6 3 3 9 4 ff 0 Standard->GetDescr->SN->length:12
11:SendOvf.
12:EP0 Event->80 6 0 3 0 0 ff 0 Standard->GetDescr->Language->length:4
13:SendOvf.
14:EP0 Event->80 6 2 3 9 4 ff 0 Standard->GetDescr->product->length:46
15:SendOvf.
16:EP0 Event->80 6 0 1 0 0 12 0 Standard->GetDescr->Device->length:18
17:SendOvf.
18:EP0 Event->80 6 0 2 0 0 9 0 Standard->GetDescr->Config->length:9
19:SendOvf.
20:EP0 Event->80 6 0 2 0 0 22 0 Standard->GetDescr->Config->length:34
21:SendOvf.
22:EP0 Event->0 9 1 0 0 0 0 0 Standard->SetCnf->enable.
23:SendOvf.


到 SetCnf(即set config)为止枚举完毕,可以听到 咚咚 声了



有人感兴趣我就贴代码

使用特权

评论回复
地板
yufe| | 2011-4-19 19:20 | 只看该作者
抱着学习的心态围观

使用特权

评论回复
5
sz_n053| | 2011-4-19 22:30 | 只看该作者
mark ( 等代码 )

使用特权

评论回复
6
David_ming|  楼主 | 2011-4-25 14:15 | 只看该作者
先上个头文件,该头文件大部分都是从官网上的demo程序中copy过来的:lol ,主要添加有如下几个宏定义:
      UsbACK------是设备回应主机一个状态信号,即发送一个 0 长度的数据给主机
      UsbStall------是设备返给主机的一个stall PID包,表示不支持当前的操作

USB请求包格式信息:
bmRequestType,bRequest。。。。。。。等等

读写寄存器宏定义:

#define      WriteSfr(address,value)   (USB[address]) = (value)
#define   ReadSfr(address)    (USB[address])

这里注意一下,之所以这样定义,是因为以后改成 84FG516(性能会强大很多哦) 可以做最小的改动


命名一个类型:
typedef enum{EP0=0,EP1=1,EP2=2,EP3=3,EP4=4,EP5=5}endpoint_num;


定义2个类型
typedef struct
{
    uint8_t  enuming;
uint8_t  remoteWakeUpEn;
uint8_t  configuration;
uint8_t  address;
uint8_t  idleRate;
uint8_t  protocol;
uint8_t  interface;
}device_info;

这个类型存储device的一些信息,包括地址,空闲率什么的

typedef struct
{
uint8_t * pData;
uint8_t dataSize;
uint8_t maxBuffer;
}endpoint_attr;

该类型存储端点的属性,包括端点的大小maxBuffer,要通过端点发送的数据地址pData,和数据大小dataSize

main.rar

1.8 KB

使用特权

评论回复
7
David_ming|  楼主 | 2011-4-25 14:24 | 只看该作者
本帖最后由 David_ming 于 2011-4-25 14:39 编辑

下面进入主程序函数的编写

#include <REG_MG84FL54.H> 定义了 8454的基本寄存器地址
#include <stdio.h> 我们要用到printf函数
#include "main.h" 把刚才定义的头文件加载进来


#define S115200 243 设定波特率



uint8_t idata USBSetup[8]; 存放SETUP封包的 8byte 数据

device_info idata usbInfo; 实例化一个usb信息的变量
endpoint_attr endPoint[2]; 实例化2个端点属性信息,EP0用于控制传输,EP1用于USB报告

使用特权

评论回复
8
David_ming|  楼主 | 2011-4-25 14:33 | 只看该作者
本帖最后由 David_ming 于 2011-4-25 14:39 编辑
void main(void)
{
IE = 0;
AUXIE = EUSB; 使能USB
PSW = 0x00; 切换到bank0
CKCON = (unsigned char)((( 12 - 1 ) << 3)|(1)); 初始化 CKCON,系统时钟初始化
Delayms(10000); 延时一下


初始化PLL,并等待其稳定

while(true)
{
USB[ACKCTL] |= EN_DLL;
if(USB[ACKCTL] & EN_DLL)break;
}

Delayms(10000); // Wait for DPLL 48Mhz Ready

while(true)
{
USB[ACKCTL] |= UCK_SEL;
if (USB[ACKCTL] & UCK_SEL)break;
}




CKCON2 |= CLK48; //主时钟初始化成 24MHz 48MHz/2 = 24MHz
Delayms(10000);

初始化串口部分
SCON = 0x40; //uart work on 8bit async mode
SM2 = 0; //disable address discern(mode 2,3)
REN = 1; //enable receive
PCON &= ~0x40; //SM0 enable,FE disable(SCON register)
AUXR2 |= 1<<6; //X12 MODE
PCON |= 1<<7; // overflow/16
TH1 = S115200;
TL1 = S115200; //set Baud rate
TMOD = 0x20; //TM1 work on 8bit auto reload mode
TR1 = 1; //open timer1;
ES = 0;
TI = 1;


打印开始:
printf("\n\n\rStart: \n\n");
UsbReset(); 软复位一下USB的寄存器
EA = 1; 开总中断
WriteSfr(UPCON, ReadSfr(UPCON) | CONEN); //使能USB上拉电阻

while(1); //OK,到这里就等待中断了
}


该主程序主要初始化用于print的串口,USB模块的配置,及主时钟的初始化。

使用特权

评论回复
9
David_ming|  楼主 | 2011-4-25 14:37 | 只看该作者
本帖最后由 David_ming 于 2011-4-25 14:45 编辑
 
EP0事件的解析过程。。。。。
void EP0Event()
{
}


USB中断函数:

void UsbInt(void) interrupt 15 using 1
{
static uint8_t counter = 0;
uint8_t intFlag;
intFlag = ReadSfr(UPCON); // Status in Power Control Register
printf("%3u:",(uint16_t)counter++);
if(intFlag & 0x0f)
{
if(intFlag & USUS)
{
WriteSfr(UPCON, (intFlag&0xf0) | USUS); 如果检测到总线挂起信号,则会到这里
printf("Suspend!\n");
}
else if(intFlag & URST)
{
WriteSfr(UPCON, (intFlag&0xf0) | URST); 如果检测到总线复位信号,则会到这里
printf("Reset!\n");
WriteSfr(UPCON, intFlag | URST);
UsbReset();
WriteSfr(UPCON, ReadSfr(UPCON) | CONEN);
}
else
{
WriteSfr(UPCON, (intFlag&0xf0) | URSM); 如果总线恢复(唤醒),那么会到这里
printf("Resume!\n");
}
}
else 从这里往下是非总线信号,即标准的USB请求信息
{
intFlag = ReadSfr(UI**);
if(intFlag & UTXD1)
{
WriteSfr(UI**, UTXD1); EP1发送完毕则会到这里
printf("EP1.\n");
}
else if(intFlag & URXD0)
{
WriteSfr(UI**, URXD0); EP0接收到一个包就到这里
printf("EP0RX->");
if(ReadSfr(RXCNT) != 0)
{
WriteSfr(EPINDEX, EP0); //must be delay sometimes
EP0Event();
}
else
{
printf("host ACK.\n");
}
}
else if(intFlag & UTXD0)
{
WriteSfr(UI**, UTXD0); EP0发送完一个包就到这里
printf("EP0TX.\n");
}
else
{
WriteSfr(UI**, 0xff); 防呆,全部清一下
}
}

}

使用特权

评论回复
10
David_ming|  楼主 | 2011-4-25 14:42 | 只看该作者
休息一下,改天接着写。。。。。。

使用特权

评论回复
11
David_ming|  楼主 | 2011-4-25 14:53 | 只看该作者
笙泉的 DFU 软件,只用这个软件 + 1颗84FL54即可进行开发,不用专用烧录工具

笙泉DFU.jpg (117.57 KB )

笙泉DFU.jpg

DFU.rar

37.88 KB

使用特权

评论回复
12
wangpe| | 2011-4-25 19:07 | 只看该作者
支持楼主一个

使用特权

评论回复
13
David_ming|  楼主 | 2011-5-3 12:27 | 只看该作者
WINXP下枚举过程,都是printf出来的


Start:
  0:Suspend!
  1:Reset!
  2:Suspend!
  3:Reset!
  4:EP0RX->Standard->GetDescriptor->device->H_max:64bytes->D_ret:8bytes[12 1 10 1 0 0 0 8 ]
  5:EP0RX->host ACK.
  6:Reset!
  7:EP0RX->Standard->setAddr.
  8:USB Address = 1.
  9:EP0RX->Standard->GetDescriptor->device->H_max:18bytes->D_ret:8bytes[12 1 10 1 0 0 0 8 ]
10:EP0 continue send->D_ret:8bytes[77 77 77 77 0 0 0 0 ]
11:EP0 continue send->D_ret:2bytes[0 1 ]
12:EP0RX->Standard->GetDescriptor->config->H_max:9bytes->D_ret:8bytes[9 2 22 0 1 1 0 a0 ]
13:EP0 continue send->D_ret:1bytes[32 ]
14:EP0RX->host ACK.
15:EP0RX->Standard->GetDescriptor->config->H_max:255bytes->D_ret:8bytes[9 2 22 0 1 1 0 a0 ]
16:EP0 continue send->D_ret:8bytes[32 9 4 0 0 1 3 1 ]
17:EP0 continue send->D_ret:8bytes[2 0 9 21 10 1 0 1 ]
18:EP0 continue send->D_ret:8bytes[22 34 0 7 5 81 3 8 ]
19:EP0 continue send->D_ret:2bytes[0 a ]
20:EP0RX->host ACK.
21:EP0 send over.
22:EP0RX->Standard->GetDescriptor->device->H_max:18bytes->D_ret:8bytes[12 1 10 1 0 0 0 8 ]
23:EP0 continue send->D_ret:8bytes[77 77 77 77 0 0 0 0 ]
24:EP0 continue send->D_ret:2bytes[0 1 ]
25:EP0RX->Standard->GetDescriptor->config->H_max:9bytes->D_ret:8bytes[9 2 22 0 1 1 0 a0 ]
26:EP0 continue send->D_ret:1bytes[32 ]
27:EP0RX->Standard->GetDescriptor->config->H_max:34bytes->D_ret:8bytes[9 2 22 0 1 1 0 a0 ]
28:EP0 continue send->D_ret:8bytes[32 9 4 0 0 1 3 1 ]
29:EP0 continue send->D_ret:8bytes[2 0 9 21 10 1 0 1 ]
30:EP0 continue send->D_ret:8bytes[22 34 0 7 5 81 3 8 ]
31:EP0 continue send->D_ret:2bytes[0 a ]
32:EP0RX->Standard->setConfig->Enable.
33:EP0 send over.
34:EP0RX->ClassReq->SetIdle=0.
35:EP0 send over.
36:EP0RX->Standard->GetDescriptor->HIDRep->H_max:116bytes->D_ret:8bytes[5 1 9 2 a1 1 9 1 ]
37:EP0 continue send->D_ret:8bytes[a1 0 5 9 19 1 29 3 ]
38:EP0 continue send->D_ret:8bytes[15 0 25 1 95 3 75 1 ]
39:EP0 continue send->D_ret:8bytes[81 2 95 1 75 5 81 3 ]
40:EP0 continue send->D_ret:8bytes[5 1 9 30 9 31 9 38 ]
41:EP0 continue send->D_ret:8bytes[15 81 25 7f 75 8 95 3 ]
42:EP0 continue send->D_ret:4bytes[81 6 c0 c0 ]
43:EP0RX->host ACK.
44:EP0 send over.

往后都是发送的报告了

D_ret:4bytes[0 1 1 0 ]
45:EP1.
D_ret:4bytes[0 1 1 0 ]
46:EP1.
D_ret:4bytes[0 1 1 0 ]
47:EP1.
D_ret:4bytes[0 1 1 0 ]
48:EP1.
D_ret:4bytes[0 1 1 0 ]
49:EP1.
D_ret:4bytes[0 1 1 0 ]

使用特权

评论回复
14
hqgboy| | 2011-5-19 13:45 | 只看该作者
顶。。。。。。

使用特权

评论回复
15
wkman| | 2011-5-20 16:38 | 只看该作者
84FL没搞通。。先放了,唉

使用特权

评论回复
16
rain_mcu| | 2011-5-20 17:06 | 只看该作者
STC原厂-笙泉科技有限公司
笙泉是一家专业做8051 IC 设计的公司,成立于1999年。总部在台湾,有一个80多人

的设计团队,在香港及深圳都有分公司,深圳分公司有20余人。笙泉8051的芯片2003

年推出,在2008年之前笙泉专注于海外市场,主要是韩国,俄罗斯,欧洲等国家。

2008年前笙泉国内市场主要是由STC来做推广。STC,2004年第三季度与笙泉有签一个

代理协议,STC从笙泉拿芯片,打STC的MARK,所以外界不知道STC只是一个代理商,两

家的协议关系已于2008年12月底终止合作关系.终止合作关系以后笙泉自己做,打自己

的牌子MEGAWIN ,并且停止给STC供货。路必康是08年12月跟笙泉签下的代理协议,是

大陆和香港唯一总代理。MEGAWIN 完全替换STC系列,需要样品,请联系:
深圳路必康电子有限公司  
联系人:刘R
电话:075583452501  13902456340  
Q Q:915351523
公司地址:深圳市深南大道6021号喜年中心20楼
http://www.road-well.com/

笙泉科技(深圳)有限公司:
地址 : 深圳市福田区车公庙泰然八路水松大厦10层A单元
http://www.megawin.com.tw/

使用特权

评论回复
17
David_ming|  楼主 | 2011-5-21 10:14 | 只看该作者
15# wkman

说说卡在哪里了,没准能帮到你~

使用特权

评论回复
18
lixupengarm| | 2011-5-22 18:51 | 只看该作者
mark!!!!

使用特权

评论回复
19
zhaor| | 2011-8-9 11:50 | 只看该作者
mark!!!!!!!

使用特权

评论回复
20
栩栩如生| | 2011-8-10 10:26 | 只看该作者
好东东

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名::“哥洒脱如此”

22

主题

762

帖子

2

粉丝