/*-----------------------------------------*\ | ZalmanZSyncController.cpp | | | | Driver for SRGBmods Raspberry Pi Pico | | LED Controller | | | | Adam Honse (CalcProgrammer1) 7/21/2022 | \*-----------------------------------------*/ #include "SRGBmodsPicoController.h" #include using namespace std::chrono_literals; SRGBmodsPicoController::SRGBmodsPicoController(hid_device* dev_handle, const char* path) { dev = dev_handle; location = path; /*-----------------------------------------------------*\ | The SRGBmods Pico controller requires a packet within | | 10 seconds of sending the lighting change in order | | to not revert back into hardware mode. Start a thread| | to continuously send a keepalive packet every 5s | \*-----------------------------------------------------*/ keepalive_thread_run = 1; keepalive_thread = new std::thread(&SRGBmodsPicoController::KeepaliveThread, this); } SRGBmodsPicoController::~SRGBmodsPicoController() { keepalive_thread_run = 0; keepalive_thread->join(); delete keepalive_thread; hid_close(dev); } void SRGBmodsPicoController::KeepaliveThread() { while(keepalive_thread_run.load()) { if((std::chrono::steady_clock::now() - last_commit_time) > std::chrono::seconds(1)) { SendPacket(1, 0, 0, false, NULL, 0); } std::this_thread::sleep_for(5s); } } std::string SRGBmodsPicoController::GetLocationString() { return("HID: " + location); } std::string SRGBmodsPicoController::GetSerialString() { wchar_t serial_string[128]; int ret = hid_get_serial_number_string(dev, serial_string, 128); if(ret != 0) { return(""); } std::wstring return_wstring = serial_string; std::string return_string(return_wstring.begin(), return_wstring.end()); return(return_string); } void SRGBmodsPicoController::SetChannelLEDs(unsigned char channel, RGBColor* colors, unsigned int num_colors) { unsigned int num_packets = (num_colors / 20) + ((num_colors % 20) > 0); unsigned int color_idx = 0; for(unsigned int packet_idx = 0; packet_idx < num_packets; packet_idx++) { unsigned int colors_in_packet = 20; if(num_colors - color_idx < colors_in_packet) { colors_in_packet = num_colors - color_idx; } SendPacket(channel, packet_idx + 1, num_packets, false, &colors[color_idx], colors_in_packet); color_idx += colors_in_packet; } } void SRGBmodsPicoController::SendPacket ( unsigned char channel, unsigned char this_packet_id, unsigned char last_packet_id, bool reset, RGBColor* colors, unsigned int num_colors ) { unsigned char usb_buf[65]; /*-----------------------------------------------------*\ | Zero out buffer | \*-----------------------------------------------------*/ memset(usb_buf, 0x00, sizeof(usb_buf)); /*-----------------------------------------------------*\ | Update last commit time | \*-----------------------------------------------------*/ last_commit_time = std::chrono::steady_clock::now(); /*-----------------------------------------------------*\ | Set up Firmware Version Request packet | \*-----------------------------------------------------*/ usb_buf[0x00] = 0x00; /* hidapi Report ID*/ usb_buf[0x01] = this_packet_id; /* This Packet ID */ usb_buf[0x02] = reset; /* Reset Flag */ usb_buf[0x03] = last_packet_id; /* Last Packet ID */ usb_buf[0x04] = channel + 1; /* Channel (1 or 2)*/ for(unsigned int color_idx = 0; color_idx < num_colors; color_idx++) { usb_buf[0x05 + (color_idx * 3)] = RGBGetRValue(colors[color_idx]); usb_buf[0x06 + (color_idx * 3)] = RGBGetGValue(colors[color_idx]); usb_buf[0x07 + (color_idx * 3)] = RGBGetBValue(colors[color_idx]); } /*-----------------------------------------------------*\ | Send packet | \*-----------------------------------------------------*/ hid_write(dev, usb_buf, 65); }