Experimenting with a RISC-V controller
-
- Location: US
- Main keyboard: Omnikey 102 Blackheart
- Main mouse: Kensington Expert Mouse
- Favorite switch: White Alps
- DT Pro Member: 0174
I feel like I'm a bit of an anomaly in the "modern" mechanical keyboard scene. When most people are building 40%, 30%, single switch boards, I've latched on to a 130% layout and keep dragging it through revision after revision. It features an incredibly naive matrix design that's 23 rows x 7 columns (so that software wise, each row can just be a straight listing of all keys included). Add LEDs, an encoder, and an OLED, and you're looking at 37 GPIOs to cover the board.
The problem is that the "go-to" controller for a large keyboard is the Teensy++. It's expensive at best, and now it's discontinued, so supplies are running thin, even of "questionable" likely bootleg ones. A lot of the new-generation of ARM boards (i. e. the common STM32F103 boards and the Raspberry Pi Pico) don't have enough GPIOs, and many of the ones that do have enough are pretty spendy.
So I've got a growing stack of PCBs that, should I decide to populate, will be difficult to source a controller for. I could redesign the PCBs to use a soldered-on AT90USB1286, but even those are hard to source at times, and I hate SMD soldering.
I recently found what looks to be a "dream" controller: the WCH CH32V305RBT6, in the form of Muse Lab's "nanoCH32V305" breakout board. The board offers 42 GPIOs, all of which are exposed on the outer edge of the board and only one of which is encumbered (onboard LED), a USB-C connector, and can be programmed without a special cable/tool. It's also six US dollars (or about 11 by the time postage from China is considered), so significantly cheaper than the Teensy++. I'm also a fan of WCH's generally zany product line; I spent a lot of last year on a hobby project using their CH375/376 "USB disc to random 8-bit bus" part.
So I had two problems. First, while the pinout is convenient for a scratch build, it's useless for an existing PCB, and I wanted to at least proof-of-concept it as capable of driving a full 130% board. Once I had gotten it working with a hard-wired 5x4 macro pad from my parts box, I prepared an "interposer" PCB: you attach pins on the bottom in a layout the size and shape of a Teensy++, which are in turn wired to holes you route to the nanoCH32V305. This was the smaller problem; throw $10 at JLCPCB and you've got more of them than you'll ever need. I was able to wire up one of my existing PCBs, and it worked with the same bodges you have to apply to the Teensy++.
The bigger problem is firmware. It's a RISC-V CPU, and I suspect a QMK or similar port is very far off. Entertainingly, there was a basic "sample HID device" package in the SDK. This provided support for wiring four pushbuttons to act as W/A/S/D and four more to simulate moving the mouse. I've spent the last two months iterating on it, and have been able to build out a modestly functional firmware from this start.
https://gitlab.com/hakfoo1/ch32v-keyboard
It's still probably delicate in a lot of ways, and could probably be refined further-- I'm not sure I've got debouncing perfectly dialed in, and it doesn't fail gracefully in every possible scenario. (I had some issues with the board going unresponsive after rebooting between operating systems that I'm not sure are resolved) but it's becoming a fairly usable proof of concept.
The problem is that the "go-to" controller for a large keyboard is the Teensy++. It's expensive at best, and now it's discontinued, so supplies are running thin, even of "questionable" likely bootleg ones. A lot of the new-generation of ARM boards (i. e. the common STM32F103 boards and the Raspberry Pi Pico) don't have enough GPIOs, and many of the ones that do have enough are pretty spendy.
So I've got a growing stack of PCBs that, should I decide to populate, will be difficult to source a controller for. I could redesign the PCBs to use a soldered-on AT90USB1286, but even those are hard to source at times, and I hate SMD soldering.
I recently found what looks to be a "dream" controller: the WCH CH32V305RBT6, in the form of Muse Lab's "nanoCH32V305" breakout board. The board offers 42 GPIOs, all of which are exposed on the outer edge of the board and only one of which is encumbered (onboard LED), a USB-C connector, and can be programmed without a special cable/tool. It's also six US dollars (or about 11 by the time postage from China is considered), so significantly cheaper than the Teensy++. I'm also a fan of WCH's generally zany product line; I spent a lot of last year on a hobby project using their CH375/376 "USB disc to random 8-bit bus" part.
So I had two problems. First, while the pinout is convenient for a scratch build, it's useless for an existing PCB, and I wanted to at least proof-of-concept it as capable of driving a full 130% board. Once I had gotten it working with a hard-wired 5x4 macro pad from my parts box, I prepared an "interposer" PCB: you attach pins on the bottom in a layout the size and shape of a Teensy++, which are in turn wired to holes you route to the nanoCH32V305. This was the smaller problem; throw $10 at JLCPCB and you've got more of them than you'll ever need. I was able to wire up one of my existing PCBs, and it worked with the same bodges you have to apply to the Teensy++.
The bigger problem is firmware. It's a RISC-V CPU, and I suspect a QMK or similar port is very far off. Entertainingly, there was a basic "sample HID device" package in the SDK. This provided support for wiring four pushbuttons to act as W/A/S/D and four more to simulate moving the mouse. I've spent the last two months iterating on it, and have been able to build out a modestly functional firmware from this start.
https://gitlab.com/hakfoo1/ch32v-keyboard
It's still probably delicate in a lot of ways, and could probably be refined further-- I'm not sure I've got debouncing perfectly dialed in, and it doesn't fail gracefully in every possible scenario. (I had some issues with the board going unresponsive after rebooting between operating systems that I'm not sure are resolved) but it's becoming a fairly usable proof of concept.
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Quite a beast of a Teensy++ successor!
https://github.com/wuxx/nanoCH32V305
Personally, I’d like a break out for the USB pins so you can attach your own socket without having to bend an awkward USB C cable through the tight internal confines of your case and PCB geometry. Often, the hardest part of a controller replacement for an existing keyboard is the damn USB cable to the new controller! Mind, the rest is easy because other people have made the firmware.
https://github.com/wuxx/nanoCH32V305
Personally, I’d like a break out for the USB pins so you can attach your own socket without having to bend an awkward USB C cable through the tight internal confines of your case and PCB geometry. Often, the hardest part of a controller replacement for an existing keyboard is the damn USB cable to the new controller! Mind, the rest is easy because other people have made the firmware.
- Scarpia
- Location: Sweden
- Main keyboard: F77 / Alps SKCM Brown TKL
- Main mouse: Logitech MX Anywhere 2
- Favorite switch: Capacitive BS, Alps SKCM Brown
- DT Pro Member: 0223
So cool! I’ll be following this even if I don’t have a need for that many GPIOs in anything I’m currently building or imagining.
-
- Location: US
- Main keyboard: Omnikey 102 Blackheart
- Main mouse: Kensington Expert Mouse
- Favorite switch: White Alps
- DT Pro Member: 0174
I figure by the time you're ready for ythat level of control, you can probably design the microcontroller straight onto the PCB.Muirium wrote: ↑22 Feb 2023, 10:41Personally, I’d like a break out for the USB pins so you can attach your own socket without having to bend an awkward USB C cable through the tight internal confines of your case and PCB geometry. Often, the hardest part of a controller replacement for an existing keyboard is the damn USB cable to the new controller! Mind, the rest is easy because other people have made the firmware.
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Maybe I should consider making my own "µController," now you mention it. A little custom PCB with the controller chip and all the right breakouts. Tiny in just the right dimensions, yet broken out for keyboard centric access. So long as it runs QMK so I don’t have to do all that work, too!
-
- Location: US
- Main keyboard: Omnikey 102 Blackheart
- Main mouse: Kensington Expert Mouse
- Favorite switch: White Alps
- DT Pro Member: 0174
It feels like for small keyboards, there ended up being a fair number of different controllers that had a Pro Micro analogous pinout. There was never a standard for larger ones. I suppose you could basically design a CH32V305 breakout with a "native" Teensy++ style pinout, but that's more surface-mount work than I want to touch, and I'm not sure if the package actually fits.
- Muirium
- µ
- Location: Edinburgh, Scotland
- Main keyboard: HHKB Type-S with Bluetooth by Hasu
- Main mouse: Apple Magic Mouse
- Favorite switch: Gotta Try 'Em All
- DT Pro Member: µ
Well I’m thinking about drop-in controller replacements for existing vintage keyboards, too. The Teensy++ is a 1:1 match for that near ubiquitous Intel chip in so many ~1980s keyboards. I’ve installed a few for that purpose—running Soarer’s controller, with any necessary hardwired pins jumped by hand—and it works pretty nicely, save for the mighty “mini” USB socket.
I’m less interested in the package than I am the pins, frankly. Keyboard matrices are as low end as it gets. We don’t need rocket science, we need pins and breakouts!
I’m less interested in the package than I am the pins, frankly. Keyboard matrices are as low end as it gets. We don’t need rocket science, we need pins and breakouts!
-
- Location: US
- Main keyboard: Omnikey 102 Blackheart
- Main mouse: Kensington Expert Mouse
- Favorite switch: White Alps
- DT Pro Member: 0174
Spending two minutes playing with footprints in EasyEDA shows it might be doable, but a tight fit. Basically, the footprint for the MCU is large enough that pins extend to the Teensy++ pin footprints.
Possibility 1: Modify the footprint with shorter leads. Not sure if this actually reflects actual size of the part though, there may not be enough space to play with.
Possibility 2: Accept the conflict, likely four pins will contact if you rotate 45 degrees. You're stuck with those pins being specifically mapped to those Teensy++ pins. This may not pass any sort of automated DRC, and then you probably have risks of desoldering or fouling those pins on the MCU when you try to solder those pins.
Possibility 3: Continue to riff on the two-PCB interposer idea-- one PCB just holds the compatibility pins, and is large enough to support sockets "beyond" the Teensy++ footprint, and the other is large enough to hold the replacement MCU with easy routing. I made my original compatibility-pin board stupidly, adding like 2cm of pointless "panniers" with labels indicating pin mapping so it would be easier to understand, but which dramatically increase clearance requirements. This should be a document instead, and doing so reduces the needed footprint. You also have way more options for the "second PCB"-- I was just trying to use the canned nanoCH32V305 product there, but you could design it with, say, pins on 3 or four sides, or double banks of pins, to reduce its overall size.
Possibility 1: Modify the footprint with shorter leads. Not sure if this actually reflects actual size of the part though, there may not be enough space to play with.
Possibility 2: Accept the conflict, likely four pins will contact if you rotate 45 degrees. You're stuck with those pins being specifically mapped to those Teensy++ pins. This may not pass any sort of automated DRC, and then you probably have risks of desoldering or fouling those pins on the MCU when you try to solder those pins.
Possibility 3: Continue to riff on the two-PCB interposer idea-- one PCB just holds the compatibility pins, and is large enough to support sockets "beyond" the Teensy++ footprint, and the other is large enough to hold the replacement MCU with easy routing. I made my original compatibility-pin board stupidly, adding like 2cm of pointless "panniers" with labels indicating pin mapping so it would be easier to understand, but which dramatically increase clearance requirements. This should be a document instead, and doing so reduces the needed footprint. You also have way more options for the "second PCB"-- I was just trying to use the canned nanoCH32V305 product there, but you could design it with, say, pins on 3 or four sides, or double banks of pins, to reduce its overall size.
- Scarpia
- Location: Sweden
- Main keyboard: F77 / Alps SKCM Brown TKL
- Main mouse: Logitech MX Anywhere 2
- Favorite switch: Capacitive BS, Alps SKCM Brown
- DT Pro Member: 0223
If you rotate the MCU back instead of rotating it 45 degrees then it looks like it might just fit. It’ll require some clever routing, but maybe?
- BorutP
- Location: Slovenia
-
- Location: Romania
You can also try Sparkfun-style staggered pins.
It doesn't necessarily have to be every odd pin moved in one direction and every even pin moved in the opposite.
You could have every pin in the middle where it meets the chip moved outwards, and then have the remaining pins alternating. I've done this with a TQFP44 package (atmega32u4), which has the same size, just bigger pin pitch with fewer pins, and it worked out fine: In fact I could have moved the holes a little bit more, cause this staggering still wasn't holding the pin headers tight, but it did restrict their freedom of movement.
You could also look into some QFN chips. For example CH32V208WBU6, which is 8x8mm, but this will be harder to route because of the thermal pad underneath.
It doesn't necessarily have to be every odd pin moved in one direction and every even pin moved in the opposite.
You could have every pin in the middle where it meets the chip moved outwards, and then have the remaining pins alternating. I've done this with a TQFP44 package (atmega32u4), which has the same size, just bigger pin pitch with fewer pins, and it worked out fine: In fact I could have moved the holes a little bit more, cause this staggering still wasn't holding the pin headers tight, but it did restrict their freedom of movement.
You could also look into some QFN chips. For example CH32V208WBU6, which is 8x8mm, but this will be harder to route because of the thermal pad underneath.
-
- Location: Stockholm, Sweden
- DT Pro Member: 0011
I superimposed the controller from the pic of the nanoCH32V305 board onto a pic of the Teensy++.
I cut out the controller from the pins of the controller: not the solder pads/footprint, so you'd have to imagine there being longer solder pads in places where appropriate, and shorter when not.
(the arrangement in the middle is kind'a useless though, I'd admit)
The pinout of the package is important.
If you'd place it diagonally, then the pins in the corners that intersect the board-pins solder pads there would need to be GPIO pins.
If you'd place it horizontally then there can't be any pins on the top and bottom sides that would need to be connected to any decoupling capacitors - because you can't place any there!
I cut out the controller from the pins of the controller: not the solder pads/footprint, so you'd have to imagine there being longer solder pads in places where appropriate, and shorter when not.
(the arrangement in the middle is kind'a useless though, I'd admit)
The pinout of the package is important.
If you'd place it diagonally, then the pins in the corners that intersect the board-pins solder pads there would need to be GPIO pins.
If you'd place it horizontally then there can't be any pins on the top and bottom sides that would need to be connected to any decoupling capacitors - because you can't place any there!
- DMA
- Location: Seattle, US
- Main keyboard: T420
- Main mouse: Trackpoint
- Favorite switch: beamspring
- DT Pro Member: NaN
- Contact:
you can easily get from 23x7 to 12x14 (if that), saving 5 GPIOs right there without sacrificing much of software simplicity.
I don't get the purpose of the interposer board tho - you don't have enough GPIOs in that form-factor, why?
I don't get the purpose of the interposer board tho - you don't have enough GPIOs in that form-factor, why?
-
- Location: US
- Main keyboard: Omnikey 102 Blackheart
- Main mouse: Kensington Expert Mouse
- Favorite switch: White Alps
- DT Pro Member: 0174
The purpose was "I had spare PCBs that were designed for a Teensy++". By mounting the nanoCH32V305 to the interposer, I can mount to a board I already have handy.
This let me prove that 1) yes, enough GPIOs work to drive a full 130% board and 2) work out some of the software and scanning weirdness that wasn't obvious on a 4x5 macropad but becomes obvious when you start to type on it at full speed and populate a huge matrix before fully redesigning the PCB to take the new controller ($$)
This let me prove that 1) yes, enough GPIOs work to drive a full 130% board and 2) work out some of the software and scanning weirdness that wasn't obvious on a 4x5 macropad but becomes obvious when you start to type on it at full speed and populate a huge matrix before fully redesigning the PCB to take the new controller ($$)
- ifohancroft
- Location: Sofia, Bulgaria
- Main keyboard: ErgoDox w/ SA Carbon on Box Jades
- Main mouse: Razer Viper Ultimate
- Favorite switch: Beamspring
- DT Pro Member: -
- Contact:
What layout is a 130% keyboard btw?
-
- Location: Stockholm, Sweden
- DT Pro Member: 0011
Here's Hak Foo's previous 129-key creation: Overton130: Because More is More (Geekhack).
- ifohancroft
- Location: Sofia, Bulgaria
- Main keyboard: ErgoDox w/ SA Carbon on Box Jades
- Main mouse: Razer Viper Ultimate
- Favorite switch: Beamspring
- DT Pro Member: -
- Contact:
Thank you!