Merge branch 'arendst:development' into development

This commit is contained in:
barkow 2022-10-27 21:28:52 +02:00 committed by GitHub
commit 32fbb03471
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 7156 additions and 903 deletions

View File

@ -1,3 +1,4 @@
name: Build_development
on:
@ -14,6 +15,41 @@ concurrency:
cancel-in-progress: true
jobs:
safeboot-images:
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
continue-on-error: true
strategy:
matrix:
variant:
- tasmota32solo1-safeboot
- tasmota32-safeboot
- tasmota32c3-safeboot
- tasmota32c3cdc-safeboot
- tasmota32s2-safeboot
- tasmota32s2cdc-safeboot
- tasmota32s3-safeboot
- tasmota32s3cdc-safeboot
steps:
- uses: actions/checkout@v3
with:
ref: development
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
pip install -U platformio
- name: Run PlatformIO
run: platformio run -e ${{ matrix.variant }}
- name: Upload safeboot firmware artifacts
uses: actions/upload-artifact@v3
with:
name: firmware_safeboot
path: ./build_output
base-images:
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
@ -31,6 +67,34 @@ jobs:
- tasmota-sensors
- tasmota-zbbridge
- tasmota-zigbee
steps:
- uses: actions/checkout@v3
with:
ref: development
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
pip install -U platformio
- name: Run PlatformIO
run: platformio run -e ${{ matrix.variant }}
- name: Upload firmware artifacts
uses: actions/upload-artifact@v3
with:
name: firmware
path: ./build_output
base32-images:
needs: safeboot-images
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
continue-on-error: true
strategy:
matrix:
variant:
- tasmota32
- tasmota32-zbbrdgpro
- tasmota32-webcam
@ -46,32 +110,36 @@ jobs:
- tasmota32s3
- tasmota32s3cdc
- tasmota32solo1
- tasmota32solo1-safeboot
- tasmota32-safeboot
- tasmota32c3-safeboot
- tasmota32c3cdc-safeboot
- tasmota32s2-safeboot
- tasmota32s2cdc-safeboot
- tasmota32s3-safeboot
- tasmota32s3cdc-safeboot
steps:
- uses: actions/checkout@v3
with:
ref: development
- name: Set up Python
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
pip install -U platformio
- name: Download safeboot firmwares
uses: actions/download-artifact@v3
with:
name: firmware_safeboot
path: ./firmware
- name: Display downloaded files
run: |
ls -R ./firmware/
- name: Run PlatformIO
run: platformio run -e ${{ matrix.variant }}
- uses: actions/upload-artifact@v3
- name: Upload firmware artifacts
uses: actions/upload-artifact@v3
with:
name: firmware
path: ./build_output
language-images:
needs: safeboot-images
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
continue-on-error: true
@ -84,27 +152,44 @@ jobs:
with:
ref: development
- name: Set up Python
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
pip install -U platformio
- name: Download safeboot firmwares
uses: actions/download-artifact@v3
with:
name: firmware_safeboot
path: ./firmware
- name: Display downloaded files
run: |
ls -R ./firmware/
- name: Run PlatformIO
run: platformio run -e ${{ matrix.variant }}-${{ matrix.language }}
- uses: actions/upload-artifact@v3
- name: Upload language firmware artifacts
uses: actions/upload-artifact@v3
with:
name: firmware
path: ./build_output
Upload:
needs: [base-images, language-images]
needs: [base-images, base32-images, language-images]
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/download-artifact@v3
- name: Download firmware
uses: actions/download-artifact@v3
with:
name: firmware
path: ./mv_firmware
- name: Downlaod safeboot firmware
uses: actions/download-artifact@v3
with:
name: firmware_safeboot
path: ./mv_firmware
- name: Display structure of downloaded files
run: ls -R
working-directory: ./mv_firmware
@ -155,7 +240,6 @@ jobs:
destination_branch: 'firmware'
user_email: 'github-actions@github.com'
user_name: 'github-actions'
Start_final_copy:
needs: Upload
runs-on: ubuntu-latest

View File

@ -1,6 +1,7 @@
name: Build_firmware_master
on:
workflow_dispatch: # Manually start a workflow
push:
branches: master
paths-ignore:
@ -13,6 +14,41 @@ concurrency:
cancel-in-progress: true
jobs:
safeboot-images:
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
continue-on-error: true
strategy:
matrix:
variant:
- tasmota32solo1-safeboot
- tasmota32-safeboot
- tasmota32c3-safeboot
- tasmota32c3cdc-safeboot
- tasmota32s2-safeboot
- tasmota32s2cdc-safeboot
- tasmota32s3-safeboot
- tasmota32s3cdc-safeboot
steps:
- uses: actions/checkout@v3
with:
ref: master
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
pip install -U platformio
- name: Run PlatformIO
run: platformio run -e ${{ matrix.variant }}
- name: Upload safeboot firmware artifacts
uses: actions/upload-artifact@v3
with:
name: firmware_safeboot
path: ./build_output
base-images:
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
@ -30,6 +66,34 @@ jobs:
- tasmota-sensors
- tasmota-zbbridge
- tasmota-zigbee
steps:
- uses: actions/checkout@v3
with:
ref: master
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
pip install -U platformio
- name: Run PlatformIO
run: platformio run -e ${{ matrix.variant }}
- name: Upload firmware artifacts
uses: actions/upload-artifact@v3
with:
name: firmware
path: ./build_output
base32-images:
needs: safeboot-images
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
continue-on-error: true
strategy:
matrix:
variant:
- tasmota32
- tasmota32-zbbrdgpro
- tasmota32-webcam
@ -45,32 +109,36 @@ jobs:
- tasmota32s3
- tasmota32s3cdc
- tasmota32solo1
- tasmota32solo1-safeboot
- tasmota32-safeboot
- tasmota32c3-safeboot
- tasmota32c3cdc-safeboot
- tasmota32s2-safeboot
- tasmota32s2cdc-safeboot
- tasmota32s3-safeboot
- tasmota32s3cdc-safeboot
steps:
- uses: actions/checkout@v3
with:
ref: master
- name: Set up Python
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
pip install -U platformio
- name: Download safeboot firmwares
uses: actions/download-artifact@v3
with:
name: firmware_safeboot
path: ./firmware
- name: Display downloaded files
run: |
ls -R ./firmware/
- name: Run PlatformIO
run: platformio run -e ${{ matrix.variant }}
- uses: actions/upload-artifact@v3
- name: Upload firmware artifacts
uses: actions/upload-artifact@v3
with:
name: firmware
path: ./build_output
language-images:
needs: safeboot-images
runs-on: ubuntu-latest
if: github.repository == 'arendst/Tasmota'
continue-on-error: true
@ -83,14 +151,25 @@ jobs:
with:
ref: master
- name: Set up Python
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
pip install -U platformio
- name: Download safeboot firmwares
uses: actions/download-artifact@v3
with:
name: firmware_safeboot
path: ./firmware
- name: Display downloaded files
run: |
ls -R ./firmware/
- name: Run PlatformIO
run: platformio run -e ${{ matrix.variant }}-${{ matrix.language }}
- uses: actions/upload-artifact@v3
- name: Upload language firmware artifacts
uses: actions/upload-artifact@v3
with:
name: firmware
path: ./build_output
@ -108,7 +187,7 @@ jobs:
- name: Display structure of downloaded files
run: ls -R ./mv_firmware/
- name: Release
uses: softprops/action-gh-release@v1
uses: jason2866/action-gh-release@v1.1
#if: startsWith(github.ref, 'refs/tags/')
with:
tag_name: ${{ github.run_number }}

View File

@ -28,7 +28,9 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
@ -44,7 +46,7 @@ jobs:
path: ./build_output
os-check-mac:
runs-on: macos-latest
runs-on: macOS-12
if: github.repository == 'arendst/Tasmota'
strategy:
fail-fast: true
@ -54,7 +56,9 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
@ -111,7 +115,9 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel
@ -137,7 +143,9 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v3
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install wheel

View File

@ -8,7 +8,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3.0.15
- uses: actions/stale@v6.0.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 25

View File

@ -3,22 +3,35 @@ All notable changes to this project will be documented in this file.
## [Unreleased] - Development
## [12.2.0.1]
## [12.2.0.2]
### Added
- DS18x20 support on up to four GPIOs by md5sum-as (#16833)
### Breaking Changed
### Changed
- Prepare for extended calibration and move some persistent data (PowerLow)
### Fixed
### Removed
## [12.2.0.1] 20221026
### Added
- DS18x20 support on up to four GPIOs by md5sum-as (#16833)
- Berry add `bytes().setbytes()` (#16892)
- Support for Shelly Pro 1/1PM and 2/2PM (#16773)
- Add Zigbee router firmware for Sonoff ZBBridgePro (#16900)
- Prepare for DMX Artnet support on ESP32
### Changed
- DS18x20 ``DS18Alias`` to ``DS18Sens`` (#16833)
- Compiling with reduced boards manifests in favour of Autoconfig (#16848)
- Add NeoPool ``NPFiltration 2`` toggle cmnd (#16859)
- ESP32 NimBLE library from v1.4.0 to v1.4.1 (#16775)
### Fixed
- BP5758D red channel corruption regression from v12.1.1.6 (#16850)
### Removed
## [Released]
## [12.2.0] 20221017

View File

@ -107,13 +107,18 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
[Complete list](BUILDS.md) of available feature and sensors.
## Changelog v12.2.0.1
## Changelog v12.2.0.2
### Added
- DS18x20 support on up to four GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Command NeoPool ``NPFiltration 2`` toggle [#16859](https://github.com/arendst/Tasmota/issues/16859)
- Support for Shelly Pro 1/1PM and 2/2PM [#16773](https://github.com/arendst/Tasmota/issues/16773)
- Support for up to four DS18x20 GPIOs by md5sum-as [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Berry add `bytes().setbytes()` [#16892](https://github.com/arendst/Tasmota/issues/16892)
- Zigbee router firmware for Sonoff ZBBridgePro [#16900](https://github.com/arendst/Tasmota/issues/16900)
### Breaking Changed
### Changed
- ESP32 NimBLE library from v1.4.0 to v1.4.1 [#16775](https://github.com/arendst/Tasmota/issues/16775)
- DS18x20 ``DS18Alias`` to ``DS18Sens`` [#16833](https://github.com/arendst/Tasmota/issues/16833)
- Compiling with reduced boards manifests in favour of Autoconfig [#16848](https://github.com/arendst/Tasmota/issues/16848)

View File

@ -949,6 +949,50 @@ static int m_setfloat(bvm *vm)
be_return_nil(vm);
}
/*
* Fills a buffer with another buffer.
*
* This is meant to be very flexible and avoid loops
*
* `setbytes(index:int, fill:bytes [, from:int, len:int]) -> nil`
*
*/
#include <stdio.h>
static int m_setbytes(bvm *vm)
{
int argc = be_top(vm);
buf_impl attr = bytes_check_data(vm, 0); /* we reserve 4 bytes anyways */
check_ptr(vm, &attr);
if (argc >=3 && be_isint(vm, 2) && (be_isbytes(vm, 3))) {
int32_t idx = be_toint(vm, 2);
size_t from_len_total;
const uint8_t* buf_ptr = (const uint8_t*) be_tobytes(vm, 3, &from_len_total);
if (idx < 0) { idx = 0; }
if ((size_t)idx >= attr.len) { idx = attr.len; }
int32_t from_byte = 0;
if (argc >= 4 && be_isint(vm, 4)) {
from_byte = be_toint(vm, 4);
if (from_byte < 0) { from_byte = 0; }
if ((size_t)from_byte >= from_len_total) { from_byte = from_len_total; }
}
int32_t from_len = from_len_total - from_byte;
if (argc >= 5 && be_isint(vm, 5)) {
from_len = be_toint(vm, 5);
if (from_len < 0) { from_len = 0; }
if (from_len >= from_len_total) { from_len = from_len_total; }
}
if ((size_t) idx + (size_t)from_len >= attr.len) { from_len = attr.len - idx; }
// all parameters ok
if (from_len > 0) {
memmove(attr.bufptr + idx, buf_ptr + from_byte, from_len);
}
}
be_return_nil(vm);
}
static int m_setitem(bvm *vm)
{
int argc = be_top(vm);
@ -1575,6 +1619,7 @@ void be_load_byteslib(bvm *vm)
{ "geti", m_geti },
{ "set", m_set },
{ "seti", m_set }, // setters for signed and unsigned are identical
{ "setbytes", m_setbytes },
{ "getfloat", m_getfloat },
{ "setfloat", m_setfloat },
{ "item", m_item },
@ -1621,6 +1666,7 @@ class be_class_bytes (scope: global, name: bytes) {
setfloat, func(m_setfloat)
set, func(m_set)
seti, func(m_set)
setbytes, func(m_setbytes)
item, func(m_item)
setitem, func(m_setitem)
size, func(m_size)

View File

@ -202,3 +202,26 @@ assert(b == bytes())
b = bytes("FFFEAABBCC")
assert(b.tohex() == "FFFEAABBCC")
assert(bytes().tohex() == "")
# assign buffer to bytes
var a0 = bytes("112233445566778899")
b = bytes("aabbccddeeff")
a = a0.copy()
a.setbytes(0, b) # assign from start
assert(a == bytes('AABBCCDDEEFF778899'))
a = a0.copy()
a.setbytes(0, b, 0, 0) # zero len
assert(a == a0)
a = a0.copy()
a.setbytes(100, b) # index out of range
assert(a == a0)
a = a0.copy()
a.setbytes(6, b) # entire buffer not fitting
assert(a == bytes('112233445566AABBCC'))
a = a0.copy()
a.setbytes(6, b, 2, 2)
assert(a == bytes('112233445566CCDD99'))
a = b.copy()
a.setbytes(0, a0)
assert(a == bytes('112233445566'))

View File

@ -29,6 +29,7 @@ extern int l_wifi(bvm *vm);
extern int l_eth(bvm *vm);
extern int l_yield(bvm *vm);
extern int l_delay(bvm *vm);
extern int l_delay_microseconds(bvm *vm);
extern int l_scaleuint(bvm *vm);
extern int l_logInfo(bvm *vm);
extern int l_save(bvm *vm);
@ -102,6 +103,7 @@ class be_class_tasmota (scope: global, name: Tasmota) {
eth, func(l_eth)
yield, func(l_yield)
delay, func(l_delay)
delay_microseconds, func(l_delay_microseconds)
scale_uint, func(l_scaleuint)
log, func(l_logInfo)
save, func(l_save)

View File

@ -249,6 +249,8 @@ class Leds : Leds_ntv
var offset
var h, w
var alternate # are rows in alternate mode (even/odd are reversed)
var pix_buffer
var pix_size
def init(strip, w, h, offset)
self.strip = strip
@ -256,6 +258,9 @@ class Leds : Leds_ntv
self.h = h
self.w = w
self.alternate = false
self.pix_buffer = self.strip.pixels_buffer()
self.pix_size = self.strip.pixel_size()
end
def clear()
@ -270,6 +275,7 @@ class Leds : Leds_ntv
# don't trigger on segment, you will need to trigger on full strip instead
if bool(force) || (self.offset == 0 && self.w * self.h == self.strip.leds)
self.strip.show()
self.pix_buffer = self.strip.pixels_buffer() # update buffer after show()
end
end
def can_show()
@ -282,10 +288,10 @@ class Leds : Leds_ntv
self.strip.dirty()
end
def pixels_buffer()
return nil
return self.strip.pixels_buffer()
end
def pixel_size()
return self.strip.pixel_size()
return self.pix_size
end
def pixel_count()
return self.w * self.h
@ -304,6 +310,14 @@ class Leds : Leds_ntv
return self.strip.get_pixel_color(idx + self.offseta)
end
# setbytes(row, bytes)
# sets the raw bytes for `row`, copying at most 3 or 4 x col bytes
def set_bytes(row, buf, offset)
var h_bytes = self.h * self.pix_size
var offset_in_matrix = self.offset + row * h_bytes
self.pix_buffer.setbytes(offset_in_matrix, buf, offset, h_bytes)
end
# Leds_matrix specific
def set_alternate(alt)
self.alternate = alt

View File

@ -17,7 +17,8 @@ class Leds_animator
#
self.clear() # clear all leds first
#
tasmota.add_driver(self)
tasmota.add_fast_loop(/-> self.fast_loop())
# it may be useful to reduce Sleep time here
end
def add_anim(anim)
@ -43,7 +44,7 @@ class Leds_animator
return self.bri
end
def every_50ms()
def fast_loop()
if self.running
# run animators first
var i = 0

View File

@ -736,66 +736,9 @@ be_local_closure(Leds_is_dirty, /* name */
/********************************************************************
** Solidified function: pixel_count
** Solidified function: pixels_buffer
********************************************************************/
be_local_closure(Leds_matrix_pixel_count, /* name */
be_nested_proto(
3, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str(w),
/* K1 */ be_nested_str(h),
}),
&be_const_str_pixel_count,
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
0x88080101, // 0001 GETMBR R2 R0 K1
0x08040202, // 0002 MUL R1 R1 R2
0x80040200, // 0003 RET 1 R1
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: set_alternate
********************************************************************/
be_local_closure(Leds_matrix_set_alternate, /* name */
be_nested_proto(
2, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 1]) { /* constants */
/* K0 */ be_nested_str(alternate),
}),
&be_const_str_set_alternate,
&be_const_str_solidified,
( &(const binstruction[ 2]) { /* code */
0x90020001, // 0000 SETMBR R0 K0 R1
0x80000000, // 0001 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: pixel_size
********************************************************************/
be_local_closure(Leds_matrix_pixel_size, /* name */
be_local_closure(Leds_matrix_pixels_buffer, /* name */
be_nested_proto(
3, /* nstack */
1, /* argc */
@ -807,9 +750,9 @@ be_local_closure(Leds_matrix_pixel_size, /* name */
1, /* has constants */
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str(strip),
/* K1 */ be_nested_str(pixel_size),
/* K1 */ be_nested_str(pixels_buffer),
}),
&be_const_str_pixel_size,
&be_const_str_pixels_buffer,
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
@ -822,6 +765,54 @@ be_local_closure(Leds_matrix_pixel_size, /* name */
/*******************************************************************/
/********************************************************************
** Solidified function: init
********************************************************************/
be_local_closure(Leds_matrix_init, /* name */
be_nested_proto(
7, /* nstack */
5, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 9]) { /* constants */
/* K0 */ be_nested_str(strip),
/* K1 */ be_nested_str(offset),
/* K2 */ be_nested_str(h),
/* K3 */ be_nested_str(w),
/* K4 */ be_nested_str(alternate),
/* K5 */ be_nested_str(pix_buffer),
/* K6 */ be_nested_str(pixels_buffer),
/* K7 */ be_nested_str(pix_size),
/* K8 */ be_nested_str(pixel_size),
}),
&be_const_str_init,
&be_const_str_solidified,
( &(const binstruction[15]) { /* code */
0x90020001, // 0000 SETMBR R0 K0 R1
0x90020204, // 0001 SETMBR R0 K1 R4
0x90020403, // 0002 SETMBR R0 K2 R3
0x90020602, // 0003 SETMBR R0 K3 R2
0x50140000, // 0004 LDBOOL R5 0 0
0x90020805, // 0005 SETMBR R0 K4 R5
0x88140100, // 0006 GETMBR R5 R0 K0
0x8C140B06, // 0007 GETMET R5 R5 K6
0x7C140200, // 0008 CALL R5 1
0x90020A05, // 0009 SETMBR R0 K5 R5
0x88140100, // 000A GETMBR R5 R0 K0
0x8C140B08, // 000B GETMET R5 R5 K8
0x7C140200, // 000C CALL R5 1
0x90020E05, // 000D SETMBR R0 K7 R5
0x80000000, // 000E RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: set_pixel_color
********************************************************************/
@ -857,6 +848,180 @@ be_local_closure(Leds_matrix_set_pixel_color, /* name */
/*******************************************************************/
/********************************************************************
** Solidified function: begin
********************************************************************/
be_local_closure(Leds_matrix_begin, /* name */
be_nested_proto(
1, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
0, /* has constants */
NULL, /* no const */
&be_const_str_begin,
&be_const_str_solidified,
( &(const binstruction[ 1]) { /* code */
0x80000000, // 0000 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: get_pixel_color
********************************************************************/
be_local_closure(Leds_matrix_get_pixel_color, /* name */
be_nested_proto(
5, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 3]) { /* constants */
/* K0 */ be_nested_str(strip),
/* K1 */ be_nested_str(get_pixel_color),
/* K2 */ be_nested_str(offseta),
}),
&be_const_str_get_pixel_color,
&be_const_str_solidified,
( &(const binstruction[ 6]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0
0x8C080501, // 0001 GETMET R2 R2 K1
0x88100102, // 0002 GETMBR R4 R0 K2
0x00100204, // 0003 ADD R4 R1 R4
0x7C080400, // 0004 CALL R2 2
0x80040400, // 0005 RET 1 R2
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: pixel_size
********************************************************************/
be_local_closure(Leds_matrix_pixel_size, /* name */
be_nested_proto(
2, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 1]) { /* constants */
/* K0 */ be_nested_str(pix_size),
}),
&be_const_str_pixel_size,
&be_const_str_solidified,
( &(const binstruction[ 2]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
0x80040200, // 0001 RET 1 R1
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: set_alternate
********************************************************************/
be_local_closure(Leds_matrix_set_alternate, /* name */
be_nested_proto(
2, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 1]) { /* constants */
/* K0 */ be_nested_str(alternate),
}),
&be_const_str_set_alternate,
&be_const_str_solidified,
( &(const binstruction[ 2]) { /* code */
0x90020001, // 0000 SETMBR R0 K0 R1
0x80000000, // 0001 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: can_show
********************************************************************/
be_local_closure(Leds_matrix_can_show, /* name */
be_nested_proto(
3, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str(strip),
/* K1 */ be_nested_str(can_show),
}),
&be_const_str_can_show,
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
0x8C040301, // 0001 GETMET R1 R1 K1
0x7C040200, // 0002 CALL R1 1
0x80040200, // 0003 RET 1 R1
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: clear
********************************************************************/
be_local_closure(Leds_matrix_clear, /* name */
be_nested_proto(
4, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 3]) { /* constants */
/* K0 */ be_nested_str(clear_to),
/* K1 */ be_const_int(0),
/* K2 */ be_nested_str(show),
}),
&be_const_str_clear,
&be_const_str_solidified,
( &(const binstruction[ 6]) { /* code */
0x8C040100, // 0000 GETMET R1 R0 K0
0x580C0001, // 0001 LDCONST R3 K1
0x7C040400, // 0002 CALL R1 2
0x8C040102, // 0003 GETMET R1 R0 K2
0x7C040200, // 0004 CALL R1 1
0x80000000, // 0005 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: set_matrix_pixel_color
********************************************************************/
@ -918,6 +1083,36 @@ be_local_closure(Leds_matrix_set_matrix_pixel_color, /* name */
/*******************************************************************/
/********************************************************************
** Solidified function: pixel_count
********************************************************************/
be_local_closure(Leds_matrix_pixel_count, /* name */
be_nested_proto(
3, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str(w),
/* K1 */ be_nested_str(h),
}),
&be_const_str_pixel_count,
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
0x88080101, // 0001 GETMBR R2 R0 K1
0x08040202, // 0002 MUL R1 R1 R2
0x80040200, // 0003 RET 1 R1
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: show
********************************************************************/
@ -931,7 +1126,7 @@ be_local_closure(Leds_matrix_show, /* name */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 7]) { /* constants */
( &(const bvalue[ 9]) { /* constants */
/* K0 */ be_nested_str(offset),
/* K1 */ be_const_int(0),
/* K2 */ be_nested_str(w),
@ -939,58 +1134,34 @@ be_local_closure(Leds_matrix_show, /* name */
/* K4 */ be_nested_str(strip),
/* K5 */ be_nested_str(leds),
/* K6 */ be_nested_str(show),
/* K7 */ be_nested_str(pix_buffer),
/* K8 */ be_nested_str(pixels_buffer),
}),
&be_const_str_show,
&be_const_str_solidified,
( &(const binstruction[18]) { /* code */
( &(const binstruction[22]) { /* code */
0x60080017, // 0000 GETGBL R2 G23
0x5C0C0200, // 0001 MOVE R3 R1
0x7C080200, // 0002 CALL R2 1
0x740A0009, // 0003 JMPT R2 #000E
0x88080100, // 0004 GETMBR R2 R0 K0
0x1C080501, // 0005 EQ R2 R2 K1
0x780A0009, // 0006 JMPF R2 #0011
0x780A000D, // 0006 JMPF R2 #0015
0x88080102, // 0007 GETMBR R2 R0 K2
0x880C0103, // 0008 GETMBR R3 R0 K3
0x08080403, // 0009 MUL R2 R2 R3
0x880C0104, // 000A GETMBR R3 R0 K4
0x880C0705, // 000B GETMBR R3 R3 K5
0x1C080403, // 000C EQ R2 R2 R3
0x780A0002, // 000D JMPF R2 #0011
0x780A0006, // 000D JMPF R2 #0015
0x88080104, // 000E GETMBR R2 R0 K4
0x8C080506, // 000F GETMET R2 R2 K6
0x7C080200, // 0010 CALL R2 1
0x80000000, // 0011 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: is_dirty
********************************************************************/
be_local_closure(Leds_matrix_is_dirty, /* name */
be_nested_proto(
3, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str(strip),
/* K1 */ be_nested_str(is_dirty),
}),
&be_const_str_is_dirty,
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
0x8C040301, // 0001 GETMET R1 R1 K1
0x7C040200, // 0002 CALL R1 1
0x80040200, // 0003 RET 1 R1
0x88080104, // 0011 GETMBR R2 R0 K4
0x8C080508, // 0012 GETMET R2 R2 K8
0x7C080200, // 0013 CALL R2 1
0x90020E02, // 0014 SETMBR R0 K7 R2
0x80000000, // 0015 RET 0
})
)
);
@ -1044,100 +1215,6 @@ be_local_closure(Leds_matrix_clear_to, /* name */
/*******************************************************************/
/********************************************************************
** Solidified function: clear
********************************************************************/
be_local_closure(Leds_matrix_clear, /* name */
be_nested_proto(
4, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 3]) { /* constants */
/* K0 */ be_nested_str(clear_to),
/* K1 */ be_const_int(0),
/* K2 */ be_nested_str(show),
}),
&be_const_str_clear,
&be_const_str_solidified,
( &(const binstruction[ 6]) { /* code */
0x8C040100, // 0000 GETMET R1 R0 K0
0x580C0001, // 0001 LDCONST R3 K1
0x7C040400, // 0002 CALL R1 2
0x8C040102, // 0003 GETMET R1 R0 K2
0x7C040200, // 0004 CALL R1 1
0x80000000, // 0005 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: pixels_buffer
********************************************************************/
be_local_closure(Leds_matrix_pixels_buffer, /* name */
be_nested_proto(
2, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
0, /* has constants */
NULL, /* no const */
&be_const_str_pixels_buffer,
&be_const_str_solidified,
( &(const binstruction[ 2]) { /* code */
0x4C040000, // 0000 LDNIL R1
0x80040200, // 0001 RET 1 R1
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: init
********************************************************************/
be_local_closure(Leds_matrix_init, /* name */
be_nested_proto(
6, /* nstack */
5, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 5]) { /* constants */
/* K0 */ be_nested_str(strip),
/* K1 */ be_nested_str(offset),
/* K2 */ be_nested_str(h),
/* K3 */ be_nested_str(w),
/* K4 */ be_nested_str(alternate),
}),
&be_const_str_init,
&be_const_str_solidified,
( &(const binstruction[ 7]) { /* code */
0x90020001, // 0000 SETMBR R0 K0 R1
0x90020204, // 0001 SETMBR R0 K1 R4
0x90020403, // 0002 SETMBR R0 K2 R3
0x90020602, // 0003 SETMBR R0 K3 R2
0x50140000, // 0004 LDBOOL R5 0 0
0x90020805, // 0005 SETMBR R0 K4 R5
0x80000000, // 0006 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: dirty
********************************************************************/
@ -1168,39 +1245,6 @@ be_local_closure(Leds_matrix_dirty, /* name */
/*******************************************************************/
/********************************************************************
** Solidified function: get_pixel_color
********************************************************************/
be_local_closure(Leds_matrix_get_pixel_color, /* name */
be_nested_proto(
5, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 3]) { /* constants */
/* K0 */ be_nested_str(strip),
/* K1 */ be_nested_str(get_pixel_color),
/* K2 */ be_nested_str(offseta),
}),
&be_const_str_get_pixel_color,
&be_const_str_solidified,
( &(const binstruction[ 6]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0
0x8C080501, // 0001 GETMET R2 R2 K1
0x88100102, // 0002 GETMBR R4 R0 K2
0x00100204, // 0003 ADD R4 R1 R4
0x7C080400, // 0004 CALL R2 2
0x80040400, // 0005 RET 1 R2
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: get_alternate
********************************************************************/
@ -1229,33 +1273,9 @@ be_local_closure(Leds_matrix_get_alternate, /* name */
/********************************************************************
** Solidified function: begin
** Solidified function: is_dirty
********************************************************************/
be_local_closure(Leds_matrix_begin, /* name */
be_nested_proto(
1, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
0, /* has constants */
NULL, /* no const */
&be_const_str_begin,
&be_const_str_solidified,
( &(const binstruction[ 1]) { /* code */
0x80000000, // 0000 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: can_show
********************************************************************/
be_local_closure(Leds_matrix_can_show, /* name */
be_local_closure(Leds_matrix_is_dirty, /* name */
be_nested_proto(
3, /* nstack */
1, /* argc */
@ -1267,9 +1287,9 @@ be_local_closure(Leds_matrix_can_show, /* name */
1, /* has constants */
( &(const bvalue[ 2]) { /* constants */
/* K0 */ be_nested_str(strip),
/* K1 */ be_nested_str(can_show),
/* K1 */ be_nested_str(is_dirty),
}),
&be_const_str_can_show,
&be_const_str_is_dirty,
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
@ -1282,35 +1302,81 @@ be_local_closure(Leds_matrix_can_show, /* name */
/*******************************************************************/
/********************************************************************
** Solidified function: set_bytes
********************************************************************/
be_local_closure(Leds_matrix_set_bytes, /* name */
be_nested_proto(
12, /* nstack */
4, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 5]) { /* constants */
/* K0 */ be_nested_str(h),
/* K1 */ be_nested_str(pix_size),
/* K2 */ be_nested_str(offset),
/* K3 */ be_nested_str(pix_buffer),
/* K4 */ be_nested_str(setbytes),
}),
&be_const_str_set_bytes,
&be_const_str_solidified,
( &(const binstruction[14]) { /* code */
0x88100100, // 0000 GETMBR R4 R0 K0
0x88140101, // 0001 GETMBR R5 R0 K1
0x08100805, // 0002 MUL R4 R4 R5
0x88140102, // 0003 GETMBR R5 R0 K2
0x08180204, // 0004 MUL R6 R1 R4
0x00140A06, // 0005 ADD R5 R5 R6
0x88180103, // 0006 GETMBR R6 R0 K3
0x8C180D04, // 0007 GETMET R6 R6 K4
0x5C200A00, // 0008 MOVE R8 R5
0x5C240400, // 0009 MOVE R9 R2
0x5C280600, // 000A MOVE R10 R3
0x5C2C0800, // 000B MOVE R11 R4
0x7C180A00, // 000C CALL R6 5
0x80000000, // 000D RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified class: Leds_matrix
********************************************************************/
be_local_class(Leds_matrix,
5,
7,
NULL,
be_nested_map(21,
be_nested_map(24,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key(pixel_count, -1), be_const_closure(Leds_matrix_pixel_count_closure) },
{ be_const_key(h, 6), be_const_var(2) },
{ be_const_key(set_alternate, 7), be_const_closure(Leds_matrix_set_alternate_closure) },
{ be_const_key(pixel_size, 16), be_const_closure(Leds_matrix_pixel_size_closure) },
{ be_const_key(set_pixel_color, 19), be_const_closure(Leds_matrix_set_pixel_color_closure) },
{ be_const_key(set_matrix_pixel_color, 10), be_const_closure(Leds_matrix_set_matrix_pixel_color_closure) },
{ be_const_key(show, -1), be_const_closure(Leds_matrix_show_closure) },
{ be_const_key(alternate, -1), be_const_var(4) },
{ be_const_key(strip, -1), be_const_var(0) },
{ be_const_key(clear_to, -1), be_const_closure(Leds_matrix_clear_to_closure) },
{ be_const_key(w, 15), be_const_var(3) },
{ be_const_key(pixels_buffer, -1), be_const_closure(Leds_matrix_pixels_buffer_closure) },
{ be_const_key(set_bytes, -1), be_const_closure(Leds_matrix_set_bytes_closure) },
{ be_const_key(pix_buffer, -1), be_const_var(5) },
{ be_const_key(pix_size, 20), be_const_var(6) },
{ be_const_key(init, -1), be_const_closure(Leds_matrix_init_closure) },
{ be_const_key(dirty, -1), be_const_closure(Leds_matrix_dirty_closure) },
{ be_const_key(get_pixel_color, -1), be_const_closure(Leds_matrix_get_pixel_color_closure) },
{ be_const_key(get_alternate, 17), be_const_closure(Leds_matrix_get_alternate_closure) },
{ be_const_key(offset, 8), be_const_var(1) },
{ be_const_key(clear, -1), be_const_closure(Leds_matrix_clear_closure) },
{ be_const_key(set_pixel_color, 16), be_const_closure(Leds_matrix_set_pixel_color_closure) },
{ be_const_key(alternate, -1), be_const_var(4) },
{ be_const_key(begin, -1), be_const_closure(Leds_matrix_begin_closure) },
{ be_const_key(is_dirty, -1), be_const_closure(Leds_matrix_is_dirty_closure) },
{ be_const_key(h, -1), be_const_var(2) },
{ be_const_key(get_pixel_color, -1), be_const_closure(Leds_matrix_get_pixel_color_closure) },
{ be_const_key(pixel_size, 21), be_const_closure(Leds_matrix_pixel_size_closure) },
{ be_const_key(set_alternate, -1), be_const_closure(Leds_matrix_set_alternate_closure) },
{ be_const_key(can_show, -1), be_const_closure(Leds_matrix_can_show_closure) },
{ be_const_key(get_alternate, 13), be_const_closure(Leds_matrix_get_alternate_closure) },
{ be_const_key(w, -1), be_const_var(3) },
{ be_const_key(set_matrix_pixel_color, 12), be_const_closure(Leds_matrix_set_matrix_pixel_color_closure) },
{ be_const_key(pixel_count, -1), be_const_closure(Leds_matrix_pixel_count_closure) },
{ be_const_key(show, -1), be_const_closure(Leds_matrix_show_closure) },
{ be_const_key(offset, -1), be_const_var(1) },
{ be_const_key(clear_to, 17), be_const_closure(Leds_matrix_clear_to_closure) },
{ be_const_key(dirty, -1), be_const_closure(Leds_matrix_dirty_closure) },
{ be_const_key(clear, 10), be_const_closure(Leds_matrix_clear_closure) },
{ be_const_key(strip, -1), be_const_var(0) },
{ be_const_key(is_dirty, -1), be_const_closure(Leds_matrix_is_dirty_closure) },
{ be_const_key(pixels_buffer, 0), be_const_closure(Leds_matrix_pixels_buffer_closure) },
})),
(bstring*) &be_const_str_Leds_matrix
);

View File

@ -14,9 +14,33 @@ be_local_closure(Leds_animator_init, /* name */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
1, /* has sup protos */
( &(const struct bproto*[ 1]) {
be_nested_proto(
2, /* nstack */
0, /* argc */
0, /* varg */
1, /* has upvals */
( &(const bupvaldesc[ 1]) { /* upvals */
be_local_const_upval(1, 0),
}),
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 1]) { /* constants */
/* K0 */ be_nested_str_weak(fast_loop),
}),
be_str_weak(_X3Clambda_X3E),
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x68000000, // 0000 GETUPV R0 U0
0x8C000100, // 0001 GETMET R0 R0 K0
0x7C000200, // 0002 CALL R0 1
0x80040000, // 0003 RET 1 R0
})
),
}),
1, /* has constants */
( &(const bvalue[ 8]) { /* constants */
/* K0 */ be_nested_str_weak(strip),
/* K1 */ be_nested_str_weak(bri),
@ -25,11 +49,11 @@ be_local_closure(Leds_animator_init, /* name */
/* K4 */ be_nested_str_weak(animators),
/* K5 */ be_nested_str_weak(clear),
/* K6 */ be_nested_str_weak(tasmota),
/* K7 */ be_nested_str_weak(add_driver),
/* K7 */ be_nested_str_weak(add_fast_loop),
}),
be_str_weak(init),
&be_const_str_solidified,
( &(const binstruction[18]) { /* code */
( &(const binstruction[19]) { /* code */
0x90020001, // 0000 SETMBR R0 K0 R1
0x540A0031, // 0001 LDINT R2 50
0x90020202, // 0002 SETMBR R0 K1 R2
@ -45,9 +69,10 @@ be_local_closure(Leds_animator_init, /* name */
0x7C080200, // 000C CALL R2 1
0xB80A0C00, // 000D GETNGBL R2 K6
0x8C080507, // 000E GETMET R2 R2 K7
0x5C100000, // 000F MOVE R4 R0
0x84100000, // 000F CLOSURE R4 P0
0x7C080400, // 0010 CALL R2 2
0x80000000, // 0011 RET 0
0xA0000000, // 0011 CLOSE R0
0x80000000, // 0012 RET 0
})
)
);
@ -55,11 +80,11 @@ be_local_closure(Leds_animator_init, /* name */
/********************************************************************
** Solidified function: set_bri
** Solidified function: add_anim
********************************************************************/
be_local_closure(Leds_animator_set_bri, /* name */
be_local_closure(Leds_animator_add_anim, /* name */
be_nested_proto(
2, /* nstack */
5, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
@ -67,14 +92,21 @@ be_local_closure(Leds_animator_set_bri, /* name */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 1]) { /* constants */
/* K0 */ be_nested_str_weak(bri),
( &(const bvalue[ 3]) { /* constants */
/* K0 */ be_nested_str_weak(animators),
/* K1 */ be_nested_str_weak(push),
/* K2 */ be_nested_str_weak(run),
}),
be_str_weak(set_bri),
be_str_weak(add_anim),
&be_const_str_solidified,
( &(const binstruction[ 2]) { /* code */
0x90020001, // 0000 SETMBR R0 K0 R1
0x80000000, // 0001 RET 0
( &(const binstruction[ 7]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0
0x8C080501, // 0001 GETMET R2 R2 K1
0x5C100200, // 0002 MOVE R4 R1
0x7C080400, // 0003 CALL R2 2
0x8C080302, // 0004 GETMET R2 R1 K2
0x7C080200, // 0005 CALL R2 1
0x80000000, // 0006 RET 0
})
)
);
@ -109,6 +141,62 @@ be_local_closure(Leds_animator_stop, /* name */
/*******************************************************************/
/********************************************************************
** Solidified function: fast_loop
********************************************************************/
be_local_closure(Leds_animator_fast_loop, /* name */
be_nested_proto(
6, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 7]) { /* constants */
/* K0 */ be_nested_str_weak(running),
/* K1 */ be_const_int(0),
/* K2 */ be_nested_str_weak(animators),
/* K3 */ be_nested_str_weak(is_running),
/* K4 */ be_nested_str_weak(animate),
/* K5 */ be_const_int(1),
/* K6 */ be_nested_str_weak(remove),
}),
be_str_weak(fast_loop),
&be_const_str_solidified,
( &(const binstruction[25]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
0x78060015, // 0001 JMPF R1 #0018
0x58040001, // 0002 LDCONST R1 K1
0x6008000C, // 0003 GETGBL R2 G12
0x880C0102, // 0004 GETMBR R3 R0 K2
0x7C080200, // 0005 CALL R2 1
0x14080202, // 0006 LT R2 R1 R2
0x780A000D, // 0007 JMPF R2 #0016
0x88080102, // 0008 GETMBR R2 R0 K2
0x94080401, // 0009 GETIDX R2 R2 R1
0x8C0C0503, // 000A GETMET R3 R2 K3
0x7C0C0200, // 000B CALL R3 1
0x780E0003, // 000C JMPF R3 #0011
0x8C0C0504, // 000D GETMET R3 R2 K4
0x7C0C0200, // 000E CALL R3 1
0x00040305, // 000F ADD R1 R1 K5
0x70020003, // 0010 JMP #0015
0x880C0102, // 0011 GETMBR R3 R0 K2
0x8C0C0706, // 0012 GETMET R3 R3 K6
0x5C140200, // 0013 MOVE R5 R1
0x7C0C0400, // 0014 CALL R3 2
0x7001FFEC, // 0015 JMP #0003
0x8C080104, // 0016 GETMET R2 R0 K4
0x7C080200, // 0017 CALL R2 1
0x80000000, // 0018 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: animate
********************************************************************/
@ -165,55 +253,26 @@ be_local_closure(Leds_animator_remove, /* name */
/********************************************************************
** Solidified function: every_50ms
** Solidified function: set_bri
********************************************************************/
be_local_closure(Leds_animator_every_50ms, /* name */
be_local_closure(Leds_animator_set_bri, /* name */
be_nested_proto(
6, /* nstack */
1, /* argc */
2, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 7]) { /* constants */
/* K0 */ be_nested_str_weak(running),
/* K1 */ be_const_int(0),
/* K2 */ be_nested_str_weak(animators),
/* K3 */ be_nested_str_weak(is_running),
/* K4 */ be_nested_str_weak(animate),
/* K5 */ be_const_int(1),
/* K6 */ be_nested_str_weak(remove),
( &(const bvalue[ 1]) { /* constants */
/* K0 */ be_nested_str_weak(bri),
}),
be_str_weak(every_50ms),
be_str_weak(set_bri),
&be_const_str_solidified,
( &(const binstruction[25]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
0x78060015, // 0001 JMPF R1 #0018
0x58040001, // 0002 LDCONST R1 K1
0x6008000C, // 0003 GETGBL R2 G12
0x880C0102, // 0004 GETMBR R3 R0 K2
0x7C080200, // 0005 CALL R2 1
0x14080202, // 0006 LT R2 R1 R2
0x780A000D, // 0007 JMPF R2 #0016
0x88080102, // 0008 GETMBR R2 R0 K2
0x94080401, // 0009 GETIDX R2 R2 R1
0x8C0C0503, // 000A GETMET R3 R2 K3
0x7C0C0200, // 000B CALL R3 1
0x780E0003, // 000C JMPF R3 #0011
0x8C0C0504, // 000D GETMET R3 R2 K4
0x7C0C0200, // 000E CALL R3 1
0x00040305, // 000F ADD R1 R1 K5
0x70020003, // 0010 JMP #0015
0x880C0102, // 0011 GETMBR R3 R0 K2
0x8C0C0706, // 0012 GETMET R3 R3 K6
0x5C140200, // 0013 MOVE R5 R1
0x7C0C0400, // 0014 CALL R3 2
0x7001FFEC, // 0015 JMP #0003
0x8C080104, // 0016 GETMET R2 R0 K4
0x7C080200, // 0017 CALL R2 1
0x80000000, // 0018 RET 0
( &(const binstruction[ 2]) { /* code */
0x90020001, // 0000 SETMBR R0 K0 R1
0x80000000, // 0001 RET 0
})
)
);
@ -275,40 +334,6 @@ be_local_closure(Leds_animator_start, /* name */
/*******************************************************************/
/********************************************************************
** Solidified function: add_anim
********************************************************************/
be_local_closure(Leds_animator_add_anim, /* name */
be_nested_proto(
5, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 3]) { /* constants */
/* K0 */ be_nested_str_weak(animators),
/* K1 */ be_nested_str_weak(push),
/* K2 */ be_nested_str_weak(run),
}),
be_str_weak(add_anim),
&be_const_str_solidified,
( &(const binstruction[ 7]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0
0x8C080501, // 0001 GETMET R2 R2 K1
0x5C100200, // 0002 MOVE R4 R1
0x7C080400, // 0003 CALL R2 2
0x8C080302, // 0004 GETMET R2 R1 K2
0x7C080200, // 0005 CALL R2 1
0x80000000, // 0006 RET 0
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: clear
********************************************************************/
@ -352,18 +377,18 @@ be_local_class(Leds_animator,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(init, 12), be_const_closure(Leds_animator_init_closure) },
{ be_const_key_weak(clear, -1), be_const_closure(Leds_animator_clear_closure) },
{ be_const_key_weak(stop, -1), be_const_closure(Leds_animator_stop_closure) },
{ be_const_key_weak(strip, 4), be_const_var(0) },
{ be_const_key_weak(stop, 13), be_const_closure(Leds_animator_stop_closure) },
{ be_const_key_weak(add_anim, 4), be_const_closure(Leds_animator_add_anim_closure) },
{ be_const_key_weak(pixel_count, 6), be_const_var(1) },
{ be_const_key_weak(animate, -1), be_const_closure(Leds_animator_animate_closure) },
{ be_const_key_weak(add_anim, 13), be_const_closure(Leds_animator_add_anim_closure) },
{ be_const_key_weak(animators, 7), be_const_var(4) },
{ be_const_key_weak(strip, -1), be_const_var(0) },
{ be_const_key_weak(bri, -1), be_const_var(2) },
{ be_const_key_weak(every_50ms, -1), be_const_closure(Leds_animator_every_50ms_closure) },
{ be_const_key_weak(remove, 7), be_const_closure(Leds_animator_remove_closure) },
{ be_const_key_weak(remove, 8), be_const_closure(Leds_animator_remove_closure) },
{ be_const_key_weak(get_bri, -1), be_const_closure(Leds_animator_get_bri_closure) },
{ be_const_key_weak(start, -1), be_const_closure(Leds_animator_start_closure) },
{ be_const_key_weak(running, -1), be_const_var(3) },
{ be_const_key_weak(animators, -1), be_const_var(4) },
{ be_const_key_weak(fast_loop, -1), be_const_closure(Leds_animator_fast_loop_closure) },
{ be_const_key_weak(set_bri, 1), be_const_closure(Leds_animator_set_bri_closure) },
})),
be_str_weak(Leds_animator)

View File

@ -2,6 +2,22 @@
All notable changes to this project will be documented in this file.
## [1.4.1] - 2022-10-23
### Fixed
- Compile warning removed for esp32c3
- NimBLEDevice::getPower incorrect value when power level is -3db.
- Failed pairing when already in progress.
### Changed
- Revert previous change that forced writing with response when subscribing in favor of allowing the application to decide.
### Added
- Added NimBLEHIDDevice::batteryLevel.
- Added NimBLEDevice::setDeviceName allowing for changing the device name while the BLE stack is active.
- CI build tests.
- Missing items in CHANGELOG that were not recorded correctly
## [1.4.0] - 2022-07-10
### Fixed
@ -11,6 +27,9 @@ All notable changes to this project will be documented in this file.
### Changed
- Updated NimBLE core to use the v1.4.0 branch of esp-nimble.
- AD flags are no longer set in the advertisements of non-connectable beacons, freeing up 3 bytes of advertisement room.
- Config option CONFIG_BT_NIMBLE_DEBUG replaced with CONFIG_BT_NIMBLE_LOG_LEVEL (see src/nimconfig.h for usage)
- Config option CONFIG_NIMBLE_CPP_ENABLE_ADVERTISMENT_TYPE_TEXT renamed to CONFIG_NIMBLE_CPP_ENABLE_ADVERTISEMENT_TYPE_TEXT
- Config option CONFIG_BT_NIMBLE_TASK_STACK_SIZE renamed to CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE
### Added
- Preliminary support for non-esp devices, NRF51 and NRF52 devices supported with [n-able arduino core](https://github.com/h2zero/n-able-Arduino)

View File

@ -38,7 +38,7 @@ PROJECT_NAME = NimBLE-Arduino
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 1.4.0
PROJECT_NUMBER = 1.4.1
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@ -58,7 +58,7 @@ PROJECT_LOGO =
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY = docs
OUTPUT_DIRECTORY = doxydocs
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
@ -836,7 +836,7 @@ WARN_NO_PARAMDOC = NO
# Possible values are: NO, YES and FAIL_ON_WARNINGS.
# The default value is: NO.
WARN_AS_ERROR = FAIL_ON_WARNINGS
WARN_AS_ERROR = YES
# The WARN_FORMAT tag determines the format of the warning messages that doxygen
# can produce. The string should contain the $file, $line, and $text tags, which

View File

@ -1,5 +1,5 @@
name=NimBLE-Arduino
version=1.4.0
version=1.4.1
author=h2zero
maintainer=h2zero <powellperalta@gmail.com>
sentence=Bluetooth low energy (BLE) library for arduino-esp32 based on NimBLE.

View File

@ -336,6 +336,7 @@ bool NimBLEClient::connect(const NimBLEAddress &address, bool deleteAttributes)
* @return True on success.
*/
bool NimBLEClient::secureConnection() {
NIMBLE_LOGD(LOG_TAG, ">> secureConnection()");
TaskHandle_t cur_task = xTaskGetCurrentTaskHandle();
ble_task_data_t taskData = {this, cur_task, 0, nullptr};
@ -345,7 +346,7 @@ bool NimBLEClient::secureConnection() {
m_pTaskData = &taskData;
int rc = NimBLEDevice::startSecurity(m_conn_id);
if(rc != 0){
if(rc != 0 && rc != BLE_HS_EALREADY){
m_lastErr = rc;
m_pTaskData = nullptr;
return false;
@ -360,9 +361,11 @@ bool NimBLEClient::secureConnection() {
if(taskData.rc != 0){
m_lastErr = taskData.rc;
NIMBLE_LOGE(LOG_TAG, "secureConnection: failed rc=%d", taskData.rc);
return false;
}
NIMBLE_LOGD(LOG_TAG, "<< secureConnection: success");
return true;
} // secureConnection

View File

@ -971,6 +971,15 @@ void NimBLEDevice::deinit(bool clearAll) {
}
} // deinit
/**
* @brief Set the BLEDevice's name
* @param [in] deviceName The device name of the device.
*/
/* STATIC */
void NimBLEDevice::setDeviceName(const std::string &deviceName) {
ble_svc_gap_device_name_set(deviceName.c_str());
} // setDeviceName
/**
* @brief Check if the initialization is complete.

View File

@ -97,6 +97,7 @@ class NimBLEDevice {
public:
static void init(const std::string &deviceName);
static void deinit(bool clearAll = false);
static void setDeviceName(const std::string &deviceName);
static bool getInitialized();
static NimBLEAddress getAddress();
static std::string toString();
@ -150,7 +151,8 @@ public:
int max_events = 0);
static bool stopAdvertising(uint8_t inst_id);
static bool stopAdvertising();
# else
# endif
# if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_)
static NimBLEAdvertising* getAdvertising();
static bool startAdvertising();
static bool stopAdvertising();

View File

@ -203,12 +203,12 @@ void NimBLEHIDDevice::setBatteryLevel(uint8_t level) {
/*
* @brief Returns battery level characteristic
* @ return battery level characteristic
*//*
BLECharacteristic* BLEHIDDevice::batteryLevel() {
*/
NimBLECharacteristic* NimBLEHIDDevice::batteryLevel() {
return m_batteryLevelCharacteristic;
}
/*
BLECharacteristic* BLEHIDDevice::reportMap() {
return m_reportMapCharacteristic;

View File

@ -55,7 +55,7 @@ public:
void pnp(uint8_t sig, uint16_t vid, uint16_t pid, uint16_t version);
//NimBLECharacteristic* hidInfo();
void hidInfo(uint8_t country, uint8_t flags);
//NimBLECharacteristic* batteryLevel();
NimBLECharacteristic* batteryLevel();
void setBatteryLevel(uint8_t level);

View File

@ -616,7 +616,6 @@ bool NimBLERemoteCharacteristic::setNotify(uint16_t val, notify_callback notifyC
NIMBLE_LOGD(LOG_TAG, "<< setNotify()");
response = true; // Always write with response as per Bluetooth core specification.
return desc->writeValue((uint8_t *)&val, 2, response);
} // setNotify

View File

@ -73,8 +73,8 @@ public:
bool subscribe(bool notifications = true,
notify_callback notifyCallback = nullptr,
bool response = true);
bool unsubscribe(bool response = true);
bool response = false);
bool unsubscribe(bool response = false);
bool registerForNotify(notify_callback notifyCallback,
bool notifications = true,
bool response = true)

View File

@ -58,7 +58,8 @@ public:
int duration = 0,
int max_events = 0);
bool stopAdvertising(uint8_t inst_id);
#else
#endif
#if !CONFIG_BT_NIMBLE_EXT_ADV || defined(_DOXYGEN_)
NimBLEAdvertising* getAdvertising();
bool startAdvertising();
#endif

View File

@ -33,15 +33,22 @@ import subprocess
sys.path.append(join(platform.get_package_dir("tool-esptoolpy")))
import esptool
github_actions = os.getenv('GITHUB_ACTIONS')
extra_flags = ''.join([element.replace("-D", " ") for element in env.BoardConfig().get("build.extra_flags", "")])
build_flags = ''.join([element.replace("-D", " ") for element in env.GetProjectOption("build_flags")])
if "CORE32SOLO1" in extra_flags or "FRAMEWORK_ARDUINO_SOLO1" in build_flags:
FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-solo1")
if github_actions and os.path.exists("./firmware/firmware"):
shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-solo1/variants/tasmota")
elif "CORE32ITEAD" in extra_flags or "FRAMEWORK_ARDUINO_ITEAD" in build_flags:
FRAMEWORK_DIR = platform.get_package_dir("framework-arduino-ITEAD")
if github_actions and os.path.exists("./firmware/firmware"):
shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduino-ITEAD/variants/tasmota")
else:
FRAMEWORK_DIR = platform.get_package_dir("framework-arduinoespressif32")
if github_actions and os.path.exists("./firmware/firmware"):
shutil.copytree("./firmware/firmware", "/home/runner/.platformio/packages/framework-arduinoespressif32/variants/tasmota")
variants_dir = join(FRAMEWORK_DIR, "variants", "tasmota")

View File

@ -19,7 +19,7 @@ class lv_touch_3_buttons
static ACTIVE_LOW = true
# Arguments:
# Physical GPIOs, generally through `gpio.pin(gpio.INPUT, 0), gpio.pin(gpio.INPUT, 1), gpio.pin(gpio.INPUT, 2)`
# Physical GPIOs, generally through `gpio.pin(gpio.GPIO_INPUT, 0), gpio.pin(gpio.GPIO_INPUT, 1), gpio.pin(gpio.GPIO_INPUT, 2)`
#
# Pre-condition:
# LVGL must be already started
@ -85,9 +85,9 @@ class lv_touch_3_buttons
end
end
return lv_touch_3_buttons(gpio.pin(gpio.INPUT, 0), gpio.pin(gpio.INPUT, 1), gpio.pin(gpio.INPUT, 2), true)
return lv_touch_3_buttons(gpio.pin(gpio.GPIO_INPUT, 0), gpio.pin(gpio.GPIO_INPUT, 1), gpio.pin(gpio.GPIO_INPUT, 2), true)
#-
lv_btn3 = lv_touch_3_buttons(gpio.pin(gpio.INPUT, 0), gpio.pin(gpio.INPUT, 1), gpio.pin(gpio.INPUT, 2), lv_touch_3_buttons.ACTIVE_LOW)
lv_btn3 = lv_touch_3_buttons(gpio.pin(gpio.GPIO_INPUT, 0), gpio.pin(gpio.GPIO_INPUT, 1), gpio.pin(gpio.GPIO_INPUT, 2), lv_touch_3_buttons.ACTIVE_LOW)
tasmota.add_driver(lv_btn3)
-#

View File

@ -19,7 +19,9 @@ const be_const_member_t lv_gpio_constants[] = {
{ "ADC_RANGE", (int32_t) GPIO_ADC_RANGE },
{ "ADC_TEMP", (int32_t) GPIO_ADC_TEMP },
{ "ADE7880_IRQ", (int32_t) GPIO_ADE7880_IRQ },
{ "ADE7953_CS", (int32_t) GPIO_ADE7953_CS },
{ "ADE7953_IRQ", (int32_t) GPIO_ADE7953_IRQ },
{ "ADE7953_RST", (int32_t) GPIO_ADE7953_RST },
{ "ARIRFRCV", (int32_t) GPIO_ARIRFRCV },
{ "ARIRFSEL", (int32_t) GPIO_ARIRFSEL },
{ "AS3935", (int32_t) GPIO_AS3935 },
@ -35,6 +37,8 @@ const be_const_member_t lv_gpio_constants[] = {
{ "BL6523_TX", (int32_t) GPIO_BL6523_TX },
{ "BOILER_OT_RX", (int32_t) GPIO_BOILER_OT_RX },
{ "BOILER_OT_TX", (int32_t) GPIO_BOILER_OT_TX },
{ "BP5758D_CLK", (int32_t) GPIO_BP5758D_CLK },
{ "BP5758D_DAT", (int32_t) GPIO_BP5758D_DAT },
{ "BS814_CLK", (int32_t) GPIO_BS814_CLK },
{ "BS814_DAT", (int32_t) GPIO_BS814_DAT },
{ "BUZZER", (int32_t) GPIO_BUZZER },
@ -75,6 +79,7 @@ const be_const_member_t lv_gpio_constants[] = {
{ "FALLING", FALLING },
{ "FLOWRATEMETER_SIGNAL", (int32_t) GPIO_FLOWRATEMETER_IN },
{ "FTC532", (int32_t) GPIO_FTC532 },
{ "GPIO_INPUT", (int32_t) GPIO_INPUT },
{ "GPS_RX", (int32_t) GPIO_GPS_RX },
{ "GPS_TX", (int32_t) GPIO_GPS_TX },
{ "HALLEFFECT", (int32_t) GPIO_HALLEFFECT },
@ -99,6 +104,7 @@ const be_const_member_t lv_gpio_constants[] = {
{ "I2S_IN_CLK", (int32_t) GPIO_I2S_BCLK_IN },
{ "I2S_IN_DATA", (int32_t) GPIO_I2S_DIN },
{ "I2S_IN_SLCT", (int32_t) GPIO_I2S_WS_IN },
{ "I2S_MCLK", (int32_t) GPIO_I2S_MCLK },
{ "I2S_OUT_CLK", (int32_t) GPIO_I2S_BCLK },
{ "I2S_OUT_DATA", (int32_t) GPIO_I2S_DOUT },
{ "I2S_OUT_SLCT", (int32_t) GPIO_I2S_WS },
@ -109,7 +115,7 @@ const be_const_member_t lv_gpio_constants[] = {
{ "ILI9341_CS", (int32_t) GPIO_ILI9341_CS },
{ "ILI9341_DC", (int32_t) GPIO_ILI9341_DC },
{ "ILI9488_CS", (int32_t) GPIO_ILI9488_CS },
{ "INPUT", (int32_t) GPIO_INPUT },
{ "INPUT", INPUT },
{ "INPUT_PULLDOWN", INPUT_PULLDOWN },
{ "INPUT_PULLUP", INPUT_PULLUP },
{ "INTERRUPT", (int32_t) GPIO_INTERRUPT },
@ -137,6 +143,8 @@ const be_const_member_t lv_gpio_constants[] = {
{ "MAX7219CS", (int32_t) GPIO_MAX7219CS },
{ "MAX7219DIN", (int32_t) GPIO_MAX7219DIN },
{ "MAX_RMT", MAX_RMT },
{ "MBR_RX", (int32_t) GPIO_MBR_RX },
{ "MBR_TX", (int32_t) GPIO_MBR_TX },
{ "MCP2515_CS", (int32_t) GPIO_MCP2515_CS },
{ "MCP39F5_RST", (int32_t) GPIO_MCP39F5_RST },
{ "MCP39F5_RX", (int32_t) GPIO_MCP39F5_RX },
@ -148,6 +156,7 @@ const be_const_member_t lv_gpio_constants[] = {
{ "MIEL_HVAC_RX", (int32_t) GPIO_MIEL_HVAC_RX },
{ "MIEL_HVAC_TX", (int32_t) GPIO_MIEL_HVAC_TX },
{ "MP3_DFR562", (int32_t) GPIO_MP3_DFR562 },
{ "MP3_DFR562_BUSY", (int32_t) GPIO_MP3_DFR562_BUSY },
{ "MS01", (int32_t) GPIO_MS01 },
{ "NEOPOOL_RX", (int32_t) GPIO_NEOPOOL_RX },
{ "NEOPOOL_TX", (int32_t) GPIO_NEOPOOL_TX },
@ -155,6 +164,8 @@ const be_const_member_t lv_gpio_constants[] = {
{ "NRF24_CS", (int32_t) GPIO_NRF24_CS },
{ "NRF24_DC", (int32_t) GPIO_NRF24_DC },
{ "NRG_CF1", (int32_t) GPIO_NRG_CF1 },
{ "NRG_MBS_RX", (int32_t) GPIO_NRG_MBS_RX },
{ "NRG_MBS_TX", (int32_t) GPIO_NRG_MBS_TX },
{ "NRG_SEL", (int32_t) GPIO_NRG_SEL },
{ "NRG_SEL_INV", (int32_t) GPIO_NRG_SEL_INV },
{ "OLED_RESET", (int32_t) GPIO_OLED_RESET },
@ -186,6 +197,8 @@ const be_const_member_t lv_gpio_constants[] = {
{ "RC522_RST", (int32_t) GPIO_RC522_RST },
{ "RDM6300_RX", (int32_t) GPIO_RDM6300_RX },
{ "REL1", (int32_t) GPIO_REL1 },
{ "REL1_BI", (int32_t) GPIO_REL1_BI },
{ "REL1_BI_INV", (int32_t) GPIO_REL1_BI_INV },
{ "REL1_INV", (int32_t) GPIO_REL1_INV },
{ "RESET", (int32_t) GPIO_RESET },
{ "RFRECV", (int32_t) GPIO_RFRECV },
@ -231,6 +244,8 @@ const be_const_member_t lv_gpio_constants[] = {
{ "SM16716_SEL", (int32_t) GPIO_SM16716_SEL },
{ "SM2135_CLK", (int32_t) GPIO_SM2135_CLK },
{ "SM2135_DAT", (int32_t) GPIO_SM2135_DAT },
{ "SM2335_CLK", (int32_t) GPIO_SM2335_CLK },
{ "SM2335_DAT", (int32_t) GPIO_SM2335_DAT },
{ "SOLAXX1_RTS", (int32_t) GPIO_SOLAXX1_RTS },
{ "SOLAXX1_RX", (int32_t) GPIO_SOLAXX1_RX },
{ "SOLAXX1_TX", (int32_t) GPIO_SOLAXX1_TX },
@ -266,6 +281,10 @@ const be_const_member_t lv_gpio_constants[] = {
{ "TELEINFO_RX", (int32_t) GPIO_TELEINFO_RX },
{ "TFMINIPLUS_RX", (int32_t) GPIO_TFMINIPLUS_RX },
{ "TFMINIPLUS_TX", (int32_t) GPIO_TFMINIPLUS_TX },
{ "TM1621_CS", (int32_t) GPIO_TM1621_CS },
{ "TM1621_DAT", (int32_t) GPIO_TM1621_DAT },
{ "TM1621_RD", (int32_t) GPIO_TM1621_RD },
{ "TM1621_WR", (int32_t) GPIO_TM1621_WR },
{ "TM1637CLK", (int32_t) GPIO_TM1637CLK },
{ "TM1637DIO", (int32_t) GPIO_TM1637DIO },
{ "TM1638CLK", (int32_t) GPIO_TM1638CLK },
@ -300,8 +319,6 @@ const be_const_member_t lv_gpio_constants[] = {
{ "ZIGBEE_RST", (int32_t) GPIO_ZIGBEE_RST },
{ "ZIGBEE_RX", (int32_t) GPIO_ZIGBEE_RX },
{ "ZIGBEE_TX", (int32_t) GPIO_ZIGBEE_TX },
{ "MBR_RX", (int32_t) GPIO_MBR_RX },
{ "MBR_TX", (int32_t) GPIO_MBR_TX },
};

View File

@ -1,257 +0,0 @@
gpio = module('gpio')
#- HIGH/LOW -#
gpio.LOW = 0
gpio.HIGH = 1
#- GPIO states -#
gpio.INPUT = 1
gpio.OUTPUT = 2
gpio.PULLUP = 4
gpio.INPUT_PULLUP = 5
gpio.PULLDOWN = 8
gpio.OPEN_DRAIN = 16
gpio.OUTPUT_OPEN_DRAIN = 18
#- Interrupt trigger -#
gpio.RISING = 1
gpio.FALLING = 2
gpio.CHANGE = 4
#- Tasmota GPIOs -#
gpio.NONE = 0
gpio.KEY1 = 1
gpio.KEY1_NP = 2
gpio.KEY1_INV = 3
gpio.KEY1_INV_NP = 4
gpio.SWT1 = 5
gpio.SWT1_NP = 6
gpio.REL1 = 7
gpio.REL1_INV = 8
gpio.LED1 = 9
gpio.LED1_INV = 10
gpio.CNTR1 = 11
gpio.CNTR1_NP = 12
gpio.PWM1 = 13
gpio.PWM1_INV = 14
gpio.BUZZER = 15
gpio.BUZZER_INV = 16
gpio.LEDLNK = 17
gpio.LEDLNK_INV = 18
gpio.I2C_SCL = 19
gpio.I2C_SDA = 20
gpio.SPI_MISO = 21
gpio.SPI_MOSI = 22
gpio.SPI_CLK = 23
gpio.SPI_CS = 24
gpio.SPI_DC = 25
gpio.SSPI_MISO = 26
gpio.SSPI_MOSI = 27
gpio.SSPI_SCLK = 28
gpio.SSPI_CS = 29
gpio.SSPI_DC = 30
gpio.BACKLIGHT = 31
gpio.OLED_RESET = 32
gpio.IRSEND = 33
gpio.IRRECV = 34
gpio.RFSEND = 35
gpio.RFRECV = 36
gpio.DHT11 = 37
gpio.DHT22 = 38
gpio.SI7021 = 39
gpio.DHT11_OUT = 40
gpio.DSB = 41
gpio.DSB_OUT = 42
gpio.WS2812 = 43
gpio.MHZ_TXD = 44
gpio.MHZ_RXD = 45
gpio.PZEM0XX_TX = 46
gpio.PZEM004_RX = 47
gpio.PZEM016_RX = 48
gpio.PZEM017_RX = 49
gpio.SAIR_TX = 50
gpio.SAIR_RX = 51
gpio.PMS5003_TX = 52
gpio.PMS5003_RX = 53
gpio.SDS0X1_TX = 54
gpio.SDS0X1_RX = 55
gpio.SBR_TX = 56
gpio.SBR_RX = 57
gpio.SR04_TRIG = 58
gpio.SR04_ECHO = 59
gpio.SDM120_TX = 60
gpio.SDM120_RX = 61
gpio.SDM630_TX = 62
gpio.SDM630_RX = 63
gpio.TM1638CLK = 64
gpio.TM1638DIO = 65
gpio.TM1638STB = 66
gpio.MP3_DFR562 = 67
gpio.HX711_SCK = 68
gpio.HX711_DAT = 69
gpio.TX2X_TXD_BLACK = 70
gpio.TUYA_TX = 71
gpio.TUYA_RX = 72
gpio.MGC3130_XFER = 73
gpio.MGC3130_RESET = 74
gpio.RF_SENSOR = 75
gpio.AZ_TXD = 76
gpio.AZ_RXD = 77
gpio.MAX31855CS = 78
gpio.MAX31855CLK = 79
gpio.MAX31855DO = 80
gpio.NRG_SEL = 81
gpio.NRG_SEL_INV = 82
gpio.NRG_CF1 = 83
gpio.HLW_CF = 84
gpio.HJL_CF = 85
gpio.MCP39F5_TX = 86
gpio.MCP39F5_RX = 87
gpio.MCP39F5_RST = 88
gpio.PN532_TXD = 89
gpio.PN532_RXD = 90
gpio.SM16716_CLK = 91
gpio.SM16716_DAT = 92
gpio.SM16716_SEL = 93
gpio.DI = 94
gpio.DCKI = 95
gpio.CSE7766_TX = 96
gpio.CSE7766_RX = 97
gpio.ARIRFRCV = 98
gpio.ARIRFSEL = 99
gpio.TXD = 100
gpio.RXD = 101
gpio.ROT1A = 102
gpio.ROT1B = 103
gpio.ADC_JOY = 104
gpio.SSPI_MAX31865_CS1 = 105
gpio.HRE_CLOCK = 106
gpio.HRE_DATA = 107
gpio.ADE7953_IRQ = 108
gpio.SOLAXX1_TX = 109
gpio.SOLAXX1_RX = 110
gpio.ZIGBEE_TX = 111
gpio.ZIGBEE_RX = 112
gpio.RDM6300_RX = 113
gpio.IBEACON_TX = 114
gpio.IBEACON_RX = 115
gpio.A4988_DIR = 116
gpio.A4988_STP = 117
gpio.A4988_ENA = 118
gpio.A4988_MS1 = 119
gpio.OUTPUT_HI = 120
gpio.OUTPUT_LO = 121
gpio.DDS2382_TX = 122
gpio.DDS2382_RX = 123
gpio.DDSU666_TX = 124
gpio.DDSU666_RX = 125
gpio.SM2135_CLK = 126
gpio.SM2135_DAT = 127
gpio.DEEPSLEEP = 128
gpio.EXS_ENABLE = 129
gpio.TASMOTACLIENT_TXD = 130
gpio.TASMOTACLIENT_RXD = 131
gpio.TASMOTACLIENT_RST = 132
gpio.TASMOTACLIENT_RST_INV = 133
gpio.HPMA_RX = 134
gpio.HPMA_TX = 135
gpio.GPS_RX = 136
gpio.GPS_TX = 137
gpio.HM10_RX = 138
gpio.HM10_TX = 139
gpio.LE01MR_RX = 140
gpio.LE01MR_TX = 141
gpio.CC1101_GDO0 = 142
gpio.CC1101_GDO2 = 143
gpio.HRXL_RX = 144
gpio.ELECTRIQ_MOODL_TX = 145
gpio.AS3935 = 146
gpio.ADC_INPUT = 147
gpio.ADC_TEMP = 148
gpio.ADC_LIGHT = 149
gpio.ADC_BUTTON = 150
gpio.ADC_BUTTON_INV = 151
gpio.ADC_RANGE = 152
gpio.ADC_CT_POWER = 153
gpio.WEBCAM_PWDN = 154
gpio.WEBCAM_RESET = 155
gpio.WEBCAM_XCLK = 156
gpio.WEBCAM_SIOD = 157
gpio.WEBCAM_SIOC = 158
gpio.WEBCAM_DATA = 159
gpio.WEBCAM_VSYNC = 160
gpio.WEBCAM_HREF = 161
gpio.WEBCAM_PCLK = 162
gpio.WEBCAM_PSCLK = 163
gpio.WEBCAM_HSD = 164
gpio.WEBCAM_PSRCS = 165
gpio.BOILER_OT_RX = 166
gpio.BOILER_OT_TX = 167
gpio.WINDMETER_SPEED = 168
gpio.KEY1_TC = 169
gpio.BL0940_RX = 170
gpio.TCP_TX = 171
gpio.TCP_RX = 172
gpio.ETH_PHY_POWER = 173
gpio.ETH_PHY_MDC = 174
gpio.ETH_PHY_MDIO = 175
gpio.TELEINFO_RX = 176
gpio.TELEINFO_ENABLE = 177
gpio.LMT01 = 178
gpio.IEM3000_TX = 179
gpio.IEM3000_RX = 180
gpio.ZIGBEE_RST = 181
gpio.DYP_RX = 182
gpio.MIEL_HVAC_TX = 183
gpio.MIEL_HVAC_RX = 184
gpio.WE517_TX = 185
gpio.WE517_RX = 186
gpio.AS608_TX = 187
gpio.AS608_RX = 188
gpio.SHELLY_DIMMER_BOOT0 = 189
gpio.SHELLY_DIMMER_RST_INV = 190
gpio.RC522_RST = 191
gpio.P9813_CLK = 192
gpio.P9813_DAT = 193
gpio.OPTION_A = 194
gpio.FTC532 = 195
gpio.RC522_CS = 196
gpio.NRF24_CS = 197
gpio.NRF24_DC = 198
gpio.ILI9341_CS = 199
gpio.ILI9341_DC = 200
gpio.ILI9488_CS = 201
gpio.EPAPER29_CS = 202
gpio.EPAPER42_CS = 203
gpio.SSD1351_CS = 204
gpio.RA8876_CS = 205
gpio.ST7789_CS = 206
gpio.ST7789_DC = 207
gpio.SSD1331_CS = 208
gpio.SSD1331_DC = 209
gpio.SDCARD_CS = 210
gpio.ROT1A_NP = 211
gpio.ROT1B_NP = 212
gpio.ADC_PH = 213
gpio.BS814_CLK = 214
gpio.BS814_DAT = 215
gpio.WIEGAND_D0 = 216
gpio.WIEGAND_D1 = 217
gpio.NEOPOOL_TX = 218
gpio.NEOPOOL_RX = 219
gpio.SDM72_TX = 220
gpio.SDM72_RX = 221
gpio.TM1637CLK = 222
gpio.TM1637DIO = 223
gpio.PROJECTOR_CTRL_TX = 224
gpio.PROJECTOR_CTRL_RX = 225
gpio.SSD1351_DC = 226
gpio.XPT2046_CS = 227
gpio.CSE7761_TX = 228
gpio.CSE7761_RX = 229
gpio.VL53LXX_XSHUT1 = 230
gpio.MAX7219CLK = 231
gpio.MAX7219DIN = 232
gpio.MAX7219CS = 233
gpio.TFMINIPLUS_TX = 234
gpio.TFMINIPLUS_RX = 235
gpio.ZEROCROSS = 236
gpio.HALLEFFECT = 237
gpio.SENSOR_END = 238
gpio.ADC_MQ = 239

View File

@ -1,4 +1,7 @@
# TouchScreen calibration
#
# rm DisplayCalibrate.tapp; zip -j -0 DisplayCalibrate.tapp ts_calibrate/*
#
var ts_calibrate = module("ts_calibrate")
ts_calibrate.init = def (m)
@ -104,8 +107,8 @@ ts_calibrate.init = def (m)
end
# draw cross
def draw_cross(x, y, size)
var sz2 = size / 2
def draw_cross(x, y, sz)
var sz2 = sz / 2
self.p1.x = x - sz2
self.p1.y = y
self.p2.x = x + sz2

View File

@ -382,7 +382,7 @@ enum XsnsFunctions {FUNC_SETTINGS_OVERRIDE, FUNC_PIN_STATE, FUNC_I2C_INIT, FUNC_
FUNC_SAVE_SETTINGS, FUNC_SAVE_AT_MIDNIGHT, FUNC_SAVE_BEFORE_RESTART,
FUNC_AFTER_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_SENSOR, FUNC_WEB_COL_SENSOR, FUNC_COMMAND, FUNC_COMMAND_SENSOR, FUNC_COMMAND_DRIVER,
FUNC_MQTT_SUBSCRIBE, FUNC_MQTT_INIT, FUNC_MQTT_DATA,
FUNC_SET_POWER, FUNC_SET_DEVICE_POWER, FUNC_SHOW_SENSOR, FUNC_ANY_KEY,
FUNC_SET_POWER, FUNC_SET_DEVICE_POWER, FUNC_SHOW_SENSOR, FUNC_ANY_KEY, FUNC_LED_LINK,
FUNC_ENERGY_EVERY_SECOND, FUNC_ENERGY_RESET,
FUNC_RULES_PROCESS, FUNC_TELEPERIOD_RULES_PROCESS, FUNC_SERIAL, FUNC_FREE_MEM, FUNC_BUTTON_PRESSED, FUNC_BUTTON_MULTI_PRESSED,
FUNC_WEB_ADD_BUTTON, FUNC_WEB_ADD_CONSOLE_BUTTON, FUNC_WEB_ADD_MANAGEMENT_BUTTON, FUNC_WEB_ADD_MAIN_BUTTON,

View File

@ -642,6 +642,7 @@
//#define USE_RC522 // Add support for MFRC522 13.56Mhz Rfid reader (+6k code)
//#define USE_MCP2515 // Add support for can bus using MCP2515 (+7k code)
//#define USE_CANSNIFFER // Add support for can bus sniffer using MCP2515 (+5k code)
#define USE_SHELLY_PRO // Add support for Shelly Pro
#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code)
#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code)

View File

@ -208,7 +208,7 @@ enum ProgramSelectablePins {
GPIO_USER, // User configurable needs to be 2047
GPIO_MAX };
#define MAX_OPTIONS_A 6 // Increase if more bits are used from GpioOptionABits
#define MAX_OPTIONS_A 7 // Increase if more bits are used from GpioOptionABits
typedef union { // Restricted by MISRA-C Rule 18.4 but so useful...
uint32_t data; // Allow bit manipulation using SetOption
@ -219,7 +219,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
uint32_t enable_ccloader : 1; // bit 3 (v9.4.0.5) - Option_A4 - (Zigbee) Enable CCLoader using Zigbee Rx/Tx/Rst Gpios
uint32_t rotary_mi_desk : 1; // bit 4 (v9.5.0.5) - Option_A5 - (Rotary) Enable Mi Desk emulation
uint32_t linkind_support : 1; // bit 5 (v10.1.0.4) - Option_A6 - (Light) LinkInd support
uint32_t spare06 : 1; // bit 6
uint32_t shelly_pro : 1; // bit 6 (v12.2.0.1) - Option_A7 - (Device) Shelly Pro
uint32_t spare07 : 1; // bit 7
uint32_t spare08 : 1; // bit 8
uint32_t spare09 : 1; // bit 9

View File

@ -549,10 +549,9 @@ typedef struct {
uint32_t energy_power_calibration; // 364
uint32_t energy_voltage_calibration; // 368
uint32_t energy_current_calibration; // 36C
uint32_t ex_energy_kWhtoday; // 370
uint32_t ex_energy_kWhyesterday; // 374
uint16_t energy_kWhdoy; // 378
uint16_t energy_min_power; // 37A
uint32_t energy_power_calibration2; // 370 - ex_energy_kWhtoday
uint32_t energy_voltage_calibration2; // 374 - ex_energy_kWhyesterday
uint32_t energy_current_calibration2; // 378 - ex_energy_kWhdoy, ex_energy_min_power
uint16_t energy_max_power; // 37C
uint16_t energy_min_voltage; // 37E
uint16_t energy_max_voltage; // 380
@ -573,8 +572,10 @@ typedef struct {
uint16_t blinkcount; // 39C
uint16_t light_rotation; // 39E
SOBitfield3 flag3; // 3A0
uint16_t energy_kWhdoy; // 3A4
uint16_t energy_min_power; // 3A6
uint8_t ex_switchmode[8]; // 3A4 - Free since 9.2.0.6
uint8_t free_3A8[4]; // 3A8 - ex_switchmode4-7, Free since 9.2.0.6
#ifdef CONFIG_IDF_TARGET_ESP32S3
// ------------------------------------

View File

@ -20,6 +20,6 @@
#ifndef _TASMOTA_VERSION_H_
#define _TASMOTA_VERSION_H_
const uint32_t VERSION = 0x0C020001; // 12.2.0.1
const uint32_t VERSION = 0x0C020002; // 12.2.0.2
#endif // _TASMOTA_VERSION_H_

View File

@ -559,6 +559,7 @@ void setup(void) {
bitWrite(Settings->rule_enabled, i, 0); // Disable rules causing boot loop
}
}
Settings->flag4.network_wifi = 1; // Enable wifi if disabled
}
if (RtcReboot.fast_reboot_count > Settings->param[P_BOOT_LOOP_OFFSET] +2) { // Restarted 4 times
Settings->rule_enabled = 0; // Disable all rules

View File

@ -45,7 +45,7 @@ void RtcSettingsSave(void) {
if (RTC_MEM_VALID != RtcSettings.valid) {
memset(&RtcSettings, 0, sizeof(RtcSettings));
RtcSettings.valid = RTC_MEM_VALID;
// RtcSettings.ex_energy_kWhtoday = Settings->ex_energy_kWhtoday;
// RtcSettings.ex_energy_kWhtoday = Settings->energy_power_calibration2;
// RtcSettings.ex_energy_kWhtotal = Settings->ex_energy_kWhtotal;
for (uint32_t i = 0; i < 3; i++) {
RtcSettings.energy_kWhtoday_ph[i] = Settings->energy_kWhtoday_ph[i];
@ -1046,6 +1046,9 @@ void SettingsDefaultSet2(void) {
Settings->energy_power_calibration = HLW_PREF_PULSE;
Settings->energy_voltage_calibration = HLW_UREF_PULSE;
Settings->energy_current_calibration = HLW_IREF_PULSE;
Settings->energy_power_calibration2 = HLW_PREF_PULSE;
Settings->energy_voltage_calibration2 = HLW_UREF_PULSE;
Settings->energy_current_calibration2 = HLW_IREF_PULSE;
// Settings->energy_kWhtoday_ph[0] = 0;
// Settings->energy_kWhtoday_ph[1] = 0;
// Settings->energy_kWhtoday_ph[2] = 0;
@ -1468,7 +1471,7 @@ void SettingsDelta(void) {
}
if (Settings->version < 0x09020006) {
for (uint32_t i = 0; i < MAX_SWITCHES_SET; i++) {
Settings->switchmode[i] = (i < 8) ? Settings->ex_switchmode[i] : SWITCH_MODE;
Settings->switchmode[i] = SWITCH_MODE;
}
for (uint32_t i = 0; i < MAX_INTERLOCKS_SET; i++) {
Settings->interlock[i] = (i < 4) ? Settings->ds3502_state[i] : 0;
@ -1532,8 +1535,8 @@ void SettingsDelta(void) {
memset(&Settings->energy_kWhtoday_ph, 0, 36);
memset(&RtcSettings.energy_kWhtoday_ph, 0, 24);
Settings->energy_kWhtotal_ph[0] = Settings->ex_energy_kWhtotal;
Settings->energy_kWhtoday_ph[0] = Settings->ex_energy_kWhtoday;
Settings->energy_kWhyesterday_ph[0] = Settings->ex_energy_kWhyesterday;
Settings->energy_kWhtoday_ph[0] = Settings->energy_power_calibration2;
Settings->energy_kWhyesterday_ph[0] = Settings->energy_voltage_calibration2;
RtcSettings.energy_kWhtoday_ph[0] = RtcSettings.ex_energy_kWhtoday;
RtcSettings.energy_kWhtotal_ph[0] = RtcSettings.ex_energy_kWhtotal;
}
@ -1598,6 +1601,13 @@ void SettingsDelta(void) {
Settings->webcam_clk = 20;
}
#endif // ESP32
if (Settings->version < 0x0C020002) { // 12.2.0.2
Settings->energy_kWhdoy = Settings->energy_current_calibration2 & 0xFFFF;
Settings->energy_min_power = (Settings->energy_current_calibration2 >> 16) & 0xFFFF;
Settings->energy_power_calibration2 = Settings->energy_power_calibration;
Settings->energy_voltage_calibration2 = Settings->energy_voltage_calibration;
Settings->energy_current_calibration2 = Settings->energy_current_calibration;
}
Settings->version = VERSION;
SettingsSave(1);

View File

@ -473,6 +473,11 @@ void ButtonHandler(void) {
valid_relay = (Button.press_counter[button_index] <= TasmotaGlobal.devices_present);
}
#endif // ESP8266
#ifdef USE_SHELLY_PRO
if (TasmotaGlobal.gpio_optiona.shelly_pro) {
valid_relay = (Button.press_counter[button_index] <= TasmotaGlobal.devices_present);
}
#endif // USE_SHELLY_PRO
if ((Button.press_counter[button_index] > 1) && valid_relay && (Button.press_counter[button_index] <= MAX_RELAY_BUTTON1)) {
ExecuteCommandPower(button_index + Button.press_counter[button_index], POWER_TOGGLE, SRC_BUTTON); // Execute Toggle command internally
// AddLog(LOG_LEVEL_DEBUG, PSTR("BTN: Relay%d found on GPIO%d"), Button.press_counter[button_index], Pin(GPIO_REL1, Button.press_counter[button_index]-1));

View File

@ -517,8 +517,13 @@ void SetLedPowerAll(uint32_t state)
}
}
void SetLedLink(uint32_t state)
{
void SetLedLink(uint32_t state) {
#ifdef ESP32
uint32_t index = XdrvMailbox.index;
XdrvMailbox.index = state;
XdrvCall(FUNC_LED_LINK);
XdrvMailbox.index = index;
#endif // ESP32
int led_pin = Pin(GPIO_LEDLNK);
uint32_t led_inv = TasmotaGlobal.ledlnk_inverted;
if (-1 == led_pin) { // Legacy - LED1 is status

View File

@ -1036,6 +1036,9 @@ void CmndMaxEnergyStart(void) {
void EnergyDrvInit(void) {
memset(&Energy, 0, sizeof(Energy)); // Reset all to 0 and false;
// Energy.voltage_common = false;
// Energy.frequency_common = false;
// Energy.use_overtemp = false;
for (uint32_t phase = 0; phase < ENERGY_MAX_PHASES; phase++) {
Energy.apparent_power[phase] = NAN;
Energy.reactive_power[phase] = NAN;

View File

@ -325,6 +325,19 @@ extern "C" {
be_raise(vm, kTypeError, nullptr);
}
// Berry: tasmota.delay_microseconds(timer:int) -> nil
//
int32_t l_delay_microseconds(struct bvm *vm);
int32_t l_delay_microseconds(struct bvm *vm) {
int32_t top = be_top(vm); // Get the number of arguments
if (top == 2 && be_isint(vm, 2)) { // only 1 argument of type string accepted
uint32_t timer = be_toint(vm, 2);
delayMicroseconds(timer);
be_return_nil(vm); // Return
}
be_raise(vm, kTypeError, nullptr);
}
// Berry: `yield() -> nil`
// ESP object
int32_t l_yield(bvm *vm);

View File

@ -0,0 +1,172 @@
/*
xdrv_88_shelly_pro.ino - Shelly pro family support for Tasmota
Copyright (C) 2022 Theo Arends
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef ESP32
#ifdef USE_SPI
#ifdef USE_SHELLY_PRO
/*********************************************************************************************\
* Shelly Pro support
*
* {"NAME":"Shelly Pro 1","GPIO":[0,1,0,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}
* {"NAME":"Shelly Pro 1PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3459,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}
* {"NAME":"Shelly Pro 2","GPIO":[0,1,0,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,0,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350;AdcParam2 2,10000,10000,3350"}
* {"NAME":"Shelly Pro 2PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,9569,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3460,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350;AdcParam2 2,10000,10000,3350"}
*
* Shelly Pro uses SPI to control one 74HC595 for relays/leds and one ADE7953 (1PM) or two ADE7953 (2PM) for energy monitoring
\*********************************************************************************************/
#define XDRV_88 88
struct SPro {
uint32_t last_update;
uint8_t pin_shift595_rclk;
uint8_t ledlink;
uint8_t power;
bool detected;
} SPro;
void ShellyProUpdate(void) {
// Shelly Pro 595 register
// bit 0 = relay/led 1
// bit 1 = relay/led 2
// bit 2 = wifi led blue
// bit 3 = wifi led green
// bit 4 = wifi led red
// bit 5 - 7 = nc
uint32_t val = SPro.power | SPro.ledlink;
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
SPI.transfer(val); // Write 74HC595 shift register
SPI.endTransaction();
delayMicroseconds(2); // Wait for SPI clock to stop
digitalWrite(SPro.pin_shift595_rclk, 1); // Latch data
delayMicroseconds(2); // Shelly 10mS
digitalWrite(SPro.pin_shift595_rclk, 0);
}
void ShellyProPreInit(void) {
if ((SPI_MOSI_MISO == TasmotaGlobal.spi_enabled) &&
PinUsed(GPIO_SPI_CS) &&
TasmotaGlobal.gpio_optiona.shelly_pro) { // Option_A7
if (PinUsed(GPIO_SWT1)) {
TasmotaGlobal.devices_present++; // Shelly Pro 1
if (PinUsed(GPIO_SWT1, 1)) {
TasmotaGlobal.devices_present++; // Shelly Pro 2
}
SPro.pin_shift595_rclk = Pin(GPIO_SPI_CS);
digitalWrite(SPro.pin_shift595_rclk, 0);
pinMode(SPro.pin_shift595_rclk, OUTPUT);
// Does nothing if SPI is already initiated (by ADE7953) so no harm done
SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
SPro.power = TasmotaGlobal.power &3; // Restore power
SPro.ledlink = 0x18; // Blue led on
ShellyProUpdate();
SPro.detected = true;
}
}
}
void ShellyProInit(void) {
int pin_lan_reset = 5; // GPIO5 = LAN8720 nRST
// delay(30); // (t-purstd) This pin must be brought low for a minimum of 25 mS after power on
digitalWrite(pin_lan_reset, 0);
pinMode(pin_lan_reset, OUTPUT);
delay(1); // (t-rstia) This pin must be brought low for a minimum of 100 uS
digitalWrite(pin_lan_reset, 1);
AddLog(LOG_LEVEL_INFO, PSTR("HDW: Shelly Pro %d%s initialized"),
TasmotaGlobal.devices_present, (PinUsed(GPIO_ADE7953_CS))?"PM":"");
}
void ShellyProPower(void) {
SPro.power = XdrvMailbox.index &3;
ShellyProUpdate();
}
void ShellyProUpdateLedLink(uint32_t ledlink) {
if (ledlink != SPro.ledlink) {
SPro.ledlink = ledlink;
ShellyProUpdate();
}
}
void ShellyProLedLink(void) {
/*
bit 2 = blue, 3 = green, 4 = red
Shelly Pro documentation
- Blue light indicator will be on if in AP mode.
- Red light indicator will be on if in STA mode and not connected to a Wi-Fi network.
- Yellow light indicator will be on if in STA mode and connected to a Wi-Fi network.
- Green light indicator will be on if in STA mode and connected to a Wi-Fi network and to the Shelly Cloud.
- The light indicator will be flashing Red/Blue if OTA update is in progress.
Tasmota behaviour
- Blue light indicator will blink if no wifi or mqtt.
- Green light indicator will be on if in STA mode and connected to a Wi-Fi network.
*/
SPro.last_update = TasmotaGlobal.uptime;
uint32_t ledlink = 0x1C; // All leds off
if (XdrvMailbox.index) { ledlink &= 0xFB; } // Blue blinks if wifi/mqtt lost
if (!TasmotaGlobal.global_state.wifi_down) { ledlink &= 0xF7; } // Green On
ShellyProUpdateLedLink(ledlink);
}
void ShellyProLedLinkWifiOff(void) {
/*
bit 2 = blue, 3 = green, 4 = red
- Green light indicator will be on if in STA mode and connected to a Wi-Fi network.
*/
if (SPro.last_update +1 < TasmotaGlobal.uptime) {
ShellyProUpdateLedLink((TasmotaGlobal.global_state.wifi_down) ? 0x1C : 0x14); // Green off if wifi OFF
}
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
bool Xdrv88(uint8_t function) {
bool result = false;
if (FUNC_PRE_INIT == function) {
ShellyProPreInit();
} else if (SPro.detected) {
switch (function) {
case FUNC_EVERY_SECOND:
ShellyProLedLinkWifiOff();
break;
case FUNC_SET_POWER:
ShellyProPower();
break;
case FUNC_LED_LINK:
ShellyProLedLink();
break;
case FUNC_INIT:
ShellyProInit();
break;
}
}
return result;
}
#endif // USE_SHELLY_PRO
#endif // USE_SPI
#endif // ESP32

View File

@ -17,29 +17,40 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_I2C
#if defined(ESP32) && defined(USE_SPI)
#define USE_ESP32_SPI
#endif
#if defined(USE_I2C) || defined(USE_ESP32_SPI)
#ifdef USE_ENERGY_SENSOR
#ifdef USE_ADE7953
/*********************************************************************************************\
* ADE7953 - Energy used in Shelly 2.5 (model 1), Shelly EM (model 2) and Shelly Plus 2PM (model 3)
* ADE7953 - Energy used in Shelly 2.5 (model 1), Shelly EM (model 2), Shelly Plus 2PM (model 3), Shelly Pro 1PM (model 4) and Shelly Pro 2PM (model 5)
*
* {"NAME":"Shelly 2.5","GPIO":[320,0,32,0,224,193,0,0,640,192,608,225,3456,4736],"FLAG":0,"BASE":18}
* {"NAME":"Shelly EM","GPIO":[0,0,0,0,0,0,0,0,640,3457,608,224,8832,1],"FLAG":0,"BASE":18}
* {"NAME":"Shelly Plus 2PM PCB v0.1.5","GPIO":[320,0,192,0,0,0,1,1,225,224,0,0,0,0,193,0,0,0,0,0,0,608,3840,32,0,0,0,0,0,640,0,0,3458,4736,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,32000,40000,3350"}
* {"NAME":"Shelly Plus 2PM PCB v0.1.9","GPIO":[320,0,0,0,32,192,0,0,225,224,0,0,0,0,193,0,0,0,0,0,0,608,640,3458,0,0,0,0,0,9472,0,4736,0,0,0,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}
* {"NAME":"Shelly Pro 1PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,0,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3459,0,0,32,4736,0,160,0],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350"}
* {"NAME":"Shelly Pro 2PM","GPIO":[9568,1,9472,1,768,0,0,0,672,704,736,9569,0,0,5600,6214,0,0,0,5568,0,0,0,0,0,0,0,0,3460,0,0,32,4736,4737,160,161],"FLAG":0,"BASE":1,"CMND":"AdcParam1 2,10000,10000,3350;AdcParam2 2,10000,10000,3350"}
*
* Based on datasheet from https://www.analog.com/en/products/ade7953.html
*
* Model differences:
* Function Model1 Model2 Model3 Remark
* ------------------------------ ------ ------ ------- -------------------------------------------------
* Shelly 2.5 EM Plus2PM
* Current measurement device shunt CT shunt CT = Current Transformer
* Swapped channel A/B Yes No No Defined by hardware design - Fixed by Tasmota
* Support Export Active No Yes No Only EM supports correct negative value detection
* Show negative (reactive) power No Yes No Only EM supports correct negative value detection
* Default phase calibration 0 200 0 CT needs different phase calibration than shunts
* Default reset pin on ESP8266 - 16 - Legacy support. Replaced by GPIO ADE7953RST
* Function Model1 Model2 Model3 Model4 Model5 Remark
* ------------------------------ ------- ------- ------- ------ ------ -------------------------------------------------
* Shelly 2.5 EM Plus2PM Pro1PM Pro2PM
* Processor ESP8266 ESP8266 ESP32 ESP32 ESP32
* Interface I2C I2C I2C SPI SPI Interface type used
* Number of ADE9753 chips 1 1 1 1 2 Count of ADE9753 chips
* ADE9753 IRQ 1 2 3 4 5 Index defines model number
* Current measurement device shunt CT shunt shunt shunt CT = Current Transformer
* Common voltage Yes Yes Yes No No Show common voltage in GUI/JSON
* Common frequency Yes Yes Yes No No Show common frequency in GUI/JSON
* Swapped channel A/B Yes No No No No Defined by hardware design - Fixed by Tasmota
* Support Export Active No Yes No No No Only EM supports correct negative value detection
* Show negative (reactive) power No Yes No No No Only EM supports correct negative value detection
* Default phase calibration 0 200 0 0 0 CT needs different phase calibration than shunts
* Default reset pin on ESP8266 - 16 - - - Legacy support. Replaced by GPIO ADE7953RST
*
* I2C Address: 0x38
*********************************************************************************************
@ -66,11 +77,10 @@
// Default calibration parameters can be overridden by a rule as documented above.
#define ADE7953_GAIN_DEFAULT 4194304 // = 0x400000 range 2097152 (min) to 6291456 (max)
#define ADE7953_PHCAL_DEFAULT 0 // = range -383 to 383 - Default phase calibration for Shunts
#define ADE7953_PHCAL_DEFAULT_CT 200 // = range -383 to 383 - Default phase calibration for Current Transformers (Shelly EM)
enum Ade7953Models { ADE7953_SHELLY_25, ADE7953_SHELLY_EM, ADE7953_SHELLY_PLUS_2PM };
enum Ade7953Models { ADE7953_SHELLY_25, ADE7953_SHELLY_EM, ADE7953_SHELLY_PLUS_2PM, ADE7953_SHELLY_PRO_1PM, ADE7953_SHELLY_PRO_2PM };
enum Ade7953_8BitRegisters {
// Register Name Addres R/W Bt Ty Default Description
@ -175,57 +185,38 @@ enum Ade7953_32BitRegisters {
};
enum Ade7953CalibrationRegisters {
ADE7953_CAL_AVGAIN,
ADE7953_CAL_BVGAIN,
ADE7953_CAL_AIGAIN,
ADE7953_CAL_BIGAIN,
ADE7953_CAL_AWGAIN,
ADE7953_CAL_BWGAIN,
ADE7953_CAL_AVAGAIN,
ADE7953_CAL_BVAGAIN,
ADE7953_CAL_AVARGAIN,
ADE7953_CAL_BVARGAIN,
ADE7943_CAL_PHCALA,
ADE7943_CAL_PHCALB
ADE7953_CAL_VGAIN,
ADE7953_CAL_IGAIN,
ADE7953_CAL_WGAIN,
ADE7953_CAL_VAGAIN,
ADE7953_CAL_VARGAIN,
ADE7943_CAL_PHCAL
};
const uint16_t Ade7953CalibRegs[] {
ADE7953_AVGAIN,
ADE7953_BVGAIN,
ADE7953_AIGAIN,
ADE7953_BIGAIN,
ADE7953_AWGAIN,
ADE7953_BWGAIN,
ADE7953_AVAGAIN,
ADE7953_BVAGAIN,
ADE7953_AVARGAIN,
ADE7953_BVARGAIN,
ADE7943_PHCALA,
ADE7943_PHCALB
const uint8_t ADE7953_CALIBREGS = 6;
const uint16_t Ade7953CalibRegs[2][ADE7953_CALIBREGS] {
{ ADE7953_AVGAIN, ADE7953_AIGAIN, ADE7953_AWGAIN, ADE7953_AVAGAIN, ADE7953_AVARGAIN, ADE7943_PHCALA },
{ ADE7953_BVGAIN, ADE7953_BIGAIN, ADE7953_BWGAIN, ADE7953_BVAGAIN, ADE7953_BVARGAIN, ADE7943_PHCALB }
};
const uint16_t Ade7953Registers[] {
ADE7953_IRMSA, // IRMSA - RMS current channel A
ADE7953_AWATT, // AWATT - Active power channel A
ADE7953_AVA, // AVA - Apparent power channel A
ADE7953_AVAR, // AVAR - Reactive power channel A
ADE7953_IRMSB, // IRMSB - RMS current channel B
ADE7953_BWATT, // BWATT - Active power channel B
ADE7953_BVA, // BVA - Apparent power channel B
ADE7953_BVAR, // BVAR - Reactive power channel B
ADE7953_VRMS, // VRMS - RMS voltage (Both channels)
ADE7943_Period, // Period - 16-bit unsigned period register
ADE7953_ACCMODE // ACCMODE - Accumulation mode
const uint8_t ADE7953_REGISTERS = 6;
const uint16_t Ade7953Registers[2][ADE7953_REGISTERS] {
{ ADE7953_IRMSA, ADE7953_AWATT, ADE7953_AVA, ADE7953_AVAR, ADE7953_VRMS, ADE7943_Period },
{ ADE7953_IRMSB, ADE7953_BWATT, ADE7953_BVA, ADE7953_BVAR, ADE7953_VRMS, ADE7943_Period }
};
struct Ade7953 {
uint32_t voltage_rms = 0;
uint32_t period = 0;
uint32_t voltage_rms[2] = { 0, 0 };
uint32_t current_rms[2] = { 0, 0 };
uint32_t active_power[2] = { 0, 0 };
int32_t calib_data[sizeof(Ade7953CalibRegs)/sizeof(uint16_t)];
int32_t calib_data[2][ADE7953_CALIBREGS];
uint8_t init_step = 0;
uint8_t model = 0; // 0 = Shelly 2.5, 1 = Shelly EM, 2 = Shelly Plus 2PM
uint8_t model = 0; // 0 = Shelly 2.5, 1 = Shelly EM, 2 = Shelly Plus 2PM, 3 = Shelly Pro 1PM, 4 = Shelly Pro 2PM
uint8_t cs_index;
#ifdef USE_ESP32_SPI
SPISettings spi_settings;
int8_t pin_cs[2];
#endif // USE_ESP32_SPI
} Ade7953;
int Ade7953RegSize(uint16_t reg) {
@ -248,6 +239,24 @@ int Ade7953RegSize(uint16_t reg) {
void Ade7953Write(uint16_t reg, uint32_t val) {
int size = Ade7953RegSize(reg);
if (size) {
// AddLog(LOG_LEVEL_DEBUG, PSTR("DBG: Write %08X"), val);
#ifdef USE_ESP32_SPI
if (Ade7953.pin_cs[0] >= 0) {
digitalWrite(Ade7953.pin_cs[Ade7953.cs_index], 0);
delayMicroseconds(1); // CS 1uS to SCLK edge
SPI.beginTransaction(Ade7953.spi_settings);
SPI.transfer16(reg);
SPI.transfer(0x00); // Write
while (size--) {
SPI.transfer((val >> (8 * size)) & 0xFF); // Write data, MSB first
}
SPI.endTransaction();
delayMicroseconds(2); // CS high 1.2uS after SCLK edge (when writing to COMM_LOCK bit)
digitalWrite(Ade7953.pin_cs[Ade7953.cs_index], 1);
} else {
#endif // USE_ESP32_SPI
Wire.beginTransmission(ADE7953_ADDR);
Wire.write((reg >> 8) & 0xFF);
Wire.write(reg & 0xFF);
@ -256,6 +265,9 @@ void Ade7953Write(uint16_t reg, uint32_t val) {
}
Wire.endTransmission();
delayMicroseconds(5); // Bus-free time minimum 4.7us
#ifdef USE_ESP32_SPI
}
#endif // USE_ESP32_SPI
}
}
@ -264,6 +276,20 @@ int32_t Ade7953Read(uint16_t reg) {
int size = Ade7953RegSize(reg);
if (size) {
#ifdef USE_ESP32_SPI
if (Ade7953.pin_cs[0] >= 0) {
digitalWrite(Ade7953.pin_cs[Ade7953.cs_index], 0);
delayMicroseconds(1); // CS 1uS to SCLK edge
SPI.beginTransaction(Ade7953.spi_settings);
SPI.transfer16(reg);
SPI.transfer(0x80); // Read
while (size--) {
response = response << 8 | SPI.transfer(0); // receive DATA (MSB first)
}
SPI.endTransaction();
digitalWrite(Ade7953.pin_cs[Ade7953.cs_index], 1);
} else {
#endif // USE_ESP32_SPI
Wire.beginTransmission(ADE7953_ADDR);
Wire.write((reg >> 8) & 0xFF);
Wire.write(reg & 0xFF);
@ -274,43 +300,68 @@ int32_t Ade7953Read(uint16_t reg) {
response = response << 8 | Wire.read(); // receive DATA (MSB first)
}
}
#ifdef USE_ESP32_SPI
}
#endif // USE_ESP32_SPI
}
return response;
}
#ifdef ADE7953_DUMP_REGS
void Ade7953DumpRegs(void) {
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: SAGCYC DISNOLD Resrvd Resrvd LCYCMOD Resrvd Resrvd PGAV PGAIA PGAIB"));
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** SAGCYC DISNOLD Resrvd Resrvd LCYCMOD Resrvd Resrvd PGAV PGAIA PGAIB"));
char data[200] = { 0 };
for (uint32_t i = 0; i < 10; i++) {
int32_t value = Ade7953Read(ADE7953_SAGCYC + i);
snprintf_P(data, sizeof(data), PSTR("%s %02X"), data, value); // 8-bit regs
}
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: Regs 0x000..009%s"), data);
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: ZXTOUT LINECYC CONFIG CF1DEN CF2DEN Resrvd Resrvd CFMODE PHCALA PHCALB PFA PFB ANGLEA ANGLEB Period"));
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** 0x000..009%s"), data);
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** ZXTOUT LINECYC CONFIG CF1DEN CF2DEN Resrvd Resrvd CFMODE PHCALA PHCALB PFA PFB ANGLEA ANGLEB Period"));
data[0] = '\0';
for (uint32_t i = 0; i < 15; i++) {
int32_t value = Ade7953Read(ADE7953_ZXTOUT + i);
snprintf_P(data, sizeof(data), PSTR("%s %04X"), data, value); // 16-bit regs
}
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: Regs 0x100..10E%s"), data);
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: IGAIN VGAIN WGAIN VARGAIN VAGAIN Resrvd IRMSOS Resrvd VRMSOS WATTOS VAROS VAOS"));
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** 0x100..10E%s"), data);
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** IGAIN VGAIN WGAIN VARGAIN VAGAIN Resrvd IRMSOS Resrvd VRMSOS WATTOS VAROS VAOS"));
data[0] = '\0';
for (uint32_t i = 0; i < 12; i++) {
int32_t value = Ade7953Read(ADE7953_AIGAIN + i);
snprintf_P(data, sizeof(data), PSTR("%s %06X"), data, value); // 24-bit regs
}
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: Regs 0x380..38B%s"), data);
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** 0x380..38B%s"), data);
data[0] = '\0';
for (uint32_t i = 0; i < 12; i++) {
int32_t value = Ade7953Read(ADE7953_BIGAIN + i);
snprintf_P(data, sizeof(data), PSTR("%s %06X"), data, value); // 24-bit regs
}
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: Regs 0x38C..397%s"), data);
AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: *** 0x38C..397%s"), data);
}
#endif // ADE7953_DUMP_REGS
void Ade7953SetCalibration(uint32_t regset, uint32_t calibset) {
Ade7953.cs_index = calibset;
for (uint32_t i = 0; i < ADE7953_CALIBREGS; i++) {
int32_t value = Ade7953.calib_data[calibset][i];
if (ADE7943_CAL_PHCAL == i) {
// if (ADE7953_PHCAL_DEFAULT == value) { continue; } // ADE7953 reset does NOT always reset all registers
if (value < 0) {
value = abs(value) + 0x200; // Add sign magnitude
}
}
// if (ADE7953_GAIN_DEFAULT == value) { continue; } // ADE7953 reset does NOT always reset all registers
Ade7953Write(Ade7953CalibRegs[regset][i], value);
}
}
void Ade7953Init(void) {
uint32_t chips = 1;
#ifdef USE_ESP32_SPI
chips = (Ade7953.pin_cs[1] >= 0) ? 2 : 1;
#endif // USE_ESP32_SPI
for (uint32_t chip = 0; chip < chips; chip++) {
Ade7953.cs_index = chip;
#ifdef ADE7953_DUMP_REGS
Ade7953DumpRegs();
#endif // ADE7953_DUMP_REGS
@ -318,59 +369,81 @@ void Ade7953Init(void) {
Ade7953Write(ADE7953_CONFIG, 0x0004); // Locking the communication interface (Clear bit COMM_LOCK), Enable HPF
Ade7953Write(0x0FE, 0x00AD); // Unlock register 0x120
Ade7953Write(0x120, 0x0030); // Configure optimum setting
#ifdef USE_ESP32_SPI
// int32_t value = Ade7953Read(0x702); // Silicon version
// AddLog(LOG_LEVEL_DEBUG, PSTR("ADE: Chip%d version %d"), chip +1, value);
#endif // USE_ESP32_SPI
}
for (uint32_t i = 0; i < sizeof(Ade7953CalibRegs)/sizeof(uint16_t); i++) {
if (i >= ADE7943_CAL_PHCALA) {
int16_t phasecal = Ade7953.calib_data[i];
if (phasecal < 0) {
phasecal = abs(phasecal) + 0x200; // Add sign magnitude
Ade7953SetCalibration(0, 0); // First ADE7953 A registers set with calibration set 0
#ifdef USE_ESP32_SPI
if (Ade7953.pin_cs[1] >= 0) { // Second ADE7953 using SPI
Ade7953SetCalibration(0, 1); // Second ADE7953 A registers set with calibration set 1
}
Ade7953Write(Ade7953CalibRegs[i], phasecal);
} else {
Ade7953Write(Ade7953CalibRegs[i], Ade7953.calib_data[i]);
}
}
int32_t regs[sizeof(Ade7953CalibRegs)/sizeof(uint16_t)];
for (uint32_t i = 0; i < sizeof(Ade7953CalibRegs)/sizeof(uint16_t); i++) {
regs[i] = Ade7953Read(Ade7953CalibRegs[i]);
if (i >= ADE7943_CAL_PHCALA) {
else if (Ade7953.pin_cs[0] == -1) // No first ADE7953 using SPI so set register set B
#endif // USE_ESP32_SPI
Ade7953SetCalibration(1, 1); // First ADE7953 B register set with calibration set 1
int32_t regs[ADE7953_CALIBREGS];
for (uint32_t chip = 0; chip < chips; chip++) {
Ade7953.cs_index = chip;
for (uint32_t channel = 0; channel < 2; channel++) {
for (uint32_t i = 0; i < ADE7953_CALIBREGS; i++) {
regs[i] = Ade7953Read(Ade7953CalibRegs[channel][i]);
if (ADE7943_CAL_PHCAL == i) {
if (regs[i] >= 0x0200) {
regs[i] &= 0x01FF; // Clear sign magnitude
regs[i] *= -1; // Make negative
}
}
}
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: CalibRegs aV %d, bV %d, aI %d, bI %d, aW %d, bW %d, aVA %d, bVA %d, aVAr %d, bVAr %d, aP %d, bP %d"),
regs[0], regs[1], regs[2], regs[3], regs[4], regs[5], regs[6], regs[7], regs[8], regs[9], regs[10], regs[11]);
#ifdef USE_ESP32_SPI
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: Chip%d CalibRegs%c V %d, I %d, W %d, VA %d, VAr %d, Ph %d"), chip +1, 'A'+channel, regs[0], regs[1], regs[2], regs[3], regs[4], regs[5]);
#else
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: CalibRegs%c V %d, I %d, W %d, VA %d, VAr %d, Ph %d"), 'A'+channel, regs[0], regs[1], regs[2], regs[3], regs[4], regs[5]);
#endif // USE_ESP32_SPI
}
#ifdef ADE7953_DUMP_REGS
Ade7953DumpRegs();
#endif // ADE7953_DUMP_REGS
}
}
void Ade7953GetData(void) {
uint32_t acc_mode;
int32_t reg[2][4];
for (uint32_t i = 0; i < sizeof(Ade7953Registers)/sizeof(uint16_t); i++) {
int32_t value = Ade7953Read(Ade7953Registers[i]);
if (8 == i) {
Ade7953.voltage_rms = value; // RMS voltage (both channels)
} else if (9 == i) {
Ade7953.period = value; // Period
} else if (10 == i) {
acc_mode = value; // Accumulation mode
uint32_t acc_mode = 0;
int32_t reg[2][ADE7953_REGISTERS];
#ifdef USE_ESP32_SPI
if (Ade7953.pin_cs[0] >= 0) {
for (uint32_t chip = 0; chip < 2; chip++) {
if (Ade7953.pin_cs[chip] < 0) { continue; }
Ade7953.cs_index = chip;
for (uint32_t i = 0; i < ADE7953_REGISTERS; i++) {
reg[chip][i] = Ade7953Read(Ade7953Registers[0][i]); // IRMS, WATT, VA, VAR, VRMS, Period
}
}
} else {
uint32_t reg_index = i >> 2; // 0 or 1
reg[(ADE7953_SHELLY_25 == Ade7953.model) ? !reg_index : reg_index][i &3] = value; // IRMS, WATT, VA, VAR
#endif // USE_ESP32_SPI
for (uint32_t channel = 0; channel < 2; channel++) {
uint32_t channel_swap = (ADE7953_SHELLY_25 == Ade7953.model) ? !channel : channel;
for (uint32_t i = 0; i < ADE7953_REGISTERS; i++) {
reg[channel_swap][i] = Ade7953Read(Ade7953Registers[channel][i]);
}
}
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: ACCMODE 0x%06X, VRMS %d, Period %d, IRMS %d, %d, WATT %d, %d, VA %d, %d, VAR %d, %d"),
acc_mode, Ade7953.voltage_rms, Ade7953.period,
acc_mode = Ade7953Read(ADE7953_ACCMODE); // Accumulation mode
#ifdef USE_ESP32_SPI
}
#endif // USE_ESP32_SPI
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ADE: ACCMODE 0x%06X, VRMS %d, %d, Period %d, %d, IRMS %d, %d, WATT %d, %d, VA %d, %d, VAR %d, %d"),
acc_mode, reg[0][4], reg[1][4], reg[0][5], reg[1][5],
reg[0][0], reg[1][0], reg[0][1], reg[1][1], reg[0][2], reg[1][2], reg[0][3], reg[1][3]);
uint32_t apparent_power[2] = { 0, 0 };
uint32_t reactive_power[2] = { 0, 0 };
for (uint32_t channel = 0; channel < 2; channel++) {
Ade7953.voltage_rms[channel] = reg[channel][4];
Ade7953.current_rms[channel] = reg[channel][0];
if (Ade7953.current_rms[channel] < 2000) { // No load threshold (20mA)
Ade7953.current_rms[channel] = 0;
@ -386,15 +459,16 @@ void Ade7953GetData(void) {
}
if (Energy.power_on) { // Powered on
float divider = (Ade7953.calib_data[ADE7953_CAL_AVGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : Settings->energy_voltage_calibration;
Energy.voltage[0] = (float)Ade7953.voltage_rms / divider;
Energy.frequency[0] = 223750.0f / ((float)Ade7953.period + 1);
float divider;
for (uint32_t channel = 0; channel < 2; channel++) {
Energy.data_valid[channel] = 0;
divider = (Ade7953.calib_data[ADE7953_CAL_AWGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
Energy.frequency[channel] = 223750.0f / ((float)reg[channel][5] + 1);
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VGAIN] != ADE7953_GAIN_DEFAULT) ? 10000 : Settings->energy_voltage_calibration;
Energy.voltage[channel] = (float)Ade7953.voltage_rms[channel] / divider;
divider = (Ade7953.calib_data[channel][ADE7953_CAL_WGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
Energy.active_power[channel] = (float)Ade7953.active_power[channel] / divider;
divider = (Ade7953.calib_data[ADE7953_CAL_AVARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VARGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
Energy.reactive_power[channel] = (float)reactive_power[channel] / divider;
if (ADE7953_SHELLY_EM == Ade7953.model) {
if (bitRead(acc_mode, 10 +channel)) { // APSIGN
@ -404,22 +478,17 @@ void Ade7953GetData(void) {
Energy.reactive_power[channel] *= -1;
}
}
divider = (Ade7953.calib_data[ADE7953_CAL_AVAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
divider = (Ade7953.calib_data[channel][ADE7953_CAL_VAGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 44 : (Settings->energy_power_calibration / 10);
Energy.apparent_power[channel] = (float)apparent_power[channel] / divider;
if (0 == Energy.active_power[channel]) {
Energy.current[channel] = 0;
} else {
divider = (Ade7953.calib_data[ADE7953_CAL_AIGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 100000 : (Settings->energy_current_calibration * 10);
divider = (Ade7953.calib_data[channel][ADE7953_CAL_IGAIN + channel] != ADE7953_GAIN_DEFAULT) ? 100000 : (Settings->energy_current_calibration * 10);
Energy.current[channel] = (float)Ade7953.current_rms[channel] / divider;
Energy.kWhtoday_delta[channel] += Energy.active_power[channel] * 1000 / 36;
}
}
EnergyUpdateToday();
/*
} else { // Powered off
Energy.data_valid[0] = ENERGY_WATCHDOG;
Energy.data_valid[1] = ENERGY_WATCHDOG;
*/
}
}
@ -439,6 +508,7 @@ void Ade7953EnergyEverySecond(void) {
bool Ade7953SetDefaults(const char* json) {
// {"angles":{"angle0":180,"angle1":176}}
// {"rms":{"current_a":4194303,"current_b":4194303,"voltage":1613194},"angles":{"angle0":0,"angle1":0},"powers":{"totactive":{"a":2723574,"b":2723574},"apparent":{"a":2723574,"b":2723574},"reactive":{"a":2723574,"b":2723574}}}
// {"rms":{"current_a":21865738,"current_b":1558533,"voltage_a":1599149,"voltage_b":1597289},"angles":{"angle0":0,"angle1":0},"powers":{"totactive":{"a":106692616,"b":3540894}}}
uint32_t len = strlen(json) +1;
if (len < 7) { return false; } // Too short
@ -457,57 +527,64 @@ bool Ade7953SetDefaults(const char* json) {
if (rms) {
val = rms[PSTR("voltage")];
if (val) {
Ade7953.calib_data[ADE7953_CAL_AVGAIN] = val.getInt();
Ade7953.calib_data[ADE7953_CAL_BVGAIN] = Ade7953.calib_data[ADE7953_CAL_AVGAIN];
Ade7953.calib_data[0][ADE7953_CAL_VGAIN] = val.getInt();
Ade7953.calib_data[1][ADE7953_CAL_VGAIN] = Ade7953.calib_data[0][ADE7953_CAL_VGAIN];
}
#ifdef USE_ESP32_SPI
val = rms[PSTR("voltage_a")];
if (val) { Ade7953.calib_data[0][ADE7953_CAL_VGAIN] = val.getInt(); }
val = rms[PSTR("voltage_b")];
if (val) { Ade7953.calib_data[1][ADE7953_CAL_VGAIN] = val.getInt(); }
#endif // USE_ESP32_SPI
val = rms[PSTR("current_a")];
if (val) { Ade7953.calib_data[ADE7953_CAL_AIGAIN] = val.getInt(); }
if (val) { Ade7953.calib_data[0][ADE7953_CAL_IGAIN] = val.getInt(); }
val = rms[PSTR("current_b")];
if (val) { Ade7953.calib_data[ADE7953_CAL_BIGAIN] = val.getInt(); }
if (val) { Ade7953.calib_data[1][ADE7953_CAL_IGAIN] = val.getInt(); }
}
JsonParserObject angles = root[PSTR("angles")].getObject();
if (angles) {
val = angles[PSTR("angle0")];
if (val) { Ade7953.calib_data[ADE7943_CAL_PHCALA] = val.getInt(); }
if (val) { Ade7953.calib_data[0][ADE7943_CAL_PHCAL] = val.getInt(); }
val = angles[PSTR("angle1")];
if (val) { Ade7953.calib_data[ADE7943_CAL_PHCALB] = val.getInt(); }
if (val) { Ade7953.calib_data[1][ADE7943_CAL_PHCAL] = val.getInt(); }
}
JsonParserObject powers = root[PSTR("powers")].getObject();
if (powers) {
JsonParserObject totactive = powers[PSTR("totactive")].getObject();
if (totactive) {
val = totactive[PSTR("a")];
if (val) { Ade7953.calib_data[ADE7953_CAL_AWGAIN] = val.getInt(); }
if (val) { Ade7953.calib_data[0][ADE7953_CAL_WGAIN] = val.getInt(); }
val = totactive[PSTR("b")];
if (val) { Ade7953.calib_data[ADE7953_CAL_BWGAIN] = val.getInt(); }
if (val) { Ade7953.calib_data[1][ADE7953_CAL_WGAIN] = val.getInt(); }
}
JsonParserObject apparent = powers[PSTR("apparent")].getObject();
if (apparent) {
val = apparent[PSTR("a")];
if (val) { Ade7953.calib_data[ADE7953_CAL_AVAGAIN] = val.getInt(); }
if (val) { Ade7953.calib_data[0][ADE7953_CAL_VAGAIN] = val.getInt(); }
val = apparent[PSTR("b")];
if (val) { Ade7953.calib_data[ADE7953_CAL_BVAGAIN] = val.getInt(); }
if (val) { Ade7953.calib_data[1][ADE7953_CAL_VAGAIN] = val.getInt(); }
}
JsonParserObject reactive = powers[PSTR("reactive")].getObject();
if (reactive) {
val = reactive[PSTR("a")];
if (val) { Ade7953.calib_data[ADE7953_CAL_AVARGAIN] = val.getInt(); }
if (val) { Ade7953.calib_data[0][ADE7953_CAL_VARGAIN] = val.getInt(); }
val = reactive[PSTR("b")];
if (val) { Ade7953.calib_data[ADE7953_CAL_BVARGAIN] = val.getInt(); }
if (val) { Ade7953.calib_data[1][ADE7953_CAL_VARGAIN] = val.getInt(); }
}
}
return true;
}
void Ade7953Defaults(void) {
for (uint32_t i = 0; i < sizeof(Ade7953CalibRegs)/sizeof(uint16_t); i++) {
if (i < sizeof(Ade7953CalibRegs)/sizeof(uint16_t) -2) {
Ade7953.calib_data[i] = ADE7953_GAIN_DEFAULT;
for (uint32_t channel = 0; channel < 2; channel++) {
for (uint32_t i = 0; i < ADE7953_CALIBREGS; i++) {
if (ADE7943_CAL_PHCAL == i) {
Ade7953.calib_data[channel][i] = (ADE7953_SHELLY_EM == Ade7953.model) ? ADE7953_PHCAL_DEFAULT_CT : ADE7953_PHCAL_DEFAULT;
} else {
Ade7953.calib_data[i] = (ADE7953_SHELLY_EM == Ade7953.model) ? ADE7953_PHCAL_DEFAULT_CT : ADE7953_PHCAL_DEFAULT;
Ade7953.calib_data[channel][i] = ADE7953_GAIN_DEFAULT;
}
}
}
#ifdef USE_RULES
// rule3 on file#calib.dat do {"angles":{"angle0":180,"angle1":176}} endon
String calib = RuleLoadFile("CALIB.DAT");
@ -519,10 +596,11 @@ void Ade7953Defaults(void) {
}
void Ade7953DrvInit(void) {
if (PinUsed(GPIO_ADE7953_IRQ, GPIO_ANY)) { // Irq on GPIO16 is not supported...
if (PinUsed(GPIO_ADE7953_IRQ, GPIO_ANY)) { // Irq is not supported...
uint32_t pin_irq = Pin(GPIO_ADE7953_IRQ, GPIO_ANY);
pinMode(pin_irq, INPUT); // Related to resetPins() - Must be set to input
Ade7953.model = GetPin(pin_irq) - AGPIO(GPIO_ADE7953_IRQ); // 0 (1 = Shelly 2.5), 1 (2 = Shelly EM), 2 (3 = Shelly Plus 2PM)
// 0 (1 = Shelly 2.5), 1 (2 = Shelly EM), 2 (3 = Shelly Plus 2PM), 3 (4 = Shelly Pro 1PM), 4 (5 = Shelly Pro 2PM)
Ade7953.model = GetPin(pin_irq) - AGPIO(GPIO_ADE7953_IRQ);
int pin_reset = Pin(GPIO_ADE7953_RST); // -1 if not defined
#ifdef ESP8266
@ -532,29 +610,72 @@ void Ade7953DrvInit(void) {
}
}
#endif
if (pin_reset > -1) {
pinMode(pin_reset, OUTPUT); // Reset pin ADE7953
if (pin_reset >= 0) {
digitalWrite(pin_reset, 0);
delay(1);
pinMode(pin_reset, OUTPUT); // Reset pin ADE7953
delay(1); // To initiate a hardware reset, this pin must be brought low for a minimum of 10 μs.
digitalWrite(pin_reset, 1);
if (Ade7953.model < ADE7953_SHELLY_PRO_1PM) {
pinMode(pin_reset, INPUT);
}
}
delay(100); // Need 100mS to init ADE7953
if (I2cSetDevice(ADE7953_ADDR)) {
#ifdef USE_ESP32_SPI
Ade7953.pin_cs[0] = -1;
Ade7953.pin_cs[1] = -1;
if (Ade7953.model >= ADE7953_SHELLY_PRO_1PM) { // SPI
if (PinUsed(GPIO_ADE7953_CS)) { // ADE7953 CS1 enabled (Pro 1PM/2PM)
Ade7953.pin_cs[0] = Pin(GPIO_ADE7953_CS);
digitalWrite(Ade7953.pin_cs[0], 1); // ADE7953 CS1 enabled (Pro 2PM)
pinMode(Ade7953.pin_cs[0], OUTPUT);
Ade7953.pin_cs[1] = Pin(GPIO_ADE7953_CS, 1);
if (Ade7953.pin_cs[1] > -1) { // ADE7953 CS2 enabled (Pro 2PM)
digitalWrite(Ade7953.pin_cs[1], 1);
pinMode(Ade7953.pin_cs[1], OUTPUT);
} else {
Ade7953.model = ADE7953_SHELLY_PRO_1PM;
}
Ade7953.cs_index = 0;
SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1);
Ade7953.spi_settings = SPISettings(1000000, MSBFIRST, SPI_MODE0); // Set up SPI at 1MHz, MSB first, Capture at rising edge
AddLog(LOG_LEVEL_INFO, PSTR("SPI: ADE7953 found"));
} else {
return; // No CS pin defined
}
} else {
#endif // USE_ESP32_SPI
if (!I2cSetDevice(ADE7953_ADDR)) {
return;
}
I2cSetActiveFound(ADE7953_ADDR, "ADE7953");
#ifdef USE_ESP32_SPI
}
#endif // USE_ESP32_SPI
if (HLW_PREF_PULSE == Settings->energy_power_calibration) {
Settings->energy_power_calibration = ADE7953_PREF;
Settings->energy_voltage_calibration = ADE7953_UREF;
Settings->energy_current_calibration = ADE7953_IREF;
}
I2cSetActiveFound(ADE7953_ADDR, "ADE7953");
Ade7953Defaults();
Ade7953.init_step = 2;
// Energy.phase_count = 1;
// Energy.voltage_common = false;
// Energy.frequency_common = false;
// Energy.use_overtemp = false;
if (ADE7953_SHELLY_PRO_1PM == Ade7953.model) {
} else {
Energy.phase_count = 2; // Handle two channels as two phases
if (ADE7953_SHELLY_PRO_2PM == Ade7953.model) {
} else {
Energy.voltage_common = true; // Use common voltage
Energy.frequency_common = true; // Use common frequency
}
}
Energy.use_overtemp = true; // Use global temperature for overtemp detection
if (ADE7953_SHELLY_EM == Ade7953.model) {
Energy.local_energy_active_export = true;
@ -562,7 +683,6 @@ void Ade7953DrvInit(void) {
TasmotaGlobal.energy_driver = XNRG_07;
}
}
}
bool Ade7953Command(void) {
bool serviced = true;
@ -590,9 +710,9 @@ bool Ade7953Command(void) {
}
}
else if (CMND_VOLTAGESET == Energy.command_code) {
if (XdrvMailbox.data_len && Ade7953.voltage_rms) {
if (XdrvMailbox.data_len && Ade7953.voltage_rms[channel]) {
if ((value > 10000) && (value < 26000)) { // Between 100V and 260V
Settings->energy_voltage_calibration = (Ade7953.voltage_rms * 100) / value; // 0.00 V
Settings->energy_voltage_calibration = (Ade7953.voltage_rms[channel] * 100) / value; // 0.00 V
}
}
}
@ -613,7 +733,7 @@ bool Ade7953Command(void) {
\*********************************************************************************************/
bool Xnrg07(uint8_t function) {
if (!I2cEnabled(XI2C_07)) { return false; }
if (!I2cEnabled(XI2C_07) && (SPI_MOSI_MISO != TasmotaGlobal.spi_enabled)) { return false; }
bool result = false;
@ -633,4 +753,4 @@ bool Xnrg07(uint8_t function) {
#endif // USE_ADE7953
#endif // USE_ENERGY_SENSOR
#endif // USE_I2C
#endif // USE_I2C or USE_ESP_SPI

View File

@ -409,13 +409,22 @@ void DataCallback(struct _ValueList * me, uint8_t flags)
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: Contract changed, now '%s'"), me->value);
}
// Contract subscribed (Power)
else if (ilabel == LABEL_ISOUSC || ilabel == LABEL_PREF)
// Contract subscribed (I Max)
else if (ilabel == LABEL_ISOUSC)
{
isousc = atoi( me->value);
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: ISousc set to %d"), isousc);
}
// Contract subscribed (Power in KVA)
else if (ilabel == LABEL_PREF)
{
// Convert KVA to A
isousc = atoi( me->value) * 5 ;
AddLog(LOG_LEVEL_DEBUG, PSTR("TIC: ISousc set to %d"), isousc);
}
// Serial Number of device
else if (ilabel == LABEL_ADCO || ilabel == LABEL_ADSC)
{
@ -877,7 +886,7 @@ const char HTTP_ENERGY_ID_TELEINFO[] PROGMEM = "{s}ID{m}%s{e}" ;
const char HTTP_ENERGY_INDEX_TELEINFO[] PROGMEM = "{s}%s{m}%s " D_UNIT_WATTHOUR "{e}" ;
const char HTTP_ENERGY_PAPP_TELEINFO[] PROGMEM = "{s}" D_POWERUSAGE "{m}%d " D_UNIT_WATT "{e}" ;
//const char HTTP_ENERGY_IINST_TELEINFO[] PROGMEM = "{s}" D_CURRENT "%s{m}%d " D_UNIT_AMPERE "{e}" ;
const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}" D_CURRENT_TARIFF "{m}Heures %s{e}" ;
const char HTTP_ENERGY_TARIF_TELEINFO[] PROGMEM = "{s}" D_CURRENT_TARIFF "{m}%s%s{e}" ;
const char HTTP_ENERGY_CONTRAT_TELEINFO[] PROGMEM = "{s}" D_CONTRACT "{m}%s %d" D_UNIT_AMPERE "{e}" ;
const char HTTP_ENERGY_LOAD_TELEINFO[] PROGMEM = "{s}" D_POWER_LOAD "{m}%d" D_UNIT_PERCENT "{e}" ;
const char HTTP_ENERGY_IMAX_TELEINFO[] PROGMEM = "{s}" D_MAX_CURRENT "{m}%d" D_UNIT_AMPERE "{e}" ;
@ -967,7 +976,11 @@ void TInfoShow(bool json)
if (tarif) {
GetTextIndexed(name, sizeof(name), tarif-1, kTarifName);
WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, name);
if (tinfo_mode==TINFO_MODE_STANDARD ) {
WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, "", name);
} else {
WSContentSend_P(HTTP_ENERGY_TARIF_TELEINFO, "Heures ", name);
}
}
if (contrat && isousc) {
int percent = (int) ((Energy.current[0]*100.0f) / isousc) ;

View File

@ -104,7 +104,7 @@
*
* Restrictions:
* - Supports Modbus floating point registers
* - Max number of uer defined registers is defined by one rule buffer (511 characters uncompressed, around 800 characters compressed)
* - Max number of user defined registers is defined by one rule buffer (511 characters uncompressed, around 800 characters compressed)
*
* To do:
* - Support all three rule slots

File diff suppressed because it is too large Load Diff

View File

@ -261,7 +261,7 @@ TFMINIPLUS_RX = GPIO_TFMINIPLUS_RX
ZEROCROSS = GPIO_ZEROCROSS
HALLEFFECT = GPIO_HALLEFFECT
EPD_DATA = GPIO_EPD_DATA
INPUT = GPIO_INPUT
GPIO_INPUT = GPIO_INPUT // avoid conflict with INPUT
KEY1_PD = GPIO_KEY1_PD
KEY1_INV_PD = GPIO_KEY1_INV_PD
SWT1_PD = GPIO_SWT1_PD
@ -307,5 +307,23 @@ SDIO_D2 = GPIO_SDIO_D2
SDIO_D3 = GPIO_SDIO_D3
FLOWRATEMETER_SIGNAL = GPIO_FLOWRATEMETER_IN
BP5758D_CLK = GPIO_BP5758D_CLK
BP5758D_DAT = GPIO_BP5758D_DAT
SM2335_CLK = GPIO_SM2335_CLK
SM2335_DAT = GPIO_SM2335_DAT
MP3_DFR562_BUSY = GPIO_MP3_DFR562_BUSY
TM1621_CS = GPIO_TM1621_CS
TM1621_WR = GPIO_TM1621_WR
TM1621_RD = GPIO_TM1621_RD
TM1621_DAT = GPIO_TM1621_DAT
REL1_BI = GPIO_REL1_BI
REL1_BI_INV = GPIO_REL1_BI_INV
I2S_MCLK = GPIO_I2S_MCLK
MBR_TX = GPIO_MBR_TX
MBR_RX = GPIO_MBR_RX
ADE7953_RST = GPIO_ADE7953_RST
NRG_MBS_TX = GPIO_NRG_MBS_TX
NRG_MBS_RX = GPIO_NRG_MBS_RX
ADE7953_CS = GPIO_ADE7953_CS
SENSOR_END = GPIO_SENSOR_END