Need help with ADC input on LPC55S69-EVK

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Need help with ADC input on LPC55S69-EVK

2,292 Views
martinfierz
Contributor II

I'm trying to get my LPC55S69-EVK board to do ADC conversions, but either I'm too stupid or the documentation is unclear... I would appreciate any help!

There are demo programs for the ADC, I started with lpadc_polling.c as this seems the simplest version. My goal is to read in a differential 16-bit value but I'm lost. Here are my questions:

1) The readme.txt says I should connect a jumper to P15-2 and P15-3. There is nothing there to connect a jumper to, so am I right to assume that I am supposed to solder a connector in the board there?

2) The function Board_InitPins seems to configure Pin23 as ADC 0_0 - I used the pin configuration tool (MCU config tools -> open pins) to also configure Pin 16 as input. I have pasted the generated BOARD_InitPins below, does that look OK?

3) I used the peripherals tool (MCU config tools -> open peripherals) to configure the ADC to make differential measurements with high resolution. I have pasted the relevant code below.

4) To test, I ran the program, with a connection between A0 and A1 on P19, expecting the ADC to produce 0, but it's producing more or less random numbers somewhere between 1900 and 3000.

Any hints as to where I am going wrong would be very much appreciated!

  best regards

     Martin

Tool-Generated function BOARD_InitPins

void BOARD_InitPins(void)
{
/* Enables the clock for the I/O controller.: Enable Clock. */
CLOCK_EnableClock(kCLOCK_Iocon);

IOCON->PIO[0][16] = ((IOCON->PIO[0][16] &
/* Mask bits to zero which are setting */
(~(IOCON_PIO_FUNC_MASK | IOCON_PIO_MODE_MASK | IOCON_PIO_DIGIMODE_MASK | IOCON_PIO_ASW_MASK)))

/* Selects pin function.
* : PORT016 (pin 14) is configured as ADC0_8. */
| IOCON_PIO_FUNC(PIO0_16_FUNC_ALT0)

/* Selects function mode (on-chip pull-up/pull-down resistor control).
* : Inactive.
* Inactive (no pull-down/pull-up resistor enabled). */
| IOCON_PIO_MODE(PIO0_16_MODE_INACTIVE)

/* Select Digital mode.
* : Disable digital mode.
* Digital input set to 0. */
| IOCON_PIO_DIGIMODE(PIO0_16_DIGIMODE_ANALOG)

/* Analog switch input control.
* : For all pins except PIO0_9, PIO0_11, PIO0_12, PIO0_15, PIO0_18, PIO0_31, PIO1_0 and
* PIO1_9 analog switch is closed (enabled). */
| IOCON_PIO_ASW(PIO0_16_ASW_VALUE1));

const uint32_t port0_pin23_config = (/* Pin is configured as ADC0_0 */
IOCON_PIO_FUNC0 |
/* No addition pin function */
IOCON_PIO_MODE_INACT |
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_SLEW_STANDARD |
/* Input function is not inverted */
IOCON_PIO_INV_DI |
/* Enables analog function */
IOCON_PIO_ANALOG_EN |
/* Open drain is disabled */
IOCON_PIO_OPENDRAIN_DI |
/* Analog switch is closed (enabled) */
IOCON_PIO_ASW_EN);
/* PORT0 PIN23 (coords: 20) is configured as ADC0_0 */
IOCON_PinMuxSet(IOCON, 0U, 23U, port0_pin23_config);

const uint32_t port0_pin29_config = (/* Pin is configured as FC0_RXD_SDA_MOSI_DATA */
IOCON_PIO_FUNC1 |
/* No addition pin function */
IOCON_PIO_MODE_INACT |
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_SLEW_STANDARD |
/* Input function is not inverted */
IOCON_PIO_INV_DI |
/* Enables digital function */
IOCON_PIO_DIGITAL_EN |
/* Open drain is disabled */
IOCON_PIO_OPENDRAIN_DI);
/* PORT0 PIN29 (coords: 92) is configured as FC0_RXD_SDA_MOSI_DATA */
IOCON_PinMuxSet(IOCON, 0U, 29U, port0_pin29_config);

const uint32_t port0_pin30_config = (/* Pin is configured as FC0_TXD_SCL_MISO_WS */
IOCON_PIO_FUNC1 |
/* No addition pin function */
IOCON_PIO_MODE_INACT |
/* Standard mode, output slew rate control is enabled */
IOCON_PIO_SLEW_STANDARD |
/* Input function is not inverted */
IOCON_PIO_INV_DI |
/* Enables digital function */
IOCON_PIO_DIGITAL_EN |
/* Open drain is disabled */
IOCON_PIO_OPENDRAIN_DI);
/* PORT0 PIN30 (coords: 94) is configured as FC0_TXD_SCL_MISO_WS */
IOCON_PinMuxSet(IOCON, 0U, 30U, port0_pin30_config);
}

*********************************** Generated peripherals.c********************

* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */
const lpadc_config_t LPADC_1_config = {
.enableInDozeMode = true,
.conversionAverageMode = kLPADC_ConversionAverage1,
.enableAnalogPreliminary = false,
.powerUpDelay = 0x80,
.referenceVoltageSource = kLPADC_ReferenceVoltageAlt1,
.powerLevelMode = kLPADC_PowerLevelAlt1,
.triggerPriorityPolicy = kLPADC_TriggerPriorityPreemptImmediately,
.enableConvPause = false,
.convPauseDelay = 0,
.FIFO0Watermark = 0,
.FIFO1Watermark = 0
};
lpadc_conv_command_config_t LPADC_1_commandsConfig[1] = {
{
.sampleChannelMode = kLPADC_SampleChannelDiffBothSide,
.channelNumber = 8U,
.chainedNextCommandNumber = 0,
.enableAutoChannelIncrement = false,
.loopCount = 0,
.hardwareAverageMode = kLPADC_HardwareAverageCount1,
.sampleTimeMode = kLPADC_SampleTimeADCK3,
.hardwareCompareMode = kLPADC_HardwareCompareDisabled,
.hardwareCompareValueHigh = 0,
.hardwareCompareValueLow = 0,
.conversionResolutionMode = kLPADC_ConversionResolutionHigh,
.enableWaitTrigger = false
}
};
lpadc_conv_trigger_config_t LPADC_1_triggersConfig[1] = {
{
.targetCommandId = 0,
.delayPower = 0,
.channelAFIFOSelect = 0,
.channelBFIFOSelect = 0,
.priority = 1,
.enableHardwareTrigger = false
}
};

void LPADC_1_init(void) {
/* Initialize LPADC converter */
LPADC_Init(LPADC_1_PERIPHERAL, &LPADC_1_config);
/* Configure conversion command 1. */
LPADC_SetConvCommandConfig(LPADC_1_PERIPHERAL, 1, &LPADC_1_commandsConfig[0]);
/* Configure trigger 0. */
LPADC_SetConvTriggerConfig(LPADC_1_PERIPHERAL, 0, &LPADC_1_triggersConfig[0]);
}

/***********************************************************************************************************************
* Initialization functions
**********************************************************************************************************************/
void BOARD_InitPeripherals(void)
{
/* Initialize components */
LPADC_1_init();
}

/***********************************************************************************************************************
* BOARD_InitBootPeripherals function
**********************************************************************************************************************/
void BOARD_InitBootPeripherals(void)
{
BOARD_InitPeripherals();
}

Labels (1)
0 Kudos
4 Replies

2,077 Views
martinfierz
Contributor II

Dear XiangJun Rong,

thanks for the very prompt reply. I have understood a bit more about the issues, but still not fully. The example program, lpadc_polling.c is using PIO0_23 / ADC0P, which is A1 on P19. If I just run the example, and use a cable from A1/P19 to connect to the adjacent P16, either to GND or +3V3, I get what I expect, namely either 0 from the ADC or 4095.

I have now tried to use 16-bit ADC by adding more configuration things just after the original line in the example:

// from example

mLpadcCommandConfigStruct.channelNumber = DEMO_LPADC_USER_CHANNEL;

// added by me: 

mLpadcCommandConfigStruct.conversionResolutionMode = kLPADC_ConversionResolutionHigh;

But instead of giving me 16 bits, I now get values from 0 to 8191, so only 13 bits. What do I need to do to get the full 16 bits?

Also, I have tried to configure it in differential mode by adding another line 

mLpadcCommandConfigStruct.sampleChannelMode = kLPADC_SampleChannelDiffBothSide;

Then I connected A0 and A1 both to GND, and sometimes the example program says 0 as output as expected, but sometimes also 8191; when I connect A0 to 3V3 and leave A1 on GND, I get 4097, when I switch the two I get 4094 - that looks like it's working perfectly (2's complement).

Can you help me again to understand how I can do a 16 bit conversion rather than 13 bits?

best regards

  Martin

0 Kudos

2,077 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Martin,

Regarding the following code, I think it is correct to set the 16 bits ADC resolution with .conversionResolutionMode = kLPADC_ConversionResolutionHigh. If the code result is not what you expected, you have to check register in debugger, in other words, check the MODE bit in corresponding  ADC command low buffer registersx.

Hope it can help you

BR

XiangJun Rong

lpadc_conv_command_config_t LPADC_1_commandsConfig[1] = {
{
.sampleChannelMode = kLPADC_SampleChannelDiffBothSide,
.channelNumber = 8U,
.chainedNextCommandNumber = 0,
.enableAutoChannelIncrement = false,
.loopCount = 0,
.hardwareAverageMode = kLPADC_HardwareAverageCount1,
.sampleTimeMode = kLPADC_SampleTimeADCK3,
.hardwareCompareMode = kLPADC_HardwareCompareDisabled,
.hardwareCompareValueHigh = 0,
.hardwareCompareValueLow = 0,
.conversionResolutionMode = kLPADC_ConversionResolutionHigh,
.enableWaitTrigger = false
}

0 Kudos

2,077 Views
martinfierz
Contributor II

Dear Xiangjun Rong,

I followed your suggestion, and used the memory monitor in debug mode to inspect the Address 0x500A0100 (ADC base address 0x500A000, Offset for command low register 1 0x100); The value in that register is 0x00000080, i.e. bit 7 is set as it should be for the high resolution mode.

I can also say that in normal mode, I get value 4095 when connecting A1 to 3V3 as expected, in high resolution mode I get value 8191, not as expected (a 13 bit value instead of 16 bit). This is for single-ended conversions, not differential as I did not want to make things more complicated than necessary.

So clearly changing to high-resolution mode of the ADC does change something, but it only gives me 1 bit more for 13 bits, rather than 4 additional bits for the 16 bits that it should.

Is there something I am missing that I need to do for 16 bit conversion?

best regards

  Martin

0 Kudos

2,077 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Martin,

First of all, if you want to measure differential analog voltage, you have to connect the differential signal to P28 as the following screenshot. But I do not know where the differential signal pair come from, if there is not any common ground between the signals and board, you have to connect one small capacitor between  ADC0_P and GND, another capacitor between ADC0_N and GND.

From software side, you can only test ADC channel 0, so

lpadc_conv_command_config_t LPADC_1_commandsConfig[1] = {
{
.sampleChannelMode = kLPADC_SampleChannelDiffBothSide,
.channelNumber = 0U, /////////////**************************************************Rong change
.chainedNextCommandNumber = 0,
.enableAutoChannelIncrement = false,
.loopCount = 0,
.hardwareAverageMode = kLPADC_HardwareAverageCount1,
.sampleTimeMode = kLPADC_SampleTimeADCK3,
.hardwareCompareMode = kLPADC_HardwareCompareDisabled,
.hardwareCompareValueHigh = 0,
.hardwareCompareValueLow = 0,
.conversionResolutionMode = kLPADC_ConversionResolutionHigh,
.enableWaitTrigger = false
}

Regarding your question:

1) The readme.txt says I should connect a jumper to P15-2 and P15-3. There is nothing there to connect a jumper to, so am I right to assume that I am supposed to solder a connector in the board there?

>>>>>>>>The P15 is used to select ADC reference voltage. you can use the default ADC reference voltage, ignore the part.

2) The function Board_InitPins seems to configure Pin23 as ADC 0_0 - I used the pin configuration tool (MCU config tools -> open pins) to also configure Pin 16 as input. I have pasted the generated BOARD_InitPins below, does that look OK?

3) I used the peripherals tool (MCU config tools -> open peripherals) to configure the ADC to make differential measurements with high resolution. I have pasted the relevant code below.

>>>>>>>>You can develop your code to set the pin as analog pin .

4) To test, I ran the program, with a connection between A0 and A1 on P19, expecting the ADC to produce 0, but it's producing more or less random numbers somewhere between 1900 and 3000.

>>>>>>>>>>>>>It is okay to use pin2 and pin4 of P19 as ADC differential signals input.

Hope it can help you

BR

XiangJun Rong

pastedImage_1.png

0 Kudos