Files
system76-embedded-controller/src/board/system76/common/keymap.c
Tim Crawford 9fb08ffa46 Mark pointers as const
Resulting binaries are identical.

Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-03-18 14:27:36 -06:00

91 lines
2.3 KiB
C

// SPDX-License-Identifier: GPL-3.0-only
#include <board/flash.h>
#include <board/keymap.h>
bool keymap_fnlock = false;
uint16_t __xdata DYNAMIC_KEYMAP[KM_LAY][KM_OUT][KM_IN];
// Config is in the last sector of flash
const uint32_t CONFIG_ADDR = 0x1FC00;
// Signature is the size of the keymap
const uint16_t CONFIG_SIGNATURE = sizeof(DYNAMIC_KEYMAP);
void keymap_init(void) {
if (!keymap_load_config()) {
keymap_load_default();
}
}
void keymap_load_default(void) {
for (uint8_t layer = 0; layer < KM_LAY; layer++) {
for (uint8_t output = 0; output < KM_OUT; output++) {
for (uint8_t input = 0; input < KM_IN; input++) {
DYNAMIC_KEYMAP[layer][output][input] = KEYMAP[layer][output][input];
}
}
}
}
bool keymap_erase_config(void) {
// This will erase 1024 bytes
flash_erase(CONFIG_ADDR);
// Verify signature is erased
return flash_read_u16(CONFIG_ADDR) == 0xFFFF;
}
bool keymap_load_config(void) {
// Check signature
if (flash_read_u16(CONFIG_ADDR) != CONFIG_SIGNATURE)
return false;
// Read the keymap if signature is valid
flash_read(
CONFIG_ADDR + sizeof(CONFIG_SIGNATURE),
(uint8_t *)DYNAMIC_KEYMAP,
sizeof(DYNAMIC_KEYMAP)
);
return true;
}
bool keymap_save_config(void) {
// Erase config region
if (!keymap_erase_config())
return false;
// Write the keymap
flash_write(
CONFIG_ADDR + sizeof(CONFIG_SIGNATURE),
(uint8_t *)DYNAMIC_KEYMAP,
sizeof(DYNAMIC_KEYMAP)
);
// Write the length of the keymap, as a signature
flash_write_u16(CONFIG_ADDR, CONFIG_SIGNATURE);
// Verify signature is valid
return flash_read_u16(CONFIG_ADDR) == CONFIG_SIGNATURE;
}
bool keymap_get(uint8_t layer, uint8_t output, uint8_t input, uint16_t *const value) {
if (layer < KM_LAY && output < KM_OUT && input < KM_IN) {
if (keymap_fnlock && keymap_is_f_key(output, input))
layer ^= 1;
*value = DYNAMIC_KEYMAP[layer][output][input];
return true;
} else {
return false;
}
}
bool keymap_set(uint8_t layer, uint8_t output, uint8_t input, uint16_t value) {
if (layer < KM_LAY && output < KM_OUT && input < KM_IN) {
DYNAMIC_KEYMAP[layer][output][input] = value;
return true;
} else {
return false;
}
}