/** * Callback for passing a new device to the driver. * * @note Currently, only boot-protocol keyboards are supported by this driver. * * @param dev Structure representing the new device. * @return Error code. */ static int usb_hid_device_add(usb_device_t *dev) { usb_log_debug("%s\n", __FUNCTION__); if (dev == NULL) { usb_log_error("Wrong parameter given for add_device().\n"); return EINVAL; } if (usb_device_get_iface_number(dev) < 0) { usb_log_error("Failed to add HID device: endpoints not found." "\n"); return ENOTSUP; } usb_hid_dev_t *hid_dev = usb_device_data_alloc(dev, sizeof(usb_hid_dev_t)); if (hid_dev == NULL) { usb_log_error("Failed to create USB/HID device structure.\n"); return ENOMEM; } int rc = usb_hid_init(hid_dev, dev); if (rc != EOK) { usb_log_error("Failed to initialize USB/HID device.\n"); usb_hid_deinit(hid_dev); return rc; } usb_log_debug("USB/HID device structure initialized.\n"); /* Start automated polling function. * This will create a separate fibril that will query the device * for the data continuously. */ rc = usb_device_auto_poll_desc(dev, /* Index of the polling pipe. */ hid_dev->poll_pipe_mapping->description, /* Callback when data arrives. */ usb_hid_polling_callback, /* How much data to request. */ hid_dev->poll_pipe_mapping->pipe.max_packet_size, /* Delay */ -1, /* Callback when the polling ends. */ usb_hid_polling_ended_callback, /* Custom argument. */ hid_dev); if (rc != EOK) { usb_log_error("Failed to start polling fibril for `%s'.\n", usb_device_get_name(dev)); usb_hid_deinit(hid_dev); return rc; } hid_dev->running = true; usb_log_info("HID device `%s' ready.\n", usb_device_get_name(dev)); return EOK; }
/***************************************************************************** ** Main Function main() *****************************************************************************/ int main (void) { USBD_API_INIT_PARAM_T usb_param; ErrorCode_t ret; USB_CORE_DESCS_T desc; SystemCoreClockUpdate(); /* Setup UART for 115.2K, 8 data bits, no parity, 1 stop bit */ UARTInit(115200); UARTSend((uint8_t *)"\r\nLPC11Uxx USB ROMAPI example>", 31); /* get USB API table pointer */ pUsbApi = (USBD_API_T*)((*(ROM **)(0x1FFF1FF8))->pUSBD); /* enable clocks and pinmux for usb */ USB_pin_clk_init(); /* initilize call back structures */ memset((void*)&usb_param, 0, sizeof(USBD_API_INIT_PARAM_T)); usb_param.usb_reg_base = LPC_USB_BASE; usb_param.mem_base = 0x10001000; usb_param.mem_size = 0x1000; usb_param.max_num_ep = 2; usb_param.USB_Configure_Event = USB_Configure_Event; /* Initialize Descriptor pointers */ memset((void*)&desc, 0, sizeof(USB_CORE_DESCS_T)); desc.device_desc = (uint8_t *)&USB_DeviceDescriptor[0]; desc.string_desc = (uint8_t *)&USB_StringDescriptor[0]; desc.full_speed_desc = (uint8_t *)&USB_FsConfigDescriptor[0]; desc.high_speed_desc = (uint8_t *)&USB_FsConfigDescriptor[0]; /* USB Initialization */ ret = pUsbApi->hw->Init(&hUsb, &desc, &usb_param); if (ret == LPC_OK) { ret = usb_hid_init(hUsb, (USB_INTERFACE_DESCRIPTOR *)&USB_FsConfigDescriptor[sizeof(USB_CONFIGURATION_DESCRIPTOR)], &usb_param.mem_base, &usb_param.mem_size); if (ret == LPC_OK) { NVIC_EnableIRQ(USB_IRQn); // enable USB interrrupts /* now connect */ pUsbApi->hw->Connect(hUsb, 1); } } else { UARTSend((uint8_t *)"\r\nhwUSB_Init error!!!", 21); } while (1); }
/** * @brief main routine for blinky example * @return Function should not exit. */ int main(void) { USBD_API_INIT_PARAM_T usb_param; USB_CORE_DESCS_T desc; ErrorCode_t ret = LPC_OK; /* Initialize board and chip */ Board_Init(); /* enable clocks */ Chip_USB_Init(); /* initialize USBD ROM API pointer. */ g_pUsbApi = (const USBD_API_T *) LPC_ROM_API->pUSBD; /* initialize call back structures */ memset((void *) &usb_param, 0, sizeof(USBD_API_INIT_PARAM_T)); usb_param.usb_reg_base = LPC_USB0_BASE; /* WORKAROUND for artf44835 ROM driver BUG: Code clearing STALL bits in endpoint reset routine corrupts memory area next to the endpoint control data. For example When EP0, EP1_IN, EP1_OUT, EP2_IN are used we need to specify 3 here. But as a workaround for this issue specify 4. So that extra EPs control structure acts as padding buffer to avoid data corruption. Corruption of padding memory doesn’t affect the stack/program behaviour. */ usb_param.max_num_ep = 2 + 1; usb_param.mem_base = USB_STACK_MEM_BASE; usb_param.mem_size = USB_STACK_MEM_SIZE; /* Set the USB descriptors */ desc.device_desc = (uint8_t *) USB_DeviceDescriptor; desc.string_desc = (uint8_t *) USB_StringDescriptor; /* Note, to pass USBCV test full-speed only devices should have both * descriptor arrays point to same location and device_qualifier set * to 0. */ desc.high_speed_desc = USB_FsConfigDescriptor; desc.full_speed_desc = USB_FsConfigDescriptor; desc.device_qualifier = 0; /* USB Initialization */ ret = USBD_API->hw->Init(&g_hUsb, &desc, &usb_param); if (ret == LPC_OK) { ret = usb_hid_init(g_hUsb, (USB_INTERFACE_DESCRIPTOR *) &USB_FsConfigDescriptor[sizeof(USB_CONFIGURATION_DESCRIPTOR)], &usb_param.mem_base, &usb_param.mem_size); if (ret == LPC_OK) { /* enable USB interrupts */ NVIC_EnableIRQ(USB0_IRQn); /* now connect */ USBD_API->hw->Connect(g_hUsb, 1); } } while (1) { __WFI(); } }
ErrorCode_t usb_init(void) { uint32_t i; uint32_t uid[4]; /* HARDWARE INIT */ /* Enable AHB clock to the USB block and USB RAM. */ LPC_SYSCON->SYSAHBCLKCTRL |= ((0x1<<14) | (0x1<<27)); /* Pull-down is needed, or internally, VBUS will be floating. This is to address the wrong status in VBUSDebouncing bit in CmdStatus register. */ LPC_IOCON->PIO0_3 &= ~0x1F; LPC_IOCON->PIO0_3 |= (0x01<<0); /* Secondary function VBUS */ LPC_IOCON->PIO0_6 &= ~0x07; LPC_IOCON->PIO0_6 |= (0x01<<0); /* Secondary function SoftConn */ for (i=0; i < strlen(CFG_USB_STRING_MANUFACTURER); i++) USB_StringDescriptor.strManufacturer[i] = CFG_USB_STRING_MANUFACTURER[i]; for (i=0; i < strlen(CFG_USB_STRING_PRODUCT); i++) USB_StringDescriptor.strProduct[i] = CFG_USB_STRING_PRODUCT[i]; /* Use the 128-bit chip ID for USB serial to make sure it's unique */ iapReadUID(uid); /* 1st byte is LSB, 4th byte is MSB */ sprintf((char*)USB_StringDescriptor.strSerial , "%08X%08X%08X%08X", (unsigned int)uid[3], (unsigned int)uid[2], (unsigned int)uid[1], (unsigned int)uid[0]); for (i = USB_STRING_SERIAL_LEN-1; i > 0; i--) { USB_StringDescriptor.strSerial[i] = ((uint8_t*)USB_StringDescriptor.strSerial)[i]; ((uint8_t*)USB_StringDescriptor.strSerial)[i] = 0; } /* ROM DRIVER INIT */ uint32_t membase = (uint32_t) usb_RomDriver_buffer; uint32_t memsize = USB_ROM_SIZE; USBD_API_INIT_PARAM_T usb_param = { .usb_reg_base = LPC_USB_BASE, .max_num_ep = USB_MAX_EP_NUM, .mem_base = membase, .mem_size = memsize, .USB_Configure_Event = USB_Configure_Event, .USB_Reset_Event = USB_Reset_Event }; USB_CORE_DESCS_T DeviceDes = { .device_desc = (uint8_t*) &USB_DeviceDescriptor, .string_desc = (uint8_t*) &USB_StringDescriptor, .full_speed_desc = (uint8_t*) &USB_FsConfigDescriptor, .high_speed_desc = (uint8_t*) &USB_FsConfigDescriptor, .device_qualifier = NULL }; /* Start USB hardware initialisation */ ASSERT_USB_STATUS(USBD_API->hw->Init(&g_hUsb, &DeviceDes, &usb_param)); membase += (memsize - usb_param.mem_size); memsize = usb_param.mem_size; /* Initialise the class driver(s) */ #ifdef CFG_USB_CDC ASSERT_USB_STATUS( usb_cdc_init(g_hUsb, &USB_FsConfigDescriptor.CDC_CCI_Interface, &USB_FsConfigDescriptor.CDC_DCI_Interface, &membase, &memsize) ); #endif #ifdef CFG_USB_HID_KEYBOARD ASSERT_USB_STATUS( usb_hid_init(g_hUsb , &USB_FsConfigDescriptor.HID_KeyboardInterface , HID_KeyboardReportDescriptor, USB_FsConfigDescriptor.HID_KeyboardHID.DescriptorList[0].wDescriptorLength, &membase , &memsize) ); #endif #ifdef CFG_USB_HID_MOUSE ASSERT_USB_STATUS( usb_hid_init(g_hUsb , &USB_FsConfigDescriptor.HID_MouseInterface , HID_MouseReportDescriptor, USB_FsConfigDescriptor.HID_MouseHID.DescriptorList[0].wDescriptorLength, &membase , &memsize) ); #endif #ifdef CFG_USB_HID_GENERIC ASSERT_USB_STATUS( usb_hid_init(g_hUsb , &USB_FsConfigDescriptor.HID_GenericInterface , HID_GenericReportDescriptor, USB_FsConfigDescriptor.HID_GenericHID.DescriptorList[0].wDescriptorLength, &membase , &memsize) ); #endif #ifdef CFG_USB_MSC // there is chance where SD card is not inserted, thus the msc init fails, should continue instead of return if ( usb_msc_init(g_hUsb, &USB_FsConfigDescriptor.MSC_Interface, &membase, &memsize) != LPC_OK) { _PRINTF("MSC class fails to init\n"); } #endif #ifdef CFG_USB_CUSTOM_CLASS ASSERT_USB_STATUS( usb_custom_init(g_hUsb, &USB_FsConfigDescriptor.Custom_Interface) ); #endif /* Enable the USB interrupt */ #if defined CFG_MCU_FAMILY_LPC11UXX NVIC_EnableIRQ(USB_IRQn); #elif defined CFG_MCU_FAMILY_LPC13UXX NVIC_EnableIRQ(USB_IRQ_IRQn); #else #error "No MCU defined" #endif /* Perform USB soft connect */ USBD_API->hw->Connect(g_hUsb, 1); return LPC_OK; } /**************************************************************************/ /*! @brief Redirect the USB IRQ handler to the ROM handler */ /**************************************************************************/ void USB_IRQHandler(void) { USBD_API->hw->ISR(g_hUsb); }
/***************************************************************************** ** Main Function main() *****************************************************************************/ int main (void) { USBD_API_INIT_PARAM_T usb_param; USB_CORE_DESCS_T desc; ErrorCode_t ret; USB_INTERFACE_DESCRIPTOR* pIntfDesc; USB_COMMON_DESCRIPTOR *pD; uint32_t next_desc_adr, total_len = 0; SystemCoreClockUpdate(); /* Setup UART for 115.2K, 8 data bits, no parity, 1 stop bit */ UARTInit(115200); UARTSend((uint8_t *)"\r\nLPC11Uxx USB ROMAPI example>", 31); /* get USB API table pointer */ pUsbApi = (USBD_API_T*)((*(ROM **)(0x1FFF1FF8))->pUSBD); /* enable clocks and pinmux for usb0 */ USB_pin_clk_init(); /* initilize call back structures */ memset((void*)&usb_param, 0, sizeof(USBD_API_INIT_PARAM_T)); usb_param.usb_reg_base = LPC_USB_BASE; usb_param.mem_base = 0x10000800; usb_param.mem_size = 0x0800; usb_param.max_num_ep = 4; usb_param.USB_Configure_Event = USB_Configure_Event; /* Initialize Descriptor pointers */ memset((void*)&desc, 0, sizeof(USB_CORE_DESCS_T)); desc.device_desc = (uint8_t *)&USB_DeviceDescriptor[0]; desc.string_desc = (uint8_t *)&USB_StringDescriptor[0]; desc.full_speed_desc = (uint8_t *)&USB_FsConfigDescriptor[0]; desc.high_speed_desc = (uint8_t *)&USB_FsConfigDescriptor[0]; /* USB Initialization */ ret = pUsbApi->hw->Init(&hUsb, &desc, &usb_param); if (ret == LPC_OK) { pD = (USB_COMMON_DESCRIPTOR *)desc.high_speed_desc; next_desc_adr = (uint32_t)desc.high_speed_desc; while (pD->bLength) { if (pD->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) { pIntfDesc = (USB_INTERFACE_DESCRIPTOR*)pD; switch(pIntfDesc->bInterfaceClass) { case USB_DEVICE_CLASS_STORAGE: ret = usb_msc_mem_init(hUsb, pIntfDesc, &usb_param.mem_base, &usb_param.mem_size); if (ret != LPC_OK) UARTSend((uint8_t *)"\r\n usb_msc_mem_init error!!!", 31); break; case USB_DEVICE_CLASS_APP: ret = usb_dfu_init(hUsb, pIntfDesc, &usb_param.mem_base, &usb_param.mem_size); if (ret != LPC_OK) UARTSend((uint8_t *)"\r\n usb_dfu_init error!!!", 27); break; case USB_DEVICE_CLASS_HUMAN_INTERFACE: ret = usb_hid_init(hUsb, pIntfDesc, &usb_param.mem_base, &usb_param.mem_size); if (ret != LPC_OK) UARTSend((uint8_t *)"\r\n usb_hid_init error!!!", 27); break; } if (ret != LPC_OK) break; /* break while loop no point proceeding further */ } pIntfDesc = 0; total_len += pD->bLength; next_desc_adr = (uint32_t)pD + pD->bLength; pD = (USB_COMMON_DESCRIPTOR*)next_desc_adr; } if (total_len != ((USB_CONFIGURATION_DESCRIPTOR *)desc.high_speed_desc)->wTotalLength) UARTSend((uint8_t *)"\r\nBadly formed config descriptor!!!", 38); if (ret == LPC_OK) { NVIC_EnableIRQ(USB_IRQn); // enable USB interrrupts /* now connect */ pUsbApi->hw->Connect(hUsb, 1); } } else { UARTSend("\r\nhwUSB_Init error!!!", 21); } while (1) { u32Milliseconds = 100; if (dfu_detach_sig) { /* disconnect */ pUsbApi->hw->Connect(hUsb, 0); /* for current test wrap-around condition is overlooked */ while (u32Milliseconds < 98); /* connect the device back */ pUsbApi->hw->Connect(hUsb, 1); dfu_detach_sig = 0; } /* Wait... */ while(u32Milliseconds); } }
/********************************************************************** ** Function name: ** ** Description: ** ** Parameters: ** ** Returned value: **********************************************************************/ void Hid_init (void) { USBD_API_INIT_PARAM_T usb_param; USB_CORE_DESCS_T desc; ErrorCode_t ret; USB_INTERFACE_DESCRIPTOR* pIntfDesc; volatile uint32_t CoreM4Freq; // SystemInit(); // CGU_Init(); CoreM4Freq = CGU_GetPCLKFrequency(CGU_PERIPHERAL_M3CORE); /* Disable PLL first */ CGU_EnableEntity(CGU_CLKSRC_PLL0, DISABLE); /* the usb core require output clock = 480MHz */ if(CGU_SetPLL0() != CGU_ERROR_SUCCESS) while(1); CGU_EntityConnect(CGU_CLKSRC_PLL0, CGU_CLKSRC_PLL0); /* Enable PLL after all setting is done */ CGU_EnableEntity(CGU_CLKSRC_PLL0, ENABLE); /* Re-Update the clock freq */ CGU_UpdateClock(); /* Distribute to USB0 base clock */ CGU_EntityConnect(CGU_CLKSRC_PLL0, CGU_BASE_USB0); /* Generate interrupt @ 1000 Hz */ // SysTick_Config(CGU_GetPCLKFrequency(CGU_PERIPHERAL_M3CORE)/1000); /* initilize call back structures */ memset((void*)&usb_param, 0, sizeof(USBD_API_INIT_PARAM_T)); usb_param.usb_reg_base = LPC_USB0_BASE; usb_param.max_num_ep = 6; usb_param.mem_base = 0x20004000; usb_param.mem_size = 0x2000; usb_param.USB_Configure_Event1 = USB_Configure_Event1; /* for eagle/raptor the local SRAM is not accesable to USB * so copy the descriptors to USB accessable memory */ copy_descriptors(&desc, usb_param.mem_base + usb_param.mem_size); /* Turn on the phy */ LPC_CREG->CREG0 &= ~(1<<5); /* USB Initialization */ ret = USBD_API->hw->Init(&hUsb, &desc, &usb_param); if (ret == LPC_OK) { pIntfDesc = (USB_INTERFACE_DESCRIPTOR*)((uint32_t)desc.high_speed_desc + USB_CONFIGUARTION_DESC_SIZE); ret = usb_hid_init(hUsb, pIntfDesc, &usb_param.mem_base, &usb_param.mem_size); if (ret != LPC_OK) vCatchError(0); //"usb_hid_init error!!!" if (ret == LPC_OK) { NVIC_EnableIRQ(USB0_IRQn); // enable USB0 interrrupts /* now connect */ USBD_API->hw->Connect(hUsb, 1); } } else { vCatchError(1); //"\r\nhwUSB_Init error!!!" } #if 0 while (1) { u32Milliseconds = 100; /* Wait... */ while(u32Milliseconds); } #endif }