diff options
author | tmk <nobody@nowhere> | 2013-05-14 23:03:23 +0900 |
---|---|---|
committer | tmk <nobody@nowhere> | 2013-05-14 23:03:23 +0900 |
commit | cbb9c408e46a7a7a567f3d6e07713256152106d0 (patch) | |
tree | bd8e7c789fbb7f191b4de31498160f05d2f80229 | |
parent | b9f558b3d89fc434d6dab348698d5100ff82d16b (diff) | |
parent | ff2d276b193632136c785d92ed01df48aea8461f (diff) |
Merge branch 'fix_print'
-rw-r--r-- | common.mk | 1 | ||||
-rw-r--r-- | common/action.c | 92 | ||||
-rw-r--r-- | common/action_layer.c | 19 | ||||
-rw-r--r-- | common/action_macro.c | 7 | ||||
-rw-r--r-- | common/action_tapping.c | 6 | ||||
-rw-r--r-- | common/debug.h | 63 | ||||
-rw-r--r-- | common/debug_config.h | 51 | ||||
-rw-r--r-- | common/host.c | 10 | ||||
-rw-r--r-- | common/nodebug.h | 49 | ||||
-rw-r--r-- | common/print.c | 147 | ||||
-rw-r--r-- | common/print.h | 71 | ||||
-rw-r--r-- | common/util.c | 22 | ||||
-rw-r--r-- | common/util.h | 4 | ||||
-rw-r--r-- | common/xprintf.S | 500 | ||||
-rw-r--r-- | common/xprintf.h | 103 |
15 files changed, 861 insertions, 284 deletions
@@ -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, |