mirror of https://github.com/arendst/Tasmota.git
v4.0.7
4.0.7 20170319 * Increased Sonoff Led PWM frequency from 432 to 1000 * Fix possible watch dog reboot after changing module type on web page * Fix reporting of GPIO usage from web page * Fix Sonoff Led blank during firmware upgrade * Fix Sonoff Led flicker and possible flash corruption by using latest Arduino-esp8266 versions * of pwm core files included in sonoff library (#211) * Add PWM output control with commands PWM1 to PWM5 using user selectable GPIOs (#211) * Fix exceptions due to low values of commands HlwPCal (10000), HlwUCal (1000) and HlwICal (2500) (#223) * Add Switch state to sensor status (#227, #233) * Add user configuarble GPIO to module Sonoff Touch (#228) * Add define WEB_PORT to user_config.h to change default web server port from 80 (#232) * Fix failed Ota Firmware upgrade started from Web page (#235)
This commit is contained in:
parent
c4cdd4459c
commit
742a87df8a
|
@ -1,7 +1,7 @@
|
|||
## Sonoff-Tasmota
|
||||
Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE.
|
||||
|
||||
Current version is **4.0.6** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
|
||||
Current version is **4.0.7** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/master/sonoff/_releasenotes.ino) for change information.
|
||||
|
||||
- This version provides all (Sonoff) modules in one file and starts up with Sonoff Basic.
|
||||
- Once uploaded select module using the configuration webpage or the commands ```Modules``` and ```Module```.
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,4 +1,18 @@
|
|||
/* 4.0.6 20170316
|
||||
/* 4.0.7 20170319
|
||||
* Increased Sonoff Led PWM frequency from 432 to 1000
|
||||
* Fix possible watch dog reboot after changing module type on web page
|
||||
* Fix reporting of GPIO usage from web page
|
||||
* Fix Sonoff Led blank during firmware upgrade
|
||||
* Fix Sonoff Led flicker and possible flash corruption by using latest Arduino-esp8266 versions
|
||||
* of pwm core files included in sonoff library (#211)
|
||||
* Add PWM output control with commands PWM1 to PWM5 using user selectable GPIOs (#211)
|
||||
* Fix exceptions due to low values of commands HlwPCal (10000), HlwUCal (1000) and HlwICal (2500) (#223)
|
||||
* Add Switch state to sensor status (#227, #233)
|
||||
* Add user configuarble GPIO to module Sonoff Touch (#228)
|
||||
* Add define WEB_PORT to user_config.h to change default web server port from 80 (#232)
|
||||
* Fix failed Ota Firmware upgrade started from Web page (#235)
|
||||
*
|
||||
* 4.0.6 20170316
|
||||
* Fix to better find device by Wifi hostname
|
||||
* Fix compile error when some I2C devices are disabled
|
||||
* Add (experimental) support for SHT1X emulating I2C (#97)
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
timer.c - Timer1 library for esp8266
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "wiring_private.h"
|
||||
#include "pins_arduino.h"
|
||||
|
||||
#include "c_types.h"
|
||||
#include "ets_sys.h"
|
||||
|
||||
// ------------------------------------------------------------------ -
|
||||
// timer 1
|
||||
|
||||
static volatile timercallback timer1_user_cb = NULL;
|
||||
|
||||
void ICACHE_RAM_ATTR timer1_isr_handler(void *para){
|
||||
(void) para;
|
||||
if ((T1C & ((1 << TCAR) | (1 << TCIT))) == 0) TEIE &= ~TEIE1;//edge int disable
|
||||
T1I = 0;
|
||||
if (timer1_user_cb) {
|
||||
// to make ISR compatible to Arduino AVR model where interrupts are disabled
|
||||
// we disable them before we call the client ISR
|
||||
uint32_t savedPS = xt_rsil(15); // stop other interrupts
|
||||
timer1_user_cb();
|
||||
xt_wsr_ps(savedPS);
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_RAM_ATTR timer1_isr_init(){
|
||||
ETS_FRC_TIMER1_INTR_ATTACH(timer1_isr_handler, NULL);
|
||||
}
|
||||
|
||||
void timer1_attachInterrupt(timercallback userFunc) {
|
||||
timer1_user_cb = userFunc;
|
||||
ETS_FRC1_INTR_ENABLE();
|
||||
}
|
||||
|
||||
void ICACHE_RAM_ATTR timer1_detachInterrupt() {
|
||||
timer1_user_cb = 0;
|
||||
TEIE &= ~TEIE1;//edge int disable
|
||||
ETS_FRC1_INTR_DISABLE();
|
||||
}
|
||||
|
||||
void timer1_enable(uint8_t divider, uint8_t int_type, uint8_t reload){
|
||||
T1C = (1 << TCTE) | ((divider & 3) << TCPD) | ((int_type & 1) << TCIT) | ((reload & 1) << TCAR);
|
||||
T1I = 0;
|
||||
}
|
||||
|
||||
void ICACHE_RAM_ATTR timer1_write(uint32_t ticks){
|
||||
T1L = ((ticks)& 0x7FFFFF);
|
||||
if ((T1C & (1 << TCIT)) == 0) TEIE |= TEIE1;//edge int enable
|
||||
}
|
||||
|
||||
void ICACHE_RAM_ATTR timer1_disable(){
|
||||
T1C = 0;
|
||||
T1I = 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// timer 0
|
||||
|
||||
static volatile timercallback timer0_user_cb = NULL;
|
||||
|
||||
void ICACHE_RAM_ATTR timer0_isr_handler(void* para){
|
||||
(void) para;
|
||||
if (timer0_user_cb) {
|
||||
// to make ISR compatible to Arduino AVR model where interrupts are disabled
|
||||
// we disable them before we call the client ISR
|
||||
uint32_t savedPS = xt_rsil(15); // stop other interrupts
|
||||
timer0_user_cb();
|
||||
xt_wsr_ps(savedPS);
|
||||
}
|
||||
}
|
||||
|
||||
void timer0_isr_init(){
|
||||
ETS_CCOMPARE0_INTR_ATTACH(timer0_isr_handler, NULL);
|
||||
}
|
||||
|
||||
void timer0_attachInterrupt(timercallback userFunc) {
|
||||
timer0_user_cb = userFunc;
|
||||
ETS_CCOMPARE0_ENABLE();
|
||||
}
|
||||
|
||||
void ICACHE_RAM_ATTR timer0_detachInterrupt() {
|
||||
timer0_user_cb = NULL;
|
||||
ETS_CCOMPARE0_DISABLE();
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
digital.c - wiring digital implementation for esp8266
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#define ARDUINO_MAIN
|
||||
#include "wiring_private.h"
|
||||
#include "pins_arduino.h"
|
||||
#include "c_types.h"
|
||||
#include "eagle_soc.h"
|
||||
#include "ets_sys.h"
|
||||
|
||||
extern void pwm_stop_pin(uint8_t pin);
|
||||
|
||||
uint8_t esp8266_gpioToFn[16] = {0x34, 0x18, 0x38, 0x14, 0x3C, 0x40, 0x1C, 0x20, 0x24, 0x28, 0x2C, 0x30, 0x04, 0x08, 0x0C, 0x10};
|
||||
|
||||
extern void __pinMode(uint8_t pin, uint8_t mode) {
|
||||
pwm_stop_pin(pin);
|
||||
if(pin < 16){
|
||||
if(mode == SPECIAL){
|
||||
GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED)
|
||||
GPEC = (1 << pin); //Disable
|
||||
GPF(pin) = GPFFS(GPFFS_BUS(pin));//Set mode to BUS (RX0, TX0, TX1, SPI, HSPI or CLK depending in the pin)
|
||||
if(pin == 3) GPF(pin) |= (1 << GPFPU);//enable pullup on RX
|
||||
} else if(mode & FUNCTION_0){
|
||||
GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED)
|
||||
GPEC = (1 << pin); //Disable
|
||||
GPF(pin) = GPFFS((mode >> 4) & 0x07);
|
||||
if(pin == 13 && mode == FUNCTION_4) GPF(pin) |= (1 << GPFPU);//enable pullup on RX
|
||||
} else if(mode == OUTPUT || mode == OUTPUT_OPEN_DRAIN){
|
||||
GPF(pin) = GPFFS(GPFFS_GPIO(pin));//Set mode to GPIO
|
||||
GPC(pin) = (GPC(pin) & (0xF << GPCI)); //SOURCE(GPIO) | DRIVER(NORMAL) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED)
|
||||
if(mode == OUTPUT_OPEN_DRAIN) GPC(pin) |= (1 << GPCD);
|
||||
GPES = (1 << pin); //Enable
|
||||
} else if(mode == INPUT || mode == INPUT_PULLUP){
|
||||
GPF(pin) = GPFFS(GPFFS_GPIO(pin));//Set mode to GPIO
|
||||
GPEC = (1 << pin); //Disable
|
||||
GPC(pin) = (GPC(pin) & (0xF << GPCI)) | (1 << GPCD); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(UNCHANGED) | WAKEUP_ENABLE(DISABLED)
|
||||
if(mode == INPUT_PULLUP) {
|
||||
GPF(pin) |= (1 << GPFPU); // Enable Pullup
|
||||
}
|
||||
} else if(mode == WAKEUP_PULLUP || mode == WAKEUP_PULLDOWN){
|
||||
GPF(pin) = GPFFS(GPFFS_GPIO(pin));//Set mode to GPIO
|
||||
GPEC = (1 << pin); //Disable
|
||||
if(mode == WAKEUP_PULLUP) {
|
||||
GPF(pin) |= (1 << GPFPU); // Enable Pullup
|
||||
GPC(pin) = (1 << GPCD) | (4 << GPCI) | (1 << GPCWE); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(LOW) | WAKEUP_ENABLE(ENABLED)
|
||||
} else {
|
||||
GPF(pin) |= (1 << GPFPD); // Enable Pulldown
|
||||
GPC(pin) = (1 << GPCD) | (5 << GPCI) | (1 << GPCWE); //SOURCE(GPIO) | DRIVER(OPEN_DRAIN) | INT_TYPE(HIGH) | WAKEUP_ENABLE(ENABLED)
|
||||
}
|
||||
}
|
||||
} else if(pin == 16){
|
||||
GPF16 = GP16FFS(GPFFS_GPIO(pin));//Set mode to GPIO
|
||||
GPC16 = 0;
|
||||
if(mode == INPUT || mode == INPUT_PULLDOWN_16){
|
||||
if(mode == INPUT_PULLDOWN_16){
|
||||
GPF16 |= (1 << GP16FPD);//Enable Pulldown
|
||||
}
|
||||
GP16E &= ~1;
|
||||
} else if(mode == OUTPUT){
|
||||
GP16E |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern void ICACHE_RAM_ATTR __digitalWrite(uint8_t pin, uint8_t val) {
|
||||
pwm_stop_pin(pin);
|
||||
if(pin < 16){
|
||||
if(val) GPOS = (1 << pin);
|
||||
else GPOC = (1 << pin);
|
||||
} else if(pin == 16){
|
||||
if(val) GP16O |= 1;
|
||||
else GP16O &= ~1;
|
||||
}
|
||||
}
|
||||
|
||||
extern int ICACHE_RAM_ATTR __digitalRead(uint8_t pin) {
|
||||
pwm_stop_pin(pin);
|
||||
if(pin < 16){
|
||||
return GPIP(pin);
|
||||
} else if(pin == 16){
|
||||
return GP16I & 0x01;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
GPIO INTERRUPTS
|
||||
*/
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
|
||||
typedef struct {
|
||||
uint8_t mode;
|
||||
void (*fn)(void);
|
||||
} interrupt_handler_t;
|
||||
|
||||
static interrupt_handler_t interrupt_handlers[16];
|
||||
static uint32_t interrupt_reg = 0;
|
||||
|
||||
void ICACHE_RAM_ATTR interrupt_handler(void *arg) {
|
||||
(void) arg;
|
||||
uint32_t status = GPIE;
|
||||
GPIEC = status;//clear them interrupts
|
||||
uint32_t levels = GPI;
|
||||
if(status == 0 || interrupt_reg == 0) return;
|
||||
ETS_GPIO_INTR_DISABLE();
|
||||
int i = 0;
|
||||
uint32_t changedbits = status & interrupt_reg;
|
||||
while(changedbits){
|
||||
while(!(changedbits & (1 << i))) i++;
|
||||
changedbits &= ~(1 << i);
|
||||
interrupt_handler_t *handler = &interrupt_handlers[i];
|
||||
if (handler->fn &&
|
||||
(handler->mode == CHANGE ||
|
||||
(handler->mode & 1) == !!(levels & (1 << i)))) {
|
||||
// to make ISR compatible to Arduino AVR model where interrupts are disabled
|
||||
// we disable them before we call the client ISR
|
||||
uint32_t savedPS = xt_rsil(15); // stop other interrupts
|
||||
handler->fn();
|
||||
xt_wsr_ps(savedPS);
|
||||
}
|
||||
}
|
||||
ETS_GPIO_INTR_ENABLE();
|
||||
}
|
||||
|
||||
extern void ICACHE_RAM_ATTR __attachInterrupt(uint8_t pin, voidFuncPtr userFunc, int mode) {
|
||||
if(pin < 16) {
|
||||
interrupt_handler_t *handler = &interrupt_handlers[pin];
|
||||
handler->mode = mode;
|
||||
handler->fn = userFunc;
|
||||
interrupt_reg |= (1 << pin);
|
||||
GPC(pin) &= ~(0xF << GPCI);//INT mode disabled
|
||||
GPIEC = (1 << pin); //Clear Interrupt for this pin
|
||||
GPC(pin) |= ((mode & 0xF) << GPCI);//INT mode "mode"
|
||||
}
|
||||
}
|
||||
|
||||
extern void ICACHE_RAM_ATTR __detachInterrupt(uint8_t pin) {
|
||||
if(pin < 16) {
|
||||
GPC(pin) &= ~(0xF << GPCI);//INT mode disabled
|
||||
GPIEC = (1 << pin); //Clear Interrupt for this pin
|
||||
interrupt_reg &= ~(1 << pin);
|
||||
interrupt_handler_t *handler = &interrupt_handlers[pin];
|
||||
handler->mode = 0;
|
||||
handler->fn = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void initPins() {
|
||||
//Disable UART interrupts
|
||||
system_set_os_print(0);
|
||||
U0IE = 0;
|
||||
U1IE = 0;
|
||||
|
||||
for (int i = 0; i <= 5; ++i) {
|
||||
pinMode(i, INPUT);
|
||||
}
|
||||
// pins 6-11 are used for the SPI flash interface
|
||||
for (int i = 12; i <= 16; ++i) {
|
||||
pinMode(i, INPUT);
|
||||
}
|
||||
|
||||
ETS_GPIO_INTR_ATTACH(interrupt_handler, &interrupt_reg);
|
||||
ETS_GPIO_INTR_ENABLE();
|
||||
}
|
||||
|
||||
extern void pinMode(uint8_t pin, uint8_t mode) __attribute__ ((weak, alias("__pinMode")));
|
||||
extern void digitalWrite(uint8_t pin, uint8_t val) __attribute__ ((weak, alias("__digitalWrite")));
|
||||
extern int digitalRead(uint8_t pin) __attribute__ ((weak, alias("__digitalRead")));
|
||||
extern void attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode) __attribute__ ((weak, alias("__attachInterrupt")));
|
||||
extern void detachInterrupt(uint8_t pin) __attribute__ ((weak, alias("__detachInterrupt")));
|
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
pwm.c - analogWrite implementation for esp8266
|
||||
|
||||
Copyright (c) 2015 Hristo Gochkov. All rights reserved.
|
||||
This file is part of the esp8266 core for Arduino environment.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "wiring_private.h"
|
||||
#include "pins_arduino.h"
|
||||
#include "c_types.h"
|
||||
#include "eagle_soc.h"
|
||||
#include "ets_sys.h"
|
||||
|
||||
#ifndef F_CPU
|
||||
#define F_CPU 800000000L
|
||||
#endif
|
||||
|
||||
struct pwm_isr_table {
|
||||
uint8_t len;
|
||||
uint16_t steps[17];
|
||||
uint32_t masks[17];
|
||||
};
|
||||
|
||||
struct pwm_isr_data {
|
||||
struct pwm_isr_table tables[2];
|
||||
uint8_t active;//0 or 1, which table is active in ISR
|
||||
};
|
||||
|
||||
static struct pwm_isr_data _pwm_isr_data;
|
||||
|
||||
uint32_t pwm_mask = 0;
|
||||
uint16_t pwm_values[17] = {0,};
|
||||
uint32_t pwm_freq = 1000;
|
||||
uint32_t pwm_range = PWMRANGE;
|
||||
|
||||
uint8_t pwm_steps_changed = 0;
|
||||
uint32_t pwm_multiplier = 0;
|
||||
|
||||
int pwm_sort_array(uint16_t a[], uint16_t al)
|
||||
{
|
||||
uint16_t i, j;
|
||||
for (i = 1; i < al; i++) {
|
||||
uint16_t tmp = a[i];
|
||||
for (j = i; j >= 1 && tmp < a[j-1]; j--) {
|
||||
a[j] = a[j-1];
|
||||
}
|
||||
a[j] = tmp;
|
||||
}
|
||||
int bl = 1;
|
||||
for(i = 1; i < al; i++) {
|
||||
if(a[i] != a[i-1]) {
|
||||
a[bl++] = a[i];
|
||||
}
|
||||
}
|
||||
return bl;
|
||||
}
|
||||
|
||||
uint32_t pwm_get_mask(uint16_t value)
|
||||
{
|
||||
uint32_t mask = 0;
|
||||
int i;
|
||||
for(i=0; i<17; i++) {
|
||||
if((pwm_mask & (1 << i)) != 0 && pwm_values[i] == value) {
|
||||
mask |= (1 << i);
|
||||
}
|
||||
}
|
||||
return mask;
|
||||
}
|
||||
|
||||
void prep_pwm_steps()
|
||||
{
|
||||
if(pwm_mask == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int pwm_temp_steps_len = 0;
|
||||
uint16_t pwm_temp_steps[17];
|
||||
uint32_t pwm_temp_masks[17];
|
||||
uint32_t range = pwm_range;
|
||||
|
||||
if((F_CPU / ESP8266_CLOCK) == 1) {
|
||||
range /= 2;
|
||||
}
|
||||
|
||||
int i;
|
||||
for(i=0; i<17; i++) {
|
||||
if((pwm_mask & (1 << i)) != 0 && pwm_values[i] != 0) {
|
||||
pwm_temp_steps[pwm_temp_steps_len++] = pwm_values[i];
|
||||
}
|
||||
}
|
||||
pwm_temp_steps[pwm_temp_steps_len++] = range;
|
||||
pwm_temp_steps_len = pwm_sort_array(pwm_temp_steps, pwm_temp_steps_len) - 1;
|
||||
for(i=0; i<pwm_temp_steps_len; i++) {
|
||||
pwm_temp_masks[i] = pwm_get_mask(pwm_temp_steps[i]);
|
||||
}
|
||||
for(i=pwm_temp_steps_len; i>0; i--) {
|
||||
pwm_temp_steps[i] = pwm_temp_steps[i] - pwm_temp_steps[i-1];
|
||||
}
|
||||
|
||||
pwm_steps_changed = 0;
|
||||
struct pwm_isr_table *table = &(_pwm_isr_data.tables[!_pwm_isr_data.active]);
|
||||
table->len = pwm_temp_steps_len;
|
||||
ets_memcpy(table->steps, pwm_temp_steps, (pwm_temp_steps_len + 1) * 2);
|
||||
ets_memcpy(table->masks, pwm_temp_masks, pwm_temp_steps_len * 4);
|
||||
pwm_multiplier = ESP8266_CLOCK/(range * pwm_freq);
|
||||
pwm_steps_changed = 1;
|
||||
}
|
||||
|
||||
void ICACHE_RAM_ATTR pwm_timer_isr() //103-138
|
||||
{
|
||||
struct pwm_isr_table *table = &(_pwm_isr_data.tables[_pwm_isr_data.active]);
|
||||
static uint8_t current_step = 0;
|
||||
TEIE &= ~TEIE1;//14
|
||||
T1I = 0;//9
|
||||
if(current_step < table->len) { //20/21
|
||||
uint32_t mask = table->masks[current_step] & pwm_mask;
|
||||
if(mask & 0xFFFF) {
|
||||
GPOC = mask & 0xFFFF; //15/21
|
||||
}
|
||||
if(mask & 0x10000) {
|
||||
GP16O = 0; //6/13
|
||||
}
|
||||
current_step++;//1
|
||||
} else {
|
||||
current_step = 0;//1
|
||||
if(pwm_mask == 0) { //12
|
||||
table->len = 0;
|
||||
return;
|
||||
}
|
||||
if(pwm_mask & 0xFFFF) {
|
||||
GPOS = pwm_mask & 0xFFFF; //11
|
||||
}
|
||||
if(pwm_mask & 0x10000) {
|
||||
GP16O = 1; //5/13
|
||||
}
|
||||
if(pwm_steps_changed) { //12/21
|
||||
_pwm_isr_data.active = !_pwm_isr_data.active;
|
||||
table = &(_pwm_isr_data.tables[_pwm_isr_data.active]);
|
||||
pwm_steps_changed = 0;
|
||||
}
|
||||
}
|
||||
T1L = (table->steps[current_step] * pwm_multiplier);//23
|
||||
TEIE |= TEIE1;//13
|
||||
}
|
||||
|
||||
void pwm_start_timer()
|
||||
{
|
||||
timer1_disable();
|
||||
ETS_FRC_TIMER1_INTR_ATTACH(NULL, NULL);
|
||||
ETS_FRC_TIMER1_NMI_INTR_ATTACH(pwm_timer_isr);
|
||||
timer1_enable(TIM_DIV1, TIM_EDGE, TIM_SINGLE);
|
||||
timer1_write(1);
|
||||
}
|
||||
|
||||
void ICACHE_RAM_ATTR pwm_stop_pin(uint8_t pin)
|
||||
{
|
||||
if(pwm_mask){
|
||||
pwm_mask &= ~(1 << pin);
|
||||
if(pwm_mask == 0) {
|
||||
ETS_FRC_TIMER1_NMI_INTR_ATTACH(NULL);
|
||||
timer1_disable();
|
||||
timer1_isr_init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern void __analogWrite(uint8_t pin, int value)
|
||||
{
|
||||
bool start_timer = false;
|
||||
if(value == 0) {
|
||||
digitalWrite(pin, LOW);
|
||||
prep_pwm_steps();
|
||||
return;
|
||||
}
|
||||
if((pwm_mask & (1 << pin)) == 0) {
|
||||
if(pwm_mask == 0) {
|
||||
memset(&_pwm_isr_data, 0, sizeof(_pwm_isr_data));
|
||||
start_timer = true;
|
||||
}
|
||||
pinMode(pin, OUTPUT);
|
||||
digitalWrite(pin, LOW);
|
||||
pwm_mask |= (1 << pin);
|
||||
}
|
||||
if((F_CPU / ESP8266_CLOCK) == 1) {
|
||||
value = (value+1) / 2;
|
||||
}
|
||||
pwm_values[pin] = value % (pwm_range + 1);
|
||||
prep_pwm_steps();
|
||||
if(start_timer) {
|
||||
pwm_start_timer();
|
||||
}
|
||||
}
|
||||
|
||||
extern void __analogWriteFreq(uint32_t freq)
|
||||
{
|
||||
pwm_freq = freq;
|
||||
prep_pwm_steps();
|
||||
}
|
||||
|
||||
extern void __analogWriteRange(uint32_t range)
|
||||
{
|
||||
pwm_range = range;
|
||||
prep_pwm_steps();
|
||||
}
|
||||
|
||||
extern void analogWrite(uint8_t pin, int val) __attribute__ ((weak, alias("__analogWrite")));
|
||||
extern void analogWriteFreq(uint32_t freq) __attribute__ ((weak, alias("__analogWriteFreq")));
|
||||
extern void analogWriteRange(uint32_t range) __attribute__ ((weak, alias("__analogWriteRange")));
|
|
@ -191,6 +191,7 @@ struct SYSCFG {
|
|||
|
||||
char ntp_server[3][33];
|
||||
uint16_t pulsetime[MAX_PULSETIMERS];
|
||||
uint16_t pwmvalue[5];
|
||||
|
||||
} sysCfg;
|
||||
|
||||
|
|
|
@ -198,7 +198,8 @@ void CFG_Save()
|
|||
}
|
||||
} else {
|
||||
#endif // USE_SPIFFS
|
||||
if (sysCfg.module != SONOFF_LED) noInterrupts();
|
||||
noInterrupts();
|
||||
// if (sysCfg.module != SONOFF_LED) noInterrupts();
|
||||
if (sysCfg.saveFlag == 0) { // Handle default and rollover
|
||||
spi_flash_erase_sector(CFG_LOCATION + (sysCfg.saveFlag &1));
|
||||
spi_flash_write((CFG_LOCATION + (sysCfg.saveFlag &1)) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
|
||||
|
@ -206,7 +207,8 @@ void CFG_Save()
|
|||
sysCfg.saveFlag++;
|
||||
spi_flash_erase_sector(CFG_LOCATION + (sysCfg.saveFlag &1));
|
||||
spi_flash_write((CFG_LOCATION + (sysCfg.saveFlag &1)) * SPI_FLASH_SEC_SIZE, (uint32*)&sysCfg, sizeof(SYSCFG));
|
||||
if (sysCfg.module != SONOFF_LED) interrupts();
|
||||
interrupts();
|
||||
// if (sysCfg.module != SONOFF_LED) interrupts();
|
||||
snprintf_P(log, sizeof(log), PSTR("Config: Saved configuration (%d bytes) to flash at %X and count %d"), sizeof(SYSCFG), CFG_LOCATION + (sysCfg.saveFlag &1), sysCfg.saveFlag);
|
||||
addLog(LOG_LEVEL_DEBUG, log);
|
||||
}
|
||||
|
@ -511,6 +513,9 @@ void CFG_DefaultSet2()
|
|||
|
||||
CFG_DefaultSet_4_0_4();
|
||||
sysCfg.pulsetime[0] = APP_PULSETIME;
|
||||
|
||||
// v4.0.7
|
||||
for (byte i = 0; i < 5; i++) sysCfg.pwmvalue[i] = 0;
|
||||
}
|
||||
|
||||
void CFG_DefaultSet_3_2_4()
|
||||
|
@ -738,6 +743,9 @@ void CFG_Delta()
|
|||
memmove(sysCfg.my_module.gp.io, sysCfg.my_module.gp.io +1, MAX_GPIO_PIN -1); // move myio 1 byte to front
|
||||
sysCfg.my_module.gp.io[MAX_GPIO_PIN -1] = 0; // Clear ADC0
|
||||
}
|
||||
if (sysCfg.version < 0x04000700) {
|
||||
for (byte i = 0; i < 5; i++) sysCfg.pwmvalue[i] = 0;
|
||||
}
|
||||
sysCfg.version = VERSION;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
|
||||
//#define ALLOW_MIGRATE_TO_V3
|
||||
#ifdef ALLOW_MIGRATE_TO_V3
|
||||
#define VERSION 0x03091D00 // 3.9.29
|
||||
#define VERSION 0x03091E00 // 3.9.30
|
||||
#else
|
||||
#define VERSION 0x04000600 // 4.0.6
|
||||
#define VERSION 0x04000700 // 4.0.7
|
||||
#endif // ALLOW_MIGRATE_TO_V3
|
||||
|
||||
enum log_t {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
|
||||
|
@ -115,6 +115,9 @@ enum emul_t {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
|
|||
#define MAX_PULSETIMERS 4 // Max number of supported pulse timers
|
||||
#define WS2812_MAX_LEDS 256 // Max number of LEDs
|
||||
|
||||
#define PWM_RANGE 1023 // 127..1023 but as Color is addressed by 8 bits it should be 255 for my code
|
||||
#define PWM_FREQ 1000 // 100..1000 Hz led refresh
|
||||
|
||||
#define MAX_POWER_HOLD 10 // Time in SECONDS to allow max agreed power (Pow)
|
||||
#define MAX_POWER_WINDOW 30 // Time in SECONDS to disable allow max agreed power (Pow)
|
||||
#define SAFE_POWER_HOLD 10 // Time in SECONDS to allow max unit safe power (Pow)
|
||||
|
@ -284,6 +287,8 @@ uint8_t swt_flg = 0; // Any external switch configured
|
|||
uint8_t dht_type = 0; // DHT type (DHT11, DHT21 or DHT22)
|
||||
uint8_t hlw_flg = 0; // Power monitor configured
|
||||
uint8_t i2c_flg = 0; // I2C configured
|
||||
uint8_t pwm_flg = 0; // PWM configured
|
||||
uint8_t pwm_idxoffset = 0; // Allowed PWM command offset (change for Sonoff Led)
|
||||
|
||||
boolean mDNSbegun = false;
|
||||
|
||||
|
@ -883,7 +888,10 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
|||
}
|
||||
else if (!strcmp(type,"MODULE")) {
|
||||
if ((data_len > 0) && (payload > 0) && (payload <= MAXMODULE)) {
|
||||
sysCfg.module = payload -1;
|
||||
payload--;
|
||||
byte new_modflg = (sysCfg.module != payload);
|
||||
sysCfg.module = payload;
|
||||
if (new_modflg) for (byte i = 0; i < MAX_GPIO_PIN; i++) sysCfg.my_module.gp.io[i] = 0;
|
||||
restartflag = 2;
|
||||
}
|
||||
snprintf_P(stemp1, sizeof(stemp1), modules[sysCfg.module].name);
|
||||
|
@ -957,6 +965,21 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
|||
}
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue);
|
||||
}
|
||||
else if (!strcmp(type,"PWM") && (index > pwm_idxoffset) && (index <= 5)) {
|
||||
if ((data_len > 0) && (payload >= 0) && (payload <= PWM_RANGE) && (pin[GPIO_PWM1 + index -1] < 99)) {
|
||||
sysCfg.pwmvalue[index -1] = payload;
|
||||
analogWrite(pin[GPIO_PWM1 + index -1], payload);
|
||||
}
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("{\"PWM\":{"));
|
||||
bool first = true;
|
||||
for (byte i = 0; i < 5; i++) {
|
||||
if(pin[GPIO_PWM1 + i] < 99) {
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"PWM%d\":%d"), svalue, first ? "" : ", ", i+1, sysCfg.pwmvalue[i]);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
snprintf_P(svalue, sizeof(svalue), PSTR("%s}}"),svalue);
|
||||
}
|
||||
else if (!strcmp(type,"SLEEP")) {
|
||||
if ((data_len > 0) && (payload >= 0) && (payload < 251)) {
|
||||
if ((!sysCfg.sleep && payload) || (sysCfg.sleep && !payload)) restartflag = 2;
|
||||
|
@ -1247,6 +1270,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
|
|||
snprintf_P(svalue, sizeof(svalue), PSTR("%s, Weblog, Webserver, WebPassword, Emulation"), svalue);
|
||||
#endif
|
||||
if (swt_flg) snprintf_P(svalue, sizeof(svalue), PSTR("%s, SwitchMode"), svalue);
|
||||
if (pwm_flg) snprintf_P(svalue, sizeof(svalue), PSTR("%s, PWM"), svalue);
|
||||
#ifdef USE_I2C
|
||||
if (i2c_flg) snprintf_P(svalue, sizeof(svalue), PSTR("%s, I2CScan"), svalue);
|
||||
#endif // USE_I2C
|
||||
|
@ -1508,7 +1532,13 @@ void state_mqttPresent(char* svalue, uint16_t ssvalue)
|
|||
void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
|
||||
{
|
||||
snprintf_P(svalue, ssvalue, PSTR("%s{\"Time\":\"%s\""), svalue, getDateTime().c_str());
|
||||
|
||||
for (byte i = 0; i < 4; i++) {
|
||||
if (pin[GPIO_SWT1 +i] < 99) {
|
||||
byte swm = ((sysCfg.switchmode[i] == FOLLOW_INV)||(sysCfg.switchmode[i] == PUSHBUTTON_INV));
|
||||
snprintf_P(svalue, ssvalue, PSTR("%s, \"Switch%d\":\"%s\""),
|
||||
svalue, i +1, (lastwallswitch[i]) ? (swm) ? MQTT_STATUS_ON : MQTT_STATUS_OFF : (swm) ? MQTT_STATUS_OFF : MQTT_STATUS_ON);
|
||||
}
|
||||
}
|
||||
#ifndef USE_ADC_VCC
|
||||
if (pin[GPIO_ADC0] < 99) {
|
||||
snprintf_P(svalue, ssvalue, PSTR("%s, \"AnalogInput0\":%d"), svalue, analogRead(A0));
|
||||
|
@ -1999,6 +2029,9 @@ void GPIO_init()
|
|||
}
|
||||
}
|
||||
|
||||
analogWriteRange(PWM_RANGE); // Default is 1023 (Arduino.h)
|
||||
analogWriteFreq(PWM_FREQ); // Default is 1000 (core_esp8266_wiring_pwm.c)
|
||||
|
||||
Maxdevice = 1;
|
||||
if (sysCfg.module == SONOFF_DUAL) {
|
||||
Maxdevice = 2;
|
||||
|
@ -2009,6 +2042,7 @@ void GPIO_init()
|
|||
Baudrate = 19200;
|
||||
}
|
||||
else if (sysCfg.module == SONOFF_LED) {
|
||||
pwm_idxoffset = 2;
|
||||
pin[GPIO_WS2812] = 99; // I do not allow both Sonoff Led AND WS2812 led
|
||||
sl_init();
|
||||
}
|
||||
|
@ -2033,6 +2067,14 @@ void GPIO_init()
|
|||
lastwallswitch[i] = digitalRead(pin[GPIO_SWT1 +i]); // set global now so doesn't change the saved power state on first switch check
|
||||
}
|
||||
}
|
||||
for (byte i = pwm_idxoffset; i < 5; i++) {
|
||||
if (pin[GPIO_PWM1 +i] < 99) {
|
||||
pwm_flg = 1;
|
||||
pinMode(pin[GPIO_PWM1 +i], OUTPUT);
|
||||
analogWrite(pin[GPIO_PWM1 +i], sysCfg.pwmvalue[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (sysCfg.module == EXS_RELAY) {
|
||||
setLatchingRelay(0,2);
|
||||
setLatchingRelay(1,2);
|
||||
|
|
|
@ -37,6 +37,11 @@ enum upins_t {
|
|||
GPIO_LED2_INV,
|
||||
GPIO_LED3_INV,
|
||||
GPIO_LED4_INV,
|
||||
GPIO_PWM1, // Sonoff Led Cold
|
||||
GPIO_PWM2, // Sonoff Led Warm
|
||||
GPIO_PWM3, // Red (swapped with Blue from original)
|
||||
GPIO_PWM4, // Green
|
||||
GPIO_PWM5, // Blue (swapped with Red from original)
|
||||
GPIO_SENSOR_END };
|
||||
|
||||
// Text in webpage Module Parameters and commands GPIOS and GPIO
|
||||
|
@ -73,17 +78,17 @@ const char sensors[GPIO_SENSOR_END][9] PROGMEM = {
|
|||
"Led1I",
|
||||
"Led2I",
|
||||
"Led3I",
|
||||
"Led4I"
|
||||
"Led4I",
|
||||
"PWM1",
|
||||
"PWM2",
|
||||
"PWM3",
|
||||
"PWM4",
|
||||
"PWM5"
|
||||
};
|
||||
|
||||
// Programmer selectable GPIO functionality offset by user selectable GPIOs
|
||||
enum fpins_t {
|
||||
GPIO_PWM0 = GPIO_SENSOR_END, // Cold
|
||||
GPIO_PWM1, // Warm
|
||||
GPIO_PWM2, // Red (swapped with Blue from original)
|
||||
GPIO_PWM3, // Green
|
||||
GPIO_PWM4, // Blue (swapped with Red from original)
|
||||
GPIO_RXD, // Serial interface
|
||||
GPIO_RXD = GPIO_SENSOR_END, // Serial interface
|
||||
GPIO_TXD, // Serial interface
|
||||
GPIO_HLW_SEL, // HLW8012 Sel output (Sonoff Pow)
|
||||
GPIO_HLW_CF1, // HLW8012 CF1 voltage / current (Sonoff Pow)
|
||||
|
@ -250,7 +255,10 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
|
|||
},
|
||||
{ "Sonoff Touch", // Sonoff Touch (ESP8285)
|
||||
GPIO_KEY1, // GPIO00 Button
|
||||
0, 0, 0, 0, 0,
|
||||
GPIO_USER, // GPIO01 Serial RXD and Optional sensor
|
||||
0,
|
||||
GPIO_USER, // GPIO03 Serial TXD and Optional sensor
|
||||
0, 0,
|
||||
0, 0, 0, // Flash connection
|
||||
0, 0, 0,
|
||||
GPIO_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On)
|
||||
|
@ -263,9 +271,9 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
|
|||
GPIO_USER, // GPIO04 Optional sensor (PWM3 Green)
|
||||
GPIO_USER, // GPIO05 Optional sensor (PWM2 Red)
|
||||
0, 0, 0, 0, 0, 0, // Flash connection
|
||||
GPIO_PWM0, // GPIO12 Cold light
|
||||
GPIO_PWM1, // GPIO12 Cold light (PWM0 Cold)
|
||||
GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off)
|
||||
GPIO_PWM1, // GPIO14 Warm light
|
||||
GPIO_PWM2, // GPIO14 Warm light (PWM1 Warm)
|
||||
GPIO_USER, // GPIO15 Optional sensor (PWM4 Blue)
|
||||
0, 0
|
||||
},
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
// -- HTTP ----------------------------------------
|
||||
#define USE_WEBSERVER // Enable web server and wifi manager (+62k code, +4k mem) - Disable by //
|
||||
#define WEB_SERVER 2 // [WebServer] Web server (0 = Off, 1 = Start as User, 2 = Start as Admin)
|
||||
#define WEB_PORT 80 // Web server Port for User and Admin mode
|
||||
#define WEB_USERNAME "admin" // Web server Admin mode user name
|
||||
#define WEB_PASSWORD "" // [WebPassword] Web server Admin mode Password for WEB_USERNAME (empty string = Disable)
|
||||
#define FRIENDLY_NAME "Sonoff" // [FriendlyName] Friendlyname up to 32 characters used by webpages and Alexa
|
||||
|
|
|
@ -278,7 +278,7 @@ void startWebserver(int type, IPAddress ipweb)
|
|||
|
||||
if (!_httpflag) {
|
||||
if (!webServer) {
|
||||
webServer = new ESP8266WebServer(80);
|
||||
webServer = new ESP8266WebServer((type==HTTP_MANAGER)?80:WEB_PORT);
|
||||
webServer->on("/", handleRoot);
|
||||
webServer->on("/cn", handleConfig);
|
||||
webServer->on("/md", handleModule);
|
||||
|
@ -805,7 +805,7 @@ void handleSave()
|
|||
{
|
||||
if (httpUser()) return;
|
||||
|
||||
char log[LOGSZ], stemp[20];
|
||||
char log[LOGSZ +20], stemp[20];
|
||||
byte what = 0, restart;
|
||||
String result = "";
|
||||
|
||||
|
@ -870,14 +870,16 @@ void handleSave()
|
|||
addLog(LOG_LEVEL_INFO, log);
|
||||
break;
|
||||
case 6:
|
||||
sysCfg.module = (!strlen(webServer->arg("mt").c_str())) ? MODULE : atoi(webServer->arg("mt").c_str());
|
||||
byte new_module = (!strlen(webServer->arg("mt").c_str())) ? MODULE : atoi(webServer->arg("mt").c_str());
|
||||
byte new_modflg = (sysCfg.module != new_module);
|
||||
sysCfg.module = new_module;
|
||||
mytmplt cmodule;
|
||||
memcpy_P(&cmodule, &modules[sysCfg.module], sizeof(cmodule));
|
||||
String gpios = "";
|
||||
for (byte i = 0; i < MAX_GPIO_PIN; i++) {
|
||||
if (cmodule.gp.io[i] == GPIO_USER) {
|
||||
snprintf_P(stemp, sizeof(stemp), PSTR("g%d"), i);
|
||||
sysCfg.my_module.gp.io[i] = (!strlen(webServer->arg(stemp).c_str())) ? 0 : atoi(webServer->arg(stemp).c_str());
|
||||
sysCfg.my_module.gp.io[i] = (new_modflg) ? 0 : (!strlen(webServer->arg(stemp).c_str())) ? 0 : atoi(webServer->arg(stemp).c_str());
|
||||
gpios += F(", GPIO"); gpios += String(i); gpios += F(" "); gpios += String(sysCfg.my_module.gp.io[i]);
|
||||
}
|
||||
}
|
||||
|
@ -961,7 +963,7 @@ void handleUpgrade()
|
|||
void handleUpgradeStart()
|
||||
{
|
||||
if (httpUser()) return;
|
||||
char svalue[16]; // was MESSZ
|
||||
char svalue[100]; // was MESSZ
|
||||
|
||||
addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Firmware upgrade start"));
|
||||
WIFI_configCounter();
|
||||
|
|
|
@ -27,9 +27,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
* Sonoff Led
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define ANALOG_WRITE_RANGE 255 // 127..1023 but as Color is addressed by 8 bits it should be 255 for my code
|
||||
#define ANALOG_WRITE_FREQ 432 // 100..1000 Hz led refresh
|
||||
|
||||
uint8_t ledTable[] = {
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
|
@ -90,8 +87,8 @@ void sl_setDim(uint8_t myDimmer)
|
|||
|
||||
void sl_init(void)
|
||||
{
|
||||
analogWriteRange(ANALOG_WRITE_RANGE); // Default is 1023 (Arduino.h)
|
||||
analogWriteFreq(ANALOG_WRITE_FREQ); // Default is 1000 (core_esp8266_wiring_pwm.c) - Try to lower flicker
|
||||
sysCfg.pwmvalue[0] = 0; // We use led_color
|
||||
sysCfg.pwmvalue[1] = 0; // We use led_color
|
||||
sl_blankv = 0;
|
||||
sl_power = 0;
|
||||
sl_any = 0;
|
||||
|
@ -104,11 +101,14 @@ void sl_blank(byte state)
|
|||
// state = 0: No blank
|
||||
// 1: Blank led to solve flicker
|
||||
|
||||
/*
|
||||
* Disabled when used with latest arduino-esp8266 pwm files
|
||||
if (sysCfg.module == SONOFF_LED) {
|
||||
sl_blankv = state;
|
||||
sl_wakeupActive = 0;
|
||||
sl_animate();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void sl_setPower(uint8_t power)
|
||||
|
@ -172,8 +172,8 @@ void sl_animate()
|
|||
sl_lcolor[0] = sl_tcolor[0];
|
||||
sl_lcolor[1] = sl_tcolor[1];
|
||||
for (byte i = 0; i < 2; i++) {
|
||||
if (pin[GPIO_PWM0 +i] < 99) {
|
||||
analogWrite(pin[GPIO_PWM0 +i], (sysCfg.led_table) ? ledTable[sl_lcolor[i]] : sl_lcolor[i]);
|
||||
if (pin[GPIO_PWM1 +i] < 99) {
|
||||
analogWrite(pin[GPIO_PWM1 +i], ((sysCfg.led_table) ? ledTable[sl_lcolor[i]] : sl_lcolor[i]) * (PWM_RANGE / 255));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -438,19 +438,19 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len
|
|||
}
|
||||
else if (!strcmp(type,"HLWPCAL")) {
|
||||
if ((data_len > 0) && (payload > 0) && (payload < 32001)) {
|
||||
sysCfg.hlw_pcal = (payload == 1) ? HLW_PREF_PULSE : payload;
|
||||
sysCfg.hlw_pcal = (payload > 9999) ? payload : HLW_PREF_PULSE; // 12530
|
||||
}
|
||||
snprintf_P(svalue, ssvalue, PSTR("(\"HlwPcal\":\"%d%s\"}"), sysCfg.hlw_pcal, (sysCfg.value_units) ? " uS" : "");
|
||||
}
|
||||
else if (!strcmp(type,"HLWUCAL")) {
|
||||
if ((data_len > 0) && (payload > 0) && (payload < 32001)) {
|
||||
sysCfg.hlw_ucal = (payload == 1) ? HLW_UREF_PULSE : payload;
|
||||
sysCfg.hlw_ucal = (payload > 999) ? payload : HLW_UREF_PULSE; // 1950
|
||||
}
|
||||
snprintf_P(svalue, ssvalue, PSTR("{\"HlwUcal\":\"%d%s\"}"), sysCfg.hlw_ucal, (sysCfg.value_units) ? " uS" : "");
|
||||
}
|
||||
else if (!strcmp(type,"HLWICAL")) {
|
||||
if ((data_len > 0) && (payload > 0) && (payload < 32001)) {
|
||||
sysCfg.hlw_ical = (payload == 1) ? HLW_IREF_PULSE : payload;
|
||||
sysCfg.hlw_ical = (payload > 2499) ? payload : HLW_IREF_PULSE; // 3500
|
||||
}
|
||||
snprintf_P(svalue, ssvalue, PSTR("{\"HlwIcal\":\"%d%s\"}"), sysCfg.hlw_ical, (sysCfg.value_units) ? " uS" : "");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue