修复NXP LPCUSBLib只能用Host1端口BUG

/ 0评 / 0

因为各种不明原因,LPCUSBLib竟然只支持Port 1,但是Port 1要占掉两个普通IO,而Port 2只需要占一个,所以就改一改了.用LPC17788举例.
首先在添加定义(位于HAL_LPC17xx.h) :

#define USB_PORT_1 0

然后添加HOST2端口的配置(位于HAL_LPC17xx.c的HAL_USBInit函数) :

#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


电源控制引脚也是不一样的,修改之(位于HAL_LPC17xx.c的HAL_USBInit函数) :

	#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

USB控制器上也是有分别的.(位于OHCI.c的HcdInitDriver函数) :

	#if USB_PORT_1
			 USB_REG(HostID)->StCtrl = 0x01;                         /* Port 1 is host */
	#else
			 USB_REG(HostID)->StCtrl = 0x00;                     /* Port 2 is host */
	#endif

然后RhPortStatus1和RhPortStatus2要分离下.波及函数有点多.(位于OHCI.c,多个函数.)

#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

当然还没完,端口改变时候通知也要变,不然通知不到.(位于OHCI.c的HcdIrqHandler函数.)

目前已经能工作了,但是依然不完美.DeInit过程.... 这个就不写了,非常简单.只是还原IO.
NXP,赶紧去修复 你的BUG.

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注