Conflicts: .gitignore common.mk common/debug_config.h common/print.hcore
*.sym | *.sym | ||||
tags | tags | ||||
*~ | *~ | ||||
build/ | |||||
*.bak |
$(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 | ||||
#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); | ||||
#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 */ |
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; |
/* 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 |
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 |
#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; | ||||
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); |
#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 |
#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 |
#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 |
#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" | ||||
/* | |||||
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 |
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; | ||||
} | } | ||||
} | } |
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(); |
#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 |
#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 |
*/ | */ | ||||
#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"); |
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 */ | ||||
}); | }); |
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 |
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); | ||||
} | } |
/* 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); |
void matrix_print(void); | void matrix_print(void); | ||||
/* power control */ | |||||
void matrix_power_up(void); | |||||
void matrix_power_down(void); | |||||
#endif | #endif |
#include "bootloader.h" | |||||
void bootloader_jump(void) {} |
#include <stdbool.h> | |||||
void suspend_power_down(void) {} | |||||
bool suspend_wakeup_condition(void) { return true; } | |||||
void suspend_wakeup_init(void) {} |
#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); | |||||
} |
#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; | |||||
*/ | |||||
} |
#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 |
*/ | */ | ||||
#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" |
#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 |
#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 |
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 |
#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 |
#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 |
/* 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; |
#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 |
#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); | ||||
#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) |
#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 |
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 | ||||
*/ | */ | ||||
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(); | ||||
} | } |
#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; | |||||
} | |||||
} | |||||
} | |||||
} |
#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 |
#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) | |||||
{ | |||||
} |
#include "host_driver.h" | |||||
extern host_driver_t mbed_driver; |
#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; | ||||
} | } | ||||
*/ | */ | ||||
#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 */ |
#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 |
#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); | |||||
} |
#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); | |||||
} |
#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(); | |||||
} | } |
# 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 $@ | ||||
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 |
############################################################################### | |||||
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) |
/*************************************************************************** | |||||
* 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; | |||||
} | |||||
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 |