瀏覽代碼

Merge branch 'rn42' into merge_rn42

Conflicts:
	.gitignore
	common.mk
	common/debug_config.h
	common/print.h
core
tmk 9 年之前
父節點
當前提交
b748f8575a
共有 61 個檔案被更改,包括 1523 行新增397 行删除
  1. 2
    0
      .gitignore
  2. 6
    6
      common.mk
  3. 1
    1
      common/action.c
  4. 10
    3
      common/action.h
  5. 1
    1
      common/action_layer.c
  6. 1
    1
      common/action_layer.h
  7. 4
    4
      common/action_macro.c
  8. 4
    4
      common/action_macro.h
  9. 10
    10
      common/action_util.c
  10. 9
    0
      common/action_util.h
  11. 0
    0
      common/avr/bootloader.c
  12. 0
    0
      common/avr/eeconfig.c
  13. 117
    0
      common/avr/suspend.c
  14. 27
    0
      common/avr/suspend_avr.h
  15. 1
    0
      common/avr/timer.c
  16. 42
    0
      common/avr/timer_avr.h
  17. 0
    0
      common/avr/xprintf.S
  18. 0
    0
      common/avr/xprintf.h
  19. 1
    1
      common/bootmagic.c
  20. 19
    9
      common/command.c
  21. 8
    2
      common/command.h
  22. 84
    28
      common/debug.h
  23. 2
    2
      common/host.c
  24. 1
    2
      common/keyboard.c
  25. 7
    4
      common/keyboard.h
  26. 2
    3
      common/keymap.c
  27. 1
    1
      common/keymap.h
  28. 5
    0
      common/matrix.h
  29. 4
    0
      common/mbed/bootloader.c
  30. 6
    0
      common/mbed/suspend.c
  31. 41
    0
      common/mbed/timer.c
  32. 46
    0
      common/mbed/xprintf.cpp
  33. 17
    0
      common/mbed/xprintf.h
  34. 0
    1
      common/mousekey.c
  35. 14
    6
      common/mousekey.h
  36. 3
    27
      common/nodebug.h
  37. 0
    22
      common/print.c
  38. 75
    69
      common/print.h
  39. 12
    0
      common/progmem.h
  40. 11
    11
      common/report.h
  41. 0
    76
      common/suspend.c
  42. 2
    21
      common/suspend.h
  43. 2
    16
      common/timer.h
  44. 20
    0
      common/wait.h
  45. 1
    0
      protocol.mk
  46. 14
    1
      protocol/lufa/lufa.c
  47. 271
    0
      protocol/mbed/HIDKeyboard.cpp
  48. 31
    0
      protocol/mbed/HIDKeyboard.h
  49. 41
    0
      protocol/mbed/mbed_driver.cpp
  50. 3
    0
      protocol/mbed/mbed_driver.h
  51. 7
    58
      protocol/ps2.h
  52. 10
    6
      protocol/ps2_busywait.c
  53. 15
    0
      protocol/ps2_io.h
  54. 74
    0
      protocol/ps2_io_avr.c
  55. 60
    0
      protocol/ps2_io_mbed.c
  56. 20
    1
      protocol/serial_uart.c
  57. 1
    0
      rules.mk
  58. 79
    0
      tool/mbed/common.mk
  59. 80
    0
      tool/mbed/gcc.mk
  60. 99
    0
      tool/mbed/lpc-vector-checksum.c
  61. 99
    0
      tool/mbed/mbed.mk

+ 2
- 0
.gitignore 查看文件

*.sym *.sym
tags tags
*~ *~
build/
*.bak

+ 6
- 6
common.mk 查看文件

$(COMMON_DIR)/action_layer.c \ $(COMMON_DIR)/action_layer.c \
$(COMMON_DIR)/action_util.c \ $(COMMON_DIR)/action_util.c \
$(COMMON_DIR)/keymap.c \ $(COMMON_DIR)/keymap.c \
$(COMMON_DIR)/timer.c \
$(COMMON_DIR)/print.c \ $(COMMON_DIR)/print.c \
$(COMMON_DIR)/debug.c \ $(COMMON_DIR)/debug.c \
$(COMMON_DIR)/bootloader.c \
$(COMMON_DIR)/suspend.c \
$(COMMON_DIR)/xprintf.S \
$(COMMON_DIR)/util.c
$(COMMON_DIR)/util.c \
$(COMMON_DIR)/avr/suspend.c \
$(COMMON_DIR)/avr/xprintf.S \
$(COMMON_DIR)/avr/timer.c \
$(COMMON_DIR)/avr/bootloader.c




# Option modules # Option modules
ifdef BOOTMAGIC_ENABLE ifdef BOOTMAGIC_ENABLE
SRC += $(COMMON_DIR)/bootmagic.c SRC += $(COMMON_DIR)/bootmagic.c
SRC += $(COMMON_DIR)/eeconfig.c
SRC += $(COMMON_DIR)/avr/eeconfig.c
OPT_DEFS += -DBOOTMAGIC_ENABLE OPT_DEFS += -DBOOTMAGIC_ENABLE
endif endif



+ 1
- 1
common/action.c 查看文件

#endif #endif
} }


bool is_tap_key(key_t key)
bool is_tap_key(keypos_t key)
{ {
action_t action = layer_switch_get_action(key); action_t action = layer_switch_get_action(key);



+ 10
- 3
common/action.h 查看文件

#include "action_macro.h" #include "action_macro.h"




#ifdef __cplusplus
extern "C" {
#endif

/* tapping count and state */ /* tapping count and state */
typedef struct { typedef struct {
bool interrupted :1; bool interrupted :1;
#endif #endif
} keyrecord_t; } keyrecord_t;



/* Execute action per keyevent */ /* Execute action per keyevent */
void action_exec(keyevent_t event); void action_exec(keyevent_t event);


/* action for key */ /* 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 */ /* macro */
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt); const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);
void clear_keyboard(void); void clear_keyboard(void);
void clear_keyboard_but_mods(void); void clear_keyboard_but_mods(void);
void layer_switch(uint8_t new_layer); void layer_switch(uint8_t new_layer);
bool is_tap_key(key_t key);
bool is_tap_key(keypos_t key);


/* debug */ /* debug */
void debug_event(keyevent_t event); void debug_event(keyevent_t event);
void debug_record(keyrecord_t record); void debug_record(keyrecord_t record);
void debug_action(action_t action); void debug_action(action_t action);


#ifdef __cplusplus
}
#endif

#endif /* ACTION_H */ #endif /* ACTION_H */

+ 1
- 1
common/action_layer.c 查看文件







action_t layer_switch_get_action(key_t key)
action_t layer_switch_get_action(keypos_t key)
{ {
action_t action; action_t action;
action.code = ACTION_TRANSPARENT; action.code = ACTION_TRANSPARENT;

+ 1
- 1
common/action_layer.h 查看文件





/* return action depending on current layer status */ /* 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 #endif

+ 4
- 4
common/action_macro.c 查看文件

You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <util/delay.h>
#include "action.h" #include "action.h"
#include "action_util.h" #include "action_util.h"
#include "action_macro.h" #include "action_macro.h"
#include "wait.h"


#ifdef DEBUG_ACTION #ifdef DEBUG_ACTION
#include "debug.h" #include "debug.h"


#ifndef NO_ACTION_MACRO #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) void action_macro_play(const macro_t *macro_p)
{ {
macro_t macro = END; macro_t macro = END;
case WAIT: case WAIT:
MACRO_READ(); MACRO_READ();
dprintf("WAIT(%u)\n", macro); dprintf("WAIT(%u)\n", macro);
{ uint8_t ms = macro; while (ms--) _delay_ms(1); }
{ uint8_t ms = macro; while (ms--) wait_ms(1); }
break; break;
case INTERVAL: case INTERVAL:
interval = MACRO_READ(); interval = MACRO_READ();
return; return;
} }
// interval // interval
{ uint8_t ms = interval; while (ms--) _delay_ms(1); }
{ uint8_t ms = interval; while (ms--) wait_ms(1); }
} }
} }
#endif #endif

+ 4
- 4
common/action_macro.h 查看文件

#ifndef ACTION_MACRO_H #ifndef ACTION_MACRO_H
#define ACTION_MACRO_H #define ACTION_MACRO_H
#include <stdint.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; typedef uint8_t macro_t;



+ 10
- 10
common/action_util.c 查看文件

static uint8_t weak_mods = 0; static uint8_t weak_mods = 0;


#ifdef USB_6KRO_ENABLE #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_INC(a) RO_ADD(a, 1)
#define RO_DEC(a) RO_SUB(a, 1) #define RO_DEC(a) RO_SUB(a, 1)
static int8_t cb_head = 0; static int8_t cb_head = 0;
void clear_keys(void) void clear_keys(void)
{ {
// not clear mods // 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; keyboard_report->raw[i] = 0;
} }
} }
uint8_t has_anykey(void) uint8_t has_anykey(void)
{ {
uint8_t cnt = 0; 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]) if (keyboard_report->raw[i])
cnt++; cnt++;
} }
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
if (keyboard_nkro) { if (keyboard_nkro) {
uint8_t i = 0; 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]); return i<<3 | biton(keyboard_report->nkro.bits[i]);
} }
#else #else
int8_t i = 0; int8_t i = 0;
int8_t empty = -1; int8_t empty = -1;
for (; i < REPORT_KEYS; i++) {
for (; i < KEYBOARD_REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) { if (keyboard_report->keys[i] == code) {
break; break;
} }
empty = i; empty = i;
} }
} }
if (i == REPORT_KEYS) {
if (i == KEYBOARD_REPORT_KEYS) {
if (empty != -1) { if (empty != -1) {
keyboard_report->keys[empty] = code; keyboard_report->keys[empty] = code;
} }
} while (i != cb_tail); } while (i != cb_tail);
} }
#else #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) { if (keyboard_report->keys[i] == code) {
keyboard_report->keys[i] = 0; keyboard_report->keys[i] = 0;
} }
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
static inline void add_key_bit(uint8_t code) 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); keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
} else { } else {
dprintf("add_key_bit: can't add: %02X\n", code); dprintf("add_key_bit: can't add: %02X\n", code);


static inline void del_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)); keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
} else { } else {
dprintf("del_key_bit: can't del: %02X\n", code); dprintf("del_key_bit: can't del: %02X\n", code);

+ 9
- 0
common/action_util.h 查看文件

#include <stdint.h> #include <stdint.h>
#include "report.h" #include "report.h"


#ifdef __cplusplus
extern "C" {
#endif

extern report_keyboard_t *keyboard_report; extern report_keyboard_t *keyboard_report;


void send_keyboard_report(void); void send_keyboard_report(void);
uint8_t has_anykey(void); uint8_t has_anykey(void);
uint8_t has_anymod(void); uint8_t has_anymod(void);
uint8_t get_first_key(void); uint8_t get_first_key(void);

#ifdef __cplusplus
}
#endif

#endif #endif

common/bootloader.c → common/avr/bootloader.c 查看文件


common/eeconfig.c → common/avr/eeconfig.c 查看文件


+ 117
- 0
common/avr/suspend.c 查看文件

#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
- 0
common/avr/suspend_avr.h 查看文件

#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

common/timer.c → common/avr/timer.c 查看文件

#include <avr/io.h> #include <avr/io.h>
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <stdint.h> #include <stdint.h>
#include "timer_avr.h"
#include "timer.h" #include "timer.h"





+ 42
- 0
common/avr/timer_avr.h 查看文件

/*
Copyright 2011 Jun Wako <[email protected]>

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

common/xprintf.S → common/avr/xprintf.S 查看文件


common/xprintf.h → common/avr/xprintf.h 查看文件


+ 1
- 1
common/bootmagic.c 查看文件

matrix_row_t matrix_row = matrix_get_row(r); matrix_row_t matrix_row = matrix_get_row(r);
for (uint8_t c = 0; c < MATRIX_COLS; c++) { for (uint8_t c = 0; c < MATRIX_COLS; c++) {
if (matrix_row & ((matrix_row_t)1<<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; return true;
} }
} }

+ 19
- 9
common/command.c 查看文件

static void switch_default_layer(uint8_t layer); 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) bool command_proc(uint8_t code)
{ {
switch (state) {
switch (command_state) {
case ONESHOT: case ONESHOT:
if (!IS_COMMAND()) if (!IS_COMMAND())
return false; return false;
return (command_extra(code) || command_common(code)); return (command_extra(code) || command_common(code));
break;
case CONSOLE: 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; break;
#ifdef MOUSEKEY_ENABLE #ifdef MOUSEKEY_ENABLE
case MOUSEKEY: case MOUSEKEY:
break; break;
#endif #endif
default: default:
state = ONESHOT;
command_state = ONESHOT;
return false; return false;
} }
return true; return true;
} }


/* TODO: Refactoring is needed. */
/* This allows to define extra commands. return false when not processed. */ /* 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) __attribute__ ((weak));
bool command_extra(uint8_t code) bool command_extra(uint8_t code)
return false; return false;
} }


bool command_console_extra(uint8_t code) __attribute__ ((weak));
bool command_console_extra(uint8_t code)
{
return false;
}



/*********************************************************** /***********************************************************
* Command common * Command common
command_console_help(); command_console_help();
print("\nEnter Console Mode\n"); print("\nEnter Console Mode\n");
print("C> "); print("C> ");
state = CONSOLE;
command_state = CONSOLE;
break; break;
case KC_PAUSE: case KC_PAUSE:
clear_keyboard(); clear_keyboard();
case KC_Q: case KC_Q:
case KC_ESC: case KC_ESC:
print("\nQuit Console Mode\n"); print("\nQuit Console Mode\n");
state = ONESHOT;
command_state = ONESHOT;
return false; return false;
#ifdef MOUSEKEY_ENABLE #ifdef MOUSEKEY_ENABLE
case KC_M: case KC_M:
mousekey_console_help(); mousekey_console_help();
print("\nEnter Mousekey Console\n"); print("\nEnter Mousekey Console\n");
print("M0>"); print("M0>");
state = MOUSEKEY;
command_state = MOUSEKEY;
return true; return true;
#endif #endif
default: default:
mousekey_param = 0; mousekey_param = 0;
print("\nQuit Mousekey Console\n"); print("\nQuit Mousekey Console\n");
print("C> "); print("C> ");
state = CONSOLE;
command_state = CONSOLE;
return false; return false;
case KC_P: case KC_P:
mousekey_param_print(); mousekey_param_print();

+ 8
- 2
common/command.h 查看文件

#ifndef COMMAND_H #ifndef COMMAND_H
#define COMMAND #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 #ifdef COMMAND_ENABLE
bool command_proc(uint8_t code); 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 #else
#define command_proc(code) false #define command_proc(code) false
#endif #endif

+ 84
- 28
common/debug.h 查看文件

#define DEBUG_H 1 #define DEBUG_H 1


#include "print.h" #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 #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))

/* 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 { \
#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) { \ if (debug_enable) { \
print(__FILE__); print(" at "); print_dec(__LINE__); print(" in "); print(": "); print(s); \ print(__FILE__); print(" at "); print_dec(__LINE__); print(" in "); print(": "); print(s); \
} \ } \
} while (0) } 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 #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


#endif #endif

+ 2
- 2
common/host.c 查看文件

*/ */


#include <stdint.h> #include <stdint.h>
#include <avr/interrupt.h>
//#include <avr/interrupt.h>
#include "keycode.h" #include "keycode.h"
#include "host.h" #include "host.h"
#include "util.h" #include "util.h"


if (debug_keyboard) { if (debug_keyboard) {
dprint("keyboard_report: "); 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]); dprintf("%02X ", report->raw[i]);
} }
dprint("\n"); dprint("\n");

+ 1
- 2
common/keyboard.c 查看文件

along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdint.h> #include <stdint.h>
#include <util/delay.h>
#include "keyboard.h" #include "keyboard.h"
#include "matrix.h" #include "matrix.h"
#include "keymap.h" #include "keymap.h"
for (uint8_t c = 0; c < MATRIX_COLS; c++) { 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){ 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)), .pressed = (matrix_row & ((matrix_row_t)1<<c)),
.time = (timer_read() | 1) /* time should not be 0 */ .time = (timer_read() | 1) /* time should not be 0 */
}); });

+ 7
- 4
common/keyboard.h 查看文件

typedef struct { typedef struct {
uint8_t col; uint8_t col;
uint8_t row; uint8_t row;
} key_t;
} keypos_t;


/* key event */ /* key event */
typedef struct { typedef struct {
key_t key;
keypos_t key;
bool pressed; bool pressed;
uint16_t time; uint16_t time;
} keyevent_t; } keyevent_t;


/* equivalent test of key_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: /* Rules for No Event:


/* Tick event */ /* Tick event */
#define TICK (keyevent_t){ \ #define TICK (keyevent_t){ \
.key = (key_t){ .row = 255, .col = 255 }, \
.key = (keypos_t){ .row = 255, .col = 255 }, \
.pressed = false, \ .pressed = false, \
.time = (timer_read() | 1) \ .time = (timer_read() | 1) \
} }
void keyboard_task(void); void keyboard_task(void);
void keyboard_set_leds(uint8_t leds); void keyboard_set_leds(uint8_t leds);


__attribute__ ((weak)) void matrix_power_up(void) {}
__attribute__ ((weak)) void matrix_power_down(void) {}

#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

+ 2
- 3
common/keymap.c 查看文件

You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <avr/pgmspace.h>
#include "keymap.h" #include "keymap.h"
#include "report.h" #include "report.h"
#include "keycode.h" #include "keycode.h"




/* converts key to action */ /* 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); uint8_t keycode = keymap_key_to_keycode(layer, key);
switch (keycode) { switch (keycode) {
* Consider using new keymap API instead. * Consider using new keymap API instead.
*/ */
__attribute__ ((weak)) __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); return keymap_get_keycode(layer, key.row, key.col);
} }

+ 1
- 1
common/keymap.h 查看文件





/* translates key to keycode */ /* 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 */ /* translates Fn keycode to action */
action_t keymap_fn_to_action(uint8_t keycode); action_t keymap_fn_to_action(uint8_t keycode);

+ 5
- 0
common/matrix.h 查看文件

void matrix_print(void); void matrix_print(void);




/* power control */
void matrix_power_up(void);
void matrix_power_down(void);


#endif #endif

+ 4
- 0
common/mbed/bootloader.c 查看文件

#include "bootloader.h"


void bootloader_jump(void) {}

+ 6
- 0
common/mbed/suspend.c 查看文件

#include <stdbool.h>


void suspend_power_down(void) {}
bool suspend_wakeup_condition(void) { return true; }
void suspend_wakeup_init(void) {}

+ 41
- 0
common/mbed/timer.c 查看文件

#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
- 0
common/mbed/xprintf.cpp 查看文件

#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
- 0
common/mbed/xprintf.h 查看文件

#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

+ 0
- 1
common/mousekey.c 查看文件

*/ */


#include <stdint.h> #include <stdint.h>
#include <util/delay.h>
#include "keycode.h" #include "keycode.h"
#include "host.h" #include "host.h"
#include "timer.h" #include "timer.h"

+ 14
- 6
common/mousekey.h 查看文件

#endif #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); void mousekey_task(void);
void mousekey_clear(void); void mousekey_clear(void);
void mousekey_send(void); void mousekey_send(void);


#ifdef __cplusplus
}
#endif

#endif #endif

+ 3
- 27
common/nodebug.h 查看文件

#ifndef NODEBUG_H #ifndef NODEBUG_H
#define NODEBUG_H 1 #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 #endif

+ 0
- 22
common/print.c 查看文件

xdev_out(sendchar_func); 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 #endif

+ 75
- 69
common/print.h 查看文件



#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <avr/pgmspace.h>
#include "xprintf.h"
#include "util.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




#if defined(__AVR__)


#ifndef NO_PRINT
#include "avr/xprintf.h"


#ifdef __cplusplus
extern "C" {

// TODO: avoid collision with arduino/Print.h
#ifndef __cplusplus
#define print(s) xputs(PSTR(s))
#endif #endif
#define println(s) xputs(PSTR(s "\r\n"))


#ifdef __cplusplus
extern "C"
#endif
/* function pointer of sendchar to be used by print utility */ /* function pointer of sendchar to be used by print utility */
void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t)); 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")


/* 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)
/* TODO: to select output destinations: UART/USBSerial */
#define print_set_sendchar(func)


/* decimal */
#define print_dec(i) xprintf("%u", i)
#define print_decs(i) xprintf("%d", i)
#endif /* __AVR__ */


/* 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)


/* decimal */
#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)
/* binary */ /* 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))

#ifdef __cplusplus
}
#endif

#else

#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))

#else /* NO_PRINT */

#define xprintf
#define print
#define println
#define print_set_sendchar(func) #define print_set_sendchar(func)
#define print_S(s)
#define print_P(s)
#define print_dec(data) #define print_dec(data)
#define print_decs(data) #define print_decs(data)
#define print_hex4(data) #define print_hex4(data)
#define print_bin_reverse8(data) #define print_bin_reverse8(data)
#define print_bin_reverse16(data) #define print_bin_reverse16(data)
#define print_bin_reverse32(data) #define print_bin_reverse32(data)

#endif
#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)




#endif #endif

+ 12
- 0
common/progmem.h 查看文件

#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

+ 11
- 11
common/report.h 查看文件

/* key report size(NKRO or boot mode) */ /* key report size(NKRO or boot mode) */
#if defined(PROTOCOL_PJRC) && defined(NKRO_ENABLE) #if defined(PROTOCOL_PJRC) && defined(NKRO_ENABLE)
# include "usb.h" # 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) #elif defined(PROTOCOL_LUFA) && defined(NKRO_ENABLE)
# include "protocol/lufa/descriptor.h" # 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 #else
# define REPORT_SIZE 8
# define REPORT_KEYS 6
# define KEYBOARD_REPORT_SIZE 8
# define KEYBOARD_REPORT_KEYS 6
#endif #endif




* *
*/ */
typedef union { typedef union {
uint8_t raw[REPORT_SIZE];
uint8_t raw[KEYBOARD_REPORT_SIZE];
struct { struct {
uint8_t mods; uint8_t mods;
uint8_t reserved; uint8_t reserved;
uint8_t keys[REPORT_KEYS];
uint8_t keys[KEYBOARD_REPORT_KEYS];
}; };
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
struct { struct {
uint8_t mods; uint8_t mods;
uint8_t bits[REPORT_BITS];
uint8_t bits[KEYBOARD_REPORT_BITS];
} nkro; } nkro;
#endif #endif
} __attribute__ ((packed)) report_keyboard_t; } __attribute__ ((packed)) report_keyboard_t;

+ 0
- 76
common/suspend.c 查看文件

#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

+ 2
- 21
common/suspend.h 查看文件



#include <stdint.h> #include <stdint.h>
#include <stdbool.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); bool suspend_wakeup_condition(void);
void suspend_wakeup_init(void); void suspend_wakeup_init(void);



+ 2
- 16
common/timer.h 查看文件



#include <stdint.h> #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 #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(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_8(a, b) TIMER_DIFF(a, b, UINT8_MAX)

+ 20
- 0
common/wait.h 查看文件

#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

+ 1
- 0
protocol.mk 查看文件



ifdef PS2_USE_BUSYWAIT ifdef PS2_USE_BUSYWAIT
SRC += protocol/ps2_busywait.c SRC += protocol/ps2_busywait.c
SRC += protocol/ps2_io_avr.c
OPT_DEFS += -DPS2_USE_BUSYWAIT OPT_DEFS += -DPS2_USE_BUSYWAIT
endif endif



+ 14
- 1
protocol/lufa/lufa.c 查看文件

*/ */
void EVENT_USB_Device_Connect(void) void EVENT_USB_Device_Connect(void)
{ {
/* For battery powered device */
if (!USB_IsInitialized) {
USB_Init();
USB_Device_EnableSOFEvents();
}
} }


void EVENT_USB_Device_Disconnect(void) void EVENT_USB_Device_Disconnect(void)
{ {
/* For battery powered device */
/* TODO: This doesn't work. After several plug in/outs can not be enumerated.
if (USB_IsInitialized) {
USB_Disable(); // Disable all interrupts
USB_Controller_Enable();
USB_INT_Enable(USB_INT_VBUSTI);
}
*/
} }


void EVENT_USB_Device_Reset(void) void EVENT_USB_Device_Reset(void)
print("Keyboard start.\n"); print("Keyboard start.\n");
while (1) { while (1) {
while (USB_DeviceState == DEVICE_STATE_Suspended) { while (USB_DeviceState == DEVICE_STATE_Suspended) {
suspend_power_down();
suspend_power_down(WDTO_120MS);
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
USB_Device_SendRemoteWakeup(); USB_Device_SendRemoteWakeup();
} }

+ 271
- 0
protocol/mbed/HIDKeyboard.cpp 查看文件

#include <stdint.h>
#include "USBHID.h"
#include "USBHID_Types.h"
#include "USBDescriptor.h"
#include "HIDKeyboard.h"

#define DEFAULT_CONFIGURATION (1)


HIDKeyboard::HIDKeyboard(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release)
{
USBDevice::connect();
}

bool HIDKeyboard::sendReport(report_keyboard_t report) {
USBDevice::write(EP1IN, report.raw, sizeof(report), MAX_PACKET_SIZE_EP1);
return true;
}

uint8_t HIDKeyboard::leds() {
return led_state;
}

bool HIDKeyboard::USBCallback_setConfiguration(uint8_t configuration) {
if (configuration != DEFAULT_CONFIGURATION) {
return false;
}

// Configure endpoints > 0
addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
//addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);

// We activate the endpoint to be able to recceive data
//readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
return true;
}


uint8_t * HIDKeyboard::stringImanufacturerDesc() {
static uint8_t stringImanufacturerDescriptor[] = {
0x18, /*bLength*/
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
't',0,'m',0,'k',0,'-',0,'k',0,'b',0,'d',0,'.',0,'c',0,'o',0,'m',0 /*bString iManufacturer*/
};
return stringImanufacturerDescriptor;
}

uint8_t * HIDKeyboard::stringIproductDesc() {
static uint8_t stringIproductDescriptor[] = {
0x0a, /*bLength*/
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
'm',0,'b',0,'e',0,'d',0 /*bString iProduct*/
};
return stringIproductDescriptor;
}

uint8_t * HIDKeyboard::stringIserialDesc() {
static uint8_t stringIserialDescriptor[] = {
0x04, /*bLength*/
STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
'0',0 /*bString iSerial*/
};
return stringIserialDescriptor;
}

uint8_t * HIDKeyboard::reportDesc() {
static uint8_t reportDescriptor[] = {
USAGE_PAGE(1), 0x01, // Generic Desktop
USAGE(1), 0x06, // Keyboard
COLLECTION(1), 0x01, // Application

USAGE_PAGE(1), 0x07, // Key Codes
USAGE_MINIMUM(1), 0xE0,
USAGE_MAXIMUM(1), 0xE7,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0x01,
REPORT_SIZE(1), 0x01,
REPORT_COUNT(1), 0x08,
INPUT(1), 0x02, // Data, Variable, Absolute

REPORT_COUNT(1), 0x01,
REPORT_SIZE(1), 0x08,
INPUT(1), 0x01, // Constant

REPORT_COUNT(1), 0x05,
REPORT_SIZE(1), 0x01,
USAGE_PAGE(1), 0x08, // LEDs
USAGE_MINIMUM(1), 0x01,
USAGE_MAXIMUM(1), 0x05,
OUTPUT(1), 0x02, // Data, Variable, Absolute

REPORT_COUNT(1), 0x01,
REPORT_SIZE(1), 0x03,
OUTPUT(1), 0x01, // Constant


REPORT_COUNT(1), 0x06,
REPORT_SIZE(1), 0x08,
LOGICAL_MINIMUM(1), 0x00,
LOGICAL_MAXIMUM(1), 0xFF,
USAGE_PAGE(1), 0x07, // Key Codes
USAGE_MINIMUM(1), 0x00,
USAGE_MAXIMUM(1), 0xFF,
INPUT(1), 0x00, // Data, Array
END_COLLECTION(0),
};
reportLength = sizeof(reportDescriptor);
return reportDescriptor;
}

uint16_t HIDKeyboard::reportDescLength() {
reportDesc();
return reportLength;
}

#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+ (1 * INTERFACE_DESCRIPTOR_LENGTH) \
+ (1 * HID_DESCRIPTOR_LENGTH) \
+ (1 * ENDPOINT_DESCRIPTOR_LENGTH))
uint8_t * HIDKeyboard::configurationDesc() {
static uint8_t configurationDescriptor[] = {
CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
CONFIGURATION_DESCRIPTOR, // bDescriptorType
LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
0x01, // bNumInterfaces
DEFAULT_CONFIGURATION, // bConfigurationValue
0x00, // iConfiguration
C_RESERVED | C_REMOTE_WAKEUP, // bmAttributes
C_POWER(100), // bMaxPowerHello World from Mbed

INTERFACE_DESCRIPTOR_LENGTH, // bLength
INTERFACE_DESCRIPTOR, // bDescriptorType
0x00, // bInterfaceNumber
0x00, // bAlternateSetting
0x01, // bNumEndpoints
HID_CLASS, // bInterfaceClass
1, // bInterfaceSubClass (boot)
1, // bInterfaceProtocol (keyboard)
0x00, // iInterface

HID_DESCRIPTOR_LENGTH, // bLength
HID_DESCRIPTOR, // bDescriptorType
LSB(HID_VERSION_1_11), // bcdHID (LSB)
MSB(HID_VERSION_1_11), // bcdHID (MSB)
0x00, // bCountryCode
0x01, // bNumDescriptors
REPORT_DESCRIPTOR, // bDescriptorType
(uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
(uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB)

ENDPOINT_DESCRIPTOR_LENGTH, // bLength
ENDPOINT_DESCRIPTOR, // bDescriptorType
PHY_TO_DESC(EP1IN), // bEndpointAddress
E_INTERRUPT, // bmAttributes
LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
1, // bInterval (milliseconds)
};
return configurationDescriptor;
}

#if 0
uint8_t * HIDKeyboard::deviceDesc() {
static uint8_t deviceDescriptor[] = {
DEVICE_DESCRIPTOR_LENGTH, /* bLength */
DEVICE_DESCRIPTOR, /* bDescriptorType */
LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */
MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */
0x00, /* bDeviceClass */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceprotocol */
MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
(uint8_t)(LSB(0xfeed)), /* idVendor (LSB) */
(uint8_t)(MSB(0xfeed)), /* idVendor (MSB) */
(uint8_t)(LSB(0x1bed)), /* idProduct (LSB) */
(uint8_t)(MSB(0x1bed)), /* idProduct (MSB) */
(uint8_t)(LSB(0x0002)), /* bcdDevice (LSB) */
(uint8_t)(MSB(0x0002)), /* bcdDevice (MSB) */
0, /* iManufacturer */
0, /* iProduct */
0, /* iSerialNumber */
0x01 /* bNumConfigurations */
};
return deviceDescriptor;
}
#endif

bool HIDKeyboard::USBCallback_request() {
bool success = false;
CONTROL_TRANSFER * transfer = getTransferPtr();
uint8_t *hidDescriptor;

// Process additional standard requests

if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
{
switch (transfer->setup.bRequest)
{
case GET_DESCRIPTOR:
switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
{
case REPORT_DESCRIPTOR:
if ((reportDesc() != NULL) \
&& (reportDescLength() != 0))
{
transfer->remaining = reportDescLength();
transfer->ptr = reportDesc();
transfer->direction = DEVICE_TO_HOST;
success = true;
}
break;
case HID_DESCRIPTOR:
// Find the HID descriptor, after the configuration descriptor
hidDescriptor = findDescriptor(HID_DESCRIPTOR);
if (hidDescriptor != NULL)
{
transfer->remaining = HID_DESCRIPTOR_LENGTH;
transfer->ptr = hidDescriptor;
transfer->direction = DEVICE_TO_HOST;
success = true;
}
break;
default:
break;
}
break;
default:
break;
}
}

// Process class-specific requests
if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
{
switch (transfer->setup.bRequest) {
case SET_REPORT:
// LED indicator
// TODO: check Interface and Report length?
// if (transfer->setup.wIndex == INTERFACE_KEYBOAD) { }
// if (transfer->setup.wLength == 1)

transfer->remaining = 1;
//transfer->ptr = ?? what ptr should be set when OUT(not used?)
transfer->direction = HOST_TO_DEVICE;
transfer->notify = true; /* notify with USBCallback_requestCompleted */
success = true;
default:
break;
}
}

return success;
}

void HIDKeyboard::USBCallback_requestCompleted(uint8_t * buf, uint32_t length)
{
if (length > 0) {
CONTROL_TRANSFER *transfer = getTransferPtr();
if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
switch (transfer->setup.bRequest) {
case SET_REPORT:
led_state = buf[0];
break;
default:
break;
}
}
}
}

+ 31
- 0
protocol/mbed/HIDKeyboard.h 查看文件

#ifndef HIDKEYBOARD_H

#include "stdint.h"
#include "stdbool.h"
#include "USBHID.h"
#include "report.h"


class HIDKeyboard : public USBDevice {
public:
HIDKeyboard(uint16_t vendor_id = 0xFEED, uint16_t product_id = 0xabed, uint16_t product_release = 0x0001);

bool sendReport(report_keyboard_t report);
uint8_t leds(void);
protected:
uint16_t reportLength;
virtual bool USBCallback_setConfiguration(uint8_t configuration);
virtual uint8_t * stringImanufacturerDesc();
virtual uint8_t * stringIproductDesc();
virtual uint8_t * stringIserialDesc();
virtual uint16_t reportDescLength();
virtual uint8_t * reportDesc();
virtual uint8_t * configurationDesc();
//virtual uint8_t * deviceDesc();
virtual bool USBCallback_request();
virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length);
private:
uint8_t led_state;
};

#endif

+ 41
- 0
protocol/mbed/mbed_driver.cpp 查看文件

#include "HIDKeyboard.h"
#include "host.h"
#include "host_driver.h"
#include "mbed_driver.h"

HIDKeyboard keyboard;


/* Host driver */
static uint8_t keyboard_leds(void);
static void send_keyboard(report_keyboard_t *report);
static void send_mouse(report_mouse_t *report);
static void send_system(uint16_t data);
static void send_consumer(uint16_t data);

host_driver_t mbed_driver = {
keyboard_leds,
send_keyboard,
send_mouse,
send_system,
send_consumer
};


static uint8_t keyboard_leds(void)
{
return keyboard.leds();
}
static void send_keyboard(report_keyboard_t *report)
{
keyboard.sendReport(*report);
}
static void send_mouse(report_mouse_t *report)
{
}
static void send_system(uint16_t data)
{
}
static void send_consumer(uint16_t data)
{
}

+ 3
- 0
protocol/mbed/mbed_driver.h 查看文件

#include "host_driver.h"

extern host_driver_t mbed_driver;

+ 7
- 58
protocol/ps2.h 查看文件

#define PS2_H #define PS2_H


#include <stdbool.h> #include <stdbool.h>
#include <util/delay.h>
#include <avr/io.h>
#include "wait.h"
#include "ps2_io.h"
#include "print.h"


/* /*
* Primitive PS/2 Library for AVR * Primitive PS/2 Library for AVR
void ps2_host_set_led(uint8_t usb_led); void ps2_host_set_led(uint8_t usb_led);




/* Check port settings for clock and data line */
#if !(defined(PS2_CLOCK_PORT) && \
defined(PS2_CLOCK_PIN) && \
defined(PS2_CLOCK_DDR) && \
defined(PS2_CLOCK_BIT))
# error "PS/2 clock port setting is required in config.h"
#endif

#if !(defined(PS2_DATA_PORT) && \
defined(PS2_DATA_PIN) && \
defined(PS2_DATA_DDR) && \
defined(PS2_DATA_BIT))
# error "PS/2 data port setting is required in config.h"
#endif

/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* static functions * static functions
*------------------------------------------------------------------*/ *------------------------------------------------------------------*/
static inline void clock_lo(void)
{
PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
PS2_CLOCK_DDR |= (1<<PS2_CLOCK_BIT);
}
static inline void clock_hi(void)
{
/* input with pull up */
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
}
static inline bool clock_in(void)
{
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
_delay_us(1);
return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
}
static inline void data_lo(void)
{
PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
PS2_DATA_DDR |= (1<<PS2_DATA_BIT);
}
static inline void data_hi(void)
{
/* input with pull up */
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
}
static inline bool data_in(void)
{
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
_delay_us(1);
return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
}

static inline uint16_t wait_clock_lo(uint16_t us) static inline uint16_t wait_clock_lo(uint16_t us)
{ {
while (clock_in() && us) { asm(""); _delay_us(1); us--; }
while (clock_in() && us) { asm(""); wait_us(1); us--; }
return us; return us;
} }
static inline uint16_t wait_clock_hi(uint16_t us) static inline uint16_t wait_clock_hi(uint16_t us)
{ {
while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
while (!clock_in() && us) { asm(""); wait_us(1); us--; }
return us; return us;
} }
static inline uint16_t wait_data_lo(uint16_t us) static inline uint16_t wait_data_lo(uint16_t us)
{ {
while (data_in() && us) { asm(""); _delay_us(1); us--; }
while (data_in() && us) { asm(""); wait_us(1); us--; }
return us; return us;
} }
static inline uint16_t wait_data_hi(uint16_t us) static inline uint16_t wait_data_hi(uint16_t us)
{ {
while (!data_in() && us) { asm(""); _delay_us(1); us--; }
while (!data_in() && us) { asm(""); wait_us(1); us--; }
return us; return us;
} }



+ 10
- 6
protocol/ps2_busywait.c 查看文件

*/ */


#include <stdbool.h> #include <stdbool.h>
#include <util/delay.h>
#include "wait.h"
#include "ps2.h" #include "ps2.h"
#include "ps2_io.h"
#include "debug.h" #include "debug.h"






void ps2_host_init(void) void ps2_host_init(void)
{ {
clock_init();
data_init();

// POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20) // POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
_delay_ms(2500);
wait_ms(2500);


inhibit(); inhibit();
} }


/* terminate a transmission if we have */ /* terminate a transmission if we have */
inhibit(); inhibit();
_delay_us(100); // 100us [4]p.13, [5]p.50
wait_us(100); // 100us [4]p.13, [5]p.50


/* 'Request to Send' and Start bit */ /* 'Request to Send' and Start bit */
data_lo(); data_lo();


/* Data bit */ /* Data bit */
for (uint8_t i = 0; i < 8; i++) { for (uint8_t i = 0; i < 8; i++) {
_delay_us(15);
wait_us(15);
if (data&(1<<i)) { if (data&(1<<i)) {
parity = !parity; parity = !parity;
data_hi(); data_hi();
} }


/* Parity bit */ /* Parity bit */
_delay_us(15);
wait_us(15);
if (parity) { data_hi(); } else { data_lo(); } if (parity) { data_hi(); } else { data_lo(); }
WAIT(clock_hi, 50, 4); WAIT(clock_hi, 50, 4);
WAIT(clock_lo, 50, 5); WAIT(clock_lo, 50, 5);


/* Stop bit */ /* Stop bit */
_delay_us(15);
wait_us(15);
data_hi(); data_hi();


/* Ack */ /* Ack */

+ 15
- 0
protocol/ps2_io.h 查看文件

#ifndef PS2_IO_H
#define PS2_IO_H


void clock_init(void);
void clock_lo(void);
void clock_hi(void);
bool clock_in(void);

void data_init(void);
void data_lo(void);
void data_hi(void);
bool data_in(void);

#endif

+ 74
- 0
protocol/ps2_io_avr.c 查看文件

#include <stdbool.h>
#include <util/delay.h>

/* Check port settings for clock and data line */
#if !(defined(PS2_CLOCK_PORT) && \
defined(PS2_CLOCK_PIN) && \
defined(PS2_CLOCK_DDR) && \
defined(PS2_CLOCK_BIT))
# error "PS/2 clock port setting is required in config.h"
#endif

#if !(defined(PS2_DATA_PORT) && \
defined(PS2_DATA_PIN) && \
defined(PS2_DATA_DDR) && \
defined(PS2_DATA_BIT))
# error "PS/2 data port setting is required in config.h"
#endif


/*
* Clock
*/
void clock_init(void)
{
}

void clock_lo(void)
{
PS2_CLOCK_PORT &= ~(1<<PS2_CLOCK_BIT);
PS2_CLOCK_DDR |= (1<<PS2_CLOCK_BIT);
}

void clock_hi(void)
{
/* input with pull up */
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
}

bool clock_in(void)
{
PS2_CLOCK_DDR &= ~(1<<PS2_CLOCK_BIT);
PS2_CLOCK_PORT |= (1<<PS2_CLOCK_BIT);
_delay_us(1);
return PS2_CLOCK_PIN&(1<<PS2_CLOCK_BIT);
}

/*
* Data
*/
void data_init(void)
{
}

void data_lo(void)
{
PS2_DATA_PORT &= ~(1<<PS2_DATA_BIT);
PS2_DATA_DDR |= (1<<PS2_DATA_BIT);
}

void data_hi(void)
{
/* input with pull up */
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
}

bool data_in(void)
{
PS2_DATA_DDR &= ~(1<<PS2_DATA_BIT);
PS2_DATA_PORT |= (1<<PS2_DATA_BIT);
_delay_us(1);
return PS2_DATA_PIN&(1<<PS2_DATA_BIT);
}

+ 60
- 0
protocol/ps2_io_mbed.c 查看文件

#include <stdbool.h>
#include "ps2_io.h"
#include "gpio_api.h"


static gpio_t clock;
static gpio_t data;

/*
* Clock
*/
void clock_init(void)
{
gpio_init(&clock, P0_9);
gpio_mode(&clock, OpenDrain|PullNone);
}

void clock_lo(void)
{
gpio_dir(&clock, PIN_OUTPUT);
gpio_write(&clock, 0);
}
void clock_hi(void)
{
gpio_dir(&clock, PIN_OUTPUT);
gpio_write(&clock, 1);
}

bool clock_in(void)
{
gpio_dir(&clock, PIN_INPUT);
return gpio_read(&clock);
}

/*
* Data
*/
void data_init(void)
{
gpio_init(&data, P0_8);
gpio_mode(&data, OpenDrain|PullNone);
}

void data_lo(void)
{
gpio_dir(&data, PIN_OUTPUT);
gpio_write(&data, 0);
}

void data_hi(void)
{
gpio_dir(&data, PIN_OUTPUT);
gpio_write(&data, 1);
}

bool data_in(void)
{
gpio_dir(&data, PIN_INPUT);
return gpio_read(&data);
}

+ 20
- 1
protocol/serial_uart.c 查看文件

#include "serial.h" #include "serial.h"




#if defined(SERIAL_UART_RTS_LO) && defined(SERIAL_UART_RTS_HI)
// Buffer state
// Empty: RBUF_SPACE == RBUF_SIZE(head==tail)
// Last 1 space: RBUF_SPACE == 2
// Full: RBUF_SPACE == 1(last cell of rbuf be never used.)
#define RBUF_SPACE() (rbuf_head < rbuf_tail ? (rbuf_tail - rbuf_head) : (RBUF_SIZE - rbuf_head + rbuf_tail))
// allow to send
#define rbuf_check_rts_lo() do { if (RBUF_SPACE() > 2) SERIAL_UART_RTS_LO(); } while (0)
// prohibit to send
#define rbuf_check_rts_hi() do { if (RBUF_SPACE() <= 2) SERIAL_UART_RTS_HI(); } while (0)
#else
#define rbuf_check_rts_lo()
#define rbuf_check_rts_hi()
#endif


void serial_init(void) void serial_init(void)
{ {
SERIAL_UART_INIT(); SERIAL_UART_INIT();
} }


// RX ring buffer // RX ring buffer
#define RBUF_SIZE 8
#define RBUF_SIZE 256
static uint8_t rbuf[RBUF_SIZE]; static uint8_t rbuf[RBUF_SIZE];
static uint8_t rbuf_head = 0; static uint8_t rbuf_head = 0;
static uint8_t rbuf_tail = 0; static uint8_t rbuf_tail = 0;


data = rbuf[rbuf_tail]; data = rbuf[rbuf_tail];
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
rbuf_check_rts_lo();
return data; return data;
} }




data = rbuf[rbuf_tail]; data = rbuf[rbuf_tail];
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
rbuf_check_rts_lo();
return data; return data;
} }


rbuf[rbuf_head] = SERIAL_UART_DATA; rbuf[rbuf_head] = SERIAL_UART_DATA;
rbuf_head = next; rbuf_head = next;
} }
rbuf_check_rts_hi();
} }

+ 1
- 0
rules.mk 查看文件

# Assemble: create object files from assembler source files. # Assemble: create object files from assembler source files.
$(OBJDIR)/%.o : %.S $(OBJDIR)/%.o : %.S
@echo @echo
mkdir -p $(@D)
@echo $(MSG_ASSEMBLING) $< @echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@ $(CC) -c $(ALL_ASFLAGS) $< -o $@



+ 79
- 0
tool/mbed/common.mk 查看文件

OBJECTS += \
$(OBJDIR)/common/action.o \
$(OBJDIR)/common/action_tapping.o \
$(OBJDIR)/common/action_macro.o \
$(OBJDIR)/common/action_layer.o \
$(OBJDIR)/common/action_util.o \
$(OBJDIR)/common/host.o \
$(OBJDIR)/common/keymap.o \
$(OBJDIR)/common/keyboard.o \
$(OBJDIR)/common/util.o \
$(OBJDIR)/common/mbed/suspend.o \
$(OBJDIR)/common/mbed/timer.o \
$(OBJDIR)/common/mbed/xprintf.o \
$(OBJDIR)/common/mbed/bootloader.o \

INCLUDE_PATHS += \
-I$(TMK_DIR)/common \
-I$(TMK_DIR)/protocol

CC_FLAGS += -include $(CONFIG_H)



# Option modules
ifdef BOOTMAGIC_ENABLE
$(error Not Supported)
OBJECTS += $(OBJDIR)/common/bootmagic.o
OBJECTS += $(OBJDIR)/common/mbed/eeprom.o
OPT_DEFS += -DBOOTMAGIC_ENABLE
endif

ifdef MOUSEKEY_ENABLE
OBJECTS += $(OBJDIR)/common/mousekey.o
OPT_DEFS += -DMOUSEKEY_ENABLE
OPT_DEFS += -DMOUSE_ENABLE
endif

ifdef EXTRAKEY_ENABLE
$(error Not Supported)
OPT_DEFS += -DEXTRAKEY_ENABLE
endif

ifdef CONSOLE_ENABLE
$(error Not Supported)
OPT_DEFS += -DCONSOLE_ENABLE
else
OPT_DEFS += -DNO_PRINT
OPT_DEFS += -DNO_DEBUG
endif

ifdef COMMAND_ENABLE
$(error Not Supported)
SRC += common/command.c
OPT_DEFS += -DCOMMAND_ENABLE
endif

ifdef NKRO_ENABLE
$(error Not Supported)
OPT_DEFS += -DNKRO_ENABLE
endif

ifdef SLEEP_LED_ENABLE
$(error Not Supported)
SRC += common/sleep_led.c
OPT_DEFS += -DSLEEP_LED_ENABLE
OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
endif

ifdef BACKLIGHT_ENABLE
$(error Not Supported)
SRC += common/backlight.c
OPT_DEFS += -DBACKLIGHT_ENABLE
endif

ifdef KEYMAP_SECTION_ENABLE
$(error Not Supported)
OPT_DEFS += -DKEYMAP_SECTION_ENABLE
EXTRALDFLAGS = -Wl,-L$(TOP_DIR),-Tldscript_keymap_avr5.x
endif

+ 80
- 0
tool/mbed/gcc.mk 查看文件

###############################################################################
GCC_BIN =
AS = $(GCC_BIN)arm-none-eabi-as
CC = $(GCC_BIN)arm-none-eabi-gcc
CPP = $(GCC_BIN)arm-none-eabi-g++
LD = $(GCC_BIN)arm-none-eabi-gcc
OBJCOPY = $(GCC_BIN)arm-none-eabi-objcopy
OBJDUMP = $(GCC_BIN)arm-none-eabi-objdump
SIZE = $(GCC_BIN)arm-none-eabi-size
CHKSUM = $(TMK_DIR)/tool/mbed/lpc-vector-checksum

CPU = -mcpu=cortex-m0 -mthumb

CC_FLAGS += $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -fno-exceptions -ffunction-sections -fdata-sections
CC_FLAGS += -MMD -MP
CC_SYMBOLS = -DTARGET_LPC11U35_401 -DTARGET_M0 -DTARGET_NXP -DTARGET_LPC11UXX -DTOOLCHAIN_GCC_ARM -DTOOLCHAIN_GCC -D__CORTEX_M0 -DARM_MATH_CM0 -DMBED_BUILD_TIMESTAMP=1399108688.49 -D__MBED__=1

LD_FLAGS = -mcpu=cortex-m0 -mthumb -Wl,--gc-sections --specs=nano.specs
LD_FLAGS += -Wl,-Map=$(OBJDIR)/$(PROJECT).map,--cref
LD_SYS_LIBS = -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys

ifeq ($(DEBUG), 1)
CC_FLAGS += -DDEBUG -O0
else
CC_FLAGS += -DNDEBUG -Os
endif

all: $(OBJDIR)/$(PROJECT).bin $(OBJDIR)/$(PROJECT).hex size

clean:
rm -f $(OBJDIR)/$(PROJECT).bin $(OBJDIR)/$(PROJECT).elf $(OBJDIR)/$(PROJECT).hex $(OBJDIR)/$(PROJECT).map $(OBJDIR)/$(PROJECT).lst $(OBJECTS) $(DEPS)
rm -fr $(OBJDIR)

$(OBJDIR)/%.o: %.s
mkdir -p $(@D)
$(AS) $(CPU) -o $@ $<

$(OBJDIR)/%.o: %.c
mkdir -p $(@D)
$(CC) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu99 $(INCLUDE_PATHS) -o $@ $<

$(OBJDIR)/%.o: %.cpp
mkdir -p $(@D)
$(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu++98 $(INCLUDE_PATHS) -o $@ $<


$(OBJDIR)/$(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS)
$(LD) $(LD_FLAGS) -T$(LINKER_SCRIPT) $(LIBRARY_PATHS) -o $@ $^ $(LIBRARIES) $(LD_SYS_LIBS) $(LIBRARIES) $(LD_SYS_LIBS)
@echo ""
@echo "*****"
@echo "***** You must modify vector checksum value in *.bin and *.hex files."
@echo "*****"
@echo ""

$(OBJDIR)/$(PROJECT).bin: $(OBJDIR)/$(PROJECT).elf
@$(OBJCOPY) -O binary $< $@
@echo "Writing vector checksum value into $@ ..."
@$(CHKSUM) $@
@echo

$(OBJDIR)/$(PROJECT).hex: $(OBJDIR)/$(PROJECT).elf
@$(OBJCOPY) -O ihex $< $@

$(OBJDIR)/$(PROJECT).lst: $(OBJDIR)/$(PROJECT).elf
@$(OBJDUMP) -Sdh $< > $@

lst: $(OBJDIR)/$(PROJECT).lst

size:
$(SIZE) $(OBJDIR)/$(PROJECT).elf

prog: $(OBJDIR)/$(PROJECT).bin
@echo "Program..."
ifneq ($(shell mount | grep 'CRP DISABLD'),)
umount /dev/nxpisp >/dev/null 2>&1
endif
dd if=$< of=/dev/nxpisp seek=4

DEPS = $(OBJECTS:.o=.d) $(SYS_OBJECTS:.o=.d)
-include $(DEPS)

+ 99
- 0
tool/mbed/lpc-vector-checksum.c 查看文件

/***************************************************************************
* https://github.com/dhylands/projects/blob/master/lpc/lpc-vector-checksum/lpc-vector-checksum.c
*
* Copyright (c) 2012 by Dave Hylands
* All Rights Reserved
*
* Permission is granted to any individual or institution to use, copy,
* modify, or redistribute this file so long as it is not sold for profit,
* and that this copyright notice is retained.
*
***************************************************************************
*
* This program calculates the vector checksum used in LPC17xx binary
* images.
*
* Usage: lpc-vector-checksum file
*
***************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>

/***************************************************************************/
/**
* update_vector_checksum
*
* The algorithim is to write the checksum such that the checksum of the
* first 8 words is equal to zero.
*
* The LPC1768 uses little-endian, and this particular routine assumes
* that it's running on a little-endian architecture.
*/
static int update_vector_checksum( const char *filename )
{
uint32_t sum;
uint32_t header[8];
FILE *fs;
int i;

if (( fs = fopen( filename, "r+b" )) == NULL )
{
fprintf( stderr, "Unable to open '%s' for reading/writing (%d): %s\n",
filename, errno, strerror( errno ));
return 0;
}

if ( fread( header, sizeof( header ), 1, fs ) != 1 )
{
fprintf( stderr, "Failed to read header from '%s' (perhaps the file is too small?)",
filename );
fclose( fs );
return 0;
}

sum = 0;
for ( i = 0; i < 7; i++ )
{
sum += header[i];
}
printf( "sum = 0x%08x, value to write = 0x%08x\n", sum, -sum );

/* write back the checksum to location 7
* http://sigalrm.blogspot.jp/2011/10/cortex-m3-exception-vector-checksum.html
*/
fseek(fs, 0x1c, SEEK_SET);
sum = -sum;
fwrite(&sum, 4, 1, fs);

fclose( fs );

return 1;
}

/***************************************************************************/
/**
* main
*/
int main( int argc, char **argv )
{
int arg;

if ( argc < 2)
{
fprintf( stderr, "Usage: lpc-vector-checksum file ...\n" );
exit( 1 );
}

for ( arg = 1; arg < argc; arg++ )
{
update_vector_checksum( argv[ arg ]);
}

exit( 0 );
return 0;
}


+ 99
- 0
tool/mbed/mbed.mk 查看文件

OBJECTS += \
$(OBJDIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX/TOOLCHAIN_GCC_ARM/startup_LPC11xx.o \
$(OBJDIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX/cmsis_nvic.o \
$(OBJDIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX/system_LPC11Uxx.o \
$(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/port_api.o \
$(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/spi_api.o \
$(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/analogin_api.o \
$(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/gpio_api.o \
$(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/gpio_irq_api.o \
$(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/serial_api.o \
$(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/i2c_api.o \
$(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/pwmout_api.o \
$(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/sleep.o \
$(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/pinmap.o \
$(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/us_ticker.o \
$(OBJDIR)/libraries/mbed/common/board.o \
$(OBJDIR)/libraries/mbed/common/mbed_interface.o \
$(OBJDIR)/libraries/mbed/common/exit.o \
$(OBJDIR)/libraries/mbed/common/rtc_time.o \
$(OBJDIR)/libraries/mbed/common/us_ticker_api.o \
$(OBJDIR)/libraries/mbed/common/pinmap_common.o \
$(OBJDIR)/libraries/mbed/common/error.o \
$(OBJDIR)/libraries/mbed/common/gpio.o \
$(OBJDIR)/libraries/mbed/common/semihost_api.o \
$(OBJDIR)/libraries/mbed/common/wait_api.o \
$(OBJDIR)/libraries/mbed/common/RawSerial.o \
$(OBJDIR)/libraries/mbed/common/Ticker.o \
$(OBJDIR)/libraries/mbed/common/FilePath.o \
$(OBJDIR)/libraries/mbed/common/I2C.o \
$(OBJDIR)/libraries/mbed/common/FileBase.o \
$(OBJDIR)/libraries/mbed/common/retarget.o \
$(OBJDIR)/libraries/mbed/common/Serial.o \
$(OBJDIR)/libraries/mbed/common/Stream.o \
$(OBJDIR)/libraries/mbed/common/FileSystemLike.o \
$(OBJDIR)/libraries/mbed/common/CallChain.o \
$(OBJDIR)/libraries/mbed/common/InterruptManager.o \
$(OBJDIR)/libraries/mbed/common/SerialBase.o \
$(OBJDIR)/libraries/mbed/common/BusInOut.o \
$(OBJDIR)/libraries/mbed/common/SPISlave.o \
$(OBJDIR)/libraries/mbed/common/I2CSlave.o \
$(OBJDIR)/libraries/mbed/common/FunctionPointer.o \
$(OBJDIR)/libraries/mbed/common/Timer.o \
$(OBJDIR)/libraries/mbed/common/SPI.o \
$(OBJDIR)/libraries/mbed/common/Timeout.o \
$(OBJDIR)/libraries/mbed/common/Ethernet.o \
$(OBJDIR)/libraries/mbed/common/TimerEvent.o \
$(OBJDIR)/libraries/mbed/common/CAN.o \
$(OBJDIR)/libraries/mbed/common/BusOut.o \
$(OBJDIR)/libraries/mbed/common/FileLike.o \
$(OBJDIR)/libraries/mbed/common/BusIn.o \
$(OBJDIR)/libraries/mbed/common/InterruptIn.o \
$(OBJDIR)/libraries/mbed/common/LocalFileSystem.o \
$(OBJDIR)/libraries/USBDevice/USBHID/USBMouse.o \
$(OBJDIR)/libraries/USBDevice/USBHID/USBHID.o \
$(OBJDIR)/libraries/USBDevice/USBHID/USBMouseKeyboard.o \
$(OBJDIR)/libraries/USBDevice/USBHID/USBKeyboard.o \
$(OBJDIR)/libraries/USBDevice/USBDevice/USBHAL_KL25Z.o \
$(OBJDIR)/libraries/USBDevice/USBDevice/USBDevice.o \
$(OBJDIR)/libraries/USBDevice/USBDevice/USBHAL_LPC17.o \
$(OBJDIR)/libraries/USBDevice/USBDevice/USBHAL_LPC40.o \
$(OBJDIR)/libraries/USBDevice/USBDevice/USBHAL_LPC11U.o \
$(OBJDIR)/libraries/USBDevice/USBDevice/USBHAL_STM32F4.o \
$(OBJDIR)/libraries/USBDevice/USBAudio/USBAudio.o \
$(OBJDIR)/libraries/USBDevice/USBSerial/USBSerial.o \
$(OBJDIR)/libraries/USBDevice/USBSerial/USBCDC.o \
$(OBJDIR)/libraries/USBDevice/USBMSD/USBMSD.o \
$(OBJDIR)/libraries/USBDevice/USBMIDI/USBMIDI.o

INCLUDE_PATHS += \
-I$(MBED_DIR)/libraries/mbed/targets \
-I$(MBED_DIR)/libraries/mbed/targets/hal \
-I$(MBED_DIR)/libraries/mbed/targets/hal/TARGET_NXP \
-I$(MBED_DIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX \
-I$(MBED_DIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401 \
-I$(MBED_DIR)/libraries/mbed/targets/cmsis \
-I$(MBED_DIR)/libraries/mbed/targets/cmsis/TARGET_NXP \
-I$(MBED_DIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX \
-I$(MBED_DIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX/TOOLCHAIN_GCC_ARM \
-I$(MBED_DIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX/TOOLCHAIN_GCC_ARM/TARGET_LPC11U35_401 \
-I$(MBED_DIR)/libraries/mbed \
-I$(MBED_DIR)/libraries/mbed/hal \
-I$(MBED_DIR)/libraries/mbed/api \
-I$(MBED_DIR)/libraries/mbed/common \
-I$(MBED_DIR)/libraries/USBDevice \
-I$(MBED_DIR)/libraries/USBDevice/USBHID \
-I$(MBED_DIR)/libraries/USBDevice/USBDevice \
-I$(MBED_DIR)/libraries/USBDevice/USBAudio \
-I$(MBED_DIR)/libraries/USBDevice/USBSerial \
-I$(MBED_DIR)/libraries/USBDevice/USBMSD \
-I$(MBED_DIR)/libraries/USBDevice/USBMIDI

OBJECTS += \
$(OBJDIR)/protocol/mbed/mbed_driver.o \
$(OBJDIR)/protocol/mbed/HIDKeyboard.o \

INCLUDE_PATHS += \
-I$(TMK_DIR)/protocol/mbed

LINKER_SCRIPT = $(MBED_DIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX/TOOLCHAIN_GCC_ARM/TARGET_LPC11U35_401/LPC11U35.ld