mirror of
https://gitee.com/beecue/fastbee.git
synced 2025-12-20 01:45:55 +08:00
添加智能灯固件代码
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
idf_component_register(SRCS "ulp_adc_example_main.c"
|
||||
INCLUDE_DIRS ""
|
||||
REQUIRES soc nvs_flash ulp driver)
|
||||
#
|
||||
# ULP support additions to component CMakeLists.txt.
|
||||
#
|
||||
# 1. The ULP app name must be unique (if multiple components use ULP).
|
||||
set(ulp_app_name ulp_${COMPONENT_NAME})
|
||||
#
|
||||
# 2. Specify all assembly source files.
|
||||
# Files should be placed into a separate directory (in this case, ulp/),
|
||||
# which should not be added to COMPONENT_SRCS.
|
||||
set(ulp_s_sources "ulp/adc.S")
|
||||
#
|
||||
# 3. List all the component source files which include automatically
|
||||
# generated ULP export file, ${ulp_app_name}.h:
|
||||
set(ulp_exp_dep_srcs "ulp_adc_example_main.c")
|
||||
#
|
||||
# 4. Call function to build ULP binary and embed in project using the argument
|
||||
# values above.
|
||||
ulp_embed_binary(${ulp_app_name} "${ulp_s_sources}" "${ulp_exp_dep_srcs}")
|
||||
@@ -0,0 +1,23 @@
|
||||
#
|
||||
# ULP support additions to component makefile.
|
||||
#
|
||||
# 1. ULP_APP_NAME must be unique (if multiple components use ULP)
|
||||
# Default value, override if necessary:
|
||||
ULP_APP_NAME ?= ulp_$(COMPONENT_NAME)
|
||||
#
|
||||
# 2. Specify all assembly source files here.
|
||||
# Files should be placed into a separate directory (in this case, ulp/),
|
||||
# which should not be added to COMPONENT_SRCDIRS.
|
||||
ULP_S_SOURCES = $(addprefix $(COMPONENT_PATH)/ulp/, \
|
||||
adc.S \
|
||||
)
|
||||
#
|
||||
# 3. List all the component object files which include automatically
|
||||
# generated ULP export file, $(ULP_APP_NAME).h:
|
||||
ULP_EXP_DEP_OBJECTS := ulp_adc_example_main.o
|
||||
#
|
||||
# 4. Include build rules for ULP program
|
||||
include $(IDF_PATH)/components/ulp/component_ulp_common.mk
|
||||
#
|
||||
# End of ULP support additions to component makefile.
|
||||
#
|
||||
@@ -0,0 +1,115 @@
|
||||
/* ULP Example: using ADC in deep sleep
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
|
||||
This file contains assembly code which runs on the ULP.
|
||||
|
||||
ULP wakes up to run this code at a certain period, determined by the values
|
||||
in SENS_ULP_CP_SLEEP_CYCx_REG registers. On each wake up, the program
|
||||
measures input voltage on the given ADC channel 'adc_oversampling_factor'
|
||||
times. Measurements are accumulated and average value is calculated.
|
||||
Average value is compared to the two thresholds: 'low_thr' and 'high_thr'.
|
||||
If the value is less than 'low_thr' or more than 'high_thr', ULP wakes up
|
||||
the chip from deep sleep.
|
||||
*/
|
||||
|
||||
/* ULP assembly files are passed through C preprocessor first, so include directives
|
||||
and C macros may be used in these files
|
||||
*/
|
||||
#include "soc/rtc_cntl_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, 2
|
||||
.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_thr
|
||||
low_thr:
|
||||
.long 0
|
||||
|
||||
/* High threshold of ADC reading.
|
||||
Set by the main program. */
|
||||
.global high_thr
|
||||
high_thr:
|
||||
.long 0
|
||||
|
||||
/* Counter of measurements done */
|
||||
.global sample_counter
|
||||
sample_counter:
|
||||
.long 0
|
||||
|
||||
.global last_result
|
||||
last_result:
|
||||
.long 0
|
||||
|
||||
/* Code goes into .text section */
|
||||
.text
|
||||
.global entry
|
||||
entry:
|
||||
/* 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 last_result */
|
||||
move r3, last_result
|
||||
st r0, r3, 0
|
||||
|
||||
/* compare with low_thr; wake up if value < low_thr */
|
||||
move r3, low_thr
|
||||
ld r3, r3, 0
|
||||
sub r3, r0, r3
|
||||
jump wake_up, ov
|
||||
|
||||
/* compare with high_thr; wake up if value > high_thr */
|
||||
move r3, high_thr
|
||||
ld r3, r3, 0
|
||||
sub r3, r3, r0
|
||||
jump wake_up, ov
|
||||
|
||||
/* value within range, end the program */
|
||||
.global exit
|
||||
exit:
|
||||
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)
|
||||
halt
|
||||
@@ -0,0 +1,100 @@
|
||||
/* ULP Example
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "esp_sleep.h"
|
||||
#include "nvs.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/sens_reg.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/rtc_io.h"
|
||||
#include "driver/adc.h"
|
||||
#include "driver/dac.h"
|
||||
#include "esp32/ulp.h"
|
||||
#include "ulp_main.h"
|
||||
|
||||
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
|
||||
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
|
||||
|
||||
/* This function is called once after power-on reset, to load ULP program into
|
||||
* RTC memory and configure the ADC.
|
||||
*/
|
||||
static void init_ulp_program(void);
|
||||
|
||||
/* This function is called every time before going into deep sleep.
|
||||
* It starts the ULP program and resets measurement counter.
|
||||
*/
|
||||
static void start_ulp_program(void);
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
||||
if (cause != ESP_SLEEP_WAKEUP_ULP) {
|
||||
printf("Not ULP wakeup\n");
|
||||
init_ulp_program();
|
||||
} else {
|
||||
printf("Deep sleep wakeup\n");
|
||||
printf("ULP did %d measurements since last reset\n", ulp_sample_counter & UINT16_MAX);
|
||||
printf("Thresholds: low=%d high=%d\n", ulp_low_thr, ulp_high_thr);
|
||||
ulp_last_result &= UINT16_MAX;
|
||||
printf("Value=%d was %s threshold\n", ulp_last_result,
|
||||
ulp_last_result < ulp_low_thr ? "below" : "above");
|
||||
}
|
||||
printf("Entering deep sleep\n\n");
|
||||
start_ulp_program();
|
||||
ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );
|
||||
esp_deep_sleep_start();
|
||||
}
|
||||
|
||||
static void init_ulp_program(void)
|
||||
{
|
||||
esp_err_t err = ulp_load_binary(0, ulp_main_bin_start,
|
||||
(ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t));
|
||||
ESP_ERROR_CHECK(err);
|
||||
|
||||
/* Configure ADC channel */
|
||||
/* Note: when changing channel here, also change 'adc_channel' constant
|
||||
in adc.S */
|
||||
adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
adc1_config_width(ADC_WIDTH_BIT_12);
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
adc1_config_width(ADC_WIDTH_BIT_13);
|
||||
#endif
|
||||
adc1_ulp_enable();
|
||||
|
||||
/* Set low and high thresholds, approx. 1.35V - 1.75V*/
|
||||
ulp_low_thr = 1500;
|
||||
ulp_high_thr = 2000;
|
||||
|
||||
/* Set ULP wake up period to 20ms */
|
||||
ulp_set_wakeup_period(0, 20000);
|
||||
|
||||
/* Disconnect GPIO12 and GPIO15 to remove current drain through
|
||||
* pullup/pulldown resistors.
|
||||
* GPIO12 may be pulled high to select flash voltage.
|
||||
*/
|
||||
rtc_gpio_isolate(GPIO_NUM_12);
|
||||
rtc_gpio_isolate(GPIO_NUM_15);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
esp_deep_sleep_disable_rom_logging(); // suppress boot messages
|
||||
#endif
|
||||
}
|
||||
|
||||
static void start_ulp_program(void)
|
||||
{
|
||||
/* Reset sample counter */
|
||||
ulp_sample_counter = 0;
|
||||
|
||||
/* Start the program */
|
||||
esp_err_t err = ulp_run(&ulp_entry - RTC_SLOW_MEM);
|
||||
ESP_ERROR_CHECK(err);
|
||||
}
|
||||
Reference in New Issue
Block a user