Skip to content

Instantly share code, notes, and snippets.

@gleber
Last active December 5, 2025 15:53
Show Gist options
  • Select an option

  • Save gleber/8d6c90d16dee45db2dd458814d3dd1fc to your computer and use it in GitHub Desktop.

Select an option

Save gleber/8d6c90d16dee45db2dd458814d3dd1fc to your computer and use it in GitHub Desktop.
X.Tips X7S Keyboard (2024-04)

QMK config

I've managed to compile a working firmware with this config: https://github.com/gleber/qmk_firmware/commit/54078ec73c0ff2bd01984242f748a837c1954d03

Details

This isn't tested much, just the basics: keys and split setup. LED, bootloader magic key and any other features are not yet implemented. Tested only the Miryoku layout so far.

I've disassembled it and found a few things.

Back of one of the sides looks like this:

A more close up photo of the chip shows some STM32 chip:

If you decode the QR code it gives you a short link to what seem to be JLC PCB page about this specific PCB:

It includes product name 【X.Tips】X7S小分体键盘_-_V2.0_【热插拔】PCB-X7S-V2-R__20240726163326 which translates with Google Translate to 【X.Tips】X7S small split keyboard_-_V2.0_【Hot plug】PCB-X7S-V2-R__20240726163326

And these schematics images for the right side:

and for the left side:

Attached via-x7.json file was sent to one of the buyers by the seller. It works for my keyboard.

{
"name": "X.Tips X7 Keyboard",
"vendorId": "0x5262",
"productId": "0x4E4B",
"keycodes": ["qmk_lighting"],
"menus": [ "qmk_rgblight"],
"matrix": {"rows": 8, "cols": 5},
"layouts": {
"keymap": [
["0,0","0,1","0,2","0,3","0,4",{"x":1},"4,4","4,3","4,2","4,1","4,0"],
["1,0","1,1","1,2","1,3","1,4",{"x":1},"5,4","5,3","5,2","5,1","5,0"],
["2,0","2,1","2,2","2,3","2,4",{"x":1},"6,4","6,3","6,2","6,1","6,0"],
[{"x":2},"3,2","3,3","3,4",{"x":1},"7,4","7,3","7,2"]
]
}
}
{
"name": "X.Tips X7 Keyboard",
"vendorProductId": 1382174283,
"macros": ["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""],
"layers": [
[
"KC_Q",
"KC_W",
"KC_E",
"KC_R",
"KC_T",
"KC_A",
"KC_S",
"KC_D",
"KC_F",
"KC_G",
"KC_Z",
"KC_X",
"KC_C",
"KC_V",
"KC_B",
"KC_NO",
"KC_NO",
"MT(MOD_LCTL,KC_ESC)",
"LT(1,KC_SPC)",
"KC_LSFT",
"KC_P",
"KC_O",
"KC_I",
"KC_U",
"KC_Y",
"KC_ENT",
"KC_L",
"KC_K",
"KC_J",
"KC_H",
"KC_BSPC",
"LT(4,KC_DOT)",
"LT(3,KC_COMM)",
"KC_M",
"KC_N",
"KC_NO",
"KC_NO",
"MT(MOD_LGUI,KC_DEL)",
"LT(7,KC_SPC)",
"MT(MOD_LALT,KC_TAB)"
],
[
"KC_7",
"KC_8",
"KC_9",
"KC_PDOT",
"KC_PPLS",
"KC_4",
"KC_5",
"KC_6",
"KC_0",
"KC_PMNS",
"KC_1",
"KC_2",
"KC_3",
"KC_BSPC",
"KC_EQL",
"KC_NO",
"KC_NO",
"KC_LCTL",
"TO(0)",
"MT(MOD_LSFT,KC_PENT)",
"KC_GRV",
"S(KC_BSLS)",
"S(KC_SCLN)",
"S(KC_4)",
"KC_PAST",
"KC_SCLN",
"S(KC_RBRC)",
"S(KC_LBRC)",
"S(KC_3)",
"KC_PSLS",
"KC_QUOT",
"S(KC_DOT)",
"S(KC_COMM)",
"S(KC_7)",
"KC_BSLS",
"KC_NO",
"KC_NO",
"KC_LGUI",
"G(KC_SPC)",
"KC_LALT"
],
[
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO"
],
[
"LCAG(KC_P)",
"KC_F9",
"KC_F10",
"KC_F11",
"KC_F12",
"LCAG(KC_ENT)",
"KC_F5",
"KC_F6",
"KC_F7",
"KC_F8",
"LCAG(KC_BSPC)",
"KC_F1",
"KC_F2",
"KC_F3",
"KC_F4",
"KC_NO",
"KC_NO",
"KC_RCTL",
"TT(6)",
"KC_RSFT",
"KC_NLCK",
"KC_APP",
"KC_INS",
"KC_VOLU",
"KC_VOLD",
"KC_SLCK",
"KC_PSCR",
"KC_PAUS",
"KC_MNXT",
"KC_MPRV",
"RCS(KC_O)",
"RCS(KC_X)",
"TO(0)",
"KC_MPLY",
"KC_MUTE",
"KC_NO",
"KC_NO",
"KC_RGUI",
"MO(5)",
"KC_RALT"
],
[
"MEH(KC_Q)",
"MEH(KC_W)",
"MEH(KC_E)",
"MEH(KC_R)",
"MEH(KC_T)",
"MEH(KC_A)",
"MEH(KC_S)",
"MEH(KC_D)",
"MEH(KC_F)",
"MEH(KC_G)",
"MEH(KC_Z)",
"MEH(KC_X)",
"MEH(KC_C)",
"MEH(KC_V)",
"MEH(KC_B)",
"KC_NO",
"MEH(KC_2)",
"MEH(KC_3)",
"MEH(KC_4)",
"MEH(KC_5)",
"MEH(KC_P)",
"MEH(KC_O)",
"MEH(KC_I)",
"MEH(KC_U)",
"MEH(KC_Y)",
"MEH(KC_ENT)",
"MEH(KC_L)",
"MEH(KC_K)",
"MEH(KC_J)",
"MEH(KC_H)",
"MEH(KC_BSPC)",
"TO(0)",
"MEH(KC_COMM)",
"MEH(KC_M)",
"MEH(KC_N)",
"KC_NO",
"KC_NO",
"MEH(KC_0)",
"MEH(KC_9)",
"MEH(KC_6)"
],
[
"RGB_HUI",
"RGB_MOD",
"HYPR(KC_E)",
"HYPR(KC_R)",
"HYPR(KC_T)",
"RGB_SAI",
"RGB_SPI",
"HYPR(KC_D)",
"HYPR(KC_F)",
"HYPR(KC_G)",
"RGB_VAI",
"RGB_TOG",
"HYPR(KC_C)",
"HYPR(KC_V)",
"HYPR(KC_B)",
"HYPR(KC_1)",
"HYPR(KC_2)",
"HYPR(KC_3)",
"HYPR(KC_4)",
"HYPR(KC_5)",
"KC_MS_BTN2",
"KC_MS_UP",
"KC_MS_BTN1",
"A(KC_TAB)",
"A(KC_F4)",
"KC_MS_RIGHT",
"KC_MS_DOWN",
"KC_MS_LEFT",
"C(KC_T)",
"C(KC_W)",
"KC_MS_BTN3",
"KC_MS_BTN5",
"KC_MS_BTN4",
"C(KC_TAB)",
"RCS(KC_TAB)",
"KC_NO",
"KC_NO",
"MEH(KC_RBRC)",
"TO(0)",
"MEH(KC_LBRC)"
],
[
"LCAG(KC_Q)",
"KC_F21",
"KC_F22",
"KC_F23",
"KC_F24",
"LCAG(KC_A)",
"KC_F17",
"KC_F18",
"KC_F19",
"KC_F20",
"LCAG(KC_Z)",
"KC_F13",
"KC_F14",
"KC_F15",
"KC_F16",
"KC_NO",
"KC_NO",
"MT(MOD_LCTL,KC_ESC)",
"TO(0)",
"MT(MOD_LSFT,KC_TAB)",
"KC_PDOT",
"KC_P9",
"KC_P8",
"KC_P7",
"KC_PPLS",
"KC_P0",
"KC_P6",
"KC_P5",
"KC_P4",
"KC_PMNS",
"KC_BSPC",
"KC_P3",
"KC_P2",
"KC_P1",
"KC_PAST",
"KC_NO",
"KC_NO",
"KC_PENT",
"MT(MOD_LSFT,KC_SPC)",
"MT(MOD_LALT,KC_PSLS)"
],
[
"S(KC_GRV)",
"S(KC_5)",
"S(KC_MINS)",
"S(KC_6)",
"S(KC_EQL)",
"S(KC_2)",
"S(KC_QUOT)",
"S(KC_1)",
"S(KC_SLSH)",
"KC_MINS",
"KC_LBRC",
"KC_RBRC",
"S(KC_9)",
"S(KC_0)",
"KC_EQL",
"KC_NO",
"KC_NO",
"KC_RCTL",
"KC_CAPS",
"KC_RSFT",
"KC_PGUP",
"KC_END",
"KC_UP",
"KC_HOME",
"S(KC_8)",
"KC_PGDN",
"KC_RGHT",
"KC_DOWN",
"KC_LEFT",
"KC_SLSH",
"KC_DEL",
"KC_TAB",
"KC_ESC",
"MEH(KC_SLSH)",
"KC_BSLS",
"KC_NO",
"KC_NO",
"KC_RGUI",
"TO(0)",
"KC_RALT"
],
[
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS",
"KC_TRNS"
]
],
"encoders": []
}
@DominikJaskowiec
Copy link

DominikJaskowiec commented Mar 13, 2025

Hello, I bricked the left side of the keyboard using the method provided, and now I cant unbrick it. I've flashed the right side first and than other and it's now unresponsive (right side still works with flashed layout). I've tried going the STLink route but it doesn't work, it shows me a window that says "Unable to get core ID" followed by "No STM32 target found". I've checked if the working half is detected by STM and it does. I've ordered the STLink v2 off of Aliexpress and updated it's firmware with the stm32 tool and connected the cables as labeled. Nothing works

Does anyone have an Idea of what to do here?

EDIT: Thought this would possibly help, I've checked and it's not completely dead. when i connect the right half to my PC, Windows detects it as "Unknown USB Device (Device Descriptor Request Failed)"

@tgfuellner
Copy link

Hi,

I was able to unbrick the left side of my X.Tips V4e Keyboard.
First I read the firmware of the working right side: st-flash read firmware.bin 0x08000000 0x10000
Then I wrote to the left side: st-flash write firmware.bin 0x08000000

@code-inflation
Copy link

@tgfuellner how did you connect the stm programmer to the V4e? Thanks!

@tgfuellner
Copy link

At that time, I wrote down the following:

SWDIO=PA13=34, SWCLK=PA14=37, GND=VSS=8, NRST=7

To flash the keyboard you need to connect the reset contacts (not necessary the holes, but the metal around them) with anything conductive DURING power up of th
e keyboard. I.e. the way I do it normally is I short these RESET contacts and I plug in the USB cable. This moves the chip on the keyboard into bootloader mode, w
hich allows you to flash it.

Hope that helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment