1
0
Fork 0

clang-format changes

This commit is contained in:
skullY 2019-08-30 11:19:03 -07:00 committed by skullydazed
parent 61af76a10d
commit b624f32f94
502 changed files with 32259 additions and 39062 deletions

File diff suppressed because it is too large Load diff

View file

@ -24,23 +24,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "action_code.h"
#include "action_macro.h"
#ifdef __cplusplus
extern "C" {
#endif
/* tapping count and state */
typedef struct {
bool interrupted :1;
bool reserved2 :1;
bool reserved1 :1;
bool reserved0 :1;
uint8_t count :4;
bool interrupted : 1;
bool reserved2 : 1;
bool reserved1 : 1;
bool reserved0 : 1;
uint8_t count : 4;
} tap_t;
/* Key event container for recording */
typedef struct {
keyevent_t event;
keyevent_t event;
#ifndef NO_ACTION_TAPPING
tap_t tap;
#endif
@ -68,17 +67,17 @@ extern bool disable_action_cache;
/* Code for handling one-handed key modifiers. */
#ifdef SWAP_HANDS_ENABLE
extern bool swap_hands;
extern bool swap_hands;
extern const keypos_t hand_swap_config[MATRIX_ROWS][MATRIX_COLS];
#if (MATRIX_COLS <= 8)
typedef uint8_t swap_state_row_t;
#elif (MATRIX_COLS <= 16)
typedef uint16_t swap_state_row_t;
#elif (MATRIX_COLS <= 32)
typedef uint32_t swap_state_row_t;
#else
#error "MATRIX_COLS: invalid value"
#endif
# if (MATRIX_COLS <= 8)
typedef uint8_t swap_state_row_t;
# elif (MATRIX_COLS <= 16)
typedef uint16_t swap_state_row_t;
# elif (MATRIX_COLS <= 32)
typedef uint32_t swap_state_row_t;
# else
# error "MATRIX_COLS: invalid value"
# endif
void process_hand_swap(keyevent_t *record);
#endif
@ -91,7 +90,7 @@ void unregister_code(uint8_t code);
void tap_code(uint8_t code);
void register_mods(uint8_t mods);
void unregister_mods(uint8_t mods);
//void set_mods(uint8_t mods);
// void set_mods(uint8_t mods);
void clear_keyboard(void);
void clear_keyboard_but_mods(void);
void clear_keyboard_but_mods_and_keys(void);
@ -112,4 +111,4 @@ void debug_action(action_t action);
}
#endif
#endif /* ACTION_H */
#endif /* ACTION_H */

View file

@ -98,30 +98,29 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
enum action_kind_id {
/* Key Actions */
ACT_MODS = 0b0000,
ACT_LMODS = 0b0000,
ACT_RMODS = 0b0001,
ACT_MODS_TAP = 0b0010,
ACT_LMODS_TAP = 0b0010,
ACT_RMODS_TAP = 0b0011,
ACT_MODS = 0b0000,
ACT_LMODS = 0b0000,
ACT_RMODS = 0b0001,
ACT_MODS_TAP = 0b0010,
ACT_LMODS_TAP = 0b0010,
ACT_RMODS_TAP = 0b0011,
/* Other Keys */
ACT_USAGE = 0b0100,
ACT_MOUSEKEY = 0b0101,
ACT_USAGE = 0b0100,
ACT_MOUSEKEY = 0b0101,
/* One-hand Support */
ACT_SWAP_HANDS = 0b0110,
ACT_SWAP_HANDS = 0b0110,
/* Layer Actions */
ACT_LAYER = 0b1000,
ACT_LAYER_MODS = 0b1001,
ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */
ACT_LAYER_TAP_EXT = 0b1011, /* Layer 16-31 */
ACT_LAYER = 0b1000,
ACT_LAYER_MODS = 0b1001,
ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */
ACT_LAYER_TAP_EXT = 0b1011, /* Layer 16-31 */
/* Extensions */
ACT_MACRO = 0b1100,
ACT_BACKLIGHT = 0b1101,
ACT_COMMAND = 0b1110,
ACT_FUNCTION = 0b1111
ACT_MACRO = 0b1100,
ACT_BACKLIGHT = 0b1101,
ACT_COMMAND = 0b1110,
ACT_FUNCTION = 0b1111
};
/** \brief Action Code Struct
*
* NOTE:
@ -139,66 +138,63 @@ enum action_kind_id {
typedef union {
uint16_t code;
struct action_kind {
uint16_t param :12;
uint8_t id :4;
uint16_t param : 12;
uint8_t id : 4;
} kind;
struct action_key {
uint8_t code :8;
uint8_t mods :4;
uint8_t kind :4;
uint8_t code : 8;
uint8_t mods : 4;
uint8_t kind : 4;
} key;
struct action_layer_bitop {
uint8_t bits :4;
uint8_t xbit :1;
uint8_t part :3;
uint8_t on :2;
uint8_t op :2;
uint8_t kind :4;
uint8_t bits : 4;
uint8_t xbit : 1;
uint8_t part : 3;
uint8_t on : 2;
uint8_t op : 2;
uint8_t kind : 4;
} layer_bitop;
struct action_layer_mods
{
uint8_t mods :8;
uint8_t layer :4;
uint8_t kind :4;
struct action_layer_mods {
uint8_t mods : 8;
uint8_t layer : 4;
uint8_t kind : 4;
} layer_mods;
struct action_layer_tap {
uint8_t code :8;
uint8_t val :5;
uint8_t kind :3;
uint8_t code : 8;
uint8_t val : 5;
uint8_t kind : 3;
} layer_tap;
struct action_usage {
uint16_t code :10;
uint8_t page :2;
uint8_t kind :4;
uint16_t code : 10;
uint8_t page : 2;
uint8_t kind : 4;
} usage;
struct action_backlight {
uint8_t level :8;
uint8_t opt :4;
uint8_t kind :4;
uint8_t level : 8;
uint8_t opt : 4;
uint8_t kind : 4;
} backlight;
struct action_command {
uint8_t id :8;
uint8_t opt :4;
uint8_t kind :4;
uint8_t id : 8;
uint8_t opt : 4;
uint8_t kind : 4;
} command;
struct action_function {
uint8_t id :8;
uint8_t opt :4;
uint8_t kind :4;
uint8_t id : 8;
uint8_t opt : 4;
uint8_t kind : 4;
} func;
struct action_swap {
uint8_t code :8;
uint8_t opt :4;
uint8_t kind :4;
uint8_t code : 8;
uint8_t opt : 4;
uint8_t kind : 4;
} swap;
} action_t;
/* action utility */
#define ACTION_NO 0
#define ACTION_TRANSPARENT 1
#define ACTION(kind, param) ((kind)<<12 | (param))
#define ACTION_NO 0
#define ACTION_TRANSPARENT 1
#define ACTION(kind, param) ((kind) << 12 | (param))
/** \brief Key Actions
*
@ -220,35 +216,29 @@ enum mods_bit {
MOD_RGUI = 0x18,
};
enum mods_codes {
MODS_ONESHOT = 0x00,
MODS_ONESHOT = 0x00,
MODS_TAP_TOGGLE = 0x01,
};
#define ACTION_KEY(key) ACTION(ACT_MODS, (key))
#define ACTION_MODS(mods) ACTION(ACT_MODS, ((mods)&0x1f)<<8 | 0)
#define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, ((mods)&0x1f)<<8 | (key))
#define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, ((mods)&0x1f)<<8 | (key))
#define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f)<<8 | MODS_ONESHOT)
#define ACTION_MODS_TAP_TOGGLE(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f)<<8 | MODS_TAP_TOGGLE)
#define ACTION_KEY(key) ACTION(ACT_MODS, (key))
#define ACTION_MODS(mods) ACTION(ACT_MODS, ((mods)&0x1f) << 8 | 0)
#define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, ((mods)&0x1f) << 8 | (key))
#define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | (key))
#define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | MODS_ONESHOT)
#define ACTION_MODS_TAP_TOGGLE(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | MODS_TAP_TOGGLE)
/** \brief Other Keys
*/
enum usage_pages {
PAGE_SYSTEM,
PAGE_CONSUMER
};
#define ACTION_USAGE_SYSTEM(id) ACTION(ACT_USAGE, PAGE_SYSTEM<<10 | (id))
#define ACTION_USAGE_CONSUMER(id) ACTION(ACT_USAGE, PAGE_CONSUMER<<10 | (id))
#define ACTION_MOUSEKEY(key) ACTION(ACT_MOUSEKEY, key)
enum usage_pages { PAGE_SYSTEM, PAGE_CONSUMER };
#define ACTION_USAGE_SYSTEM(id) ACTION(ACT_USAGE, PAGE_SYSTEM << 10 | (id))
#define ACTION_USAGE_CONSUMER(id) ACTION(ACT_USAGE, PAGE_CONSUMER << 10 | (id))
#define ACTION_MOUSEKEY(key) ACTION(ACT_MOUSEKEY, key)
/** \brief Layer Actions
*/
enum layer_param_on {
ON_PRESS = 1,
ON_RELEASE = 2,
ON_BOTH = 3,
ON_PRESS = 1,
ON_RELEASE = 2,
ON_BOTH = 3,
};
/** \brief Layer Actions
@ -269,37 +259,36 @@ enum layer_param_tap_op {
OP_SET_CLEAR,
OP_ONESHOT,
};
#define ACTION_LAYER_BITOP(op, part, bits, on) ACTION(ACT_LAYER, (op)<<10 | (on)<<8 | (part)<<5 | ((bits)&0x1f))
#define ACTION_LAYER_TAP(layer, key) ACTION(ACT_LAYER_TAP, (layer)<<8 | (key))
#define ACTION_LAYER_BITOP(op, part, bits, on) ACTION(ACT_LAYER, (op) << 10 | (on) << 8 | (part) << 5 | ((bits)&0x1f))
#define ACTION_LAYER_TAP(layer, key) ACTION(ACT_LAYER_TAP, (layer) << 8 | (key))
/* Default Layer */
#define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_BIT_SET((layer)/4, 1<<((layer)%4))
#define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_BIT_SET((layer) / 4, 1 << ((layer) % 4))
/* Layer Operation */
#define ACTION_LAYER_CLEAR(on) ACTION_LAYER_BIT_AND(0, 0, (on))
#define ACTION_LAYER_MOMENTARY(layer) ACTION_LAYER_ON_OFF(layer)
#define ACTION_LAYER_TOGGLE(layer) ACTION_LAYER_INVERT(layer, ON_RELEASE)
#define ACTION_LAYER_INVERT(layer, on) ACTION_LAYER_BIT_XOR((layer)/4, 1<<((layer)%4), (on))
#define ACTION_LAYER_ON(layer, on) ACTION_LAYER_BIT_OR( (layer)/4, 1<<((layer)%4), (on))
#define ACTION_LAYER_OFF(layer, on) ACTION_LAYER_BIT_AND((layer)/4, ~(1<<((layer)%4)), (on))
#define ACTION_LAYER_SET(layer, on) ACTION_LAYER_BIT_SET((layer)/4, 1<<((layer)%4), (on))
#define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF)
#define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON)
#define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR)
#define ACTION_LAYER_ONESHOT(layer) ACTION_LAYER_TAP((layer), OP_ONESHOT)
#define ACTION_LAYER_MODS(layer, mods) ACTION(ACT_LAYER_MODS, (layer) << 8 | (mods))
#define ACTION_LAYER_CLEAR(on) ACTION_LAYER_BIT_AND(0, 0, (on))
#define ACTION_LAYER_MOMENTARY(layer) ACTION_LAYER_ON_OFF(layer)
#define ACTION_LAYER_TOGGLE(layer) ACTION_LAYER_INVERT(layer, ON_RELEASE)
#define ACTION_LAYER_INVERT(layer, on) ACTION_LAYER_BIT_XOR((layer) / 4, 1 << ((layer) % 4), (on))
#define ACTION_LAYER_ON(layer, on) ACTION_LAYER_BIT_OR((layer) / 4, 1 << ((layer) % 4), (on))
#define ACTION_LAYER_OFF(layer, on) ACTION_LAYER_BIT_AND((layer) / 4, ~(1 << ((layer) % 4)), (on))
#define ACTION_LAYER_SET(layer, on) ACTION_LAYER_BIT_SET((layer) / 4, 1 << ((layer) % 4), (on))
#define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF)
#define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON)
#define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR)
#define ACTION_LAYER_ONESHOT(layer) ACTION_LAYER_TAP((layer), OP_ONESHOT)
#define ACTION_LAYER_MODS(layer, mods) ACTION(ACT_LAYER_MODS, (layer) << 8 | (mods))
/* With Tapping */
#define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key))
#define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE)
#define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key))
#define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE)
/* Bitwise Operation */
#define ACTION_LAYER_BIT_AND(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), (on))
#define ACTION_LAYER_BIT_OR( part, bits, on) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), (on))
#define ACTION_LAYER_BIT_XOR(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), (on))
#define ACTION_LAYER_BIT_SET(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), (on))
#define ACTION_LAYER_BIT_AND(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), (on))
#define ACTION_LAYER_BIT_OR(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), (on))
#define ACTION_LAYER_BIT_XOR(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), (on))
#define ACTION_LAYER_BIT_SET(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), (on))
/* Default Layer Bitwise Operation */
#define ACTION_DEFAULT_LAYER_BIT_AND(part, bits) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), 0)
#define ACTION_DEFAULT_LAYER_BIT_OR( part, bits) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), 0)
#define ACTION_DEFAULT_LAYER_BIT_XOR(part, bits) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), 0)
#define ACTION_DEFAULT_LAYER_BIT_SET(part, bits) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), 0)
#define ACTION_DEFAULT_LAYER_BIT_AND(part, bits) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), 0)
#define ACTION_DEFAULT_LAYER_BIT_OR(part, bits) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), 0)
#define ACTION_DEFAULT_LAYER_BIT_XOR(part, bits) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), 0)
#define ACTION_DEFAULT_LAYER_BIT_SET(part, bits) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), 0)
/** \brief Extensions
*/
@ -313,25 +302,25 @@ enum backlight_opt {
};
/* Macro */
#define ACTION_MACRO(id) ACTION(ACT_MACRO, (id))
#define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP<<8 | (id))
#define ACTION_MACRO_OPT(id, opt) ACTION(ACT_MACRO, (opt)<<8 | (id))
#define ACTION_MACRO(id) ACTION(ACT_MACRO, (id))
#define ACTION_MACRO_TAP(id) ACTION(ACT_MACRO, FUNC_TAP << 8 | (id))
#define ACTION_MACRO_OPT(id, opt) ACTION(ACT_MACRO, (opt) << 8 | (id))
/* Backlight */
#define ACTION_BACKLIGHT_INCREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_INCREASE << 8)
#define ACTION_BACKLIGHT_DECREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_DECREASE << 8)
#define ACTION_BACKLIGHT_TOGGLE() ACTION(ACT_BACKLIGHT, BACKLIGHT_TOGGLE << 8)
#define ACTION_BACKLIGHT_STEP() ACTION(ACT_BACKLIGHT, BACKLIGHT_STEP << 8)
#define ACTION_BACKLIGHT_ON() ACTION(ACT_BACKLIGHT, BACKLIGHT_ON << 8)
#define ACTION_BACKLIGHT_OFF() ACTION(ACT_BACKLIGHT, BACKLIGHT_OFF << 8)
#define ACTION_BACKLIGHT_INCREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_INCREASE << 8)
#define ACTION_BACKLIGHT_DECREASE() ACTION(ACT_BACKLIGHT, BACKLIGHT_DECREASE << 8)
#define ACTION_BACKLIGHT_TOGGLE() ACTION(ACT_BACKLIGHT, BACKLIGHT_TOGGLE << 8)
#define ACTION_BACKLIGHT_STEP() ACTION(ACT_BACKLIGHT, BACKLIGHT_STEP << 8)
#define ACTION_BACKLIGHT_ON() ACTION(ACT_BACKLIGHT, BACKLIGHT_ON << 8)
#define ACTION_BACKLIGHT_OFF() ACTION(ACT_BACKLIGHT, BACKLIGHT_OFF << 8)
/* Command */
#define ACTION_COMMAND(id, opt) ACTION(ACT_COMMAND, (opt)<<8 | (id))
#define ACTION_COMMAND(id, opt) ACTION(ACT_COMMAND, (opt) << 8 | (id))
/* Function */
enum function_opts {
FUNC_TAP = 0x8, /* indciates function is tappable */
FUNC_TAP = 0x8, /* indciates function is tappable */
};
#define ACTION_FUNCTION(id) ACTION(ACT_FUNCTION, (id))
#define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP<<8 | (id))
#define ACTION_FUNCTION_OPT(id, opt) ACTION(ACT_FUNCTION, (opt)<<8 | (id))
#define ACTION_FUNCTION(id) ACTION(ACT_FUNCTION, (id))
#define ACTION_FUNCTION_TAP(id) ACTION(ACT_FUNCTION, FUNC_TAP << 8 | (id))
#define ACTION_FUNCTION_OPT(id, opt) ACTION(ACT_FUNCTION, (opt) << 8 | (id))
/* OneHand Support */
enum swap_hands_param_tap_op {
OP_SH_TOGGLE = 0xF0,
@ -342,13 +331,13 @@ enum swap_hands_param_tap_op {
OP_SH_ON,
};
#define ACTION_SWAP_HANDS() ACTION_SWAP_HANDS_ON_OFF()
#define ACTION_SWAP_HANDS_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TOGGLE)
#define ACTION_SWAP_HANDS_TAP_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TAP_TOGGLE)
#define ACTION_SWAP_HANDS_TAP_KEY(key) ACTION(ACT_SWAP_HANDS, key)
#define ACTION_SWAP_HANDS_ON_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_ON_OFF)
#define ACTION_SWAP_HANDS_OFF_ON() ACTION(ACT_SWAP_HANDS, OP_SH_OFF_ON)
#define ACTION_SWAP_HANDS_ON() ACTION(ACT_SWAP_HANDS, OP_SH_ON)
#define ACTION_SWAP_HANDS_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_OFF)
#define ACTION_SWAP_HANDS() ACTION_SWAP_HANDS_ON_OFF()
#define ACTION_SWAP_HANDS_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TOGGLE)
#define ACTION_SWAP_HANDS_TAP_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TAP_TOGGLE)
#define ACTION_SWAP_HANDS_TAP_KEY(key) ACTION(ACT_SWAP_HANDS, key)
#define ACTION_SWAP_HANDS_ON_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_ON_OFF)
#define ACTION_SWAP_HANDS_OFF_ON() ACTION(ACT_SWAP_HANDS, OP_SH_OFF_ON)
#define ACTION_SWAP_HANDS_ON() ACTION(ACT_SWAP_HANDS, OP_SH_ON)
#define ACTION_SWAP_HANDS_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_OFF)
#endif /* ACTION_CODE_H */

View file

@ -5,12 +5,11 @@
#include "action_layer.h"
#ifdef DEBUG_ACTION
#include "debug.h"
# include "debug.h"
#else
#include "nodebug.h"
# include "nodebug.h"
#endif
/** \brief Default Layer State
*/
layer_state_t default_layer_state = 0;
@ -19,34 +18,30 @@ layer_state_t default_layer_state = 0;
*
* Run user code on default layer state change
*/
__attribute__((weak))
layer_state_t default_layer_state_set_user(layer_state_t state) {
return state;
}
__attribute__((weak)) layer_state_t default_layer_state_set_user(layer_state_t state) { return state; }
/** \brief Default Layer State Set At Keyboard Level
*
* Run keyboard code on default layer state change
*/
__attribute__((weak))
layer_state_t default_layer_state_set_kb(layer_state_t state) {
return default_layer_state_set_user(state);
}
__attribute__((weak)) layer_state_t default_layer_state_set_kb(layer_state_t state) { return default_layer_state_set_user(state); }
/** \brief Default Layer State Set
*
* Static function to set the default layer state, prints debug info and clears keys
*/
static void default_layer_state_set(layer_state_t state) {
state = default_layer_state_set_kb(state);
debug("default_layer_state: ");
default_layer_debug(); debug(" to ");
default_layer_state = state;
default_layer_debug(); debug("\n");
state = default_layer_state_set_kb(state);
debug("default_layer_state: ");
default_layer_debug();
debug(" to ");
default_layer_state = state;
default_layer_debug();
debug("\n");
#ifdef STRICT_LAYER_RELEASE
clear_keyboard_but_mods(); // To avoid stuck keys
clear_keyboard_but_mods(); // To avoid stuck keys
#else
clear_keyboard_but_mods_and_keys(); // Don't reset held keys
clear_keyboard_but_mods_and_keys(); // Don't reset held keys
#endif
}
@ -54,43 +49,32 @@ static void default_layer_state_set(layer_state_t state) {
*
* Print out the hex value of the 32-bit default layer state, as well as the value of the highest bit.
*/
void default_layer_debug(void) {
dprintf("%08lX(%u)", default_layer_state, biton32(default_layer_state));
}
void default_layer_debug(void) { dprintf("%08lX(%u)", default_layer_state, biton32(default_layer_state)); }
/** \brief Default Layer Set
*
* Sets the default layer state.
*/
void default_layer_set(layer_state_t state) {
default_layer_state_set(state);
}
void default_layer_set(layer_state_t state) { default_layer_state_set(state); }
#ifndef NO_ACTION_LAYER
/** \brief Default Layer Or
*
* Turns on the default layer based on matching bits between specifed layer and existing layer state
*/
void default_layer_or(layer_state_t state) {
default_layer_state_set(default_layer_state | state);
}
void default_layer_or(layer_state_t state) { default_layer_state_set(default_layer_state | state); }
/** \brief Default Layer And
*
* Turns on default layer based on matching enabled bits between specifed layer and existing layer state
*/
void default_layer_and(layer_state_t state) {
default_layer_state_set(default_layer_state & state);
}
void default_layer_and(layer_state_t state) { default_layer_state_set(default_layer_state & state); }
/** \brief Default Layer Xor
*
* Turns on default layer based on non-matching bits between specifed layer and existing layer state
*/
void default_layer_xor(layer_state_t state) {
default_layer_state_set(default_layer_state ^ state);
}
void default_layer_xor(layer_state_t state) { default_layer_state_set(default_layer_state ^ state); }
#endif
#ifndef NO_ACTION_LAYER
/** \brief Keymap Layer State
*/
@ -100,123 +84,101 @@ layer_state_t layer_state = 0;
*
* Runs user code on layer state change
*/
__attribute__((weak))
layer_state_t layer_state_set_user(layer_state_t state) {
return state;
}
__attribute__((weak)) layer_state_t layer_state_set_user(layer_state_t state) { return state; }
/** \brief Layer state set keyboard
*
* Runs keyboard code on layer state change
*/
__attribute__((weak))
layer_state_t layer_state_set_kb(layer_state_t state) {
return layer_state_set_user(state);
}
__attribute__((weak)) layer_state_t layer_state_set_kb(layer_state_t state) { return layer_state_set_user(state); }
/** \brief Layer state set
*
* Sets the layer to match the specifed state (a bitmask)
*/
void layer_state_set(layer_state_t state) {
state = layer_state_set_kb(state);
dprint("layer_state: ");
layer_debug(); dprint(" to ");
layer_state = state;
layer_debug(); dprintln();
#ifdef STRICT_LAYER_RELEASE
clear_keyboard_but_mods(); // To avoid stuck keys
#else
clear_keyboard_but_mods_and_keys(); // Don't reset held keys
#endif
state = layer_state_set_kb(state);
dprint("layer_state: ");
layer_debug();
dprint(" to ");
layer_state = state;
layer_debug();
dprintln();
# ifdef STRICT_LAYER_RELEASE
clear_keyboard_but_mods(); // To avoid stuck keys
# else
clear_keyboard_but_mods_and_keys(); // Don't reset held keys
# endif
}
/** \brief Layer clear
*
* Turn off all layers
*/
void layer_clear(void) {
layer_state_set(0);
}
void layer_clear(void) { layer_state_set(0); }
/** \brief Layer state is
*
* Return whether the given state is on (it might still be shadowed by a higher state, though)
*/
bool layer_state_is(uint8_t layer) {
return layer_state_cmp(layer_state, layer);
}
bool layer_state_is(uint8_t layer) { return layer_state_cmp(layer_state, layer); }
/** \brief Layer state compare
*
* Used for comparing layers {mostly used for unit testing}
*/
bool layer_state_cmp(layer_state_t cmp_layer_state, uint8_t layer) {
if (!cmp_layer_state) { return layer == 0; }
return (cmp_layer_state & (1UL<<layer)) != 0;
if (!cmp_layer_state) {
return layer == 0;
}
return (cmp_layer_state & (1UL << layer)) != 0;
}
/** \brief Layer move
*
* Turns on the given layer and turn off all other layers
*/
void layer_move(uint8_t layer) {
layer_state_set(1UL<<layer);
}
void layer_move(uint8_t layer) { layer_state_set(1UL << layer); }
/** \brief Layer on
*
* Turns on given layer
*/
void layer_on(uint8_t layer) {
layer_state_set(layer_state | (1UL<<layer));
}
void layer_on(uint8_t layer) { layer_state_set(layer_state | (1UL << layer)); }
/** \brief Layer off
*
* Turns off given layer
*/
void layer_off(uint8_t layer) {
layer_state_set(layer_state & ~(1UL<<layer));
}
void layer_off(uint8_t layer) { layer_state_set(layer_state & ~(1UL << layer)); }
/** \brief Layer invert
*
* Toggle the given layer (set it if it's unset, or unset it if it's set)
*/
void layer_invert(uint8_t layer) {
layer_state_set(layer_state ^ (1UL<<layer));
}
void layer_invert(uint8_t layer) { layer_state_set(layer_state ^ (1UL << layer)); }
/** \brief Layer or
*
* Turns on layers based on matching bits between specifed layer and existing layer state
*/
void layer_or(layer_state_t state) {
layer_state_set(layer_state | state);
}
void layer_or(layer_state_t state) { layer_state_set(layer_state | state); }
/** \brief Layer and
*
* Turns on layers based on matching enabled bits between specifed layer and existing layer state
*/
void layer_and(layer_state_t state) {
layer_state_set(layer_state & state);
}
void layer_and(layer_state_t state) { layer_state_set(layer_state & state); }
/** \brief Layer xor
*
* Turns on layers based on non-matching bits between specifed layer and existing layer state
*/
void layer_xor(layer_state_t state) {
layer_state_set(layer_state ^ state);
}
void layer_xor(layer_state_t state) { layer_state_set(layer_state ^ state); }
/** \brief Layer debug printing
*
* Print out the hex value of the 32-bit layer state, as well as the value of the highest bit.
*/
void layer_debug(void) {
dprintf("%08lX(%u)", layer_state, biton32(layer_state));
}
void layer_debug(void) { dprintf("%08lX(%u)", layer_state, biton32(layer_state)); }
#endif
#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
@ -230,16 +192,13 @@ uint8_t source_layers_cache[(MATRIX_ROWS * MATRIX_COLS + 7) / 8][MAX_LAYER_BITS]
* Updates the cached keys when changing layers
*/
void update_source_layers_cache(keypos_t key, uint8_t layer) {
const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
const uint8_t storage_row = key_number / 8;
const uint8_t storage_bit = key_number % 8;
const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
const uint8_t storage_row = key_number / 8;
const uint8_t storage_bit = key_number % 8;
for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
source_layers_cache[storage_row][bit_number] ^=
(-((layer & (1U << bit_number)) != 0)
^ source_layers_cache[storage_row][bit_number])
& (1U << storage_bit);
}
for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
source_layers_cache[storage_row][bit_number] ^= (-((layer & (1U << bit_number)) != 0) ^ source_layers_cache[storage_row][bit_number]) & (1U << storage_bit);
}
}
/** \brief read source layers cache
@ -247,19 +206,16 @@ void update_source_layers_cache(keypos_t key, uint8_t layer) {
* reads the cached keys stored when the layer was changed
*/
uint8_t read_source_layers_cache(keypos_t key) {
const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
const uint8_t storage_row = key_number / 8;
const uint8_t storage_bit = key_number % 8;
uint8_t layer = 0;
const uint8_t key_number = key.col + (key.row * MATRIX_COLS);
const uint8_t storage_row = key_number / 8;
const uint8_t storage_bit = key_number % 8;
uint8_t layer = 0;
for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
layer |=
((source_layers_cache[storage_row][bit_number]
& (1U << storage_bit)) != 0)
<< bit_number;
}
for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) {
layer |= ((source_layers_cache[storage_row][bit_number] & (1U << storage_bit)) != 0) << bit_number;
}
return layer;
return layer;
}
#endif
@ -272,49 +228,47 @@ uint8_t read_source_layers_cache(keypos_t key) {
*/
action_t store_or_get_action(bool pressed, keypos_t key) {
#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
if (disable_action_cache) {
return layer_switch_get_action(key);
}
if (disable_action_cache) {
return layer_switch_get_action(key);
}
uint8_t layer;
uint8_t layer;
if (pressed) {
layer = layer_switch_get_layer(key);
update_source_layers_cache(key, layer);
}
else {
layer = read_source_layers_cache(key);
}
return action_for_key(layer, key);
if (pressed) {
layer = layer_switch_get_layer(key);
update_source_layers_cache(key, layer);
} else {
layer = read_source_layers_cache(key);
}
return action_for_key(layer, key);
#else
return layer_switch_get_action(key);
return layer_switch_get_action(key);
#endif
}
/** \brief Layer switch get layer
*
* Gets the layer based on key info
*/
uint8_t layer_switch_get_layer(keypos_t key) {
#ifndef NO_ACTION_LAYER
action_t action;
action.code = ACTION_TRANSPARENT;
action_t action;
action.code = ACTION_TRANSPARENT;
layer_state_t layers = layer_state | default_layer_state;
/* check top layer first */
for (int8_t i = sizeof(layer_state_t) * 8 - 1; i >= 0; i--) {
if (layers & (1UL << i)) {
action = action_for_key(i, key);
if (action.code != ACTION_TRANSPARENT) {
return i;
}
layer_state_t layers = layer_state | default_layer_state;
/* check top layer first */
for (int8_t i = sizeof(layer_state_t) * 8 - 1; i >= 0; i--) {
if (layers & (1UL << i)) {
action = action_for_key(i, key);
if (action.code != ACTION_TRANSPARENT) {
return i;
}
}
}
}
/* fall back to layer 0 */
return 0;
/* fall back to layer 0 */
return 0;
#else
return biton32(default_layer_state);
return biton32(default_layer_state);
#endif
}
@ -322,6 +276,4 @@ uint8_t layer_switch_get_layer(keypos_t key) {
*
* Gets action code based on key position
*/
action_t layer_switch_get_action(keypos_t key) {
return action_for_key(layer_switch_get_layer(key), key);
}
action_t layer_switch_get_action(keypos_t key) { return action_for_key(layer_switch_get_layer(key), key); }

View file

@ -23,27 +23,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#if defined(LAYER_STATE_8BIT)
typedef uint8_t layer_state_t;
#define get_highest_layer(state) biton8(state)
# define get_highest_layer(state) biton8(state)
#elif defined(LAYER_STATE_16BIT)
typedef uint16_t layer_state_t;
#define get_highest_layer(state) biton16(state)
# define get_highest_layer(state) biton16(state)
#else
typedef uint32_t layer_state_t;
#define get_highest_layer(state) biton32(state)
# define get_highest_layer(state) biton32(state)
#endif
/*
* Default Layer
*/
extern layer_state_t default_layer_state;
void default_layer_debug(void);
void default_layer_set(layer_state_t state);
void default_layer_debug(void);
void default_layer_set(layer_state_t state);
__attribute__((weak))
layer_state_t default_layer_state_set_kb(layer_state_t state);
__attribute__((weak))
layer_state_t default_layer_state_set_user(layer_state_t state);
__attribute__((weak)) layer_state_t default_layer_state_set_kb(layer_state_t state);
__attribute__((weak)) layer_state_t default_layer_state_set_user(layer_state_t state);
#ifndef NO_ACTION_LAYER
/* bitwise operation */
@ -51,12 +48,11 @@ void default_layer_or(layer_state_t state);
void default_layer_and(layer_state_t state);
void default_layer_xor(layer_state_t state);
#else
#define default_layer_or(state)
#define default_layer_and(state)
#define default_layer_xor(state)
# define default_layer_or(state)
# define default_layer_and(state)
# define default_layer_xor(state)
#endif
/*
* Keymap Layer
*/
@ -78,21 +74,21 @@ void layer_or(layer_state_t state);
void layer_and(layer_state_t state);
void layer_xor(layer_state_t state);
#else
#define layer_state 0
# define layer_state 0
#define layer_state_set(layer)
#define layer_state_is(layer) (layer == 0)
#define layer_state_cmp(state, layer) (state == 0 ? layer == 0 : (state & 1UL << layer) != 0)
# define layer_state_set(layer)
# define layer_state_is(layer) (layer == 0)
# define layer_state_cmp(state, layer) (state == 0 ? layer == 0 : (state & 1UL << layer) != 0)
#define layer_debug()
#define layer_clear()
#define layer_move(layer)
#define layer_on(layer)
#define layer_off(layer)
#define layer_invert(layer)
#define layer_or(state)
#define layer_and(state)
#define layer_xor(state)
# define layer_debug()
# define layer_clear()
# define layer_move(layer)
# define layer_on(layer)
# define layer_off(layer)
# define layer_invert(layer)
# define layer_or(state)
# define layer_and(state)
# define layer_xor(state)
#endif
layer_state_t layer_state_set_user(layer_state_t state);
@ -101,8 +97,8 @@ layer_state_t layer_state_set_kb(layer_state_t state);
/* pressed actions cache */
#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE)
/* The number of bits needed to represent the layer number: log2(32). */
#define MAX_LAYER_BITS 5
void update_source_layers_cache(keypos_t key, uint8_t layer);
# define MAX_LAYER_BITS 5
void update_source_layers_cache(keypos_t key, uint8_t layer);
uint8_t read_source_layers_cache(keypos_t key);
#endif
action_t store_or_get_action(bool pressed, keypos_t key);

View file

@ -20,22 +20,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "wait.h"
#ifdef DEBUG_ACTION
#include "debug.h"
# include "debug.h"
#else
#include "nodebug.h"
# include "nodebug.h"
#endif
#ifndef NO_ACTION_MACRO
#define MACRO_READ() (macro = MACRO_GET(macro_p++))
# define MACRO_READ() (macro = MACRO_GET(macro_p++))
/** \brief Action Macro Play
*
* FIXME: Needs doc
*/
void action_macro_play(const macro_t *macro_p)
{
macro_t macro = END;
void action_macro_play(const macro_t *macro_p) {
macro_t macro = END;
uint8_t interval = 0;
if (!macro_p) return;
@ -64,7 +62,10 @@ void action_macro_play(const macro_t *macro_p)
case WAIT:
MACRO_READ();
dprintf("WAIT(%u)\n", macro);
{ uint8_t ms = macro; while (ms--) wait_ms(1); }
{
uint8_t ms = macro;
while (ms--) wait_ms(1);
}
break;
case INTERVAL:
interval = MACRO_READ();
@ -76,14 +77,17 @@ void action_macro_play(const macro_t *macro_p)
break;
case 0x84 ... 0xF3:
dprintf("UP(%02X)\n", macro);
unregister_code(macro&0x7F);
unregister_code(macro & 0x7F);
break;
case END:
default:
return;
}
// interval
{ uint8_t ms = interval; while (ms--) wait_ms(1); }
{
uint8_t ms = interval;
while (ms--) wait_ms(1);
}
}
}
#endif

View file

@ -19,18 +19,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#include "progmem.h"
typedef uint8_t macro_t;
#define MACRO_NONE (macro_t*)0
#define MACRO(...) ({ static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; })
#define MACRO_GET(p) pgm_read_byte(p)
#define MACRO_NONE (macro_t *)0
#define MACRO(...) \
({ \
static const macro_t __m[] PROGMEM = {__VA_ARGS__}; \
&__m[0]; \
})
#define MACRO_GET(p) pgm_read_byte(p)
// Sends press when the macro key is pressed, release when release, or tap_macro when the key has been tapped
#define MACRO_TAP_HOLD(record, press, release, tap_macro) ( ((record)->event.pressed) ? \
( ((record)->tap.count <= 0 || (record)->tap.interrupted) ? (press) : MACRO_NONE ) : \
( ((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (tap_macro) : (release) ) )
#define MACRO_TAP_HOLD(record, press, release, tap_macro) (((record)->event.pressed) ? (((record)->tap.count <= 0 || (record)->tap.interrupted) ? (press) : MACRO_NONE) : (((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (tap_macro) : (release)))
// Holds down the modifier mod when the macro key is held, or sends macro instead when tapped
#define MACRO_TAP_HOLD_MOD(record, macro, mod) MACRO_TAP_HOLD(record, (MACRO(D(mod), END)), MACRO(U(mod), END), macro)
@ -38,25 +38,27 @@ typedef uint8_t macro_t;
// Holds down the modifier mod when the macro key is held, or pressed a shifted key when tapped (eg: shift+3 for #)
#define MACRO_TAP_SHFT_KEY_HOLD_MOD(record, key, mod) MACRO_TAP_HOLD_MOD(record, (MACRO(I(10), D(LSFT), T(key), U(LSFT), END)), mod)
// Momentary switch layer when held, sends macro if tapped
#define MACRO_TAP_HOLD_LAYER(record, macro, layer) ( ((record)->event.pressed) ? \
( ((record)->tap.count <= 0 || (record)->tap.interrupted) ? ({layer_on((layer)); MACRO_NONE; }) : MACRO_NONE ) : \
( ((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (macro) : ({layer_off((layer)); MACRO_NONE; }) ) )
#define MACRO_TAP_HOLD_LAYER(record, macro, layer) \
(((record)->event.pressed) ? (((record)->tap.count <= 0 || (record)->tap.interrupted) ? ({ \
layer_on((layer)); \
MACRO_NONE; \
}) \
: MACRO_NONE) \
: (((record)->tap.count > 0 && !((record)->tap.interrupted)) ? (macro) : ({ \
layer_off((layer)); \
MACRO_NONE; \
})))
// Momentary switch layer when held, presses a shifted key when tapped (eg: shift+3 for #)
#define MACRO_TAP_SHFT_KEY_HOLD_LAYER(record, key, layer) MACRO_TAP_HOLD_LAYER(record, MACRO(I(10), D(LSFT), T(key), U(LSFT), END), layer)
#ifndef NO_ACTION_MACRO
void action_macro_play(const macro_t *macro_p);
#else
#define action_macro_play(macro)
# define action_macro_play(macro)
#endif
/* Macro commands
* code(0x04-73) // key down(1byte)
* code(0x04-73) | 0x80 // key up(1byte)
@ -75,16 +77,16 @@ void action_macro_play(const macro_t *macro_p);
* conditionals
* loop
*/
enum macro_command_id{
enum macro_command_id {
/* 0x00 - 0x03 */
END = 0x00,
END = 0x00,
KEY_DOWN,
KEY_UP,
/* 0x04 - 0x73 (reserved for keycode down) */
/* 0x74 - 0x83 */
WAIT = 0x74,
WAIT = 0x74,
INTERVAL,
/* 0x84 - 0xf3 (reserved for keycode up) */
@ -92,33 +94,31 @@ enum macro_command_id{
/* 0xf4 - 0xff */
};
/* TODO: keycode:0x04-0x73 can be handled by 1byte command else 2bytes are needed
* if keycode between 0x04 and 0x73
* keycode / (keycode|0x80)
* else
* {KEY_DOWN, keycode} / {KEY_UP, keycode}
*/
#define DOWN(key) KEY_DOWN, (key)
#define UP(key) KEY_UP, (key)
#define TYPE(key) DOWN(key), UP(key)
#define WAIT(ms) WAIT, (ms)
#define INTERVAL(ms) INTERVAL, (ms)
*/
#define DOWN(key) KEY_DOWN, (key)
#define UP(key) KEY_UP, (key)
#define TYPE(key) DOWN(key), UP(key)
#define WAIT(ms) WAIT, (ms)
#define INTERVAL(ms) INTERVAL, (ms)
/* key down */
#define D(key) DOWN(KC_##key)
#define D(key) DOWN(KC_##key)
/* key up */
#define U(key) UP(KC_##key)
#define U(key) UP(KC_##key)
/* key type */
#define T(key) TYPE(KC_##key)
#define T(key) TYPE(KC_##key)
/* wait */
#define W(ms) WAIT(ms)
#define W(ms) WAIT(ms)
/* interval */
#define I(ms) INTERVAL(ms)
#define I(ms) INTERVAL(ms)
/* for backward comaptibility */
#define MD(key) DOWN(KC_##key)
#define MU(key) UP(KC_##key)
#define MD(key) DOWN(KC_##key)
#define MU(key) UP(KC_##key)
#endif /* ACTION_MACRO_H */

View file

@ -7,33 +7,30 @@
#include "timer.h"
#ifdef DEBUG_ACTION
#include "debug.h"
# include "debug.h"
#else
#include "nodebug.h"
# include "nodebug.h"
#endif
#ifndef NO_ACTION_TAPPING
#define IS_TAPPING() !IS_NOEVENT(tapping_key.event)
#define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed)
#define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)
#define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k)))
# define IS_TAPPING() !IS_NOEVENT(tapping_key.event)
# define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed)
# define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed)
# define IS_TAPPING_KEY(k) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (k)))
__attribute__ ((weak))
uint16_t get_tapping_term(uint16_t keycode) {
return TAPPING_TERM;
}
__attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode) { return TAPPING_TERM; }
#ifdef TAPPING_TERM_PER_KEY
#define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_event_keycode(tapping_key.event)))
#else
#define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM)
#endif
# ifdef TAPPING_TERM_PER_KEY
# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < get_tapping_term(get_event_keycode(tapping_key.event)))
# else
# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < TAPPING_TERM)
# endif
static keyrecord_t tapping_key = {};
static keyrecord_t tapping_key = {};
static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {};
static uint8_t waiting_buffer_head = 0;
static uint8_t waiting_buffer_tail = 0;
static uint8_t waiting_buffer_head = 0;
static uint8_t waiting_buffer_tail = 0;
static bool process_tapping(keyrecord_t *record);
static bool waiting_buffer_enq(keyrecord_t record);
@ -44,16 +41,16 @@ static void waiting_buffer_scan_tap(void);
static void debug_tapping_key(void);
static void debug_waiting_buffer(void);
/** \brief Action Tapping Process
*
* FIXME: Needs doc
*/
void action_tapping_process(keyrecord_t record)
{
void action_tapping_process(keyrecord_t record) {
if (process_tapping(&record)) {
if (!IS_NOEVENT(record.event)) {
debug("processed: "); debug_record(record); debug("\n");
debug("processed: ");
debug_record(record);
debug("\n");
}
} else {
if (!waiting_buffer_enq(record)) {
@ -71,8 +68,11 @@ void action_tapping_process(keyrecord_t record)
}
for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) {
if (process_tapping(&waiting_buffer[waiting_buffer_tail])) {
debug("processed: waiting_buffer["); debug_dec(waiting_buffer_tail); debug("] = ");
debug_record(waiting_buffer[waiting_buffer_tail]); debug("\n\n");
debug("processed: waiting_buffer[");
debug_dec(waiting_buffer_tail);
debug("] = ");
debug_record(waiting_buffer[waiting_buffer_tail]);
debug("\n\n");
} else {
break;
}
@ -82,15 +82,13 @@ void action_tapping_process(keyrecord_t record)
}
}
/** \brief Tapping
*
* Rule: Tap key is typed(pressed and released) within TAPPING_TERM.
* (without interfering by typing other key)
*/
/* return true when key event is processed or consumed. */
bool process_tapping(keyrecord_t *keyp)
{
bool process_tapping(keyrecord_t *keyp) {
keyevent_t event = keyp->event;
// if tapping
@ -113,12 +111,12 @@ bool process_tapping(keyrecord_t *keyp)
* This can register the key before settlement of tapping,
* useful for long TAPPING_TERM but may prevent fast typing.
*/
#if defined(TAPPING_TERM_PER_KEY) || (!defined(PER_KEY_TAPPING_TERM) && TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD)
#ifdef TAPPING_TERM_PER_KEY
else if ( ( get_tapping_term(get_event_keycode(tapping_key.event)) >= 500) && IS_RELEASED(event) && waiting_buffer_typed(event))
#else
else if ( IS_RELEASED(event) && waiting_buffer_typed(event))
#endif
# if defined(TAPPING_TERM_PER_KEY) || (!defined(PER_KEY_TAPPING_TERM) && TAPPING_TERM >= 500) || defined(PERMISSIVE_HOLD)
# ifdef TAPPING_TERM_PER_KEY
else if ((get_tapping_term(get_event_keycode(tapping_key.event)) >= 500) && IS_RELEASED(event) && waiting_buffer_typed(event))
# else
else if (IS_RELEASED(event) && waiting_buffer_typed(event))
# endif
{
debug("Tapping: End. No tap. Interfered by typing key\n");
process_record(&tapping_key);
@ -127,7 +125,7 @@ bool process_tapping(keyrecord_t *keyp)
// enqueue
return false;
}
#endif
# endif
/* Process release event of a key pressed before tapping starts
* Without this unexpected repeating will occur with having fast repeating setting
* https://github.com/tmk/tmk_keyboard/issues/60
@ -151,8 +149,7 @@ bool process_tapping(keyrecord_t *keyp)
debug("Tapping: release event of a key pressed before tapping\n");
process_record(keyp);
return true;
}
else {
} else {
// set interrupted flag when other key preesed during tapping
if (event.pressed) {
tapping_key.tap.interrupted = true;
@ -164,23 +161,19 @@ bool process_tapping(keyrecord_t *keyp)
// tap_count > 0
else {
if (IS_TAPPING_KEY(event.key) && !event.pressed) {
debug("Tapping: Tap release("); debug_dec(tapping_key.tap.count); debug(")\n");
debug("Tapping: Tap release(");
debug_dec(tapping_key.tap.count);
debug(")\n");
keyp->tap = tapping_key.tap;
process_record(keyp);
tapping_key = *keyp;
debug_tapping_key();
return true;
}
else if (is_tap_key(event.key) && event.pressed) {
} else if (is_tap_key(event.key) && event.pressed) {
if (tapping_key.tap.count > 1) {
debug("Tapping: Start new tap with releasing last tap(>1).\n");
// unregister key
process_record(&(keyrecord_t){
.tap = tapping_key.tap,
.event.key = tapping_key.event.key,
.event.time = event.time,
.event.pressed = false
});
process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false});
} else {
debug("Tapping: Start while last tap(1).\n");
}
@ -188,8 +181,7 @@ bool process_tapping(keyrecord_t *keyp)
waiting_buffer_scan_tap();
debug_tapping_key();
return true;
}
else {
} else {
if (!IS_NOEVENT(event)) {
debug("Tapping: key event while last tap(>0).\n");
}
@ -202,29 +194,24 @@ bool process_tapping(keyrecord_t *keyp)
else {
if (tapping_key.tap.count == 0) {
debug("Tapping: End. Timeout. Not tap(0): ");
debug_event(event); debug("\n");
debug_event(event);
debug("\n");
process_record(&tapping_key);
tapping_key = (keyrecord_t){};
debug_tapping_key();
return false;
} else {
} else {
if (IS_TAPPING_KEY(event.key) && !event.pressed) {
debug("Tapping: End. last timeout tap release(>0).");
keyp->tap = tapping_key.tap;
process_record(keyp);
tapping_key = (keyrecord_t){};
return true;
}
else if (is_tap_key(event.key) && event.pressed) {
} else if (is_tap_key(event.key) && event.pressed) {
if (tapping_key.tap.count > 1) {
debug("Tapping: Start new tap with releasing last timeout tap(>1).\n");
// unregister key
process_record(&(keyrecord_t){
.tap = tapping_key.tap,
.event.key = tapping_key.event.key,
.event.time = event.time,
.event.pressed = false
});
process_record(&(keyrecord_t){.tap = tapping_key.tap, .event.key = tapping_key.event.key, .event.time = event.time, .event.pressed = false});
} else {
debug("Tapping: Start while last timeout tap(1).\n");
}
@ -232,8 +219,7 @@ bool process_tapping(keyrecord_t *keyp)
waiting_buffer_scan_tap();
debug_tapping_key();
return true;
}
else {
} else {
if (!IS_NOEVENT(event)) {
debug("Tapping: key event while last timeout tap(>0).\n");
}
@ -246,18 +232,20 @@ bool process_tapping(keyrecord_t *keyp)
if (WITHIN_TAPPING_TERM(event)) {
if (event.pressed) {
if (IS_TAPPING_KEY(event.key)) {
#ifndef TAPPING_FORCE_HOLD
# ifndef TAPPING_FORCE_HOLD
if (!tapping_key.tap.interrupted && tapping_key.tap.count > 0) {
// sequential tap.
keyp->tap = tapping_key.tap;
if (keyp->tap.count < 15) keyp->tap.count += 1;
debug("Tapping: Tap press("); debug_dec(keyp->tap.count); debug(")\n");
debug("Tapping: Tap press(");
debug_dec(keyp->tap.count);
debug(")\n");
process_record(keyp);
tapping_key = *keyp;
debug_tapping_key();
return true;
}
#endif
# endif
// FIX: start new tap again
tapping_key = *keyp;
return true;
@ -284,7 +272,8 @@ bool process_tapping(keyrecord_t *keyp)
// FIX: process_action here?
// timeout. no sequential tap.
debug("Tapping: End(Timeout after releasing last tap): ");
debug_event(event); debug("\n");
debug_event(event);
debug("\n");
tapping_key = (keyrecord_t){};
debug_tapping_key();
return false;
@ -306,13 +295,11 @@ bool process_tapping(keyrecord_t *keyp)
}
}
/** \brief Waiting buffer enq
*
* FIXME: Needs docs
*/
bool waiting_buffer_enq(keyrecord_t record)
{
bool waiting_buffer_enq(keyrecord_t record) {
if (IS_NOEVENT(record.event)) {
return true;
}
@ -323,9 +310,10 @@ bool waiting_buffer_enq(keyrecord_t record)
}
waiting_buffer[waiting_buffer_head] = record;
waiting_buffer_head = (waiting_buffer_head + 1) % WAITING_BUFFER_SIZE;
waiting_buffer_head = (waiting_buffer_head + 1) % WAITING_BUFFER_SIZE;
debug("waiting_buffer_enq: "); debug_waiting_buffer();
debug("waiting_buffer_enq: ");
debug_waiting_buffer();
return true;
}
@ -333,8 +321,7 @@ bool waiting_buffer_enq(keyrecord_t record)
*
* FIXME: Needs docs
*/
void waiting_buffer_clear(void)
{
void waiting_buffer_clear(void) {
waiting_buffer_head = 0;
waiting_buffer_tail = 0;
}
@ -343,10 +330,9 @@ void waiting_buffer_clear(void)
*
* FIXME: Needs docs
*/
bool waiting_buffer_typed(keyevent_t event)
{
bool waiting_buffer_typed(keyevent_t event) {
for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
if (KEYEQ(event.key, waiting_buffer[i].event.key) && event.pressed != waiting_buffer[i].event.pressed) {
if (KEYEQ(event.key, waiting_buffer[i].event.key) && event.pressed != waiting_buffer[i].event.pressed) {
return true;
}
}
@ -357,9 +343,7 @@ bool waiting_buffer_typed(keyevent_t event)
*
* FIXME: Needs docs
*/
__attribute__((unused))
bool waiting_buffer_has_anykey_pressed(void)
{
__attribute__((unused)) bool waiting_buffer_has_anykey_pressed(void) {
for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
if (waiting_buffer[i].event.pressed) return true;
}
@ -370,47 +354,49 @@ bool waiting_buffer_has_anykey_pressed(void)
*
* FIXME: Needs docs
*/
void waiting_buffer_scan_tap(void)
{
void waiting_buffer_scan_tap(void) {
// tapping already is settled
if (tapping_key.tap.count > 0) return;
// invalid state: tapping_key released && tap.count == 0
if (!tapping_key.event.pressed) return;
for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
if (IS_TAPPING_KEY(waiting_buffer[i].event.key) &&
!waiting_buffer[i].event.pressed &&
WITHIN_TAPPING_TERM(waiting_buffer[i].event)) {
tapping_key.tap.count = 1;
if (IS_TAPPING_KEY(waiting_buffer[i].event.key) && !waiting_buffer[i].event.pressed && WITHIN_TAPPING_TERM(waiting_buffer[i].event)) {
tapping_key.tap.count = 1;
waiting_buffer[i].tap.count = 1;
process_record(&tapping_key);
debug("waiting_buffer_scan_tap: found at ["); debug_dec(i); debug("]\n");
debug("waiting_buffer_scan_tap: found at [");
debug_dec(i);
debug("]\n");
debug_waiting_buffer();
return;
}
}
}
/** \brief Tapping key debug print
*
* FIXME: Needs docs
*/
static void debug_tapping_key(void)
{
debug("TAPPING_KEY="); debug_record(tapping_key); debug("\n");
static void debug_tapping_key(void) {
debug("TAPPING_KEY=");
debug_record(tapping_key);
debug("\n");
}
/** \brief Waiting buffer debug print
*
* FIXME: Needs docs
*/
static void debug_waiting_buffer(void)
{
static void debug_waiting_buffer(void) {
debug("{ ");
for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) {
debug("["); debug_dec(i); debug("]="); debug_record(waiting_buffer[i]); debug(" ");
debug("[");
debug_dec(i);
debug("]=");
debug_record(waiting_buffer[i]);
debug(" ");
}
debug("}\n");
}

View file

@ -17,27 +17,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef ACTION_TAPPING_H
#define ACTION_TAPPING_H
/* period of tapping(ms) */
#ifndef TAPPING_TERM
#define TAPPING_TERM 200
# define TAPPING_TERM 200
#endif
//#define RETRO_TAPPING // Tap anyway, even after TAPPING_TERM, as long as there was no interruption
/* tap count needed for toggling a feature */
#ifndef TAPPING_TOGGLE
#define TAPPING_TOGGLE 5
# define TAPPING_TOGGLE 5
#endif
#define WAITING_BUFFER_SIZE 8
#ifndef NO_ACTION_TAPPING
uint16_t get_event_keycode(keyevent_t event);
uint16_t get_tapping_term(uint16_t keycode);
void action_tapping_process(keyrecord_t record);
void action_tapping_process(keyrecord_t record);
#endif
#endif

View file

@ -24,23 +24,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
extern keymap_config_t keymap_config;
static uint8_t real_mods = 0;
static uint8_t weak_mods = 0;
static uint8_t real_mods = 0;
static uint8_t weak_mods = 0;
static uint8_t macro_mods = 0;
#ifdef USB_6KRO_ENABLE
#define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS)
#define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS)
#define RO_INC(a) RO_ADD(a, 1)
#define RO_DEC(a) RO_SUB(a, 1)
static int8_t cb_head = 0;
static int8_t cb_tail = 0;
# define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS)
# define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS)
# define RO_INC(a) RO_ADD(a, 1)
# define RO_DEC(a) RO_SUB(a, 1)
static int8_t cb_head = 0;
static int8_t cb_tail = 0;
static int8_t cb_count = 0;
#endif
// TODO: pointer variable is not needed
//report_keyboard_t keyboard_report = {};
// report_keyboard_t keyboard_report = {};
report_keyboard_t *keyboard_report = &(report_keyboard_t){};
extern inline void add_key(uint8_t key);
@ -48,10 +47,10 @@ extern inline void del_key(uint8_t key);
extern inline void clear_keys(void);
#ifndef NO_ACTION_ONESHOT
static uint8_t oneshot_mods = 0;
static uint8_t oneshot_mods = 0;
static uint8_t oneshot_locked_mods = 0;
uint8_t get_oneshot_locked_mods(void) { return oneshot_locked_mods; }
void set_oneshot_locked_mods(uint8_t mods) {
uint8_t get_oneshot_locked_mods(void) { return oneshot_locked_mods; }
void set_oneshot_locked_mods(uint8_t mods) {
if (mods != oneshot_locked_mods) {
oneshot_locked_mods = mods;
oneshot_locked_mods_changed_kb(oneshot_locked_mods);
@ -63,16 +62,12 @@ void clear_oneshot_locked_mods(void) {
oneshot_locked_mods_changed_kb(oneshot_locked_mods);
}
}
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
static uint16_t oneshot_time = 0;
bool has_oneshot_mods_timed_out(void) {
return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT;
}
#else
bool has_oneshot_mods_timed_out(void) {
return false;
}
#endif
bool has_oneshot_mods_timed_out(void) { return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; }
# else
bool has_oneshot_mods_timed_out(void) { return false; }
# endif
#endif
/* oneshot layer */
@ -88,44 +83,39 @@ static int8_t oneshot_layer_data = 0;
inline uint8_t get_oneshot_layer(void) { return oneshot_layer_data >> 3; }
inline uint8_t get_oneshot_layer_state(void) { return oneshot_layer_data & 0b111; }
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
static uint16_t oneshot_layer_time = 0;
inline bool has_oneshot_layer_timed_out() {
return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT &&
!(get_oneshot_layer_state() & ONESHOT_TOGGLED);
}
#endif
inline bool has_oneshot_layer_timed_out() { return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && !(get_oneshot_layer_state() & ONESHOT_TOGGLED); }
# endif
/** \brief Set oneshot layer
/** \brief Set oneshot layer
*
* FIXME: needs doc
*/
void set_oneshot_layer(uint8_t layer, uint8_t state)
{
void set_oneshot_layer(uint8_t layer, uint8_t state) {
oneshot_layer_data = layer << 3 | state;
layer_on(layer);
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_layer_time = timer_read();
#endif
# endif
oneshot_layer_changed_kb(get_oneshot_layer());
}
/** \brief Reset oneshot layer
/** \brief Reset oneshot layer
*
* FIXME: needs doc
*/
void reset_oneshot_layer(void) {
oneshot_layer_data = 0;
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_layer_time = 0;
#endif
# endif
oneshot_layer_changed_kb(get_oneshot_layer());
}
/** \brief Clear oneshot layer
/** \brief Clear oneshot layer
*
* FIXME: needs doc
*/
void clear_oneshot_layer_state(oneshot_fullfillment_t state)
{
void clear_oneshot_layer_state(oneshot_fullfillment_t state) {
uint8_t start_state = oneshot_layer_data;
oneshot_layer_data &= ~state;
if (!get_oneshot_layer_state() && start_state != oneshot_layer_data) {
@ -137,10 +127,7 @@ void clear_oneshot_layer_state(oneshot_fullfillment_t state)
*
* FIXME: needs doc
*/
bool is_oneshot_layer_active(void)
{
return get_oneshot_layer_state();
}
bool is_oneshot_layer_active(void) { return get_oneshot_layer_state(); }
#endif
/** \brief Send keyboard report
@ -148,17 +135,17 @@ bool is_oneshot_layer_active(void)
* FIXME: needs doc
*/
void send_keyboard_report(void) {
keyboard_report->mods = real_mods;
keyboard_report->mods = real_mods;
keyboard_report->mods |= weak_mods;
keyboard_report->mods |= macro_mods;
#ifndef NO_ACTION_ONESHOT
if (oneshot_mods) {
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
if (has_oneshot_mods_timed_out()) {
dprintf("Oneshot: timeout\n");
clear_oneshot_mods();
}
#endif
# endif
keyboard_report->mods |= oneshot_mods;
if (has_anykey(keyboard_report)) {
clear_oneshot_mods();
@ -254,90 +241,72 @@ void clear_macro_mods(void) { macro_mods = 0; }
* FIXME: needs doc
*/
void set_oneshot_mods(uint8_t mods) {
if (oneshot_mods != mods) {
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = timer_read();
#endif
oneshot_mods = mods;
oneshot_mods_changed_kb(mods);
}
if (oneshot_mods != mods) {
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = timer_read();
# endif
oneshot_mods = mods;
oneshot_mods_changed_kb(mods);
}
}
/** \brief clear oneshot mods
*
* FIXME: needs doc
*/
void clear_oneshot_mods(void) {
if (oneshot_mods) {
oneshot_mods = 0;
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = 0;
#endif
oneshot_mods_changed_kb(oneshot_mods);
}
if (oneshot_mods) {
oneshot_mods = 0;
# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
oneshot_time = 0;
# endif
oneshot_mods_changed_kb(oneshot_mods);
}
}
/** \brief get oneshot mods
*
* FIXME: needs doc
*/
uint8_t get_oneshot_mods(void)
{
return oneshot_mods;
}
uint8_t get_oneshot_mods(void) { return oneshot_mods; }
#endif
/** \brief Called when the one shot modifiers have been changed.
*
* \param mods Contains the active modifiers active after the change.
*
* \param mods Contains the active modifiers active after the change.
*/
__attribute__((weak))
void oneshot_locked_mods_changed_user(uint8_t mods) { }
__attribute__((weak)) void oneshot_locked_mods_changed_user(uint8_t mods) {}
/** \brief Called when the locked one shot modifiers have been changed.
*
* \param mods Contains the active modifiers active after the change.
*/
__attribute__((weak))
void oneshot_locked_mods_changed_kb(uint8_t mods) {
oneshot_locked_mods_changed_user(mods);
}
/** \brief Called when the one shot modifiers have been changed.
*
*
* \param mods Contains the active modifiers active after the change.
*/
__attribute__((weak))
void oneshot_mods_changed_user(uint8_t mods) { }
__attribute__((weak)) void oneshot_locked_mods_changed_kb(uint8_t mods) { oneshot_locked_mods_changed_user(mods); }
/** \brief Called when the one shot modifiers have been changed.
*
*
* \param mods Contains the active modifiers active after the change.
*/
__attribute__((weak))
void oneshot_mods_changed_kb(uint8_t mods) {
oneshot_mods_changed_user(mods);
}
__attribute__((weak)) void oneshot_mods_changed_user(uint8_t mods) {}
/** \brief Called when the one shot layers have been changed.
*
* \param layer Contains the layer that is toggled on, or zero when toggled off.
/** \brief Called when the one shot modifiers have been changed.
*
* \param mods Contains the active modifiers active after the change.
*/
__attribute__((weak))
void oneshot_layer_changed_user(uint8_t layer) { }
__attribute__((weak)) void oneshot_mods_changed_kb(uint8_t mods) { oneshot_mods_changed_user(mods); }
/** \brief Called when the one shot layers have been changed.
*
*
* \param layer Contains the layer that is toggled on, or zero when toggled off.
*/
__attribute__((weak))
void oneshot_layer_changed_kb(uint8_t layer) {
oneshot_layer_changed_user(layer);
}
__attribute__((weak)) void oneshot_layer_changed_user(uint8_t layer) {}
/** \brief Called when the one shot layers have been changed.
*
* \param layer Contains the layer that is toggled on, or zero when toggled off.
*/
__attribute__((weak)) void oneshot_layer_changed_kb(uint8_t layer) { oneshot_layer_changed_user(layer); }
/** \brief inspect keyboard state
*
* FIXME: needs doc
*/
uint8_t has_anymod(void)
{
return bitpop(real_mods);
}
uint8_t has_anymod(void) { return bitpop(real_mods); }

View file

@ -29,65 +29,54 @@ extern report_keyboard_t *keyboard_report;
void send_keyboard_report(void);
/* key */
inline void add_key(uint8_t key) {
add_key_to_report(keyboard_report, key);
}
inline void add_key(uint8_t key) { add_key_to_report(keyboard_report, key); }
inline void del_key(uint8_t key) {
del_key_from_report(keyboard_report, key);
}
inline void del_key(uint8_t key) { del_key_from_report(keyboard_report, key); }
inline void clear_keys(void) {
clear_keys_from_report(keyboard_report);
}
inline void clear_keys(void) { clear_keys_from_report(keyboard_report); }
/* modifier */
uint8_t get_mods(void);
void add_mods(uint8_t mods);
void del_mods(uint8_t mods);
void set_mods(uint8_t mods);
void clear_mods(void);
void add_mods(uint8_t mods);
void del_mods(uint8_t mods);
void set_mods(uint8_t mods);
void clear_mods(void);
/* weak modifier */
uint8_t get_weak_mods(void);
void add_weak_mods(uint8_t mods);
void del_weak_mods(uint8_t mods);
void set_weak_mods(uint8_t mods);
void clear_weak_mods(void);
void add_weak_mods(uint8_t mods);
void del_weak_mods(uint8_t mods);
void set_weak_mods(uint8_t mods);
void clear_weak_mods(void);
/* macro modifier */
uint8_t get_macro_mods(void);
void add_macro_mods(uint8_t mods);
void del_macro_mods(uint8_t mods);
void set_macro_mods(uint8_t mods);
void clear_macro_mods(void);
void add_macro_mods(uint8_t mods);
void del_macro_mods(uint8_t mods);
void set_macro_mods(uint8_t mods);
void clear_macro_mods(void);
/* oneshot modifier */
void set_oneshot_mods(uint8_t mods);
void set_oneshot_mods(uint8_t mods);
uint8_t get_oneshot_mods(void);
void clear_oneshot_mods(void);
void oneshot_toggle(void);
void oneshot_enable(void);
void oneshot_disable(void);
bool has_oneshot_mods_timed_out(void);
void clear_oneshot_mods(void);
void oneshot_toggle(void);
void oneshot_enable(void);
void oneshot_disable(void);
bool has_oneshot_mods_timed_out(void);
uint8_t get_oneshot_locked_mods(void);
void set_oneshot_locked_mods(uint8_t mods);
void clear_oneshot_locked_mods(void);
void set_oneshot_locked_mods(uint8_t mods);
void clear_oneshot_locked_mods(void);
typedef enum {
ONESHOT_PRESSED = 0b01,
ONESHOT_OTHER_KEY_PRESSED = 0b10,
ONESHOT_START = 0b11,
ONESHOT_TOGGLED = 0b100
} oneshot_fullfillment_t;
void set_oneshot_layer(uint8_t layer, uint8_t state);
typedef enum { ONESHOT_PRESSED = 0b01, ONESHOT_OTHER_KEY_PRESSED = 0b10, ONESHOT_START = 0b11, ONESHOT_TOGGLED = 0b100 } oneshot_fullfillment_t;
void set_oneshot_layer(uint8_t layer, uint8_t state);
uint8_t get_oneshot_layer(void);
void clear_oneshot_layer_state(oneshot_fullfillment_t state);
void reset_oneshot_layer(void);
bool is_oneshot_layer_active(void);
void clear_oneshot_layer_state(oneshot_fullfillment_t state);
void reset_oneshot_layer(void);
bool is_oneshot_layer_active(void);
uint8_t get_oneshot_layer_state(void);
bool has_oneshot_layer_timed_out(void);
bool has_oneshot_layer_timed_out(void);
void oneshot_locked_mods_changed_user(uint8_t mods);
void oneshot_locked_mods_changed_kb(uint8_t mods);

View file

@ -18,34 +18,40 @@
#include "samd51j18a.h"
#include "md_bootloader.h"
//Set watchdog timer to reset. Directs the bootloader to stay in programming mode.
// Set watchdog timer to reset. Directs the bootloader to stay in programming mode.
void bootloader_jump(void) {
#ifdef KEYBOARD_massdrop_ctrl
//CTRL keyboards released with bootloader version below must use RAM method. Otherwise use WDT method.
uint8_t ver_ram_method[] = "v2.18Jun 22 2018 17:28:08"; //The version to match (NULL terminated by compiler)
uint8_t *ver_check = ver_ram_method; //Pointer to version match string for traversal
uint8_t *ver_rom = (uint8_t *)0x21A0; //Pointer to address in ROM where this specific bootloader version would exist
// CTRL keyboards released with bootloader version below must use RAM method. Otherwise use WDT method.
uint8_t ver_ram_method[] = "v2.18Jun 22 2018 17:28:08"; // The version to match (NULL terminated by compiler)
uint8_t *ver_check = ver_ram_method; // Pointer to version match string for traversal
uint8_t *ver_rom = (uint8_t *)0x21A0; // Pointer to address in ROM where this specific bootloader version would exist
while (*ver_check && *ver_rom == *ver_check) { //While there are check version characters to match and bootloader's version matches check's version
ver_check++; //Move check version pointer to next character
ver_rom++; //Move ROM version pointer to next character
while (*ver_check && *ver_rom == *ver_check) { // While there are check version characters to match and bootloader's version matches check's version
ver_check++; // Move check version pointer to next character
ver_rom++; // Move ROM version pointer to next character
}
if (!*ver_check) { //If check version pointer is NULL, all characters have matched
*MAGIC_ADDR = BOOTLOADER_MAGIC; //Set magic number into RAM
NVIC_SystemReset(); //Perform system reset
while (1) {} //Won't get here
if (!*ver_check) { // If check version pointer is NULL, all characters have matched
*MAGIC_ADDR = BOOTLOADER_MAGIC; // Set magic number into RAM
NVIC_SystemReset(); // Perform system reset
while (1) {
} // Won't get here
}
#endif
WDT->CTRLA.bit.ENABLE = 0;
while (WDT->SYNCBUSY.bit.ENABLE) {}
while (WDT->CTRLA.bit.ENABLE) {}
WDT->CONFIG.bit.WINDOW = 0;
WDT->CONFIG.bit.PER = 0;
while (WDT->SYNCBUSY.bit.ENABLE) {
}
while (WDT->CTRLA.bit.ENABLE) {
}
WDT->CONFIG.bit.WINDOW = 0;
WDT->CONFIG.bit.PER = 0;
WDT->EWCTRL.bit.EWOFFSET = 0;
WDT->CTRLA.bit.ENABLE = 1;
while (WDT->SYNCBUSY.bit.ENABLE) {}
while (!WDT->CTRLA.bit.ENABLE) {}
while (1) {} //Wait on timeout
WDT->CTRLA.bit.ENABLE = 1;
while (WDT->SYNCBUSY.bit.ENABLE) {
}
while (!WDT->CTRLA.bit.ENABLE) {
}
while (1) {
} // Wait on timeout
}

View file

@ -21,78 +21,75 @@
static uint8_t buffer[EEPROM_SIZE];
uint8_t eeprom_read_byte(const uint8_t *addr) {
uintptr_t offset = (uintptr_t)addr;
return buffer[offset];
uintptr_t offset = (uintptr_t)addr;
return buffer[offset];
}
void eeprom_write_byte(uint8_t *addr, uint8_t value) {
uintptr_t offset = (uintptr_t)addr;
buffer[offset] = value;
uintptr_t offset = (uintptr_t)addr;
buffer[offset] = value;
}
uint16_t eeprom_read_word(const uint16_t *addr) {
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8);
}
uint32_t eeprom_read_dword(const uint32_t *addr) {
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
| (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24);
}
void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
const uint8_t *p = (const uint8_t *)addr;
uint8_t *dest = (uint8_t *)buf;
while (len--) {
*dest++ = eeprom_read_byte(p++);
}
const uint8_t *p = (const uint8_t *)addr;
uint8_t * dest = (uint8_t *)buf;
while (len--) {
*dest++ = eeprom_read_byte(p++);
}
}
void eeprom_write_word(uint16_t *addr, uint16_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
}
void eeprom_write_dword(uint32_t *addr, uint32_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
}
void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
uint8_t *p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
uint8_t * p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
}
void eeprom_update_byte(uint8_t *addr, uint8_t value) {
eeprom_write_byte(addr, value);
}
void eeprom_update_byte(uint8_t *addr, uint8_t value) { eeprom_write_byte(addr, value); }
void eeprom_update_word(uint16_t *addr, uint16_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
}
void eeprom_update_dword(uint32_t *addr, uint32_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
}
void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
uint8_t *p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
uint8_t * p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
}

View file

@ -17,50 +17,52 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef CONSOLE_ENABLE
#include "samd51j18a.h"
#include "arm_atsam_protocol.h"
#include "printf.h"
#include <string.h>
#include <stdarg.h>
# include "samd51j18a.h"
# include "arm_atsam_protocol.h"
# include "printf.h"
# include <string.h>
# include <stdarg.h>
void console_printf(char *fmt, ...) {
while (udi_hid_con_b_report_trans_ongoing) {} //Wait for any previous transfers to complete
while (udi_hid_con_b_report_trans_ongoing) {
} // Wait for any previous transfers to complete
static char console_printbuf[CONSOLE_PRINTBUF_SIZE]; //Print and send buffer
va_list va;
int result;
static char console_printbuf[CONSOLE_PRINTBUF_SIZE]; // Print and send buffer
va_list va;
int result;
va_start(va, fmt);
result = vsnprintf(console_printbuf, CONSOLE_PRINTBUF_SIZE, fmt, va);
va_end(va);
uint32_t irqflags;
char *pconbuf = console_printbuf; //Pointer to start send from
int send_out = CONSOLE_EPSIZE; //Bytes to send per transfer
char * pconbuf = console_printbuf; // Pointer to start send from
int send_out = CONSOLE_EPSIZE; // Bytes to send per transfer
while (result > 0) { //While not error and bytes remain
while (udi_hid_con_b_report_trans_ongoing) {} //Wait for any previous transfers to complete
while (result > 0) { // While not error and bytes remain
while (udi_hid_con_b_report_trans_ongoing) {
} // Wait for any previous transfers to complete
irqflags = __get_PRIMASK();
__disable_irq();
__DMB();
if (result < CONSOLE_EPSIZE) { //If remaining bytes are less than console epsize
memset(udi_hid_con_report, 0, CONSOLE_EPSIZE); //Clear the buffer
send_out = result; //Send remaining size
if (result < CONSOLE_EPSIZE) { // If remaining bytes are less than console epsize
memset(udi_hid_con_report, 0, CONSOLE_EPSIZE); // Clear the buffer
send_out = result; // Send remaining size
}
memcpy(udi_hid_con_report, pconbuf, send_out); //Copy data into the send buffer
memcpy(udi_hid_con_report, pconbuf, send_out); // Copy data into the send buffer
udi_hid_con_b_report_valid = 1; //Set report valid
udi_hid_con_send_report(); //Send report
udi_hid_con_b_report_valid = 1; // Set report valid
udi_hid_con_send_report(); // Send report
__DMB();
__set_PRIMASK(irqflags);
result -= send_out; //Decrement result by bytes sent
pconbuf += send_out; //Increment buffer point by bytes sent
result -= send_out; // Decrement result by bytes sent
pconbuf += send_out; // Increment buffer point by bytes sent
}
}
#endif //CONSOLE_ENABLE
#endif // CONSOLE_ENABLE

View file

@ -7,5 +7,4 @@ void console_printf(char *fmt, ...);
#define __xprintf console_printf
#endif //_PRINTF_H_
#endif //_PRINTF_H_

View file

@ -7,44 +7,35 @@
*
* FIXME: needs doc
*/
void suspend_idle(uint8_t time) {
/* Note: Not used anywhere currently */
}
void suspend_idle(uint8_t time) { /* Note: Not used anywhere currently */ }
/** \brief Run user level Power down
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void suspend_power_down_user (void) {
}
__attribute__((weak)) void suspend_power_down_user(void) {}
/** \brief Run keyboard level Power down
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void suspend_power_down_kb(void) {
suspend_power_down_user();
}
__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); }
/** \brief Suspend power down
*
* FIXME: needs doc
*/
void suspend_power_down(void)
{
void suspend_power_down(void) {
#ifdef RGB_MATRIX_ENABLE
I2C3733_Control_Set(0); //Disable LED driver
I2C3733_Control_Set(0); // Disable LED driver
#endif
suspend_power_down_kb();
}
__attribute__ ((weak)) void matrix_power_up(void) {}
__attribute__ ((weak)) void matrix_power_down(void) {}
bool suspend_wakeup_condition(void) {
__attribute__((weak)) void matrix_power_up(void) {}
__attribute__((weak)) void matrix_power_down(void) {}
bool suspend_wakeup_condition(void) {
matrix_power_up();
matrix_scan();
matrix_power_down();
@ -58,19 +49,13 @@ bool suspend_wakeup_condition(void) {
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void suspend_wakeup_init_user(void) {
}
__attribute__((weak)) void suspend_wakeup_init_user(void) {}
/** \brief run keyboard level code immediately after wakeup
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void suspend_wakeup_init_kb(void) {
suspend_wakeup_init_user();
}
__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); }
/** \brief run immediately after wakeup
*
@ -78,15 +63,14 @@ void suspend_wakeup_init_kb(void) {
*/
void suspend_wakeup_init(void) {
#ifdef RGB_MATRIX_ENABLE
#ifdef USE_MASSDROP_CONFIGURATOR
# ifdef USE_MASSDROP_CONFIGURATOR
if (led_enabled) {
I2C3733_Control_Set(1);
}
#else
# else
I2C3733_Control_Set(1);
#endif
# endif
#endif
suspend_wakeup_init_kb();
}

View file

@ -2,42 +2,18 @@
#include "timer.h"
#include "tmk_core/protocol/arm_atsam/clks.h"
void set_time(uint64_t tset)
{
ms_clk = tset;
}
void set_time(uint64_t tset) { ms_clk = tset; }
void timer_init(void)
{
timer_clear();
}
void timer_init(void) { timer_clear(); }
uint16_t timer_read(void)
{
return (uint16_t)ms_clk;
}
uint16_t timer_read(void) { return (uint16_t)ms_clk; }
uint32_t timer_read32(void)
{
return (uint32_t)ms_clk;
}
uint32_t timer_read32(void) { return (uint32_t)ms_clk; }
uint64_t timer_read64(void)
{
return ms_clk;
}
uint64_t timer_read64(void) { return ms_clk; }
uint16_t timer_elapsed(uint16_t tlast)
{
return TIMER_DIFF_16(timer_read(), tlast);
}
uint16_t timer_elapsed(uint16_t tlast) { return TIMER_DIFF_16(timer_read(), tlast); }
uint32_t timer_elapsed32(uint32_t tlast)
{
return TIMER_DIFF_32(timer_read32(), tlast);
}
uint32_t timer_elapsed32(uint32_t tlast) { return TIMER_DIFF_32(timer_read32(), tlast); }
void timer_clear(void)
{
set_time(0);
}
void timer_clear(void) { set_time(0); }

View file

@ -9,10 +9,9 @@
#include <avr/boot.h>
#ifdef PROTOCOL_LUFA
#include <LUFA/Drivers/USB/USB.h>
# include <LUFA/Drivers/USB/USB.h>
#endif
/** \brief Bootloader Size in *bytes*
*
* AVR Boot section size are defined by setting BOOTSZ fuse in fact. Consult with your MCU datasheet.
@ -57,19 +56,19 @@
#define FLASH_SIZE (FLASHEND + 1L)
#if !defined(BOOTLOADER_SIZE)
uint16_t bootloader_start;
uint16_t bootloader_start;
#endif
#define BOOT_SIZE_256 0b110
#define BOOT_SIZE_512 0b100
#define BOOT_SIZE_256 0b110
#define BOOT_SIZE_512 0b100
#define BOOT_SIZE_1024 0b010
#define BOOT_SIZE_2048 0b000
//compatibility between ATMega8 and ATMega88
#if !defined (MCUCSR)
#if defined (MCUSR)
#define MCUCSR MCUSR
#endif
// compatibility between ATMega8 and ATMega88
#if !defined(MCUCSR)
# if defined(MCUSR)
# define MCUCSR MCUSR
# endif
#endif
/** \brief Entering the Bootloader via Software
@ -77,163 +76,223 @@
* http://www.fourwalledcubicle.com/files/LUFA/Doc/120730/html/_page__software_bootloader_start.html
*/
#define BOOTLOADER_RESET_KEY 0xB007B007
uint32_t reset_key __attribute__ ((section (".noinit,\"aw\",@nobits;")));
uint32_t reset_key __attribute__((section(".noinit,\"aw\",@nobits;")));
/** \brief initialize MCU status by watchdog reset
*
* FIXME: needs doc
*/
void bootloader_jump(void) {
#if !defined(BOOTLOADER_SIZE)
uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
#if !defined(BOOTLOADER_SIZE)
uint8_t high_fuse = boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS);
if (high_fuse & BOOT_SIZE_256) {
bootloader_start = (FLASH_SIZE - 512) >> 1;
} else if (high_fuse & BOOT_SIZE_512) {
bootloader_start = (FLASH_SIZE - 1024) >> 1;
} else if (high_fuse & BOOT_SIZE_1024) {
bootloader_start = (FLASH_SIZE - 2048) >> 1;
} else {
bootloader_start = (FLASH_SIZE - 4096) >> 1;
}
#endif
if (high_fuse & BOOT_SIZE_256) {
bootloader_start = (FLASH_SIZE - 512) >> 1;
} else if (high_fuse & BOOT_SIZE_512) {
bootloader_start = (FLASH_SIZE - 1024) >> 1;
} else if (high_fuse & BOOT_SIZE_1024) {
bootloader_start = (FLASH_SIZE - 2048) >> 1;
} else {
bootloader_start = (FLASH_SIZE - 4096) >> 1;
}
#endif
// Something like this might work, but it compiled larger than the block above
// bootloader_start = FLASH_SIZE - (256 << (~high_fuse & 0b110 >> 1));
#if defined(BOOTLOADER_HALFKAY)
// http://www.pjrc.com/teensy/jump_to_bootloader.html
cli();
// disable watchdog, if enabled (it's not)
// disable all peripherals
// a shutdown call might make sense here
UDCON = 1;
USBCON = (1 << FRZCLK); // disable USB
UCSR1B = 0;
_delay_ms(5);
# if defined(__AVR_AT90USB162__) // Teensy 1.0
EIMSK = 0;
PCICR = 0;
SPCR = 0;
ACSR = 0;
EECR = 0;
TIMSK0 = 0;
TIMSK1 = 0;
UCSR1B = 0;
DDRB = 0;
DDRC = 0;
DDRD = 0;
PORTB = 0;
PORTC = 0;
PORTD = 0;
asm volatile("jmp 0x3E00");
# elif defined(__AVR_ATmega32U4__) // Teensy 2.0
EIMSK = 0;
PCICR = 0;
SPCR = 0;
ACSR = 0;
EECR = 0;
ADCSRA = 0;
TIMSK0 = 0;
TIMSK1 = 0;
TIMSK3 = 0;
TIMSK4 = 0;
UCSR1B = 0;
TWCR = 0;
DDRB = 0;
DDRC = 0;
DDRD = 0;
DDRE = 0;
DDRF = 0;
TWCR = 0;
PORTB = 0;
PORTC = 0;
PORTD = 0;
PORTE = 0;
PORTF = 0;
asm volatile("jmp 0x7E00");
# elif defined(__AVR_AT90USB646__) // Teensy++ 1.0
EIMSK = 0;
PCICR = 0;
SPCR = 0;
ACSR = 0;
EECR = 0;
ADCSRA = 0;
TIMSK0 = 0;
TIMSK1 = 0;
TIMSK2 = 0;
TIMSK3 = 0;
UCSR1B = 0;
TWCR = 0;
DDRA = 0;
DDRB = 0;
DDRC = 0;
DDRD = 0;
DDRE = 0;
DDRF = 0;
PORTA = 0;
PORTB = 0;
PORTC = 0;
PORTD = 0;
PORTE = 0;
PORTF = 0;
asm volatile("jmp 0xFC00");
# elif defined(__AVR_AT90USB1286__) // Teensy++ 2.0
EIMSK = 0;
PCICR = 0;
SPCR = 0;
ACSR = 0;
EECR = 0;
ADCSRA = 0;
TIMSK0 = 0;
TIMSK1 = 0;
TIMSK2 = 0;
TIMSK3 = 0;
UCSR1B = 0;
TWCR = 0;
DDRA = 0;
DDRB = 0;
DDRC = 0;
DDRD = 0;
DDRE = 0;
DDRF = 0;
PORTA = 0;
PORTB = 0;
PORTC = 0;
PORTD = 0;
PORTE = 0;
PORTF = 0;
asm volatile("jmp 0x1FC00");
# endif
#if defined(BOOTLOADER_HALFKAY)
// http://www.pjrc.com/teensy/jump_to_bootloader.html
cli();
// disable watchdog, if enabled (it's not)
// disable all peripherals
// a shutdown call might make sense here
UDCON = 1;
USBCON = (1<<FRZCLK); // disable USB
UCSR1B = 0;
_delay_ms(5);
#if defined(__AVR_AT90USB162__) // Teensy 1.0
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0;
TIMSK0 = 0; TIMSK1 = 0; UCSR1B = 0;
DDRB = 0; DDRC = 0; DDRD = 0;
PORTB = 0; PORTC = 0; PORTD = 0;
asm volatile("jmp 0x3E00");
#elif defined(__AVR_ATmega32U4__) // Teensy 2.0
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
TIMSK0 = 0; TIMSK1 = 0; TIMSK3 = 0; TIMSK4 = 0; UCSR1B = 0; TWCR = 0;
DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0; TWCR = 0;
PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
asm volatile("jmp 0x7E00");
#elif defined(__AVR_AT90USB646__) // Teensy++ 1.0
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
asm volatile("jmp 0xFC00");
#elif defined(__AVR_AT90USB1286__) // Teensy++ 2.0
EIMSK = 0; PCICR = 0; SPCR = 0; ACSR = 0; EECR = 0; ADCSRA = 0;
TIMSK0 = 0; TIMSK1 = 0; TIMSK2 = 0; TIMSK3 = 0; UCSR1B = 0; TWCR = 0;
DDRA = 0; DDRB = 0; DDRC = 0; DDRD = 0; DDRE = 0; DDRF = 0;
PORTA = 0; PORTB = 0; PORTC = 0; PORTD = 0; PORTE = 0; PORTF = 0;
asm volatile("jmp 0x1FC00");
#endif
#elif defined(BOOTLOADER_CATERINA)
// this block may be optional
// TODO: figure it out
#elif defined(BOOTLOADER_CATERINA)
// this block may be optional
// TODO: figure it out
uint16_t *const bootKeyPtr = (uint16_t *)0x0800;
uint16_t *const bootKeyPtr = (uint16_t *)0x0800;
// Value used by Caterina bootloader use to determine whether to run the
// sketch or the bootloader programmer.
uint16_t bootKey = 0x7777;
// Value used by Caterina bootloader use to determine whether to run the
// sketch or the bootloader programmer.
uint16_t bootKey = 0x7777;
*bootKeyPtr = bootKey;
*bootKeyPtr = bootKey;
// setup watchdog timeout
wdt_enable(WDTO_60MS);
// setup watchdog timeout
wdt_enable(WDTO_60MS);
while (1) {
} // wait for watchdog timer to trigger
while(1) {} // wait for watchdog timer to trigger
#elif defined(BOOTLOADER_USBASP)
// Taken with permission of Stephan Baerwolf from https://github.com/tinyusbboard/API/blob/master/apipage.c
wdt_enable(WDTO_15MS);
wdt_reset();
asm volatile("cli \n\t"
"ldi r29 , %[ramendhi] \n\t"
"ldi r28 , %[ramendlo] \n\t"
# if (FLASHEND > 131071)
"ldi r18 , %[bootaddrhi] \n\t"
"st Y+, r18 \n\t"
# endif
"ldi r18 , %[bootaddrme] \n\t"
"st Y+, r18 \n\t"
"ldi r18 , %[bootaddrlo] \n\t"
"st Y+, r18 \n\t"
"out %[mcucsrio], __zero_reg__ \n\t"
"bootloader_startup_loop%=: \n\t"
"rjmp bootloader_startup_loop%= \n\t"
:
: [ mcucsrio ] "I"(_SFR_IO_ADDR(MCUCSR)),
# if (FLASHEND > 131071)
[ ramendhi ] "M"(((RAMEND - 2) >> 8) & 0xff), [ ramendlo ] "M"(((RAMEND - 2) >> 0) & 0xff), [ bootaddrhi ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 16) & 0xff),
# else
[ ramendhi ] "M"(((RAMEND - 1) >> 8) & 0xff), [ ramendlo ] "M"(((RAMEND - 1) >> 0) & 0xff),
# endif
[ bootaddrme ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), [ bootaddrlo ] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff));
#elif defined(BOOTLOADER_USBASP)
// Taken with permission of Stephan Baerwolf from https://github.com/tinyusbboard/API/blob/master/apipage.c
wdt_enable(WDTO_15MS);
wdt_reset();
asm volatile (
"cli \n\t"
"ldi r29 , %[ramendhi] \n\t"
"ldi r28 , %[ramendlo] \n\t"
#if (FLASHEND>131071)
"ldi r18 , %[bootaddrhi] \n\t"
"st Y+, r18 \n\t"
#endif
"ldi r18 , %[bootaddrme] \n\t"
"st Y+, r18 \n\t"
"ldi r18 , %[bootaddrlo] \n\t"
"st Y+, r18 \n\t"
"out %[mcucsrio], __zero_reg__ \n\t"
"bootloader_startup_loop%=: \n\t"
"rjmp bootloader_startup_loop%= \n\t"
:
: [mcucsrio] "I" (_SFR_IO_ADDR(MCUCSR)),
#if (FLASHEND>131071)
[ramendhi] "M" (((RAMEND - 2) >> 8) & 0xff),
[ramendlo] "M" (((RAMEND - 2) >> 0) & 0xff),
[bootaddrhi] "M" ((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >>16) & 0xff),
#else
[ramendhi] "M" (((RAMEND - 1) >> 8) & 0xff),
[ramendlo] "M" (((RAMEND - 1) >> 0) & 0xff),
#endif
[bootaddrme] "M" ((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff),
[bootaddrlo] "M" ((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff)
);
#else // Assume remaining boards are DFU, even if the flag isn't set
#else // Assume remaining boards are DFU, even if the flag isn't set
# if !(defined(__AVR_ATmega32A__) || defined(__AVR_ATmega328P__)) // no USB - maybe BOOTLOADER_BOOTLOADHID instead though?
UDCON = 1;
USBCON = (1 << FRZCLK); // disable USB
UCSR1B = 0;
_delay_ms(5); // 5 seems to work fine
# endif
#if !(defined(__AVR_ATmega32A__) || defined(__AVR_ATmega328P__)) // no USB - maybe BOOTLOADER_BOOTLOADHID instead though?
UDCON = 1;
USBCON = (1<<FRZCLK); // disable USB
UCSR1B = 0;
_delay_ms(5); // 5 seems to work fine
#endif
#ifdef BOOTLOADER_BOOTLOADHID
// force bootloadHID to stay in bootloader mode, so that it waits
// for a new firmware to be flashed
eeprom_write_byte((uint8_t *)1, 0x00);
#endif
// watchdog reset
reset_key = BOOTLOADER_RESET_KEY;
wdt_enable(WDTO_250MS);
for (;;);
#endif
# ifdef BOOTLOADER_BOOTLOADHID
// force bootloadHID to stay in bootloader mode, so that it waits
// for a new firmware to be flashed
eeprom_write_byte((uint8_t *)1, 0x00);
# endif
// watchdog reset
reset_key = BOOTLOADER_RESET_KEY;
wdt_enable(WDTO_250MS);
for (;;)
;
#endif
}
/* this runs before main() */
void bootloader_jump_after_watchdog_reset(void) __attribute__ ((used, naked, section (".init3")));
void bootloader_jump_after_watchdog_reset(void)
{
#ifndef BOOTLOADER_HALFKAY
if ((MCUCSR & (1<<WDRF)) && reset_key == BOOTLOADER_RESET_KEY) {
reset_key = 0;
void bootloader_jump_after_watchdog_reset(void) __attribute__((used, naked, section(".init3")));
void bootloader_jump_after_watchdog_reset(void) {
#ifndef BOOTLOADER_HALFKAY
if ((MCUCSR & (1 << WDRF)) && reset_key == BOOTLOADER_RESET_KEY) {
reset_key = 0;
// My custom USBasploader requires this to come up.
MCUCSR = 0;
// My custom USBasploader requires this to come up.
MCUCSR = 0;
// Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog.
MCUCSR &= ~(1<<WDRF);
wdt_disable();
// Seems like Teensy halfkay loader requires clearing WDRF and disabling watchdog.
MCUCSR &= ~(1 << WDRF);
wdt_disable();
// This is compled into 'icall', address should be in word unit, not byte.
#ifdef BOOTLOADER_SIZE
((void (*)(void))( (FLASH_SIZE - BOOTLOADER_SIZE) >> 1))();
#else
asm("ijmp" :: "z" (bootloader_start));
#endif
}
#endif
// This is compled into 'icall', address should be in word unit, not byte.
# ifdef BOOTLOADER_SIZE
((void (*)(void))((FLASH_SIZE - BOOTLOADER_SIZE) >> 1))();
# else
asm("ijmp" ::"z"(bootloader_start));
# endif
}
#endif
}

View file

@ -16,14 +16,13 @@
* 256*64 interrupts/second
* F_CPU/(256*64) clocks/interrupt
*/
#define SLEEP_LED_TIMER_TOP F_CPU/(256*64)
#define SLEEP_LED_TIMER_TOP F_CPU / (256 * 64)
/** \brief Sleep LED initialization
*
* FIXME: needs doc
*/
void sleep_led_init(void)
{
void sleep_led_init(void) {
/* Timer1 setup */
/* CTC mode */
TCCR1B |= _BV(WGM12);
@ -32,17 +31,16 @@ void sleep_led_init(void)
/* Set TOP value */
uint8_t sreg = SREG;
cli();
OCR1AH = (SLEEP_LED_TIMER_TOP>>8)&0xff;
OCR1AL = SLEEP_LED_TIMER_TOP&0xff;
SREG = sreg;
OCR1AH = (SLEEP_LED_TIMER_TOP >> 8) & 0xff;
OCR1AL = SLEEP_LED_TIMER_TOP & 0xff;
SREG = sreg;
}
/** \brief Sleep LED enable
*
* FIXME: needs doc
*/
void sleep_led_enable(void)
{
void sleep_led_enable(void) {
/* Enable Compare Match Interrupt */
TIMSK1 |= _BV(OCIE1A);
}
@ -51,8 +49,7 @@ void sleep_led_enable(void)
*
* FIXME: needs doc
*/
void sleep_led_disable(void)
{
void sleep_led_disable(void) {
/* Disable Compare Match Interrupt */
TIMSK1 &= ~_BV(OCIE1A);
}
@ -61,13 +58,11 @@ void sleep_led_disable(void)
*
* FIXME: needs doc
*/
void sleep_led_toggle(void)
{
void sleep_led_toggle(void) {
/* Disable Compare Match Interrupt */
TIMSK1 ^= _BV(OCIE1A);
}
/** \brief Breathing Sleep LED brighness(PWM On period) table
*
* (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
@ -75,15 +70,9 @@ void sleep_led_toggle(void)
* http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
* (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
*/
static const uint8_t breathing_table[64] PROGMEM = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10,
15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23,
15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static const uint8_t breathing_table[64] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
ISR(TIMER1_COMPA_vect)
{
ISR(TIMER1_COMPA_vect) {
/* Software PWM
* timer:1111 1111 1111 1111
* \_____/\/ \_______/____ count(0-255)
@ -93,17 +82,17 @@ ISR(TIMER1_COMPA_vect)
static union {
uint16_t row;
struct {
uint8_t count:8;
uint8_t duration:2;
uint8_t index:6;
uint8_t count : 8;
uint8_t duration : 2;
uint8_t index : 6;
} pwm;
} timer = { .row = 0 };
} timer = {.row = 0};
timer.row++;
// LED on
if (timer.pwm.count == 0) {
led_set(1<<USB_LED_CAPS_LOCK);
led_set(1 << USB_LED_CAPS_LOCK);
}
// LED off
if (timer.pwm.count == pgm_read_byte(&breathing_table[timer.pwm.index])) {

View file

@ -13,37 +13,36 @@
#include "rgblight_reconfig.h"
#ifdef PROTOCOL_LUFA
#include "lufa.h"
# include "lufa.h"
#endif
#ifdef AUDIO_ENABLE
#include "audio.h"
# include "audio.h"
#endif /* AUDIO_ENABLE */
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
#include "rgblight.h"
extern rgblight_config_t rgblight_config;
static bool rgblight_enabled;
static bool is_suspended;
# include "rgblight.h"
extern rgblight_config_t rgblight_config;
static bool rgblight_enabled;
static bool is_suspended;
#endif
#define wdt_intr_enable(value) \
__asm__ __volatile__ ( \
"in __tmp_reg__,__SREG__" "\n\t" \
"cli" "\n\t" \
"wdr" "\n\t" \
"sts %0,%1" "\n\t" \
"out __SREG__,__tmp_reg__" "\n\t" \
"sts %0,%2" "\n\t" \
: /* no outputs */ \
: "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
"r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
"r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
_BV(WDIE) | (value & 0x07)) ) \
: "r0" \
)
#define wdt_intr_enable(value) \
__asm__ __volatile__("in __tmp_reg__,__SREG__" \
"\n\t" \
"cli" \
"\n\t" \
"wdr" \
"\n\t" \
"sts %0,%1" \
"\n\t" \
"out __SREG__,__tmp_reg__" \
"\n\t" \
"sts %0,%2" \
"\n\t" \
: /* no outputs */ \
: "M"(_SFR_MEM_ADDR(_WD_CONTROL_REG)), "r"(_BV(_WD_CHANGE_BIT) | _BV(WDE)), "r"((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) | _BV(WDIE) | (value & 0x07))) \
: "r0")
/** \brief Suspend idle
*
@ -58,23 +57,18 @@ void suspend_idle(uint8_t time) {
sleep_disable();
}
// TODO: This needs some cleanup
/** \brief Run keyboard level Power down
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void suspend_power_down_user (void) { }
__attribute__((weak)) void suspend_power_down_user(void) {}
/** \brief Run keyboard level Power down
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void suspend_power_down_kb(void) {
suspend_power_down_user();
}
__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); }
#ifndef NO_SUSPEND_POWER_DOWN
/** \brief Power down MCU with watchdog timer
@ -98,43 +92,43 @@ static uint8_t wdt_timeout = 0;
* FIXME: needs doc
*/
static void power_down(uint8_t wdto) {
#ifdef PROTOCOL_LUFA
if (USB_DeviceState == DEVICE_STATE_Configured) return;
#endif
wdt_timeout = wdto;
# ifdef PROTOCOL_LUFA
if (USB_DeviceState == DEVICE_STATE_Configured) return;
# endif
wdt_timeout = wdto;
// Watchdog Interrupt Mode
wdt_intr_enable(wdto);
// Watchdog Interrupt Mode
wdt_intr_enable(wdto);
#ifdef BACKLIGHT_ENABLE
backlight_set(0);
#endif
# ifdef BACKLIGHT_ENABLE
backlight_set(0);
# endif
// Turn off LED indicators
uint8_t leds_off = 0;
#if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
if (is_backlight_enabled()) {
// Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off
leds_off |= (1<<USB_LED_CAPS_LOCK);
}
#endif
led_set(leds_off);
// Turn off LED indicators
uint8_t leds_off = 0;
# if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
if (is_backlight_enabled()) {
// Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off
leds_off |= (1 << USB_LED_CAPS_LOCK);
}
# endif
led_set(leds_off);
#ifdef AUDIO_ENABLE
// This sometimes disables the start-up noise, so it's been disabled
// stop_all_notes();
#endif /* AUDIO_ENABLE */
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
#ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_disable();
#endif
if (!is_suspended) {
is_suspended = true;
rgblight_enabled = rgblight_config.enable;
rgblight_disable_noeeprom();
}
#endif
suspend_power_down_kb();
# ifdef AUDIO_ENABLE
// This sometimes disables the start-up noise, so it's been disabled
// stop_all_notes();
# endif /* AUDIO_ENABLE */
# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
# ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_disable();
# endif
if (!is_suspended) {
is_suspended = true;
rgblight_enabled = rgblight_config.enable;
rgblight_disable_noeeprom();
}
# endif
suspend_power_down_kb();
// TODO: more power saving
// See PicoPower application note
@ -158,40 +152,36 @@ static void power_down(uint8_t wdto) {
* FIXME: needs doc
*/
void suspend_power_down(void) {
suspend_power_down_kb();
suspend_power_down_kb();
#ifndef NO_SUSPEND_POWER_DOWN
power_down(WDTO_15MS);
#endif
}
__attribute__ ((weak)) void matrix_power_up(void) {}
__attribute__ ((weak)) void matrix_power_down(void) {}
bool suspend_wakeup_condition(void) {
__attribute__((weak)) void matrix_power_up(void) {}
__attribute__((weak)) void matrix_power_down(void) {}
bool suspend_wakeup_condition(void) {
matrix_power_up();
matrix_scan();
matrix_power_down();
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
if (matrix_get_row(r)) return true;
}
return false;
return false;
}
/** \brief run user level code immediately after wakeup
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void suspend_wakeup_init_user(void) { }
__attribute__((weak)) void suspend_wakeup_init_user(void) {}
/** \brief run keyboard level code immediately after wakeup
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void suspend_wakeup_init_kb(void) {
suspend_wakeup_init_user();
}
__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); }
/** \brief run immediately after wakeup
*
* FIXME: needs doc
@ -202,18 +192,18 @@ void suspend_wakeup_init(void) {
#ifdef BACKLIGHT_ENABLE
backlight_init();
#endif
led_set(host_keyboard_leds());
led_set(host_keyboard_leds());
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
is_suspended = false;
if (rgblight_enabled) {
#ifdef BOOTLOADER_TEENSY
wait_ms(10);
#endif
rgblight_enable_noeeprom();
}
#ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_enable();
#endif
is_suspended = false;
if (rgblight_enabled) {
# ifdef BOOTLOADER_TEENSY
wait_ms(10);
# endif
rgblight_enable_noeeprom();
}
# ifdef RGBLIGHT_ANIMATIONS
rgblight_timer_enable();
# endif
#endif
suspend_wakeup_init_kb();
}
@ -226,8 +216,7 @@ ISR(WDT_vect) {
case WDTO_15MS:
timer_count += 15 + 2; // WDTO_15MS + 2(from observation)
break;
default:
;
default:;
}
}
#endif

View file

@ -7,21 +7,21 @@
#include <avr/wdt.h>
#include <avr/interrupt.h>
#define wdt_intr_enable(value) \
__asm__ __volatile__ ( \
"in __tmp_reg__,__SREG__" "\n\t" \
"cli" "\n\t" \
"wdr" "\n\t" \
"sts %0,%1" "\n\t" \
"out __SREG__,__tmp_reg__" "\n\t" \
"sts %0,%2" "\n\t" \
: /* no outputs */ \
: "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
"r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
"r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
_BV(WDIE) | (value & 0x07)) ) \
: "r0" \
)
#define wdt_intr_enable(value) \
__asm__ __volatile__("in __tmp_reg__,__SREG__" \
"\n\t" \
"cli" \
"\n\t" \
"wdr" \
"\n\t" \
"sts %0,%1" \
"\n\t" \
"out __SREG__,__tmp_reg__" \
"\n\t" \
"sts %0,%2" \
"\n\t" \
: /* no outputs */ \
: "M"(_SFR_MEM_ADDR(_WD_CONTROL_REG)), "r"(_BV(_WD_CHANGE_BIT) | _BV(WDE)), "r"((uint8_t)((value & 0x08 ? _WD_PS3_MASK : 0x00) | _BV(WDIE) | (value & 0x07))) \
: "r0")
#endif

View file

@ -22,7 +22,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "timer_avr.h"
#include "timer.h"
// counter resolution 1ms
// NOTE: union { uint32_t timer32; struct { uint16_t dummy; uint16_t timer16; }}
volatile uint32_t timer_count;
@ -31,8 +30,7 @@ volatile uint32_t timer_count;
*
* FIXME: needs doc
*/
void timer_init(void)
{
void timer_init(void) {
#if TIMER_PRESCALER == 1
uint8_t prescaler = 0x01;
#elif TIMER_PRESCALER == 8
@ -44,7 +42,7 @@ void timer_init(void)
#elif TIMER_PRESCALER == 1024
uint8_t prescaler = 0x05;
#else
# error "Timer prescaler value is NOT vaild."
# error "Timer prescaler value is NOT vaild."
#endif
#ifndef __AVR_ATmega32A__
@ -53,13 +51,13 @@ void timer_init(void)
TCCR0B = prescaler;
OCR0A = TIMER_RAW_TOP;
TIMSK0 = (1<<OCIE0A);
OCR0A = TIMER_RAW_TOP;
TIMSK0 = (1 << OCIE0A);
#else
// Timer0 CTC mode
TCCR0 = (1 << WGM01) | prescaler;
OCR0 = TIMER_RAW_TOP;
OCR0 = TIMER_RAW_TOP;
TIMSK = (1 << OCIE0);
#endif
}
@ -68,26 +66,18 @@ void timer_init(void)
*
* FIXME: needs doc
*/
inline
void timer_clear(void)
{
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
timer_count = 0;
}
inline void timer_clear(void) {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { timer_count = 0; }
}
/** \brief timer read
*
* FIXME: needs doc
*/
inline
uint16_t timer_read(void)
{
inline uint16_t timer_read(void) {
uint32_t t;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
t = timer_count;
}
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { t = timer_count; }
return (t & 0xFFFF);
}
@ -96,14 +86,10 @@ uint16_t timer_read(void)
*
* FIXME: needs doc
*/
inline
uint32_t timer_read32(void)
{
inline uint32_t timer_read32(void) {
uint32_t t;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
t = timer_count;
}
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { t = timer_count; }
return t;
}
@ -112,14 +98,10 @@ uint32_t timer_read32(void)
*
* FIXME: needs doc
*/
inline
uint16_t timer_elapsed(uint16_t last)
{
inline uint16_t timer_elapsed(uint16_t last) {
uint32_t t;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
t = timer_count;
}
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { t = timer_count; }
return TIMER_DIFF_16((t & 0xFFFF), last);
}
@ -128,25 +110,18 @@ uint16_t timer_elapsed(uint16_t last)
*
* FIXME: needs doc
*/
inline
uint32_t timer_elapsed32(uint32_t last)
{
inline uint32_t timer_elapsed32(uint32_t last) {
uint32_t t;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
t = timer_count;
}
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { t = timer_count; }
return TIMER_DIFF_32(t, last);
}
// excecuted once per 1ms.(excess for just timer count?)
#ifndef __AVR_ATmega32A__
#define TIMER_INTERRUPT_VECTOR TIMER0_COMPA_vect
# define TIMER_INTERRUPT_VECTOR TIMER0_COMPA_vect
#else
#define TIMER_INTERRUPT_VECTOR TIMER0_COMP_vect
# define TIMER_INTERRUPT_VECTOR TIMER0_COMP_vect
#endif
ISR(TIMER_INTERRUPT_VECTOR, ISR_NOBLOCK)
{
timer_count++;
}
ISR(TIMER_INTERRUPT_VECTOR, ISR_NOBLOCK) { timer_count++; }

View file

@ -21,22 +21,22 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#ifndef TIMER_PRESCALER
# if F_CPU > 16000000
# define TIMER_PRESCALER 256
# elif F_CPU > 2000000
# define TIMER_PRESCALER 64
# elif F_CPU > 250000
# define TIMER_PRESCALER 8
# else
# define TIMER_PRESCALER 1
# endif
# if F_CPU > 16000000
# define TIMER_PRESCALER 256
# elif F_CPU > 2000000
# define TIMER_PRESCALER 64
# elif F_CPU > 250000
# define TIMER_PRESCALER 8
# else
# define TIMER_PRESCALER 1
# endif
#endif
#define TIMER_RAW_FREQ (F_CPU/TIMER_PRESCALER)
#define TIMER_RAW TCNT0
#define TIMER_RAW_TOP (TIMER_RAW_FREQ/1000)
#define TIMER_RAW_FREQ (F_CPU / TIMER_PRESCALER)
#define TIMER_RAW TCNT0
#define TIMER_RAW_TOP (TIMER_RAW_FREQ / 1000)
#if (TIMER_RAW_TOP > 255)
# error "Timer0 can't count 1ms at this clock freq. Use larger prescaler."
# error "Timer0 can't count 1ms at this clock freq. Use larger prescaler."
#endif
#endif

View file

@ -13,7 +13,7 @@ extern "C" {
#endif
extern void (*xfunc_out)(uint8_t);
#define xdev_out(func) xfunc_out = (void(*)(uint8_t))(func)
#define xdev_out(func) xfunc_out = (void (*)(uint8_t))(func)
/* This is a pointer to user defined output function. It must be initialized
before using this modle.
@ -25,13 +25,11 @@ void xputc(char chr);
All outputs from this module are output via this function.
*/
/*-----------------------------------------------------------------------------*/
void xputs(const char *string_p);
/* The string placed in the ROM is forwarded to xputc() directly.
*/
*/
/*-----------------------------------------------------------------------------*/
void xitoa(long value, char radix, char width);
@ -49,13 +47,12 @@ void xitoa(long value, char radix, char width);
0x55 2 -8 "01010101"
*/
/*-----------------------------------------------------------------------------*/
#define xprintf(format, ...) __xprintf(PSTR(format), ##__VA_ARGS__)
#define xsprintf(str, format, ...) __xsprintf(str, PSTR(format), ##__VA_ARGS__)
#define xfprintf(func, format, ...) __xfprintf(func, PSTR(format), ##__VA_ARGS__)
#define xprintf(format, ...) __xprintf(PSTR(format), ##__VA_ARGS__)
#define xsprintf(str, format, ...) __xsprintf(str, PSTR(format), ##__VA_ARGS__)
#define xfprintf(func, format, ...) __xfprintf(func, PSTR(format), ##__VA_ARGS__)
void __xprintf(const char *format_p, ...); /* Send formatted string to the registered device */
void __xprintf(const char *format_p, ...); /* Send formatted string to the registered device */
// void __xsprintf(char*, const char *format_p, ...); /* Put formatted string to the memory */
// void __xfprintf(void(*func)(uint8_t), const char *format_p, ...); /* Send formatted string to the specified device */
@ -84,7 +81,6 @@ void __xprintf(const char *format_p, ...); /* Send formatted string to the regis
*/
/*-----------------------------------------------------------------------------*/
char xatoi(char **str, long *ret);
@ -108,4 +104,3 @@ char xatoi(char **str, long *ret);
#endif
#endif

View file

@ -25,15 +25,14 @@ backlight_config_t backlight_config;
*
* FIXME: needs doc
*/
void backlight_init(void)
{
void backlight_init(void) {
/* check signature */
if (!eeconfig_is_enabled()) {
eeconfig_init();
}
backlight_config.raw = eeconfig_read_backlight();
if (backlight_config.level > BACKLIGHT_LEVELS) {
backlight_config.level = BACKLIGHT_LEVELS;
backlight_config.level = BACKLIGHT_LEVELS;
}
backlight_set(backlight_config.enable ? backlight_config.level : 0);
}
@ -42,10 +41,8 @@ void backlight_init(void)
*
* FIXME: needs doc
*/
void backlight_increase(void)
{
if(backlight_config.level < BACKLIGHT_LEVELS)
{
void backlight_increase(void) {
if (backlight_config.level < BACKLIGHT_LEVELS) {
backlight_config.level++;
}
backlight_config.enable = 1;
@ -58,10 +55,8 @@ void backlight_increase(void)
*
* FIXME: needs doc
*/
void backlight_decrease(void)
{
if(backlight_config.level > 0)
{
void backlight_decrease(void) {
if (backlight_config.level > 0) {
backlight_config.level--;
backlight_config.enable = !!backlight_config.level;
eeconfig_update_backlight(backlight_config.raw);
@ -74,64 +69,56 @@ void backlight_decrease(void)
*
* FIXME: needs doc
*/
void backlight_toggle(void)
{
bool enabled = backlight_config.enable;
dprintf("backlight toggle: %u\n", enabled);
if (enabled)
backlight_disable();
else
backlight_enable();
void backlight_toggle(void) {
bool enabled = backlight_config.enable;
dprintf("backlight toggle: %u\n", enabled);
if (enabled)
backlight_disable();
else
backlight_enable();
}
/** \brief Enable backlight
*
* FIXME: needs doc
*/
void backlight_enable(void)
{
if (backlight_config.enable) return; // do nothing if backlight is already on
void backlight_enable(void) {
if (backlight_config.enable) return; // do nothing if backlight is already on
backlight_config.enable = true;
if (backlight_config.raw == 1) // enabled but level == 0
backlight_config.level = 1;
eeconfig_update_backlight(backlight_config.raw);
dprintf("backlight enable\n");
backlight_set(backlight_config.level);
backlight_config.enable = true;
if (backlight_config.raw == 1) // enabled but level == 0
backlight_config.level = 1;
eeconfig_update_backlight(backlight_config.raw);
dprintf("backlight enable\n");
backlight_set(backlight_config.level);
}
/** \brief Disable backlight
*
* FIXME: needs doc
*/
void backlight_disable(void)
{
if (!backlight_config.enable) return; // do nothing if backlight is already off
void backlight_disable(void) {
if (!backlight_config.enable) return; // do nothing if backlight is already off
backlight_config.enable = false;
eeconfig_update_backlight(backlight_config.raw);
dprintf("backlight disable\n");
backlight_set(0);
backlight_config.enable = false;
eeconfig_update_backlight(backlight_config.raw);
dprintf("backlight disable\n");
backlight_set(0);
}
/** /brief Get the backlight status
*
* FIXME: needs doc
*/
bool is_backlight_enabled(void)
{
return backlight_config.enable;
}
bool is_backlight_enabled(void) { return backlight_config.enable; }
/** \brief Backlight step through levels
*
* FIXME: needs doc
*/
void backlight_step(void)
{
void backlight_step(void) {
backlight_config.level++;
if(backlight_config.level > BACKLIGHT_LEVELS)
{
if (backlight_config.level > BACKLIGHT_LEVELS) {
backlight_config.level = 0;
}
backlight_config.enable = !!backlight_config.level;
@ -144,11 +131,9 @@ void backlight_step(void)
*
* FIXME: needs doc
*/
void backlight_level(uint8_t level)
{
if (level > BACKLIGHT_LEVELS)
level = BACKLIGHT_LEVELS;
backlight_config.level = level;
void backlight_level(uint8_t level) {
if (level > BACKLIGHT_LEVELS) level = BACKLIGHT_LEVELS;
backlight_config.level = level;
backlight_config.enable = !!backlight_config.level;
eeconfig_update_backlight(backlight_config.raw);
backlight_set(backlight_config.level);
@ -158,21 +143,17 @@ void backlight_level(uint8_t level)
*
* FIXME: needs doc
*/
uint8_t get_backlight_level(void)
{
return backlight_config.level;
}
uint8_t get_backlight_level(void) { return backlight_config.level; }
#ifdef BACKLIGHT_BREATHING
/** \brief Backlight breathing toggle
*
* FIXME: needs doc
*/
void backlight_toggle_breathing(void)
{
void backlight_toggle_breathing(void) {
bool breathing = backlight_config.breathing;
dprintf("backlight breathing toggle: %u\n", breathing);
if (breathing)
if (breathing)
backlight_disable_breathing();
else
backlight_enable_breathing();
@ -182,9 +163,8 @@ void backlight_toggle_breathing(void)
*
* FIXME: needs doc
*/
void backlight_enable_breathing(void)
{
if (backlight_config.breathing) return; // do nothing if breathing is already on
void backlight_enable_breathing(void) {
if (backlight_config.breathing) return; // do nothing if breathing is already on
backlight_config.breathing = true;
eeconfig_update_backlight(backlight_config.raw);
@ -196,9 +176,8 @@ void backlight_enable_breathing(void)
*
* FIXME: needs doc
*/
void backlight_disable_breathing(void)
{
if (!backlight_config.breathing) return; // do nothing if breathing is already off
void backlight_disable_breathing(void) {
if (!backlight_config.breathing) return; // do nothing if breathing is already off
backlight_config.breathing = false;
eeconfig_update_backlight(backlight_config.raw);
@ -210,8 +189,5 @@ void backlight_disable_breathing(void)
*
* FIXME: needs doc
*/
bool is_backlight_breathing(void)
{
return backlight_config.breathing;
}
bool is_backlight_breathing(void) { return backlight_config.breathing; }
#endif

View file

@ -21,31 +21,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdbool.h>
#ifndef BACKLIGHT_LEVELS
#define BACKLIGHT_LEVELS 3
# define BACKLIGHT_LEVELS 3
#elif BACKLIGHT_LEVELS > 31
#error "Maximum value of BACKLIGHT_LEVELS is 31"
# error "Maximum value of BACKLIGHT_LEVELS is 31"
#endif
typedef union {
uint8_t raw;
struct {
bool enable :1;
bool breathing :1;
uint8_t reserved :1; // Reserved for possible future backlight modes
uint8_t level :5;
bool enable : 1;
bool breathing : 1;
uint8_t reserved : 1; // Reserved for possible future backlight modes
uint8_t level : 5;
};
} backlight_config_t;
void backlight_init(void);
void backlight_increase(void);
void backlight_decrease(void);
void backlight_toggle(void);
void backlight_enable(void);
void backlight_disable(void);
bool is_backlight_enabled(void);
void backlight_step(void);
void backlight_set(uint8_t level);
void backlight_level(uint8_t level);
void backlight_init(void);
void backlight_increase(void);
void backlight_decrease(void);
void backlight_toggle(void);
void backlight_enable(void);
void backlight_disable(void);
bool is_backlight_enabled(void);
void backlight_step(void);
void backlight_set(uint8_t level);
void backlight_level(uint8_t level);
uint8_t get_backlight_level(void);
#ifdef BACKLIGHT_BREATHING

View file

@ -18,7 +18,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef BOOTLOADER_H
#define BOOTLOADER_H
/* give code for your bootloader to come up if needed */
void bootloader_jump(void);

View file

@ -16,8 +16,7 @@ keymap_config_t keymap_config;
*
* FIXME: needs doc
*/
void bootmagic(void)
{
void bootmagic(void) {
/* check signature */
if (!eeconfig_is_enabled()) {
eeconfig_init();
@ -26,7 +25,10 @@ void bootmagic(void)
/* do scans in case of bounce */
print("bootmagic scan: ... ");
uint8_t scan = 100;
while (scan--) { matrix_scan(); wait_ms(10); }
while (scan--) {
matrix_scan();
wait_ms(10);
}
print("done.\n");
/* bootmagic skip */
@ -89,14 +91,30 @@ void bootmagic(void)
/* default layer */
uint8_t default_layer = 0;
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_0)) { default_layer |= (1<<0); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_1)) { default_layer |= (1<<1); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_2)) { default_layer |= (1<<2); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_3)) { default_layer |= (1<<3); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_4)) { default_layer |= (1<<4); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_5)) { default_layer |= (1<<5); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_6)) { default_layer |= (1<<6); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_7)) { default_layer |= (1<<7); }
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_0)) {
default_layer |= (1 << 0);
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_1)) {
default_layer |= (1 << 1);
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_2)) {
default_layer |= (1 << 2);
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_3)) {
default_layer |= (1 << 3);
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_4)) {
default_layer |= (1 << 4);
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_5)) {
default_layer |= (1 << 5);
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_6)) {
default_layer |= (1 << 6);
}
if (bootmagic_scan_keycode(BOOTMAGIC_KEY_DEFAULT_LAYER_7)) {
default_layer |= (1 << 7);
}
if (default_layer) {
eeconfig_update_default_layer(default_layer);
default_layer_set((layer_state_t)default_layer);
@ -110,13 +128,12 @@ void bootmagic(void)
*
* FIXME: needs doc
*/
static bool scan_keycode(uint8_t keycode)
{
static bool scan_keycode(uint8_t keycode) {
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
matrix_row_t matrix_row = matrix_get_row(r);
for (uint8_t c = 0; c < MATRIX_COLS; c++) {
if (matrix_row & ((matrix_row_t)1<<c)) {
if (keycode == keymap_key_to_keycode(0, (keypos_t){ .row = r, .col = c })) {
if (matrix_row & ((matrix_row_t)1 << c)) {
if (keycode == keymap_key_to_keycode(0, (keypos_t){.row = r, .col = c})) {
return true;
}
}
@ -129,8 +146,7 @@ static bool scan_keycode(uint8_t keycode)
*
* FIXME: needs doc
*/
bool bootmagic_scan_keycode(uint8_t keycode)
{
bool bootmagic_scan_keycode(uint8_t keycode) {
if (!scan_keycode(BOOTMAGIC_KEY_SALT)) return false;
return scan_keycode(keycode);

View file

@ -1,101 +1,98 @@
#ifndef BOOTMAGIC_H
#define BOOTMAGIC_H
/* FIXME: Add special doxygen comments for defines here. */
/* bootmagic salt key */
#ifndef BOOTMAGIC_KEY_SALT
#define BOOTMAGIC_KEY_SALT KC_SPACE
# define BOOTMAGIC_KEY_SALT KC_SPACE
#endif
/* skip bootmagic and eeconfig */
#ifndef BOOTMAGIC_KEY_SKIP
#define BOOTMAGIC_KEY_SKIP KC_ESC
# define BOOTMAGIC_KEY_SKIP KC_ESC
#endif
/* eeprom clear */
#ifndef BOOTMAGIC_KEY_EEPROM_CLEAR
#define BOOTMAGIC_KEY_EEPROM_CLEAR KC_BSPACE
# define BOOTMAGIC_KEY_EEPROM_CLEAR KC_BSPACE
#endif
/* kick up bootloader */
#ifndef BOOTMAGIC_KEY_BOOTLOADER
#define BOOTMAGIC_KEY_BOOTLOADER KC_B
# define BOOTMAGIC_KEY_BOOTLOADER KC_B
#endif
/* debug enable */
#ifndef BOOTMAGIC_KEY_DEBUG_ENABLE
#define BOOTMAGIC_KEY_DEBUG_ENABLE KC_D
# define BOOTMAGIC_KEY_DEBUG_ENABLE KC_D
#endif
#ifndef BOOTMAGIC_KEY_DEBUG_MATRIX
#define BOOTMAGIC_KEY_DEBUG_MATRIX KC_X
# define BOOTMAGIC_KEY_DEBUG_MATRIX KC_X
#endif
#ifndef BOOTMAGIC_KEY_DEBUG_KEYBOARD
#define BOOTMAGIC_KEY_DEBUG_KEYBOARD KC_K
# define BOOTMAGIC_KEY_DEBUG_KEYBOARD KC_K
#endif
#ifndef BOOTMAGIC_KEY_DEBUG_MOUSE
#define BOOTMAGIC_KEY_DEBUG_MOUSE KC_M
# define BOOTMAGIC_KEY_DEBUG_MOUSE KC_M
#endif
/*
* keymap config
*/
#ifndef BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK
#define BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK KC_LCTRL
# define BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK KC_LCTRL
#endif
#ifndef BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL
#define BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL KC_CAPSLOCK
# define BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL KC_CAPSLOCK
#endif
#ifndef BOOTMAGIC_KEY_SWAP_LALT_LGUI
#define BOOTMAGIC_KEY_SWAP_LALT_LGUI KC_LALT
# define BOOTMAGIC_KEY_SWAP_LALT_LGUI KC_LALT
#endif
#ifndef BOOTMAGIC_KEY_SWAP_RALT_RGUI
#define BOOTMAGIC_KEY_SWAP_RALT_RGUI KC_RALT
# define BOOTMAGIC_KEY_SWAP_RALT_RGUI KC_RALT
#endif
#ifndef BOOTMAGIC_KEY_NO_GUI
#define BOOTMAGIC_KEY_NO_GUI KC_LGUI
# define BOOTMAGIC_KEY_NO_GUI KC_LGUI
#endif
#ifndef BOOTMAGIC_KEY_SWAP_GRAVE_ESC
#define BOOTMAGIC_KEY_SWAP_GRAVE_ESC KC_GRAVE
# define BOOTMAGIC_KEY_SWAP_GRAVE_ESC KC_GRAVE
#endif
#ifndef BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE
#define BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE KC_BSLASH
# define BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE KC_BSLASH
#endif
#ifndef BOOTMAGIC_HOST_NKRO
#define BOOTMAGIC_HOST_NKRO KC_N
# define BOOTMAGIC_HOST_NKRO KC_N
#endif
/*
* change default layer
*/
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_0
#define BOOTMAGIC_KEY_DEFAULT_LAYER_0 KC_0
# define BOOTMAGIC_KEY_DEFAULT_LAYER_0 KC_0
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_1
#define BOOTMAGIC_KEY_DEFAULT_LAYER_1 KC_1
# define BOOTMAGIC_KEY_DEFAULT_LAYER_1 KC_1
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_2
#define BOOTMAGIC_KEY_DEFAULT_LAYER_2 KC_2
# define BOOTMAGIC_KEY_DEFAULT_LAYER_2 KC_2
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_3
#define BOOTMAGIC_KEY_DEFAULT_LAYER_3 KC_3
# define BOOTMAGIC_KEY_DEFAULT_LAYER_3 KC_3
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_4
#define BOOTMAGIC_KEY_DEFAULT_LAYER_4 KC_4
# define BOOTMAGIC_KEY_DEFAULT_LAYER_4 KC_4
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_5
#define BOOTMAGIC_KEY_DEFAULT_LAYER_5 KC_5
# define BOOTMAGIC_KEY_DEFAULT_LAYER_5 KC_5
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_6
#define BOOTMAGIC_KEY_DEFAULT_LAYER_6 KC_6
# define BOOTMAGIC_KEY_DEFAULT_LAYER_6 KC_6
#endif
#ifndef BOOTMAGIC_KEY_DEFAULT_LAYER_7
#define BOOTMAGIC_KEY_DEFAULT_LAYER_7 KC_7
# define BOOTMAGIC_KEY_DEFAULT_LAYER_7 KC_7
#endif
void bootmagic(void);
bool bootmagic_scan_keycode(uint8_t keycode);

View file

@ -7,63 +7,62 @@
/* STM32 */
/* This code should be checked whether it runs correctly on platforms */
#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
# define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
extern uint32_t __ram0_end__;
#define BOOTLOADER_MAGIC 0xDEADBEEF
#define MAGIC_ADDR (unsigned long*)(SYMVAL(__ram0_end__) - 4)
# define BOOTLOADER_MAGIC 0xDEADBEEF
# define MAGIC_ADDR (unsigned long *)(SYMVAL(__ram0_end__) - 4)
/** \brief Jump to the bootloader
*
* FIXME: needs doc
*/
void bootloader_jump(void) {
*MAGIC_ADDR = BOOTLOADER_MAGIC; // set magic flag => reset handler will jump into boot loader
NVIC_SystemReset();
*MAGIC_ADDR = BOOTLOADER_MAGIC; // set magic flag => reset handler will jump into boot loader
NVIC_SystemReset();
}
/** \brief Enter bootloader mode if requested
*
* FIXME: needs doc
*/
void enter_bootloader_mode_if_requested(void) {
unsigned long* check = MAGIC_ADDR;
if(*check == BOOTLOADER_MAGIC) {
*check = 0;
__set_CONTROL(0);
__set_MSP(*(__IO uint32_t*)STM32_BOOTLOADER_ADDRESS);
__enable_irq();
void enter_bootloader_mode_if_requested(void) {
unsigned long *check = MAGIC_ADDR;
if (*check == BOOTLOADER_MAGIC) {
*check = 0;
__set_CONTROL(0);
__set_MSP(*(__IO uint32_t *)STM32_BOOTLOADER_ADDRESS);
__enable_irq();
typedef void (*BootJump_t)(void);
BootJump_t boot_jump = *(BootJump_t*)(STM32_BOOTLOADER_ADDRESS + 4);
boot_jump();
while(1);
}
}
typedef void (*BootJump_t)(void);
BootJump_t boot_jump = *(BootJump_t *)(STM32_BOOTLOADER_ADDRESS + 4);
boot_jump();
while (1)
;
}
}
#elif defined(KL2x) || defined(K20x) /* STM32_BOOTLOADER_ADDRESS */
/* Kinetis */
#if defined(KIIBOHD_BOOTLOADER)
# if defined(KIIBOHD_BOOTLOADER)
/* Kiibohd Bootloader (MCHCK and Infinity KB) */
#define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000
# define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000
const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff";
void bootloader_jump(void) {
__builtin_memcpy((void *)VBAT, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic));
// request reset
SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk;
void bootloader_jump(void) {
__builtin_memcpy((void *)VBAT, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic));
// request reset
SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk;
}
#else /* defined(KIIBOHD_BOOTLOADER) */
# else /* defined(KIIBOHD_BOOTLOADER) */
/* Default for Kinetis - expecting an ARM Teensy */
#include "wait.h"
# include "wait.h"
void bootloader_jump(void) {
wait_ms(100);
__BKPT(0);
wait_ms(100);
__BKPT(0);
}
#endif /* defined(KIIBOHD_BOOTLOADER) */
# endif /* defined(KIIBOHD_BOOTLOADER) */
#else /* neither STM32 nor KINETIS */
__attribute__((weak))
void bootloader_jump(void) {}
__attribute__((weak)) void bootloader_jump(void) {}
#endif

142
tmk_core/common/chibios/eeprom_stm32.c Executable file → Normal file
View file

@ -24,7 +24,7 @@
* the functionality use the EEPROM_Init() function. Be sure that by reprogramming
* of the controller just affected pages will be deleted. In other case the non
* volatile data will be lost.
******************************************************************************/
******************************************************************************/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
@ -32,23 +32,22 @@
uint8_t DataBuf[FEE_PAGE_SIZE];
/*****************************************************************************
* Delete Flash Space used for user Data, deletes the whole space between
* RW_PAGE_BASE_ADDRESS and the last uC Flash Page
******************************************************************************/
* Delete Flash Space used for user Data, deletes the whole space between
* RW_PAGE_BASE_ADDRESS and the last uC Flash Page
******************************************************************************/
uint16_t EEPROM_Init(void) {
// unlock flash
FLASH_Unlock();
// Clear Flags
//FLASH_ClearFlag(FLASH_SR_EOP|FLASH_SR_PGERR|FLASH_SR_WRPERR);
// FLASH_ClearFlag(FLASH_SR_EOP|FLASH_SR_PGERR|FLASH_SR_WRPERR);
return FEE_DENSITY_BYTES;
}
/*****************************************************************************
* Erase the whole reserved Flash Space used for user Data
******************************************************************************/
void EEPROM_Erase (void) {
* Erase the whole reserved Flash Space used for user Data
******************************************************************************/
void EEPROM_Erase(void) {
int page_num = 0;
// delete all pages from specified start page to the last page
@ -58,16 +57,15 @@ void EEPROM_Erase (void) {
} while (page_num < FEE_DENSITY_PAGES);
}
/*****************************************************************************
* Writes once data byte to flash on specified address. If a byte is already
* written, the whole page must be copied to a buffer, the byte changed and
* the manipulated buffer written after PageErase.
*******************************************************************************/
uint16_t EEPROM_WriteDataByte (uint16_t Address, uint8_t DataByte) {
* Writes once data byte to flash on specified address. If a byte is already
* written, the whole page must be copied to a buffer, the byte changed and
* the manipulated buffer written after PageErase.
*******************************************************************************/
uint16_t EEPROM_WriteDataByte(uint16_t Address, uint8_t DataByte) {
FLASH_Status FlashStatus = FLASH_COMPLETE;
uint32_t page;
int i;
int i;
// exit if desired address is above the limit (e.G. under 2048 Bytes for 4 pages)
if (Address > FEE_DENSITY_BYTES) {
@ -78,27 +76,25 @@ uint16_t EEPROM_WriteDataByte (uint16_t Address, uint8_t DataByte) {
page = FEE_ADDR_OFFSET(Address) / FEE_PAGE_SIZE;
// if current data is 0xFF, the byte is empty, just overwrite with the new one
if ((*(__IO uint16_t*)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))) == FEE_EMPTY_WORD) {
if ((*(__IO uint16_t *)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))) == FEE_EMPTY_WORD) {
FlashStatus = FLASH_ProgramHalfWord(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address), (uint16_t)(0x00FF & DataByte));
} else {
// Copy Page to a buffer
memcpy(DataBuf, (uint8_t*)FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE), FEE_PAGE_SIZE); // !!! Calculate base address for the desired page
memcpy(DataBuf, (uint8_t *)FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE), FEE_PAGE_SIZE); // !!! Calculate base address for the desired page
// check if new data is differ to current data, return if not, proceed if yes
if (DataByte == *(__IO uint8_t*)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))) {
if (DataByte == *(__IO uint8_t *)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address))) {
return 0;
}
// manipulate desired data byte in temp data array if new byte is differ to the current
DataBuf[FEE_ADDR_OFFSET(Address) % FEE_PAGE_SIZE] = DataByte;
//Erase Page
// Erase Page
FlashStatus = FLASH_ErasePage(FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE));
// Write new data (whole page) to flash if data has been changed
for(i = 0; i < (FEE_PAGE_SIZE / 2); i++) {
for (i = 0; i < (FEE_PAGE_SIZE / 2); i++) {
if ((__IO uint16_t)(0xFF00 | DataBuf[FEE_ADDR_OFFSET(i)]) != 0xFFFF) {
FlashStatus = FLASH_ProgramHalfWord((FEE_PAGE_BASE_ADDRESS + (page * FEE_PAGE_SIZE)) + (i * 2), (uint16_t)(0xFF00 | DataBuf[FEE_ADDR_OFFSET(i)]));
}
@ -107,98 +103,86 @@ uint16_t EEPROM_WriteDataByte (uint16_t Address, uint8_t DataByte) {
return FlashStatus;
}
/*****************************************************************************
* Read once data byte from a specified address.
*******************************************************************************/
uint8_t EEPROM_ReadDataByte (uint16_t Address) {
* Read once data byte from a specified address.
*******************************************************************************/
uint8_t EEPROM_ReadDataByte(uint16_t Address) {
uint8_t DataByte = 0xFF;
// Get Byte from specified address
DataByte = (*(__IO uint8_t*)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address)));
DataByte = (*(__IO uint8_t *)(FEE_PAGE_BASE_ADDRESS + FEE_ADDR_OFFSET(Address)));
return DataByte;
}
/*****************************************************************************
* Wrap library in AVR style functions.
*******************************************************************************/
uint8_t eeprom_read_byte (const uint8_t *Address)
{
const uint16_t p = (const uint32_t) Address;
* Wrap library in AVR style functions.
*******************************************************************************/
uint8_t eeprom_read_byte(const uint8_t *Address) {
const uint16_t p = (const uint32_t)Address;
return EEPROM_ReadDataByte(p);
}
void eeprom_write_byte (uint8_t *Address, uint8_t Value)
{
uint16_t p = (uint32_t) Address;
void eeprom_write_byte(uint8_t *Address, uint8_t Value) {
uint16_t p = (uint32_t)Address;
EEPROM_WriteDataByte(p, Value);
}
void eeprom_update_byte (uint8_t *Address, uint8_t Value)
{
uint16_t p = (uint32_t) Address;
void eeprom_update_byte(uint8_t *Address, uint8_t Value) {
uint16_t p = (uint32_t)Address;
EEPROM_WriteDataByte(p, Value);
}
uint16_t eeprom_read_word (const uint16_t *Address)
{
const uint16_t p = (const uint32_t) Address;
return EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p+1) << 8);
uint16_t eeprom_read_word(const uint16_t *Address) {
const uint16_t p = (const uint32_t)Address;
return EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p + 1) << 8);
}
void eeprom_write_word (uint16_t *Address, uint16_t Value)
{
uint16_t p = (uint32_t) Address;
EEPROM_WriteDataByte(p, (uint8_t) Value);
EEPROM_WriteDataByte(p + 1, (uint8_t) (Value >> 8));
void eeprom_write_word(uint16_t *Address, uint16_t Value) {
uint16_t p = (uint32_t)Address;
EEPROM_WriteDataByte(p, (uint8_t)Value);
EEPROM_WriteDataByte(p + 1, (uint8_t)(Value >> 8));
}
void eeprom_update_word (uint16_t *Address, uint16_t Value)
{
uint16_t p = (uint32_t) Address;
EEPROM_WriteDataByte(p, (uint8_t) Value);
EEPROM_WriteDataByte(p + 1, (uint8_t) (Value >> 8));
void eeprom_update_word(uint16_t *Address, uint16_t Value) {
uint16_t p = (uint32_t)Address;
EEPROM_WriteDataByte(p, (uint8_t)Value);
EEPROM_WriteDataByte(p + 1, (uint8_t)(Value >> 8));
}
uint32_t eeprom_read_dword (const uint32_t *Address)
{
const uint16_t p = (const uint32_t) Address;
return EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p+1) << 8)
| (EEPROM_ReadDataByte(p+2) << 16) | (EEPROM_ReadDataByte(p+3) << 24);
uint32_t eeprom_read_dword(const uint32_t *Address) {
const uint16_t p = (const uint32_t)Address;
return EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p + 1) << 8) | (EEPROM_ReadDataByte(p + 2) << 16) | (EEPROM_ReadDataByte(p + 3) << 24);
}
void eeprom_write_dword (uint32_t *Address, uint32_t Value)
{
uint16_t p = (const uint32_t) Address;
EEPROM_WriteDataByte(p, (uint8_t) Value);
EEPROM_WriteDataByte(p+1, (uint8_t) (Value >> 8));
EEPROM_WriteDataByte(p+2, (uint8_t) (Value >> 16));
EEPROM_WriteDataByte(p+3, (uint8_t) (Value >> 24));
void eeprom_write_dword(uint32_t *Address, uint32_t Value) {
uint16_t p = (const uint32_t)Address;
EEPROM_WriteDataByte(p, (uint8_t)Value);
EEPROM_WriteDataByte(p + 1, (uint8_t)(Value >> 8));
EEPROM_WriteDataByte(p + 2, (uint8_t)(Value >> 16));
EEPROM_WriteDataByte(p + 3, (uint8_t)(Value >> 24));
}
void eeprom_update_dword (uint32_t *Address, uint32_t Value)
{
uint16_t p = (const uint32_t) Address;
uint32_t existingValue = EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p+1) << 8)
| (EEPROM_ReadDataByte(p+2) << 16) | (EEPROM_ReadDataByte(p+3) << 24);
if(Value != existingValue){
EEPROM_WriteDataByte(p, (uint8_t) Value);
EEPROM_WriteDataByte(p+1, (uint8_t) (Value >> 8));
EEPROM_WriteDataByte(p+2, (uint8_t) (Value >> 16));
EEPROM_WriteDataByte(p+3, (uint8_t) (Value >> 24));
void eeprom_update_dword(uint32_t *Address, uint32_t Value) {
uint16_t p = (const uint32_t)Address;
uint32_t existingValue = EEPROM_ReadDataByte(p) | (EEPROM_ReadDataByte(p + 1) << 8) | (EEPROM_ReadDataByte(p + 2) << 16) | (EEPROM_ReadDataByte(p + 3) << 24);
if (Value != existingValue) {
EEPROM_WriteDataByte(p, (uint8_t)Value);
EEPROM_WriteDataByte(p + 1, (uint8_t)(Value >> 8));
EEPROM_WriteDataByte(p + 2, (uint8_t)(Value >> 16));
EEPROM_WriteDataByte(p + 3, (uint8_t)(Value >> 24));
}
}
void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
const uint8_t *p = (const uint8_t *)addr;
uint8_t *dest = (uint8_t *)buf;
const uint8_t *p = (const uint8_t *)addr;
uint8_t * dest = (uint8_t *)buf;
while (len--) {
*dest++ = eeprom_read_byte(p++);
}
}
void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
uint8_t *p = (uint8_t *)addr;
uint8_t * p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
@ -206,7 +190,7 @@ void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
}
void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
uint8_t *p = (uint8_t *)addr;
uint8_t * p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);

64
tmk_core/common/chibios/eeprom_stm32.h Executable file → Normal file
View file

@ -31,53 +31,53 @@
// HACK ALERT. This definition may not match your processor
// To Do. Work out correct value for EEPROM_PAGE_SIZE on the STM32F103CT6 etc
#if defined(EEPROM_EMU_STM32F303xC)
#define MCU_STM32F303CC
# define MCU_STM32F303CC
#elif defined(EEPROM_EMU_STM32F103xB)
#define MCU_STM32F103RB
# define MCU_STM32F103RB
#elif defined(EEPROM_EMU_STM32F072xB)
#define MCU_STM32F072CB
# define MCU_STM32F072CB
#else
#error "not implemented."
# error "not implemented."
#endif
#ifndef EEPROM_PAGE_SIZE
#if defined (MCU_STM32F103RB)
#define FEE_PAGE_SIZE (uint16_t)0x400 // Page size = 1KByte
#define FEE_DENSITY_PAGES 2 // How many pages are used
#elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE) || defined (MCU_STM32F103RD) || defined (MCU_STM32F303CC) || defined(MCU_STM32F072CB)
#define FEE_PAGE_SIZE (uint16_t)0x800 // Page size = 2KByte
#define FEE_DENSITY_PAGES 4 // How many pages are used
#else
#error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
#endif
# if defined(MCU_STM32F103RB)
# define FEE_PAGE_SIZE (uint16_t)0x400 // Page size = 1KByte
# define FEE_DENSITY_PAGES 2 // How many pages are used
# elif defined(MCU_STM32F103ZE) || defined(MCU_STM32F103RE) || defined(MCU_STM32F103RD) || defined(MCU_STM32F303CC) || defined(MCU_STM32F072CB)
# define FEE_PAGE_SIZE (uint16_t)0x800 // Page size = 2KByte
# define FEE_DENSITY_PAGES 4 // How many pages are used
# else
# error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
# endif
#endif
#ifndef EEPROM_START_ADDRESS
#if defined (MCU_STM32F103RB) || defined(MCU_STM32F072CB)
#define FEE_MCU_FLASH_SIZE 128 // Size in Kb
#elif defined (MCU_STM32F103ZE) || defined (MCU_STM32F103RE)
#define FEE_MCU_FLASH_SIZE 512 // Size in Kb
#elif defined (MCU_STM32F103RD)
#define FEE_MCU_FLASH_SIZE 384 // Size in Kb
#elif defined (MCU_STM32F303CC)
#define FEE_MCU_FLASH_SIZE 256 // Size in Kb
#else
#error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
#endif
# if defined(MCU_STM32F103RB) || defined(MCU_STM32F072CB)
# define FEE_MCU_FLASH_SIZE 128 // Size in Kb
# elif defined(MCU_STM32F103ZE) || defined(MCU_STM32F103RE)
# define FEE_MCU_FLASH_SIZE 512 // Size in Kb
# elif defined(MCU_STM32F103RD)
# define FEE_MCU_FLASH_SIZE 384 // Size in Kb
# elif defined(MCU_STM32F303CC)
# define FEE_MCU_FLASH_SIZE 256 // Size in Kb
# else
# error "No MCU type specified. Add something like -DMCU_STM32F103RB to your compiler arguments (probably in a Makefile)."
# endif
#endif
// DONT CHANGE
// Choose location for the first EEPROM Page address on the top of flash
#define FEE_PAGE_BASE_ADDRESS ((uint32_t)(0x8000000 + FEE_MCU_FLASH_SIZE * 1024 - FEE_DENSITY_PAGES * FEE_PAGE_SIZE))
#define FEE_DENSITY_BYTES ((FEE_PAGE_SIZE / 2) * FEE_DENSITY_PAGES - 1)
#define FEE_LAST_PAGE_ADDRESS (FEE_PAGE_BASE_ADDRESS + (FEE_PAGE_SIZE * FEE_DENSITY_PAGES))
#define FEE_EMPTY_WORD ((uint16_t)0xFFFF)
#define FEE_ADDR_OFFSET(Address)(Address * 2) // 1Byte per Word will be saved to preserve Flash
#define FEE_DENSITY_BYTES ((FEE_PAGE_SIZE / 2) * FEE_DENSITY_PAGES - 1)
#define FEE_LAST_PAGE_ADDRESS (FEE_PAGE_BASE_ADDRESS + (FEE_PAGE_SIZE * FEE_DENSITY_PAGES))
#define FEE_EMPTY_WORD ((uint16_t)0xFFFF)
#define FEE_ADDR_OFFSET(Address) (Address * 2) // 1Byte per Word will be saved to preserve Flash
// Use this function to initialize the functionality
uint16_t EEPROM_Init(void);
void EEPROM_Erase (void);
uint16_t EEPROM_WriteDataByte (uint16_t Address, uint8_t DataByte);
uint8_t EEPROM_ReadDataByte (uint16_t Address);
void EEPROM_Erase(void);
uint16_t EEPROM_WriteDataByte(uint16_t Address, uint8_t DataByte);
uint8_t EEPROM_ReadDataByte(uint16_t Address);
#endif /* __EEPROM_H */
#endif /* __EEPROM_H */

View file

@ -21,10 +21,10 @@
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* 1. The above copyright notice and this permission notice shall be
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
@ -39,7 +39,6 @@
* SOFTWARE.
*/
#if defined(K20x) /* chip selection */
/* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */
@ -51,7 +50,7 @@
// (aligned to 2 or 4 byte boundaries) has twice the endurance
// compared to writing 8 bit bytes.
//
#define EEPROM_SIZE 32
# define EEPROM_SIZE 32
// Writing unaligned 16 or 32 bit data is handled automatically when
// this is defined, but at a cost of extra code size. Without this,
@ -59,286 +58,271 @@
// absolutely sure all 16 and 32 bit writes will be aligned, you can
// remove the extra unnecessary code.
//
#define HANDLE_UNALIGNED_WRITES
# define HANDLE_UNALIGNED_WRITES
// Minimum EEPROM Endurance
// ------------------------
#if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word
#define EEESIZE 0x33
#elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word
#define EEESIZE 0x34
#elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word
#define EEESIZE 0x35
#elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word
#define EEESIZE 0x36
#elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word
#define EEESIZE 0x37
#elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word
#define EEESIZE 0x38
#elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word
#define EEESIZE 0x39
#endif
# if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word
# define EEESIZE 0x33
# elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word
# define EEESIZE 0x34
# elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word
# define EEESIZE 0x35
# elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word
# define EEESIZE 0x36
# elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word
# define EEESIZE 0x37
# elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word
# define EEESIZE 0x38
# elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word
# define EEESIZE 0x39
# endif
/** \brief eeprom initialization
*
* FIXME: needs doc
*/
void eeprom_initialize(void)
{
uint32_t count=0;
uint16_t do_flash_cmd[] = {
0xf06f, 0x037f, 0x7003, 0x7803,
0xf013, 0x0f80, 0xd0fb, 0x4770};
uint8_t status;
void eeprom_initialize(void) {
uint32_t count = 0;
uint16_t do_flash_cmd[] = {0xf06f, 0x037f, 0x7003, 0x7803, 0xf013, 0x0f80, 0xd0fb, 0x4770};
uint8_t status;
if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) {
// FlexRAM is configured as traditional RAM
// We need to reconfigure for EEPROM usage
FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command
FTFL->FCCOB4 = EEESIZE; // EEPROM Size
FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup
__disable_irq();
// do_flash_cmd() must execute from RAM. Luckily the C syntax is simple...
(*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT));
__enable_irq();
status = FTFL->FSTAT;
if (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL)) {
FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL));
return; // error
}
}
// wait for eeprom to become ready (is this really necessary?)
while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) {
if (++count > 20000) break;
}
if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) {
// FlexRAM is configured as traditional RAM
// We need to reconfigure for EEPROM usage
FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command
FTFL->FCCOB4 = EEESIZE; // EEPROM Size
FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup
__disable_irq();
// do_flash_cmd() must execute from RAM. Luckily the C syntax is simple...
(*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT));
__enable_irq();
status = FTFL->FSTAT;
if (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL)) {
FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL));
return; // error
}
}
// wait for eeprom to become ready (is this really necessary?)
while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) {
if (++count > 20000) break;
}
}
#define FlexRAM ((uint8_t *)0x14000000)
# define FlexRAM ((uint8_t *)0x14000000)
/** \brief eeprom read byte
*
* FIXME: needs doc
*/
uint8_t eeprom_read_byte(const uint8_t *addr)
{
uint32_t offset = (uint32_t)addr;
if (offset >= EEPROM_SIZE) return 0;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
return FlexRAM[offset];
uint8_t eeprom_read_byte(const uint8_t *addr) {
uint32_t offset = (uint32_t)addr;
if (offset >= EEPROM_SIZE) return 0;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
return FlexRAM[offset];
}
/** \brief eeprom read word
*
* FIXME: needs doc
*/
uint16_t eeprom_read_word(const uint16_t *addr)
{
uint32_t offset = (uint32_t)addr;
if (offset >= EEPROM_SIZE-1) return 0;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
return *(uint16_t *)(&FlexRAM[offset]);
uint16_t eeprom_read_word(const uint16_t *addr) {
uint32_t offset = (uint32_t)addr;
if (offset >= EEPROM_SIZE - 1) return 0;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
return *(uint16_t *)(&FlexRAM[offset]);
}
/** \brief eeprom read dword
*
* FIXME: needs doc
*/
uint32_t eeprom_read_dword(const uint32_t *addr)
{
uint32_t offset = (uint32_t)addr;
if (offset >= EEPROM_SIZE-3) return 0;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
return *(uint32_t *)(&FlexRAM[offset]);
uint32_t eeprom_read_dword(const uint32_t *addr) {
uint32_t offset = (uint32_t)addr;
if (offset >= EEPROM_SIZE - 3) return 0;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
return *(uint32_t *)(&FlexRAM[offset]);
}
/** \brief eeprom read block
*
* FIXME: needs doc
*/
void eeprom_read_block(void *buf, const void *addr, uint32_t len)
{
uint32_t offset = (uint32_t)addr;
uint8_t *dest = (uint8_t *)buf;
uint32_t end = offset + len;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
if (end > EEPROM_SIZE) end = EEPROM_SIZE;
while (offset < end) {
*dest++ = FlexRAM[offset++];
}
void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
uint32_t offset = (uint32_t)addr;
uint8_t *dest = (uint8_t *)buf;
uint32_t end = offset + len;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
if (end > EEPROM_SIZE) end = EEPROM_SIZE;
while (offset < end) {
*dest++ = FlexRAM[offset++];
}
}
/** \brief eeprom is ready
*
* FIXME: needs doc
*/
int eeprom_is_ready(void)
{
return (FTFL->FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0;
}
int eeprom_is_ready(void) { return (FTFL->FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0; }
/** \brief flexram wait
*
* FIXME: needs doc
*/
static void flexram_wait(void)
{
while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) {
// TODO: timeout
}
static void flexram_wait(void) {
while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) {
// TODO: timeout
}
}
/** \brief eeprom_write_byte
*
* FIXME: needs doc
*/
void eeprom_write_byte(uint8_t *addr, uint8_t value)
{
uint32_t offset = (uint32_t)addr;
void eeprom_write_byte(uint8_t *addr, uint8_t value) {
uint32_t offset = (uint32_t)addr;
if (offset >= EEPROM_SIZE) return;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
if (FlexRAM[offset] != value) {
FlexRAM[offset] = value;
flexram_wait();
}
if (offset >= EEPROM_SIZE) return;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
if (FlexRAM[offset] != value) {
FlexRAM[offset] = value;
flexram_wait();
}
}
/** \brief eeprom write word
*
* FIXME: needs doc
*/
void eeprom_write_word(uint16_t *addr, uint16_t value)
{
uint32_t offset = (uint32_t)addr;
void eeprom_write_word(uint16_t *addr, uint16_t value) {
uint32_t offset = (uint32_t)addr;
if (offset >= EEPROM_SIZE-1) return;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
#ifdef HANDLE_UNALIGNED_WRITES
if ((offset & 1) == 0) {
#endif
if (*(uint16_t *)(&FlexRAM[offset]) != value) {
*(uint16_t *)(&FlexRAM[offset]) = value;
flexram_wait();
}
#ifdef HANDLE_UNALIGNED_WRITES
} else {
if (FlexRAM[offset] != value) {
FlexRAM[offset] = value;
flexram_wait();
}
if (FlexRAM[offset + 1] != (value >> 8)) {
FlexRAM[offset + 1] = value >> 8;
flexram_wait();
}
}
#endif
if (offset >= EEPROM_SIZE - 1) return;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
# ifdef HANDLE_UNALIGNED_WRITES
if ((offset & 1) == 0) {
# endif
if (*(uint16_t *)(&FlexRAM[offset]) != value) {
*(uint16_t *)(&FlexRAM[offset]) = value;
flexram_wait();
}
# ifdef HANDLE_UNALIGNED_WRITES
} else {
if (FlexRAM[offset] != value) {
FlexRAM[offset] = value;
flexram_wait();
}
if (FlexRAM[offset + 1] != (value >> 8)) {
FlexRAM[offset + 1] = value >> 8;
flexram_wait();
}
}
# endif
}
/** \brief eeprom write dword
*
* FIXME: needs doc
*/
void eeprom_write_dword(uint32_t *addr, uint32_t value)
{
uint32_t offset = (uint32_t)addr;
void eeprom_write_dword(uint32_t *addr, uint32_t value) {
uint32_t offset = (uint32_t)addr;
if (offset >= EEPROM_SIZE-3) return;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
#ifdef HANDLE_UNALIGNED_WRITES
switch (offset & 3) {
case 0:
#endif
if (*(uint32_t *)(&FlexRAM[offset]) != value) {
*(uint32_t *)(&FlexRAM[offset]) = value;
flexram_wait();
}
return;
#ifdef HANDLE_UNALIGNED_WRITES
case 2:
if (*(uint16_t *)(&FlexRAM[offset]) != value) {
*(uint16_t *)(&FlexRAM[offset]) = value;
flexram_wait();
}
if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) {
*(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16;
flexram_wait();
}
return;
default:
if (FlexRAM[offset] != value) {
FlexRAM[offset] = value;
flexram_wait();
}
if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) {
*(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8;
flexram_wait();
}
if (FlexRAM[offset + 3] != (value >> 24)) {
FlexRAM[offset + 3] = value >> 24;
flexram_wait();
}
}
#endif
if (offset >= EEPROM_SIZE - 3) return;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
# ifdef HANDLE_UNALIGNED_WRITES
switch (offset & 3) {
case 0:
# endif
if (*(uint32_t *)(&FlexRAM[offset]) != value) {
*(uint32_t *)(&FlexRAM[offset]) = value;
flexram_wait();
}
return;
# ifdef HANDLE_UNALIGNED_WRITES
case 2:
if (*(uint16_t *)(&FlexRAM[offset]) != value) {
*(uint16_t *)(&FlexRAM[offset]) = value;
flexram_wait();
}
if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) {
*(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16;
flexram_wait();
}
return;
default:
if (FlexRAM[offset] != value) {
FlexRAM[offset] = value;
flexram_wait();
}
if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) {
*(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8;
flexram_wait();
}
if (FlexRAM[offset + 3] != (value >> 24)) {
FlexRAM[offset + 3] = value >> 24;
flexram_wait();
}
}
# endif
}
/** \brief eeprom write block
*
* FIXME: needs doc
*/
void eeprom_write_block(const void *buf, void *addr, uint32_t len)
{
uint32_t offset = (uint32_t)addr;
const uint8_t *src = (const uint8_t *)buf;
void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
uint32_t offset = (uint32_t)addr;
const uint8_t *src = (const uint8_t *)buf;
if (offset >= EEPROM_SIZE) return;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
if (len >= EEPROM_SIZE) len = EEPROM_SIZE;
if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset;
while (len > 0) {
uint32_t lsb = offset & 3;
if (lsb == 0 && len >= 4) {
// write aligned 32 bits
uint32_t val32;
val32 = *src++;
val32 |= (*src++ << 8);
val32 |= (*src++ << 16);
val32 |= (*src++ << 24);
if (*(uint32_t *)(&FlexRAM[offset]) != val32) {
*(uint32_t *)(&FlexRAM[offset]) = val32;
flexram_wait();
}
offset += 4;
len -= 4;
} else if ((lsb == 0 || lsb == 2) && len >= 2) {
// write aligned 16 bits
uint16_t val16;
val16 = *src++;
val16 |= (*src++ << 8);
if (*(uint16_t *)(&FlexRAM[offset]) != val16) {
*(uint16_t *)(&FlexRAM[offset]) = val16;
flexram_wait();
}
offset += 2;
len -= 2;
} else {
// write 8 bits
uint8_t val8 = *src++;
if (FlexRAM[offset] != val8) {
FlexRAM[offset] = val8;
flexram_wait();
}
offset++;
len--;
}
}
if (offset >= EEPROM_SIZE) return;
if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
if (len >= EEPROM_SIZE) len = EEPROM_SIZE;
if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset;
while (len > 0) {
uint32_t lsb = offset & 3;
if (lsb == 0 && len >= 4) {
// write aligned 32 bits
uint32_t val32;
val32 = *src++;
val32 |= (*src++ << 8);
val32 |= (*src++ << 16);
val32 |= (*src++ << 24);
if (*(uint32_t *)(&FlexRAM[offset]) != val32) {
*(uint32_t *)(&FlexRAM[offset]) = val32;
flexram_wait();
}
offset += 4;
len -= 4;
} else if ((lsb == 0 || lsb == 2) && len >= 2) {
// write aligned 16 bits
uint16_t val16;
val16 = *src++;
val16 |= (*src++ << 8);
if (*(uint16_t *)(&FlexRAM[offset]) != val16) {
*(uint16_t *)(&FlexRAM[offset]) = val16;
flexram_wait();
}
offset += 2;
len -= 2;
} else {
// write 8 bits
uint8_t val8 = *src++;
if (FlexRAM[offset] != val8) {
FlexRAM[offset] = val8;
flexram_wait();
}
offset++;
len--;
}
}
}
/*
void do_flash_cmd(volatile uint8_t *fstat)
{
*fstat = 0x80;
while ((*fstat & 0x80) == 0) ; // wait
*fstat = 0x80;
while ((*fstat & 0x80) == 0) ; // wait
}
00000000 <do_flash_cmd>:
0: f06f 037f mvn.w r3, #127 ; 0x7f
@ -352,128 +336,124 @@ void do_flash_cmd(volatile uint8_t *fstat)
#elif defined(KL2x) /* chip selection */
/* Teensy LC (emulated) */
#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
# define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
extern uint32_t __eeprom_workarea_start__;
extern uint32_t __eeprom_workarea_end__;
#define EEPROM_SIZE 128
# define EEPROM_SIZE 128
static uint32_t flashend = 0;
void eeprom_initialize(void)
{
const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__);
void eeprom_initialize(void) {
const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__);
do {
if (*p++ == 0xFFFF) {
flashend = (uint32_t)(p - 2);
return;
}
} while (p < (uint16_t *)SYMVAL(__eeprom_workarea_end__));
flashend = (uint32_t)((uint16_t *)SYMVAL(__eeprom_workarea_end__) - 1);
do {
if (*p++ == 0xFFFF) {
flashend = (uint32_t)(p - 2);
return;
}
} while (p < (uint16_t *)SYMVAL(__eeprom_workarea_end__));
flashend = (uint32_t)((uint16_t *)SYMVAL(__eeprom_workarea_end__) - 1);
}
uint8_t eeprom_read_byte(const uint8_t *addr)
{
uint32_t offset = (uint32_t)addr;
const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__);
const uint16_t *end = (const uint16_t *)((uint32_t)flashend);
uint16_t val;
uint8_t data=0xFF;
uint8_t eeprom_read_byte(const uint8_t *addr) {
uint32_t offset = (uint32_t)addr;
const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__);
const uint16_t *end = (const uint16_t *)((uint32_t)flashend);
uint16_t val;
uint8_t data = 0xFF;
if (!end) {
eeprom_initialize();
end = (const uint16_t *)((uint32_t)flashend);
}
if (offset < EEPROM_SIZE) {
while (p <= end) {
val = *p++;
if ((val & 255) == offset) data = val >> 8;
}
}
return data;
if (!end) {
eeprom_initialize();
end = (const uint16_t *)((uint32_t)flashend);
}
if (offset < EEPROM_SIZE) {
while (p <= end) {
val = *p++;
if ((val & 255) == offset) data = val >> 8;
}
}
return data;
}
static void flash_write(const uint16_t *code, uint32_t addr, uint32_t data)
{
// with great power comes great responsibility....
uint32_t stat;
*(uint32_t *)&(FTFA->FCCOB3) = 0x06000000 | (addr & 0x00FFFFFC);
*(uint32_t *)&(FTFA->FCCOB7) = data;
__disable_irq();
(*((void (*)(volatile uint8_t *))((uint32_t)code | 1)))(&(FTFA->FSTAT));
__enable_irq();
stat = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL);
if (stat) {
FTFA->FSTAT = stat;
}
MCM->PLACR |= MCM_PLACR_CFCC;
static void flash_write(const uint16_t *code, uint32_t addr, uint32_t data) {
// with great power comes great responsibility....
uint32_t stat;
*(uint32_t *)&(FTFA->FCCOB3) = 0x06000000 | (addr & 0x00FFFFFC);
*(uint32_t *)&(FTFA->FCCOB7) = data;
__disable_irq();
(*((void (*)(volatile uint8_t *))((uint32_t)code | 1)))(&(FTFA->FSTAT));
__enable_irq();
stat = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR | FTFA_FSTAT_ACCERR | FTFA_FSTAT_FPVIOL);
if (stat) {
FTFA->FSTAT = stat;
}
MCM->PLACR |= MCM_PLACR_CFCC;
}
void eeprom_write_byte(uint8_t *addr, uint8_t data)
{
uint32_t offset = (uint32_t)addr;
const uint16_t *p, *end = (const uint16_t *)((uint32_t)flashend);
uint32_t i, val, flashaddr;
uint16_t do_flash_cmd[] = {
0x2380, 0x7003, 0x7803, 0xb25b, 0x2b00, 0xdafb, 0x4770};
uint8_t buf[EEPROM_SIZE];
void eeprom_write_byte(uint8_t *addr, uint8_t data) {
uint32_t offset = (uint32_t)addr;
const uint16_t *p, *end = (const uint16_t *)((uint32_t)flashend);
uint32_t i, val, flashaddr;
uint16_t do_flash_cmd[] = {0x2380, 0x7003, 0x7803, 0xb25b, 0x2b00, 0xdafb, 0x4770};
uint8_t buf[EEPROM_SIZE];
if (offset >= EEPROM_SIZE) return;
if (!end) {
eeprom_initialize();
end = (const uint16_t *)((uint32_t)flashend);
}
if (++end < (uint16_t *)SYMVAL(__eeprom_workarea_end__)) {
val = (data << 8) | offset;
flashaddr = (uint32_t)end;
flashend = flashaddr;
if ((flashaddr & 2) == 0) {
val |= 0xFFFF0000;
} else {
val <<= 16;
val |= 0x0000FFFF;
}
flash_write(do_flash_cmd, flashaddr, val);
} else {
for (i=0; i < EEPROM_SIZE; i++) {
buf[i] = 0xFF;
}
val = 0;
for (p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); p < (uint16_t *)SYMVAL(__eeprom_workarea_end__); p++) {
val = *p;
if ((val & 255) < EEPROM_SIZE) {
buf[val & 255] = val >> 8;
}
}
buf[offset] = data;
for (flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__); flashaddr < (uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_end__); flashaddr += 1024) {
*(uint32_t *)&(FTFA->FCCOB3) = 0x09000000 | flashaddr;
__disable_irq();
(*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFA->FSTAT));
__enable_irq();
val = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL);;
if (val) FTFA->FSTAT = val;
MCM->PLACR |= MCM_PLACR_CFCC;
}
flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__);
for (i=0; i < EEPROM_SIZE; i++) {
if (buf[i] == 0xFF) continue;
if ((flashaddr & 2) == 0) {
val = (buf[i] << 8) | i;
} else {
val = val | (buf[i] << 24) | (i << 16);
flash_write(do_flash_cmd, flashaddr, val);
}
flashaddr += 2;
}
flashend = flashaddr;
if ((flashaddr & 2)) {
val |= 0xFFFF0000;
flash_write(do_flash_cmd, flashaddr, val);
}
}
if (offset >= EEPROM_SIZE) return;
if (!end) {
eeprom_initialize();
end = (const uint16_t *)((uint32_t)flashend);
}
if (++end < (uint16_t *)SYMVAL(__eeprom_workarea_end__)) {
val = (data << 8) | offset;
flashaddr = (uint32_t)end;
flashend = flashaddr;
if ((flashaddr & 2) == 0) {
val |= 0xFFFF0000;
} else {
val <<= 16;
val |= 0x0000FFFF;
}
flash_write(do_flash_cmd, flashaddr, val);
} else {
for (i = 0; i < EEPROM_SIZE; i++) {
buf[i] = 0xFF;
}
val = 0;
for (p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); p < (uint16_t *)SYMVAL(__eeprom_workarea_end__); p++) {
val = *p;
if ((val & 255) < EEPROM_SIZE) {
buf[val & 255] = val >> 8;
}
}
buf[offset] = data;
for (flashaddr = (uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__); flashaddr < (uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_end__); flashaddr += 1024) {
*(uint32_t *)&(FTFA->FCCOB3) = 0x09000000 | flashaddr;
__disable_irq();
(*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFA->FSTAT));
__enable_irq();
val = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR | FTFA_FSTAT_ACCERR | FTFA_FSTAT_FPVIOL);
;
if (val) FTFA->FSTAT = val;
MCM->PLACR |= MCM_PLACR_CFCC;
}
flashaddr = (uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__);
for (i = 0; i < EEPROM_SIZE; i++) {
if (buf[i] == 0xFF) continue;
if ((flashaddr & 2) == 0) {
val = (buf[i] << 8) | i;
} else {
val = val | (buf[i] << 24) | (i << 16);
flash_write(do_flash_cmd, flashaddr, val);
}
flashaddr += 2;
}
flashend = flashaddr;
if ((flashaddr & 2)) {
val |= 0xFFFF0000;
flash_write(do_flash_cmd, flashaddr, val);
}
}
}
/*
@ -492,141 +472,127 @@ void do_flash_cmd(volatile uint8_t *fstat)
c: 4770 bx lr
*/
uint16_t eeprom_read_word(const uint16_t *addr)
{
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
uint16_t eeprom_read_word(const uint16_t *addr) {
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8);
}
uint32_t eeprom_read_dword(const uint32_t *addr)
{
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
| (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
uint32_t eeprom_read_dword(const uint32_t *addr) {
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24);
}
void eeprom_read_block(void *buf, const void *addr, uint32_t len)
{
const uint8_t *p = (const uint8_t *)addr;
uint8_t *dest = (uint8_t *)buf;
while (len--) {
*dest++ = eeprom_read_byte(p++);
}
void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
const uint8_t *p = (const uint8_t *)addr;
uint8_t * dest = (uint8_t *)buf;
while (len--) {
*dest++ = eeprom_read_byte(p++);
}
}
int eeprom_is_ready(void)
{
return 1;
int eeprom_is_ready(void) { return 1; }
void eeprom_write_word(uint16_t *addr, uint16_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
}
void eeprom_write_word(uint16_t *addr, uint16_t value)
{
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
void eeprom_write_dword(uint32_t *addr, uint32_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
}
void eeprom_write_dword(uint32_t *addr, uint32_t value)
{
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
}
void eeprom_write_block(const void *buf, void *addr, uint32_t len)
{
uint8_t *p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
uint8_t * p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
}
#else
// No EEPROM supported, so emulate it
#define EEPROM_SIZE 32
# define EEPROM_SIZE 32
static uint8_t buffer[EEPROM_SIZE];
uint8_t eeprom_read_byte(const uint8_t *addr) {
uint32_t offset = (uint32_t)addr;
return buffer[offset];
uint32_t offset = (uint32_t)addr;
return buffer[offset];
}
void eeprom_write_byte(uint8_t *addr, uint8_t value) {
uint32_t offset = (uint32_t)addr;
buffer[offset] = value;
uint32_t offset = (uint32_t)addr;
buffer[offset] = value;
}
uint16_t eeprom_read_word(const uint16_t *addr) {
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8);
}
uint32_t eeprom_read_dword(const uint32_t *addr) {
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
| (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24);
}
void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
const uint8_t *p = (const uint8_t *)addr;
uint8_t *dest = (uint8_t *)buf;
while (len--) {
*dest++ = eeprom_read_byte(p++);
}
const uint8_t *p = (const uint8_t *)addr;
uint8_t * dest = (uint8_t *)buf;
while (len--) {
*dest++ = eeprom_read_byte(p++);
}
}
void eeprom_write_word(uint16_t *addr, uint16_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
}
void eeprom_write_dword(uint32_t *addr, uint32_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
}
void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
uint8_t *p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
uint8_t * p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
}
#endif /* chip selection */
// The update functions just calls write for now, but could probably be optimized
void eeprom_update_byte(uint8_t *addr, uint8_t value) {
eeprom_write_byte(addr, value);
}
void eeprom_update_byte(uint8_t *addr, uint8_t value) { eeprom_write_byte(addr, value); }
void eeprom_update_word(uint16_t *addr, uint16_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
}
void eeprom_update_dword(uint32_t *addr, uint32_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
}
void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
uint8_t *p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
uint8_t * p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
}

162
tmk_core/common/chibios/flash_stm32.c Executable file → Normal file
View file

@ -17,105 +17,95 @@
*/
#if defined(EEPROM_EMU_STM32F303xC)
#define STM32F303xC
#include "stm32f3xx.h"
# define STM32F303xC
# include "stm32f3xx.h"
#elif defined(EEPROM_EMU_STM32F103xB)
#define STM32F103xB
#include "stm32f1xx.h"
# define STM32F103xB
# include "stm32f1xx.h"
#elif defined(EEPROM_EMU_STM32F072xB)
#define STM32F072xB
#include "stm32f0xx.h"
# define STM32F072xB
# include "stm32f0xx.h"
#else
#error "not implemented."
# error "not implemented."
#endif
#include "flash_stm32.h"
#if defined(EEPROM_EMU_STM32F103xB)
#define FLASH_SR_WRPERR FLASH_SR_WRPRTERR
# define FLASH_SR_WRPERR FLASH_SR_WRPRTERR
#endif
/* Delay definition */
#define EraseTimeout ((uint32_t)0x00000FFF)
#define ProgramTimeout ((uint32_t)0x0000001F)
#define EraseTimeout ((uint32_t)0x00000FFF)
#define ProgramTimeout ((uint32_t)0x0000001F)
#define ASSERT(exp) (void)((0))
/**
* @brief Inserts a time delay.
* @param None
* @retval None
*/
static void delay(void)
{
* @brief Inserts a time delay.
* @param None
* @retval None
*/
static void delay(void) {
__IO uint32_t i = 0;
for(i = 0xFF; i != 0; i--) { }
for (i = 0xFF; i != 0; i--) {
}
}
/**
* @brief Returns the FLASH Status.
* @param None
* @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP or FLASH_COMPLETE
*/
FLASH_Status FLASH_GetStatus(void)
{
if ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY)
return FLASH_BUSY;
* @brief Returns the FLASH Status.
* @param None
* @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP or FLASH_COMPLETE
*/
FLASH_Status FLASH_GetStatus(void) {
if ((FLASH->SR & FLASH_SR_BSY) == FLASH_SR_BSY) return FLASH_BUSY;
if ((FLASH->SR & FLASH_SR_PGERR) != 0)
return FLASH_ERROR_PG;
if ((FLASH->SR & FLASH_SR_PGERR) != 0) return FLASH_ERROR_PG;
if ((FLASH->SR & FLASH_SR_WRPERR) != 0 )
return FLASH_ERROR_WRP;
if ((FLASH->SR & FLASH_SR_WRPERR) != 0) return FLASH_ERROR_WRP;
if ((FLASH->SR & FLASH_OBR_OPTERR) != 0 )
return FLASH_ERROR_OPT;
if ((FLASH->SR & FLASH_OBR_OPTERR) != 0) return FLASH_ERROR_OPT;
return FLASH_COMPLETE;
}
/**
* @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
* @param Timeout: FLASH progamming Timeout
* @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout)
{
* @brief Waits for a Flash operation to complete or a TIMEOUT to occur.
* @param Timeout: FLASH progamming Timeout
* @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout) {
FLASH_Status status;
/* Check for the Flash Status */
status = FLASH_GetStatus();
/* Wait for a Flash operation to complete or a TIMEOUT to occur */
while ((status == FLASH_BUSY) && (Timeout != 0x00))
{
while ((status == FLASH_BUSY) && (Timeout != 0x00)) {
delay();
status = FLASH_GetStatus();
Timeout--;
}
if (Timeout == 0)
status = FLASH_TIMEOUT;
if (Timeout == 0) status = FLASH_TIMEOUT;
/* Return the operation status */
return status;
}
/**
* @brief Erases a specified FLASH page.
* @param Page_Address: The page address to be erased.
* @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
{
* @brief Erases a specified FLASH page.
* @param Page_Address: The page address to be erased.
* @retval FLASH Status: The returned value can be: FLASH_BUSY, FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ErasePage(uint32_t Page_Address) {
FLASH_Status status = FLASH_COMPLETE;
/* Check the parameters */
ASSERT(IS_FLASH_ADDRESS(Page_Address));
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(EraseTimeout);
if(status == FLASH_COMPLETE)
{
if (status == FLASH_COMPLETE) {
/* if the previous operation is completed, proceed to erase the page */
FLASH->CR |= FLASH_CR_PER;
FLASH->AR = Page_Address;
@ -123,8 +113,7 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(EraseTimeout);
if(status != FLASH_TIMEOUT)
{
if (status != FLASH_TIMEOUT) {
/* if the erase operation is completed, disable the PER Bit */
FLASH->CR &= ~FLASH_CR_PER;
}
@ -135,29 +124,25 @@ FLASH_Status FLASH_ErasePage(uint32_t Page_Address)
}
/**
* @brief Programs a half word at a specified address.
* @param Address: specifies the address to be programmed.
* @param Data: specifies the data to be programmed.
* @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
{
* @brief Programs a half word at a specified address.
* @param Address: specifies the address to be programmed.
* @param Data: specifies the data to be programmed.
* @retval FLASH Status: The returned value can be: FLASH_ERROR_PG,
* FLASH_ERROR_WRP, FLASH_COMPLETE or FLASH_TIMEOUT.
*/
FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data) {
FLASH_Status status = FLASH_BAD_ADDRESS;
if (IS_FLASH_ADDRESS(Address))
{
if (IS_FLASH_ADDRESS(Address)) {
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(ProgramTimeout);
if(status == FLASH_COMPLETE)
{
if (status == FLASH_COMPLETE) {
/* if the previous operation is completed, proceed to program the new data */
FLASH->CR |= FLASH_CR_PG;
*(__IO uint16_t*)Address = Data;
/* Wait for last operation to be completed */
status = FLASH_WaitForLastOperation(ProgramTimeout);
if(status != FLASH_TIMEOUT)
{
if (status != FLASH_TIMEOUT) {
/* if the program operation is completed, disable the PG Bit */
FLASH->CR &= ~FLASH_CR_PG;
}
@ -168,39 +153,36 @@ FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)
}
/**
* @brief Unlocks the FLASH Program Erase Controller.
* @param None
* @retval None
*/
void FLASH_Unlock(void)
{
* @brief Unlocks the FLASH Program Erase Controller.
* @param None
* @retval None
*/
void FLASH_Unlock(void) {
/* Authorize the FPEC Access */
FLASH->KEYR = FLASH_KEY1;
FLASH->KEYR = FLASH_KEY2;
}
/**
* @brief Locks the FLASH Program Erase Controller.
* @param None
* @retval None
*/
void FLASH_Lock(void)
{
* @brief Locks the FLASH Program Erase Controller.
* @param None
* @retval None
*/
void FLASH_Lock(void) {
/* Set the Lock Bit to lock the FPEC and the FCR */
FLASH->CR |= FLASH_CR_LOCK;
}
/**
* @brief Clears the FLASH's pending flags.
* @param FLASH_FLAG: specifies the FLASH flags to clear.
* This parameter can be any combination of the following values:
* @arg FLASH_FLAG_PGERR: FLASH Programming error flag flag
* @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag
* @arg FLASH_FLAG_EOP: FLASH End of Programming flag
* @retval None
*/
void FLASH_ClearFlag(uint32_t FLASH_FLAG)
{
* @brief Clears the FLASH's pending flags.
* @param FLASH_FLAG: specifies the FLASH flags to clear.
* This parameter can be any combination of the following values:
* @arg FLASH_FLAG_PGERR: FLASH Programming error flag flag
* @arg FLASH_FLAG_WRPERR: FLASH Write protected error flag
* @arg FLASH_FLAG_EOP: FLASH End of Programming flag
* @retval None
*/
void FLASH_ClearFlag(uint32_t FLASH_FLAG) {
/* Clear the flags */
FLASH->SR = FLASH_FLAG;
}

15
tmk_core/common/chibios/flash_stm32.h Executable file → Normal file
View file

@ -10,7 +10,7 @@
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
* This files are free to use from https://github.com/rogerclarkmelbourne/Arduino_STM32 and
* https://github.com/leaflabs/libmaple
*
* Modifications for QMK and STM32F303 by Yiancar
@ -20,22 +20,13 @@
#define __FLASH_STM32_H
#ifdef __cplusplus
extern "C" {
extern "C" {
#endif
#include "ch.h"
#include "hal.h"
typedef enum
{
FLASH_BUSY = 1,
FLASH_ERROR_PG,
FLASH_ERROR_WRP,
FLASH_ERROR_OPT,
FLASH_COMPLETE,
FLASH_TIMEOUT,
FLASH_BAD_ADDRESS
} FLASH_Status;
typedef enum { FLASH_BUSY = 1, FLASH_ERROR_PG, FLASH_ERROR_WRP, FLASH_ERROR_OPT, FLASH_COMPLETE, FLASH_TIMEOUT, FLASH_BAD_ADDRESS } FLASH_Status;
#define IS_FLASH_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) < 0x0807FFFF))

View file

@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "printf.h"
typedef void (*putcf) (void*,char);
typedef void (*putcf)(void*, char);
static putcf stdout_putf;
static void* stdout_putp;
@ -35,206 +35,185 @@ static void* stdout_putp;
#ifdef PRINTF_LONG_SUPPORT
static void uli2a(unsigned long int num, unsigned int base, int uc,char * bf)
{
int n=0;
unsigned int d=1;
while (num/d >= base)
d*=base;
while (d!=0) {
static void uli2a(unsigned long int num, unsigned int base, int uc, char* bf) {
int n = 0;
unsigned int d = 1;
while (num / d >= base) d *= base;
while (d != 0) {
int dgt = num / d;
num%=d;
d/=base;
if (n || dgt>0|| d==0) {
*bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10);
num %= d;
d /= base;
if (n || dgt > 0 || d == 0) {
*bf++ = dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10);
++n;
}
}
*bf=0;
}
*bf = 0;
}
static void li2a (long num, char * bf)
{
if (num<0) {
num=-num;
static void li2a(long num, char* bf) {
if (num < 0) {
num = -num;
*bf++ = '-';
}
uli2a(num,10,0,bf);
}
uli2a(num, 10, 0, bf);
}
#endif
static void ui2a(unsigned int num, unsigned int base, int uc,char * bf)
{
int n=0;
unsigned int d=1;
while (num/d >= base)
d*=base;
while (d!=0) {
static void ui2a(unsigned int num, unsigned int base, int uc, char* bf) {
int n = 0;
unsigned int d = 1;
while (num / d >= base) d *= base;
while (d != 0) {
int dgt = num / d;
num%= d;
d/=base;
if (n || dgt>0 || d==0) {
*bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10);
num %= d;
d /= base;
if (n || dgt > 0 || d == 0) {
*bf++ = dgt + (dgt < 10 ? '0' : (uc ? 'A' : 'a') - 10);
++n;
}
}
*bf=0;
}
*bf = 0;
}
static void i2a (int num, char * bf)
{
if (num<0) {
num=-num;
static void i2a(int num, char* bf) {
if (num < 0) {
num = -num;
*bf++ = '-';
}
ui2a(num,10,0,bf);
}
ui2a(num, 10, 0, bf);
}
static int a2d(char ch)
{
if (ch>='0' && ch<='9')
return ch-'0';
else if (ch>='a' && ch<='f')
return ch-'a'+10;
else if (ch>='A' && ch<='F')
return ch-'A'+10;
else return -1;
static int a2d(char ch) {
if (ch >= '0' && ch <= '9')
return ch - '0';
else if (ch >= 'a' && ch <= 'f')
return ch - 'a' + 10;
else if (ch >= 'A' && ch <= 'F')
return ch - 'A' + 10;
else
return -1;
}
static char a2i(char ch, char** src, int base, int* nump) {
char* p = *src;
int num = 0;
int digit;
while ((digit = a2d(ch)) >= 0) {
if (digit > base) break;
num = num * base + digit;
ch = *p++;
}
static char a2i(char ch, char** src,int base,int* nump)
{
char* p= *src;
int num=0;
int digit;
while ((digit=a2d(ch))>=0) {
if (digit>base) break;
num=num*base+digit;
ch=*p++;
}
*src=p;
*nump=num;
*src = p;
*nump = num;
return ch;
}
}
static void putchw(void* putp,putcf putf,int n, char z, char* bf)
{
char fc=z? '0' : ' ';
char ch;
char* p=bf;
while (*p++ && n > 0)
n--;
while (n-- > 0)
putf(putp,fc);
while ((ch= *bf++))
putf(putp,ch);
}
static void putchw(void* putp, putcf putf, int n, char z, char* bf) {
char fc = z ? '0' : ' ';
char ch;
char* p = bf;
while (*p++ && n > 0) n--;
while (n-- > 0) putf(putp, fc);
while ((ch = *bf++)) putf(putp, ch);
}
void tfp_format(void* putp,putcf putf,char *fmt, va_list va)
{
void tfp_format(void* putp, putcf putf, char* fmt, va_list va) {
char bf[12];
char ch;
while ((ch=*(fmt++))) {
if (ch!='%')
putf(putp,ch);
while ((ch = *(fmt++))) {
if (ch != '%')
putf(putp, ch);
else {
char lz=0;
#ifdef PRINTF_LONG_SUPPORT
char lng=0;
char lz = 0;
#ifdef PRINTF_LONG_SUPPORT
char lng = 0;
#endif
int w=0;
ch=*(fmt++);
if (ch=='0') {
ch=*(fmt++);
lz=1;
}
if (ch>='0' && ch<='9') {
ch=a2i(ch,&fmt,10,&w);
}
#ifdef PRINTF_LONG_SUPPORT
if (ch=='l') {
ch=*(fmt++);
lng=1;
int w = 0;
ch = *(fmt++);
if (ch == '0') {
ch = *(fmt++);
lz = 1;
}
if (ch >= '0' && ch <= '9') {
ch = a2i(ch, &fmt, 10, &w);
}
#ifdef PRINTF_LONG_SUPPORT
if (ch == 'l') {
ch = *(fmt++);
lng = 1;
}
#endif
switch (ch) {
case 0:
case 0:
goto abort;
case 'u' : {
#ifdef PRINTF_LONG_SUPPORT
case 'u': {
#ifdef PRINTF_LONG_SUPPORT
if (lng)
uli2a(va_arg(va, unsigned long int),10,0,bf);
uli2a(va_arg(va, unsigned long int), 10, 0, bf);
else
#endif
ui2a(va_arg(va, unsigned int),10,0,bf);
putchw(putp,putf,w,lz,bf);
break;
}
case 'd' : {
#ifdef PRINTF_LONG_SUPPORT
if (lng)
li2a(va_arg(va, unsigned long int),bf);
else
#endif
i2a(va_arg(va, int),bf);
putchw(putp,putf,w,lz,bf);
break;
}
case 'x': case 'X' :
#ifdef PRINTF_LONG_SUPPORT
if (lng)
uli2a(va_arg(va, unsigned long int),16,(ch=='X'),bf);
else
#endif
ui2a(va_arg(va, unsigned int),16,(ch=='X'),bf);
putchw(putp,putf,w,lz,bf);
break;
case 'c' :
putf(putp,(char)(va_arg(va, int)));
break;
case 's' :
putchw(putp,putf,w,0,va_arg(va, char*));
break;
case '%' :
putf(putp,ch);
default:
ui2a(va_arg(va, unsigned int), 10, 0, bf);
putchw(putp, putf, w, lz, bf);
break;
}
case 'd': {
#ifdef PRINTF_LONG_SUPPORT
if (lng)
li2a(va_arg(va, unsigned long int), bf);
else
#endif
i2a(va_arg(va, int), bf);
putchw(putp, putf, w, lz, bf);
break;
}
case 'x':
case 'X':
#ifdef PRINTF_LONG_SUPPORT
if (lng)
uli2a(va_arg(va, unsigned long int), 16, (ch == 'X'), bf);
else
#endif
ui2a(va_arg(va, unsigned int), 16, (ch == 'X'), bf);
putchw(putp, putf, w, lz, bf);
break;
case 'c':
putf(putp, (char)(va_arg(va, int)));
break;
case 's':
putchw(putp, putf, w, 0, va_arg(va, char*));
break;
case '%':
putf(putp, ch);
default:
break;
}
}
abort:;
}
abort:;
}
void init_printf(void* putp, void (*putf)(void*, char)) {
stdout_putf = putf;
stdout_putp = putp;
}
void init_printf(void* putp,void (*putf) (void*,char))
{
stdout_putf=putf;
stdout_putp=putp;
}
void tfp_printf(char *fmt, ...)
{
void tfp_printf(char* fmt, ...) {
va_list va;
va_start(va,fmt);
tfp_format(stdout_putp,stdout_putf,fmt,va);
va_start(va, fmt);
tfp_format(stdout_putp, stdout_putf, fmt, va);
va_end(va);
}
}
static void putcp(void* p,char c)
{
*(*((char**)p))++ = c;
}
static void putcp(void* p, char c) { *(*((char**)p))++ = c; }
void tfp_sprintf(char* s,char *fmt, ...)
{
void tfp_sprintf(char* s, char* fmt, ...) {
va_list va;
va_start(va,fmt);
tfp_format(&s,putcp,fmt,va);
putcp(&s,0);
va_start(va, fmt);
tfp_format(&s, putcp, fmt, va);
putcp(&s, 0);
va_end(va);
}
}

View file

@ -15,7 +15,7 @@ version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
@ -24,35 +24,35 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
This library is realy just two files: 'printf.h' and 'printf.c'.
They provide a simple and small (+200 loc) printf functionality to
They provide a simple and small (+200 loc) printf functionality to
be used in embedded systems.
I've found them so usefull in debugging that I do not bother with a
I've found them so usefull in debugging that I do not bother with a
debugger at all.
They are distributed in source form, so to use them, just compile them
into your project.
They are distributed in source form, so to use them, just compile them
into your project.
Two printf variants are provided: printf and sprintf.
Two printf variants are provided: printf and sprintf.
The formats supported by this implementation are: 'd' 'u' 'c' 's' 'x' 'X'.
Zero padding and field width are also supported.
If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the
If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the
long specifier is also
supported. Note that this will pull in some long math routines (pun intended!)
and thus make your executable noticably longer.
The memory foot print of course depends on the target cpu, compiler and
compiler options, but a rough guestimate (based on a H8S target) is about
1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space.
Not too bad. Your milage may vary. By hacking the source code you can
get rid of some hunred bytes, I'm sure, but personally I feel the balance of
The memory foot print of course depends on the target cpu, compiler and
compiler options, but a rough guestimate (based on a H8S target) is about
1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space.
Not too bad. Your milage may vary. By hacking the source code you can
get rid of some hunred bytes, I'm sure, but personally I feel the balance of
functionality and flexibility versus code size is close to optimal for
many embedded systems.
To use the printf you need to supply your own character output function,
To use the printf you need to supply your own character output function,
something like :
void putc ( void* p, char c)
@ -61,25 +61,25 @@ something like :
SERIAL_PORT_TX_REGISTER = c;
}
Before you can call printf you need to initialize it to use your
Before you can call printf you need to initialize it to use your
character output function with something like:
init_printf(NULL,putc);
Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc',
the NULL (or any pointer) you pass into the 'init_printf' will eventually be
passed to your 'putc' routine. This allows you to pass some storage space (or
anything realy) to the character output function, if necessary.
This is not often needed but it was implemented like that because it made
Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc',
the NULL (or any pointer) you pass into the 'init_printf' will eventually be
passed to your 'putc' routine. This allows you to pass some storage space (or
anything realy) to the character output function, if necessary.
This is not often needed but it was implemented like that because it made
implementing the sprintf function so neat (look at the source code).
The code is re-entrant, except for the 'init_printf' function, so it
is safe to call it from interupts too, although this may result in mixed output.
The code is re-entrant, except for the 'init_printf' function, so it
is safe to call it from interupts too, although this may result in mixed output.
If you rely on re-entrancy, take care that your 'putc' function is re-entrant!
The printf and sprintf functions are actually macros that translate to
The printf and sprintf functions are actually macros that translate to
'tfp_printf' and 'tfp_sprintf'. This makes it possible
to use them along with 'stdio.h' printf's in a single source file.
to use them along with 'stdio.h' printf's in a single source file.
You just need to undef the names before you include the 'stdio.h'.
Note that these are not function like macros, so if you have variables
or struct members with these names, things will explode in your face.
@ -92,20 +92,19 @@ For further details see source code.
regs Kusti, 23.10.2004
*/
#ifndef __TFP_PRINTF__
#define __TFP_PRINTF__
#include <stdarg.h>
void init_printf(void* putp,void (*putf) (void*,char));
void init_printf(void* putp, void (*putf)(void*, char));
void tfp_printf(char *fmt, ...);
void tfp_sprintf(char* s,char *fmt, ...);
void tfp_printf(char* fmt, ...);
void tfp_sprintf(char* s, char* fmt, ...);
void tfp_format(void* putp,void (*putf) (void*,char),char *fmt, va_list va);
void tfp_format(void* putp, void (*putf)(void*, char), char* fmt, va_list va);
#define printf tfp_printf
#define sprintf tfp_sprintf
#define printf tfp_printf
#define sprintf tfp_sprintf
#endif

View file

@ -12,14 +12,14 @@
#if defined(KL2x) || defined(K20x)
/* Use Low Power Timer (LPTMR) */
#define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR
#define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF
# define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR
# define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF
#elif defined(STM32F0XX)
/* Use TIM14 manually */
#define TIMER_INTERRUPT_VECTOR STM32_TIM14_HANDLER
#define RESET_COUNTER STM32_TIM14->SR &= ~STM32_TIM_SR_UIF
# define TIMER_INTERRUPT_VECTOR STM32_TIM14_HANDLER
# define RESET_COUNTER STM32_TIM14->SR &= ~STM32_TIM_SR_UIF
#endif
@ -31,39 +31,34 @@
* http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63
* (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i }
*/
static const uint8_t breathing_table[64] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10,
15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252,
255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23,
15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static const uint8_t breathing_table[64] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
/* interrupt handler */
OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
OSAL_IRQ_PROLOGUE();
/* Software PWM
* timer:1111 1111 1111 1111
* \_____/\/ \_______/____ count(0-255)
* \ \______________ duration of step(4)
* \__________________ index of step table(0-63)
*/
* timer:1111 1111 1111 1111
* \_____/\/ \_______/____ count(0-255)
* \ \______________ duration of step(4)
* \__________________ index of step table(0-63)
*/
// this works for cca 65536 irqs/sec
static union {
uint16_t row;
struct {
uint8_t count:8;
uint8_t duration:2;
uint8_t index:6;
} pwm;
} timer = { .row = 0 };
uint16_t row;
struct {
uint8_t count : 8;
uint8_t duration : 2;
uint8_t index : 6;
} pwm;
} timer = {.row = 0};
timer.row++;
// LED on
if (timer.pwm.count == 0) {
led_set(1<<USB_LED_CAPS_LOCK);
led_set(1 << USB_LED_CAPS_LOCK);
}
// LED off
if (timer.pwm.count == breathing_table[timer.pwm.index]) {
@ -78,19 +73,18 @@ OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
#endif /* common parts for known platforms */
#if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */
/* LPTMR clock options */
#define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */
#define LPTMR_CLOCK_LPO 1 /* 1kHz clock */
#define LPTMR_CLOCK_ERCLK32K 2 /* external 32kHz crystal */
#define LPTMR_CLOCK_OSCERCLK 3 /* output from OSC */
# define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */
# define LPTMR_CLOCK_LPO 1 /* 1kHz clock */
# define LPTMR_CLOCK_ERCLK32K 2 /* external 32kHz crystal */
# define LPTMR_CLOCK_OSCERCLK 3 /* output from OSC */
/* Work around inconsistencies in Freescale naming */
#if !defined(SIM_SCGC5_LPTMR)
#define SIM_SCGC5_LPTMR SIM_SCGC5_LPTIMER
#endif
# if !defined(SIM_SCGC5_LPTMR)
# define SIM_SCGC5_LPTMR SIM_SCGC5_LPTIMER
# endif
/* Initialise the timer */
void sleep_led_init(void) {
@ -101,52 +95,52 @@ void sleep_led_init(void) {
/* Set the compare value */
LPTMR0->CMR = 0; // trigger on counter value (i.e. every time)
/* Set up clock source and prescaler */
/* Software PWM
* ______ ______ __
* | ON |___OFF___| ON |___OFF___| ....
* |<-------------->|<-------------->|<- ....
* PWM period PWM period
*
* R interrupts/period[resolution]
* F periods/second[frequency]
* R * F interrupts/second
*/
/* Set up clock source and prescaler */
/* Software PWM
* ______ ______ __
* | ON |___OFF___| ON |___OFF___| ....
* |<-------------->|<-------------->|<- ....
* PWM period PWM period
*
* R interrupts/period[resolution]
* F periods/second[frequency]
* R * F interrupts/second
*/
/* === OPTION 1 === */
#if 0
/* === OPTION 1 === */
# if 0
// 1kHz LPO
// No prescaler => 1024 irqs/sec
// Note: this is too slow for a smooth breathe
LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_LPO)|LPTMRx_PSR_PBYP;
#endif /* OPTION 1 */
# endif /* OPTION 1 */
/* === OPTION 2 === */
#if 1
/* === OPTION 2 === */
# if 1
// nMHz IRC (n=4 on KL25Z, KL26Z and K20x; n=2 or 8 on KL27Z)
MCG->C2 |= MCG_C2_IRCS; // fast (4MHz) internal ref clock
#if defined(KL27) // divide the 8MHz IRC by 2, to have the same MCGIRCLK speed as others
MCG->C2 |= MCG_C2_IRCS; // fast (4MHz) internal ref clock
# if defined(KL27) // divide the 8MHz IRC by 2, to have the same MCGIRCLK speed as others
MCG->MC |= MCG_MC_LIRC_DIV2_DIV2;
#endif /* KL27 */
MCG->C1 |= MCG_C1_IRCLKEN; // enable internal ref clock
# endif /* KL27 */
MCG->C1 |= MCG_C1_IRCLKEN; // enable internal ref clock
// to work in stop mode, also MCG_C1_IREFSTEN
// Divide 4MHz by 2^N (N=6) => 62500 irqs/sec =>
// => approx F=61, R=256, duration = 4
LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_MCGIRCLK)|LPTMRx_PSR_PRESCALE(6);
#endif /* OPTION 2 */
LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_MCGIRCLK) | LPTMRx_PSR_PRESCALE(6);
# endif /* OPTION 2 */
/* === OPTION 3 === */
#if 0
/* === OPTION 3 === */
# if 0
// OSC output (external crystal), usually 8MHz or 16MHz
OSC0->CR |= OSC_CR_ERCLKEN; // enable ext ref clock
// to work in stop mode, also OSC_CR_EREFSTEN
// Divide by 2^N
LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_OSCERCLK)|LPTMRx_PSR_PRESCALE(7);
#endif /* OPTION 3 */
# endif /* OPTION 3 */
/* === END OPTIONS === */
/* Interrupt on TCF set (compare flag) */
nvicEnableVector(LPTMR0_IRQn, 2); // vector, priority
nvicEnableVector(LPTMR0_IRQn, 2); // vector, priority
LPTMR0->CSR |= LPTMRx_CSR_TIE;
}
@ -205,20 +199,14 @@ void sleep_led_toggle(void) {
STM32_TIM14->CR1 ^= STM32_TIM_CR1_CEN;
}
#else /* platform selection: not on familiar chips */
void sleep_led_init(void) {
}
void sleep_led_enable(void) {
led_set(1<<USB_LED_CAPS_LOCK);
}
void sleep_led_disable(void) {
led_set(0);
}
void sleep_led_init(void) {}
void sleep_led_enable(void) { led_set(1 << USB_LED_CAPS_LOCK); }
void sleep_led_disable(void) { led_set(0); }
void sleep_led_toggle(void) {
// not implemented
}

View file

@ -17,49 +17,44 @@
* FIXME: needs doc
*/
void suspend_idle(uint8_t time) {
// TODO: this is not used anywhere - what units is 'time' in?
wait_ms(time);
// TODO: this is not used anywhere - what units is 'time' in?
wait_ms(time);
}
/** \brief Run keyboard level Power down
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void suspend_power_down_user (void) { }
__attribute__((weak)) void suspend_power_down_user(void) {}
/** \brief Run keyboard level Power down
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void suspend_power_down_kb(void) {
suspend_power_down_user();
}
__attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); }
/** \brief suspend power down
*
* FIXME: needs doc
*/
void suspend_power_down(void) {
// TODO: figure out what to power down and how
// shouldn't power down TPM/FTM if we want a breathing LED
// also shouldn't power down USB
// TODO: figure out what to power down and how
// shouldn't power down TPM/FTM if we want a breathing LED
// also shouldn't power down USB
suspend_power_down_kb();
// on AVR, this enables the watchdog for 15ms (max), and goes to
// SLEEP_MODE_PWR_DOWN
suspend_power_down_kb();
// on AVR, this enables the watchdog for 15ms (max), and goes to
// SLEEP_MODE_PWR_DOWN
wait_ms(17);
wait_ms(17);
}
/** \brief suspend wakeup condition
*
* FIXME: needs doc
*/
__attribute__ ((weak)) void matrix_power_up(void) {}
__attribute__ ((weak)) void matrix_power_down(void) {}
bool suspend_wakeup_condition(void)
{
__attribute__((weak)) void matrix_power_up(void) {}
__attribute__((weak)) void matrix_power_down(void) {}
bool suspend_wakeup_condition(void) {
matrix_power_up();
matrix_scan();
matrix_power_down();
@ -73,25 +68,20 @@ bool suspend_wakeup_condition(void)
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void suspend_wakeup_init_user(void) { }
__attribute__((weak)) void suspend_wakeup_init_user(void) {}
/** \brief run keyboard level code immediately after wakeup
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void suspend_wakeup_init_kb(void) {
suspend_wakeup_init_user();
}
__attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); }
/** \brief suspend wakeup condition
*
* run immediately after wakeup
* FIXME: needs doc
*/
void suspend_wakeup_init(void)
{
void suspend_wakeup_init(void) {
// clear keyboard state
// need to do it manually, because we're running from ISR
// and clear_keyboard() calls print
@ -111,5 +101,5 @@ void suspend_wakeup_init(void)
#ifdef BACKLIGHT_ENABLE
backlight_init();
#endif /* BACKLIGHT_ENABLE */
suspend_wakeup_init_kb();
suspend_wakeup_init_kb();
}

View file

@ -2,40 +2,32 @@
#include "timer.h"
static systime_t last_systime = 0;
static systime_t overflow = 0;
static uint32_t current_time_ms = 0;
static systime_t last_systime = 0;
static systime_t overflow = 0;
static uint32_t current_time_ms = 0;
void timer_init(void) {
timer_clear();
}
void timer_init(void) { timer_clear(); }
void timer_clear(void) {
last_systime = chVTGetSystemTime();
overflow = 0;
current_time_ms = 0;
last_systime = chVTGetSystemTime();
overflow = 0;
current_time_ms = 0;
}
uint16_t timer_read(void) {
return (uint16_t)timer_read32();
}
uint16_t timer_read(void) { return (uint16_t)timer_read32(); }
uint32_t timer_read32(void) {
// Note: We assume that the timer update is called at least once betweeen every wrap around of the system time
systime_t current_systime = chVTGetSystemTime();
systime_t elapsed = current_systime - last_systime + overflow;
uint32_t elapsed_ms = ST2MS(elapsed);
current_time_ms += elapsed_ms;
overflow = elapsed - MS2ST(elapsed_ms);
last_systime = current_systime;
// Note: We assume that the timer update is called at least once betweeen every wrap around of the system time
systime_t current_systime = chVTGetSystemTime();
systime_t elapsed = current_systime - last_systime + overflow;
uint32_t elapsed_ms = ST2MS(elapsed);
current_time_ms += elapsed_ms;
overflow = elapsed - MS2ST(elapsed_ms);
last_systime = current_systime;
return current_time_ms;
return current_time_ms;
}
uint16_t timer_elapsed(uint16_t last) {
return timer_read() - last;
}
uint16_t timer_elapsed(uint16_t last) { return timer_read() - last; }
uint32_t timer_elapsed32(uint32_t last) {
return timer_read32() - last;
}
uint32_t timer_elapsed32(uint32_t last) { return timer_read32() - last; }

View file

@ -37,25 +37,24 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "version.h"
#ifdef MOUSEKEY_ENABLE
#include "mousekey.h"
# include "mousekey.h"
#endif
#ifdef PROTOCOL_PJRC
#include "usb_keyboard.h"
#ifdef EXTRAKEY_ENABLE
#include "usb_extra.h"
#endif
# include "usb_keyboard.h"
# ifdef EXTRAKEY_ENABLE
# include "usb_extra.h"
# endif
#endif
#ifdef PROTOCOL_VUSB
#include "usbdrv.h"
# include "usbdrv.h"
#endif
#ifdef AUDIO_ENABLE
#include "audio.h"
# include "audio.h"
#endif /* AUDIO_ENABLE */
static bool command_common(uint8_t code);
static void command_common_help(void);
static void print_version(void);
@ -69,16 +68,12 @@ static void mousekey_console_help(void);
static void switch_default_layer(uint8_t layer);
command_state_t command_state = ONESHOT;
bool command_proc(uint8_t code)
{
bool command_proc(uint8_t code) {
switch (command_state) {
case ONESHOT:
if (!IS_COMMAND())
return false;
if (!IS_COMMAND()) return false;
return (command_extra(code) || command_common(code));
break;
case CONSOLE:
@ -101,86 +96,63 @@ bool command_proc(uint8_t code)
/* TODO: Refactoring is needed. */
/* This allows to define extra commands. return false when not processed. */
bool command_extra(uint8_t code) __attribute__ ((weak));
bool command_extra(uint8_t code)
{
bool command_extra(uint8_t code) __attribute__((weak));
bool command_extra(uint8_t code) {
(void)code;
return false;
}
bool command_console_extra(uint8_t code) __attribute__ ((weak));
bool command_console_extra(uint8_t code)
{
bool command_console_extra(uint8_t code) __attribute__((weak));
bool command_console_extra(uint8_t code) {
(void)code;
return false;
}
/***********************************************************
* Command common
***********************************************************/
static void command_common_help(void)
{
print( "\n\t- Magic -\n"
STR(MAGIC_KEY_DEBUG ) ": Debug Message Toggle\n"
STR(MAGIC_KEY_DEBUG_MATRIX) ": Matrix Debug Mode Toggle - Show keypresses in matrix grid\n"
STR(MAGIC_KEY_DEBUG_KBD ) ": Keyboard Debug Toggle - Show keypress report\n"
STR(MAGIC_KEY_DEBUG_MOUSE ) ": Debug Mouse Toggle\n"
STR(MAGIC_KEY_VERSION ) ": Version\n"
STR(MAGIC_KEY_STATUS ) ": Status\n"
STR(MAGIC_KEY_CONSOLE ) ": Activate Console Mode\n"
static void command_common_help(void) {
print("\n\t- Magic -\n" STR(MAGIC_KEY_DEBUG) ": Debug Message Toggle\n" STR(MAGIC_KEY_DEBUG_MATRIX) ": Matrix Debug Mode Toggle - Show keypresses in matrix grid\n" STR(MAGIC_KEY_DEBUG_KBD) ": Keyboard Debug Toggle - Show keypress report\n" STR(MAGIC_KEY_DEBUG_MOUSE) ": Debug Mouse Toggle\n" STR(MAGIC_KEY_VERSION) ": Version\n" STR(MAGIC_KEY_STATUS) ": Status\n" STR(MAGIC_KEY_CONSOLE) ": Activate Console Mode\n"
#if MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
STR(MAGIC_KEY_LAYER0 ) ": Switch to Layer 0\n"
STR(MAGIC_KEY_LAYER1 ) ": Switch to Layer 1\n"
STR(MAGIC_KEY_LAYER2 ) ": Switch to Layer 2\n"
STR(MAGIC_KEY_LAYER3 ) ": Switch to Layer 3\n"
STR(MAGIC_KEY_LAYER4 ) ": Switch to Layer 4\n"
STR(MAGIC_KEY_LAYER5 ) ": Switch to Layer 5\n"
STR(MAGIC_KEY_LAYER6 ) ": Switch to Layer 6\n"
STR(MAGIC_KEY_LAYER7 ) ": Switch to Layer 7\n"
STR(MAGIC_KEY_LAYER8 ) ": Switch to Layer 8\n"
STR(MAGIC_KEY_LAYER9 ) ": Switch to Layer 9\n"
STR(MAGIC_KEY_LAYER0) ": Switch to Layer 0\n" STR(MAGIC_KEY_LAYER1) ": Switch to Layer 1\n" STR(MAGIC_KEY_LAYER2) ": Switch to Layer 2\n" STR(MAGIC_KEY_LAYER3) ": Switch to Layer 3\n" STR(MAGIC_KEY_LAYER4) ": Switch to Layer 4\n" STR(MAGIC_KEY_LAYER5) ": Switch to Layer 5\n" STR(MAGIC_KEY_LAYER6) ": Switch to Layer 6\n" STR(MAGIC_KEY_LAYER7) ": Switch to Layer 7\n" STR(MAGIC_KEY_LAYER8) ": Switch to Layer 8\n" STR(MAGIC_KEY_LAYER9) ": Switch to Layer 9\n"
#endif
#if MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
"F1-F10: Switch to Layer 0-9 (F10 = L0)\n"
"F1-F10: Switch to Layer 0-9 (F10 = L0)\n"
#endif
#if MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
"0-9: Switch to Layer 0-9\n"
"0-9: Switch to Layer 0-9\n"
#endif
STR(MAGIC_KEY_LAYER0_ALT ) ": Switch to Layer 0 (alternate)\n"
STR(MAGIC_KEY_LAYER0_ALT) ": Switch to Layer 0 (alternate)\n"
STR(MAGIC_KEY_BOOTLOADER ) ": Jump to Bootloader\n"
STR(MAGIC_KEY_BOOTLOADER_ALT) ": Jump to Bootloader (alternate)\n"
STR(MAGIC_KEY_BOOTLOADER) ": Jump to Bootloader\n" STR(MAGIC_KEY_BOOTLOADER_ALT) ": Jump to Bootloader (alternate)\n"
#ifdef KEYBOARD_LOCK_ENABLE
STR(MAGIC_KEY_LOCK ) ": Lock Keyboard\n"
STR(MAGIC_KEY_LOCK) ": Lock Keyboard\n"
#endif
STR(MAGIC_KEY_EEPROM ) ": Print EEPROM Settings\n"
STR(MAGIC_KEY_EEPROM_CLEAR) ": Clear EEPROM\n"
STR(MAGIC_KEY_EEPROM) ": Print EEPROM Settings\n" STR(MAGIC_KEY_EEPROM_CLEAR) ": Clear EEPROM\n"
#ifdef NKRO_ENABLE
STR(MAGIC_KEY_NKRO ) ": NKRO Toggle\n"
STR(MAGIC_KEY_NKRO) ": NKRO Toggle\n"
#endif
#ifdef SLEEP_LED_ENABLE
STR(MAGIC_KEY_SLEEP_LED ) ": Sleep LED Test\n"
STR(MAGIC_KEY_SLEEP_LED) ": Sleep LED Test\n"
#endif
);
}
static void print_version(void)
{
// print version & information
static void print_version(void) {
// print version & information
print("\n\t- Version -\n");
print("DESC: " STR(DESCRIPTION) "\n");
print("VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") "
"PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
"VER: " STR(DEVICE_VER) "\n");
"PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") "
"VER: " STR(DEVICE_VER) "\n");
#ifdef SKIP_VERSION
print("BUILD: (" __DATE__ ")\n");
#else
@ -191,51 +163,48 @@ static void print_version(void)
print("OPTIONS:"
#ifdef PROTOCOL_PJRC
" PJRC"
" PJRC"
#endif
#ifdef PROTOCOL_LUFA
" LUFA"
" LUFA"
#endif
#ifdef PROTOCOL_VUSB
" VUSB"
" VUSB"
#endif
#ifdef BOOTMAGIC_ENABLE
" BOOTMAGIC"
" BOOTMAGIC"
#endif
#ifdef MOUSEKEY_ENABLE
" MOUSEKEY"
" MOUSEKEY"
#endif
#ifdef EXTRAKEY_ENABLE
" EXTRAKEY"
" EXTRAKEY"
#endif
#ifdef CONSOLE_ENABLE
" CONSOLE"
" CONSOLE"
#endif
#ifdef COMMAND_ENABLE
" COMMAND"
" COMMAND"
#endif
#ifdef NKRO_ENABLE
" NKRO"
" NKRO"
#endif
#ifdef KEYMAP_SECTION_ENABLE
" KEYMAP_SECTION"
" KEYMAP_SECTION"
#endif
" " STR(BOOTLOADER_SIZE) "\n");
" " STR(BOOTLOADER_SIZE) "\n");
print("GCC: " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__)
#if defined(__AVR__)
" AVR-LIBC: " __AVR_LIBC_VERSION_STRING__
" AVR_ARCH: avr" STR(__AVR_ARCH__)
" AVR-LIBC: " __AVR_LIBC_VERSION_STRING__ " AVR_ARCH: avr" STR(__AVR_ARCH__)
#endif
"\n");
"\n");
return;
return;
}
static void print_status(void)
{
static void print_status(void) {
print("\n\t- Status -\n");
print_val_hex8(host_keyboard_leds());
@ -258,67 +227,101 @@ static void print_status(void)
#endif
#ifdef PROTOCOL_PJRC
# if USB_COUNT_SOF
# if USB_COUNT_SOF
print_val_hex8(usbSofCount);
# endif
# endif
#endif
return;
return;
}
static void print_eeconfig(void)
{
static void print_eeconfig(void) {
// Print these variables if NO_PRINT or USER_PRINT are not defined.
#if !defined(NO_PRINT) && !defined(USER_PRINT)
print("default_layer: "); print_dec(eeconfig_read_default_layer()); print("\n");
print("default_layer: ");
print_dec(eeconfig_read_default_layer());
print("\n");
debug_config_t dc;
dc.raw = eeconfig_read_debug();
print("debug_config.raw: "); print_hex8(dc.raw); print("\n");
print(".enable: "); print_dec(dc.enable); print("\n");
print(".matrix: "); print_dec(dc.matrix); print("\n");
print(".keyboard: "); print_dec(dc.keyboard); print("\n");
print(".mouse: "); print_dec(dc.mouse); print("\n");
print("debug_config.raw: ");
print_hex8(dc.raw);
print("\n");
print(".enable: ");
print_dec(dc.enable);
print("\n");
print(".matrix: ");
print_dec(dc.matrix);
print("\n");
print(".keyboard: ");
print_dec(dc.keyboard);
print("\n");
print(".mouse: ");
print_dec(dc.mouse);
print("\n");
keymap_config_t kc;
kc.raw = eeconfig_read_keymap();
print("keymap_config.raw: "); print_hex8(kc.raw); print("\n");
print(".swap_control_capslock: "); print_dec(kc.swap_control_capslock); print("\n");
print(".capslock_to_control: "); print_dec(kc.capslock_to_control); print("\n");
print(".swap_lctl_lgui: "); print_dec(kc.swap_lctl_lgui); print("\n");
print(".swap_rctl_rgui: "); print_dec(kc.swap_rctl_rgui); print("\n");
print(".swap_lalt_lgui: "); print_dec(kc.swap_lalt_lgui); print("\n");
print(".swap_ralt_rgui: "); print_dec(kc.swap_ralt_rgui); print("\n");
print(".no_gui: "); print_dec(kc.no_gui); print("\n");
print(".swap_grave_esc: "); print_dec(kc.swap_grave_esc); print("\n");
print(".swap_backslash_backspace: "); print_dec(kc.swap_backslash_backspace); print("\n");
print(".nkro: "); print_dec(kc.nkro); print("\n");
print("keymap_config.raw: ");
print_hex8(kc.raw);
print("\n");
print(".swap_control_capslock: ");
print_dec(kc.swap_control_capslock);
print("\n");
print(".capslock_to_control: ");
print_dec(kc.capslock_to_control);
print("\n");
print(".swap_lctl_lgui: ");
print_dec(kc.swap_lctl_lgui);
print("\n");
print(".swap_rctl_rgui: ");
print_dec(kc.swap_rctl_rgui);
print("\n");
print(".swap_lalt_lgui: ");
print_dec(kc.swap_lalt_lgui);
print("\n");
print(".swap_ralt_rgui: ");
print_dec(kc.swap_ralt_rgui);
print("\n");
print(".no_gui: ");
print_dec(kc.no_gui);
print("\n");
print(".swap_grave_esc: ");
print_dec(kc.swap_grave_esc);
print("\n");
print(".swap_backslash_backspace: ");
print_dec(kc.swap_backslash_backspace);
print("\n");
print(".nkro: ");
print_dec(kc.nkro);
print("\n");
#ifdef BACKLIGHT_ENABLE
# ifdef BACKLIGHT_ENABLE
backlight_config_t bc;
bc.raw = eeconfig_read_backlight();
print("backlight_config.raw: "); print_hex8(bc.raw); print("\n");
print(".enable: "); print_dec(bc.enable); print("\n");
print(".level: "); print_dec(bc.level); print("\n");
#endif /* BACKLIGHT_ENABLE */
print("backlight_config.raw: ");
print_hex8(bc.raw);
print("\n");
print(".enable: ");
print_dec(bc.enable);
print("\n");
print(".level: ");
print_dec(bc.level);
print("\n");
# endif /* BACKLIGHT_ENABLE */
#endif /* !NO_PRINT */
}
static bool command_common(uint8_t code)
{
static bool command_common(uint8_t code) {
#ifdef KEYBOARD_LOCK_ENABLE
static host_driver_t *host_driver = 0;
#endif
switch (code) {
#ifdef SLEEP_LED_ENABLE
// test breathing sleep LED
// test breathing sleep LED
case MAGIC_KC(MAGIC_KEY_SLEEP_LED):
print("Sleep LED Test\n");
sleep_led_toggle();
@ -326,21 +329,21 @@ static bool command_common(uint8_t code)
break;
#endif
// print stored eeprom config
// print stored eeprom config
case MAGIC_KC(MAGIC_KEY_EEPROM):
print("eeconfig:\n");
print_eeconfig();
break;
// clear eeprom
// clear eeprom
case MAGIC_KC(MAGIC_KEY_EEPROM_CLEAR):
print("Clearing EEPROM\n");
eeconfig_init();
eeconfig_init();
break;
#ifdef KEYBOARD_LOCK_ENABLE
// lock/unlock keyboard
// lock/unlock keyboard
case MAGIC_KC(MAGIC_KEY_LOCK):
if (host_get_driver()) {
host_driver = host_get_driver();
@ -354,13 +357,13 @@ static bool command_common(uint8_t code)
break;
#endif
// print help
// print help
case MAGIC_KC(MAGIC_KEY_HELP):
case MAGIC_KC(MAGIC_KEY_HELP_ALT):
command_common_help();
break;
// activate console
// activate console
case MAGIC_KC(MAGIC_KEY_CONSOLE):
debug_matrix = false;
debug_keyboard = false;
@ -374,15 +377,15 @@ static bool command_common(uint8_t code)
// jump to bootloader
case MAGIC_KC(MAGIC_KEY_BOOTLOADER):
case MAGIC_KC(MAGIC_KEY_BOOTLOADER_ALT):
clear_keyboard(); // clear to prevent stuck keys
clear_keyboard(); // clear to prevent stuck keys
print("\n\nJumping to bootloader... ");
#ifdef AUDIO_ENABLE
stop_all_notes();
shutdown_user();
#else
wait_ms(1000);
#endif
bootloader_jump(); // not return
#ifdef AUDIO_ENABLE
stop_all_notes();
shutdown_user();
#else
wait_ms(1000);
#endif
bootloader_jump(); // not return
break;
// debug toggle
@ -427,25 +430,25 @@ static bool command_common(uint8_t code)
print("\nmouse: on\n");
debug_enable = true;
} else {
print("\nmouse: off\n");
print("\nmouse: off\n");
}
break;
// print version
// print version
case MAGIC_KC(MAGIC_KEY_VERSION):
print_version();
break;
print_version();
break;
// print status
case MAGIC_KC(MAGIC_KEY_STATUS):
print_status();
// print status
case MAGIC_KC(MAGIC_KEY_STATUS):
print_status();
break;
#ifdef NKRO_ENABLE
// NKRO toggle
// NKRO toggle
case MAGIC_KC(MAGIC_KEY_NKRO):
clear_keyboard(); // clear to prevent stuck keys
clear_keyboard(); // clear to prevent stuck keys
keymap_config.nkro = !keymap_config.nkro;
if (keymap_config.nkro) {
print("NKRO: on\n");
@ -455,56 +458,55 @@ static bool command_common(uint8_t code)
break;
#endif
// switch layers
// switch layers
case MAGIC_KC(MAGIC_KEY_LAYER0_ALT):
case MAGIC_KC(MAGIC_KEY_LAYER0_ALT):
switch_default_layer(0);
break;
#if MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
case MAGIC_KC(MAGIC_KEY_LAYER0):
case MAGIC_KC(MAGIC_KEY_LAYER0):
switch_default_layer(0);
break;
case MAGIC_KC(MAGIC_KEY_LAYER1):
case MAGIC_KC(MAGIC_KEY_LAYER1):
switch_default_layer(1);
break;
case MAGIC_KC(MAGIC_KEY_LAYER2):
case MAGIC_KC(MAGIC_KEY_LAYER2):
switch_default_layer(2);
break;
case MAGIC_KC(MAGIC_KEY_LAYER3):
case MAGIC_KC(MAGIC_KEY_LAYER3):
switch_default_layer(3);
break;
case MAGIC_KC(MAGIC_KEY_LAYER4):
case MAGIC_KC(MAGIC_KEY_LAYER4):
switch_default_layer(4);
break;
case MAGIC_KC(MAGIC_KEY_LAYER5):
case MAGIC_KC(MAGIC_KEY_LAYER5):
switch_default_layer(5);
break;
case MAGIC_KC(MAGIC_KEY_LAYER6):
case MAGIC_KC(MAGIC_KEY_LAYER6):
switch_default_layer(6);
break;
case MAGIC_KC(MAGIC_KEY_LAYER7):
case MAGIC_KC(MAGIC_KEY_LAYER7):
switch_default_layer(7);
break;
case MAGIC_KC(MAGIC_KEY_LAYER8):
case MAGIC_KC(MAGIC_KEY_LAYER8):
switch_default_layer(8);
break;
case MAGIC_KC(MAGIC_KEY_LAYER9):
case MAGIC_KC(MAGIC_KEY_LAYER9):
switch_default_layer(9);
break;
#endif
#if MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
case KC_F1 ... KC_F9:
@ -532,12 +534,10 @@ static bool command_common(uint8_t code)
return true;
}
/***********************************************************
* Command console
***********************************************************/
static void command_console_help(void)
{
static void command_console_help(void) {
print("\n\t- Console -\n"
"ESC/q: quit\n"
#ifdef MOUSEKEY_ENABLE
@ -546,8 +546,7 @@ static void command_console_help(void)
);
}
static bool command_console(uint8_t code)
{
static bool command_console(uint8_t code) {
switch (code) {
case KC_H:
case KC_SLASH: /* ? */
@ -572,32 +571,40 @@ static bool command_console(uint8_t code)
return true;
}
#ifdef MOUSEKEY_ENABLE
/***********************************************************
* Mousekey console
***********************************************************/
static uint8_t mousekey_param = 0;
static void mousekey_param_print(void)
{
static void mousekey_param_print(void) {
// Print these variables if NO_PRINT or USER_PRINT are not defined.
#if !defined(NO_PRINT) && !defined(USER_PRINT)
# if !defined(NO_PRINT) && !defined(USER_PRINT)
print("\n\t- Values -\n");
print("1: delay(*10ms): "); pdec(mk_delay); print("\n");
print("2: interval(ms): "); pdec(mk_interval); print("\n");
print("3: max_speed: "); pdec(mk_max_speed); print("\n");
print("4: time_to_max: "); pdec(mk_time_to_max); print("\n");
print("5: wheel_max_speed: "); pdec(mk_wheel_max_speed); print("\n");
print("6: wheel_time_to_max: "); pdec(mk_wheel_time_to_max); print("\n");
#endif /* !NO_PRINT */
print("1: delay(*10ms): ");
pdec(mk_delay);
print("\n");
print("2: interval(ms): ");
pdec(mk_interval);
print("\n");
print("3: max_speed: ");
pdec(mk_max_speed);
print("\n");
print("4: time_to_max: ");
pdec(mk_time_to_max);
print("\n");
print("5: wheel_max_speed: ");
pdec(mk_wheel_max_speed);
print("\n");
print("6: wheel_time_to_max: ");
pdec(mk_wheel_time_to_max);
print("\n");
# endif /* !NO_PRINT */
}
//#define PRINT_SET_VAL(v) print(#v " = "); print_dec(v); print("\n");
#define PRINT_SET_VAL(v) xprintf(#v " = %d\n", (v))
static void mousekey_param_inc(uint8_t param, uint8_t inc)
{
# define PRINT_SET_VAL(v) xprintf(# v " = %d\n", (v))
static void mousekey_param_inc(uint8_t param, uint8_t inc) {
switch (param) {
case 1:
if (mk_delay + inc < UINT8_MAX)
@ -644,8 +651,7 @@ static void mousekey_param_inc(uint8_t param, uint8_t inc)
}
}
static void mousekey_param_dec(uint8_t param, uint8_t dec)
{
static void mousekey_param_dec(uint8_t param, uint8_t dec) {
switch (param) {
case 1:
if (mk_delay > dec)
@ -692,8 +698,7 @@ static void mousekey_param_dec(uint8_t param, uint8_t dec)
}
}
static void mousekey_console_help(void)
{
static void mousekey_console_help(void) {
print("\n\t- Mousekey -\n"
"ESC/q: quit\n"
"1: delay(*10ms)\n"
@ -712,11 +717,11 @@ static void mousekey_console_help(void)
"\n"
"speed = delta * max_speed * (repeat / time_to_max)\n");
xprintf("where delta: cursor=%d, wheel=%d\n"
"See http://en.wikipedia.org/wiki/Mouse_keys\n", MOUSEKEY_MOVE_DELTA, MOUSEKEY_WHEEL_DELTA);
"See http://en.wikipedia.org/wiki/Mouse_keys\n",
MOUSEKEY_MOVE_DELTA, MOUSEKEY_WHEEL_DELTA);
}
static bool mousekey_console(uint8_t code)
{
static bool mousekey_console(uint8_t code) {
switch (code) {
case KC_H:
case KC_SLASH: /* ? */
@ -756,11 +761,11 @@ static bool mousekey_console(uint8_t code)
mousekey_param_dec(mousekey_param, 10);
break;
case KC_D:
mk_delay = MOUSEKEY_DELAY/10;
mk_interval = MOUSEKEY_INTERVAL;
mk_max_speed = MOUSEKEY_MAX_SPEED;
mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
mk_delay = MOUSEKEY_DELAY / 10;
mk_interval = MOUSEKEY_INTERVAL;
mk_max_speed = MOUSEKEY_MAX_SPEED;
mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;
print("set default\n");
break;
@ -771,36 +776,43 @@ static bool mousekey_console(uint8_t code)
if (mousekey_param) {
xprintf("M%d> ", mousekey_param);
} else {
print("M>" );
print("M>");
}
return true;
}
#endif
/***********************************************************
* Utilities
***********************************************************/
uint8_t numkey2num(uint8_t code)
{
uint8_t numkey2num(uint8_t code) {
switch (code) {
case KC_1: return 1;
case KC_2: return 2;
case KC_3: return 3;
case KC_4: return 4;
case KC_5: return 5;
case KC_6: return 6;
case KC_7: return 7;
case KC_8: return 8;
case KC_9: return 9;
case KC_0: return 0;
case KC_1:
return 1;
case KC_2:
return 2;
case KC_3:
return 3;
case KC_4:
return 4;
case KC_5:
return 5;
case KC_6:
return 6;
case KC_7:
return 7;
case KC_8:
return 8;
case KC_9:
return 9;
case KC_0:
return 0;
}
return 0;
}
static void switch_default_layer(uint8_t layer)
{
static void switch_default_layer(uint8_t layer) {
xprintf("L%d\n", layer);
default_layer_set(1UL<<layer);
default_layer_set(1UL << layer);
clear_keyboard();
}

View file

@ -29,135 +29,135 @@ bool command_console_extra(uint8_t code);
#ifdef COMMAND_ENABLE
uint8_t numkey2num(uint8_t code);
bool command_proc(uint8_t code);
bool command_proc(uint8_t code);
#else
#define command_proc(code) false
# define command_proc(code) false
#endif
#ifndef IS_COMMAND
#define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)
# define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)
#endif
#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS
#define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
# define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true
#endif
#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS
#define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
# define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true
#endif
#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM
#define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
# define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false
#endif
#ifndef MAGIC_KEY_HELP
#define MAGIC_KEY_HELP H
# define MAGIC_KEY_HELP H
#endif
#ifndef MAGIC_KEY_HELP_ALT
#define MAGIC_KEY_HELP_ALT SLASH
# define MAGIC_KEY_HELP_ALT SLASH
#endif
#ifndef MAGIC_KEY_DEBUG
#define MAGIC_KEY_DEBUG D
# define MAGIC_KEY_DEBUG D
#endif
#ifndef MAGIC_KEY_DEBUG_MATRIX
#define MAGIC_KEY_DEBUG_MATRIX X
# define MAGIC_KEY_DEBUG_MATRIX X
#endif
#ifndef MAGIC_KEY_DEBUG_KBD
#define MAGIC_KEY_DEBUG_KBD K
# define MAGIC_KEY_DEBUG_KBD K
#endif
#ifndef MAGIC_KEY_DEBUG_MOUSE
#define MAGIC_KEY_DEBUG_MOUSE M
# define MAGIC_KEY_DEBUG_MOUSE M
#endif
#ifndef MAGIC_KEY_VERSION
#define MAGIC_KEY_VERSION V
# define MAGIC_KEY_VERSION V
#endif
#ifndef MAGIC_KEY_STATUS
#define MAGIC_KEY_STATUS S
# define MAGIC_KEY_STATUS S
#endif
#ifndef MAGIC_KEY_CONSOLE
#define MAGIC_KEY_CONSOLE C
# define MAGIC_KEY_CONSOLE C
#endif
#ifndef MAGIC_KEY_LAYER0
#define MAGIC_KEY_LAYER0 0
# define MAGIC_KEY_LAYER0 0
#endif
#ifndef MAGIC_KEY_LAYER0_ALT
#define MAGIC_KEY_LAYER0_ALT GRAVE
# define MAGIC_KEY_LAYER0_ALT GRAVE
#endif
#ifndef MAGIC_KEY_LAYER1
#define MAGIC_KEY_LAYER1 1
# define MAGIC_KEY_LAYER1 1
#endif
#ifndef MAGIC_KEY_LAYER2
#define MAGIC_KEY_LAYER2 2
# define MAGIC_KEY_LAYER2 2
#endif
#ifndef MAGIC_KEY_LAYER3
#define MAGIC_KEY_LAYER3 3
# define MAGIC_KEY_LAYER3 3
#endif
#ifndef MAGIC_KEY_LAYER4
#define MAGIC_KEY_LAYER4 4
# define MAGIC_KEY_LAYER4 4
#endif
#ifndef MAGIC_KEY_LAYER5
#define MAGIC_KEY_LAYER5 5
# define MAGIC_KEY_LAYER5 5
#endif
#ifndef MAGIC_KEY_LAYER6
#define MAGIC_KEY_LAYER6 6
# define MAGIC_KEY_LAYER6 6
#endif
#ifndef MAGIC_KEY_LAYER7
#define MAGIC_KEY_LAYER7 7
# define MAGIC_KEY_LAYER7 7
#endif
#ifndef MAGIC_KEY_LAYER8
#define MAGIC_KEY_LAYER8 8
# define MAGIC_KEY_LAYER8 8
#endif
#ifndef MAGIC_KEY_LAYER9
#define MAGIC_KEY_LAYER9 9
# define MAGIC_KEY_LAYER9 9
#endif
#ifndef MAGIC_KEY_BOOTLOADER
#define MAGIC_KEY_BOOTLOADER B
# define MAGIC_KEY_BOOTLOADER B
#endif
#ifndef MAGIC_KEY_BOOTLOADER_ALT
#define MAGIC_KEY_BOOTLOADER_ALT ESC
# define MAGIC_KEY_BOOTLOADER_ALT ESC
#endif
#ifndef MAGIC_KEY_LOCK
#define MAGIC_KEY_LOCK CAPS
# define MAGIC_KEY_LOCK CAPS
#endif
#ifndef MAGIC_KEY_EEPROM
#define MAGIC_KEY_EEPROM E
# define MAGIC_KEY_EEPROM E
#endif
#ifndef MAGIC_KEY_EEPROM_CLEAR
#define MAGIC_KEY_EEPROM_CLEAR BSPACE
# define MAGIC_KEY_EEPROM_CLEAR BSPACE
#endif
#ifndef MAGIC_KEY_NKRO
#define MAGIC_KEY_NKRO N
# define MAGIC_KEY_NKRO N
#endif
#ifndef MAGIC_KEY_SLEEP_LED
#define MAGIC_KEY_SLEEP_LED Z
# define MAGIC_KEY_SLEEP_LED Z
#endif
#define XMAGIC_KC(key) KC_ ## key
#define MAGIC_KC(key) XMAGIC_KC(key)
#define XMAGIC_KC(key) KC_##key
#define MAGIC_KC(key) XMAGIC_KC(key)

View file

@ -7,10 +7,10 @@ debug_config_t debug_config = {
/* GCC Bug 10676 - Using unnamed fields in initializers
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10676 */
#if GCC_VERSION >= 40600
.enable = false,
.matrix = false,
.enable = false,
.matrix = false,
.keyboard = false,
.mouse = false,
.mouse = false,
.reserved = 0
#else
{

View file

@ -21,7 +21,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdbool.h>
#include "print.h"
#ifdef __cplusplus
extern "C" {
#endif
@ -31,11 +30,11 @@ extern "C" {
*/
typedef union {
struct {
bool enable:1;
bool matrix:1;
bool keyboard:1;
bool mouse:1;
uint8_t reserved:4;
bool enable : 1;
bool matrix : 1;
bool keyboard : 1;
bool mouse : 1;
uint8_t reserved : 4;
};
uint8_t raw;
} debug_config_t;
@ -47,70 +46,126 @@ extern debug_config_t debug_config;
#endif
/* for backward compatibility */
#define debug_enable (debug_config.enable)
#define debug_matrix (debug_config.matrix)
#define debug_keyboard (debug_config.keyboard)
#define debug_mouse (debug_config.mouse)
#define debug_enable (debug_config.enable)
#define debug_matrix (debug_config.matrix)
#define debug_keyboard (debug_config.keyboard)
#define debug_mouse (debug_config.mouse)
/*
* Debug print utils
*/
#ifndef NO_DEBUG
#define dprint(s) do { if (debug_enable) print(s); } while (0)
#define dprintln(s) do { if (debug_enable) println(s); } while (0)
#define dprintf(fmt, ...) do { if (debug_enable) xprintf(fmt, ##__VA_ARGS__); } while (0)
#define dmsg(s) dprintf("%s at %s: %S\n", __FILE__, __LINE__, PSTR(s))
# define dprint(s) \
do { \
if (debug_enable) print(s); \
} while (0)
# define dprintln(s) \
do { \
if (debug_enable) println(s); \
} while (0)
# define dprintf(fmt, ...) \
do { \
if (debug_enable) xprintf(fmt, ##__VA_ARGS__); \
} while (0)
# define dmsg(s) dprintf("%s at %s: %S\n", __FILE__, __LINE__, PSTR(s))
/* Deprecated. DO NOT USE these anymore, use dprintf instead. */
#define debug(s) do { if (debug_enable) print(s); } while (0)
#define debugln(s) do { if (debug_enable) println(s); } while (0)
#define debug_msg(s) do { \
if (debug_enable) { \
print(__FILE__); print(" at "); print_dec(__LINE__); print(" in "); print(": "); print(s); \
} \
} while (0)
#define debug_dec(data) do { if (debug_enable) print_dec(data); } while (0)
#define debug_decs(data) do { if (debug_enable) print_decs(data); } while (0)
#define debug_hex4(data) do { if (debug_enable) print_hex4(data); } while (0)
#define debug_hex8(data) do { if (debug_enable) print_hex8(data); } while (0)
#define debug_hex16(data) do { if (debug_enable) print_hex16(data); } while (0)
#define debug_hex32(data) do { if (debug_enable) print_hex32(data); } while (0)
#define debug_bin8(data) do { if (debug_enable) print_bin8(data); } while (0)
#define debug_bin16(data) do { if (debug_enable) print_bin16(data); } while (0)
#define debug_bin32(data) do { if (debug_enable) print_bin32(data); } while (0)
#define debug_bin_reverse8(data) do { if (debug_enable) print_bin_reverse8(data); } while (0)
#define debug_bin_reverse16(data) do { if (debug_enable) print_bin_reverse16(data); } while (0)
#define debug_bin_reverse32(data) do { if (debug_enable) print_bin_reverse32(data); } while (0)
#define debug_hex(data) debug_hex8(data)
#define debug_bin(data) debug_bin8(data)
#define debug_bin_reverse(data) debug_bin8(data)
# define debug(s) \
do { \
if (debug_enable) print(s); \
} while (0)
# define debugln(s) \
do { \
if (debug_enable) println(s); \
} while (0)
# define debug_msg(s) \
do { \
if (debug_enable) { \
print(__FILE__); \
print(" at "); \
print_dec(__LINE__); \
print(" in "); \
print(": "); \
print(s); \
} \
} while (0)
# define debug_dec(data) \
do { \
if (debug_enable) print_dec(data); \
} while (0)
# define debug_decs(data) \
do { \
if (debug_enable) print_decs(data); \
} while (0)
# define debug_hex4(data) \
do { \
if (debug_enable) print_hex4(data); \
} while (0)
# define debug_hex8(data) \
do { \
if (debug_enable) print_hex8(data); \
} while (0)
# define debug_hex16(data) \
do { \
if (debug_enable) print_hex16(data); \
} while (0)
# define debug_hex32(data) \
do { \
if (debug_enable) print_hex32(data); \
} while (0)
# define debug_bin8(data) \
do { \
if (debug_enable) print_bin8(data); \
} while (0)
# define debug_bin16(data) \
do { \
if (debug_enable) print_bin16(data); \
} while (0)
# define debug_bin32(data) \
do { \
if (debug_enable) print_bin32(data); \
} while (0)
# define debug_bin_reverse8(data) \
do { \
if (debug_enable) print_bin_reverse8(data); \
} while (0)
# define debug_bin_reverse16(data) \
do { \
if (debug_enable) print_bin_reverse16(data); \
} while (0)
# define debug_bin_reverse32(data) \
do { \
if (debug_enable) print_bin_reverse32(data); \
} while (0)
# define debug_hex(data) debug_hex8(data)
# define debug_bin(data) debug_bin8(data)
# define debug_bin_reverse(data) debug_bin8(data)
#else /* NO_DEBUG */
#define dprint(s)
#define dprintln(s)
#define dprintf(fmt, ...)
#define dmsg(s)
#define debug(s)
#define debugln(s)
#define debug_msg(s)
#define debug_dec(data)
#define debug_decs(data)
#define debug_hex4(data)
#define debug_hex8(data)
#define debug_hex16(data)
#define debug_hex32(data)
#define debug_bin8(data)
#define debug_bin16(data)
#define debug_bin32(data)
#define debug_bin_reverse8(data)
#define debug_bin_reverse16(data)
#define debug_bin_reverse32(data)
#define debug_hex(data)
#define debug_bin(data)
#define debug_bin_reverse(data)
# define dprint(s)
# define dprintln(s)
# define dprintf(fmt, ...)
# define dmsg(s)
# define debug(s)
# define debugln(s)
# define debug_msg(s)
# define debug_dec(data)
# define debug_decs(data)
# define debug_hex4(data)
# define debug_hex8(data)
# define debug_hex16(data)
# define debug_hex32(data)
# define debug_bin8(data)
# define debug_bin16(data)
# define debug_bin32(data)
# define debug_bin_reverse8(data)
# define debug_bin_reverse16(data)
# define debug_bin_reverse32(data)
# define debug_hex(data)
# define debug_bin(data)
# define debug_bin_reverse(data)
#endif /* NO_DEBUG */

View file

@ -4,8 +4,8 @@
#include "eeconfig.h"
#ifdef STM32_EEPROM_ENABLE
#include "hal.h"
#include "eeprom_stm32.h"
# include "hal.h"
# include "eeprom_stm32.h"
#endif
extern uint32_t default_layer_state;
@ -13,21 +13,18 @@ extern uint32_t default_layer_state;
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void eeconfig_init_user(void) {
// Reset user EEPROM value to blank, rather than to a set value
eeconfig_update_user(0);
__attribute__((weak)) void eeconfig_init_user(void) {
// Reset user EEPROM value to blank, rather than to a set value
eeconfig_update_user(0);
}
__attribute__ ((weak))
void eeconfig_init_kb(void) {
// Reset Keyboard EEPROM value to blank, rather than to a set value
eeconfig_update_kb(0);
__attribute__((weak)) void eeconfig_init_kb(void) {
// Reset Keyboard EEPROM value to blank, rather than to a set value
eeconfig_update_kb(0);
eeconfig_init_user();
eeconfig_init_user();
}
/*
* FIXME: needs doc
*/
@ -35,49 +32,42 @@ void eeconfig_init_quantum(void) {
#ifdef STM32_EEPROM_ENABLE
EEPROM_Erase();
#endif
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
eeprom_update_byte(EECONFIG_DEBUG, 0);
eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0);
default_layer_state = 0;
eeprom_update_byte(EECONFIG_KEYMAP_LOWER_BYTE, 0);
eeprom_update_byte(EECONFIG_KEYMAP_UPPER_BYTE, 0);
eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0);
eeprom_update_byte(EECONFIG_BACKLIGHT, 0);
eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default
eeprom_update_dword(EECONFIG_RGBLIGHT, 0);
eeprom_update_byte(EECONFIG_STENOMODE, 0);
eeprom_update_dword(EECONFIG_HAPTIC, 0);
eeprom_update_byte(EECONFIG_VELOCIKEY, 0);
eeprom_update_dword(EECONFIG_RGB_MATRIX, 0);
eeprom_update_byte(EECONFIG_RGB_MATRIX_SPEED, 0);
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
eeprom_update_byte(EECONFIG_DEBUG, 0);
eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0);
default_layer_state = 0;
eeprom_update_byte(EECONFIG_KEYMAP_LOWER_BYTE, 0);
eeprom_update_byte(EECONFIG_KEYMAP_UPPER_BYTE, 0);
eeprom_update_byte(EECONFIG_MOUSEKEY_ACCEL, 0);
eeprom_update_byte(EECONFIG_BACKLIGHT, 0);
eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default
eeprom_update_dword(EECONFIG_RGBLIGHT, 0);
eeprom_update_byte(EECONFIG_STENOMODE, 0);
eeprom_update_dword(EECONFIG_HAPTIC, 0);
eeprom_update_byte(EECONFIG_VELOCIKEY, 0);
eeprom_update_dword(EECONFIG_RGB_MATRIX, 0);
eeprom_update_byte(EECONFIG_RGB_MATRIX_SPEED, 0);
eeconfig_init_kb();
eeconfig_init_kb();
}
/** \brief eeconfig initialization
*
* FIXME: needs doc
*/
void eeconfig_init(void) {
eeconfig_init_quantum();
}
void eeconfig_init(void) { eeconfig_init_quantum(); }
/** \brief eeconfig enable
*
* FIXME: needs doc
*/
void eeconfig_enable(void)
{
eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER);
}
void eeconfig_enable(void) { eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); }
/** \brief eeconfig disable
*
* FIXME: needs doc
*/
void eeconfig_disable(void)
{
void eeconfig_disable(void) {
#ifdef STM32_EEPROM_ENABLE
EEPROM_Erase();
#endif
@ -88,25 +78,19 @@ void eeconfig_disable(void)
*
* FIXME: needs doc
*/
bool eeconfig_is_enabled(void)
{
return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER);
}
bool eeconfig_is_enabled(void) { return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER); }
/** \brief eeconfig is disabled
*
* FIXME: needs doc
*/
bool eeconfig_is_disabled(void)
{
return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF);
}
bool eeconfig_is_disabled(void) { return (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF); }
/** \brief eeconfig read debug
*
* FIXME: needs doc
*/
uint8_t eeconfig_read_debug(void) { return eeprom_read_byte(EECONFIG_DEBUG); }
uint8_t eeconfig_read_debug(void) { return eeprom_read_byte(EECONFIG_DEBUG); }
/** \brief eeconfig update debug
*
* FIXME: needs doc
@ -117,7 +101,7 @@ void eeconfig_update_debug(uint8_t val) { eeprom_update_byte(EECONFIG_DEBUG, val
*
* FIXME: needs doc
*/
uint8_t eeconfig_read_default_layer(void) { return eeprom_read_byte(EECONFIG_DEFAULT_LAYER); }
uint8_t eeconfig_read_default_layer(void) { return eeprom_read_byte(EECONFIG_DEFAULT_LAYER); }
/** \brief eeconfig update default layer
*
* FIXME: needs doc
@ -128,47 +112,43 @@ void eeconfig_update_default_layer(uint8_t val) { eeprom_update_byte(EECONFIG_DE
*
* FIXME: needs doc
*/
uint16_t eeconfig_read_keymap(void) {
return ( eeprom_read_byte(EECONFIG_KEYMAP_LOWER_BYTE) | (eeprom_read_byte(EECONFIG_KEYMAP_UPPER_BYTE) << 8) );
}
uint16_t eeconfig_read_keymap(void) { return (eeprom_read_byte(EECONFIG_KEYMAP_LOWER_BYTE) | (eeprom_read_byte(EECONFIG_KEYMAP_UPPER_BYTE) << 8)); }
/** \brief eeconfig update keymap
*
* FIXME: needs doc
*/
void eeconfig_update_keymap(uint16_t val) {
eeprom_update_byte(EECONFIG_KEYMAP_LOWER_BYTE, val & 0xFF);
eeprom_update_byte(EECONFIG_KEYMAP_UPPER_BYTE, ( val >> 8 ) & 0xFF );
eeprom_update_byte(EECONFIG_KEYMAP_UPPER_BYTE, (val >> 8) & 0xFF);
}
/** \brief eeconfig read backlight
*
* FIXME: needs doc
*/
uint8_t eeconfig_read_backlight(void) { return eeprom_read_byte(EECONFIG_BACKLIGHT); }
uint8_t eeconfig_read_backlight(void) { return eeprom_read_byte(EECONFIG_BACKLIGHT); }
/** \brief eeconfig update backlight
*
* FIXME: needs doc
*/
void eeconfig_update_backlight(uint8_t val) { eeprom_update_byte(EECONFIG_BACKLIGHT, val); }
/** \brief eeconfig read audio
*
* FIXME: needs doc
*/
uint8_t eeconfig_read_audio(void) { return eeprom_read_byte(EECONFIG_AUDIO); }
uint8_t eeconfig_read_audio(void) { return eeprom_read_byte(EECONFIG_AUDIO); }
/** \brief eeconfig update audio
*
* FIXME: needs doc
*/
void eeconfig_update_audio(uint8_t val) { eeprom_update_byte(EECONFIG_AUDIO, val); }
/** \brief eeconfig read kb
*
* FIXME: needs doc
*/
uint32_t eeconfig_read_kb(void) { return eeprom_read_dword(EECONFIG_KEYBOARD); }
uint32_t eeconfig_read_kb(void) { return eeprom_read_dword(EECONFIG_KEYBOARD); }
/** \brief eeconfig update kb
*
* FIXME: needs doc
@ -179,15 +159,14 @@ void eeconfig_update_kb(uint32_t val) { eeprom_update_dword(EECONFIG_KEYBOARD, v
*
* FIXME: needs doc
*/
uint32_t eeconfig_read_user(void) { return eeprom_read_dword(EECONFIG_USER); }
uint32_t eeconfig_read_user(void) { return eeprom_read_dword(EECONFIG_USER); }
/** \brief eeconfig update user
*
* FIXME: needs doc
*/
void eeconfig_update_user(uint32_t val) { eeprom_update_dword(EECONFIG_USER, val); }
uint32_t eeconfig_read_haptic(void) { return eeprom_read_dword(EECONFIG_HAPTIC); }
uint32_t eeconfig_read_haptic(void) { return eeprom_read_dword(EECONFIG_HAPTIC); }
/** \brief eeconfig update user
*
* FIXME: needs doc

View file

@ -21,49 +21,48 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#include <stdbool.h>
#ifndef EECONFIG_MAGIC_NUMBER
# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEEC
# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEEC
#endif
#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF
/* EEPROM parameter address */
#define EECONFIG_MAGIC (uint16_t *)0
#define EECONFIG_DEBUG (uint8_t *)2
#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
#define EECONFIG_KEYMAP (uint8_t *)4
#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5
#define EECONFIG_BACKLIGHT (uint8_t *)6
#define EECONFIG_AUDIO (uint8_t *)7
#define EECONFIG_RGBLIGHT (uint32_t *)8
#define EECONFIG_UNICODEMODE (uint8_t *)12
#define EECONFIG_STENOMODE (uint8_t *)13
#define EECONFIG_MAGIC (uint16_t *)0
#define EECONFIG_DEBUG (uint8_t *)2
#define EECONFIG_DEFAULT_LAYER (uint8_t *)3
#define EECONFIG_KEYMAP (uint8_t *)4
#define EECONFIG_MOUSEKEY_ACCEL (uint8_t *)5
#define EECONFIG_BACKLIGHT (uint8_t *)6
#define EECONFIG_AUDIO (uint8_t *)7
#define EECONFIG_RGBLIGHT (uint32_t *)8
#define EECONFIG_UNICODEMODE (uint8_t *)12
#define EECONFIG_STENOMODE (uint8_t *)13
// EEHANDS for two handed boards
#define EECONFIG_HANDEDNESS (uint8_t *)14
#define EECONFIG_KEYBOARD (uint32_t *)15
#define EECONFIG_USER (uint32_t *)19
#define EECONFIG_VELOCIKEY (uint8_t *)23
#define EECONFIG_HANDEDNESS (uint8_t *)14
#define EECONFIG_KEYBOARD (uint32_t *)15
#define EECONFIG_USER (uint32_t *)19
#define EECONFIG_VELOCIKEY (uint8_t *)23
#define EECONFIG_HAPTIC (uint32_t *)24
#define EECONFIG_RGB_MATRIX (uint32_t *)28
#define EECONFIG_RGB_MATRIX_SPEED (uint8_t *)32
#define EECONFIG_HAPTIC (uint32_t *)24
#define EECONFIG_RGB_MATRIX (uint32_t *)28
#define EECONFIG_RGB_MATRIX_SPEED (uint8_t *)32
// TODO: Combine these into a single word and single block of EEPROM
#define EECONFIG_KEYMAP_UPPER_BYTE (uint8_t *)33
#define EECONFIG_KEYMAP_UPPER_BYTE (uint8_t *)33
/* debug bit */
#define EECONFIG_DEBUG_ENABLE (1<<0)
#define EECONFIG_DEBUG_MATRIX (1<<1)
#define EECONFIG_DEBUG_KEYBOARD (1<<2)
#define EECONFIG_DEBUG_MOUSE (1<<3)
#define EECONFIG_DEBUG_ENABLE (1 << 0)
#define EECONFIG_DEBUG_MATRIX (1 << 1)
#define EECONFIG_DEBUG_KEYBOARD (1 << 2)
#define EECONFIG_DEBUG_MOUSE (1 << 3)
/* keyconf bit */
#define EECONFIG_KEYMAP_SWAP_CONTROL_CAPSLOCK (1<<0)
#define EECONFIG_KEYMAP_CAPSLOCK_TO_CONTROL (1<<1)
#define EECONFIG_KEYMAP_SWAP_LALT_LGUI (1<<2)
#define EECONFIG_KEYMAP_SWAP_RALT_RGUI (1<<3)
#define EECONFIG_KEYMAP_NO_GUI (1<<4)
#define EECONFIG_KEYMAP_SWAP_GRAVE_ESC (1<<5)
#define EECONFIG_KEYMAP_SWAP_BACKSLASH_BACKSPACE (1<<6)
#define EECONFIG_KEYMAP_NKRO (1<<7)
#define EECONFIG_KEYMAP_SWAP_CONTROL_CAPSLOCK (1 << 0)
#define EECONFIG_KEYMAP_CAPSLOCK_TO_CONTROL (1 << 1)
#define EECONFIG_KEYMAP_SWAP_LALT_LGUI (1 << 2)
#define EECONFIG_KEYMAP_SWAP_RALT_RGUI (1 << 3)
#define EECONFIG_KEYMAP_NO_GUI (1 << 4)
#define EECONFIG_KEYMAP_SWAP_GRAVE_ESC (1 << 5)
#define EECONFIG_KEYMAP_SWAP_BACKSLASH_BACKSPACE (1 << 6)
#define EECONFIG_KEYMAP_NKRO (1 << 7)
#define EECONFIG_KEYMAP_LOWER_BYTE EECONFIG_KEYMAP
@ -80,32 +79,32 @@ void eeconfig_enable(void);
void eeconfig_disable(void);
uint8_t eeconfig_read_debug(void);
void eeconfig_update_debug(uint8_t val);
void eeconfig_update_debug(uint8_t val);
uint8_t eeconfig_read_default_layer(void);
void eeconfig_update_default_layer(uint8_t val);
void eeconfig_update_default_layer(uint8_t val);
uint16_t eeconfig_read_keymap(void);
void eeconfig_update_keymap(uint16_t val);
void eeconfig_update_keymap(uint16_t val);
#ifdef BACKLIGHT_ENABLE
uint8_t eeconfig_read_backlight(void);
void eeconfig_update_backlight(uint8_t val);
void eeconfig_update_backlight(uint8_t val);
#endif
#ifdef AUDIO_ENABLE
uint8_t eeconfig_read_audio(void);
void eeconfig_update_audio(uint8_t val);
void eeconfig_update_audio(uint8_t val);
#endif
uint32_t eeconfig_read_kb(void);
void eeconfig_update_kb(uint32_t val);
void eeconfig_update_kb(uint32_t val);
uint32_t eeconfig_read_user(void);
void eeconfig_update_user(uint32_t val);
void eeconfig_update_user(uint32_t val);
#ifdef HAPTIC_ENABLE
uint32_t eeconfig_read_haptic(void);
void eeconfig_update_haptic(uint32_t val);
void eeconfig_update_haptic(uint32_t val);
#endif
#endif

View file

@ -2,22 +2,22 @@
#define TMK_CORE_COMMON_EEPROM_H_
#if defined(__AVR__)
#include <avr/eeprom.h>
# include <avr/eeprom.h>
#else
#include <stdint.h>
# include <stdint.h>
uint8_t eeprom_read_byte (const uint8_t *__p);
uint16_t eeprom_read_word (const uint16_t *__p);
uint32_t eeprom_read_dword (const uint32_t *__p);
void eeprom_read_block (void *__dst, const void *__src, uint32_t __n);
void eeprom_write_byte (uint8_t *__p, uint8_t __value);
void eeprom_write_word (uint16_t *__p, uint16_t __value);
void eeprom_write_dword (uint32_t *__p, uint32_t __value);
void eeprom_write_block (const void *__src, void *__dst, uint32_t __n);
void eeprom_update_byte (uint8_t *__p, uint8_t __value);
void eeprom_update_word (uint16_t *__p, uint16_t __value);
void eeprom_update_dword (uint32_t *__p, uint32_t __value);
void eeprom_update_block (const void *__src, void *__dst, uint32_t __n);
uint8_t eeprom_read_byte(const uint8_t *__p);
uint16_t eeprom_read_word(const uint16_t *__p);
uint32_t eeprom_read_dword(const uint32_t *__p);
void eeprom_read_block(void *__dst, const void *__src, uint32_t __n);
void eeprom_write_byte(uint8_t *__p, uint8_t __value);
void eeprom_write_word(uint16_t *__p, uint16_t __value);
void eeprom_write_dword(uint32_t *__p, uint32_t __value);
void eeprom_write_block(const void *__src, void *__dst, uint32_t __n);
void eeprom_update_byte(uint8_t *__p, uint8_t __value);
void eeprom_update_word(uint16_t *__p, uint16_t __value);
void eeprom_update_dword(uint32_t *__p, uint32_t __value);
void eeprom_update_block(const void *__src, void *__dst, uint32_t __n);
#endif
#endif /* TMK_CORE_COMMON_EEPROM_H_ */

View file

@ -23,40 +23,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "debug.h"
#ifdef NKRO_ENABLE
#include "keycode_config.h"
extern keymap_config_t keymap_config;
# include "keycode_config.h"
extern keymap_config_t keymap_config;
#endif
static host_driver_t *driver;
static uint16_t last_system_report = 0;
static uint16_t last_consumer_report = 0;
static uint16_t last_system_report = 0;
static uint16_t last_consumer_report = 0;
void host_set_driver(host_driver_t *d) { driver = d; }
void host_set_driver(host_driver_t *d)
{
driver = d;
}
host_driver_t *host_get_driver(void) { return driver; }
host_driver_t *host_get_driver(void)
{
return driver;
}
uint8_t host_keyboard_leds(void)
{
uint8_t host_keyboard_leds(void) {
if (!driver) return 0;
return (*driver->keyboard_leds)();
}
/* send report */
void host_keyboard_send(report_keyboard_t *report)
{
void host_keyboard_send(report_keyboard_t *report) {
if (!driver) return;
#if defined(NKRO_ENABLE) && defined(NKRO_SHARED_EP)
if (keyboard_protocol && keymap_config.nkro) {
/* The callers of this function assume that report->mods is where mods go in.
* But report->nkro.mods can be at a different offset if core keyboard does not have a report ID.
*/
report->nkro.mods = report->mods;
report->nkro.mods = report->mods;
report->nkro.report_id = REPORT_ID_NKRO;
} else
#endif
@ -76,8 +67,7 @@ void host_keyboard_send(report_keyboard_t *report)
}
}
void host_mouse_send(report_mouse_t *report)
{
void host_mouse_send(report_mouse_t *report) {
if (!driver) return;
#ifdef MOUSE_SHARED_EP
report->report_id = REPORT_ID_MOUSE;
@ -85,8 +75,7 @@ void host_mouse_send(report_mouse_t *report)
(*driver->send_mouse)(report);
}
void host_system_send(uint16_t report)
{
void host_system_send(uint16_t report) {
if (report == last_system_report) return;
last_system_report = report;
@ -94,8 +83,7 @@ void host_system_send(uint16_t report)
(*driver->send_system)(report);
}
void host_consumer_send(uint16_t report)
{
void host_consumer_send(uint16_t report) {
if (report == last_consumer_report) return;
last_consumer_report = report;
@ -103,12 +91,6 @@ void host_consumer_send(uint16_t report)
(*driver->send_consumer)(report);
}
uint16_t host_last_system_report(void)
{
return last_system_report;
}
uint16_t host_last_system_report(void) { return last_system_report; }
uint16_t host_last_consumer_report(void)
{
return last_consumer_report;
}
uint16_t host_last_consumer_report(void) { return last_consumer_report; }

View file

@ -22,11 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "report.h"
#include "host_driver.h"
#define IS_LED_ON(leds, led_name) ( (leds) & (1 << (led_name)))
#define IS_LED_OFF(leds, led_name) (~(leds) & (1 << (led_name)))
#define IS_LED_ON(leds, led_name) ((leds) & (1 << (led_name)))
#define IS_LED_OFF(leds, led_name) (~(leds) & (1 << (led_name)))
#define IS_HOST_LED_ON(led_name) IS_LED_ON(host_keyboard_leds(), led_name)
#define IS_HOST_LED_OFF(led_name) IS_LED_OFF(host_keyboard_leds(), led_name)
#define IS_HOST_LED_ON(led_name) IS_LED_ON(host_keyboard_leds(), led_name)
#define IS_HOST_LED_OFF(led_name) IS_LED_OFF(host_keyboard_leds(), led_name)
#ifdef __cplusplus
extern "C" {
@ -36,15 +36,15 @@ extern uint8_t keyboard_idle;
extern uint8_t keyboard_protocol;
/* host driver */
void host_set_driver(host_driver_t *driver);
void host_set_driver(host_driver_t *driver);
host_driver_t *host_get_driver(void);
/* host driver interface */
uint8_t host_keyboard_leds(void);
void host_keyboard_send(report_keyboard_t *report);
void host_mouse_send(report_mouse_t *report);
void host_system_send(uint16_t data);
void host_consumer_send(uint16_t data);
void host_keyboard_send(report_keyboard_t *report);
void host_mouse_send(report_mouse_t *report);
void host_system_send(uint16_t data);
void host_consumer_send(uint16_t data);
uint16_t host_last_system_report(void);
uint16_t host_last_consumer_report(void);

View file

@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#include "report.h"
#ifdef MIDI_ENABLE
#include "midi.h"
# include "midi.h"
#endif
typedef struct {

View file

@ -32,84 +32,82 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "backlight.h"
#include "action_layer.h"
#ifdef BOOTMAGIC_ENABLE
# include "bootmagic.h"
# include "bootmagic.h"
#else
# include "magic.h"
# include "magic.h"
#endif
#ifdef MOUSEKEY_ENABLE
# include "mousekey.h"
# include "mousekey.h"
#endif
#ifdef PS2_MOUSE_ENABLE
# include "ps2_mouse.h"
# include "ps2_mouse.h"
#endif
#ifdef SERIAL_MOUSE_ENABLE
# include "serial_mouse.h"
# include "serial_mouse.h"
#endif
#ifdef ADB_MOUSE_ENABLE
# include "adb.h"
# include "adb.h"
#endif
#ifdef RGBLIGHT_ENABLE
# include "rgblight.h"
# include "rgblight.h"
#endif
#ifdef STENO_ENABLE
# include "process_steno.h"
# include "process_steno.h"
#endif
#ifdef FAUXCLICKY_ENABLE
# include "fauxclicky.h"
# include "fauxclicky.h"
#endif
#ifdef SERIAL_LINK_ENABLE
# include "serial_link/system/serial_link.h"
# include "serial_link/system/serial_link.h"
#endif
#ifdef VISUALIZER_ENABLE
# include "visualizer/visualizer.h"
# include "visualizer/visualizer.h"
#endif
#ifdef POINTING_DEVICE_ENABLE
# include "pointing_device.h"
# include "pointing_device.h"
#endif
#ifdef MIDI_ENABLE
# include "process_midi.h"
# include "process_midi.h"
#endif
#ifdef HD44780_ENABLE
# include "hd44780.h"
# include "hd44780.h"
#endif
#ifdef QWIIC_ENABLE
# include "qwiic.h"
# include "qwiic.h"
#endif
#ifdef OLED_DRIVER_ENABLE
#include "oled_driver.h"
# include "oled_driver.h"
#endif
#ifdef VELOCIKEY_ENABLE
#include "velocikey.h"
# include "velocikey.h"
#endif
#ifdef MATRIX_HAS_GHOST
extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
static matrix_row_t get_real_keys(uint8_t row, matrix_row_t rowdata){
static matrix_row_t get_real_keys(uint8_t row, matrix_row_t rowdata) {
matrix_row_t out = 0;
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
//read each key in the row data and check if the keymap defines it as a real key
if (pgm_read_byte(&keymaps[0][row][col]) && (rowdata & (1<<col))){
//this creates new row data, if a key is defined in the keymap, it will be set here
out |= 1<<col;
// read each key in the row data and check if the keymap defines it as a real key
if (pgm_read_byte(&keymaps[0][row][col]) && (rowdata & (1 << col))) {
// this creates new row data, if a key is defined in the keymap, it will be set here
out |= 1 << col;
}
}
return out;
}
static inline bool popcount_more_than_one(matrix_row_t rowdata)
{
rowdata &= rowdata-1; //if there are less than two bits (keys) set, rowdata will become zero
static inline bool popcount_more_than_one(matrix_row_t rowdata) {
rowdata &= rowdata - 1; // if there are less than two bits (keys) set, rowdata will become zero
return rowdata;
}
static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata)
{
static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) {
/* No ghost exists when less than 2 keys are down on the row.
If there are "active" blanks in the matrix, the key can't be pressed by the user,
there is no doubt as to which keys are really being pressed.
The ghosts will be ignored, they are KC_NO. */
rowdata = get_real_keys(row, rowdata);
if ((popcount_more_than_one(rowdata)) == 0){
if ((popcount_more_than_one(rowdata)) == 0) {
return false;
}
/* Ghost occurs when the row shares a column line with other row,
@ -119,8 +117,8 @@ static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata)
at least two of another row's real keys, the row will be ignored. Keep in mind,
we are checking one row at a time, not all of them at once.
*/
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
if (i != row && popcount_more_than_one(get_real_keys(i, matrix_get_row(i)) & rowdata)){
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
if (i != row && popcount_more_than_one(get_real_keys(i, matrix_get_row(i)) & rowdata)) {
return true;
}
}
@ -131,9 +129,7 @@ static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata)
void disable_jtag(void) {
// To use PF4-7 (PC2-5 on ATmega32A), disable JTAG by writing JTD bit twice within four cycles.
#if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || \
defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || \
defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
#if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__))
MCUCR |= _BV(JTD);
MCUCR |= _BV(JTD);
#elif defined(__AVR_ATmega32A__)
@ -146,43 +142,33 @@ void disable_jtag(void) {
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void matrix_setup(void) {
}
__attribute__((weak)) void matrix_setup(void) {}
/** \brief keyboard_pre_init_user
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void keyboard_pre_init_user(void) { }
__attribute__((weak)) void keyboard_pre_init_user(void) {}
/** \brief keyboard_pre_init_kb
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void keyboard_pre_init_kb(void) {
keyboard_pre_init_user();
}
__attribute__((weak)) void keyboard_pre_init_kb(void) { keyboard_pre_init_user(); }
/** \brief keyboard_post_init_user
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void keyboard_post_init_user() {}
__attribute__((weak)) void keyboard_post_init_user() {}
/** \brief keyboard_post_init_kb
*
* FIXME: needs doc
*/
__attribute__ ((weak))
void keyboard_post_init_kb(void) {
keyboard_post_init_user();
}
__attribute__((weak)) void keyboard_post_init_kb(void) { keyboard_post_init_user(); }
/** \brief keyboard_setup
*
@ -200,10 +186,7 @@ void keyboard_setup(void) {
*
* FIXME: needs doc
*/
__attribute__((weak))
bool is_keyboard_master(void) {
return true;
}
__attribute__((weak)) bool is_keyboard_master(void) { return true; }
/** \brief keyboard_init
*
@ -265,12 +248,11 @@ void keyboard_init(void) {
*
* This is repeatedly called as fast as possible.
*/
void keyboard_task(void)
{
void keyboard_task(void) {
static matrix_row_t matrix_prev[MATRIX_ROWS];
static uint8_t led_status = 0;
matrix_row_t matrix_row = 0;
matrix_row_t matrix_change = 0;
static uint8_t led_status = 0;
matrix_row_t matrix_row = 0;
matrix_row_t matrix_change = 0;
#ifdef QMK_KEYS_PER_SCAN
uint8_t keys_processed = 0;
#endif
@ -283,28 +265,28 @@ void keyboard_task(void)
if (is_keyboard_master()) {
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
matrix_row = matrix_get_row(r);
matrix_row = matrix_get_row(r);
matrix_change = matrix_row ^ matrix_prev[r];
if (matrix_change) {
#ifdef MATRIX_HAS_GHOST
if (has_ghost_in_row(r, matrix_row)) { continue; }
if (has_ghost_in_row(r, matrix_row)) {
continue;
}
#endif
if (debug_matrix) matrix_print();
for (uint8_t c = 0; c < MATRIX_COLS; c++) {
if (matrix_change & ((matrix_row_t)1<<c)) {
if (matrix_change & ((matrix_row_t)1 << c)) {
action_exec((keyevent_t){
.key = (keypos_t){ .row = r, .col = c },
.pressed = (matrix_row & ((matrix_row_t)1<<c)),
.time = (timer_read() | 1) /* time should not be 0 */
.key = (keypos_t){.row = r, .col = c}, .pressed = (matrix_row & ((matrix_row_t)1 << c)), .time = (timer_read() | 1) /* time should not be 0 */
});
// record a processed key
matrix_prev[r] ^= ((matrix_row_t)1<<c);
matrix_prev[r] ^= ((matrix_row_t)1 << c);
#ifdef QMK_KEYS_PER_SCAN
// only jump out if we have processed "enough" keys.
if (++keys_processed >= QMK_KEYS_PER_SCAN)
#endif
// process a key per task call
goto MATRIX_LOOP_END;
// process a key per task call
goto MATRIX_LOOP_END;
}
}
}
@ -315,7 +297,7 @@ void keyboard_task(void)
// we can get here with some keys processed now.
if (!keys_processed)
#endif
action_exec(TICK);
action_exec(TICK);
MATRIX_LOOP_END:
@ -325,11 +307,10 @@ MATRIX_LOOP_END:
#ifdef OLED_DRIVER_ENABLE
oled_task();
#ifndef OLED_DISABLE_TIMEOUT
# ifndef OLED_DISABLE_TIMEOUT
// Wake up oled if user is using those fabulous keys!
if (ret)
oled_on();
#endif
if (ret) oled_on();
# endif
#endif
#ifdef MOUSEKEY_ENABLE
@ -350,7 +331,7 @@ MATRIX_LOOP_END:
#endif
#ifdef SERIAL_LINK_ENABLE
serial_link_update();
serial_link_update();
#endif
#ifdef VISUALIZER_ENABLE
@ -366,7 +347,9 @@ MATRIX_LOOP_END:
#endif
#ifdef VELOCIKEY_ENABLE
if (velocikey_enabled()) { velocikey_decelerate(); }
if (velocikey_enabled()) {
velocikey_decelerate();
}
#endif
// update LED
@ -380,8 +363,11 @@ MATRIX_LOOP_END:
*
* FIXME: needs doc
*/
void keyboard_set_leds(uint8_t leds)
{
if (debug_keyboard) { debug("keyboard_set_led: "); debug_hex8(leds); debug("\n"); }
void keyboard_set_leds(uint8_t leds) {
if (debug_keyboard) {
debug("keyboard_set_led: ");
debug_hex8(leds);
debug("\n");
}
led_set(leds);
}

View file

@ -21,7 +21,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
@ -40,7 +39,7 @@ typedef struct {
} keyevent_t;
/* equivalent test of keypos_t */
#define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col)
#define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col)
/* Rules for No Event:
* 1) (time == 0) to handle (keyevent_t){} as empty event
@ -51,11 +50,8 @@ static inline bool IS_PRESSED(keyevent_t event) { return (!IS_NOEVENT(event) &&
static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) && !event.pressed); }
/* Tick event */
#define TICK (keyevent_t){ \
.key = (keypos_t){ .row = 255, .col = 255 }, \
.pressed = false, \
.time = (timer_read() | 1) \
}
#define TICK \
(keyevent_t) { .key = (keypos_t){.row = 255, .col = 255}, .pressed = false, .time = (timer_read() | 1) }
/* it runs once at early stage of startup before keyboard_init. */
void keyboard_setup(void);

View file

@ -26,68 +26,68 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* FIXME: Add doxygen comments here */
#define IS_ERROR(code) (KC_ROLL_OVER <= (code) && (code) <= KC_UNDEFINED)
#define IS_ANY(code) (KC_A <= (code) && (code) <= 0xFF)
#define IS_KEY(code) (KC_A <= (code) && (code) <= KC_EXSEL)
#define IS_MOD(code) (KC_LCTRL <= (code) && (code) <= KC_RGUI)
#define IS_ERROR(code) (KC_ROLL_OVER <= (code) && (code) <= KC_UNDEFINED)
#define IS_ANY(code) (KC_A <= (code) && (code) <= 0xFF)
#define IS_KEY(code) (KC_A <= (code) && (code) <= KC_EXSEL)
#define IS_MOD(code) (KC_LCTRL <= (code) && (code) <= KC_RGUI)
#define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF))
#define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE)
#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_BRID)
#define IS_SPECIAL(code) ((0xA5 <= (code) && (code) <= 0xDF) || (0xE8 <= (code) && (code) <= 0xFF))
#define IS_SYSTEM(code) (KC_PWR <= (code) && (code) <= KC_WAKE)
#define IS_CONSUMER(code) (KC_MUTE <= (code) && (code) <= KC_BRID)
#define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31)
#define IS_FN(code) (KC_FN0 <= (code) && (code) <= KC_FN31)
#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2)
#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT)
#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN5)
#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT)
#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2)
#define IS_MOUSEKEY(code) (KC_MS_UP <= (code) && (code) <= KC_MS_ACCEL2)
#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT)
#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN5)
#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT)
#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2)
#define MOD_BIT(code) (1 << MOD_INDEX(code))
#define MOD_INDEX(code) ((code) & 0x07)
#define MOD_BIT(code) (1 << MOD_INDEX(code))
#define MOD_INDEX(code) ((code)&0x07)
#define MOD_MASK_CTRL (MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RCTRL))
#define MOD_MASK_SHIFT (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))
#define MOD_MASK_ALT (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))
#define MOD_MASK_GUI (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))
#define MOD_MASK_CS (MOD_MASK_CTRL | MOD_MASK_SHIFT)
#define MOD_MASK_CA (MOD_MASK_CTRL | MOD_MASK_ALT)
#define MOD_MASK_CG (MOD_MASK_CTRL | MOD_MASK_GUI)
#define MOD_MASK_SA (MOD_MASK_SHIFT | MOD_MASK_ALT)
#define MOD_MASK_SG (MOD_MASK_SHIFT | MOD_MASK_GUI)
#define MOD_MASK_AG (MOD_MASK_ALT | MOD_MASK_GUI)
#define MOD_MASK_CSA (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT)
#define MOD_MASK_CSG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_GUI)
#define MOD_MASK_CAG (MOD_MASK_CTRL | MOD_MASK_ALT | MOD_MASK_GUI)
#define MOD_MASK_SAG (MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI)
#define MOD_MASK_CSAG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI)
#define MOD_MASK_CTRL (MOD_BIT(KC_LCTRL) | MOD_BIT(KC_RCTRL))
#define MOD_MASK_SHIFT (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT))
#define MOD_MASK_ALT (MOD_BIT(KC_LALT) | MOD_BIT(KC_RALT))
#define MOD_MASK_GUI (MOD_BIT(KC_LGUI) | MOD_BIT(KC_RGUI))
#define MOD_MASK_CS (MOD_MASK_CTRL | MOD_MASK_SHIFT)
#define MOD_MASK_CA (MOD_MASK_CTRL | MOD_MASK_ALT)
#define MOD_MASK_CG (MOD_MASK_CTRL | MOD_MASK_GUI)
#define MOD_MASK_SA (MOD_MASK_SHIFT | MOD_MASK_ALT)
#define MOD_MASK_SG (MOD_MASK_SHIFT | MOD_MASK_GUI)
#define MOD_MASK_AG (MOD_MASK_ALT | MOD_MASK_GUI)
#define MOD_MASK_CSA (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT)
#define MOD_MASK_CSG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_GUI)
#define MOD_MASK_CAG (MOD_MASK_CTRL | MOD_MASK_ALT | MOD_MASK_GUI)
#define MOD_MASK_SAG (MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI)
#define MOD_MASK_CSAG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI)
#define FN_BIT(code) (1 << FN_INDEX(code))
#define FN_INDEX(code) ((code) - KC_FN0)
#define FN_MIN KC_FN0
#define FN_MAX KC_FN31
#define FN_BIT(code) (1 << FN_INDEX(code))
#define FN_INDEX(code) ((code)-KC_FN0)
#define FN_MIN KC_FN0
#define FN_MAX KC_FN31
/*
* Short names for ease of definition of keymap
*/
/* Transparent */
#define KC_TRANSPARENT 0x01
#define KC_TRNS KC_TRANSPARENT
#define KC_TRNS KC_TRANSPARENT
/* Punctuation */
#define KC_ENT KC_ENTER
#define KC_ESC KC_ESCAPE
#define KC_ENT KC_ENTER
#define KC_ESC KC_ESCAPE
#define KC_BSPC KC_BSPACE
#define KC_SPC KC_SPACE
#define KC_SPC KC_SPACE
#define KC_MINS KC_MINUS
#define KC_EQL KC_EQUAL
#define KC_EQL KC_EQUAL
#define KC_LBRC KC_LBRACKET
#define KC_RBRC KC_RBRACKET
#define KC_BSLS KC_BSLASH
#define KC_NUHS KC_NONUS_HASH
#define KC_SCLN KC_SCOLON
#define KC_QUOT KC_QUOTE
#define KC_GRV KC_GRAVE
#define KC_GRV KC_GRAVE
#define KC_COMM KC_COMMA
#define KC_SLSH KC_SLASH
#define KC_NUBS KC_NONUS_BSLASH
@ -104,18 +104,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Commands */
#define KC_PSCR KC_PSCREEN
#define KC_PAUS KC_PAUSE
#define KC_BRK KC_PAUSE
#define KC_INS KC_INSERT
#define KC_DEL KC_DELETE
#define KC_BRK KC_PAUSE
#define KC_INS KC_INSERT
#define KC_DEL KC_DELETE
#define KC_PGDN KC_PGDOWN
#define KC_RGHT KC_RIGHT
#define KC_APP KC_APPLICATION
#define KC_APP KC_APPLICATION
#define KC_EXEC KC_EXECUTE
#define KC_SLCT KC_SELECT
#define KC_AGIN KC_AGAIN
#define KC_PSTE KC_PASTE
#define KC_ERAS KC_ALT_ERASE
#define KC_CLR KC_CLEAR
#define KC_CLR KC_CLEAR
/* Keypad */
#define KC_PSLS KC_KP_SLASH
@ -123,23 +123,23 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KC_PMNS KC_KP_MINUS
#define KC_PPLS KC_KP_PLUS
#define KC_PENT KC_KP_ENTER
#define KC_P1 KC_KP_1
#define KC_P2 KC_KP_2
#define KC_P3 KC_KP_3
#define KC_P4 KC_KP_4
#define KC_P5 KC_KP_5
#define KC_P6 KC_KP_6
#define KC_P7 KC_KP_7
#define KC_P8 KC_KP_8
#define KC_P9 KC_KP_9
#define KC_P0 KC_KP_0
#define KC_P1 KC_KP_1
#define KC_P2 KC_KP_2
#define KC_P3 KC_KP_3
#define KC_P4 KC_KP_4
#define KC_P5 KC_KP_5
#define KC_P6 KC_KP_6
#define KC_P7 KC_KP_7
#define KC_P8 KC_KP_8
#define KC_P9 KC_KP_9
#define KC_P0 KC_KP_0
#define KC_PDOT KC_KP_DOT
#define KC_PEQL KC_KP_EQUAL
#define KC_PCMM KC_KP_COMMA
/* Japanese specific */
#define KC_ZKHK KC_GRAVE
#define KC_RO KC_INT1
#define KC_RO KC_INT1
#define KC_KANA KC_INT2
#define KC_JYEN KC_INT3
#define KC_HENK KC_INT4
@ -161,7 +161,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define KC_RWIN KC_RGUI
/* Generic Desktop Page (0x01) */
#define KC_PWR KC_SYSTEM_POWER
#define KC_PWR KC_SYSTEM_POWER
#define KC_SLEP KC_SYSTEM_SLEEP
#define KC_WAKE KC_SYSTEM_WAKE
@ -214,171 +214,171 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Keyboard/Keypad Page (0x07) */
enum hid_keyboard_keypad_usage {
KC_NO = 0x00,
KC_ROLL_OVER,
KC_POST_FAIL,
KC_UNDEFINED,
KC_A,
KC_B,
KC_C,
KC_D,
KC_E,
KC_F,
KC_G,
KC_H,
KC_I,
KC_J,
KC_K,
KC_L,
KC_M, //0x10
KC_N,
KC_O,
KC_P,
KC_Q,
KC_R,
KC_S,
KC_T,
KC_U,
KC_V,
KC_W,
KC_X,
KC_Y,
KC_Z,
KC_1,
KC_2,
KC_3, //0x20
KC_4,
KC_5,
KC_6,
KC_7,
KC_8,
KC_9,
KC_0,
KC_ENTER,
KC_ESCAPE,
KC_BSPACE,
KC_TAB,
KC_SPACE,
KC_MINUS,
KC_EQUAL,
KC_LBRACKET,
KC_RBRACKET, //0x30
KC_BSLASH,
KC_NONUS_HASH,
KC_SCOLON,
KC_QUOTE,
KC_GRAVE,
KC_COMMA,
KC_DOT,
KC_SLASH,
KC_CAPSLOCK,
KC_F1,
KC_F2,
KC_F3,
KC_F4,
KC_F5,
KC_F6,
KC_F7, //0x40
KC_F8,
KC_F9,
KC_F10,
KC_F11,
KC_F12,
KC_PSCREEN,
KC_SCROLLLOCK,
KC_PAUSE,
KC_INSERT,
KC_HOME,
KC_PGUP,
KC_DELETE,
KC_END,
KC_PGDOWN,
KC_RIGHT,
KC_LEFT, //0x50
KC_DOWN,
KC_UP,
KC_NUMLOCK,
KC_KP_SLASH,
KC_KP_ASTERISK,
KC_KP_MINUS,
KC_KP_PLUS,
KC_KP_ENTER,
KC_KP_1,
KC_KP_2,
KC_KP_3,
KC_KP_4,
KC_KP_5,
KC_KP_6,
KC_KP_7,
KC_KP_8, //0x60
KC_KP_9,
KC_KP_0,
KC_KP_DOT,
KC_NONUS_BSLASH,
KC_APPLICATION,
KC_POWER,
KC_KP_EQUAL,
KC_F13,
KC_F14,
KC_F15,
KC_F16,
KC_F17,
KC_F18,
KC_F19,
KC_F20,
KC_F21, //0x70
KC_F22,
KC_F23,
KC_F24,
KC_EXECUTE,
KC_HELP,
KC_MENU,
KC_SELECT,
KC_STOP,
KC_AGAIN,
KC_UNDO,
KC_CUT,
KC_COPY,
KC_PASTE,
KC_FIND,
KC__MUTE,
KC__VOLUP, //0x80
KC__VOLDOWN,
KC_LOCKING_CAPS,
KC_LOCKING_NUM,
KC_LOCKING_SCROLL,
KC_KP_COMMA,
KC_KP_EQUAL_AS400,
KC_INT1,
KC_INT2,
KC_INT3,
KC_INT4,
KC_INT5,
KC_INT6,
KC_INT7,
KC_INT8,
KC_INT9,
KC_LANG1, //0x90
KC_LANG2,
KC_LANG3,
KC_LANG4,
KC_LANG5,
KC_LANG6,
KC_LANG7,
KC_LANG8,
KC_LANG9,
KC_ALT_ERASE,
KC_SYSREQ,
KC_CANCEL,
KC_CLEAR,
KC_PRIOR,
KC_RETURN,
KC_SEPARATOR,
KC_OUT, //0xA0
KC_OPER,
KC_CLEAR_AGAIN,
KC_CRSEL,
KC_EXSEL,
KC_NO = 0x00,
KC_ROLL_OVER,
KC_POST_FAIL,
KC_UNDEFINED,
KC_A,
KC_B,
KC_C,
KC_D,
KC_E,
KC_F,
KC_G,
KC_H,
KC_I,
KC_J,
KC_K,
KC_L,
KC_M, // 0x10
KC_N,
KC_O,
KC_P,
KC_Q,
KC_R,
KC_S,
KC_T,
KC_U,
KC_V,
KC_W,
KC_X,
KC_Y,
KC_Z,
KC_1,
KC_2,
KC_3, // 0x20
KC_4,
KC_5,
KC_6,
KC_7,
KC_8,
KC_9,
KC_0,
KC_ENTER,
KC_ESCAPE,
KC_BSPACE,
KC_TAB,
KC_SPACE,
KC_MINUS,
KC_EQUAL,
KC_LBRACKET,
KC_RBRACKET, // 0x30
KC_BSLASH,
KC_NONUS_HASH,
KC_SCOLON,
KC_QUOTE,
KC_GRAVE,
KC_COMMA,
KC_DOT,
KC_SLASH,
KC_CAPSLOCK,
KC_F1,
KC_F2,
KC_F3,
KC_F4,
KC_F5,
KC_F6,
KC_F7, // 0x40
KC_F8,
KC_F9,
KC_F10,
KC_F11,
KC_F12,
KC_PSCREEN,
KC_SCROLLLOCK,
KC_PAUSE,
KC_INSERT,
KC_HOME,
KC_PGUP,
KC_DELETE,
KC_END,
KC_PGDOWN,
KC_RIGHT,
KC_LEFT, // 0x50
KC_DOWN,
KC_UP,
KC_NUMLOCK,
KC_KP_SLASH,
KC_KP_ASTERISK,
KC_KP_MINUS,
KC_KP_PLUS,
KC_KP_ENTER,
KC_KP_1,
KC_KP_2,
KC_KP_3,
KC_KP_4,
KC_KP_5,
KC_KP_6,
KC_KP_7,
KC_KP_8, // 0x60
KC_KP_9,
KC_KP_0,
KC_KP_DOT,
KC_NONUS_BSLASH,
KC_APPLICATION,
KC_POWER,
KC_KP_EQUAL,
KC_F13,
KC_F14,
KC_F15,
KC_F16,
KC_F17,
KC_F18,
KC_F19,
KC_F20,
KC_F21, // 0x70
KC_F22,
KC_F23,
KC_F24,
KC_EXECUTE,
KC_HELP,
KC_MENU,
KC_SELECT,
KC_STOP,
KC_AGAIN,
KC_UNDO,
KC_CUT,
KC_COPY,
KC_PASTE,
KC_FIND,
KC__MUTE,
KC__VOLUP, // 0x80
KC__VOLDOWN,
KC_LOCKING_CAPS,
KC_LOCKING_NUM,
KC_LOCKING_SCROLL,
KC_KP_COMMA,
KC_KP_EQUAL_AS400,
KC_INT1,
KC_INT2,
KC_INT3,
KC_INT4,
KC_INT5,
KC_INT6,
KC_INT7,
KC_INT8,
KC_INT9,
KC_LANG1, // 0x90
KC_LANG2,
KC_LANG3,
KC_LANG4,
KC_LANG5,
KC_LANG6,
KC_LANG7,
KC_LANG8,
KC_LANG9,
KC_ALT_ERASE,
KC_SYSREQ,
KC_CANCEL,
KC_CLEAR,
KC_PRIOR,
KC_RETURN,
KC_SEPARATOR,
KC_OUT, // 0xA0
KC_OPER,
KC_CLEAR_AGAIN,
KC_CRSEL,
KC_EXSEL,
#if 0
// ***************************************************************
@ -435,110 +435,110 @@ enum hid_keyboard_keypad_usage {
KC_KP_HEXADECIMAL,
#endif
/* Modifiers */
KC_LCTRL = 0xE0,
KC_LSHIFT,
KC_LALT,
KC_LGUI,
KC_RCTRL,
KC_RSHIFT,
KC_RALT,
KC_RGUI
/* Modifiers */
KC_LCTRL = 0xE0,
KC_LSHIFT,
KC_LALT,
KC_LGUI,
KC_RCTRL,
KC_RSHIFT,
KC_RALT,
KC_RGUI
// **********************************************
// * 0xF0-0xFF are unallocated in the HID spec. *
// * QMK uses these for Mouse Keys - see below. *
// **********************************************
// **********************************************
// * 0xF0-0xFF are unallocated in the HID spec. *
// * QMK uses these for Mouse Keys - see below. *
// **********************************************
};
/* Media and Function keys */
enum internal_special_keycodes {
/* Generic Desktop Page (0x01) */
KC_SYSTEM_POWER = 0xA5,
KC_SYSTEM_SLEEP,
KC_SYSTEM_WAKE,
/* Generic Desktop Page (0x01) */
KC_SYSTEM_POWER = 0xA5,
KC_SYSTEM_SLEEP,
KC_SYSTEM_WAKE,
/* Consumer Page (0x0C) */
KC_AUDIO_MUTE,
KC_AUDIO_VOL_UP,
KC_AUDIO_VOL_DOWN,
KC_MEDIA_NEXT_TRACK,
KC_MEDIA_PREV_TRACK,
KC_MEDIA_STOP,
KC_MEDIA_PLAY_PAUSE,
KC_MEDIA_SELECT,
KC_MEDIA_EJECT, //0xB0
KC_MAIL,
KC_CALCULATOR,
KC_MY_COMPUTER,
KC_WWW_SEARCH,
KC_WWW_HOME,
KC_WWW_BACK,
KC_WWW_FORWARD,
KC_WWW_STOP,
KC_WWW_REFRESH,
KC_WWW_FAVORITES,
KC_MEDIA_FAST_FORWARD,
KC_MEDIA_REWIND,
KC_BRIGHTNESS_UP,
KC_BRIGHTNESS_DOWN,
/* Consumer Page (0x0C) */
KC_AUDIO_MUTE,
KC_AUDIO_VOL_UP,
KC_AUDIO_VOL_DOWN,
KC_MEDIA_NEXT_TRACK,
KC_MEDIA_PREV_TRACK,
KC_MEDIA_STOP,
KC_MEDIA_PLAY_PAUSE,
KC_MEDIA_SELECT,
KC_MEDIA_EJECT, // 0xB0
KC_MAIL,
KC_CALCULATOR,
KC_MY_COMPUTER,
KC_WWW_SEARCH,
KC_WWW_HOME,
KC_WWW_BACK,
KC_WWW_FORWARD,
KC_WWW_STOP,
KC_WWW_REFRESH,
KC_WWW_FAVORITES,
KC_MEDIA_FAST_FORWARD,
KC_MEDIA_REWIND,
KC_BRIGHTNESS_UP,
KC_BRIGHTNESS_DOWN,
/* Fn keys */
KC_FN0 = 0xC0,
KC_FN1,
KC_FN2,
KC_FN3,
KC_FN4,
KC_FN5,
KC_FN6,
KC_FN7,
KC_FN8,
KC_FN9,
KC_FN10,
KC_FN11,
KC_FN12,
KC_FN13,
KC_FN14,
KC_FN15,
KC_FN16, //0xD0
KC_FN17,
KC_FN18,
KC_FN19,
KC_FN20,
KC_FN21,
KC_FN22,
KC_FN23,
KC_FN24,
KC_FN25,
KC_FN26,
KC_FN27,
KC_FN28,
KC_FN29,
KC_FN30,
KC_FN31
/* Fn keys */
KC_FN0 = 0xC0,
KC_FN1,
KC_FN2,
KC_FN3,
KC_FN4,
KC_FN5,
KC_FN6,
KC_FN7,
KC_FN8,
KC_FN9,
KC_FN10,
KC_FN11,
KC_FN12,
KC_FN13,
KC_FN14,
KC_FN15,
KC_FN16, // 0xD0
KC_FN17,
KC_FN18,
KC_FN19,
KC_FN20,
KC_FN21,
KC_FN22,
KC_FN23,
KC_FN24,
KC_FN25,
KC_FN26,
KC_FN27,
KC_FN28,
KC_FN29,
KC_FN30,
KC_FN31
};
enum mouse_keys {
/* Mouse Buttons */
KC_MS_UP = 0xF0,
KC_MS_DOWN,
KC_MS_LEFT,
KC_MS_RIGHT,
KC_MS_BTN1,
KC_MS_BTN2,
KC_MS_BTN3,
KC_MS_BTN4,
KC_MS_BTN5,
/* Mouse Buttons */
KC_MS_UP = 0xF0,
KC_MS_DOWN,
KC_MS_LEFT,
KC_MS_RIGHT,
KC_MS_BTN1,
KC_MS_BTN2,
KC_MS_BTN3,
KC_MS_BTN4,
KC_MS_BTN5,
/* Mouse Wheel */
KC_MS_WH_UP,
KC_MS_WH_DOWN,
KC_MS_WH_LEFT,
KC_MS_WH_RIGHT,
/* Mouse Wheel */
KC_MS_WH_UP,
KC_MS_WH_DOWN,
KC_MS_WH_LEFT,
KC_MS_WH_RIGHT,
/* Acceleration */
KC_MS_ACCEL0,
KC_MS_ACCEL1,
KC_MS_ACCEL2
/* Acceleration */
KC_MS_ACCEL0,
KC_MS_ACCEL1,
KC_MS_ACCEL2
};
#endif

View file

@ -22,12 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* FIXME: Add doxygen comments here. */
/* keyboard LEDs */
#define USB_LED_NUM_LOCK 0
#define USB_LED_CAPS_LOCK 1
#define USB_LED_SCROLL_LOCK 2
#define USB_LED_COMPOSE 3
#define USB_LED_KANA 4
#define USB_LED_NUM_LOCK 0
#define USB_LED_CAPS_LOCK 1
#define USB_LED_SCROLL_LOCK 2
#define USB_LED_COMPOSE 3
#define USB_LED_KANA 4
#ifdef __cplusplus
extern "C" {

View file

@ -1,7 +1,7 @@
#include <stdint.h>
#include <stdbool.h>
#if defined(__AVR__)
#include <util/delay.h>
# include <util/delay.h>
#endif
#include "matrix.h"
#include "bootloader.h"
@ -18,8 +18,7 @@ keymap_config_t keymap_config;
*
* FIXME: Needs doc
*/
void magic(void)
{
void magic(void) {
/* check signature */
if (!eeconfig_is_enabled()) {
eeconfig_init();
@ -32,7 +31,6 @@ void magic(void)
keymap_config.raw = eeconfig_read_keymap();
uint8_t default_layer = 0;
default_layer = eeconfig_read_default_layer();
default_layer = eeconfig_read_default_layer();
default_layer_set((layer_state_t)default_layer);
}

View file

@ -20,29 +20,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#include <stdbool.h>
#if (MATRIX_COLS <= 8)
typedef uint8_t matrix_row_t;
typedef uint8_t matrix_row_t;
#elif (MATRIX_COLS <= 16)
typedef uint16_t matrix_row_t;
typedef uint16_t matrix_row_t;
#elif (MATRIX_COLS <= 32)
typedef uint32_t matrix_row_t;
typedef uint32_t matrix_row_t;
#else
#error "MATRIX_COLS: invalid value"
# error "MATRIX_COLS: invalid value"
#endif
#if (MATRIX_ROWS <= 8)
typedef uint8_t matrix_col_t;
typedef uint8_t matrix_col_t;
#elif (MATRIX_ROWS <= 16)
typedef uint16_t matrix_col_t;
typedef uint16_t matrix_col_t;
#elif (MATRIX_ROWS <= 32)
typedef uint32_t matrix_col_t;
typedef uint32_t matrix_col_t;
#else
#error "MATRIX_ROWS: invalid value"
# error "MATRIX_ROWS: invalid value"
#endif
#define MATRIX_IS_ON(row, col) (matrix_get_row(row) && (1<<col))
#define MATRIX_IS_ON(row, col) (matrix_get_row(row) && (1 << col))
#ifdef __cplusplus
extern "C" {
@ -59,7 +57,7 @@ void matrix_init(void);
/* scan all key states on matrix */
uint8_t matrix_scan(void);
/* whether modified from previous scan. used after matrix_scan. */
bool matrix_is_modified(void) __attribute__ ((deprecated));
bool matrix_is_modified(void) __attribute__((deprecated));
/* whether a switch is on */
bool matrix_is_on(uint8_t row, uint8_t col);
/* matrix state on row */
@ -67,7 +65,6 @@ matrix_row_t matrix_get_row(uint8_t row);
/* print matrix for debug */
void matrix_print(void);
/* power control */
void matrix_power_up(void);
void matrix_power_down(void);
@ -83,8 +80,8 @@ void matrix_init_user(void);
void matrix_scan_user(void);
#ifdef I2C_SPLIT
void slave_matrix_init(void);
uint8_t slave_matrix_scan(void);
void slave_matrix_init(void);
uint8_t slave_matrix_scan(void);
#endif
#ifdef __cplusplus

View file

@ -1,4 +1,3 @@
#include "bootloader.h"
void bootloader_jump(void) {}

View file

@ -1,6 +1,5 @@
#include <stdbool.h>
void suspend_power_down(void) {}
bool suspend_wakeup_condition(void) { return true; }
void suspend_wakeup_init(void) {}

View file

@ -5,37 +5,19 @@
volatile uint32_t timer_count = 0;
/* Timer interrupt handler */
void SysTick_Handler(void) {
timer_count++;
}
void SysTick_Handler(void) { timer_count++; }
void timer_init(void)
{
void timer_init(void) {
timer_count = 0;
SysTick_Config(SystemCoreClock / 1000); /* 1ms tick */
}
void timer_clear(void)
{
timer_count = 0;
}
void timer_clear(void) { timer_count = 0; }
uint16_t timer_read(void)
{
return (uint16_t)(timer_count & 0xFFFF);
}
uint16_t timer_read(void) { return (uint16_t)(timer_count & 0xFFFF); }
uint32_t timer_read32(void)
{
return timer_count;
}
uint32_t timer_read32(void) { return timer_count; }
uint16_t timer_elapsed(uint16_t last)
{
return TIMER_DIFF_16(timer_read(), last);
}
uint16_t timer_elapsed(uint16_t last) { return TIMER_DIFF_16(timer_read(), last); }
uint32_t timer_elapsed32(uint32_t last)
{
return TIMER_DIFF_32(timer_read32(), last);
}
uint32_t timer_elapsed32(uint32_t last) { return TIMER_DIFF_32(timer_read32(), last); }

View file

@ -3,10 +3,9 @@
#include "mbed.h"
#include "mbed/xprintf.h"
#define STRING_STACK_LIMIT 120
#define STRING_STACK_LIMIT 120
//TODO
// TODO
int __xprintf(const char* format, ...) { return 0; }
#if 0

View file

@ -13,5 +13,4 @@ int __xprintf(const char *format, ...);
}
#endif
#endif

View file

@ -24,25 +24,21 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "mousekey.h"
inline int8_t times_inv_sqrt2(int8_t x) {
// 181/256 is pretty close to 1/sqrt(2)
// 0.70703125 0.707106781
// 1 too small for x=99 and x=198
// This ends up being a mult and discard lower 8 bits
return (x * 181) >> 8;
// 181/256 is pretty close to 1/sqrt(2)
// 0.70703125 0.707106781
// 1 too small for x=99 and x=198
// This ends up being a mult and discard lower 8 bits
return (x * 181) >> 8;
}
static report_mouse_t mouse_report = {0};
static void mousekey_debug(void);
static uint8_t mousekey_accel = 0;
static uint8_t mousekey_repeat = 0;
static uint16_t last_timer = 0;
static void mousekey_debug(void);
static uint8_t mousekey_accel = 0;
static uint8_t mousekey_repeat = 0;
static uint16_t last_timer = 0;
#ifndef MK_3_SPEED
/*
* Mouse keys acceleration algorithm
* http://en.wikipedia.org/wiki/Mouse_keys
@ -50,7 +46,7 @@ static uint16_t last_timer = 0;
* speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000)
*/
/* milliseconds between the initial key press and first repeated motion event (0-2550) */
uint8_t mk_delay = MOUSEKEY_DELAY/10;
uint8_t mk_delay = MOUSEKEY_DELAY / 10;
/* milliseconds between repeated motion events (0-255) */
uint8_t mk_interval = MOUSEKEY_INTERVAL;
/* steady speed (in action_delta units) applied each event (0-255) */
@ -58,268 +54,320 @@ uint8_t mk_max_speed = MOUSEKEY_MAX_SPEED;
/* number of events (count) accelerating to steady speed (0-255) */
uint8_t mk_time_to_max = MOUSEKEY_TIME_TO_MAX;
/* ramp used to reach maximum pointer speed (NOT SUPPORTED) */
//int8_t mk_curve = 0;
// int8_t mk_curve = 0;
/* wheel params */
uint8_t mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
uint8_t mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED;
uint8_t mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX;
static uint8_t move_unit(void) {
uint16_t unit;
if (mousekey_accel & (1<<0)) {
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed)/4;
} else if (mousekey_accel & (1<<1)) {
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed)/2;
} else if (mousekey_accel & (1<<2)) {
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed);
} else if (mousekey_repeat == 0) {
unit = MOUSEKEY_MOVE_DELTA;
} else if (mousekey_repeat >= mk_time_to_max) {
unit = MOUSEKEY_MOVE_DELTA * mk_max_speed;
} else {
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max;
}
return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit));
uint16_t unit;
if (mousekey_accel & (1 << 0)) {
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 4;
} else if (mousekey_accel & (1 << 1)) {
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2;
} else if (mousekey_accel & (1 << 2)) {
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed);
} else if (mousekey_repeat == 0) {
unit = MOUSEKEY_MOVE_DELTA;
} else if (mousekey_repeat >= mk_time_to_max) {
unit = MOUSEKEY_MOVE_DELTA * mk_max_speed;
} else {
unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max;
}
return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit));
}
static uint8_t wheel_unit(void) {
uint16_t unit;
if (mousekey_accel & (1<<0)) {
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed)/4;
} else if (mousekey_accel & (1<<1)) {
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed)/2;
} else if (mousekey_accel & (1<<2)) {
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed);
} else if (mousekey_repeat == 0) {
unit = MOUSEKEY_WHEEL_DELTA;
} else if (mousekey_repeat >= mk_wheel_time_to_max) {
unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed;
} else {
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_repeat) / mk_wheel_time_to_max;
}
return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
uint16_t unit;
if (mousekey_accel & (1 << 0)) {
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 4;
} else if (mousekey_accel & (1 << 1)) {
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2;
} else if (mousekey_accel & (1 << 2)) {
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed);
} else if (mousekey_repeat == 0) {
unit = MOUSEKEY_WHEEL_DELTA;
} else if (mousekey_repeat >= mk_wheel_time_to_max) {
unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed;
} else {
unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_repeat) / mk_wheel_time_to_max;
}
return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit));
}
void mousekey_task(void) {
if (timer_elapsed(last_timer) < (mousekey_repeat ? mk_interval : mk_delay*10)) {
return;
}
if (mouse_report.x == 0 && mouse_report.y == 0 && mouse_report.v == 0 && mouse_report.h == 0) {
return;
}
if (mousekey_repeat != UINT8_MAX) mousekey_repeat++;
if (mouse_report.x > 0) mouse_report.x = move_unit();
if (mouse_report.x < 0) mouse_report.x = move_unit() * -1;
if (mouse_report.y > 0) mouse_report.y = move_unit();
if (mouse_report.y < 0) mouse_report.y = move_unit() * -1;
/* diagonal move [1/sqrt(2)] */
if (mouse_report.x && mouse_report.y) {
mouse_report.x = times_inv_sqrt2(mouse_report.x);
if (mouse_report.x == 0) { mouse_report.x = 1; }
mouse_report.y = times_inv_sqrt2(mouse_report.y);
if (mouse_report.y == 0) { mouse_report.y = 1; }
}
if (mouse_report.v > 0) mouse_report.v = wheel_unit();
if (mouse_report.v < 0) mouse_report.v = wheel_unit() * -1;
if (mouse_report.h > 0) mouse_report.h = wheel_unit();
if (mouse_report.h < 0) mouse_report.h = wheel_unit() * -1;
mousekey_send();
if (timer_elapsed(last_timer) < (mousekey_repeat ? mk_interval : mk_delay * 10)) {
return;
}
if (mouse_report.x == 0 && mouse_report.y == 0 && mouse_report.v == 0 && mouse_report.h == 0) {
return;
}
if (mousekey_repeat != UINT8_MAX) mousekey_repeat++;
if (mouse_report.x > 0) mouse_report.x = move_unit();
if (mouse_report.x < 0) mouse_report.x = move_unit() * -1;
if (mouse_report.y > 0) mouse_report.y = move_unit();
if (mouse_report.y < 0) mouse_report.y = move_unit() * -1;
/* diagonal move [1/sqrt(2)] */
if (mouse_report.x && mouse_report.y) {
mouse_report.x = times_inv_sqrt2(mouse_report.x);
if (mouse_report.x == 0) {
mouse_report.x = 1;
}
mouse_report.y = times_inv_sqrt2(mouse_report.y);
if (mouse_report.y == 0) {
mouse_report.y = 1;
}
}
if (mouse_report.v > 0) mouse_report.v = wheel_unit();
if (mouse_report.v < 0) mouse_report.v = wheel_unit() * -1;
if (mouse_report.h > 0) mouse_report.h = wheel_unit();
if (mouse_report.h < 0) mouse_report.h = wheel_unit() * -1;
mousekey_send();
}
void mousekey_on(uint8_t code) {
if (code == KC_MS_UP) mouse_report.y = move_unit() * -1;
else if (code == KC_MS_DOWN) mouse_report.y = move_unit();
else if (code == KC_MS_LEFT) mouse_report.x = move_unit() * -1;
else if (code == KC_MS_RIGHT) mouse_report.x = move_unit();
else if (code == KC_MS_WH_UP) mouse_report.v = wheel_unit();
else if (code == KC_MS_WH_DOWN) mouse_report.v = wheel_unit() * -1;
else if (code == KC_MS_WH_LEFT) mouse_report.h = wheel_unit() * -1;
else if (code == KC_MS_WH_RIGHT) mouse_report.h = wheel_unit();
else if (code == KC_MS_BTN1) mouse_report.buttons |= MOUSE_BTN1;
else if (code == KC_MS_BTN2) mouse_report.buttons |= MOUSE_BTN2;
else if (code == KC_MS_BTN3) mouse_report.buttons |= MOUSE_BTN3;
else if (code == KC_MS_BTN4) mouse_report.buttons |= MOUSE_BTN4;
else if (code == KC_MS_BTN5) mouse_report.buttons |= MOUSE_BTN5;
else if (code == KC_MS_ACCEL0) mousekey_accel |= (1<<0);
else if (code == KC_MS_ACCEL1) mousekey_accel |= (1<<1);
else if (code == KC_MS_ACCEL2) mousekey_accel |= (1<<2);
if (code == KC_MS_UP)
mouse_report.y = move_unit() * -1;
else if (code == KC_MS_DOWN)
mouse_report.y = move_unit();
else if (code == KC_MS_LEFT)
mouse_report.x = move_unit() * -1;
else if (code == KC_MS_RIGHT)
mouse_report.x = move_unit();
else if (code == KC_MS_WH_UP)
mouse_report.v = wheel_unit();
else if (code == KC_MS_WH_DOWN)
mouse_report.v = wheel_unit() * -1;
else if (code == KC_MS_WH_LEFT)
mouse_report.h = wheel_unit() * -1;
else if (code == KC_MS_WH_RIGHT)
mouse_report.h = wheel_unit();
else if (code == KC_MS_BTN1)
mouse_report.buttons |= MOUSE_BTN1;
else if (code == KC_MS_BTN2)
mouse_report.buttons |= MOUSE_BTN2;
else if (code == KC_MS_BTN3)
mouse_report.buttons |= MOUSE_BTN3;
else if (code == KC_MS_BTN4)
mouse_report.buttons |= MOUSE_BTN4;
else if (code == KC_MS_BTN5)
mouse_report.buttons |= MOUSE_BTN5;
else if (code == KC_MS_ACCEL0)
mousekey_accel |= (1 << 0);
else if (code == KC_MS_ACCEL1)
mousekey_accel |= (1 << 1);
else if (code == KC_MS_ACCEL2)
mousekey_accel |= (1 << 2);
}
void mousekey_off(uint8_t code) {
if (code == KC_MS_UP && mouse_report.y < 0) mouse_report.y = 0;
else if (code == KC_MS_DOWN && mouse_report.y > 0) mouse_report.y = 0;
else if (code == KC_MS_LEFT && mouse_report.x < 0) mouse_report.x = 0;
else if (code == KC_MS_RIGHT && mouse_report.x > 0) mouse_report.x = 0;
else if (code == KC_MS_WH_UP && mouse_report.v > 0) mouse_report.v = 0;
else if (code == KC_MS_WH_DOWN && mouse_report.v < 0) mouse_report.v = 0;
else if (code == KC_MS_WH_LEFT && mouse_report.h < 0) mouse_report.h = 0;
else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0) mouse_report.h = 0;
else if (code == KC_MS_BTN1) mouse_report.buttons &= ~MOUSE_BTN1;
else if (code == KC_MS_BTN2) mouse_report.buttons &= ~MOUSE_BTN2;
else if (code == KC_MS_BTN3) mouse_report.buttons &= ~MOUSE_BTN3;
else if (code == KC_MS_BTN4) mouse_report.buttons &= ~MOUSE_BTN4;
else if (code == KC_MS_BTN5) mouse_report.buttons &= ~MOUSE_BTN5;
else if (code == KC_MS_ACCEL0) mousekey_accel &= ~(1<<0);
else if (code == KC_MS_ACCEL1) mousekey_accel &= ~(1<<1);
else if (code == KC_MS_ACCEL2) mousekey_accel &= ~(1<<2);
if (mouse_report.x == 0 && mouse_report.y == 0 && mouse_report.v == 0 && mouse_report.h == 0)
mousekey_repeat = 0;
if (code == KC_MS_UP && mouse_report.y < 0)
mouse_report.y = 0;
else if (code == KC_MS_DOWN && mouse_report.y > 0)
mouse_report.y = 0;
else if (code == KC_MS_LEFT && mouse_report.x < 0)
mouse_report.x = 0;
else if (code == KC_MS_RIGHT && mouse_report.x > 0)
mouse_report.x = 0;
else if (code == KC_MS_WH_UP && mouse_report.v > 0)
mouse_report.v = 0;
else if (code == KC_MS_WH_DOWN && mouse_report.v < 0)
mouse_report.v = 0;
else if (code == KC_MS_WH_LEFT && mouse_report.h < 0)
mouse_report.h = 0;
else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
mouse_report.h = 0;
else if (code == KC_MS_BTN1)
mouse_report.buttons &= ~MOUSE_BTN1;
else if (code == KC_MS_BTN2)
mouse_report.buttons &= ~MOUSE_BTN2;
else if (code == KC_MS_BTN3)
mouse_report.buttons &= ~MOUSE_BTN3;
else if (code == KC_MS_BTN4)
mouse_report.buttons &= ~MOUSE_BTN4;
else if (code == KC_MS_BTN5)
mouse_report.buttons &= ~MOUSE_BTN5;
else if (code == KC_MS_ACCEL0)
mousekey_accel &= ~(1 << 0);
else if (code == KC_MS_ACCEL1)
mousekey_accel &= ~(1 << 1);
else if (code == KC_MS_ACCEL2)
mousekey_accel &= ~(1 << 2);
if (mouse_report.x == 0 && mouse_report.y == 0 && mouse_report.v == 0 && mouse_report.h == 0) mousekey_repeat = 0;
}
#else /* #ifndef MK_3_SPEED */
#else /* #ifndef MK_3_SPEED */
enum {
mkspd_unmod,
mkspd_0,
mkspd_1,
mkspd_2,
mkspd_COUNT
};
#ifndef MK_MOMENTARY_ACCEL
static uint8_t mk_speed = mkspd_1;
#else
static uint8_t mk_speed = mkspd_unmod;
enum { mkspd_unmod, mkspd_0, mkspd_1, mkspd_2, mkspd_COUNT };
# ifndef MK_MOMENTARY_ACCEL
static uint8_t mk_speed = mkspd_1;
# else
static uint8_t mk_speed = mkspd_unmod;
static uint8_t mkspd_DEFAULT = mkspd_unmod;
#endif
static uint16_t last_timer_c = 0;
static uint16_t last_timer_w = 0;
uint16_t c_offsets[mkspd_COUNT] = {
MK_C_OFFSET_UNMOD, MK_C_OFFSET_0, MK_C_OFFSET_1, MK_C_OFFSET_2
};
uint16_t c_intervals[mkspd_COUNT] = {
MK_C_INTERVAL_UNMOD, MK_C_INTERVAL_0, MK_C_INTERVAL_1, MK_C_INTERVAL_2
};
uint16_t w_offsets[mkspd_COUNT] = {
MK_W_OFFSET_UNMOD, MK_W_OFFSET_0, MK_W_OFFSET_1, MK_W_OFFSET_2
};
uint16_t w_intervals[mkspd_COUNT] = {
MK_W_INTERVAL_UNMOD, MK_W_INTERVAL_0, MK_W_INTERVAL_1, MK_W_INTERVAL_2
};
# endif
static uint16_t last_timer_c = 0;
static uint16_t last_timer_w = 0;
uint16_t c_offsets[mkspd_COUNT] = {MK_C_OFFSET_UNMOD, MK_C_OFFSET_0, MK_C_OFFSET_1, MK_C_OFFSET_2};
uint16_t c_intervals[mkspd_COUNT] = {MK_C_INTERVAL_UNMOD, MK_C_INTERVAL_0, MK_C_INTERVAL_1, MK_C_INTERVAL_2};
uint16_t w_offsets[mkspd_COUNT] = {MK_W_OFFSET_UNMOD, MK_W_OFFSET_0, MK_W_OFFSET_1, MK_W_OFFSET_2};
uint16_t w_intervals[mkspd_COUNT] = {MK_W_INTERVAL_UNMOD, MK_W_INTERVAL_0, MK_W_INTERVAL_1, MK_W_INTERVAL_2};
void mousekey_task(void) {
// report cursor and scroll movement independently
report_mouse_t const tmpmr = mouse_report;
if ((mouse_report.x || mouse_report.y) && timer_elapsed(last_timer_c) > c_intervals[mk_speed]) {
mouse_report.h = 0;
mouse_report.v = 0;
mousekey_send();
last_timer_c = last_timer;
mouse_report = tmpmr;
}
if ((mouse_report.h || mouse_report.v) && timer_elapsed(last_timer_w) > w_intervals[mk_speed]) {
mouse_report.x = 0;
mouse_report.y = 0;
mousekey_send();
last_timer_w = last_timer;
mouse_report = tmpmr;
}
// report cursor and scroll movement independently
report_mouse_t const tmpmr = mouse_report;
if ((mouse_report.x || mouse_report.y) && timer_elapsed(last_timer_c) > c_intervals[mk_speed]) {
mouse_report.h = 0;
mouse_report.v = 0;
mousekey_send();
last_timer_c = last_timer;
mouse_report = tmpmr;
}
if ((mouse_report.h || mouse_report.v) && timer_elapsed(last_timer_w) > w_intervals[mk_speed]) {
mouse_report.x = 0;
mouse_report.y = 0;
mousekey_send();
last_timer_w = last_timer;
mouse_report = tmpmr;
}
}
void adjust_speed(void) {
uint16_t const c_offset = c_offsets[mk_speed];
uint16_t const w_offset = w_offsets[mk_speed];
if (mouse_report.x > 0) mouse_report.x = c_offset;
if (mouse_report.x < 0) mouse_report.x = c_offset * -1;
if (mouse_report.y > 0) mouse_report.y = c_offset;
if (mouse_report.y < 0) mouse_report.y = c_offset * -1;
if (mouse_report.h > 0) mouse_report.h = w_offset;
if (mouse_report.h < 0) mouse_report.h = w_offset * -1;
if (mouse_report.v > 0) mouse_report.v = w_offset;
if (mouse_report.v < 0) mouse_report.v = w_offset * -1;
// adjust for diagonals
if (mouse_report.x && mouse_report.y) {
mouse_report.x = times_inv_sqrt2(mouse_report.x);
if (mouse_report.x == 0) { mouse_report.x = 1; }
mouse_report.y = times_inv_sqrt2(mouse_report.y);
if (mouse_report.y == 0) { mouse_report.y = 1; }
}
if (mouse_report.h && mouse_report.v) {
mouse_report.h = times_inv_sqrt2(mouse_report.h);
mouse_report.v = times_inv_sqrt2(mouse_report.v);
}
uint16_t const c_offset = c_offsets[mk_speed];
uint16_t const w_offset = w_offsets[mk_speed];
if (mouse_report.x > 0) mouse_report.x = c_offset;
if (mouse_report.x < 0) mouse_report.x = c_offset * -1;
if (mouse_report.y > 0) mouse_report.y = c_offset;
if (mouse_report.y < 0) mouse_report.y = c_offset * -1;
if (mouse_report.h > 0) mouse_report.h = w_offset;
if (mouse_report.h < 0) mouse_report.h = w_offset * -1;
if (mouse_report.v > 0) mouse_report.v = w_offset;
if (mouse_report.v < 0) mouse_report.v = w_offset * -1;
// adjust for diagonals
if (mouse_report.x && mouse_report.y) {
mouse_report.x = times_inv_sqrt2(mouse_report.x);
if (mouse_report.x == 0) {
mouse_report.x = 1;
}
mouse_report.y = times_inv_sqrt2(mouse_report.y);
if (mouse_report.y == 0) {
mouse_report.y = 1;
}
}
if (mouse_report.h && mouse_report.v) {
mouse_report.h = times_inv_sqrt2(mouse_report.h);
mouse_report.v = times_inv_sqrt2(mouse_report.v);
}
}
void mousekey_on(uint8_t code) {
uint16_t const c_offset = c_offsets[mk_speed];
uint16_t const w_offset = w_offsets[mk_speed];
uint8_t const old_speed = mk_speed;
if (code == KC_MS_UP) mouse_report.y = c_offset * -1;
else if (code == KC_MS_DOWN) mouse_report.y = c_offset;
else if (code == KC_MS_LEFT) mouse_report.x = c_offset * -1;
else if (code == KC_MS_RIGHT) mouse_report.x = c_offset;
else if (code == KC_MS_WH_UP) mouse_report.v = w_offset;
else if (code == KC_MS_WH_DOWN) mouse_report.v = w_offset * -1;
else if (code == KC_MS_WH_LEFT) mouse_report.h = w_offset * -1;
else if (code == KC_MS_WH_RIGHT) mouse_report.h = w_offset;
else if (code == KC_MS_BTN1) mouse_report.buttons |= MOUSE_BTN1;
else if (code == KC_MS_BTN2) mouse_report.buttons |= MOUSE_BTN2;
else if (code == KC_MS_BTN3) mouse_report.buttons |= MOUSE_BTN3;
else if (code == KC_MS_BTN4) mouse_report.buttons |= MOUSE_BTN4;
else if (code == KC_MS_BTN5) mouse_report.buttons |= MOUSE_BTN5;
else if (code == KC_MS_ACCEL0) mk_speed = mkspd_0;
else if (code == KC_MS_ACCEL1) mk_speed = mkspd_1;
else if (code == KC_MS_ACCEL2) mk_speed = mkspd_2;
if (mk_speed != old_speed) adjust_speed();
uint16_t const c_offset = c_offsets[mk_speed];
uint16_t const w_offset = w_offsets[mk_speed];
uint8_t const old_speed = mk_speed;
if (code == KC_MS_UP)
mouse_report.y = c_offset * -1;
else if (code == KC_MS_DOWN)
mouse_report.y = c_offset;
else if (code == KC_MS_LEFT)
mouse_report.x = c_offset * -1;
else if (code == KC_MS_RIGHT)
mouse_report.x = c_offset;
else if (code == KC_MS_WH_UP)
mouse_report.v = w_offset;
else if (code == KC_MS_WH_DOWN)
mouse_report.v = w_offset * -1;
else if (code == KC_MS_WH_LEFT)
mouse_report.h = w_offset * -1;
else if (code == KC_MS_WH_RIGHT)
mouse_report.h = w_offset;
else if (code == KC_MS_BTN1)
mouse_report.buttons |= MOUSE_BTN1;
else if (code == KC_MS_BTN2)
mouse_report.buttons |= MOUSE_BTN2;
else if (code == KC_MS_BTN3)
mouse_report.buttons |= MOUSE_BTN3;
else if (code == KC_MS_BTN4)
mouse_report.buttons |= MOUSE_BTN4;
else if (code == KC_MS_BTN5)
mouse_report.buttons |= MOUSE_BTN5;
else if (code == KC_MS_ACCEL0)
mk_speed = mkspd_0;
else if (code == KC_MS_ACCEL1)
mk_speed = mkspd_1;
else if (code == KC_MS_ACCEL2)
mk_speed = mkspd_2;
if (mk_speed != old_speed) adjust_speed();
}
void mousekey_off(uint8_t code) {
#ifdef MK_MOMENTARY_ACCEL
uint8_t const old_speed = mk_speed;
#endif
if (code == KC_MS_UP && mouse_report.y < 0) mouse_report.y = 0;
else if (code == KC_MS_DOWN && mouse_report.y > 0) mouse_report.y = 0;
else if (code == KC_MS_LEFT && mouse_report.x < 0) mouse_report.x = 0;
else if (code == KC_MS_RIGHT && mouse_report.x > 0) mouse_report.x = 0;
else if (code == KC_MS_WH_UP && mouse_report.v > 0) mouse_report.v = 0;
else if (code == KC_MS_WH_DOWN && mouse_report.v < 0) mouse_report.v = 0;
else if (code == KC_MS_WH_LEFT && mouse_report.h < 0) mouse_report.h = 0;
else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0) mouse_report.h = 0;
else if (code == KC_MS_BTN1) mouse_report.buttons &= ~MOUSE_BTN1;
else if (code == KC_MS_BTN2) mouse_report.buttons &= ~MOUSE_BTN2;
else if (code == KC_MS_BTN3) mouse_report.buttons &= ~MOUSE_BTN3;
else if (code == KC_MS_BTN4) mouse_report.buttons &= ~MOUSE_BTN4;
else if (code == KC_MS_BTN5) mouse_report.buttons &= ~MOUSE_BTN5;
#ifdef MK_MOMENTARY_ACCEL
else if (code == KC_MS_ACCEL0) mk_speed = mkspd_DEFAULT;
else if (code == KC_MS_ACCEL1) mk_speed = mkspd_DEFAULT;
else if (code == KC_MS_ACCEL2) mk_speed = mkspd_DEFAULT;
if (mk_speed != old_speed) adjust_speed();
#endif
# ifdef MK_MOMENTARY_ACCEL
uint8_t const old_speed = mk_speed;
# endif
if (code == KC_MS_UP && mouse_report.y < 0)
mouse_report.y = 0;
else if (code == KC_MS_DOWN && mouse_report.y > 0)
mouse_report.y = 0;
else if (code == KC_MS_LEFT && mouse_report.x < 0)
mouse_report.x = 0;
else if (code == KC_MS_RIGHT && mouse_report.x > 0)
mouse_report.x = 0;
else if (code == KC_MS_WH_UP && mouse_report.v > 0)
mouse_report.v = 0;
else if (code == KC_MS_WH_DOWN && mouse_report.v < 0)
mouse_report.v = 0;
else if (code == KC_MS_WH_LEFT && mouse_report.h < 0)
mouse_report.h = 0;
else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0)
mouse_report.h = 0;
else if (code == KC_MS_BTN1)
mouse_report.buttons &= ~MOUSE_BTN1;
else if (code == KC_MS_BTN2)
mouse_report.buttons &= ~MOUSE_BTN2;
else if (code == KC_MS_BTN3)
mouse_report.buttons &= ~MOUSE_BTN3;
else if (code == KC_MS_BTN4)
mouse_report.buttons &= ~MOUSE_BTN4;
else if (code == KC_MS_BTN5)
mouse_report.buttons &= ~MOUSE_BTN5;
# ifdef MK_MOMENTARY_ACCEL
else if (code == KC_MS_ACCEL0)
mk_speed = mkspd_DEFAULT;
else if (code == KC_MS_ACCEL1)
mk_speed = mkspd_DEFAULT;
else if (code == KC_MS_ACCEL2)
mk_speed = mkspd_DEFAULT;
if (mk_speed != old_speed) adjust_speed();
# endif
}
#endif /* #ifndef MK_3_SPEED */
void mousekey_send(void) {
mousekey_debug();
host_mouse_send(&mouse_report);
last_timer = timer_read();
mousekey_debug();
host_mouse_send(&mouse_report);
last_timer = timer_read();
}
void mousekey_clear(void) {
mouse_report = (report_mouse_t){};
mousekey_repeat = 0;
mousekey_accel = 0;
mouse_report = (report_mouse_t){};
mousekey_repeat = 0;
mousekey_accel = 0;
}
static void mousekey_debug(void) {
if (!debug_mouse) return;
print("mousekey [btn|x y v h](rep/acl): [");
phex(mouse_report.buttons); print("|");
print_decs(mouse_report.x); print(" ");
print_decs(mouse_report.y); print(" ");
print_decs(mouse_report.v); print(" ");
print_decs(mouse_report.h); print("](");
print_dec(mousekey_repeat); print("/");
print_dec(mousekey_accel); print(")\n");
if (!debug_mouse) return;
print("mousekey [btn|x y v h](rep/acl): [");
phex(mouse_report.buttons);
print("|");
print_decs(mouse_report.x);
print(" ");
print_decs(mouse_report.y);
print(" ");
print_decs(mouse_report.v);
print(" ");
print_decs(mouse_report.h);
print("](");
print_dec(mousekey_repeat);
print("/");
print_dec(mousekey_accel);
print(")\n");
}

View file

@ -16,7 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef MOUSEKEY_H
#define MOUSEKEY_H
# define MOUSEKEY_H
#endif
#include <stdbool.h>
@ -25,94 +25,94 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef MK_3_SPEED
/* max value on report descriptor */
#ifndef MOUSEKEY_MOVE_MAX
#define MOUSEKEY_MOVE_MAX 127
#elif MOUSEKEY_MOVE_MAX > 127
#error MOUSEKEY_MOVE_MAX needs to be smaller than 127
#endif
# ifndef MOUSEKEY_MOVE_MAX
# define MOUSEKEY_MOVE_MAX 127
# elif MOUSEKEY_MOVE_MAX > 127
# error MOUSEKEY_MOVE_MAX needs to be smaller than 127
# endif
#ifndef MOUSEKEY_WHEEL_MAX
#define MOUSEKEY_WHEEL_MAX 127
#elif MOUSEKEY_WHEEL_MAX > 127
#error MOUSEKEY_WHEEL_MAX needs to be smaller than 127
#endif
# ifndef MOUSEKEY_WHEEL_MAX
# define MOUSEKEY_WHEEL_MAX 127
# elif MOUSEKEY_WHEEL_MAX > 127
# error MOUSEKEY_WHEEL_MAX needs to be smaller than 127
# endif
#ifndef MOUSEKEY_MOVE_DELTA
#define MOUSEKEY_MOVE_DELTA 5
#endif
#ifndef MOUSEKEY_WHEEL_DELTA
#define MOUSEKEY_WHEEL_DELTA 1
#endif
#ifndef MOUSEKEY_DELAY
#define MOUSEKEY_DELAY 300
#endif
#ifndef MOUSEKEY_INTERVAL
#define MOUSEKEY_INTERVAL 50
#endif
#ifndef MOUSEKEY_MAX_SPEED
#define MOUSEKEY_MAX_SPEED 10
#endif
#ifndef MOUSEKEY_TIME_TO_MAX
#define MOUSEKEY_TIME_TO_MAX 20
#endif
#ifndef MOUSEKEY_WHEEL_MAX_SPEED
#define MOUSEKEY_WHEEL_MAX_SPEED 8
#endif
#ifndef MOUSEKEY_WHEEL_TIME_TO_MAX
#define MOUSEKEY_WHEEL_TIME_TO_MAX 40
#endif
# ifndef MOUSEKEY_MOVE_DELTA
# define MOUSEKEY_MOVE_DELTA 5
# endif
# ifndef MOUSEKEY_WHEEL_DELTA
# define MOUSEKEY_WHEEL_DELTA 1
# endif
# ifndef MOUSEKEY_DELAY
# define MOUSEKEY_DELAY 300
# endif
# ifndef MOUSEKEY_INTERVAL
# define MOUSEKEY_INTERVAL 50
# endif
# ifndef MOUSEKEY_MAX_SPEED
# define MOUSEKEY_MAX_SPEED 10
# endif
# ifndef MOUSEKEY_TIME_TO_MAX
# define MOUSEKEY_TIME_TO_MAX 20
# endif
# ifndef MOUSEKEY_WHEEL_MAX_SPEED
# define MOUSEKEY_WHEEL_MAX_SPEED 8
# endif
# ifndef MOUSEKEY_WHEEL_TIME_TO_MAX
# define MOUSEKEY_WHEEL_TIME_TO_MAX 40
# endif
#else /* #ifndef MK_3_SPEED */
#ifndef MK_C_OFFSET_UNMOD
#define MK_C_OFFSET_UNMOD 16
#endif
#ifndef MK_C_INTERVAL_UNMOD
#define MK_C_INTERVAL_UNMOD 16
#endif
#ifndef MK_C_OFFSET_0
#define MK_C_OFFSET_0 1
#endif
#ifndef MK_C_INTERVAL_0
#define MK_C_INTERVAL_0 32
#endif
#ifndef MK_C_OFFSET_1
#define MK_C_OFFSET_1 4
#endif
#ifndef MK_C_INTERVAL_1
#define MK_C_INTERVAL_1 16
#endif
#ifndef MK_C_OFFSET_2
#define MK_C_OFFSET_2 32
#endif
#ifndef MK_C_INTERVAL_2
#define MK_C_INTERVAL_2 16
#endif
# ifndef MK_C_OFFSET_UNMOD
# define MK_C_OFFSET_UNMOD 16
# endif
# ifndef MK_C_INTERVAL_UNMOD
# define MK_C_INTERVAL_UNMOD 16
# endif
# ifndef MK_C_OFFSET_0
# define MK_C_OFFSET_0 1
# endif
# ifndef MK_C_INTERVAL_0
# define MK_C_INTERVAL_0 32
# endif
# ifndef MK_C_OFFSET_1
# define MK_C_OFFSET_1 4
# endif
# ifndef MK_C_INTERVAL_1
# define MK_C_INTERVAL_1 16
# endif
# ifndef MK_C_OFFSET_2
# define MK_C_OFFSET_2 32
# endif
# ifndef MK_C_INTERVAL_2
# define MK_C_INTERVAL_2 16
# endif
#ifndef MK_W_OFFSET_UNMOD
#define MK_W_OFFSET_UNMOD 1
#endif
#ifndef MK_W_INTERVAL_UNMOD
#define MK_W_INTERVAL_UNMOD 40
#endif
#ifndef MK_W_OFFSET_0
#define MK_W_OFFSET_0 1
#endif
#ifndef MK_W_INTERVAL_0
#define MK_W_INTERVAL_0 360
#endif
#ifndef MK_W_OFFSET_1
#define MK_W_OFFSET_1 1
#endif
#ifndef MK_W_INTERVAL_1
#define MK_W_INTERVAL_1 120
#endif
#ifndef MK_W_OFFSET_2
#define MK_W_OFFSET_2 1
#endif
#ifndef MK_W_INTERVAL_2
#define MK_W_INTERVAL_2 20
#endif
# ifndef MK_W_OFFSET_UNMOD
# define MK_W_OFFSET_UNMOD 1
# endif
# ifndef MK_W_INTERVAL_UNMOD
# define MK_W_INTERVAL_UNMOD 40
# endif
# ifndef MK_W_OFFSET_0
# define MK_W_OFFSET_0 1
# endif
# ifndef MK_W_INTERVAL_0
# define MK_W_INTERVAL_0 360
# endif
# ifndef MK_W_OFFSET_1
# define MK_W_OFFSET_1 1
# endif
# ifndef MK_W_INTERVAL_1
# define MK_W_INTERVAL_1 120
# endif
# ifndef MK_W_OFFSET_2
# define MK_W_OFFSET_2 1
# endif
# ifndef MK_W_INTERVAL_2
# define MK_W_INTERVAL_2 20
# endif
#endif /* #ifndef MK_3_SPEED */

View file

@ -19,11 +19,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define NODEBUG_H
#ifndef NO_DEBUG
#define NO_DEBUG
#include "debug.h"
#undef NO_DEBUG
# define NO_DEBUG
# include "debug.h"
# undef NO_DEBUG
#else
#include "debug.h"
# include "debug.h"
#endif
#endif

View file

@ -2,17 +2,17 @@
/* Very basic print functions, intended to be used with usb_debug_only.c
* http://www.pjrc.com/teensy/
* Copyright (c) 2008 PJRC.COM, LLC
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -25,28 +25,23 @@
#include <stdint.h>
#include "print.h"
#ifndef NO_PRINT
#if defined(__AVR__)
# if defined(__AVR__)
#define sendchar(c) xputc(c)
# define sendchar(c) xputc(c)
void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { xdev_out(sendchar_func); }
void print_set_sendchar(int8_t (*sendchar_func)(uint8_t))
{
xdev_out(sendchar_func);
}
#elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */
# elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */
// don't need anything extra
#elif defined(__arm__) /* __AVR__ */
# elif defined(__arm__) /* __AVR__ */
// TODO
//void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { }
// void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { }
#endif /* __AVR__ */
# endif /* __AVR__ */
#endif

View file

@ -30,137 +30,136 @@
#include "util.h"
#if defined(PROTOCOL_CHIBIOS) || defined(PROTOCOL_ARM_ATSAM)
#define PSTR(x) x
# define PSTR(x) x
#endif
#ifndef NO_PRINT
#if defined(__AVR__) /* __AVR__ */
# if defined(__AVR__) /* __AVR__ */
# include "avr/xprintf.h"
# include "avr/xprintf.h"
# ifdef USER_PRINT /* USER_PRINT */
# ifdef USER_PRINT /* USER_PRINT */
// Remove normal print defines
# define print(s)
# define println(s)
# undef xprintf
# define xprintf(fmt, ...)
# define print(s)
# define println(s)
# undef xprintf
# define xprintf(fmt, ...)
// Create user print defines
# define uprint(s) xputs(PSTR(s))
# define uprintln(s) xputs(PSTR(s "\r\n"))
# define uprintf(fmt, ...) __xprintf(PSTR(fmt), ##__VA_ARGS__)
# define uprint(s) xputs(PSTR(s))
# define uprintln(s) xputs(PSTR(s "\r\n"))
# define uprintf(fmt, ...) __xprintf(PSTR(fmt), ##__VA_ARGS__)
# else /* NORMAL PRINT */
# else /* NORMAL PRINT */
// Create user & normal print defines
# define print(s) xputs(PSTR(s))
# define println(s) xputs(PSTR(s "\r\n"))
# define uprint(s) print(s)
# define uprintln(s) println(s)
# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
# define print(s) xputs(PSTR(s))
# define println(s) xputs(PSTR(s "\r\n"))
# define uprint(s) print(s)
# define uprintln(s) println(s)
# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
# endif /* USER_PRINT / NORMAL PRINT */
# endif /* USER_PRINT / NORMAL PRINT */
# ifdef __cplusplus
# ifdef __cplusplus
extern "C"
# endif
# endif
/* function pointer of sendchar to be used by print utility */
void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
/* function pointer of sendchar to be used by print utility */
void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
#elif defined(PROTOCOL_CHIBIOS) /* PROTOCOL_CHIBIOS */
# elif defined(PROTOCOL_CHIBIOS) /* PROTOCOL_CHIBIOS */
#ifndef TERMINAL_ENABLE
# include "chibios/printf.h"
#endif
# ifndef TERMINAL_ENABLE
# include "chibios/printf.h"
# endif
# ifdef USER_PRINT /* USER_PRINT */
# ifdef USER_PRINT /* USER_PRINT */
// Remove normal print defines
# define print(s)
# define println(s)
# define xprintf(fmt, ...)
# define print(s)
# define println(s)
# define xprintf(fmt, ...)
// Create user print defines
# define uprint(s) printf(s)
# define uprintln(s) printf(s "\r\n")
# define uprintf printf
# define uprint(s) printf(s)
# define uprintln(s) printf(s "\r\n")
# define uprintf printf
# else /* NORMAL PRINT */
# else /* NORMAL PRINT */
// Create user & normal print defines
# define print(s) printf(s)
# define println(s) printf(s "\r\n")
# define xprintf printf
# define uprint(s) printf(s)
# define uprintln(s) printf(s "\r\n")
# define uprintf printf
# define print(s) printf(s)
# define println(s) printf(s "\r\n")
# define xprintf printf
# define uprint(s) printf(s)
# define uprintln(s) printf(s "\r\n")
# define uprintf printf
# endif /* USER_PRINT / NORMAL PRINT */
# endif /* USER_PRINT / NORMAL PRINT */
#elif defined(PROTOCOL_ARM_ATSAM) /* PROTOCOL_ARM_ATSAM */
# elif defined(PROTOCOL_ARM_ATSAM) /* PROTOCOL_ARM_ATSAM */
# include "arm_atsam/printf.h"
# include "arm_atsam/printf.h"
# ifdef USER_PRINT /* USER_PRINT */
# ifdef USER_PRINT /* USER_PRINT */
// Remove normal print defines
# define print(s)
# define println(s)
# define xprintf(fmt, ...)
# define print(s)
# define println(s)
# define xprintf(fmt, ...)
// Create user print defines
# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
# define uprint(s) xprintf(s)
# define uprintln(s) xprintf(s "\r\n")
# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
# define uprint(s) xprintf(s)
# define uprintln(s) xprintf(s "\r\n")
# else /* NORMAL PRINT */
# else /* NORMAL PRINT */
// Create user & normal print defines
# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
# define print(s) xprintf(s)
# define println(s) xprintf(s "\r\n")
# define uprint(s) print(s)
# define uprintln(s) println(s)
# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
# define print(s) xprintf(s)
# define println(s) xprintf(s "\r\n")
# define uprint(s) print(s)
# define uprintln(s) println(s)
# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
# endif /* USER_PRINT / NORMAL PRINT */
# endif /* USER_PRINT / NORMAL PRINT */
#elif defined(__arm__) /* __arm__ */
# elif defined(__arm__) /* __arm__ */
# include "mbed/xprintf.h"
# include "mbed/xprintf.h"
# ifdef USER_PRINT /* USER_PRINT */
# ifdef USER_PRINT /* USER_PRINT */
// Remove normal print defines
# define print(s)
# define println(s)
# define xprintf(fmt, ...)
# define print(s)
# define println(s)
# define xprintf(fmt, ...)
// Create user print defines
# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
# define uprint(s) xprintf(s)
# define uprintln(s) xprintf(s "\r\n")
# define uprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
# define uprint(s) xprintf(s)
# define uprintln(s) xprintf(s "\r\n")
# else /* NORMAL PRINT */
# else /* NORMAL PRINT */
// Create user & normal print defines
# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
# define print(s) xprintf(s)
# define println(s) xprintf(s "\r\n")
# define uprint(s) print(s)
# define uprintln(s) println(s)
# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
# define xprintf(fmt, ...) __xprintf(fmt, ##__VA_ARGS__)
# define print(s) xprintf(s)
# define println(s) xprintf(s "\r\n")
# define uprint(s) print(s)
# define uprintln(s) println(s)
# define uprintf(fmt, ...) xprintf(fmt, ##__VA_ARGS__)
# endif /* USER_PRINT / NORMAL PRINT */
# endif /* USER_PRINT / NORMAL PRINT */
/* TODO: to select output destinations: UART/USBSerial */
# define print_set_sendchar(func)
# define print_set_sendchar(func)
#endif /* __AVR__ / PROTOCOL_CHIBIOS / PROTOCOL_ARM_ATSAM / __arm__ */
# endif /* __AVR__ / PROTOCOL_CHIBIOS / PROTOCOL_ARM_ATSAM / __arm__ */
// User print disables the normal print messages in the body of QMK/TMK code and
// is meant as a lightweight alternative to NOPRINT. Use it when you only want to do
@ -169,141 +168,140 @@ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
//
// !!! DO NOT USE USER PRINT CALLS IN THE BODY OF QMK/TMK !!!
//
#ifdef USER_PRINT
# ifdef USER_PRINT
// Disable normal print
#define print_dec(data)
#define print_decs(data)
#define print_hex4(data)
#define print_hex8(data)
#define print_hex16(data)
#define print_hex32(data)
#define print_bin4(data)
#define print_bin8(data)
#define print_bin16(data)
#define print_bin32(data)
#define print_bin_reverse8(data)
#define print_bin_reverse16(data)
#define print_bin_reverse32(data)
#define print_val_dec(v)
#define print_val_decs(v)
#define print_val_hex8(v)
#define print_val_hex16(v)
#define print_val_hex32(v)
#define print_val_bin8(v)
#define print_val_bin16(v)
#define print_val_bin32(v)
#define print_val_bin_reverse8(v)
#define print_val_bin_reverse16(v)
#define print_val_bin_reverse32(v)
# define print_dec(data)
# define print_decs(data)
# define print_hex4(data)
# define print_hex8(data)
# define print_hex16(data)
# define print_hex32(data)
# define print_bin4(data)
# define print_bin8(data)
# define print_bin16(data)
# define print_bin32(data)
# define print_bin_reverse8(data)
# define print_bin_reverse16(data)
# define print_bin_reverse32(data)
# define print_val_dec(v)
# define print_val_decs(v)
# define print_val_hex8(v)
# define print_val_hex16(v)
# define print_val_hex32(v)
# define print_val_bin8(v)
# define print_val_bin16(v)
# define print_val_bin32(v)
# define print_val_bin_reverse8(v)
# define print_val_bin_reverse16(v)
# define print_val_bin_reverse32(v)
#else /* NORMAL_PRINT */
# else /* NORMAL_PRINT */
//Enable normal print
// Enable normal print
/* decimal */
#define print_dec(i) xprintf("%u", i)
#define print_decs(i) xprintf("%d", i)
# define print_dec(i) xprintf("%u", i)
# define print_decs(i) xprintf("%d", i)
/* hex */
#define print_hex4(i) xprintf("%X", i)
#define print_hex8(i) xprintf("%02X", i)
#define print_hex16(i) xprintf("%04X", i)
#define print_hex32(i) xprintf("%08lX", i)
# define print_hex4(i) xprintf("%X", i)
# define print_hex8(i) xprintf("%02X", i)
# define print_hex16(i) xprintf("%04X", i)
# define print_hex32(i) xprintf("%08lX", i)
/* binary */
#define print_bin4(i) xprintf("%04b", i)
#define print_bin8(i) xprintf("%08b", i)
#define print_bin16(i) xprintf("%016b", i)
#define print_bin32(i) xprintf("%032lb", i)
#define print_bin_reverse8(i) xprintf("%08b", bitrev(i))
#define print_bin_reverse16(i) xprintf("%016b", bitrev16(i))
#define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i))
# define print_bin4(i) xprintf("%04b", i)
# define print_bin8(i) xprintf("%08b", i)
# define print_bin16(i) xprintf("%016b", i)
# define print_bin32(i) xprintf("%032lb", i)
# define print_bin_reverse8(i) xprintf("%08b", bitrev(i))
# define print_bin_reverse16(i) xprintf("%016b", bitrev16(i))
# define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i))
/* print value utility */
#define print_val_dec(v) xprintf(#v ": %u\n", v)
#define print_val_decs(v) xprintf(#v ": %d\n", v)
#define print_val_hex8(v) xprintf(#v ": %X\n", v)
#define print_val_hex16(v) xprintf(#v ": %02X\n", v)
#define print_val_hex32(v) xprintf(#v ": %04lX\n", v)
#define print_val_bin8(v) xprintf(#v ": %08b\n", v)
#define print_val_bin16(v) xprintf(#v ": %016b\n", v)
#define print_val_bin32(v) xprintf(#v ": %032lb\n", v)
#define print_val_bin_reverse8(v) xprintf(#v ": %08b\n", bitrev(v))
#define print_val_bin_reverse16(v) xprintf(#v ": %016b\n", bitrev16(v))
#define print_val_bin_reverse32(v) xprintf(#v ": %032lb\n", bitrev32(v))
# define print_val_dec(v) xprintf(# v ": %u\n", v)
# define print_val_decs(v) xprintf(# v ": %d\n", v)
# define print_val_hex8(v) xprintf(# v ": %X\n", v)
# define print_val_hex16(v) xprintf(# v ": %02X\n", v)
# define print_val_hex32(v) xprintf(# v ": %04lX\n", v)
# define print_val_bin8(v) xprintf(# v ": %08b\n", v)
# define print_val_bin16(v) xprintf(# v ": %016b\n", v)
# define print_val_bin32(v) xprintf(# v ": %032lb\n", v)
# define print_val_bin_reverse8(v) xprintf(# v ": %08b\n", bitrev(v))
# define print_val_bin_reverse16(v) xprintf(# v ": %016b\n", bitrev16(v))
# define print_val_bin_reverse32(v) xprintf(# v ": %032lb\n", bitrev32(v))
#endif /* USER_PRINT / NORMAL_PRINT */
# endif /* USER_PRINT / NORMAL_PRINT */
// User Print
/* decimal */
#define uprint_dec(i) uprintf("%u", i)
#define uprint_decs(i) uprintf("%d", i)
# define uprint_dec(i) uprintf("%u", i)
# define uprint_decs(i) uprintf("%d", i)
/* hex */
#define uprint_hex4(i) uprintf("%X", i)
#define uprint_hex8(i) uprintf("%02X", i)
#define uprint_hex16(i) uprintf("%04X", i)
#define uprint_hex32(i) uprintf("%08lX", i)
# define uprint_hex4(i) uprintf("%X", i)
# define uprint_hex8(i) uprintf("%02X", i)
# define uprint_hex16(i) uprintf("%04X", i)
# define uprint_hex32(i) uprintf("%08lX", i)
/* binary */
#define uprint_bin4(i) uprintf("%04b", i)
#define uprint_bin8(i) uprintf("%08b", i)
#define uprint_bin16(i) uprintf("%016b", i)
#define uprint_bin32(i) uprintf("%032lb", i)
#define uprint_bin_reverse8(i) uprintf("%08b", bitrev(i))
#define uprint_bin_reverse16(i) uprintf("%016b", bitrev16(i))
#define uprint_bin_reverse32(i) uprintf("%032lb", bitrev32(i))
# define uprint_bin4(i) uprintf("%04b", i)
# define uprint_bin8(i) uprintf("%08b", i)
# define uprint_bin16(i) uprintf("%016b", i)
# define uprint_bin32(i) uprintf("%032lb", i)
# define uprint_bin_reverse8(i) uprintf("%08b", bitrev(i))
# define uprint_bin_reverse16(i) uprintf("%016b", bitrev16(i))
# define uprint_bin_reverse32(i) uprintf("%032lb", bitrev32(i))
/* print value utility */
#define uprint_val_dec(v) uprintf(#v ": %u\n", v)
#define uprint_val_decs(v) uprintf(#v ": %d\n", v)
#define uprint_val_hex8(v) uprintf(#v ": %X\n", v)
#define uprint_val_hex16(v) uprintf(#v ": %02X\n", v)
#define uprint_val_hex32(v) uprintf(#v ": %04lX\n", v)
#define uprint_val_bin8(v) uprintf(#v ": %08b\n", v)
#define uprint_val_bin16(v) uprintf(#v ": %016b\n", v)
#define uprint_val_bin32(v) uprintf(#v ": %032lb\n", v)
#define uprint_val_bin_reverse8(v) uprintf(#v ": %08b\n", bitrev(v))
#define uprint_val_bin_reverse16(v) uprintf(#v ": %016b\n", bitrev16(v))
#define uprint_val_bin_reverse32(v) uprintf(#v ": %032lb\n", bitrev32(v))
# define uprint_val_dec(v) uprintf(# v ": %u\n", v)
# define uprint_val_decs(v) uprintf(# v ": %d\n", v)
# define uprint_val_hex8(v) uprintf(# v ": %X\n", v)
# define uprint_val_hex16(v) uprintf(# v ": %02X\n", v)
# define uprint_val_hex32(v) uprintf(# v ": %04lX\n", v)
# define uprint_val_bin8(v) uprintf(# v ": %08b\n", v)
# define uprint_val_bin16(v) uprintf(# v ": %016b\n", v)
# define uprint_val_bin32(v) uprintf(# v ": %032lb\n", v)
# define uprint_val_bin_reverse8(v) uprintf(# v ": %08b\n", bitrev(v))
# define uprint_val_bin_reverse16(v) uprintf(# v ": %016b\n", bitrev16(v))
# define uprint_val_bin_reverse32(v) uprintf(# v ": %032lb\n", bitrev32(v))
#else /* NO_PRINT */
#else /* NO_PRINT */
#define xprintf(fmt, ...)
#define print(s)
#define println(s)
#define print_set_sendchar(func)
#define print_dec(data)
#define print_decs(data)
#define print_hex4(data)
#define print_hex8(data)
#define print_hex16(data)
#define print_hex32(data)
#define print_bin4(data)
#define print_bin8(data)
#define print_bin16(data)
#define print_bin32(data)
#define print_bin_reverse8(data)
#define print_bin_reverse16(data)
#define print_bin_reverse32(data)
#define print_val_dec(v)
#define print_val_decs(v)
#define print_val_hex8(v)
#define print_val_hex16(v)
#define print_val_hex32(v)
#define print_val_bin8(v)
#define print_val_bin16(v)
#define print_val_bin32(v)
#define print_val_bin_reverse8(v)
#define print_val_bin_reverse16(v)
#define print_val_bin_reverse32(v)
#endif /* NO_PRINT */
# define xprintf(fmt, ...)
# define print(s)
# define println(s)
# define print_set_sendchar(func)
# define print_dec(data)
# define print_decs(data)
# define print_hex4(data)
# define print_hex8(data)
# define print_hex16(data)
# define print_hex32(data)
# define print_bin4(data)
# define print_bin8(data)
# define print_bin16(data)
# define print_bin32(data)
# define print_bin_reverse8(data)
# define print_bin_reverse16(data)
# define print_bin_reverse32(data)
# define print_val_dec(v)
# define print_val_decs(v)
# define print_val_hex8(v)
# define print_val_hex16(v)
# define print_val_hex32(v)
# define print_val_bin8(v)
# define print_val_bin16(v)
# define print_val_bin32(v)
# define print_val_bin_reverse8(v)
# define print_val_bin_reverse16(v)
# define print_val_bin_reverse32(v)
#endif /* NO_PRINT */
/* Backward compatiblitly for old name */
#define pdec(data) print_dec(data)
#define pdec16(data) print_dec(data)
#define phex(data) print_hex8(data)
#define phex16(data) print_hex16(data)
#define pbin(data) print_bin8(data)
#define pbin16(data) print_bin16(data)
#define pbin_reverse(data) print_bin_reverse8(data)
#define pbin_reverse16(data) print_bin_reverse16(data)
#define pdec(data) print_dec(data)
#define pdec16(data) print_dec(data)
#define phex(data) print_hex8(data)
#define phex16(data) print_hex16(data)
#define pbin(data) print_bin8(data)
#define pbin16(data) print_bin16(data)
#define pbin_reverse(data) print_bin_reverse8(data)
#define pbin_reverse16(data) print_bin_reverse16(data)
#endif

View file

@ -2,12 +2,12 @@
#define PROGMEM_H 1
#if defined(__AVR__)
# include <avr/pgmspace.h>
# include <avr/pgmspace.h>
#else
# define PROGMEM
# define pgm_read_byte(p) *((unsigned char*)(p))
# define pgm_read_word(p) *((uint16_t*)(p))
# define pgm_read_dword(p) *((uint32_t*)(p))
# define PROGMEM
# define pgm_read_byte(p) *((unsigned char*)(p))
# define pgm_read_word(p) *((uint16_t*)(p))
# define pgm_read_dword(p) *((uint32_t*)(p))
#endif
#endif

View file

@ -1,8 +1,8 @@
#ifndef _RAW_HID_H_
#define _RAW_HID_H_
void raw_hid_receive( uint8_t *data, uint8_t length );
void raw_hid_receive(uint8_t *data, uint8_t length);
void raw_hid_send( uint8_t *data, uint8_t length );
void raw_hid_send(uint8_t *data, uint8_t length);
#endif

View file

@ -25,20 +25,18 @@
*
* FIXME: Needs doc
*/
uint8_t has_anykey(report_keyboard_t* keyboard_report)
{
uint8_t cnt = 0;
uint8_t *p = keyboard_report->keys;
uint8_t lp = sizeof(keyboard_report->keys);
uint8_t has_anykey(report_keyboard_t* keyboard_report) {
uint8_t cnt = 0;
uint8_t* p = keyboard_report->keys;
uint8_t lp = sizeof(keyboard_report->keys);
#ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) {
p = keyboard_report->nkro.bits;
p = keyboard_report->nkro.bits;
lp = sizeof(keyboard_report->nkro.bits);
}
#endif
while (lp--) {
if (*p++)
cnt++;
if (*p++) cnt++;
}
return cnt;
}
@ -47,14 +45,13 @@ uint8_t has_anykey(report_keyboard_t* keyboard_report)
*
* FIXME: Needs doc
*/
uint8_t get_first_key(report_keyboard_t* keyboard_report)
{
uint8_t get_first_key(report_keyboard_t* keyboard_report) {
#ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) {
uint8_t i = 0;
for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
;
return i<<3 | biton(keyboard_report->nkro.bits[i]);
return i << 3 | biton(keyboard_report->nkro.bits[i]);
}
#endif
#ifdef USB_6KRO_ENABLE
@ -75,10 +72,9 @@ uint8_t get_first_key(report_keyboard_t* keyboard_report)
*
* FIXME: Needs doc
*/
void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
{
void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
#ifdef USB_6KRO_ENABLE
int8_t i = cb_head;
int8_t i = cb_head;
int8_t empty = -1;
if (cb_count) {
do {
@ -97,18 +93,16 @@ void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
// pop head when has no empty space
cb_head = RO_INC(cb_head);
cb_count--;
}
else {
} else {
// left shift when has empty space
uint8_t offset = 1;
i = RO_INC(empty);
i = RO_INC(empty);
do {
if (keyboard_report->keys[i] != 0) {
keyboard_report->keys[empty] = keyboard_report->keys[i];
keyboard_report->keys[i] = 0;
empty = RO_INC(empty);
}
else {
keyboard_report->keys[i] = 0;
empty = RO_INC(empty);
} else {
offset++;
}
i = RO_INC(i);
@ -120,10 +114,10 @@ void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
}
// add to tail
keyboard_report->keys[cb_tail] = code;
cb_tail = RO_INC(cb_tail);
cb_tail = RO_INC(cb_tail);
cb_count++;
#else
int8_t i = 0;
int8_t i = 0;
int8_t empty = -1;
for (; i < KEYBOARD_REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) {
@ -145,8 +139,7 @@ void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
*
* FIXME: Needs doc
*/
void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
{
void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code) {
#ifdef USB_6KRO_ENABLE
uint8_t i = cb_head;
if (cb_count) {
@ -186,10 +179,9 @@ void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
*
* FIXME: Needs doc
*/
void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
{
if ((code>>3) < KEYBOARD_REPORT_BITS) {
keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
if ((code >> 3) < KEYBOARD_REPORT_BITS) {
keyboard_report->nkro.bits[code >> 3] |= 1 << (code & 7);
} else {
dprintf("add_key_bit: can't add: %02X\n", code);
}
@ -199,10 +191,9 @@ void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
*
* FIXME: Needs doc
*/
void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
{
if ((code>>3) < KEYBOARD_REPORT_BITS) {
keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code) {
if ((code >> 3) < KEYBOARD_REPORT_BITS) {
keyboard_report->nkro.bits[code >> 3] &= ~(1 << (code & 7));
} else {
dprintf("del_key_bit: can't del: %02X\n", code);
}
@ -213,8 +204,7 @@ void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
*
* FIXME: Needs doc
*/
void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key)
{
void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key) {
#ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) {
add_key_bit(keyboard_report, key);
@ -228,8 +218,7 @@ void add_key_to_report(report_keyboard_t* keyboard_report, uint8_t key)
*
* FIXME: Needs doc
*/
void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key)
{
void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key) {
#ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) {
del_key_bit(keyboard_report, key);
@ -243,8 +232,7 @@ void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key)
*
* FIXME: Needs doc
*/
void clear_keys_from_report(report_keyboard_t* keyboard_report)
{
void clear_keys_from_report(report_keyboard_t* keyboard_report) {
// not clear mods
#ifdef NKRO_ENABLE
if (keyboard_protocol && keymap_config.nkro) {

View file

@ -21,90 +21,88 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#include "keycode.h"
/* report id */
#define REPORT_ID_KEYBOARD 1
#define REPORT_ID_MOUSE 2
#define REPORT_ID_SYSTEM 3
#define REPORT_ID_CONSUMER 4
#define REPORT_ID_NKRO 5
#define REPORT_ID_KEYBOARD 1
#define REPORT_ID_MOUSE 2
#define REPORT_ID_SYSTEM 3
#define REPORT_ID_CONSUMER 4
#define REPORT_ID_NKRO 5
/* mouse buttons */
#define MOUSE_BTN1 (1<<0)
#define MOUSE_BTN2 (1<<1)
#define MOUSE_BTN3 (1<<2)
#define MOUSE_BTN4 (1<<3)
#define MOUSE_BTN5 (1<<4)
#define MOUSE_BTN1 (1 << 0)
#define MOUSE_BTN2 (1 << 1)
#define MOUSE_BTN3 (1 << 2)
#define MOUSE_BTN4 (1 << 3)
#define MOUSE_BTN5 (1 << 4)
/* Consumer Page(0x0C)
* following are supported by Windows: http://msdn.microsoft.com/en-us/windows/hardware/gg463372.aspx
* see also https://docs.microsoft.com/en-us/windows-hardware/drivers/hid/display-brightness-control
*/
#define AUDIO_MUTE 0x00E2
#define AUDIO_VOL_UP 0x00E9
#define AUDIO_VOL_DOWN 0x00EA
#define TRANSPORT_NEXT_TRACK 0x00B5
#define TRANSPORT_PREV_TRACK 0x00B6
#define TRANSPORT_STOP 0x00B7
#define TRANSPORT_STOP_EJECT 0x00CC
#define TRANSPORT_PLAY_PAUSE 0x00CD
#define BRIGHTNESS_UP 0x006F
#define BRIGHTNESS_DOWN 0x0070
#define AUDIO_MUTE 0x00E2
#define AUDIO_VOL_UP 0x00E9
#define AUDIO_VOL_DOWN 0x00EA
#define TRANSPORT_NEXT_TRACK 0x00B5
#define TRANSPORT_PREV_TRACK 0x00B6
#define TRANSPORT_STOP 0x00B7
#define TRANSPORT_STOP_EJECT 0x00CC
#define TRANSPORT_PLAY_PAUSE 0x00CD
#define BRIGHTNESS_UP 0x006F
#define BRIGHTNESS_DOWN 0x0070
/* application launch */
#define AL_CC_CONFIG 0x0183
#define AL_EMAIL 0x018A
#define AL_CALCULATOR 0x0192
#define AL_LOCAL_BROWSER 0x0194
#define AL_CC_CONFIG 0x0183
#define AL_EMAIL 0x018A
#define AL_CALCULATOR 0x0192
#define AL_LOCAL_BROWSER 0x0194
/* application control */
#define AC_SEARCH 0x0221
#define AC_HOME 0x0223
#define AC_BACK 0x0224
#define AC_FORWARD 0x0225
#define AC_STOP 0x0226
#define AC_REFRESH 0x0227
#define AC_BOOKMARKS 0x022A
#define AC_SEARCH 0x0221
#define AC_HOME 0x0223
#define AC_BACK 0x0224
#define AC_FORWARD 0x0225
#define AC_STOP 0x0226
#define AC_REFRESH 0x0227
#define AC_BOOKMARKS 0x022A
/* supplement for Bluegiga iWRAP HID(not supported by Windows?) */
#define AL_LOCK 0x019E
#define TRANSPORT_RECORD 0x00B2
#define TRANSPORT_FAST_FORWARD 0x00B3
#define TRANSPORT_REWIND 0x00B4
#define TRANSPORT_EJECT 0x00B8
#define AC_MINIMIZE 0x0206
#define AL_LOCK 0x019E
#define TRANSPORT_RECORD 0x00B2
#define TRANSPORT_FAST_FORWARD 0x00B3
#define TRANSPORT_REWIND 0x00B4
#define TRANSPORT_EJECT 0x00B8
#define AC_MINIMIZE 0x0206
/* Generic Desktop Page(0x01) - system power control */
#define SYSTEM_POWER_DOWN 0x0081
#define SYSTEM_SLEEP 0x0082
#define SYSTEM_WAKE_UP 0x0083
#define SYSTEM_POWER_DOWN 0x0081
#define SYSTEM_SLEEP 0x0082
#define SYSTEM_WAKE_UP 0x0083
#define NKRO_SHARED_EP
/* key report size(NKRO or boot mode) */
#if defined(NKRO_ENABLE)
#if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
#include "protocol/usb_descriptor.h"
#define KEYBOARD_REPORT_BITS (SHARED_EPSIZE - 2)
#elif defined(PROTOCOL_ARM_ATSAM)
#include "protocol/arm_atsam/usb/udi_device_epsize.h"
#define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
#undef NKRO_SHARED_EP
#undef MOUSE_SHARED_EP
#else
#error "NKRO not supported with this protocol"
#endif
# if defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
# include "protocol/usb_descriptor.h"
# define KEYBOARD_REPORT_BITS (SHARED_EPSIZE - 2)
# elif defined(PROTOCOL_ARM_ATSAM)
# include "protocol/arm_atsam/usb/udi_device_epsize.h"
# define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
# undef NKRO_SHARED_EP
# undef MOUSE_SHARED_EP
# else
# error "NKRO not supported with this protocol"
# endif
#endif
#ifdef KEYBOARD_SHARED_EP
# define KEYBOARD_REPORT_SIZE 9
# define KEYBOARD_REPORT_SIZE 9
#else
# define KEYBOARD_REPORT_SIZE 8
# define KEYBOARD_REPORT_SIZE 8
#endif
#define KEYBOARD_REPORT_KEYS 6
/* VUSB hardcodes keyboard and mouse+extrakey only */
#if defined(PROTOCOL_VUSB)
#undef KEYBOARD_SHARED_EP
#undef MOUSE_SHARED_EP
# undef KEYBOARD_SHARED_EP
# undef MOUSE_SHARED_EP
#endif
#ifdef __cplusplus
@ -143,58 +141,32 @@ typedef union {
};
#ifdef NKRO_ENABLE
struct nkro_report {
#ifdef NKRO_SHARED_EP
# ifdef NKRO_SHARED_EP
uint8_t report_id;
#endif
# endif
uint8_t mods;
uint8_t bits[KEYBOARD_REPORT_BITS];
} nkro;
#endif
} __attribute__ ((packed)) report_keyboard_t;
} __attribute__((packed)) report_keyboard_t;
typedef struct {
#ifdef MOUSE_SHARED_EP
uint8_t report_id;
#endif
uint8_t buttons;
int8_t x;
int8_t y;
int8_t v;
int8_t h;
} __attribute__ ((packed)) report_mouse_t;
int8_t x;
int8_t y;
int8_t v;
int8_t h;
} __attribute__((packed)) report_mouse_t;
/* keycode to system usage */
#define KEYCODE2SYSTEM(key) \
(key == KC_SYSTEM_POWER ? SYSTEM_POWER_DOWN : \
(key == KC_SYSTEM_SLEEP ? SYSTEM_SLEEP : \
(key == KC_SYSTEM_WAKE ? SYSTEM_WAKE_UP : 0)))
#define KEYCODE2SYSTEM(key) (key == KC_SYSTEM_POWER ? SYSTEM_POWER_DOWN : (key == KC_SYSTEM_SLEEP ? SYSTEM_SLEEP : (key == KC_SYSTEM_WAKE ? SYSTEM_WAKE_UP : 0)))
/* keycode to consumer usage */
#define KEYCODE2CONSUMER(key) \
(key == KC_AUDIO_MUTE ? AUDIO_MUTE : \
(key == KC_AUDIO_VOL_UP ? AUDIO_VOL_UP : \
(key == KC_AUDIO_VOL_DOWN ? AUDIO_VOL_DOWN : \
(key == KC_MEDIA_NEXT_TRACK ? TRANSPORT_NEXT_TRACK : \
(key == KC_MEDIA_PREV_TRACK ? TRANSPORT_PREV_TRACK : \
(key == KC_MEDIA_FAST_FORWARD ? TRANSPORT_FAST_FORWARD : \
(key == KC_MEDIA_REWIND ? TRANSPORT_REWIND : \
(key == KC_MEDIA_STOP ? TRANSPORT_STOP : \
(key == KC_MEDIA_EJECT ? TRANSPORT_STOP_EJECT : \
(key == KC_MEDIA_PLAY_PAUSE ? TRANSPORT_PLAY_PAUSE : \
(key == KC_MEDIA_SELECT ? AL_CC_CONFIG : \
(key == KC_MAIL ? AL_EMAIL : \
(key == KC_CALCULATOR ? AL_CALCULATOR : \
(key == KC_MY_COMPUTER ? AL_LOCAL_BROWSER : \
(key == KC_WWW_SEARCH ? AC_SEARCH : \
(key == KC_WWW_HOME ? AC_HOME : \
(key == KC_WWW_BACK ? AC_BACK : \
(key == KC_WWW_FORWARD ? AC_FORWARD : \
(key == KC_WWW_STOP ? AC_STOP : \
(key == KC_WWW_REFRESH ? AC_REFRESH : \
(key == KC_BRIGHTNESS_UP ? BRIGHTNESS_UP : \
(key == KC_BRIGHTNESS_DOWN ? BRIGHTNESS_DOWN : \
(key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0)))))))))))))))))))))))
(key == KC_AUDIO_MUTE ? AUDIO_MUTE : (key == KC_AUDIO_VOL_UP ? AUDIO_VOL_UP : (key == KC_AUDIO_VOL_DOWN ? AUDIO_VOL_DOWN : (key == KC_MEDIA_NEXT_TRACK ? TRANSPORT_NEXT_TRACK : (key == KC_MEDIA_PREV_TRACK ? TRANSPORT_PREV_TRACK : (key == KC_MEDIA_FAST_FORWARD ? TRANSPORT_FAST_FORWARD : (key == KC_MEDIA_REWIND ? TRANSPORT_REWIND : (key == KC_MEDIA_STOP ? TRANSPORT_STOP : (key == KC_MEDIA_EJECT ? TRANSPORT_STOP_EJECT : (key == KC_MEDIA_PLAY_PAUSE ? TRANSPORT_PLAY_PAUSE : (key == KC_MEDIA_SELECT ? AL_CC_CONFIG : (key == KC_MAIL ? AL_EMAIL : (key == KC_CALCULATOR ? AL_CALCULATOR : (key == KC_MY_COMPUTER ? AL_LOCAL_BROWSER : (key == KC_WWW_SEARCH ? AC_SEARCH : (key == KC_WWW_HOME ? AC_HOME : (key == KC_WWW_BACK ? AC_BACK : (key == KC_WWW_FORWARD ? AC_FORWARD : (key == KC_WWW_STOP ? AC_STOP : (key == KC_WWW_REFRESH ? AC_REFRESH : (key == KC_BRIGHTNESS_UP ? BRIGHTNESS_UP : (key == KC_BRIGHTNESS_DOWN ? BRIGHTNESS_DOWN : (key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0)))))))))))))))))))))))
uint8_t has_anykey(report_keyboard_t* keyboard_report);
uint8_t get_first_key(report_keyboard_t* keyboard_report);

View file

@ -20,7 +20,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif

View file

@ -16,8 +16,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "sendchar.h"
int8_t sendchar(uint8_t c)
{
return 0;
}
int8_t sendchar(uint8_t c) { return 0; }

View file

@ -17,9 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "uart.h"
#include "sendchar.h"
int8_t sendchar(uint8_t c)
{
int8_t sendchar(uint8_t c) {
uart_putchar(c);
return 0;
}

View file

@ -1,7 +1,6 @@
#ifndef SLEEP_LED_H
#define SLEEP_LED_H
#ifdef SLEEP_LED_ENABLE
void sleep_led_init(void);
@ -11,10 +10,10 @@ void sleep_led_toggle(void);
#else
#define sleep_led_init()
#define sleep_led_enable()
#define sleep_led_disable()
#define sleep_led_toggle()
# define sleep_led_init()
# define sleep_led_enable()
# define sleep_led_disable()
# define sleep_led_toggle()
#endif

View file

@ -4,7 +4,6 @@
#include <stdint.h>
#include <stdbool.h>
void suspend_idle(uint8_t timeout);
void suspend_power_down(void);
bool suspend_wakeup_condition(void);
@ -12,7 +11,7 @@ void suspend_wakeup_init(void);
void suspend_wakeup_init_user(void);
void suspend_wakeup_init_kb(void);
void suspend_power_down_user (void);
void suspend_power_down_user(void);
void suspend_power_down_kb(void);
#endif

View file

@ -21,78 +21,75 @@
static uint8_t buffer[EEPROM_SIZE];
uint8_t eeprom_read_byte(const uint8_t *addr) {
uintptr_t offset = (uintptr_t)addr;
return buffer[offset];
uintptr_t offset = (uintptr_t)addr;
return buffer[offset];
}
void eeprom_write_byte(uint8_t *addr, uint8_t value) {
uintptr_t offset = (uintptr_t)addr;
buffer[offset] = value;
uintptr_t offset = (uintptr_t)addr;
buffer[offset] = value;
}
uint16_t eeprom_read_word(const uint16_t *addr) {
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8);
}
uint32_t eeprom_read_dword(const uint32_t *addr) {
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
| (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
const uint8_t *p = (const uint8_t *)addr;
return eeprom_read_byte(p) | (eeprom_read_byte(p + 1) << 8) | (eeprom_read_byte(p + 2) << 16) | (eeprom_read_byte(p + 3) << 24);
}
void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
const uint8_t *p = (const uint8_t *)addr;
uint8_t *dest = (uint8_t *)buf;
while (len--) {
*dest++ = eeprom_read_byte(p++);
}
const uint8_t *p = (const uint8_t *)addr;
uint8_t * dest = (uint8_t *)buf;
while (len--) {
*dest++ = eeprom_read_byte(p++);
}
}
void eeprom_write_word(uint16_t *addr, uint16_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
}
void eeprom_write_dword(uint32_t *addr, uint32_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
}
void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
uint8_t *p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
uint8_t * p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
}
void eeprom_update_byte(uint8_t *addr, uint8_t value) {
eeprom_write_byte(addr, value);
}
void eeprom_update_byte(uint8_t *addr, uint8_t value) { eeprom_write_byte(addr, value); }
void eeprom_update_word(uint16_t *addr, uint16_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p, value >> 8);
}
void eeprom_update_dword(uint32_t *addr, uint32_t value) {
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
uint8_t *p = (uint8_t *)addr;
eeprom_write_byte(p++, value);
eeprom_write_byte(p++, value >> 8);
eeprom_write_byte(p++, value >> 16);
eeprom_write_byte(p, value >> 24);
}
void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
uint8_t *p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
uint8_t * p = (uint8_t *)addr;
const uint8_t *src = (const uint8_t *)buf;
while (len--) {
eeprom_write_byte(p++, *src++);
}
}

View file

@ -13,5 +13,3 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

View file

@ -18,9 +18,9 @@
static uint32_t current_time = 0;
void timer_init(void) {current_time = 0;}
void timer_init(void) { current_time = 0; }
void timer_clear(void) {current_time = 0;}
void timer_clear(void) { current_time = 0; }
uint16_t timer_read(void) { return current_time & 0xFFFF; }
uint32_t timer_read32(void) { return current_time; }
@ -30,6 +30,4 @@ uint32_t timer_elapsed32(uint32_t last) { return TIMER_DIFF_32(timer_read32(), l
void set_time(uint32_t t) { current_time = t; }
void advance_time(uint32_t ms) { current_time += ms; }
void wait_ms(uint32_t ms) {
advance_time(ms);
}
void wait_ms(uint32_t ms) { advance_time(ms); }

View file

@ -22,16 +22,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdbool.h>
#if defined(__AVR__)
#include "avr/timer_avr.h"
# include "avr/timer_avr.h"
#endif
#define TIMER_DIFF(a, b, max) ((a) >= (b) ? (a) - (b) : (max) - (b) + (a))
#define TIMER_DIFF_8(a, b) TIMER_DIFF(a, b, UINT8_MAX)
#define TIMER_DIFF_16(a, b) TIMER_DIFF(a, b, UINT16_MAX)
#define TIMER_DIFF_32(a, b) TIMER_DIFF(a, b, UINT32_MAX)
#define TIMER_DIFF_RAW(a, b) TIMER_DIFF_8(a, b)
#define TIMER_DIFF(a, b, max) ((a) >= (b) ? (a) - (b) : (max) - (b) + (a))
#define TIMER_DIFF_8(a, b) TIMER_DIFF(a, b, UINT8_MAX)
#define TIMER_DIFF_16(a, b) TIMER_DIFF(a, b, UINT16_MAX)
#define TIMER_DIFF_32(a, b) TIMER_DIFF(a, b, UINT32_MAX)
#define TIMER_DIFF_RAW(a, b) TIMER_DIFF_8(a, b)
#ifdef __cplusplus
extern "C" {
@ -39,23 +37,17 @@ extern "C" {
extern volatile uint32_t timer_count;
void timer_init(void);
void timer_clear(void);
void timer_init(void);
void timer_clear(void);
uint16_t timer_read(void);
uint32_t timer_read32(void);
uint16_t timer_elapsed(uint16_t last);
uint32_t timer_elapsed32(uint32_t last);
// Utility functions to check if a future time has expired & autmatically handle time wrapping if checked / reset frequently (half of max value)
inline bool timer_expired(uint16_t current, uint16_t last)
{
return current - last < 0x8000;
}
inline bool timer_expired(uint16_t current, uint16_t last) { return current - last < 0x8000; }
inline bool timer_expired32(uint32_t current, uint32_t future) {
return current - future < 0x80000000;
}
inline bool timer_expired32(uint32_t current, uint32_t future) { return current - future < 0x80000000; }
#ifdef __cplusplus
}

View file

@ -3,17 +3,17 @@
/* UART Example for Teensy USB Development Board
* http://www.pjrc.com/teensy/
* Copyright (c) 2009 PJRC.COM, LLC
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
@ -26,7 +26,6 @@
// Version 1.0: Initial Release
// Version 1.1: Add support for Teensy 2.0, minor optimizations
#include <avr/io.h>
#include <avr/interrupt.h>
@ -44,86 +43,81 @@ static volatile uint8_t rx_buffer_head;
static volatile uint8_t rx_buffer_tail;
// Initialize the UART
void uart_init(uint32_t baud)
{
cli();
UBRR0 = (F_CPU / 4 / baud - 1) / 2;
UCSR0A = (1<<U2X0);
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
tx_buffer_head = tx_buffer_tail = 0;
rx_buffer_head = rx_buffer_tail = 0;
sei();
void uart_init(uint32_t baud) {
cli();
UBRR0 = (F_CPU / 4 / baud - 1) / 2;
UCSR0A = (1 << U2X0);
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
tx_buffer_head = tx_buffer_tail = 0;
rx_buffer_head = rx_buffer_tail = 0;
sei();
}
// Transmit a byte
void uart_putchar(uint8_t c)
{
uint8_t i;
void uart_putchar(uint8_t c) {
uint8_t i;
i = tx_buffer_head + 1;
if (i >= TX_BUFFER_SIZE) i = 0;
while (tx_buffer_tail == i) ; // wait until space in buffer
//cli();
tx_buffer[i] = c;
tx_buffer_head = i;
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (1<<UDRIE0);
//sei();
i = tx_buffer_head + 1;
if (i >= TX_BUFFER_SIZE) i = 0;
while (tx_buffer_tail == i)
; // wait until space in buffer
// cli();
tx_buffer[i] = c;
tx_buffer_head = i;
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0) | (1 << UDRIE0);
// sei();
}
// Receive a byte
uint8_t uart_getchar(void)
{
uint8_t c, i;
uint8_t uart_getchar(void) {
uint8_t c, i;
while (rx_buffer_head == rx_buffer_tail) ; // wait for character
i = rx_buffer_tail + 1;
if (i >= RX_BUFFER_SIZE) i = 0;
c = rx_buffer[i];
rx_buffer_tail = i;
return c;
while (rx_buffer_head == rx_buffer_tail)
; // wait for character
i = rx_buffer_tail + 1;
if (i >= RX_BUFFER_SIZE) i = 0;
c = rx_buffer[i];
rx_buffer_tail = i;
return c;
}
// Return the number of bytes waiting in the receive buffer.
// Call this before uart_getchar() to check if it will need
// to wait for a byte to arrive.
uint8_t uart_available(void)
{
uint8_t head, tail;
uint8_t uart_available(void) {
uint8_t head, tail;
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head >= tail) return head - tail;
return RX_BUFFER_SIZE + head - tail;
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head >= tail) return head - tail;
return RX_BUFFER_SIZE + head - tail;
}
// Transmit Interrupt
ISR(USART_UDRE_vect)
{
uint8_t i;
ISR(USART_UDRE_vect) {
uint8_t i;
if (tx_buffer_head == tx_buffer_tail) {
// buffer is empty, disable transmit interrupt
UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0);
} else {
i = tx_buffer_tail + 1;
if (i >= TX_BUFFER_SIZE) i = 0;
UDR0 = tx_buffer[i];
tx_buffer_tail = i;
}
if (tx_buffer_head == tx_buffer_tail) {
// buffer is empty, disable transmit interrupt
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
} else {
i = tx_buffer_tail + 1;
if (i >= TX_BUFFER_SIZE) i = 0;
UDR0 = tx_buffer[i];
tx_buffer_tail = i;
}
}
// Receive Interrupt
ISR(USART_RX_vect)
{
uint8_t c, i;
ISR(USART_RX_vect) {
uint8_t c, i;
c = UDR0;
i = rx_buffer_head + 1;
if (i >= RX_BUFFER_SIZE) i = 0;
if (i != rx_buffer_tail) {
rx_buffer[i] = c;
rx_buffer_head = i;
}
c = UDR0;
i = rx_buffer_head + 1;
if (i >= RX_BUFFER_SIZE) i = 0;
if (i != rx_buffer_tail) {
rx_buffer[i] = c;
rx_buffer_head = i;
}
}

View file

@ -3,8 +3,8 @@
#include <stdint.h>
void uart_init(uint32_t baud);
void uart_putchar(uint8_t c);
void uart_init(uint32_t baud);
void uart_putchar(uint8_t c);
uint8_t uart_getchar(void);
uint8_t uart_available(void);

View file

@ -18,84 +18,106 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "util.h"
// bit population - return number of on-bit
uint8_t bitpop(uint8_t bits)
{
uint8_t bitpop(uint8_t bits) {
uint8_t c;
for (c = 0; bits; c++)
bits &= bits - 1;
for (c = 0; bits; c++) bits &= bits - 1;
return c;
/*
const uint8_t bit_count[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
return bit_count[bits>>4] + bit_count[bits&0x0F]
*/
/*
const uint8_t bit_count[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
return bit_count[bits>>4] + bit_count[bits&0x0F]
*/
}
uint8_t bitpop16(uint16_t bits)
{
uint8_t bitpop16(uint16_t bits) {
uint8_t c;
for (c = 0; bits; c++)
bits &= bits - 1;
for (c = 0; bits; c++) bits &= bits - 1;
return c;
}
uint8_t bitpop32(uint32_t bits)
{
uint8_t bitpop32(uint32_t bits) {
uint8_t c;
for (c = 0; bits; c++)
bits &= bits - 1;
for (c = 0; bits; c++) bits &= bits - 1;
return c;
}
// most significant on-bit - return highest location of on-bit
// NOTE: return 0 when bit0 is on or all bits are off
uint8_t biton(uint8_t bits)
{
uint8_t biton(uint8_t bits) {
uint8_t n = 0;
if (bits >> 4) { bits >>= 4; n += 4;}
if (bits >> 2) { bits >>= 2; n += 2;}
if (bits >> 1) { bits >>= 1; n += 1;}
if (bits >> 4) {
bits >>= 4;
n += 4;
}
if (bits >> 2) {
bits >>= 2;
n += 2;
}
if (bits >> 1) {
bits >>= 1;
n += 1;
}
return n;
}
uint8_t biton16(uint16_t bits)
{
uint8_t biton16(uint16_t bits) {
uint8_t n = 0;
if (bits >> 8) { bits >>= 8; n += 8;}
if (bits >> 4) { bits >>= 4; n += 4;}
if (bits >> 2) { bits >>= 2; n += 2;}
if (bits >> 1) { bits >>= 1; n += 1;}
if (bits >> 8) {
bits >>= 8;
n += 8;
}
if (bits >> 4) {
bits >>= 4;
n += 4;
}
if (bits >> 2) {
bits >>= 2;
n += 2;
}
if (bits >> 1) {
bits >>= 1;
n += 1;
}
return n;
}
uint8_t biton32(uint32_t bits)
{
uint8_t biton32(uint32_t bits) {
uint8_t n = 0;
if (bits >>16) { bits >>=16; n +=16;}
if (bits >> 8) { bits >>= 8; n += 8;}
if (bits >> 4) { bits >>= 4; n += 4;}
if (bits >> 2) { bits >>= 2; n += 2;}
if (bits >> 1) { bits >>= 1; n += 1;}
if (bits >> 16) {
bits >>= 16;
n += 16;
}
if (bits >> 8) {
bits >>= 8;
n += 8;
}
if (bits >> 4) {
bits >>= 4;
n += 4;
}
if (bits >> 2) {
bits >>= 2;
n += 2;
}
if (bits >> 1) {
bits >>= 1;
n += 1;
}
return n;
}
uint8_t bitrev(uint8_t bits)
{
bits = (bits & 0x0f)<<4 | (bits & 0xf0)>>4;
bits = (bits & 0b00110011)<<2 | (bits & 0b11001100)>>2;
bits = (bits & 0b01010101)<<1 | (bits & 0b10101010)>>1;
uint8_t bitrev(uint8_t bits) {
bits = (bits & 0x0f) << 4 | (bits & 0xf0) >> 4;
bits = (bits & 0b00110011) << 2 | (bits & 0b11001100) >> 2;
bits = (bits & 0b01010101) << 1 | (bits & 0b10101010) >> 1;
return bits;
}
uint16_t bitrev16(uint16_t bits)
{
bits = bitrev(bits & 0x00ff)<<8 | bitrev((bits & 0xff00)>>8);
uint16_t bitrev16(uint16_t bits) {
bits = bitrev(bits & 0x00ff) << 8 | bitrev((bits & 0xff00) >> 8);
return bits;
}
uint32_t bitrev32(uint32_t bits)
{
bits = (uint32_t)bitrev16(bits & 0x0000ffff)<<16 | bitrev16((bits & 0xffff0000)>>16);
uint32_t bitrev32(uint32_t bits) {
bits = (uint32_t)bitrev16(bits & 0x0000ffff) << 16 | bitrev16((bits & 0xffff0000) >> 16);
return bits;
}

View file

@ -22,12 +22,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// convert to L string
#define LSTR(s) XLSTR(s)
#define XLSTR(s) L ## #s
#define XLSTR(s) L## #s
// convert to string
#define STR(s) XSTR(s)
#define XSTR(s) #s
uint8_t bitpop(uint8_t bits);
uint8_t bitpop16(uint16_t bits);
uint8_t bitpop32(uint32_t bits);

View file

@ -8,22 +8,36 @@ extern "C" {
#endif
#if defined(__AVR__)
# include <util/delay.h>
# define wait_ms(ms) _delay_ms(ms)
# define wait_us(us) _delay_us(us)
# include <util/delay.h>
# define wait_ms(ms) _delay_ms(ms)
# define wait_us(us) _delay_us(us)
#elif defined PROTOCOL_CHIBIOS
# include "ch.h"
# define wait_ms(ms) do { if (ms != 0) { chThdSleepMilliseconds(ms); } else { chThdSleepMicroseconds(1); } } while (0)
# define wait_us(us) do { if (us != 0) { chThdSleepMicroseconds(us); } else { chThdSleepMicroseconds(1); } } while (0)
# include "ch.h"
# define wait_ms(ms) \
do { \
if (ms != 0) { \
chThdSleepMilliseconds(ms); \
} else { \
chThdSleepMicroseconds(1); \
} \
} while (0)
# define wait_us(us) \
do { \
if (us != 0) { \
chThdSleepMicroseconds(us); \
} else { \
chThdSleepMicroseconds(1); \
} \
} while (0)
#elif defined PROTOCOL_ARM_ATSAM
# include "clks.h"
# define wait_ms(ms) CLK_delay_ms(ms)
# define wait_us(us) CLK_delay_us(us)
# include "clks.h"
# define wait_ms(ms) CLK_delay_ms(ms)
# define wait_us(us) CLK_delay_us(us)
#elif defined(__arm__)
# include "wait_api.h"
# include "wait_api.h"
#else // Unit tests
void wait_ms(uint32_t ms);
#define wait_us(us) wait_ms(us / 1000)
# define wait_us(us) wait_ms(us / 1000)
#endif
#ifdef __cplusplus

View file

@ -42,11 +42,10 @@ POSSIBILITY OF SUCH DAMAGE.
#include <avr/interrupt.h>
#include "adb.h"
// GCC doesn't inline functions normally
#define data_lo() (ADB_DDR |= (1<<ADB_DATA_BIT))
#define data_hi() (ADB_DDR &= ~(1<<ADB_DATA_BIT))
#define data_in() (ADB_PIN & (1<<ADB_DATA_BIT))
#define data_lo() (ADB_DDR |= (1 << ADB_DATA_BIT))
#define data_hi() (ADB_DDR &= ~(1 << ADB_DATA_BIT))
#define data_in() (ADB_PIN & (1 << ADB_DATA_BIT))
#ifdef ADB_PSW_BIT
static inline void psw_lo(void);
@ -54,18 +53,16 @@ static inline void psw_hi(void);
static inline bool psw_in(void);
#endif
static inline void attention(void);
static inline void place_bit0(void);
static inline void place_bit1(void);
static inline void send_byte(uint8_t data);
static inline void attention(void);
static inline void place_bit0(void);
static inline void place_bit1(void);
static inline void send_byte(uint8_t data);
static inline uint16_t wait_data_lo(uint16_t us);
static inline uint16_t wait_data_hi(uint16_t us);
static inline uint16_t adb_host_dev_recv(uint8_t device);
void adb_host_init(void)
{
ADB_PORT &= ~(1<<ADB_DATA_BIT);
void adb_host_init(void) {
ADB_PORT &= ~(1 << ADB_DATA_BIT);
data_hi();
#ifdef ADB_PSW_BIT
psw_hi();
@ -73,10 +70,7 @@ void adb_host_init(void)
}
#ifdef ADB_PSW_BIT
bool adb_host_psw(void)
{
return psw_in();
}
bool adb_host_psw(void) { return psw_in(); }
#endif
/*
@ -105,11 +99,11 @@ bool adb_host_psw(void)
// bit0:
// 70us bit cell:
// ____________~~~~~~
// 42-49 21-28
// 42-49 21-28
//
// 130us bit cell:
// ____________~~~~~~
// 78-91 39-52
// 78-91 39-52
//
// bit1:
// 70us bit cell:
@ -122,66 +116,50 @@ bool adb_host_psw(void)
//
// [from Apple IIgs Hardware Reference Second Edition]
enum {
ADDR_KEYB = 0x20,
ADDR_MOUSE = 0x30
};
enum { ADDR_KEYB = 0x20, ADDR_MOUSE = 0x30 };
uint16_t adb_host_kbd_recv(void)
{
return adb_host_dev_recv(ADDR_KEYB);
}
uint16_t adb_host_kbd_recv(void) { return adb_host_dev_recv(ADDR_KEYB); }
#ifdef ADB_MOUSE_ENABLE
void adb_mouse_init(void) {
return;
}
void adb_mouse_init(void) { return; }
uint16_t adb_host_mouse_recv(void)
{
return adb_host_dev_recv(ADDR_MOUSE);
}
uint16_t adb_host_mouse_recv(void) { return adb_host_dev_recv(ADDR_MOUSE); }
#endif
static inline uint16_t adb_host_dev_recv(uint8_t device)
{
static inline uint16_t adb_host_dev_recv(uint8_t device) {
uint16_t data = 0;
cli();
attention();
send_byte(device|0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00)
place_bit0(); // Stopbit(0)
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
send_byte(device | 0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00)
place_bit0(); // Stopbit(0)
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
sei();
return -30; // something wrong
return -30; // something wrong
}
if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
sei();
return 0; // No data to send
return 0; // No data to send
}
uint8_t n = 17; // start bit + 16 data bits
uint8_t n = 17; // start bit + 16 data bits
do {
uint8_t lo = (uint8_t) wait_data_hi(130);
if (!lo)
goto error;
uint8_t hi = (uint8_t) wait_data_lo(lo);
if (!hi)
goto error;
uint8_t lo = (uint8_t)wait_data_hi(130);
if (!lo) goto error;
uint8_t hi = (uint8_t)wait_data_lo(lo);
if (!hi) goto error;
hi = lo - hi;
lo = 130 - lo;
data <<= 1;
if (lo < hi) {
data |= 1;
}
else if (n == 17) {
} else if (n == 17) {
sei();
return -20;
}
}
while ( --n );
} while (--n);
// Stop bit can't be checked normally since it could have service request lenghtening
// and its high state never goes low.
@ -197,76 +175,66 @@ error:
return -n;
}
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l)
{
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l) {
cli();
attention();
send_byte(cmd);
place_bit0(); // Stopbit(0)
_delay_us(200); // Tlt/Stop to Start
place_bit1(); // Startbit(1)
send_byte(data_h);
place_bit0(); // Stopbit(0)
_delay_us(200); // Tlt/Stop to Start
place_bit1(); // Startbit(1)
send_byte(data_h);
send_byte(data_l);
place_bit0(); // Stopbit(0);
place_bit0(); // Stopbit(0);
sei();
}
// send state of LEDs
void adb_host_kbd_led(uint8_t led)
{
void adb_host_kbd_led(uint8_t led) {
// Addr:Keyboard(0010), Cmd:Listen(10), Register2(10)
// send upper byte (not used)
// send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0:
adb_host_listen(0x2A,0,led&0x07);
adb_host_listen(0x2A, 0, led & 0x07);
}
#ifdef ADB_PSW_BIT
static inline void psw_lo()
{
ADB_DDR |= (1<<ADB_PSW_BIT);
ADB_PORT &= ~(1<<ADB_PSW_BIT);
static inline void psw_lo() {
ADB_DDR |= (1 << ADB_PSW_BIT);
ADB_PORT &= ~(1 << ADB_PSW_BIT);
}
static inline void psw_hi()
{
ADB_PORT |= (1<<ADB_PSW_BIT);
ADB_DDR &= ~(1<<ADB_PSW_BIT);
static inline void psw_hi() {
ADB_PORT |= (1 << ADB_PSW_BIT);
ADB_DDR &= ~(1 << ADB_PSW_BIT);
}
static inline bool psw_in()
{
ADB_PORT |= (1<<ADB_PSW_BIT);
ADB_DDR &= ~(1<<ADB_PSW_BIT);
return ADB_PIN&(1<<ADB_PSW_BIT);
static inline bool psw_in() {
ADB_PORT |= (1 << ADB_PSW_BIT);
ADB_DDR &= ~(1 << ADB_PSW_BIT);
return ADB_PIN & (1 << ADB_PSW_BIT);
}
#endif
static inline void attention(void)
{
static inline void attention(void) {
data_lo();
_delay_us(800-35); // bit1 holds lo for 35 more
_delay_us(800 - 35); // bit1 holds lo for 35 more
place_bit1();
}
static inline void place_bit0(void)
{
static inline void place_bit0(void) {
data_lo();
_delay_us(65);
data_hi();
_delay_us(35);
}
static inline void place_bit1(void)
{
static inline void place_bit1(void) {
data_lo();
_delay_us(35);
data_hi();
_delay_us(65);
}
static inline void send_byte(uint8_t data)
{
static inline void send_byte(uint8_t data) {
for (int i = 0; i < 8; i++) {
if (data&(0x80>>i))
if (data & (0x80 >> i))
place_bit1();
else
place_bit0();
@ -275,29 +243,22 @@ static inline void send_byte(uint8_t data)
// These are carefully coded to take 6 cycles of overhead.
// inline asm approach became too convoluted
static inline uint16_t wait_data_lo(uint16_t us)
{
static inline uint16_t wait_data_lo(uint16_t us) {
do {
if ( !data_in() )
break;
if (!data_in()) break;
_delay_us(1 - (6 * 1000000.0 / F_CPU));
}
while ( --us );
} while (--us);
return us;
}
static inline uint16_t wait_data_hi(uint16_t us)
{
static inline uint16_t wait_data_hi(uint16_t us) {
do {
if ( data_in() )
break;
if (data_in()) break;
_delay_us(1 - (6 * 1000000.0 / F_CPU));
}
while ( --us );
} while (--us);
return us;
}
/*
ADB Protocol
============
@ -375,7 +336,7 @@ Commands
A A A A 1 1 R R Talk(read from a device)
The command to read keycodes from keyboard is 0x2C which
consist of keyboard address 2 and Talk against register 0.
consist of keyboard address 2 and Talk against register 0.
Address:
2: keyboard
@ -457,7 +418,7 @@ Keyboard Data(Register0)
Keyboard LEDs & state of keys(Register2)
This register hold current state of three LEDs and nine keys.
The state of LEDs can be changed by sending Listen command.
1514 . . . . . . 7 6 5 . 3 2 1 0
| | | | | | | | | | | | | | | +- LED1(NumLock)
| | | | | | | | | | | | | | +--- LED2(CapsLock)

View file

@ -41,16 +41,12 @@ POSSIBILITY OF SUCH DAMAGE.
#include <stdint.h>
#include <stdbool.h>
#if !(defined(ADB_PORT) && \
defined(ADB_PIN) && \
defined(ADB_DDR) && \
defined(ADB_DATA_BIT))
# error "ADB port setting is required in config.h"
#if !(defined(ADB_PORT) && defined(ADB_PIN) && defined(ADB_DDR) && defined(ADB_DATA_BIT))
# error "ADB port setting is required in config.h"
#endif
#define ADB_POWER 0x7F
#define ADB_CAPS 0x39
#define ADB_POWER 0x7F
#define ADB_CAPS 0x39
// ADB host
void adb_host_init(void);
@ -62,5 +58,4 @@ void adb_host_kbd_led(uint8_t led);
void adb_mouse_task(void);
void adb_mouse_init(void);
#endif

View file

@ -24,76 +24,92 @@ uint16_t v_con_2;
uint16_t v_con_1_boot;
uint16_t v_con_2_boot;
void ADC0_clock_init(void)
{
void ADC0_clock_init(void) {
DBGC(DC_ADC0_CLOCK_INIT_BEGIN);
MCLK->APBDMASK.bit.ADC0_ = 1; //ADC0 Clock Enable
MCLK->APBDMASK.bit.ADC0_ = 1; // ADC0 Clock Enable
GCLK->PCHCTRL[ADC0_GCLK_ID].bit.GEN = GEN_OSC0; //Select generator clock
GCLK->PCHCTRL[ADC0_GCLK_ID].bit.CHEN = 1; //Enable peripheral clock
GCLK->PCHCTRL[ADC0_GCLK_ID].bit.GEN = GEN_OSC0; // Select generator clock
GCLK->PCHCTRL[ADC0_GCLK_ID].bit.CHEN = 1; // Enable peripheral clock
DBGC(DC_ADC0_CLOCK_INIT_COMPLETE);
}
void ADC0_init(void)
{
void ADC0_init(void) {
DBGC(DC_ADC0_INIT_BEGIN);
//MCU
PORT->Group[1].DIRCLR.reg = 1 << 0; //PB00 as input 5V
PORT->Group[1].DIRCLR.reg = 1 << 1; //PB01 as input CON2
PORT->Group[1].DIRCLR.reg = 1 << 2; //PB02 as input CON1
PORT->Group[1].PMUX[0].bit.PMUXE = 1; //PB00 mux select B ADC 5V
PORT->Group[1].PMUX[0].bit.PMUXO = 1; //PB01 mux select B ADC CON2
PORT->Group[1].PMUX[1].bit.PMUXE = 1; //PB02 mux select B ADC CON1
PORT->Group[1].PINCFG[0].bit.PMUXEN = 1; //PB01 mux ADC Enable 5V
PORT->Group[1].PINCFG[1].bit.PMUXEN = 1; //PB01 mux ADC Enable CON2
PORT->Group[1].PINCFG[2].bit.PMUXEN = 1; //PB02 mux ADC Enable CON1
// MCU
PORT->Group[1].DIRCLR.reg = 1 << 0; // PB00 as input 5V
PORT->Group[1].DIRCLR.reg = 1 << 1; // PB01 as input CON2
PORT->Group[1].DIRCLR.reg = 1 << 2; // PB02 as input CON1
PORT->Group[1].PMUX[0].bit.PMUXE = 1; // PB00 mux select B ADC 5V
PORT->Group[1].PMUX[0].bit.PMUXO = 1; // PB01 mux select B ADC CON2
PORT->Group[1].PMUX[1].bit.PMUXE = 1; // PB02 mux select B ADC CON1
PORT->Group[1].PINCFG[0].bit.PMUXEN = 1; // PB01 mux ADC Enable 5V
PORT->Group[1].PINCFG[1].bit.PMUXEN = 1; // PB01 mux ADC Enable CON2
PORT->Group[1].PINCFG[2].bit.PMUXEN = 1; // PB02 mux ADC Enable CON1
//ADC
// ADC
ADC0->CTRLA.bit.SWRST = 1;
while (ADC0->SYNCBUSY.bit.SWRST) { DBGC(DC_ADC0_SWRST_SYNCING_1); }
while (ADC0->CTRLA.bit.SWRST) { DBGC(DC_ADC0_SWRST_SYNCING_2); }
while (ADC0->SYNCBUSY.bit.SWRST) {
DBGC(DC_ADC0_SWRST_SYNCING_1);
}
while (ADC0->CTRLA.bit.SWRST) {
DBGC(DC_ADC0_SWRST_SYNCING_2);
}
//Clock divide
// Clock divide
ADC0->CTRLA.bit.PRESCALER = ADC_CTRLA_PRESCALER_DIV2_Val;
//Averaging
// Averaging
ADC0->AVGCTRL.bit.SAMPLENUM = ADC_AVGCTRL_SAMPLENUM_4_Val;
while (ADC0->SYNCBUSY.bit.AVGCTRL) { DBGC(DC_ADC0_AVGCTRL_SYNCING_1); }
if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_1_Val) ADC0->AVGCTRL.bit.ADJRES = 0;
else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_2_Val) ADC0->AVGCTRL.bit.ADJRES = 1;
else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_4_Val) ADC0->AVGCTRL.bit.ADJRES = 2;
else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_8_Val) ADC0->AVGCTRL.bit.ADJRES = 3;
else ADC0->AVGCTRL.bit.ADJRES = 4;
while (ADC0->SYNCBUSY.bit.AVGCTRL) { DBGC(DC_ADC0_AVGCTRL_SYNCING_2); }
while (ADC0->SYNCBUSY.bit.AVGCTRL) {
DBGC(DC_ADC0_AVGCTRL_SYNCING_1);
}
if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_1_Val)
ADC0->AVGCTRL.bit.ADJRES = 0;
else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_2_Val)
ADC0->AVGCTRL.bit.ADJRES = 1;
else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_4_Val)
ADC0->AVGCTRL.bit.ADJRES = 2;
else if (ADC0->AVGCTRL.bit.SAMPLENUM == ADC_AVGCTRL_SAMPLENUM_8_Val)
ADC0->AVGCTRL.bit.ADJRES = 3;
else
ADC0->AVGCTRL.bit.ADJRES = 4;
while (ADC0->SYNCBUSY.bit.AVGCTRL) {
DBGC(DC_ADC0_AVGCTRL_SYNCING_2);
}
//Settling
ADC0->SAMPCTRL.bit.SAMPLEN = 45; //Sampling Time Length: 1-63, 1 ADC CLK per
while (ADC0->SYNCBUSY.bit.SAMPCTRL) { DBGC(DC_ADC0_SAMPCTRL_SYNCING_1); }
// Settling
ADC0->SAMPCTRL.bit.SAMPLEN = 45; // Sampling Time Length: 1-63, 1 ADC CLK per
while (ADC0->SYNCBUSY.bit.SAMPCTRL) {
DBGC(DC_ADC0_SAMPCTRL_SYNCING_1);
}
//Load factory calibration data
ADC0->CALIB.bit.BIASCOMP = ((*(uint32_t *)ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos;
ADC0->CALIB.bit.BIASR2R = ((*(uint32_t *)ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos;
// Load factory calibration data
ADC0->CALIB.bit.BIASCOMP = ((*(uint32_t *)ADC0_FUSES_BIASCOMP_ADDR) & ADC0_FUSES_BIASCOMP_Msk) >> ADC0_FUSES_BIASCOMP_Pos;
ADC0->CALIB.bit.BIASR2R = ((*(uint32_t *)ADC0_FUSES_BIASR2R_ADDR) & ADC0_FUSES_BIASR2R_Msk) >> ADC0_FUSES_BIASR2R_Pos;
ADC0->CALIB.bit.BIASREFBUF = ((*(uint32_t *)ADC0_FUSES_BIASREFBUF_ADDR) & ADC0_FUSES_BIASREFBUF_Msk) >> ADC0_FUSES_BIASREFBUF_Pos;
//Enable
// Enable
ADC0->CTRLA.bit.ENABLE = 1;
while (ADC0->SYNCBUSY.bit.ENABLE) { DBGC(DC_ADC0_ENABLE_SYNCING_1); }
while (ADC0->SYNCBUSY.bit.ENABLE) {
DBGC(DC_ADC0_ENABLE_SYNCING_1);
}
DBGC(DC_ADC0_INIT_COMPLETE);
}
uint16_t adc_get(uint8_t muxpos)
{
uint16_t adc_get(uint8_t muxpos) {
ADC0->INPUTCTRL.bit.MUXPOS = muxpos;
while (ADC0->SYNCBUSY.bit.INPUTCTRL) {}
while (ADC0->SYNCBUSY.bit.INPUTCTRL) {
}
ADC0->SWTRIG.bit.START = 1;
while (ADC0->SYNCBUSY.bit.SWTRIG) {}
while (!ADC0->INTFLAG.bit.RESRDY) {}
while (ADC0->SYNCBUSY.bit.SWTRIG) {
}
while (!ADC0->INTFLAG.bit.RESRDY) {
}
return ADC0->RESULT.reg;
}

View file

@ -18,11 +18,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef _ADC_H_
#define _ADC_H_
#define ADC_5V_START_LEVEL 2365
#define ADC_5V_START_LEVEL 2365
#define ADC_5V ADC_INPUTCTRL_MUXPOS_AIN12_Val
#define ADC_CON1 ADC_INPUTCTRL_MUXPOS_AIN14_Val
#define ADC_CON2 ADC_INPUTCTRL_MUXPOS_AIN13_Val
#define ADC_5V ADC_INPUTCTRL_MUXPOS_AIN12_Val
#define ADC_CON1 ADC_INPUTCTRL_MUXPOS_AIN14_Val
#define ADC_CON2 ADC_INPUTCTRL_MUXPOS_AIN13_Val
extern uint16_t v_5v;
extern uint16_t v_5v_avg;
@ -34,4 +34,4 @@ extern uint16_t v_con_2_boot;
void ADC0_clock_init(void);
void ADC0_init(void);
#endif //_ADC_H_
#endif //_ADC_H_

View file

@ -33,17 +33,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef MD_BOOTLOADER
#include "main_arm_atsam.h"
#ifdef RGB_MATRIX_ENABLE
#include "led_matrix.h"
#include "rgb_matrix.h"
#endif
#include "issi3733_driver.h"
#include "./usb/compiler.h"
#include "./usb/udc.h"
#include "./usb/udi_cdc.h"
# include "main_arm_atsam.h"
# ifdef RGB_MATRIX_ENABLE
# include "led_matrix.h"
# include "rgb_matrix.h"
# endif
# include "issi3733_driver.h"
# include "./usb/compiler.h"
# include "./usb/udc.h"
# include "./usb/udi_cdc.h"
#endif //MD_BOOTLOADER
#endif //_ARM_ATSAM_PROTOCOL_H_
#endif // MD_BOOTLOADER
#endif //_ARM_ATSAM_PROTOCOL_H_

View file

@ -19,83 +19,105 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <string.h>
volatile clk_t system_clks;
volatile clk_t system_clks;
volatile uint64_t ms_clk;
uint32_t usec_delay_mult;
#define USEC_DELAY_LOOP_CYCLES 3 //Sum of instruction cycles in us delay loop
uint32_t usec_delay_mult;
#define USEC_DELAY_LOOP_CYCLES 3 // Sum of instruction cycles in us delay loop
const uint32_t sercom_apbbase[] = {(uint32_t)SERCOM0,(uint32_t)SERCOM1,(uint32_t)SERCOM2,(uint32_t)SERCOM3,(uint32_t)SERCOM4,(uint32_t)SERCOM5};
const uint8_t sercom_pchan[] = {7, 8, 23, 24, 34, 35};
const uint32_t sercom_apbbase[] = {(uint32_t)SERCOM0, (uint32_t)SERCOM1, (uint32_t)SERCOM2, (uint32_t)SERCOM3, (uint32_t)SERCOM4, (uint32_t)SERCOM5};
const uint8_t sercom_pchan[] = {7, 8, 23, 24, 34, 35};
#define USE_DPLL_IND 0
#define USE_DPLL_DEF GCLK_SOURCE_DPLL0
#define USE_DPLL_IND 0
#define USE_DPLL_DEF GCLK_SOURCE_DPLL0
void CLK_oscctrl_init(void)
{
void CLK_oscctrl_init(void) {
Oscctrl *posctrl = OSCCTRL;
Gclk *pgclk = GCLK;
Gclk * pgclk = GCLK;
DBGC(DC_CLK_OSC_INIT_BEGIN);
//default setup on por
system_clks.freq_dfll = FREQ_DFLL_DEFAULT;
// default setup on por
system_clks.freq_dfll = FREQ_DFLL_DEFAULT;
system_clks.freq_gclk[0] = system_clks.freq_dfll;
//configure and startup 16MHz xosc0
posctrl->XOSCCTRL[0].bit.ENABLE = 0;
posctrl->XOSCCTRL[0].bit.STARTUP = 0xD;
posctrl->XOSCCTRL[0].bit.ENALC = 1;
posctrl->XOSCCTRL[0].bit.IMULT = 5;
posctrl->XOSCCTRL[0].bit.IPTAT = 3;
// configure and startup 16MHz xosc0
posctrl->XOSCCTRL[0].bit.ENABLE = 0;
posctrl->XOSCCTRL[0].bit.STARTUP = 0xD;
posctrl->XOSCCTRL[0].bit.ENALC = 1;
posctrl->XOSCCTRL[0].bit.IMULT = 5;
posctrl->XOSCCTRL[0].bit.IPTAT = 3;
posctrl->XOSCCTRL[0].bit.ONDEMAND = 0;
posctrl->XOSCCTRL[0].bit.XTALEN = 1;
posctrl->XOSCCTRL[0].bit.ENABLE = 1;
while (posctrl->STATUS.bit.XOSCRDY0 == 0) { DBGC(DC_CLK_OSC_INIT_XOSC0_SYNC); }
posctrl->XOSCCTRL[0].bit.XTALEN = 1;
posctrl->XOSCCTRL[0].bit.ENABLE = 1;
while (posctrl->STATUS.bit.XOSCRDY0 == 0) {
DBGC(DC_CLK_OSC_INIT_XOSC0_SYNC);
}
system_clks.freq_xosc0 = FREQ_XOSC0;
//configure and startup DPLL
// configure and startup DPLL
posctrl->Dpll[USE_DPLL_IND].DPLLCTRLA.bit.ENABLE = 0;
while (posctrl->Dpll[USE_DPLL_IND].DPLLSYNCBUSY.bit.ENABLE) { DBGC(DC_CLK_OSC_INIT_DPLL_SYNC_DISABLE); }
posctrl->Dpll[USE_DPLL_IND].DPLLCTRLB.bit.REFCLK = 2; //select XOSC0 (16MHz)
posctrl->Dpll[USE_DPLL_IND].DPLLCTRLB.bit.DIV = 7; //16 MHz / (2 * (7 + 1)) = 1 MHz
posctrl->Dpll[USE_DPLL_IND].DPLLRATIO.bit.LDR = PLL_RATIO; //1 MHz * (PLL_RATIO(47) + 1) = 48MHz
while (posctrl->Dpll[USE_DPLL_IND].DPLLSYNCBUSY.bit.DPLLRATIO) { DBGC(DC_CLK_OSC_INIT_DPLL_SYNC_RATIO); }
while (posctrl->Dpll[USE_DPLL_IND].DPLLSYNCBUSY.bit.ENABLE) {
DBGC(DC_CLK_OSC_INIT_DPLL_SYNC_DISABLE);
}
posctrl->Dpll[USE_DPLL_IND].DPLLCTRLB.bit.REFCLK = 2; // select XOSC0 (16MHz)
posctrl->Dpll[USE_DPLL_IND].DPLLCTRLB.bit.DIV = 7; // 16 MHz / (2 * (7 + 1)) = 1 MHz
posctrl->Dpll[USE_DPLL_IND].DPLLRATIO.bit.LDR = PLL_RATIO; // 1 MHz * (PLL_RATIO(47) + 1) = 48MHz
while (posctrl->Dpll[USE_DPLL_IND].DPLLSYNCBUSY.bit.DPLLRATIO) {
DBGC(DC_CLK_OSC_INIT_DPLL_SYNC_RATIO);
}
posctrl->Dpll[USE_DPLL_IND].DPLLCTRLA.bit.ONDEMAND = 0;
posctrl->Dpll[USE_DPLL_IND].DPLLCTRLA.bit.ENABLE = 1;
while (posctrl->Dpll[USE_DPLL_IND].DPLLSYNCBUSY.bit.ENABLE) { DBGC(DC_CLK_OSC_INIT_DPLL_SYNC_ENABLE); }
while (posctrl->Dpll[USE_DPLL_IND].DPLLSTATUS.bit.LOCK == 0) { DBGC(DC_CLK_OSC_INIT_DPLL_WAIT_LOCK); }
while (posctrl->Dpll[USE_DPLL_IND].DPLLSTATUS.bit.CLKRDY == 0) { DBGC(DC_CLK_OSC_INIT_DPLL_WAIT_CLKRDY); }
posctrl->Dpll[USE_DPLL_IND].DPLLCTRLA.bit.ENABLE = 1;
while (posctrl->Dpll[USE_DPLL_IND].DPLLSYNCBUSY.bit.ENABLE) {
DBGC(DC_CLK_OSC_INIT_DPLL_SYNC_ENABLE);
}
while (posctrl->Dpll[USE_DPLL_IND].DPLLSTATUS.bit.LOCK == 0) {
DBGC(DC_CLK_OSC_INIT_DPLL_WAIT_LOCK);
}
while (posctrl->Dpll[USE_DPLL_IND].DPLLSTATUS.bit.CLKRDY == 0) {
DBGC(DC_CLK_OSC_INIT_DPLL_WAIT_CLKRDY);
}
system_clks.freq_dpll[0] = (system_clks.freq_xosc0 / 2 / (posctrl->Dpll[USE_DPLL_IND].DPLLCTRLB.bit.DIV + 1)) * (posctrl->Dpll[USE_DPLL_IND].DPLLRATIO.bit.LDR + 1);
//change gclk0 to DPLL
// change gclk0 to DPLL
pgclk->GENCTRL[GEN_DPLL0].bit.SRC = USE_DPLL_DEF;
while (pgclk->SYNCBUSY.bit.GENCTRL0) { DBGC(DC_CLK_OSC_INIT_GCLK_SYNC_GENCTRL0); }
while (pgclk->SYNCBUSY.bit.GENCTRL0) {
DBGC(DC_CLK_OSC_INIT_GCLK_SYNC_GENCTRL0);
}
system_clks.freq_gclk[0] = system_clks.freq_dpll[0];
usec_delay_mult = system_clks.freq_gclk[0] / (USEC_DELAY_LOOP_CYCLES * 1000000);
if (usec_delay_mult < 1) usec_delay_mult = 1; //Never allow a multiplier of zero
if (usec_delay_mult < 1) usec_delay_mult = 1; // Never allow a multiplier of zero
DBGC(DC_CLK_OSC_INIT_COMPLETE);
}
//configure for 1MHz (1 usec timebase)
//call CLK_set_gclk_freq(GEN_TC45, FREQ_TC45_DEFAULT);
uint32_t CLK_set_gclk_freq(uint8_t gclkn, uint32_t freq)
{
// configure for 1MHz (1 usec timebase)
// call CLK_set_gclk_freq(GEN_TC45, FREQ_TC45_DEFAULT);
uint32_t CLK_set_gclk_freq(uint8_t gclkn, uint32_t freq) {
Gclk *pgclk = GCLK;
DBGC(DC_CLK_SET_GCLK_FREQ_BEGIN);
while (pgclk->SYNCBUSY.vec.GENCTRL) { DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_1); }
while (pgclk->SYNCBUSY.vec.GENCTRL) {
DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_1);
}
pgclk->GENCTRL[gclkn].bit.SRC = USE_DPLL_DEF;
while (pgclk->SYNCBUSY.vec.GENCTRL) { DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_2); }
while (pgclk->SYNCBUSY.vec.GENCTRL) {
DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_2);
}
pgclk->GENCTRL[gclkn].bit.DIV = (uint8_t)(system_clks.freq_dpll[0] / freq);
while (pgclk->SYNCBUSY.vec.GENCTRL) { DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_3); }
while (pgclk->SYNCBUSY.vec.GENCTRL) {
DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_3);
}
pgclk->GENCTRL[gclkn].bit.DIVSEL = 0;
while (pgclk->SYNCBUSY.vec.GENCTRL) { DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_4); }
while (pgclk->SYNCBUSY.vec.GENCTRL) {
DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_4);
}
pgclk->GENCTRL[gclkn].bit.GENEN = 1;
while (pgclk->SYNCBUSY.vec.GENCTRL) { DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_5); }
while (pgclk->SYNCBUSY.vec.GENCTRL) {
DBGC(DC_CLK_SET_GCLK_FREQ_SYNC_5);
}
system_clks.freq_gclk[gclkn] = system_clks.freq_dpll[0] / pgclk->GENCTRL[gclkn].bit.DIV;
DBGC(DC_CLK_SET_GCLK_FREQ_COMPLETE);
@ -103,29 +125,37 @@ uint32_t CLK_set_gclk_freq(uint8_t gclkn, uint32_t freq)
return system_clks.freq_gclk[gclkn];
}
void CLK_init_osc(void)
{
void CLK_init_osc(void) {
uint8_t gclkn = GEN_OSC0;
Gclk *pgclk = GCLK;
Gclk * pgclk = GCLK;
DBGC(DC_CLK_INIT_OSC_BEGIN);
while (pgclk->SYNCBUSY.vec.GENCTRL) { DBGC(DC_CLK_INIT_OSC_SYNC_1); }
while (pgclk->SYNCBUSY.vec.GENCTRL) {
DBGC(DC_CLK_INIT_OSC_SYNC_1);
}
pgclk->GENCTRL[gclkn].bit.SRC = GCLK_SOURCE_XOSC0;
while (pgclk->SYNCBUSY.vec.GENCTRL) { DBGC(DC_CLK_INIT_OSC_SYNC_2); }
while (pgclk->SYNCBUSY.vec.GENCTRL) {
DBGC(DC_CLK_INIT_OSC_SYNC_2);
}
pgclk->GENCTRL[gclkn].bit.DIV = 1;
while (pgclk->SYNCBUSY.vec.GENCTRL) { DBGC(DC_CLK_INIT_OSC_SYNC_3); }
while (pgclk->SYNCBUSY.vec.GENCTRL) {
DBGC(DC_CLK_INIT_OSC_SYNC_3);
}
pgclk->GENCTRL[gclkn].bit.DIVSEL = 0;
while (pgclk->SYNCBUSY.vec.GENCTRL) { DBGC(DC_CLK_INIT_OSC_SYNC_4); }
while (pgclk->SYNCBUSY.vec.GENCTRL) {
DBGC(DC_CLK_INIT_OSC_SYNC_4);
}
pgclk->GENCTRL[gclkn].bit.GENEN = 1;
while (pgclk->SYNCBUSY.vec.GENCTRL) { DBGC(DC_CLK_INIT_OSC_SYNC_5); }
while (pgclk->SYNCBUSY.vec.GENCTRL) {
DBGC(DC_CLK_INIT_OSC_SYNC_5);
}
system_clks.freq_gclk[gclkn] = system_clks.freq_xosc0;
DBGC(DC_CLK_INIT_OSC_COMPLETE);
}
void CLK_reset_time(void)
{
void CLK_reset_time(void) {
Tc *ptc4 = TC4;
Tc *ptc0 = TC0;
@ -133,72 +163,85 @@ void CLK_reset_time(void)
DBGC(DC_CLK_RESET_TIME_BEGIN);
//stop counters
// stop counters
ptc4->COUNT16.CTRLA.bit.ENABLE = 0;
while (ptc4->COUNT16.SYNCBUSY.bit.ENABLE) {}
while (ptc4->COUNT16.SYNCBUSY.bit.ENABLE) {
}
ptc0->COUNT32.CTRLA.bit.ENABLE = 0;
while (ptc0->COUNT32.SYNCBUSY.bit.ENABLE) {}
//zero counters
while (ptc0->COUNT32.SYNCBUSY.bit.ENABLE) {
}
// zero counters
ptc4->COUNT16.COUNT.reg = 0;
while (ptc4->COUNT16.SYNCBUSY.bit.COUNT) {}
while (ptc4->COUNT16.SYNCBUSY.bit.COUNT) {
}
ptc0->COUNT32.COUNT.reg = 0;
while (ptc0->COUNT32.SYNCBUSY.bit.COUNT) {}
//start counters
while (ptc0->COUNT32.SYNCBUSY.bit.COUNT) {
}
// start counters
ptc0->COUNT32.CTRLA.bit.ENABLE = 1;
while (ptc0->COUNT32.SYNCBUSY.bit.ENABLE) {}
while (ptc0->COUNT32.SYNCBUSY.bit.ENABLE) {
}
ptc4->COUNT16.CTRLA.bit.ENABLE = 1;
while (ptc4->COUNT16.SYNCBUSY.bit.ENABLE) {}
while (ptc4->COUNT16.SYNCBUSY.bit.ENABLE) {
}
DBGC(DC_CLK_RESET_TIME_COMPLETE);
}
void TC4_Handler()
{
if (TC4->COUNT16.INTFLAG.bit.MC0)
{
void TC4_Handler() {
if (TC4->COUNT16.INTFLAG.bit.MC0) {
TC4->COUNT16.INTFLAG.reg = TC_INTENCLR_MC0;
ms_clk++;
}
}
uint32_t CLK_enable_timebase(void)
{
Gclk *pgclk = GCLK;
Mclk *pmclk = MCLK;
Tc *ptc4 = TC4;
Tc *ptc0 = TC0;
uint32_t CLK_enable_timebase(void) {
Gclk * pgclk = GCLK;
Mclk * pmclk = MCLK;
Tc * ptc4 = TC4;
Tc * ptc0 = TC0;
Evsys *pevsys = EVSYS;
DBGC(DC_CLK_ENABLE_TIMEBASE_BEGIN);
//gclk2 highspeed time base
// gclk2 highspeed time base
CLK_set_gclk_freq(GEN_TC45, FREQ_TC45_DEFAULT);
CLK_init_osc();
//unmask TC4, sourcegclk2 to TC4
pmclk->APBCMASK.bit.TC4_ = 1;
pgclk->PCHCTRL[TC4_GCLK_ID].bit.GEN = GEN_TC45;
// unmask TC4, sourcegclk2 to TC4
pmclk->APBCMASK.bit.TC4_ = 1;
pgclk->PCHCTRL[TC4_GCLK_ID].bit.GEN = GEN_TC45;
pgclk->PCHCTRL[TC4_GCLK_ID].bit.CHEN = 1;
//configure TC4
// configure TC4
DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_BEGIN);
ptc4->COUNT16.CTRLA.bit.ENABLE = 0;
while (ptc4->COUNT16.SYNCBUSY.bit.ENABLE) { DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_DISABLE); }
while (ptc4->COUNT16.SYNCBUSY.bit.ENABLE) {
DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_DISABLE);
}
ptc4->COUNT16.CTRLA.bit.SWRST = 1;
while (ptc4->COUNT16.SYNCBUSY.bit.SWRST) { DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_1); }
while (ptc4->COUNT16.CTRLA.bit.SWRST) { DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_2); }
while (ptc4->COUNT16.SYNCBUSY.bit.SWRST) {
DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_1);
}
while (ptc4->COUNT16.CTRLA.bit.SWRST) {
DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_SWRST_2);
}
//CTRLA defaults
//CTRLB as default, counting up
// CTRLA defaults
// CTRLB as default, counting up
ptc4->COUNT16.CTRLBCLR.reg = 5;
while (ptc4->COUNT16.SYNCBUSY.bit.CTRLB) { DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CLTRB); }
while (ptc4->COUNT16.SYNCBUSY.bit.CTRLB) {
DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CLTRB);
}
ptc4->COUNT16.CC[0].reg = 999;
while (ptc4->COUNT16.SYNCBUSY.bit.CC0) { DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CC0); }
//ptc4->COUNT16.DBGCTRL.bit.DBGRUN = 1;
while (ptc4->COUNT16.SYNCBUSY.bit.CC0) {
DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_SYNC_CC0);
}
// ptc4->COUNT16.DBGCTRL.bit.DBGRUN = 1;
//wave mode
ptc4->COUNT16.WAVE.bit.WAVEGEN = 1; //MFRQ match frequency mode, toggle each CC match
//generate event for next stage
// wave mode
ptc4->COUNT16.WAVE.bit.WAVEGEN = 1; // MFRQ match frequency mode, toggle each CC match
// generate event for next stage
ptc4->COUNT16.EVCTRL.bit.MCEO0 = 1;
NVIC_EnableIRQ(TC4_IRQn);
@ -206,39 +249,45 @@ uint32_t CLK_enable_timebase(void)
DBGC(DC_CLK_ENABLE_TIMEBASE_TC4_COMPLETE);
//unmask TC0,1, sourcegclk2 to TC0,1
pmclk->APBAMASK.bit.TC0_ = 1;
pgclk->PCHCTRL[TC0_GCLK_ID].bit.GEN = GEN_TC45;
// unmask TC0,1, sourcegclk2 to TC0,1
pmclk->APBAMASK.bit.TC0_ = 1;
pgclk->PCHCTRL[TC0_GCLK_ID].bit.GEN = GEN_TC45;
pgclk->PCHCTRL[TC0_GCLK_ID].bit.CHEN = 1;
pmclk->APBAMASK.bit.TC1_ = 1;
pgclk->PCHCTRL[TC1_GCLK_ID].bit.GEN = GEN_TC45;
pmclk->APBAMASK.bit.TC1_ = 1;
pgclk->PCHCTRL[TC1_GCLK_ID].bit.GEN = GEN_TC45;
pgclk->PCHCTRL[TC1_GCLK_ID].bit.CHEN = 1;
//configure TC0
// configure TC0
DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_BEGIN);
ptc0->COUNT32.CTRLA.bit.ENABLE = 0;
while (ptc0->COUNT32.SYNCBUSY.bit.ENABLE) { DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_DISABLE); }
while (ptc0->COUNT32.SYNCBUSY.bit.ENABLE) {
DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_DISABLE);
}
ptc0->COUNT32.CTRLA.bit.SWRST = 1;
while (ptc0->COUNT32.SYNCBUSY.bit.SWRST) { DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_1); }
while (ptc0->COUNT32.CTRLA.bit.SWRST) { DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_2); }
//CTRLA as default
ptc0->COUNT32.CTRLA.bit.MODE = 2; //32 bit mode
ptc0->COUNT32.EVCTRL.bit.TCEI = 1; //enable incoming events
ptc0->COUNT32.EVCTRL.bit.EVACT = 2 ; //count events
while (ptc0->COUNT32.SYNCBUSY.bit.SWRST) {
DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_1);
}
while (ptc0->COUNT32.CTRLA.bit.SWRST) {
DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_SYNC_SWRST_2);
}
// CTRLA as default
ptc0->COUNT32.CTRLA.bit.MODE = 2; // 32 bit mode
ptc0->COUNT32.EVCTRL.bit.TCEI = 1; // enable incoming events
ptc0->COUNT32.EVCTRL.bit.EVACT = 2; // count events
DBGC(DC_CLK_ENABLE_TIMEBASE_TC0_COMPLETE);
DBGC(DC_CLK_ENABLE_TIMEBASE_EVSYS_BEGIN);
//configure event system
pmclk->APBBMASK.bit.EVSYS_ = 1;
pgclk->PCHCTRL[EVSYS_GCLK_ID_0].bit.GEN = GEN_TC45;
// configure event system
pmclk->APBBMASK.bit.EVSYS_ = 1;
pgclk->PCHCTRL[EVSYS_GCLK_ID_0].bit.GEN = GEN_TC45;
pgclk->PCHCTRL[EVSYS_GCLK_ID_0].bit.CHEN = 1;
pevsys->USER[44].reg = EVSYS_ID_USER_PORT_EV_0; //TC0 will get event channel 0
pevsys->Channel[0].CHANNEL.bit.EDGSEL = EVSYS_CHANNEL_EDGSEL_RISING_EDGE_Val; //Rising edge
pevsys->Channel[0].CHANNEL.bit.PATH = EVSYS_CHANNEL_PATH_SYNCHRONOUS_Val; //Synchronous
pevsys->Channel[0].CHANNEL.bit.EVGEN = EVSYS_ID_GEN_TC4_MCX_0; //TC4 MC0
pevsys->USER[44].reg = EVSYS_ID_USER_PORT_EV_0; // TC0 will get event channel 0
pevsys->Channel[0].CHANNEL.bit.EDGSEL = EVSYS_CHANNEL_EDGSEL_RISING_EDGE_Val; // Rising edge
pevsys->Channel[0].CHANNEL.bit.PATH = EVSYS_CHANNEL_PATH_SYNCHRONOUS_Val; // Synchronous
pevsys->Channel[0].CHANNEL.bit.EVGEN = EVSYS_ID_GEN_TC4_MCX_0; // TC4 MC0
DBGC(DC_CLK_ENABLE_TIMEBASE_EVSYS_COMPLETE);
@ -251,34 +300,29 @@ uint32_t CLK_enable_timebase(void)
return 0;
}
void CLK_delay_us(uint32_t usec)
{
asm (
"CBZ R0, return\n\t" //If usec == 0, branch to return label
void CLK_delay_us(uint32_t usec) {
asm("CBZ R0, return\n\t" // If usec == 0, branch to return label
);
asm (
"MULS R0, %0\n\t" //Multiply R0(usec) by usec_delay_mult and store in R0
".balign 16\n\t" //Ensure loop is aligned for fastest performance
"loop: SUBS R0, #1\n\t" //Subtract 1 from R0 and update flags (1 cycle)
"BNE loop\n\t" //Branch if non-zero to loop label (2 cycles) NOTE: USEC_DELAY_LOOP_CYCLES is the sum of loop cycles
"return:\n\t" //Return label
: //No output registers
: "r" (usec_delay_mult) //For %0
asm("MULS R0, %0\n\t" // Multiply R0(usec) by usec_delay_mult and store in R0
".balign 16\n\t" // Ensure loop is aligned for fastest performance
"loop: SUBS R0, #1\n\t" // Subtract 1 from R0 and update flags (1 cycle)
"BNE loop\n\t" // Branch if non-zero to loop label (2 cycles) NOTE: USEC_DELAY_LOOP_CYCLES is the sum of loop cycles
"return:\n\t" // Return label
: // No output registers
: "r"(usec_delay_mult) // For %0
);
//Note: BX LR generated
// Note: BX LR generated
}
void CLK_delay_ms(uint64_t msec)
{
void CLK_delay_ms(uint64_t msec) {
msec += timer_read64();
while (msec > timer_read64()) {}
while (msec > timer_read64()) {
}
}
void clk_enable_sercom_apbmask(int sercomn)
{
void clk_enable_sercom_apbmask(int sercomn) {
Mclk *pmclk = MCLK;
switch (sercomn)
{
switch (sercomn) {
case 0:
pmclk->APBAMASK.bit.SERCOM0_ = 1;
break;
@ -296,26 +340,27 @@ void clk_enable_sercom_apbmask(int sercomn)
}
}
//call CLK_oscctrl_init first
//call CLK_set_spi_freq(CHAN_SERCOM_SPI, FREQ_SPI_DEFAULT);
uint32_t CLK_set_spi_freq(uint8_t sercomn, uint32_t freq)
{
// call CLK_oscctrl_init first
// call CLK_set_spi_freq(CHAN_SERCOM_SPI, FREQ_SPI_DEFAULT);
uint32_t CLK_set_spi_freq(uint8_t sercomn, uint32_t freq) {
DBGC(DC_CLK_SET_SPI_FREQ_BEGIN);
Gclk *pgclk = GCLK;
Gclk * pgclk = GCLK;
Sercom *psercom = (Sercom *)sercom_apbbase[sercomn];
clk_enable_sercom_apbmask(sercomn);
//all gclk0 for now
pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.GEN = 0;
// all gclk0 for now
pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.GEN = 0;
pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.CHEN = 1;
psercom->I2CM.CTRLA.bit.SWRST = 1;
while (psercom->I2CM.SYNCBUSY.bit.SWRST) {}
while (psercom->I2CM.CTRLA.bit.SWRST) {}
while (psercom->I2CM.SYNCBUSY.bit.SWRST) {
}
while (psercom->I2CM.CTRLA.bit.SWRST) {
}
psercom->SPI.BAUD.reg = (uint8_t) (system_clks.freq_gclk[0]/2/freq-1);
system_clks.freq_spi = system_clks.freq_gclk[0]/2/(psercom->SPI.BAUD.reg+1);
psercom->SPI.BAUD.reg = (uint8_t)(system_clks.freq_gclk[0] / 2 / freq - 1);
system_clks.freq_spi = system_clks.freq_gclk[0] / 2 / (psercom->SPI.BAUD.reg + 1);
system_clks.freq_sercom[sercomn] = system_clks.freq_spi;
DBGC(DC_CLK_SET_SPI_FREQ_COMPLETE);
@ -323,26 +368,27 @@ uint32_t CLK_set_spi_freq(uint8_t sercomn, uint32_t freq)
return system_clks.freq_spi;
}
//call CLK_oscctrl_init first
//call CLK_set_i2c0_freq(CHAN_SERCOM_I2C0, FREQ_I2C0_DEFAULT);
uint32_t CLK_set_i2c0_freq(uint8_t sercomn, uint32_t freq)
{
// call CLK_oscctrl_init first
// call CLK_set_i2c0_freq(CHAN_SERCOM_I2C0, FREQ_I2C0_DEFAULT);
uint32_t CLK_set_i2c0_freq(uint8_t sercomn, uint32_t freq) {
DBGC(DC_CLK_SET_I2C0_FREQ_BEGIN);
Gclk *pgclk = GCLK;
Gclk * pgclk = GCLK;
Sercom *psercom = (Sercom *)sercom_apbbase[sercomn];
clk_enable_sercom_apbmask(sercomn);
//all gclk0 for now
pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.GEN = 0;
// all gclk0 for now
pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.GEN = 0;
pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.CHEN = 1;
psercom->I2CM.CTRLA.bit.SWRST = 1;
while (psercom->I2CM.SYNCBUSY.bit.SWRST) {}
while (psercom->I2CM.CTRLA.bit.SWRST) {}
while (psercom->I2CM.SYNCBUSY.bit.SWRST) {
}
while (psercom->I2CM.CTRLA.bit.SWRST) {
}
psercom->I2CM.BAUD.bit.BAUD = (uint8_t) (system_clks.freq_gclk[0]/2/freq-1);
system_clks.freq_i2c0 = system_clks.freq_gclk[0]/2/(psercom->I2CM.BAUD.bit.BAUD+1);
psercom->I2CM.BAUD.bit.BAUD = (uint8_t)(system_clks.freq_gclk[0] / 2 / freq - 1);
system_clks.freq_i2c0 = system_clks.freq_gclk[0] / 2 / (psercom->I2CM.BAUD.bit.BAUD + 1);
system_clks.freq_sercom[sercomn] = system_clks.freq_i2c0;
DBGC(DC_CLK_SET_I2C0_FREQ_COMPLETE);
@ -350,26 +396,27 @@ uint32_t CLK_set_i2c0_freq(uint8_t sercomn, uint32_t freq)
return system_clks.freq_i2c0;
}
//call CLK_oscctrl_init first
//call CLK_set_i2c1_freq(CHAN_SERCOM_I2C1, FREQ_I2C1_DEFAULT);
uint32_t CLK_set_i2c1_freq(uint8_t sercomn, uint32_t freq)
{
// call CLK_oscctrl_init first
// call CLK_set_i2c1_freq(CHAN_SERCOM_I2C1, FREQ_I2C1_DEFAULT);
uint32_t CLK_set_i2c1_freq(uint8_t sercomn, uint32_t freq) {
DBGC(DC_CLK_SET_I2C1_FREQ_BEGIN);
Gclk *pgclk = GCLK;
Gclk * pgclk = GCLK;
Sercom *psercom = (Sercom *)sercom_apbbase[sercomn];
clk_enable_sercom_apbmask(sercomn);
//all gclk0 for now
pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.GEN = 0;
// all gclk0 for now
pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.GEN = 0;
pgclk->PCHCTRL[sercom_pchan[sercomn]].bit.CHEN = 1;
psercom->I2CM.CTRLA.bit.SWRST = 1;
while (psercom->I2CM.SYNCBUSY.bit.SWRST) {}
while (psercom->I2CM.CTRLA.bit.SWRST) {}
while (psercom->I2CM.SYNCBUSY.bit.SWRST) {
}
while (psercom->I2CM.CTRLA.bit.SWRST) {
}
psercom->I2CM.BAUD.bit.BAUD = (uint8_t) (system_clks.freq_gclk[0]/2/freq-10);
system_clks.freq_i2c1 = system_clks.freq_gclk[0]/2/(psercom->I2CM.BAUD.bit.BAUD+10);
psercom->I2CM.BAUD.bit.BAUD = (uint8_t)(system_clks.freq_gclk[0] / 2 / freq - 10);
system_clks.freq_i2c1 = system_clks.freq_gclk[0] / 2 / (psercom->I2CM.BAUD.bit.BAUD + 10);
system_clks.freq_sercom[sercomn] = system_clks.freq_i2c1;
DBGC(DC_CLK_SET_I2C1_FREQ_COMPLETE);
@ -377,15 +424,13 @@ uint32_t CLK_set_i2c1_freq(uint8_t sercomn, uint32_t freq)
return system_clks.freq_i2c1;
}
void CLK_init(void)
{
void CLK_init(void) {
DBGC(DC_CLK_INIT_BEGIN);
memset((void *)&system_clks,0,sizeof(system_clks));
memset((void *)&system_clks, 0, sizeof(system_clks));
CLK_oscctrl_init();
CLK_enable_timebase();
DBGC(DC_CLK_INIT_COMPLETE);
}

View file

@ -20,20 +20,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef MD_BOOTLOADER
//From keyboard
#include "config_led.h"
#include "config.h"
// From keyboard
# include "config_led.h"
# include "config.h"
#endif //MD_BOOTLOADER
#endif // MD_BOOTLOADER
#define PLL_RATIO 47 //mcu frequency ((X+1)MHz)
#define FREQ_DFLL_DEFAULT 48000000 //DFLL frequency / usb clock
#define FREQ_SPI_DEFAULT 1000000 //spi to 595 shift regs
#define FREQ_I2C0_DEFAULT 100000 //i2c to hub
#define FREQ_I2C1_DEFAULT I2C_HZ //i2c to LED drivers
#define FREQ_TC45_DEFAULT 1000000 //1 usec resolution
#define PLL_RATIO 47 // mcu frequency ((X+1)MHz)
#define FREQ_DFLL_DEFAULT 48000000 // DFLL frequency / usb clock
#define FREQ_SPI_DEFAULT 1000000 // spi to 595 shift regs
#define FREQ_I2C0_DEFAULT 100000 // i2c to hub
#define FREQ_I2C1_DEFAULT I2C_HZ // i2c to LED drivers
#define FREQ_TC45_DEFAULT 1000000 // 1 usec resolution
//I2C1 Set ~Result PWM Time (2x Drivers)
// I2C1 Set ~Result PWM Time (2x Drivers)
// 1000000 1090000
// 900000 1000000 3.82ms
// 800000 860000
@ -42,20 +42,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// 580000 615000 6.08ms
// 500000 522000
#define FREQ_XOSC0 16000000
#define FREQ_XOSC0 16000000
#define CHAN_SERCOM_SPI 2 //shift regs
#define CHAN_SERCOM_I2C0 0 //hub
#define CHAN_SERCOM_I2C1 1 //led drivers
#define CHAN_SERCOM_UART 3 //debug util
#define CHAN_SERCOM_SPI 2 // shift regs
#define CHAN_SERCOM_I2C0 0 // hub
#define CHAN_SERCOM_I2C1 1 // led drivers
#define CHAN_SERCOM_UART 3 // debug util
//Generator clock channels
#define GEN_DPLL0 0
#define GEN_OSC0 1
#define GEN_TC45 2
// Generator clock channels
#define GEN_DPLL0 0
#define GEN_OSC0 1
#define GEN_TC45 2
#define SERCOM_COUNT 5
#define GCLK_COUNT 12
#define GCLK_COUNT 12
typedef struct clk_s {
uint32_t freq_dfll;
@ -70,20 +70,20 @@ typedef struct clk_s {
uint32_t freq_adc0;
} clk_t;
extern volatile clk_t system_clks;
extern volatile clk_t system_clks;
extern volatile uint64_t ms_clk;
void CLK_oscctrl_init(void);
void CLK_reset_time(void);
void CLK_oscctrl_init(void);
void CLK_reset_time(void);
uint32_t CLK_set_gclk_freq(uint8_t gclkn, uint32_t freq);
uint32_t CLK_enable_timebase(void);
uint64_t timer_read64(void);
void CLK_delay_us(uint32_t usec);
void CLK_delay_ms(uint64_t msec);
void CLK_delay_us(uint32_t usec);
void CLK_delay_ms(uint64_t msec);
uint32_t CLK_set_spi_freq(uint8_t sercomn, uint32_t freq);
uint32_t CLK_set_i2c0_freq(uint8_t sercomn, uint32_t freq);
uint32_t CLK_set_i2c1_freq(uint8_t sercomn, uint32_t freq);
void CLK_init(void);
void CLK_init(void);
#endif // _CLKS_H_
#endif // _CLKS_H_

View file

@ -1,46 +1,50 @@
#include "d51_util.h"
static volatile uint32_t w;
//Display unsigned 32-bit number by port toggling DBG_1 (to view on a scope)
//Read as follows: 1230 = | | | | | | || (note zero is fast double toggle)
// Display unsigned 32-bit number by port toggling DBG_1 (to view on a scope)
// Read as follows: 1230 = | | | | | | || (note zero is fast double toggle)
#define DBG_PAUSE 5
void dbg_print(uint32_t x)
{
int8_t t;
void dbg_print(uint32_t x) {
int8_t t;
uint32_t n;
uint32_t p, p2;
if (x < 10) t = 0;
else if (x < 100) t = 1;
else if (x < 1000) t = 2;
else if (x < 10000) t = 3;
else if (x < 100000) t = 4;
else if (x < 1000000) t = 5;
else if (x < 10000000) t = 6;
else if (x < 100000000) t = 7;
else if (x < 1000000000) t = 8;
else t = 9;
if (x < 10)
t = 0;
else if (x < 100)
t = 1;
else if (x < 1000)
t = 2;
else if (x < 10000)
t = 3;
else if (x < 100000)
t = 4;
else if (x < 1000000)
t = 5;
else if (x < 10000000)
t = 6;
else if (x < 100000000)
t = 7;
else if (x < 1000000000)
t = 8;
else
t = 9;
while (t >= 0)
{
while (t >= 0) {
p2 = t;
p = 1;
p = 1;
while (p2--) p *= 10;
n = x / p;
x -= n * p;
if (!n)
{
if (!n) {
DBG_1_ON;
DBG_1_OFF;
DBG_1_ON;
DBG_1_OFF;
n--;
}
else
{
while (n > 0)
{
} else {
while (n > 0) {
DBG_1_ON;
DBG_1_OFF;
n--;
@ -50,68 +54,80 @@ void dbg_print(uint32_t x)
t--;
}
for (w = DBG_PAUSE; w; w--); //Long pause after number is complete
for (w = DBG_PAUSE; w; w--)
; // Long pause after number is complete
}
//Display unsigned 32-bit number through debug led
//Read as follows: 1230 = [*] [* *] [* * *] [**] (note zero is fast double flash)
// Display unsigned 32-bit number through debug led
// Read as follows: 1230 = [*] [* *] [* * *] [**] (note zero is fast double flash)
#define DLED_ONTIME 1000000
#define DLED_PAUSE 1500000
void dled_print(uint32_t x, uint8_t long_pause)
{
int8_t t;
void dled_print(uint32_t x, uint8_t long_pause) {
int8_t t;
uint32_t n;
uint32_t p, p2;
if (x < 10) t = 0;
else if (x < 100) t = 1;
else if (x < 1000) t = 2;
else if (x < 10000) t = 3;
else if (x < 100000) t = 4;
else if (x < 1000000) t = 5;
else if (x < 10000000) t = 6;
else if (x < 100000000) t = 7;
else if (x < 1000000000) t = 8;
else t = 9;
if (x < 10)
t = 0;
else if (x < 100)
t = 1;
else if (x < 1000)
t = 2;
else if (x < 10000)
t = 3;
else if (x < 100000)
t = 4;
else if (x < 1000000)
t = 5;
else if (x < 10000000)
t = 6;
else if (x < 100000000)
t = 7;
else if (x < 1000000000)
t = 8;
else
t = 9;
while (t >= 0)
{
while (t >= 0) {
p2 = t;
p = 1;
p = 1;
while (p2--) p *= 10;
n = x / p;
x -= n * p;
if (!n)
{
if (!n) {
DBG_LED_ON;
for (w = DLED_ONTIME / 4; w; w--);
for (w = DLED_ONTIME / 4; w; w--)
;
DBG_LED_OFF;
for (w = DLED_ONTIME / 4; w; w--);
for (w = DLED_ONTIME / 4; w; w--)
;
DBG_LED_ON;
for (w = DLED_ONTIME / 4; w; w--);
for (w = DLED_ONTIME / 4; w; w--)
;
DBG_LED_OFF;
for (w = DLED_ONTIME / 4; w; w--);
for (w = DLED_ONTIME / 4; w; w--)
;
n--;
}
else
{
while (n > 0)
{
} else {
while (n > 0) {
DBG_LED_ON;
for (w = DLED_ONTIME; w; w--);
for (w = DLED_ONTIME; w; w--)
;
DBG_LED_OFF;
for (w = DLED_ONTIME / 2; w; w--);
for (w = DLED_ONTIME / 2; w; w--)
;
n--;
}
}
for (w = DLED_PAUSE; w; w--);
for (w = DLED_PAUSE; w; w--)
;
t--;
}
if (long_pause)
{
for (w = DLED_PAUSE * 4; w; w--);
if (long_pause) {
for (w = DLED_PAUSE * 4; w; w--)
;
}
}
@ -119,103 +135,102 @@ void dled_print(uint32_t x, uint8_t long_pause)
volatile uint32_t debug_code;
//These macros are for compile time substitution
#define DEBUG_BOOT_TRACING_EXTINTn (DEBUG_BOOT_TRACING_PIN % _U_(0x10))
#define DEBUG_BOOT_TRACING_EXTINTb (_U_(0x1) << DEBUG_BOOT_TRACING_EXTINTn)
#define DEBUG_BOOT_TRACING_CONFIG_INDn (DEBUG_BOOT_TRACING_EXTINTn / _U_(0x8))
#define DEBUG_BOOT_TRACING_CONFIG_SENSEn (DEBUG_BOOT_TRACING_EXTINTn % _U_(0x8))
#define DEBUG_BOOT_TRACING_CONFIG_SENSEb (DEBUG_BOOT_TRACING_CONFIG_SENSEn * _U_(0x4))
#define DEBUG_BOOT_TRACING_IRQn (EIC_0_IRQn + DEBUG_BOOT_TRACING_EXTINTn)
// These macros are for compile time substitution
# define DEBUG_BOOT_TRACING_EXTINTn (DEBUG_BOOT_TRACING_PIN % _U_(0x10))
# define DEBUG_BOOT_TRACING_EXTINTb (_U_(0x1) << DEBUG_BOOT_TRACING_EXTINTn)
# define DEBUG_BOOT_TRACING_CONFIG_INDn (DEBUG_BOOT_TRACING_EXTINTn / _U_(0x8))
# define DEBUG_BOOT_TRACING_CONFIG_SENSEn (DEBUG_BOOT_TRACING_EXTINTn % _U_(0x8))
# define DEBUG_BOOT_TRACING_CONFIG_SENSEb (DEBUG_BOOT_TRACING_CONFIG_SENSEn * _U_(0x4))
# define DEBUG_BOOT_TRACING_IRQn (EIC_0_IRQn + DEBUG_BOOT_TRACING_EXTINTn)
//These macros perform PORT+PIN definition translation to IRQn in the preprocessor
#define PORTPIN_TO_IRQn_EXPAND(def) def
#define PORTPIN_TO_IRQn_DEF(def) PORTPIN_TO_IRQn_EXPAND(def)
#if DEBUG_BOOT_TRACING_PIN < 10
#define PORTPIN_TO_IRQn_TODEF(port, pin) PORTPIN_TO_IRQn_DEF(PIN_ ## port ## 0 ## pin ## A_EIC_EXTINT_NUM)
#else
#define PORTPIN_TO_IRQn_TODEF(port, pin) PORTPIN_TO_IRQn_DEF(PIN_ ## port ## pin ## A_EIC_EXTINT_NUM)
#endif
#define PORTPIN_TO_IRQn(port, pin) PORTPIN_TO_IRQn_TODEF(port, pin)
// These macros perform PORT+PIN definition translation to IRQn in the preprocessor
# define PORTPIN_TO_IRQn_EXPAND(def) def
# define PORTPIN_TO_IRQn_DEF(def) PORTPIN_TO_IRQn_EXPAND(def)
# if DEBUG_BOOT_TRACING_PIN < 10
# define PORTPIN_TO_IRQn_TODEF(port, pin) PORTPIN_TO_IRQn_DEF(PIN_##port##0##pin##A_EIC_EXTINT_NUM)
# else
# define PORTPIN_TO_IRQn_TODEF(port, pin) PORTPIN_TO_IRQn_DEF(PIN_##port##pin##A_EIC_EXTINT_NUM)
# endif
# define PORTPIN_TO_IRQn(port, pin) PORTPIN_TO_IRQn_TODEF(port, pin)
//These macros perform function name output in the preprocessor
#define DEBUG_BOOT_TRACING_HANDLER_CONCAT(irq) void EIC_ ## irq ## _Handler(void)
#define DEBUG_BOOT_TRACING_HANDLER(irq) DEBUG_BOOT_TRACING_HANDLER_CONCAT(irq)
// These macros perform function name output in the preprocessor
# define DEBUG_BOOT_TRACING_HANDLER_CONCAT(irq) void EIC_##irq##_Handler(void)
# define DEBUG_BOOT_TRACING_HANDLER(irq) DEBUG_BOOT_TRACING_HANDLER_CONCAT(irq)
//To generate the function name of the IRQ handler catching boot tracing,
// To generate the function name of the IRQ handler catching boot tracing,
// certain macros must be undefined, so save their current values to macro stack
#pragma push_macro("PA")
#pragma push_macro("PB")
#pragma push_macro("_L_")
# pragma push_macro("PA")
# pragma push_macro("PB")
# pragma push_macro("_L_")
//Undefine / redefine pushed macros
#undef PA
#undef PB
#undef _L_
#define _L_(x) x
// Undefine / redefine pushed macros
# undef PA
# undef PB
# undef _L_
# define _L_(x) x
//Perform the work and output
//Ex: PORT PB, PIN 31 = void EIC_15_Handler(void)
// Perform the work and output
// Ex: PORT PB, PIN 31 = void EIC_15_Handler(void)
DEBUG_BOOT_TRACING_HANDLER(PORTPIN_TO_IRQn(DEBUG_BOOT_TRACING_PORT, DEBUG_BOOT_TRACING_PIN))
//Restore macros
#pragma pop_macro("PA")
#pragma pop_macro("PB")
#pragma pop_macro("_L_")
// Restore macros
# pragma pop_macro("PA")
# pragma pop_macro("PB")
# pragma pop_macro("_L_")
{
//This is only for non-functional keyboard troubleshooting and should be disabled after boot
//Intention is to lock up the keyboard here with repeating debug led code
while (1)
{
// This is only for non-functional keyboard troubleshooting and should be disabled after boot
// Intention is to lock up the keyboard here with repeating debug led code
while (1) {
dled_print(debug_code, 1);
}
}
void debug_code_init(void)
{
void debug_code_init(void) {
DBGC(DC_UNSET);
//Configure Ports for EIC
PORT->Group[DEBUG_BOOT_TRACING_PORT].DIRCLR.reg = 1 << DEBUG_BOOT_TRACING_PIN; //Input
PORT->Group[DEBUG_BOOT_TRACING_PORT].OUTSET.reg = 1 << DEBUG_BOOT_TRACING_PIN; //High
PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.INEN = 1; //Input Enable
PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PULLEN = 1; //Pull Enable
PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PMUXEN = 1; //Mux Enable
PORT->Group[DEBUG_BOOT_TRACING_PORT].PMUX[DEBUG_BOOT_TRACING_PIN / 2].bit.PMUXO = 0; //Mux A
// Configure Ports for EIC
PORT->Group[DEBUG_BOOT_TRACING_PORT].DIRCLR.reg = 1 << DEBUG_BOOT_TRACING_PIN; // Input
PORT->Group[DEBUG_BOOT_TRACING_PORT].OUTSET.reg = 1 << DEBUG_BOOT_TRACING_PIN; // High
PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.INEN = 1; // Input Enable
PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PULLEN = 1; // Pull Enable
PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PMUXEN = 1; // Mux Enable
PORT->Group[DEBUG_BOOT_TRACING_PORT].PMUX[DEBUG_BOOT_TRACING_PIN / 2].bit.PMUXO = 0; // Mux A
//Enable CLK_EIC_APB
// Enable CLK_EIC_APB
MCLK->APBAMASK.bit.EIC_ = 1;
//Configure EIC
// Configure EIC
EIC->CTRLA.bit.SWRST = 1;
while (EIC->SYNCBUSY.bit.SWRST) {}
EIC->ASYNCH.reg = DEBUG_BOOT_TRACING_EXTINTb;
while (EIC->SYNCBUSY.bit.SWRST) {
}
EIC->ASYNCH.reg = DEBUG_BOOT_TRACING_EXTINTb;
EIC->INTENSET.reg = DEBUG_BOOT_TRACING_EXTINTb;
EIC->CONFIG[DEBUG_BOOT_TRACING_CONFIG_INDn].reg |= (EIC_CONFIG_SENSE0_FALL_Val << DEBUG_BOOT_TRACING_CONFIG_SENSEb);
EIC->CTRLA.bit.ENABLE = 1;
while (EIC->SYNCBUSY.bit.ENABLE) {}
while (EIC->SYNCBUSY.bit.ENABLE) {
}
//Enable EIC IRQ
// Enable EIC IRQ
NVIC_EnableIRQ(DEBUG_BOOT_TRACING_IRQn);
}
void debug_code_disable(void)
{
//Disable EIC IRQ
void debug_code_disable(void) {
// Disable EIC IRQ
NVIC_DisableIRQ(DEBUG_BOOT_TRACING_IRQn);
//Disable EIC
// Disable EIC
EIC->CTRLA.bit.ENABLE = 0;
while (EIC->SYNCBUSY.bit.ENABLE) {}
while (EIC->SYNCBUSY.bit.ENABLE) {
}
//Default port configuration
PORT->Group[DEBUG_BOOT_TRACING_PORT].DIRCLR.reg = 1 << DEBUG_BOOT_TRACING_PIN; //Input
PORT->Group[DEBUG_BOOT_TRACING_PORT].OUTCLR.reg = 1 << DEBUG_BOOT_TRACING_PIN; //Low
PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.INEN = 0; //Input Disable
PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PULLEN = 0; //Pull Disable
PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PMUXEN = 0; //Mux Disable
PORT->Group[DEBUG_BOOT_TRACING_PORT].PMUX[DEBUG_BOOT_TRACING_PIN / 2].bit.PMUXO = 0; //Mux A
// Default port configuration
PORT->Group[DEBUG_BOOT_TRACING_PORT].DIRCLR.reg = 1 << DEBUG_BOOT_TRACING_PIN; // Input
PORT->Group[DEBUG_BOOT_TRACING_PORT].OUTCLR.reg = 1 << DEBUG_BOOT_TRACING_PIN; // Low
PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.INEN = 0; // Input Disable
PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PULLEN = 0; // Pull Disable
PORT->Group[DEBUG_BOOT_TRACING_PORT].PINCFG[DEBUG_BOOT_TRACING_PIN].bit.PMUXEN = 0; // Mux Disable
PORT->Group[DEBUG_BOOT_TRACING_PORT].PMUX[DEBUG_BOOT_TRACING_PIN / 2].bit.PMUXO = 0; // Mux A
//Disable CLK_EIC_APB
// Disable CLK_EIC_APB
MCLK->APBAMASK.bit.EIC_ = 0;
}
@ -224,4 +239,4 @@ void debug_code_disable(void)
void debug_code_init(void) {}
void debug_code_disable(void) {}
#endif //DEBUG_BOOT_TRACING_ENABLE
#endif // DEBUG_BOOT_TRACING_ENABLE

View file

@ -22,54 +22,54 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* Debug LED */
#if DEBUG_LED_ENABLE == 1
#define DBG_LED_ENA PORT->Group[DEBUG_LED_PORT].DIRSET.reg = (1 << DEBUG_LED_PIN)
#define DBG_LED_DIS PORT->Group[DEBUG_LED_PORT].DIRCLR.reg = (1 << DEBUG_LED_PIN)
#define DBG_LED_ON PORT->Group[DEBUG_LED_PORT].OUTSET.reg = (1 << DEBUG_LED_PIN)
#define DBG_LED_OFF PORT->Group[DEBUG_LED_PORT].OUTCLR.reg = (1 << DEBUG_LED_PIN)
# define DBG_LED_ENA PORT->Group[DEBUG_LED_PORT].DIRSET.reg = (1 << DEBUG_LED_PIN)
# define DBG_LED_DIS PORT->Group[DEBUG_LED_PORT].DIRCLR.reg = (1 << DEBUG_LED_PIN)
# define DBG_LED_ON PORT->Group[DEBUG_LED_PORT].OUTSET.reg = (1 << DEBUG_LED_PIN)
# define DBG_LED_OFF PORT->Group[DEBUG_LED_PORT].OUTCLR.reg = (1 << DEBUG_LED_PIN)
#else
#define DBG_LED_ENA
#define DBG_LED_DIS
#define DBG_LED_ON
#define DBG_LED_OFF
# define DBG_LED_ENA
# define DBG_LED_DIS
# define DBG_LED_ON
# define DBG_LED_OFF
#endif
/* Debug Port 1 */
#if DEBUG_PORT1_ENABLE == 1
#define DBG_1_ENA PORT->Group[DEBUG_PORT1_PORT].DIRSET.reg = (1 << DEBUG_PORT1_PIN)
#define DBG_1_DIS PORT->Group[DEBUG_PORT1_PORT].DIRCLR.reg = (1 << DEBUG_PORT1_PIN)
#define DBG_1_ON PORT->Group[DEBUG_PORT1_PORT].OUTSET.reg = (1 << DEBUG_PORT1_PIN)
#define DBG_1_OFF PORT->Group[DEBUG_PORT1_PORT].OUTCLR.reg = (1 << DEBUG_PORT1_PIN)
# define DBG_1_ENA PORT->Group[DEBUG_PORT1_PORT].DIRSET.reg = (1 << DEBUG_PORT1_PIN)
# define DBG_1_DIS PORT->Group[DEBUG_PORT1_PORT].DIRCLR.reg = (1 << DEBUG_PORT1_PIN)
# define DBG_1_ON PORT->Group[DEBUG_PORT1_PORT].OUTSET.reg = (1 << DEBUG_PORT1_PIN)
# define DBG_1_OFF PORT->Group[DEBUG_PORT1_PORT].OUTCLR.reg = (1 << DEBUG_PORT1_PIN)
#else
#define DBG_1_ENA
#define DBG_1_DIS
#define DBG_1_ON
#define DBG_1_OFF
# define DBG_1_ENA
# define DBG_1_DIS
# define DBG_1_ON
# define DBG_1_OFF
#endif
/* Debug Port 2 */
#if DEBUG_PORT2_ENABLE == 1
#define DBG_2_ENA PORT->Group[DEBUG_PORT2_PORT].DIRSET.reg = (1 << DEBUG_PORT2_PIN)
#define DBG_2_DIS PORT->Group[DEBUG_PORT2_PORT].DIRCLR.reg = (1 << DEBUG_PORT2_PIN)
#define DBG_2_ON PORT->Group[DEBUG_PORT2_PORT].OUTSET.reg = (1 << DEBUG_PORT2_PIN)
#define DBG_2_OFF PORT->Group[DEBUG_PORT2_PORT].OUTCLR.reg = (1 << DEBUG_PORT2_PIN)
# define DBG_2_ENA PORT->Group[DEBUG_PORT2_PORT].DIRSET.reg = (1 << DEBUG_PORT2_PIN)
# define DBG_2_DIS PORT->Group[DEBUG_PORT2_PORT].DIRCLR.reg = (1 << DEBUG_PORT2_PIN)
# define DBG_2_ON PORT->Group[DEBUG_PORT2_PORT].OUTSET.reg = (1 << DEBUG_PORT2_PIN)
# define DBG_2_OFF PORT->Group[DEBUG_PORT2_PORT].OUTCLR.reg = (1 << DEBUG_PORT2_PIN)
#else
#define DBG_2_ENA
#define DBG_2_DIS
#define DBG_2_ON
#define DBG_2_OFF
# define DBG_2_ENA
# define DBG_2_DIS
# define DBG_2_ON
# define DBG_2_OFF
#endif
/* Debug Port 3 */
#if DEBUG_PORT3_ENABLE == 1
#define DBG_3_ENA PORT->Group[DEBUG_PORT3_PORT].DIRSET.reg = (1 << DEBUG_PORT3_PIN)
#define DBG_3_DIS PORT->Group[DEBUG_PORT3_PORT].DIRCLR.reg = (1 << DEBUG_PORT3_PIN)
#define DBG_3_ON PORT->Group[DEBUG_PORT3_PORT].OUTSET.reg = (1 << DEBUG_PORT3_PIN)
#define DBG_3_OFF PORT->Group[DEBUG_PORT3_PORT].OUTCLR.reg = (1 << DEBUG_PORT3_PIN)
# define DBG_3_ENA PORT->Group[DEBUG_PORT3_PORT].DIRSET.reg = (1 << DEBUG_PORT3_PIN)
# define DBG_3_DIS PORT->Group[DEBUG_PORT3_PORT].DIRCLR.reg = (1 << DEBUG_PORT3_PIN)
# define DBG_3_ON PORT->Group[DEBUG_PORT3_PORT].OUTSET.reg = (1 << DEBUG_PORT3_PIN)
# define DBG_3_OFF PORT->Group[DEBUG_PORT3_PORT].OUTCLR.reg = (1 << DEBUG_PORT3_PIN)
#else
#define DBG_3_ENA
#define DBG_3_DIS
#define DBG_3_ON
#define DBG_3_OFF
# define DBG_3_ENA
# define DBG_3_DIS
# define DBG_3_ON
# define DBG_3_OFF
#endif
void dbg_print(uint32_t x);
@ -80,7 +80,7 @@ void debug_code_disable(void);
#ifdef DEBUG_BOOT_TRACING_ENABLE
#define DBGC(n) debug_code = n
# define DBGC(n) debug_code = n
extern volatile uint32_t debug_code;
@ -216,8 +216,9 @@ enum debug_code_list {
#else
#define DBGC(n) {}
# define DBGC(n) \
{}
#endif //DEBUG_BOOT_TRACING_ENABLE
#endif // DEBUG_BOOT_TRACING_ENABLE
#endif //_D51_UTIL_H_
#endif //_D51_UTIL_H_

View file

@ -19,77 +19,84 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#if !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
#include <string.h>
# include <string.h>
//From keyboard
#include "config.h"
#include "config_led.h"
#include "matrix.h"
// From keyboard
# include "config.h"
# include "config_led.h"
# include "matrix.h"
#define I2C_LED_USE_DMA 1 //Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers
# define I2C_LED_USE_DMA 1 // Set 1 to use background DMA transfers for leds, Set 0 to use inline software transfers
static uint8_t i2c_led_q[I2C_Q_SIZE]; //I2C queue circular buffer
static uint8_t i2c_led_q_s; //Start of circular buffer
static uint8_t i2c_led_q_e; //End of circular buffer
static uint8_t i2c_led_q_full; //Queue full counter for reset
static uint8_t i2c_led_q[I2C_Q_SIZE]; // I2C queue circular buffer
static uint8_t i2c_led_q_s; // Start of circular buffer
static uint8_t i2c_led_q_e; // End of circular buffer
static uint8_t i2c_led_q_full; // Queue full counter for reset
static uint8_t dma_sendbuf[I2C_DMA_MAX_SEND]; //Data being written to I2C
static uint8_t dma_sendbuf[I2C_DMA_MAX_SEND]; // Data being written to I2C
volatile uint8_t i2c_led_q_running;
#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
void i2c0_init(void)
{
void i2c0_init(void) {
DBGC(DC_I2C0_INIT_BEGIN);
CLK_set_i2c0_freq(CHAN_SERCOM_I2C0, FREQ_I2C0_DEFAULT);
//MCU
PORT->Group[0].PMUX[4].bit.PMUXE = 2;
PORT->Group[0].PMUX[4].bit.PMUXO = 2;
// MCU
PORT->Group[0].PMUX[4].bit.PMUXE = 2;
PORT->Group[0].PMUX[4].bit.PMUXO = 2;
PORT->Group[0].PINCFG[8].bit.PMUXEN = 1;
PORT->Group[0].PINCFG[9].bit.PMUXEN = 1;
//I2C
//Note: SW Reset handled in CLK_set_i2c0_freq clks.c
// I2C
// Note: SW Reset handled in CLK_set_i2c0_freq clks.c
SERCOM0->I2CM.CTRLA.bit.MODE = 5; //Set master mode
SERCOM0->I2CM.CTRLA.bit.MODE = 5; // Set master mode
SERCOM0->I2CM.CTRLA.bit.SPEED = 0; //Set to 1 for Fast-mode Plus (FM+) up to 1 MHz
SERCOM0->I2CM.CTRLA.bit.RUNSTDBY = 1; //Enabled
SERCOM0->I2CM.CTRLA.bit.SPEED = 0; // Set to 1 for Fast-mode Plus (FM+) up to 1 MHz
SERCOM0->I2CM.CTRLA.bit.RUNSTDBY = 1; // Enabled
SERCOM0->I2CM.CTRLA.bit.ENABLE = 1; //Enable the device
while (SERCOM0->I2CM.SYNCBUSY.bit.ENABLE) { DBGC(DC_I2C0_INIT_SYNC_ENABLING); } //Wait for SYNCBUSY.ENABLE to clear
SERCOM0->I2CM.CTRLA.bit.ENABLE = 1; // Enable the device
while (SERCOM0->I2CM.SYNCBUSY.bit.ENABLE) {
DBGC(DC_I2C0_INIT_SYNC_ENABLING);
} // Wait for SYNCBUSY.ENABLE to clear
SERCOM0->I2CM.STATUS.bit.BUSSTATE = 1; //Force into IDLE state
while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) { DBGC(DC_I2C0_INIT_SYNC_SYSOP); }
while (SERCOM0->I2CM.STATUS.bit.BUSSTATE != 1) { DBGC(DC_I2C0_INIT_WAIT_IDLE); } //Wait while not idle
SERCOM0->I2CM.STATUS.bit.BUSSTATE = 1; // Force into IDLE state
while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) {
DBGC(DC_I2C0_INIT_SYNC_SYSOP);
}
while (SERCOM0->I2CM.STATUS.bit.BUSSTATE != 1) {
DBGC(DC_I2C0_INIT_WAIT_IDLE);
} // Wait while not idle
DBGC(DC_I2C0_INIT_COMPLETE);
}
uint8_t i2c0_start(uint8_t address)
{
uint8_t i2c0_start(uint8_t address) {
SERCOM0->I2CM.ADDR.bit.ADDR = address;
while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) {}
while (SERCOM0->I2CM.INTFLAG.bit.MB == 0) {}
while (SERCOM0->I2CM.STATUS.bit.RXNACK) {}
while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP) {
}
while (SERCOM0->I2CM.INTFLAG.bit.MB == 0) {
}
while (SERCOM0->I2CM.STATUS.bit.RXNACK) {
}
return 1;
}
uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout)
{
uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout) {
if (!length) return 0;
i2c0_start(address);
while (length)
{
while (length) {
SERCOM0->I2CM.DATA.bit.DATA = *data;
while (SERCOM0->I2CM.INTFLAG.bit.MB == 0) {}
while (SERCOM0->I2CM.STATUS.bit.RXNACK) {}
while (SERCOM0->I2CM.INTFLAG.bit.MB == 0) {
}
while (SERCOM0->I2CM.STATUS.bit.RXNACK) {
}
data++;
length--;
@ -100,74 +107,83 @@ uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t
return 1;
}
void i2c0_stop(void)
{
if (SERCOM0->I2CM.STATUS.bit.CLKHOLD || SERCOM0->I2CM.INTFLAG.bit.MB == 1 || SERCOM0->I2CM.STATUS.bit.BUSSTATE != 1)
{
void i2c0_stop(void) {
if (SERCOM0->I2CM.STATUS.bit.CLKHOLD || SERCOM0->I2CM.INTFLAG.bit.MB == 1 || SERCOM0->I2CM.STATUS.bit.BUSSTATE != 1) {
SERCOM0->I2CM.CTRLB.bit.CMD = 3;
while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP);
while (SERCOM0->I2CM.STATUS.bit.CLKHOLD);
while (SERCOM0->I2CM.INTFLAG.bit.MB);
while (SERCOM0->I2CM.STATUS.bit.BUSSTATE != 1);
while (SERCOM0->I2CM.SYNCBUSY.bit.SYSOP)
;
while (SERCOM0->I2CM.STATUS.bit.CLKHOLD)
;
while (SERCOM0->I2CM.INTFLAG.bit.MB)
;
while (SERCOM0->I2CM.STATUS.bit.BUSSTATE != 1)
;
}
}
#if !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
void i2c1_init(void)
{
void i2c1_init(void) {
DBGC(DC_I2C1_INIT_BEGIN);
CLK_set_i2c1_freq(CHAN_SERCOM_I2C1, FREQ_I2C1_DEFAULT);
/* MCU */
PORT->Group[0].PMUX[8].bit.PMUXE = 2;
PORT->Group[0].PMUX[8].bit.PMUXO = 2;
PORT->Group[0].PMUX[8].bit.PMUXE = 2;
PORT->Group[0].PMUX[8].bit.PMUXO = 2;
PORT->Group[0].PINCFG[16].bit.PMUXEN = 1;
PORT->Group[0].PINCFG[17].bit.PMUXEN = 1;
/* I2C */
//Note: SW Reset handled in CLK_set_i2c1_freq clks.c
// Note: SW Reset handled in CLK_set_i2c1_freq clks.c
SERCOM1->I2CM.CTRLA.bit.MODE = 5; //MODE: Set master mode (No sync)
SERCOM1->I2CM.CTRLA.bit.SPEED = 1; //SPEED: Fm+ up to 1MHz (No sync)
SERCOM1->I2CM.CTRLA.bit.RUNSTDBY = 1; //RUNSTBY: Enabled (No sync)
SERCOM1->I2CM.CTRLA.bit.MODE = 5; // MODE: Set master mode (No sync)
SERCOM1->I2CM.CTRLA.bit.SPEED = 1; // SPEED: Fm+ up to 1MHz (No sync)
SERCOM1->I2CM.CTRLA.bit.RUNSTDBY = 1; // RUNSTBY: Enabled (No sync)
SERCOM1->I2CM.CTRLB.bit.SMEN = 1; //SMEN: Smart mode enabled (For DMA)(No sync)
SERCOM1->I2CM.CTRLB.bit.SMEN = 1; // SMEN: Smart mode enabled (For DMA)(No sync)
NVIC_EnableIRQ(SERCOM1_0_IRQn);
SERCOM1->I2CM.INTENSET.bit.ERROR = 1;
SERCOM1->I2CM.CTRLA.bit.ENABLE = 1; //ENABLE: Enable the device (sync SYNCBUSY.ENABLE)
while (SERCOM1->I2CM.SYNCBUSY.bit.ENABLE) { DBGC(DC_I2C1_INIT_SYNC_ENABLING); } //Wait for SYNCBUSY.ENABLE to clear
SERCOM1->I2CM.CTRLA.bit.ENABLE = 1; // ENABLE: Enable the device (sync SYNCBUSY.ENABLE)
while (SERCOM1->I2CM.SYNCBUSY.bit.ENABLE) {
DBGC(DC_I2C1_INIT_SYNC_ENABLING);
} // Wait for SYNCBUSY.ENABLE to clear
SERCOM1->I2CM.STATUS.bit.BUSSTATE = 1; //BUSSTATE: Force into IDLE state (sync SYNCBUSY.SYSOP)
while (SERCOM1->I2CM.SYNCBUSY.bit.SYSOP) { DBGC(DC_I2C1_INIT_SYNC_SYSOP); }
while (SERCOM1->I2CM.STATUS.bit.BUSSTATE != 1) { DBGC(DC_I2C1_INIT_WAIT_IDLE); } //Wait while not idle
SERCOM1->I2CM.STATUS.bit.BUSSTATE = 1; // BUSSTATE: Force into IDLE state (sync SYNCBUSY.SYSOP)
while (SERCOM1->I2CM.SYNCBUSY.bit.SYSOP) {
DBGC(DC_I2C1_INIT_SYNC_SYSOP);
}
while (SERCOM1->I2CM.STATUS.bit.BUSSTATE != 1) {
DBGC(DC_I2C1_INIT_WAIT_IDLE);
} // Wait while not idle
DBGC(DC_I2C1_INIT_COMPLETE);
}
uint8_t i2c1_start(uint8_t address)
{
uint8_t i2c1_start(uint8_t address) {
SERCOM1->I2CM.ADDR.bit.ADDR = address;
while (SERCOM1->I2CM.SYNCBUSY.bit.SYSOP) {}
while (SERCOM1->I2CM.INTFLAG.bit.MB == 0) {}
while (SERCOM1->I2CM.STATUS.bit.RXNACK) {}
while (SERCOM1->I2CM.SYNCBUSY.bit.SYSOP) {
}
while (SERCOM1->I2CM.INTFLAG.bit.MB == 0) {
}
while (SERCOM1->I2CM.STATUS.bit.RXNACK) {
}
return 1;
}
uint8_t i2c1_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout)
{
uint8_t i2c1_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout) {
if (!length) return 0;
i2c1_start(address);
while (length)
{
while (length) {
SERCOM1->I2CM.DATA.bit.DATA = *data;
while (SERCOM1->I2CM.INTFLAG.bit.MB == 0) {}
while (SERCOM1->I2CM.STATUS.bit.RXNACK) {}
while (SERCOM1->I2CM.INTFLAG.bit.MB == 0) {
}
while (SERCOM1->I2CM.STATUS.bit.RXNACK) {
}
data++;
length--;
@ -178,33 +194,32 @@ uint8_t i2c1_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t
return 1;
}
void i2c1_stop(void)
{
if (SERCOM1->I2CM.STATUS.bit.CLKHOLD || SERCOM1->I2CM.INTFLAG.bit.MB == 1 || SERCOM1->I2CM.STATUS.bit.BUSSTATE != 1)
{
void i2c1_stop(void) {
if (SERCOM1->I2CM.STATUS.bit.CLKHOLD || SERCOM1->I2CM.INTFLAG.bit.MB == 1 || SERCOM1->I2CM.STATUS.bit.BUSSTATE != 1) {
SERCOM1->I2CM.CTRLB.bit.CMD = 3;
while (SERCOM1->I2CM.SYNCBUSY.bit.SYSOP);
while (SERCOM1->I2CM.STATUS.bit.CLKHOLD);
while (SERCOM1->I2CM.INTFLAG.bit.MB);
while (SERCOM1->I2CM.STATUS.bit.BUSSTATE != 1);
while (SERCOM1->I2CM.SYNCBUSY.bit.SYSOP)
;
while (SERCOM1->I2CM.STATUS.bit.CLKHOLD)
;
while (SERCOM1->I2CM.INTFLAG.bit.MB)
;
while (SERCOM1->I2CM.STATUS.bit.BUSSTATE != 1)
;
}
}
void i2c_led_send_CRWL(uint8_t drvid)
{
uint8_t i2cdata[] = { ISSI3733_CMDRWL, ISSI3733_CMDRWL_WRITE_ENABLE_ONCE };
void i2c_led_send_CRWL(uint8_t drvid) {
uint8_t i2cdata[] = {ISSI3733_CMDRWL, ISSI3733_CMDRWL_WRITE_ENABLE_ONCE};
i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0);
}
void i2c_led_select_page(uint8_t drvid, uint8_t pageno)
{
uint8_t i2cdata[] = { ISSI3733_CMDR, pageno };
void i2c_led_select_page(uint8_t drvid, uint8_t pageno) {
uint8_t i2cdata[] = {ISSI3733_CMDR, pageno};
i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0);
}
void i2c_led_send_GCR(uint8_t drvid)
{
uint8_t i2cdata[] = { ISSI3733_GCCR, 0x00 };
void i2c_led_send_GCR(uint8_t drvid) {
uint8_t i2cdata[] = {ISSI3733_GCCR, 0x00};
if (gcr_actual > LED_GCR_MAX) gcr_actual = LED_GCR_MAX;
i2cdata[1] = gcr_actual;
@ -212,57 +227,50 @@ void i2c_led_send_GCR(uint8_t drvid)
i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0);
}
void i2c_led_send_onoff(uint8_t drvid)
{
#if I2C_LED_USE_DMA != 1
if (!i2c_led_q_running)
{
#endif
void i2c_led_send_onoff(uint8_t drvid) {
# if I2C_LED_USE_DMA != 1
if (!i2c_led_q_running) {
# endif
i2c_led_send_CRWL(drvid);
i2c_led_select_page(drvid, 0);
#if I2C_LED_USE_DMA != 1
# if I2C_LED_USE_DMA != 1
}
#endif
# endif
*issidrv[drvid].onoff = 0; //Force start location offset to zero
*issidrv[drvid].onoff = 0; // Force start location offset to zero
i2c1_transmit(issidrv[drvid].addr, issidrv[drvid].onoff, ISSI3733_PG0_BYTES, 0);
}
void i2c_led_send_mode_op_gcr(uint8_t drvid, uint8_t mode, uint8_t operation)
{
uint8_t i2cdata[] = { ISSI3733_CR, mode | operation, gcr_actual};
void i2c_led_send_mode_op_gcr(uint8_t drvid, uint8_t mode, uint8_t operation) {
uint8_t i2cdata[] = {ISSI3733_CR, mode | operation, gcr_actual};
i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0);
}
void i2c_led_send_pur_pdr(uint8_t drvid, uint8_t pur, uint8_t pdr)
{
uint8_t i2cdata[] = { ISSI3733_SWYR_PUR, pur, pdr };
void i2c_led_send_pur_pdr(uint8_t drvid, uint8_t pur, uint8_t pdr) {
uint8_t i2cdata[] = {ISSI3733_SWYR_PUR, pur, pdr};
i2c1_transmit(issidrv[drvid].addr, i2cdata, sizeof(i2cdata), 0);
}
void i2c_led_send_pwm(uint8_t drvid)
{
#if I2C_LED_USE_DMA != 1
if (!i2c_led_q_running)
{
#endif
void i2c_led_send_pwm(uint8_t drvid) {
# if I2C_LED_USE_DMA != 1
if (!i2c_led_q_running) {
# endif
i2c_led_send_CRWL(drvid);
i2c_led_select_page(drvid, 0);
#if I2C_LED_USE_DMA != 1
# if I2C_LED_USE_DMA != 1
}
#endif
# endif
*issidrv[drvid].pwm = 0; //Force start location offset to zero
*issidrv[drvid].pwm = 0; // Force start location offset to zero
i2c1_transmit(issidrv[drvid].addr, issidrv[drvid].pwm, ISSI3733_PG1_BYTES, 0);
}
uint8_t I2C3733_Init_Control(void)
{
uint8_t I2C3733_Init_Control(void) {
DBGC(DC_I2C3733_INIT_CONTROL_BEGIN);
//Hardware state shutdown on boot
//USB state machine will enable driver when communication is ready
// Hardware state shutdown on boot
// USB state machine will enable driver when communication is ready
I2C3733_Control_Set(0);
wait_ms(1);
@ -277,25 +285,24 @@ uint8_t I2C3733_Init_Control(void)
return 1;
}
uint8_t I2C3733_Init_Drivers(void)
{
uint8_t I2C3733_Init_Drivers(void) {
DBGC(DC_I2C3733_INIT_DRIVERS_BEGIN);
gcr_actual = ISSI3733_GCR_DEFAULT;
gcr_actual = ISSI3733_GCR_DEFAULT;
gcr_actual_last = gcr_actual;
if (gcr_actual > LED_GCR_MAX) gcr_actual = LED_GCR_MAX;
gcr_desired = gcr_actual;
//Set up master device
// Set up master device
i2c_led_send_CRWL(0);
i2c_led_select_page(0, 3);
i2c_led_send_mode_op_gcr(0, 0, ISSI3733_CR_SSD_NORMAL); //No SYNC due to brightness mismatch with second driver
i2c_led_send_mode_op_gcr(0, 0, ISSI3733_CR_SSD_NORMAL); // No SYNC due to brightness mismatch with second driver
//Set up slave device
// Set up slave device
i2c_led_send_CRWL(1);
i2c_led_select_page(1, 3);
i2c_led_send_mode_op_gcr(1, 0, ISSI3733_CR_SSD_NORMAL); //No SYNC due to brightness mismatch with first driver and slight flicker at rgb values 1,2
i2c_led_send_mode_op_gcr(1, 0, ISSI3733_CR_SSD_NORMAL); // No SYNC due to brightness mismatch with first driver and slight flicker at rgb values 1,2
i2c_led_send_CRWL(0);
i2c_led_select_page(0, 3);
@ -310,51 +317,54 @@ uint8_t I2C3733_Init_Drivers(void)
return 1;
}
void I2C_DMAC_LED_Init(void)
{
void I2C_DMAC_LED_Init(void) {
Dmac *dmac = DMAC;
DBGC(DC_I2C_DMAC_LED_INIT_BEGIN);
//Disable device
dmac->CTRL.bit.DMAENABLE = 0; //Disable DMAC
while (dmac->CTRL.bit.DMAENABLE) {} //Wait for disabled state in case of ongoing transfers
dmac->CTRL.bit.SWRST = 1; //Software Reset DMAC
while (dmac->CTRL.bit.SWRST) {} //Wait for software reset to complete
// Disable device
dmac->CTRL.bit.DMAENABLE = 0; // Disable DMAC
while (dmac->CTRL.bit.DMAENABLE) {
} // Wait for disabled state in case of ongoing transfers
dmac->CTRL.bit.SWRST = 1; // Software Reset DMAC
while (dmac->CTRL.bit.SWRST) {
} // Wait for software reset to complete
//Configure device
dmac->BASEADDR.reg = (uint32_t)&dmac_desc; //Set descriptor base address
dmac->WRBADDR.reg = (uint32_t)&dmac_desc_wb; //Set descriptor write back address
dmac->CTRL.reg |= 0x0f00; //Handle all priorities (LVL0-3)
// Configure device
dmac->BASEADDR.reg = (uint32_t)&dmac_desc; // Set descriptor base address
dmac->WRBADDR.reg = (uint32_t)&dmac_desc_wb; // Set descriptor write back address
dmac->CTRL.reg |= 0x0f00; // Handle all priorities (LVL0-3)
//Disable channel
dmac->Channel[0].CHCTRLA.bit.ENABLE = 0; //Disable the channel
while (dmac->Channel[0].CHCTRLA.bit.ENABLE) {} //Wait for disabled state in case of ongoing transfers
dmac->Channel[0].CHCTRLA.bit.SWRST = 1; //Software Reset the channel
while (dmac->Channel[0].CHCTRLA.bit.SWRST) {} //Wait for software reset to complete
// Disable channel
dmac->Channel[0].CHCTRLA.bit.ENABLE = 0; // Disable the channel
while (dmac->Channel[0].CHCTRLA.bit.ENABLE) {
} // Wait for disabled state in case of ongoing transfers
dmac->Channel[0].CHCTRLA.bit.SWRST = 1; // Software Reset the channel
while (dmac->Channel[0].CHCTRLA.bit.SWRST) {
} // Wait for software reset to complete
//Configure channel
dmac->Channel[0].CHCTRLA.bit.THRESHOLD = 0; //1BEAT
dmac->Channel[0].CHCTRLA.bit.BURSTLEN = 0; //SINGLE
dmac->Channel[0].CHCTRLA.bit.TRIGACT = 2; //BURST
dmac->Channel[0].CHCTRLA.bit.TRIGSRC = SERCOM1_DMAC_ID_TX; //Trigger source
dmac->Channel[0].CHCTRLA.bit.RUNSTDBY = 1; //Run in standby
// Configure channel
dmac->Channel[0].CHCTRLA.bit.THRESHOLD = 0; // 1BEAT
dmac->Channel[0].CHCTRLA.bit.BURSTLEN = 0; // SINGLE
dmac->Channel[0].CHCTRLA.bit.TRIGACT = 2; // BURST
dmac->Channel[0].CHCTRLA.bit.TRIGSRC = SERCOM1_DMAC_ID_TX; // Trigger source
dmac->Channel[0].CHCTRLA.bit.RUNSTDBY = 1; // Run in standby
NVIC_EnableIRQ(DMAC_0_IRQn);
dmac->Channel[0].CHINTENSET.bit.TCMPL = 1;
dmac->Channel[0].CHINTENSET.bit.TERR = 1;
dmac->Channel[0].CHINTENSET.bit.TERR = 1;
//Enable device
dmac->CTRL.bit.DMAENABLE = 1; //Enable DMAC
while (dmac->CTRL.bit.DMAENABLE == 0) {} //Wait for enable state
// Enable device
dmac->CTRL.bit.DMAENABLE = 1; // Enable DMAC
while (dmac->CTRL.bit.DMAENABLE == 0) {
} // Wait for enable state
DBGC(DC_I2C_DMAC_LED_INIT_COMPLETE);
}
//state = 1 enable
//state = 0 disable
void I2C3733_Control_Set(uint8_t state)
{
// state = 1 enable
// state = 0 disable
void I2C3733_Control_Set(uint8_t state) {
DBGC(DC_I2C3733_CONTROL_SET_BEGIN);
sr_exp_data.bit.SDB_N = (state == 1 ? 1 : 0);
@ -363,131 +373,111 @@ void I2C3733_Control_Set(uint8_t state)
DBGC(DC_I2C3733_CONTROL_SET_COMPLETE);
}
void i2c_led_desc_defaults(void)
{
dmac_desc.BTCTRL.bit.STEPSIZE = 0; //SRCINC used in favor for auto 1 inc
dmac_desc.BTCTRL.bit.STEPSEL = 0; //SRCINC used in favor for auto 1 inc
dmac_desc.BTCTRL.bit.DSTINC = 0; //The Destination Address Increment is disabled
dmac_desc.BTCTRL.bit.SRCINC = 1; //The Source Address Increment is enabled (Inc by 1)
dmac_desc.BTCTRL.bit.BEATSIZE = 0; //8-bit bus transfer
dmac_desc.BTCTRL.bit.BLOCKACT = 0; //Channel will be disabled if it is the last block transfer in the transaction
dmac_desc.BTCTRL.bit.EVOSEL = 0; //Event generation disabled
dmac_desc.BTCTRL.bit.VALID = 1; //Set dmac valid
void i2c_led_desc_defaults(void) {
dmac_desc.BTCTRL.bit.STEPSIZE = 0; // SRCINC used in favor for auto 1 inc
dmac_desc.BTCTRL.bit.STEPSEL = 0; // SRCINC used in favor for auto 1 inc
dmac_desc.BTCTRL.bit.DSTINC = 0; // The Destination Address Increment is disabled
dmac_desc.BTCTRL.bit.SRCINC = 1; // The Source Address Increment is enabled (Inc by 1)
dmac_desc.BTCTRL.bit.BEATSIZE = 0; // 8-bit bus transfer
dmac_desc.BTCTRL.bit.BLOCKACT = 0; // Channel will be disabled if it is the last block transfer in the transaction
dmac_desc.BTCTRL.bit.EVOSEL = 0; // Event generation disabled
dmac_desc.BTCTRL.bit.VALID = 1; // Set dmac valid
}
void i2c_led_prepare_send_dma(uint8_t *data, uint8_t len)
{
void i2c_led_prepare_send_dma(uint8_t *data, uint8_t len) {
i2c_led_desc_defaults();
dmac_desc.BTCNT.reg = len;
dmac_desc.SRCADDR.reg = (uint32_t)data + len;
dmac_desc.DSTADDR.reg = (uint32_t)&SERCOM1->I2CM.DATA.reg;
dmac_desc.BTCNT.reg = len;
dmac_desc.SRCADDR.reg = (uint32_t)data + len;
dmac_desc.DSTADDR.reg = (uint32_t)&SERCOM1->I2CM.DATA.reg;
dmac_desc.DESCADDR.reg = 0;
}
void i2c_led_begin_dma(uint8_t drvid)
{
DMAC->Channel[0].CHCTRLA.bit.ENABLE = 1; //Enable the channel
void i2c_led_begin_dma(uint8_t drvid) {
DMAC->Channel[0].CHCTRLA.bit.ENABLE = 1; // Enable the channel
SERCOM1->I2CM.ADDR.reg = (dmac_desc.BTCNT.reg << 16) | 0x2000 | issidrv[drvid].addr; //Begin transfer
SERCOM1->I2CM.ADDR.reg = (dmac_desc.BTCNT.reg << 16) | 0x2000 | issidrv[drvid].addr; // Begin transfer
}
void i2c_led_send_CRWL_dma(uint8_t drvid)
{
*(dma_sendbuf+0) = ISSI3733_CMDRWL;
*(dma_sendbuf+1) = ISSI3733_CMDRWL_WRITE_ENABLE_ONCE;
void i2c_led_send_CRWL_dma(uint8_t drvid) {
*(dma_sendbuf + 0) = ISSI3733_CMDRWL;
*(dma_sendbuf + 1) = ISSI3733_CMDRWL_WRITE_ENABLE_ONCE;
i2c_led_prepare_send_dma(dma_sendbuf, 2);
i2c_led_begin_dma(drvid);
}
void i2c_led_select_page_dma(uint8_t drvid, uint8_t pageno)
{
*(dma_sendbuf+0) = ISSI3733_CMDR;
*(dma_sendbuf+1) = pageno;
void i2c_led_select_page_dma(uint8_t drvid, uint8_t pageno) {
*(dma_sendbuf + 0) = ISSI3733_CMDR;
*(dma_sendbuf + 1) = pageno;
i2c_led_prepare_send_dma(dma_sendbuf, 2);
i2c_led_begin_dma(drvid);
}
void i2c_led_send_GCR_dma(uint8_t drvid)
{
*(dma_sendbuf+0) = ISSI3733_GCCR;
*(dma_sendbuf+1) = gcr_actual;
void i2c_led_send_GCR_dma(uint8_t drvid) {
*(dma_sendbuf + 0) = ISSI3733_GCCR;
*(dma_sendbuf + 1) = gcr_actual;
i2c_led_prepare_send_dma(dma_sendbuf, 2);
i2c_led_begin_dma(drvid);
}
void i2c_led_send_pwm_dma(uint8_t drvid)
{
//Note: This copies the CURRENT pwm buffer, which may be getting modified
void i2c_led_send_pwm_dma(uint8_t drvid) {
// Note: This copies the CURRENT pwm buffer, which may be getting modified
memcpy(dma_sendbuf, issidrv[drvid].pwm, ISSI3733_PG1_BYTES);
*dma_sendbuf = 0; //Force start location offset to zero
*dma_sendbuf = 0; // Force start location offset to zero
i2c_led_prepare_send_dma(dma_sendbuf, ISSI3733_PG1_BYTES);
i2c_led_begin_dma(drvid);
}
void i2c_led_send_onoff_dma(uint8_t drvid)
{
//Note: This copies the CURRENT onoff buffer, which may be getting modified
void i2c_led_send_onoff_dma(uint8_t drvid) {
// Note: This copies the CURRENT onoff buffer, which may be getting modified
memcpy(dma_sendbuf, issidrv[drvid].onoff, ISSI3733_PG0_BYTES);
*dma_sendbuf = 0; //Force start location offset to zero
*dma_sendbuf = 0; // Force start location offset to zero
i2c_led_prepare_send_dma(dma_sendbuf, ISSI3733_PG0_BYTES);
i2c_led_begin_dma(drvid);
}
void i2c_led_q_init(void)
{
void i2c_led_q_init(void) {
memset(i2c_led_q, 0, I2C_Q_SIZE);
i2c_led_q_s = 0;
i2c_led_q_e = 0;
i2c_led_q_s = 0;
i2c_led_q_e = 0;
i2c_led_q_running = 0;
i2c_led_q_full = 0;
i2c_led_q_full = 0;
}
uint8_t i2c_led_q_isempty(void)
{
return i2c_led_q_s == i2c_led_q_e;
uint8_t i2c_led_q_isempty(void) { return i2c_led_q_s == i2c_led_q_e; }
uint8_t i2c_led_q_size(void) { return (i2c_led_q_e - i2c_led_q_s) % I2C_Q_SIZE; }
uint8_t i2c_led_q_available(void) {
return I2C_Q_SIZE - i2c_led_q_size() - 1; // Never allow end to meet start
}
uint8_t i2c_led_q_size(void)
{
return (i2c_led_q_e - i2c_led_q_s) % I2C_Q_SIZE;
}
void i2c_led_q_add(uint8_t cmd) {
// WARNING: Always request room before adding commands!
uint8_t i2c_led_q_available(void)
{
return I2C_Q_SIZE - i2c_led_q_size() - 1; //Never allow end to meet start
}
void i2c_led_q_add(uint8_t cmd)
{
//WARNING: Always request room before adding commands!
//Assign command
// Assign command
i2c_led_q[i2c_led_q_e] = cmd;
i2c_led_q_e = (i2c_led_q_e + 1) % I2C_Q_SIZE; //Move end up one or wrap
i2c_led_q_e = (i2c_led_q_e + 1) % I2C_Q_SIZE; // Move end up one or wrap
}
void i2c_led_q_s_advance(void)
{
i2c_led_q_s = (i2c_led_q_s + 1) % I2C_Q_SIZE; //Move start up one or wrap
void i2c_led_q_s_advance(void) {
i2c_led_q_s = (i2c_led_q_s + 1) % I2C_Q_SIZE; // Move start up one or wrap
}
//Always request room before adding commands
//PS: In case the queue somehow gets filled, it will reset if it can not clear up
//PS: Could only get this to happen through unrealistic timings to overload the I2C bus
uint8_t i2c_led_q_request_room(uint8_t request_size)
{
if (request_size > i2c_led_q_available())
{
// Always request room before adding commands
// PS: In case the queue somehow gets filled, it will reset if it can not clear up
// PS: Could only get this to happen through unrealistic timings to overload the I2C bus
uint8_t i2c_led_q_request_room(uint8_t request_size) {
if (request_size > i2c_led_q_available()) {
i2c_led_q_full++;
if (i2c_led_q_full >= 100) //Give the queue a chance to clear up
if (i2c_led_q_full >= 100) // Give the queue a chance to clear up
{
DBG_LED_ON;
I2C_DMAC_LED_Init();
@ -503,10 +493,8 @@ uint8_t i2c_led_q_request_room(uint8_t request_size)
return 1;
}
uint8_t i2c_led_q_run(void)
{
if (i2c_led_q_isempty())
{
uint8_t i2c_led_q_run(void) {
if (i2c_led_q_isempty()) {
i2c_led_q_running = 0;
return 0;
}
@ -515,72 +503,62 @@ uint8_t i2c_led_q_run(void)
i2c_led_q_running = 1;
#if I2C_LED_USE_DMA != 1
while (!i2c_led_q_isempty())
{
#endif
//run command
if (i2c_led_q[i2c_led_q_s] == I2C_Q_CRWL)
{
# if I2C_LED_USE_DMA != 1
while (!i2c_led_q_isempty()) {
# endif
// run command
if (i2c_led_q[i2c_led_q_s] == I2C_Q_CRWL) {
i2c_led_q_s_advance();
uint8_t drvid = i2c_led_q[i2c_led_q_s];
#if I2C_LED_USE_DMA == 1
# if I2C_LED_USE_DMA == 1
i2c_led_send_CRWL_dma(drvid);
#else
i2c_led_send_CRWL(drvid);
#endif
}
else if (i2c_led_q[i2c_led_q_s] == I2C_Q_PAGE_SELECT)
{
# else
i2c_led_send_CRWL(drvid);
# endif
} else if (i2c_led_q[i2c_led_q_s] == I2C_Q_PAGE_SELECT) {
i2c_led_q_s_advance();
uint8_t drvid = i2c_led_q[i2c_led_q_s];
i2c_led_q_s_advance();
uint8_t page = i2c_led_q[i2c_led_q_s];
#if I2C_LED_USE_DMA == 1
# if I2C_LED_USE_DMA == 1
i2c_led_select_page_dma(drvid, page);
#else
i2c_led_select_page(drvid, page);
#endif
}
else if (i2c_led_q[i2c_led_q_s] == I2C_Q_PWM)
{
# else
i2c_led_select_page(drvid, page);
# endif
} else if (i2c_led_q[i2c_led_q_s] == I2C_Q_PWM) {
i2c_led_q_s_advance();
uint8_t drvid = i2c_led_q[i2c_led_q_s];
#if I2C_LED_USE_DMA == 1
# if I2C_LED_USE_DMA == 1
i2c_led_send_pwm_dma(drvid);
#else
i2c_led_send_pwm(drvid);
#endif
}
else if (i2c_led_q[i2c_led_q_s] == I2C_Q_GCR)
{
# else
i2c_led_send_pwm(drvid);
# endif
} else if (i2c_led_q[i2c_led_q_s] == I2C_Q_GCR) {
i2c_led_q_s_advance();
uint8_t drvid = i2c_led_q[i2c_led_q_s];
#if I2C_LED_USE_DMA == 1
# if I2C_LED_USE_DMA == 1
i2c_led_send_GCR_dma(drvid);
#else
i2c_led_send_GCR(drvid);
#endif
}
else if (i2c_led_q[i2c_led_q_s] == I2C_Q_ONOFF)
{
# else
i2c_led_send_GCR(drvid);
# endif
} else if (i2c_led_q[i2c_led_q_s] == I2C_Q_ONOFF) {
i2c_led_q_s_advance();
uint8_t drvid = i2c_led_q[i2c_led_q_s];
#if I2C_LED_USE_DMA == 1
# if I2C_LED_USE_DMA == 1
i2c_led_send_onoff_dma(drvid);
#else
i2c_led_send_onoff(drvid);
#endif
# else
i2c_led_send_onoff(drvid);
# endif
}
i2c_led_q_s_advance(); //Advance last run command or if the command byte was not serviced
i2c_led_q_s_advance(); // Advance last run command or if the command byte was not serviced
#if I2C_LED_USE_DMA != 1
# if I2C_LED_USE_DMA != 1
}
i2c_led_q_running = 0;
#endif
# endif
return 1;
}
#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)
#endif // !defined(MD_BOOTLOADER) && defined(RGB_MATRIX_ENABLE)

View file

@ -20,89 +20,85 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef MD_BOOTLOADER
#include "samd51j18a.h"
#include "issi3733_driver.h"
#include "config.h"
# include "samd51j18a.h"
# include "issi3733_driver.h"
# include "config.h"
__attribute__((__aligned__(16)))
DmacDescriptor dmac_desc;
__attribute__((__aligned__(16)))
DmacDescriptor dmac_desc_wb;
__attribute__((__aligned__(16))) DmacDescriptor dmac_desc;
__attribute__((__aligned__(16))) DmacDescriptor dmac_desc_wb;
uint8_t I2C3733_Init_Control(void);
uint8_t I2C3733_Init_Drivers(void);
void I2C3733_Control_Set(uint8_t state);
void I2C_DMAC_LED_Init(void);
void I2C3733_Control_Set(uint8_t state);
void I2C_DMAC_LED_Init(void);
#define I2C_Q_SIZE 100
# define I2C_Q_SIZE 100
#define I2C_Q_NA 100
#define I2C_Q_CRWL 101
#define I2C_Q_PAGE_SELECT 102
#define I2C_Q_PWM 103
#define I2C_Q_GCR 104
#define I2C_Q_ONOFF 105
# define I2C_Q_NA 100
# define I2C_Q_CRWL 101
# define I2C_Q_PAGE_SELECT 102
# define I2C_Q_PWM 103
# define I2C_Q_GCR 104
# define I2C_Q_ONOFF 105
#define I2C_DMA_MAX_SEND 255
# define I2C_DMA_MAX_SEND 255
extern volatile uint8_t i2c_led_q_running;
#define I2C_LED_Q_PWM(a) { \
if (i2c_led_q_request_room(7)) \
{ \
i2c_led_q_add(I2C_Q_CRWL); \
i2c_led_q_add(a); \
i2c_led_q_add(I2C_Q_PAGE_SELECT); \
i2c_led_q_add(a); \
i2c_led_q_add(ISSI3733_PG_PWM); \
i2c_led_q_add(I2C_Q_PWM); \
i2c_led_q_add(a); \
} \
}
# define I2C_LED_Q_PWM(a) \
{ \
if (i2c_led_q_request_room(7)) { \
i2c_led_q_add(I2C_Q_CRWL); \
i2c_led_q_add(a); \
i2c_led_q_add(I2C_Q_PAGE_SELECT); \
i2c_led_q_add(a); \
i2c_led_q_add(ISSI3733_PG_PWM); \
i2c_led_q_add(I2C_Q_PWM); \
i2c_led_q_add(a); \
} \
}
#define I2C_LED_Q_GCR(a) { \
if (i2c_led_q_request_room(7)) \
{ \
i2c_led_q_add(I2C_Q_CRWL); \
i2c_led_q_add(a); \
i2c_led_q_add(I2C_Q_PAGE_SELECT); \
i2c_led_q_add(a); \
i2c_led_q_add(ISSI3733_PG_FN); \
i2c_led_q_add(I2C_Q_GCR); \
i2c_led_q_add(a); \
} \
}
# define I2C_LED_Q_GCR(a) \
{ \
if (i2c_led_q_request_room(7)) { \
i2c_led_q_add(I2C_Q_CRWL); \
i2c_led_q_add(a); \
i2c_led_q_add(I2C_Q_PAGE_SELECT); \
i2c_led_q_add(a); \
i2c_led_q_add(ISSI3733_PG_FN); \
i2c_led_q_add(I2C_Q_GCR); \
i2c_led_q_add(a); \
} \
}
#define I2C_LED_Q_ONOFF(a) { \
if (i2c_led_q_request_room(7)) \
{ \
i2c_led_q_add(I2C_Q_CRWL); \
i2c_led_q_add(a); \
i2c_led_q_add(I2C_Q_PAGE_SELECT); \
i2c_led_q_add(a); \
i2c_led_q_add(ISSI3733_PG_ONOFF); \
i2c_led_q_add(I2C_Q_ONOFF); \
i2c_led_q_add(a); \
} \
}
# define I2C_LED_Q_ONOFF(a) \
{ \
if (i2c_led_q_request_room(7)) { \
i2c_led_q_add(I2C_Q_CRWL); \
i2c_led_q_add(a); \
i2c_led_q_add(I2C_Q_PAGE_SELECT); \
i2c_led_q_add(a); \
i2c_led_q_add(ISSI3733_PG_ONOFF); \
i2c_led_q_add(I2C_Q_ONOFF); \
i2c_led_q_add(a); \
} \
}
void i2c_led_q_init(void);
void i2c_led_q_add(uint8_t cmd);
void i2c_led_q_s_advance(void);
void i2c_led_q_init(void);
void i2c_led_q_add(uint8_t cmd);
void i2c_led_q_s_advance(void);
uint8_t i2c_led_q_size(void);
uint8_t i2c_led_q_request_room(uint8_t request_size);
uint8_t i2c_led_q_run(void);
void i2c1_init(void);
void i2c1_init(void);
uint8_t i2c1_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout);
void i2c1_stop(void);
void i2c1_stop(void);
#endif //MD_BOOTLOADER
#endif // MD_BOOTLOADER
void i2c0_init(void);
void i2c0_init(void);
uint8_t i2c0_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout);
void i2c0_stop(void);
#endif // _I2C_MASTER_H_
void i2c0_stop(void);
#endif // _I2C_MASTER_H_

View file

@ -18,31 +18,31 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef _ISSI3733_DRIVER_H_
#define _ISSI3733_DRIVER_H_
//ISII3733 Registers
// ISII3733 Registers
#define ISSI3733_CMDR 0xFD //Command Register (Write Only)
#define ISSI3733_CMDR 0xFD // Command Register (Write Only)
#define ISSI3733_CMDRWL 0xFE //Command Register Write Lock (Read/Write)
#define ISSI3733_CMDRWL_WRITE_DISABLE 0x00 //Lock register
#define ISSI3733_CMDRWL_WRITE_ENABLE_ONCE 0xC5 //Enable one write to register then reset to locked
#define ISSI3733_CMDRWL 0xFE // Command Register Write Lock (Read/Write)
#define ISSI3733_CMDRWL_WRITE_DISABLE 0x00 // Lock register
#define ISSI3733_CMDRWL_WRITE_ENABLE_ONCE 0xC5 // Enable one write to register then reset to locked
#define ISSI3733_IMR 0xF0 //Interrupt Mask Register (Write Only)
#define ISSI3733_IMR_IAC_ON 0x08 //Auto Clear Interrupt Bit - Interrupt auto clear when INTB stay low exceeds 8ms
#define ISSI3733_IMR_IAB_ON 0x04 //Auto Breath Interrupt Bit - Enable auto breath loop finish interrupt
#define ISSI3733_IMR_IS_ON 0x02 //Dot Short Interrupt Bit - Enable dot short interrupt
#define ISSI3733_IMR_IO_ON 0x01 //Dot Open Interrupt Bit - Enable dot open interrupt
#define ISSI3733_IMR 0xF0 // Interrupt Mask Register (Write Only)
#define ISSI3733_IMR_IAC_ON 0x08 // Auto Clear Interrupt Bit - Interrupt auto clear when INTB stay low exceeds 8ms
#define ISSI3733_IMR_IAB_ON 0x04 // Auto Breath Interrupt Bit - Enable auto breath loop finish interrupt
#define ISSI3733_IMR_IS_ON 0x02 // Dot Short Interrupt Bit - Enable dot short interrupt
#define ISSI3733_IMR_IO_ON 0x01 // Dot Open Interrupt Bit - Enable dot open interrupt
#define ISSI3733_ISR 0xF1 //Interrupt Status Register (Read Only)
#define ISSI3733_ISR_ABM3_FINISH 0x10 //Auto Breath Mode 3 Finish Bit - ABM3 finished
#define ISSI3733_ISR_ABM2_FINISH 0x08 //Auto Breath Mode 2 Finish Bit - ABM2 finished
#define ISSI3733_ISR_ABM1_FINISH 0x04 //Auto Breath Mode 1 Finish Bit - ABM1 finished
#define ISSI3733_ISR_SB 0x02 //Short Bit - Shorted
#define ISSI3733_ISR_OB 0x01 //Open Bit - Opened
#define ISSI3733_ISR 0xF1 // Interrupt Status Register (Read Only)
#define ISSI3733_ISR_ABM3_FINISH 0x10 // Auto Breath Mode 3 Finish Bit - ABM3 finished
#define ISSI3733_ISR_ABM2_FINISH 0x08 // Auto Breath Mode 2 Finish Bit - ABM2 finished
#define ISSI3733_ISR_ABM1_FINISH 0x04 // Auto Breath Mode 1 Finish Bit - ABM1 finished
#define ISSI3733_ISR_SB 0x02 // Short Bit - Shorted
#define ISSI3733_ISR_OB 0x01 // Open Bit - Opened
#define ISSI3733_PG0 0x00 //LED Control Register
#define ISSI3733_PG1 0x01 //PWM Register
#define ISSI3733_PG2 0x02 //Auto Breath Mode Register
#define ISSI3733_PG3 0x03 //Function Register
#define ISSI3733_PG0 0x00 // LED Control Register
#define ISSI3733_PG1 0x01 // PWM Register
#define ISSI3733_PG2 0x02 // Auto Breath Mode Register
#define ISSI3733_PG3 0x03 // Function Register
#define ISSI3733_PG_ONOFF ISSI3733_PG0
#define ISSI3733_PG_OR ISSI3733_PG0
@ -51,88 +51,88 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define ISSI3733_PG_ABM ISSI3733_PG2
#define ISSI3733_PG_FN ISSI3733_PG3
#define ISSI3733_CR 0x00 //Configuration Register
#define ISSI3733_CR 0x00 // Configuration Register
//PG3: Configuration Register: Synchronize Configuration
#define ISSI3733_CR_SYNC_MASTER 0x40 //Master
#define ISSI3733_CR_SYNC_SLAVE 0x80 //Slave
#define ISSI3733_CR_SYNC_HIGH_IMP 0xC0 //High Impedance
// PG3: Configuration Register: Synchronize Configuration
#define ISSI3733_CR_SYNC_MASTER 0x40 // Master
#define ISSI3733_CR_SYNC_SLAVE 0x80 // Slave
#define ISSI3733_CR_SYNC_HIGH_IMP 0xC0 // High Impedance
//PG3: Configuration Register: Open/Short Detection Enable Bit
// PG3: Configuration Register: Open/Short Detection Enable Bit
//#define ISSI3733_CR_OSD_DISABLE 0x00 //Disable open/short detection
#define ISSI3733_CR_OSD_ENABLE 0x04 //Enable open/short detection
#define ISSI3733_CR_OSD_ENABLE 0x04 // Enable open/short detection
//PG3: Configuration Register: Auto Breath Enable
// PG3: Configuration Register: Auto Breath Enable
//#define ISSI3733_CR_B_EN_PWM 0x00 //PWM Mode Enable
#define ISSI3733_CR_B_EN_AUTO 0x02 //Auto Breath Mode Enable
#define ISSI3733_CR_B_EN_AUTO 0x02 // Auto Breath Mode Enable
//PG3: Configuration Register: Software Shutdown Control
// PG3: Configuration Register: Software Shutdown Control
//#define ISSI3733_CR_SSD_SHUTDOWN 0x00 //Software shutdown
#define ISSI3733_CR_SSD_NORMAL 0x01 //Normal operation
#define ISSI3733_CR_SSD_NORMAL 0x01 // Normal operation
#define ISSI3733_GCCR 0x01 //Global Current Control Register
#define ISSI3733_GCCR 0x01 // Global Current Control Register
//1 Byte, Iout = (GCC / 256) * (840 / Rext)
//TODO: Give user define for Rext
// 1 Byte, Iout = (GCC / 256) * (840 / Rext)
// TODO: Give user define for Rext
//PG3: Auto Breath Control Register 1
#define ISSI3733_ABCR1_ABM1 0x02 //Auto Breath Control Register 1 of ABM-1
#define ISSI3733_ABCR1_ABM2 0x06 //Auto Breath Control Register 1 of ABM-2
#define ISSI3733_ABCR1_ABM3 0x0A //Auto Breath Control Register 1 of ABM-3
// PG3: Auto Breath Control Register 1
#define ISSI3733_ABCR1_ABM1 0x02 // Auto Breath Control Register 1 of ABM-1
#define ISSI3733_ABCR1_ABM2 0x06 // Auto Breath Control Register 1 of ABM-2
#define ISSI3733_ABCR1_ABM3 0x0A // Auto Breath Control Register 1 of ABM-3
//Rise time
#define ISSI3733_ABCR1_T1_0021 0x00 //0.21s
#define ISSI3733_ABCR1_T1_0042 0x20 //0.42s
#define ISSI3733_ABCR1_T1_0084 0x40 //0.84s
#define ISSI3733_ABCR1_T1_0168 0x60 //1.68s
#define ISSI3733_ABCR1_T1_0336 0x80 //3.36s
#define ISSI3733_ABCR1_T1_0672 0xA0 //6.72s
#define ISSI3733_ABCR1_T1_1344 0xC0 //13.44s
#define ISSI3733_ABCR1_T1_2688 0xE0 //26.88s
// Rise time
#define ISSI3733_ABCR1_T1_0021 0x00 // 0.21s
#define ISSI3733_ABCR1_T1_0042 0x20 // 0.42s
#define ISSI3733_ABCR1_T1_0084 0x40 // 0.84s
#define ISSI3733_ABCR1_T1_0168 0x60 // 1.68s
#define ISSI3733_ABCR1_T1_0336 0x80 // 3.36s
#define ISSI3733_ABCR1_T1_0672 0xA0 // 6.72s
#define ISSI3733_ABCR1_T1_1344 0xC0 // 13.44s
#define ISSI3733_ABCR1_T1_2688 0xE0 // 26.88s
//Max value time
#define ISSI3733_ABCR1_T2_0000 0x00 //0s
#define ISSI3733_ABCR1_T2_0021 0x02 //0.21s
#define ISSI3733_ABCR1_T2_0042 0x04 //0.42s
#define ISSI3733_ABCR1_T2_0084 0x06 //0.84s
#define ISSI3733_ABCR1_T2_0168 0x08 //1.68s
#define ISSI3733_ABCR1_T2_0336 0x0A //3.36s
#define ISSI3733_ABCR1_T2_0672 0x0C //6.72s
#define ISSI3733_ABCR1_T2_1344 0x0E //13.44s
#define ISSI3733_ABCR1_T2_2688 0x10 //26.88s
// Max value time
#define ISSI3733_ABCR1_T2_0000 0x00 // 0s
#define ISSI3733_ABCR1_T2_0021 0x02 // 0.21s
#define ISSI3733_ABCR1_T2_0042 0x04 // 0.42s
#define ISSI3733_ABCR1_T2_0084 0x06 // 0.84s
#define ISSI3733_ABCR1_T2_0168 0x08 // 1.68s
#define ISSI3733_ABCR1_T2_0336 0x0A // 3.36s
#define ISSI3733_ABCR1_T2_0672 0x0C // 6.72s
#define ISSI3733_ABCR1_T2_1344 0x0E // 13.44s
#define ISSI3733_ABCR1_T2_2688 0x10 // 26.88s
//PG3: Auto Breath Control Register 2
#define ISSI3733_ABCR2_ABM1 0x03 //Auto Breath Control Register 2 of ABM-1
#define ISSI3733_ABCR2_ABM2 0x07 //Auto Breath Control Register 2 of ABM-2
#define ISSI3733_ABCR2_ABM3 0x0B //Auto Breath Control Register 2 of ABM-3
// PG3: Auto Breath Control Register 2
#define ISSI3733_ABCR2_ABM1 0x03 // Auto Breath Control Register 2 of ABM-1
#define ISSI3733_ABCR2_ABM2 0x07 // Auto Breath Control Register 2 of ABM-2
#define ISSI3733_ABCR2_ABM3 0x0B // Auto Breath Control Register 2 of ABM-3
//Fall time
#define ISSI3733_ABCR2_T3_0021 0x00 //0.21s
#define ISSI3733_ABCR2_T3_0042 0x20 //0.42s
#define ISSI3733_ABCR2_T3_0084 0x40 //0.84s
#define ISSI3733_ABCR2_T3_0168 0x60 //1.68s
#define ISSI3733_ABCR2_T3_0336 0x80 //3.36s
#define ISSI3733_ABCR2_T3_0672 0xA0 //6.72s
#define ISSI3733_ABCR2_T3_1344 0xC0 //13.44s
#define ISSI3733_ABCR2_T3_2688 0xE0 //26.88s
// Fall time
#define ISSI3733_ABCR2_T3_0021 0x00 // 0.21s
#define ISSI3733_ABCR2_T3_0042 0x20 // 0.42s
#define ISSI3733_ABCR2_T3_0084 0x40 // 0.84s
#define ISSI3733_ABCR2_T3_0168 0x60 // 1.68s
#define ISSI3733_ABCR2_T3_0336 0x80 // 3.36s
#define ISSI3733_ABCR2_T3_0672 0xA0 // 6.72s
#define ISSI3733_ABCR2_T3_1344 0xC0 // 13.44s
#define ISSI3733_ABCR2_T3_2688 0xE0 // 26.88s
//Min value time
#define ISSI3733_ABCR2_T4_0000 0x00 //0s
#define ISSI3733_ABCR2_T4_0021 0x02 //0.21s
#define ISSI3733_ABCR2_T4_0042 0x04 //0.42s
#define ISSI3733_ABCR2_T4_0084 0x06 //0.84s
#define ISSI3733_ABCR2_T4_0168 0x08 //1.68s
#define ISSI3733_ABCR2_T4_0336 0x0A //3.36s
#define ISSI3733_ABCR2_T4_0672 0x0C //6.72s
#define ISSI3733_ABCR2_T4_1344 0x0E //13.44s
#define ISSI3733_ABCR2_T4_2688 0x10 //26.88s
#define ISSI3733_ABCR2_T4_5376 0x12 //53.76s
#define ISSI3733_ABCR2_T4_10752 0x14 //107.52s
// Min value time
#define ISSI3733_ABCR2_T4_0000 0x00 // 0s
#define ISSI3733_ABCR2_T4_0021 0x02 // 0.21s
#define ISSI3733_ABCR2_T4_0042 0x04 // 0.42s
#define ISSI3733_ABCR2_T4_0084 0x06 // 0.84s
#define ISSI3733_ABCR2_T4_0168 0x08 // 1.68s
#define ISSI3733_ABCR2_T4_0336 0x0A // 3.36s
#define ISSI3733_ABCR2_T4_0672 0x0C // 6.72s
#define ISSI3733_ABCR2_T4_1344 0x0E // 13.44s
#define ISSI3733_ABCR2_T4_2688 0x10 // 26.88s
#define ISSI3733_ABCR2_T4_5376 0x12 // 53.76s
#define ISSI3733_ABCR2_T4_10752 0x14 // 107.52s
//PG3: Auto Breath Control Register 3
#define ISSI3733_ABCR3_ABM1 0x04 //Auto Breath Control Register 3 of ABM-1
#define ISSI3733_ABCR3_ABM2 0x08 //Auto Breath Control Register 3 of ABM-2
#define ISSI3733_ABCR3_ABM3 0x0C //Auto Breath Control Register 3 of ABM-3
// PG3: Auto Breath Control Register 3
#define ISSI3733_ABCR3_ABM1 0x04 // Auto Breath Control Register 3 of ABM-1
#define ISSI3733_ABCR3_ABM2 0x08 // Auto Breath Control Register 3 of ABM-2
#define ISSI3733_ABCR3_ABM3 0x0C // Auto Breath Control Register 3 of ABM-3
#define ISSI3733_ABCR3_LTA_LOOP_ENDLESS 0x00
#define ISSI3733_ABCR3_LTA_LOOP_1 0x01
@ -151,51 +151,51 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define ISSI3733_ABCR3_LTA_LOOP_14 0x0E
#define ISSI3733_ABCR3_LTA_LOOP_15 0x0F
//Loop Begin
// Loop Begin
#define ISSI3733_ABCR3_LB_T1 0x00
#define ISSI3733_ABCR3_LB_T2 0x10
#define ISSI3733_ABCR3_LB_T3 0x20
#define ISSI3733_ABCR3_LB_T4 0x30
//Loop End
#define ISSI3733_ABCR3_LE_T3 0x00 //End at Off state
#define ISSI3733_ABCR3_LE_T1 0x40 //End at On State
// Loop End
#define ISSI3733_ABCR3_LE_T3 0x00 // End at Off state
#define ISSI3733_ABCR3_LE_T1 0x40 // End at On State
//PG3: Auto Breath Control Register 4
#define ISSI3733_ABCR4_ABM1 0x05 //Auto Breath Control Register 4 of ABM-1
#define ISSI3733_ABCR4_ABM2 0x09 //Auto Breath Control Register 4 of ABM-2
#define ISSI3733_ABCR4_ABM3 0x0D //Auto Breath Control Register 4 of ABM-3
// PG3: Auto Breath Control Register 4
#define ISSI3733_ABCR4_ABM1 0x05 // Auto Breath Control Register 4 of ABM-1
#define ISSI3733_ABCR4_ABM2 0x09 // Auto Breath Control Register 4 of ABM-2
#define ISSI3733_ABCR4_ABM3 0x0D // Auto Breath Control Register 4 of ABM-3
#define ISSI3733_ABCR4_LTB_LOOP_ENDLESS 0x00
//Or 8bit loop times
// Or 8bit loop times
//PG3: Time Update Register
// PG3: Time Update Register
#define ISSI3733_TUR 0x0E
#define ISSI3733_TUR_UPDATE 0x00 //Write to update 02h~0Dh time registers after configuring
#define ISSI3733_TUR_UPDATE 0x00 // Write to update 02h~0Dh time registers after configuring
//PG3: SWy Pull-Up Resistor Selection Register
// PG3: SWy Pull-Up Resistor Selection Register
#define ISSI3733_SWYR_PUR 0x0F
#define ISSI3733_SWYR_PUR_NONE 0x00 //No pull-up resistor
#define ISSI3733_SWYR_PUR_500 0x01 //0.5k Ohm
#define ISSI3733_SWYR_PUR_1000 0x02 //1.0k Ohm
#define ISSI3733_SWYR_PUR_2000 0x03 //2.0k Ohm
#define ISSI3733_SWYR_PUR_4000 0x04 //4.0k Ohm
#define ISSI3733_SWYR_PUR_8000 0x05 //8.0k Ohm
#define ISSI3733_SWYR_PUR_16000 0x06 //16k Ohm
#define ISSI3733_SWYR_PUR_32000 0x07 //32k Ohm
#define ISSI3733_SWYR_PUR_NONE 0x00 // No pull-up resistor
#define ISSI3733_SWYR_PUR_500 0x01 // 0.5k Ohm
#define ISSI3733_SWYR_PUR_1000 0x02 // 1.0k Ohm
#define ISSI3733_SWYR_PUR_2000 0x03 // 2.0k Ohm
#define ISSI3733_SWYR_PUR_4000 0x04 // 4.0k Ohm
#define ISSI3733_SWYR_PUR_8000 0x05 // 8.0k Ohm
#define ISSI3733_SWYR_PUR_16000 0x06 // 16k Ohm
#define ISSI3733_SWYR_PUR_32000 0x07 // 32k Ohm
//PG3: CSx Pull-Down Resistor Selection Register
// PG3: CSx Pull-Down Resistor Selection Register
#define ISSI3733_CSXR_PDR 0x10
#define ISSI3733_CSXR_PDR_NONE 0x00 //No pull-down resistor
#define ISSI3733_CSXR_PDR_500 0x01 //0.5k Ohm
#define ISSI3733_CSXR_PDR_1000 0x02 //1.0k Ohm
#define ISSI3733_CSXR_PDR_2000 0x03 //2.0k Ohm
#define ISSI3733_CSXR_PDR_4000 0x04 //4.0k Ohm
#define ISSI3733_CSXR_PDR_8000 0x05 //8.0k Ohm
#define ISSI3733_CSXR_PDR_16000 0x06 //16k Ohm
#define ISSI3733_CSXR_PDR_32000 0x07 //32k Ohm
#define ISSI3733_CSXR_PDR_NONE 0x00 // No pull-down resistor
#define ISSI3733_CSXR_PDR_500 0x01 // 0.5k Ohm
#define ISSI3733_CSXR_PDR_1000 0x02 // 1.0k Ohm
#define ISSI3733_CSXR_PDR_2000 0x03 // 2.0k Ohm
#define ISSI3733_CSXR_PDR_4000 0x04 // 4.0k Ohm
#define ISSI3733_CSXR_PDR_8000 0x05 // 8.0k Ohm
#define ISSI3733_CSXR_PDR_16000 0x06 // 16k Ohm
#define ISSI3733_CSXR_PDR_32000 0x07 // 32k Ohm
//PG3: Reset Register
#define ISSI3733_RR 0x11 //Read to reset all registers to default values
// PG3: Reset Register
#define ISSI3733_RR 0x11 // Read to reset all registers to default values
#endif //_ISSI3733_DRIVER_H_
#endif //_ISSI3733_DRIVER_H_

View file

@ -22,24 +22,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <math.h>
#ifdef USE_MASSDROP_CONFIGURATOR
__attribute__((weak))
led_instruction_t led_instructions[] = { { .end = 1 } };
static void led_matrix_massdrop_config_override(int i);
#endif // USE_MASSDROP_CONFIGURATOR
__attribute__((weak)) led_instruction_t led_instructions[] = {{.end = 1}};
static void led_matrix_massdrop_config_override(int i);
#endif // USE_MASSDROP_CONFIGURATOR
void SERCOM1_0_Handler( void )
{
if (SERCOM1->I2CM.INTFLAG.bit.ERROR)
{
void SERCOM1_0_Handler(void) {
if (SERCOM1->I2CM.INTFLAG.bit.ERROR) {
SERCOM1->I2CM.INTFLAG.reg = SERCOM_I2CM_INTENCLR_ERROR;
}
}
void DMAC_0_Handler( void )
{
if (DMAC->Channel[0].CHINTFLAG.bit.TCMPL)
{
void DMAC_0_Handler(void) {
if (DMAC->Channel[0].CHINTFLAG.bit.TCMPL) {
DMAC->Channel[0].CHINTFLAG.reg = DMAC_CHINTENCLR_TCMPL;
i2c1_stop();
@ -51,8 +45,7 @@ void DMAC_0_Handler( void )
return;
}
if (DMAC->Channel[0].CHINTFLAG.bit.TERR)
{
if (DMAC->Channel[0].CHINTFLAG.bit.TERR) {
DMAC->Channel[0].CHINTFLAG.reg = DMAC_CHINTENCLR_TERR;
}
}
@ -60,118 +53,109 @@ void DMAC_0_Handler( void )
issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
issi3733_led_t led_map[ISSI3733_LED_COUNT] = ISSI3733_LED_MAP;
RGB led_buffer[ISSI3733_LED_COUNT];
RGB led_buffer[ISSI3733_LED_COUNT];
uint8_t gcr_desired;
uint8_t gcr_actual;
uint8_t gcr_actual_last;
#ifdef USE_MASSDROP_CONFIGURATOR
uint8_t gcr_breathe;
float breathe_mult;
float pomod;
float breathe_mult;
float pomod;
#endif
#define ACT_GCR_NONE 0
#define ACT_GCR_INC 1
#define ACT_GCR_DEC 2
#define ACT_GCR_NONE 0
#define ACT_GCR_INC 1
#define ACT_GCR_DEC 2
#define LED_GCR_STEP_AUTO 2
static uint8_t gcr_min_counter;
static uint8_t v_5v_cat_hit;
//WARNING: Automatic GCR is in place to prevent USB shutdown and LED driver overloading
void gcr_compute(void)
{
uint8_t action = ACT_GCR_NONE;
// WARNING: Automatic GCR is in place to prevent USB shutdown and LED driver overloading
void gcr_compute(void) {
uint8_t action = ACT_GCR_NONE;
uint8_t gcr_use = gcr_desired;
#ifdef USE_MASSDROP_CONFIGURATOR
if (led_animation_breathing)
{
if (led_animation_breathing) {
gcr_use = gcr_breathe;
}
#endif
//If the 5v takes a catastrophic hit, disable the LED drivers briefly, assert auto gcr mode, min gcr and let the auto take over
if (v_5v < V5_CAT)
{
// If the 5v takes a catastrophic hit, disable the LED drivers briefly, assert auto gcr mode, min gcr and let the auto take over
if (v_5v < V5_CAT) {
I2C3733_Control_Set(0);
//CDC_print("USB: WARNING: 5V catastrophic level reached! Disabling LED drivers!\r\n"); //Blocking print is bad here!
v_5v_cat_hit = 20; //~100ms recover
gcr_actual = 0; //Minimize GCR
usb_gcr_auto = 1; //Force auto mode enabled
// CDC_print("USB: WARNING: 5V catastrophic level reached! Disabling LED drivers!\r\n"); //Blocking print is bad here!
v_5v_cat_hit = 20; //~100ms recover
gcr_actual = 0; // Minimize GCR
usb_gcr_auto = 1; // Force auto mode enabled
return;
}
else if (v_5v_cat_hit > 1)
{
} else if (v_5v_cat_hit > 1) {
v_5v_cat_hit--;
return;
}
else if (v_5v_cat_hit == 1)
{
} else if (v_5v_cat_hit == 1) {
I2C3733_Control_Set(1);
CDC_print("USB: WARNING: Re-enabling LED drivers\r\n");
v_5v_cat_hit = 0;
return;
}
if (usb_gcr_auto)
{
if (v_5v_avg < V5_LOW) action = ACT_GCR_DEC;
else if (v_5v_avg > V5_HIGH && gcr_actual < gcr_use) action = ACT_GCR_INC;
else if (gcr_actual > gcr_use) action = ACT_GCR_DEC;
}
else
{
if (gcr_actual < gcr_use) action = ACT_GCR_INC;
else if (gcr_actual > gcr_use) action = ACT_GCR_DEC;
if (usb_gcr_auto) {
if (v_5v_avg < V5_LOW)
action = ACT_GCR_DEC;
else if (v_5v_avg > V5_HIGH && gcr_actual < gcr_use)
action = ACT_GCR_INC;
else if (gcr_actual > gcr_use)
action = ACT_GCR_DEC;
} else {
if (gcr_actual < gcr_use)
action = ACT_GCR_INC;
else if (gcr_actual > gcr_use)
action = ACT_GCR_DEC;
}
if (action == ACT_GCR_NONE)
{
if (action == ACT_GCR_NONE) {
gcr_min_counter = 0;
}
else if (action == ACT_GCR_INC)
{
if (LED_GCR_STEP_AUTO > LED_GCR_MAX - gcr_actual) gcr_actual = LED_GCR_MAX; //Obey max and prevent wrapping
else gcr_actual += LED_GCR_STEP_AUTO;
} else if (action == ACT_GCR_INC) {
if (LED_GCR_STEP_AUTO > LED_GCR_MAX - gcr_actual)
gcr_actual = LED_GCR_MAX; // Obey max and prevent wrapping
else
gcr_actual += LED_GCR_STEP_AUTO;
gcr_min_counter = 0;
}
else if (action == ACT_GCR_DEC)
{
if (LED_GCR_STEP_AUTO > gcr_actual) //Prevent wrapping
} else if (action == ACT_GCR_DEC) {
if (LED_GCR_STEP_AUTO > gcr_actual) // Prevent wrapping
{
gcr_actual = 0;
//At this point, power can no longer be cut from the LED drivers, so focus on cutting out extra port if active
if (usb_extra_state != USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) //If not in a wait for replug state
// At this point, power can no longer be cut from the LED drivers, so focus on cutting out extra port if active
if (usb_extra_state != USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG) // If not in a wait for replug state
{
if (usb_extra_state == USB_EXTRA_STATE_ENABLED) //If extra usb is enabled
if (usb_extra_state == USB_EXTRA_STATE_ENABLED) // If extra usb is enabled
{
gcr_min_counter++;
if (gcr_min_counter > 200) //5ms per check = 1s delay
if (gcr_min_counter > 200) // 5ms per check = 1s delay
{
USB_ExtraSetState(USB_EXTRA_STATE_DISABLED_UNTIL_REPLUG);
usb_extra_manual = 0; //Force disable manual mode of extra port
if (usb_extra_manual) CDC_print("USB: Disabling extra port until replug and manual mode toggle!\r\n");
else CDC_print("USB: Disabling extra port until replug!\r\n");
usb_extra_manual = 0; // Force disable manual mode of extra port
if (usb_extra_manual)
CDC_print("USB: Disabling extra port until replug and manual mode toggle!\r\n");
else
CDC_print("USB: Disabling extra port until replug!\r\n");
}
}
}
}
else
{
//Power successfully cut back from LED drivers
} else {
// Power successfully cut back from LED drivers
gcr_actual -= LED_GCR_STEP_AUTO;
gcr_min_counter = 0;
#ifdef USE_MASSDROP_CONFIGURATOR
//If breathe mode is active, the top end can fluctuate if the host can not supply enough current
//So set the breathe GCR to where it becomes stable
if (led_animation_breathing == 1)
{
// If breathe mode is active, the top end can fluctuate if the host can not supply enough current
// So set the breathe GCR to where it becomes stable
if (led_animation_breathing == 1) {
gcr_breathe = gcr_actual;
//PS: At this point, setting breathing to exhale makes a noticebly shorter cycle
// PS: At this point, setting breathing to exhale makes a noticebly shorter cycle
// and the same would happen maybe one or two more times. Therefore I'm favoring
// powering through one full breathe and letting gcr settle completely
}
@ -180,47 +164,40 @@ void gcr_compute(void)
}
}
void issi3733_prepare_arrays(void)
{
memset(issidrv,0,sizeof(issi3733_driver_t) * ISSI3733_DRIVER_COUNT);
void issi3733_prepare_arrays(void) {
memset(issidrv, 0, sizeof(issi3733_driver_t) * ISSI3733_DRIVER_COUNT);
int i;
int i;
uint8_t addrs[ISSI3733_DRIVER_COUNT] = ISSI3773_DRIVER_ADDRESSES;
for (i=0;i<ISSI3733_DRIVER_COUNT;i++)
{
for (i = 0; i < ISSI3733_DRIVER_COUNT; i++) {
issidrv[i].addr = addrs[i];
}
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++)
{
//BYTE: 1 + (SW-1)*16 + (CS-1)
led_map[i].rgb.g = issidrv[led_map[i].adr.drv-1].pwm + 1 + ((led_map[i].adr.swg-1)*16 + (led_map[i].adr.cs-1));
led_map[i].rgb.r = issidrv[led_map[i].adr.drv-1].pwm + 1 + ((led_map[i].adr.swr-1)*16 + (led_map[i].adr.cs-1));
led_map[i].rgb.b = issidrv[led_map[i].adr.drv-1].pwm + 1 + ((led_map[i].adr.swb-1)*16 + (led_map[i].adr.cs-1));
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
// BYTE: 1 + (SW-1)*16 + (CS-1)
led_map[i].rgb.g = issidrv[led_map[i].adr.drv - 1].pwm + 1 + ((led_map[i].adr.swg - 1) * 16 + (led_map[i].adr.cs - 1));
led_map[i].rgb.r = issidrv[led_map[i].adr.drv - 1].pwm + 1 + ((led_map[i].adr.swr - 1) * 16 + (led_map[i].adr.cs - 1));
led_map[i].rgb.b = issidrv[led_map[i].adr.drv - 1].pwm + 1 + ((led_map[i].adr.swb - 1) * 16 + (led_map[i].adr.cs - 1));
//BYTE: 1 + (SW-1)*2 + (CS-1)/8
//BIT: (CS-1)%8
*(issidrv[led_map[i].adr.drv-1].onoff + 1 + (led_map[i].adr.swg-1)*2+(led_map[i].adr.cs-1)/8) |= (1<<((led_map[i].adr.cs-1)%8));
*(issidrv[led_map[i].adr.drv-1].onoff + 1 + (led_map[i].adr.swr-1)*2+(led_map[i].adr.cs-1)/8) |= (1<<((led_map[i].adr.cs-1)%8));
*(issidrv[led_map[i].adr.drv-1].onoff + 1 + (led_map[i].adr.swb-1)*2+(led_map[i].adr.cs-1)/8) |= (1<<((led_map[i].adr.cs-1)%8));
// BYTE: 1 + (SW-1)*2 + (CS-1)/8
// BIT: (CS-1)%8
*(issidrv[led_map[i].adr.drv - 1].onoff + 1 + (led_map[i].adr.swg - 1) * 2 + (led_map[i].adr.cs - 1) / 8) |= (1 << ((led_map[i].adr.cs - 1) % 8));
*(issidrv[led_map[i].adr.drv - 1].onoff + 1 + (led_map[i].adr.swr - 1) * 2 + (led_map[i].adr.cs - 1) / 8) |= (1 << ((led_map[i].adr.cs - 1) % 8));
*(issidrv[led_map[i].adr.drv - 1].onoff + 1 + (led_map[i].adr.swb - 1) * 2 + (led_map[i].adr.cs - 1) / 8) |= (1 << ((led_map[i].adr.cs - 1) % 8));
}
}
void led_matrix_prepare(void)
{
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++)
{
void led_matrix_prepare(void) {
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
*led_map[i].rgb.r = 0;
*led_map[i].rgb.g = 0;
*led_map[i].rgb.b = 0;
}
}
void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b)
{
if (i < ISSI3733_LED_COUNT)
{
void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b) {
if (i < ISSI3733_LED_COUNT) {
#ifdef USE_MASSDROP_CONFIGURATOR
led_matrix_massdrop_config_override(i);
#else
@ -231,16 +208,13 @@ void led_set_one(int i, uint8_t r, uint8_t g, uint8_t b)
}
}
void led_set_all(uint8_t r, uint8_t g, uint8_t b)
{
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++)
{
led_set_one(i, r, g, b);
}
void led_set_all(uint8_t r, uint8_t g, uint8_t b) {
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
led_set_one(i, r, g, b);
}
}
void init(void)
{
void init(void) {
DBGC(DC_LED_MATRIX_INIT_BEGIN);
issi3733_prepare_arrays();
@ -248,25 +222,28 @@ void init(void)
led_matrix_prepare();
gcr_min_counter = 0;
v_5v_cat_hit = 0;
v_5v_cat_hit = 0;
DBGC(DC_LED_MATRIX_INIT_COMPLETE);
}
void flush(void)
{
void flush(void) {
#ifdef USE_MASSDROP_CONFIGURATOR
if (!led_enabled) { return; } //Prevent calculations and I2C traffic if LED drivers are not enabled
if (!led_enabled) {
return;
} // Prevent calculations and I2C traffic if LED drivers are not enabled
#else
if (!sr_exp_data.bit.SDB_N) { return; } //Prevent calculations and I2C traffic if LED drivers are not enabled
if (!sr_exp_data.bit.SDB_N) {
return;
} // Prevent calculations and I2C traffic if LED drivers are not enabled
#endif
// Wait for previous transfer to complete
while (i2c_led_q_running) {}
while (i2c_led_q_running) {
}
// Copy buffer to live DMA region
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++)
{
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
*led_map[i].rgb.r = led_buffer[i].r;
*led_map[i].rgb.g = led_buffer[i].g;
*led_map[i].rgb.b = led_buffer[i].b;
@ -275,8 +252,7 @@ void flush(void)
#ifdef USE_MASSDROP_CONFIGURATOR
breathe_mult = 1;
if (led_animation_breathing)
{
if (led_animation_breathing) {
//+60us 119 LED
led_animation_breathe_cur += BREATHE_STEP * breathe_dir;
@ -285,76 +261,65 @@ void flush(void)
else if (led_animation_breathe_cur <= BREATHE_MIN_STEP)
breathe_dir = 1;
//Brightness curve created for 256 steps, 0 - ~98%
// Brightness curve created for 256 steps, 0 - ~98%
breathe_mult = 0.000015 * led_animation_breathe_cur * led_animation_breathe_cur;
if (breathe_mult > 1) breathe_mult = 1;
else if (breathe_mult < 0) breathe_mult = 0;
if (breathe_mult > 1)
breathe_mult = 1;
else if (breathe_mult < 0)
breathe_mult = 0;
}
//This should only be performed once per frame
// This should only be performed once per frame
pomod = (float)((g_rgb_counters.tick / 10) % (uint32_t)(1000.0f / led_animation_speed)) / 10.0f * led_animation_speed;
pomod *= 100.0f;
pomod = (uint32_t)pomod % 10000;
pomod /= 100.0f;
#endif // USE_MASSDROP_CONFIGURATOR
#endif // USE_MASSDROP_CONFIGURATOR
uint8_t drvid;
//NOTE: GCR does not need to be timed with LED processing, but there is really no harm
if (gcr_actual != gcr_actual_last)
{
for (drvid=0;drvid<ISSI3733_DRIVER_COUNT;drvid++)
I2C_LED_Q_GCR(drvid); //Queue data
// NOTE: GCR does not need to be timed with LED processing, but there is really no harm
if (gcr_actual != gcr_actual_last) {
for (drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++) I2C_LED_Q_GCR(drvid); // Queue data
gcr_actual_last = gcr_actual;
}
for (drvid=0;drvid<ISSI3733_DRIVER_COUNT;drvid++)
I2C_LED_Q_PWM(drvid); //Queue data
for (drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++) I2C_LED_Q_PWM(drvid); // Queue data
i2c_led_q_run();
}
void led_matrix_indicators(void)
{
void led_matrix_indicators(void) {
uint8_t kbled = keyboard_leds();
if (kbled && rgb_matrix_config.enable)
{
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++)
{
if (kbled && rgb_matrix_config.enable) {
for (uint8_t i = 0; i < ISSI3733_LED_COUNT; i++) {
if (
#if USB_LED_NUM_LOCK_SCANCODE != 255
(led_map[i].scan == USB_LED_NUM_LOCK_SCANCODE && (kbled & (1<<USB_LED_NUM_LOCK))) ||
#endif //NUM LOCK
#if USB_LED_CAPS_LOCK_SCANCODE != 255
(led_map[i].scan == USB_LED_CAPS_LOCK_SCANCODE && (kbled & (1<<USB_LED_CAPS_LOCK))) ||
#endif //CAPS LOCK
#if USB_LED_SCROLL_LOCK_SCANCODE != 255
(led_map[i].scan == USB_LED_SCROLL_LOCK_SCANCODE && (kbled & (1<<USB_LED_SCROLL_LOCK))) ||
#endif //SCROLL LOCK
#if USB_LED_COMPOSE_SCANCODE != 255
(led_map[i].scan == USB_LED_COMPOSE_SCANCODE && (kbled & (1<<USB_LED_COMPOSE))) ||
#endif //COMPOSE
#if USB_LED_KANA_SCANCODE != 255
(led_map[i].scan == USB_LED_KANA_SCANCODE && (kbled & (1<<USB_LED_KANA))) ||
#endif //KANA
(0))
{
#if USB_LED_NUM_LOCK_SCANCODE != 255
(led_map[i].scan == USB_LED_NUM_LOCK_SCANCODE && (kbled & (1 << USB_LED_NUM_LOCK))) ||
#endif // NUM LOCK
#if USB_LED_CAPS_LOCK_SCANCODE != 255
(led_map[i].scan == USB_LED_CAPS_LOCK_SCANCODE && (kbled & (1 << USB_LED_CAPS_LOCK))) ||
#endif // CAPS LOCK
#if USB_LED_SCROLL_LOCK_SCANCODE != 255
(led_map[i].scan == USB_LED_SCROLL_LOCK_SCANCODE && (kbled & (1 << USB_LED_SCROLL_LOCK))) ||
#endif // SCROLL LOCK
#if USB_LED_COMPOSE_SCANCODE != 255
(led_map[i].scan == USB_LED_COMPOSE_SCANCODE && (kbled & (1 << USB_LED_COMPOSE))) ||
#endif // COMPOSE
#if USB_LED_KANA_SCANCODE != 255
(led_map[i].scan == USB_LED_KANA_SCANCODE && (kbled & (1 << USB_LED_KANA))) ||
#endif // KANA
(0)) {
led_buffer[i].r = 255 - led_buffer[i].r;
led_buffer[i].g = 255 - led_buffer[i].g;
led_buffer[i].b = 255 - led_buffer[i].b;
}
}
}
}
const rgb_matrix_driver_t rgb_matrix_driver = {
.init = init,
.flush = flush,
.set_color = led_set_one,
.set_color_all = led_set_all
};
const rgb_matrix_driver_t rgb_matrix_driver = {.init = init, .flush = flush, .set_color = led_set_one, .set_color_all = led_set_all};
/*==============================================================================
= Legacy Lighting Support =
@ -365,103 +330,100 @@ const rgb_matrix_driver_t rgb_matrix_driver = {
// TODO?: wire these up to keymap.c
uint8_t led_animation_orientation = 0;
uint8_t led_animation_direction = 0;
uint8_t led_animation_breathing = 0;
uint8_t led_animation_id = 0;
float led_animation_speed = 4.0f;
uint8_t led_lighting_mode = LED_MODE_NORMAL;
uint8_t led_enabled = 1;
uint8_t led_animation_direction = 0;
uint8_t led_animation_breathing = 0;
uint8_t led_animation_id = 0;
float led_animation_speed = 4.0f;
uint8_t led_lighting_mode = LED_MODE_NORMAL;
uint8_t led_enabled = 1;
uint8_t led_animation_breathe_cur = BREATHE_MIN_STEP;
uint8_t breathe_dir = 1;
uint8_t breathe_dir = 1;
static void led_run_pattern(led_setup_t *f, float* ro, float* go, float* bo, float pos) {
static void led_run_pattern(led_setup_t* f, float* ro, float* go, float* bo, float pos) {
float po;
while (f->end != 1)
{
po = pos; //Reset po for new frame
while (f->end != 1) {
po = pos; // Reset po for new frame
//Add in any moving effects
if ((!led_animation_direction && f->ef & EF_SCR_R) || (led_animation_direction && (f->ef & EF_SCR_L)))
{
// Add in any moving effects
if ((!led_animation_direction && f->ef & EF_SCR_R) || (led_animation_direction && (f->ef & EF_SCR_L))) {
po -= pomod;
if (po > 100) po -= 100;
else if (po < 0) po += 100;
}
else if ((!led_animation_direction && f->ef & EF_SCR_L) || (led_animation_direction && (f->ef & EF_SCR_R)))
{
if (po > 100)
po -= 100;
else if (po < 0)
po += 100;
} else if ((!led_animation_direction && f->ef & EF_SCR_L) || (led_animation_direction && (f->ef & EF_SCR_R))) {
po += pomod;
if (po > 100) po -= 100;
else if (po < 0) po += 100;
if (po > 100)
po -= 100;
else if (po < 0)
po += 100;
}
//Check if LED's po is in current frame
if (po < f->hs) { f++; continue; }
if (po > f->he) { f++; continue; }
//note: < 0 or > 100 continue
// Check if LED's po is in current frame
if (po < f->hs) {
f++;
continue;
}
if (po > f->he) {
f++;
continue;
}
// note: < 0 or > 100 continue
//Calculate the po within the start-stop percentage for color blending
// Calculate the po within the start-stop percentage for color blending
po = (po - f->hs) / (f->he - f->hs);
//Add in any color effects
if (f->ef & EF_OVER)
{
*ro = (po * (f->re - f->rs)) + f->rs;// + 0.5;
*go = (po * (f->ge - f->gs)) + f->gs;// + 0.5;
*bo = (po * (f->be - f->bs)) + f->bs;// + 0.5;
}
else if (f->ef & EF_SUBTRACT)
{
*ro -= (po * (f->re - f->rs)) + f->rs;// + 0.5;
*go -= (po * (f->ge - f->gs)) + f->gs;// + 0.5;
*bo -= (po * (f->be - f->bs)) + f->bs;// + 0.5;
}
else
{
*ro += (po * (f->re - f->rs)) + f->rs;// + 0.5;
*go += (po * (f->ge - f->gs)) + f->gs;// + 0.5;
*bo += (po * (f->be - f->bs)) + f->bs;// + 0.5;
// Add in any color effects
if (f->ef & EF_OVER) {
*ro = (po * (f->re - f->rs)) + f->rs; // + 0.5;
*go = (po * (f->ge - f->gs)) + f->gs; // + 0.5;
*bo = (po * (f->be - f->bs)) + f->bs; // + 0.5;
} else if (f->ef & EF_SUBTRACT) {
*ro -= (po * (f->re - f->rs)) + f->rs; // + 0.5;
*go -= (po * (f->ge - f->gs)) + f->gs; // + 0.5;
*bo -= (po * (f->be - f->bs)) + f->bs; // + 0.5;
} else {
*ro += (po * (f->re - f->rs)) + f->rs; // + 0.5;
*go += (po * (f->ge - f->gs)) + f->gs; // + 0.5;
*bo += (po * (f->be - f->bs)) + f->bs; // + 0.5;
}
f++;
}
}
static void led_matrix_massdrop_config_override(int i)
{
static void led_matrix_massdrop_config_override(int i) {
float ro = 0;
float go = 0;
float bo = 0;
float po = (led_animation_orientation)
? (float)g_led_config.point[i].y / 64.f * 100
: (float)g_led_config.point[i].x / 224.f * 100;
float po = (led_animation_orientation) ? (float)g_led_config.point[i].y / 64.f * 100 : (float)g_led_config.point[i].x / 224.f * 100;
uint8_t highest_active_layer = biton32(layer_state);
if (led_lighting_mode == LED_MODE_KEYS_ONLY && HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) {
//Do not act on this LED
// Do not act on this LED
} else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && !HAS_FLAGS(g_led_config.flags[i], LED_FLAG_UNDERGLOW)) {
//Do not act on this LED
// Do not act on this LED
} else if (led_lighting_mode == LED_MODE_INDICATORS_ONLY) {
//Do not act on this LED (Only show indicators)
// Do not act on this LED (Only show indicators)
} else {
led_instruction_t* led_cur_instruction = led_instructions;
while (!led_cur_instruction->end) {
// Check if this applies to current layer
if ((led_cur_instruction->flags & LED_FLAG_MATCH_LAYER) &&
(led_cur_instruction->layer != highest_active_layer)) {
if ((led_cur_instruction->flags & LED_FLAG_MATCH_LAYER) && (led_cur_instruction->layer != highest_active_layer)) {
goto next_iter;
}
// Check if this applies to current index
if (led_cur_instruction->flags & LED_FLAG_MATCH_ID) {
uint8_t modid = i / 32; //Calculate which id# contains the led bit
uint32_t modidbit = 1 << (i % 32); //Calculate the bit within the id#
uint32_t *bitfield = &led_cur_instruction->id0 + modid; //Add modid as offset to id0 address. *bitfield is now idX of the led id
if (~(*bitfield) & modidbit) { //Check if led bit is not set in idX
uint8_t modid = i / 32; // Calculate which id# contains the led bit
uint32_t modidbit = 1 << (i % 32); // Calculate the bit within the id#
uint32_t* bitfield = &led_cur_instruction->id0 + modid; // Add modid as offset to id0 address. *bitfield is now idX of the led id
if (~(*bitfield) & modidbit) { // Check if led bit is not set in idX
goto next_iter;
}
}
@ -476,16 +438,24 @@ static void led_matrix_massdrop_config_override(int i)
led_run_pattern(led_setups[led_animation_id], &ro, &go, &bo, po);
}
next_iter:
led_cur_instruction++;
next_iter:
led_cur_instruction++;
}
if (ro > 255) ro = 255; else if (ro < 0) ro = 0;
if (go > 255) go = 255; else if (go < 0) go = 0;
if (bo > 255) bo = 255; else if (bo < 0) bo = 0;
if (ro > 255)
ro = 255;
else if (ro < 0)
ro = 0;
if (go > 255)
go = 255;
else if (go < 0)
go = 0;
if (bo > 255)
bo = 255;
else if (bo < 0)
bo = 0;
if (led_animation_breathing)
{
if (led_animation_breathing) {
ro *= breathe_mult;
go *= breathe_mult;
bo *= breathe_mult;
@ -497,4 +467,4 @@ static void led_matrix_massdrop_config_override(int i)
led_buffer[i].b = (uint8_t)bo;
}
#endif // USE_MASSDROP_CONFIGURATOR
#endif // USE_MASSDROP_CONFIGURATOR

View file

@ -20,20 +20,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "quantum.h"
//From keyboard
// From keyboard
#include "config_led.h"
//CS1-CS16 Current Source "Col"
// CS1-CS16 Current Source "Col"
#define ISSI3733_CS_COUNT 16
//SW1-SW12 Switch "Row"
// SW1-SW12 Switch "Row"
#define ISSI3733_SW_COUNT 12
#define ISSI3733_LED_RGB_COUNT ISSI3733_CS_COUNT * ISSI3733_SW_COUNT
#define ISSI3733_PG0_BYTES ISSI3733_LED_RGB_COUNT / 8 + 1 //+1 for first byte being memory start offset for I2C transfer
#define ISSI3733_PG1_BYTES ISSI3733_LED_RGB_COUNT + 1 //+1 for first byte being memory start offset for I2C transfer
#define ISSI3733_PG2_BYTES ISSI3733_LED_RGB_COUNT + 1 //+1 for first byte being memory start offset for I2C transfer
#define ISSI3733_PG3_BYTES 18 + 1 //+1 for first byte being memory start offset for I2C transfer
#define ISSI3733_LED_RGB_COUNT ISSI3733_CS_COUNT *ISSI3733_SW_COUNT
#define ISSI3733_PG0_BYTES ISSI3733_LED_RGB_COUNT / 8 + 1 //+1 for first byte being memory start offset for I2C transfer
#define ISSI3733_PG1_BYTES ISSI3733_LED_RGB_COUNT + 1 //+1 for first byte being memory start offset for I2C transfer
#define ISSI3733_PG2_BYTES ISSI3733_LED_RGB_COUNT + 1 //+1 for first byte being memory start offset for I2C transfer
#define ISSI3733_PG3_BYTES 18 + 1 //+1 for first byte being memory start offset for I2C transfer
#define ISSI3733_PG_ONOFF_BYTES ISSI3733_PG0_BYTES
#define ISSI3733_PG_OR_BYTES ISSI3733_PG0_BYTES
@ -43,38 +43,38 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define ISSI3733_PG_FN_BYTES ISSI3733_PG3_BYTES
typedef struct issi3733_driver_s {
uint8_t addr; //Address of the driver according to wiring "ISSI3733: Table 1 Slave Address"
uint8_t onoff[ISSI3733_PG_ONOFF_BYTES]; //PG0 - LED Control Register - LED On/Off Register
uint8_t open[ISSI3733_PG_OR_BYTES]; //PG0 - LED Control Register - LED Open Register
uint8_t shrt[ISSI3733_PG_SR_BYTES]; //PG0 - LED Control Register - LED Short Register
uint8_t pwm[ISSI3733_PG_PWM_BYTES]; //PG1 - PWM Register
uint8_t abm[ISSI3733_PG_ABM_BYTES]; //PG2 - Auto Breath Mode Register
uint8_t conf[ISSI3733_PG_FN_BYTES]; //PG3 - Function Register
uint8_t addr; // Address of the driver according to wiring "ISSI3733: Table 1 Slave Address"
uint8_t onoff[ISSI3733_PG_ONOFF_BYTES]; // PG0 - LED Control Register - LED On/Off Register
uint8_t open[ISSI3733_PG_OR_BYTES]; // PG0 - LED Control Register - LED Open Register
uint8_t shrt[ISSI3733_PG_SR_BYTES]; // PG0 - LED Control Register - LED Short Register
uint8_t pwm[ISSI3733_PG_PWM_BYTES]; // PG1 - PWM Register
uint8_t abm[ISSI3733_PG_ABM_BYTES]; // PG2 - Auto Breath Mode Register
uint8_t conf[ISSI3733_PG_FN_BYTES]; // PG3 - Function Register
} issi3733_driver_t;
typedef struct issi3733_rgb_s {
uint8_t *r; //Direct access into PWM data
uint8_t *g; //Direct access into PWM data
uint8_t *b; //Direct access into PWM data
uint8_t *r; // Direct access into PWM data
uint8_t *g; // Direct access into PWM data
uint8_t *b; // Direct access into PWM data
} issi3733_rgb_t;
typedef struct issi3733_rgb_adr_s {
uint8_t drv; //Driver from given list
uint8_t cs; //CS
uint8_t swr; //SW Red
uint8_t swg; //SW Green
uint8_t swb; //SW Blue
uint8_t drv; // Driver from given list
uint8_t cs; // CS
uint8_t swr; // SW Red
uint8_t swg; // SW Green
uint8_t swb; // SW Blue
} issi3733_rgb_adr_t;
typedef struct issi3733_led_s {
uint8_t id; //According to PCB ref
issi3733_rgb_t rgb; //PWM settings of R G B
issi3733_rgb_adr_t adr; //Hardware addresses
float x; //Physical position X
float y; //Physical position Y
float px; //Physical position X in percent
float py; //Physical position Y in percent
uint8_t scan; //Key scan code from wiring (set 0xFF if no key)
uint8_t id; // According to PCB ref
issi3733_rgb_t rgb; // PWM settings of R G B
issi3733_rgb_adr_t adr; // Hardware addresses
float x; // Physical position X
float y; // Physical position Y
float px; // Physical position X in percent
float py; // Physical position Y in percent
uint8_t scan; // Key scan code from wiring (set 0xFF if no key)
} issi3733_led_t;
extern issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT];
@ -92,67 +92,67 @@ void led_matrix_indicators(void);
#ifdef USE_MASSDROP_CONFIGURATOR
#define EF_NONE 0x00000000 //No effect
#define EF_OVER 0x00000001 //Overwrite any previous color information with new
#define EF_SCR_L 0x00000002 //Scroll left
#define EF_SCR_R 0x00000004 //Scroll right
#define EF_SUBTRACT 0x00000008 //Subtract color values
# define EF_NONE 0x00000000 // No effect
# define EF_OVER 0x00000001 // Overwrite any previous color information with new
# define EF_SCR_L 0x00000002 // Scroll left
# define EF_SCR_R 0x00000004 // Scroll right
# define EF_SUBTRACT 0x00000008 // Subtract color values
typedef struct led_setup_s {
float hs; //Band begin at percent
float he; //Band end at percent
uint8_t rs; //Red start value
uint8_t re; //Red end value
uint8_t gs; //Green start value
uint8_t ge; //Green end value
uint8_t bs; //Blue start value
uint8_t be; //Blue end value
uint32_t ef; //Animation and color effects
uint8_t end; //Set to signal end of the setup
float hs; // Band begin at percent
float he; // Band end at percent
uint8_t rs; // Red start value
uint8_t re; // Red end value
uint8_t gs; // Green start value
uint8_t ge; // Green end value
uint8_t bs; // Blue start value
uint8_t be; // Blue end value
uint32_t ef; // Animation and color effects
uint8_t end; // Set to signal end of the setup
} led_setup_t;
extern const uint8_t led_setups_count;
extern void *led_setups[];
extern void * led_setups[];
//LED Extra Instructions
#define LED_FLAG_NULL 0x00 //Matching and coloring not used (default)
#define LED_FLAG_MATCH_ID 0x01 //Match on the ID of the LED (set id#'s to desired bit pattern, first LED is id 1)
#define LED_FLAG_MATCH_LAYER 0x02 //Match on the current active layer (set layer to desired match layer)
#define LED_FLAG_USE_RGB 0x10 //Use a specific RGB value (set r, g, b to desired output color values)
#define LED_FLAG_USE_PATTERN 0x20 //Use a specific pattern ID (set pattern_id to desired output pattern)
#define LED_FLAG_USE_ROTATE_PATTERN 0x40 //Use pattern the user has cycled to manually
// LED Extra Instructions
# define LED_FLAG_NULL 0x00 // Matching and coloring not used (default)
# define LED_FLAG_MATCH_ID 0x01 // Match on the ID of the LED (set id#'s to desired bit pattern, first LED is id 1)
# define LED_FLAG_MATCH_LAYER 0x02 // Match on the current active layer (set layer to desired match layer)
# define LED_FLAG_USE_RGB 0x10 // Use a specific RGB value (set r, g, b to desired output color values)
# define LED_FLAG_USE_PATTERN 0x20 // Use a specific pattern ID (set pattern_id to desired output pattern)
# define LED_FLAG_USE_ROTATE_PATTERN 0x40 // Use pattern the user has cycled to manually
typedef struct led_instruction_s {
uint16_t flags; // Bitfield for LED instructions
uint32_t id0; // Bitwise id, IDs 0-31
uint32_t id1; // Bitwise id, IDs 32-63
uint32_t id2; // Bitwise id, IDs 64-95
uint32_t id3; // Bitwise id, IDs 96-127
uint8_t layer;
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t pattern_id;
uint8_t end;
uint16_t flags; // Bitfield for LED instructions
uint32_t id0; // Bitwise id, IDs 0-31
uint32_t id1; // Bitwise id, IDs 32-63
uint32_t id2; // Bitwise id, IDs 64-95
uint32_t id3; // Bitwise id, IDs 96-127
uint8_t layer;
uint8_t r;
uint8_t g;
uint8_t b;
uint8_t pattern_id;
uint8_t end;
} led_instruction_t;
extern led_instruction_t led_instructions[];
extern uint8_t led_animation_breathing;
extern uint8_t led_animation_id;
extern float led_animation_speed;
extern float led_animation_speed;
extern uint8_t led_lighting_mode;
extern uint8_t led_enabled;
extern uint8_t led_animation_breathe_cur;
extern uint8_t led_animation_direction;
extern uint8_t breathe_dir;
#define LED_MODE_NORMAL 0 //Must be 0
#define LED_MODE_KEYS_ONLY 1
#define LED_MODE_NON_KEYS_ONLY 2
#define LED_MODE_INDICATORS_ONLY 3
#define LED_MODE_MAX_INDEX LED_MODE_INDICATORS_ONLY //Must be highest value
# define LED_MODE_NORMAL 0 // Must be 0
# define LED_MODE_KEYS_ONLY 1
# define LED_MODE_NON_KEYS_ONLY 2
# define LED_MODE_INDICATORS_ONLY 3
# define LED_MODE_MAX_INDEX LED_MODE_INDICATORS_ONLY // Must be highest value
#endif // USE_MASSDROP_CONFIGURATOR
#endif // USE_MASSDROP_CONFIGURATOR
#endif //_LED_MATRIX_H_
#endif //_LED_MATRIX_H_

View file

@ -17,106 +17,82 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifdef USE_MASSDROP_CONFIGURATOR
#include "led_matrix.h"
# include "led_matrix.h"
//Teal <-> Salmon
// Teal <-> Salmon
led_setup_t leds_teal_salmon[] = {
{ .hs = 0, .he = 33, .rs = 24, .re = 24, .gs = 215, .ge = 215, .bs = 204, .be = 204, .ef = EF_NONE },
{ .hs = 33, .he = 66, .rs = 24, .re = 255, .gs = 215, .ge = 114, .bs = 204, .be = 118, .ef = EF_NONE },
{ .hs = 66, .he = 100, .rs = 255, .re = 255, .gs = 114, .ge = 114, .bs = 118, .be = 118, .ef = EF_NONE },
{ .end = 1 },
{.hs = 0, .he = 33, .rs = 24, .re = 24, .gs = 215, .ge = 215, .bs = 204, .be = 204, .ef = EF_NONE},
{.hs = 33, .he = 66, .rs = 24, .re = 255, .gs = 215, .ge = 114, .bs = 204, .be = 118, .ef = EF_NONE},
{.hs = 66, .he = 100, .rs = 255, .re = 255, .gs = 114, .ge = 114, .bs = 118, .be = 118, .ef = EF_NONE},
{.end = 1},
};
//Yellow
// Yellow
led_setup_t leds_yellow[] = {
{ .hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_NONE },
{ .end = 1 },
{.hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_NONE},
{.end = 1},
};
//Off
// Off
led_setup_t leds_off[] = {
{ .hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_NONE },
{ .end = 1 },
{.hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_NONE},
{.end = 1},
};
//Red
// Red
led_setup_t leds_red[] = {
{ .hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_NONE },
{ .end = 1 },
{.hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_NONE},
{.end = 1},
};
//Green
// Green
led_setup_t leds_green[] = {
{ .hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_NONE },
{ .end = 1 },
{.hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_NONE},
{.end = 1},
};
//Blue
// Blue
led_setup_t leds_blue[] = {
{ .hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_NONE },
{ .end = 1 },
{.hs = 0, .he = 100, .rs = 0, .re = 0, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_NONE},
{.end = 1},
};
//White
// White
led_setup_t leds_white[] = {
{ .hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 255, .be = 255, .ef = EF_NONE },
{ .end = 1 },
{.hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 255, .be = 255, .ef = EF_NONE},
{.end = 1},
};
//White with moving red stripe
// White with moving red stripe
led_setup_t leds_white_with_red_stripe[] = {
{ .hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 255, .be = 255, .ef = EF_NONE },
{ .hs = 0, .he = 15, .rs = 0, .re = 0, .gs = 0, .ge = 255, .bs = 0, .be = 255, .ef = EF_SCR_R | EF_SUBTRACT },
{ .hs = 15, .he = 30, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 0, .ef = EF_SCR_R | EF_SUBTRACT },
{ .end = 1 },
{.hs = 0, .he = 100, .rs = 255, .re = 255, .gs = 255, .ge = 255, .bs = 255, .be = 255, .ef = EF_NONE},
{.hs = 0, .he = 15, .rs = 0, .re = 0, .gs = 0, .ge = 255, .bs = 0, .be = 255, .ef = EF_SCR_R | EF_SUBTRACT},
{.hs = 15, .he = 30, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 0, .ef = EF_SCR_R | EF_SUBTRACT},
{.end = 1},
};
//Black with moving red stripe
// Black with moving red stripe
led_setup_t leds_black_with_red_stripe[] = {
{ .hs = 0, .he = 15, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_SCR_R },
{ .hs = 15, .he = 30, .rs = 255, .re = 0, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_SCR_R },
{ .end = 1 },
{.hs = 0, .he = 15, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_SCR_R},
{.hs = 15, .he = 30, .rs = 255, .re = 0, .gs = 0, .ge = 0, .bs = 0, .be = 0, .ef = EF_SCR_R},
{.end = 1},
};
//Rainbow no scrolling
// Rainbow no scrolling
led_setup_t leds_rainbow_ns[] = {
{ .hs = 0, .he = 16.67, .rs = 255, .re = 255, .gs = 0, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER },
{ .hs = 16.67, .he = 33.33, .rs = 255, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER },
{ .hs = 33.33, .he = 50, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 255, .ef = EF_OVER },
{ .hs = 50, .he = 66.67, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER },
{ .hs = 66.67, .he = 83.33, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER },
{ .hs = 83.33, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 0, .ef = EF_OVER },
{ .end = 1 },
{.hs = 0, .he = 16.67, .rs = 255, .re = 255, .gs = 0, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER}, {.hs = 16.67, .he = 33.33, .rs = 255, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER}, {.hs = 33.33, .he = 50, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 255, .ef = EF_OVER}, {.hs = 50, .he = 66.67, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER}, {.hs = 66.67, .he = 83.33, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER}, {.hs = 83.33, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 0, .ef = EF_OVER}, {.end = 1},
};
//Rainbow scrolling
// Rainbow scrolling
led_setup_t leds_rainbow_s[] = {
{ .hs = 0, .he = 16.67, .rs = 255, .re = 255, .gs = 0, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER | EF_SCR_R },
{ .hs = 16.67, .he = 33.33, .rs = 255, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER | EF_SCR_R },
{ .hs = 33.33, .he = 50, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 255, .ef = EF_OVER | EF_SCR_R },
{ .hs = 50, .he = 66.67, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER | EF_SCR_R },
{ .hs = 66.67, .he = 83.33, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER | EF_SCR_R },
{ .hs = 83.33, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 0, .ef = EF_OVER | EF_SCR_R },
{ .end = 1 },
{.hs = 0, .he = 16.67, .rs = 255, .re = 255, .gs = 0, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER | EF_SCR_R}, {.hs = 16.67, .he = 33.33, .rs = 255, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 0, .ef = EF_OVER | EF_SCR_R}, {.hs = 33.33, .he = 50, .rs = 0, .re = 0, .gs = 255, .ge = 255, .bs = 0, .be = 255, .ef = EF_OVER | EF_SCR_R}, {.hs = 50, .he = 66.67, .rs = 0, .re = 0, .gs = 255, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER | EF_SCR_R}, {.hs = 66.67, .he = 83.33, .rs = 0, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 255, .ef = EF_OVER | EF_SCR_R}, {.hs = 83.33, .he = 100, .rs = 255, .re = 255, .gs = 0, .ge = 0, .bs = 255, .be = 0, .ef = EF_OVER | EF_SCR_R}, {.end = 1},
};
//Add new LED animations here using one from above as example
//The last entry must be { .end = 1 }
//Add the new animation name to the list below following its format
// Add new LED animations here using one from above as example
// The last entry must be { .end = 1 }
// Add the new animation name to the list below following its format
void *led_setups[] = {
leds_rainbow_s,
leds_rainbow_ns,
leds_teal_salmon,
leds_yellow,
leds_red,
leds_green,
leds_blue,
leds_white,
leds_white_with_red_stripe,
leds_black_with_red_stripe,
leds_off
};
void *led_setups[] = {leds_rainbow_s, leds_rainbow_ns, leds_teal_salmon, leds_yellow, leds_red, leds_green, leds_blue, leds_white, leds_white_with_red_stripe, leds_black_with_red_stripe, leds_off};
const uint8_t led_setups_count = sizeof(led_setups) / sizeof(led_setups[0]);

View file

@ -25,50 +25,43 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <string.h>
#include "quantum.h"
//From protocol directory
// From protocol directory
#include "arm_atsam_protocol.h"
//From keyboard's directory
// From keyboard's directory
#include "config_led.h"
uint8_t g_usb_state = USB_FSMSTATUS_FSMSTATE_OFF_Val; //Saved USB state from hardware value to detect changes
uint8_t g_usb_state = USB_FSMSTATUS_FSMSTATE_OFF_Val; // Saved USB state from hardware value to detect changes
void main_subtasks(void);
void main_subtasks(void);
uint8_t keyboard_leds(void);
void send_keyboard(report_keyboard_t *report);
void send_mouse(report_mouse_t *report);
void send_system(uint16_t data);
void send_consumer(uint16_t data);
void send_keyboard(report_keyboard_t *report);
void send_mouse(report_mouse_t *report);
void send_system(uint16_t data);
void send_consumer(uint16_t data);
host_driver_t arm_atsam_driver = {
keyboard_leds,
send_keyboard,
send_mouse,
send_system,
send_consumer
};
host_driver_t arm_atsam_driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer};
uint8_t led_states;
uint8_t keyboard_leds(void)
{
uint8_t keyboard_leds(void) {
#ifdef NKRO_ENABLE
if (keymap_config.nkro)
return udi_hid_nkro_report_set;
else
#endif //NKRO_ENABLE
#endif // NKRO_ENABLE
return udi_hid_kbd_report_set;
}
void send_keyboard(report_keyboard_t *report)
{
void send_keyboard(report_keyboard_t *report) {
uint32_t irqflags;
#ifdef NKRO_ENABLE
if (!keymap_config.nkro)
{
#endif //NKRO_ENABLE
while (udi_hid_kbd_b_report_trans_ongoing) { main_subtasks(); } //Run other tasks while waiting for USB to be free
if (!keymap_config.nkro) {
#endif // NKRO_ENABLE
while (udi_hid_kbd_b_report_trans_ongoing) {
main_subtasks();
} // Run other tasks while waiting for USB to be free
irqflags = __get_PRIMASK();
__disable_irq();
@ -81,10 +74,10 @@ void send_keyboard(report_keyboard_t *report)
__DMB();
__set_PRIMASK(irqflags);
#ifdef NKRO_ENABLE
}
else
{
while (udi_hid_nkro_b_report_trans_ongoing) { main_subtasks(); } //Run other tasks while waiting for USB to be free
} else {
while (udi_hid_nkro_b_report_trans_ongoing) {
main_subtasks();
} // Run other tasks while waiting for USB to be free
irqflags = __get_PRIMASK();
__disable_irq();
@ -97,11 +90,10 @@ void send_keyboard(report_keyboard_t *report)
__DMB();
__set_PRIMASK(irqflags);
}
#endif //NKRO_ENABLE
#endif // NKRO_ENABLE
}
void send_mouse(report_mouse_t *report)
{
void send_mouse(report_mouse_t *report) {
#ifdef MOUSEKEY_ENABLE
uint32_t irqflags;
@ -115,11 +107,10 @@ void send_mouse(report_mouse_t *report)
__DMB();
__set_PRIMASK(irqflags);
#endif //MOUSEKEY_ENABLE
#endif // MOUSEKEY_ENABLE
}
void send_system(uint16_t data)
{
void send_system(uint16_t data) {
#ifdef EXTRAKEY_ENABLE
uint32_t irqflags;
@ -130,16 +121,15 @@ void send_system(uint16_t data)
udi_hid_exk_report.desc.report_id = REPORT_ID_SYSTEM;
if (data != 0) data = data - SYSTEM_POWER_DOWN + 1;
udi_hid_exk_report.desc.report_data = data;
udi_hid_exk_b_report_valid = 1;
udi_hid_exk_b_report_valid = 1;
udi_hid_exk_send_report();
__DMB();
__set_PRIMASK(irqflags);
#endif //EXTRAKEY_ENABLE
#endif // EXTRAKEY_ENABLE
}
void send_consumer(uint16_t data)
{
void send_consumer(uint16_t data) {
#ifdef EXTRAKEY_ENABLE
uint32_t irqflags;
@ -147,71 +137,64 @@ void send_consumer(uint16_t data)
__disable_irq();
__DMB();
udi_hid_exk_report.desc.report_id = REPORT_ID_CONSUMER;
udi_hid_exk_report.desc.report_id = REPORT_ID_CONSUMER;
udi_hid_exk_report.desc.report_data = data;
udi_hid_exk_b_report_valid = 1;
udi_hid_exk_b_report_valid = 1;
udi_hid_exk_send_report();
__DMB();
__set_PRIMASK(irqflags);
#endif //EXTRAKEY_ENABLE
#endif // EXTRAKEY_ENABLE
}
void main_subtask_usb_state(void)
{
static uint64_t fsmstate_on_delay = 0; //Delay timer to be sure USB is actually operating before bringing up hardware
uint8_t fsmstate_now = USB->DEVICE.FSMSTATUS.reg; //Current state from hardware register
void main_subtask_usb_state(void) {
static uint64_t fsmstate_on_delay = 0; // Delay timer to be sure USB is actually operating before bringing up hardware
uint8_t fsmstate_now = USB->DEVICE.FSMSTATUS.reg; // Current state from hardware register
if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) //If USB SUSPENDED
if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) // If USB SUSPENDED
{
fsmstate_on_delay = 0; //Clear ON delay timer
fsmstate_on_delay = 0; // Clear ON delay timer
if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) //If previously not SUSPENDED
if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SUSPEND_Val) // If previously not SUSPENDED
{
suspend_power_down(); //Run suspend routine
g_usb_state = fsmstate_now; //Save current USB state
suspend_power_down(); // Run suspend routine
g_usb_state = fsmstate_now; // Save current USB state
}
}
else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SLEEP_Val) //Else if USB SLEEPING
} else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_SLEEP_Val) // Else if USB SLEEPING
{
fsmstate_on_delay = 0; //Clear ON delay timer
fsmstate_on_delay = 0; // Clear ON delay timer
if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SLEEP_Val) //If previously not SLEEPING
if (g_usb_state != USB_FSMSTATUS_FSMSTATE_SLEEP_Val) // If previously not SLEEPING
{
suspend_power_down(); //Run suspend routine
g_usb_state = fsmstate_now; //Save current USB state
suspend_power_down(); // Run suspend routine
g_usb_state = fsmstate_now; // Save current USB state
}
}
else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_ON_Val) //Else if USB ON
} else if (fsmstate_now == USB_FSMSTATUS_FSMSTATE_ON_Val) // Else if USB ON
{
if (g_usb_state != USB_FSMSTATUS_FSMSTATE_ON_Val) //If previously not ON
if (g_usb_state != USB_FSMSTATUS_FSMSTATE_ON_Val) // If previously not ON
{
if (fsmstate_on_delay == 0) //If ON delay timer is cleared
if (fsmstate_on_delay == 0) // If ON delay timer is cleared
{
fsmstate_on_delay = timer_read64() + 250; //Set ON delay timer
}
else if (timer_read64() > fsmstate_on_delay) //Else if ON delay timer is active and timed out
fsmstate_on_delay = timer_read64() + 250; // Set ON delay timer
} else if (timer_read64() > fsmstate_on_delay) // Else if ON delay timer is active and timed out
{
suspend_wakeup_init(); //Run wakeup routine
g_usb_state = fsmstate_now; //Save current USB state
suspend_wakeup_init(); // Run wakeup routine
g_usb_state = fsmstate_now; // Save current USB state
}
}
}
else //Else if USB is in a state not being tracked
} else // Else if USB is in a state not being tracked
{
fsmstate_on_delay = 0; //Clear ON delay timer
fsmstate_on_delay = 0; // Clear ON delay timer
}
}
void main_subtask_power_check(void)
{
void main_subtask_power_check(void) {
static uint64_t next_5v_checkup = 0;
if (timer_read64() > next_5v_checkup)
{
if (timer_read64() > next_5v_checkup) {
next_5v_checkup = timer_read64() + 5;
v_5v = adc_get(ADC_5V);
v_5v = adc_get(ADC_5V);
v_5v_avg = 0.9 * v_5v_avg + 0.1 * v_5v;
#ifdef RGB_MATRIX_ENABLE
@ -220,27 +203,23 @@ void main_subtask_power_check(void)
}
}
void main_subtask_usb_extra_device(void)
{
void main_subtask_usb_extra_device(void) {
static uint64_t next_usb_checkup = 0;
if (timer_read64() > next_usb_checkup)
{
if (timer_read64() > next_usb_checkup) {
next_usb_checkup = timer_read64() + 10;
USB_HandleExtraDevice();
}
}
void main_subtasks(void)
{
void main_subtasks(void) {
main_subtask_usb_state();
main_subtask_power_check();
main_subtask_usb_extra_device();
}
int main(void)
{
int main(void) {
DBG_LED_ENA;
DBG_1_ENA;
DBG_1_OFF;
@ -259,7 +238,7 @@ int main(void)
#ifdef RGB_MATRIX_ENABLE
i2c1_init();
#endif // RGB_MATRIX_ENABLE
#endif // RGB_MATRIX_ENABLE
matrix_init();
@ -273,21 +252,23 @@ int main(void)
CDC_init();
DBGC(DC_MAIN_CDC_INIT_COMPLETE);
while (USB2422_Port_Detect_Init() == 0) {}
while (USB2422_Port_Detect_Init() == 0) {
}
DBG_LED_OFF;
#ifdef RGB_MATRIX_ENABLE
while (I2C3733_Init_Control() != 1) {}
while (I2C3733_Init_Drivers() != 1) {}
while (I2C3733_Init_Control() != 1) {
}
while (I2C3733_Init_Drivers() != 1) {
}
I2C_DMAC_LED_Init();
i2c_led_q_init();
for (uint8_t drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++)
I2C_LED_Q_ONOFF(drvid); //Queue data
#endif // RGB_MATRIX_ENABLE
for (uint8_t drvid = 0; drvid < ISSI3733_DRIVER_COUNT; drvid++) I2C_LED_Q_ONOFF(drvid); // Queue data
#endif // RGB_MATRIX_ENABLE
keyboard_setup();
@ -297,21 +278,18 @@ int main(void)
#ifdef CONSOLE_ENABLE
uint64_t next_print = 0;
#endif //CONSOLE_ENABLE
#endif // CONSOLE_ENABLE
v_5v_avg = adc_get(ADC_5V);
debug_code_disable();
while (1)
{
main_subtasks(); //Note these tasks will also be run while waiting for USB keyboard polling intervals
while (1) {
main_subtasks(); // Note these tasks will also be run while waiting for USB keyboard polling intervals
if (g_usb_state == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val || g_usb_state == USB_FSMSTATUS_FSMSTATE_SLEEP_Val)
{
if (suspend_wakeup_condition())
{
udc_remotewakeup(); //Send remote wakeup signal
if (g_usb_state == USB_FSMSTATUS_FSMSTATE_SUSPEND_Val || g_usb_state == USB_FSMSTATUS_FSMSTATE_SLEEP_Val) {
if (suspend_wakeup_condition()) {
udc_remotewakeup(); // Send remote wakeup signal
wait_ms(50);
}
@ -321,16 +299,13 @@ int main(void)
keyboard_task();
#ifdef CONSOLE_ENABLE
if (timer_read64() > next_print)
{
if (timer_read64() > next_print) {
next_print = timer_read64() + 250;
//Add any debug information here that you want to see very often
//dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired);
// Add any debug information here that you want to see very often
// dprintf("5v=%u 5vu=%u dlow=%u dhi=%u gca=%u gcd=%u\r\n", v_5v, v_5v_avg, v_5v_avg - V5_LOW, v_5v_avg - V5_HIGH, gcr_actual, gcr_desired);
}
#endif //CONSOLE_ENABLE
#endif // CONSOLE_ENABLE
}
return 1;
}

Some files were not shown because too many files have changed in this diff Show more