Skip to content

Commit

Permalink
Add SteelSeries Prime+ mouse (qmk#24408)
Browse files Browse the repository at this point in the history
Co-authored-by: Joel Challis <git@zvecr.com>
  • Loading branch information
daskygit and zvecr authored Sep 20, 2024
1 parent 9cbb4a2 commit 90b87ab
Show file tree
Hide file tree
Showing 13 changed files with 318 additions and 0 deletions.
9 changes: 9 additions & 0 deletions keyboards/steelseries/prime_plus/board.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2024 Dasky (@daskygit)
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include_next <board.h>

#undef STM32_HSECLK
#define STM32_HSECLK 12000000
32 changes: 32 additions & 0 deletions keyboards/steelseries/prime_plus/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright 2024 Dasky (@daskygit)
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#define POINTING_DEVICE_CS_PIN A4
#define POINTING_DEVICE_MOTION_PIN B0
#define POINTING_DEVICE_TASK_THROTTLE_MS 1

#define SPI_DRIVER SPID1
#define SPI_SCK_PIN A5
#define SPI_MOSI_PIN A7
#define SPI_MISO_PIN A6

#define I2C1_SCL_PIN B8
#define I2C1_SDA_PIN B9

#define OLED_RESET B7
#define OLED_PWR B2

#define RGB_PWM_DRIVER PWMD1
#define RGB_BLUE_PIN A10
#define RGB_BLUE_PWM_CHANNEL 3
#define RGB_GREEN_PIN A8
#define RGB_GREEN_PWM_CHANNEL 1
#define RGB_RED_PIN A9
#define RGB_RED_PWM_CHANNEL 2

#define OPTICAL_SW_PWR A2

#define I2C1_CLOCK_SPEED 400000
#define I2C1_DUTY_CYCLE FAST_DUTY_CYCLE_2
31 changes: 31 additions & 0 deletions keyboards/steelseries/prime_plus/graphics/primeplus.qgf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2024 QMK -- generated source code only, image retains original copyright
// SPDX-License-Identifier: GPL-2.0-or-later

#include <qp.h>

const uint32_t gfx_primeplus_length = 317;

// clang-format off
const uint8_t gfx_primeplus[317] = {
0x00, 0xFF, 0x12, 0x00, 0x00, 0x51, 0x47, 0x46, 0x01, 0x3D, 0x01, 0x00, 0x00, 0xC2, 0xFE, 0xFF,
0xFF, 0x60, 0x00, 0x18, 0x00, 0x01, 0x00, 0x01, 0xFE, 0x04, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
0x02, 0xFD, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xE8, 0x03, 0x05, 0xFA, 0x0D, 0x01, 0x00,
0x0C, 0x00, 0x82, 0x80, 0x24, 0x09, 0x09, 0x00, 0x82, 0x80, 0x24, 0x09, 0x09, 0x00, 0xA4, 0x80,
0x24, 0x09, 0x38, 0xA6, 0x7A, 0xE7, 0x1D, 0x4E, 0xC2, 0x7C, 0x09, 0xC0, 0xFF, 0x1F, 0x48, 0xA9,
0x0A, 0x29, 0x24, 0x52, 0x22, 0x55, 0x09, 0xE0, 0xFF, 0x3F, 0x48, 0xA9, 0x0A, 0x29, 0x24, 0x52,
0x22, 0x55, 0x05, 0xFC, 0x02, 0xFF, 0xAF, 0x49, 0xA9, 0x3A, 0xE9, 0x24, 0xCE, 0x23, 0x55, 0x03,
0xE0, 0xDE, 0x3B, 0x38, 0xA9, 0x0A, 0x27, 0x24, 0x12, 0x22, 0x55, 0x05, 0xE0, 0xDE, 0x3B, 0x08,
0xA9, 0x0A, 0x29, 0x24, 0x12, 0xA2, 0x54, 0x09, 0xFC, 0xDE, 0xFB, 0x09, 0x46, 0x79, 0xE9, 0x1D,
0xCE, 0x43, 0x55, 0x09, 0xE0, 0xDE, 0x3B, 0x09, 0x00, 0x82, 0xE0, 0xDE, 0x3B, 0x09, 0x00, 0x85,
0xFC, 0xDC, 0xF9, 0x01, 0x00, 0xF0, 0x03, 0xFF, 0x80, 0x0F, 0x02, 0x00, 0x82, 0xE0, 0xD9, 0x3C,
0x02, 0x00, 0x80, 0xF8, 0x03, 0xFF, 0x80, 0x1F, 0x02, 0x00, 0x82, 0xE0, 0x03, 0x3E, 0x02, 0x00,
0x84, 0x18, 0x63, 0x04, 0xE1, 0x1F, 0x02, 0x00, 0x89, 0xFC, 0xDF, 0xFF, 0x01, 0x00, 0xD8, 0xDA,
0x56, 0xFD, 0x1E, 0x02, 0x00, 0x82, 0xE0, 0xDF, 0x3F, 0x02, 0x00, 0x84, 0xD8, 0xDA, 0x56, 0xFD,
0x1E, 0x02, 0x00, 0x82, 0xE0, 0xDF, 0x3F, 0x02, 0x00, 0x84, 0xD8, 0xDA, 0x56, 0x31, 0x18, 0x02,
0x00, 0x80, 0xFC, 0x02, 0xFF, 0x86, 0x01, 0x00, 0x18, 0xE3, 0x56, 0xFD, 0x1E, 0x02, 0x00, 0x82,
0xE0, 0xFF, 0x3F, 0x02, 0x00, 0x84, 0xD8, 0xDB, 0x56, 0xFD, 0x1E, 0x02, 0x00, 0x82, 0xC0, 0xFF,
0x1F, 0x02, 0x00, 0x84, 0xD8, 0x5B, 0x54, 0xE1, 0x1F, 0x02, 0x00, 0x82, 0x80, 0x24, 0x09, 0x02,
0x00, 0x80, 0xF8, 0x03, 0xFF, 0x80, 0x1F, 0x02, 0x00, 0x82, 0x80, 0x24, 0x09, 0x02, 0x00, 0x80,
0xF0, 0x03, 0xFF, 0x80, 0x0F, 0x02, 0x00, 0x82, 0x80, 0x24, 0x09, 0x09, 0x00,
};
// clang-format on
9 changes: 9 additions & 0 deletions keyboards/steelseries/prime_plus/graphics/primeplus.qgf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright 2024 QMK -- generated source code only, image retains original copyright
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include <qp.h>

extern const uint32_t gfx_primeplus_length;
extern const uint8_t gfx_primeplus[317];
10 changes: 10 additions & 0 deletions keyboards/steelseries/prime_plus/halconf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright 2024 Dasky (@daskygit)
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#define HAL_USE_SPI TRUE
#define HAL_USE_I2C TRUE
#define HAL_USE_PWM TRUE

#include_next <halconf.h>
59 changes: 59 additions & 0 deletions keyboards/steelseries/prime_plus/keyboard.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"manufacturer": "SteelSeries",
"keyboard_name": "Prime+",
"maintainer": "Dasky",
"bootloader": "uf2boot",
"build": {
"debounce_type": "asym_eager_defer_pk",
"lto": true
},
"encoder": {
"rotary": [
{"pin_a": "B5", "pin_b": "B4", "resolution": 2}
]
},
"features": {
"bootmagic": true,
"encoder": true,
"extrakey": true,
"mousekey": true,
"pointing_device": true,
"quantum_painter": true,
"rgblight": true
},
"matrix_pins": {
"direct": [
["A0", "C15", "A1", "C13", "C14", "A3"]
]
},
"processor": "STM32F103",
"rgblight": {
"animations": {
"breathing": true,
"rainbow_mood": true
},
"default": {
"animation": "rainbow_mood"
},
"driver": "custom",
"led_count": 1
},
"url": "https://steelseries.com/gaming-mice/prime-plus",
"usb": {
"device_version": "1.0.0",
"pid": "0x0000",
"vid": "0xFEED"
},
"layouts": {
"LAYOUT": {
"layout": [
{"matrix": [0, 0], "x": 0, "y": 0},
{"matrix": [0, 1], "x": 1, "y": 0},
{"matrix": [0, 2], "x": 2, "y": 0},
{"matrix": [0, 3], "x": 0, "y": 1},
{"matrix": [0, 4], "x": 0, "y": 2},
{"matrix": [0, 5], "x": 2, "y": 2}
]
}
}
}
29 changes: 29 additions & 0 deletions keyboards/steelseries/prime_plus/keymaps/default/keymap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2024 Dasky (@daskygit)
// SPDX-License-Identifier: GPL-2.0-or-later

#include QMK_KEYBOARD_H

// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
// Left, Middle, Right,
// Forward
// Back
// Underneath
[0] = LAYOUT(
MS_BTN1, MS_BTN3, MS_BTN2,
MS_BTN5,
MS_BTN4,
QK_BOOT
)
};
// clang-format on

void pointing_device_init_kb(void) {
pointing_device_set_cpi(1600);
}

#if defined(ENCODER_MAP_ENABLE)
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
[0] = {ENCODER_CCW_CW(MS_WHLU, MS_WHLD)},
};
#endif
1 change: 1 addition & 0 deletions keyboards/steelseries/prime_plus/keymaps/default/rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ENCODER_MAP_ENABLE = yes
18 changes: 18 additions & 0 deletions keyboards/steelseries/prime_plus/mcuconf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2024 Dasky (@daskygit)
// SPDX-License-Identifier: GPL-2.0-or-later

#pragma once

#include_next <mcuconf.h>

#undef STM32_I2C_USE_I2C1
#define STM32_I2C_USE_I2C1 TRUE

#undef STM32_PWM_USE_TIM1
#define STM32_PWM_USE_TIM1 TRUE

#undef STM32_SPI_USE_SPI1
#define STM32_SPI_USE_SPI1 TRUE

#undef STM32_PLLMUL_VALUE
#define STM32_PLLMUL_VALUE 6
40 changes: 40 additions & 0 deletions keyboards/steelseries/prime_plus/prime_plus.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2024 Dasky (@daskygit)
// SPDX-License-Identifier: GPL-2.0-or-later

#include "quantum.h"
#include "graphics/primeplus.qgf.h"

painter_image_handle_t primeplus;
painter_device_t display;

void board_init(void) {
AFIO->MAPR |= AFIO_MAPR_I2C1_REMAP;

gpio_set_pin_output(A15);
gpio_write_pin_high(A15); // Activate D+ pullup

gpio_set_pin_output(OPTICAL_SW_PWR);
gpio_write_pin_low(OPTICAL_SW_PWR); // Enable power for optical switches

gpio_set_pin_output(OLED_PWR);
gpio_write_pin_high(OLED_PWR); // Enable OLED power
}

void keyboard_post_init_kb(void) {
wait_ms(1); // Wait for OLED

gpio_set_pin_output(OLED_RESET);
gpio_write_pin_low(OLED_RESET);
wait_us(10); // Minimum wait 1us

gpio_write_pin_high(OLED_RESET);
wait_ms(1); // Minimum wait 1ms

primeplus = qp_load_image_mem(gfx_primeplus);
display = qp_ld7032_make_i2c_device(96, 24, 0x37);

qp_init(display, QP_ROTATION_180);
qp_drawimage(display, 0, 0, primeplus);

keyboard_post_init_user();
}
28 changes: 28 additions & 0 deletions keyboards/steelseries/prime_plus/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# SteelSeries Prime +

![Prime+](https://i.imgur.com/QhNHmwxh.png)

This firmware does not support the dedicated lift off sensor.

Erase with an stlink and flash this [uf2boot bootloader](https://github.com/daskygit/uf2-prime-plus), this is a a one way procedure voiding any warranty so be sure you don't want to use the original manufacturers firmware.

* Keyboard Maintainer: [Dasky](https://github.com/daskygit)
* Hardware Supported: SteelSeries Prime+
* Hardware Availability: https://steelseries.com/gaming-mice/prime-plus

Make example for this keyboard (after setting up your build environment):

make steelseries/prime_plus:default

Flashing example for this keyboard:

make steelseries/prime_plus:default:flash

See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).

## Bootloader

Enter the bootloader in 2 ways:

* **Bootmagic reset**: Hold down left mouse button and plug in.
* **Bootloader entry**: Hold the underneath button while plugging in.
45 changes: 45 additions & 0 deletions keyboards/steelseries/prime_plus/rgblight_custom.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2024 Dasky (@daskygit)
// SPDX-License-Identifier: GPL-2.0-or-later

#include "quantum.h"

static PWMConfig pwmCFG = {
.frequency = 0xFFFF,
.period = 256,
};

void prime_setleds(rgb_led_t *start_led, uint16_t num_leds) {
if (start_led[0].r == 0) {
pwmDisableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1);
} else {
uint32_t duty = ((uint32_t)0xFFFF * start_led[0].r) / 0xFF;
pwmEnableChannel(&RGB_PWM_DRIVER, RGB_RED_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty));
}
if (start_led[0].g == 0) {
pwmDisableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1);
} else {
uint32_t duty = ((uint32_t)0xFFFF * start_led[0].g) / 0xFF;
pwmEnableChannel(&RGB_PWM_DRIVER, RGB_GREEN_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty));
}
if (start_led[0].b == 0) {
pwmDisableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1);
} else {
uint32_t duty = ((uint32_t)0xFFFF * start_led[0].b) / 0xFF;
pwmEnableChannel(&RGB_PWM_DRIVER, RGB_BLUE_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&RGB_PWM_DRIVER, 0xFFFF, duty));
}
}

void prime_initleds(void) {
palSetPadMode(PAL_PORT(RGB_RED_PIN), PAL_PAD(RGB_RED_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
palSetPadMode(PAL_PORT(RGB_GREEN_PIN), PAL_PAD(RGB_GREEN_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
palSetPadMode(PAL_PORT(RGB_BLUE_PIN), PAL_PAD(RGB_BLUE_PIN), PAL_MODE_ALTERNATE_PUSHPULL);
pwmCFG.channels[RGB_RED_PWM_CHANNEL - 1].mode = PWM_OUTPUT_ACTIVE_HIGH;
pwmCFG.channels[RGB_GREEN_PWM_CHANNEL - 1].mode = PWM_OUTPUT_ACTIVE_HIGH;
pwmCFG.channels[RGB_BLUE_PWM_CHANNEL - 1].mode = PWM_OUTPUT_ACTIVE_HIGH;
pwmStart(&RGB_PWM_DRIVER, &pwmCFG);
}

const rgblight_driver_t rgblight_driver = {
.init = prime_initleds,
.setleds = prime_setleds,
};
7 changes: 7 additions & 0 deletions keyboards/steelseries/prime_plus/rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
MCU_LDSCRIPT = STM32F103xB_uf2boot

QUANTUM_PAINTER_DRIVERS = ld7032_i2c
POINTING_DEVICE_DRIVER = pmw3389

SRC += graphics/primeplus.qgf.c
SRC += rgblight_custom.c

0 comments on commit 90b87ab

Please sign in to comment.