Merge branch 'rn42' into merge_rn42
Conflicts: .gitignore common.mk common/debug_config.h common/print.h
This commit is contained in:
commit
b748f8575a
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,3 +9,5 @@
|
||||
*.sym
|
||||
tags
|
||||
*~
|
||||
build/
|
||||
*.bak
|
||||
|
12
common.mk
12
common.mk
@ -7,19 +7,19 @@ SRC += $(COMMON_DIR)/host.c \
|
||||
$(COMMON_DIR)/action_layer.c \
|
||||
$(COMMON_DIR)/action_util.c \
|
||||
$(COMMON_DIR)/keymap.c \
|
||||
$(COMMON_DIR)/timer.c \
|
||||
$(COMMON_DIR)/print.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
|
||||
ifdef BOOTMAGIC_ENABLE
|
||||
SRC += $(COMMON_DIR)/bootmagic.c
|
||||
SRC += $(COMMON_DIR)/eeconfig.c
|
||||
SRC += $(COMMON_DIR)/avr/eeconfig.c
|
||||
OPT_DEFS += -DBOOTMAGIC_ENABLE
|
||||
endif
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
117
common/avr/suspend.c
Normal 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
27
common/avr/suspend_avr.h
Normal 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
|
@ -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
42
common/avr/timer_avr.h
Normal 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
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
110
common/debug.h
110
common/debug.h
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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 */
|
||||
});
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
4
common/mbed/bootloader.c
Normal file
@ -0,0 +1,4 @@
|
||||
#include "bootloader.h"
|
||||
|
||||
|
||||
void bootloader_jump(void) {}
|
6
common/mbed/suspend.c
Normal file
6
common/mbed/suspend.c
Normal 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
41
common/mbed/timer.c
Normal 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
46
common/mbed/xprintf.cpp
Normal 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
17
common/mbed/xprintf.h
Normal 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
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
144
common/print.h
144
common/print.h
@ -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
12
common/progmem.h
Normal 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
|
@ -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;
|
||||
|
@ -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
|
@ -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);
|
||||
|
||||
|
@ -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
20
common/wait.h
Normal 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
|
@ -9,6 +9,7 @@ endif
|
||||
|
||||
ifdef PS2_USE_BUSYWAIT
|
||||
SRC += protocol/ps2_busywait.c
|
||||
SRC += protocol/ps2_io_avr.c
|
||||
OPT_DEFS += -DPS2_USE_BUSYWAIT
|
||||
endif
|
||||
|
||||
|
@ -148,10 +148,23 @@ static void Console_Task(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)
|
||||
{
|
||||
/* 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)
|
||||
@ -574,7 +587,7 @@ int main(void)
|
||||
print("Keyboard start.\n");
|
||||
while (1) {
|
||||
while (USB_DeviceState == DEVICE_STATE_Suspended) {
|
||||
suspend_power_down();
|
||||
suspend_power_down(WDTO_120MS);
|
||||
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
|
||||
USB_Device_SendRemoteWakeup();
|
||||
}
|
||||
|
271
protocol/mbed/HIDKeyboard.cpp
Normal file
271
protocol/mbed/HIDKeyboard.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
#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
protocol/mbed/HIDKeyboard.h
Normal file
31
protocol/mbed/HIDKeyboard.h
Normal file
@ -0,0 +1,31 @@
|
||||
#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
protocol/mbed/mbed_driver.cpp
Normal file
41
protocol/mbed/mbed_driver.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#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
protocol/mbed/mbed_driver.h
Normal file
3
protocol/mbed/mbed_driver.h
Normal file
@ -0,0 +1,3 @@
|
||||
#include "host_driver.h"
|
||||
|
||||
extern host_driver_t mbed_driver;
|
@ -39,8 +39,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#define PS2_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
|
||||
@ -92,79 +93,27 @@ uint8_t ps2_host_recv(void);
|
||||
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 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)
|
||||
{
|
||||
while (clock_in() && us) { asm(""); _delay_us(1); us--; }
|
||||
while (clock_in() && us) { asm(""); wait_us(1); us--; }
|
||||
return 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -40,8 +40,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <util/delay.h>
|
||||
#include "wait.h"
|
||||
#include "ps2.h"
|
||||
#include "ps2_io.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
@ -58,8 +59,11 @@ uint8_t ps2_error = PS2_ERR_NONE;
|
||||
|
||||
void ps2_host_init(void)
|
||||
{
|
||||
clock_init();
|
||||
data_init();
|
||||
|
||||
// POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
|
||||
_delay_ms(2500);
|
||||
wait_ms(2500);
|
||||
|
||||
inhibit();
|
||||
}
|
||||
@ -71,7 +75,7 @@ uint8_t ps2_host_send(uint8_t data)
|
||||
|
||||
/* terminate a transmission if we have */
|
||||
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 */
|
||||
data_lo();
|
||||
@ -80,7 +84,7 @@ uint8_t ps2_host_send(uint8_t data)
|
||||
|
||||
/* Data bit */
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
_delay_us(15);
|
||||
wait_us(15);
|
||||
if (data&(1<<i)) {
|
||||
parity = !parity;
|
||||
data_hi();
|
||||
@ -92,13 +96,13 @@ uint8_t ps2_host_send(uint8_t data)
|
||||
}
|
||||
|
||||
/* Parity bit */
|
||||
_delay_us(15);
|
||||
wait_us(15);
|
||||
if (parity) { data_hi(); } else { data_lo(); }
|
||||
WAIT(clock_hi, 50, 4);
|
||||
WAIT(clock_lo, 50, 5);
|
||||
|
||||
/* Stop bit */
|
||||
_delay_us(15);
|
||||
wait_us(15);
|
||||
data_hi();
|
||||
|
||||
/* Ack */
|
||||
|
15
protocol/ps2_io.h
Normal file
15
protocol/ps2_io.h
Normal file
@ -0,0 +1,15 @@
|
||||
#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
protocol/ps2_io_avr.c
Normal file
74
protocol/ps2_io_avr.c
Normal file
@ -0,0 +1,74 @@
|
||||
#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
protocol/ps2_io_mbed.c
Normal file
60
protocol/ps2_io_mbed.c
Normal file
@ -0,0 +1,60 @@
|
||||
#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);
|
||||
}
|
@ -41,13 +41,29 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
#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)
|
||||
{
|
||||
SERIAL_UART_INIT();
|
||||
}
|
||||
|
||||
// RX ring buffer
|
||||
#define RBUF_SIZE 8
|
||||
#define RBUF_SIZE 256
|
||||
static uint8_t rbuf[RBUF_SIZE];
|
||||
static uint8_t rbuf_head = 0;
|
||||
static uint8_t rbuf_tail = 0;
|
||||
@ -61,6 +77,7 @@ uint8_t serial_recv(void)
|
||||
|
||||
data = rbuf[rbuf_tail];
|
||||
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
|
||||
rbuf_check_rts_lo();
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -73,6 +90,7 @@ int16_t serial_recv2(void)
|
||||
|
||||
data = rbuf[rbuf_tail];
|
||||
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
|
||||
rbuf_check_rts_lo();
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -90,4 +108,5 @@ ISR(SERIAL_UART_RXD_VECT)
|
||||
rbuf[rbuf_head] = SERIAL_UART_DATA;
|
||||
rbuf_head = next;
|
||||
}
|
||||
rbuf_check_rts_hi();
|
||||
}
|
||||
|
1
rules.mk
1
rules.mk
@ -565,6 +565,7 @@ $(OBJDIR)/%.o : %.cpp
|
||||
# Assemble: create object files from assembler source files.
|
||||
$(OBJDIR)/%.o : %.S
|
||||
@echo
|
||||
mkdir -p $(@D)
|
||||
@echo $(MSG_ASSEMBLING) $<
|
||||
$(CC) -c $(ALL_ASFLAGS) $< -o $@
|
||||
|
||||
|
79
tool/mbed/common.mk
Normal file
79
tool/mbed/common.mk
Normal file
@ -0,0 +1,79 @@
|
||||
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
tool/mbed/gcc.mk
Normal file
80
tool/mbed/gcc.mk
Normal file
@ -0,0 +1,80 @@
|
||||
###############################################################################
|
||||
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
tool/mbed/lpc-vector-checksum.c
Normal file
99
tool/mbed/lpc-vector-checksum.c
Normal file
@ -0,0 +1,99 @@
|
||||
/***************************************************************************
|
||||
* 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
tool/mbed/mbed.mk
Normal file
99
tool/mbed/mbed.mk
Normal file
@ -0,0 +1,99 @@
|
||||
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
|
Reference in New Issue
Block a user