1
0
Fork 0

Merge branch 'rn42' into merge_rn42

Conflicts:
	.gitignore
	common.mk
	common/debug_config.h
	common/print.h
This commit is contained in:
tmk 2014-11-24 13:50:33 +09:00
commit 363950982a
92 changed files with 4461 additions and 401 deletions

View file

@ -509,7 +509,7 @@ void clear_keyboard_but_mods(void)
#endif
}
bool is_tap_key(key_t key)
bool is_tap_key(keypos_t key)
{
action_t action = layer_switch_get_action(key);

View file

@ -25,6 +25,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "action_macro.h"
#ifdef __cplusplus
extern "C" {
#endif
/* tapping count and state */
typedef struct {
bool interrupted :1;
@ -42,12 +46,11 @@ typedef struct {
#endif
} keyrecord_t;
/* Execute action per keyevent */
void action_exec(keyevent_t event);
/* action for key */
action_t action_for_key(uint8_t layer, key_t key);
action_t action_for_key(uint8_t layer, keypos_t key);
/* macro */
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);
@ -65,11 +68,15 @@ void unregister_mods(uint8_t mods);
void clear_keyboard(void);
void clear_keyboard_but_mods(void);
void layer_switch(uint8_t new_layer);
bool is_tap_key(key_t key);
bool is_tap_key(keypos_t key);
/* debug */
void debug_event(keyevent_t event);
void debug_record(keyrecord_t record);
void debug_action(action_t action);
#ifdef __cplusplus
}
#endif
#endif /* ACTION_H */

View file

@ -112,7 +112,7 @@ void layer_debug(void)
action_t layer_switch_get_action(key_t key)
action_t layer_switch_get_action(keypos_t key)
{
action_t action;
action.code = ACTION_TRANSPARENT;

View file

@ -72,6 +72,6 @@ void layer_xor(uint32_t state);
/* return action depending on current layer status */
action_t layer_switch_get_action(key_t key);
action_t layer_switch_get_action(keypos_t key);
#endif

View file

@ -14,10 +14,10 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <util/delay.h>
#include "action.h"
#include "action_util.h"
#include "action_macro.h"
#include "wait.h"
#ifdef DEBUG_ACTION
#include "debug.h"
@ -28,7 +28,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NO_ACTION_MACRO
#define MACRO_READ() (macro = pgm_read_byte(macro_p++))
#define MACRO_READ() (macro = MACRO_GET(macro_p++))
void action_macro_play(const macro_t *macro_p)
{
macro_t macro = END;
@ -58,7 +58,7 @@ void action_macro_play(const macro_t *macro_p)
case WAIT:
MACRO_READ();
dprintf("WAIT(%u)\n", macro);
{ uint8_t ms = macro; while (ms--) _delay_ms(1); }
{ uint8_t ms = macro; while (ms--) wait_ms(1); }
break;
case INTERVAL:
interval = MACRO_READ();
@ -77,7 +77,7 @@ void action_macro_play(const macro_t *macro_p)
return;
}
// interval
{ uint8_t ms = interval; while (ms--) _delay_ms(1); }
{ uint8_t ms = interval; while (ms--) wait_ms(1); }
}
}
#endif

View file

@ -17,12 +17,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef ACTION_MACRO_H
#define ACTION_MACRO_H
#include <stdint.h>
#include <avr/pgmspace.h>
#include "progmem.h"
#define MACRO_NONE 0
#define MACRO(...) ({ static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; })
#define MACRO_NONE 0
#define MACRO(...) ({ static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; })
#define MACRO_GET(p) pgm_read_byte(p)
typedef uint8_t macro_t;

View file

@ -31,8 +31,8 @@ static uint8_t real_mods = 0;
static uint8_t weak_mods = 0;
#ifdef USB_6KRO_ENABLE
#define RO_ADD(a, b) ((a + b) % REPORT_KEYS)
#define RO_SUB(a, b) ((a - b + REPORT_KEYS) % REPORT_KEYS)
#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;
@ -98,7 +98,7 @@ void del_key(uint8_t key)
void clear_keys(void)
{
// not clear mods
for (int8_t i = 1; i < REPORT_SIZE; i++) {
for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
keyboard_report->raw[i] = 0;
}
}
@ -145,7 +145,7 @@ void clear_oneshot_mods(void)
uint8_t has_anykey(void)
{
uint8_t cnt = 0;
for (uint8_t i = 1; i < REPORT_SIZE; i++) {
for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
if (keyboard_report->raw[i])
cnt++;
}
@ -162,7 +162,7 @@ uint8_t get_first_key(void)
#ifdef NKRO_ENABLE
if (keyboard_nkro) {
uint8_t i = 0;
for (; i < REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
;
return i<<3 | biton(keyboard_report->nkro.bits[i]);
}
@ -234,7 +234,7 @@ static inline void add_key_byte(uint8_t code)
#else
int8_t i = 0;
int8_t empty = -1;
for (; i < REPORT_KEYS; i++) {
for (; i < KEYBOARD_REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) {
break;
}
@ -242,7 +242,7 @@ static inline void add_key_byte(uint8_t code)
empty = i;
}
}
if (i == REPORT_KEYS) {
if (i == KEYBOARD_REPORT_KEYS) {
if (empty != -1) {
keyboard_report->keys[empty] = code;
}
@ -278,7 +278,7 @@ static inline void del_key_byte(uint8_t code)
} while (i != cb_tail);
}
#else
for (uint8_t i = 0; i < REPORT_KEYS; i++) {
for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) {
keyboard_report->keys[i] = 0;
}
@ -289,7 +289,7 @@ static inline void del_key_byte(uint8_t code)
#ifdef NKRO_ENABLE
static inline void add_key_bit(uint8_t code)
{
if ((code>>3) < REPORT_BITS) {
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);
@ -298,7 +298,7 @@ static inline void add_key_bit(uint8_t code)
static inline void del_key_bit(uint8_t code)
{
if ((code>>3) < REPORT_BITS) {
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);

View file

@ -20,6 +20,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h>
#include "report.h"
#ifdef __cplusplus
extern "C" {
#endif
extern report_keyboard_t *keyboard_report;
void send_keyboard_report(void);
@ -54,4 +58,9 @@ void oneshot_disable(void);
uint8_t has_anykey(void);
uint8_t has_anymod(void);
uint8_t get_first_key(void);
#ifdef __cplusplus
}
#endif
#endif

117
common/avr/suspend.c Normal file
View file

@ -0,0 +1,117 @@
#include <stdbool.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include "matrix.h"
#include "action.h"
#include "backlight.h"
#include "suspend_avr.h"
#include "suspend.h"
#ifdef PROTOCOL_LUFA
#include "lufa.h"
#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" \
)
void suspend_idle(uint8_t time)
{
cli();
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
}
/* Power down MCU with watchdog timer
* wdto: watchdog timer timeout defined in <avr/wdt.h>
* WDTO_15MS
* WDTO_30MS
* WDTO_60MS
* WDTO_120MS
* WDTO_250MS
* WDTO_500MS
* WDTO_1S
* WDTO_2S
* WDTO_4S
* WDTO_8S
*/
void suspend_power_down(uint8_t wdto)
{
#ifdef PROTOCOL_LUFA
if (USB_DeviceState == DEVICE_STATE_Configured) return;
#endif
// Watchdog Interrupt Mode
wdt_intr_enable(wdto);
// TODO: more power saving
// See PicoPower application note
// - I/O port input with pullup
// - prescale clock
// - BOD disable
// - Power Reduction Register PRR
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
// Disable watchdog after sleep
wdt_disable();
}
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;
}
// run immediately after wakeup
void suspend_wakeup_init(void)
{
// clear keyboard state
clear_keyboard();
#ifdef BACKLIGHT_ENABLE
backlight_init();
#endif
}
#ifndef NO_SUSPEND_POWER_DOWN
/* watchdog timeout */
ISR(WDT_vect)
{
/* wakeup from MCU sleep mode */
/*
// blink LED
static uint8_t led_state = 0;
static uint8_t led_count = 0;
led_count++;
if ((led_count & 0x07) == 0) {
led_set((led_state ^= (1<<USB_LED_CAPS_LOCK)));
}
*/
}
#endif

27
common/avr/suspend_avr.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef SUSPEND_AVR_H
#define SUSPEND_AVR_H
#include <stdint.h>
#include <stdbool.h>
#include <avr/sleep.h>
#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" \
)
#endif

View file

@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include "timer_avr.h"
#include "timer.h"

42
common/avr/timer_avr.h Normal file
View file

@ -0,0 +1,42 @@
/*
Copyright 2011 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program 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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TIMER_AVR_H
#define TIMER_AVR_H 1
#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
#endif
#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."
#endif
#endif

View file

@ -111,7 +111,7 @@ static bool scan_keycode(uint8_t keycode)
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, (key_t){ .row = r, .col = c })) {
if (keycode == keymap_key_to_keycode(0, (keypos_t){ .row = r, .col = c })) {
return true;
}
}

View file

@ -63,19 +63,22 @@ static uint8_t numkey2num(uint8_t code);
static void switch_default_layer(uint8_t layer);
typedef enum { ONESHOT, CONSOLE, MOUSEKEY } cmdstate_t;
static cmdstate_t state = ONESHOT;
command_state_t command_state = ONESHOT;
bool command_proc(uint8_t code)
{
switch (state) {
switch (command_state) {
case ONESHOT:
if (!IS_COMMAND())
return false;
return (command_extra(code) || command_common(code));
break;
case CONSOLE:
command_console(code);
if (IS_COMMAND())
return (command_extra(code) || command_common(code));
else
return (command_console_extra(code) || command_console(code));
break;
#ifdef MOUSEKEY_ENABLE
case MOUSEKEY:
@ -83,12 +86,13 @@ bool command_proc(uint8_t code)
break;
#endif
default:
state = ONESHOT;
command_state = ONESHOT;
return false;
}
return true;
}
/* 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)
@ -96,6 +100,12 @@ bool command_extra(uint8_t code)
return false;
}
bool command_console_extra(uint8_t code) __attribute__ ((weak));
bool command_console_extra(uint8_t code)
{
return false;
}
/***********************************************************
* Command common
@ -203,7 +213,7 @@ static bool command_common(uint8_t code)
command_console_help();
print("\nEnter Console Mode\n");
print("C> ");
state = CONSOLE;
command_state = CONSOLE;
break;
case KC_PAUSE:
clear_keyboard();
@ -388,14 +398,14 @@ static bool command_console(uint8_t code)
case KC_Q:
case KC_ESC:
print("\nQuit Console Mode\n");
state = ONESHOT;
command_state = ONESHOT;
return false;
#ifdef MOUSEKEY_ENABLE
case KC_M:
mousekey_console_help();
print("\nEnter Mousekey Console\n");
print("M0>");
state = MOUSEKEY;
command_state = MOUSEKEY;
return true;
#endif
default:
@ -555,7 +565,7 @@ static bool mousekey_console(uint8_t code)
mousekey_param = 0;
print("\nQuit Mousekey Console\n");
print("C> ");
state = CONSOLE;
command_state = CONSOLE;
return false;
case KC_P:
mousekey_param_print();

View file

@ -18,10 +18,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef COMMAND_H
#define COMMAND
/* TODO: Refactoring */
typedef enum { ONESHOT, CONSOLE, MOUSEKEY } command_state_t;
extern command_state_t command_state;
/* This allows to extend commands. Return false when command is not processed. */
bool command_extra(uint8_t code);
bool command_console_extra(uint8_t code);
#ifdef COMMAND_ENABLE
bool command_proc(uint8_t code);
/* This allows to extend commands. Return 0 when command is not processed. */
bool command_extra(uint8_t code);
#else
#define command_proc(code) false
#endif

View file

@ -19,44 +19,100 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define DEBUG_H 1
#include "print.h"
#include "debug_config.h"
/*
* Debug output control
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef union {
struct {
bool enable:1;
bool matrix:1;
bool keyboard:1;
bool mouse:1;
uint8_t reserved:4;
};
uint8_t raw;
} debug_config_t;
extern debug_config_t debug_config;
debug_config_t debug_config __attribute__ ((weak)) = {};
#ifdef __cplusplus
}
#endif
#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() do { if (debug_enable) print_crlf(); } while (0)
#define dprintf(fmt, ...) do { if (debug_enable) __xprintf(PSTR(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))
/* DO NOT USE these anymore */
#define debug(s) do { if (debug_enable) print(s); } while (0)
#define debugln(s) do { if (debug_enable) print_crlf(); } while (0)
#define debug_S(s) do { if (debug_enable) print_S(s); } while (0)
#define debug_P(s) do { if (debug_enable) print_P(s); } while (0)
#define debug_msg(s) do { \
/* 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_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
#include "nodebug.h"
/* 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)
#endif
#endif

View file

@ -16,7 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <avr/interrupt.h>
//#include <avr/interrupt.h>
#include "keycode.h"
#include "host.h"
#include "util.h"
@ -55,7 +55,7 @@ void host_keyboard_send(report_keyboard_t *report)
if (debug_keyboard) {
dprint("keyboard_report: ");
for (uint8_t i = 0; i < REPORT_SIZE; i++) {
for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) {
dprintf("%02X ", report->raw[i]);
}
dprint("\n");

View file

@ -15,7 +15,6 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <util/delay.h>
#include "keyboard.h"
#include "matrix.h"
#include "keymap.h"
@ -107,7 +106,7 @@ void keyboard_task(void)
for (uint8_t c = 0; c < MATRIX_COLS; c++) {
if (matrix_change & ((matrix_row_t)1<<c)) {
action_exec((keyevent_t){
.key = (key_t){ .row = r, .col = c },
.key = (keypos_t){ .row = r, .col = c },
.pressed = (matrix_row & ((matrix_row_t)1<<c)),
.time = (timer_read() | 1) /* time should not be 0 */
});

View file

@ -30,16 +30,16 @@ extern "C" {
typedef struct {
uint8_t col;
uint8_t row;
} key_t;
} keypos_t;
/* key event */
typedef struct {
key_t key;
keypos_t key;
bool pressed;
uint16_t time;
} keyevent_t;
/* equivalent test of key_t */
/* equivalent test of keypos_t */
#define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col)
/* Rules for No Event:
@ -52,7 +52,7 @@ static inline bool IS_RELEASED(keyevent_t event) { return (!IS_NOEVENT(event) &&
/* Tick event */
#define TICK (keyevent_t){ \
.key = (key_t){ .row = 255, .col = 255 }, \
.key = (keypos_t){ .row = 255, .col = 255 }, \
.pressed = false, \
.time = (timer_read() | 1) \
}
@ -62,6 +62,9 @@ void keyboard_init(void);
void keyboard_task(void);
void keyboard_set_leds(uint8_t leds);
__attribute__ ((weak)) void matrix_power_up(void) {}
__attribute__ ((weak)) void matrix_power_down(void) {}
#ifdef __cplusplus
}
#endif

View file

@ -14,7 +14,6 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <avr/pgmspace.h>
#include "keymap.h"
#include "report.h"
#include "keycode.h"
@ -28,7 +27,7 @@ static action_t keycode_to_action(uint8_t keycode);
/* converts key to action */
action_t action_for_key(uint8_t layer, key_t key)
action_t action_for_key(uint8_t layer, keypos_t key)
{
uint8_t keycode = keymap_key_to_keycode(layer, key);
switch (keycode) {
@ -156,7 +155,7 @@ static action_t keycode_to_action(uint8_t keycode)
* Consider using new keymap API instead.
*/
__attribute__ ((weak))
uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
{
return keymap_get_keycode(layer, key.row, key.col);
}

View file

@ -43,7 +43,7 @@ keymap_config_t keymap_config;
/* translates key to keycode */
uint8_t keymap_key_to_keycode(uint8_t layer, key_t key);
uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
/* translates Fn keycode to action */
action_t keymap_fn_to_action(uint8_t keycode);

View file

@ -53,4 +53,9 @@ matrix_row_t matrix_get_row(uint8_t row);
void matrix_print(void);
/* power control */
void matrix_power_up(void);
void matrix_power_down(void);
#endif

4
common/mbed/bootloader.c Normal file
View file

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

6
common/mbed/suspend.c Normal file
View file

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

41
common/mbed/timer.c Normal file
View file

@ -0,0 +1,41 @@
#include "cmsis.h"
#include "timer.h"
/* Mill second tick count */
volatile uint32_t timer_count = 0;
/* Timer interrupt handler */
void SysTick_Handler(void) {
timer_count++;
}
void timer_init(void)
{
timer_count = 0;
SysTick_Config(SystemCoreClock / 1000); /* 1ms tick */
}
void timer_clear(void)
{
timer_count = 0;
}
uint16_t timer_read(void)
{
return (uint16_t)(timer_count & 0xFFFF);
}
uint32_t timer_read32(void)
{
return timer_count;
}
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);
}

46
common/mbed/xprintf.cpp Normal file
View file

@ -0,0 +1,46 @@
#include <cstdarg>
//#include <stdarg.h>
#include "mbed.h"
#include "mbed/xprintf.h"
#define STRING_STACK_LIMIT 120
/* mbed Serial */
Serial ser(UART_TX, UART_RX);
/* TODO: Need small implementation for embedded */
int xprintf(const char* format, ...)
{
/* copy from mbed/common/RawSerial.cpp */
std::va_list arg;
va_start(arg, format);
int len = vsnprintf(NULL, 0, format, arg);
if (len < STRING_STACK_LIMIT) {
char temp[STRING_STACK_LIMIT];
vsprintf(temp, format, arg);
ser.puts(temp);
} else {
char *temp = new char[len + 1];
vsprintf(temp, format, arg);
ser.puts(temp);
delete[] temp;
}
va_end(arg);
return len;
/* Fail: __builtin_va_arg_pack?
* https://gcc.gnu.org/onlinedocs/gcc-4.3.5/gcc/Constructing-Calls.html#Constructing-Calls
void *arg = __builtin_apply_args();
void *ret = __builtin_apply((void*)(&(ser.printf)), arg, 100);
__builtin_return(ret)
*/
/* Fail: varargs can not be passed to printf
//int r = ser.printf("test %i\r\n", 123);
va_list arg;
va_start(arg, format);
int r = ser.printf(format, arg);
va_end(arg);
return r;
*/
}

17
common/mbed/xprintf.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef XPRINTF_H
#define XPRINTF_H
//#define xprintf(format, ...) __xprintf(format, ##__VA_ARGS__)
#ifdef __cplusplus
extern "C" {
#endif
int xprintf(const char *format, ...);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -16,7 +16,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <util/delay.h>
#include "keycode.h"
#include "host.h"
#include "timer.h"

View file

@ -52,12 +52,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif
uint8_t mk_delay;
uint8_t mk_interval;
uint8_t mk_max_speed;
uint8_t mk_time_to_max;
uint8_t mk_wheel_max_speed;
uint8_t mk_wheel_time_to_max;
#ifdef __cplusplus
extern "C" {
#endif
extern uint8_t mk_delay;
extern uint8_t mk_interval;
extern uint8_t mk_max_speed;
extern uint8_t mk_time_to_max;
extern uint8_t mk_wheel_max_speed;
extern uint8_t mk_wheel_time_to_max;
void mousekey_task(void);
@ -66,4 +70,8 @@ void mousekey_off(uint8_t code);
void mousekey_clear(void);
void mousekey_send(void);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -18,32 +18,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NODEBUG_H
#define NODEBUG_H 1
#include "debug_config.h"
#define dprint(s)
#define dprintln(s)
#define dprintf(fmt, ...)
#define dmsg(s)
#define debug(s)
#define debugln(s)
#define debug_S(s)
#define debug_P(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 NO_DEBUG
#include "debug.h"
#undef NO_DEBUG
#endif

View file

@ -37,26 +37,4 @@ void print_set_sendchar(int8_t (*sendchar_func)(uint8_t))
xdev_out(sendchar_func);
}
void print_S(const char *s)
{
uint8_t c;
while (1) {
c = *s++;
if (!c) break;
if (c == '\n') sendchar('\r');
sendchar(c);
}
}
void print_lf(void)
{
sendchar('\n');
}
void print_crlf(void)
{
sendchar('\r');
sendchar('\n');
}
#endif

View file

@ -27,95 +27,79 @@
#include <stdint.h>
#include <stdbool.h>
#include <avr/pgmspace.h>
#include "xprintf.h"
#include "util.h"
// this macro allows you to write print("some text") and
// the string is automatically placed into flash memory :)
#define print(s) print_P(PSTR(s))
#define println(s) print_P(PSTR(s "\n"))
/* 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)
/* 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))
#ifndef NO_PRINT
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__AVR__)
#include "avr/xprintf.h"
// TODO: avoid collision with arduino/Print.h
#ifndef __cplusplus
#define print(s) xputs(PSTR(s))
#endif
#define println(s) xputs(PSTR(s "\r\n"))
#ifdef __cplusplus
extern "C"
#endif
/* function pointer of sendchar to be used by print utility */
void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
/* print string stored in data memory(SRAM)
* print_S("hello world");
* This consumes precious SRAM memory space for string.
*/
void print_S(const char *s);
#elif defined(__arm__)
void print_lf(void);
void print_crlf(void);
#include "mbed/xprintf.h"
#define print(s) xprintf(s)
#define println(s) xprintf(s "\r\n")
/* TODO: to select output destinations: UART/USBSerial */
#define print_set_sendchar(func)
#endif /* __AVR__ */
/* print string stored in program memory(FLASH)
* print_P(PSTR("hello world");
* This consumes relatively abundant FLASH memory area not SRAM.
*/
#define print_P(s) xputs(s)
/* 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_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_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))
#ifdef __cplusplus
}
#endif
#else
#else /* NO_PRINT */
#define xprintf
#define print
#define println
#define print_set_sendchar(func)
#define print_S(s)
#define print_P(s)
#define print_dec(data)
#define print_decs(data)
#define print_hex4(data)
@ -129,8 +113,30 @@ void print_crlf(void);
#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
#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)
#endif

12
common/progmem.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef PROGMEM_H
#define PROGMEM_H 1
#if defined(__AVR__)
# include <avr/pgmspace.h>
#elif defined(__arm__)
# define PROGMEM
# define pgm_read_byte(p) *(p)
# define pgm_read_word(p) *(p)
#endif
#endif

View file

@ -74,19 +74,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* key report size(NKRO or boot mode) */
#if defined(PROTOCOL_PJRC) && defined(NKRO_ENABLE)
# include "usb.h"
# define REPORT_SIZE KBD2_SIZE
# define REPORT_KEYS (KBD2_SIZE - 2)
# define REPORT_BITS (KBD2_SIZE - 1)
# define KEYBOARD_REPORT_SIZE KBD2_SIZE
# define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
# define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
#elif defined(PROTOCOL_LUFA) && defined(NKRO_ENABLE)
# include "protocol/lufa/descriptor.h"
# define REPORT_SIZE NKRO_EPSIZE
# define REPORT_KEYS (NKRO_EPSIZE - 2)
# define REPORT_BITS (NKRO_EPSIZE - 1)
# define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
# define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
# define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
#else
# define REPORT_SIZE 8
# define REPORT_KEYS 6
# define KEYBOARD_REPORT_SIZE 8
# define KEYBOARD_REPORT_KEYS 6
#endif
@ -115,16 +115,16 @@ extern "C" {
*
*/
typedef union {
uint8_t raw[REPORT_SIZE];
uint8_t raw[KEYBOARD_REPORT_SIZE];
struct {
uint8_t mods;
uint8_t reserved;
uint8_t keys[REPORT_KEYS];
uint8_t keys[KEYBOARD_REPORT_KEYS];
};
#ifdef NKRO_ENABLE
struct {
uint8_t mods;
uint8_t bits[REPORT_BITS];
uint8_t bits[KEYBOARD_REPORT_BITS];
} nkro;
#endif
} __attribute__ ((packed)) report_keyboard_t;

View file

@ -1,76 +0,0 @@
#include "suspend.h"
#include "matrix.h"
#include "action.h"
#include "backlight.h"
void suspend_power_down(void)
{
#ifdef BACKLIGHT_ENABLE
backlight_set(0);
#endif
#ifndef NO_SUSPEND_POWER_DOWN
// Enable watchdog to wake from MCU sleep
cli();
wdt_reset();
// Watchdog Interrupt and System Reset Mode
//wdt_enable(WDTO_1S);
//WDTCSR |= _BV(WDIE);
// Watchdog Interrupt Mode
wdt_intr_enable(WDTO_120MS);
// TODO: more power saving
// See PicoPower application note
// - I/O port input with pullup
// - prescale clock
// - BOD disable
// - Power Reduction Register PRR
// sleep in power down mode
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
// Disable watchdog after sleep
wdt_disable();
#endif
}
bool suspend_wakeup_condition(void)
{
matrix_scan();
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
if (matrix_get_row(r)) return true;
}
return false;
}
// run immediately after wakeup
void suspend_wakeup_init(void)
{
// clear keyboard state
clear_keyboard();
#ifdef BACKLIGHT_ENABLE
backlight_init();
#endif
}
#ifndef NO_SUSPEND_POWER_DOWN
/* watchdog timeout */
ISR(WDT_vect)
{
/* wakeup from MCU sleep mode */
/*
// blink LED
static uint8_t led_state = 0;
static uint8_t led_count = 0;
led_count++;
if ((led_count & 0x07) == 0) {
led_set((led_state ^= (1<<USB_LED_CAPS_LOCK)));
}
*/
}
#endif

View file

@ -3,29 +3,10 @@
#include <stdint.h>
#include <stdbool.h>
#include <avr/sleep.h>
#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" \
)
void suspend_power_down(void);
void suspend_idle(uint8_t timeout);
void suspend_power_down(uint8_t timeout);
bool suspend_wakeup_condition(void);
void suspend_wakeup_init(void);

View file

@ -20,24 +20,10 @@ 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 defined(__AVR__)
#include "avr/timer_avr.h"
#endif
#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."
#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)

20
common/wait.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef WAIT_H
#define WAIT_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__AVR__)
# include <util/delay.h>
# define wait_ms(ms) _delay_ms(ms)
# define wait_us(us) _delay_us(us)
#elif defined(__arm__)
# include "wait_api.h"
#endif
#ifdef __cplusplus
}
#endif
#endif