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": []
}
@Javierg9n4
Copy link

@gleber Could you please explain the hole process in detail or reffer to a comprehensive tutorial on how to compile and flash the firmware with miryoku layout please?? I just got the keyboard but the default keymaps are a bit weird.

@ejingles
Copy link

I think I've bricked my right part of keyboard. I've trying using a clip on pins, but yeah, no response at all from it. Any suggestions?

Copy link

ghost commented Nov 23, 2024

I think I've bricked my right part of keyboard. I've trying using a clip on pins, but yeah, no response at all from it. Any suggestions?

I bricked mine too while attempting to flash. Have you found a way on how to fix it?

Copy link

ghost commented Nov 23, 2024

I think I've bricked my right part of keyboard. I've trying using a clip on pins, but yeah, no response at all from it. Any suggestions?

@gleber Sorry for bothering, but would you have any idea on how to fix this problem?

@pragmaticgeek
Copy link

likewise for me. I tried to flash it and it errored out. Now trying the reset pins doesn't put it back to bootloader mode unfortunately. What I am trying is to short the 2 empty holes to the right of the STM chip with no success.

@ejingles
Copy link

I think I've bricked my right part of keyboard. I've trying using a clip on pins, but yeah, no response at all from it. Any suggestions?

I bricked mine too while attempting to flash. Have you found a way on how to fix it?

No, I've contacted the seller, no help was provided whatsoever. There was a huge language barrier, couldn't communicate with them properly, sadly.

@ejingles
Copy link

likewise for me. I tried to flash it and it errored out. Now trying the reset pins doesn't put it back to bootloader mode unfortunately. What I am trying is to short the 2 empty holes to the right of the STM chip with no success.

Same! There was some pictures, mentioning there was 2 RESET holes, nothing happened. I kinda gave up on my keyboard at this point :S It's sad cuz I think it has so much potential.

@gleber
Copy link
Author

gleber commented Nov 27, 2024

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 the 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, which allows you to flash it.

@zundr
Copy link

zundr commented Nov 28, 2024

I was able to build your qmk firmware, thank you so much for writing it!
And it successfully flashed to the left split.

However, during the flashing the right split was connected through the TRSS cable (I missed that it was not supposed to...).
Now the right split does not work at all (not sure if this is the same that has happened to others above).
If I connect the right split directly to USB, my computer does not recognize any device.
I have tried all (known to me) methods to put in bootloader mode without success (pressing /, pressing I, shorting RESET pins, pressing all keys at once, ...).

Would you have any idea how to debrick it? Thanks!

@ejingles
Copy link

Apparently everyone is having the same issue. My right part is bricked too. @gleber Do you have any youtube channel? Is there any way that you can make a video on how to boot using the shorting reset pings method? We would be thankful for that! I've tried all methods too, even contacting the support. Believe or not, they told me to look into github for methods to solve it lol Either that or send back to china, what would cost prolly the same of buying a new keyboard. Thanks alot guys!

@AlejandroUPC
Copy link

got a .bin file for the seller as I am having a lot of problems to config using usevia, would it be to some help for me to share it? (was not told what it does or how to use it)

Copy link

ghost commented Dec 6, 2024

@ejingles @pragmaticgeek @zundr

I managed to fix it.

Since by USB it just couldn't communicate with my machine at all and just kept throwing the error: Unknown USB Device (Device Descriptor Request Failed) and shorting the PCB RESET pins did nothing, I had to buy one of those cheap ST-LINK V2 STLink CLONE (https://ibb.co/HCRhYmJ) to connect the keyboard to my pc, and use a 4 pin thingy (https://ibb.co/23JvCpj) I had laying around, because this PCB doesn't have embedded pins to make the connections we need.

Then after you have both things I mentioned above, follow these steps:

  1. Download, install and open this program: STM32CubeProgrammer (https://www.st.com/en/development-tools/stm32cubeprog.html)
  2. On the left of the green 'CONNECT' button, change the connection method to ST-LINK.
  3. Plug in the STLink to the computer, then connect the SWCLK; SWDIO; GND and 3v3 pins correctly into the PCB (use the 3v3 pin or a USB cable to power up the keyboard, not both)
  4. Click the refresh button on the right side of the "Serial number" tab.
  5. If properly connected, clicking 'CONNECT' should establish a connection with the keyboard.
  6. Click on the hamburguer button on the top left corner and go into "Erasing and programming"
  7. Download and select this file (https://github.com/rogerclarkmelbourne/STM32duino-bootloader/blob/master/binaries/maple_rev5_boot20.bin) on the "file path" box and set "Start address" to: 0x08000000 // There is a rev3 in the repo too if you want to try.
  8. Press "Start Programming". If it throws any error, try programming again or unchecking Verify/ Run after programming and retry.
  9. Click 'DISCONNECT' remove the STLink pins of the PCB, and plug in the keyboard via USB, if you go into Windows device manager or check the dmesg on Linux, plugging it now should make it be recognizable as "Maple or Maple 003"

So now if you follow the QMK steps on how to compile (https://docs.qmk.fm/newbs_building_firmware#build-your-firmware) then flash (https://docs.qmk.fm/newbs_flashing#flash-your-keyboard-from-the-command-line) using the QMK CLI tool, when you end up on the "Bootloader not found. Make sure the board is in bootloader mode." prompt, just removing and reconnecting the USB cable should trigger the bootloader and start flashing.

FIY:

  • The original source code of this keyboard is this one btw (https://drive.proton.me/urls/XXK8T7B9J4#7tKLU2BHvExv) or if you want the already compiled original binary (https://drive.proton.me/urls/Z3K71XWZGW#bzqW7FqwoGce)
  • For some reason the QMK toolbox is really inconsistent for me. Most of the times it just outputs "No DFU capable USB device available" then sometimes it just works, so I just stick to the CLI one that is more reliable.
  • I did not try to use the PCB RESET pins after flashing this bootloader, but it probably works like it should.

So, in the end of the day, I believe what happened was that the bootloader just died when we triggered to flash, and for some reason it affected the way the firmware should boot maybe? (don't quote me on that)

And the funny thing is, now if for some reason it errors when flashing the firmware binary, it just doesn't break like it did before. I can just replug and try flashing it again, the keyboard still works, the bootloader is still there, so yeah, confusing.

@RollMan
Copy link

RollMan commented Dec 15, 2024

I recovered the bootloader by a similar way by kyonav but I used nucleo and had to use the other binary generic_boot20_pc13.bin. Flashing maple_rev*_boot20.bin disables the nucleo st-link for a moment but updating the st-link firmware resolved it (perhaps the cause was something rather than the binary? but I don't wanna try it again). Nevertheless, the right one does not work as well.

@GreyTime
Copy link

@kyonav Thanks for the detailed tutorial. I bought the ST-Link and did the steps, but sadly the right side is not working (for the left side I didn't't even need to do the ST-Link process). It doesn't seem to go out of bootloader mode, and windows is giving me an error that it's corrupted or something. I tried a bunch of different bootloaders, but had luck unfortunately.

@zundr
Copy link

zundr commented Jan 2, 2025

@kyonav Thanks for the tutorial too! I had similar results than @GreyTime, in Linux in my case.

I am able to flash the bootloader with both STM32CubeProgrammer as well as with st-flash.
Once flashed through the ST-link v2, I disconnect and connect through the USB, and it is recognized as Maple (0x1eaf:0x0003).
In this state, dfu-util -l detects the device and recognizes 3 interfaces. However, when I try to flash QMK firmware (any .bin), it complains that it cannot set the alternate interface:

Opening DFU capable USB device...
Device ID 1eaf:0003
Device DFU version 0110
Claiming USB DFU Interface...
Setting Alternate Interface #2 ...
dfu-util: Cannot set alternate interface: LIBUSB_ERROR_OTHER
make[1]: *** [platforms/chibios/flash.mk:42: dfu-util] Error 74

I tried the maple_rev3, with similar results.
With the generic_boot20_pc13.bin firmware, the device was recognized as a USB modem, and dfu-util didn't detect it.

Then, I tried rebooting shorting the bootloader pins, and I got the "Unable to enumerate" error.

usb 1-2: new full-speed USB device number 83 using xhci_hcd
usb 1-2: Device not responding to setup address.
usb 1-2: Device not responding to setup address.
usb 1-2: device not accepting address 83, error -71
usb 1-2: WARN: invalid context state for evaluate context command.
usb usb1-port2: unable to enumerate USB device

Finally, I tried flashing the firmware directly with STM32CubeProgrammer and with st-flash, which completed successfully, but then produced the same "Unable to enumerate USB device". Shorting the pins, don't make a difference.

I think it's a bit striking than after flashing the maple bootloader and shorting the pins produces the same "bricked" state (while the pins are shorted), as than flashing the QMK firmware through ST-link.

@sietschie
Copy link

Just wanted to add my own datapoint: Flashing went well for me, nothing got bricked. Thanks for the effort of figuring everyting out.

@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