clang-format changes
This commit is contained in:
		
							parent
							
								
									61af76a10d
								
							
						
					
					
						commit
						b624f32f94
					
				
					 502 changed files with 32259 additions and 39062 deletions
				
			
		
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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); }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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); }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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++);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,5 +7,4 @@ void console_printf(char *fmt, ...);
 | 
			
		|||
 | 
			
		||||
#define __xprintf console_printf
 | 
			
		||||
 | 
			
		||||
#endif //_PRINTF_H_
 | 
			
		||||
 | 
			
		||||
#endif  //_PRINTF_H_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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); }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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])) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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++; }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
									
								
							
							
						
						
									
										142
									
								
								tmk_core/common/chibios/eeprom_stm32.c
									
										
									
									
									
										
										
										Executable file → Normal 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
									
								
							
							
						
						
									
										64
									
								
								tmk_core/common/chibios/eeprom_stm32.h
									
										
									
									
									
										
										
										Executable file → Normal 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 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
									
								
							
							
						
						
									
										162
									
								
								tmk_core/common/chibios/flash_stm32.c
									
										
									
									
									
										
										
										Executable file → Normal 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
									
								
							
							
						
						
									
										15
									
								
								tmk_core/common/chibios/flash_stm32.h
									
										
									
									
									
										
										
										Executable file → Normal 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))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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; }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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_ */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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; }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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" {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,3 @@
 | 
			
		|||
#include "bootloader.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void bootloader_jump(void) {}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,5 @@
 | 
			
		|||
#include <stdbool.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void suspend_power_down(void) {}
 | 
			
		||||
bool suspend_wakeup_condition(void) { return true; }
 | 
			
		||||
void suspend_wakeup_init(void) {}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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); }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,5 +13,4 @@ int __xprintf(const char *format, ...);
 | 
			
		|||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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");
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 */
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,7 +20,6 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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; }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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++);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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/>.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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); }
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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_
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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]);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue