您尚未登录。

楼主 #1 2020-02-20 22:32:38

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 22

CH552 版 CMSIS-DAP v2

关注晕哥论坛好久,刚看完新世界结局完美!希望早日战胜疫情迎来我们的新世界!

假期太长了,闲着没事把年前做的CH552的51板子移植了cmsis dap v2,测试下载速度有20k,还行。
当时做这板子主要震惊于51还能跑USB而且不需要晶振,还支持触摸按键,而且1块钱!
明天上传程序,有ch552的可以试试,再一同改进一下!

离线

楼主 #6 2020-02-21 07:05:11

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 22

Re: CH552 版 CMSIS-DAP v2

DAP-20200212-删除打印.7z
我只实现了SWD功能! wink
Program Size: data=56.0 xdata=1009 code=7828
代码空间应还有,还可以加东西,后期可能加上串口!
修改自keil安装目录下的 LPC-Link-II V2,驱动也在该工程文件夹里!

最近编辑记录 ljbfly (2020-02-21 07:10:00)

离线

楼主 #10 2020-02-21 11:52:29

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 22

Re: CH552 版 CMSIS-DAP v2

不太懂,需要手动装驱动,我只是代码搬运工,哈哈,大家一起改
找个可以自动装驱动的DAP-link看一下枚举过程,改一下枚举就行了吧

最近编辑记录 ljbfly (2020-02-21 11:56:54)

离线

楼主 #12 2020-02-21 12:23:29

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 22

Re: CH552 版 CMSIS-DAP v2

@metro 厉害,USB我不太懂,弄这个小板子就是想学学USB
@metro有没有学USB的相关资料,今天晚上加上去试试

最近编辑记录 ljbfly (2020-02-21 12:26:31)

离线

楼主 #14 2020-02-22 11:26:33

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 22

Re: CH552 版 CMSIS-DAP v2

@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; //清中断标志
    }
}

代码应该没有问题呀,咋提示没有兼容驱动

FluxBB bbcode 测试

离线

楼主 #16 2020-02-22 13:43:04

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 22

Re: CH552 版 CMSIS-DAP v2

@metro 厉害,驱动好了,可是Keil识别不到是那的问题呢!是字符描述吗

离线

楼主 #18 2020-02-22 15:08:35

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 22

Re: CH552 版 CMSIS-DAP v2

metro 说:

有可能是,你按照官方的VID/PID和描述符改改,我这边是可以正常识别的。

这个是程序问题,获取描述长度大于255了,我只看了低字节,导致回应错误不能识别!

再次感谢@metro大神!

DAP-20200222-免驱动.7zTIM截图20200222150610.png

离线

楼主 #24 2020-02-23 17:06:00

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 22

Re: CH552 版 CMSIS-DAP v2

wuxx 说:

感谢分享~不过CH552的IO默认是5V的,连接到3.3V的目标芯片的IO上会不会有点风险

STM32的调试口写的是兼容5V的



jiangming1399 说:

读了一下楼主的代码,有几个疑问想请教一下楼主:
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功能,代码中肯定还有需要改进的地方,我只是简单的实现一下功能!

DAP-20200223+CDC.7z

设备管理器为什么只显示USB 串行设备呢,不能改名字吗?@metro
TIM截图20200223170326.png

离线

楼主 #29 2020-03-01 09:22:01

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 22

Re: CH552 版 CMSIS-DAP v2

这个PCB文件能分享吗?

这个板子没有3.3电源,管脚电压都是5V的,两个触摸按键

PCB1.7z

离线

楼主 #32 2020-03-04 10:32:56

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 22

Re: CH552 版 CMSIS-DAP v2

sy373466062 说:

这个DAP Link速度有点慢

可以优化,参见 metro 的帖子
我的板子现在的程序, keil下载FLASH不擦除、不校验,应该是30K左右,有时间用汇编优化试试
https://whycan.cn/viewtopic.php?id=3766

最近编辑记录 ljbfly (2020-03-04 10:33:48)

离线

楼主 #34 2020-03-04 11:20:14

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 22

Re: CH552 版 CMSIS-DAP v2

anve 说:

DAP-20200223+CDC.7z   这个文件下载不了。

试试这个

DAP-20200302.7z

离线

楼主 #37 2020-03-30 12:22:52

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 22

Re: CH552 版 CMSIS-DAP v2

gddddd 说:

感谢楼主的分享,下了DAP-20200223+CDC.7z这个代码,编译运行可以找到CMSIS-DAP v2和DAPLink-CDCExt两个设备,不过DAPLink-CDCExt一直提示“这个设备没有兼容驱动程序。”,手动指定位置安装CMSIS-DAP_CDC_Driver.inf还是驱动不了,系统是win8.1,已经禁用过签名了,还请指点一下,是这个代码需要专用的inf驱动文件吗?

用DAP-20200302.7z那版试试,win10能用

离线

楼主 #45 2020-05-01 14:34:52

ljbfly
会员
注册时间: 2017-12-07
已发帖子: 37
积分: 22

Re: CH552 版 CMSIS-DAP v2

mini_uc 说:

大侠在不,有没有DAP的驱动,我安装KEIL后,在 LPC-Link-II V2找不到驱动,WIN7下使用.

LPC-Link-II.zip

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn