1 /*
2 * @brief Vitual communication port example
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 "cdc_vcom.h"
37
38 /*****************************************************************************
39 * Private types/enumerations/variables
40 ****************************************************************************/
41
42 /*****************************************************************************
43 * Public types/enumerations/variables
44 ****************************************************************************/
45
46 static USBD_HANDLE_T g_hUsb;
47 static uint8_t g_rxBuff[256];
48 const USBD_API_T *g_pUsbApi;
49
50 /*****************************************************************************
51 * Private functions
52 ****************************************************************************/
53
54 /*****************************************************************************
55 * Public functions
56 ****************************************************************************/
57
58 /**
59 * @brief Handle interrupt from USB0
60 * @return Nothing
61 */
USB_IRQHandler(void)62 void USB_IRQHandler(void)
63 {
64 USBD_API->hw->ISR(g_hUsb);
65 }
66
67 /* Find the address of interface descriptor for given class type. */
find_IntfDesc(const uint8_t * pDesc,uint32_t intfClass)68 USB_INTERFACE_DESCRIPTOR *find_IntfDesc(const uint8_t *pDesc, uint32_t intfClass)
69 {
70 USB_COMMON_DESCRIPTOR *pD;
71 USB_INTERFACE_DESCRIPTOR *pIntfDesc = 0;
72 uint32_t next_desc_adr;
73
74 pD = (USB_COMMON_DESCRIPTOR *) pDesc;
75 next_desc_adr = (uint32_t) pDesc;
76
77 while (pD->bLength) {
78 /* is it interface descriptor */
79 if (pD->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) {
80
81 pIntfDesc = (USB_INTERFACE_DESCRIPTOR *) pD;
82 /* did we find the right interface descriptor */
83 if (pIntfDesc->bInterfaceClass == intfClass) {
84 break;
85 }
86 }
87 pIntfDesc = 0;
88 next_desc_adr = (uint32_t) pD + pD->bLength;
89 pD = (USB_COMMON_DESCRIPTOR *) next_desc_adr;
90 }
91
92 return pIntfDesc;
93 }
94
95 /**
96 * @brief main routine for blinky example
97 * @return Function should not exit.
98 */
main(void)99 int main(void)
100 {
101 USBD_API_INIT_PARAM_T usb_param;
102 USB_CORE_DESCS_T desc;
103 ErrorCode_t ret = LPC_OK;
104 uint32_t prompt = 0, rdCnt = 0;
105
106 SystemCoreClockUpdate();
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 = 3 + 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[0];
133 desc.string_desc = (uint8_t *) &USB_StringDescriptor[0];
134 /* Note, to pass USBCV test full-speed only devices should have both
135 descriptor arrays point to same location and device_qualifier set to 0.
136 */
137 desc.high_speed_desc = (uint8_t *) &USB_FsConfigDescriptor[0];
138 desc.full_speed_desc = (uint8_t *) &USB_FsConfigDescriptor[0];
139 desc.device_qualifier = 0;
140
141 /* USB Initialization */
142 ret = USBD_API->hw->Init(&g_hUsb, &desc, &usb_param);
143 if (ret == LPC_OK) {
144
145 /* Init VCOM interface */
146 ret = vcom_init(g_hUsb, &desc, &usb_param);
147 if (ret == LPC_OK) {
148 /* enable USB interrupts */
149 NVIC_EnableIRQ(USB0_IRQn);
150 /* now connect */
151 USBD_API->hw->Connect(g_hUsb, 1);
152 }
153
154 }
155
156 DEBUGSTR("USB CDC class based virtual Comm port example!\r\n");
157
158 while (1) {
159 /* Check if host has connected and opened the VCOM port */
160 if ((vcom_connected() != 0) && (prompt == 0)) {
161 vcom_write("Hello World!!\r\n", 15);
162 prompt = 1;
163 }
164 /* If VCOM port is opened echo whatever we receive back to host. */
165 if (prompt) {
166 rdCnt = vcom_bread(&g_rxBuff[0], 256);
167 if (rdCnt) {
168 vcom_write(&g_rxBuff[0], rdCnt);
169 }
170 }
171 /* Sleep until next IRQ happens */
172 __WFI();
173 }
174 }
175