打印
[ZLG-ARM]

lpc2146 USB超时???????????????????????

[复制链接]
2156|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
cunxing|  楼主 | 2008-1-15 16:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
   我用LPC2146的实现一个USBAUDIO设备,其中使用了物理端点5(BULK)上传相关的AUDIO消息,但是有时调用UsbWriteEndpoint()之后,会有时不会出现相关的发送中断,出现这种情况可能是USB发送数超时或者其它错误(固件禁止了相关错误中断),但是我再次调用UsbWriteEndpoint()之后,仍然没有发送中断产生.问,如果是超时或者其它中断产生,一定要清楚相关中断位(在没有开相关中断的情况下)后,才能继续调用UsbWriteEndpoint()发送数据吗?

相关帖子

沙发
zlgarm| | 2008-1-15 16:57 | 只看该作者

回复如下:

cunxing,您好
     一般情况下,只调用我们公司的软件包是不会出现问题的。
     您可以调用如下语句来获取错误代码:
     USB_SendCmd(USBCMD_GET_DEVSTATUS, 0);
     ucErrCode = USB_GetData(USBDAT_GET_DEVSTATUS);
     查看返回的ucErrCode来判断到底出现的是什么错误。

     另:
     如果出现了超时或者其它中断,请先清除相关中断位(不管有没有开关中断)后,再继续调用UsbWriteEndpoint()发送数据。

    如果还不能解决问题,方便的话,请考虑将您的程序贴出来让我们看一下。

                                                          By zlgarm-wls



使用特权

评论回复
板凳
cunxing|  楼主 | 2008-1-16 14:10 | 只看该作者

代码

INT8U UsbInitialize(void)
{
    UsbInitHareware();
    bEPPflags.value = 0;                                /* 置USB事件标志为0   set USB event flags to zero */
    
    if (UsbReadTestRegister() != 0xa50f)        //read test register
    {
        return 1;
    }
    UsbDeviceIntConfig();
    UsbConfigEndpoint();
    UsbSetMode(0x00);            //generate interrupt
    ReConnectUsb();
    return 0;
}

void UsbMidiSystemConstruct(void)
{
    g_UsbMidiErr = UsbInitialize();
    g_UsbMidiOutBusy = USBOUT_IDLE;

       //InitUsbIntrrupt();
}

void Ep2RxDone(void)
{
    INT8U len;
    INT8U class;
    INT8U i;
    
    UsbSelectClrIntEndpoint(4);
    i = 0;
    len = UsbReadEndpoint(4, sizeof(g_EpBuf), g_EpBuf);
    class = g_EpBuf[0] & 0x0f;
    
    if ( (len != 0) && (class >= 0x04) &&  (class < 0x0f) )
    {
        bEPPflags.bits.ep2_rxdone = 1;                     /* 标识该端点收到数据      flag endpoint received data */
        do 
        {
            g_UsbMidiInBuffer[g_UsbMidiInTail][0] = g_EpBuf[i++];
            g_UsbMidiInBuffer[g_UsbMidiInTail][1] = g_EpBuf[i++];
            g_UsbMidiInBuffer[g_UsbMidiInTail][2] = g_EpBuf[i++];
            g_UsbMidiInBuffer[g_UsbMidiInTail][3] = g_EpBuf[i++];
            g_UsbMidiInMessages++;
            g_UsbMidiInTail++;
            if (g_UsbMidiInTail == USB_MIDIIN_SIZE)
            {
                g_UsbMidiInTail = 0;
            }
            if (i < len)
            {
                class = g_EpBuf & 0x0f;
            }
            else
            {
                break;
            }
        }while((class >= 0x04) &&  (class < 0x0f));
    }
}


void Usb_LPService(void)
{
    INT32U ep_st;
    ep_st = USBEpIntSt;                                    /* 读端点中断状态寄存器 read endpoint interrupt status register */
    if(ep_st & USB_ENDP00)
    {
        Ep0RxDone();                                    /* 控制端点接收数据处理     process controll endpoint receive data */
    }
    if(ep_st & USB_ENDP01)
    {
        Ep0TxDone();                                    /* 控制端点发送数据处理     process controll endpoint transmit data */
    }
    if(ep_st & USB_ENDP04)
    {
        Ep2RxDone();                                    /* 逻辑端点2接收数据处理    process logic endpoint 2 receive data */    
    }
    if(ep_st & USB_ENDP05)    
    {
        Ep2TxDone();                                    /* 逻辑端点2发送数据处理    process logic endpoint 2 transmit data */    
    }        
    USBDevIntClr = SLOWINTERRUPT;
}

void SendUsbMidiOutEvent(void)
{
    INT8U usbbuf[4];
    INT8U i;
    if ( (g_UsbMidiErr) || (g_UsbMidiBulkOkCounter < 100) )
    {
        return;
    }
    
    if ((MidiByte1 & 0xf0) == 0xc0)
    {
        MidiByte3 = 0;
    }
    usbbuf[0] = (MidiByte1 >> 4) & 0x0f;
    usbbuf[1] = MidiByte1;
    usbbuf[2] = MidiByte2;
    usbbuf[3] = MidiByte3;

    if (g_UsbMidiOutBusy == USBOUT_BUSY)
    {
        for (i = 0; i < 4; i++)
        {
            g_UsbMidiOutBuffer[g_UsbMidiInTail] = usbbuf;
        }
        OS_ENTER_CRITICAL();
        g_UsbMidiOutMessages++;
        OS_EXIT_CRITICAL();
        g_UsbMidiInTail++;
        if (g_UsbMidiInTail ==     USB_MIDIOUT_SIZE)
        {
            g_UsbMidiInTail = 0;    
        }
    }
    else
    {
        OS_ENTER_CRITICAL();
        g_UsbMidiOutBusy = USBOUT_BUSY;
        g_UsbMidiTimeOut = 0;        
        OS_EXIT_CRITICAL();
        UsbWriteEndpoint(5, 4, usbbuf);
/*        for (i = 0; i < 200; i++)
        {
            ;
        }
*/        
        
    }
}


主程序不断调用SendUsbMidiOutEvent()上传消息,用PC上位机软件,监视上传消息,总是在不确定时刻就停止了上传消息.此时把g_UsbMidiOutBusy信号量强制等于USBOUT_IDLE(停止时显然没有来发送中断,清除该信号),使得再次发送,但是仍然没有数据上传,并且也不再产生发送中断.

使用特权

评论回复
地板
cunxing|  楼主 | 2008-1-16 14:22 | 只看该作者

之前用台湾一的一个51核的一个片子

注,我之前用过一个台湾十速51核的USB片子,实现同样的功能,但是我监视到长时间没有来发送中断之后,清除相关信号,再次调UsbWriteEndpoint()发送数据之后,又可以上传数据了,不知道PHILIP这个是怎么回事.为什么再次调用UsbWriteEndpoint()之后仍然没有数据上传上来?

使用特权

评论回复
5
cunxing|  楼主 | 2008-1-16 15:05 | 只看该作者

补充发送中断处理

上面贴错了一个接收中断处理,应该贴发送中断处理的
void Ep2TxDone(void)
{
    UsbSelectClrIntEndpoint(5);    
    g_UsbMidiOutBusy = USBOUT_IDLE;
    
    
    if (g_UsbMidiOutMessages != 0)
    {
        g_UsbMidiOutBusy = USBOUT_BUSY;
        g_UsbMidiTimeOut = 0;
        g_UsbMidiOutMessages--;
        UsbWriteEndpoint(5, 4, g_UsbMidiOutBuffer[g_UsbMidiOutHead++]);
        if (g_UsbMidiOutHead == USB_MIDIOUT_SIZE)
        {
            g_UsbMidiOutHead = 0;
        }
    }
}

使用特权

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

本版积分规则

62

主题

87

帖子

1

粉丝