mirror of https://github.com/arendst/Tasmota.git
Now using display_options instead of display_type
This commit is contained in:
commit
850aff3ab6
|
@ -7,7 +7,7 @@
|
|||
- [ ] Only relevant files were touched
|
||||
- [ ] Only one feature/fix was added per PR and the code change compiles without warnings
|
||||
- [ ] The code change is tested and works on Tasmota core ESP8266 V.2.7.4.9
|
||||
- [ ] The code change is tested and works on Tasmota core ESP32 V.1.0.5-rc6
|
||||
- [ ] The code change is tested and works with core ESP32 V.1.0.5
|
||||
- [ ] I accept the [CLA](https://github.com/arendst/Tasmota/blob/development/CONTRIBUTING.md#contributor-license-agreement-cla).
|
||||
|
||||
_NOTE: The code change must pass CI tests. **Your PR cannot be merged unless tests pass**_
|
||||
|
|
|
@ -12,6 +12,7 @@ All notable changes to this project will be documented in this file.
|
|||
|
||||
### Changed
|
||||
- TuyaMcu dimmer timeout (#11121)
|
||||
- TasmotaSerial library from v3.2.0 to v3.3.0
|
||||
|
||||
### Fixed
|
||||
- Refactor acceleration function for shutter stepper and servo (#11088)
|
||||
|
|
|
@ -87,6 +87,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
|
|||
|
||||
### Changed
|
||||
- TuyaMcu dimmer timeout [#11121](https://github.com/arendst/Tasmota/issues/11121)
|
||||
- TasmotaSerial library from v3.2.0 to v3.3.0
|
||||
|
||||
### Fixed
|
||||
- Refactor acceleration function for shutter stepper and servo [#11088](https://github.com/arendst/Tasmota/issues/11088)
|
||||
|
|
|
@ -212,6 +212,9 @@ char * copyStr(const char * str) {
|
|||
return cpy;
|
||||
}
|
||||
|
||||
const char ext_invalid_mem[] PROGMEM = "<--INVALID-->";
|
||||
const uint32_t min_valid_ptr = 0x3FF00000; // addresses below this line are invalid
|
||||
|
||||
int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list va) {
|
||||
va_list va_cpy;
|
||||
va_copy(va_cpy, va);
|
||||
|
@ -222,7 +225,7 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
|
|||
char * fmt = fmt_cpy;
|
||||
|
||||
const uint32_t ALLOC_SIZE = 12;
|
||||
static char * allocs[ALLOC_SIZE] = {}; // initialized to zeroes
|
||||
static const char * allocs[ALLOC_SIZE] = {}; // initialized to zeroes
|
||||
uint32_t alloc_idx = 0;
|
||||
static char hex[20]; // buffer used for 64 bits, favor RAM instead of stack to remove pressure
|
||||
|
||||
|
@ -264,12 +267,13 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
|
|||
fmt++;
|
||||
uint32_t cur_val = va_arg(va, uint32_t); // current value
|
||||
const char ** cur_val_ptr = va_cur_ptr4(va, const char*); // pointer to value on stack
|
||||
char * new_val_str = (char*) "";
|
||||
const char * new_val_str = "";
|
||||
switch (*fmt) {
|
||||
case 'H': // Hex, decimals indicates the length, default 2
|
||||
{
|
||||
if (decimals < 0) { decimals = 0; }
|
||||
if (decimals > 0) {
|
||||
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
|
||||
else if (decimals > 0) {
|
||||
char * hex_char = (char*) malloc(decimals*2 + 2);
|
||||
ToHex_P((const uint8_t *)cur_val, decimals, hex_char, decimals*2 + 2);
|
||||
new_val_str = hex_char;
|
||||
|
@ -280,13 +284,16 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
|
|||
break;
|
||||
case 'B': // Pointer to SBuffer
|
||||
{
|
||||
const SBuffer & buf = *(const SBuffer*)cur_val;
|
||||
size_t buf_len = (&buf != nullptr) ? buf.len() : 0;
|
||||
if (buf_len) {
|
||||
char * hex_char = (char*) malloc(buf_len*2 + 2);
|
||||
ToHex_P(buf.getBuffer(), buf_len, hex_char, buf_len*2 + 2);
|
||||
new_val_str = hex_char;
|
||||
allocs[alloc_idx++] = new_val_str;
|
||||
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
|
||||
else {
|
||||
const SBuffer & buf = *(const SBuffer*)cur_val;
|
||||
size_t buf_len = (&buf != nullptr) ? buf.len() : 0;
|
||||
if (buf_len) {
|
||||
char * hex_char = (char*) malloc(buf_len*2 + 2);
|
||||
ToHex_P(buf.getBuffer(), buf_len, hex_char, buf_len*2 + 2);
|
||||
new_val_str = hex_char;
|
||||
allocs[alloc_idx++] = new_val_str;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -315,40 +322,46 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
|
|||
// Note: float MUST be passed by address, because C alsays promoted float to double when in vararg
|
||||
case 'f': // input is `float`, printed to float with 2 decimals
|
||||
{
|
||||
bool truncate = false;
|
||||
if (decimals < 0) {
|
||||
decimals = -decimals;
|
||||
truncate = true;
|
||||
}
|
||||
float number = *(float*)cur_val;
|
||||
if (isnan(number) || isinf(number)) {
|
||||
new_val_str = (char*) "null";
|
||||
} else {
|
||||
dtostrf(*(float*)cur_val, (decimals + 2), decimals, hex);
|
||||
|
||||
if (truncate) {
|
||||
uint32_t last = strlen(hex) - 1;
|
||||
// remove trailing zeros
|
||||
while (hex[last] == '0') {
|
||||
hex[last--] = 0; // remove last char
|
||||
}
|
||||
// remove trailing dot
|
||||
if (hex[last] == '.') {
|
||||
hex[last] = 0;
|
||||
}
|
||||
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
|
||||
else {
|
||||
bool truncate = false;
|
||||
if (decimals < 0) {
|
||||
decimals = -decimals;
|
||||
truncate = true;
|
||||
}
|
||||
float number = *(float*)cur_val;
|
||||
if (isnan(number) || isinf(number)) {
|
||||
new_val_str = "null";
|
||||
} else {
|
||||
dtostrf(*(float*)cur_val, (decimals + 2), decimals, hex);
|
||||
|
||||
if (truncate) {
|
||||
uint32_t last = strlen(hex) - 1;
|
||||
// remove trailing zeros
|
||||
while (hex[last] == '0') {
|
||||
hex[last--] = 0; // remove last char
|
||||
}
|
||||
// remove trailing dot
|
||||
if (hex[last] == '.') {
|
||||
hex[last] = 0;
|
||||
}
|
||||
}
|
||||
new_val_str = copyStr(hex);
|
||||
allocs[alloc_idx++] = new_val_str;
|
||||
}
|
||||
new_val_str = copyStr(hex);
|
||||
allocs[alloc_idx++] = new_val_str;
|
||||
}
|
||||
}
|
||||
break;
|
||||
// '%_X' outputs a 64 bits unsigned int to uppercase HEX with 16 digits
|
||||
case 'X': // input is `uint64_t*`, printed as 16 hex digits (no prefix 0x)
|
||||
{
|
||||
if ((decimals < 0) || (decimals > 16)) { decimals = 16; }
|
||||
U64toHex(*(uint64_t*)cur_val, hex, decimals);
|
||||
new_val_str = copyStr(hex);
|
||||
allocs[alloc_idx++] = new_val_str;
|
||||
if (cur_val < min_valid_ptr) { new_val_str = ext_invalid_mem; }
|
||||
else {
|
||||
if ((decimals < 0) || (decimals > 16)) { decimals = 16; }
|
||||
U64toHex(*(uint64_t*)cur_val, hex, decimals);
|
||||
new_val_str = copyStr(hex);
|
||||
allocs[alloc_idx++] = new_val_str;
|
||||
}
|
||||
}
|
||||
break;
|
||||
// Trying to do String allocation alternatives, but not as interesting as I thought in the beginning
|
||||
|
@ -382,7 +395,7 @@ int32_t ext_vsnprintf_P(char * buf, size_t buf_len, const char * fmt_P, va_list
|
|||
|
||||
// disallocated all temporary strings
|
||||
for (uint32_t i = 0; i < alloc_idx; i++) {
|
||||
free(allocs[i]); // it is ok to call free() on nullptr so we don't test for nullptr first
|
||||
free((void*)allocs[i]); // it is ok to call free() on nullptr so we don't test for nullptr first
|
||||
allocs[i] = nullptr;
|
||||
}
|
||||
free(fmt_cpy); // free the local copy of the format string
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "TasmotaSerial",
|
||||
"version": "3.2.0",
|
||||
"version": "3.3.0",
|
||||
"keywords": [
|
||||
"serial", "io", "TasmotaSerial"
|
||||
],
|
|
@ -1,5 +1,5 @@
|
|||
name=TasmotaSerial
|
||||
version=3.2.0
|
||||
version=3.3.0
|
||||
author=Theo Arends
|
||||
maintainer=Theo Arends <theo@arends.com>
|
||||
sentence=Implementation of software serial with hardware serial fallback for ESP8266 and ESP32.
|
|
@ -109,16 +109,27 @@ bool TasmotaSerial::isValidGPIOpin(int pin) {
|
|||
return (pin >= -1 && pin <= 5) || (pin >= 12 && pin <= 15);
|
||||
}
|
||||
|
||||
bool TasmotaSerial::begin(long speed, int stop_bits) {
|
||||
m_stop_bits = ((stop_bits -1) &1) +1;
|
||||
bool TasmotaSerial::begin(uint32_t speed, uint32_t config) {
|
||||
if (config > 2) {
|
||||
// Legacy support where software serial fakes two stop bits if either stop bits is 2 or parity is not None
|
||||
m_stop_bits = ((config &0x30) >> 5) +1;
|
||||
if ((1 == m_stop_bits) && (config &0x03)) {
|
||||
m_stop_bits++;
|
||||
}
|
||||
} else {
|
||||
m_stop_bits = ((config -1) &1) +1;
|
||||
#ifdef ESP8266
|
||||
config = (2 == m_stop_bits) ? (uint32_t)SERIAL_8N2 : (uint32_t)SERIAL_8N1;
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
config = (2 == m_stop_bits) ? SERIAL_8N2 : SERIAL_8N1;
|
||||
#endif // ESP32
|
||||
}
|
||||
|
||||
if (m_hardserial) {
|
||||
#ifdef ESP8266
|
||||
Serial.flush();
|
||||
if (2 == m_stop_bits) {
|
||||
Serial.begin(speed, SERIAL_8N2);
|
||||
} else {
|
||||
Serial.begin(speed, SERIAL_8N1);
|
||||
}
|
||||
Serial.begin(speed, (SerialConfig)config);
|
||||
if (m_hardswap) {
|
||||
Serial.swap();
|
||||
}
|
||||
|
@ -131,11 +142,7 @@ bool TasmotaSerial::begin(long speed, int stop_bits) {
|
|||
m_uart = tasmota_serial_index;
|
||||
tasmota_serial_index--;
|
||||
TSerial = new HardwareSerial(m_uart);
|
||||
if (2 == m_stop_bits) {
|
||||
TSerial->begin(speed, SERIAL_8N2, m_rx_pin, m_tx_pin);
|
||||
} else {
|
||||
TSerial->begin(speed, SERIAL_8N1, m_rx_pin, m_tx_pin);
|
||||
}
|
||||
TSerial->begin(speed, config, m_rx_pin, m_tx_pin);
|
||||
if (serial_buffer_size > 256) {
|
||||
TSerial->setRxBufferSize(serial_buffer_size);
|
||||
}
|
||||
|
@ -154,10 +161,6 @@ bool TasmotaSerial::begin(long speed, int stop_bits) {
|
|||
return m_valid;
|
||||
}
|
||||
|
||||
bool TasmotaSerial::begin(void) {
|
||||
return begin(TM_SERIAL_BAUDRATE);
|
||||
}
|
||||
|
||||
bool TasmotaSerial::hardwareSerial(void) {
|
||||
#ifdef ESP8266
|
||||
return m_hardserial;
|
|
@ -40,8 +40,7 @@ class TasmotaSerial : public Stream {
|
|||
TasmotaSerial(int receive_pin, int transmit_pin, int hardware_fallback = 0, int nwmode = 0, int buffer_size = TM_SERIAL_BUFFER_SIZE);
|
||||
virtual ~TasmotaSerial();
|
||||
|
||||
bool begin(long speed, int stop_bits = 1);
|
||||
bool begin(void);
|
||||
bool begin(uint32_t speed = TM_SERIAL_BAUDRATE, uint32_t config = SERIAL_8N1);
|
||||
bool hardwareSerial(void);
|
||||
int peek(void);
|
||||
|
|
@ -26,18 +26,29 @@
|
|||
|
||||
const char * k_current_json_buffer = "";
|
||||
|
||||
// returns nibble value or -1 if not an hex digit
|
||||
static int32_t asc2byte(char chr) {
|
||||
if (chr >= '0' && chr <= '9') { return chr - '0'; }
|
||||
else if (chr >= 'A' && chr <= 'F') { return chr + 10 - 'A'; }
|
||||
else if (chr >= 'a' && chr <= 'f') { return chr + 10 - 'a'; }
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Lightweight String to Float, because atof() or strtof() takes 10KB
|
||||
*
|
||||
* To remove code, exponents are not parsed
|
||||
* (commented out below, just in case we need them after all)
|
||||
*
|
||||
* Moved to double to be able to parse 32 bits int as well without loss in accuracy
|
||||
\*********************************************************************************************/
|
||||
// Inspired from https://searchcode.com/codesearch/view/22115068/
|
||||
float json_strtof(const char* s) {
|
||||
double JsonParserToken::json_strtof(const char* s) {
|
||||
const char* p = s;
|
||||
float value = 0.;
|
||||
double value = 0.;
|
||||
int32_t sign = +1;
|
||||
float factor;
|
||||
double factor;
|
||||
uint32_t base = 10; // support hex mode if start with Ox or OX
|
||||
// unsigned int expo;
|
||||
|
||||
while (isspace(*p)){ // skip any leading white-spaces
|
||||
|
@ -45,22 +56,30 @@ float json_strtof(const char* s) {
|
|||
}
|
||||
|
||||
switch (*p) {
|
||||
case '-': sign = -1;
|
||||
case '-': sign = -1; // no break on purpose
|
||||
case '+': p++;
|
||||
default : break;
|
||||
}
|
||||
|
||||
while ((unsigned int)(*p - '0') < 10u) {
|
||||
value = value*10 + (*p++ - '0');
|
||||
if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { // detect hex mode
|
||||
base = 16;
|
||||
p += 2;
|
||||
}
|
||||
|
||||
int32_t v; // temp nibble value
|
||||
while ((v = asc2byte(*p)) >= 0) {
|
||||
value = value * base + v;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p == '.' ) {
|
||||
factor = 1.0f;
|
||||
|
||||
p++;
|
||||
while ((unsigned int)(*p - '0') < 10u) {
|
||||
factor *= 0.1f;
|
||||
value += (*p++ - '0') * factor;
|
||||
while ((v = asc2byte(*p)) >= 0) {
|
||||
factor /= base;
|
||||
value += v * factor;
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -114,6 +114,9 @@ public:
|
|||
JsonParserObject getObject(void) const;
|
||||
JsonParserArray getArray(void) const;
|
||||
|
||||
// general parser from string to int/hex/float
|
||||
static double json_strtof(const char* s);
|
||||
|
||||
public:
|
||||
// the following should be 'protected' but then it can't be accessed by iterators
|
||||
const jsmntok_t * t;
|
||||
|
|
|
@ -549,6 +549,9 @@ void Renderer::setDrawMode(uint8_t mode) {
|
|||
void Renderer::invertDisplay(boolean i) {
|
||||
}
|
||||
|
||||
void Renderer::reverseDisplay(boolean i) {
|
||||
}
|
||||
|
||||
void Renderer::setScrollMargins(uint16_t top, uint16_t bottom) {
|
||||
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
virtual void pushColors(uint16_t *data, uint16_t len, boolean first);
|
||||
virtual void setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1);
|
||||
virtual void invertDisplay(boolean i);
|
||||
virtual void reverseDisplay(boolean i);
|
||||
virtual void setScrollMargins(uint16_t top, uint16_t bottom);
|
||||
virtual void scrollTo(uint16_t y);
|
||||
void setDrawMode(uint8_t mode);
|
||||
|
|
|
@ -568,6 +568,28 @@ void ILI9341_2::invertDisplay(boolean i) {
|
|||
SPI_END_TRANSACTION();
|
||||
}
|
||||
|
||||
void ILI9341_2::reverseDisplay(boolean i) {
|
||||
SPI_BEGIN_TRANSACTION();
|
||||
ILI9341_2_CS_LOW
|
||||
if (i) {
|
||||
writecmd(ILI9341_2_FRMCTR1);
|
||||
spiwrite(0x00);
|
||||
spiwrite(0x13);
|
||||
writecmd(ILI9341_2_MADCTL);
|
||||
spiwrite(0x01);
|
||||
spiwrite(0x08);
|
||||
} else {
|
||||
writecmd(ILI9341_2_FRMCTR1);
|
||||
spiwrite(0x00);
|
||||
spiwrite(0x18);
|
||||
writecmd(ILI9341_2_MADCTL);
|
||||
spiwrite(0x01);
|
||||
spiwrite(0x48);
|
||||
}
|
||||
ILI9341_2_CS_HIGH
|
||||
SPI_END_TRANSACTION();
|
||||
}
|
||||
|
||||
void ili9342_dimm(uint8_t dim);
|
||||
|
||||
// dimmer 0-100
|
||||
|
|
|
@ -138,6 +138,7 @@ class ILI9341_2 : public Renderer {
|
|||
void dim(uint8_t dim);
|
||||
void pushColors(uint16_t *data, uint16_t len, boolean first);
|
||||
void invertDisplay(boolean i);
|
||||
void reverseDisplay(boolean i);
|
||||
void spiwrite(uint8_t c);
|
||||
void spiwrite16(uint16_t c);
|
||||
void spiwrite32(uint32_t c);
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
# XPT2046 Touchscreen Arduino Library
|
||||
|
||||
XPT2046_Touchscreen is a library for the XPT2046 resistive touchscreen controllers used on many low cost TFT displays.
|
||||
|
||||
![ILI9431Test Example Program](doc/ILI9431Test.jpg)
|
||||
|
||||
## Setup Functions
|
||||
|
||||
First, create an instance of the library for your touchscreen. The digital pin
|
||||
used for chip select is required. The normal MISO, MOSI and SCK pins will be
|
||||
used automatically.
|
||||
|
||||
#define CS_PIN 8
|
||||
XPT2046_Touchscreen ts(CS_PIN);
|
||||
|
||||
The use of the Touch interrupt pin can be optionally specified. If the Teensy
|
||||
pin specified is actively connected to the T_IRQ display pin then the normal
|
||||
touch calls will respond, but can be called more often as each call returns
|
||||
without hardware access when no interrupt was recorded.
|
||||
|
||||
#define TIRQ_PIN 2
|
||||
XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN);
|
||||
|
||||
In setup(), use the begin() function to initialize the touchscreen, and
|
||||
optionally use setRotation(n), where n is 0 to 3, matching the rotation
|
||||
setting in ILI9341_t3, Adafruit_ILI9341 or other Adafruit compatible TFT
|
||||
libraries.
|
||||
|
||||
ts.begin();
|
||||
ts.setRotation(1);
|
||||
|
||||
## Reading Touch Info
|
||||
|
||||
The touched() function tells if the display is currently being touched,
|
||||
returning true or false.
|
||||
|
||||
if (ts.touched()) {
|
||||
// do something....
|
||||
}
|
||||
|
||||
You can read the touch coordinates with readData()
|
||||
|
||||
uint16_t x, y, z;
|
||||
ts.readData(&x, &y, &z);
|
||||
|
||||
or with getPoint(), which returns a TS_Point object:
|
||||
|
||||
TS_Point p = ts.getPoint();
|
||||
Serial.print("x = ");
|
||||
Serial.print(p.x);
|
||||
Serial.print(", y = ");
|
||||
Serial.print(p.y);
|
||||
|
||||
The Z coordinate represents the amount of pressure applied to the screen.
|
||||
|
||||
## Adafruit Library Compatibility
|
||||
|
||||
XPT2046_Touchscreen is meant to be a compatible with sketches written for Adafruit_STMPE610, offering the same functions, parameters and numerical ranges as Adafruit's library.
|
||||
|
||||
## Using The Interrupt Pin : Built in support when connected nothing else is needed. When specified as above
|
||||
no SPI calls are made unless a Touch was detected. On normal connections - this means the Teensy LED
|
||||
won't blink on every touch query.
|
||||
|
||||
## Using The Interrupt Pin : Custom use would preclude the normal built in usage. The warning below is justified.
|
||||
|
||||
The XPT2046 chip has an interrupt output, which is typically labeled T_IRQ on many low cost TFT displays. No special software support is needed in this library. The interrupt pin always outputs a digital signal related to the touch controller signals, which is LOW when the display is touched. It also is driven low while software reads the touch position.
|
||||
|
||||
The interrupt can be used as a wakeup signal, if you put your microcontroller into a deep sleep mode. Normally, you would stop reading the touch data, then enable the interrupt pin with attachInterrupt(), and then configure your processor to wake when the interrupt occurs, before enter a deep sleep mode. Upon waking, you would normally disable the interrupt before reading the display, to prevent false interrupts caused by the process of reading touch positions.
|
||||
|
||||
You can also use the interrupt to respond to touch events. Setup might look similar to this:
|
||||
|
||||
SPI.usingInterrupt(digitalPinToInterrupt(pin))
|
||||
attachInterrupt(digitalPinToInterrupt(pin), myFunction, FALLING);
|
||||
|
||||
However, inside your interrupt function, if the display is no longer being touched, any attempt to read the touch position will cause the interrupt pin to create another falling edge. This can lead to an infinite loop of falsely triggered interrupts. Special care is needed to avoid triggering more interrupts on the low signal due to reading the touch position.
|
||||
|
||||
For most applications, regularly reading the touch position from the main program is much simpler.
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
/* Touchscreen library for XPT2046 Touch Controller Chip
|
||||
* Copyright (c) 2015, Paul Stoffregen, paul@pjrc.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice, development funding notice, and this permission
|
||||
* notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "XPT2046_Touchscreen.h"
|
||||
|
||||
#define Z_THRESHOLD 400
|
||||
#define Z_THRESHOLD_INT 75
|
||||
#define MSEC_THRESHOLD 3
|
||||
#define SPI_SETTING SPISettings(2000000, MSBFIRST, SPI_MODE0)
|
||||
|
||||
static XPT2046_Touchscreen *isrPinptr;
|
||||
void isrPin(void);
|
||||
|
||||
bool XPT2046_Touchscreen::begin(SPIClass &wspi)
|
||||
{
|
||||
_pspi = &wspi;
|
||||
_pspi->begin();
|
||||
pinMode(csPin, OUTPUT);
|
||||
digitalWrite(csPin, HIGH);
|
||||
if (255 != tirqPin) {
|
||||
pinMode( tirqPin, INPUT );
|
||||
attachInterrupt(digitalPinToInterrupt(tirqPin), isrPin, FALLING);
|
||||
isrPinptr = this;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(_FLEXIO_SPI_H_)
|
||||
#define FLEXSPI_SETTING FlexIOSPISettings(2000000, MSBFIRST, SPI_MODE0)
|
||||
bool XPT2046_Touchscreen::begin(FlexIOSPI &wflexspi)
|
||||
{
|
||||
_pspi = nullptr; // make sure we dont use this one...
|
||||
_pflexspi = &wflexspi;
|
||||
_pflexspi->begin();
|
||||
pinMode(csPin, OUTPUT);
|
||||
digitalWrite(csPin, HIGH);
|
||||
if (255 != tirqPin) {
|
||||
pinMode( tirqPin, INPUT );
|
||||
attachInterrupt(digitalPinToInterrupt(tirqPin), isrPin, FALLING);
|
||||
isrPinptr = this;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
ISR_PREFIX
|
||||
void isrPin( void )
|
||||
{
|
||||
XPT2046_Touchscreen *o = isrPinptr;
|
||||
o->isrWake = true;
|
||||
}
|
||||
|
||||
TS_Point XPT2046_Touchscreen::getPoint()
|
||||
{
|
||||
update();
|
||||
return TS_Point(xraw, yraw, zraw);
|
||||
}
|
||||
|
||||
bool XPT2046_Touchscreen::tirqTouched()
|
||||
{
|
||||
return (isrWake);
|
||||
}
|
||||
|
||||
bool XPT2046_Touchscreen::touched()
|
||||
{
|
||||
update();
|
||||
return (zraw >= Z_THRESHOLD);
|
||||
}
|
||||
|
||||
void XPT2046_Touchscreen::readData(uint16_t *x, uint16_t *y, uint8_t *z)
|
||||
{
|
||||
update();
|
||||
*x = xraw;
|
||||
*y = yraw;
|
||||
*z = zraw;
|
||||
}
|
||||
|
||||
bool XPT2046_Touchscreen::bufferEmpty()
|
||||
{
|
||||
return ((millis() - msraw) < MSEC_THRESHOLD);
|
||||
}
|
||||
|
||||
static int16_t besttwoavg( int16_t x , int16_t y , int16_t z ) {
|
||||
int16_t da, db, dc;
|
||||
int16_t reta = 0;
|
||||
if ( x > y ) da = x - y; else da = y - x;
|
||||
if ( x > z ) db = x - z; else db = z - x;
|
||||
if ( z > y ) dc = z - y; else dc = y - z;
|
||||
|
||||
if ( da <= db && da <= dc ) reta = (x + y) >> 1;
|
||||
else if ( db <= da && db <= dc ) reta = (x + z) >> 1;
|
||||
else reta = (y + z) >> 1; // else if ( dc <= da && dc <= db ) reta = (x + y) >> 1;
|
||||
|
||||
return (reta);
|
||||
}
|
||||
|
||||
// TODO: perhaps a future version should offer an option for more oversampling,
|
||||
// with the RANSAC algorithm https://en.wikipedia.org/wiki/RANSAC
|
||||
|
||||
void XPT2046_Touchscreen::update()
|
||||
{
|
||||
int16_t data[6];
|
||||
int z;
|
||||
if (!isrWake) return;
|
||||
uint32_t now = millis();
|
||||
if (now - msraw < MSEC_THRESHOLD) return;
|
||||
if (_pspi) {
|
||||
_pspi->beginTransaction(SPI_SETTING);
|
||||
digitalWrite(csPin, LOW);
|
||||
_pspi->transfer(0xB1 /* Z1 */);
|
||||
int16_t z1 = _pspi->transfer16(0xC1 /* Z2 */) >> 3;
|
||||
z = z1 + 4095;
|
||||
int16_t z2 = _pspi->transfer16(0x91 /* X */) >> 3;
|
||||
z -= z2;
|
||||
if (z >= Z_THRESHOLD) {
|
||||
_pspi->transfer16(0x91 /* X */); // dummy X measure, 1st is always noisy
|
||||
data[0] = _pspi->transfer16(0xD1 /* Y */) >> 3;
|
||||
data[1] = _pspi->transfer16(0x91 /* X */) >> 3; // make 3 x-y measurements
|
||||
data[2] = _pspi->transfer16(0xD1 /* Y */) >> 3;
|
||||
data[3] = _pspi->transfer16(0x91 /* X */) >> 3;
|
||||
}
|
||||
else data[0] = data[1] = data[2] = data[3] = 0; // Compiler warns these values may be used unset on early exit.
|
||||
data[4] = _pspi->transfer16(0xD0 /* Y */) >> 3; // Last Y touch power down
|
||||
data[5] = _pspi->transfer16(0) >> 3;
|
||||
digitalWrite(csPin, HIGH);
|
||||
_pspi->endTransaction();
|
||||
}
|
||||
#if defined(_FLEXIO_SPI_H_)
|
||||
else if (_pflexspi) {
|
||||
_pflexspi->beginTransaction(FLEXSPI_SETTING);
|
||||
digitalWrite(csPin, LOW);
|
||||
_pflexspi->transfer(0xB1 /* Z1 */);
|
||||
int16_t z1 = _pflexspi->transfer16(0xC1 /* Z2 */) >> 3;
|
||||
z = z1 + 4095;
|
||||
int16_t z2 = _pflexspi->transfer16(0x91 /* X */) >> 3;
|
||||
z -= z2;
|
||||
if (z >= Z_THRESHOLD) {
|
||||
_pflexspi->transfer16(0x91 /* X */); // dummy X measure, 1st is always noisy
|
||||
data[0] = _pflexspi->transfer16(0xD1 /* Y */) >> 3;
|
||||
data[1] = _pflexspi->transfer16(0x91 /* X */) >> 3; // make 3 x-y measurements
|
||||
data[2] = _pflexspi->transfer16(0xD1 /* Y */) >> 3;
|
||||
data[3] = _pflexspi->transfer16(0x91 /* X */) >> 3;
|
||||
}
|
||||
else data[0] = data[1] = data[2] = data[3] = 0; // Compiler warns these values may be used unset on early exit.
|
||||
data[4] = _pflexspi->transfer16(0xD0 /* Y */) >> 3; // Last Y touch power down
|
||||
data[5] = _pflexspi->transfer16(0) >> 3;
|
||||
digitalWrite(csPin, HIGH);
|
||||
_pflexspi->endTransaction();
|
||||
|
||||
}
|
||||
#endif
|
||||
// If we do not have either _pspi or _pflexspi than bail.
|
||||
else return;
|
||||
|
||||
//Serial.printf("z=%d :: z1=%d, z2=%d ", z, z1, z2);
|
||||
if (z < 0) z = 0;
|
||||
if (z < Z_THRESHOLD) { // if ( !touched ) {
|
||||
// Serial.println();
|
||||
zraw = 0;
|
||||
if (z < Z_THRESHOLD_INT) { // if ( !touched ) {
|
||||
if (255 != tirqPin) isrWake = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
zraw = z;
|
||||
|
||||
// Average pair with least distance between each measured x then y
|
||||
//Serial.printf(" z1=%d,z2=%d ", z1, z2);
|
||||
//Serial.printf("p=%d, %d,%d %d,%d %d,%d", zraw,
|
||||
//data[0], data[1], data[2], data[3], data[4], data[5]);
|
||||
int16_t x = besttwoavg( data[0], data[2], data[4] );
|
||||
int16_t y = besttwoavg( data[1], data[3], data[5] );
|
||||
|
||||
//Serial.printf(" %d,%d", x, y);
|
||||
//Serial.println();
|
||||
if (z >= Z_THRESHOLD) {
|
||||
msraw = now; // good read completed, set wait
|
||||
switch (rotation) {
|
||||
case 0:
|
||||
xraw = 4095 - y;
|
||||
yraw = x;
|
||||
break;
|
||||
case 1:
|
||||
xraw = x;
|
||||
yraw = y;
|
||||
break;
|
||||
case 2:
|
||||
xraw = y;
|
||||
yraw = 4095 - x;
|
||||
break;
|
||||
default: // 3
|
||||
xraw = 4095 - x;
|
||||
yraw = 4095 - y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/* Touchscreen library for XPT2046 Touch Controller Chip
|
||||
* Copyright (c) 2015, Paul Stoffregen, paul@pjrc.com
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice, development funding notice, and this permission
|
||||
* notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _XPT2046_Touchscreen_h_
|
||||
#define _XPT2046_Touchscreen_h_
|
||||
|
||||
#include "Arduino.h"
|
||||
#include <SPI.h>
|
||||
|
||||
#if defined(__IMXRT1062__)
|
||||
#if __has_include(<FlexIOSPI.h>)
|
||||
#include <FlexIOSPI.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ARDUINO < 10600
|
||||
#error "Arduino 1.6.0 or later (SPI library) is required"
|
||||
#endif
|
||||
|
||||
class TS_Point {
|
||||
public:
|
||||
TS_Point(void) : x(0), y(0), z(0) {}
|
||||
TS_Point(int16_t x, int16_t y, int16_t z) : x(x), y(y), z(z) {}
|
||||
bool operator==(TS_Point p) { return ((p.x == x) && (p.y == y) && (p.z == z)); }
|
||||
bool operator!=(TS_Point p) { return ((p.x != x) || (p.y != y) || (p.z != z)); }
|
||||
int16_t x, y, z;
|
||||
};
|
||||
|
||||
class XPT2046_Touchscreen {
|
||||
public:
|
||||
constexpr XPT2046_Touchscreen(uint8_t cspin, uint8_t tirq=255)
|
||||
: csPin(cspin), tirqPin(tirq) { }
|
||||
bool begin(SPIClass &wspi = SPI);
|
||||
#if defined(_FLEXIO_SPI_H_)
|
||||
bool begin(FlexIOSPI &wflexspi);
|
||||
#endif
|
||||
|
||||
TS_Point getPoint();
|
||||
bool tirqTouched();
|
||||
bool touched();
|
||||
void readData(uint16_t *x, uint16_t *y, uint8_t *z);
|
||||
bool bufferEmpty();
|
||||
uint8_t bufferSize() { return 1; }
|
||||
void setRotation(uint8_t n) { rotation = n % 4; }
|
||||
// protected:
|
||||
volatile bool isrWake=true;
|
||||
|
||||
private:
|
||||
void update();
|
||||
uint8_t csPin, tirqPin, rotation=1;
|
||||
int16_t xraw=0, yraw=0, zraw=0;
|
||||
uint32_t msraw=0x80000000;
|
||||
SPIClass *_pspi = nullptr;
|
||||
#if defined(_FLEXIO_SPI_H_)
|
||||
FlexIOSPI *_pflexspi = nullptr;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef ISR_PREFIX
|
||||
#if defined(ESP8266)
|
||||
#define ISR_PREFIX ICACHE_RAM_ATTR
|
||||
#elif defined(ESP32)
|
||||
// TODO: should this also be ICACHE_RAM_ATTR ??
|
||||
#define ISR_PREFIX IRAM_ATTR
|
||||
#else
|
||||
#define ISR_PREFIX
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
|
@ -0,0 +1,64 @@
|
|||
Please use this form only to report code defects or bugs.
|
||||
|
||||
For any question, even questions directly pertaining to this code, post your question on the forums related to the board you are using.
|
||||
|
||||
Arduino: forum.arduino.cc
|
||||
Teensy: forum.pjrc.com
|
||||
ESP8266: www.esp8266.com
|
||||
ESP32: www.esp32.com
|
||||
Adafruit Feather/Metro/Trinket: forums.adafruit.com
|
||||
Particle Photon: community.particle.io
|
||||
|
||||
If you are experiencing trouble but not certain of the cause, or need help using this code, ask on the appropriate forum. This is not the place to ask for support or help, even directly related to this code. Only use this form you are certain you have discovered a defect in this code!
|
||||
|
||||
Please verify the problem occurs when using the very latest version, using the newest version of Arduino and any other related software.
|
||||
|
||||
|
||||
----------------------------- Remove above -----------------------------
|
||||
|
||||
|
||||
|
||||
### Description
|
||||
|
||||
Describe your problem.
|
||||
|
||||
|
||||
|
||||
### Steps To Reproduce Problem
|
||||
|
||||
Please give detailed instructions needed for anyone to attempt to reproduce the problem.
|
||||
|
||||
|
||||
|
||||
### Hardware & Software
|
||||
|
||||
Board
|
||||
Shields / modules used
|
||||
Arduino IDE version
|
||||
Teensyduino version (if using Teensy)
|
||||
Version info & package name (from Tools > Boards > Board Manager)
|
||||
Operating system & version
|
||||
Any other software or hardware?
|
||||
|
||||
|
||||
### Arduino Sketch
|
||||
|
||||
```cpp
|
||||
// Change the code below by your sketch (please try to give the smallest code which demonstrates the problem)
|
||||
#include <Arduino.h>
|
||||
|
||||
// libraries: give links/details so anyone can compile your code for the same result
|
||||
|
||||
void setup() {
|
||||
}
|
||||
|
||||
void loop() {
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
### Errors or Incorrect Output
|
||||
|
||||
If you see any errors or incorrect output, please show it here. Please use copy & paste to give an exact copy of the message. Details matter, so please show (not merely describe) the actual message or error exactly as it appears.
|
||||
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
#include <ILI9341_t3.h>
|
||||
#include <font_Arial.h> // from ILI9341_t3
|
||||
#include <XPT2046_Touchscreen.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#define CS_PIN 8
|
||||
#define TFT_DC 9
|
||||
#define TFT_CS 10
|
||||
// MOSI=11, MISO=12, SCK=13
|
||||
|
||||
XPT2046_Touchscreen ts(CS_PIN);
|
||||
#define TIRQ_PIN 2
|
||||
//XPT2046_Touchscreen ts(CS_PIN); // Param 2 - NULL - No interrupts
|
||||
//XPT2046_Touchscreen ts(CS_PIN, 255); // Param 2 - 255 - No interrupts
|
||||
//XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN); // Param 2 - Touch IRQ Pin - interrupt enabled polling
|
||||
|
||||
ILI9341_t3 tft = ILI9341_t3(TFT_CS, TFT_DC);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(38400);
|
||||
tft.begin();
|
||||
tft.setRotation(1);
|
||||
tft.fillScreen(ILI9341_BLACK);
|
||||
ts.begin();
|
||||
ts.setRotation(1);
|
||||
while (!Serial && (millis() <= 1000));
|
||||
}
|
||||
|
||||
boolean wastouched = true;
|
||||
|
||||
void loop() {
|
||||
boolean istouched = ts.touched();
|
||||
if (istouched) {
|
||||
TS_Point p = ts.getPoint();
|
||||
if (!wastouched) {
|
||||
tft.fillScreen(ILI9341_BLACK);
|
||||
tft.setTextColor(ILI9341_YELLOW);
|
||||
tft.setFont(Arial_60);
|
||||
tft.setCursor(60, 80);
|
||||
tft.print("Touch");
|
||||
}
|
||||
tft.fillRect(100, 150, 140, 60, ILI9341_BLACK);
|
||||
tft.setTextColor(ILI9341_GREEN);
|
||||
tft.setFont(Arial_24);
|
||||
tft.setCursor(100, 150);
|
||||
tft.print("X = ");
|
||||
tft.print(p.x);
|
||||
tft.setCursor(100, 180);
|
||||
tft.print("Y = ");
|
||||
tft.print(p.y);
|
||||
Serial.print(", x = ");
|
||||
Serial.print(p.x);
|
||||
Serial.print(", y = ");
|
||||
Serial.println(p.y);
|
||||
} else {
|
||||
if (wastouched) {
|
||||
tft.fillScreen(ILI9341_BLACK);
|
||||
tft.setTextColor(ILI9341_RED);
|
||||
tft.setFont(Arial_48);
|
||||
tft.setCursor(120, 50);
|
||||
tft.print("No");
|
||||
tft.setCursor(80, 120);
|
||||
tft.print("Touch");
|
||||
}
|
||||
Serial.println("no touch");
|
||||
}
|
||||
wastouched = istouched;
|
||||
delay(100);
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#include <XPT2046_Touchscreen.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#define CS_PIN 8
|
||||
// MOSI=11, MISO=12, SCK=13
|
||||
|
||||
//XPT2046_Touchscreen ts(CS_PIN);
|
||||
#define TIRQ_PIN 2
|
||||
//XPT2046_Touchscreen ts(CS_PIN); // Param 2 - NULL - No interrupts
|
||||
//XPT2046_Touchscreen ts(CS_PIN, 255); // Param 2 - 255 - No interrupts
|
||||
XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN); // Param 2 - Touch IRQ Pin - interrupt enabled polling
|
||||
|
||||
void setup() {
|
||||
Serial.begin(38400);
|
||||
ts.begin();
|
||||
ts.setRotation(1);
|
||||
while (!Serial && (millis() <= 1000));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
if (ts.touched()) {
|
||||
TS_Point p = ts.getPoint();
|
||||
Serial.print("Pressure = ");
|
||||
Serial.print(p.z);
|
||||
Serial.print(", x = ");
|
||||
Serial.print(p.x);
|
||||
Serial.print(", y = ");
|
||||
Serial.print(p.y);
|
||||
delay(30);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#include <XPT2046_Touchscreen.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#define CS_PIN 8
|
||||
// MOSI=11, MISO=12, SCK=13
|
||||
|
||||
// The TIRQ interrupt signal must be used for this example.
|
||||
#define TIRQ_PIN 2
|
||||
XPT2046_Touchscreen ts(CS_PIN, TIRQ_PIN); // Param 2 - Touch IRQ Pin - interrupt enabled polling
|
||||
|
||||
void setup() {
|
||||
Serial.begin(38400);
|
||||
ts.begin();
|
||||
ts.setRotation(1);
|
||||
while (!Serial && (millis() <= 1000));
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
// tirqTouched() is much faster than touched(). For projects where other SPI chips
|
||||
// or other time sensitive tasks are added to loop(), using tirqTouched() can greatly
|
||||
// reduce the delay added to loop() when the screen has not been touched.
|
||||
if (ts.tirqTouched()) {
|
||||
if (ts.touched()) {
|
||||
TS_Point p = ts.getPoint();
|
||||
Serial.print("Pressure = ");
|
||||
Serial.print(p.z);
|
||||
Serial.print(", x = ");
|
||||
Serial.print(p.x);
|
||||
Serial.print(", y = ");
|
||||
Serial.print(p.y);
|
||||
delay(30);
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
XPT2046_Touchscreen KEYWORD1
|
||||
TS_Point KEYWORD1
|
||||
getPoint KEYWORD2
|
||||
touched KEYWORD2
|
||||
readData KEYWORD2
|
||||
bufferEmpty KEYWORD2
|
||||
bufferSize KEYWORD2
|
||||
setRotation KEYWORD2
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"name": "XPT2046_Touchscreen",
|
||||
"keywords": "display, tft, lcd, graphics, spi, touchscreen",
|
||||
"description": "Touchscreens using the XPT2046 controller chip. Many very low cost color TFT displays with touch screens have this chip.",
|
||||
"exclude": "doc",
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/PaulStoffregen/XPT2046_Touchscreen.git"
|
||||
},
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*"
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
name=XPT2046_Touchscreen
|
||||
version=1.3
|
||||
author=Paul Stoffregen
|
||||
maintainer=Paul Stoffregen
|
||||
sentence=Touchscreens using the XPT2046 controller chip.
|
||||
paragraph=Many very low cost color TFT displays with touch screens have this chip.
|
||||
category=Display
|
||||
url=https://github.com/PaulStoffregen/XPT2046_Touchscreen
|
||||
architectures=*
|
||||
|
|
@ -504,6 +504,9 @@ void be_gc_collect(bvm *vm)
|
|||
if (vm->gc.status & GC_HALT) {
|
||||
return; /* the GC cannot run for some reason */
|
||||
}
|
||||
#if BE_USE_OBSERVABILITY_HOOK
|
||||
if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_GC_START, vm->gc.usage);
|
||||
#endif
|
||||
/* step 1: set root-set reference objects to unscanned */
|
||||
premark_internal(vm); /* object internal the VM */
|
||||
premark_global(vm); /* global objects */
|
||||
|
@ -520,4 +523,7 @@ void be_gc_collect(bvm *vm)
|
|||
reset_fixedlist(vm);
|
||||
/* step 5: calculate the next GC threshold */
|
||||
vm->gc.threshold = next_threshold(vm->gc);
|
||||
#if BE_USE_OBSERVABILITY_HOOK
|
||||
if (vm->obshook != NULL) (*vm->obshook)(vm, BE_OBS_GC_END, vm->gc.usage);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -398,6 +398,9 @@ BERRY_API bvm* be_vm_new(void)
|
|||
be_globalvar_init(vm);
|
||||
be_gc_setpause(vm, 1);
|
||||
be_loadlibs(vm);
|
||||
#if BE_USE_OBSERVABILITY_HOOK
|
||||
vm->obshook = NULL;
|
||||
#endif
|
||||
return vm;
|
||||
}
|
||||
|
||||
|
@ -1051,3 +1054,10 @@ void be_dofunc(bvm *vm, bvalue *v, int argc)
|
|||
default: call_error(vm, v);
|
||||
}
|
||||
}
|
||||
|
||||
BERRY_API void be_set_obs_hook(bvm *vm, beobshook hook)
|
||||
{
|
||||
#if BE_USE_OBSERVABILITY_HOOK
|
||||
vm->obshook = hook;
|
||||
#endif
|
||||
}
|
|
@ -86,6 +86,9 @@ struct bvm {
|
|||
bmap *ntvclass; /* native class table */
|
||||
blist *registry; /* registry list */
|
||||
struct bgc gc;
|
||||
#if BE_USE_OBSERVABILITY_HOOK
|
||||
beobshook obshook;
|
||||
#endif
|
||||
#if BE_USE_DEBUG_HOOK
|
||||
bvalue hook;
|
||||
bbyte hookmask;
|
||||
|
|
|
@ -273,6 +273,14 @@ typedef void(*bntvhook)(bvm *vm, bhookinfo *info);
|
|||
#define be_assert(expr) ((void)0)
|
||||
#endif
|
||||
|
||||
/* Observability hook */
|
||||
|
||||
typedef void(*beobshook)(bvm *vm, int event, ...);
|
||||
enum beobshookevents {
|
||||
BE_OBS_GC_START, // start of GC, arg = allocated size
|
||||
BE_OBS_GC_END, // end of GC, arg = allocated size
|
||||
};
|
||||
|
||||
/* FFI functions */
|
||||
#define be_writestring(s) be_writebuffer((s), strlen(s))
|
||||
#define be_writenewline() be_writebuffer("\n", 1)
|
||||
|
@ -406,6 +414,9 @@ BERRY_API void be_regclass(bvm *vm, const char *name, const bnfuncinfo *lib);
|
|||
BERRY_API bvm* be_vm_new(void);
|
||||
BERRY_API void be_vm_delete(bvm *vm);
|
||||
|
||||
/* Observability hook */
|
||||
BERRY_API void be_set_obs_hook(bvm *vm, beobshook hook);
|
||||
|
||||
/* code load APIs */
|
||||
BERRY_API int be_loadbuffer(bvm *vm,
|
||||
const char *name, const char *buffer, size_t length);
|
||||
|
|
|
@ -18,6 +18,7 @@ extern int l_respCmndStr(bvm *vm);
|
|||
extern int l_respCmndDone(bvm *vm);
|
||||
extern int l_respCmndError(bvm *vm);
|
||||
extern int l_respCmndFailed(bvm *vm);
|
||||
extern int l_resolveCmnd(bvm *vm);
|
||||
|
||||
// #if !BE_USE_PRECOMPILED_OBJECT
|
||||
#if 1 // TODO we will do pre-compiled later
|
||||
|
@ -36,6 +37,7 @@ be_native_module_attr_table(tasmota_ntv) {
|
|||
be_native_module_function("respcmnd_done", l_respCmndDone),
|
||||
be_native_module_function("respcmnd_error", l_respCmndError),
|
||||
be_native_module_function("respcmnd_failed", l_respCmndFailed),
|
||||
be_native_module_function("resolvecmnd", l_resolveCmnd),
|
||||
|
||||
be_native_module_str("_operators", "=<>!|"),
|
||||
};
|
||||
|
|
|
@ -14,6 +14,8 @@ extern int b_wire_available(bvm *vm);
|
|||
extern int b_wire_write(bvm *vm);
|
||||
extern int b_wire_read(bvm *vm);
|
||||
|
||||
extern int b_wire_validread(bvm *vm);
|
||||
|
||||
// #if !BE_USE_PRECOMPILED_OBJECT
|
||||
#if 1 // TODO we will do pre-compiled later
|
||||
be_native_module_attr_table(wire) {
|
||||
|
@ -23,6 +25,7 @@ be_native_module_attr_table(wire) {
|
|||
be_native_module_function("available", b_wire_available),
|
||||
be_native_module_function("write", b_wire_write),
|
||||
be_native_module_function("read", b_wire_read),
|
||||
be_native_module_function("validread", b_wire_validread),
|
||||
};
|
||||
|
||||
be_define_native_module(wire, NULL);
|
||||
|
|
|
@ -64,6 +64,12 @@
|
|||
**/
|
||||
#define BE_DEBUG_VAR_INFO 0
|
||||
|
||||
/* Macro: BE_USE_OBSERVABILITY_HOOK
|
||||
* Use the obshook function to report low-level actions.
|
||||
* Default: 0
|
||||
**/
|
||||
#define BE_USE_OBSERVABILITY_HOOK 1
|
||||
|
||||
/* Macro: BE_STACK_TOTAL_MAX
|
||||
* Set the maximum total stack size.
|
||||
* Default: 20000
|
||||
|
|
|
@ -124,16 +124,16 @@ lib_extra_dirs = ${library.lib_extra_dirs}
|
|||
|
||||
[core32]
|
||||
; Activate Stage Core32 by removing ";" in next 3 lines, if you want to override the standard core32
|
||||
platform_packages = ${core32_stage.platform_packages}
|
||||
build_unflags = ${core32_stage.build_unflags}
|
||||
build_flags = ${core32_stage.build_flags}
|
||||
;platform_packages = ${core32_stage.platform_packages}
|
||||
;build_unflags = ${core32_stage.build_unflags}
|
||||
;build_flags = ${core32_stage.build_flags}
|
||||
|
||||
[core32_stage]
|
||||
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/1.0.5-rc7/esp32-1.0.5-rc7.zip
|
||||
platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git
|
||||
platformio/tool-mklittlefs @ ~1.203.200522
|
||||
build_unflags = ${esp32_defaults.build_unflags}
|
||||
build_flags = ${esp32_defaults.build_flags}
|
||||
;-DESP32_STAGE=true
|
||||
-DESP32_STAGE=true
|
||||
|
||||
[library]
|
||||
shared_libdeps_dir = lib
|
||||
|
|
|
@ -94,8 +94,7 @@ build_flags = ${esp_defaults.build_flags}
|
|||
|
||||
|
||||
[core32]
|
||||
platform = espressif32 @ 3.0.0
|
||||
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/arduino-esp32/releases/download/1.0.5-rc6/esp32-1.0.5-rc6.zip
|
||||
platformio/tool-mklittlefs @ ~1.203.200522
|
||||
platform = espressif32 @ 3.1.0
|
||||
platform_packages = platformio/tool-mklittlefs @ ~1.203.200522
|
||||
build_unflags = ${esp32_defaults.build_unflags}
|
||||
build_flags = ${esp32_defaults.build_flags}
|
||||
|
|
|
@ -550,7 +550,7 @@
|
|||
#define D_CMND_ZIGBEE_PERMITJOIN "PermitJoin"
|
||||
#define D_CMND_ZIGBEE_STATUS "Status"
|
||||
#define D_CMND_ZIGBEE_RESET "Reset"
|
||||
#define D_JSON_ZIGBEE_CC2530 "CC2530"
|
||||
#define D_JSON_ZIGBEE_CC2530 "CCxxxx"
|
||||
#define D_JSON_ZIGBEE_EZSP "EZSP"
|
||||
#define D_CMND_ZIGBEEZNPRECEIVE "ZNPReceive" // only for debug
|
||||
#define D_CMND_ZIGBEE_EZSP_RECEIVE "EZSPReceive" // only for debug
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -673,6 +673,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
#define D_SENSOR_EPAPER29_CS "EPaper29 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -670,6 +670,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 TX"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 RX"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 TX"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 RX"
|
||||
#define D_SENSOR_PN532_TX "PN532 TX"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
#define D_SENSOR_EPAPER29_CS "EPaper29 CS"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_EPAPER42_CS "EPaper42 CS"
|
||||
#define D_SENSOR_SSD1351_CS "SSD1351 CS"
|
||||
#define D_SENSOR_SSD1351_DC "SSD1351 DC"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -666,7 +666,7 @@
|
|||
#define D_SENSOR_MAX31855_CS "MX31855 - CS"
|
||||
#define D_SENSOR_MAX31855_CLK "MX31855 - CLK"
|
||||
#define D_SENSOR_MAX31855_DO "MX31855 - DO"
|
||||
#define D_SENSOR_MAX31865_CS "MX31865 CS"
|
||||
#define D_SENSOR_MAX31865_CS "MX31865 - CS"
|
||||
#define D_SENSOR_NRG_SEL "HLWBL - SEL" // Suffix "i"
|
||||
#define D_SENSOR_NRG_CF1 "HLWBL - CF1"
|
||||
#define D_SENSOR_HLW_CF "HLW8012 - CF"
|
||||
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 - TX"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 - RX"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 - Reset"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 - Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 - Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 - TX"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 - RX"
|
||||
#define D_SENSOR_PN532_TX "PN532 - TX"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 - CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 - CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 - DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 - CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 - CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 - DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 - CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -674,6 +674,8 @@
|
|||
#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx"
|
||||
#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx"
|
||||
#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst"
|
||||
#define D_SENSOR_CSE7761_TX "CSE7761 Tx"
|
||||
#define D_SENSOR_CSE7761_RX "CSE7761 Rx"
|
||||
#define D_SENSOR_CSE7766_TX "CSE7766 Tx"
|
||||
#define D_SENSOR_CSE7766_RX "CSE7766 Rx"
|
||||
#define D_SENSOR_PN532_TX "PN532 Tx"
|
||||
|
@ -777,6 +779,7 @@
|
|||
#define D_SENSOR_RC522_CS "RC522 CS"
|
||||
#define D_SENSOR_NRF24_CS "NRF24 CS"
|
||||
#define D_SENSOR_NRF24_DC "NRF24 DC"
|
||||
#define D_SENSOR_XPT2046_CS "XPT2046 CS"
|
||||
#define D_SENSOR_ILI9341_CS "ILI9341 CS"
|
||||
#define D_SENSOR_ILI9341_DC "ILI9341 DC"
|
||||
#define D_SENSOR_ILI9488_CS "ILI9488 CS"
|
||||
|
|
|
@ -275,8 +275,11 @@
|
|||
#define KEY_SWAP_DOUBLE_PRESS false // [SetOption11] Swap button single and double press functionality
|
||||
#define KEY_ONLY_SINGLE_PRESS false // [SetOption13] Enable only single press to speed up button press recognition
|
||||
|
||||
#define MQTT_BUTTONS false // [SetOption73] Detach buttons from relays and send multi-press and hold MQTT messages instead
|
||||
|
||||
#define SWITCH_DEBOUNCE_TIME 50 // [SwitchDebounce] Number of mSeconds switch press debounce time
|
||||
#define SWITCH_MODE TOGGLE // [SwitchMode] TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, TOGGLEMULTI, FOLLOWMULTI, FOLLOWMULTI_INV (the wall switch state)
|
||||
#define MQTT_SWITCHES false // [SetOption114] Detach switches from relays and send MQTT messages instead
|
||||
|
||||
#define TEMP_CONVERSION false // [SetOption8] Return temperature in (false = Celsius or true = Fahrenheit)
|
||||
#define PRESSURE_CONVERSION false // [SetOption24] Return pressure in (false = hPa or true = mmHg)
|
||||
|
@ -330,6 +333,7 @@
|
|||
#define SHUTTER_SUPPORT false // [SetOption80] Enable shutter support
|
||||
#define PCF8574_INVERT_PORTS false // [SetOption81] Invert all ports on PCF8574 devices
|
||||
#define ZIGBEE_FRIENDLY_NAMES false // [SetOption83] Enable Zigbee FriendlyNames instead of ShortAddresses when possible
|
||||
#define ZIGBEE_DISTINCT_TOPICS false // [SetOption89] Enable unique device topic based on Zigbee device ShortAddr
|
||||
#define ZIGBEE_RMV_ZBRECEIVED false // [SetOption100] Remove ZbReceived form JSON message
|
||||
#define ZIGBEE_INDEX_EP false // [SetOption101] Add the source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3
|
||||
|
||||
|
@ -515,6 +519,9 @@
|
|||
|
||||
// -- I2C sensors ---------------------------------
|
||||
#define USE_I2C // I2C using library wire (+10k code, 0k2 mem, 124 iram)
|
||||
#define I2CDRIVERS_0_31 0xFFFFFFFF // Enable I2CDriver0 to I2CDriver31
|
||||
#define I2CDRIVERS_32_63 0xFFFFFFFF // Enable I2CDriver32 to I2CDriver63
|
||||
#define I2CDRIVERS_64_95 0xFFFFFFFF // Enable I2CDriver64 to I2CDriver95
|
||||
|
||||
#ifdef USE_I2C
|
||||
// #define USE_SHT // [I2cDriver8] Enable SHT1X sensor (+1k4 code)
|
||||
|
@ -883,6 +890,8 @@
|
|||
//#define USE_IBEACON_ESP32
|
||||
//#define USE_WEBCAM // Add support for webcam
|
||||
|
||||
#define USE_CSE7761 // Add support for CSE7761 Energy monitor as used in Sonoff Dual R3
|
||||
|
||||
#endif // ESP32
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
|
|
@ -327,6 +327,18 @@ typedef struct {
|
|||
uint8_t dpid = 0;
|
||||
} TuyaFnidDpidMap;
|
||||
|
||||
typedef union {
|
||||
uint8_t data;
|
||||
struct {
|
||||
uint8_t ilimode : 3;
|
||||
uint8_t Invert : 1;
|
||||
uint8_t spare2 : 1;
|
||||
uint8_t spare3 : 1;
|
||||
uint8_t spare4 : 1;
|
||||
uint8_t spare5 : 1;
|
||||
};
|
||||
} DisplayOptions;
|
||||
|
||||
const uint32_t settings_text_size = 699; // Settings.text_pool[size] = Settings.display_model (2D2) - Settings.text_pool (017)
|
||||
const uint8_t MAX_TUYA_FUNCTIONS = 16;
|
||||
|
||||
|
@ -355,7 +367,6 @@ struct {
|
|||
uint8_t text_pool_290[66]; // 290
|
||||
|
||||
// End of single char array of 698 chars max ****************
|
||||
|
||||
uint8_t display_model; // 2D2
|
||||
uint8_t display_mode; // 2D3
|
||||
uint8_t display_refresh; // 2D4
|
||||
|
@ -375,7 +386,7 @@ struct {
|
|||
uint8_t param[PARAM8_SIZE]; // 2FC SetOption32 .. SetOption49
|
||||
int16_t toffset[2]; // 30E
|
||||
uint8_t display_font; // 312
|
||||
uint8_t display_type; // 313
|
||||
DisplayOptions display_options; // 313
|
||||
|
||||
uint8_t free_314[43]; // 314
|
||||
|
||||
|
|
|
@ -726,6 +726,7 @@ void SettingsDefaultSet2(void) {
|
|||
flag3.no_power_feedback |= APP_NO_RELAY_SCAN;
|
||||
flag3.fast_power_cycle_disable |= APP_DISABLE_POWERCYCLE;
|
||||
flag3.bootcount_update |= DEEPSLEEP_BOOTCOUNT;
|
||||
flag3.mqtt_buttons |= MQTT_BUTTONS;
|
||||
Settings.save_data = SAVE_DATA;
|
||||
Settings.param[P_BACKLOG_DELAY] = MIN_BACKLOG_DELAY;
|
||||
Settings.param[P_BOOT_LOOP_OFFSET] = BOOT_LOOP_OFFSET; // SetOption36
|
||||
|
@ -833,6 +834,7 @@ void SettingsDefaultSet2(void) {
|
|||
flag.mqtt_sensor_retain |= MQTT_SENSOR_RETAIN;
|
||||
flag5.mqtt_info_retain |= MQTT_INFO_RETAIN;
|
||||
flag5.mqtt_state_retain |= MQTT_STATE_RETAIN;
|
||||
flag5.mqtt_switches |= MQTT_SWITCHES;
|
||||
// flag.mqtt_serial |= 0;
|
||||
flag.device_index_enable |= MQTT_POWER_FORMAT;
|
||||
flag3.time_append_timezone |= MQTT_APPEND_TIMEZONE;
|
||||
|
@ -1058,6 +1060,7 @@ void SettingsDefaultSet2(void) {
|
|||
flag3.shutter_mode |= SHUTTER_SUPPORT;
|
||||
flag3.pcf8574_ports_inverted |= PCF8574_INVERT_PORTS;
|
||||
flag4.zigbee_use_names |= ZIGBEE_FRIENDLY_NAMES;
|
||||
flag4.zigbee_distinct_topics |= ZIGBEE_DISTINCT_TOPICS;
|
||||
flag4.remove_zbreceived |= ZIGBEE_RMV_ZBRECEIVED;
|
||||
flag4.zb_index_ep |= ZIGBEE_INDEX_EP;
|
||||
flag4.mqtt_tls |= MQTT_TLS_ENABLED;
|
||||
|
@ -1072,6 +1075,7 @@ void SettingsDefaultSet2(void) {
|
|||
Settings.flag2 = flag2;
|
||||
Settings.flag3 = flag3;
|
||||
Settings.flag4 = flag4;
|
||||
Settings.flag5 = flag5;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
@ -1102,9 +1106,9 @@ void SettingsDefaultWebColor(void) {
|
|||
}
|
||||
|
||||
void SettingsEnableAllI2cDrivers(void) {
|
||||
Settings.i2c_drivers[0] = 0xFFFFFFFF;
|
||||
Settings.i2c_drivers[1] = 0xFFFFFFFF;
|
||||
Settings.i2c_drivers[2] = 0xFFFFFFFF;
|
||||
Settings.i2c_drivers[0] = I2CDRIVERS_0_31;
|
||||
Settings.i2c_drivers[1] = I2CDRIVERS_32_63;
|
||||
Settings.i2c_drivers[2] = I2CDRIVERS_64_95;
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
|
|
@ -238,6 +238,11 @@ const uint32_t LOOP_SLEEP_DELAY = 50; // Lowest number of milliseconds to
|
|||
#define KNX_MAX_device_param 31
|
||||
#define MAX_KNXTX_CMNDS 5
|
||||
|
||||
// XPT2046 resistive touch driver min/max raw values
|
||||
#define XPT2046_MINX 192
|
||||
#define XPT2046_MAXX 3895
|
||||
#define XPT2046_MINY 346
|
||||
#define XPT2046_MAXY 3870
|
||||
/*********************************************************************************************\
|
||||
* Enumeration
|
||||
\*********************************************************************************************/
|
||||
|
|
|
@ -153,6 +153,8 @@ enum UserSelectablePins {
|
|||
GPIO_TM1638CLK, GPIO_TM1638DIO, GPIO_TM1638STB, // TM1638 interface
|
||||
GPIO_PROJECTOR_CTRL_TX, GPIO_PROJECTOR_CTRL_RX, // LCD/DLP Projector Serial Control
|
||||
GPIO_SSD1351_DC,
|
||||
GPIO_XPT2046_CS, // XPT2046 SPI Chip Select
|
||||
GPIO_CSE7761_TX, GPIO_CSE7761_RX, // CSE7761 Serial interface (Dual R3)
|
||||
GPIO_SENSOR_END };
|
||||
|
||||
enum ProgramSelectablePins {
|
||||
|
@ -326,6 +328,8 @@ const char kSensorNames[] PROGMEM =
|
|||
D_SENSOR_TM1638_CLK "|" D_SENSOR_TM1638_DIO "|" D_SENSOR_TM1638_STB "|"
|
||||
D_SENSOR_PROJECTOR_CTRL_TX "|" D_SENSOR_PROJECTOR_CTRL_RX "|"
|
||||
D_SENSOR_SSD1351_DC "|"
|
||||
D_SENSOR_XPT2046_CS "|"
|
||||
D_SENSOR_CSE7761_TX "|" D_SENSOR_CSE7761_RX "|"
|
||||
;
|
||||
|
||||
const char kSensorNamesFixed[] PROGMEM =
|
||||
|
@ -415,6 +419,10 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
|||
#ifdef USE_DISPLAY_ILI9341
|
||||
AGPIO(GPIO_ILI9341_CS),
|
||||
AGPIO(GPIO_ILI9341_DC),
|
||||
#ifdef USE_XPT2046
|
||||
AGPIO(GPIO_XPT2046_CS), // XPT2046 SPI Chip Select
|
||||
#endif
|
||||
|
||||
#endif // USE_DISPLAY_ILI9341
|
||||
#ifdef USE_DISPLAY_ILI9488
|
||||
AGPIO(GPIO_ILI9488_CS),
|
||||
|
@ -568,6 +576,10 @@ const uint16_t kGpioNiceList[] PROGMEM = {
|
|||
#if defined(USE_I2C) && defined(USE_ADE7953)
|
||||
AGPIO(GPIO_ADE7953_IRQ), // ADE7953 IRQ
|
||||
#endif
|
||||
#ifdef USE_CSE7761
|
||||
AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3)
|
||||
AGPIO(GPIO_CSE7761_RX), // CSE7761 Serial interface (Dual R3)
|
||||
#endif
|
||||
#ifdef USE_CSE7766
|
||||
AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2)
|
||||
AGPIO(GPIO_CSE7766_RX), // CSE7766 Serial interface (S31 and Pow R2)
|
||||
|
@ -2623,7 +2635,7 @@ const mytmplt kModules[] PROGMEM = {
|
|||
AGPIO(GPIO_USER), // 2 IO GPIO2, SPKR_DATA
|
||||
AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD
|
||||
AGPIO(GPIO_SDCARD_CS), // 4 IO GPIO4, SPI_CS_CARD
|
||||
0, // 5 IO GPIO5, SPI_CS_LCD
|
||||
AGPIO(GPIO_ILI9341_CS), // 5 IO GPIO5, SPI_CS_LCD
|
||||
// 6 IO GPIO6, Flash CLK
|
||||
// 7 IO GPIO7, Flash D0
|
||||
// 8 IO GPIO8, Flash D1
|
||||
|
@ -2633,7 +2645,7 @@ const mytmplt kModules[] PROGMEM = {
|
|||
0, // 12 (I)O GPIO12, SPKR_CLK
|
||||
AGPIO(GPIO_USER), // 13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER
|
||||
AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2
|
||||
0, // 15 (I)O GPIO15, SPI_DC_LCD
|
||||
AGPIO(GPIO_ILI9341_DC), // 15 (I)O GPIO15, SPI_DC_LCD
|
||||
0, // 16 IO GPIO16, PSRAM_CS
|
||||
0, // 17 IO GPIO17, PSRAM_CLK
|
||||
AGPIO(GPIO_SPI_CLK), // 18 IO GPIO18, SPI_CLK
|
||||
|
|
|
@ -82,6 +82,7 @@ Examples :
|
|||
#define WIFI_DNS MY_DNS // If not using DHCP set DNS IP address (might be equal to WIFI_GATEWAY)
|
||||
#endif
|
||||
|
||||
// !!! Remember that your changes GOES AT THE BOTTOM OF THIS FILE right before the last #endif !!!
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -84,6 +84,8 @@ const uint8_t DISPLAY_LOG_ROWS = 32; // Number of lines in display log
|
|||
#define D_CMND_DISP_SCROLLTEXT "ScrollText"
|
||||
#define D_CMND_DISP_TYPE "Type"
|
||||
|
||||
#define D_CMND_DISP_ILIMODE "ILIMode"
|
||||
#define D_CMND_DISP_ILIINVERT "Invert"
|
||||
|
||||
|
||||
enum XdspFunctions { FUNC_DISPLAY_INIT_DRIVER, FUNC_DISPLAY_INIT, FUNC_DISPLAY_EVERY_50_MSECOND, FUNC_DISPLAY_EVERY_SECOND,
|
||||
|
@ -115,7 +117,7 @@ const char kDisplayCommands[] PROGMEM = D_PRFX_DISPLAY "|" // Prefix
|
|||
"|" D_CMND_DISP_CLEAR "|" D_CMND_DISP_NUMBER "|" D_CMND_DISP_FLOAT "|" D_CMND_DISP_NUMBERNC "|" D_CMND_DISP_FLOATNC "|"
|
||||
D_CMND_DISP_BRIGHTNESS "|" D_CMND_DISP_RAW "|" D_CMND_DISP_LEVEL "|" D_CMND_DISP_SEVENSEG_TEXT "|" D_CMND_DISP_SEVENSEG_TEXTNC "|"
|
||||
D_CMND_DISP_SCROLLDELAY "|" D_CMND_DISP_CLOCK "|" D_CMND_DISP_TEXTNC "|" D_CMND_DISP_SETLEDS "|" D_CMND_DISP_SETLED "|"
|
||||
D_CMND_DISP_BUTTONS "|" D_CMND_DISP_SCROLLTEXT "|" D_CMND_DISP_TYPE
|
||||
D_CMND_DISP_BUTTONS "|" D_CMND_DISP_SCROLLTEXT "|" D_CMND_DISP_TYPE "|" D_CMND_DISP_ILIMODE "|" D_CMND_DISP_ILIINVERT
|
||||
;
|
||||
|
||||
void (* const DisplayCommand[])(void) PROGMEM = {
|
||||
|
@ -128,7 +130,7 @@ void (* const DisplayCommand[])(void) PROGMEM = {
|
|||
, &CmndDisplayClear, &CmndDisplayNumber, &CmndDisplayFloat, &CmndDisplayNumberNC, &CmndDisplayFloatNC,
|
||||
&CmndDisplayBrightness, &CmndDisplayRaw, &CmndDisplayLevel, &CmndDisplaySevensegText, &CmndDisplaySevensegTextNC,
|
||||
&CmndDisplayScrollDelay, &CmndDisplayClock, &CmndDisplayTextNC, &CmndDisplaySetLEDs, &CmndDisplaySetLED,
|
||||
&CmndDisplayButtons, &CmndDisplayScrollText, &CmndDisplayType
|
||||
&CmndDisplayButtons, &CmndDisplayScrollText, &CmndDisplayType, &CmndDisplayILIMOde , &CmndDisplayILIInvert
|
||||
};
|
||||
|
||||
char *dsp_str;
|
||||
|
@ -1904,13 +1906,13 @@ void CmndDisplayScrollText(void)
|
|||
void CmndDisplayType(void)
|
||||
{
|
||||
if(ArgC() == 0) {
|
||||
XdrvMailbox.payload = Settings.display_type;
|
||||
XdrvMailbox.payload = Settings.display_options.data;
|
||||
} else {
|
||||
uint8_t prev_type = Settings.display_type;
|
||||
uint8_t prev_type = Settings.display_options.data;
|
||||
if(prev_type != XdrvMailbox.payload) {
|
||||
if (!renderer) {
|
||||
XdspCall(FUNC_DISPLAY_TYPE);
|
||||
Settings.display_type = XdrvMailbox.payload;
|
||||
Settings.display_options.data = XdrvMailbox.payload;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1941,10 +1943,29 @@ void CmndDisplayFont(void)
|
|||
ResponseCmndNumber(Settings.display_font);
|
||||
}
|
||||
|
||||
|
||||
void CmndDisplayILIMOde(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload < 16)) {
|
||||
Settings.display_options.ilimode = XdrvMailbox.payload;
|
||||
TasmotaGlobal.restart_flag = 2;
|
||||
}
|
||||
ResponseCmndNumber(Settings.display_options.ilimode);
|
||||
}
|
||||
|
||||
void CmndDisplayILIInvert(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) {
|
||||
Settings.display_options.Invert = XdrvMailbox.payload;
|
||||
if (renderer) renderer->invertDisplay(Settings.display_options.Invert);
|
||||
}
|
||||
ResponseCmndNumber(Settings.display_options.Invert);
|
||||
}
|
||||
|
||||
void CmndDisplayRotate(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 4)) {
|
||||
if (Settings.display_rotate != XdrvMailbox.payload) {
|
||||
if ((Settings.display_rotate) != XdrvMailbox.payload) {
|
||||
/*
|
||||
// Needs font info regarding height and width
|
||||
if ((Settings.display_rotate &1) != (XdrvMailbox.payload &1)) {
|
||||
|
@ -2033,7 +2054,6 @@ void CmndDisplayRows(void)
|
|||
/*********************************************************************************************\
|
||||
* optional drivers
|
||||
\*********************************************************************************************/
|
||||
|
||||
#ifdef USE_TOUCH_BUTTONS
|
||||
// very limited path size, so, add .jpg
|
||||
void draw_picture(char *path, uint32_t xp, uint32_t yp, uint32_t xs, uint32_t ys, uint32_t ocol, bool inverted) {
|
||||
|
@ -2588,6 +2608,7 @@ void AddValue(uint8_t num,float fval) {
|
|||
}
|
||||
#endif // USE_GRAPH
|
||||
|
||||
#if defined(USE_FT5206) || defined(USE_XPT2046)
|
||||
#ifdef USE_FT5206
|
||||
|
||||
#include <FT5206.h>
|
||||
|
@ -2624,11 +2645,49 @@ uint32_t Touch_Status(uint32_t sel) {
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_XPT2046) && defined(USE_DISPLAY_ILI9341)
|
||||
#include <XPT2046_Touchscreen.h>
|
||||
|
||||
XPT2046_Touchscreen *touchp;
|
||||
TS_Point pLoc;
|
||||
bool XPT2046_found;
|
||||
|
||||
bool Touch_Init(uint16_t CS) {
|
||||
touchp = new XPT2046_Touchscreen(CS);
|
||||
XPT2046_found = touchp->begin();
|
||||
if (XPT2046_found) {
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("TS: XPT2046"));
|
||||
}
|
||||
return XPT2046_found;
|
||||
}
|
||||
|
||||
uint32_t Touch_Status(uint32_t sel) {
|
||||
if (XPT2046_found) {
|
||||
switch (sel) {
|
||||
case 0:
|
||||
return touchp->touched();
|
||||
case 1:
|
||||
return pLoc.x;
|
||||
case 2:
|
||||
return pLoc.y;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_TOUCH_BUTTONS
|
||||
void Touch_MQTT(uint8_t index, const char *cp, uint32_t val) {
|
||||
#if defined(USE_FT5206)
|
||||
ResponseTime_P(PSTR(",\"FT5206\":{\"%s%d\":\"%d\"}}"), cp, index+1, val);
|
||||
#elif defined(USE_XPT2046)
|
||||
ResponseTime_P(PSTR(",\"XPT2046\":{\"%s%d\":\"%d\"}}"), cp, index+1, val);
|
||||
#endif
|
||||
MqttPublishTeleSensor();
|
||||
}
|
||||
|
||||
|
@ -2649,10 +2708,13 @@ uint8_t rbutt=0;
|
|||
uint8_t vbutt=0;
|
||||
|
||||
|
||||
if (touchp->touched()) {
|
||||
if (touchp->touched()) {
|
||||
// did find a hit
|
||||
#if defined(USE_FT5206)
|
||||
pLoc = touchp->getPoint(0);
|
||||
|
||||
#elif defined(USE_XPT2046)
|
||||
pLoc = touchp->getPoint();
|
||||
#endif
|
||||
if (renderer) {
|
||||
|
||||
#ifdef USE_M5STACK_CORE2
|
||||
|
@ -2677,7 +2739,7 @@ uint8_t vbutt=0;
|
|||
|
||||
rotconvert(&pLoc.x, &pLoc.y);
|
||||
|
||||
//AddLog(LOG_LEVEL_INFO, PSTR("touch %d - %d"), pLoc.x, pLoc.y);
|
||||
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("touch after convert %d - %d"), pLoc.x, pLoc.y);
|
||||
// now must compare with defined buttons
|
||||
for (uint8_t count = 0; count < MAX_TOUCH_BUTTONS; count++) {
|
||||
if (buttons[count]) {
|
||||
|
|
|
@ -191,6 +191,9 @@ public:
|
|||
int32_t getInt(void) const;
|
||||
uint32_t getUInt(void) const;
|
||||
bool getBool(void) const;
|
||||
// optimistically try to get any value as literal or in string - double to not lose precision for 32 bits
|
||||
double getOptimisticDouble(void) const;
|
||||
//
|
||||
const SBuffer * getRaw(void) const;
|
||||
|
||||
// always return a point to a string, if not defined then empty string.
|
||||
|
@ -437,6 +440,17 @@ JsonGeneratorArray & Z_attribute::newJsonArray(void) {
|
|||
}
|
||||
|
||||
// get num values
|
||||
double Z_attribute::getOptimisticDouble(void) const {
|
||||
switch (type) {
|
||||
case Za_type::Za_bool:
|
||||
case Za_type::Za_uint: return (double) val.uval32;
|
||||
case Za_type::Za_int: return (double) val.ival32;
|
||||
case Za_type::Za_float: return (double) val.fval;
|
||||
case Za_type::Za_str: return JsonParserToken::json_strtof(val.sval);
|
||||
default: return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
float Z_attribute::getFloat(void) const {
|
||||
switch (type) {
|
||||
case Za_type::Za_bool:
|
||||
|
|
|
@ -1739,6 +1739,10 @@ void ZCLFrame::syntheticAqaraSensor(Z_attribute_list &attr_list, class Z_attribu
|
|||
if (0x64 == attrid) {
|
||||
attr_list.addAttributePMEM(PSTR("SmokeDensity")).copyVal(attr);
|
||||
}
|
||||
} else if (modelId.startsWith(F("lumi.sensor_wleak"))) { // gas leak
|
||||
if (0x64 == attrid) {
|
||||
attr_list.addAttributePMEM(PSTR("Water")).copyVal(attr);
|
||||
}
|
||||
} else if (modelId.startsWith(F("lumi.sensor_natgas"))) { // gas leak
|
||||
if (0x64 == attrid) {
|
||||
attr_list.addAttributePMEM(PSTR("GasDensity")).copyVal(attr);
|
||||
|
|
|
@ -418,7 +418,7 @@ int32_t ZNP_Reboot(int32_t res, SBuffer &buf) {
|
|||
}
|
||||
|
||||
Response_P(PSTR("{\"" D_JSON_ZIGBEE_STATE "\":{"
|
||||
"\"Status\":%d,\"Message\":\"CC2530 booted\",\"RestartReason\":\"%s\""
|
||||
"\"Status\":%d,\"Message\":\"CCxxxx booted\",\"RestartReason\":\"%s\""
|
||||
",\"MajorRel\":%d,\"MinorRel\":%d}}"),
|
||||
ZIGBEE_STATUS_BOOT, reason_str,
|
||||
major_rel, minor_rel);
|
||||
|
|
|
@ -265,7 +265,7 @@ void ZigbeeInputLoop(void) {
|
|||
}
|
||||
} else {
|
||||
// the buffer timed-out, print error and discard
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %s, %_B"), zigbee_buffer);
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR(D_JSON_ZIGBEE_EZSP_RECEIVED ": time-out, discarding %_B"), zigbee_buffer);
|
||||
}
|
||||
zigbee_buffer->setLen(0); // empty buffer
|
||||
escape = false;
|
||||
|
|
|
@ -235,7 +235,7 @@ void ZbApplyMultiplier(double &val_d, int8_t multiplier) {
|
|||
// Write Tuya-Moes attribute
|
||||
//
|
||||
bool ZbTuyaWrite(SBuffer & buf, const Z_attribute & attr) {
|
||||
double val_d = attr.getFloat();
|
||||
double val_d = attr.getOptimisticDouble();
|
||||
const char * val_str = attr.getStr();
|
||||
|
||||
if (attr.key_is_str) { return false; } // couldn't find attr if so skip
|
||||
|
@ -294,7 +294,7 @@ bool ZbTuyaWrite(SBuffer & buf, const Z_attribute & attr) {
|
|||
// Send Attribute Write, apply mutlipliers before
|
||||
//
|
||||
bool ZbAppendWriteBuf(SBuffer & buf, const Z_attribute & attr, bool prepend_status_ok) {
|
||||
double val_d = attr.getFloat();
|
||||
double val_d = attr.getOptimisticDouble();
|
||||
const char * val_str = attr.getStr();
|
||||
|
||||
if (attr.key_is_str) { return false; } // couldn't find attr if so skip
|
||||
|
|
|
@ -177,6 +177,17 @@ extern "C" {
|
|||
ResponseCmndFailed();
|
||||
be_return_nil(vm);
|
||||
}
|
||||
|
||||
// update XdrvMailbox.command with actual command
|
||||
int32_t l_resolveCmnd(bvm *vm);
|
||||
int32_t l_resolveCmnd(bvm *vm) {
|
||||
int32_t top = be_top(vm); // Get the number of arguments
|
||||
if (top == 1 && be_isstring(vm, 1)) {
|
||||
const char *msg = be_tostring(vm, 1);
|
||||
strlcpy(XdrvMailbox.command, msg, CMDSZ);
|
||||
}
|
||||
be_return_nil(vm); // Return nil when something goes wrong
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -277,6 +288,24 @@ extern "C" {
|
|||
be_return_nil(vm); // Return nil when something goes wrong
|
||||
}
|
||||
|
||||
// Berry: `validread(address:int, reg:int, size:int) -> int or nil`
|
||||
int32_t b_wire_validread(struct bvm *vm);
|
||||
int32_t b_wire_validread(struct bvm *vm) {
|
||||
int32_t top = be_top(vm); // Get the number of arguments
|
||||
if (top == 3 && be_isint(vm, 1) && be_isint(vm, 2) && be_isint(vm, 3)) {
|
||||
uint8_t addr = be_toint(vm, 1);
|
||||
uint8_t reg = be_toint(vm, 2);
|
||||
uint8_t size = be_toint(vm, 3);
|
||||
bool ok = I2cValidRead(addr, reg, size);
|
||||
if (ok) {
|
||||
be_pushint(vm, i2c_buffer);
|
||||
} else {
|
||||
be_pushnil(vm);
|
||||
}
|
||||
be_return(vm); // Return
|
||||
}
|
||||
be_return_nil(vm); // Return nil when something goes wrong
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
|
|
@ -44,7 +44,7 @@ const char berry_prog[] =
|
|||
// Map all native functions to methods
|
||||
// Again, this will be eventually pre-compiled
|
||||
"var getfreeheap, publish, cmd, getoption, millis, timereached, yield "
|
||||
"var respcmnd, respcmndstr, respcmnd_done, respcmnd_error, respcmnd_failed "
|
||||
"var respcmnd, respcmndstr, respcmnd_done, respcmnd_error, respcmnd_failed, resolvecmnd "
|
||||
"def init_ntv() "
|
||||
"import tasmota_ntv "
|
||||
"self.getfreeheap = tasmota_ntv.getfreeheap "
|
||||
|
@ -61,6 +61,7 @@ const char berry_prog[] =
|
|||
"self.respcmnd_done = tasmota_ntv.respcmnd_done "
|
||||
"self.respcmnd_error = tasmota_ntv.respcmnd_error "
|
||||
"self.respcmnd_failed = tasmota_ntv.respcmnd_failed "
|
||||
"self.resolvecmnd = tasmota_ntv.resolvecmnd "
|
||||
"end "
|
||||
|
||||
"def init() "
|
||||
|
@ -207,8 +208,11 @@ const char berry_prog[] =
|
|||
"var payload_json = json.load(payload) "
|
||||
"var cmd_found = self.findkeyi(self._cmd, cmd) "
|
||||
"if cmd_found != nil "
|
||||
"return self._cmd[cmd_found](cmd_found, idx, payload, payload_json) "
|
||||
"self.resolvecmnd(cmd_found) " // set the command name in XdrvMailbox.command
|
||||
"self._cmd[cmd_found](cmd_found, idx, payload, payload_json) "
|
||||
"return true "
|
||||
"end "
|
||||
"return false "
|
||||
"end "
|
||||
|
||||
// Force gc and return allocated memory
|
||||
|
@ -259,23 +263,6 @@ const char berry_prog[] =
|
|||
// "try compile('/autoexec.be','file')() except .. log('BRY: no /autoexec.bat file') end "
|
||||
|
||||
// Wire
|
||||
"wire.validread = def(addr, reg, size) "
|
||||
"var ret = nil "
|
||||
"for i:0..2 "
|
||||
"wire.begintransmission(addr) "
|
||||
"wire.write(reg) "
|
||||
"if wire.endtransmission(false) == 0 "
|
||||
"wire.requestfrom(addr, size) "
|
||||
"if wire.available() == size "
|
||||
"for j:0..size-1 "
|
||||
"ret = ((ret != nil ? ret : 0) << 8) + wire.read() "
|
||||
"end "
|
||||
"return ret "
|
||||
"end "
|
||||
"end "
|
||||
"end "
|
||||
"wire.endtransmission() "
|
||||
"end "
|
||||
;
|
||||
|
||||
#endif // USE_BERRY
|
||||
|
|
|
@ -102,7 +102,7 @@ bool callBerryRule(void) {
|
|||
}
|
||||
|
||||
bool callBerryCommand(void) {
|
||||
const char * command = nullptr;
|
||||
bool serviced = false;
|
||||
|
||||
checkBeTop();
|
||||
be_getglobal(berry.vm, "_exec_cmd");
|
||||
|
@ -111,16 +111,21 @@ bool callBerryCommand(void) {
|
|||
be_pushint(berry.vm, XdrvMailbox.index);
|
||||
be_pushstring(berry.vm, XdrvMailbox.data);
|
||||
int ret = be_pcall(berry.vm, 3);
|
||||
command = be_tostring(berry.vm, 3);
|
||||
strlcpy(XdrvMailbox.topic, command, CMDSZ);
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Command (%s) serviced=%d"), XdrvMailbox.command, serviced);
|
||||
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: top=%d", be_top(berry.vm));
|
||||
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: type(1)=%s", be_typename(berry.vm, 1));
|
||||
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: type(2)=%s", be_typename(berry.vm, 2));
|
||||
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: type(3)=%s", be_typename(berry.vm, 3));
|
||||
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: type(4)=%s", be_typename(berry.vm, 4));
|
||||
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: type(5)=%s", be_typename(berry.vm, 5));
|
||||
serviced = be_tobool(berry.vm, 1); // return value is in slot 1
|
||||
// AddLog(LOG_LEVEL_INFO, "callBerryCommand: serviced=%d", serviced);
|
||||
be_pop(berry.vm, 4); // remove function object
|
||||
} else {
|
||||
be_pop(berry.vm, 1); // remove nil object
|
||||
}
|
||||
checkBeTop();
|
||||
|
||||
return command != nullptr; // TODO event not handled
|
||||
return serviced; // TODO event not handled
|
||||
}
|
||||
|
||||
size_t callBerryGC(void) {
|
||||
|
@ -173,6 +178,35 @@ void callBerryFunctionVoid(const char * fname) {
|
|||
checkBeTop();
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* VM Observability
|
||||
\*********************************************************************************************/
|
||||
void BerryObservability(bvm *vm, int32_t event...);
|
||||
void BerryObservability(bvm *vm, int32_t event...) {
|
||||
va_list param;
|
||||
va_start(param, event);
|
||||
static int32_t vm_usage = 0;
|
||||
static uint32_t gc_time = 0;
|
||||
|
||||
switch (event) {
|
||||
case BE_OBS_GC_START:
|
||||
{
|
||||
gc_time = millis();
|
||||
vm_usage = va_arg(param, int32_t);
|
||||
}
|
||||
break;
|
||||
case BE_OBS_GC_END:
|
||||
{
|
||||
int32_t vm_usage2 = va_arg(param, int32_t);
|
||||
uint32_t gc_elapsed = millis() - gc_time;
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "GC from %i to %i bytes (in %d ms)"), vm_usage, vm_usage2, gc_elapsed);
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
va_end(param);
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* VM Init
|
||||
\*********************************************************************************************/
|
||||
|
@ -191,6 +225,7 @@ void BrReset(void) {
|
|||
bool berry_init_ok = false;
|
||||
do {
|
||||
berry.vm = be_vm_new(); /* create a virtual machine instance */
|
||||
be_set_obs_hook(berry.vm, &BerryObservability);
|
||||
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "Berry VM created, RAM used=%u"), be_gc_memcount(berry.vm));
|
||||
|
||||
// Register functions
|
||||
|
@ -264,12 +299,12 @@ void CmndBrRun(void) {
|
|||
} while (0);
|
||||
|
||||
if (0 == ret_code) {
|
||||
// AddLog(LOG_LEVEL_INFO, "run: top=%d", be_top(berry.vm));
|
||||
// AddLog(LOG_LEVEL_INFO, "run: type(1)=%s", be_typename(berry.vm, 1));
|
||||
// AddLog(LOG_LEVEL_INFO, "run: type(2)=%s", be_typename(berry.vm, 2));
|
||||
|
||||
// code taken from REPL, look first at top, and if nil, look at return value
|
||||
if (be_isnil(berry.vm, 0)) {
|
||||
ret_val = be_tostring(berry.vm, -1);
|
||||
} else {
|
||||
ret_val = be_tostring(berry.vm, 0);
|
||||
}
|
||||
ret_val = be_tostring(berry.vm, 1);
|
||||
Response_P("{\"" D_PRFX_BR "\":\"%s\"}", ret_val); // can't use XdrvMailbox.command as it may have been overwritten by subcommand
|
||||
be_pop(berry.vm, 1);
|
||||
} else {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#ifdef USE_SPI
|
||||
#ifdef USE_DISPLAY
|
||||
#if (defined(USE_DISPLAY_ILI9341) || defined(USE_DISPLAY_ILI9342))
|
||||
#ifdef USE_DISPLAY_ILI9341
|
||||
|
||||
#define XDSP_04 4
|
||||
|
||||
|
@ -29,26 +29,30 @@ extern uint8_t *buffer;
|
|||
extern uint8_t color_type;
|
||||
ILI9341_2 *ili9341_2;
|
||||
|
||||
#ifdef USE_FT5206
|
||||
#if defined(USE_FT5206)
|
||||
#include <FT5206.h>
|
||||
uint8_t ili9342_ctouch_counter = 0;
|
||||
#elif defined(USE_XPT2046)
|
||||
#include <XPT2046_Touchscreen.h>
|
||||
uint8_t ili9342_ctouch_counter = 0;
|
||||
#endif // USE_FT5206
|
||||
|
||||
|
||||
bool tft_init_done = false;
|
||||
|
||||
#define ILI9341_ID 1
|
||||
#define ILI9342_ID 2
|
||||
|
||||
//Settings.display_options.ilimode = ILI9341_ID;
|
||||
|
||||
/*********************************************************************************************/
|
||||
|
||||
void ILI9341_InitDriver()
|
||||
{
|
||||
|
||||
#if (defined(USE_M5STACK_CORE2) || defined(USE_M5STACK_CORE_BASIC))
|
||||
if (TasmotaGlobal.spi_enabled) {
|
||||
#else
|
||||
// There are displays without CS
|
||||
if (PinUsed(GPIO_ILI9341_CS) || PinUsed(GPIO_ILI9341_DC) &&
|
||||
(TasmotaGlobal.spi_enabled || TasmotaGlobal.soft_spi_enabled)) {
|
||||
#endif
|
||||
|
||||
Settings.display_model = XDSP_04;
|
||||
|
||||
|
@ -62,35 +66,25 @@ void ILI9341_InitDriver()
|
|||
// disable screen buffer
|
||||
buffer = NULL;
|
||||
|
||||
#ifdef USE_DISPLAY_ILI9341
|
||||
uint8_t dtype = 1;
|
||||
#else
|
||||
uint8_t dtype = 3; // sign ili9342 with variable spi pins
|
||||
#endif // USE_DISPLAY_ILI9341
|
||||
if (!Settings.display_options.ilimode) {
|
||||
Settings.display_options.ilimode = ILI9341_ID;
|
||||
}
|
||||
|
||||
// default colors
|
||||
fg_color = ILI9341_WHITE;
|
||||
bg_color = ILI9341_BLACK;
|
||||
|
||||
#ifdef USE_M5STACK_CORE2
|
||||
// fixed pins on m5stack core2
|
||||
ili9341_2 = new ILI9341_2(5, -2, 15, -2);
|
||||
#elif defined(USE_M5STACK_CORE_BASIC)
|
||||
// int8_t cs, int8_t res, int8_t dc, int8_t bp)
|
||||
ili9341_2 = new ILI9341_2(14, 33, 27, 32);
|
||||
#else
|
||||
// check for special case with 2 SPI busses (ESP32 bitcoin)
|
||||
if (TasmotaGlobal.soft_spi_enabled) {
|
||||
// Init renderer, may use hardware spi, however we use SSPI defintion because SD card uses SPI definition (2 spi busses)
|
||||
if (PinUsed(GPIO_SSPI_MOSI) && PinUsed(GPIO_SSPI_MISO) && PinUsed(GPIO_SSPI_SCLK)) {
|
||||
ili9341_2 = new ILI9341_2(Pin(GPIO_ILI9341_CS), Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_MISO), Pin(GPIO_SSPI_SCLK), Pin(GPIO_OLED_RESET), Pin(GPIO_ILI9341_DC), Pin(GPIO_BACKLIGHT), 2, dtype);
|
||||
ili9341_2 = new ILI9341_2(Pin(GPIO_ILI9341_CS), Pin(GPIO_SSPI_MOSI), Pin(GPIO_SSPI_MISO), Pin(GPIO_SSPI_SCLK), Pin(GPIO_OLED_RESET), Pin(GPIO_ILI9341_DC), Pin(GPIO_BACKLIGHT), 2, Settings.display_options.ilimode & 3);
|
||||
}
|
||||
} else if (TasmotaGlobal.spi_enabled) {
|
||||
if (PinUsed(GPIO_ILI9341_DC)) {
|
||||
ili9341_2 = new ILI9341_2(Pin(GPIO_ILI9341_CS), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK), Pin(GPIO_OLED_RESET), Pin(GPIO_ILI9341_DC), Pin(GPIO_BACKLIGHT), 1, dtype);
|
||||
ili9341_2 = new ILI9341_2(Pin(GPIO_ILI9341_CS), Pin(GPIO_SPI_MOSI), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_CLK), Pin(GPIO_OLED_RESET), Pin(GPIO_ILI9341_DC), Pin(GPIO_BACKLIGHT), 1, Settings.display_options.ilimode & 3);
|
||||
}
|
||||
}
|
||||
#endif // USE_M5STACK_CORE2
|
||||
|
||||
if (ili9341_2 == nullptr) {
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: ILI934x invalid GPIOs"));
|
||||
|
@ -99,6 +93,7 @@ void ILI9341_InitDriver()
|
|||
|
||||
ili9341_2->init(Settings.display_width, Settings.display_height);
|
||||
renderer = ili9341_2;
|
||||
|
||||
renderer->DisplayInit(DISPLAY_INIT_MODE, Settings.display_size, Settings.display_rotate, Settings.display_font);
|
||||
renderer->dim(Settings.display_dimmer);
|
||||
|
||||
|
@ -107,11 +102,7 @@ void ILI9341_InitDriver()
|
|||
renderer->setTextFont(2);
|
||||
renderer->setTextSize(1);
|
||||
renderer->setTextColor(ILI9341_WHITE, ILI9341_BLACK);
|
||||
#ifdef USE_DISPLAY_ILI9341
|
||||
renderer->DrawStringAt(50, (Settings.display_height/2)-12, "ILI9341 TFT!", ILI9341_WHITE, 0);
|
||||
#else
|
||||
renderer->DrawStringAt(50, (Settings.display_height/2)-12, "ILI9342 TFT!", ILI9341_WHITE, 0);
|
||||
#endif
|
||||
renderer->DrawStringAt(50, (Settings.display_height/2)-12, (Settings.display_options.ilimode & 3)==ILI9341_ID?"ILI9341 TFT!":"ILI9342 TFT!", ILI9341_WHITE, 0);
|
||||
delay(1000);
|
||||
#endif // SHOW_SPLASH
|
||||
|
||||
|
@ -136,15 +127,16 @@ void ILI9341_InitDriver()
|
|||
#endif // USE_FT5206
|
||||
#endif // ESP32
|
||||
|
||||
tft_init_done = true;
|
||||
#ifdef USE_DISPLAY_ILI9341
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: ILI9341"));
|
||||
#else
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: ILI9342"));
|
||||
#ifdef USE_XPT2046
|
||||
Touch_Init(Pin(GPIO_XPT2046_CS));
|
||||
#endif
|
||||
|
||||
tft_init_done = true;
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("DSP: ILI9341"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void core2_disp_pwr(uint8_t on);
|
||||
void core2_disp_dim(uint8_t dim);
|
||||
|
||||
|
@ -160,11 +152,11 @@ void ili9342_dimm(uint8_t dim) {
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
#ifdef USE_FT5206
|
||||
#if defined(USE_FT5206) || defined(USE_XPT2046)
|
||||
#ifdef USE_TOUCH_BUTTONS
|
||||
|
||||
void ili9342_RotConvert(int16_t *x, int16_t *y) {
|
||||
#if defined(USE_FT5206)
|
||||
void TS_RotConvert(int16_t *x, int16_t *y) {
|
||||
|
||||
int16_t temp;
|
||||
if (renderer) {
|
||||
|
@ -189,6 +181,38 @@ int16_t temp;
|
|||
}
|
||||
}
|
||||
}
|
||||
#elif defined(USE_XPT2046)
|
||||
void TS_RotConvert(int16_t *x, int16_t *y) {
|
||||
|
||||
int16_t temp;
|
||||
if (renderer) {
|
||||
uint8_t rot = renderer->getRotation();
|
||||
// AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(" TS: before convert x:%d / y:%d screen r:%d / w:%d / h:%d"), *x, *y,rot,renderer->width(),renderer->height());
|
||||
temp = map(*x,XPT2046_MINX,XPT2046_MAXX, renderer->height(), 0);
|
||||
*x = map(*y,XPT2046_MINY,XPT2046_MAXY, renderer->width(), 0);
|
||||
*y = temp;
|
||||
switch (rot) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
temp = *y;
|
||||
*y = renderer->width() - *x;
|
||||
*x = temp;
|
||||
break;
|
||||
case 2:
|
||||
*x = renderer->width() - *x;
|
||||
*y = renderer->height() - *y;
|
||||
break;
|
||||
case 3:
|
||||
temp = *y;
|
||||
*y = *x;
|
||||
*x = renderer->height() - temp;
|
||||
break;
|
||||
}
|
||||
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(" TS: after convert x:%d / y:%d screen r:%d / w:%d / h:%d"), *x, *y,rot,renderer->width(),renderer->height());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// check digitizer hit
|
||||
void ili9342_CheckTouch() {
|
||||
|
@ -196,12 +220,12 @@ ili9342_ctouch_counter++;
|
|||
if (2 == ili9342_ctouch_counter) {
|
||||
// every 100 ms should be enough
|
||||
ili9342_ctouch_counter = 0;
|
||||
Touch_Check(ili9342_RotConvert);
|
||||
Touch_Check(TS_RotConvert);
|
||||
}
|
||||
}
|
||||
#endif // USE_TOUCH_BUTTONS
|
||||
#endif // USE_FT5206
|
||||
#endif // ESP32
|
||||
|
||||
|
||||
|
||||
#ifdef USE_DISPLAY_MODES1TO5
|
||||
|
@ -235,7 +259,7 @@ bool Ili9341Header(void) {
|
|||
void Ili9341InitMode(void) {
|
||||
// renderer->setRotation(Settings.display_rotate); // 0
|
||||
#ifdef USE_DISPLAY_ILI9341
|
||||
renderer->invertDisplay(0);
|
||||
// renderer->invertDisplay(0);
|
||||
#endif
|
||||
renderer->fillScreen(ILI9341_BLACK);
|
||||
renderer->setTextWrap(false); // Allow text to run off edges
|
||||
|
@ -360,10 +384,15 @@ bool Xdsp04(uint8_t function)
|
|||
case DISPLAY_INIT_MODE:
|
||||
renderer->clearDisplay();
|
||||
break;
|
||||
#ifdef USE_FT5206
|
||||
#if defined(USE_FT5206) || defined(USE_XPT2046)
|
||||
#ifdef USE_TOUCH_BUTTONS
|
||||
case FUNC_DISPLAY_EVERY_50_MSECOND:
|
||||
#if defined(USE_FT5206)
|
||||
if (FT5206_found) {
|
||||
#elif defined(USE_XPT2046)
|
||||
if (XPT2046_found) {
|
||||
#endif
|
||||
|
||||
ili9342_CheckTouch();
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,363 @@
|
|||
/*
|
||||
xnrg_19_cse7761.ino - CSE7761 energy sensor support for Tasmota
|
||||
|
||||
Copyright (C) 2021 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 USE_ENERGY_SENSOR
|
||||
#ifdef USE_CSE7761
|
||||
/*********************************************************************************************\
|
||||
* CSE7761 - Energy (Sonoff Dual R3 Pow)
|
||||
*
|
||||
* Based on datasheet from ChipSea
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XNRG_19 19
|
||||
|
||||
#define CSE7761_K1 2 // Current channel sampling resistance in milli Ohm
|
||||
#define CSE7761_K2 2 // Voltage divider resistance in 1k/1M
|
||||
|
||||
#define CSE7761_2POWER22 4194304
|
||||
#define CSE7761_2POWER23 8388608
|
||||
#define CSE7761_2POWER31 2147483648
|
||||
|
||||
enum CSE7761 { RmsIAC, RmsIBC, RmsUC, PowerPAC, PowerPBC, PowerSC, EnergyAc, EnergyBC };
|
||||
|
||||
#include <TasmotaSerial.h>
|
||||
|
||||
TasmotaSerial *Cse7761Serial = nullptr;
|
||||
|
||||
struct {
|
||||
uint32_t voltage_rms = 0;
|
||||
uint32_t current_rms[2] = { 0 };
|
||||
uint32_t active_power[2] = { 0 };
|
||||
uint16_t coefficient[8] = { 0 };
|
||||
uint8_t init = 0;
|
||||
bool found = false;
|
||||
} CSE7761Data;
|
||||
|
||||
void Cse7761Write(uint32_t reg, uint32_t data) {
|
||||
uint8_t buffer[5];
|
||||
|
||||
buffer[0] = 0xA5;
|
||||
buffer[1] = reg;
|
||||
uint32_t len = 2;
|
||||
if (data) {
|
||||
if (data < 0xFF) {
|
||||
buffer[2] = data & 0xFF;
|
||||
len = 3;
|
||||
} else {
|
||||
buffer[2] = (data >> 8) & 0xFF;
|
||||
buffer[3] = data & 0xFF;
|
||||
len = 4;
|
||||
}
|
||||
uint8_t crc = 0;
|
||||
for (uint32_t i = 0; i < len; i++) {
|
||||
crc += buffer[i];
|
||||
}
|
||||
buffer[len] = ~crc;
|
||||
len++;
|
||||
}
|
||||
|
||||
Cse7761Serial->write(buffer, len);
|
||||
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("C61: Send %d, Data %*_H"), len, len, buffer);
|
||||
}
|
||||
|
||||
uint32_t Cse7761Read(uint32_t reg, uint32_t request) {
|
||||
Cse7761Serial->flush();
|
||||
Cse7761Write(reg, 0);
|
||||
|
||||
uint8_t buffer[8];
|
||||
uint32_t rcvd = 0;
|
||||
uint32_t timeout = millis() + 3;
|
||||
while (!TimeReached(timeout)) {
|
||||
int value = Cse7761Serial->read();
|
||||
if ((value > -1) && (rcvd < sizeof(buffer) -1)) {
|
||||
buffer[rcvd++] = value;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rcvd) {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("C61: Rcvd %d"), rcvd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("C61: Rcvd %d, Data %*_H"), rcvd, rcvd, buffer);
|
||||
|
||||
int result = 0;
|
||||
uint8_t crc = 0xA5 + reg;
|
||||
for (uint32_t i = 0; i < rcvd -1; i++) {
|
||||
result = (result << 8) | buffer[i];
|
||||
crc += buffer[i];
|
||||
}
|
||||
crc = ~crc;
|
||||
if (crc != buffer[rcvd]) {
|
||||
result = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Cse7761ChipInit(void) {
|
||||
uint16_t calc_chksum = 0xFFFF;
|
||||
for (uint32_t i = 0; i < 8; i++) {
|
||||
CSE7761Data.coefficient[i] = Cse7761Read(0x70 + i, 2);
|
||||
calc_chksum += CSE7761Data.coefficient[i];
|
||||
}
|
||||
uint16_t dummy = Cse7761Read(0x6E, 2);
|
||||
uint16_t coeff_chksum = Cse7761Read(0x6F, 2);
|
||||
if (calc_chksum != coeff_chksum) {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("C61: Coefficients invalid"));
|
||||
// return false;
|
||||
}
|
||||
|
||||
delay(3);
|
||||
Cse7761Write(0xEA, 0xE5); // Enable write operation
|
||||
delay(5);
|
||||
uint8_t sys_status = Cse7761Read(0x43, 1);
|
||||
if (sys_status & 0x10) { // Write enable to protected registers (WREN)
|
||||
delay(3);
|
||||
/*
|
||||
System Control Register (SYSCON) Addr:0x00 Default value: 0x0A04
|
||||
Bit name Function description
|
||||
15-11 NC -, the default is 1
|
||||
10 ADC2ON
|
||||
=1, means ADC current channel B is on (Sonoff Dual R3 Pow)
|
||||
=0, means ADC current channel B is closed
|
||||
9 NC -, the default is 1.
|
||||
8-6 PGAIB[2:0] Current channel B analog gain selection highest bit
|
||||
=1XX, PGA of current channel B=16
|
||||
=011, PGA of current channel B=8
|
||||
=010, PGA of current channel B=4
|
||||
=001, PGA of current channel B=2
|
||||
=000, PGA of current channel B=1 (Sonoff Dual R3 Pow)
|
||||
5-3 PGAU[2:0] Highest bit of voltage channel analog gain selection
|
||||
=1XX, PGA of current channel U=16
|
||||
=011, PGA of current channel U=8
|
||||
=010, PGA of current channel U=4
|
||||
=001, PGA of current channel U=2 (Sonoff Dual R3 Pow)
|
||||
=000, PGA of current channel U=1
|
||||
2-0 PGAIA[2:0] Current channel A analog gain selection highest bit
|
||||
=1XX, PGA of current channel A=16
|
||||
=011, PGA of current channel A=8
|
||||
=010, PGA of current channel A=4
|
||||
=001, PGA of current channel A=2
|
||||
=000, PGA of current channel A=1 (Sonoff Dual R3 Pow)
|
||||
*/
|
||||
Cse7761Write(0x80, 0xFF04); // Set SYSCON
|
||||
/*
|
||||
Energy Measure Control Register (EMUCON) Addr:0x01 Default value: 0x0000
|
||||
Bit name Function description
|
||||
15-14 Tsensor_Step[1:0] Measurement steps of temperature sensor:
|
||||
=2'b00 The first step of temperature sensor measurement, the Offset of OP1 and OP2 is +/+. (Sonoff Dual R3 Pow)
|
||||
=2'b01 The second step of temperature sensor measurement, the Offset of OP1 and OP2 is +/-.
|
||||
=2'b10 The third step of temperature sensor measurement, the Offset of OP1 and OP2 is -/+.
|
||||
=2'b11 The fourth step of temperature sensor measurement, the Offset of OP1 and OP2 is -/-.
|
||||
After measuring these four results and averaging, the AD value of the current measured temperature can be obtained.
|
||||
13 tensor_en Temperature measurement module control
|
||||
=0 when the temperature measurement module is closed; (Sonoff Dual R3 Pow)
|
||||
=1 when the temperature measurement module is turned on;
|
||||
12 comp_off Comparator module close signal:
|
||||
=0 when the comparator module is in working state
|
||||
=1 when the comparator module is off (Sonoff Dual R3 Pow)
|
||||
11-10 Pmode[1:0] Selection of active energy calculation method:
|
||||
Pmode =00, both positive and negative active energy participate in the accumulation,
|
||||
the accumulation method is algebraic sum mode, the reverse REVQ symbol indicates to active power; (Sonoff Dual R3 Pow)
|
||||
Pmode = 01, only accumulate positive active energy;
|
||||
Pmode = 10, both positive and negative active energy participate in the accumulation,
|
||||
and the accumulation method is absolute value method. No reverse active power indication;
|
||||
Pmode =11, reserved, the mode is the same as Pmode =00
|
||||
9 NC -
|
||||
8 ZXD1 The initial value of ZX output is 0, and different waveforms are output according to the configuration of ZXD1 and ZXD0:
|
||||
=0, it means that the ZX output changes only at the selected zero-crossing point (Sonoff Dual R3 Pow)
|
||||
=1, indicating that the ZX output changes at both the positive and negative zero crossings
|
||||
7 ZXD0
|
||||
=0, indicates that the positive zero-crossing point is selected as the zero-crossing detection signal (Sonoff Dual R3 Pow)
|
||||
=1, indicating that the negative zero-crossing point is selected as the zero-crossing detection signal
|
||||
6 HPFIBOFF
|
||||
=0, enable current channel B digital high-pass filter (Sonoff Dual R3 Pow)
|
||||
=1, turn off the digital high-pass filter of current channel B
|
||||
5 HPFIAOFF
|
||||
=0, enable current channel A digital high-pass filter (Sonoff Dual R3 Pow)
|
||||
=1, turn off the digital high-pass filter of current channel A
|
||||
4 HPFUOFF
|
||||
=0, enable U channel digital high pass filter (Sonoff Dual R3 Pow)
|
||||
=1, turn off the U channel digital high-pass filter
|
||||
3-2 NC -
|
||||
1 PBRUN
|
||||
=1, enable PFB pulse output and active energy register accumulation; (Sonoff Dual R3 Pow)
|
||||
=0 (default), turn off PFB pulse output and active energy register accumulation.
|
||||
0 PARUN
|
||||
=1, enable PFA pulse output and active energy register accumulation; (Sonoff Dual R3 Pow)
|
||||
=0 (default), turn off PFA pulse output and active energy register accumulation.
|
||||
*/
|
||||
Cse7761Write(0x81, 0x1003); // Set EMUCON
|
||||
/*
|
||||
Energy Measure Control Register (EMUCON2) Addr: 0x13 Default value: 0x0001
|
||||
Bit name Function description
|
||||
15-13 NC -
|
||||
12 SDOCmos
|
||||
=1, SDO pin CMOS open-drain output (Sonoff Dual R3 Pow)
|
||||
=0, SDO pin CMOS output
|
||||
11 EPB_CB Energy_PB clear signal control, the default is 0, and it needs to be configured to 1 in UART mode.
|
||||
Clear after reading is not supported in UART mode
|
||||
=1, Energy_PB will not be cleared after reading; (Sonoff Dual R3 Pow)
|
||||
=0, Energy_PB is cleared after reading;
|
||||
10 EPA_CB Energy_PA clear signal control, the default is 0, it needs to be configured to 1 in UART mode,
|
||||
Clear after reading is not supported in UART mode
|
||||
=1, Energy_PA will not be cleared after reading; (Sonoff Dual R3 Pow)
|
||||
=0, Energy_PA is cleared after reading;
|
||||
9-8 DUPSEL[1:0] Average register update frequency control
|
||||
=00, Update frequency 3.4Hz
|
||||
=01, Update frequency 6.8Hz
|
||||
=10, Update frequency 13.65Hz
|
||||
=11, Update frequency 27.3Hz (Sonoff Dual R3 Pow)
|
||||
7 CHS_IB Current channel B measurement selection signal
|
||||
=1, measure the current of channel B (Sonoff Dual R3 Pow)
|
||||
=0, measure the internal temperature of the chip
|
||||
6 PfactorEN Power factor function enable
|
||||
=1, turn on the power factor output function (Sonoff Dual R3 Pow)
|
||||
=0, turn off the power factor output function
|
||||
5 WaveEN Waveform data, instantaneous data output enable signal
|
||||
=1, turn on the waveform data output function
|
||||
=0, turn off the waveform data output function (Sonoff Dual R3 Pow)
|
||||
4 SAGEN Voltage drop detection enable signal, WaveEN=1 must be configured first
|
||||
=1, turn on the voltage drop detection function
|
||||
=0, turn off the voltage drop detection function (Sonoff Dual R3 Pow)
|
||||
3 OverEN Overvoltage, overcurrent, and overload detection enable signal, WaveEN=1 must be configured first
|
||||
=1, turn on the overvoltage, overcurrent, and overload detection functions
|
||||
=0, turn off the overvoltage, overcurrent, and overload detection functions (Sonoff Dual R3 Pow)
|
||||
2 ZxEN Zero-crossing detection, phase angle, voltage frequency measurement enable signal
|
||||
=1, turn on the zero-crossing detection, phase angle, and voltage frequency measurement functions
|
||||
=0, disable zero-crossing detection, phase angle, voltage frequency measurement functions (Sonoff Dual R3 Pow)
|
||||
1 PeakEN Peak detect enable signal
|
||||
=1, turn on the peak detection function
|
||||
=0, turn off the peak detection function (Sonoff Dual R3 Pow)
|
||||
0 NC Default is 1
|
||||
*/
|
||||
Cse7761Write(0x93, 0x0FC1); // Set EMUCON2
|
||||
} else {
|
||||
AddLog(LOG_LEVEL_DEBUG, PSTR("C61: Write enable failed"));
|
||||
// return false;
|
||||
}
|
||||
delay(80);
|
||||
Cse7761Write(0xEA, 0xDC); // Close write operation
|
||||
return true;
|
||||
}
|
||||
|
||||
void Cse7761GetData(void) {
|
||||
CSE7761Data.voltage_rms = Cse7761Read(0x26, 3);
|
||||
CSE7761Data.current_rms[0] = Cse7761Read(0x24, 3);
|
||||
CSE7761Data.active_power[0] = Cse7761Read(0x2C, 4);
|
||||
CSE7761Data.current_rms[1] = Cse7761Read(0x25, 3);
|
||||
CSE7761Data.active_power[1] = Cse7761Read(0x2D, 4);
|
||||
|
||||
if (Energy.power_on) { // Powered on
|
||||
Energy.voltage[0] = ((float)CSE7761Data.voltage_rms * ((double)CSE7761Data.coefficient[RmsUC] / (CSE7761_K2 * 2 * CSE7761_2POWER22))) / 1000; // V
|
||||
|
||||
for (uint32_t channel = 0; channel < 2; channel++) {
|
||||
Energy.data_valid[channel] = 0;
|
||||
Energy.active_power[channel] = (float)CSE7761Data.active_power[channel] * ((double)CSE7761Data.coefficient[PowerPAC + channel] / (CSE7761_K1 * CSE7761_K2 * 2 * CSE7761_2POWER31)); // W
|
||||
if (0 == Energy.active_power[channel]) {
|
||||
Energy.current[channel] = 0;
|
||||
} else {
|
||||
Energy.current[channel] = (float)CSE7761Data.current_rms[channel] * ((double)CSE7761Data.coefficient[RmsIAC + channel] / (CSE7761_K1 * 2 * CSE7761_2POWER23)); // mA
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t active_power_sum = (Energy.active_power[0] + Energy.active_power[1]) * 1000;
|
||||
if (active_power_sum) {
|
||||
Energy.kWhtoday_delta += active_power_sum / 36;
|
||||
EnergyUpdateToday();
|
||||
}
|
||||
} else { // Powered off
|
||||
Energy.data_valid[0] = ENERGY_WATCHDOG;
|
||||
Energy.data_valid[1] = ENERGY_WATCHDOG;
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void Cse7761EverySecond(void) {
|
||||
if (CSE7761Data.init) {
|
||||
if (2 == CSE7761Data.init) {
|
||||
Cse7761Write(0xEA, 0x96); // Reset chip
|
||||
}
|
||||
else if (1 == CSE7761Data.init) {
|
||||
uint16_t syscon = Cse7761Read(0x00, 2); // Default 0x0A04
|
||||
if (0x0A04 == syscon) {
|
||||
CSE7761Data.found = Cse7761ChipInit();
|
||||
}
|
||||
if (CSE7761Data.found) {
|
||||
AddLog(LOG_LEVEL_INFO, PSTR("C61: CSE7761 found"));
|
||||
}
|
||||
}
|
||||
CSE7761Data.init--;
|
||||
}
|
||||
else {
|
||||
if (CSE7761Data.found) {
|
||||
Cse7761GetData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cse7761SnsInit(void) {
|
||||
// Software serial init needs to be done here as earlier (serial) interrupts may lead to Exceptions
|
||||
Cse7761Serial = new TasmotaSerial(Pin(GPIO_CSE7761_RX), Pin(GPIO_CSE7761_TX), 1);
|
||||
if (Cse7761Serial->begin(38400, SERIAL_8E1)) {
|
||||
if (Cse7761Serial->hardwareSerial()) {
|
||||
// SetSerial(38400, TS_SERIAL_8E1);
|
||||
ClaimSerial();
|
||||
}
|
||||
} else {
|
||||
TasmotaGlobal.energy_driver = ENERGY_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
void Cse7761DrvInit(void) {
|
||||
if (PinUsed(GPIO_CSE7761_RX) && PinUsed(GPIO_CSE7761_TX)) {
|
||||
CSE7761Data.found = false;
|
||||
CSE7761Data.init = 3; // Init setup steps
|
||||
Energy.phase_count = 2; // Handle two channels as two phases
|
||||
Energy.voltage_common = true; // Use common voltage
|
||||
TasmotaGlobal.energy_driver = XNRG_19;
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
bool Xnrg19(uint8_t function) {
|
||||
bool result = false;
|
||||
|
||||
switch (function) {
|
||||
case FUNC_EVERY_SECOND:
|
||||
Cse7761EverySecond();
|
||||
break;
|
||||
case FUNC_INIT:
|
||||
Cse7761SnsInit();
|
||||
break;
|
||||
case FUNC_PRE_INIT:
|
||||
Cse7761DrvInit();
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_CSE7761
|
||||
#endif // USE_ENERGY_SENSOR
|
|
@ -822,8 +822,12 @@ uint8_t Serial_peek() {
|
|||
return meter_ss[num-1]->peek();
|
||||
}
|
||||
|
||||
uint8_t sml_logindex;
|
||||
char log_data[128];
|
||||
#ifndef SML_DUMP_SIZE
|
||||
#define SML_DUMP_SIZE 128
|
||||
#endif
|
||||
|
||||
uint16_t sml_logindex;
|
||||
char log_data[SML_DUMP_SIZE];
|
||||
|
||||
#define SML_EBUS_SKIP_SYNC_DUMPS
|
||||
|
||||
|
@ -884,8 +888,8 @@ void Dump2log(void) {
|
|||
char c = SML_SREAD&0x7f;
|
||||
if (c == '\n' || c == '\r') {
|
||||
if (sml_logindex > 2) {
|
||||
AddLogData(LOG_LEVEL_INFO, log_data);
|
||||
log_data[sml_logindex] = 0;
|
||||
AddLogData(LOG_LEVEL_INFO, log_data);
|
||||
log_data[0] = ':';
|
||||
log_data[1] = ' ';
|
||||
sml_logindex = 2;
|
||||
|
@ -903,6 +907,7 @@ void Dump2log(void) {
|
|||
while (SML_SAVAILABLE) {
|
||||
c = SML_SREAD;
|
||||
if (c == VBUS_SYNC) {
|
||||
log_data[sml_logindex] = 0;
|
||||
AddLogData(LOG_LEVEL_INFO, log_data);
|
||||
log_data[0] = ':';
|
||||
log_data[1] = ' ';
|
||||
|
@ -922,6 +927,7 @@ void Dump2log(void) {
|
|||
p = SML_SPEAK;
|
||||
if (p != EBUS_SYNC && sml_logindex > 5) {
|
||||
// new packet, plot last one
|
||||
log_data[sml_logindex] = 0;
|
||||
AddLogData(LOG_LEVEL_INFO, log_data);
|
||||
strcpy(&log_data[0], ": aa ");
|
||||
sml_logindex = 5;
|
||||
|
@ -939,6 +945,7 @@ void Dump2log(void) {
|
|||
while (SML_SAVAILABLE) {
|
||||
c = SML_SREAD;
|
||||
if (c == SML_SYNC) {
|
||||
log_data[sml_logindex] = 0;
|
||||
AddLogData(LOG_LEVEL_INFO, log_data);
|
||||
log_data[0] = ':';
|
||||
log_data[1] = ' ';
|
||||
|
@ -962,6 +969,7 @@ void Dump2log(void) {
|
|||
}
|
||||
}
|
||||
if (sml_logindex > 2) {
|
||||
log_data[sml_logindex] = 0;
|
||||
AddLogData(LOG_LEVEL_INFO, log_data);
|
||||
}
|
||||
}
|
||||
|
@ -1472,6 +1480,7 @@ void SML_Decode(uint8_t index) {
|
|||
double fac = CharToDouble((char*)mp);
|
||||
meter_vars[vindex] /= fac;
|
||||
SML_Immediate_MQTT((const char*)mp, vindex, mindex);
|
||||
dvalid[vindex] = 1;
|
||||
// get sfac
|
||||
} else if (*mp=='d') {
|
||||
// calc deltas d ind 10 (eg every 10 secs)
|
||||
|
@ -1489,7 +1498,16 @@ void SML_Decode(uint8_t index) {
|
|||
dtimes[dindex] = millis();
|
||||
double vdiff = meter_vars[ind - 1] - dvalues[dindex];
|
||||
dvalues[dindex] = meter_vars[ind - 1];
|
||||
meter_vars[vindex] = (double)360000.0 * vdiff / ((double)dtime / 10000.0);
|
||||
double dres = (double)360000.0 * vdiff / ((double)dtime / 10000.0);
|
||||
#ifdef USE_SML_MEDIAN_FILTER
|
||||
if (meter_desc_p[mindex].flag & 16) {
|
||||
meter_vars[vindex] = sml_median(&sml_mf[vindex], dres);
|
||||
} else {
|
||||
meter_vars[vindex] = dres;
|
||||
}
|
||||
#else
|
||||
meter_vars[vindex] = dres;
|
||||
#endif
|
||||
|
||||
mp=strchr(mp,'@');
|
||||
if (mp) {
|
||||
|
@ -1499,6 +1517,7 @@ void SML_Decode(uint8_t index) {
|
|||
SML_Immediate_MQTT((const char*)mp, vindex, mindex);
|
||||
}
|
||||
}
|
||||
dvalid[vindex] = 1;
|
||||
dindex++;
|
||||
}
|
||||
} else if (*mp == 'h') {
|
||||
|
@ -1731,6 +1750,7 @@ void SML_Decode(uint8_t index) {
|
|||
}
|
||||
if (found) {
|
||||
// matches, get value
|
||||
dvalid[vindex] = 1;
|
||||
mp++;
|
||||
#ifdef ED300L
|
||||
g_mindex=mindex;
|
||||
|
@ -1838,7 +1858,6 @@ void SML_Decode(uint8_t index) {
|
|||
SML_Immediate_MQTT((const char*)mp, vindex, mindex);
|
||||
}
|
||||
}
|
||||
dvalid[vindex] = 1;
|
||||
//AddLog(LOG_LEVEL_INFO, PSTR("set valid in line %d"), vindex);
|
||||
}
|
||||
nextsect:
|
||||
|
|
Loading…
Reference in New Issue