AnsweredAssumed Answered

LPC4370 ADC gives incorrect data

Question asked by Richard Marquardt on Dec 19, 2016

Hi,

we are using LPC4370 with LPCexpresso for high speed meassurement. The microcontroller gives control signals to 4 analog multiplexer (8:1). Simultaneously, the same microcontroller is used for reading the ouput signals of the four multiplexer. The 4 output signals is given to ADC GPIOS. These input GPIOS have the same initialisation. However, just 3 of them works. The last GPIO gives wrong data. Do you have same experiences, any suggestions or tips ?

 

The initialisation code is attached below:     

int main(void)
{
USBD_API_INIT_PARAM_T usb_param;
USB_CORE_DESCS_T desc;
ErrorCode_t ret = LPC_OK;
USB_CORE_CTRL_T *pCtrl;

/* Initialize board and chip */
SystemCoreClockUpdate();
Board_Init();

/* enable clocks and pinmux */
USB_init_pin_clk();

/* Setting up the HSADC clock is more complex than other peripherals.
The HSADC clock is driven directly from the CGU/CCU and has limited
source and divider options. Because the HSADC clocking is entirely
handled outside the HSADC peripheral, example code for setting up
the CGU/CCU to get a rough HSADC clock rate is included in this
example. */

Chip_USB0_Init(); /* Initialize the USB0 PLL to 480 MHz */
Chip_Clock_SetDivider(CLK_IDIV_A, CLKIN_USBPLL, 4); /* Source DIV_A from USB0PLL, and set divider to 2 (Max div value supported is 4) [IN 480 MHz; OUT 120 MHz */
Chip_Clock_SetDivider(CLK_IDIV_B, CLKIN_IDIVA, 15); /* Source DIV_B from DIV_A, [IN 120 MHz; OUT 8 MHz */
Chip_Clock_SetBaseClock(CLK_BASE_ADCHS, CLKIN_IDIVB, true, false); /* Source ADHCS base clock from DIV_B */
Chip_Clock_EnableOpts(CLK_ADCHS, true, true, 1); /* Enable the clock */

/* Initialize HSADC */
Chip_HSADC_Init(LPC_ADCHS);

/* Setup FIFO trip points for interrupt/DMA to 8 samples, no packing */
Chip_HSADC_SetupFIFO(LPC_ADCHS, 8, false);

/* Software trigger only, 0x90 recovery clocks, add channel IF to FIFO entry */
Chip_HSADC_ConfigureTrigger(LPC_ADCHS, HSADC_CONFIG_TRIGGER_SW,
HSADC_CONFIG_TRIGGER_RISEEXT, HSADC_CONFIG_TRIGGER_NOEXTSYNC,
HSADC_CHANNEL_ID_EN_ADD, 0x90);

/* Select both positive and negative DC biasing for input 3 */
//Chip_HSADC_SetACDCBias(LPC_ADCHS, 3, HSADC_CHANNEL_DCBIAS, HSADC_CHANNEL_DCBIAS);
Chip_HSADC_SetACDCBias(LPC_ADCHS, 0, HSADC_CHANNEL_DCBIAS, HSADC_CHANNEL_NODCBIAS);

/* Set low A threshold to 10% and high A threshold to 90% */
Chip_HSADC_SetThrLowValue(LPC_ADCHS, 0, ((HSADC_MAX_SAMPLEVAL * 1) / 10));
Chip_HSADC_SetThrHighValue(LPC_ADCHS, 0, ((HSADC_MAX_SAMPLEVAL * 9) / 10));

/* Set low B threshold to 40% and high B threshold to 60% */
Chip_HSADC_SetThrLowValue(LPC_ADCHS, 1, ((HSADC_MAX_SAMPLEVAL * 4) / 10));
Chip_HSADC_SetThrHighValue(LPC_ADCHS, 1, ((HSADC_MAX_SAMPLEVAL * 6) / 10));

/* Setup data format for 2's complement and update clock settings. This function
should be called whenever a clock change is made to the HSADC */
Chip_HSADC_SetPowerSpeed(LPC_ADCHS, false);

/* Enable HSADC power */
Chip_HSADC_EnablePower(LPC_ADCHS);

/* Setup HSADC table 0 descriptors */
/* Descriptor entries are mapped as follows */
/* 0-1 : mapped to input 0, branch to next descriptor after sample, match time
is 1 test against no threshold */
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 0, (HSADC_DESC_CH(0) |
HSADC_DESC_BRANCH_NEXT | HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE |
HSADC_DESC_RESET_TIMER));

Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 1, (HSADC_DESC_CH(0) |
HSADC_DESC_BRANCH_NEXT | HSADC_DESC_MATCH(1) |
HSADC_DESC_THRESH_NONE | HSADC_DESC_RESET_TIMER));
/* 2-3 : mapped to input 1, branch to next descriptor after sample, match time
is 1 test against no threshold */
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 2, (HSADC_DESC_CH(1) |
HSADC_DESC_BRANCH_NEXT | HSADC_DESC_MATCH(1) |
HSADC_DESC_THRESH_NONE | HSADC_DESC_RESET_TIMER));

Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 3, (HSADC_DESC_CH(1) |
HSADC_DESC_BRANCH_NEXT | HSADC_DESC_MATCH(1) |
HSADC_DESC_THRESH_A | HSADC_DESC_RESET_TIMER));
/* 4-5 : mapped to input 2, branch to next descriptor after sample, match time
is 1 test against no threshold */
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 4, (HSADC_DESC_CH(2) |
HSADC_DESC_BRANCH_NEXT | HSADC_DESC_MATCH(1) |
HSADC_DESC_THRESH_NONE | HSADC_DESC_RESET_TIMER));

Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 5, (HSADC_DESC_CH(2) |
HSADC_DESC_BRANCH_NEXT | HSADC_DESC_MATCH(1) |
HSADC_DESC_THRESH_NONE | HSADC_DESC_RESET_TIMER));
/* 6-7 : mapped to input 3, branch to next descriptor after sample, match time
is 1 test against no threshold */
Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 6, (HSADC_DESC_CH(3) |
HSADC_DESC_BRANCH_NEXT | HSADC_DESC_MATCH(1) |
HSADC_DESC_THRESH_NONE | HSADC_DESC_RESET_TIMER));

Chip_HSADC_SetupDescEntry(LPC_ADCHS, 0, 7, (HSADC_DESC_CH(3) |
HSADC_DESC_BRANCH_FIRST | HSADC_DESC_INT |
HSADC_DESC_MATCH(1) | HSADC_DESC_THRESH_NONE | HSADC_DESC_RESET_TIMER));

/* Setup HSADC interrupts on group 0 - FIFO trip (full), FIFO overrun
error, and descriptor statuses */
Chip_HSADC_EnableInts(LPC_ADCHS, 0, (HSADC_INT0_FIFO_FULL));


/* Init USB API structure */
g_pUsbApi = (const USBD_API_T *) LPC_ROM_API->usbdApiBase;

/* initialize call back structures */
memset((void *) &usb_param, 0, sizeof(USBD_API_INIT_PARAM_T));
usb_param.usb_reg_base = LPC_USB_BASE;
usb_param.max_num_ep = 4;
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;
desc.string_desc = (uint8_t *) USB_StringDescriptor;
#ifdef USE_USB0
desc.high_speed_desc = USB_HsConfigDescriptor;
desc.full_speed_desc = USB_FsConfigDescriptor;
desc.device_qualifier = (uint8_t *) USB_DeviceQualifier;
#else
/* 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 = USB_FsConfigDescriptor;
desc.full_speed_desc = USB_FsConfigDescriptor;
desc.device_qualifier = 0;
#endif

/* USB Initialization */
ret = USBD_API->hw->Init(&g_hUsb, &desc, &usb_param);
if (ret == LPC_OK) {

/* WORKAROUND for artf45032 ROM driver BUG:
Due to a race condition there is the chance that a second NAK event will
occur before the default endpoint0 handler has completed its preparation
of the DMA engine for the first NAK event. This can cause certain fields
in the DMA descriptors to be in an invalid state when the USB controller
reads them, thereby causing a hang.
*/
pCtrl = (USB_CORE_CTRL_T *) g_hUsb; /* convert the handle to control structure */
g_Ep0BaseHdlr = pCtrl->ep_event_hdlr[0];/* retrieve the default EP0_OUT handler */
pCtrl->ep_event_hdlr[0] = EP0_patch;/* set our patch routine as EP0_OUT handler */

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

/* Initial all GPIO */
Chip_GPIO_Init(LPC_GPIO_PORT);
Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 3, 1);
Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 1, 1);
Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 1, 3);
Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 1, 12);


/* Set them low for mux_state = 0 */
Chip_GPIO_SetPinOutLow(LPC_GPIO_PORT, 3, 1);
Chip_GPIO_SetPinOutLow(LPC_GPIO_PORT, 1, 1);
Chip_GPIO_SetPinOutLow(LPC_GPIO_PORT, 1, 3);
Chip_GPIO_SetPinOutLow(LPC_GPIO_PORT, 1, 12);

/* Enable HSADC interrupts in NVIC */
NVIC_EnableIRQ(ADCHS_IRQn);

/* Update descriptor tables - needed after updating any descriptors */
Chip_HSADC_UpdateDescTable(LPC_ADCHS, 0);

/* Chose active Descriptor */
Chip_HSADC_SetActiveDescriptor(LPC_ADCHS, 0, 0);

/* Initial Descriptor with Software-Trigger */
Chip_HSADC_SWTrigger(LPC_ADCHS);

/* Sleep while waiting for conversions */
while (1) {
__WFI();
}
}

 

Thank you for your help and comments. 

Outcomes