From ecc837b5651b61f152c14ff6aa2a4d6b0786c862 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Sat, 12 Nov 2022 20:53:04 -0600 Subject: [PATCH] Get both direct and effect modes working together --- .../AMDWraithPrismController.cpp | 192 ++++++++++++++++- .../AMDWraithPrismController.h | 43 +++- .../RGBController_AMDWraithPrism.cpp | 193 ++++++++++++++++-- 3 files changed, 404 insertions(+), 24 deletions(-) diff --git a/Controllers/AMDWraithPrismController/AMDWraithPrismController.cpp b/Controllers/AMDWraithPrismController/AMDWraithPrismController.cpp index e72be409..03c620c4 100644 --- a/Controllers/AMDWraithPrismController/AMDWraithPrismController.cpp +++ b/Controllers/AMDWraithPrismController/AMDWraithPrismController.cpp @@ -16,6 +16,21 @@ AMDWraithPrismController::AMDWraithPrismController(hid_device* dev_handle, const { dev = dev_handle; location = path; + + current_fan_mode = AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC; + current_fan_speed = 0xFF; + current_fan_random_color = false; + current_fan_brightness = 0xFF; + + current_logo_mode = AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC; + current_logo_speed = 0xFF; + current_logo_random_color = false; + current_logo_brightness = 0xFF; + + current_ring_mode = AMD_WRAITH_PRISM_EFFECT_CHANNEL_STATIC; + current_ring_speed = 0xFF; + current_ring_direction = false; + current_ring_brightness = 0xFF; } AMDWraithPrismController::~AMDWraithPrismController() @@ -91,12 +106,94 @@ std::string AMDWraithPrismController::GetFirmwareVersionString() return(ret_string); } -void AMDWraithPrismController::SendEnableCommand() +void AMDWraithPrismController::SetFanMode(unsigned char mode, unsigned char speed, unsigned char brightness, bool random_color) +{ + current_fan_mode = mode; + current_fan_speed = speed_values_fan_logo[mode][speed]; + current_fan_brightness = brightness; + current_fan_random_color = random_color; +} + +void AMDWraithPrismController::SetFanColor(unsigned char red, unsigned char green, unsigned char blue) +{ + SendEffectChannelUpdate + ( + AMD_WRAITH_PRISM_EFFECT_CHANNEL_FAN_LED, + current_fan_speed, + false, + current_fan_random_color, + current_fan_mode, + current_fan_brightness, + red, + green, + blue + ); +} + +void AMDWraithPrismController::SetLogoMode(unsigned char mode, unsigned char speed, unsigned char brightness, bool random_color) +{ + current_logo_mode = mode; + current_logo_speed = speed_values_fan_logo[mode][speed]; + current_logo_brightness = brightness; + current_logo_random_color = random_color; +} + +void AMDWraithPrismController::SetLogoColor(unsigned char red, unsigned char green, unsigned char blue) +{ + SendEffectChannelUpdate + ( + AMD_WRAITH_PRISM_EFFECT_CHANNEL_LOGO_LED, + current_logo_speed, + false, + current_logo_random_color, + current_logo_mode, + current_logo_brightness, + red, + green, + blue + ); +} + +void AMDWraithPrismController::SetRingMode(unsigned char mode, unsigned char speed, unsigned char brightness, bool direction, bool random_color) +{ + current_ring_mode = mode; + current_ring_speed = speed_values_ring[mode][speed]; + current_ring_direction = direction; + current_ring_brightness = brightness; + current_ring_random_color = random_color; +} + +void AMDWraithPrismController::SetRingColor(unsigned char red, unsigned char green, unsigned char blue) +{ + SetRingEffectChannel(current_ring_mode); + + SendEffectChannelUpdate + ( + current_ring_mode, + current_ring_speed, + current_ring_direction, + current_ring_random_color, + mode_value_ring[current_ring_mode], + current_ring_brightness, + red, + green, + blue + ); + + SendApplyCommand(); +} + +void AMDWraithPrismController::SetRingEffectChannel(unsigned char channel) +{ + SendChannelRemap(channel, AMD_WRAITH_PRISM_EFFECT_CHANNEL_LOGO_LED, AMD_WRAITH_PRISM_EFFECT_CHANNEL_FAN_LED); +} + +void AMDWraithPrismController::SendEnableCommand(bool direct) { unsigned char usb_buf[] = { 0x00, - 0x41, 0x03, 0x00, 0x00, + 0x41, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -114,6 +211,11 @@ void AMDWraithPrismController::SendEnableCommand() 0x00, 0x00, 0x00, 0x00, }; + if(direct) + { + usb_buf[0x02] = 0x03; + } + hid_write(dev, usb_buf, 65); hid_read(dev, usb_buf, 64); } @@ -124,7 +226,7 @@ void AMDWraithPrismController::SendApplyCommand() { 0x00, 0x51, 0x28, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, + 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -186,3 +288,87 @@ void AMDWraithPrismController::SendDirectPacket hid_write(dev, usb_buf, 65); hid_read(dev, usb_buf, 64); } + +void AMDWraithPrismController::SendEffectChannelUpdate + ( + unsigned char effect_channel, + unsigned char speed, + bool direction, + bool random_color, + unsigned char mode, + unsigned char brightness, + unsigned char red, + unsigned char green, + unsigned char blue + ) +{ + unsigned char usb_buf[] = + { + 0x00, + 0x51, 0x2C, 0x01, 0x00, + 0x05, 0xFF, 0x00, 0x01, + 0xFF, 0xFF, 0x00, 0xFF, + 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF + }; + + usb_buf[0x05] = effect_channel; + usb_buf[0x06] = speed; + usb_buf[0x07] = (direction ? 0x01 : 0x00) | (random_color ? 0x80 : 0x00); + usb_buf[0x08] = mode; + + usb_buf[0x0A] = brightness; + + usb_buf[0x0B] = red; + usb_buf[0x0C] = green; + usb_buf[0x0D] = blue; + + hid_write(dev, usb_buf, 65); + hid_read(dev, usb_buf, 64); +} + +void AMDWraithPrismController::SendChannelRemap(unsigned char ring_channel, unsigned char logo_channel, unsigned char fan_channel) +{ + unsigned char usb_buf[] = + { + 0x00, + 0x51, 0xA0, 0x01, 0x00, + 0x00, 0x03, 0x00, 0x00, + 0x05, 0x06, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, + 0x07, 0x07, 0x07, 0x07, + 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + }; + + usb_buf[0x09] = logo_channel; + usb_buf[0x0A] = fan_channel; + + for(int led = 0x0B; led <= 0x19; led++) + { + usb_buf[led] = ring_channel; + } + + hid_write(dev, usb_buf, 65); + hid_read(dev, usb_buf, 64); +} diff --git a/Controllers/AMDWraithPrismController/AMDWraithPrismController.h b/Controllers/AMDWraithPrismController/AMDWraithPrismController.h index ce10b4cd..02008de3 100644 --- a/Controllers/AMDWraithPrismController/AMDWraithPrismController.h +++ b/Controllers/AMDWraithPrismController/AMDWraithPrismController.h @@ -76,6 +76,7 @@ enum AMD_WRAITH_PRISM_EFFECT_CHANNEL_CHASE = 0x09, /* Chase effect channel */ AMD_WRAITH_PRISM_EFFECT_CHANNEL_SWIRL = 0x0A, /* Swirl effect channel */ AMD_WRAITH_PRISM_EFFECT_CHANNEL_MORSE = 0x0B, /* Morse code effect channel */ + AMD_WRAITH_PRISM_EFFECT_CHANNEL_DIRECT = 0xFF, /* Value for direct mode */ }; enum @@ -98,6 +99,29 @@ public: std::string GetLocationString(); std::string GetSerialString(); + unsigned char current_fan_mode; + unsigned char current_fan_speed; + unsigned char current_fan_brightness; + bool current_fan_random_color; + + unsigned char current_logo_mode; + unsigned char current_logo_speed; + unsigned char current_logo_brightness; + bool current_logo_random_color; + + unsigned char current_ring_mode; + unsigned char current_ring_speed; + unsigned char current_ring_brightness; + bool current_ring_direction; + bool current_ring_random_color; + + void SetFanMode(unsigned char mode, unsigned char speed, unsigned char brightness, bool random_color); + void SetFanColor(unsigned char red, unsigned char green, unsigned char blue); + void SetLogoMode(unsigned char mode, unsigned char speed, unsigned char brightness, bool random_color); + void SetLogoColor(unsigned char red, unsigned char green, unsigned char blue); + void SetRingMode(unsigned char mode, unsigned char speed, unsigned char brightness, bool direction, bool random_color); + void SetRingColor(unsigned char red, unsigned char green, unsigned char blue); + void SendDirectPacket ( unsigned char size, @@ -105,11 +129,28 @@ public: RGBColor * colors ); - void SendEnableCommand(); + void SendEnableCommand(bool direct); void SendApplyCommand(); private: hid_device* dev; std::string location; + + void SetRingEffectChannel(unsigned char channel); + + void SendEffectChannelUpdate + ( + unsigned char effect_channel, + unsigned char speed, + bool direction, + bool random_color, + unsigned char mode, + unsigned char brightness, + unsigned char red, + unsigned char green, + unsigned char blue + ); + + void SendChannelRemap(unsigned char ring_channel, unsigned char logo_channel, unsigned char fan_channel); }; diff --git a/Controllers/AMDWraithPrismController/RGBController_AMDWraithPrism.cpp b/Controllers/AMDWraithPrismController/RGBController_AMDWraithPrism.cpp index 504a9cf3..b88db23a 100644 --- a/Controllers/AMDWraithPrismController/RGBController_AMDWraithPrism.cpp +++ b/Controllers/AMDWraithPrismController/RGBController_AMDWraithPrism.cpp @@ -36,7 +36,7 @@ RGBController_AMDWraithPrism::RGBController_AMDWraithPrism(AMDWraithPrismControl mode Direct; Direct.name = "Direct"; - Direct.value = 0; + Direct.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_DIRECT; Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS; Direct.brightness_min = 0; Direct.brightness_max = 0; @@ -44,8 +44,86 @@ RGBController_AMDWraithPrism::RGBController_AMDWraithPrism(AMDWraithPrismControl Direct.color_mode = MODE_COLORS_PER_LED; modes.push_back(Direct); - controller->SendEnableCommand(); - controller->SendApplyCommand(); + mode Breathing; + Breathing.name = "Breathing"; + Breathing.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_BREATHING; + Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Breathing.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST; + Breathing.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST; + Breathing.brightness_min = 0; + Breathing.brightness_max = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX; + Breathing.brightness = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX; + Breathing.color_mode = MODE_COLORS_MODE_SPECIFIC; + Breathing.speed = AMD_WRAITH_PRISM_SPEED_NORMAL; + Breathing.colors.resize(3); + modes.push_back(Breathing); + + mode ColorCycle; + ColorCycle.name = "Spectrum Cycle"; + ColorCycle.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_COLOR_CYCLE; + ColorCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS; + ColorCycle.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST; + ColorCycle.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST; + ColorCycle.brightness_min = 0; + ColorCycle.brightness_max = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_CYCLE_MAX; + ColorCycle.brightness = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_CYCLE_MAX; + ColorCycle.color_mode = MODE_COLORS_NONE; + ColorCycle.speed = AMD_WRAITH_PRISM_SPEED_NORMAL; + modes.push_back(ColorCycle); + + mode Rainbow; + Rainbow.name = "Rainbow Wave"; + Rainbow.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_RAINBOW; + Rainbow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS; + Rainbow.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST; + Rainbow.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST; + Rainbow.brightness_min = 0; + Rainbow.brightness_max = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX; + Rainbow.brightness = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX; //The Ring zone can not get brighter but Logo / Fan can + Rainbow.color_mode = MODE_COLORS_NONE; + Rainbow.speed = AMD_WRAITH_PRISM_SPEED_NORMAL; + modes.push_back(Rainbow); + + mode Bounce; + Bounce.name = "Bounce"; + Bounce.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_BOUNCE; + Bounce.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS; + Bounce.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST; + Bounce.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST; + Bounce.brightness_min = 0; + Bounce.brightness_max = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX; + Bounce.brightness = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX; //The Ring zone can not get brighter but Logo / Fan can + Bounce.color_mode = MODE_COLORS_NONE; + Bounce.speed = AMD_WRAITH_PRISM_SPEED_NORMAL; + modes.push_back(Bounce); + + mode Chase; + Chase.name = "Chase"; + Chase.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_CHASE; + Chase.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Chase.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST; + Chase.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST; + Chase.brightness_min = 0; + Chase.brightness_max = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX; + Chase.brightness = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX; + Chase.color_mode = MODE_COLORS_MODE_SPECIFIC; + Chase.speed = AMD_WRAITH_PRISM_SPEED_NORMAL; + Chase.colors.resize(3); + modes.push_back(Chase); + + mode Swirl; + Swirl.name = "Swirl"; + Swirl.value = AMD_WRAITH_PRISM_EFFECT_CHANNEL_SWIRL; + Swirl.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS; + Swirl.speed_min = AMD_WRAITH_PRISM_SPEED_SLOWEST; + Swirl.speed_max = AMD_WRAITH_PRISM_SPEED_FASTEST; + Swirl.brightness_min = 0; + Swirl.brightness_max = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX; + Swirl.brightness = AMD_WRAITH_PRISM_FAN_BRIGHTNESS_DEFAULT_MAX; + Swirl.color_mode = MODE_COLORS_MODE_SPECIFIC; + Swirl.speed = AMD_WRAITH_PRISM_SPEED_NORMAL; + Swirl.colors.resize(3); + modes.push_back(Swirl); SetupZones(); } @@ -134,41 +212,116 @@ void RGBController_AMDWraithPrism::ResizeZone(int /*zone*/, int /*new_size*/) void RGBController_AMDWraithPrism::DeviceUpdateLEDs() { - unsigned char led_ids[15]; - RGBColor color_buf[15]; - unsigned int leds_count = 0; - - for(unsigned int led_idx = 0; led_idx < colors.size(); led_idx++) + if(modes[active_mode].color_mode == MODE_COLORS_PER_LED) { - led_ids[leds_count] = (unsigned char)leds[led_idx].value; - color_buf[leds_count] = colors[led_idx]; + unsigned char led_ids[15]; + RGBColor color_buf[15]; + unsigned int leds_count = 0; - leds_count++; - - if(leds_count >= 15) + for(unsigned int led_idx = 0; led_idx < colors.size(); led_idx++) { - controller->SendDirectPacket(15, led_ids, color_buf); - leds_count = 0; + led_ids[leds_count] = (unsigned char)leds[led_idx].value; + color_buf[leds_count] = colors[led_idx]; + + leds_count++; + + if(leds_count >= 15) + { + controller->SendDirectPacket(15, led_ids, color_buf); + leds_count = 0; + } + } + + if(leds_count > 0) + { + controller->SendDirectPacket(leds_count, led_ids, color_buf); } } - - if(leds_count > 0) + else if(modes[active_mode].color_mode == MODE_COLORS_MODE_SPECIFIC) { - controller->SendDirectPacket(leds_count, led_ids, color_buf); + unsigned char red = RGBGetRValue(modes[active_mode].colors[0]); + unsigned char grn = RGBGetGValue(modes[active_mode].colors[0]); + unsigned char blu = RGBGetBValue(modes[active_mode].colors[0]); + controller->SetLogoColor(red, grn, blu); + + red = RGBGetRValue(modes[active_mode].colors[1]); + grn = RGBGetGValue(modes[active_mode].colors[1]); + blu = RGBGetBValue(modes[active_mode].colors[1]); + controller->SetFanColor(red, grn, blu); + + red = RGBGetRValue(modes[active_mode].colors[2]); + grn = RGBGetGValue(modes[active_mode].colors[2]); + blu = RGBGetBValue(modes[active_mode].colors[2]); + controller->SetRingColor(red, grn, blu); + } + else + { + controller->SetLogoColor(0, 0, 0); + controller->SetFanColor(0, 0, 0); + controller->SetRingColor(0, 0, 0); } } void RGBController_AMDWraithPrism::UpdateZoneLEDs(int zone) { - + DeviceUpdateLEDs(); } void RGBController_AMDWraithPrism::UpdateSingleLED(int led) { - + DeviceUpdateLEDs(); } void RGBController_AMDWraithPrism::DeviceUpdateMode() { + bool random = (modes[active_mode].color_mode == MODE_COLORS_RANDOM); + switch(modes[active_mode].value) + { + case AMD_WRAITH_PRISM_EFFECT_CHANNEL_DIRECT: + controller->SendEnableCommand(true); + controller->SendApplyCommand(); + break; + + case AMD_WRAITH_PRISM_EFFECT_CHANNEL_COLOR_CYCLE: + controller->SendEnableCommand(false); + controller->SetRingMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, modes[active_mode].direction, random); + controller->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, modes[active_mode].brightness, random); + controller->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, modes[active_mode].brightness, random); + break; + + case AMD_WRAITH_PRISM_EFFECT_CHANNEL_RAINBOW: + case AMD_WRAITH_PRISM_EFFECT_CHANNEL_BOUNCE: + controller->SendEnableCommand(false); + controller->SetRingMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, modes[active_mode].direction, random); + controller->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, (modes[active_mode].brightness >> 1), random); + controller->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, (modes[active_mode].brightness >> 1), random); + break; + + case AMD_WRAITH_PRISM_EFFECT_CHANNEL_BREATHING: + controller->SendEnableCommand(false); + controller->SetRingMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, modes[active_mode].direction, random); + controller->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_BREATHING, modes[active_mode].speed, modes[active_mode].brightness, random); + controller->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_BREATHING, modes[active_mode].speed, modes[active_mode].brightness, random); + break; + + default: + if(random) + { + controller->SendEnableCommand(false); + controller->SetRingMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, modes[active_mode].direction, random); + controller->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, modes[active_mode].brightness, random); + controller->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_COLOR_CYCLE, modes[active_mode].speed, modes[active_mode].brightness, random); + } + else + { + controller->SendEnableCommand(false); + controller->SetRingMode(modes[active_mode].value, modes[active_mode].speed, modes[active_mode].brightness, modes[active_mode].direction, random); + controller->SetFanMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC, modes[active_mode].speed, modes[active_mode].brightness, random); + controller->SetLogoMode(AMD_WRAITH_PRISM_FAN_LOGO_MODE_STATIC, modes[active_mode].speed, modes[active_mode].brightness, random); + } + break; + } + + DeviceUpdateLEDs(); }