搜索
bottom↓
回复: 8

ATMEGA32U4 USB模块 调试 讨论&请教

[复制链接]

出0入0汤圆

发表于 2013-9-10 15:24:22 | 显示全部楼层 |阅读模式
硬件:ATMEGA32U4,8MHZ
目标:通过CONTROL端口0,实现HID免驱通信

之前用的是飞利浦PDIUSBD12,现在尝试ATMEGA32U4。两者的的硬件USB应答操作相差很大,现在卡在USB枚举上。

大概思路如下:
1,我是检测UEINTX寄存器的RXSTPI位,判断有SETUP包,并成功收到GET_DESCRIPTOR的请求,并清除 RXSTPI位以ACK应答
2,上面步骤后,我直接向UEDATX写入描术数组,后清除TXINI位发送(应该是这样子吧)
3,上面发送后,就没再收到SETUP包,WINDOWS提示无法识别USB设备

请教各位出了什么问题。

下面是具体程序:

void USB_Task(void)
{
        USB_General_Int();
       
        if (Is_usb_receive_setup())
        {
                usb_process_request();
        }
       
        USB_Send_Data();
}


void usb_process_request(void)
{
        USB_Read_Bytes(8,USB_READ_BUFFER);

        USB_ControlRequest.bmRequestType = USB_READ_BUFFER[0];
        USB_ControlRequest.bRequest      = USB_READ_BUFFER[1];
        USB_ControlRequest.wValue                 = USB_READ_BUFFER[3];
        USB_ControlRequest.wValue                 = ((USB_ControlRequest.wValue << 8) | USB_READ_BUFFER[2]);
        USB_ControlRequest.wIndex        = USB_READ_BUFFER[5];
        USB_ControlRequest.wIndex                 = ((USB_ControlRequest.wIndex << 8) | USB_READ_BUFFER[4]);
        USB_ControlRequest.wLength       = USB_READ_BUFFER[7];
        USB_ControlRequest.wLength                 = ((USB_ControlRequest.wLength << 8) | USB_READ_BUFFER[6]);

if ((USB_ControlRequest.bmRequestType & HID_Requests_Mark) == HID_Requests_Mark)
{
        switch(USB_ControlRequest.bRequest)
        {               
                case GET_REPORT:
                        hid_get_report();
                        break;

                case SET_REPORT:
                        hid_set_report();
                        break;

                /*case GET_PROTOCOL:
                case SET_PROTOCOL:
                case SET_IDLE:
                case GET_IDLE:*/
                default:
                        Usb_ack_receive_setup();
                        UEINTX &= ~(1<<TXINI);
                        while(!(UEINTX&(1<<TXINI)));
                        break;
        }
}
else
{
        switch (USB_ControlRequest.bRequest)
        {
                case GET_DESCRIPTOR:
                        usb_get_descriptor();
                        break;

                case GET_CONFIGURATION:
                        usb_get_configuration();
                        break;

                case SET_ADDRESS:
                        usb_set_address();
                        break;

                case SET_INTERFACE:
                        usb_set_interface();
                        break;
                       
                /*case CLEAR_FEATURE:
                case SET_FEATURE:
                case GET_STATUS:
                case GET_INTERFACE:
                case SET_CONFIGURATION:
                case SET_DESCRIPTOR:
                case SYNCH_FRAME:*/
                default:
                        Usb_enable_stall_handshake();
                        Usb_ack_receive_setup();
                        return;
                        break;
        }
}


void usb_get_descriptor(void)
{
        uint8 DescriptorType = (USB_ControlRequest.wValue >> 8);
        uint8 DescriptorNumber = (USB_ControlRequest.wValue & 0xFF);
       
        switch (DescriptorType)
        {
                case DEVICE_DESCRIPTOR:
                len_w = sizeof(USB_DeviceDescriptor); //!< sizeof (usb_user_device_descriptor);
                pbuffp_w = USB_DeviceDescriptor;
                break;
                               
                case CONFIGURATION_DESCRIPTOR:
                len_w = sizeof(USB_ConfigDescriptor); //!< sizeof (usb_user_configuration_descriptor);
                pbuffp_w = USB_ConfigDescriptor;
                break;
                               
                case STRING_DESCRIPTOR:
                switch (DescriptorNumber)
                {
                        case 0x00:
                        len_w = sizeof(USB_LanguageString); //!< sizeof (USB_LanguageString);
                        pbuffp_w = USB_LanguageString;
                        break;
                                       
                        case 0x01:
                        len_w = sizeof(USB_ManufacturerString); //!< sizeof (USB_ManufacturerString);
                        pbuffp_w = USB_ManufacturerString;
                        break;
                                       
                        case 0x02:
                        len_w = sizeof(USB_ProductString); //!< sizeof (USB_ProductString);
                        pbuffp_w = USB_ProductString;
                        break;
                                       
                        case 0x03:
                        len_w = sizeof(USB_SerialNumberString); //!< sizeof (USB_SerialNumberString);
                        pbuffp_w = USB_SerialNumberString;
                        break;
                                       
                        default:
                        break;
                }
                break;
                       
                case REPORT:
                len_w = sizeof(USB_ReportDescriptor); //!< sizeof (USB_ReportDescriptor);
                pbuffp_w = USB_ReportDescriptor;
                break;
               
                default:
                Usb_enable_stall_handshake();
                Usb_ack_receive_setup();
                break;
        }
               
        Usb_ack_receive_setup() ;                  //!< clear the receive setup flag
       
        USB_Send_Data();

        while(!(UEINTX&(1<<RXOUTI)));
        Usb_ack_receive_out();
}


void USB_Send_Data(void)
{
        if (len_w > USB_ConfigDescriptor[7])
        {
                USB_Write_Bytes(USB_ConfigDescriptor[7]);
                len_w -= USB_ConfigDescriptor[7];
                pbuffp_w += USB_ConfigDescriptor[7];
        }
        else
        {
                if (len_w != 0)
                {
                        USB_Write_Bytes(len_w);
                        len_w = 0;
                }
                else
                {
                        if(zlp == TRUE)
                        {
                                USB_Write_Bytes(0);
                                zlp = FALSE;
                        }
                }
        }
}


void USB_Read_Bytes(uint8 len_r , uint8 *pbuffp_r)
{
        for (uint8 i=0;i<len_r;i++)
        {
                *(pbuffp_r+i) = UEDATX;
        }
}

void USB_Write_Bytes(uint8 temp_len)
{
        //while(!Is_usb_read_control_enabled());
       
        for (uint8 i=0;i<temp_len;i++)
        {
                UEDATX = (*(pbuffp_w+i));
        }
       
        UEINTX &= ~(1<<TXINI);
}


void USB_General_Int(void)
{
        // - Device start of frame received
        if (Is_usb_sof())
        {
                Usb_ack_sof();
                //Usb_sof_action();
        }
       
        // - Device Suspend event (no more USB activity detected)
        if (Is_usb_suspend())
        {
                Usb_ack_suspend();
                //Usb_ack_wake_up();                 // clear wake up to detect next event
                //Usb_freeze_clock();
                //Usb_suspend_action();
        }
       
        // - Wake up event (USB activity detected): Used to resume
        if (Is_usb_wake_up())
        {
                //Usb_unfreeze_clock();
                Usb_ack_wake_up();
                //Usb_wake_up_action();
        }
       
        // - Resume state bus detection
        if (Is_usb_resume())
        {
                Usb_ack_resume();
                //Usb_resume_action();
        }
       
        // - USB bus reset detection
        if (Is_usb_reset())
        {
                Usb_ack_reset();
                Usb_ack_suspend();
                Usb_reset_endpoint(EP_CONTROL);
                Config_USB_EndPoint();
        }
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

 楼主| 发表于 2013-9-11 10:24:07 | 显示全部楼层
本帖最后由 neilshao 于 2013-9-11 16:25 编辑

CONTOL端口0配置为:

(UECFG0X = 0x00)      //UECFG0X_CONTROL_DIR_OUT();
(UECFG1X = 0x32)      //UECFG1X_SIZE64_ONE_BANK_ALLOC();

出0入0汤圆

 楼主| 发表于 2013-9-11 16:22:52 | 显示全部楼层
细读ATMEGA32UE手册,发现CONTROL端口0只涉及到RXSTPI,RXOUTI,TXINI三位
程序改成如果,但结果还是依旧,在接收到0x80 , 0x06 , 0x00 0x01 , 0x00 0x00 , 0x40 0x00后,反回对应描术符后,再没有发应,UEINTX均为0,提示无法识别USB设备
程序修改如下:
void USB_Task(void)
{
        //Usb_select_endpoint(EP_CONTROL);
       
        USB_General_Int();

        // Here connection to the device enumeration process

        if (Is_usb_receive_setup())
        {
                usb_process_request();
        }
       
        if(Is_usb_receive_out())
        {
                Usb_ack_receive_out();
        }

        USB_Send_Data();
}


void usb_process_request(void)
{
        USB_Read_Bytes(8,USB_READ_BUFFER);

        USB_ControlRequest.bmRequestType = USB_READ_BUFFER[0];
        USB_ControlRequest.bRequest      = USB_READ_BUFFER[1];
        USB_ControlRequest.wValue                 = USB_READ_BUFFER[3];
        USB_ControlRequest.wValue                 = ((USB_ControlRequest.wValue << 8) | USB_READ_BUFFER[2]);
        USB_ControlRequest.wIndex        = USB_READ_BUFFER[5];
        USB_ControlRequest.wIndex                 = ((USB_ControlRequest.wIndex << 8) | USB_READ_BUFFER[4]);
        USB_ControlRequest.wLength       = USB_READ_BUFFER[7];
        USB_ControlRequest.wLength                 = ((USB_ControlRequest.wLength << 8) | USB_READ_BUFFER[6]);
       
        Usb_ack_receive_setup();                  //!< clear the receive setup flag

if ((USB_ControlRequest.bmRequestType & 0x60) == Std_Requests)
{
        switch (USB_ControlRequest.bRequest)
        {
                case GET_DESCRIPTOR:
                        usb_get_descriptor();
                        break;

                case GET_CONFIGURATION:
                        usb_get_configuration();
                        break;

                case SET_ADDRESS:
                        usb_set_address();
                        break;
                       
                /*case CLEAR_FEATURE:
                case SET_FEATURE:
                case GET_STATUS:
                case GET_INTERFACE:
                case SET_CONFIGURATION:
                case SET_DESCRIPTOR:
                case SET_INTERFACE:
                case SYNCH_FRAME:*/
                default: //!< un-supported request => call to user read request
                        Usb_send_control_in();
                        return;
                        break;
        }
}
else
{
        switch(USB_ControlRequest.bRequest)
        {               
                case GET_REPORT:
                        hid_get_report();
                        break;

                case SET_REPORT:
                        hid_set_report();
                        break;

                /*case GET_PROTOCOL:
                case SET_PROTOCOL:
                case SET_IDLE:
                case GET_IDLE:*/
                default:
                        Usb_send_control_in();
                        break;
        }
}
}


void usb_set_address(void)
{
        uint8 addr = (USB_ControlRequest.wValue & 0x7F);
       
        Usb_configure_address(addr);

        //Usb_ack_receive_setup();

        Usb_send_control_in();                    //!< send a ZLP for STATUS phase
        while(!Is_usb_in_ready());                //!< waits for status phase done
        //!< before using the new address
        Usb_enable_address();
}


void usb_get_descriptor(void)
{
        uint8 DescriptorType = (USB_ControlRequest.wValue >> 8);
        uint8 DescriptorNumber = (USB_ControlRequest.wValue & 0xFF);
       
        switch (DescriptorType)
        {
                case DEVICE_DESCRIPTOR:
                if (USB_ControlRequest.wLength > sizeof(USB_DeviceDescriptor))
                {
                        len_w = sizeof(USB_DeviceDescriptor);
                }
                else
                {
                        len_w = USB_ControlRequest.wLength;
                }
                pbuffp_w = USB_DeviceDescriptor;
                break;
                               
                case CONFIGURATION_DESCRIPTOR:
                if (USB_ControlRequest.wLength > sizeof(USB_ConfigDescriptor))
                {
                        len_w = sizeof(USB_ConfigDescriptor);
                }
                else
                {
                        len_w = USB_ControlRequest.wLength;
                }
                pbuffp_w = USB_ConfigDescriptor;
                break;
                               
                case STRING_DESCRIPTOR:
                switch (DescriptorNumber)
                {
                        case 0x00:
                        if (USB_ControlRequest.wLength > sizeof(USB_LanguageString))
                        {
                                len_w = sizeof(USB_LanguageString);
                        }
                        else
                        {
                                len_w = USB_ControlRequest.wLength;
                        }
                        pbuffp_w = USB_LanguageString;
                        break;
                                       
                        case 0x01:
                        if (USB_ControlRequest.wLength > sizeof(USB_ManufacturerString))
                        {
                                len_w = sizeof(USB_ManufacturerString);
                        }
                        else
                        {
                                len_w = USB_ControlRequest.wLength;
                        }
                        pbuffp_w = USB_ManufacturerString;
                        break;
                                       
                        case 0x02:
                        if (USB_ControlRequest.wLength > sizeof(USB_ProductString))
                        {
                                len_w = sizeof(USB_ProductString);
                        }
                        else
                        {
                                len_w = USB_ControlRequest.wLength;
                        }
                        pbuffp_w = USB_ProductString;
                        break;
                                       
                        case 0x03:
                        if (USB_ControlRequest.wLength > sizeof(USB_SerialNumberString))
                        {
                                len_w = sizeof(USB_SerialNumberString);
                        }
                        else
                        {
                                len_w = USB_ControlRequest.wLength;
                        }
                        pbuffp_w = USB_SerialNumberString;
                        break;
                                       
                        default:
                        Usb_send_control_in();
                        //Usb_enable_stall_handshake();
                        break;
                }
                break;
                       
                case REPORT:
                if (USB_ControlRequest.wLength > sizeof(USB_ReportDescriptor))
                {
                        len_w = sizeof(USB_ReportDescriptor);
                }
                else
                {
                        len_w = USB_ControlRequest.wLength;
                }
                pbuffp_w = USB_ReportDescriptor;
                break;
               
                default:
                Usb_send_control_in();
                //Usb_enable_stall_handshake();
                break;
        }
       
        USB_Send_Data();
}


void USB_Send_Data(void)
{
        if (len_w > USB_ConfigDescriptor[7])
        {
                USB_Write_Bytes(USB_ConfigDescriptor[7]);
                len_w -= USB_ConfigDescriptor[7];
                pbuffp_w += USB_ConfigDescriptor[7];
        }
        else
        {
                if (len_w != 0)
                {
                        USB_Write_Bytes(len_w);
                        len_w = 0;
                }
                else
                {
                        if(zlp == TRUE)
                        {
                                Usb_send_control_in();
                                zlp = FALSE;
                        }
                }
        }
}


void USB_Write_Bytes(uint8 temp_len)
{
        for (uint8 i=0;i<temp_len;i++)
        {
                Usb_read_byte() = (*(pbuffp_w+i));
        }
       
        Usb_send_control_in();
}


void USB_Read_Bytes(uint8 len_r , uint8 *pbuffp_r)
{
        for (uint8 i=0;i<len_r;i++)
        {
                *(pbuffp_r+i) = Usb_read_byte();
        }
}

出0入0汤圆

 楼主| 发表于 2013-9-12 09:29:46 | 显示全部楼层
原来将LSM设成LOW SPEED的导致,将设备设置成FULL SPEED,枚举成功了。

有朋友可以讲解下原因吗?

出0入0汤圆

发表于 2013-9-12 10:18:15 | 显示全部楼层
跟你外部的上拉电阻有关吧

出0入0汤圆

 楼主| 发表于 2013-9-13 08:55:55 | 显示全部楼层
外部上拉电阻?

手册上说是用22欧电阻呀

出0入0汤圆

发表于 2016-8-13 10:35:48 | 显示全部楼层
刚刚也在弄32U4通讯,还没成功能发一个你的通讯程序给我测试看看是硬件还是软件有问题吗?谢谢!

出0入0汤圆

发表于 2016-8-13 10:36:57 | 显示全部楼层
邮箱:416504258@qq.com

出0入0汤圆

发表于 2016-9-11 09:19:59 | 显示全部楼层
D12这芯片是十几年前的产物了,但USB的通信核心是一样的,用U4的话最好你还是配上个分析仪,这样很快就知道出错在那里,只是建议!很久前刚开始用D12的时候,死搞都是搞不通,后来用分析议看了才知道出错在那个数据包
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-21 19:42

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表