1 /*
2 * @brief This file contains USB HID Mouse example using USB ROM Drivers.
3 *
4 * @note
5 * Copyright(C) NXP Semiconductors, 2013
6 * All rights reserved.
7 *
8 * @par
9 * Software that is described herein is for illustrative purposes only
10 * which provides customers with programming information regarding the
11 * LPC products. This software is supplied "AS IS" without any warranties of
12 * any kind, and NXP Semiconductors and its licensor disclaim any and
13 * all warranties, express or implied, including all implied warranties of
14 * merchantability, fitness for a particular purpose and non-infringement of
15 * intellectual property rights. NXP Semiconductors assumes no responsibility
16 * or liability for the use of the software, conveys no license or rights under any
17 * patent, copyright, mask work right, or any other intellectual property rights in
18 * or to any products. NXP Semiconductors reserves the right to make changes
19 * in the software without notification. NXP Semiconductors also makes no
20 * representation or warranty that such application will be suitable for the
21 * specified use without further testing or modification.
22 *
23 * @par
24 * Permission to use, copy, modify, and distribute this software and its
25 * documentation is hereby granted, under NXP Semiconductors' and its
26 * licensor's relevant copyrights in the software, without fee, provided that it
27 * is used in conjunction with NXP Semiconductors microcontrollers. This
28 * copyright, permission, and disclaimer notice must appear in all copies of
29 * this code.
30 */
31
32 #include "board.h"
33 #include <stdio.h>
34 #include <string.h>
35 #include "app_usbd_cfg.h"
36 #include "hid_mouse.h"
37 #include "cdc_vcom.h"
38
39 /*****************************************************************************
40 * Private types/enumerations/variables
41 ****************************************************************************/
42
43 /*****************************************************************************
44 * Public types/enumerations/variables
45 ****************************************************************************/
46
47 static USBD_HANDLE_T g_hUsb;
48 static uint8_t g_rxBuff[256];
49 const USBD_API_T *g_pUsbApi;
50
51 /*****************************************************************************
52 * Private functions
53 ****************************************************************************/
54
55 /*****************************************************************************
56 * Public functions
57 ****************************************************************************/
58
59 /**
60 * @brief Handle interrupt from USB0
61 * @return Nothing
62 */
USB_IRQHandler(void)63 void USB_IRQHandler(void)
64 {
65 USBD_API->hw->ISR(g_hUsb);
66 }
67
68 /* Find the address of interface descriptor for given class type. */
find_IntfDesc(const uint8_t * pDesc,uint32_t intfClass)69 USB_INTERFACE_DESCRIPTOR *find_IntfDesc(const uint8_t *pDesc, uint32_t intfClass)
70 {
71 USB_COMMON_DESCRIPTOR *pD;
72 USB_INTERFACE_DESCRIPTOR *pIntfDesc = 0;
73 uint32_t next_desc_adr;
74
75 pD = (USB_COMMON_DESCRIPTOR *) pDesc;
76 next_desc_adr = (uint32_t) pDesc;
77
78 while (pD->bLength) {
79 /* is it interface descriptor */
80 if (pD->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) {
81
82 pIntfDesc = (USB_INTERFACE_DESCRIPTOR *) pD;
83 /* did we find the right interface descriptor */
84 if (pIntfDesc->bInterfaceClass == intfClass) {
85 break;
86 }
87 }
88 pIntfDesc = 0;
89 next_desc_adr = (uint32_t) pD + pD->bLength;
90 pD = (USB_COMMON_DESCRIPTOR *) next_desc_adr;
91 }
92
93 return pIntfDesc;
94 }
95
96 /**
97 * @brief main routine for blinky example
98 * @return Function should not exit.
99 */
main(void)100 int main(void)
101 {
102 USBD_API_INIT_PARAM_T usb_param;
103 USB_CORE_DESCS_T desc;
104 ErrorCode_t ret = LPC_OK;
105 uint32_t prompt = 0, rdCnt = 0;
106
107 /* Initialize board and chip */
108 Board_Init();
109
110 /* enable clocks */
111 Chip_USB_Init();
112
113 /* initialize USBD ROM API pointer. */
114 g_pUsbApi = (const USBD_API_T *) LPC_ROM_API->pUSBD;
115
116 /* initialize call back structures */
117 memset((void *) &usb_param, 0, sizeof(USBD_API_INIT_PARAM_T));
118 usb_param.usb_reg_base = LPC_USB0_BASE;
119 /* WORKAROUND for artf44835 ROM driver BUG:
120 Code clearing STALL bits in endpoint reset routine corrupts memory area
121 next to the endpoint control data. For example When EP0, EP1_IN, EP1_OUT,
122 EP2_IN are used we need to specify 3 here. But as a workaround for this
123 issue specify 4. So that extra EPs control structure acts as padding buffer
124 to avoid data corruption. Corruption of padding memory doesn’t affect the
125 stack/program behaviour.
126 */
127 usb_param.max_num_ep = 4 + 1;
128 usb_param.mem_base = USB_STACK_MEM_BASE;
129 usb_param.mem_size = USB_STACK_MEM_SIZE;
130
131 /* Set the USB descriptors */
132 desc.device_desc = (uint8_t *) USB_DeviceDescriptor;
133 desc.string_desc = (uint8_t *) USB_StringDescriptor;
134
135 /* Note, to pass USBCV test full-speed only devices should have both
136 * descriptor arrays point to same location and device_qualifier set
137 * to 0.
138 */
139 desc.high_speed_desc = USB_FsConfigDescriptor;
140 desc.full_speed_desc = USB_FsConfigDescriptor;
141 desc.device_qualifier = 0;
142
143 /* USB Initialization */
144 ret = USBD_API->hw->Init(&g_hUsb, &desc, &usb_param);
145 if (ret == LPC_OK) {
146
147 ret = Mouse_Init(g_hUsb,
148 (USB_INTERFACE_DESCRIPTOR *) find_IntfDesc(desc.high_speed_desc,
149 USB_DEVICE_CLASS_HUMAN_INTERFACE),
150 &usb_param.mem_base, &usb_param.mem_size);
151 if (ret == LPC_OK) {
152 /* Init VCOM interface */
153 ret = vcom_init(g_hUsb, &desc, &usb_param);
154 if (ret == LPC_OK) {
155 /* enable USB interrupts */
156 NVIC_EnableIRQ(USB0_IRQn);
157 /* now connect */
158 USBD_API->hw->Connect(g_hUsb, 1);
159 }
160 }
161 }
162
163 while (1) {
164 /* If everything went well with stack init do the tasks or else sleep */
165 if (ret == LPC_OK) {
166 /* Do Mouse tasks */
167 Mouse_Tasks();
168
169 /* Check if host has connected and opened the VCOM port */
170 if ((vcom_connected() != 0) && (prompt == 0)) {
171 vcom_write("Hello World!!\r\n", 15);
172 prompt = 1;
173 }
174 /* If VCOM port is opened echo whatever we receive back to host. */
175 if (prompt) {
176 rdCnt = vcom_bread(&g_rxBuff[0], 256);
177 if (rdCnt) {
178 vcom_write(&g_rxBuff[0], rdCnt);
179 }
180 }
181 }
182
183 /* Sleep until next IRQ happens */
184 __WFI();
185 }
186 }
187