479af576ca
The argument to ulp_run should be expressed in 32-bit words. Both the address of ulp_entry and RTC_SLOW_MEM already are uint32_t*, so their difference is the difference in addresses divided by sizeof(uint32_t). Therefore the extra division by sizeof(uint32_t) is not needed.
119 lines
4.1 KiB
C
119 lines
4.1 KiB
C
/* 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 "esp_sleep.h"
|
|
#include "nvs.h"
|
|
#include "nvs_flash.h"
|
|
#include "soc/rtc_cntl_reg.h"
|
|
#include "soc/sens_reg.h"
|
|
#include "soc/rtc_periph.h"
|
|
#include "driver/gpio.h"
|
|
#include "driver/rtc_io.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");
|
|
|
|
static void init_ulp_program();
|
|
static void update_pulse_count();
|
|
|
|
void app_main()
|
|
{
|
|
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
|
if (cause != ESP_SLEEP_WAKEUP_ULP) {
|
|
printf("Not ULP wakeup, initializing ULP\n");
|
|
init_ulp_program();
|
|
} else {
|
|
printf("ULP wakeup, saving pulse count\n");
|
|
update_pulse_count();
|
|
}
|
|
|
|
printf("Entering deep sleep\n\n");
|
|
ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup() );
|
|
esp_deep_sleep_start();
|
|
}
|
|
|
|
static void init_ulp_program()
|
|
{
|
|
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);
|
|
|
|
/* GPIO used for pulse counting. */
|
|
gpio_num_t gpio_num = GPIO_NUM_0;
|
|
assert(rtc_gpio_desc[gpio_num].reg && "GPIO used for pulse counting must be an RTC IO");
|
|
|
|
/* Initialize some variables used by ULP program.
|
|
* Each 'ulp_xyz' variable corresponds to 'xyz' variable in the ULP program.
|
|
* These variables are declared in an auto generated header file,
|
|
* 'ulp_main.h', name of this file is defined in component.mk as ULP_APP_NAME.
|
|
* These variables are located in RTC_SLOW_MEM and can be accessed both by the
|
|
* ULP and the main CPUs.
|
|
*
|
|
* Note that the ULP reads only the lower 16 bits of these variables.
|
|
*/
|
|
ulp_debounce_counter = 3;
|
|
ulp_debounce_max_count = 3;
|
|
ulp_next_edge = 0;
|
|
ulp_io_number = rtc_gpio_desc[gpio_num].rtc_num; /* map from GPIO# to RTC_IO# */
|
|
ulp_edge_count_to_wake_up = 10;
|
|
|
|
/* Initialize selected GPIO as RTC IO, enable input, disable pullup and pulldown */
|
|
rtc_gpio_init(gpio_num);
|
|
rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_INPUT_ONLY);
|
|
rtc_gpio_pulldown_dis(gpio_num);
|
|
rtc_gpio_pullup_dis(gpio_num);
|
|
rtc_gpio_hold_en(gpio_num);
|
|
|
|
/* Disconnect GPIO12 and GPIO15 to remove current drain through
|
|
* pullup/pulldown resistors.
|
|
* GPIO15 may be connected to ground to suppress boot messages.
|
|
* GPIO12 may be pulled high to select flash voltage.
|
|
*/
|
|
rtc_gpio_isolate(GPIO_NUM_12);
|
|
rtc_gpio_isolate(GPIO_NUM_15);
|
|
|
|
/* Set ULP wake up period to T = 20ms.
|
|
* Minimum pulse width has to be T * (ulp_debounce_counter + 1) = 80ms.
|
|
*/
|
|
ulp_set_wakeup_period(0, 20000);
|
|
|
|
/* Start the program */
|
|
err = ulp_run(&ulp_entry - RTC_SLOW_MEM);
|
|
ESP_ERROR_CHECK(err);
|
|
}
|
|
|
|
static void update_pulse_count()
|
|
{
|
|
const char* namespace = "plusecnt";
|
|
const char* count_key = "count";
|
|
|
|
ESP_ERROR_CHECK( nvs_flash_init() );
|
|
nvs_handle handle;
|
|
ESP_ERROR_CHECK( nvs_open(namespace, NVS_READWRITE, &handle));
|
|
uint32_t pulse_count = 0;
|
|
esp_err_t err = nvs_get_u32(handle, count_key, &pulse_count);
|
|
assert(err == ESP_OK || err == ESP_ERR_NVS_NOT_FOUND);
|
|
printf("Read pulse count from NVS: %5d\n", pulse_count);
|
|
|
|
/* ULP program counts signal edges, convert that to the number of pulses */
|
|
uint32_t pulse_count_from_ulp = (ulp_edge_count & UINT16_MAX) / 2;
|
|
/* In case of an odd number of edges, keep one until next time */
|
|
ulp_edge_count = ulp_edge_count % 2;
|
|
printf("Pulse count from ULP: %5d\n", pulse_count_from_ulp);
|
|
|
|
/* Save the new pulse count to NVS */
|
|
pulse_count += pulse_count_from_ulp;
|
|
ESP_ERROR_CHECK(nvs_set_u32(handle, count_key, pulse_count));
|
|
ESP_ERROR_CHECK(nvs_commit(handle));
|
|
nvs_close(handle);
|
|
printf("Wrote updated pulse count to NVS: %5d\n", pulse_count);
|
|
}
|