still planning for lib/eeprom_macro

partial-rewrite
Ben Blazak 2013-05-31 02:54:20 -07:00
parent 3582dfbc65
commit 3a2af3a9dd
1 changed files with 100 additions and 57 deletions

View File

@ -44,13 +44,89 @@
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// - "block"s are 4 bytes, aligned on the 4 byte boundary
// - all pointers are 1 byte (until converted for use), representing the offset
// of a block
/*
* layout_matrix_index
* header block 0x00
* .--------+--------+--------+--------. addresses 0x0000..0x0003
* 0 |version | free | padding | = 0x00<<2..(0x00<<2)+3
* '--------+--------+--------+--------'
*
* (see struct below)
* table blocks 0x01..0x03
* (example for a [3][3] matrix) addresses 0x0004..0x000F
* .--------. .--------. .--------. = 0x01<<2..(0x03<<2)+3
* 1 |pointer | |pointer | |pointer |
* '--------' '--------' '--------'
* .--------. .--------. .--------.
* |pointer | 2 |pointer | |pointer |
* '--------' '--------' '--------'
* .--------. .--------. .--------.
* |pointer | |pointer | 3 |pointer |
* '--------' '--------' '--------'
* .--------. .--------. .--------.
* |padding | |padding | |padding |
* '--------' '--------' '--------'
*
* - this format artificially limits the number of layers, rows, and columns to
*
* macros blocks 0x04..0xFF
* (example for a [3][3] matrix, above) addresses 0x0016..0x03FF
*
* .--------+--------. .--------+--------.
* 4 | next |run_len | | index |
* '--------+--------' '-----------------'
* .--------+--------.
* 5 | index |
* '--------+--------'
* .--------+--------.
* | index |
* '--------+--------'
*
* 6 ...
*/
#define ROWS OPT__KB__ROWS // for '.c' file
#define COLS OPT__KB__COLUMNS // for '.c' file
#define START_HEADER 0x00
#define START_TABLE 0x01
#define START_MACROS (((ROWS * COLS + 0x3) >> 2) + 1) // > 1
#define END_EEPROM 0xFF
#define FLAG_DELETED 0x01
struct header {
uint8_t version; // of this layout; 0x00 or 0xFF => uninitialized
uint8_t start_free; // pointer to the first unallocated block
uint16_t padding;
};
struct table {
uint8_t pointers[ ROWS * COLS ]; // to `macro`s
uint8_t padding[ 3 - ((ROWS * COLS) & 0x3) ]; // may be length = 0
};
struct macro {
uint8_t next; // 0x00 => last for this [row][col]
// 0x01 => "deleted" macro
uint8_t run_length;
eeprom_macro__index_t index;
};
struct action { // `run_length` of these will follow `macro`
eeprom_macro__index_t index; // `layer` will be unset and ignored
};
// ----------------------------------------------------------------------------
typedef struct {
bool pressed : 1;
uint8_t layer : 5;
uint8_t row : 5;
uint8_t column : 5;
} eeprom_macro__index_t;
/* - this format artificially limits the number of layers, rows, and columns to
* 2^5 = 32 each, which seems like it'd be hard to practically exceed. this
* is done because it's much easier to extract the values we're going to use
* if we separate them this way than if we reverse the array offset
@ -62,65 +138,20 @@
* there's only 32256 bytes of PROGMEM to begin with.
*/
/*
* EEPROM
*
* ls = layers, rs = rows, cs = columns (total)
* l = layer, r = row, c = column (current)
*
* 0<<2 : version number of the layout (0x00 or 0xFF => not initialized)
* +1 : (address >> 2) of the first unused 4-byte block
* +2 : padding
* +3 : padding
* 1<<2 : (start)
* ... : table of 8-bit pointers to 4-byte blocks, beginning after this table,
* containing headers for macro sequences
* - 1 pointer for each key in the rs*cs matrix
* - a "macro sequence" is a `macro_header` followed by a varying number
* of `key_actions`
* ceil([rs*cs]/4)<<2 = ((rs*cs)+0x3)&0xFC : (end)
* previous + (1<<2) : (start)
* ... : macro sequences
* 255<<2 : (end) (end of EEPROM)
*/
/*
* TODO: rename everything and reorganize and stuff
*/
struct layout_matrix_index {
bool pressed : 1;
uint8_t layer : 5;
uint8_t row : 5;
uint8_t column : 5;
}; // total: 2 bytes
struct macro_header {
uint8_t next : 8;
/* (address >> 2) of the next macro sequence assigned to the same (row,
* column)
*/
uint8_t run_length : 8;
/* the number of `key_action`s following this header
*/
struct layout_matrix_index index : 16;
}; // total: 4 bytes
struct key_action {
bool _ignore : 1; // padding
bool pressed : 1;
uint8_t row : 7;
uint8_t column : 7;
}; // total: 2 bytes
uint8_t eeprom_macro__init(void);
/* - check version
* - initialize the EEPROM if necessary
* - "zero" EEPROM if necessary (i.e. if uninitialized for the current version)
*/
void eeprom_macro__play(uint16_t layout_matrix_index);
uint8_t eeprom_macro__get_size_free(void);
/* - return free space, in blocks
*/
void eeprom_macro__play(eeprom_macro__index_t index);
/* - play back keystrokes (loop: call `kb__layout__exec_key()`)
*/
void eeprom_macro__record__start(uint8_t skip);
uint8_t eeprom_macro__record__start(uint8_t skip);
/* - skip `skip` keypresses
* - (`...exec_key()` may need these to determine what key to assign the
* macro to
@ -129,14 +160,26 @@ void eeprom_macro__record__start(uint8_t skip);
* can't tell what key to assign it to ourselves without a bunch of pain
* anyway
* - start recording
* - return 0 on success, other on failure
*/
void eeprom_macro__record__stop(uint8_t skip, uint16_t layout_matrix_index);
uint8_t eeprom_macro__record__stop(uint8_t skip, eeprom_macro__index_t index);
/* - stop recording
* - discard `skip` keypresses
* - update all header and "filesystem" information
* - return 0 on success, other on failure
*/
// TODO: we probably want a delete, and maybe a clear-all function
void eeprom_macro__compress(void);
/* - remove all "deleted" macros, shifting active ones toward address 0
*/
void eeprom_macro__clear(eeprom_macro__index_t index);
/* - set the `next` pointer for this index to `FLAG_DELETED`
*/
void eeprom_macro__clear_all(void);
/* - put EEPROM into a valid and intialized, but "zeroed" state
*/
// ----------------------------------------------------------------------------