My Journey into the World of DIY Mechanical Keyboards
I recently fell into the rabbit hole of DIY mechanical keyboards. It all started when I began experiencing pain in my hands, prompting me to search for ergonomic keyboards. That’s when I discovered the ZSA Moonlander Mark 1. However, its high price led me to explore cheaper alternatives, and I stumbled upon the fascinating world of DIY keyboards. After considering options like the Lily58 Pro, Corne, and Ferris, I ultimately chose the 34-key Sweep keyboard.
Most build examples I found online used the nice!nano v2. In an effort to save money, I opted for a compatible clone from AliExpress, the Super Mini NRF52840. Unfortunately, it didn’t come with the nice!nano bootloader and had Access Port Protection (APP) enabled, resulting in the error message: Error: Could not find MEM-AP to control the core
when attempting to write into memory.
TL;DR
To solve this issue, use the following commands:
openocd -f interface/raspberrypi-native.cfg -f target/nrf52.cfg -c "gdb_flash_program enable" -c "gdb_breakpoint_override hard" -c "init" -c "reset halt" -c "nrf52_recover"
or
openocd -f interface/raspberrypi-native.cfg -f target/nrf52.cfg -c "gdb_flash_program enable"
And in another shell:
telnet localhost 4444
nrf52.dap apreg 0x04 0x01
Configuration for interface/raspberrypi-native.cfg
With the follwing interface/raspberrypi-native.cfg
:
# SPDX-License-Identifier: GPL-2.0-or-later
adapter driver bcm2835gpio
bcm2835gpio peripheral_base 0x20000000
bcm2835gpio speed_coeffs 113714 28
transport select swd
# Each of the SWD lines need a gpio number set: swclk swdio
# Header pin numbers: 23 22
adapter gpio swclk -chip 0 11
adapter gpio swdio -chip 0 25
# If you define trst or srst, use appropriate reset_config
# Header pin numbers: TRST - 26, SRST - 18
# adapter gpio trst -chip 0 7
# reset_config trst_only
adapter gpio srst -chip 0 24
reset_config srst_only srst_push_pull
# or if you have both connected,
# reset_config trst_and_srst srst_push_pull
Raspberry Pi OpenOCD installation
I installed Raspberry Pi OS using Raspberry Pi Imager, configured it, and connected via SSH. To install OpenOCD on it, I executed the following commands:
cd ~
sudo apt-get update
sudo apt-get install git autoconf libtool make pkg-config libusb-1.0-0 libusb-1.0-0-dev
git clone http://openocd.zylin.com/openocd
cd openocd
./bootstrap
./configure --enable-sysfsgpio --enable-bcm2835gpio
make
sudo make install
Connections
I soldered the back SWCLK and SWDIO to GPIO 11 and 25, respectively, connected a GND, and the NRF board reset pin to GPIO 24, as shown in the figure below.
Understanding Access Port Protection
The CTRL-AP (Control Access Port) allows control of the device even if other access ports are disabled by access port protection. If APP is enabled in the APPROTECT register (0x10001208) of the UICR, debugger access to CPU registers and memory is blocked.
To check the APPROTECTSTATUS register (0x00C) of the CTRL-AP, execute the following in OpenOCD:
nrf52.dap apreg 1 0x0c
- If the least significant bit is ‘0’, access port protection is enabled.
- If the least significant bit is ‘1’, access port protection is not enabled. Proceed to halt the CPU.
To unlock a device with APP enabled, issue an ERASEALL command through the CTRL-AP, followed by a reset. This erases the entire code flash, UICR area, and RAM. Perform this with:
openocd -f interface/raspberrypi-native.cfg -f target/nrf52.cfg -c "gdb_flash_program enable" -c "gdb_breakpoint_override hard" -c "init" -c "reset halt" -c "nrf52_recover"
or
openocd -f interface/raspberrypi-native.cfg -f target/nrf52.cfg -c "gdb_flash_program enable"
And in another shell:
telnet localhost 4444
nrf52.dap apreg 0x04 0x01
Re-reading the APPROTECTSTATUS register (0x00C) should now return 1. After unlocking, I flashed the bootloader and began training my muscle memory to use this new layout. I’m already using the new keyboard as I write this post! 😂
The command that I used to flash the bootloader, was:
$ openocd -f interface/raspberrypi-native.cfg -f target/nrf52.cfg -c "gdb_flash_program enable" -c "gdb_breakpoint_override hard" -c "init" -c "reset halt" -c "flash write_image erase ./nice_nano_bootloader-0.6.0_s140_6.1.1.hex"
References
- Raspberry Pi and OpenOCD – Lean2
- Nordic Semiconductor Infocenter
- Removing flash protection from the nRF52 using JLink + OpenOCD
- Troubleshooting - nice!nano
I hope this helps someone save time figuring it all out. Feel free to ask if you need further assistance! See you in the next post!
jmmb