From 85fe82dd7ad96d978f389489beb7d16f3d227304 Mon Sep 17 00:00:00 2001 From: Adam Honse Date: Tue, 16 Nov 2021 00:23:08 -0600 Subject: [PATCH] Decode the NVME command for XPG SSD --- .../RGBController_XPGSpectrixS40G.cpp | 69 +++++++++++++++++++ .../RGBController_XPGSpectrixS40G.h | 2 + .../XPGSpectrixS40GController.cpp | 49 ++++++++----- 3 files changed, 101 insertions(+), 19 deletions(-) diff --git a/Controllers/XPGSpectrixS40GController/RGBController_XPGSpectrixS40G.cpp b/Controllers/XPGSpectrixS40GController/RGBController_XPGSpectrixS40G.cpp index fa996535d..9e435e009 100644 --- a/Controllers/XPGSpectrixS40GController/RGBController_XPGSpectrixS40G.cpp +++ b/Controllers/XPGSpectrixS40GController/RGBController_XPGSpectrixS40G.cpp @@ -9,6 +9,70 @@ #include "RGBController_XPGSpectrixS40G.h" +int RGBController_XPGSpectrixS40G::GetDeviceMode() +{ + /*-----------------------------------------------------------------*\ + | Determine starting mode by reading the mode and direct registers | + \*-----------------------------------------------------------------*/ + int dev_mode = aura->AuraRegisterRead(AURA_REG_MODE); + int color_mode = MODE_COLORS_PER_LED; + int speed = aura->AuraRegisterRead(AURA_REG_SPEED); + int direction = aura->AuraRegisterRead(AURA_REG_DIRECTION); + + if(aura->AuraRegisterRead(AURA_REG_DIRECT)) + { + dev_mode = 0xFFFF; + } + + switch(dev_mode) + { + case AURA_MODE_OFF: + case AURA_MODE_RAINBOW: + case AURA_MODE_SPECTRUM_CYCLE: + case AURA_MODE_RANDOM_FLICKER: + color_mode = MODE_COLORS_NONE; + break; + + case AURA_MODE_SPECTRUM_CYCLE_CHASE: + dev_mode = AURA_MODE_CHASE; + color_mode = MODE_COLORS_RANDOM; + break; + + case AURA_MODE_SPECTRUM_CYCLE_BREATHING: + dev_mode = AURA_MODE_BREATHING; + color_mode = MODE_COLORS_RANDOM; + break; + + case AURA_MODE_SPECTRUM_CYCLE_CHASE_FADE: + dev_mode = AURA_MODE_CHASE_FADE; + color_mode = MODE_COLORS_RANDOM; + break; + } + + for(std::size_t mode = 0; mode < modes.size(); mode++) + { + if(modes[mode].value == dev_mode) + { + active_mode = mode; + modes[mode].color_mode = color_mode; + + if(modes[mode].flags & MODE_FLAG_HAS_SPEED) + { + modes[mode].speed = speed; + } + + if(modes[mode].flags & MODE_FLAG_HAS_DIRECTION_LR) + { + modes[mode].direction = direction; + } + + break; + } + } + + return(active_mode); +} + void RGBController_XPGSpectrixS40G::DeviceUpdateLEDs() { if(GetMode() == 0) @@ -173,6 +237,11 @@ RGBController_XPGSpectrixS40G::RGBController_XPGSpectrixS40G(XPGSpectrixS40GCont modes.push_back(RandomFlicker); SetupZones(); + + /*-------------------------------------------------*\ + | Initialize active mode | + \*-------------------------------------------------*/ + //active_mode = GetDeviceMode(); } RGBController_XPGSpectrixS40G::~RGBController_XPGSpectrixS40G() diff --git a/Controllers/XPGSpectrixS40GController/RGBController_XPGSpectrixS40G.h b/Controllers/XPGSpectrixS40GController/RGBController_XPGSpectrixS40G.h index 9f53c4196..acf68f2aa 100644 --- a/Controllers/XPGSpectrixS40GController/RGBController_XPGSpectrixS40G.h +++ b/Controllers/XPGSpectrixS40GController/RGBController_XPGSpectrixS40G.h @@ -30,6 +30,8 @@ public: void DeviceUpdateMode(); void DeviceSaveMode(); + int GetDeviceMode(); + private: XPGSpectrixS40GController* aura; }; diff --git a/Controllers/XPGSpectrixS40GController/XPGSpectrixS40GController.cpp b/Controllers/XPGSpectrixS40GController/XPGSpectrixS40GController.cpp index ec824ef46..910838196 100644 --- a/Controllers/XPGSpectrixS40GController/XPGSpectrixS40GController.cpp +++ b/Controllers/XPGSpectrixS40GController/XPGSpectrixS40GController.cpp @@ -10,11 +10,13 @@ #include "XPGSpectrixS40GController.h" #include #include +#include "LogManager.h" #ifdef _WIN32 #include #include #include + #include #else #endif @@ -289,20 +291,26 @@ void XPGSpectrixS40GController::AuraRegisterWrite(aura_register reg, unsigned ch | Create ENE Register Write command, filling in the appropriate register and | | value | \*-----------------------------------------------------------------------------*/ - DWORD CommandValue[34] = { 0x003000FB, 0x00000031, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x01100001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000001, 0x00000000 }; + PNVME_COMMAND CommandValue = (PNVME_COMMAND)command->Command; unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF); - CommandValue[12] = (corrected_reg << 16) | (dev << 1); - CommandValue[32] = val; + CommandValue->CDW0.OPC = 0xFB; + CommandValue->CDW0.CID = 0x0030; + CommandValue->NSID = 0x00000031; + CommandValue->u.GENERAL.CDW12 = (corrected_reg << 16) | (dev << 1); + CommandValue->u.GENERAL.CDW13 = 0x01100001; + + DWORD ExtraValue[18] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }; + + ExtraValue[16] = val; /*-----------------------------------------------------------------------------*\ - | Copy the ENE Register Write command into the STORAGE_PROTOCOL_COMMAND buffer | + | Copy the ENE Register Write extra data into the STORAGE_PROTOCOL_COMMAND | + | buffer | \*-----------------------------------------------------------------------------*/ - memcpy(&command->Command, CommandValue, sizeof(CommandValue)); + memcpy(&command->Command + sizeof(NVME_COMMAND), ExtraValue, sizeof(ExtraValue)); /*-----------------------------------------------------------------------------*\ | Send the STORAGE_PROTOCOL_COMMAND to the device | @@ -356,24 +364,27 @@ void XPGSpectrixS40GController::AuraRegisterWriteBlock(aura_register reg, unsign | Create ENE Register Write Block command, filling in the appropriate register | | and value | \*-----------------------------------------------------------------------------*/ - DWORD CommandValue[39] = { 0x003000FB, 0x00000031, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x03100000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + PNVME_COMMAND CommandValue = (PNVME_COMMAND)command->Command; + unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF); - unsigned short corrected_reg = ((reg << 8) & 0xFF00) | ((reg >> 8) & 0x00FF); + CommandValue->CDW0.OPC = 0xFB; + CommandValue->CDW0.CID = 0x0030; + CommandValue->NSID = 0x00000031; + CommandValue->u.GENERAL.CDW12 = (corrected_reg << 16) | (dev << 1); + CommandValue->u.GENERAL.CDW13 = 0x03100000 | sz; - CommandValue[12] = (corrected_reg << 16) | (dev << 1); - CommandValue[13] = 0x03100000 | sz; + DWORD ExtraValue[23] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000 }; - memcpy(&CommandValue[32], data, sz); + memcpy(&ExtraValue[16], data, sz); /*-----------------------------------------------------------------------------*\ - | Copy the ENE Register Write Block command into the STORAGE_PROTOCOL_COMMAND | - | buffer | + | Copy the ENE Register Write Block extra data into the | + | STORAGE_PROTOCOL_COMMAND buffer | \*-----------------------------------------------------------------------------*/ - memcpy(&command->Command, CommandValue, sizeof(CommandValue)); + memcpy(&command->Command + sizeof(NVME_COMMAND), ExtraValue, sizeof(ExtraValue)); /*-----------------------------------------------------------------------------*\ | Send the STORAGE_PROTOCOL_COMMAND to the device |