#ifndef RAZER_H #define RAZER_H #include #include #include #define VENDOR_ID 0x1532 #define REPORT_SIZE 90 /* Devices */ #include "viper_mini.h" typedef struct REPORT_HEADER { uint8_t status; uint8_t transaction_id; uint8_t remaining_packets_high; uint8_t remaining_packets_low; uint8_t protocol_type; // 0x0 uint8_t report_size; uint8_t command_class; uint8_t command_id; } __attribute__((packed)) report_header_t; typedef struct REPORT_FOOTER { uint8_t crc; // Control, xored bytes of report uint8_t reserved; } __attribute__((packed)) report_footer_t; /* Commands of the BASIC (0x0) class */ #define COMMAND_CLASS_BASIC 0x0 struct REPORT_FIRMWARE_VERSION { report_header_t header; uint8_t version_major; uint8_t version_minor; uint8_t zeros[REPORT_SIZE - sizeof(report_header_t) - sizeof(report_footer_t) - 2]; report_footer_t footer; } __attribute__((packed)); #define REPORT_SIZE_FIRMWARE_VERSION 0x2 #define COMMAND_REPORT_FIRMWARE_VERSION 0x81 static_assert(sizeof(struct REPORT_FIRMWARE_VERSION) == REPORT_SIZE, "REPORT_FIRMWARE_VERSION is not of the right size"); struct REPORT_POLLING_RATE { report_header_t header; // There is another report for up to 8000Hz polling // 0x01: 1000Hz, 0x2: 500Hz, 0x3: 125Hz uint8_t polling_rate; uint8_t zeros[REPORT_SIZE - sizeof(report_header_t) - sizeof(report_footer_t) - 1]; report_footer_t footer; } __attribute__((packed)); static_assert(sizeof(struct REPORT_POLLING_RATE) == REPORT_SIZE, "REPORT_POLLING_RATE is not of the right size"); #define REPORT_SIZE_POLLING_RATE 0x1 #define COMMAND_REPORT_POLLING_RATE 0x85 /* Commands of the DPI (0x4) class */ #define COMMAND_CLASS_DPI 0x4 struct REPORT_DPI { report_header_t header; uint8_t variable_storage; uint8_t dpi_x_high; uint8_t dpi_x_low; uint8_t dpi_y_high; uint8_t dpi_y_low; uint8_t unknown_0; uint8_t unknown_1; uint8_t zeros[REPORT_SIZE - sizeof(report_header_t) - sizeof(report_footer_t) - 7]; report_footer_t footer; } __attribute__((packed)); static_assert(sizeof(struct REPORT_DPI) == REPORT_SIZE, "REPORT_DPI is not of the right size"); #define REPORT_SIZE_DPI 0x07 #define COMMAND_REPORT_DPI 0x85 typedef struct DPI_STAGE { uint8_t stage_index; uint8_t dpi_x_high; uint8_t dpi_x_low; uint8_t dpi_y_high; uint8_t dpi_y_low; uint8_t unknown_0; uint8_t unknown_1; } __attribute__((packed)) dpi_stage_t; struct REPORT_DPI_STAGES { report_header_t header; uint8_t variable_storage; uint8_t active_dpi_stage; uint8_t dpi_stages_count; dpi_stage_t stages[5]; uint8_t zeros[REPORT_SIZE - sizeof(report_header_t) - sizeof(report_footer_t) - 38]; report_footer_t footer; } __attribute__((packed)); static_assert(sizeof(struct REPORT_DPI_STAGES) == REPORT_SIZE, "REPORT_DPI_STAGES is not of the right size"); #define REPORT_SIZE_DPI_STAGES 0x26 #define COMMAND_REPORT_DPI_STAGES 0x86 /* Commands of the BATTERY (0x7) class */ #define COMMAND_CLASS_BATTERY 0x7 struct REPORT_BATTERY_LEVEL { report_header_t header; uint8_t ignored; uint8_t battery_level; // 0-255 report_footer_t footer; } __attribute__((packed)); #define REPORT_SIZE_BATTERY_LEVEL 0x2 #define COMMAND_REPORT_BATTERY_LEVEL 0x80 struct REPORT_BATTERY_STATUS { report_header_t header; uint8_t ignored; uint8_t charging; // 0: not charging, 1:charging report_footer_t footer; } __attribute__((packed)); #define REPORT_SIZE_BATTERY_STATUS 0x2 #define COMMAND_REPORT_BATTERY_STATUS 0x84 #endif