Reading 2 ADC Channels ulp

TheIronMechanc
Posts: 1
Joined: Sun Feb 10, 2019 10:13 pm

Reading 2 ADC Channels ulp

Postby TheIronMechanc » Thu Feb 21, 2019 1:41 am

Hi everyone!
I'm having an Issue with ULP assembler.
I need to read 2 digial inputs with the ulp core.

The way I'm trying to do it is by measuring channel 6 of ADC1 (I'm aware you can't use the second one while using wifi) and comparing the value with a treshold. This works fine with 1 channel. Now I need to measure a second one. so i change the ADC channel and compare it again, but it only works with the first one.

What am I doing wrong?
Do you know a more efficient way of doing it? Kinda like a digital read?

Help would be greatly appreciated, I'm a total assembler noob.

Board: ESP-Wroom-32 dev module

code:

Code: Select all

#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_reg.h"
#include "soc/soc_ulp.h"

/* ADC1 channel 6, GPIO34 */
.set adc_channel, 6

/* Configure the number of ADC samples to average on each measurement.
   For convenience, make it a power of 2. */
.set adc_oversampling_factor_log, 1
.set adc_oversampling_factor, (1 << adc_oversampling_factor_log)

/* Define variables, which go into .bss section (zero-initialized data) */
.bss

/* Low threshold of ADC reading.
   Set by the main program. */
.global low_threshold
low_threshold: .long 0

/* High threshold of ADC reading.
   Set by the main program. */
.global high_threshold
high_threshold: .long 0

/* Counter of measurements done */
.global sample_counter
sample_counter:
.long 0

.global ADC_reading
ADC_reading:
.long 0

.global ADC_reading2
ADC_reading2:
.long 0
/* Code goes into .text section */
.text
.global entry
entry:


/*DEBUG*/
/* Disable hold of GPIO13 output */
WRITE_RTC_REG(RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_HOLD_S, 1, 0)
/* Set the GPIO13 output HIGH */
WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TS_S + 14, 1, 1)

/* increment sample counter */
move r3, sample_counter
ld R2, r3, 0
add R2, R2, 1
st R2, r3, 0

/* do measurements using ADC */
/* r0 will be used as accumulator */
move r0, 0
/* initialize the loop counter */
stage_rst

measure:
/* measure and add value to accumulator */
adc r1, 0, adc_channel + 1
add r0, r0, r1
/* increment loop counter and check exit condition */
stage_inc 1
jumps measure, adc_oversampling_factor, lt

/* divide accumulator by adc_oversampling_factor.
   Since it is chosen as a power of two, use right shift */
rsh r0, r0, adc_oversampling_factor_log
/* averaged value is now in r0; store it into ADC_reading */
move r3, ADC_reading
st r0, r3, 0


/* compare with low_threshold; wake up if value < low_threshold */
/*move r3, low_threshold
ld r3, r3, 0
sub r3, r0, r3
jump led_off, ov


/* compare with high_threshold; wake up if value > high_threshold */
move r3, high_threshold
ld r3, r3, 0
sub r3, r3, r0
jump wake_up, ov

/*ADC1 channel 5, GPIO33*/
.set adc_channel, 5

/* Configure the number of ADC samples to average on each measurement.
   For convenience, make it a power of 2. */
.set adc_oversampling_factor_log, 1
.set adc_oversampling_factor, (1 << adc_oversampling_factor_log)

/* Define variables, which go into .bss section (zero-initialized data) */
/*.bss*/

/*move r0, 0*/
/* initialize the loop counter */
/*stage_rst*/

measure2:
/* measure and add value to accumulator */
adc r1, 0, adc_channel + 1
add r0, r0, r1
/* increment loop counter and check exit condition */
stage_inc 1
jumps measure2, adc_oversampling_factor, lt

/* divide accumulator by adc_oversampling_factor.
   Since it is chosen as a power of two, use right shift */
rsh r0, r0, adc_oversampling_factor_log
/* averaged value is now in r0; store it into ADC_reading2 */
move r3, ADC_reading2
st r0, r3, 0


/* compare with low_threshold; wake up if value < low_threshold */
/*move r3, low_threshold
ld r3, r3, 0
sub r3, r0, r3
jump led_off, ov*/


/* compare with high_threshold; wake up if value > high_threshold */
move r3, high_threshold
ld r3, r3, 0
sub r3, r3, r0
jump wake_up, ov


/* value within range, end the program */
.global exit
exit:


/*DEBUG*/
/* Set the GPIO13 output LOW (clear output) to signal that ULP is now going down */
WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG, RTC_GPIO_OUT_DATA_W1TC_S + 14, 1, 1)
/* Enable hold on GPIO13 output */
WRITE_RTC_REG(RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_HOLD_S, 1, 1)


halt

.global wake_up
wake_up:
/* Check if the system can be woken up */
READ_RTC_FIELD(RTC_CNTL_LOW_POWER_ST_REG, RTC_CNTL_RDY_FOR_WAKEUP)
and r0, r0, 1
jump exit, eq

/* Wake up the SoC, end program */
wake
WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0)
jump exit
Thanks
The Iron Mechanic

subzero
Posts: 3
Joined: Sat Feb 23, 2019 8:18 pm

Re: Reading 2 ADC Channels ulp

Postby subzero » Sun Feb 24, 2019 5:28 pm

Have you tried channel 6 and 7?
Channel 5 is a touch pad and channel 6 and 7 are not.
Channel 4 is also a touch pad, GPIO32.
Maybe they have to be enabled via an RTC command?

Ritesh
Posts: 1383
Joined: Tue Sep 06, 2016 9:37 am
Location: India
Contact:

Re: Reading 2 ADC Channels ulp

Postby Ritesh » Mon Feb 25, 2019 2:42 am

TheIronMechanc wrote:
Thu Feb 21, 2019 1:41 am
Hi everyone!
I'm having an Issue with ULP assembler.
I need to read 2 digial inputs with the ulp core.

The way I'm trying to do it is by measuring channel 6 of ADC1 (I'm aware you can't use the second one while using wifi) and comparing the value with a treshold. This works fine with 1 channel. Now I need to measure a second one. so i change the ADC channel and compare it again, but it only works with the first one.

What am I doing wrong?
Do you know a more efficient way of doing it? Kinda like a digital read?

Help would be greatly appreciated, I'm a total assembler noob.

Board: ESP-Wroom-32 dev module

code:

Code: Select all

#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_io_reg.h"
#include "soc/soc_ulp.h"

/* ADC1 channel 6, GPIO34 */
.set adc_channel, 6

/* Configure the number of ADC samples to average on each measurement.
   For convenience, make it a power of 2. */
.set adc_oversampling_factor_log, 1
.set adc_oversampling_factor, (1 << adc_oversampling_factor_log)

/* Define variables, which go into .bss section (zero-initialized data) */
.bss

/* Low threshold of ADC reading.
   Set by the main program. */
.global low_threshold
low_threshold: .long 0

/* High threshold of ADC reading.
   Set by the main program. */
.global high_threshold
high_threshold: .long 0

/* Counter of measurements done */
.global sample_counter
sample_counter:
.long 0

.global ADC_reading
ADC_reading:
.long 0

.global ADC_reading2
ADC_reading2:
.long 0
/* Code goes into .text section */
.text
.global entry
entry:


/*DEBUG*/
/* Disable hold of GPIO13 output */
WRITE_RTC_REG(RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_HOLD_S, 1, 0)
/* Set the GPIO13 output HIGH */
WRITE_RTC_REG(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TS_S + 14, 1, 1)

/* increment sample counter */
move r3, sample_counter
ld R2, r3, 0
add R2, R2, 1
st R2, r3, 0

/* do measurements using ADC */
/* r0 will be used as accumulator */
move r0, 0
/* initialize the loop counter */
stage_rst

measure:
/* measure and add value to accumulator */
adc r1, 0, adc_channel + 1
add r0, r0, r1
/* increment loop counter and check exit condition */
stage_inc 1
jumps measure, adc_oversampling_factor, lt

/* divide accumulator by adc_oversampling_factor.
   Since it is chosen as a power of two, use right shift */
rsh r0, r0, adc_oversampling_factor_log
/* averaged value is now in r0; store it into ADC_reading */
move r3, ADC_reading
st r0, r3, 0


/* compare with low_threshold; wake up if value < low_threshold */
/*move r3, low_threshold
ld r3, r3, 0
sub r3, r0, r3
jump led_off, ov


/* compare with high_threshold; wake up if value > high_threshold */
move r3, high_threshold
ld r3, r3, 0
sub r3, r3, r0
jump wake_up, ov

/*ADC1 channel 5, GPIO33*/
.set adc_channel, 5

/* Configure the number of ADC samples to average on each measurement.
   For convenience, make it a power of 2. */
.set adc_oversampling_factor_log, 1
.set adc_oversampling_factor, (1 << adc_oversampling_factor_log)

/* Define variables, which go into .bss section (zero-initialized data) */
/*.bss*/

/*move r0, 0*/
/* initialize the loop counter */
/*stage_rst*/

measure2:
/* measure and add value to accumulator */
adc r1, 0, adc_channel + 1
add r0, r0, r1
/* increment loop counter and check exit condition */
stage_inc 1
jumps measure2, adc_oversampling_factor, lt

/* divide accumulator by adc_oversampling_factor.
   Since it is chosen as a power of two, use right shift */
rsh r0, r0, adc_oversampling_factor_log
/* averaged value is now in r0; store it into ADC_reading2 */
move r3, ADC_reading2
st r0, r3, 0


/* compare with low_threshold; wake up if value < low_threshold */
/*move r3, low_threshold
ld r3, r3, 0
sub r3, r0, r3
jump led_off, ov*/


/* compare with high_threshold; wake up if value > high_threshold */
move r3, high_threshold
ld r3, r3, 0
sub r3, r3, r0
jump wake_up, ov


/* value within range, end the program */
.global exit
exit:


/*DEBUG*/
/* Set the GPIO13 output LOW (clear output) to signal that ULP is now going down */
WRITE_RTC_REG(RTC_GPIO_OUT_W1TC_REG, RTC_GPIO_OUT_DATA_W1TC_S + 14, 1, 1)
/* Enable hold on GPIO13 output */
WRITE_RTC_REG(RTC_IO_TOUCH_PAD4_REG, RTC_IO_TOUCH_PAD4_HOLD_S, 1, 1)


halt

.global wake_up
wake_up:
/* Check if the system can be woken up */
READ_RTC_FIELD(RTC_CNTL_LOW_POWER_ST_REG, RTC_CNTL_RDY_FOR_WAKEUP)
and r0, r0, 1
jump exit, eq

/* Wake up the SoC, end program */
wake
WRITE_RTC_FIELD(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN, 0)
jump exit
Thanks
The Iron Mechanic
Hi,

Would you please let me know which ADC channels you are trying to read ADC1? Because, We have almost used all possible channels into ADC1 and didn't face any issue.

Would you please check multi purpose functionality for ADC channel which you are using like that is used into other section or not?
Regards,
Ritesh Prajapati

Who is online

Users browsing this forum: No registered users and 182 guests