(working: eeprom-macro)
parent
0fd92b5840
commit
b099061e6a
|
@ -655,11 +655,72 @@ out:
|
||||||
return 2; // write failed; data lost
|
return 2; // write failed; data lost
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// helper functions -----------------------------------------------------------
|
||||||
|
|
||||||
|
/** functions/write_key_action_for_new_macro/description
|
||||||
|
* Write the given key-action to the next empty space in the macros block of
|
||||||
|
* the EEPROM
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* - `k`: A pointer to the key-action to write
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* - success: `0`
|
||||||
|
* - failure: [other]
|
||||||
|
*
|
||||||
|
* Assumptions:
|
||||||
|
* - A macro is currently in progress (i.e. `new_end_macro` is not `0`).
|
||||||
|
*
|
||||||
|
* Notes:
|
||||||
|
* - We make sure to leave 1 empty byte for the end macro.
|
||||||
|
* - We update the value of `new_end_macro` (either to indicate the bytes that
|
||||||
|
* were written, or to cancel the current macro if writing failed).
|
||||||
|
*/
|
||||||
|
static inline uint8_t write_key_action_for_new_macro(key_action_t * k) {
|
||||||
|
uint8_t ret; // for function return values
|
||||||
|
|
||||||
|
ret = write_key_action(new_end_macro, k, EEMEM_MACROS_END-1);
|
||||||
|
if (! ret) {
|
||||||
|
if ( compress() ) goto out; // compress failed (macro cancelled)
|
||||||
|
|
||||||
|
ret = write_key_action(new_end_macro, k, EEMEM_MACROS_END-1);
|
||||||
|
if (! ret) goto out; // write failed again, or not enough room
|
||||||
|
}
|
||||||
|
|
||||||
|
new_end_macro += ret;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
new_end_macro = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the macro remapping the given key-action, if it exists
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* - `k`: A pointer to the key-action to delete
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* - success: `0`
|
||||||
|
* - failure: [other]
|
||||||
|
*/
|
||||||
|
static inline uint8_t delete_macro_if_exists(key_action_t * k) {
|
||||||
|
void * k_location = find_key_action(k);
|
||||||
|
|
||||||
|
if (k_location)
|
||||||
|
if ( eeprom__write(k_location, TYPE_DELETED) )
|
||||||
|
return 1; // write failed
|
||||||
|
|
||||||
|
return 0; // success
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// public functions -----------------------------------------------------------
|
// public functions -----------------------------------------------------------
|
||||||
|
|
||||||
// TODO: go over all these, and make sure they conform to the header
|
// TODO: go over all these, and make sure they conform to the header
|
||||||
// documentation
|
// documentation (and that they work properly)
|
||||||
|
|
||||||
/** functions/eeprom_macro__init/description
|
/** functions/eeprom_macro__init/description
|
||||||
* Implementation notes:
|
* Implementation notes:
|
||||||
|
@ -695,10 +756,10 @@ uint8_t eeprom_macro__init(void) {
|
||||||
|
|
||||||
/** functions/eeprom_macro__record_init/description
|
/** functions/eeprom_macro__record_init/description
|
||||||
* Implementation notes:
|
* Implementation notes:
|
||||||
* - At minimum, for a normal macro, we will need a `type` byte, `length` byte,
|
* - At minimum, for a normal macro, we will need a `type` byte, a `length`
|
||||||
* key-action 0 (the action to remap), key-action 1 (a press), and key-action
|
* byte, and 3 key-actions (the key-action to remap, 1 press, and 1 release).
|
||||||
* 2 (a release). Key-actions take a minimum of 1 byte, so our minimum macro
|
* Key-actions take a minimum of 1 byte, so our minimum macro will be 5
|
||||||
* will be 5 bytes.
|
* bytes.
|
||||||
*/
|
*/
|
||||||
uint8_t eeprom_macro__record_init( bool pressed,
|
uint8_t eeprom_macro__record_init( bool pressed,
|
||||||
uint8_t layer,
|
uint8_t layer,
|
||||||
|
@ -711,11 +772,6 @@ uint8_t eeprom_macro__record_init( bool pressed,
|
||||||
if ( end_macro + 5 > EEMEM_MACROS_END )
|
if ( end_macro + 5 > EEMEM_MACROS_END )
|
||||||
return 1; // not enough room
|
return 1; // not enough room
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// - if a macro remapping the given key-action already exists, delete it.
|
|
||||||
|
|
||||||
uint8_t ret; // for function return values
|
|
||||||
|
|
||||||
key_action_t k = {
|
key_action_t k = {
|
||||||
.pressed = pressed,
|
.pressed = pressed,
|
||||||
.layer = layer,
|
.layer = layer,
|
||||||
|
@ -723,18 +779,11 @@ uint8_t eeprom_macro__record_init( bool pressed,
|
||||||
.column = column,
|
.column = column,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if ( delete_macro_if_exists(&k) ) return 1; // failure
|
||||||
|
|
||||||
new_end_macro = end_macro + 2;
|
new_end_macro = end_macro + 2;
|
||||||
|
|
||||||
// TODO:
|
return write_key_action_for_new_macro(&k);
|
||||||
// - call compress() if the write fails, to see if that helps
|
|
||||||
// - if compress() succeeds, but the write still fails, we should cancel
|
|
||||||
// the current macro (if compress() fails, the current macro will be
|
|
||||||
// canceled anyway)
|
|
||||||
ret = write_key_action(new_end_macro, &k, EEMEM_MACROS_END-1);
|
|
||||||
if (! ret) return 1; // write failed, or not enough room
|
|
||||||
end_macro += ret;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t eeprom_macro__record_action( bool pressed,
|
uint8_t eeprom_macro__record_action( bool pressed,
|
||||||
|
@ -745,8 +794,6 @@ uint8_t eeprom_macro__record_action( bool pressed,
|
||||||
if (! new_end_macro)
|
if (! new_end_macro)
|
||||||
return 1; // no macro in progress
|
return 1; // no macro in progress
|
||||||
|
|
||||||
uint8_t ret; // for function return values
|
|
||||||
|
|
||||||
key_action_t k = {
|
key_action_t k = {
|
||||||
.pressed = pressed,
|
.pressed = pressed,
|
||||||
.layer = layer,
|
.layer = layer,
|
||||||
|
@ -754,21 +801,33 @@ uint8_t eeprom_macro__record_action( bool pressed,
|
||||||
.column = column,
|
.column = column,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO:
|
// TODO: if length is too long, finalize this macro, and start a
|
||||||
// - call compress() if the write fails, to see if that helps
|
// continuation one
|
||||||
// - if compress() succeeds, but the write still fails, we should cancel
|
//
|
||||||
// the current macro (if compress() fails, the current macro will be
|
// - key-actions are at most 4 bytes long, so we make sure there are at
|
||||||
// canceled anyway)
|
// least 4 bytes left in the allowable length of this macro; not worth it
|
||||||
ret = write_key_action(new_end_macro, &k, EEMEM_MACROS_END-1);
|
// to calculate the encoded length of the key-action to be written
|
||||||
if (! ret) return 1; // write failed, or not enough room
|
if ( new_end_macro - end_macro > UINT8_MAX - 4 ) {
|
||||||
end_macro += ret;
|
if ( eeprom_macro__record_finalize() ) return 1; // failure
|
||||||
|
|
||||||
return 0;
|
// TODO: we can't just call ...init(). we probably need a file-local
|
||||||
|
// variable too, to keep track of whether the new macro is
|
||||||
|
// `TYPE_VALID_MACRO` or `TYPE_CONTINUED`.
|
||||||
|
}
|
||||||
|
|
||||||
|
return write_key_action_for_new_macro(&k);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t eeprom_macro__record_finalize(void) {
|
uint8_t eeprom_macro__record_finalize(void) {
|
||||||
// TODO
|
if ( eeprom__write( new_end_macro, TYPE_END ) ) goto out;
|
||||||
|
if ( eeprom__write( end_macro+1, new_end_macro - end_macro ) ) goto out;
|
||||||
|
if ( eeprom__write( end_macro, TYPE_VALID_MACRO ) ) goto out;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
new_end_macro = 0;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t eeprom_macro__record_cancel(void) {
|
uint8_t eeprom_macro__record_cancel(void) {
|
||||||
|
@ -788,16 +847,30 @@ bool eeprom_macro__exists( bool pressed,
|
||||||
uint8_t layer,
|
uint8_t layer,
|
||||||
uint8_t row,
|
uint8_t row,
|
||||||
uint8_t column ) {
|
uint8_t column ) {
|
||||||
// TODO
|
|
||||||
return false;
|
key_action_t k = {
|
||||||
|
.pressed = pressed,
|
||||||
|
.layer = layer,
|
||||||
|
.row = row,
|
||||||
|
.column = column,
|
||||||
|
};
|
||||||
|
|
||||||
|
return find_key_action(&k);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t eeprom_macro__clear( bool pressed,
|
uint8_t eeprom_macro__clear( bool pressed,
|
||||||
uint8_t layer,
|
uint8_t layer,
|
||||||
uint8_t row,
|
uint8_t row,
|
||||||
uint8_t column ) {
|
uint8_t column ) {
|
||||||
// TODO
|
|
||||||
return 0;
|
key_action_t k = {
|
||||||
|
.pressed = pressed,
|
||||||
|
.layer = layer,
|
||||||
|
.row = row,
|
||||||
|
.column = column,
|
||||||
|
};
|
||||||
|
|
||||||
|
return delete_macro_if_exists(&k);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** functions/eeprom_macro__clear_all/description
|
/** functions/eeprom_macro__clear_all/description
|
||||||
|
|
Loading…
Reference in New Issue