mirror of https://github.com/arendst/Tasmota.git
parent
019dc76740
commit
4ff340d368
|
@ -322,6 +322,7 @@
|
|||
// #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial RXD) (+1k mem). When USE_WS2812_DMA is enabled expect Exceptions on Pow
|
||||
#define USE_WS2812_HARDWARE NEO_HW_WS2812 // Hardware type (NEO_HW_WS2812, NEO_HW_WS2812X, NEO_HW_WS2813, NEO_HW_SK6812, NEO_HW_LC8812, NEO_HW_APA106)
|
||||
#define USE_WS2812_CTYPE NEO_GRB // Color type (NEO_RGB, NEO_GRB, NEO_BRG, NEO_RBG, NEO_RGBW, NEO_GRBW)
|
||||
#define USE_MY92X1 // Add support for MY92X1 RGBCW led controller as used in Sonoff B1, Ailight and Lohas
|
||||
#define USE_SM16716 // Add support for SM16716 RGB LED controller (+0k7 code)
|
||||
#define USE_SM2135 // Add support for SM2135 RGBCW led control as used in Action LSC (+0k6 code)
|
||||
|
||||
|
|
|
@ -550,8 +550,10 @@ const uint8_t kGpioNiceList[] PROGMEM = {
|
|||
GPIO_ARIRFRCV, // AriLux RF Receive input
|
||||
GPIO_ARIRFSEL, // Arilux RF Receive input selected
|
||||
#endif
|
||||
#ifdef USE_MY92X1
|
||||
GPIO_DI, // my92x1 PWM input
|
||||
GPIO_DCKI, // my92x1 CLK input
|
||||
#endif // USE_MY92X1
|
||||
#ifdef USE_SM16716
|
||||
GPIO_SM16716_CLK, // SM16716 CLOCK
|
||||
GPIO_SM16716_DAT, // SM16716 DATA
|
||||
|
|
|
@ -1185,91 +1185,6 @@ void AriluxRfDisable(void)
|
|||
}
|
||||
#endif // USE_ARILUX_RF
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Sonoff B1 and AiLight inspired by OpenLight https://github.com/icamgo/noduino-sdk
|
||||
\*********************************************************************************************/
|
||||
|
||||
extern "C" {
|
||||
void os_delay_us(unsigned int);
|
||||
}
|
||||
|
||||
uint8_t light_pdi_pin;
|
||||
uint8_t light_pdcki_pin;
|
||||
|
||||
void LightDiPulse(uint8_t times)
|
||||
{
|
||||
for (uint32_t i = 0; i < times; i++) {
|
||||
digitalWrite(light_pdi_pin, HIGH);
|
||||
digitalWrite(light_pdi_pin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void LightDckiPulse(uint8_t times)
|
||||
{
|
||||
for (uint32_t i = 0; i < times; i++) {
|
||||
digitalWrite(light_pdcki_pin, HIGH);
|
||||
digitalWrite(light_pdcki_pin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void LightMy92x1Write(uint8_t data)
|
||||
{
|
||||
for (uint32_t i = 0; i < 4; i++) { // Send 8bit Data
|
||||
digitalWrite(light_pdcki_pin, LOW);
|
||||
digitalWrite(light_pdi_pin, (data & 0x80));
|
||||
digitalWrite(light_pdcki_pin, HIGH);
|
||||
data = data << 1;
|
||||
digitalWrite(light_pdi_pin, (data & 0x80));
|
||||
digitalWrite(light_pdcki_pin, LOW);
|
||||
digitalWrite(light_pdi_pin, LOW);
|
||||
data = data << 1;
|
||||
}
|
||||
}
|
||||
|
||||
void LightMy92x1Init(void)
|
||||
{
|
||||
uint8_t chips = 1; // 1 (AiLight)
|
||||
if (LT_RGBWC == light_type) {
|
||||
chips = 2; // 2 (Sonoff B1)
|
||||
}
|
||||
|
||||
LightDckiPulse(chips * 32); // Clear all duty register
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
// Send 12 DI pulse, after 6 pulse's falling edge store duty data, and 12
|
||||
// pulse's rising edge convert to command mode.
|
||||
LightDiPulse(12);
|
||||
os_delay_us(12); // Delay >12us, begin send CMD data
|
||||
for (uint32_t n = 0; n < chips; n++) { // Send CMD data
|
||||
LightMy92x1Write(0x18); // ONE_SHOT_DISABLE, REACTION_FAST, BIT_WIDTH_8, FREQUENCY_DIVIDE_1, SCATTER_APDM
|
||||
}
|
||||
os_delay_us(12); // TStart > 12us. Delay 12 us.
|
||||
// Send 16 DI pulse, at 14 pulse's falling edge store CMD data, and
|
||||
// at 16 pulse's falling edge convert to duty mode.
|
||||
LightDiPulse(16);
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
}
|
||||
|
||||
void LightMy92x1Duty(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b, uint8_t duty_w, uint8_t duty_c)
|
||||
{
|
||||
uint8_t channels[2] = { 4, 6 };
|
||||
|
||||
uint8_t didx = 0; // 0 (AiLight)
|
||||
if (LT_RGBWC == light_type) {
|
||||
didx = 1; // 1 (Sonoff B1)
|
||||
}
|
||||
|
||||
uint8_t duty[2][6] = {{ duty_r, duty_g, duty_b, duty_w, 0, 0 }, // Definition for RGBW channels
|
||||
{ duty_w, duty_c, 0, duty_g, duty_r, duty_b }}; // Definition for RGBWC channels
|
||||
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
for (uint32_t channel = 0; channel < channels[didx]; channel++) {
|
||||
LightMy92x1Write(duty[didx][channel]); // Send 8bit Data
|
||||
}
|
||||
os_delay_us(12); // TStart > 12us. Ready for send DI pulse.
|
||||
LightDiPulse(8); // Send 8 DI pulse. After 8 pulse falling edge, store old data.
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
void LightPwmOffset(uint32_t offset)
|
||||
|
@ -1309,12 +1224,6 @@ bool LightModuleInit(void)
|
|||
}
|
||||
light_type = LT_PWM2;
|
||||
}
|
||||
else if (AILIGHT == my_module_type) { // RGBW led
|
||||
light_type = LT_RGBW;
|
||||
}
|
||||
else if (SONOFF_B1 == my_module_type) { // RGBWC led
|
||||
light_type = LT_RGBWC;
|
||||
}
|
||||
#ifdef USE_WS2812
|
||||
if (!light_type && (pin[GPIO_WS2812] < 99)) { // RGB led
|
||||
light_type = LT_WS2812;
|
||||
|
@ -1380,6 +1289,7 @@ void LightInit(void)
|
|||
max_scheme = LS_MAX + WS2812_SCHEMES;
|
||||
}
|
||||
#endif // USE_WS2812 ************************************************************************
|
||||
/*
|
||||
else {
|
||||
light_pdi_pin = pin[GPIO_DI];
|
||||
light_pdcki_pin = pin[GPIO_DCKI];
|
||||
|
@ -1391,7 +1301,7 @@ void LightInit(void)
|
|||
|
||||
LightMy92x1Init();
|
||||
}
|
||||
|
||||
*/
|
||||
if (Light.subtype < LST_RGB) {
|
||||
max_scheme = LS_POWER;
|
||||
}
|
||||
|
@ -1954,10 +1864,6 @@ void LightAnimate(void)
|
|||
Ws2812SetColor(0, cur_col[0], cur_col[1], cur_col[2], cur_col[3]);
|
||||
}
|
||||
#endif // USE_ES2812 ************************************************************************
|
||||
else if (light_type > LT_WS2812) {
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION "Cur_Col %d,%d,%d,%d,%d"), cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]);
|
||||
LightMy92x1Duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]);
|
||||
}
|
||||
XdrvMailbox.data = tmp_data;
|
||||
XdrvMailbox.data_len = tmp_data_len;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
xlgt_02_my92x1.ino - led support for Sonoff-Tasmota
|
||||
|
||||
Copyright (C) 2019 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_LIGHT
|
||||
#ifdef USE_MY92X1
|
||||
/*********************************************************************************************\
|
||||
* Sonoff B1 and AiLight inspired by OpenLight https://github.com/icamgo/noduino-sdk
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XLGT_02 2
|
||||
|
||||
struct MY92X1 {
|
||||
uint8_t pdi_pin;
|
||||
uint8_t pdcki_pin;
|
||||
} My92x1;
|
||||
|
||||
extern "C" {
|
||||
void os_delay_us(unsigned int);
|
||||
}
|
||||
|
||||
void LightDiPulse(uint8_t times)
|
||||
{
|
||||
for (uint32_t i = 0; i < times; i++) {
|
||||
digitalWrite(My92x1.pdi_pin, HIGH);
|
||||
digitalWrite(My92x1.pdi_pin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void LightDckiPulse(uint8_t times)
|
||||
{
|
||||
for (uint32_t i = 0; i < times; i++) {
|
||||
digitalWrite(My92x1.pdcki_pin, HIGH);
|
||||
digitalWrite(My92x1.pdcki_pin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void LightMy92x1Write(uint8_t data)
|
||||
{
|
||||
for (uint32_t i = 0; i < 4; i++) { // Send 8bit Data
|
||||
digitalWrite(My92x1.pdcki_pin, LOW);
|
||||
digitalWrite(My92x1.pdi_pin, (data & 0x80));
|
||||
digitalWrite(My92x1.pdcki_pin, HIGH);
|
||||
data = data << 1;
|
||||
digitalWrite(My92x1.pdi_pin, (data & 0x80));
|
||||
digitalWrite(My92x1.pdcki_pin, LOW);
|
||||
digitalWrite(My92x1.pdi_pin, LOW);
|
||||
data = data << 1;
|
||||
}
|
||||
}
|
||||
|
||||
void LightMy92x1Init(void)
|
||||
{
|
||||
uint8_t chips = 1; // 1 (AiLight)
|
||||
if (LT_RGBWC == light_type) {
|
||||
chips = 2; // 2 (Sonoff B1)
|
||||
}
|
||||
|
||||
LightDckiPulse(chips * 32); // Clear all duty register
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
// Send 12 DI pulse, after 6 pulse's falling edge store duty data, and 12
|
||||
// pulse's rising edge convert to command mode.
|
||||
LightDiPulse(12);
|
||||
os_delay_us(12); // Delay >12us, begin send CMD data
|
||||
for (uint32_t n = 0; n < chips; n++) { // Send CMD data
|
||||
LightMy92x1Write(0x18); // ONE_SHOT_DISABLE, REACTION_FAST, BIT_WIDTH_8, FREQUENCY_DIVIDE_1, SCATTER_APDM
|
||||
}
|
||||
os_delay_us(12); // TStart > 12us. Delay 12 us.
|
||||
// Send 16 DI pulse, at 14 pulse's falling edge store CMD data, and
|
||||
// at 16 pulse's falling edge convert to duty mode.
|
||||
LightDiPulse(16);
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
}
|
||||
|
||||
void LightMy92x1Duty(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b, uint8_t duty_w, uint8_t duty_c)
|
||||
{
|
||||
uint8_t channels[2] = { 4, 6 };
|
||||
|
||||
uint8_t didx = 0; // 0 (AiLight)
|
||||
if (LT_RGBWC == light_type) {
|
||||
didx = 1; // 1 (Sonoff B1)
|
||||
}
|
||||
|
||||
uint8_t duty[2][6] = {{ duty_r, duty_g, duty_b, duty_w, duty_w, duty_w }, // Definition for RGBW(WW) channels
|
||||
{ duty_w, duty_c, 0, duty_g, duty_r, duty_b }}; // Definition for RGBWC channels
|
||||
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
for (uint32_t channel = 0; channel < channels[didx]; channel++) {
|
||||
LightMy92x1Write(duty[didx][channel]); // Send 8bit Data
|
||||
}
|
||||
os_delay_us(12); // TStart > 12us. Ready for send DI pulse.
|
||||
LightDiPulse(8); // Send 8 DI pulse. After 8 pulse falling edge, store old data.
|
||||
os_delay_us(12); // TStop > 12us.
|
||||
}
|
||||
|
||||
/********************************************************************************************/
|
||||
|
||||
bool My92x1SetChannels(void)
|
||||
{
|
||||
uint8_t *cur_col = (uint8_t*)XdrvMailbox.data;
|
||||
|
||||
LightMy92x1Duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void My92x1ModuleSelected(void)
|
||||
{
|
||||
if ((pin[GPIO_DCKI] < 99) && (pin[GPIO_DI] < 99)) {
|
||||
My92x1.pdi_pin = pin[GPIO_DI];
|
||||
My92x1.pdcki_pin = pin[GPIO_DCKI];
|
||||
|
||||
pinMode(My92x1.pdi_pin, OUTPUT);
|
||||
pinMode(My92x1.pdcki_pin, OUTPUT);
|
||||
digitalWrite(My92x1.pdi_pin, LOW);
|
||||
digitalWrite(My92x1.pdcki_pin, LOW);
|
||||
|
||||
LightMy92x1Init();
|
||||
|
||||
if (AILIGHT == my_module_type) { // RGBW(WW) led
|
||||
light_type = LT_RGBW;
|
||||
}
|
||||
else if (SONOFF_B1 == my_module_type) { // RGBWC led
|
||||
light_type = LT_RGBWC;
|
||||
}
|
||||
light_flg = XLGT_02;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DBG: MY29x1 Found"));
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
* Interface
|
||||
\*********************************************************************************************/
|
||||
|
||||
bool Xlgt02(uint8_t function)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
switch (function) {
|
||||
case FUNC_SET_CHANNELS:
|
||||
result = My92x1SetChannels();
|
||||
break;
|
||||
case FUNC_MODULE_INIT:
|
||||
My92x1ModuleSelected();
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // USE_MY92X1
|
||||
#endif // USE_LIGHT
|
Loading…
Reference in New Issue