Peter Johanson
4 years ago
committed by
Pete Johanson
7 changed files with 214 additions and 64 deletions
@ -1,56 +0,0 @@ |
|||||||
--- |
|
||||||
title: Supported Hardware |
|
||||||
sidebar_label: Supported Hardware |
|
||||||
--- |
|
||||||
|
|
||||||
:::warning |
|
||||||
|
|
||||||
ZMK Firmware is still an early stage project. Many features are still waiting to be implemented, and only a select few keyboards |
|
||||||
have had their hardware details codified in boards/shields for ZMK. |
|
||||||
|
|
||||||
::: |
|
||||||
|
|
||||||
With the solid technical foundation of Zephyr™ RTOS, ZMK can support a wide diversity of hardware targets. |
|
||||||
That being said, there are currently only a few specific [boards](faq.md#what-is-a-board)/[shields](faq.md#what-is-a-shield) that have been written and tested by the ZMK contributors. |
|
||||||
|
|
||||||
## Boards |
|
||||||
|
|
||||||
- [nice!nano](https://nicekeyboards.com/nice-nano) (`nice_nano`, `nice_nano_v2`) |
|
||||||
- [nrfMicro](https://github.com/joric/nrfmicro) (`nrfmicro_13`, `nrfmicro_11`, `nrfmicro_11_flipped`) |
|
||||||
- [BlueMicro840](https://store.jpconstantineau.com/#/group/bluemicro) (`bluemicro840_v1`) |
|
||||||
- [QMK Proton-C](https://qmk.fm/proton-c/) (`proton_c`) |
|
||||||
- [BDN9 Rev2](https://keeb.io/products/bdn9-rev-2-3x3-9-key-macropad-rotary-encoder-and-rgb) (`bdn9_rev2`) |
|
||||||
|
|
||||||
## Keyboard Shields |
|
||||||
|
|
||||||
- [Kyria](https://splitkb.com/products/kyria-pcb-kit) (`kyria_left` and `kyria_right`) |
|
||||||
- [Corne](https://github.com/foostan/crkbd) (`corne_left` and `corne_right`) |
|
||||||
- [Helix](https://github.com/mcmadhatter/helix) (`helix_left` and `helix_right`) |
|
||||||
- [Lily58](https://github.com/kata0510/Lily58) (`lily58_left` and `lily58_right`) |
|
||||||
- [Sofle](https://github.com/josefadamcik/SofleKeyboard) (`sofle_left` and `sofle_right`) |
|
||||||
- [Splitreus62](https://github.com/Na-Cly/splitreus62) (`splitreus62_left` and `splitreus62_right`) |
|
||||||
- [Jorne](https://github.com/joric/jorne) (`jorne_left` and `jorne_right`) |
|
||||||
- [Jian](https://github.com/KGOH/Jian-Info) (`jian_left` and `jian_right`) |
|
||||||
- [Reviung41](https://github.com/gtips/reviung/tree/master/reviung41) (`reviung41`) |
|
||||||
- [RoMac+ v4](https://www.littlekeyboards.com/products/romac) (`romac_plus`) |
|
||||||
- [RoMac v2](https://mechboards.co.uk/shop/kits/romac-macro-pad/) (`romac`) |
|
||||||
- [Boardsource 3x4 Macro](https://boardsource.xyz/store/5ecc2008eee64242946c98c1) (`boardsource3x4`) |
|
||||||
- [QAZ](https://www.cbkbd.com/product/qaz-keyboard-kit) (`qaz`) |
|
||||||
- [CRBN](https://keygem.store/collections/group-buys/products/group-buy-featherlight-40-kit) (`crbn`) |
|
||||||
- [tidbit](https://nullbits.co/tidbit/) (`tidbit`) |
|
||||||
- [Eek!](https://www.cbkbd.com/product/eek-keyboard) (`eek`) |
|
||||||
- [BFO-9000](https://keeb.io/products/bfo-9000-keyboard-customizable-full-size-split-ortholinear) (`bfo9000_left` and `bfo9000_right`) |
|
||||||
|
|
||||||
## Other Hardware |
|
||||||
|
|
||||||
In addition to the basic keyboard functionality, there is some initial support for additional keyboard hardware: |
|
||||||
|
|
||||||
- Encoders |
|
||||||
- OLEDs |
|
||||||
- RGB Underglow |
|
||||||
|
|
||||||
Until detailed documentation is available, feel free to ask questions about how these are supported in the [Discord server](https://zmk.dev/community/discord/invite). |
|
||||||
|
|
||||||
## Contributing |
|
||||||
|
|
||||||
If you'd like to add support for a new keyboard shield, head over to the [New Keyboard Shield](development/new-shield.md) documentation. |
|
@ -0,0 +1,26 @@ |
|||||||
|
--- |
||||||
|
title: Supported Hardware |
||||||
|
sidebar_label: Supported Hardware |
||||||
|
--- |
||||||
|
|
||||||
|
import HardwareList from "@site/src/components/hardware-list"; |
||||||
|
import Metadata from "@site/src/data/hardware-metadata.json"; |
||||||
|
|
||||||
|
With the solid technical foundation of Zephyr™ RTOS, ZMK can support a wide diversity of hardware targets. |
||||||
|
That being said, there are currently only a few specific [boards](/docs/faq#what-is-a-board)/[shields](faq.md#what-is-a-shield) that have been implemented and tested by the ZMK contributors. |
||||||
|
|
||||||
|
<HardwareList items={Metadata} /> |
||||||
|
|
||||||
|
## Other Hardware |
||||||
|
|
||||||
|
In addition to the basic keyboard functionality, there is some initial support for additional keyboard hardware: |
||||||
|
|
||||||
|
- Encoders |
||||||
|
- Displays |
||||||
|
- RGB Underglow |
||||||
|
|
||||||
|
Until detailed documentation is available, feel free to ask questions about how these are supported in the [Discord server](https://zmk.dev/community/discord/invite). |
||||||
|
|
||||||
|
## Contributing |
||||||
|
|
||||||
|
If you'd like to add support for a new keyboard shield, head over to the [New Keyboard Shield](development/new-shield.md) documentation. |
@ -0,0 +1,176 @@ |
|||||||
|
import React from "react"; |
||||||
|
|
||||||
|
import { |
||||||
|
Board, |
||||||
|
HardwareMetadata, |
||||||
|
Interconnect, |
||||||
|
Shield, |
||||||
|
} from "../hardware-metadata"; |
||||||
|
|
||||||
|
interface HardwareListProps { |
||||||
|
items: HardwareMetadata[]; |
||||||
|
} |
||||||
|
|
||||||
|
type ElementOrString = JSX.Element | string; |
||||||
|
|
||||||
|
function itemHasMultiple(item: HardwareMetadata) { |
||||||
|
return ( |
||||||
|
(item.type == "board" || item.type == "shield") && |
||||||
|
(item.siblings?.length ?? 1) > 1 |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
function itemIds(item: HardwareMetadata) { |
||||||
|
if (item.type == "board" || item.type == "shield") { |
||||||
|
let nodes = (item.siblings ?? [item.id]) |
||||||
|
.map<ElementOrString>((id) => <code key={id}>{id}</code>) |
||||||
|
.reduce( |
||||||
|
(prev, curr, index) => [...prev, index > 0 ? ", " : "", curr], |
||||||
|
[] as ElementOrString[] |
||||||
|
); |
||||||
|
return <span key={item.id}>{nodes}</span>; |
||||||
|
} else { |
||||||
|
return <code key={item.id}>{item.id}</code>; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const TYPE_LABELS: Record< |
||||||
|
HardwareMetadata["type"], |
||||||
|
Record<"singular" | "plural", string> |
||||||
|
> = { |
||||||
|
board: { plural: "Boards: ", singular: "Board: " }, |
||||||
|
shield: { singular: "Shield: ", plural: "Shields: " }, |
||||||
|
interconnect: { singular: "Interconnect: ", plural: "Interconnects: " }, |
||||||
|
}; |
||||||
|
|
||||||
|
function HardwareLineItem({ item }: { item: HardwareMetadata }) { |
||||||
|
return ( |
||||||
|
<li> |
||||||
|
<a href={item.url}>{item.name}</a> ( |
||||||
|
{TYPE_LABELS[item.type][itemHasMultiple(item) ? "plural" : "singular"]}{" "} |
||||||
|
{itemIds(item)}) |
||||||
|
</li> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
interface InterconnectDetails { |
||||||
|
interconnect?: Interconnect; |
||||||
|
boards: Board[]; |
||||||
|
shields: Shield[]; |
||||||
|
} |
||||||
|
|
||||||
|
function mapInterconnect({ |
||||||
|
interconnect, |
||||||
|
boards, |
||||||
|
shields, |
||||||
|
}: InterconnectDetails) { |
||||||
|
if (!interconnect) { |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
return ( |
||||||
|
<div key={interconnect.id}> |
||||||
|
<h4>{interconnect.name} Keyboards</h4> |
||||||
|
{interconnect.description && <p>{interconnect.description}</p>} |
||||||
|
<h5>Boards</h5> |
||||||
|
<ul> |
||||||
|
{boards.map((s) => ( |
||||||
|
<HardwareLineItem key={s.id} item={s} /> |
||||||
|
))} |
||||||
|
</ul> |
||||||
|
<h5>Shields</h5> |
||||||
|
<ul> |
||||||
|
{shields.map((s) => ( |
||||||
|
<HardwareLineItem key={s.id} item={s} /> |
||||||
|
))} |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
interface GroupedMetadata { |
||||||
|
onboard: Board[]; |
||||||
|
interconnects: Record<string, InterconnectDetails>; |
||||||
|
} |
||||||
|
|
||||||
|
function groupedBoard(agg: GroupedMetadata, board: Board) { |
||||||
|
if (board.features?.includes("keys")) { |
||||||
|
agg.onboard.push(board); |
||||||
|
} else if (board.exposes) { |
||||||
|
board.exposes.forEach((element) => { |
||||||
|
let ic = agg.interconnects[element] ?? { |
||||||
|
boards: [], |
||||||
|
shields: [], |
||||||
|
}; |
||||||
|
ic.boards.push(board); |
||||||
|
agg.interconnects[element] = ic; |
||||||
|
}); |
||||||
|
} else { |
||||||
|
console.error("Board without keys or interconnect"); |
||||||
|
} |
||||||
|
|
||||||
|
return agg; |
||||||
|
} |
||||||
|
|
||||||
|
function groupedShield(agg: GroupedMetadata, shield: Shield) { |
||||||
|
shield.requires.forEach((id) => { |
||||||
|
let ic = agg.interconnects[id] ?? { boards: [], shields: [] }; |
||||||
|
ic.shields.push(shield); |
||||||
|
agg.interconnects[id] = ic; |
||||||
|
}); |
||||||
|
|
||||||
|
return agg; |
||||||
|
} |
||||||
|
|
||||||
|
function groupedInterconnect(agg: GroupedMetadata, item: Interconnect) { |
||||||
|
let ic = agg.interconnects[item.id] ?? { boards: [], shields: [] }; |
||||||
|
ic.interconnect = item; |
||||||
|
agg.interconnects[item.id] = ic; |
||||||
|
|
||||||
|
return agg; |
||||||
|
} |
||||||
|
|
||||||
|
function HardwareList({ items }: HardwareListProps) { |
||||||
|
let grouped = items.reduce<GroupedMetadata>( |
||||||
|
(agg, hm) => { |
||||||
|
switch (hm.type) { |
||||||
|
case "board": |
||||||
|
return groupedBoard(agg, hm); |
||||||
|
case "shield": |
||||||
|
return groupedShield(agg, hm); |
||||||
|
case "interconnect": |
||||||
|
return groupedInterconnect(agg, hm); |
||||||
|
} |
||||||
|
}, |
||||||
|
{ onboard: [] as Board[], interconnects: {} } |
||||||
|
); |
||||||
|
|
||||||
|
return ( |
||||||
|
<> |
||||||
|
<h2>Keyboards</h2> |
||||||
|
<h3>Onboard Controller Boards</h3> |
||||||
|
<p> |
||||||
|
Keyboards with onboard controllers are single PCBs that contain all the |
||||||
|
components of a keyboard, including the controller chip, switch |
||||||
|
footprints, etc. |
||||||
|
</p> |
||||||
|
<ul> |
||||||
|
{grouped["onboard"] |
||||||
|
.sort((a, b) => a.name.localeCompare(b.name)) |
||||||
|
.map((s) => ( |
||||||
|
<HardwareLineItem key={s.id} item={s} /> |
||||||
|
))} |
||||||
|
</ul> |
||||||
|
<h3>Composite Boards</h3> |
||||||
|
<p> |
||||||
|
Composite keyboards are composed of two main PCBs: a small controller |
||||||
|
board with exposed pads, and a larger keyboard PCB (a shield, in ZMK |
||||||
|
lingo) with switch footprints and location a where the controller is |
||||||
|
added. |
||||||
|
</p> |
||||||
|
{Object.values(grouped.interconnects).map(mapInterconnect)} |
||||||
|
</> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export default HardwareList; |
Loading…
Reference in new issue