4 * Created on: Jun 18, 2015
16 #include "usb_driver.h"
18 #define PDRUNCFGUSEMASK 0x0000E800
19 #define PDRUNCFGMASKTMP 0x000005FF
21 USBD_HANDLE_T g_usb_hnd;
22 const USBD_API_T *g_pUsbApi;
25 /* Find the address of interface descriptor for given class type. */
26 USB_INTERFACE_DESCRIPTOR *find_IntfDesc(const uint8_t *pDesc, uint32_t intfClass)
28 USB_COMMON_DESCRIPTOR *pD;
29 USB_INTERFACE_DESCRIPTOR *pIntfDesc = 0;
30 uint32_t next_desc_adr;
32 pD = (USB_COMMON_DESCRIPTOR *) pDesc;
33 next_desc_adr = (uint32_t) pDesc;
36 /* is it interface descriptor */
37 if (pD->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) {
39 pIntfDesc = (USB_INTERFACE_DESCRIPTOR *) pD;
40 /* did we find the right interface descriptor */
41 if (pIntfDesc->bInterfaceClass == intfClass) {
46 next_desc_adr = (uint32_t) pD + pD->bLength;
47 pD = (USB_COMMON_DESCRIPTOR *) next_desc_adr;
56 void init_usb_clock () {
57 // no need to do this: LPC_SYSCON->PDRUNCFG &= ~(1 << 8);
58 // system_LPC11Uxx.c done that already.
59 // configure SYSAHBCLKCTRL
61 // no need to do this: enabled in ResetISR()
62 //LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 26; // ram1 clock source enable
63 //LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 27; // usbram clock source enable
64 // conf usb main clock
65 LPC_SYSCON->USBCLKSEL = 0;
66 LPC_SYSCON->USBCLKUEN = 0;
67 LPC_SYSCON->USBCLKUEN = 1;
68 LPC_SYSCON->USBCLKDIV = 1;
70 LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 14; // usb clock source
71 //LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 26;
72 LPC_SYSCON->SYSAHBCLKCTRL |= 1 << 27;
75 void init_usb_power () {
77 pdrun = LPC_SYSCON->PDRUNCFG & PDRUNCFGMASKTMP;
78 pdrun &= ~((1 << 10) & PDRUNCFGMASKTMP);
79 LPC_SYSCON->PDRUNCFG = (pdrun | PDRUNCFGUSEMASK);
82 void USB_IRQHandler(void) {
83 uint32_t *addr = (uint32_t *) LPC_USB->EPLISTSTART;
85 /* WORKAROUND for artf32289 ROM driver BUG:
86 As part of USB specification the device should respond
87 with STALL condition for any unsupported setup packet. The host will send
88 new setup packet/request on seeing STALL condition for EP0 instead of sending
89 a clear STALL request. Current driver in ROM doesn't clear the STALL
90 condition on new setup packet which should be fixed.
92 if ( LPC_USB->DEVCMDSTAT & (1 << 8) ) { /* if setup packet is received */
93 addr[0] &= ~(1 << 29); /* clear EP0_OUT stall */
94 addr[2] &= ~(1 << 29); /* clear EP0_IN stall */
96 USBD_API->hw->ISR(g_usb_hnd);
99 int init_usb_driver (USBD_API_INIT_PARAM_T *usb_param) {
100 USB_CORE_DESCS_T desc;
101 ErrorCode_t ret = LPC_OK;
103 g_pUsbApi = (const USBD_API_T *) LPC_ROM_API->usbdApiBase;
104 memset((void *) usb_param, 0, sizeof(USBD_API_INIT_PARAM_T));
105 usb_param->usb_reg_base = LPC_USB_BASE;
106 /* WORKAROUND for artf44835 ROM driver BUG:
107 Code clearing STALL bits in endpoint reset routine corrupts memory area
108 next to the endpoint control data. For example When EP0, EP1_IN, EP1_OUT,
109 EP2_IN are used we need to specify 3 here. But as a workaround for this
110 issue specify 4. So that extra EPs control structure acts as padding buffer
111 to avoid data corruption. Corruption of padding memory doesn’t affect the
112 stack/program behaviour.
114 usb_param->max_num_ep = 2 + 1;
115 usb_param->mem_base = USB_STACK_MEM_BASE;
116 usb_param->mem_size = USB_STACK_MEM_SIZE;
118 desc.device_desc = (uint8_t *) USB_DeviceDescriptor;
119 desc.string_desc = (uint8_t *) USB_StringDescriptor;
121 desc.high_speed_desc = USB_FsConfigDescriptor;
122 desc.full_speed_desc = USB_FsConfigDescriptor;
123 desc.device_qualifier = 0;
125 ret = USBD_API->hw->Init(&g_usb_hnd, &desc, usb_param);
126 if (ret != LPC_OK) return -1;
128 usb_param->mem_base = USB_STACK_MEM_BASE + (USB_STACK_MEM_SIZE - usb_param->mem_size);
134 int init_usb_hid (USBD_API_INIT_PARAM_T *usb_param,
135 HID_GetReport_Func_T getreport_fun, HID_SetReport_Func_T setreport_fun,
136 HID_EpIn_Hdlr_Func_T epin_hdlr_fun, HID_EpOut_Hdlr_Func_T epout_hdlr_fun,
137 uint8_t** report_saddr, int report_size) {
138 USBD_HID_INIT_PARAM_T hid_param;
139 USB_HID_REPORT_T reports_data[1];
140 ErrorCode_t ret = LPC_OK;
142 memset((void *) &hid_param, 0, sizeof(USBD_HID_INIT_PARAM_T));
143 hid_param.max_reports = 1;
145 /* Init reports_data */
146 reports_data[0].len = hid_report_size;
147 reports_data[0].idle_time = 0;
148 reports_data[0].desc = (uint8_t *) &HID_ReportDescriptor[0];
150 USB_INTERFACE_DESCRIPTOR *pIntfDesc = (USB_INTERFACE_DESCRIPTOR *) &USB_FsConfigDescriptor[sizeof(USB_CONFIGURATION_DESCRIPTOR)];
152 if ((pIntfDesc == 0) || (pIntfDesc->bInterfaceClass != USB_DEVICE_CLASS_HUMAN_INTERFACE)) {
156 hid_param.mem_base = usb_param->mem_base;
157 hid_param.mem_size = usb_param->mem_size;
158 hid_param.intf_desc = (uint8_t *) pIntfDesc;
159 /* user defined functions */
160 hid_param.HID_GetReport = getreport_fun;
161 hid_param.HID_SetReport = setreport_fun;
162 hid_param.HID_EpIn_Hdlr = epin_hdlr_fun;
163 hid_param.HID_EpOut_Hdlr = epout_hdlr_fun;
164 hid_param.report_data = reports_data;
166 ret = USBD_API->hid->init(g_usb_hnd, &hid_param);
167 if (ret != LPC_OK) return -2;
168 /* allocate USB accessable memory space for report data */
169 *report_saddr = (uint8_t *) hid_param.mem_base;
170 memset (hid_param.mem_base, 0, report_size);
171 hid_param.mem_base += report_size;
172 hid_param.mem_size -= report_size;
173 /* update memory variables */
174 usb_param->mem_base = hid_param.mem_base;
175 usb_param->mem_size = hid_param.mem_size;
179 void connect_to_usb_bus () {
180 NVIC_EnableIRQ (USB_IRQn);
181 USBD_API->hw->Connect (g_usb_hnd, 1);
184 void disconnect_to_usb_bus () {
185 USBD_API->hw->Connect (g_usb_hnd, 0);
186 NVIC_DisableIRQ (USB_IRQn);