lpcware

LPCOpen USB example - hardfault using custom hardware

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by DennisFrie on Sat Jul 05 12:09:00 MST 2014
Hi guys
I'm trying to verify the USB-interface on a platform with LPC1548.

Using LPCOpen and the LPCXpresso 1549 dev. board, the USB examples works as expected.
However, when testing with the custom hardware, I get a hardfault error, that I simply can't find.

Example used:
usbd_rom_cdc

Changed in sysinit.c
In Board_SetupMuxing I've removed all pin-configs and only use:

Chip_IOCON_PinMuxSet(LPC_IOCON, 1, 6, (IOCON_MODE_PULLDOWN | IOCON_DIGMODE_EN)); // USB_VBUS on custrom hardware
Chip_IOCON_PinMuxSet(LPC_IOCON, 1, 11, (IOCON_MODE_PULLDOWN | IOCON_DIGMODE_EN)); // USB_VBUS on LPCXpresso dev board

//Chip_SWM_MovablePinAssign(SWM_USB_VBUS_I, 38); // For testing custom hardware
Chip_SWM_MovablePinAssign(SWM_USB_VBUS_I, 43); // For testing on dev. board


In main:
Board_init removed and only Chip_GPIO_Init(LPC_GPIO) called.

Testing with the dev. the code runs just fine and USB is detected when connected.
When using the custom hardware, the initialization ends in a hardfault error.

This is the last function called, that seems to be causing the problem:
ret = vcom_init(g_hUsb, &desc, &usb_param);

More specific in that function, this is the last call that happens before the hardfault
ret = USBD_API->cdc->init(hUsb, &cdc_param, &g_vCOM.hCdc);

Any good suggestions as to what I'm missing here?
Project settings have been changed to LPC1548 as microcontroller, which loads just fine on LPC1549.

Code copy-pasted here just for quick reference.
Main function:

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 */
//Board_Init();

Chip_GPIO_Init(LPC_GPIO);

/* enable clocks */
Chip_USB_Init();

/* initialize USBD ROM API pointer. */
g_pUsbApi = (const USBD_API_T *) LPC_ROM_API->pUSBD;

/* initialize call back structures */
memset((void *) &usb_param, 0, sizeof(USBD_API_INIT_PARAM_T));
usb_param.usb_reg_base = LPC_USB0_BASE;
/*WORKAROUND for artf44835 ROM driver BUG:
    Code clearing STALL bits in endpoint reset routine corrupts memory area
    next to the endpoint control data. For example When EP0, EP1_IN, EP1_OUT,
    EP2_IN are used we need to specify 3 here. But as a workaround for this
    issue specify 4. So that extra EPs control structure acts as padding buffer
    to avoid data corruption. Corruption of padding memory doesn’t affect the
    stack/program behaviour.
*/
usb_param.max_num_ep = 3 + 1;
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;

/* 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 interrupts */
NVIC_EnableIRQ(USB0_IRQn);
/* now connect */
USBD_API->hw->Connect(g_hUsb, 1);
}

}


vcom_init function

/* Virtual com port init routine */
ErrorCode_t vcom_init(USBD_HANDLE_T hUsb, USB_CORE_DESCS_T *pDesc, USBD_API_INIT_PARAM_T *pUsbParam)
{
USBD_CDC_INIT_PARAM_T cdc_param;
ErrorCode_t ret = LPC_OK;
uint32_t ep_indx;

g_vCOM.hUsb = hUsb;
memset((void *) &cdc_param, 0, sizeof(USBD_CDC_INIT_PARAM_T));
cdc_param.mem_base = pUsbParam->mem_base;
cdc_param.mem_size = pUsbParam->mem_size;
cdc_param.cif_intf_desc = (uint8_t *) find_IntfDesc(pDesc->high_speed_desc, CDC_COMMUNICATION_INTERFACE_CLASS);
cdc_param.dif_intf_desc = (uint8_t *) find_IntfDesc(pDesc->high_speed_desc, CDC_DATA_INTERFACE_CLASS);
cdc_param.SetLineCode = VCOM_SetLineCode;

ret = USBD_API->cdc->init(hUsb, &cdc_param, &g_vCOM.hCdc);

if (ret == LPC_OK) {
/* allocate transfer buffers */
g_vCOM.rx_buff = (uint8_t *) cdc_param.mem_base;
cdc_param.mem_base += VCOM_RX_BUF_SZ;
cdc_param.mem_size -= VCOM_RX_BUF_SZ;

/* register endpoint interrupt handler */
ep_indx = (((USB_CDC_IN_EP & 0x0F) << 1) + 1);
ret = USBD_API->core->RegisterEpHandler(hUsb, ep_indx, VCOM_bulk_in_hdlr, &g_vCOM);
if (ret == LPC_OK) {
/* register endpoint interrupt handler */
ep_indx = ((USB_CDC_OUT_EP & 0x0F) << 1);
ret = USBD_API->core->RegisterEpHandler(hUsb, ep_indx, VCOM_bulk_out_hdlr, &g_vCOM);

}
/* update mem_base and size variables for cascading calls. */
pUsbParam->mem_base = cdc_param.mem_base;
pUsbParam->mem_size = cdc_param.mem_size;
}

return ret;
}

Outcomes