# ACID firmware

## Building

### Compiling libxkbcommon

Before compiling the firmware itself, its C dependencies must be compiled separately first.
This needs to be done on Linux or in WSL.
Download and install [`eim`, the ESP-IDF Installation Manager](github.com/espressif/idf-im-ui/releases/latest).
Enable the ESP-IDF using:

```sh
eim select
```

Compile the libxkbcommon library.

```sh
./libxkbcommon-compile.sh build
```

### Compiling the firmware

To compile the firmware, run:
```ps1
cargo build --release
```

If you wish to download the firmware on the keyboard, the following command can be used:
```ps1
cargo run --release -- --port=[PORT]
```
where `[PORT]` shall be replaced by a serial port such as `COM5`.

## Building for development

The following arguments are useful to build the libxkbcommon library for debugging.
```sh
./libxkbcommon-compile.sh build-debug --buildtype=debug -Dc_args="-fdebug-prefix-map=@GLOBAL_SOURCE_ROOT@=[PATH_TO_LIBRARY_ON_WINDOWS]"
```
where `[PATH_TO_LIBRARY_ON_WINDOWS]` is the path to the libxkbcommon submodule on Windows.
This replaces the debugging symbols with paths that will be available when debugging on Windows.

Then compile the firmware with:
```ps1
$env:XKBCOMMON_BUILD_DIR="libxkbcommon/build-debug"; cargo build
```

## Debugging via alternative UART pins

Connect your serial debugger's TX to GPIO5 and its RX to GPIO12.
On Linux, listen to the serial stream using:

```sh
tio -m INLCRNL /dev/ttyUSB1
```

On Windows, use PuTTY with a baudrate of 115200.

### Creating keymaps

To generate an English (US) keymap, the following command may be used:

`xkbcli compile-keymap --include [path-to-xkb-directory] --layout us >my_keymap.xkb`

Substitute `us` for any other 2-letter country code.

Where the `[path-to-xkb-directory]` is one of the following:
  * the `/usr/share/X11/xkb` directory on X11-based Linux distributions;
  * the [`xkeyboard-config` git repository](https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config). There's an button to download it as a ZIP archive.

The most relevant part of the keymap is likely found in the `symbols` directory,
where variants of keymaps are defined for many languages.

### Compiling Compose files

Use libxkbcommon's `xkbcli` to compile a standalone compose file:

`xkbcli compile-compose [path-to-Compose-file] >my_compose.txt`

Compose files to replace `[path-to-Compose-file]` with may be found in:
  * the `/usr/share/X11/locale` directory on X11-based Linux distributions;
  * the [`libx11` git repository](https://gitlab.freedesktop.org/xorg/lib/libx11/-/tree/master/nls). There's a button to download it as a ZIP archive.

### Setup in GNOME

#### Making all xkb layouts available

By default, GNOME displays only the most common keyboard layouts (`xkb_symbols`). Other keyboard layouts can be made visible via:
```sh
gsettings set org.gnome.desktop.input-sources show-all-sources true
```

In order to use completely custom layouts, [this article](https://web.archive.org/web/20260212010717/https://staticf0x.github.io/2021/custom-keyboard-layout-in-x11-and-wayland.html) may be helpful.

# esp32s3 BLE example

To run this example, you should have latest Rust in **esp** channel installed. The full instruction of installing esp Rust toolchain can be found [here](https://docs.esp-rs.org/book/installation/index.html).

[`espflash`](https://github.com/esp-rs/espflash) should also be installed:

```
cargo install cargo-espflash espflash
```

After having everything installed, use the following command to run the example:

```
cd examples/use_rust/esp32s3_ble
cargo +esp run --release
```

If everything is good, you'll see the log as the following:

```shell
cargo run --release
    Compiling ...
    ...
    ...
    Finished `release` profile [optimized + debuginfo] target(s) in 11.70s
     Running `espflash flash --monitor --port /dev/cu.usbmodem211401 target/xtensa-esp32s3-none-elf/release/rmk-esp32s3`
[2025-04-10T10:01:23Z INFO ] Serial port: '/dev/cu.usbmodem211401'
[2025-04-10T10:01:23Z INFO ] Connecting...
[2025-04-10T10:01:23Z INFO ] Using flash stub
Chip type:         esp32s3 (revision v0.1)
Crystal frequency: 40 MHz
Flash size:        4MB
Features:          WiFi 6, BT 5
MAC address:       40:4c:ca:5b:c7:dc
App/part. size:    768,944/4,128,768 bytes, 18.62%
[2025-04-10T10:01:23Z INFO ] Segment at address '0x0' has not changed, skipping write
[2025-04-10T10:01:23Z INFO ] Segment at address '0x8000' has not changed, skipping write
[00:00:06] [========================================]     411/411     0x10000                                                                                             [2025-04-10T10:01:31Z INFO ] Flashing has completed!
```

If espflash reports the following error:

```
Error: espflash::connection_failed

  × Error while connecting to device
  ╰─▶ Serial port not found
```

You should to identify which serial port are connected to your esp board, and use `--port` to specify the used serial port:

```
# Suppose that the esp board are connected to /dev/cu.usbmodem211401
cargo run --release -- --port /dev/cu.usbmodem211401
```

If you want to get some insight of segments of your binary, [`espsegs`](https://github.com/bjoernQ/espsegs) would help:

```
# Install it first
cargo install --git https://github.com/bjoernQ/espsegs

# Check all segments
espsegs target/xtensa-esp32s3-none-elf/release/rmk-esp32s3 --chip esp32s3
```
