AnsweredAssumed Answered

Copying USB vcom example on LPC11u24 - what am I doing wrong?

Question asked by Matt Hollands on Feb 13, 2017
Latest reply on Feb 16, 2017 by LPCX presso support

New to the forum so hi!

 

I have developed my own board using an LPC11U24 chip and want to be able to have a USB virtual serial port so that I can communicate with the chip over USB. I have downloaded the LPCOpen libraries and if I build and flash the nxp_lpcxpresso_11u14_usbd_lib_cdc example to the chip then /dev/ttyACM0 appears on my PC and I can open a serial terminal and have my text echoed back.

 

But I have been trying to copy the code from nxp_lpcxpresso_11u14_usbd_lib_cdc into my own project and I am never able to get /dev/ttyACMx to appear. Specifically vcom_connected() always returns false in my application. I'm really not sure what I am missing!

 

Here is the code. As you can see, it is largely borrowed from the nxp_lpcxpresso_11u14_usbd_lib_cdc example so I'm not sure what I am missing. This has been doing my head in for weeks!

#include "chip.h"
#include "Pin.h" //my own thing
#include "PinAssignments.h" //my own thing
#include "SevenSegmentDriver.h" //my own thing
#include "Button.h" //my own thing
#include "LED.h" //my own thing
#include "TestFunctions.h" //my own thing
#include "app_usbd_cfg.h" //referencing nxp_lpcxpresso_11u14_usbd_lib_cdc
#include "cdc_vcom.h" //referencing nxp_lpcxpresso_11u14_usbd_lib_cdc
#include "cdc_vcom.c" //referencing nxp_lpcxpresso_11u14_usbd_lib_cdc
#include "cdc_desc.c" //referencing nxp_lpcxpresso_11u14_usbd_lib_cdc
#include <string.h>

 

//COPIED FROM nxp_lpcxpresso_11u14_usbd_lib_cdc

/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/

static USBD_HANDLE_T g_hUsb;
static uint8_t g_rxBuff[256];

extern const USBD_HW_API_T hw_api;
extern const USBD_CORE_API_T core_api;
extern const USBD_CDC_API_T cdc_api;
/* Since this example only uses CDC class link functions for that clas only */
static const USBD_API_T g_usbApi = {
&hw_api,
&core_api,
0,
0,
0,
&cdc_api,
0,
0x02221101,
};

const USBD_API_T *g_pUsbApi = &g_usbApi;

 

/*****************************************************************************
* Private functions
****************************************************************************/

/* Initialize pin and clocks for USB0/USB1 port */
static void usb_pin_clk_init(void)
{
/* enable USB main clock */
Chip_Clock_SetUSBClockSource(SYSCTL_USBCLKSRC_PLLOUT, 1);
/* Enable AHB clock to the USB block and USB RAM. */
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_USB);
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_USBRAM);
/* power UP USB Phy */
Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_USBPAD_PD);
}

 

/*****************************************************************************
* Public functions
****************************************************************************/

/**
* @brief Handle interrupt from USB0
* @return Nothing
*/
void USB_IRQHandler(void)
{
USBD_API->hw->ISR(g_hUsb);
}

 

/* Find the address of interface descriptor for given class type. */
USB_INTERFACE_DESCRIPTOR *find_IntfDesc(const uint8_t *pDesc, uint32_t intfClass)
{
USB_COMMON_DESCRIPTOR *pD;
USB_INTERFACE_DESCRIPTOR *pIntfDesc = 0;
uint32_t next_desc_adr;

pD = (USB_COMMON_DESCRIPTOR *) pDesc;
next_desc_adr = (uint32_t) pDesc;

while (pD->bLength) {
/* is it interface descriptor */
if (pD->bDescriptorType == USB_INTERFACE_DESCRIPTOR_TYPE) {

pIntfDesc = (USB_INTERFACE_DESCRIPTOR *) pD;
/* did we find the right interface descriptor */
if (pIntfDesc->bInterfaceClass == intfClass) {
break;
}
}
pIntfDesc = 0;
next_desc_adr = (uint32_t) pD + pD->bLength;
pD = (USB_COMMON_DESCRIPTOR *) next_desc_adr;
}

return pIntfDesc;
}

 

int main(void) {
USBD_API_INIT_PARAM_T usb_param;
USB_CORE_DESCS_T desc;
ErrorCode_t ret = LPC_OK;
uint32_t prompt = 0, rdCnt = 0;

SystemCoreClockUpdate();

/* Initialize board and chip */
Chip_GPIO_Init(LPC_GPIO);
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 11, 1); //set red led pin function to IO

/* enable clocks and pinmux */
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_USB0_BASE;
usb_param.max_num_ep = 3;
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[0];
desc.string_desc = (uint8_t *) &USB_StringDescriptor[0];
/* 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 = (uint8_t *) &USB_FsConfigDescriptor[0];
desc.full_speed_desc = (uint8_t *) &USB_FsConfigDescriptor[0];
desc.device_qualifier = 0;

//LEDS
LED yellowLED(LEDPins[0]);
LED redLED(LEDPins[1]);
yellowLED = 0;
redLED = 1;

/* USB Initialization */
ret = USBD_API->hw->Init(&g_hUsb, &desc, &usb_param);
if (ret == LPC_OK) {
/* Init VCOM interface */
ret = vcom_init(g_hUsb, &desc, &usb_param);
if (ret == LPC_OK) {
/* enable USB interrrupts */
NVIC_EnableIRQ(USB0_IRQn);
/* now connect */
USBD_API->hw->Connect(g_hUsb, 1);
}

}

redLED = 0;

while (1) {
/* Check if host has connected and opened the VCOM port */
//if ((vcom_connected() != 0) && (prompt == 0)) {
// vcom_write("Hello World!!\r\n", 15);
// prompt = 1;
//}
yellowLED = vcom_connected();
/* If VCOM port is opened echo whatever we receive back to host. */
if (1==1 || prompt) {
rdCnt = vcom_bread(&g_rxBuff[0], 256);
if (rdCnt) {
vcom_write(&g_rxBuff[0], rdCnt);
}
}
/* Sleep until next IRQ happens */
__WFI();
}
}

Outcomes