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:
Gordon Williams 2025-02-26 16:22:58 +00:00
parent aa3ce23467
commit b84efeca3e
38 changed files with 384 additions and 404 deletions

View File

@ -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)

View File

@ -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' : {

View File

@ -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' : {

View File

@ -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',

View File

@ -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:

View File

@ -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:

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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"]
}
};

View File

@ -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)

View File

@ -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{

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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
}

View File

@ -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('}')

View File

@ -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("");

View File

@ -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",

View File

@ -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) {

View File

@ -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

View File

@ -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? */

View File

@ -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);
}
// -----------------------------------------------------------------------
}

View File

@ -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

View File

@ -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);

View File

@ -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{

View File

@ -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

View File

@ -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) {

View File

@ -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){

View File

@ -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 =====

View File

@ -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 =====

View File

@ -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) {

View File

@ -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;
}

View File

@ -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));
}
}

View File

@ -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:

View File

@ -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);
}