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