still planning for lib/eeprom_macro
parent
3582dfbc65
commit
3a2af3a9dd
|
@ -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
|
||||
*/
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue