Home

Awesome

<div align="center"> <img src="assets/images/icon_square.png" width="120" height="120"> </div> <br> <div align="center"> <h1>NyanOS 🐱 (NOS) - A Fast Keyboard Firmware</h1> </div>

Nyan Keys Keyboard Firmware

STM32F723 Firmware for the Nyan Keys keyboard. This architecture places the highest priority on performance, latency, and reliability.

Supported Hardware

Keyboard PCBs

PCBDescription
NyanKeys ProtoNyan Keys Prototype 0
NyanKeys 60Nyan Keys Production

Please make a PR if you decide to use NyanOS for your keyboard PCB

MCUs

MCUDescription
STM32F723xxSTM32 F7 w/ USB2.0 HS PHY

Responsibilities

NyanOS Terminal

One of the nicer features of NyanOS is a fully functional USB-CDC (serial) interface to interact with NyanOSk. Currently functionality is limited to only the most necessary commands for keyboard operation and configuration.

FPGA Bitstream Loading

The NyanOS out of the box should support any Lattice Ice40HX FPGAs that are also supported by IceStorm. For a complete hardware support list visit. https://clifford.at/icestorm The flow for synthesizing, placing, and routing is outlined below

  1. yosys <args>
  2. nextpnr <args>
  3. icepack <bitstream.asc> <bitstream.bin
  4. icecompr.py < bitstream.bin > bitstream_compr.bin

The icecompr tool is utilized to compress the bitstream, typically achieving a final ratio of approximately 25-30%. This compression allows an Ice40HX4K bitstream to fit on a 1Mbit I2C EEPROM. Without compression, the bitstream would occupy 131070 bytes, exceeding the capacity of the I2C EEPROM.

In NyanOS, the FPGA is treated as an SPI slave. The system manages all dummy bits both before (8 bits) and after (47 bits) the bitstream programming. NyanOS sends 48 dummy bits to the slave, as 47 is not divisible by 8, and thus it rounds up.

The FPGA bitstream programming in NyanOS occurs at startup and typically takes 2-3 seconds. This duration is primarily due to loading the bitstream from the I2C bus at 200KHz. Speed improvements might be possible in future updates by using lower value pull-up resistors. Currently, 10K resistors are used in Nyan Keys hardware.

NOTE: The time to load the Bitstream is roughly 2-3 seconds and will occur on device power-on. The FPGA can be reprogrammed without a complete device reset, by setting the nos_fpga->configured to false. The main loop will eventually catch this after the interrupts complete and reload the bitstream from the contents of the EEPROM IC that are in Bank 1, using the value stored in the EEPROM bank 0 EEPROM FPGA Bitstream Len address 0x00B0 aligned as 4 Words, where each word is little endian encoded. This will be fixed later but current functions correct and you can use the write-bitstream <size> command and this will all be handled. THE MAXIMUM BITSTREAM SIZE IS 65536 BYTES anything more and you will get a size error returned.

User input to keys is not handled until the FPGA bitstream is loaded. Any keys pressed before configuration will not be relayed via the HID peripheral.

Persistent Windows Logo Key Disable

Nyan Keys now supports Windows logo key disablement. The user just has to press [FN + Windows Logo Key] to toggle the state between enabled and disabled. Each time this is done, the state is saved to the onboard EEPROM, ensuring it persists across reboots

Status Indication

On the Nyan Keys 0.8x - 0.9x boards there are 5 status leds that are activated upon boot. The labels for these LED(s) are as follows

IDNameDescription
0LED_0MCU Functional POST
5LED_1FPGA Configured

The system status LED should pulse at a rate of 1.287hz and have a period of 777ms. This is driven by TIM1 and TIM6 using interrupts.

The FPGA configuration LED will always match the pin status of c_done of the Lattice FPGA. c_done is an active high signal and will only go high once the FPGA has been programmed AND the 47 dummy bits have been sent over the SPI bus. NyanOS handles all of this without any additional programming using the FPGAInit function in lattice_ice_hx.c

EEPROM Address Layout

BlockAddressDescriptionLength
00x0000Board Serial Number32
00x0020Board Owner64
00x0060Board Build Block16
00x0070Board Version16
00x0080Total Keystrokes16
00x0090Total USB Connections16
00x00A0Total Times Powered On16
00x00B0FPGA Bitstream Len16
00x00C0Reserved 016
00x00D0Reserved 116
00x00E0Reserved 216
00x00F0Reserved 316
00x0100Reserved 416
00x0110Reserved 516
00x0120Reserved 616
00x0130Reserved 716
00x0140Reserved 816
00x0150Reserved 916
00x0160Reserved 1016
00x0170Reserved 1116
00x0180Reserved 1216
00x0190Reserved 1316
00x01A0Reserved 1416
00x01B0Reserved 1516
00x01C0Reserved 1616
00x01D0Reserved 1716
00x01E0Reserved 1816
00x01F0Reserved 1916
10x0000FPGA Bitstream65535