From e5c3490dd66f476e7476fe8ac621a8916e03c13b Mon Sep 17 00:00:00 2001 From: Ben Blazak Date: Wed, 5 Jun 2013 14:59:19 -0700 Subject: [PATCH] (intermediate checkin; working on lib/eeprom-macro stuff still) --- firmware/lib/layout/eeprom-macro.h | 8 +- firmware/lib/layout/eeprom-macro/atmega32u4.c | 118 ++++++++++++------ 2 files changed, 88 insertions(+), 38 deletions(-) diff --git a/firmware/lib/layout/eeprom-macro.h b/firmware/lib/layout/eeprom-macro.h index 999b809..7a9957d 100644 --- a/firmware/lib/layout/eeprom-macro.h +++ b/firmware/lib/layout/eeprom-macro.h @@ -52,13 +52,19 @@ typedef struct { uint8_t layer : 5; uint8_t row : 5; uint8_t column : 5; -} eeprom_macro__index_t; +} eeprom_macro__index_t __attribute__((packed, aligned(1))); // ---------------------------------------------------------------------------- uint8_t eeprom_macro__init (void); uint8_t eeprom_macro__record__start (uint8_t skip); uint8_t eeprom_macro__record__stop (uint8_t skip, eeprom_macro__index_t index); +// TODO: do it this way: +// uint8_t eeprom_macro__record__stop ( uint8_t skip, +// bool pressed, +// uint8_t layer, +// uint8_t row, +// uint8_t column ); uint8_t eeprom_macro__play (eeprom_macro__index_t index); void eeprom_macro__clear (eeprom_macro__index_t index); void eeprom_macro__clear_all (void); diff --git a/firmware/lib/layout/eeprom-macro/atmega32u4.c b/firmware/lib/layout/eeprom-macro/atmega32u4.c index 8db40a5..24b3127 100644 --- a/firmware/lib/layout/eeprom-macro/atmega32u4.c +++ b/firmware/lib/layout/eeprom-macro/atmega32u4.c @@ -7,14 +7,12 @@ /** description * Implements the eeprom-macro functionality defined in "../eeprom-macro.h" for * the ATMega32U4 - * - * Terms (for the purposes of this file): - * - A "UID" (Unique IDentifier) is an `eeprom_macro__index_t` */ #include #include +#include "../../../../firmware/keyboard.h" #include "../eeprom-macro.h" // ---------------------------------------------------------------------------- @@ -35,7 +33,7 @@ // ---------------------------------------------------------------------------- /** macros/VERSION/description - * The version number of this EEPROM layout + * The version number of `struct eeprom` */ #define VERSION 1 @@ -45,7 +43,7 @@ * The layout of this library's data in the EEPROM * * Struct members: - * - `header`: For keeping track of layout metadata + * - `meta0`: For keeping track of layout metadata * - `version`: The version of this layout * - `0x00`, `0xFF` => uninitialized * - `free`: The first free element in `macros.data` @@ -56,15 +54,28 @@ * - `data`: Each entry contains the index of the beginning of the first * macro with the corresponding row and column in its UID * + * - `meta1`: For redundancy and write balancing (see `meta0`) + * * - `macros`: A block of memory for storing macros - * - `size`: `sizeof(struct macros) >> 2`; - * - `data`: TODO + * - `size`: The number of elements in `macros.data` + * - `data`: A collection of `macro_header`s followed by the defined number + * of `macro_action`s. Essentially, a collection of (not necessarily + * contiguous) linked lists of macros, with one list for every row, + * column pair that has a remapping. + * + * - `meta2`: For redundancy and write balancing (see `meta0`) + * + * Notes: + * - We keep track of `table.rows`, `table.columns`, and `macros.size`, in + * addition to `header.version`, because they all effect the precise layout + * of the persistent data; if any of them is different, special handling is + * required at the least, and usually the stored data will be unusable. */ struct eeprom { - struct header { + struct meta0 { uint8_t version; uint8_t free; - } header; + } meta0; struct table { uint8_t rows; @@ -72,56 +83,89 @@ struct eeprom { uint8_t data[OPT__KB__ROWS][OPT__KB__COLUMNS]; } table; + struct meta1 { + uint8_t version; + uint8_t free; + } meta1; + struct macros { uint8_t size; uint32_t data[ ( OPT__EEPROM_MACRO__EEPROM_SIZE - - sizeof(struct header) + - sizeof(struct meta0) * 3 - sizeof(struct table) ) >> 2 ]; } macros; -}; + struct meta2 { + uint8_t version; + uint8_t free; + } meta2; +} __attribute__((packed, aligned(1))); /** types/macro_header/description - * TODO + * The header for a macro living in `macros.data` + * + * Struct members: + * - `next`: The index (in `macros.data`) of the next macro with the same row + * and column in its UID + * - `0x00` => This macro is (currently) the last in its linked list + * - `0xFF` => This macro has been deleted + * - `length`: The number of `macro_action`s following this header + * - `uid`: The Unique IDentifier (UID) of this macro */ struct macro_header { uint8_t next; uint8_t length; - eeprom_macro__index_t index; -}; + eeprom_macro__index_t uid; +} __attribute__((packed, aligned(1))); /** types/macro_action/description - * TODO + * A single action belonging to a macro living in `eeprom.macros.data` + * + * Struct members: + * - The key state (`pressed` or unpressed), `row`, and `column` of the action + * recorded + * + * Notes: + * - To be "executed" by calling `kb__layout__exec_key()` with the appropriate + * arguments. + * + * TODO: binary format is important: use explicit bit shifting/masking instead + * of bitfields */ struct macro_action { + uint8_t padding : 1; bool pressed : 1; uint8_t row : 7; uint8_t column : 7; -}; +} __attribute__((packed, aligned(1))); // ---------------------------------------------------------------------------- -// TODO: functions +struct eeprom eeprom EEMEM; +uint8_t test[ sizeof(eeprom.macros.data) ]; -/* - * Format: macro header: - * - * struct { - * uint8_t next; // a block pointer to the next macro with the same - * // `row` and `column` in its UID - * // `0x00` => this macro is the last in the linked - * // list for this `row`, `column` pair - * // `0xFF` => this macro has been deleted - * uint8_t length; // the run length of the macro, in number of - * // key actions - * eeprom_macro__index_t index; // the UID of this macro - * }; - * - * Format: key action: - * - * struct { - * eeprom_macro__index_t index; // `layer` will be ignored - * }; - */ +// ---------------------------------------------------------------------------- + +uint8_t eeprom_macro__init(void) { + return 0; +} + +uint8_t eeprom_macro__record__start(uint8_t skip) { + return 0; +} + +uint8_t eeprom_macro__record__stop(uint8_t skip, eeprom_macro__index_t index) { + return 0; +} + +uint8_t eeprom_macro__play(eeprom_macro__index_t index) { + return 0; +} + +void eeprom_macro__clear(eeprom_macro__index_t index) { +} + +void eeprom_macro__clear_all(void) { +}