First WASM commit
This commit is contained in:
parent
123bd0bb92
commit
301cacc91d
@ -158,6 +158,7 @@ lib_compat_mode = strict
|
||||
lib_deps =
|
||||
fastled/FastLED @ 3.4.0
|
||||
IRremoteESP8266 @ 2.7.18
|
||||
wasm3/Wasm3 @ 0.5.0
|
||||
https://github.com/lorol/LITTLEFS.git
|
||||
https://github.com/Aircoookie/ESPAsyncWebServer.git @ ~2.0.2
|
||||
#For use of the TTGO T-Display ESP32 Module with integrated TFT display uncomment the following line
|
||||
|
@ -38,6 +38,23 @@ uint16_t WS2812FX::mode_static(void) {
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Custom mode. Executes WebAssembly fx() function
|
||||
*/
|
||||
uint16_t WS2812FX::mode_custom(void) {
|
||||
wasm.call();
|
||||
return FRAMETIME;
|
||||
}
|
||||
|
||||
|
||||
//testing TEMP
|
||||
uint16_t WS2812FX::mode_benchmark(void) {
|
||||
wasm.call();
|
||||
return FRAMETIME;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Blink/strobe function
|
||||
* Alternate between color1 and color2
|
||||
|
11
wled00/FX.h
11
wled00/FX.h
@ -113,7 +113,7 @@
|
||||
#define IS_REVERSE ((SEGMENT.options & REVERSE ) == REVERSE )
|
||||
#define IS_SELECTED ((SEGMENT.options & SELECTED ) == SELECTED )
|
||||
|
||||
#define MODE_COUNT 118
|
||||
#define MODE_COUNT 120
|
||||
|
||||
#define FX_MODE_STATIC 0
|
||||
#define FX_MODE_BLINK 1
|
||||
@ -233,6 +233,8 @@
|
||||
#define FX_MODE_BLENDS 115
|
||||
#define FX_MODE_TV_SIMULATOR 116
|
||||
#define FX_MODE_DYNAMIC_SMOOTH 117
|
||||
#define FX_MODE_CUSTOM 118
|
||||
#define FX_MODE_BENCHMARK 119
|
||||
|
||||
|
||||
class WS2812FX {
|
||||
@ -594,6 +596,8 @@ class WS2812FX {
|
||||
_mode[FX_MODE_BLENDS] = &WS2812FX::mode_blends;
|
||||
_mode[FX_MODE_TV_SIMULATOR] = &WS2812FX::mode_tv_simulator;
|
||||
_mode[FX_MODE_DYNAMIC_SMOOTH] = &WS2812FX::mode_dynamic_smooth;
|
||||
_mode[FX_MODE_CUSTOM] = &WS2812FX::mode_custom;
|
||||
_mode[FX_MODE_BENCHMARK] = &WS2812FX::mode_benchmark;
|
||||
|
||||
_brightness = DEFAULT_BRIGHTNESS;
|
||||
currentPalette = CRGBPalette16(CRGB::Black);
|
||||
@ -816,7 +820,9 @@ class WS2812FX {
|
||||
mode_candy_cane(void),
|
||||
mode_blends(void),
|
||||
mode_tv_simulator(void),
|
||||
mode_dynamic_smooth(void);
|
||||
mode_dynamic_smooth(void),
|
||||
mode_custom(void),
|
||||
mode_benchmark(void);
|
||||
|
||||
private:
|
||||
uint32_t crgb_to_col(CRGB fastled);
|
||||
@ -892,6 +898,7 @@ class WS2812FX {
|
||||
|
||||
ColorTransition transitions[MAX_NUM_TRANSITIONS]; //12 bytes per element
|
||||
friend class ColorTransition;
|
||||
friend class WASMVM;
|
||||
|
||||
uint16_t
|
||||
realPixelIndex(uint16_t i),
|
||||
|
255
wled00/wasm.cpp
Normal file
255
wled00/wasm.cpp
Normal file
@ -0,0 +1,255 @@
|
||||
#include <wasm3.h>
|
||||
#include <m3_env.h>
|
||||
|
||||
#define WASM_STACK_SLOTS 1024
|
||||
#define NATIVE_STACK_SIZE (32*1024)
|
||||
|
||||
// For (most) devices that cannot allocate a 64KiB wasm page
|
||||
#define WASM_MEMORY_LIMIT 4096
|
||||
|
||||
unsigned char app_wasm[] = {
|
||||
0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x11, 0x04, 0x60,
|
||||
0x02, 0x7f, 0x7f, 0x00, 0x60, 0x00, 0x00, 0x60, 0x01, 0x7f, 0x00, 0x60,
|
||||
0x00, 0x01, 0x7f, 0x02, 0x4e, 0x04, 0x07, 0x61, 0x72, 0x64, 0x75, 0x69,
|
||||
0x6e, 0x6f, 0x09, 0x67, 0x65, 0x74, 0x50, 0x69, 0x6e, 0x4c, 0x45, 0x44,
|
||||
0x00, 0x03, 0x07, 0x61, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x07, 0x70,
|
||||
0x69, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x00, 0x00, 0x07, 0x61, 0x72, 0x64,
|
||||
0x75, 0x69, 0x6e, 0x6f, 0x0c, 0x64, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c,
|
||||
0x57, 0x72, 0x69, 0x74, 0x65, 0x00, 0x00, 0x07, 0x61, 0x72, 0x64, 0x75,
|
||||
0x69, 0x6e, 0x6f, 0x05, 0x64, 0x65, 0x6c, 0x61, 0x79, 0x00, 0x02, 0x03,
|
||||
0x02, 0x01, 0x01, 0x05, 0x03, 0x01, 0x00, 0x01, 0x07, 0x13, 0x02, 0x06,
|
||||
0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x02, 0x00, 0x06, 0x5f, 0x73, 0x74,
|
||||
0x61, 0x72, 0x74, 0x00, 0x04, 0x0a, 0x3a, 0x01, 0x38, 0x01, 0x01, 0x7f,
|
||||
0x41, 0x80, 0x08, 0x10, 0x00, 0x22, 0x00, 0x36, 0x02, 0x00, 0x20, 0x00,
|
||||
0x41, 0x01, 0x10, 0x01, 0x03, 0x40, 0x41, 0x80, 0x08, 0x28, 0x02, 0x00,
|
||||
0x41, 0x01, 0x10, 0x02, 0x41, 0xe4, 0x00, 0x10, 0x03, 0x41, 0x80, 0x08,
|
||||
0x28, 0x02, 0x00, 0x41, 0x00, 0x10, 0x02, 0x41, 0x84, 0x07, 0x10, 0x03,
|
||||
0x0c, 0x00, 0x0b, 0x00, 0x0b
|
||||
};
|
||||
unsigned int app_wasm_len = 197;
|
||||
|
||||
/*
|
||||
* API bindings
|
||||
*
|
||||
* Note: each RawFunction should complete with one of these calls:
|
||||
* m3ApiReturn(val) - Returns a value
|
||||
* m3ApiSuccess() - Returns void (and no traps)
|
||||
* m3ApiTrap(trap) - Returns a trap
|
||||
*/
|
||||
|
||||
class WASMVM {
|
||||
WS2812FX inst = nullptr;
|
||||
|
||||
m3ApiRawFunction(m3_arduino_millis)
|
||||
{
|
||||
m3ApiReturnType (uint32_t)
|
||||
|
||||
m3ApiReturn(millis());
|
||||
}
|
||||
|
||||
m3ApiRawFunction(m3_arduino_delay)
|
||||
{
|
||||
m3ApiGetArg (uint32_t, ms)
|
||||
|
||||
// You can also trace API calls
|
||||
//Serial.print("api: delay "); Serial.println(ms);
|
||||
|
||||
delay(ms);
|
||||
|
||||
m3ApiSuccess();
|
||||
}
|
||||
|
||||
// This maps pin modes from arduino_wasm_api.h
|
||||
// to actual platform-specific values
|
||||
uint8_t mapPinMode(uint8_t mode)
|
||||
{
|
||||
switch(mode) {
|
||||
case 0: return INPUT;
|
||||
case 1: return OUTPUT;
|
||||
case 2: return INPUT_PULLUP;
|
||||
}
|
||||
return INPUT;
|
||||
}
|
||||
|
||||
m3ApiRawFunction(m3_arduino_pinMode)
|
||||
{
|
||||
m3ApiGetArg (uint32_t, pin)
|
||||
m3ApiGetArg (uint32_t, mode)
|
||||
|
||||
pinMode(pin, (uint8_t)mapPinMode(mode));
|
||||
|
||||
m3ApiSuccess();
|
||||
}
|
||||
|
||||
m3ApiRawFunction(m3_arduino_digitalWrite)
|
||||
{
|
||||
m3ApiGetArg (uint32_t, pin)
|
||||
m3ApiGetArg (uint32_t, value)
|
||||
|
||||
digitalWrite(pin, value);
|
||||
|
||||
m3ApiSuccess();
|
||||
}
|
||||
|
||||
m3ApiRawFunction(m3_arduino_getPinLED)
|
||||
{
|
||||
m3ApiReturnType (uint32_t)
|
||||
|
||||
m3ApiReturn(LED_PIN);
|
||||
}
|
||||
|
||||
m3ApiRawFunction(m3_arduino_print)
|
||||
{
|
||||
m3ApiGetArgMem (const uint8_t *, buf)
|
||||
m3ApiGetArg (uint32_t, len)
|
||||
|
||||
Serial.write(buf, len);
|
||||
m3ApiSuccess();
|
||||
}
|
||||
|
||||
m3ApiRawFunction(m3_led_now) {
|
||||
m3ApiReturnType(uint32_t)
|
||||
m3ApiReturn(strip.now());
|
||||
}
|
||||
|
||||
m3ApiRawFunction(m3_led_speed) {
|
||||
m3ApiReturnType(uint32_t)
|
||||
m3ApiReturn(strip._segments[strip._segment_index].speed);
|
||||
}
|
||||
|
||||
m3ApiRawFunction(m3_led_intensity) {
|
||||
m3ApiReturnType(uint32_t)
|
||||
m3ApiReturn(strip._segments[strip._segment_index].intensity);
|
||||
}
|
||||
|
||||
m3ApiRawFunction(m3_led_len) {
|
||||
m3ApiReturnType(uint32_t)
|
||||
m3ApiReturn(strip._virtualSegmentLength);
|
||||
}
|
||||
|
||||
m3ApiRawFunction(m3_led_fill) {
|
||||
m3ApiGetArg (uint32_t, color)
|
||||
|
||||
strip.fill(color);
|
||||
|
||||
m3ApiSuccess();
|
||||
}
|
||||
|
||||
m3ApiRawFunction(m3_led_set) {
|
||||
m3ApiGetArg (uint32_t, index)
|
||||
m3ApiGetArg (uint32_t, color)
|
||||
|
||||
strip.setPixelColor(index, color);
|
||||
|
||||
m3ApiSuccess();
|
||||
}
|
||||
|
||||
m3ApiRawFunction(m3_led_rgb) {
|
||||
m3ApiGetArg (uint32_t, r)
|
||||
m3ApiGetArg (uint32_t, g)
|
||||
m3ApiGetArg (uint32_t, b)
|
||||
|
||||
m3ApiReturnType(uint32_t)
|
||||
uint32_t c = (r << 16) + (g << 8) + b;
|
||||
m3ApiReturn(c);
|
||||
}
|
||||
|
||||
M3Result LinkArduino (IM3Runtime runtime)
|
||||
{
|
||||
IM3Module module = runtime->modules;
|
||||
const char* arduino = "arduino";
|
||||
const char* led = "led";
|
||||
|
||||
m3_LinkRawFunction (module, arduino, "millis", "i()", &m3_arduino_millis);
|
||||
m3_LinkRawFunction (module, arduino, "delay", "v(i)", &m3_arduino_delay); //temp
|
||||
m3_LinkRawFunction (module, arduino, "pinMode", "v(ii)", &m3_arduino_pinMode); //temp
|
||||
m3_LinkRawFunction (module, arduino, "digitalWrite", "v(ii)", &m3_arduino_digitalWrite); //temp
|
||||
|
||||
// Test functions
|
||||
m3_LinkRawFunction (module, arduino, "getPinLED", "i()", &m3_arduino_getPinLED); //temp
|
||||
m3_LinkRawFunction (module, arduino, "print", "v(*i)", &m3_arduino_print);
|
||||
|
||||
//WLED functions
|
||||
m3_LinkRawFunction (module, led, "now", "i()", &m3_led_now);
|
||||
m3_LinkRawFunction (module, led, "speed", "i()", &m3_led_speed);
|
||||
m3_LinkRawFunction (module, led, "intensity", "i()", &m3_led_intensity);
|
||||
m3_LinkRawFunction (module, led, "len", "i()", &m3_led_len);
|
||||
m3_LinkRawFunction (module, led, "fill", "v(i)", &m3_led_fill);
|
||||
m3_LinkRawFunction (module, led, "set", "v(ii)", &m3_led_set);
|
||||
m3_LinkRawFunction (module, led, "rgb", "i(iii)", &m3_led_rgb);
|
||||
|
||||
return m3Err_none;
|
||||
}
|
||||
|
||||
/*
|
||||
* Engine start, liftoff!
|
||||
*/
|
||||
|
||||
#define FATAL(func, msg) { Serial.print("Fatal: " func " "); Serial.println(msg); return; }
|
||||
|
||||
void wasm_task(void*)
|
||||
{
|
||||
M3Result result = m3Err_none;
|
||||
|
||||
IM3Environment env = m3_NewEnvironment ();
|
||||
if (!env) FATAL("NewEnv", "failed");
|
||||
|
||||
IM3Runtime runtime = m3_NewRuntime (env, WASM_STACK_SLOTS, NULL);
|
||||
if (!runtime) FATAL("NewRt", "failed");
|
||||
|
||||
#ifdef WASM_MEMORY_LIMIT
|
||||
runtime->memoryLimit = WASM_MEMORY_LIMIT;
|
||||
#endif
|
||||
|
||||
IM3Module module;
|
||||
result = m3_ParseModule (env, &module, app_wasm, app_wasm_len);
|
||||
if (result) FATAL("ParseModule", result);
|
||||
|
||||
result = m3_LoadModule (runtime, module);
|
||||
if (result) FATAL("LoadModule", result);
|
||||
|
||||
result = LinkArduino (runtime);
|
||||
if (result) FATAL("LinkArd", result);
|
||||
|
||||
IM3Function f;
|
||||
result = m3_FindFunction (&f, runtime, "_start");
|
||||
if (result) FATAL("FindFunc", result);
|
||||
|
||||
Serial.println("Run WASM...");
|
||||
|
||||
result = m3_CallV (f);
|
||||
|
||||
// Should not arrive here
|
||||
|
||||
if (result) {
|
||||
M3ErrorInfo info;
|
||||
m3_GetErrorInfo (runtime, &info);
|
||||
Serial.print("Err: ");
|
||||
Serial.print(result);
|
||||
Serial.print(" (");
|
||||
Serial.print(info.message);
|
||||
Serial.println(")");
|
||||
if (info.file && strlen(info.file) && info.line) {
|
||||
Serial.print("At ");
|
||||
Serial.print(info.file);
|
||||
Serial.print(":");
|
||||
Serial.println(info.line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setup(WS2812FX* instance)
|
||||
{
|
||||
if (!instance) return;
|
||||
inst = instance;
|
||||
Serial.println("\nWasm3 v" M3_VERSION " (" M3_ARCH "), build " __DATE__ " " __TIME__);
|
||||
|
||||
#ifdef ESP32
|
||||
// On ESP32, we can launch in a separate thread
|
||||
xTaskCreate(&wasm_task, "wasm3", NATIVE_STACK_SIZE, NULL, 5, NULL);
|
||||
#else
|
||||
wasm_task(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user