From 428692fa3a6746be66a913745824826e611c7ec5 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Sun, 27 Nov 2022 23:15:53 +0000 Subject: [PATCH] Basic i2c --- .../LEDStripController/LEDStripController.cpp | 94 ++++++++++++++++++- .../LEDStripController/LEDStripController.h | 8 +- .../LEDStripControllerDetect.cpp | 4 + .../OpenRGBSerialSettingsEntry.cpp | 14 +++ .../OpenRGBSerialSettingsEntry.h | 2 + .../OpenRGBSerialSettingsPage.cpp | 7 ++ 6 files changed, 124 insertions(+), 5 deletions(-) diff --git a/Controllers/LEDStripController/LEDStripController.cpp b/Controllers/LEDStripController/LEDStripController.cpp index 4b925e62..2a220572 100644 --- a/Controllers/LEDStripController/LEDStripController.cpp +++ b/Controllers/LEDStripController/LEDStripController.cpp @@ -5,6 +5,7 @@ \*---------------------------------------------------------*/ #include "LEDStripController.h" +#include "ResourceManager.h" #include #include @@ -26,13 +27,16 @@ void LEDStripController::Initialize(char* ledstring, led_protocol proto) LPSTR source = NULL; LPSTR udpport_baud = NULL; LPSTR next = NULL; - + //Set the protocol protocol = proto; //Assume serial device unless a different protocol is specified bool serial = TRUE; - + + //Default i2c address out of range + i2c_addr = 255; + source = strtok_s(ledstring, ",", &next); //Check if we are setting up a Keyboard Visualizer UDP protocol device @@ -41,7 +45,7 @@ void LEDStripController::Initialize(char* ledstring, led_protocol proto) source = source + 4; serial = FALSE; } - + //Check for either the UDP port or the serial baud rate if (strlen(next)) { @@ -56,7 +60,13 @@ void LEDStripController::Initialize(char* ledstring, led_protocol proto) if (serial) { - if (udpport_baud == NULL) + if (protocol == LED_PROTOCOL_BASIC_I2C) + { + //I2C uses the baud field for address + i2c_addr = atoi(udpport_baud); + InitializeI2C(source); + } + else if (udpport_baud == NULL) { //Initialize with default baud rate InitializeSerial(source, 115200); @@ -86,6 +96,24 @@ void LEDStripController::Initialize(char* ledstring, led_protocol proto) } } +void LEDStripController::InitializeI2C(char* i2cname) +{ + for(unsigned int i2c_idx = 0; i2c_idx < ResourceManager::get()->GetI2CBusses().size(); i2c_idx++) + { + if(ResourceManager::get()->GetI2CBusses()[i2c_idx]->device_name == std::string(i2cname)) + { + if(i2c_addr < 128) + { + i2cport = ResourceManager::get()->GetI2CBusses()[i2c_idx]; + break; + } + } + } + + serialport = NULL; + udpport = NULL; +} + void LEDStripController::InitializeSerial(char* portname, int baud) { portname = strtok(portname, "\r"); @@ -93,6 +121,7 @@ void LEDStripController::InitializeSerial(char* portname, int baud) baud_rate = baud; serialport = new serial_port(port_name.c_str(), baud_rate); udpport = NULL; + i2cport = NULL; } void LEDStripController::InitializeUDP(char * clientname, char * port) @@ -102,6 +131,7 @@ void LEDStripController::InitializeUDP(char * clientname, char * port) udpport = new net_port(client_name.c_str(), port_name.c_str()); serialport = NULL; + i2cport = NULL; } std::string LEDStripController::GetLocation() @@ -114,6 +144,10 @@ std::string LEDStripController::GetLocation() { return("UDP: " + client_name + ":" + port_name); } + else if(i2cport != NULL) + { + return("I2C: " + std::string(i2cport->device_name) + ", Address " + std::to_string(i2c_addr)); + } else { return(""); @@ -140,6 +174,10 @@ void LEDStripController::SetLEDs(std::vector colors) case LED_PROTOCOL_TPM2: SetLEDsTPM2(colors); break; + + case LED_PROTOCOL_BASIC_I2C: + SetLEDsBasicI2C(colors); + break; } } @@ -318,3 +356,51 @@ void LEDStripController::SetLEDsTPM2(std::vector colors) delete[] serial_buf; } + +void LEDStripController::SetLEDsBasicI2C(std::vector colors) +{ + unsigned char serial_buf[30]; + + /*-------------------------------------------------------------*\ + | Basic I2C Protocol | + | | + | Packet size: At most 32 bytes (SMBus block size) | + | | + | Packet is in RGBRGBRGB... format, also provide start index | + \*-------------------------------------------------------------*/ + + unsigned char index = 0; + unsigned char offset = 0; + + for(unsigned int color_idx = 0; color_idx < colors.size(); color_idx++) + { + serial_buf[index + 0] = RGBGetRValue(colors[color_idx]); + serial_buf[index + 1] = RGBGetGValue(colors[color_idx]); + serial_buf[index + 2] = RGBGetBValue(colors[color_idx]); + + index += 3; + + if(index >= 30) + { + if(i2cport != NULL) + { + i2cport->i2c_smbus_write_i2c_block_data(i2c_addr, offset, 30, serial_buf); + offset += 30; + index = 0; + } + } + } + + if(index > 0) + { + if(i2cport != NULL) + { + i2cport->i2c_smbus_write_i2c_block_data(i2c_addr, offset, index, serial_buf); + } + } + + if(i2cport != NULL) + { + i2cport->i2c_smbus_write_byte(i2c_addr, 0xFF); + } +} diff --git a/Controllers/LEDStripController/LEDStripController.h b/Controllers/LEDStripController/LEDStripController.h index cf0a3f41..aae68e0e 100644 --- a/Controllers/LEDStripController/LEDStripController.h +++ b/Controllers/LEDStripController/LEDStripController.h @@ -8,6 +8,7 @@ #define LED_STRIP_H #include "RGBController.h" +#include "i2c_smbus.h" #include "serial_port.h" #include "net_port.h" #include @@ -29,7 +30,8 @@ enum { LED_PROTOCOL_KEYBOARD_VISUALIZER, LED_PROTOCOL_ADALIGHT, - LED_PROTOCOL_TPM2 + LED_PROTOCOL_TPM2, + LED_PROTOCOL_BASIC_I2C }; struct LEDStripDevice @@ -49,6 +51,7 @@ public: void Initialize(char* ledstring, led_protocol proto); + void InitializeI2C(char* i2cname); void InitializeSerial(char* portname, int baud); void InitializeUDP(char* clientname, char* port); @@ -60,6 +63,7 @@ public: void SetLEDsKeyboardVisualizer(std::vector colors); void SetLEDsAdalight(std::vector colors); void SetLEDsTPM2(std::vector colors); + void SetLEDsBasicI2C(std::vector colors); int num_leds; @@ -71,6 +75,8 @@ private: std::string client_name; serial_port *serialport; net_port *udpport; + i2c_smbus_interface *i2cport; + unsigned char i2c_addr; led_protocol protocol; }; diff --git a/Controllers/LEDStripController/LEDStripControllerDetect.cpp b/Controllers/LEDStripController/LEDStripControllerDetect.cpp index bc2240ff..7c8ed43d 100644 --- a/Controllers/LEDStripController/LEDStripControllerDetect.cpp +++ b/Controllers/LEDStripController/LEDStripControllerDetect.cpp @@ -74,6 +74,10 @@ void DetectLEDStripControllers(std::vector &rgb_controllers) { dev.protocol = LED_PROTOCOL_TPM2; } + else if(protocol_string == "basic_i2c") + { + dev.protocol = LED_PROTOCOL_BASIC_I2C; + } } std::string value = dev.port + "," + std::to_string(dev.baud) + "," + std::to_string(dev.num_leds); diff --git a/qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.cpp b/qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.cpp index dac20b0d..cbd36e10 100644 --- a/qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.cpp +++ b/qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.cpp @@ -12,6 +12,7 @@ OpenRGBSerialSettingsEntry::OpenRGBSerialSettingsEntry(QWidget *parent) : ui->ProtocolComboBox->addItem("Keyboard Visualizer"); ui->ProtocolComboBox->addItem("Adalight"); ui->ProtocolComboBox->addItem("TPM2"); + ui->ProtocolComboBox->addItem("Basic I2C"); } OpenRGBSerialSettingsEntry::~OpenRGBSerialSettingsEntry() @@ -26,3 +27,16 @@ void OpenRGBSerialSettingsEntry::changeEvent(QEvent *event) ui->retranslateUi(this); } } + +void Ui::OpenRGBSerialSettingsEntry::on_ProtocolComboBox_currentIndexChanged(int index) +{ + if(index == 3) + { + ui->BaudLabel->setText("Address:"); + } + else + { + ui->BaudLabel->setText("Baud:"); + } +} + diff --git a/qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.h b/qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.h index c9733fec..69e8c629 100644 --- a/qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.h +++ b/qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsEntry.h @@ -15,6 +15,8 @@ class Ui::OpenRGBSerialSettingsEntry : public QWidget private slots: void changeEvent(QEvent *event); + void on_ProtocolComboBox_currentIndexChanged(int index); + public: explicit OpenRGBSerialSettingsEntry(QWidget *parent = nullptr); ~OpenRGBSerialSettingsEntry(); diff --git a/qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsPage.cpp b/qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsPage.cpp index 6ca9c05c..f4ef229a 100644 --- a/qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsPage.cpp +++ b/qt/OpenRGBSerialSettingsPage/OpenRGBSerialSettingsPage.cpp @@ -62,6 +62,10 @@ OpenRGBSerialSettingsPage::OpenRGBSerialSettingsPage(QWidget *parent) : { entry->ui->ProtocolComboBox->setCurrentIndex(2); } + else if(protocol_string == "basic_i2c") + { + entry->ui->ProtocolComboBox->setCurrentIndex(3); + } } entries.push_back(entry); @@ -154,6 +158,9 @@ void Ui::OpenRGBSerialSettingsPage::on_SaveSerialConfigurationButton_clicked() case 2: ledstrip_settings["devices"][device_idx]["protocol"] = "tpm2"; break; + case 3: + ledstrip_settings["devices"][device_idx]["protocol"] = "basic_i2c"; + break; } }