ESP32: support ULP via Berry

This commit is contained in:
Christian Baars 2022-07-02 21:30:04 +02:00
parent a04687b314
commit a793296bc1
6 changed files with 1289 additions and 1074 deletions

View File

@ -50,6 +50,7 @@ be_extern_native_module(animate);
be_extern_native_module(partition_core); be_extern_native_module(partition_core);
be_extern_native_module(crc); be_extern_native_module(crc);
be_extern_native_module(crypto); be_extern_native_module(crypto);
be_extern_native_module(ULP);
#ifdef USE_ZIGBEE #ifdef USE_ZIGBEE
be_extern_native_module(zigbee); be_extern_native_module(zigbee);
#endif // USE_ZIGBEE #endif // USE_ZIGBEE
@ -162,6 +163,9 @@ BERRY_LOCAL const bntvmodule* const be_module_table[] = {
#ifdef USE_ALEXA_AVS #ifdef USE_ALEXA_AVS
&be_native_module(crypto), &be_native_module(crypto),
#endif #endif
#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
&be_native_module(ULP),
#endif // USE_BERRY_ULP
/* user-defined modules register end */ /* user-defined modules register end */
NULL /* do not remove */ NULL /* do not remove */

View File

@ -237,6 +237,7 @@ extern const bcstring be_const_str_a;
extern const bcstring be_const_str_abs; extern const bcstring be_const_str_abs;
extern const bcstring be_const_str_acos; extern const bcstring be_const_str_acos;
extern const bcstring be_const_str_active_otadata; extern const bcstring be_const_str_active_otadata;
extern const bcstring be_const_str_adc_config;
extern const bcstring be_const_str_add; extern const bcstring be_const_str_add;
extern const bcstring be_const_str_add_anim; extern const bcstring be_const_str_add_anim;
extern const bcstring be_const_str_add_cb_event_closure; extern const bcstring be_const_str_add_cb_event_closure;
@ -456,6 +457,7 @@ extern const bcstring be_const_str_get_image_size;
extern const bcstring be_const_str_get_input_power_status; extern const bcstring be_const_str_get_input_power_status;
extern const bcstring be_const_str_get_light; extern const bcstring be_const_str_get_light;
extern const bcstring be_const_str_get_log; extern const bcstring be_const_str_get_log;
extern const bcstring be_const_str_get_mem;
extern const bcstring be_const_str_get_name; extern const bcstring be_const_str_get_name;
extern const bcstring be_const_str_get_object_from_ptr; extern const bcstring be_const_str_get_object_from_ptr;
extern const bcstring be_const_str_get_option; extern const bcstring be_const_str_get_option;
@ -475,6 +477,7 @@ extern const bcstring be_const_str_getfloat;
extern const bcstring be_const_str_geti; extern const bcstring be_const_str_geti;
extern const bcstring be_const_str_global; extern const bcstring be_const_str_global;
extern const bcstring be_const_str_gpio; extern const bcstring be_const_str_gpio;
extern const bcstring be_const_str_gpio_init;
extern const bcstring be_const_str_group_def; extern const bcstring be_const_str_group_def;
extern const bcstring be_const_str_groups; extern const bcstring be_const_str_groups;
extern const bcstring be_const_str_h; extern const bcstring be_const_str_h;
@ -724,6 +727,7 @@ extern const bcstring be_const_str_set_ldo_enable;
extern const bcstring be_const_str_set_ldo_voltage; extern const bcstring be_const_str_set_ldo_voltage;
extern const bcstring be_const_str_set_light; extern const bcstring be_const_str_set_light;
extern const bcstring be_const_str_set_matrix_pixel_color; extern const bcstring be_const_str_set_matrix_pixel_color;
extern const bcstring be_const_str_set_mem;
extern const bcstring be_const_str_set_mode_ct; extern const bcstring be_const_str_set_mode_ct;
extern const bcstring be_const_str_set_mode_rgb; extern const bcstring be_const_str_set_mode_rgb;
extern const bcstring be_const_str_set_ota_max; extern const bcstring be_const_str_set_ota_max;
@ -749,6 +753,7 @@ extern const bcstring be_const_str_signal_change;
extern const bcstring be_const_str_sin; extern const bcstring be_const_str_sin;
extern const bcstring be_const_str_sinh; extern const bcstring be_const_str_sinh;
extern const bcstring be_const_str_size; extern const bcstring be_const_str_size;
extern const bcstring be_const_str_sleep;
extern const bcstring be_const_str_slots; extern const bcstring be_const_str_slots;
extern const bcstring be_const_str_solidified; extern const bcstring be_const_str_solidified;
extern const bcstring be_const_str_spiffs; extern const bcstring be_const_str_spiffs;
@ -826,6 +831,7 @@ extern const bcstring be_const_str_value_error;
extern const bcstring be_const_str_valuer_error; extern const bcstring be_const_str_valuer_error;
extern const bcstring be_const_str_var; extern const bcstring be_const_str_var;
extern const bcstring be_const_str_w; extern const bcstring be_const_str_w;
extern const bcstring be_const_str_wake_period;
extern const bcstring be_const_str_wd; extern const bcstring be_const_str_wd;
extern const bcstring be_const_str_web_add_button; extern const bcstring be_const_str_web_add_button;
extern const bcstring be_const_str_web_add_config_button; extern const bcstring be_const_str_web_add_config_button;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
#include "be_constobj.h"
static be_define_const_map_slots(m_libULP_map) {
{ be_const_key(sleep, -1), be_const_ctype_func(be_ULP_sleep) },
{ be_const_key(get_mem, 6), be_const_ctype_func(be_ULP_get_mem) },
{ be_const_key(run, -1), be_const_ctype_func(be_ULP_run) },
{ be_const_key(load, -1), be_const_ctype_func(be_ULP_load) },
{ be_const_key(adc_config, -1), be_const_ctype_func(be_ULP_adc_config) },
{ be_const_key(set_mem, -1), be_const_ctype_func(be_ULP_set_mem) },
{ be_const_key(gpio_init, 3), be_const_ctype_func(be_ULP_gpio_init) },
{ be_const_key(wake_period, -1), be_const_ctype_func(be_ULP_wake_up_period) },
};
static be_define_const_map(
m_libULP_map,
8
);
static be_define_const_module(
m_libULP,
"ULP"
);
BE_EXPORT_VARIABLE be_define_const_native_module(ULP);

View File

@ -0,0 +1,55 @@
/********************************************************************
* Tasmota lib
*
* To use: import ULP`
*******************************************************************/
#include "be_constobj.h"
#include "be_mapping.h"
#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
#include "esp32/ulp.h"
#include "driver/rtc_io.h"
#include "driver/gpio.h"
#include "driver/adc.h"
extern void be_ULP_run(int32_t entry);
BE_FUNC_CTYPE_DECLARE(be_ULP_run, "", "[i]");
extern void be_ULP_wake_up_period(int32_t period_index, int32_t period_us);
BE_FUNC_CTYPE_DECLARE(be_ULP_wake_up_period, "", "ii");
extern int32_t be_ULP_set_mem(int32_t pos, int32_t value);
BE_FUNC_CTYPE_DECLARE(be_ULP_set_mem, "i", "ii");
extern int32_t be_ULP_get_mem(int32_t pos);
BE_FUNC_CTYPE_DECLARE(be_ULP_get_mem, "i", "i");
extern int32_t be_ULP_gpio_init(gpio_num_t pin, rtc_gpio_mode_t mode);
BE_FUNC_CTYPE_DECLARE(be_ULP_gpio_init, "i", "ii");
extern int32_t be_ULP_adc_config(adc1_channel_t channel, adc_atten_t attenuation, adc_bits_width_t width);
BE_FUNC_CTYPE_DECLARE(be_ULP_adc_config, "i", "iii");
extern void be_ULP_sleep(int32_t wake_up_s);
BE_FUNC_CTYPE_DECLARE(be_ULP_sleep, "", "[i]"); // optional int arg
extern void be_ULP_load(struct bvm *vm, const uint8_t *buf, size_t size);
BE_FUNC_CTYPE_DECLARE(be_ULP_load, "", "@(bytes)~"); // pass: 1/ vm, 2/ bytes point, 3/ bytes size
#include "be_fixed_ULP.h"
/* @const_object_info_begin
module ULP (scope: global) {
run, ctype_func(be_ULP_run)
load, ctype_func(be_ULP_load)
set_mem, ctype_func(be_ULP_set_mem)
get_mem, ctype_func(be_ULP_get_mem)
gpio_init, ctype_func(be_ULP_gpio_init)
wake_period, ctype_func(be_ULP_wake_up_period)
sleep, ctype_func(be_ULP_sleep)
adc_config, ctype_func(be_ULP_adc_config)
}
@const_object_info_end */
#endif // USE_BERRY_ULP

View File

@ -0,0 +1,117 @@
/*
xdrv_52_3_berry_ulp.ino - Berry scripting language, ULP support for ESP32
Copyright (C) 2021 Stephan Hadinger & Christian Baars, Berry language by Guan Wenliang https://github.com/Skiars/berry
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_BERRY
#ifdef USE_BERRY_ULP
#include <berry.h>
#if defined(USE_BERRY_ULP) && defined(CONFIG_IDF_TARGET_ESP32)
#include "esp32/ulp.h"
#include "driver/rtc_io.h"
#include "driver/gpio.h"
#include "driver/adc.h"
#include "sdkconfig.h"
extern "C" {
// start the ULP program - always from offset 0 (optional: pass entry)
// The first 32 bits must be a JMP instruction to the start of the program
//
// `ULP.run() -> nil`
void be_ULP_run(int32_t entry) {
ulp_run(entry); // entry point should be at the beginning of program
}
// `ULP.wake_period(period_index:int, period_us:int) -> nil`
void be_ULP_wake_up_period(int32_t period_index, int32_t period_us) {
ulp_set_wakeup_period(period_index, period_us);
}
// `ULP.set_mem(position:int, value:int) -> value:int`
int32_t be_ULP_set_mem(int32_t pos, int32_t value) {
RTC_SLOW_MEM[pos]=value;
return value;
}
// `ULP.get_mem(position:int) -> int`
int32_t be_ULP_get_mem(int32_t pos) {
return RTC_SLOW_MEM[pos] & 0xFFFF; // only low 16 bits are used
}
// `ULP.gpio_init(pin:int, mode:int) -> rtc_pin:int`
// returns -1 if pin is invalid
int32_t be_ULP_gpio_init(gpio_num_t pin, rtc_gpio_mode_t mode) {
if (rtc_gpio_is_valid_gpio(pin)){
rtc_gpio_init(pin);
rtc_gpio_set_direction(pin, mode);
return rtc_io_number_get(pin);
} else {
return -1;
}
}
// `ULP.adc_config(channel:int, attenuation:int, width:int) -> err:int`
// returns combined error like xxx000yyy, xxx for adc1_config_channel_atten and yyy for adc1_config_width
// enums: channel 0-7, attenuation 0-3, width 0-3
int32_t be_ULP_adc_config(adc1_channel_t channel, adc_atten_t attenuation, adc_bits_width_t width) {
esp_err_t err = adc1_config_channel_atten(channel, attenuation) * 1000000; //shift error left
err += adc1_config_width(width);
if(err==ESP_OK){
adc1_ulp_enable();
}
return err;
}
/**
* @brief Load a Berry byte buffer containing a ULP program as raw byte data
*
* @param vm as `ULP.load(code:bytes) -> nil`
* @return int
*/
void be_ULP_load(struct bvm *vm, const uint8_t *buf, size_t size) {
// AddLog(LOG_LEVEL_INFO, "ULP: load addr=%p size=%i %*_H", buf, size/4, size, buf);
esp_err_t err = ulp_load_binary(0, buf, size / 4);
if (err != ESP_OK) {
be_raisef(vm, "ulp_load_error", "ULP: invalid code err=%i", err);
}
}
// `ULP.sleep([wake time in seconds:int]) -> nil`
void be_ULP_sleep(int32_t wake_up_s) {
AddLog(LOG_LEVEL_INFO, "ULP: Enter sleep mode.");
WifiShutdown();
RtcSettingsSave();
RtcRebootReset();
if (wake_up_s) {
AddLog(LOG_LEVEL_INFO, PSTR("ULP: will wake up in %u seconds."), wake_up_s);
esp_sleep_enable_timer_wakeup(wake_up_s * 1000000);
}
esp_sleep_enable_ulp_wakeup();
esp_deep_sleep_start();
}
} //extern "C"
#endif //CONFIG_IDF_TARGET_ESP32
#endif // USE_BERRY_ULP
#endif // USE_BERRY