部分代码:
static struct ep_id _ep_pool[] =
{
{0x0, USB_EP_ATTR_CONTROL, USB_DIR_OUT, 64, ID_ASSIGNED },
{0x1, USB_EP_ATTR_CONTROL, USB_DIR_IN, 64, ID_UNASSIGNED},
{0x2, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
{0x3, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
{0x4, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
{0x5, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
{0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
};
static void _usb_hw_init(void)
{
// USB_DEV_CLK_EN,USB_AHB_CLK_EN,USB_OTG_CLK_EN
rt_uint32_t ulClkCtrl = 0x1A ;
LPC_SC->PCONP |= 0x80000000; // 给USB控制器提供电源
LPC_USB->USBClkCtrl = ulClkCtrl; // 配置USB时钟控制寄存器
while ((LPC_USB->USBClkSt & ulClkCtrl) != ulClkCtrl);
LPC_USB->StCtrl |= 0x03; // U1 HOST, U2 devices
// LPC_IOCON->P0_29 &= ~0x07; // P0.29 D1+, P0.30 D1-
// LPC_IOCON->P0_29 |= 0x01;
// LPC_IOCON->P0_30 &= ~0x07;
// LPC_IOCON->P0_30 |= 0x01;
LPC_IOCON->P0_31 &= ~0x07;
LPC_IOCON->P0_31 |= 0x01;
LPC_IOCON->P0_14 &= ~0x07;
LPC_IOCON->P0_14 |= 0x01;
}
static void _usb_inturrupt_init(void)
{
rt_uint32_t intTmp = 0x04; // ep_slow
LPC_USB->DevIntClr = 0x01; // 禁止同步传输帧中断
LPC_USB->DevIntEn = intTmp; // 使能复位中断, 低速中断
LPC_USB->DevIntPri = 0; // 使能端点中断为低优先级中断
intTmp = (0x01 << 0) + (0x01 << 1) + (0x01 << 4) + (0x01 << 5); // 使能端点 0,1,4,5 从机中断
LPC_USB->EpIntEn = intTmp;
LPC_USB->EpIntPri &= ~intTmp; // 设置为低优先级中断
LPC_SC->USBIntSt = 0x80000000; // 允许USB中断
}
static void _usb_endpoint_config(void)
{
// 配置各物理端点的最大包大小
#if 0
usbd_devConfigMaxPaketSize(EP0_CTR_OUT, USBD_PACKET_SIZE_64BYTE);
usbd_devConfigMaxPaketSize(EP0_CTR_IN, USBD_PACKET_SIZE_64BYTE);
usbd_devConfigMaxPaketSize(EP2_BULK_OUT, USBD_PACKET_SIZE_64BYTE);
usbd_devConfigMaxPaketSize(EP2_BULK_IN, USBD_PACKET_SIZE_64BYTE);
#else
rt_uint8_t idx = 0;
while(_ep_pool[idx].addr != 0xFF)
{
usbd_devConfigMaxPaketSize(_ep_pool[idx].addr, _ep_pool[idx].maxpacket);
idx++;
}
#endif
}
// 初始化usb设备控制器
static rt_err_t _init(rt_device_t device)
{
// TODO:PLL1的配置要统一到原时钟配置的位置上
// PLL1时钟配置,提供48MHz的usbclk
LPC_SC->PLL1CFG = 0x23;
LPC_SC->PLL1CON = 0x01; // PLL1 Enable
LPC_SC->PLL1FEED = 0xAA;
LPC_SC->PLL1FEED = 0x55;
while (!(LPC_SC->PLL1STAT & (1<<10))); // Wait for PLOCK1
// USBCLKSEL.USBDIV=1,output 48MHz USBCLKSEL.USBSEL=2,Alt PLL
LPC_SC->USBCLKSEL = (0x00000001|(0x02<<8)); // Setup USB Clock Divider
NVIC_SetPriority(USB_IRQn, 5);
NVIC_EnableIRQ(USB_IRQn);
// usb hw init
_usb_hw_init();
// interrupt config
_usb_inturrupt_init();
// endpoint config
_usb_endpoint_config();
// set mode
usbd_devSetMode(0); // 成功传输才产生中断
return RT_EOK;
}