diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index dec628ae1..292a61b18 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index d6c73baa9..48e34a4c3 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index a9d85ba3c..98d3cf16f 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index b6b9dfa9d..8acf24fa7 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index 0a85d6a8b..2d07be421 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index 4503c4e57..b8b2f5950 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index 89a863810..2b71e0066 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/he-HE.h b/sonoff/language/he-HE.h index 7e2deacab..eb4feb449 100644 --- a/sonoff/language/he-HE.h +++ b/sonoff/language/he-HE.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index a7db58513..cf924b2ac 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index a5ffca743..3698bc57d 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index 773442714..e33a5cf90 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -481,6 +481,7 @@ #define D_TX20_SOUTH "S" #define D_TX20_WEST "W" + // sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box #define D_SENSOR_NONE "Geen" #define D_SENSOR_DHT11 "DHT11" @@ -555,6 +556,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index 63a15c5a5..b2847923b 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -481,6 +481,7 @@ #define D_TX20_SOUTH "S" #define D_TX20_WEST "W" + // sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box #define D_SENSOR_NONE "Brak" #define D_SENSOR_DHT11 "DHT11" @@ -555,6 +556,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index 1b0c34b16..d66ed8589 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index b969449d2..a9d22221f 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index b2ad0a1d8..762bfe1f5 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/sk-SK.h b/sonoff/language/sk-SK.h index 49430c31e..0c8d0f428 100644 --- a/sonoff/language/sk-SK.h +++ b/sonoff/language/sk-SK.h @@ -481,6 +481,7 @@ #define D_TX20_SOUTH "J" #define D_TX20_WEST "Z" + // sonoff_template.h - keep them as short as possible to be able to fit them in GUI drop down box #define D_SENSOR_NONE "Žiaden" #define D_SENSOR_DHT11 "DHT11" @@ -555,6 +556,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/sv-SE.h b/sonoff/language/sv-SE.h index 61ab33b57..2c36c1d8b 100644 --- a/sonoff/language/sv-SE.h +++ b/sonoff/language/sv-SE.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h index cfad17ca0..b41e57f10 100755 --- a/sonoff/language/tr-TR.h +++ b/sonoff/language/tr-TR.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h index ce72f093f..47b62987b 100644 --- a/sonoff/language/uk-UK.h +++ b/sonoff/language/uk-UK.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index a022f7939..5a581d0da 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "安" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index 06274c41b..602ecbe4d 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -555,6 +555,9 @@ #define D_SENSOR_CSE7766_RX "CSE7766 Rx" #define D_SENSOR_PN532_TX "PN532 Tx" #define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" // Units #define D_UNIT_AMPERE "安" diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index 182957209..3029a3dc4 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -418,6 +418,8 @@ // #define USE_THEO_V2 // Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver (+1k4 code) // #define USE_ALECTO_V2 // Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 weather stations using 868MHz RF sensor receiver (+1k7 code) +#define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code) + /*********************************************************************************************\ * Debug features are only supported in development branch \*********************************************************************************************/ diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 9ba91f091..b54a32f3c 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -168,6 +168,8 @@ typedef unsigned long power_t; // Power (Relay) type #define NEO_RGBW 5 // Neopixel RGBW leds #define NEO_GRBW 6 // Neopixel GRBW leds +#define LT_SM16716 16 // Lights that use SM16716 will have this bit set in light_type + #define MQTT_PUBSUBCLIENT 1 // Mqtt PubSubClient library #define MQTT_TASMOTAMQTT 2 // Mqtt TasmotaMqtt library based on esp-mqtt-arduino - soon obsolete #define MQTT_ESPMQTTARDUINO 3 // Mqtt esp-mqtt-arduino library by Ingo Randolf - obsolete but define is present for debugging purposes diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 8f220eb7a..17f9bdf4a 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -2429,6 +2429,12 @@ void GpioInit(void) light_type = LT_WS2812; } #endif // USE_WS2812 +#ifdef USE_SM16716 + if (SM16716_ModuleSelected()) { + light_type += 3; + light_type |= LT_SM16716; + } +#endif // ifdef USE_SM16716 if (!light_type) { for (uint8_t i = 0; i < MAX_PWMS; i++) { // Basic PWM control only if (pin[GPIO_PWM1 +i] < 99) { diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index f6ae3aced..a400d2afd 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -164,6 +164,9 @@ enum UserSelectablePins { GPIO_MCP39F5_RST, // MCP39F501 Reset (Shelly2) GPIO_PN532_TXD, // PN532 NFC Serial Tx GPIO_PN532_RXD, // PN532 NFC Serial Rx + GPIO_SM16716_CLK, // SM16716 CLOCK + GPIO_SM16716_DAT, // SM16716 DATA + GPIO_SM16716_SEL, // SM16716 SELECT GPIO_SENSOR_END }; // Programmer selectable GPIO functionality offset by user selectable GPIOs @@ -229,7 +232,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_BUTTON "1in|" D_SENSOR_BUTTON "2in|" D_SENSOR_BUTTON "3in|" D_SENSOR_BUTTON "4in|" D_SENSOR_NRG_SEL "|" D_SENSOR_NRG_SEL "i|" D_SENSOR_NRG_CF1 "|" D_SENSOR_HLW_CF "|" D_SENSOR_HJL_CF "|" D_SENSOR_MCP39F5_TX "|" D_SENSOR_MCP39F5_RX "|" D_SENSOR_MCP39F5_RST "|" - D_SENSOR_PN532_TX "|" D_SENSOR_PN532_RX + D_SENSOR_PN532_TX "|" D_SENSOR_PN532_RX "|" + D_SENSOR_SM16716_CLK "|" D_SENSOR_SM16716_DAT "|" D_SENSOR_SM16716_POWER ; /********************************************************************************************/ @@ -304,6 +308,7 @@ enum SupportedModules { MI_DESK_LAMP, SP10, WAGA, + SYF05, MAXMODULE }; /********************************************************************************************/ @@ -553,6 +558,18 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_MAX31855CLK, // MAX31855 Serial interface GPIO_MAX31855DO, // MAX31855 Serial interface #endif +#ifdef USE_SM16716 + GPIO_SM16716_CLK, // SM16716 CLOCK + GPIO_SM16716_DAT, // SM16716 DATA + GPIO_SM16716_SEL, // SM16716 SELECT +#endif // USE_SM16716 +#if defined(USE_ENERGY_SENSOR) && defined(USE_HLW8012) + GPIO_NRG_SEL, // HLW8012/HLJ-01 Sel output (1 = Voltage) + GPIO_NRG_SEL_INV, // HLW8012/HLJ-01 Sel output (0 = Voltage) + GPIO_NRG_CF1, // HLW8012/HLJ-01 CF1 voltage / current + GPIO_HLW_CF, // HLW8012 CF power + GPIO_HJL_CF, // HJL-01/BL0937 CF power +#endif }; const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { @@ -623,7 +640,8 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { PHILIPS, YTF_IR_BRIDGE, WITTY, // Development Devices - WEMOS + WEMOS, + SYF05 }; // Default module settings @@ -1863,6 +1881,31 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_NRG_CF1, // GPIO14 HJL-01 CF1 voltage / current GPIO_LED1_INV, // GPIO15 Blue LED - Link status 0, 0 + }, + { "SYF05", // Sunyesmart SYF05 (a.k.a. Fcmila) = TYWE3S + SM16726 + // Also works with Merkury 904 RGBW Bulbs with 13 set to GPIO_SM16716_SEL + // https://www.flipkart.com/fc-mila-bxav-xs-ad-smart-bulb/p/itmf85zgs45fzr7n + // https://docs.tuya.com/en/hardware/WiFi-module/wifi-e3s-module.html + // http://www.datasheet-pdf.com/PDF/SM16716-Datasheet-Sunmoon-932771 + GPIO_USER, // GPIO00 N.C. + 0, + GPIO_USER, // GPIO02 N.C. + 0, + GPIO_SM16716_CLK, // GPIO04 SM16716 Clock + GPIO_PWM1, // GPIO05 White + // GPIO06 + // GPIO07 + // GPIO08 + 0, // GPIO09 + 0, // GPIO10 + // GPIO11 + GPIO_USER, // GPIO12 Alt. White on some devices + GPIO_USER, // GPIO13 SM16716 Enable on some devices + GPIO_SM16716_DAT, // GPIO14 SM16716 Data + 0, // GPIO15 wired to GND + GPIO_USER, // GPIO16 N.C. + GPIO_FLAG_ADC0 // ADC0 A0 Analog input +// + GPIO_FLAG_PULLUP // Allow input pull-up control } }; diff --git a/sonoff/support_features.ino b/sonoff/support_features.ino index 09d5d140c..31c449531 100644 --- a/sonoff/support_features.ino +++ b/sonoff/support_features.ino @@ -177,8 +177,10 @@ void GetFeatures(void) #ifdef USE_ARMTRONIX_DIMMERS feature_drv2 |= 0x00020000; // xdrv_18_armtronixdimmer.ino #endif +#ifdef USE_SM16716 + feature_drv2 |= 0x00040000; // xdrv_04_light.ino +#endif -// feature_drv2 |= 0x00040000; // feature_drv2 |= 0x00080000; // feature_drv2 |= 0x00100000; // feature_drv2 |= 0x00200000; diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 9d8740ccb..bc4a9b91c 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -32,6 +32,9 @@ * 11 +WS2812 RGB(W) no (One WS2812 RGB or RGBW ledstrip) * 12 AiLight RGBW no * 13 Sonoff B1 RGBCW yes + * 19 SM16716 RGB no + * 20 SM16716+W RGBW no + * 21 SM16716+CW RGBCW yes * * light_scheme WS2812 3+ Colors 1+2 Colors Effect * ------------ ------ --------- ---------- ----------------- @@ -354,6 +357,117 @@ void LightMy92x1Duty(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b, uint8_t dut os_delay_us(12); // TStop > 12us. } +#ifdef USE_SM16716 +/*********************************************************************************************\ + * SM16716 - Controlling RGB over a synchronous serial line + * Copyright (C) 2019 Gabor Simon + * + * Source: https://community.home-assistant.io/t/cheap-uk-wifi-bulbs-with-tasmota-teardown-help-tywe3s/40508/27 + * +\*********************************************************************************************/ + +// Enable this for debug logging +//#define D_LOG_SM16716 "SM16716: " + +uint8_t sm16716_pin_clk = 100; +uint8_t sm16716_pin_dat = 100; +uint8_t sm16716_pin_sel = 100; +uint8_t sm16716_enabled = 0; + +void SM16716_SendBit(uint8_t v) +{ + /* NOTE: + * According to the spec sheet, max freq is 30 MHz, that is 16.6 ns per high/low half of the + * clk square wave. That is less than the overhead of 'digitalWrite' at this clock rate, + * so no additional delays are needed yet. */ + + digitalWrite(sm16716_pin_dat, (v != 0) ? HIGH : LOW); + //delayMicroseconds(1); + digitalWrite(sm16716_pin_clk, HIGH); + //delayMicroseconds(1); + digitalWrite(sm16716_pin_clk, LOW); +} + +void SM16716_SendByte(uint8_t v) +{ + uint8_t mask; + + for (mask = 0x80; mask; mask >>= 1) { + SM16716_SendBit(v & mask); + } +} + +void SM16716_Update(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b) +{ + if (sm16716_pin_sel < 99) { + uint8_t sm16716_should_enable = (duty_r | duty_g | duty_b); + if (!sm16716_enabled && sm16716_should_enable) { +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "turning color on")); + AddLog(LOG_LEVEL_DEBUG); +#endif // D_LOG_SM16716 + sm16716_enabled = 1; + digitalWrite(sm16716_pin_sel, HIGH); + // in testing I found it takes a minimum of ~380us to wake up the chip + // tested on a Merkury RGBW with an SM726EB + delayMicroseconds(400); + SM16716_Init(); + } + else if (sm16716_enabled && !sm16716_should_enable) { +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_SM16716 "turning color off")); + AddLog(LOG_LEVEL_DEBUG); +#endif // D_LOG_SM16716 + sm16716_enabled = 0; + digitalWrite(sm16716_pin_sel, LOW); + } + } +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "Update; rgb=%02x%02x%02x"), + duty_r, duty_g, duty_b); + AddLog(LOG_LEVEL_DEBUG); +#endif // D_LOG_SM16716 + + // send start bit + SM16716_SendBit(1); + // send 24-bit rgb data + SM16716_SendByte(duty_r); + SM16716_SendByte(duty_g); + SM16716_SendByte(duty_b); + // send a 'do it' pulse + // (if multiple chips are chained, each one processes the 1st '1rgb' 25-bit block and + // passes on the rest, right until the one starting with 0) + //SM16716_Init(); + SM16716_SendBit(0); + SM16716_SendByte(0); + SM16716_SendByte(0); + SM16716_SendByte(0); +} + +bool SM16716_ModuleSelected(void) +{ + sm16716_pin_clk = pin[GPIO_SM16716_CLK]; + sm16716_pin_dat = pin[GPIO_SM16716_DAT]; + sm16716_pin_sel = pin[GPIO_SM16716_SEL]; +#ifdef D_LOG_SM16716 + snprintf_P(log_data, sizeof(log_data), + PSTR(D_LOG_SM16716 "ModuleSelected; clk_pin=%d, dat_pin=%d)"), + sm16716_pin_clk, sm16716_pin_dat); + AddLog(LOG_LEVEL_DEBUG); +#endif // D_LOG_SM16716 + return (sm16716_pin_clk < 99) && (sm16716_pin_dat < 99); +} + +void SM16716_Init(void) +{ + for (uint8_t t_init = 0; t_init < 50; ++t_init) { + SM16716_SendBit(0); + } +} + +#endif // ifdef USE_SM16716 + /********************************************************************************************/ void LightInit(void) @@ -402,6 +516,32 @@ void LightInit(void) max_scheme = LS_MAX + WS2812_SCHEMES; } #endif // USE_WS2812 ************************************************************************ +#ifdef USE_SM16716 + else if (LT_SM16716 == light_type - light_subtype) { + // init PWM + for (uint8_t i = 0; i < light_subtype; i++) { + Settings.pwm_value[i] = 0; // Disable direct PWM control + if (pin[GPIO_PWM1 +i] < 99) { + pinMode(pin[GPIO_PWM1 +i], OUTPUT); + } + } + // init sm16716 + pinMode(sm16716_pin_clk, OUTPUT); + digitalWrite(sm16716_pin_clk, LOW); + + pinMode(sm16716_pin_dat, OUTPUT); + digitalWrite(sm16716_pin_dat, LOW); + + if (sm16716_pin_sel < 99) { + pinMode(sm16716_pin_sel, OUTPUT); + digitalWrite(sm16716_pin_sel, LOW); + // no need to call SM16716_Init here, it will be called after sel goes HIGH + } else { + // no sel pin means you have an 'always on' chip, so init right away + SM16716_Init(); + } + } +#endif // ifdef USE_SM16716 else { light_pdi_pin = pin[GPIO_DI]; light_pdcki_pin = pin[GPIO_DCKI]; @@ -844,6 +984,24 @@ void LightAnimate(void) Ws2812SetColor(0, cur_col[0], cur_col[1], cur_col[2], cur_col[3]); } #endif // USE_ES2812 ************************************************************************ +#ifdef USE_SM16716 + else if (LT_SM16716 == light_type - light_subtype) { + // handle any PWM pins, skipping the first 3 values for sm16716 + for (uint8_t i = 3; i < light_subtype; i++) { + if (pin[GPIO_PWM1 +i-3] < 99) { + if (cur_col[i] > 0xFC) { + cur_col[i] = 0xFC; // Fix unwanted blinking and PWM watchdog errors for values close to pwm_range (H801, Arilux and BN-SZ01) + } + uint16_t curcol = cur_col[i] * (Settings.pwm_range / 255); +// snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "Cur_Col%d %d, CurCol %d"), i, cur_col[i], curcol); +// AddLog(LOG_LEVEL_DEBUG); + analogWrite(pin[GPIO_PWM1 +i-3], bitRead(pwm_inverted, i-3) ? Settings.pwm_range - curcol : curcol); + } + } + // handle sm16716 update + SM16716_Update(cur_col[0], cur_col[1], cur_col[2]); + } +#endif // ifdef USE_SM16716 else if (light_type > LT_WS2812) { LightMy92x1Duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]); }