关注晕哥论坛好久,刚看完新世界结局完美!希望早日战胜疫情迎来我们的新世界!
假期太长了,闲着没事把年前做的CH552的51板子移植了cmsis dap v2,测试下载速度有20k,还行。
当时做这板子主要震惊于51还能跑USB而且不需要晶振,还支持触摸按键,而且1块钱!
明天上传程序,有ch552的可以试试,再一同改进一下!
离线
DAP-20200212-删除打印.7z
我只实现了SWD功能!
Program Size: data=56.0 xdata=1009 code=7828
代码空间应还有,还可以加东西,后期可能加上串口!
修改自keil安装目录下的 LPC-Link-II V2,驱动也在该工程文件夹里!
最近编辑记录 ljbfly (2020-02-21 07:10:00)
离线
不太懂,需要手动装驱动,我只是代码搬运工,哈哈,大家一起改
找个可以自动装驱动的DAP-link看一下枚举过程,改一下枚举就行了吧
最近编辑记录 ljbfly (2020-02-21 11:56:54)
离线
@metro 厉害,USB我不太懂,弄这个小板子就是想学学USB
@metro有没有学USB的相关资料,今天晚上加上去试试
最近编辑记录 ljbfly (2020-02-21 12:26:31)
离线
@metro 求助
#if (WINUSB == 1)
UINT8C DevDesc[] =
{
0x12, 0x01, 0x10, 0x02, 0x00, 0x00, 0x00, THIS_ENDP0_SIZE,
0x28, 0x0D, 0x04, 0x02, 0x00, 0x01, 0x01, 0x02,
0x03, 0x01
};
UINT8C CfgDesc[] =
{
0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0xfa, //配置描述符
0x09, 0x04, 0x00, 0x00, 0x02, 0xff, 0x00, 0x00, 0x04, //接口描述符
0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00, //端点描述符
0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00
};
#else
#Err no USB interface define
#endif
/*字符串描述符 略*/
// 语言描述符
UINT8C MyLangDescr[] = {0x04, 0x03, 0x09, 0x04};
// 厂家信息: KEI - Tools By ARM
UINT8C MyManuInfo[] = {0x28, 0x03, 0x4B, 0x00, 0x45, 0x00, 0x49, 0x00, 0x4C, 0x00, 0x20, 0x00, 0x2D, 0x00, 0x20, 0x00, 0x54, 0x00, 0x6F, 0x00, 0x6F, 0x00, 0x6c, 0x00, 0x73, 0x00, 0x20, 0x00, 0x42, 0x00, 0x79, 0x00, 0x20, 0x00, 0x41, 0x00, 0x52, 0x00, 0x4D, 0x00};
// 产品信息: DAP-Link-II
UINT8C MyProdInfo[] = {0x18, 0x03, 0x44, 0x00, 0x41, 0x00, 0x50, 0x00, 0x2D, 0x00, 0x4C, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x6B, 0x00, 0x2D, 0x00, 0x49, 0x00, 0x49, 0x00};
// 序列号: 0001A0000000
UINT8C MySerNumber[] = {0x1A, 0x03, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x31, 0x00, 0x41, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00, 0x30, 0x00};
// 接口: CMSIS-DAP
UINT8C MyInterface[] = {0x14, 0x03, 0x43, 0x00, 0x4d, 0x00, 0x53, 0x00, 0x49, 0x00, 0x53, 0x00, 0x2d, 0x00, 0x44, 0x00, 0x41, 0x00, 0x50, 0x00};
UINT8C USB_BOSDescriptor[0x21] =
{
0x05, 0x0F, 0x21, 0x00, 0x01, 0x1C, 0x10, 0x05, 0x00, 0xDF, 0x60, 0xDD, 0xD8, 0x89, 0x45, 0xC7,
0x4C, 0x9C, 0xD2, 0x65, 0x9D, 0x9E, 0x64, 0x8A, 0x9F, 0x00, 0x00, 0x03, 0x06, 0xAA, 0x00, 0x20,
0x00
};
UINT8C WINUSB_Descriptor[0xAA] =
{
0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0xAA, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00,
0xA0, 0x00, 0x14, 0x00, 0x03, 0x00, 0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x00, 0x04, 0x00, 0x07, 0x00, 0x2A, 0x00, 0x44, 0x00,
0x65, 0x00, 0x76, 0x00, 0x69, 0x00, 0x63, 0x00, 0x65, 0x00, 0x49, 0x00, 0x6E, 0x00, 0x74, 0x00,
0x65, 0x00, 0x72, 0x00, 0x66, 0x00, 0x61, 0x00, 0x63, 0x00, 0x65, 0x00, 0x47, 0x00, 0x55, 0x00,
0x49, 0x00, 0x44, 0x00, 0x73, 0x00, 0x00, 0x00, 0x50, 0x00, 0x7B, 0x00, 0x43, 0x00, 0x44, 0x00,
0x42, 0x00, 0x33, 0x00, 0x42, 0x00, 0x35, 0x00, 0x41, 0x00, 0x44, 0x00, 0x2D, 0x00, 0x32, 0x00,
0x39, 0x00, 0x33, 0x00, 0x42, 0x00, 0x2D, 0x00, 0x34, 0x00, 0x36, 0x00, 0x36, 0x00, 0x33, 0x00,
0x2D, 0x00, 0x41, 0x00, 0x41, 0x00, 0x33, 0x00, 0x36, 0x00, 0x2D, 0x00, 0x31, 0x00, 0x41, 0x00,
0x41, 0x00, 0x45, 0x00, 0x34, 0x00, 0x36, 0x00, 0x34, 0x00, 0x36, 0x00, 0x33, 0x00, 0x37, 0x00,
0x37, 0x00, 0x36, 0x00, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x00
};
void DeviceInterrupt(void) interrupt INT_NO_USB using 1 //USB中断服务程序,使用寄存器组1
{
UINT8 len;
if (UIF_TRANSFER) //USB传输完成标志
{
switch (USB_INT_ST & (MASK_UIS_TOKEN | MASK_UIS_ENDP))
{
case UIS_TOKEN_IN | 2: //endpoint 2# 端点批量上传
UEP2_T_LEN = 0; //预使用发送长度一定要清空
Endp2Busy = 0;
UEP2_CTRL = UEP2_CTRL & ~MASK_UEP_T_RES | UEP_T_RES_NAK; //默认应答NAK
break;
case UIS_TOKEN_OUT | 2: //endpoint 2# 端点批量下传
if (U_TOG_OK) // 不同步的数据包将丢弃
{
len = USB_RX_LEN;
memcpy(Ep2DataO[Ep2Oi++], Ep2BufferO, len); //待优化
if (Ep2Oi >= DAP_PACKET_COUNT)
Ep2Oi = 0;
}
break;
case UIS_TOKEN_SETUP | 0: //SETUP事务
len = USB_RX_LEN;
if (len == (sizeof(USB_SETUP_REQ)))
{
SetupLen = UsbSetupBuf->wLengthL;
len = 0; // 默认为成功并且上传0长度
SetupReq = UsbSetupBuf->bRequest;
if ((UsbSetupBuf->bRequestType & USB_REQ_TYP_MASK) != USB_REQ_TYP_STANDARD) /*HID类命令*/
{
if ((UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_DEVICE)
{
switch (SetupReq)
{
case 0x20: //GetReport
if (UsbSetupBuf->wIndexL == 0x07)
{
pDescr = WINUSB_Descriptor; //把设备描述符送到要发送的缓冲区
len = sizeof(WINUSB_Descriptor);
}
break;
default:
len = 0xFF; /*命令不支持*/
break;
}
}
if (SetupLen > len)
{
SetupLen = len; //限制总长度
}
len = SetupLen >= THIS_ENDP0_SIZE ? THIS_ENDP0_SIZE : SetupLen; //本次传输长度
memcpy(Ep0Buffer, pDescr, len); //加载上传数据
SetupLen -= len;
pDescr += len;
}
else //标准请求
{
switch (SetupReq) //请求码
{
case USB_GET_DESCRIPTOR:
switch (UsbSetupBuf->wValueH)
{
case 1: //设备描述符
pDescr = DevDesc; //把设备描述符送到要发送的缓冲区
len = sizeof(DevDesc);
break;
case 2: //配置描述符
pDescr = CfgDesc; //把设备描述符送到要发送的缓冲区
len = sizeof(CfgDesc);
break;
case 3: // 字符串描述符
switch (UsbSetupBuf->wValueL)
{
case 0:
pDescr = (PUINT8)(&MyLangDescr[0]);
len = sizeof(MyLangDescr);
break;
case 1:
pDescr = (PUINT8)(&MyManuInfo[0]);
len = sizeof(MyManuInfo);
break;
case 2:
pDescr = (PUINT8)(&MyProdInfo[0]);
len = sizeof(MyProdInfo);
break;
case 3:
pDescr = (PUINT8)(&MySerNumber[0]);
len = sizeof(MySerNumber);
break;
case 4:
pDescr = (PUINT8)(&MyInterface[0]);
len = sizeof(MyInterface);
break;
default:
len = 0xFF; // 不支持的字符串描述符
break;
}
break;
case 15:
pDescr = (PUINT8)(&USB_BOSDescriptor[0]);
len = sizeof(USB_BOSDescriptor);
break;
default:
len = 0xff; //不支持的命令或者出错
break;
}
if (SetupLen > len)
{
SetupLen = len; //限制总长度
}
len = SetupLen >= THIS_ENDP0_SIZE ? THIS_ENDP0_SIZE : SetupLen; //本次传输长度
memcpy(Ep0Buffer, pDescr, len); //加载上传数据
SetupLen -= len;
pDescr += len;
break;
case USB_SET_ADDRESS:
SetupLen = UsbSetupBuf->wValueL; //暂存USB设备地址
break;
case USB_GET_CONFIGURATION:
Ep0Buffer[0] = UsbConfig;
if (SetupLen >= 1)
{
len = 1;
}
break;
case USB_SET_CONFIGURATION:
UsbConfig = UsbSetupBuf->wValueL;
if (UsbConfig)
{
Ready = 1; //set config命令一般代表usb枚举完成的标志
}
break;
case 0x0A:
break;
case USB_CLEAR_FEATURE: //Clear Feature
if ((UsbSetupBuf->bRequestType & USB_REQ_RECIP_MASK) == USB_REQ_RECIP_ENDP) // 端点
{
switch (UsbSetupBuf->wIndexL)
{
case 0x82:
UEP2_CTRL = UEP2_CTRL & ~(bUEP_T_TOG | MASK_UEP_T_RES) | UEP_T_RES_NAK;
break;
case 0x81:
UEP1_CTRL = UEP1_CTRL & ~(bUEP_T_TOG | MASK_UEP_T_RES) | UEP_T_RES_NAK;
break;
case 0x02:
UEP2_CTRL = UEP2_CTRL & ~(bUEP_R_TOG | MASK_UEP_R_RES) | UEP_R_RES_ACK;
break;
default:
len = 0xFF; // 不支持的端点
break;
}
}
else
{
len = 0xFF; // 不是端点不支持
}
break;
case USB_SET_FEATURE: /* Set Feature */
if ((UsbSetupBuf->bRequestType & 0x1F) == 0x00) /* 设置设备 */
{
if ((((UINT16)UsbSetupBuf->wValueH << 8) | UsbSetupBuf->wValueL) == 0x01)
{
if (CfgDesc[7] & 0x20)
{
/* 设置唤醒使能标志 */
}
else
{
len = 0xFF; /* 操作失败 */
}
}
else
{
len = 0xFF; /* 操作失败 */
}
}
else if ((UsbSetupBuf->bRequestType & 0x1F) == 0x02) /* 设置端点 */
{
if ((((UINT16)UsbSetupBuf->wValueH << 8) | UsbSetupBuf->wValueL) == 0x00)
{
switch (((UINT16)UsbSetupBuf->wIndexH << 8) | UsbSetupBuf->wIndexL)
{
case 0x82:
UEP2_CTRL = UEP2_CTRL & (~bUEP_T_TOG) | UEP_T_RES_STALL; /* 设置端点2 IN STALL */
break;
case 0x02:
UEP2_CTRL = UEP2_CTRL & (~bUEP_R_TOG) | UEP_R_RES_STALL; /* 设置端点2 OUT Stall */
break;
case 0x81:
UEP1_CTRL = UEP1_CTRL & (~bUEP_T_TOG) | UEP_T_RES_STALL; /* 设置端点1 IN STALL */
break;
default:
len = 0xFF; /* 操作失败 */
break;
}
}
else
{
len = 0xFF; /* 操作失败 */
}
}
else
{
len = 0xFF; /* 操作失败 */
}
break;
case USB_GET_STATUS:
Ep0Buffer[0] = 0x00;
Ep0Buffer[1] = 0x00;
if (SetupLen >= 2)
{
len = 2;
}
else
{
len = SetupLen;
}
break;
default:
len = 0xff; //操作失败
break;
}
}
}
else
{
len = 0xff; //包长度错误
}
if (len == 0xff)
{
SetupReq = 0xFF;
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_STALL | UEP_T_RES_STALL; //STALL
}
else if (len <= THIS_ENDP0_SIZE) //上传数据或者状态阶段返回0长度包
{
UEP0_T_LEN = len;
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK; //默认数据包是DATA1,返回应答ACK
}
else
{
UEP0_T_LEN = 0; //虽然尚未到状态阶段,但是提前预置上传0长度数据包以防主机提前进入状态阶段
UEP0_CTRL = bUEP_R_TOG | bUEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK; //默认数据包是DATA1,返回应答ACK
}
break;
case UIS_TOKEN_IN | 0: //endpoint0 IN
switch (SetupReq)
{
case USB_GET_DESCRIPTOR:
case 0x20:
len = SetupLen >= THIS_ENDP0_SIZE ? THIS_ENDP0_SIZE : SetupLen; //本次传输长度
memcpy(Ep0Buffer, pDescr, len); //加载上传数据
SetupLen -= len;
pDescr += len;
UEP0_T_LEN = len;
UEP0_CTRL ^= bUEP_T_TOG; //同步标志位翻转
break;
case USB_SET_ADDRESS:
USB_DEV_AD = USB_DEV_AD & bUDA_GP_BIT | SetupLen;
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
break;
default:
UEP0_T_LEN = 0; //状态阶段完成中断或者是强制上传0长度数据包结束控制传输
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
break;
}
break;
case UIS_TOKEN_OUT | 0: // endpoint0 OUT
len = USB_RX_LEN;
if (SetupReq == 0x09)
{
if (Ep0Buffer[0])
{
}
else if (Ep0Buffer[0] == 0)
{
}
}
UEP0_CTRL ^= bUEP_R_TOG; //同步标志位翻转
break;
default:
break;
}
UIF_TRANSFER = 0; //写0清空中断
}
if (UIF_BUS_RST) //设备模式USB总线复位中断
{
UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
UEP1_CTRL = bUEP_AUTO_TOG | UEP_R_RES_ACK;
UEP2_CTRL = bUEP_AUTO_TOG | UEP_R_RES_ACK | UEP_T_RES_NAK;
USB_DEV_AD = 0x00;
UIF_SUSPEND = 0;
UIF_TRANSFER = 0;
Endp2Busy = 0;
UIF_BUS_RST = 0; //清中断标志
}
if (UIF_SUSPEND) //USB总线挂起/唤醒完成
{
UIF_SUSPEND = 0;
if (USB_MIS_ST & bUMS_SUSPEND) //挂起
{
}
}
else
{
//意外的中断,不可能发生的情况
USB_INT_FG = 0xFF; //清中断标志
}
}
代码应该没有问题呀,咋提示没有兼容驱动
离线
@metro 厉害,驱动好了,可是Keil识别不到是那的问题呢!是字符描述吗
离线
有可能是,你按照官方的VID/PID和描述符改改,我这边是可以正常识别的。
这个是程序问题,获取描述长度大于255了,我只看了低字节,导致回应错误不能识别!
再次感谢@metro大神!
离线
感谢分享~不过CH552的IO默认是5V的,连接到3.3V的目标芯片的IO上会不会有点风险
STM32的调试口写的是兼容5V的
读了一下楼主的代码,有几个疑问想请教一下楼主:
1. SW_DP.c中,原版代码是有PIN_SWDIO_OUT_ENABLE这一个切换SWDIO的功能的宏的,我看在楼主的代码里面并没有使用,而是直接将这个IO设置为1。请问IO在PP模式下可以直接这样读取到SWDIO的值吗?
2. DAP.c的DAP_SWJ_Clock函数中,原版代码是有设置快速和慢速的区分,而楼主代码里面则是强制设置为快速,并取消掉所有的IO延时。请问这样在实际使用中是否有发现问题?
1.能读到,这个可能和GPIO的结构有关
2.感觉51速度慢,就没有加延时,强制快速就行了
今天加了USB转串口CDC功能,代码中肯定还有需要改进的地方,我只是简单的实现一下功能!
设备管理器为什么只显示USB 串行设备呢,不能改名字吗?@metro
离线
这个DAP Link速度有点慢
可以优化,参见 metro 的帖子
我的板子现在的程序, keil下载FLASH不擦除、不校验,应该是30K左右,有时间用汇编优化试试
https://whycan.cn/viewtopic.php?id=3766
最近编辑记录 ljbfly (2020-03-04 10:33:48)
离线
离线
感谢楼主的分享,下了DAP-20200223+CDC.7z这个代码,编译运行可以找到CMSIS-DAP v2和DAPLink-CDCExt两个设备,不过DAPLink-CDCExt一直提示“这个设备没有兼容驱动程序。”,手动指定位置安装CMSIS-DAP_CDC_Driver.inf还是驱动不了,系统是win8.1,已经禁用过签名了,还请指点一下,是这个代码需要专用的inf驱动文件吗?
用DAP-20200302.7z那版试试,win10能用
离线
大侠在不,有没有DAP的驱动,我安装KEIL后,在 LPC-Link-II V2找不到驱动,WIN7下使用.
离线