mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
Change ioBuffer FIFO from 4 byte blocks to variable length blocks. Far more efficient for USB/BLE/other block data
This commit is contained in:
parent
aa3ce23467
commit
b84efeca3e
@ -17,6 +17,7 @@
|
||||
Pipboy: allow audio files to be played at the same time as (silent) video. add audioStopped/videoStopped events and audioStop method
|
||||
Pipboy: Pip.audioStartVar(wav,{overlap:true}) can now play sounds over the top of other sounds. audioRead now doesn't stop audio playback
|
||||
STM32: Ensure proper distribution of analogRead values (now `0<=analogRead()<1` as on other boards) and add docs (fix #2612)
|
||||
Change ioBuffer FIFO from 4 byte blocks to variable length blocks. Far more efficient for USB/BLE/other block data
|
||||
|
||||
2v25 : ESP32C3: Get analogRead working correctly
|
||||
Graphics: Adjust image alignment when rotating images to avoid cropping (fix #2535)
|
||||
|
||||
@ -26,7 +26,7 @@ info = {
|
||||
# 'default_console_baudrate' : "9600",
|
||||
'variables' : 12000, # How many variables are allocated for Espruino to use. RAM will be overflowed if this number is too high and code won't compile.
|
||||
# Currently leaves around 38k of free stack - *loads* more than we need
|
||||
'io_buffer_size' : 512, # How big is the input buffer (in 4 byte words). Default on nRF52 is 256
|
||||
'io_buffer_size' : 2048, # How big is the input buffer (in bytes). Default on nRF52 is 1024
|
||||
'bootloader' : 1,
|
||||
'binary_name' : 'espruino_%v_banglejs2.hex',
|
||||
'build' : {
|
||||
|
||||
@ -31,7 +31,7 @@ info = {
|
||||
# 'default_console_baudrate' : "9600",
|
||||
'variables' : 12000, # How many variables are allocated for Espruino to use. RAM will be overflowed if this number is too high and code won't compile.
|
||||
# Currently leaves around 38k of free stack - *loads* more than we need
|
||||
'io_buffer_size' : 512, # How big is the input buffer (in 4 byte words). Default on nRF52 is 256
|
||||
'io_buffer_size' : 2048, # How big is the input buffer (in bytes). Default on nRF52 is 1024
|
||||
'bootloader' : 1,
|
||||
'binary_name' : 'espruino_%v_banglejs2_iflash.hex',
|
||||
'build' : {
|
||||
|
||||
@ -18,7 +18,7 @@ import pinutils;
|
||||
info = {
|
||||
'name' : "Bangle.js 2 (No external flash)", # Using SMA Q3
|
||||
# A build for Bangle.js 2 that uses only internal flash
|
||||
'boardname' : "BANGLEJS2",
|
||||
'boardname' : "BANGLEJS2",
|
||||
'link' : [ "https://espruino.com/Bangle.js2" ],
|
||||
'espruino_page_link' : 'Bangle.js2',
|
||||
'default_console' : "EV_TERMINAL",
|
||||
@ -28,7 +28,7 @@ info = {
|
||||
# 'default_console_baudrate' : "9600",
|
||||
'variables' : 12000, # How many variables are allocated for Espruino to use. RAM will be overflowed if this number is too high and code won't compile.
|
||||
# Currently leaves around 38k of free stack - *loads* more than we need
|
||||
'io_buffer_size' : 512, # How big is the input buffer (in 4 byte words). Default on nRF52 is 256
|
||||
'io_buffer_size' : 2048, # How big is the input buffer (in bytes). Default on nRF52 is 1024
|
||||
'bootloader' : 1,
|
||||
'binary_name' : 'espruino_%v_banglejs2_noflash.hex',
|
||||
'build' : {
|
||||
@ -54,8 +54,8 @@ info = {
|
||||
'DEFINES += -DESPR_DCDC_ENABLE=1', # Use DC/DC converter
|
||||
'ESPR_BLUETOOTH_ANCS=1', # Enable ANCS (Apple notifications) support
|
||||
'DEFINES += -DSPIFLASH_SLEEP_CMD', # SPI flash needs to be explicitly slept and woken up
|
||||
'DEFINES += -DSPIFLASH_READ2X', # Read SPI flash at 2x speed using MISO and MOSI for IO
|
||||
'DEFINES += -DESPR_JSVAR_FLASH_BUFFER_SIZE=32', # The buffer size we use when executing/iterating over data in flash memory (default 16). Should be set based on benchmarks.
|
||||
'DEFINES += -DSPIFLASH_READ2X', # Read SPI flash at 2x speed using MISO and MOSI for IO
|
||||
'DEFINES += -DESPR_JSVAR_FLASH_BUFFER_SIZE=32', # The buffer size we use when executing/iterating over data in flash memory (default 16). Should be set based on benchmarks.
|
||||
'DEFINES += -DAPP_TIMER_OP_QUEUE_SIZE=6', # Bangle.js accelerometer poll handler needs something else in queue size
|
||||
'DEFINES+=-DBLUETOOTH_NAME_PREFIX=\'"Bangle.js"\'',
|
||||
'DEFINES+=-DCUSTOM_GETBATTERY=jswrap_banglejs_getBattery',
|
||||
@ -124,7 +124,7 @@ devices = {
|
||||
'BTN1' : { 'pin' : 'D17', 'pinstate' : 'IN_PULLDOWN' }, # Pin negated in software
|
||||
'LED1' : { 'pin' : 'D8', 'novariable':True }, # Backlight flash for low level debug - but in code we just use 'fake' LEDs
|
||||
'LCD' : {
|
||||
'width' : 176, 'height' : 176,
|
||||
'width' : 176, 'height' : 176,
|
||||
'bpp' : 3, # LCD is native 3 bit (fastest transfers), but 4 is faster for drawing and slow to transfer
|
||||
'controller' : 'LPM013M126', # LPM013M126C
|
||||
'pin_cs' : 'D5',
|
||||
@ -145,7 +145,7 @@ devices = {
|
||||
'GPS' : {
|
||||
'device' : 'Casic URANUS',
|
||||
'pin_en' : 'D29',
|
||||
'pin_rx' : 'D30',
|
||||
'pin_rx' : 'D30',
|
||||
'pin_tx' : 'D31'
|
||||
},
|
||||
'BAT' : {
|
||||
@ -153,10 +153,10 @@ devices = {
|
||||
'pin_voltage' : 'D3'
|
||||
},
|
||||
'HEARTRATE' : {
|
||||
'device' : 'VC31', 'addr' : 0x33,
|
||||
'pin_sda' : 'D24',
|
||||
'pin_scl' : 'D32',
|
||||
'pin_en' : 'D21',
|
||||
'device' : 'VC31', 'addr' : 0x33,
|
||||
'pin_sda' : 'D24',
|
||||
'pin_scl' : 'D32',
|
||||
'pin_en' : 'D21',
|
||||
'pin_int' : 'D22'
|
||||
},
|
||||
'ACCEL' : {
|
||||
@ -165,7 +165,7 @@ devices = {
|
||||
'pin_scl' : 'D37'
|
||||
},
|
||||
'MAG' : { # Magnetometer/compass
|
||||
'device' : 'UNKNOWN_0C',
|
||||
'device' : 'UNKNOWN_0C',
|
||||
'addr' : 0x0C,
|
||||
'pin_sda' : 'D44',
|
||||
'pin_scl' : 'D45'
|
||||
@ -174,7 +174,7 @@ devices = {
|
||||
'device' : 'BMP280', # v2.1 uses Goertek SPL06-001 - we handle both
|
||||
'addr' : 0x76, # both versions use the same address
|
||||
'pin_sda' : 'D47',
|
||||
'pin_scl' : 'D2'
|
||||
'pin_scl' : 'D2'
|
||||
},
|
||||
'SPIFLASH' : {
|
||||
'pin_cs' : 'D14',
|
||||
|
||||
@ -53,7 +53,7 @@ info = {
|
||||
'default_console' : "EV_SERIAL1",
|
||||
'default_console_baudrate' : "115200",
|
||||
'variables' : 16383, # See note above
|
||||
'io_buffer_size' : 1024, # How big is the input buffer (in 4 byte words). Default is 256, but this makes us less likely to drop data
|
||||
'io_buffer_size' : 4096, # How big is the input buffer (in bytes). Default on nRF52 is 1024
|
||||
'binary_name' : 'espruino_%v_curio.bin',
|
||||
'build' : {
|
||||
'optimizeflags' : '-Og',
|
||||
@ -161,21 +161,21 @@ def get_pins():
|
||||
# pinutils.findpin(pins, "PD5", True)["functions"]["ADC2_IN0"]=0;
|
||||
# pinutils.findpin(pins, "PD8", True)["functions"]["NEGATED"]=0; # LED negated - but ESP32 port ignores negation
|
||||
# D12-D17 are SPI (internal SPI) - not sure they should even be exposed??
|
||||
|
||||
|
||||
pinutils.findpin(pins, "PD18", True)["functions"]["USB"]=0; # D-
|
||||
pinutils.findpin(pins, "PD19", True)["functions"]["USB"]=0; # D+
|
||||
pinutils.findpin(pins, "PD20", True)["functions"]["USART1_RX"]=0;
|
||||
pinutils.findpin(pins, "PD21", True)["functions"]["USART1_TX"]=0;
|
||||
pinutils.findpin(pins, "PD9", True)["functions"]["I2C1_SCL"]=0; # added for issue #2589 fix
|
||||
pinutils.findpin(pins, "PD8", True)["functions"]["I2C1_SDA"]=0; # added for issue #2589 fix
|
||||
|
||||
# SPI added for issue #2601
|
||||
|
||||
# SPI added for issue #2601
|
||||
# See esp-idf-4 /components/soc/esp32c3/include/soc/soc_caps.h
|
||||
pinutils.findpin(pins, "PD6", True)["functions"]["SPI1_SCK"]=0;
|
||||
pinutils.findpin(pins, "PD2", True)["functions"]["SPI1_MISO"]=0;
|
||||
pinutils.findpin(pins, "PD7", True)["functions"]["SPI1_MOSI"]=0;
|
||||
|
||||
|
||||
|
||||
|
||||
# everything is non-5v tolerant
|
||||
for pin in pins:
|
||||
|
||||
@ -38,8 +38,8 @@ import pinutils;
|
||||
# o D14 VCC
|
||||
# D15 D17
|
||||
# D2 D19
|
||||
# GND D18
|
||||
#
|
||||
# GND D18
|
||||
#
|
||||
|
||||
# unfitted header (assuming same dir as Button flex header)
|
||||
# VCC D10
|
||||
@ -61,7 +61,7 @@ info = {
|
||||
'espruino_page_link' : '',
|
||||
'default_console' : "EV_BLUETOOTH",
|
||||
'variables' : 5000, # How many variables are allocated for Espruino to use. RAM will be overflowed if this number is too high and code won't compile.
|
||||
'io_buffer_size' : 512,
|
||||
'io_buffer_size' : 2048, # How big is the input buffer (in bytes). Default on nRF52 is 1024
|
||||
'bootloader' : 1,
|
||||
'binary_name' : 'espruino_%v_dickens.hex',
|
||||
'build' : {
|
||||
@ -163,16 +163,16 @@ devices = {
|
||||
'pin_sck' : 'D12',
|
||||
'pin_mosi' : 'D5',
|
||||
'pin_miso' : 'D27',
|
||||
'pin_en' : 'D43',
|
||||
'pin_en' : 'D43',
|
||||
'pin_bl' : 'D33', # Also enables the power supply for the vibration motor
|
||||
'bitrate' : 32000000
|
||||
},
|
||||
'BAT' : {
|
||||
'pin_charging' : 'D13',
|
||||
'pin_charging' : 'D13',
|
||||
'pin_voltage' : 'D4'
|
||||
},
|
||||
'MAG' : { # Magnetometer/compass
|
||||
'device' : 'GMC303',
|
||||
'device' : 'GMC303',
|
||||
'addr' : 0x0C,
|
||||
'pin_sda' : 'D9',
|
||||
'pin_scl' : 'D10'
|
||||
@ -196,7 +196,7 @@ devices = {
|
||||
'pin_miso' : 'D23', # D1
|
||||
'pin_wp' : 'D21', # D2
|
||||
'pin_rst' : 'D24', # D3
|
||||
'size' : 4096*1024,
|
||||
'size' : 4096*1024,
|
||||
'memmap_base' : 0x60000000 # map into the address space (in software)
|
||||
}
|
||||
};
|
||||
@ -224,7 +224,7 @@ def get_pins():
|
||||
pinutils.findpin(pins, "PD46", True)["functions"]["NEGATED"]=0; # ok
|
||||
pinutils.findpin(pins, "PD42", True)["functions"]["NEGATED"]=0; # ok
|
||||
pinutils.findpin(pins, "PD28", True)["functions"]["NEGATED"]=0; # ok
|
||||
|
||||
|
||||
|
||||
# everything is non-5v tlerant
|
||||
for pin in pins:
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
|
||||
# A Note about the 'variables' parameter on ESP32 Builds
|
||||
# ------------------------------------------------------
|
||||
#
|
||||
#
|
||||
# For the ESP32 build, the number of JsVars is governed by two factors:
|
||||
# * Available memory
|
||||
# * Maximum number of JsVars for the used JsVar format
|
||||
@ -50,8 +50,8 @@ info = {
|
||||
'espruino_page_link' : 'ESP32',
|
||||
'default_console' : "EV_SERIAL1",
|
||||
'default_console_baudrate' : "115200",
|
||||
'variables' : 16383, # See note above
|
||||
'io_buffer_size' : 1024, # How big is the input buffer (in 4 byte words). Default is 256, but this makes us less likely to drop data
|
||||
'variables' : 16383, # See note above
|
||||
'io_buffer_size' : 4096, # How big is the input buffer (in bytes). Default on nRF52 is 1024
|
||||
'binary_name' : 'espruino_%v_esp32.bin',
|
||||
'build' : {
|
||||
'optimizeflags' : '-Og',
|
||||
@ -65,7 +65,7 @@ info = {
|
||||
'NEOPIXEL',
|
||||
'FILESYSTEM',
|
||||
'FLASHFS',
|
||||
'BLUETOOTH'
|
||||
'BLUETOOTH'
|
||||
],
|
||||
'makefile' : [
|
||||
'DEFINES+=-DESP_PLATFORM -DESP32=1',
|
||||
@ -187,8 +187,8 @@ def get_pins():
|
||||
pinutils.findpin(pins, "PD10", True)["functions"]["USART1_TX"]=0; # doesn't match jshardwareUart?
|
||||
pinutils.findpin(pins, "PD32", True)["functions"]["USART1_RX"]=0; # doesn't match jshardwareUart?
|
||||
pinutils.findpin(pins, "PD16", True)["functions"]["USART3_RX"]=0;
|
||||
pinutils.findpin(pins, "PD17", True)["functions"]["USART3_TX"]=0;
|
||||
|
||||
pinutils.findpin(pins, "PD17", True)["functions"]["USART3_TX"]=0;
|
||||
|
||||
pinutils.findpin(pins, "PD16", True)["functions"]["I2C2_SCL"]=1; # added for issue #2589 fix
|
||||
pinutils.findpin(pins, "PD17", True)["functions"]["I2C2_SDA"]=1; # added for issue #2589 fix
|
||||
pinutils.findpin(pins, "PD22", True)["functions"]["I2C1_SCL"]=0; # SCL moved from P21 for issue #2589
|
||||
@ -196,7 +196,7 @@ def get_pins():
|
||||
|
||||
# These SPI Pin defs used in jshSPISetup as of issue #2601
|
||||
# see esp-idf-4 /components/soc/esp32/include/soc/spi_pins.h
|
||||
pinutils.findpin(pins, "PD14", True)["functions"]["SPI1_SCK"]=0;
|
||||
pinutils.findpin(pins, "PD14", True)["functions"]["SPI1_SCK"]=0;
|
||||
pinutils.findpin(pins, "PD12", True)["functions"]["SPI1_MISO"]=0;
|
||||
pinutils.findpin(pins, "PD13", True)["functions"]["SPI1_MOSI"]=0;
|
||||
pinutils.findpin(pins, "PD18", True)["functions"]["SPI2_SCK"]=0;
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
# A Note about the 'variables' parameter on ESP32 Builds
|
||||
# ------------------------------------------------------
|
||||
#
|
||||
#
|
||||
# For the ESP32 build, the number of JsVars is governed by two factors:
|
||||
# * Available memory
|
||||
# * Maximum number of JsVars for the used JsVar format
|
||||
@ -52,8 +52,8 @@ info = {
|
||||
'espruino_page_link' : 'ESP32',
|
||||
'default_console' : "EV_SERIAL1",
|
||||
'default_console_baudrate' : "115200",
|
||||
'variables' : 16383, # See note above
|
||||
'io_buffer_size' : 1024, # How big is the input buffer (in 4 byte words). Default is 256, but this makes us less likely to drop data
|
||||
'variables' : 16383, # See note above
|
||||
'io_buffer_size' : 4096, # How big is the input buffer (in bytes). Default on nRF52 is 1024
|
||||
'binary_name' : 'espruino_%v_esp32c3.bin',
|
||||
'build' : {
|
||||
'optimizeflags' : '-Og',
|
||||
@ -67,14 +67,14 @@ info = {
|
||||
# 'FILESYSTEM',
|
||||
# 'FLASHFS',
|
||||
'BLUETOOTH',
|
||||
'NEOPIXEL'
|
||||
'NEOPIXEL'
|
||||
],
|
||||
'makefile' : [
|
||||
'DEFINES+=-DESP_PLATFORM -DESP32=1',
|
||||
'DEFINES+=-DESP_STACK_SIZE=25000',
|
||||
'DEFINES+=-DJSVAR_MALLOC', # Allocate space for variables at jsvInit time
|
||||
'DEFINES+=-DUSE_FONT_6X8',
|
||||
'DEFINES+=-DUSB_CDC', # Comment out to disable USB_CDC if board has uart interface
|
||||
'DEFINES+=-DUSB_CDC', # Comment out to disable USB_CDC if board has uart interface
|
||||
'ESP32_FLASH_MAX=1572864'
|
||||
]
|
||||
}
|
||||
@ -153,25 +153,25 @@ def get_pins():
|
||||
pinutils.findpin(pins, "PD2", True)["functions"]["ADC1_IN2"]=0;
|
||||
pinutils.findpin(pins, "PD3", True)["functions"]["ADC1_IN3"]=0;
|
||||
pinutils.findpin(pins, "PD4", True)["functions"]["ADC1_IN4"]=0;
|
||||
# pinutils.findpin(pins, "PD5", True)["functions"]["ADC2_IN0"]=0;
|
||||
# pinutils.findpin(pins, "PD5", True)["functions"]["ADC2_IN0"]=0;
|
||||
# On supermini D8 is (inverted) LED
|
||||
# On supermini D9 is (inverted) Button
|
||||
# D12-D17 are SPI (internal SPI) - not sure they should even be exposed??
|
||||
|
||||
|
||||
pinutils.findpin(pins, "PD18", True)["functions"]["USB"]=0; # D-
|
||||
pinutils.findpin(pins, "PD19", True)["functions"]["USB"]=0; # D+
|
||||
pinutils.findpin(pins, "PD20", True)["functions"]["USART1_RX"]=0;
|
||||
pinutils.findpin(pins, "PD21", True)["functions"]["USART1_TX"]=0;
|
||||
pinutils.findpin(pins, "PD9", True)["functions"]["I2C1_SCL"]=0; # added for issue #2589 fix
|
||||
pinutils.findpin(pins, "PD8", True)["functions"]["I2C1_SDA"]=0; # added for issue #2589 fix
|
||||
|
||||
# SPI added for issue #2601
|
||||
|
||||
# SPI added for issue #2601
|
||||
# See esp-idf-4 /components/soc/esp32c3/include/soc/soc_caps.h
|
||||
pinutils.findpin(pins, "PD6", True)["functions"]["SPI1_SCK"]=0;
|
||||
pinutils.findpin(pins, "PD2", True)["functions"]["SPI1_MISO"]=0;
|
||||
pinutils.findpin(pins, "PD7", True)["functions"]["SPI1_MOSI"]=0;
|
||||
|
||||
|
||||
|
||||
|
||||
# everything is non-5v tolerant
|
||||
for pin in pins:
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
# A Note about the 'variables' parameter on ESP32 Builds
|
||||
# ------------------------------------------------------
|
||||
#
|
||||
#
|
||||
# For the ESP32 build, the number of JsVars is governed by two factors:
|
||||
# * Available memory
|
||||
# * Maximum number of JsVars for the used JsVar format
|
||||
@ -52,8 +52,8 @@ info = {
|
||||
'espruino_page_link' : 'ESP32',
|
||||
'default_console' : "EV_SERIAL1",
|
||||
'default_console_baudrate' : "115200",
|
||||
'variables' : 16383, # See note above
|
||||
'io_buffer_size' : 1024, # How big is the input buffer (in 4 byte words). Default is 256, but this makes us less likely to drop data
|
||||
'variables' : 16383, # See note above
|
||||
'io_buffer_size' : 4096, # How big is the input buffer (in bytes). Default on nRF52 is 1024
|
||||
'binary_name' : 'espruino_%v_esp32s3.bin',
|
||||
'build' : {
|
||||
'optimizeflags' : '-Og',
|
||||
@ -67,14 +67,14 @@ info = {
|
||||
'NEOPIXEL',
|
||||
'FILESYSTEM',
|
||||
# 'FLASHFS',
|
||||
'BLUETOOTH'
|
||||
'BLUETOOTH'
|
||||
],
|
||||
'makefile' : [
|
||||
'DEFINES+=-DESP_PLATFORM -DESP32=1',
|
||||
'DEFINES+=-DESP_STACK_SIZE=25000',
|
||||
'DEFINES+=-DJSVAR_MALLOC', # Allocate space for variables at jsvInit time
|
||||
'DEFINES+=-DUSE_FONT_6X8',
|
||||
'DEFINES+=-DUSB_CDC', # Comment out to disable USB_CDC if board has uart interface
|
||||
'DEFINES+=-DUSB_CDC', # Comment out to disable USB_CDC if board has uart interface
|
||||
'ESP32_FLASH_MAX=1572864'
|
||||
]
|
||||
}
|
||||
@ -149,14 +149,14 @@ def get_pins():
|
||||
# Todo review as ESP32-S3 has there are 45 Physical GPIO pins Numbered 0->21 and 26->48
|
||||
# see https://www.espressif.com/sites/default/files/documentation/esp32-s3_technical_reference_manual_en.pdf
|
||||
pins = pinutils.generate_pins(0,39) # 40 General Purpose I/O Pins.
|
||||
|
||||
# I2C added for issue #2589 - all decided by user (not defined in specs)
|
||||
pinutils.findpin(pins, "PD8", True)["functions"]["I2C1_SDA"]=0;
|
||||
pinutils.findpin(pins, "PD9", True)["functions"]["I2C1_SCL"]=0;
|
||||
pinutils.findpin(pins, "PD18", True)["functions"]["I2C2_SDA"]=0;
|
||||
pinutils.findpin(pins, "PD19", True)["functions"]["I2C2_SCL"]=0;
|
||||
|
||||
# SPI added for issue #2601
|
||||
# I2C added for issue #2589 - all decided by user (not defined in specs)
|
||||
pinutils.findpin(pins, "PD8", True)["functions"]["I2C1_SDA"]=0;
|
||||
pinutils.findpin(pins, "PD9", True)["functions"]["I2C1_SCL"]=0;
|
||||
pinutils.findpin(pins, "PD18", True)["functions"]["I2C2_SDA"]=0;
|
||||
pinutils.findpin(pins, "PD19", True)["functions"]["I2C2_SCL"]=0;
|
||||
|
||||
# SPI added for issue #2601
|
||||
# - for SPI1 use pins that will bypass GPIO matrix (So Quicker) see esp-idf-4 /components/soc/esp32s3/include/soc/spi_pins.h
|
||||
pinutils.findpin(pins, "PD12", True)["functions"]["SPI1_SCK"]=0;
|
||||
pinutils.findpin(pins, "PD13", True)["functions"]["SPI1_MISO"]=0;
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
# A Note about the 'variables' parameter on ESP32 Builds
|
||||
# ------------------------------------------------------
|
||||
#
|
||||
#
|
||||
# For the ESP32 build, the number of JsVars is governed by two factors:
|
||||
# * Available memory
|
||||
# * Maximum number of JsVars for the used JsVar format
|
||||
@ -56,8 +56,8 @@ info = {
|
||||
'espruino_page_link' : 'ESP32',
|
||||
'default_console' : "EV_SERIAL1",
|
||||
'default_console_baudrate' : "115200",
|
||||
'variables' : 16383, # See note above
|
||||
'io_buffer_size' : 1024, # How big is the input buffer (in 4 byte words). Default is 256, but this makes us less likely to drop data
|
||||
'variables' : 16383, # See note above
|
||||
'io_buffer_size' : 4096, # How big is the input buffer (in bytes). Default on nRF52 is 1024
|
||||
'binary_name' : 'espruino_%v_esp32_cyd.bin',
|
||||
'build' : {
|
||||
'optimizeflags' : '-Og',
|
||||
@ -111,7 +111,7 @@ devices = {
|
||||
'LED2' : { 'pin' : 'D16' },
|
||||
'LED3' : { 'pin' : 'D17' },
|
||||
'BTN1' : { 'pin' : 'D0' },
|
||||
'SD' : { 'pin_cs' : 'D5',
|
||||
'SD' : { 'pin_cs' : 'D5',
|
||||
'pin_di' : 'D23',
|
||||
'pin_do' : 'D19',
|
||||
'pin_clk' : 'D18' },
|
||||
@ -128,7 +128,7 @@ devices = {
|
||||
'pin_scl' : 'D22',
|
||||
'pin_vcc' : 'D21',
|
||||
},
|
||||
'TOUCH' : {
|
||||
'TOUCH' : {
|
||||
'device' : 'XPT2046',
|
||||
'pin_irq' : 'D36',
|
||||
'pin_cs' : 'D33',
|
||||
@ -233,8 +233,8 @@ def get_pins():
|
||||
pinutils.findpin(pins, "PD10", True)["functions"]["USART1_TX"]=0; # doesn't match jshardwareUart?
|
||||
pinutils.findpin(pins, "PD32", True)["functions"]["USART1_RX"]=0; # doesn't match jshardwareUart?
|
||||
pinutils.findpin(pins, "PD16", True)["functions"]["USART3_RX"]=0;
|
||||
pinutils.findpin(pins, "PD17", True)["functions"]["USART3_TX"]=0;
|
||||
|
||||
pinutils.findpin(pins, "PD17", True)["functions"]["USART3_TX"]=0;
|
||||
|
||||
pinutils.findpin(pins, "PD16", True)["functions"]["I2C2_SCL"]=1; # added for issue #2589 fix
|
||||
pinutils.findpin(pins, "PD17", True)["functions"]["I2C2_SDA"]=1; # added for issue #2589 fix
|
||||
pinutils.findpin(pins, "PD22", True)["functions"]["I2C1_SCL"]=0; # SCL moved from P21 for issue #2589
|
||||
@ -242,7 +242,7 @@ def get_pins():
|
||||
|
||||
# These SPI Pin defs used in jshSPISetup as of issue #2601
|
||||
# see esp-idf-4 /components/soc/esp32/include/soc/spi_pins.h
|
||||
pinutils.findpin(pins, "PD14", True)["functions"]["SPI1_SCK"]=0;
|
||||
pinutils.findpin(pins, "PD14", True)["functions"]["SPI1_SCK"]=0;
|
||||
pinutils.findpin(pins, "PD12", True)["functions"]["SPI1_MISO"]=0;
|
||||
pinutils.findpin(pins, "PD13", True)["functions"]["SPI1_MOSI"]=0;
|
||||
pinutils.findpin(pins, "PD18", True)["functions"]["SPI2_SCK"]=0;
|
||||
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
# A Note about the 'variables' parameter on ESP32 Builds
|
||||
# ------------------------------------------------------
|
||||
#
|
||||
#
|
||||
# For the ESP32 build, the number of JsVars is governed by two factors:
|
||||
# * Available memory
|
||||
# * Maximum number of JsVars for the used JsVar format
|
||||
@ -52,8 +52,8 @@ info = {
|
||||
'espruino_page_link' : 'ESP32',
|
||||
'default_console' : "EV_SERIAL1",
|
||||
'default_console_baudrate' : "115200",
|
||||
'variables' : 16383, # See note above
|
||||
'io_buffer_size' : 1024, # How big is the input buffer (in 4 byte words). Default is 256, but this makes us less likely to drop data
|
||||
'variables' : 16383, # See note above
|
||||
'io_buffer_size' : 4096, # How big is the input buffer (in bytes). Default on nRF52 is 1024
|
||||
'binary_name' : 'espruino_%v_esp32.bin',
|
||||
'build' : {
|
||||
'optimizeflags' : '-Og',
|
||||
@ -67,7 +67,7 @@ info = {
|
||||
'NEOPIXEL',
|
||||
# 'FILESYSTEM',
|
||||
# 'FLASHFS',
|
||||
'BLUETOOTH'
|
||||
'BLUETOOTH'
|
||||
],
|
||||
'makefile' : [
|
||||
'DEFINES+=-DESP_PLATFORM -DESP32=1',
|
||||
@ -189,8 +189,8 @@ def get_pins():
|
||||
pinutils.findpin(pins, "PD10", True)["functions"]["USART1_TX"]=0; # doesn't match jshardwareUart?
|
||||
pinutils.findpin(pins, "PD32", True)["functions"]["USART1_RX"]=0; # doesn't match jshardwareUart?
|
||||
pinutils.findpin(pins, "PD16", True)["functions"]["USART3_RX"]=0;
|
||||
pinutils.findpin(pins, "PD17", True)["functions"]["USART3_TX"]=0;
|
||||
|
||||
pinutils.findpin(pins, "PD17", True)["functions"]["USART3_TX"]=0;
|
||||
|
||||
pinutils.findpin(pins, "PD16", True)["functions"]["I2C2_SCL"]=1; # added for issue #2589 fix
|
||||
pinutils.findpin(pins, "PD17", True)["functions"]["I2C2_SDA"]=1; # added for issue #2589 fix
|
||||
pinutils.findpin(pins, "PD22", True)["functions"]["I2C1_SCL"]=0; # SCL moved from P21 for issue #2589
|
||||
@ -198,7 +198,7 @@ def get_pins():
|
||||
|
||||
# These SPI Pin defs used in jshSPISetup as of issue #2601
|
||||
# see esp-idf-4 /components/soc/esp32/include/soc/spi_pins.h
|
||||
pinutils.findpin(pins, "PD14", True)["functions"]["SPI1_SCK"]=0;
|
||||
pinutils.findpin(pins, "PD14", True)["functions"]["SPI1_SCK"]=0;
|
||||
pinutils.findpin(pins, "PD12", True)["functions"]["SPI1_MISO"]=0;
|
||||
pinutils.findpin(pins, "PD13", True)["functions"]["SPI1_MOSI"]=0;
|
||||
pinutils.findpin(pins, "PD18", True)["functions"]["SPI2_SCK"]=0;
|
||||
|
||||
@ -24,7 +24,7 @@ info = {
|
||||
# 'default_console_rx' : "D8",
|
||||
# 'default_console_baudrate' : "9600",
|
||||
'variables' : 12000, # How many variables are allocated for Espruino to use. RAM will be overflowed if this number is too high and code won't compile.
|
||||
'io_buffer_size' : 512, # How big is the input buffer (in 4 byte words). Default on nRF52 is 256
|
||||
'io_buffer_size' : 2048, # How big is the input buffer (in bytes). Default on nRF52 is 1024
|
||||
'bootloader' : 1,
|
||||
'binary_name' : 'espruino_%v_joltjs.hex',
|
||||
'build' : {
|
||||
@ -133,7 +133,7 @@ devices = {
|
||||
'pin_d2' : 'D25',
|
||||
'pin_d3' : 'D34',
|
||||
'pin_d0_analog' : 'D30',
|
||||
'pin_d2_analog' : 'D28'
|
||||
'pin_d2_analog' : 'D28'
|
||||
}
|
||||
};
|
||||
|
||||
@ -162,18 +162,18 @@ board = {
|
||||
'Q1.fet' : "INVERTED. Connected to 500mA FET. When 1, GND on Q1 is pulled low. When 0, GND on Q1 is open circuit",
|
||||
},
|
||||
'_pinfunctions' : {
|
||||
'Q0.scl' : ["ADC1_IN5","3.3"],
|
||||
'Q0.scl' : ["ADC1_IN5","3.3"],
|
||||
'Q0.sda' : ["ADC1_IN1","3.3"],
|
||||
'Q1.scl' : ["ADC1_IN7","3.3"],
|
||||
'Q1.sda' : ["ADC1_IN0","3.3"],
|
||||
'Q2.scl' : ["3.3"],
|
||||
'Q2.scl' : ["3.3"],
|
||||
'Q2.sda' : ["3.3"],
|
||||
'Q2.vcc' : ["3.3"],
|
||||
'Q2.gnd' : ["3.3"],
|
||||
'Q3.scl' : ["3.3"],
|
||||
'Q3.scl' : ["3.3"],
|
||||
'Q3.sda' : ["3.3"],
|
||||
'Q3.vcc' : ["3.3"],
|
||||
'Q3.gnd' : ["3.3"],
|
||||
'Q3.gnd' : ["3.3"],
|
||||
'VCC' : ["3.3"]
|
||||
}
|
||||
};
|
||||
|
||||
@ -23,7 +23,7 @@ info = {
|
||||
'default_console_tx' : "B10",
|
||||
'default_console_rx' : "B11",
|
||||
'default_console_baudrate' : "115200",
|
||||
'io_buffer_size' : 512,
|
||||
'io_buffer_size' : 2048, # How big is the input buffer (in bytes). Default on nRF52 is 1024
|
||||
'xoff_thresh' : 3,
|
||||
'xon_thresh' : 2,
|
||||
'build' : {
|
||||
@ -66,7 +66,7 @@ info = {
|
||||
'WRAPPERSOURCES += libs/pipboy/jswrap_font_monofonto_28.c',
|
||||
'WRAPPERSOURCES += libs/pipboy/jswrap_font_monofonto_23.c',
|
||||
'WRAPPERSOURCES += libs/pipboy/jswrap_font_monofonto_18.c',
|
||||
'WRAPPERSOURCES += libs/pipboy/jswrap_font_monofonto_16.c',
|
||||
'WRAPPERSOURCES += libs/pipboy/jswrap_font_monofonto_16.c',
|
||||
'DEFINES+=-DUSBD_MANUFACTURER_STRING=\'"The Wand Company"\'',
|
||||
'DEFINES+=-DUSBD_PRODUCT_STRING_FS=\'"Pip-Boy"\'',
|
||||
'DEFINES+=-DUSB_PRODUCT_ID=0xA4F1', # 0xA4F1 assigned by ST for the Pip-Boy (0xA4DF = Tricorder)
|
||||
|
||||
@ -6401,10 +6401,10 @@ JsVar *jswrap_banglejs_appRect() {
|
||||
|
||||
|
||||
/// Called from jsinteractive when an event is parsed from the event queue for Bangle.js (executed outside IRQ)
|
||||
void jsbangle_exec_pending(IOEvent *evt) {
|
||||
assert(evt->flags & EV_BANGLEJS);
|
||||
uint16_t value = ((uint8_t)evt->data.chars[1])<<8 | (uint8_t)evt->data.chars[2];
|
||||
switch ((JsBangleEvent)evt->data.chars[0]) {
|
||||
void jsbangle_exec_pending(uint8_t *data, int dataLen) {
|
||||
JsBangleEvent evt = (JsBangleEvent)data[0];
|
||||
uint16_t value = data[1] | (data[2]<<8);
|
||||
switch (evt) {
|
||||
case JSBE_HRM_ENV: {
|
||||
JsVar *bangle = jsvObjectGetChildIfExists(execInfo.root, "Bangle");
|
||||
if (bangle) {
|
||||
@ -6420,12 +6420,11 @@ void jsbangle_exec_pending(IOEvent *evt) {
|
||||
|
||||
/// Called from jsinteractive when an event is parsed from the event queue for Bangle.js
|
||||
void jsbangle_push_event(JsBangleEvent type, uint16_t value) {
|
||||
IOEvent evt;
|
||||
evt.flags = EV_BANGLEJS;
|
||||
evt.data.chars[0] = type;
|
||||
evt.data.chars[1] = (char)((value>>8) & 0xFF);
|
||||
evt.data.chars[2] = (char)(value & 0xFF);
|
||||
jshPushEvent(&evt);
|
||||
uint8_t buf[3];
|
||||
buf[0] = type;
|
||||
buf[1] = (uint8_t)value;
|
||||
buf[2] = value>>8;
|
||||
jshPushEvent(EV_BANGLEJS, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
/*JSON{
|
||||
|
||||
@ -101,7 +101,7 @@ typedef enum {
|
||||
} JsBangleEvent;
|
||||
|
||||
/// Called from jsinteractive when an event is parsed from the event queue for Bangle.js (executed outside IRQ)
|
||||
void jsbangle_exec_pending(IOEvent *event);
|
||||
void jsbangle_exec_pending(uint8_t *data, int dataLen);
|
||||
/// queue an event for Bangle.js (usually called from inside an IRQ)
|
||||
void jsbangle_push_event(JsBangleEvent type, uint16_t value);
|
||||
|
||||
|
||||
@ -239,8 +239,8 @@ bool jsble_kill();
|
||||
/// Checks for error and reports an exception string if there was one, else 0 if no error
|
||||
JsVar *jsble_get_error_string(uint32_t err_code);
|
||||
|
||||
/** Execute a task that was added by jsble_queue_pending - this is done outside of IRQ land. Returns number of events handled */
|
||||
int jsble_exec_pending(IOEvent *event);
|
||||
/** Execute a task that was added by jsble_queue_pending - this is done outside of IRQ land. Returns number of event bytes handled */
|
||||
int jsble_exec_pending(uint8_t *data, int dataLen);
|
||||
|
||||
/** Stop and restart the softdevice so that we can update the services in it -
|
||||
* both user-defined as well as UART/HID. If jsFunction is a function it is
|
||||
|
||||
@ -374,32 +374,30 @@ uint16_t bleGetGATTHandle(ble_uuid_t char_uuid) {
|
||||
|
||||
/// Add a new bluetooth event to the queue with a buffer of data
|
||||
void jsble_queue_pending_buf(BLEPending blep, uint16_t data, char *ptr, size_t len) {
|
||||
assert(ptr);
|
||||
assert(len+3 < IOEVENT_MAX_LEN);
|
||||
if (len+3 > IOEVENT_MAX_LEN)
|
||||
len = IOEVENT_MAX_LEN-3;
|
||||
// check to ensure we have space for the data we're adding
|
||||
if (!jshHasEventSpaceForChars(len+IOEVENT_MAXCHARS)) {
|
||||
if (!jshHasEventSpaceForChars(len+3)) {
|
||||
jsErrorFlags |= JSERR_RX_FIFO_FULL;
|
||||
return;
|
||||
}
|
||||
// Push the data for the event first
|
||||
while (len) {
|
||||
int evtLen = len;
|
||||
if (evtLen > IOEVENT_MAXCHARS) evtLen=IOEVENT_MAXCHARS;
|
||||
IOEvent evt;
|
||||
evt.flags = EV_BLUETOOTH_PENDING_DATA;
|
||||
IOEVENTFLAGS_SETCHARS(evt.flags, evtLen);
|
||||
memcpy(evt.data.chars, ptr, evtLen);
|
||||
jshPushEvent(&evt);
|
||||
ptr += evtLen;
|
||||
len -= evtLen;
|
||||
}
|
||||
// Push the actual event
|
||||
JsSysTime d = (JsSysTime)((data<<8)|blep);
|
||||
jshPushIOEvent(EV_BLUETOOTH_PENDING, d);
|
||||
uint8_t buf[IOEVENT_MAX_LEN];
|
||||
buf[0] = blep;
|
||||
buf[1] = data;
|
||||
buf[2] = data>>8;
|
||||
memcpy(&buf[3], ptr, len);
|
||||
jshPushEvent(EV_BLUETOOTH_PENDING, buf, len+3);
|
||||
}
|
||||
|
||||
/// Add a new bluetooth event to the queue with 16 bits of data
|
||||
void jsble_queue_pending(BLEPending blep, uint16_t data) {
|
||||
JsSysTime d = (JsSysTime)((data<<8)|blep);
|
||||
jshPushIOEvent(EV_BLUETOOTH_PENDING, d);
|
||||
uint8_t buf[3];
|
||||
buf[0] = blep;
|
||||
buf[1] = data;
|
||||
buf[2] = data>>8;
|
||||
jshPushEvent(EV_BLUETOOTH_PENDING, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
/* Handler for common event types (between nRF52/ESP32). Called first
|
||||
@ -417,7 +415,9 @@ bool jsble_exec_pending_common(BLEPending blep, uint16_t data, unsigned char *bu
|
||||
BLEAdvReportData *p_adv = (BLEAdvReportData *)buffer;
|
||||
size_t len = sizeof(BLEAdvReportData) + p_adv->dlen - BLE_GAP_ADV_MAX_SIZE;
|
||||
if (bufferLen != len) {
|
||||
jsiConsolePrintf("%d %d %d\n", bufferLen,len,p_adv->dlen);
|
||||
#ifndef RELEASE
|
||||
jsiConsolePrintf("BLEP_ADV %d %d %d\n", bufferLen,len,p_adv->dlen);
|
||||
#endif
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -185,13 +185,10 @@ void trigOnTimingPulse(TriggerStruct *data, JsSysTime pulseTime) {
|
||||
|
||||
/** Actually handle a trigger event, and do stuff if it is for us */
|
||||
bool trigHandleEXTI(IOEventFlags channel, JsSysTime time) {
|
||||
IOEvent event;
|
||||
event.flags = channel;
|
||||
|
||||
if (mainTrigger.sensorPin!=PIN_UNDEFINED && jshIsEventForPin(&event, mainTrigger.sensorPin)) {
|
||||
if (mainTrigger.sensorPin!=PIN_UNDEFINED && jshIsEventForPin(channel, mainTrigger.sensorPin)) {
|
||||
// jshPinOutput(JSH_PORTB_OFFSET + 4, event.flags & EV_EXTI_IS_HIGH);
|
||||
|
||||
if (!(event.flags & EV_EXTI_IS_HIGH)) // we only care about falling edges
|
||||
if (!(channel & EV_EXTI_IS_HIGH)) // we only care about falling edges
|
||||
trigOnTimingPulse(&mainTrigger, time);
|
||||
return true; // return true anyway, so stop this being added to our event queue
|
||||
}
|
||||
|
||||
@ -758,20 +758,28 @@ codeOut('')
|
||||
|
||||
codeOut("/** Tasks to run when a character is received on a certain event channel. True if handled and shouldn't go to IRQ (type:'EV_SERIAL1/etc' in JSON) */")
|
||||
codeOut('bool jswOnCharEvent(IOEventFlags channel, char charData) {')
|
||||
codeOut(' NOT_USED(channel);')
|
||||
codeOut(' NOT_USED(charData);')
|
||||
used = False
|
||||
for jsondata in jsondatas:
|
||||
if "type" in jsondata and jsondata["type"]!="EV_CUSTOM" and jsondata["type"].startswith("EV_"):
|
||||
codeOut(" if (channel=="+jsondata["type"]+") return "+jsondata["generate"]+"(charData);")
|
||||
used = True
|
||||
if not used:
|
||||
codeOut(' NOT_USED(channel);')
|
||||
codeOut(' NOT_USED(charData);')
|
||||
codeOut(' return false;')
|
||||
codeOut('}')
|
||||
|
||||
codeOut("/** When we receive EV_CUSTOM, this is called so any library (eg Waveform) can hook onto it (type:'EV_CUSTOM' in JSON) */")
|
||||
codeOut('void jswOnCustomEvent(IOEvent *event) {')
|
||||
codeOut(' NOT_USED(event);')
|
||||
codeOut('void jswOnCustomEvent(IOEventFlags eventFlags, uint8_t *data, int dataLen) {')
|
||||
used = False
|
||||
for jsondata in jsondatas:
|
||||
if "type" in jsondata and jsondata["type"]=="EV_CUSTOM":
|
||||
codeOut(" "+jsondata["generate"]+"(event);")
|
||||
codeOut(" "+jsondata["generate"]+"(eventFlags, data, dataLen);")
|
||||
used = True
|
||||
if not used:
|
||||
codeOut(' NOT_USED(eventFlags);')
|
||||
codeOut(' NOT_USED(data);')
|
||||
codeOut(' NOT_USED(dataLen);')
|
||||
codeOut('}')
|
||||
|
||||
codeOut('')
|
||||
@ -783,9 +791,12 @@ codeOut('')
|
||||
|
||||
codeOut("/** If we have a built-in module with the given name, return the module's contents - or 0 */")
|
||||
codeOut('const char *jswGetBuiltInJSLibrary(const char *name) {')
|
||||
codeOut(' NOT_USED(name);')
|
||||
used = False
|
||||
for modulename in jsmodules:
|
||||
codeOut(" if (!strcmp(name,\""+modulename+"\")) return "+common.as_c_string(jsmodules[modulename])+";")
|
||||
used = True
|
||||
if not used:
|
||||
codeOut(' NOT_USED(name);')
|
||||
codeOut(' return 0;')
|
||||
codeOut('}')
|
||||
|
||||
|
||||
@ -341,21 +341,21 @@ xoff_thresh = 6 # how full (out of 8) is buffer when we sent the XOFF flow contr
|
||||
xon_thresh = 3 # how full (out of 8) is buffer when we sent the XON flow control char to say 'go'
|
||||
|
||||
if LINUX:
|
||||
bufferSizeIO = 256
|
||||
bufferSizeIO = 1024
|
||||
bufferSizeTX = 256
|
||||
bufferSizeTimer = 16
|
||||
elif EMSCRIPTEN:
|
||||
bufferSizeIO = 256
|
||||
bufferSizeIO = 1024
|
||||
bufferSizeTX = 256
|
||||
bufferSizeTimer = 16
|
||||
else:
|
||||
# IO buffer - for received chars, setWatch, etc
|
||||
bufferSizeIO = 64
|
||||
if board.chip["ram"]>=20: bufferSizeIO = 128
|
||||
if board.chip["ram"]>=96: bufferSizeIO = 256
|
||||
bufferSizeIO = 256
|
||||
if board.chip["ram"]>=20: bufferSizeIO = 512
|
||||
if board.chip["ram"]>=96: bufferSizeIO = 1024
|
||||
# NRF52 needs this as Bluetooth traffic is funnelled through the buffer
|
||||
if board.chip["family"]=="NRF52":
|
||||
bufferSizeIO = 256
|
||||
bufferSizeIO = 1024
|
||||
# we often use increased MTUs and even with a big buffer these mean we need to leave
|
||||
# a lot of space when we send XOFF (due to delay in response from sender)
|
||||
xoff_thresh = 3
|
||||
@ -376,8 +376,8 @@ if 'xoff_thresh' in board.info:
|
||||
if 'xon_thresh' in board.info:
|
||||
xon_thresh = board.info['xon_thresh']
|
||||
|
||||
codeOut("#define IOBUFFERMASK "+str(bufferSizeIO-1)+" // (max 65535) amount of items in event buffer - events take 5 bytes each")
|
||||
codeOut("#define TXBUFFERMASK "+str(bufferSizeTX-1)+" // (max 255) amount of items in the transmit buffer - 2 bytes each")
|
||||
codeOut("#define IOBUFFERMASK "+str(bufferSizeIO-1)+" // (max 65535, 2^n-1) amount of items in event buffer - each event uses 2+dataLen bytes")
|
||||
codeOut("#define TXBUFFERMASK "+str(bufferSizeTX-1)+" // (max 255, 2^n-1) amount of items in the transmit buffer - 2 bytes each")
|
||||
codeOut("#define UTILTIMERTASK_TASKS ("+str(bufferSizeTimer)+") // Must be power of 2 - and max 256")
|
||||
|
||||
codeOut("");
|
||||
|
||||
@ -68,7 +68,7 @@ if "check_output" not in dir( subprocess ):
|
||||
# // hwinit = function to run on Hardware Initialisation (called once at boot time, after jshInit, before jsvInit/etc)
|
||||
# // init = function to run on Initialisation (eg boot/load/reset/after save/etc)
|
||||
# // kill = function to run on Deinitialisation (eg before save/reset/etc)
|
||||
# // EV_CUSTOM = Called whenever an event of type EV_CUSTOM is received (jswOnCustomEvent(event))
|
||||
# // EV_CUSTOM = Called whenever an event of type EV_CUSTOM is received (jswOnCustomEvent(eventFlags, data, dataLen))
|
||||
# // EV_xxx = Something to be called with a character in an IRQ when it is received (eg. EV_SERIAL1) (jswOnCharEvent)
|
||||
# // powerusage = fn(JsVar*) called with an object, and should insert fields for deviec names and estimated power usage in uA (jswGetPowerUsage)
|
||||
# "class" : "Double",
|
||||
|
||||
223
src/jsdevices.c
223
src/jsdevices.c
@ -35,22 +35,16 @@ JshEventCallbackCallback jshEventCallbacks[EV_EXTI_MAX+1-EV_EXTI0];
|
||||
// ----------------------------------------------------------------------------
|
||||
// DATA TRANSMIT BUFFER
|
||||
|
||||
/**
|
||||
* A single character to be transmitted.
|
||||
*/
|
||||
/// A single character to be transmitted.
|
||||
typedef struct {
|
||||
IOEventFlags flags; //!< Where this data should be transmitted
|
||||
unsigned char data; //!< data to transmit
|
||||
} PACKED_FLAGS TxBufferItem;
|
||||
|
||||
/**
|
||||
* An array of items to transmit.
|
||||
*/
|
||||
/// A FIFO of items to transmit, to be read from IRQ
|
||||
volatile TxBufferItem txBuffer[TXBUFFERMASK+1];
|
||||
|
||||
/**
|
||||
* The head and tail of the list.
|
||||
*/
|
||||
/// The head and tail of the list.
|
||||
volatile unsigned char txHead=0, txTail=0;
|
||||
|
||||
typedef enum {
|
||||
@ -79,8 +73,36 @@ typedef uint8_t IOBufferIdx;
|
||||
typedef uint16_t IOBufferIdx;
|
||||
#endif
|
||||
|
||||
volatile IOEvent ioBuffer[IOBUFFERMASK+1];
|
||||
volatile IOBufferIdx ioHead=0, ioTail=0;
|
||||
/** A FIFO of received events from IRQ -> mainloop
|
||||
|
||||
Format:
|
||||
|
||||
* 1 byte: Length (excl length+flags)
|
||||
* 1 byte: Flags (IOEventFlags)
|
||||
* ... Length bytes of data ...
|
||||
|
||||
So to skip forward you add 2 to length
|
||||
|
||||
|
||||
.....LFdddddLFdddLFddddd......
|
||||
^ ^ ^
|
||||
ioTail ioLastHead ioHead
|
||||
|
||||
* Data added at ioHead
|
||||
* ioLastHead is the last packet data was added (or ioHead if none)
|
||||
- this is used for appending single characters to existing packets
|
||||
* Data removed from ioTail
|
||||
|
||||
|
||||
|
||||
* EV_EXTx events include a uint32_t time
|
||||
* EV_CUSTOM events start with IOCustomEventFlags
|
||||
|
||||
*/
|
||||
volatile uint8_t ioBuffer[IOBUFFERMASK+1];
|
||||
|
||||
/// The head and tail of the list.
|
||||
volatile IOBufferIdx ioHead=0, ioLastHead=0, ioTail=0;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
@ -414,82 +436,77 @@ void CALLED_FROM_INTERRUPT jshIOEventOverflowed() {
|
||||
jsErrorFlags |= JSERR_RX_FIFO_FULL;
|
||||
}
|
||||
|
||||
/// Push an IO event into the ioBuffer (designed to be called from IRQ)
|
||||
void CALLED_FROM_INTERRUPT jshPushEvent(IOEvent *evt) {
|
||||
/* Make new buffer
|
||||
*
|
||||
* We're disabling IRQs for this bit because it's actually quite likely for
|
||||
/// Push an IO event (max IOEVENT_MAX_LEN) into the ioBuffer (designed to be called from IRQ), returns true on success, Calls jshHadEvent();
|
||||
bool CALLED_FROM_INTERRUPT jshPushEvent(IOEventFlags evt, uint8_t *data, int length) {
|
||||
assert(length<IOEVENT_MAX_LEN);
|
||||
if (length>IOEVENT_MAX_LEN) length=IOEVENT_MAX_LEN;
|
||||
/* We're disabling IRQs for this bit because it's actually quite likely for
|
||||
* USB and USART data to be coming in at the same time, and it can trip
|
||||
* things up if one IRQ interrupts another. */
|
||||
jshInterruptOff();
|
||||
IOBufferIdx nextHead = (IOBufferIdx)((ioHead+1) & IOBUFFERMASK);
|
||||
if (ioTail == nextHead) {
|
||||
int available = IOBUFFERMASK+1-jshGetEventsUsed();
|
||||
if (available < length+2) {
|
||||
jshInterruptOn();
|
||||
jshIOEventOverflowed();
|
||||
return; // queue full - dump this event!
|
||||
return false; // queue full - dump this event!
|
||||
}
|
||||
ioBuffer[ioHead] = *evt;
|
||||
ioHead = nextHead;
|
||||
IOBufferIdx idx = ioHead;
|
||||
ioBuffer[idx] = length;
|
||||
idx = (idx+1) & IOBUFFERMASK;
|
||||
ioBuffer[idx] = evt;
|
||||
idx = (idx+1) & IOBUFFERMASK;
|
||||
for (int i=0;i<length;i++) {
|
||||
ioBuffer[idx] = data[i];
|
||||
idx = (idx+1) & IOBUFFERMASK;
|
||||
}
|
||||
ioLastHead = ioHead;
|
||||
ioHead = idx;
|
||||
jshInterruptOn();
|
||||
}
|
||||
|
||||
/// Attempt to push characters onto an existing event
|
||||
static bool jshPushIOCharEventAppend(IOEventFlags channel, char charData) {
|
||||
IOBufferIdx lastHead = (IOBufferIdx)((ioHead+IOBUFFERMASK) & IOBUFFERMASK); // one behind head
|
||||
if (ioHead!=ioTail && lastHead!=ioTail) {
|
||||
// we can do this because we only read in main loop, and we're in an interrupt here
|
||||
if (IOEVENTFLAGS_GETTYPE(ioBuffer[lastHead].flags) == channel) {
|
||||
unsigned char c = (unsigned char)IOEVENTFLAGS_GETCHARS(ioBuffer[lastHead].flags);
|
||||
if (c < IOEVENT_MAXCHARS) {
|
||||
// last event was for this event type, and it has chars left
|
||||
ioBuffer[lastHead].data.chars[c] = charData;
|
||||
IOEVENTFLAGS_SETCHARS(ioBuffer[lastHead].flags, c+1);
|
||||
return true; // char added, job done
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
jshHadEvent();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Try and handle events in the IRQ itself. true if handled and shouldn't go in queue
|
||||
static bool jshPushIOCharEventHandler(IOEventFlags channel, char charData) {
|
||||
static bool jshPushIOCharEventsHandler(IOEventFlags channel, char *data, unsigned int count) {
|
||||
// Check for a CTRL+C
|
||||
if (charData==3 && channel==jsiGetConsoleDevice()) {
|
||||
jsiCtrlC(); // Ctrl-C - force interrupt of execution
|
||||
bool handled = false;
|
||||
for (unsigned int i=0;i<count;i++) {
|
||||
if (data[i]==3 && channel==jsiGetConsoleDevice()) {
|
||||
jsiCtrlC(); // Ctrl-C - force interrupt of execution
|
||||
}
|
||||
handled |= jswOnCharEvent(channel, data[i]); // FIXME: this could handle multiple events at once?
|
||||
}
|
||||
return jswOnCharEvent(channel, charData);
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
||||
// Set flow control (as we're going to use more data)
|
||||
static void jshPushIOCharEventFlowControl(IOEventFlags channel) {
|
||||
void jshPushIOCharEvents(IOEventFlags channel, char *data, unsigned int count) {
|
||||
// See if we need to handle this in the IRQ
|
||||
if (jshPushIOCharEventsHandler(channel, data, count)) return;
|
||||
// See if we can add this onto an existing event
|
||||
if (ioLastHead != ioHead && // we have a 'last head'
|
||||
ioLastHead != ioTail && // it's not something that'll be processed immediately (we're in IRQ so main loop might be in the process right now)
|
||||
ioBuffer[(ioLastHead+1)&IOBUFFERMASK] == channel && // same channel
|
||||
ioBuffer[ioLastHead]+count < IOEVENT_MAX_LEN // we have space in this event!
|
||||
) {
|
||||
// increase event count
|
||||
ioBuffer[ioLastHead] += count;
|
||||
// copy data
|
||||
for (int i=0;i<count;i++) {
|
||||
ioBuffer[ioHead] = data[i];
|
||||
ioHead = (ioHead+1) & IOBUFFERMASK;
|
||||
}
|
||||
} else {
|
||||
// Push the event
|
||||
jshPushEvent(channel, data, count);
|
||||
}
|
||||
// Set flow control (as we've just filled the buffer up more)
|
||||
if (DEVICE_HAS_DEVICE_STATE(channel) && jshGetEventsUsed() > IOBUFFER_XOFF)
|
||||
jshSetFlowControlXON(channel, false);
|
||||
}
|
||||
|
||||
/// Send a character to the specified device.
|
||||
void jshPushIOCharEvent(
|
||||
IOEventFlags channel, // !< The device to target for output.
|
||||
char charData // !< The character to send to the device.
|
||||
) {
|
||||
// See if we need to handle this in the IRQ
|
||||
if (jshPushIOCharEventHandler(channel, charData)) return;
|
||||
// Check if we can push into existing buffer (we must have at least 2 in the queue to avoid dropping chars though!)
|
||||
if (jshPushIOCharEventAppend(channel, charData)) return;
|
||||
|
||||
IOEvent evt;
|
||||
evt.flags = channel;
|
||||
IOEVENTFLAGS_SETCHARS(evt.flags, 1);
|
||||
evt.data.chars[0] = charData;
|
||||
jshPushEvent(&evt);
|
||||
// Set flow control (as we're going to use more data)
|
||||
jshPushIOCharEventFlowControl(channel);
|
||||
}
|
||||
|
||||
void jshPushIOCharEvents(IOEventFlags channel, char *data, unsigned int count) {
|
||||
// TODO: optimise me!
|
||||
unsigned int i;
|
||||
for (i=0;i<count;i++) jshPushIOCharEvent(channel, data[i]);
|
||||
void jshPushIOCharEvent(IOEventFlags channel, char ch) {
|
||||
jshPushIOCharEvents(channel, &ch, 1);
|
||||
}
|
||||
|
||||
/* Signal an IO watch event as having happened. Calls jshHadEvent();
|
||||
@ -529,55 +546,69 @@ void CALLED_FROM_INTERRUPT jshPushIOWatchEvent(
|
||||
jshPushIOEvent(channel, time);
|
||||
}
|
||||
|
||||
/// Add this IO event to the IO event queue. Calls jshHadEvent();
|
||||
/// Add this IO event to the IO event queue.
|
||||
void CALLED_FROM_INTERRUPT jshPushIOEvent(
|
||||
IOEventFlags channel, //!< The event to add to the queue.
|
||||
JsSysTime time //!< The time that the event is thought to have happened.
|
||||
) {
|
||||
IOEvent evt;
|
||||
evt.flags = channel;
|
||||
evt.data.time = (unsigned int)time;
|
||||
jshPushEvent(&evt);
|
||||
jshHadEvent();
|
||||
uint32_t t = (uint32_t)time;
|
||||
jshPushEvent(channel, &t, 4);
|
||||
}
|
||||
|
||||
// returns true on success
|
||||
bool jshPopIOEvent(IOEvent *result) {
|
||||
if (ioHead==ioTail) return false;
|
||||
*result = ioBuffer[ioTail];
|
||||
ioTail = (IOBufferIdx)((ioTail+1) & IOBUFFERMASK);
|
||||
return true;
|
||||
// pop an IO event, returns EV_NONE on failure
|
||||
IOEventFlags jshPopIOEvent(uint8_t *data, int *length) {
|
||||
if (ioHead==ioTail) return EV_NONE;
|
||||
if (ioLastHead==ioTail) ioLastHead = ioHead; // if we're processing last head now, reset it
|
||||
IOBufferIdx idx = ioTail;
|
||||
int len = (int)(uint32_t)ioBuffer[idx];
|
||||
idx = (IOBufferIdx)((idx+1) & IOBUFFERMASK);
|
||||
IOEventFlags evt = (IOEventFlags)ioBuffer[idx];
|
||||
idx = (IOBufferIdx)((idx+1) & IOBUFFERMASK);
|
||||
// pull out data
|
||||
if (length) *length=len;
|
||||
for (int i=0;i<len;i++) {
|
||||
if (data) data[i] = ioBuffer[idx];
|
||||
idx = (IOBufferIdx)((idx+1) & IOBUFFERMASK);
|
||||
}
|
||||
ioTail = idx;
|
||||
return evt;
|
||||
}
|
||||
|
||||
// returns true on success
|
||||
bool jshPopIOEventOfType(IOEventFlags eventType, IOEvent *result) {
|
||||
// Special case for top - it's easier!
|
||||
if (IOEVENTFLAGS_GETTYPE(ioBuffer[ioTail].flags) == eventType)
|
||||
return jshPopIOEvent(result);
|
||||
// Now check non-top
|
||||
// pop an IO event of type eventType, returns true on success
|
||||
IOEventFlags jshPopIOEventOfType(IOEventFlags eventType, uint8_t *data, int *length) {
|
||||
IOBufferIdx i = ioTail;
|
||||
while (ioHead!=i) {
|
||||
if (IOEVENTFLAGS_GETTYPE(ioBuffer[i].flags) == eventType) {
|
||||
uint32_t len = (uint32_t)ioBuffer[ioTail];
|
||||
IOBufferIdx j = (IOBufferIdx)((i+1) & IOBUFFERMASK);
|
||||
IOEventFlags evt = (IOEventFlags)ioBuffer[ioTail];
|
||||
if (IOEVENTFLAGS_GETTYPE(evt) == eventType) {
|
||||
j = (IOBufferIdx)((j+1) & IOBUFFERMASK);
|
||||
/* We need IRQ off for this, because if we get data it's possible
|
||||
that the IRQ will push data and will try and add characters to this
|
||||
exact position in the buffer */
|
||||
jshInterruptOff();
|
||||
*result = ioBuffer[i];
|
||||
// work back and shift all items in out queue
|
||||
IOBufferIdx n = (IOBufferIdx)((i+IOBUFFERMASK) & IOBUFFERMASK);
|
||||
// copy out data
|
||||
if (length) *length=len;
|
||||
for (int i=0;i<len;i++) {
|
||||
if (data) data[i] = ioBuffer[j];
|
||||
j = (IOBufferIdx)((j+1) & IOBUFFERMASK);
|
||||
}
|
||||
// work back and shift all items in queue
|
||||
IOBufferIdx n = (IOBufferIdx)((i+IOBUFFERMASK+1-len) & IOBUFFERMASK);
|
||||
while (n!=ioTail) {
|
||||
ioBuffer[i] = ioBuffer[n];
|
||||
i = n;
|
||||
n = (IOBufferIdx)((n+IOBUFFERMASK) & IOBUFFERMASK);
|
||||
}
|
||||
// finally update the tail pointer, and return
|
||||
ioTail = (IOBufferIdx)((ioTail+1) & IOBUFFERMASK);
|
||||
ioTail = (IOBufferIdx)((ioTail+IOBUFFERMASK+1-len) & IOBUFFERMASK);
|
||||
ioLastHead = ioHead; // reset last head - if we're removing stuff in the middle it's easier not to optimise!
|
||||
jshInterruptOn();
|
||||
return true;
|
||||
return evt;
|
||||
}
|
||||
i = (IOBufferIdx)((i+1) & IOBUFFERMASK);
|
||||
i = (IOBufferIdx)((i+len+2) & IOBUFFERMASK);
|
||||
}
|
||||
return false;
|
||||
return EV_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -591,7 +622,7 @@ bool jshHasEvents() {
|
||||
/// Check if the top event is for the given device
|
||||
bool jshIsTopEvent(IOEventFlags eventType) {
|
||||
if (ioHead==ioTail) return false;
|
||||
return IOEVENTFLAGS_GETTYPE(ioBuffer[ioTail].flags) == eventType;
|
||||
return IOEVENTFLAGS_GETTYPE(ioBuffer[(ioTail+1)&IOBUFFERMASK]) == eventType;
|
||||
}
|
||||
|
||||
int jshGetEventsUsed() {
|
||||
@ -601,7 +632,7 @@ int jshGetEventsUsed() {
|
||||
|
||||
int jshGetIOCharEventsFree() {
|
||||
int spaceLeft = IOBUFFERMASK+1-jshGetEventsUsed();
|
||||
return spaceLeft*IOEVENT_MAXCHARS-4; // be sensible - leave a little spare
|
||||
return spaceLeft-4; // be sensible - leave a little spare
|
||||
}
|
||||
|
||||
bool jshHasEventSpaceForChars(int n) {
|
||||
|
||||
@ -86,7 +86,6 @@ typedef enum {
|
||||
#endif
|
||||
#ifdef BLUETOOTH
|
||||
EV_BLUETOOTH_PENDING, // Tasks that came from the Bluetooth Stack in an IRQ
|
||||
EV_BLUETOOTH_PENDING_DATA, // Data for pending tasks - this comes after the EV_BLUETOOTH_PENDING task itself
|
||||
#endif
|
||||
EV_CUSTOM, ///< Custom event (See IOCustomEventFlags)
|
||||
#ifdef BANGLEJS
|
||||
@ -119,10 +118,6 @@ typedef enum {
|
||||
EV_DEVICE_MAX,
|
||||
// EV_DEVICE_MAX should not be >64 - see DEVICE_INITIALISED_FLAGS
|
||||
EV_TYPE_MASK = NEXT_POWER_2(EV_DEVICE_MAX) - 1,
|
||||
// ----------------------------------------- CHARACTERS RECEIVED
|
||||
EV_CHARS_ONE = EV_TYPE_MASK+1,
|
||||
EV_CHARS_SHIFT = GET_BIT_NUMBER(EV_CHARS_ONE),
|
||||
EV_CHARS_MASK = 3 * EV_CHARS_ONE, // see IOEVENT_MAXCHARS
|
||||
// ----------------------------------------- SERIAL STATUS
|
||||
EV_SERIAL_STATUS_FRAMING_ERR = EV_TYPE_MASK+1,
|
||||
EV_SERIAL_STATUS_PARITY_ERR = EV_SERIAL_STATUS_FRAMING_ERR<<1,
|
||||
@ -178,37 +173,31 @@ typedef enum {
|
||||
#endif
|
||||
|
||||
#define IOEVENTFLAGS_GETTYPE(X) ((X)&EV_TYPE_MASK)
|
||||
#define IOEVENTFLAGS_GETCHARS(X) ((((X)&EV_CHARS_MASK)>>EV_CHARS_SHIFT)+1)
|
||||
#define IOEVENTFLAGS_SETCHARS(X,CHARS) ((X)=(((X)&(IOEventFlags)~EV_CHARS_MASK) | (((CHARS)-1)<<EV_CHARS_SHIFT)))
|
||||
#define IOEVENT_MAXCHARS 4 // See EV_CHARS_MASK
|
||||
|
||||
typedef union {
|
||||
unsigned int time; ///< BOTTOM 32 BITS of time the event occurred
|
||||
char chars[IOEVENT_MAXCHARS]; ///< Characters received
|
||||
} PACKED_FLAGS IOEventData;
|
||||
|
||||
// IO Events - these happen when a pin changes
|
||||
typedef struct IOEvent {
|
||||
IOEventFlags flags; //!< Where this came from, and # of chars in it
|
||||
IOEventData data;
|
||||
} PACKED_FLAGS IOEvent;
|
||||
|
||||
// maximum length for an event. BLE is the biggest event we have so deal with that if we need to
|
||||
#if NRF_BLE_MAX_MTU_SIZE>61
|
||||
#define IOEVENT_MAX_LEN (NRF_BLE_MAX_MTU_SIZE+3)
|
||||
#else
|
||||
#define IOEVENT_MAX_LEN 64
|
||||
#endif
|
||||
|
||||
#include "jspin.h"
|
||||
|
||||
/// Push an IO event into the ioBuffer (designed to be called from IRQ)
|
||||
void jshPushEvent(IOEvent *evt);
|
||||
/// Push an IO event (max IOEVENT_MAX_LEN) into the ioBuffer (designed to be called from IRQ), returns true on success, Calls jshHadEvent();
|
||||
bool CALLED_FROM_INTERRUPT jshPushEvent(IOEventFlags evt, uint8_t *data, int length);
|
||||
/// Add this IO event to the IO event queue. Calls jshHadEvent();
|
||||
void jshPushIOEvent(IOEventFlags channel, JsSysTime time);
|
||||
/// Signal an IO watch event as having happened. Calls jshHadEvent();
|
||||
void jshPushIOWatchEvent(IOEventFlags channel);
|
||||
/// Push a single character event (for example USART RX)
|
||||
void jshPushIOCharEvent(IOEventFlags channel, char charData);
|
||||
void jshPushIOCharEvent(IOEventFlags channel, char ch);
|
||||
/// Push many character events at once (for example USB RX)
|
||||
void jshPushIOCharEvents(IOEventFlags channel, char *data, unsigned int count);
|
||||
|
||||
bool jshPopIOEvent(IOEvent *result); ///< returns true on success
|
||||
bool jshPopIOEventOfType(IOEventFlags eventType, IOEvent *result); ///< returns true on success
|
||||
/// pop an IO event, returns EV_NONE on failure. data must be IOEVENT_MAX_LEN bytes
|
||||
IOEventFlags jshPopIOEvent(uint8_t *data, int *length);
|
||||
// pop an IO event of type eventType, returns true on success. data must be IOEVENT_MAX_LEN bytes
|
||||
IOEventFlags jshPopIOEventOfType(IOEventFlags eventType, uint8_t *data, int *length);
|
||||
/// Do we have any events pending? Will jshPopIOEvent return true?
|
||||
bool jshHasEvents();
|
||||
/// Check if the top event is for the given device
|
||||
|
||||
@ -171,7 +171,7 @@ void jshKickSoftWatchDog();
|
||||
bool jshGetWatchedPinState(IOEventFlags device);
|
||||
|
||||
/// Given an event, check the EXTI flags and see if it was for the given pin
|
||||
bool jshIsEventForPin(IOEvent *event, Pin pin);
|
||||
bool jshIsEventForPin(IOEventFlags eventFlags, Pin pin);
|
||||
|
||||
/** Is the given device initialised?
|
||||
* eg. has jshUSARTSetup/jshI2CSetup/jshSPISetup been called previously? */
|
||||
|
||||
@ -1777,7 +1777,7 @@ static void jsiPacketProcess() {
|
||||
|
||||
|
||||
|
||||
void jsiHandleChar(char ch) {
|
||||
static void jsiHandleConsoleChar(char ch) {
|
||||
//jsiConsolePrintf("[%d:%d]\n", inputState, ch);
|
||||
//
|
||||
// special stuff
|
||||
@ -1876,11 +1876,11 @@ void jsiHandleChar(char ch) {
|
||||
inputState = IPS_NONE;
|
||||
if (ch == 70) jsiHandleEnd();
|
||||
else if (ch == 72) jsiHandleHome();
|
||||
else if (ch == 111) jsiHandleChar('/');
|
||||
else if (ch == 106) jsiHandleChar('*');
|
||||
else if (ch == 109) jsiHandleChar('-');
|
||||
else if (ch == 107) jsiHandleChar('+');
|
||||
else if (ch == 77) jsiHandleChar('\r');
|
||||
else if (ch == 111) jsiHandleConsoleChar('/');
|
||||
else if (ch == 106) jsiHandleConsoleChar('*');
|
||||
else if (ch == 109) jsiHandleConsoleChar('-');
|
||||
else if (ch == 107) jsiHandleConsoleChar('+');
|
||||
else if (ch == 77) jsiHandleConsoleChar('\r');
|
||||
} else if (inputState==IPS_HAD_27_91) {
|
||||
inputState = IPS_NONE;
|
||||
if (ch>='0' && ch<='9') {
|
||||
@ -2143,54 +2143,29 @@ void jsiCtrlC() {
|
||||
execInfo.execute |= EXEC_CTRL_C;
|
||||
}
|
||||
|
||||
/** Grab as many characters as possible from the event queue for the given event
|
||||
and return a JsVar containing them. 'eventsHandled' is set to the number of
|
||||
extra events (not characters) is returned */
|
||||
static JsVar *jsiExtractIOEventData(IOEvent *event, int *eventsHandled) {
|
||||
assert(eventsHandled);
|
||||
*eventsHandled = 0;
|
||||
|
||||
JsVar *stringData = jsvNewFromEmptyString();
|
||||
if (stringData) {
|
||||
JsvStringIterator it;
|
||||
jsvStringIteratorNew(&it, stringData, 0);
|
||||
|
||||
int i, chars = IOEVENTFLAGS_GETCHARS(event->flags);
|
||||
while (chars) {
|
||||
for (i=0;i<chars;i++) {
|
||||
jsvStringIteratorAppend(&it, event->data.chars[i]);
|
||||
}
|
||||
// look down the stack and see if there is more data
|
||||
if (jshIsTopEvent(IOEVENTFLAGS_GETTYPE(event->flags))) {
|
||||
jshPopIOEvent(event);
|
||||
(*eventsHandled)++;
|
||||
chars = IOEVENTFLAGS_GETCHARS(event->flags);
|
||||
} else
|
||||
chars = 0;
|
||||
}
|
||||
jsvStringIteratorFree(&it);
|
||||
}
|
||||
return stringData;
|
||||
}
|
||||
|
||||
/** Take an event for a UART and handle the characters we're getting, potentially
|
||||
* grabbing more characters as well if it's easy. If more character events are
|
||||
* grabbed, the number of extra events (not characters) is returned */
|
||||
int jsiHandleIOEventForSerial(JsVar *usartClass, IOEvent *event) {
|
||||
int eventsHandled = 0;
|
||||
JsVar *stringData = jsiExtractIOEventData(event, &eventsHandled);
|
||||
int jsiHandleIOEventForSerial(JsVar *usartClass, IOEventFlags eventFlags, uint8_t *data, int length) {
|
||||
int eventsHandled = length+2;
|
||||
JsVar *stringData = length ? jsvNewStringOfLength(length, (char*)data) : NULL;
|
||||
if (stringData) {
|
||||
while (jshIsTopEvent(IOEVENTFLAGS_GETTYPE(eventFlags))) {
|
||||
jshPopIOEvent(data, &length); // we know data/length are big enough
|
||||
eventsHandled += length+2;
|
||||
jsvAppendStringBuf(stringData, (char*)data, length);
|
||||
// don't use an iterator for appending as we just assume we're probably not handling *that* much data this way - normally it'll come in big chunks
|
||||
}
|
||||
// Now run the handler
|
||||
jswrap_stream_pushData(usartClass, stringData, true);
|
||||
jsvUnLock(stringData);
|
||||
}
|
||||
return eventsHandled;
|
||||
return length+2;
|
||||
}
|
||||
|
||||
void jsiHandleIOEventForConsole(IOEvent *event) {
|
||||
int i, c = IOEVENTFLAGS_GETCHARS(event->flags);
|
||||
void jsiHandleIOEventForConsole(uint8_t *eventData, int eventLen) {
|
||||
jsiSetBusy(BUSY_INTERACTIVE, true);
|
||||
for (i=0;i<c;i++) jsiHandleChar(event->data.chars[i]);
|
||||
for (int i=0;i<eventLen;i++) jsiHandleConsoleChar(eventData[i]);
|
||||
jsiSetBusy(BUSY_INTERACTIVE, false);
|
||||
}
|
||||
|
||||
@ -2201,58 +2176,61 @@ void jsiIdle() {
|
||||
|
||||
// Handle hardware-related idle stuff (like checking for pin events)
|
||||
bool wasBusy = false;
|
||||
IOEvent event;
|
||||
IOEventFlags eventFlags;
|
||||
uint8_t eventData[IOEVENT_MAX_LEN];
|
||||
int eventLen;
|
||||
// ensure we can't get totally swamped by having more events than we can process.
|
||||
// Just process what was in the event queue at the start
|
||||
int maxEvents = jshGetEventsUsed();
|
||||
|
||||
while ((maxEvents--)>0 && jshPopIOEvent(&event)) {
|
||||
while ((maxEvents--)>0 && ((eventFlags=jshPopIOEvent(eventData, &eventLen))!=EV_NONE)) {
|
||||
jsiSetBusy(BUSY_INTERACTIVE, true);
|
||||
wasBusy = true;
|
||||
|
||||
IOEventFlags eventType = IOEVENTFLAGS_GETTYPE(event.flags);
|
||||
IOEventFlags eventType = IOEVENTFLAGS_GETTYPE(eventFlags);
|
||||
|
||||
loopsIdling = 0; // because we're not idling
|
||||
if (eventType == consoleDevice) {
|
||||
jsiHandleIOEventForConsole(&event);
|
||||
jsiHandleIOEventForConsole(eventData, eventLen);
|
||||
/** don't allow us to read data when the device is our
|
||||
console device. It slows us down and just causes pain. */
|
||||
} else if (DEVICE_IS_SERIAL(eventType)) {
|
||||
// ------------------------------------------------------------------------ SERIAL CALLBACK
|
||||
JsVar *usartClass = jsvSkipNameAndUnLock(jsiGetClassNameFromDevice(eventType));
|
||||
if (jsvIsObject(usartClass)) {
|
||||
maxEvents -= jsiHandleIOEventForSerial(usartClass, &event);
|
||||
maxEvents -= jsiHandleIOEventForSerial(usartClass, eventFlags, eventData, eventLen);
|
||||
}
|
||||
jsvUnLock(usartClass);
|
||||
#if ESPR_USART_COUNT>0
|
||||
} else if (DEVICE_IS_USART_STATUS(eventType)) {
|
||||
// ------------------------------------------------------------------------ SERIAL STATUS CALLBACK
|
||||
JsVar *usartClass = jsvSkipNameAndUnLock(jsiGetClassNameFromDevice(IOEVENTFLAGS_GETTYPE(IOEVENTFLAGS_SERIAL_STATUS_TO_SERIAL(event.flags))));
|
||||
JsVar *usartClass = jsvSkipNameAndUnLock(jsiGetClassNameFromDevice(IOEVENTFLAGS_GETTYPE(IOEVENTFLAGS_SERIAL_STATUS_TO_SERIAL(eventFlags))));
|
||||
if (jsvIsObject(usartClass)) {
|
||||
if (event.flags & EV_SERIAL_STATUS_FRAMING_ERR)
|
||||
if (eventFlags & EV_SERIAL_STATUS_FRAMING_ERR)
|
||||
jsiExecuteEventCallbackName(usartClass, JS_EVENT_PREFIX"framing", 0, 0);
|
||||
if (event.flags & EV_SERIAL_STATUS_PARITY_ERR)
|
||||
if (eventFlags & EV_SERIAL_STATUS_PARITY_ERR)
|
||||
jsiExecuteEventCallbackName(usartClass, JS_EVENT_PREFIX"parity", 0, 0);
|
||||
}
|
||||
jsvUnLock(usartClass);
|
||||
#endif
|
||||
} else if (eventType == EV_CUSTOM) {
|
||||
jswOnCustomEvent(&event);
|
||||
jswOnCustomEvent(eventFlags, eventData, eventLen);
|
||||
#ifdef BLUETOOTH
|
||||
} else if ((eventType == EV_BLUETOOTH_PENDING) || (eventType == EV_BLUETOOTH_PENDING_DATA)) {
|
||||
maxEvents -= jsble_exec_pending(&event);
|
||||
} else if (eventType == EV_BLUETOOTH_PENDING) {
|
||||
maxEvents -= jsble_exec_pending(eventData, eventLen);
|
||||
#endif
|
||||
#ifdef BANGLEJS
|
||||
} else if (eventType == EV_BANGLEJS) {
|
||||
jsbangle_exec_pending(&event);
|
||||
jsbangle_exec_pending(eventData, eventLen);
|
||||
#endif
|
||||
#ifdef I2C_SLAVE
|
||||
} else if (DEVICE_IS_I2C(eventType)) {
|
||||
// ------------------------------------------------------------------------ I2C CALLBACK
|
||||
JsVar *i2cClass = jsvSkipNameAndUnLock(jsiGetClassNameFromDevice(eventType));
|
||||
if (jsvIsObject(i2cClass)) {
|
||||
uint8_t addr = event.data.time&0xff;
|
||||
int len = event.data.time>>8;
|
||||
uint32_t eventU32 = *(uint32_t*)eventData;
|
||||
uint8_t addr = eventU32&0xff;
|
||||
int len = eventU32>>8;
|
||||
JsVar *obj = jsvNewObject();
|
||||
if (obj) {
|
||||
jsvObjectSetChildAndUnLock(obj, "addr", jsvNewFromInteger(addr&0x7F));
|
||||
@ -2274,7 +2252,7 @@ void jsiIdle() {
|
||||
JsVar *watchPtr = jsvObjectIteratorGetValue(&it);
|
||||
Pin pin = jshGetPinFromVarAndUnLock(jsvObjectGetChildIfExists(watchPtr, "pin"));
|
||||
|
||||
if (jshIsEventForPin(&event, pin)) {
|
||||
if (jshIsEventForPin(eventFlags, pin)) {
|
||||
/** Work out event time. Events time is only stored in 32 bits, so we need to
|
||||
* use the correct 'high' 32 bits from the current time.
|
||||
*
|
||||
@ -2284,19 +2262,20 @@ void jsiIdle() {
|
||||
* from the current time.
|
||||
*/
|
||||
JsSysTime time = jshGetSystemTime();
|
||||
if (((unsigned int)time) < (unsigned int)event.data.time)
|
||||
uint32_t eventTime32 = *(uint32_t*)eventData;
|
||||
if (((uint32_t)time) < eventTime32)
|
||||
time = time - 0x100000000LL;
|
||||
// finally, mask in the event's time
|
||||
JsSysTime eventTime = (time & ~0xFFFFFFFFLL) | (JsSysTime)event.data.time;
|
||||
JsSysTime eventTime = (time & ~0xFFFFFFFFLL) | (JsSysTime)eventTime32;
|
||||
|
||||
// Now actually process the event
|
||||
bool pinIsHigh = (event.flags&EV_EXTI_IS_HIGH)!=0;
|
||||
bool pinIsHigh = (eventFlags&EV_EXTI_IS_HIGH)!=0;
|
||||
bool ignoreEvent = false;
|
||||
#ifdef BANGLEJS
|
||||
/* This is a bodge for Bangle.js. We want to get events for any button press here so
|
||||
we can keep our debounce state machine up to date, but for some button presses we
|
||||
may not want to actually forward them to user-facing code. */
|
||||
ignoreEvent = (event.flags&EV_EXTI_DATA_PIN_HIGH)!=0;
|
||||
ignoreEvent = (eventFlags&EV_EXTI_DATA_PIN_HIGH)!=0;
|
||||
#endif
|
||||
|
||||
bool executeNow = false;
|
||||
@ -2357,7 +2336,7 @@ void jsiIdle() {
|
||||
jsvObjectSetChildAndUnLock(data, "pin", jsvNewFromPin(pin));
|
||||
Pin dataPin = jshGetEventDataPin(eventType);
|
||||
if (jshIsPinValid(dataPin))
|
||||
jsvObjectSetChildAndUnLock(data, "data", jsvNewFromBool((event.flags&EV_EXTI_DATA_PIN_HIGH)!=0));
|
||||
jsvObjectSetChildAndUnLock(data, "data", jsvNewFromBool((eventFlags&EV_EXTI_DATA_PIN_HIGH)!=0));
|
||||
}
|
||||
if (!jsiExecuteEventCallback(0, watchCallback, 1, &data) && watchRecurring) {
|
||||
jsError("Ctrl-C while processing watch - removing it.");
|
||||
@ -2841,20 +2820,22 @@ void jsiDebuggerLoop() {
|
||||
jsiConsoleReturnInputLine();
|
||||
// idle stuff for hardware
|
||||
jshIdle();
|
||||
// Idle just for debug (much stuff removed) -------------------------------
|
||||
IOEvent event;
|
||||
// If we have too many events (> half full) drain the queue
|
||||
uint8_t eventData[IOEVENT_MAX_LEN];
|
||||
int eventLen;
|
||||
while (jshGetEventsUsed()>IOBUFFERMASK*1/2 &&
|
||||
!(jsiStatus & JSIS_EXIT_DEBUGGER) &&
|
||||
!(execInfo.execute & EXEC_CTRL_C_MASK)) {
|
||||
if (jshPopIOEvent(&event) && IOEVENTFLAGS_GETTYPE(event.flags)==consoleDevice)
|
||||
jsiHandleIOEventForConsole(&event);
|
||||
if (IOEVENTFLAGS_GETTYPE(jshPopIOEvent(eventData, &eventLen)) == consoleDevice)
|
||||
jsiHandleIOEventForConsole(eventData, eventLen);
|
||||
else
|
||||
jsErrorFlags |= JSERR_RX_FIFO_FULL;
|
||||
}
|
||||
// otherwise grab the remaining console events
|
||||
while (jshPopIOEventOfType(consoleDevice, &event) &&
|
||||
while (jshPopIOEventOfType(consoleDevice, eventData, &eventLen)!=EV_NONE &&
|
||||
!(jsiStatus & JSIS_EXIT_DEBUGGER) &&
|
||||
!(execInfo.execute & EXEC_CTRL_C_MASK)) {
|
||||
jsiHandleIOEventForConsole(&event);
|
||||
jsiHandleIOEventForConsole(eventData, eventLen);
|
||||
}
|
||||
// -----------------------------------------------------------------------
|
||||
}
|
||||
|
||||
@ -704,11 +704,12 @@ Called when a bit rises or falls above a set level. See `E.setComparator` for se
|
||||
"generate" : "jswrap_espruino_setComparator_eventHandler"
|
||||
}
|
||||
*/
|
||||
void jswrap_espruino_setComparator_eventHandler(IOEvent *event) {
|
||||
void jswrap_espruino_setComparator_eventHandler(IOEventFlags eventFlags, uint8_t *data, int *length) {
|
||||
#if defined(NRF52_SERIES) && !defined(SAVE_ON_FLASH)
|
||||
// see jshSetComparator / E.setComparator
|
||||
if ((event->data.time & EVC_TYPE_MASK) == EVC_LPCOMP) {
|
||||
JsVar *arg = jsvNewFromInteger((event->data.time & EVC_DATA_LPCOMP_UP) ? 1 : -1);
|
||||
IOCustomEventFlags customFlags = *(IOCustomEventFlags*)data;
|
||||
if ((customFlags & EVC_TYPE_MASK) == EVC_LPCOMP) {
|
||||
JsVar *arg = jsvNewFromInteger((customFlags & EVC_DATA_LPCOMP_UP) ? 1 : -1);
|
||||
jsiExecuteEventCallbackOn("E",JS_EVENT_PREFIX"comparator",1,&arg);
|
||||
jsvUnLock(arg);
|
||||
}
|
||||
@ -728,7 +729,7 @@ void jswrap_espruino_setComparator_eventHandler(IOEvent *event) {
|
||||
(Added 2v25) Enable the nRF52 chip's `LPCOMP` hardware. When enabled, it creates an `E.on("comparator", ...)`
|
||||
event whenever the pin supplied rises or falls past the setpoint given (with 50mv hysteresis).
|
||||
|
||||
```JS
|
||||
```
|
||||
E.setComparator(D28, 8/16); // compare with VDD/2
|
||||
E.on("comparator", e => {
|
||||
print(e); // 1 for up, or -1 for down
|
||||
|
||||
@ -30,7 +30,7 @@ void jswrap_espruino_FFT(JsVar *arrReal, JsVar *arrImag, bool inverse);
|
||||
|
||||
void jswrap_espruino_enableWatchdog(JsVarFloat time, JsVar *isAuto);
|
||||
void jswrap_espruino_kickWatchdog();
|
||||
void jswrap_espruino_setComparator_eventHandler(IOEvent *event);
|
||||
void jswrap_espruino_setComparator_eventHandler(IOEventFlags eventFlags, uint8_t *data, int *length);
|
||||
void jswrap_espruino_setComparator(Pin pin, JsVarFloat level);
|
||||
/// Return an array of errors based on the current flags
|
||||
JsVar *jswrap_espruino_getErrorFlagArray(JsErrorFlags flags);
|
||||
|
||||
@ -501,14 +501,14 @@ Serial1.inject('Hello World');
|
||||
This is most useful if you wish to send characters to Espruino's REPL (console)
|
||||
while it is on another device.
|
||||
*/
|
||||
static void _jswrap_serial_inject_cb(int data, void *userData) {
|
||||
IOEventFlags device = *(IOEventFlags*)userData;
|
||||
jshPushIOCharEvent(device, (char)data);
|
||||
static void _jswrap_serial_inject_cb(unsigned char *data, unsigned int len, void *callbackData) {
|
||||
IOEventFlags device = *(IOEventFlags*)callbackData;
|
||||
jshPushIOCharEvents(device, (char*)data, len);
|
||||
}
|
||||
void jswrap_serial_inject(JsVar *parent, JsVar *args) {
|
||||
IOEventFlags device = jsiGetDeviceFromClass(parent);
|
||||
if (!DEVICE_IS_SERIAL(device)) return;
|
||||
jsvIterateCallback(args, _jswrap_serial_inject_cb, (void*)&device);
|
||||
jsvIterateBufferCallback(args, _jswrap_serial_inject_cb, (void*)&device);
|
||||
}
|
||||
|
||||
/*JSON{
|
||||
|
||||
@ -156,7 +156,7 @@ void jswGetPowerUsage(JsVar *devices);
|
||||
bool jswOnCharEvent(IOEventFlags channel, char charData);
|
||||
|
||||
/** When we receive EV_CUSTOM, this is called so any library (eg Waveform) can hook onto it (type:'EV_CUSTOM' in JSON) */
|
||||
void jswOnCustomEvent(IOEvent *event);
|
||||
void jswOnCustomEvent(IOEventFlags eventFlags, uint8_t *data, int dataLen);
|
||||
|
||||
/** If we get this in 'require', do we have the object for this
|
||||
inside the interpreter already? If so, return the native function
|
||||
|
||||
@ -77,7 +77,7 @@ void jshBusyIdle() {
|
||||
|
||||
int jshGetSerialNumber(unsigned char *data, int maxChars) {
|
||||
long initialSerial = 0;
|
||||
long long serial = 0xDEADDEADDEADDEADL;
|
||||
long long serial = 0xDEADDEADDEADDEADL;
|
||||
memcpy(&data[0], &initialSerial, 4);
|
||||
memcpy(&data[4], &serial, 8);
|
||||
return 12;
|
||||
@ -151,7 +151,7 @@ int jshPinAnalogFast(Pin pin) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
JshPinFunction jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq, JshAnalogOutputFlags flags) { // if freq<=0,
|
||||
JshPinFunction jshPinAnalogOutput(Pin pin, JsVarFloat value, JsVarFloat freq, JshAnalogOutputFlags flags) { // if freq<=0,
|
||||
return JSH_NOTHING;
|
||||
}
|
||||
|
||||
@ -185,8 +185,8 @@ bool jshGetWatchedPinState(IOEventFlags device) {
|
||||
return jshPinGetValue(eventFlagsToPin[device-EV_EXTI0]);
|
||||
}
|
||||
|
||||
bool jshIsEventForPin(IOEvent *event, Pin pin) {
|
||||
return IOEVENTFLAGS_GETTYPE(event->flags) == jshGetEventFlagsForPin(pin);
|
||||
bool jshIsEventForPin(IOEventFlags eventFlags, Pin pin) {
|
||||
return IOEVENTFLAGS_GETTYPE(eventFlags) == jshGetEventFlagsForPin(pin);
|
||||
}
|
||||
|
||||
void jshUSARTSetup(IOEventFlags device, JshUSARTInfo *inf) {
|
||||
|
||||
@ -73,33 +73,17 @@ JsVar *jsble_get_error_string(uint32_t err_code) {
|
||||
return jsvVarPrintf("ERR 0x%x", err_code);
|
||||
}
|
||||
|
||||
/// Executes a pending BLE event - returns the number of events Handled
|
||||
int jsble_exec_pending(IOEvent *event) {
|
||||
int eventsHandled = 1;
|
||||
// if we got event data, unpack it first into a buffer
|
||||
#if NRF_BLE_MAX_MTU_SIZE>64
|
||||
unsigned char buffer[NRF_BLE_MAX_MTU_SIZE];
|
||||
#else
|
||||
unsigned char buffer[64];
|
||||
#endif
|
||||
assert(sizeof(buffer) >= sizeof(BLEAdvReportData));
|
||||
size_t bufferLen = 0;
|
||||
while (IOEVENTFLAGS_GETTYPE(event->flags) == EV_BLUETOOTH_PENDING_DATA) {
|
||||
int i, chars = IOEVENTFLAGS_GETCHARS(event->flags);
|
||||
for (i=0;i<chars;i++) {
|
||||
assert(bufferLen < sizeof(buffer));
|
||||
if (bufferLen < sizeof(buffer))
|
||||
buffer[bufferLen++] = event->data.chars[i];
|
||||
}
|
||||
|
||||
jshPopIOEvent(event);
|
||||
eventsHandled++;
|
||||
}
|
||||
assert(IOEVENTFLAGS_GETTYPE(event->flags) == EV_BLUETOOTH_PENDING);
|
||||
|
||||
/// Executes a pending BLE event - returns the number of event bytes handled. sizeof(buffer)==IOEVENT_MAX_LEN
|
||||
int jsble_exec_pending(uint8_t *buffer, int bufferLen) {
|
||||
assert(IOEVENT_MAX_LEN >= sizeof(BLEAdvReportData));
|
||||
int eventBytesHandled = 2+bufferLen;
|
||||
// Now handle the actual event
|
||||
BLEPending blep = (BLEPending)(event->data.time&255);
|
||||
uint16_t data = (uint16_t)(event->data.time>>8);
|
||||
if (bufferLen<3) return;
|
||||
BLEPending blep = (BLEPending)buffer[0];
|
||||
uint16_t data = (uint16_t)(buffer[1] | (buffer[2]<<8));
|
||||
// skip first 3 bytes
|
||||
buffer += 3;
|
||||
bufferLen -= 3;
|
||||
/* jsble_exec_pending_common handles 'common' events between nRF52/ESP32, then
|
||||
* we handle nRF52-specific events below */
|
||||
if (!jsble_exec_pending_common(blep, data, buffer, bufferLen)) switch (blep) {
|
||||
@ -107,7 +91,7 @@ int jsble_exec_pending(IOEvent *event) {
|
||||
default:
|
||||
jsWarn("jsble_exec_pending: Unknown enum type %d",(int)blep);
|
||||
}
|
||||
return eventsHandled;
|
||||
return eventBytesHandled;
|
||||
}
|
||||
|
||||
void jsble_restart_softdevice(JsVar *jsFunction){
|
||||
|
||||
@ -553,10 +553,10 @@ JshPinFunction jshGetCurrentPinFunction(Pin pin) {
|
||||
* \return True if the event is associated with the pin and false otherwise.
|
||||
*/
|
||||
bool jshIsEventForPin(
|
||||
IOEvent *event, //!< The event that has been detected.
|
||||
IOEventFlags eventFlags, //!< The event type that has been detected.
|
||||
Pin pin //!< The identity of a pin.
|
||||
) {
|
||||
return IOEVENTFLAGS_GETTYPE(event->flags) == pinToEV_EXTI(pin);
|
||||
return IOEVENTFLAGS_GETTYPE(eventFlags) == pinToEV_EXTI(pin);
|
||||
}
|
||||
|
||||
//===== USART and Serial =====
|
||||
|
||||
@ -741,10 +741,10 @@ JshPinFunction jshGetCurrentPinFunction(Pin pin) {
|
||||
* \return True if the event is associated with the pin and false otherwise.
|
||||
*/
|
||||
bool jshIsEventForPin(
|
||||
IOEvent *event, //!< The event that has been detected.
|
||||
IOEventFlags eventFlags, //!< The event that has been detected.
|
||||
Pin pin //!< The identity of a pin.
|
||||
) {
|
||||
return IOEVENTFLAGS_GETTYPE(event->flags) == pinToEV_EXTI(pin);
|
||||
return IOEVENTFLAGS_GETTYPE(eventFlags) == pinToEV_EXTI(pin);
|
||||
}
|
||||
|
||||
//===== USART and Serial =====
|
||||
|
||||
@ -628,8 +628,8 @@ bool jshGetWatchedPinState(IOEventFlags device) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool jshIsEventForPin(IOEvent *event, Pin pin) {
|
||||
return IOEVENTFLAGS_GETTYPE(event->flags) == pinToEVEXTI(pin);
|
||||
bool jshIsEventForPin(IOEventFlags eventFlags, Pin pin) {
|
||||
return IOEVENTFLAGS_GETTYPE(eventFlags) == pinToEVEXTI(pin);
|
||||
}
|
||||
|
||||
void jshUSARTSetup(IOEventFlags device, JshUSARTInfo *inf) {
|
||||
|
||||
@ -300,34 +300,18 @@ JsVar *jsble_get_error_string(uint32_t err_code) {
|
||||
// -----------------------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------------------
|
||||
|
||||
/// Executes a pending BLE event - returns the number of events Handled
|
||||
int jsble_exec_pending(IOEvent *event) {
|
||||
int eventsHandled = 1;
|
||||
// if we got event data, unpack it first into a buffer
|
||||
#if NRF_BLE_MAX_MTU_SIZE>64
|
||||
unsigned char buffer[NRF_BLE_MAX_MTU_SIZE];
|
||||
#else
|
||||
unsigned char buffer[64];
|
||||
#endif
|
||||
assert(sizeof(buffer) >= sizeof(BLEAdvReportData));
|
||||
assert(sizeof(buffer) >= NRF_BLE_MAX_MTU_SIZE);
|
||||
size_t bufferLen = 0;
|
||||
while (IOEVENTFLAGS_GETTYPE(event->flags) == EV_BLUETOOTH_PENDING_DATA) {
|
||||
int i, chars = IOEVENTFLAGS_GETCHARS(event->flags);
|
||||
for (i=0;i<chars;i++) {
|
||||
assert(bufferLen < sizeof(buffer));
|
||||
if (bufferLen < sizeof(buffer))
|
||||
buffer[bufferLen++] = event->data.chars[i];
|
||||
}
|
||||
|
||||
jshPopIOEvent(event);
|
||||
eventsHandled++;
|
||||
}
|
||||
assert(IOEVENTFLAGS_GETTYPE(event->flags) == EV_BLUETOOTH_PENDING);
|
||||
|
||||
/// Executes a pending BLE event - returns the number of event bytes handled. sizeof(buffer)==IOEVENT_MAX_LEN
|
||||
int jsble_exec_pending(uint8_t *buffer, int bufferLen) {
|
||||
assert(IOEVENT_MAX_LEN >= sizeof(BLEAdvReportData));
|
||||
assert(IOEVENT_MAX_LEN >= NRF_BLE_MAX_MTU_SIZE);
|
||||
int eventBytesHandled = 2+bufferLen;
|
||||
// Now handle the actual event
|
||||
BLEPending blep = (BLEPending)(event->data.time&255);
|
||||
uint16_t data = (uint16_t)(event->data.time>>8);
|
||||
if (bufferLen<3) return;
|
||||
BLEPending blep = (BLEPending)buffer[0];
|
||||
uint16_t data = (uint16_t)(buffer[1] | (buffer[2]<<8));
|
||||
// skip first 3 bytes
|
||||
buffer += 3;
|
||||
bufferLen -= 3;
|
||||
/* jsble_exec_pending_common handles 'common' events between nRF52/ESP32, then
|
||||
* we handle nRF52-specific events below */
|
||||
if (!jsble_exec_pending_common(blep, data, buffer, bufferLen)) switch (blep) {
|
||||
@ -673,7 +657,7 @@ uint8_t match_request : 1; If 1 requires the application to report
|
||||
}
|
||||
if (jspIsInterrupted())
|
||||
jsWarn("Interrupted processing event %d",(int)blep);
|
||||
return eventsHandled;
|
||||
return eventBytesHandled;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1751,8 +1751,8 @@ bool jshGetWatchedPinState(IOEventFlags device) {
|
||||
return lastHandledPinState;
|
||||
}
|
||||
|
||||
bool jshIsEventForPin(IOEvent *event, Pin pin) {
|
||||
return IOEVENTFLAGS_GETTYPE(event->flags) == jshGetEventFlagsForWatchedPin((uint32_t)pinInfo[pin].pin);
|
||||
bool jshIsEventForPin(IOEventFlags eventFlags, Pin pin) {
|
||||
return IOEVENTFLAGS_GETTYPE(eventFlags) == jshGetEventFlagsForWatchedPin((uint32_t)pinInfo[pin].pin);
|
||||
}
|
||||
|
||||
/** Is the given device initialised? */
|
||||
@ -2924,11 +2924,13 @@ void jsvGetProcessorPowerUsage(JsVar *devices) {
|
||||
void COMP_LPCOMP_IRQHandler() {
|
||||
if (nrf_lpcomp_event_check(NRF_LPCOMP_EVENT_UP) && nrf_lpcomp_int_enable_check(LPCOMP_INTENSET_UP_Msk)) {
|
||||
nrf_lpcomp_event_clear(NRF_LPCOMP_EVENT_UP);
|
||||
jshPushIOEvent(EV_CUSTOM, EVC_LPCOMP | EVC_DATA_LPCOMP_UP);
|
||||
IOCustomEventFlags customFlags = EVC_LPCOMP | EVC_DATA_LPCOMP_UP;
|
||||
jshPushEvent(EV_CUSTOM, &customFlags, sizeof(customFlags));
|
||||
}
|
||||
if (nrf_lpcomp_event_check(NRF_LPCOMP_EVENT_DOWN) && nrf_lpcomp_int_enable_check(LPCOMP_INTENSET_DOWN_Msk)) {
|
||||
nrf_lpcomp_event_clear(NRF_LPCOMP_EVENT_DOWN);
|
||||
jshPushIOEvent(EV_CUSTOM, EVC_LPCOMP);
|
||||
IOCustomEventFlags customFlags = EVC_LPCOMP;
|
||||
jshPushEvent(EV_CUSTOM, &customFlags, sizeof(customFlags));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2159,8 +2159,8 @@ bool jshGetWatchedPinState(IOEventFlags device) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool jshIsEventForPin(IOEvent *event, Pin pin) {
|
||||
return IOEVENTFLAGS_GETTYPE(event->flags) == pinToEVEXTI(pin);
|
||||
bool jshIsEventForPin(IOEventFlags eventFlags, Pin pin) {
|
||||
return IOEVENTFLAGS_GETTYPE(eventFlags) == pinToEVEXTI(pin);
|
||||
}
|
||||
|
||||
/** Usage:
|
||||
|
||||
@ -1568,8 +1568,8 @@ void jshKickWatchDog(void){
|
||||
|
||||
|
||||
/// Given an event, check the EXTI flags and see if it was for the given pin
|
||||
bool jshIsEventForPin(IOEvent *event, Pin pin){
|
||||
return IOEVENTFLAGS_GETTYPE(event->flags) == pinToEVEXTI(pin);
|
||||
bool jshIsEventForPin(IOEventFlags eventFlags, Pin pin){
|
||||
return IOEVENTFLAGS_GETTYPE(eventFlags) == pinToEVEXTI(pin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user