diff --git a/Controllers/BlinkyTapeController/BlinkyTapeController.cpp b/Controllers/BlinkyTapeController/BlinkyTapeController.cpp new file mode 100644 index 00000000..d6e8183f --- /dev/null +++ b/Controllers/BlinkyTapeController/BlinkyTapeController.cpp @@ -0,0 +1,105 @@ +/*---------------------------------------------------------*\ +| BlinkyTapeController.cpp | +| | +| BlinkyTape controller interface | +| | +| Matt Mets (matt@blinkinlabs.com), 07/01/2021 | +\*---------------------------------------------------------*/ + +#include "BlinkyTapeController.h" + +#include +#include +#include +#include + +#ifndef WIN32 +#define LPSTR char * +#define strtok_s strtok_r +#endif + +BlinkyTapeController::BlinkyTapeController() +{ +} + +BlinkyTapeController::~BlinkyTapeController() +{ + if(serialport != nullptr) + { + serialport->serial_close(); + delete serialport; + } +} + +void BlinkyTapeController::Initialize(const std::string &portname, int led_count) +{ + num_leds = led_count; + port_name = portname; + + serialport = new serial_port(); + + if(!serialport->serial_open(port_name.c_str(), 115200)) + { + delete serialport; + serialport = nullptr; + } +} + +std::string BlinkyTapeController::GetLocation() +{ + if(serialport == nullptr) + { + return(""); + } + + return("COM: " + port_name); +} + +char* BlinkyTapeController::GetLEDString() +{ + return(led_string); +} + +void BlinkyTapeController::SetLEDs(std::vector colors) +{ + if(serialport == nullptr) + { + return; + } + + /*-------------------------------------------------------------*\ + | BlinkyTape Protocol | + | | + | Packet size: Number of data bytes + 1 | + | | + | 0-n: Data Byte (0-254) | + | n+1: Packet End Byte (0xFF) | + \*-------------------------------------------------------------*/ + const unsigned int payload_size = (colors.size() * 3); + const unsigned int packet_size = payload_size + 1; + + std::vector serial_buf(packet_size); + + /*-------------------------------------------------------------*\ + | Set up end byte | + \*-------------------------------------------------------------*/ + serial_buf[packet_size - 1] = 0xFF; + + /*-------------------------------------------------------------*\ + | Copy in color data in RGB order | + \*-------------------------------------------------------------*/ + for(unsigned int color_idx = 0; color_idx < colors.size(); color_idx++) + { + const unsigned int color_offset = color_idx * 3; + + serial_buf[0x00 + color_offset] = std::min((unsigned int)254, RGBGetRValue(colors[color_idx])); + serial_buf[0x01 + color_offset] = std::min((unsigned int)254, RGBGetGValue(colors[color_idx])); + serial_buf[0x02 + color_offset] = std::min((unsigned int)254, RGBGetBValue(colors[color_idx])); + } + + /*-------------------------------------------------------------*\ + | Send the packet | + \*-------------------------------------------------------------*/ + serialport->serial_write((char *)serial_buf.data(), packet_size); +} + diff --git a/Controllers/BlinkyTapeController/BlinkyTapeController.h b/Controllers/BlinkyTapeController/BlinkyTapeController.h new file mode 100644 index 00000000..ff02789a --- /dev/null +++ b/Controllers/BlinkyTapeController/BlinkyTapeController.h @@ -0,0 +1,40 @@ +/*---------------------------------------------------------*\ +| Definitions for BlinkyTape Interface | +| | +| Matt Mets (matt@blinkinlabs.com), 07/01/2021 | +\*---------------------------------------------------------*/ + +#ifndef BLINKYTAPE_H +#define BLINKYTAPE_H + +#include "RGBController.h" +#include "serial_port.h" + +struct BlinkyTapeDevice +{ + std::string port; + unsigned int num_leds; +}; + +class BlinkyTapeController +{ +public: + BlinkyTapeController(); + ~BlinkyTapeController(); + + void Initialize(const std::string &portname, int led_count); + + char* GetLEDString(); + std::string GetLocation(); + + void SetLEDs(std::vector colors); + + int num_leds; + +private: + char led_string[1024]; + std::string port_name; + serial_port *serialport = nullptr; +}; + +#endif diff --git a/Controllers/BlinkyTapeController/BlinkyTapeControllerDetect.cpp b/Controllers/BlinkyTapeController/BlinkyTapeControllerDetect.cpp new file mode 100644 index 00000000..e00223c4 --- /dev/null +++ b/Controllers/BlinkyTapeController/BlinkyTapeControllerDetect.cpp @@ -0,0 +1,38 @@ +#include "Detector.h" +#include "BlinkyTapeController.h" +#include "RGBController.h" +#include "RGBController_BlinkyTape.h" +#include "SettingsManager.h" +#include "find_usb_serial_port.h" +#include +#include +#include + +#define BLINKINLABS_VID 0x1D50 +#define BLINKYTAPE_PID 0x605E + +/******************************************************************************************\ +* * +* DetectBlinkyTapeControllers * +* * +* Detect BlinkyTape devices * +* * +\******************************************************************************************/ + +void DetectBlinkyTapeControllers(std::vector &rgb_controllers) +{ + std::vector device_locations = find_usb_serial_port(BLINKINLABS_VID, BLINKYTAPE_PID); + + for(unsigned int device_idx = 0; device_idx < device_locations.size(); device_idx++) + { + int led_count = 64; + + BlinkyTapeController* controller = new BlinkyTapeController(); + controller->Initialize(*device_locations[device_idx], led_count); + + RGBController_BlinkyTape* rgb_controller = new RGBController_BlinkyTape(controller); + rgb_controllers.push_back(rgb_controller); + } +} + +REGISTER_DETECTOR("BlinkyTape", DetectBlinkyTapeControllers); diff --git a/Controllers/BlinkyTapeController/RGBController_BlinkyTape.cpp b/Controllers/BlinkyTapeController/RGBController_BlinkyTape.cpp new file mode 100644 index 00000000..f76c246f --- /dev/null +++ b/Controllers/BlinkyTapeController/RGBController_BlinkyTape.cpp @@ -0,0 +1,137 @@ +/*---------------------------------------------------------*\ +| RGBController_BlinkyTape.cpp | +| | +| Generic RGB Interface for BlinkyTape Led controller | +| | +| Matt Mets (matt@blinkinlabs.com), 07/01/2021 | +\*---------------------------------------------------------*/ + +#include "RGBController_BlinkyTape.h" + +RGBController_BlinkyTape::RGBController_BlinkyTape(BlinkyTapeController* controller_ptr) +{ + controller = controller_ptr; + + name = "BlinkyTape"; + vendor = "Blinkinlabs"; + type = DEVICE_TYPE_LEDSTRIP; + description = "BlinkyTape Controller Device"; + location = controller->GetLocation(); + + mode Direct; + Direct.name = "Direct"; + Direct.value = 0; + Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; + Direct.color_mode = MODE_COLORS_PER_LED; + modes.push_back(Direct); + + SetupZones(); +} + +RGBController_BlinkyTape::~RGBController_BlinkyTape() +{ + delete controller; +} + +void RGBController_BlinkyTape::SetupZones() +{ + zones.clear(); + leds.clear(); + + zone led_zone; + led_zone.name = "LED Strip"; + led_zone.type = ZONE_TYPE_LINEAR; + led_zone.leds_min = 1; + led_zone.leds_max = 512; + led_zone.leds_count = 0; + led_zone.matrix_map = NULL; + zones.push_back(led_zone); + + ResizeZone(0, controller->num_leds); +} + +void RGBController_BlinkyTape::ResizeZone(int zone, int new_size) +{ + /*-------------------------------------------------*\ + | Explicitly cast these to avoid compiler warnings | + \*-------------------------------------------------*/ + const unsigned int zone_u = static_cast(zone); + const unsigned int new_size_u = static_cast(new_size); + + /*-------------------------------------------------*\ + | Check that the zone is in bounds | + \*-------------------------------------------------*/ + if((zone_u > zones.size()) || (zone < 0)) + { + return; + } + + /*-------------------------------------------------*\ + | And that the new size is in bounds | + \*-------------------------------------------------*/ + if((new_size_u > zones.at(zone).leds_max) || (new_size_u < zones.at(zone).leds_min)) + { + return; + } + + /*-------------------------------------------------*\ + | And that there's actually a change | + \*-------------------------------------------------*/ + if(zones.at(zone).leds_count == new_size_u) + { + return; + } + + /*-------------------------------------------------*\ + | If the new size is less than the current size, | + | just chop off the end | + \*-------------------------------------------------*/ + if(leds.size() > new_size_u) + { + leds.resize(new_size); + } + + /*-------------------------------------------------*\ + | Otherwise, add new LEDs to the end | + \*-------------------------------------------------*/ + if(leds.size() < new_size_u) + { + for(size_t led_idx = leds.size(); led_idx < new_size_u; led_idx++) + { + led new_led; + new_led.name = "LED "; + new_led.name.append(std::to_string(led_idx)); + + leds.push_back(new_led); + } + } + + zones.at(zone).leds_count = new_size; + + SetupColors(); +} + +void RGBController_BlinkyTape::DeviceUpdateLEDs() +{ + controller->SetLEDs(colors); +} + +void RGBController_BlinkyTape::UpdateZoneLEDs(int /*zone*/) +{ + controller->SetLEDs(colors); +} + +void RGBController_BlinkyTape::UpdateSingleLED(int /*led*/) +{ + controller->SetLEDs(colors); +} + +void RGBController_BlinkyTape::SetCustomMode() +{ + +} + +void RGBController_BlinkyTape::DeviceUpdateMode() +{ + +} diff --git a/Controllers/BlinkyTapeController/RGBController_BlinkyTape.h b/Controllers/BlinkyTapeController/RGBController_BlinkyTape.h new file mode 100644 index 00000000..92b2329a --- /dev/null +++ b/Controllers/BlinkyTapeController/RGBController_BlinkyTape.h @@ -0,0 +1,33 @@ +/*---------------------------------------------------------*\ +| RGBController_BlinkyTape.h | +| | +| Generic RGB Interface for BlinkyTape Led controller | +| | +| Matt Mets (matt@blinkinlabs.com), 07/01/2021 | +\*---------------------------------------------------------*/ + +#pragma once +#include "RGBController.h" +#include "serial_port.h" +#include "BlinkyTapeController.h" + +class RGBController_BlinkyTape : public RGBController +{ +public: + RGBController_BlinkyTape(BlinkyTapeController* controller_ptr); + ~RGBController_BlinkyTape(); + + void SetupZones(); + + void ResizeZone(int zone, int new_size); + + void DeviceUpdateLEDs(); + void UpdateZoneLEDs(int zone); + void UpdateSingleLED(int led); + + void SetCustomMode(); + void DeviceUpdateMode(); + +private: + BlinkyTapeController* controller; +}; diff --git a/OpenRGB.pro b/OpenRGB.pro index 587469d8..7c5f41c6 100644 --- a/OpenRGB.pro +++ b/OpenRGB.pro @@ -206,6 +206,8 @@ HEADERS += Controllers/AsusAuraUSBController/RGBController_AsusAuraMouse.h \ Controllers/AsusAuraUSBController/RGBController_AsusAuraTUFKeyboard.h \ Controllers/AsusAuraUSBController/RGBController_AsusAuraUSB.h \ + Controllers/BlinkyTapeController/BlinkyTapeController.h \ + Controllers/BlinkyTapeController/RGBController_BlinkyTape.h \ Controllers/CoolerMasterController/CMARGBcontroller.h \ Controllers/CoolerMasterController/CMMP750Controller.h \ Controllers/CoolerMasterController/CMSmallARGBController.h \ @@ -513,6 +515,9 @@ SOURCES += Controllers/AsusAuraUSBController/RGBController_AsusAuraMouse.cpp \ Controllers/AsusAuraUSBController/RGBController_AsusAuraTUFKeyboard.cpp \ Controllers/AsusAuraUSBController/RGBController_AsusAuraUSB.cpp \ + Controllers/BlinkyTapeController/BlinkyTapeController.cpp \ + Controllers/BlinkyTapeController/BlinkyTapeControllerDetect.cpp \ + Controllers/BlinkyTapeController/RGBController_BlinkyTape.cpp \ Controllers/CoolerMasterController/CMARGBcontroller.cpp \ Controllers/CoolerMasterController/CMMP750Controller.cpp \ Controllers/CoolerMasterController/CMSmallARGBController.cpp \ diff --git a/serial_port/serial_port.h b/serial_port/serial_port.h index 2342f380..2da9a49e 100644 --- a/serial_port/serial_port.h +++ b/serial_port/serial_port.h @@ -14,7 +14,10 @@ #include #ifdef _WIN32 - +/*---------------------------------------------------------*\ +| Windows interferes with std::max unless NOMINMAX defined | +\*---------------------------------------------------------*/ +#define NOMINMAX #include #endif /* _WIN32 */