我在调试lpc1788的usb host部分时候发现
lpcusblib的ohci.c中只针对 port1 处理没有针对port2 做处理
if (IntStatus & HC_INTERRUPT_RootHubStatusChange) { //´¦Àí root hubµÄ״̬¸ü¸Ä ÓÐ
for(;USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_StatusChangeMask;){
/* only 1 port/host --> skip to get the number of ports */ //ÕâÀïÖ»´¦ÀíÁË USB1µÄÇé¿öûÓд¦Àí USB2µÄÇé¿ö ..À¬»ø¿â
if (USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_ConnectStatusChange) {
if (USB_REG(HostID)->RhStatus & HC_RH_STATUS_DeviceRemoteWakeupEnable) { /* means a remote wakeup event */ //Ô¶³Ì»½ÐÑ
}
else {}
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_ConnectStatusChange; /* clear CSC bit */ //¼ì²âµ½²åÈë »òÕ߰γöʼþ
OHciRhStatusChangeIsr(HostID, USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_CurrentConnectStatus);
}
if (USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_PortEnableStatusChange) {
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_PortEnableStatusChange; /* clear PESC */ //½«¶Ë¿ÚʹÄÜ
}
if (USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_PortSuspendStatusChange) {
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_PortSuspendStatusChange; /* clear PSSC */ //¹ÒÆð´Ë¶Ë¿Ú
}
if (USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_OverCurrentIndicatorChange) { /* Over-current handler to avoid physical damage */
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_OverCurrentIndicatorChange; /* clear OCIC */ //½áÊøʲô ָʾ·û±êÖ¾
}
if (USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_PortResetStatusChange) {
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_PortResetStatusChange; /* clear PRSC */ //Èí¼þ¸´Î»¶Ë¿Ú
}
}
}
Hi,
Thank you ask me , I've changed that before that, but enum device stop in pipe get device description in
host.c
if ((SubErrorCode = USB_Host_SendControlRequest(corenum, &DevDescriptor)) != HOST_SENDCONTROL_Successful) { //sendControlRequest
ErrorCode = HOST_ENUMERROR_ControlError;
break;
}
DEBUGOUT("Get devicedescription\r\n"); //
USB_Host_ControlPipeSize[corenum] = DevDescriptor.Endpoint0Size;
Pipe_ClosePipe(corenum, PIPE_CONTROLPIPE);
debug is stoping this function:
static HCD_STATUS WaitForTransferComplete(uint8_t EdIdx)
{
#ifndef __TEST__
while ( HcdED(EdIdx)->status == HCD_STATUS_TRANSFER_QUEUED ) {}
return (HCD_STATUS) HcdED(EdIdx)->status;
#else
return HCD_STATUS_OK;
#endif
}
hi,
mini92
have you got any solution for this particular issue..??
i am facing similar issue .. can u plz help!
Hi Chao Li,
Are you also modifying the lpcusblib_MassStorageHost example of lpcopen for lpc1788? Are you testing it on an evaluation board? Please make sure you are implementing the changes described above.
Best Regards!
Carlos Mendoza
Technical Support Engineer
Hi Carlos Mendoza
I'm also with the same problem with Chao Li, my code are stoping in the function
static HCD_STATUS WaitForTransferComplete(uint8_t EdIdx)
I have made the modifications described above like you.
Hi Chao Li,
This is what I changed on lpcusblib_MassStorageHost example of lpcopen 2.10 for lpc1788 and it can work fine on usb port 2 on EA lpc1788 board.:
In HAL_LPC17xx.h I added a MACRO to switch between USB port 1 and port 2
#define USB_PORT_1 0
In HAL_LPC17xx.c, I modified IOCON configuration:
#if USB_PORT_1
Chip_IOCON_PinMux(LPC_IOCON, 0, 29, IOCON_MODE_INACT, IOCON_FUNC1); /* P0.29 D1+, P0.30 D1- */
Chip_IOCON_PinMux(LPC_IOCON, 0, 30, IOCON_MODE_INACT, IOCON_FUNC1);
#else
Chip_IOCON_PinMux(LPC_IOCON, 0, 31, IOCON_MODE_INACT, IOCON_FUNC1); /* P0.31 D2+ */
//Chip_IOCON_PinMux(LPC_IOCON, 1, 30, IOCON_MODE_INACT, IOCON_FUNC1); /* P1.30 USB_PWRD2 */
//Chip_IOCON_PinMux(LPC_IOCON, 1, 31, IOCON_MODE_INACT, IOCON_FUNC1); /* P1.31 USB_OVRCR2 */
#endif
#if defined(USB_CAN_BE_HOST)
#if USB_PORT_1
Chip_IOCON_PinMux(LPC_IOCON, 1, 19, IOCON_MODE_INACT, IOCON_FUNC2); /* USB_Power switch */
#else
Chip_IOCON_PinMux(LPC_IOCON, 0, 12, IOCON_MODE_INACT, IOCON_FUNC1); /* USB_PPWR2 */
#endif
#endif
And finally, on OHCI.c file, I changed. In HcdInitDriver function:
#if USB_PORT_1
USB_REG(HostID)->StCtrl = 0x1; /* Port 1 is host */
#else
USB_REG(HostID)->StCtrl = 0x00; /* Port 2 is host */
#endif
In same OHCI.c file, I replace next functions to substitute RhPortStatus1 by RhPortStatus2:
#if USB_PORT_1
HCD_STATUS HcdGetDeviceSpeed(uint8_t HostID, HCD_USB_SPEED *DeviceSpeed)
{
if ( USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_CurrentConnectStatus) { /* If device is connected */
*DeviceSpeed =
( USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_LowSpeedDeviceAttached) ? LOW_SPEED : FULL_SPEED;
return HCD_STATUS_OK;
}
else {
return HCD_STATUS_DEVICE_DISCONNECTED;
}
}
uint32_t HcdGetFrameNumber(uint8_t HostID)
{
return ohci_data[HostID].hcca.HccaFrameNumber;
}
HCD_STATUS HcdRhPortReset(uint8_t HostID)
{
HcdDelayMS(400);// TODO delay should be on Host_LPC
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_PortResetStatus; /* SetPortReset */
/* should have time-out */
while ( USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_PortResetStatus) {}
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_PortResetStatusChange;/* Clear Port Reset Status Change */
HcdDelayMS(400);// TODO delay should be on Host_LPC
return HCD_STATUS_OK;
}
HCD_STATUS HcdRhPortEnable(uint8_t HostID)
{
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_PowerEnableStatus;/* SetPortEnable */
return HCD_STATUS_OK;
}
HCD_STATUS HcdRhPortDisable(uint8_t HostID)
{
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_CurrentConnectStatus; /* ClearPortEnable */
return HCD_STATUS_OK;
}
#else
HCD_STATUS HcdGetDeviceSpeed(uint8_t HostID, HCD_USB_SPEED *DeviceSpeed)
{
if ( USB_REG(HostID)->RhPortStatus2 & HC_RH_PORT_STATUS_CurrentConnectStatus) { /* If device is connected */
*DeviceSpeed =
( USB_REG(HostID)->RhPortStatus2 & HC_RH_PORT_STATUS_LowSpeedDeviceAttached) ? LOW_SPEED : FULL_SPEED;
return HCD_STATUS_OK;
}
else {
return HCD_STATUS_DEVICE_DISCONNECTED;
}
}
uint32_t HcdGetFrameNumber(uint8_t HostID)
{
return ohci_data[HostID].hcca.HccaFrameNumber;
}
HCD_STATUS HcdRhPortReset(uint8_t HostID)
{
HcdDelayMS(400);// TODO delay should be on Host_LPC
USB_REG(HostID)->RhPortStatus2 = HC_RH_PORT_STATUS_PortResetStatus; /* SetPortReset */
/* should have time-out */
while ( USB_REG(HostID)->RhPortStatus2 & HC_RH_PORT_STATUS_PortResetStatus) {}
USB_REG(HostID)->RhPortStatus2 = HC_RH_PORT_STATUS_PortResetStatusChange;/* Clear Port Reset Status Change */
HcdDelayMS(400);// TODO delay should be on Host_LPC
return HCD_STATUS_OK;
}
HCD_STATUS HcdRhPortEnable(uint8_t HostID)
{
USB_REG(HostID)->RhPortStatus2 = HC_RH_PORT_STATUS_PowerEnableStatus;/* SetPortEnable */
return HCD_STATUS_OK;
}
HCD_STATUS HcdRhPortDisable(uint8_t HostID)
{
USB_REG(HostID)->RhPortStatus2 = HC_RH_PORT_STATUS_CurrentConnectStatus; /* ClearPortEnable */
return HCD_STATUS_OK;
}
#endif
And finally, in HcdirqHandler function RhPortStatus1 must be changed by RhPortStatus2:
#if USB_PORT_1
/* Process RootHub Status Change */
if (IntStatus & HC_INTERRUPT_RootHubStatusChange) {
for(;USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_StatusChangeMask;){
/* only 1 port/host --> skip to get the number of ports */
if (USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_ConnectStatusChange) {
if (USB_REG(HostID)->RhStatus & HC_RH_STATUS_DeviceRemoteWakeupEnable) { /* means a remote wakeup event */
}
else {}
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_ConnectStatusChange; /* clear CSC bit */
OHciRhStatusChangeIsr(HostID, USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_CurrentConnectStatus);
}
if (USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_PortEnableStatusChange) {
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_PortEnableStatusChange; /* clear PESC */
}
if (USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_PortSuspendStatusChange) {
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_PortSuspendStatusChange; /* clear PSSC */
}
if (USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_OverCurrentIndicatorChange) { /* Over-current handler to avoid physical damage */
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_OverCurrentIndicatorChange; /* clear OCIC */
}
if (USB_REG(HostID)->RhPortStatus1 & HC_RH_PORT_STATUS_PortResetStatusChange) {
USB_REG(HostID)->RhPortStatus1 = HC_RH_PORT_STATUS_PortResetStatusChange; /* clear PRSC */
}
}
}
#else
/* Process RootHub Status Change */
if (IntStatus & HC_INTERRUPT_RootHubStatusChange) {
for(;USB_REG(HostID)->RhPortStatus2 & HC_RH_PORT_STATUS_StatusChangeMask;){
/* only 1 port/host --> skip to get the number of ports */
if (USB_REG(HostID)->RhPortStatus2 & HC_RH_PORT_STATUS_ConnectStatusChange) {
if (USB_REG(HostID)->RhStatus & HC_RH_STATUS_DeviceRemoteWakeupEnable) { /* means a remote wakeup event */
}
else {}
USB_REG(HostID)->RhPortStatus2 = HC_RH_PORT_STATUS_ConnectStatusChange; /* clear CSC bit */
OHciRhStatusChangeIsr(HostID, USB_REG(HostID)->RhPortStatus2 & HC_RH_PORT_STATUS_CurrentConnectStatus);
}
if (USB_REG(HostID)->RhPortStatus2 & HC_RH_PORT_STATUS_PortEnableStatusChange) {
USB_REG(HostID)->RhPortStatus2 = HC_RH_PORT_STATUS_PortEnableStatusChange; /* clear PESC */
}
if (USB_REG(HostID)->RhPortStatus2 & HC_RH_PORT_STATUS_PortSuspendStatusChange) {
USB_REG(HostID)->RhPortStatus2 = HC_RH_PORT_STATUS_PortSuspendStatusChange; /* clear PSSC */
}
if (USB_REG(HostID)->RhPortStatus2 & HC_RH_PORT_STATUS_OverCurrentIndicatorChange) { /* Over-current handler to avoid physical damage */
USB_REG(HostID)->RhPortStatus2 = HC_RH_PORT_STATUS_OverCurrentIndicatorChange; /* clear OCIC */
}
if (USB_REG(HostID)->RhPortStatus2 & HC_RH_PORT_STATUS_PortResetStatusChange) {
USB_REG(HostID)->RhPortStatus2 = HC_RH_PORT_STATUS_PortResetStatusChange; /* clear PRSC */
}
}
}
#endif
Hope it helps!
Best Regards,
Carlos Mendoza
Technical Support Engineer
Hi,
Thank you ask me , I've changed that before that, but enum device stop in pipe get device description in
host.c
if ((SubErrorCode = USB_Host_SendControlRequest(corenum, &DevDescriptor)) != HOST_SENDCONTROL_Successful) { //sendControlRequest
ErrorCode = HOST_ENUMERROR_ControlError;
break;
}
DEBUGOUT("Get devicedescription\r\n"); //
USB_Host_ControlPipeSize[corenum] = DevDescriptor.Endpoint0Size;
Pipe_ClosePipe(corenum, PIPE_CONTROLPIPE);
debug is stoping this function:
static HCD_STATUS WaitForTransferComplete(uint8_t EdIdx)
{
#ifndef __TEST__
while ( HcdED(EdIdx)->status == HCD_STATUS_TRANSFER_QUEUED ) {}
return (HCD_STATUS) HcdED(EdIdx)->status;
#else
return HCD_STATUS_OK;
#endif
}