#include
#include "INTRINS.h"
#define OP_CMD 1 // 命令操作码
#define OP_DATA 0 // 数据操作码
#define DELAY_TIMES 8 // 延时2微秒
#define DELAY_CNT_NUMS 2*DELAY_TIMES // 延时2微秒所需的时钟周期数(对于22.1184MHz晶振,每个微秒包含22.1184个时钟周期)
//#define MY_USB_VENDOR_ID 0x4348 // USB设备制造商标识
//#define MY_USB_PRODUCT_ID 0x5537 // USB设备产品标识
//sbit USB_CS = P1^3; //cs接地 内部晶振24.5M 倍频49M
sbit USB_INT = P0^0;
sbit USB_A0 = P1^4;
sbit USB_WR = P1^6;
sbit USB_RD = P1^5;
//sfr USB_DATA = 0x84;
#define get_usb P2
#define set_usb(dat1) P2=dat1
//#define set_usb(dat1) P2|=(dat1>>1);P17=((dat1 & 0x01)==1)
#define delay_ns _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_()
const UINT8C MyDevDescr[] = { 0x12, 0x01, 0x10, 0x01,
0xFF, 0x80, 0x37, 0x08,
0x48, 0x43, 0x37, 0x55, // 厂商ID和产品ID
0x00, 0x01, 0x01, 0x02,
0x00, 0x01 };
// 配置描述符
const UINT8C MyCfgDescr[] = { 0x09, 0x02, 0x27, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32,
0x09, 0x04, 0x00, 0x00, 0x03, 0xFF, 0x80, 0x37, 0x00,
0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00,
0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00,
0x07, 0x05, 0x81, 0x03, 0x08, 0x00, 0x00 };
// 语言描述符
const UINT8C MyLangDescr[] = { 0x04, 0x03, 0x09, 0x04 };
// 厂家信息
const UINT8C MyManuInfo[] = { 0x0E, 0x03, 'w', 0, 'c', 0, 'h', 0, '.', 0, 'c', 0, 'n', 0 };
// 产品信息
const UINT8C MyProdInfo[] = { 0x0C, 0x03, 'C', 0, 'H', 0, '3', 0, '7', 0, '4', 0 };
UINT8 UsbConfig = 0;
void Delay2us( )
{
INT8U i;
i = (INT8U)DELAY_CNT_NUMS;
while (--i);
}
void mDelaymS( INT8U ms )
{
INT8U j;
while ( ms -- ) {
j=250;
do
{
Delay2us();
Delay2us();
//Delay2us();
//Delay2us();
}
while ( j -- );
}
}
void CH375_WR_CMD_PORT(INT8U dat)
{
USB_WR = 1;
USB_RD = 1;
set_usb(dat);
delay_ns;
USB_A0 = OP_CMD;
// 准备写命令
_nop_();
//USB_CS = 0;
USB_WR = 0;
USB_WR = 0;
USB_WR = 0;
USB_WR = 0;
USB_WR = 1;
//USB_CS = 1; // 结束写命令(USB_WR信号的有效时间不能超过10us)
USB_A0 = 0;
P2=0xff;
//P2|=0x7f;
//P1|=0x80;
}
void CH375_WR_DAT_PORT(INT8U dat)
{
USB_WR = 1;
USB_RD = 1;
set_usb(dat);
delay_ns;
USB_A0 = OP_DATA; // 准备写数据
_nop_();
//USB_CS = 0;
USB_WR = 0;
USB_WR = 0; // 开始写数据
USB_WR = 0;
USB_WR = 0;
USB_WR = 1; // 结束写命令(USB_WR信号的有效时间不能超过10us)
//USB_CS = 1;
USB_A0 = 0;
P2=0xff;
//P2|=0x7f;
//P1|=0x80;
}
INT8U CH375_RD_DAT_PORT(void)
{
INT8U nData;
USB_WR = 1;
USB_RD = 1;
delay_ns;
//delay_ns; // 将USB_DATA(P4口)配置为数字输入
USB_A0 = OP_DATA;
//USB_CS = 0; // 准备读数据
_nop_();
USB_RD = 0;
USB_RD = 0;
USB_RD = 0;
nData = get_usb;
USB_RD = 1; // 结束读命令(USB_RD信号的有效时间不能超过10us)
//USB_CS = 1;
USB_A0 = 0;
return nData; // 返回读取的数据
}
INT8U Read374Byte(INT8U mAddr )
{
CH375_WR_CMD_PORT( mAddr );
return( CH375_RD_DAT_PORT());
}
void Write374Byte( INT8U mAddr, INT8U mData )
{
CH375_WR_CMD_PORT( mAddr );
CH375_WR_DAT_PORT( mData );
}
void Read374Block( INT8U mAddr, INT8U mLen, INT8U * mBuf )
{
CH375_WR_CMD_PORT( mAddr );
while ( mLen -- ) *mBuf++ = CH375_RD_DAT_PORT( );
}
void Write374Block( INT8U mAddr, INT8U mLen, INT8U * mBuf )
{
INT8U dat,k;
k=0;
CH375_WR_CMD_PORT( mAddr );
while ( mLen -- )
{
dat= *mBuf++;
//dat= up[k++];
CH375_WR_DAT_PORT(dat);
}
}
void write_buf1to374()
{
INT8U dat,k,mLen;
Write374Byte( REG_USB_LENGTH, 64 );
//Write374Block( RAM_ENDP2_TRAN, 64, &up[0]);
k=0;
mLen=64;
CH375_WR_CMD_PORT( RAM_ENDP2_TRAN );
while ( mLen -- )
{
//dat= *mBuf++;
dat= up[k++];
CH375_WR_DAT_PORT(dat);
}
// Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_RECV_TOG );
Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) );
}
void write_buf2to374()
{
INT8U dat,k,mLen;
Write374Byte( REG_USB_LENGTH, 64 );
//Write374Block( RAM_ENDP2_TRAN, 64, &up[0]);
k=0;
mLen=64;
CH375_WR_CMD_PORT( RAM_ENDP2_TRAN );
while ( mLen -- )
{
//dat= *mBuf++;
dat= up1[k++];
CH375_WR_DAT_PORT(dat);
}
//Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_RECV_TOG );
Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) );
}
void CH375_Init(void)
{
//INT8U m;
//USB_CS=0;
mDelaymS(100);
//Write374Byte( REG_SYS_CTRL, BIT_CTRL_RESET_NOW );
//mDelaymS(50);
//Write374Byte( REG_SYS_CTRL, 0 );
//m= Read374Byte(REG_USB_SETUP);
//Write374Byte( REG_USB_SETUP, 0x03 );
//m= Read374Byte(REG_USB_SETUP);
//Write374Byte( REG_USB_SETUP, 0x00 );
Write374Byte( REG_USB_ADDR, 0x00 );
//m= Read374Byte(REG_USB_ADDR);
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); //清端点0控制寄存器
Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( 0 ) );
Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( 0 ) );
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG ); // 清所有中断标志
Write374Byte( REG_INTER_EN, BIT_IE_TRANSFER | BIT_IE_BUS_RESET | BIT_IE_USB_SUSPEND ); // 允许使能传输完成中断和USB总线复位中断以及USB总线挂起中断,芯片唤醒完成中断
//m= Read374Byte(REG_INTER_EN);
Write374Byte( REG_SYS_CTRL, BIT_CTRL_OE_POLAR ); // 对于CH374T或者UEN引脚悬空的CH374S必须置BIT_CTRL_OE_POLAR为1
Write374Byte( REG_USB_SETUP, BIT_SETP_TRANS_EN | BIT_SETP_PULLUP_EN ); // 启动USB设备
//m= Read374Byte(REG_USB_SETUP);
//m= Read374Byte(REG_USB_SETUP);
//Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_RECV_TOG );
}
void CH375_process()
{
UINT8 s, l;
static UINT8 SetupReq, SetupLen;
static PUINT8 pDescr;
//static UINT8 SetupReq, SetupLen;
//static PUINT8 pDescr;
if (USB_INT)
return;
s = Read374Byte( REG_INTER_FLAG );
if ( s & BIT_IF_BUS_RESET )
{ // USB总线复位
// Write374Byte( REG_USB_SETUP, 0x00 );
Write374Byte( REG_USB_ADDR, 0x00 ); // 清USB设备地址
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) );
Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( 0 ) );
Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( 0 ) );
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_BUS_RESET ); // 清中断标志
}
else if ( s & BIT_IF_TRANSFER )
{ // USB传输完成
s = Read374Byte( REG_USB_STATUS );
//Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); // 清中断标志
switch( s & BIT_STAT_PID_ENDP ) { // USB设备中断状态
case USB_INT_EP2_OUT: { // 批量端点下传成功
//UINT8 buf[64];
if ( s & BIT_STAT_TOG_MATCH ) // ljj@wch.cn
{ // 仅同步包
l = Read374Byte( REG_USB_LENGTH );
Read374Block( RAM_ENDP2_RECV, l, &down[0] );
if (down[l-1]==calc_sum(&down[0]))
pc_process();
Write374Byte( REG_USB_ENDP2, Read374Byte( REG_USB_ENDP2 )^ BIT_EP2_RECV_TOG );
//for ( s = 0; s < l; s ++ ) buf[s] ^= 0xFF; // 数据取反由计算机验证
//Write374Block( RAM_ENDP2_TRAN, l, buf ); // 演示回传
//Write374Byte( REG_USB_LENGTH, l );
//Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_ACK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_RECV_TOG );
// Write374Index( REG_USB_ENDP2 ); // 对于并口连接可以用本行及下面一行代替上一行的程序,减少写一次index的时间,提高效率
// Write374Data( M_SET_EP2_TRAN_ACK( Read374Data0( ) ) ^ BIT_EP2_RECV_TOG );
}
break;
}
case USB_INT_EP2_IN: { // 批量端点上传成功,未处理
if (!bfree)
bfree=1;
Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_TRAN_TOG );
//Write374Index( REG_USB_ENDP2 ); // 对于并口连接可以用本行及下面一行代替上一行的程序,减少写一次index的时间,提高效率
//Write374Data( M_SET_EP2_TRAN_NAK( Read374Data0( ) ) ^ BIT_EP2_TRAN_TOG );
break;
}
case USB_INT_EP1_IN: { // 中断端点上传成功,未处理
Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( Read374Byte( REG_USB_ENDP1 ) ) ^ BIT_EP1_TRAN_TOG );
break;
}
case USB_INT_EP0_SETUP: { // 控制传输
USB_SETUP_REQ SetupReqBuf;
l = Read374Byte( REG_USB_LENGTH );
if ( l == sizeof( USB_SETUP_REQ ) ) {
Read374Block( RAM_ENDP0_RECV, l, (PUINT8)&SetupReqBuf );
SetupLen = SetupReqBuf.wLengthL;
if ( SetupReqBuf.wLengthH || SetupLen > 0x7F ) SetupLen = 0x7F; // 限制总长度
l = 0; // 默认为成功并且上传0长度
if ( ( SetupReqBuf.bType & DEF_USB_REQ_TYPE ) != DEF_USB_REQ_STAND ) {
l = 0xFF; // 操作失败
}
else { // 标准请求
SetupReq = SetupReqBuf.bReq; // 请求码
switch( SetupReq ) {
case DEF_USB_GET_DESCR:
switch( SetupReqBuf.wValueH ) {
case 1:
pDescr = (PUINT8)( &MyDevDescr[0] );
l = sizeof( MyDevDescr );
break;
case 2:
pDescr = (PUINT8)( &MyCfgDescr[0] );
l = sizeof( MyCfgDescr );
break;
case 3:
switch( SetupReqBuf.wValueL ) {
case 1:
pDescr = (PUINT8)( &MyManuInfo[0] );
l = sizeof( MyManuInfo );
break;
case 2:
pDescr = (PUINT8)( &MyProdInfo[0] );
l = sizeof( MyProdInfo );
break;
case 0:
pDescr = (PUINT8)( &MyLangDescr[0] );
l = sizeof( MyLangDescr );
break;
default:
l = 0xFF; // 操作失败
break;
}
break;
default:
l = 0xFF; // 操作失败
break;
}
if ( SetupLen > l ) SetupLen = l; // 限制总长度
l = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen; // 本次传输长度
Write374Block( RAM_ENDP0_TRAN, l, pDescr );
SetupLen -= l;
pDescr += l;
break;
case DEF_USB_SET_ADDRESS:
SetupLen = SetupReqBuf.wValueL; // 暂存USB设备地址
break;
case DEF_USB_GET_CONFIG:
Write374Byte( RAM_ENDP0_TRAN, UsbConfig );
if ( SetupLen >= 1 ) l = 1;
break;
case DEF_USB_SET_CONFIG:
UsbConfig = SetupReqBuf.wValueL;
break;
case DEF_USB_CLR_FEATURE:
if ( ( SetupReqBuf.bType & 0x1F ) == 0x02 ) { // 不是端点不支持
switch( SetupReqBuf.wIndexL ) {
case 0x82:
Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) );
break;
case 0x02:
Write374Byte( REG_USB_ENDP2, M_SET_EP2_RECV_ACK( Read374Byte( REG_USB_ENDP2 ) ) );
break;
case 0x81:
Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( Read374Byte( REG_USB_ENDP1 ) ) );
break;
case 0x01:
Write374Byte( REG_USB_ENDP1, M_SET_EP1_RECV_ACK( Read374Byte( REG_USB_ENDP1 ) ) );
break;
default:
l = 0xFF; // 操作失败
break;
}
}
else l = 0xFF; // 操作失败
break;
case DEF_USB_GET_INTERF:
Write374Byte( RAM_ENDP0_TRAN, 0 );
if ( SetupLen >= 1 ) l = 1;
break;
case DEF_USB_GET_STATUS:
Write374Byte( RAM_ENDP0_TRAN, 0 );
Write374Byte( RAM_ENDP0_TRAN + 1, 0 );
if ( SetupLen >= 2 ) l = 2;
else l = SetupLen;
break;
default:
l = 0xFF; // 操作失败
break;
}
}
}
else l = 0xFF; // 操作失败
if ( l == 0xFF ) { // 操作失败
Write374Byte( REG_USB_ENDP0, M_SET_EP0_RECV_STA( M_SET_EP0_TRAN_STA( 0 ) ) ); // STALL
}
else if ( l <= RAM_ENDP0_SIZE ) { // 上传数据
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ), l ) | BIT_EP0_TRAN_TOG ); // DATA1
}
else { // 下传数据或其它
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ) ) | BIT_EP0_RECV_TOG ); // DATA1
}
break;
}
case USB_INT_EP0_IN: {
switch( SetupReq ) {
case DEF_USB_GET_DESCR:
l = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen; // 本次传输长度
Write374Block( RAM_ENDP0_TRAN, l, pDescr );
SetupLen -= l;
pDescr += l;
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( Read374Byte( REG_USB_ENDP0 ), l ) ^ BIT_EP0_TRAN_TOG );
break;
case DEF_USB_SET_ADDRESS:
Write374Byte( REG_USB_ADDR, SetupLen );
default:
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); // 结束
break;
}
break;
}
case USB_INT_EP0_OUT: {
switch( SetupReq ) {
// case download:
// get_data;
// break;
case DEF_USB_GET_DESCR:
default:
Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); // 结束
break;
}
break;
}
default: {
break;
}
}
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER );
}
else if ( s & BIT_IF_USB_SUSPEND ) { // USB总线挂起
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_USB_SUSPEND ); // 清中断标志
Write374Byte( REG_SYS_CTRL, Read374Byte( REG_SYS_CTRL ) | BIT_CTRL_OSCIL_OFF ); // 时钟振荡器停止振荡,进入睡眠状态
}
else if ( s & BIT_IF_WAKE_UP ) { // 芯片唤醒完成
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_WAKE_UP ); // 清中断标志
}
else { // 意外的中断,不可能发生的情况,除了硬件损坏
Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG ); // 清中断标志
}
}
上一篇:C8051F020 AD转换和USB通信
下一篇:AT89C52控制温度传感器DS18B20并在LM016L_LCD上显示
推荐阅读最新更新时间:2024-03-16 15:43
设计资源 培训 开发板 精华推荐
- TI有奖创意征集,CC3200开发套件等100份礼品等你来
- 已结束|ADI•世健工业嘉年华——工业应用云会展
- ADI有奖下载活动之2——太阳能光伏发电解决方案
- TI带你一起解剖共享单车智能锁!看视频涨知识赢好礼喽!
- 观看TI IOT解决方案研讨会 答题即可赢取更多精美好礼!
- 有奖直播:人机互动介面和机器视觉应用上的最佳助手--瑞萨电子 RZ/G, RZ/A 和 RZ/V SoC系列
- 【芯币兑换】活动一:用社区芯币兑换51开发板PCB板!
- 有奖国产芯直播:先楫800MHz RISC-V MCU高能秀,岂止控4只伺服电机,干货多多
- Intel最新物联网解决方案,抢先阅读,下载有惊喜
- Microchip最新SAM 以及 PIC32单片机软件开发平台-- MPLAB® Harmony V3介绍 ”