summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2013-05-14 23:03:23 +0900
committertmk <nobody@nowhere>2013-05-14 23:03:23 +0900
commitcbb9c408e46a7a7a567f3d6e07713256152106d0 (patch)
treebd8e7c789fbb7f191b4de31498160f05d2f80229
parentb9f558b3d89fc434d6dab348698d5100ff82d16b (diff)
parentff2d276b193632136c785d92ed01df48aea8461f (diff)
Merge branch 'fix_print'
-rw-r--r--common.mk1
-rw-r--r--common/action.c92
-rw-r--r--common/action_layer.c19
-rw-r--r--common/action_macro.c7
-rw-r--r--common/action_tapping.c6
-rw-r--r--common/debug.h63
-rw-r--r--common/debug_config.h51
-rw-r--r--common/host.c10
-rw-r--r--common/nodebug.h49
-rw-r--r--common/print.c147
-rw-r--r--common/print.h71
-rw-r--r--common/util.c22
-rw-r--r--common/util.h4
-rw-r--r--common/xprintf.S500
-rw-r--r--common/xprintf.h103
15 files changed, 861 insertions, 284 deletions
diff --git a/common.mk b/common.mk
index 810f802c66..5f47e5c1bc 100644
--- a/common.mk
+++ b/common.mk
@@ -11,6 +11,7 @@ SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/print.c \
$(COMMON_DIR)/bootloader.c \
$(COMMON_DIR)/suspend.c \
+ $(COMMON_DIR)/xprintf.S \
$(COMMON_DIR)/util.c
diff --git a/common/action.c b/common/action.c
index 0651887444..c7c8f71f2c 100644
--- a/common/action.c
+++ b/common/action.c
@@ -19,7 +19,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "keyboard.h"
#include "mousekey.h"
#include "command.h"
-#include "debug.h"
#include "led.h"
#include "action_layer.h"
#include "action_tapping.h"
@@ -27,12 +26,18 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "action_macro.h"
#include "action.h"
+#ifdef DEBUG_ACTION
+#include "debug.h"
+#else
+#include "nodebug.h"
+#endif
+
void action_exec(keyevent_t event)
{
if (!IS_NOEVENT(event)) {
- debug("\n---- action_exec: start -----\n");
- debug("EVENT: "); debug_event(event); debug("\n");
+ dprint("\n---- action_exec: start -----\n");
+ dprint("EVENT: "); debug_event(event); dprintln();
}
keyrecord_t record = { .event = event };
@@ -42,7 +47,7 @@ void action_exec(keyevent_t event)
#else
process_action(&record);
if (!IS_NOEVENT(record.event)) {
- debug("processed: "); debug_record(record); debug("\n");
+ dprint("processed: "); debug_record(record); dprintln();
}
#endif
}
@@ -57,12 +62,12 @@ void process_action(keyrecord_t *record)
if (IS_NOEVENT(event)) { return; }
action_t action = layer_switch_get_action(event.key);
- debug("ACTION: "); debug_action(action);
+ dprint("ACTION: "); debug_action(action);
#ifndef NO_ACTION_LAYER
- debug(" layer_state: "); layer_debug();
- debug(" default_layer_state: "); default_layer_debug();
+ dprint(" layer_state: "); layer_debug();
+ dprint(" default_layer_state: "); default_layer_debug();
#endif
- debug("\n");
+ dprintln();
switch (action.kind.id) {
/* Key and Mods */
@@ -98,37 +103,37 @@ void process_action(keyrecord_t *record)
// Oneshot modifier
if (event.pressed) {
if (tap_count == 0) {
- debug("MODS_TAP: Oneshot: add_mods\n");
+ dprint("MODS_TAP: Oneshot: add_mods\n");
add_mods(mods);
}
else if (tap_count == 1) {
- debug("MODS_TAP: Oneshot: start\n");
+ dprint("MODS_TAP: Oneshot: start\n");
oneshot_start(mods);
}
else if (tap_count == TAPPING_TOGGLE) {
- debug("MODS_TAP: Oneshot: toggle\n");
+ dprint("MODS_TAP: Oneshot: toggle\n");
oneshot_toggle();
}
else {
- debug("MODS_TAP: Oneshot: cancel&add_mods\n");
+ dprint("MODS_TAP: Oneshot: cancel&add_mods\n");
// double tap cancels oneshot and works as normal modifier.
oneshot_cancel();
add_mods(mods);
}
} else {
if (tap_count == 0) {
- debug("MODS_TAP: Oneshot: cancel/del_mods\n");
+ dprint("MODS_TAP: Oneshot: cancel/del_mods\n");
// cancel oneshot on hold
oneshot_cancel();
del_mods(mods);
}
else if (tap_count == 1) {
- debug("MODS_TAP: Oneshot: del_mods\n");
+ dprint("MODS_TAP: Oneshot: del_mods\n");
// retain Oneshot
del_mods(mods);
}
else {
- debug("MODS_TAP: Oneshot: del_mods\n");
+ dprint("MODS_TAP: Oneshot: del_mods\n");
// cancel Mods
del_mods(mods);
}
@@ -139,24 +144,24 @@ void process_action(keyrecord_t *record)
if (event.pressed) {
if (tap_count > 0) {
if (record->tap.interrupted) {
- debug("MODS_TAP: Tap: Cancel: add_mods\n");
+ dprint("MODS_TAP: Tap: Cancel: add_mods\n");
// ad hoc: set 0 to cancel tap
record->tap.count = 0;
add_mods(mods);
} else {
- debug("MODS_TAP: Tap: register_code\n");
+ dprint("MODS_TAP: Tap: register_code\n");
register_code(action.key.code);
}
} else {
- debug("MODS_TAP: No tap: add_mods\n");
+ dprint("MODS_TAP: No tap: add_mods\n");
add_mods(mods);
}
} else {
if (tap_count > 0) {
- debug("MODS_TAP: Tap: unregister_code\n");
+ dprint("MODS_TAP: Tap: unregister_code\n");
unregister_code(action.key.code);
} else {
- debug("MODS_TAP: No tap: add_mods\n");
+ dprint("MODS_TAP: No tap: add_mods\n");
del_mods(mods);
}
}
@@ -261,18 +266,18 @@ void process_action(keyrecord_t *record)
/* tap key */
if (event.pressed) {
if (tap_count > 0) {
- debug("KEYMAP_TAP_KEY: Tap: register_code\n");
+ dprint("KEYMAP_TAP_KEY: Tap: register_code\n");
register_code(action.layer_tap.code);
} else {
- debug("KEYMAP_TAP_KEY: No tap: On on press\n");
+ dprint("KEYMAP_TAP_KEY: No tap: On on press\n");
layer_on(action.layer_tap.val);
}
} else {
if (tap_count > 0) {
- debug("KEYMAP_TAP_KEY: Tap: unregister_code\n");
+ dprint("KEYMAP_TAP_KEY: Tap: unregister_code\n");
unregister_code(action.layer_tap.code);
} else {
- debug("KEYMAP_TAP_KEY: No tap: Off on release\n");
+ dprint("KEYMAP_TAP_KEY: No tap: Off on release\n");
layer_off(action.layer_tap.val);
}
}
@@ -448,40 +453,33 @@ bool is_tap_key(key_t key)
*/
void debug_event(keyevent_t event)
{
- debug_hex16((event.key.row<<8) | event.key.col);
- if (event.pressed) debug("d("); else debug("u(");
- debug_dec(event.time); debug(")");
+ dprintf("%04X%c(%u)", (event.key.row<<8 | event.key.col), (event.pressed ? 'd' : 'u'), event.time);
}
void debug_record(keyrecord_t record)
{
debug_event(record.event);
#ifndef NO_ACTION_TAPPING
- debug(":"); debug_dec(record.tap.count);
- if (record.tap.interrupted) debug("-");
+ dprintf(":%u%c", record.tap.count, (record.tap.interrupted ? '-' : ' '));
#endif
}
void debug_action(action_t action)
{
switch (action.kind.id) {
- case ACT_LMODS: debug("ACT_LMODS"); break;
- case ACT_RMODS: debug("ACT_RMODS"); break;
- case ACT_LMODS_TAP: debug("ACT_LMODS_TAP"); break;
- case ACT_RMODS_TAP: debug("ACT_RMODS_TAP"); break;
- case ACT_USAGE: debug("ACT_USAGE"); break;
- case ACT_MOUSEKEY: debug("ACT_MOUSEKEY"); break;
- case ACT_LAYER: debug("ACT_LAYER"); break;
- case ACT_LAYER_TAP: debug("ACT_LAYER_TAP"); break;
- case ACT_LAYER_TAP1: debug("ACT_LAYER_TAP1"); break;
- case ACT_MACRO: debug("ACT_MACRO"); break;
- case ACT_COMMAND: debug("ACT_COMMAND"); break;
- case ACT_FUNCTION: debug("ACT_FUNCTION"); break;
- default: debug("UNKNOWN"); break;
+ case ACT_LMODS: dprint("ACT_LMODS"); break;
+ case ACT_RMODS: dprint("ACT_RMODS"); break;
+ case ACT_LMODS_TAP: dprint("ACT_LMODS_TAP"); break;
+ case ACT_RMODS_TAP: dprint("ACT_RMODS_TAP"); break;
+ case ACT_USAGE: dprint("ACT_USAGE"); break;
+ case ACT_MOUSEKEY: dprint("ACT_MOUSEKEY"); break;
+ case ACT_LAYER: dprint("ACT_LAYER"); break;
+ case ACT_LAYER_TAP: dprint("ACT_LAYER_TAP"); break;
+ case ACT_LAYER_TAP1: dprint("ACT_LAYER_TAP1"); break;
+ case ACT_MACRO: dprint("ACT_MACRO"); break;
+ case ACT_COMMAND: dprint("ACT_COMMAND"); break;
+ case ACT_FUNCTION: dprint("ACT_FUNCTION"); break;
+ default: dprint("UNKNOWN"); break;
}
- debug("[");
- debug_hex4(action.kind.param>>8);
- debug(":");
- debug_hex8(action.kind.param & 0xff);
- debug("]");
+ dprintf("[%X:%02X]", action.kind.param>>8, action.kind.param&0xff);
}
diff --git a/common/action_layer.c b/common/action_layer.c
index 3413c53e65..d24aa2e19f 100644
--- a/common/action_layer.c
+++ b/common/action_layer.c
@@ -1,10 +1,15 @@
#include <stdint.h>
#include "keyboard.h"
#include "action.h"
-#include "debug.h"
#include "util.h"
#include "action_layer.h"
+#ifdef DEBUG_ACTION
+#include "debug.h"
+#else
+#include "nodebug.h"
+#endif
+
/*
* Default Layer State
@@ -22,8 +27,7 @@ static void default_layer_state_set(uint32_t state)
void default_layer_debug(void)
{
- debug_hex32(default_layer_state);
- debug("("); debug_dec(biton32(default_layer_state)); debug(")");
+ dprintf("%08lX(%u)", default_layer_state, biton32(default_layer_state));
}
void default_layer_set(uint8_t layer)
@@ -55,10 +59,10 @@ uint32_t layer_state = 0;
static void layer_state_set(uint32_t state)
{
- debug("layer_state: ");
- layer_debug(); debug(" to ");
+ dprint("layer_state: ");
+ layer_debug(); dprint(" to ");
layer_state = state;
- layer_debug(); debug("\n");
+ layer_debug(); dprintln();
clear_keyboard_but_mods(); // To avoid stuck keys
}
@@ -102,8 +106,7 @@ void layer_xor(uint32_t state)
void layer_debug(void)
{
- debug_hex32(layer_state);
- debug("("); debug_dec(biton32(layer_state)); debug(")");
+ dprintf("%08lX(%u)", layer_state, biton32(layer_state));
}
#endif
diff --git a/common/action_macro.c b/common/action_macro.c
index 6d81a1efb4..71d1506f5c 100644
--- a/common/action_macro.c
+++ b/common/action_macro.c
@@ -15,10 +15,15 @@ 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 "debug.h"
#include "action.h"
#include "action_macro.h"
+#ifdef DEBUG_ACTION
+#include "debug.h"
+#else
+#include "nodebug.h"
+#endif
+
#ifndef NO_ACTION_MACRO
diff --git a/common/action_tapping.c b/common/action_tapping.c
index abb0bf5182..8b466079d2 100644
--- a/common/action_tapping.c
+++ b/common/action_tapping.c
@@ -3,8 +3,12 @@
#include "action.h"
#include "action_tapping.h"
#include "timer.h"
-#include "debug.h"
+#ifdef DEBUG_ACTION
+#include "debug.h"
+#else
+#include "nodebug.h"
+#endif
#ifndef NO_ACTION_TAPPING
diff --git a/common/debug.h b/common/debug.h
index cac682703d..8aaa5ed915 100644
--- a/common/debug.h
+++ b/common/debug.h
@@ -18,14 +18,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef DEBUG_H
#define DEBUG_H 1
-#include <stdbool.h>
#include "print.h"
+#include "debug_config.h"
#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) println(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 { \
@@ -50,58 +56,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define debug_bin_reverse(data) debug_bin8(data)
#else
-
-#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)
-
-#endif
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* NOTE: Not portable. Bit field order depends on implementation */
-typedef union {
- uint8_t raw;
- struct {
- bool enable:1;
- bool matrix:1;
- bool keyboard:1;
- bool mouse:1;
- uint8_t reserved:4;
- };
-} debug_config_t;
-debug_config_t debug_config;
-
-/* for backward compatibility */
-#define debug_enable (debug_config.enable)
-#define debug_matrix (debug_config.matrix)
-#define debug_keyboard (debug_config.keyboard)
-#define debug_mouse (debug_config.mouse)
-
-
-#ifdef __cplusplus
-}
+#include "nodebug.h"
#endif
#endif
diff --git a/common/debug_config.h b/common/debug_config.h
new file mode 100644
index 0000000000..e00fd10336
--- /dev/null
+++ b/common/debug_config.h
@@ -0,0 +1,51 @@
+/*
+Copyright 2013 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 DEBUG_CONFIG_H
+#define DEBUG_CONFIG_H 1
+
+#include <stdbool.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* NOTE: Not portable. Bit field order depends on implementation */
+typedef union {
+ uint8_t raw;
+ struct {
+ bool enable:1;
+ bool matrix:1;
+ bool keyboard:1;
+ bool mouse:1;
+ uint8_t reserved:4;
+ };
+} debug_config_t;
+debug_config_t debug_config;
+
+/* for backward compatibility */
+#define debug_enable (debug_config.enable)
+#define debug_matrix (debug_config.matrix)
+#define debug_keyboard (debug_config.keyboard)
+#define debug_mouse (debug_config.mouse)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/common/host.c b/common/host.c
index 6ed3d780f6..2c2279aa4e 100644
--- a/common/host.c
+++ b/common/host.c
@@ -63,11 +63,11 @@ void host_keyboard_send(report_keyboard_t *report)
(*driver->send_keyboard)(report);
if (debug_keyboard) {
- print("keys: ");
+ dprint("keys: ");
for (int i = 0; i < REPORT_KEYS; i++) {
- phex(keyboard_report->keys[i]); print(" ");
+ dprintf("%02X ", keyboard_report->keys[i]);
}
- print(" mods: "); phex(keyboard_report->mods); print("\n");
+ dprintf(" mods: %02X\n", keyboard_report->mods);
}
}
@@ -235,7 +235,7 @@ static inline void add_key_bit(uint8_t code)
if ((code>>3) < REPORT_KEYS) {
keyboard_report->keys[code>>3] |= 1<<(code&7);
} else {
- debug("add_key_bit: can't add: "); phex(code); debug("\n");
+ dprintf("add_key_bit: can't add: %02X\n", code);
}
}
@@ -244,6 +244,6 @@ static inline void del_key_bit(uint8_t code)
if ((code>>3) < REPORT_KEYS) {
keyboard_report->keys[code>>3] &= ~(1<<(code&7));
} else {
- debug("del_key_bit: can't del: "); phex(code); debug("\n");
+ dprintf("del_key_bit: can't del: %02X\n", code);
}
}
diff --git a/common/nodebug.h b/common/nodebug.h
new file mode 100644
index 0000000000..aec790bbc1
--- /dev/null
+++ b/common/nodebug.h
@@ -0,0 +1,49 @@
+/*
+Copyright 2013 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 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)
+
+#endif
diff --git a/common/print.c b/common/print.c
index 329f835125..783bb4e9bb 100644
--- a/common/print.c
+++ b/common/print.c
@@ -1,4 +1,4 @@
-/* Copyright 2012 Jun Wako <wakojun@gmail.com> */
+/* Copyright 2012,2013 Jun Wako <wakojun@gmail.com> */
/* Very basic print functions, intended to be used with usb_debug_only.c
* http://www.pjrc.com/teensy/
* Copyright (c) 2008 PJRC.COM, LLC
@@ -29,20 +29,14 @@
#ifndef NO_PRINT
-#define sendchar(c) do { if (print_sendchar_func) (print_sendchar_func)(c); } while (0)
+#define sendchar(c) xputc(c)
-static int8_t (*print_sendchar_func)(uint8_t) = 0;
-
void print_set_sendchar(int8_t (*sendchar_func)(uint8_t))
{
- print_sendchar_func = sendchar_func;
+ xdev_out(sendchar_func);
}
-/* print string stored in data memory(SRAM)
- * print_P("hello world");
- * This consumes precious SRAM memory space for string.
- */
void print_S(const char *s)
{
uint8_t c;
@@ -54,140 +48,15 @@ void print_S(const char *s)
}
}
-/* print string stored in program memory(FLASH)
- * print_P(PSTR("hello world");
- * This consumes relatively abundant FLASH memory area not SRAM.
- */
-void print_P(const char *s)
-{
- uint8_t c;
- while (1) {
- c = pgm_read_byte(s++);
- if (!c) break;
- if (c == '\n') sendchar('\r');
- sendchar(c);
- }
-}
-
-void print_CRLF(void)
-{
- sendchar('\r'); sendchar('\n');
-}
-
-
-#define SIGNED 0x80
-#define BIN 2
-#define OCT 8
-#define DEC 10
-#define HEX 16
-
-static inline
-char itoc(uint8_t i)
-{
- return (i < 10 ? '0' + i : 'A' + i - 10);
-}
-
-static inline
-void print_int(uint16_t data, uint8_t base)
-{
- char buf[7] = {'\0'};
- char *p = &buf[6];
- if ((base & SIGNED) && (data & 0x8000)) {
- data = -data;
- buf[0] = '-';
- }
- base &= ~SIGNED;
- uint16_t n;
- do {
- n = data;
- data /= base;
- *(--p) = itoc(n - data*base);
- } while (data);
- if (buf[0]) *(--p) = buf[0];
- print_S(p);
-}
-
-void print_dec(uint16_t data)
-{
- print_int(data, DEC);
-}
-
-void print_decs(int16_t data)
-{
- print_int(data, DEC|SIGNED);
-}
-
-
-void print_hex4(uint8_t data)
-{
- sendchar(data + ((data < 10) ? '0' : 'A' - 10));
-}
-
-void print_hex8(uint8_t data)
-{
- print_hex4(data>>4);
- print_hex4(data&0x0F);
-}
-
-void print_hex16(uint16_t data)
-{
- print_hex8(data>>8);
- print_hex8(data);
-}
-
-void print_hex32(uint32_t data)
-{
- print_hex16(data>>16);
- print_hex16(data);
-}
-
-void print_bin4(uint8_t data)
-{
- for (int i = 4; i >= 0; i--) {
- sendchar((data & (1<<i)) ? '1' : '0');
- }
-}
-
-void print_bin8(uint8_t data)
-{
- for (int i = 7; i >= 0; i--) {
- sendchar((data & (1<<i)) ? '1' : '0');
- }
-}
-
-void print_bin16(uint16_t data)
-{
- print_bin8(data>>8);
- print_bin8(data);
-}
-
-void print_bin32(uint32_t data)
-{
- print_bin8(data>>24);
- print_bin8(data>>16);
- print_bin8(data>>8);
- print_bin8(data);
-}
-
-void print_bin_reverse8(uint8_t data)
-{
- for (int i = 0; i < 8; i++) {
- sendchar((data & (1<<i)) ? '1' : '0');
- }
-}
-
-void print_bin_reverse16(uint16_t data)
+void print_lf(void)
{
- print_bin_reverse8(data);
- print_bin_reverse8(data>>8);
+ sendchar('\n');
}
-void print_bin_reverse32(uint32_t data)
+void print_crlf(void)
{
- print_bin_reverse8(data);
- print_bin_reverse8(data>>8);
- print_bin_reverse8(data>>16);
- print_bin_reverse8(data>>24);
+ sendchar('\r');
+ sendchar('\n');
}
#endif
diff --git a/common/print.h b/common/print.h
index 80858b3bc5..930e84be99 100644
--- a/common/print.h
+++ b/common/print.h
@@ -28,6 +28,8 @@
#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
@@ -49,17 +51,17 @@
#define pbin_reverse16(data) print_bin_reverse16(data)
/* print value utility */
-#define print_val_dec(v) do { print_P(PSTR(#v ": ")); print_dec(v); print_P(PSTR("\n")); } while (0)
-#define print_val_decs(v) do { print_P(PSTR(#v ": ")); print_decs(v); print_P(PSTR("\n")); } while (0)
-#define print_val_hex8(v) do { print_P(PSTR(#v ": ")); print_hex8(v); print_P(PSTR("\n")); } while (0)
-#define print_val_hex16(v) do { print_P(PSTR(#v ": ")); print_hex16(v); print_P(PSTR("\n")); } while (0)
-#define print_val_hex32(v) do { print_P(PSTR(#v ": ")); print_hex32(v); print_P(PSTR("\n")); } while (0)
-#define print_val_bin8(v) do { print_P(PSTR(#v ": ")); print_bin8(v); print_P(PSTR("\n")); } while (0)
-#define print_val_bin16(v) do { print_P(PSTR(#v ": ")); print_bin16(v); print_P(PSTR("\n")); } while (0)
-#define print_val_bin32(v) do { print_P(PSTR(#v ": ")); print_bin32(v); print_P(PSTR("\n")); } while (0)
-#define print_val_bin_reverse8(v) do { print_P(PSTR(#v ": ")); print_bin_reverse8(v); print_P(PSTR("\n")); } while (0)
-#define print_val_bin_reverse16(v) do { print_P(PSTR(#v ": ")); print_bin_reverse16(v); print_P(PSTR("\n")); } while (0)
-#define print_val_bin_reverse32(v) do { print_P(PSTR(#v ": ")); print_bin_reverse32(v); print_P(PSTR("\n")); } while (0)
+#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))
@@ -68,34 +70,46 @@
#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 string stored in data memory(SRAM)
+ * print_S("hello world");
+ * This consumes precious SRAM memory space for string.
+ */
void print_S(const char *s);
-/* print string stored in program memory(FLASH) */
-void print_P(const char *s);
-void print_CRLF(void);
+void print_lf(void);
+void print_crlf(void);
+
+
+/* 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 */
-void print_dec(uint16_t data);
-void print_decs(int16_t data);
+#define print_dec(i) xprintf("%u", i)
+#define print_decs(i) xprintf("%d", i)
/* hex */
-void print_hex4(uint8_t data);
-void print_hex8(uint8_t data);
-void print_hex16(uint16_t data);
-void print_hex32(uint32_t data);
+#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 */
-void print_bin4(uint8_t data);
-void print_bin8(uint8_t data);
-void print_bin16(uint16_t data);
-void print_bin32(uint32_t data);
-void print_bin_reverse8(uint8_t data);
-void print_bin_reverse16(uint16_t data);
-void print_bin_reverse32(uint32_t data);
+#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
@@ -105,7 +119,6 @@ void print_bin_reverse32(uint32_t data);
#define print_set_sendchar(func)
#define print_S(s)
#define print_P(s)
-#define print_CRLF()
#define print_dec(data)
#define print_decs(data)
#define print_hex4(data)
diff --git a/common/util.c b/common/util.c
index 6d4d6bfda1..7e0d542993 100644
--- a/common/util.c
+++ b/common/util.c
@@ -77,3 +77,25 @@ uint8_t biton32(uint32_t bits)
if (bits >> 1) { bits >>= 1; n += 1;}
return n;
}
+
+
+
+uint8_t bitrev(uint8_t bits)
+{
+ bits = (bits & 0x0f)<<4 | (bits & 0xf0)>>4;
+ bits = (bits & 0b00110011)<<2 | (bits & 0b11001100)>>2;
+ bits = (bits & 0b01010101)<<1 | (bits & 0b10101010)>>1;
+ return bits;
+}
+
+uint16_t bitrev16(uint16_t bits)
+{
+ bits = bitrev(bits & 0x00ff)<<8 | bitrev((bits & 0xff00)>>8);
+ return bits;
+}
+
+uint32_t bitrev32(uint32_t bits)
+{
+ bits = (uint32_t)bitrev16(bits & 0x0000ffff)<<16 | bitrev16((bits & 0xffff0000)>>16);
+ return bits;
+}
diff --git a/common/util.h b/common/util.h
index 4b8b5ca3a4..7451cc084d 100644
--- a/common/util.h
+++ b/common/util.h
@@ -36,4 +36,8 @@ uint8_t biton(uint8_t bits);
uint8_t biton16(uint16_t bits);
uint8_t biton32(uint32_t bits);
+uint8_t bitrev(uint8_t bits);
+uint16_t bitrev16(uint16_t bits);
+uint32_t bitrev32(uint32_t bits);
+
#endif
diff --git a/common/xprintf.S b/common/xprintf.S
new file mode 100644
index 0000000000..b5a97b20a9
--- /dev/null
+++ b/common/xprintf.S
@@ -0,0 +1,500 @@
+;---------------------------------------------------------------------------;
+; Extended itoa, puts, printf and atoi (C)ChaN, 2011
+;---------------------------------------------------------------------------;
+
+ // Base size is 152 bytes
+#define CR_CRLF 0 // Convert \n to \r\n (+10 bytes)
+#define USE_XPRINTF 1 // Enable xprintf function (+194 bytes)
+#define USE_XSPRINTF 0 // Add xsprintf function (+78 bytes)
+#define USE_XFPRINTF 0 // Add xfprintf function (+54 bytes)
+#define USE_XATOI 0 // Enable xatoi function (+182 bytes)
+
+
+#if FLASHEND > 0x1FFFF
+#error xitoa module does not support 256K devices
+#endif
+
+.nolist
+#include <avr/io.h> // Include device specific definitions.
+.list
+
+#ifdef SPM_PAGESIZE // Recent devices have "lpm Rd,Z+" and "movw".
+.macro _LPMI reg
+ lpm \reg, Z+
+.endm
+.macro _MOVW dh,dl, sh,sl
+ movw \dl, \sl
+.endm
+#else // Earlier devices do not have "lpm Rd,Z+" nor "movw".
+.macro _LPMI reg
+ lpm
+ mov \reg, r0
+ adiw ZL, 1
+.endm
+.macro _MOVW dh,dl, sh,sl
+ mov \dl, \sl
+ mov \dh, \sh
+.endm
+#endif
+
+
+
+;---------------------------------------------------------------------------
+; Stub function to forward to user output function
+;
+;Prototype: void xputc (char chr // a character to be output
+; );
+;Size: 12/12 words
+
+.section .bss
+.global xfunc_out ; xfunc_out must be initialized before using this module.
+xfunc_out: .ds.w 1
+.section .text
+
+
+.func xputc
+.global xputc
+xputc:
+#if CR_CRLF
+ cpi r24, 10 ;LF --> CRLF
+ brne 1f ;
+ ldi r24, 13 ;
+ rcall 1f ;
+ ldi r24, 10 ;/
+1:
+#endif
+ push ZH
+ push ZL
+ lds ZL, xfunc_out+0 ;Pointer to the registered output function.
+ lds ZH, xfunc_out+1 ;/
+ sbiw ZL,