forked from mirrors/qmk_userspace
		
	Merge branch 'fix_print'
This commit is contained in:
		
				commit
				
					
						cbb9c408e4
					
				
			
		
					 15 changed files with 861 additions and 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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										51
									
								
								common/debug_config.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								common/debug_config.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										49
									
								
								common/nodebug.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								common/nodebug.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
							
								
								
									
										147
									
								
								common/print.c
									
										
									
									
									
								
							
							
						
						
									
										147
									
								
								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)
 | 
			
		||||
void print_lf(void)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t c;
 | 
			
		||||
    while (1) {
 | 
			
		||||
        c = pgm_read_byte(s++);
 | 
			
		||||
        if (!c) break;
 | 
			
		||||
        if (c == '\n') sendchar('\r');
 | 
			
		||||
        sendchar(c);
 | 
			
		||||
    }
 | 
			
		||||
    sendchar('\n');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void print_CRLF(void)
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
    print_bin_reverse8(data);
 | 
			
		||||
    print_bin_reverse8(data>>8);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void print_bin_reverse32(uint32_t data)
 | 
			
		||||
{
 | 
			
		||||
    print_bin_reverse8(data);
 | 
			
		||||
    print_bin_reverse8(data>>8);
 | 
			
		||||
    print_bin_reverse8(data>>16);
 | 
			
		||||
    print_bin_reverse8(data>>24);
 | 
			
		||||
    sendchar('\r');
 | 
			
		||||
    sendchar('\n');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										500
									
								
								common/xprintf.S
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										500
									
								
								common/xprintf.S
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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, 0		;Skip if null
 | 
			
		||||
	breq	2f		;/
 | 
			
		||||
	icall
 | 
			
		||||
2:	pop	ZL
 | 
			
		||||
	pop	ZH
 | 
			
		||||
	ret
 | 
			
		||||
.endfunc
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
;---------------------------------------------------------------------------
 | 
			
		||||
; Direct ROM string output
 | 
			
		||||
;
 | 
			
		||||
;Prototype: void xputs (const prog_char *str // rom string to be output
 | 
			
		||||
;			);
 | 
			
		||||
 | 
			
		||||
.func xputs
 | 
			
		||||
.global xputs
 | 
			
		||||
xputs:
 | 
			
		||||
	_MOVW	ZH,ZL, r25,r24	; Z = pointer to rom string
 | 
			
		||||
1:	_LPMI	r24
 | 
			
		||||
	cpi	r24, 0
 | 
			
		||||
	breq	2f
 | 
			
		||||
	rcall	xputc
 | 
			
		||||
	rjmp	1b
 | 
			
		||||
2:	ret
 | 
			
		||||
.endfunc
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
;---------------------------------------------------------------------------
 | 
			
		||||
; Extended direct numeral string output (32bit version)
 | 
			
		||||
;
 | 
			
		||||
;Prototype: void xitoa (long value,	// value to be output
 | 
			
		||||
;                       char radix,	// radix
 | 
			
		||||
;                       char width);	// minimum width
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
.func xitoa
 | 
			
		||||
.global xitoa
 | 
			
		||||
xitoa:
 | 
			
		||||
				;r25:r22 = value, r20 = base, r18 = digits
 | 
			
		||||
	clr	r31		;r31 = stack level
 | 
			
		||||
	ldi	r30, ' '	;r30 = sign
 | 
			
		||||
	ldi	r19, ' '	;r19 = filler
 | 
			
		||||
	sbrs	r20, 7		;When base indicates signd format and the value
 | 
			
		||||
	rjmp	0f		;is minus, add a '-'.
 | 
			
		||||
	neg	r20		;
 | 
			
		||||
	sbrs	r25, 7		;
 | 
			
		||||
	rjmp	0f		;
 | 
			
		||||
	ldi	r30, '-'	;
 | 
			
		||||
	com	r22		;
 | 
			
		||||
	com	r23		;
 | 
			
		||||
	com	r24		;
 | 
			
		||||
	com	r25		;
 | 
			
		||||
	adc	r22, r1		;
 | 
			
		||||
	adc	r23, r1		;
 | 
			
		||||
	adc	r24, r1		;
 | 
			
		||||
	adc	r25, r1		;/
 | 
			
		||||
0:	sbrs	r18, 7		;When digits indicates zero filled,
 | 
			
		||||
	rjmp	1f		;filler is '0'.
 | 
			
		||||
	neg	r18		;
 | 
			
		||||
	ldi	r19, '0'	;/
 | 
			
		||||
				;----- string conversion loop
 | 
			
		||||
1:	ldi	r21, 32		;r26 = r25:r22 % r20
 | 
			
		||||
	clr	r26		;r25:r22 /= r20
 | 
			
		||||
2:	lsl	r22		;
 | 
			
		||||
	rol	r23		;
 | 
			
		||||
	rol	r24		;
 | 
			
		||||
	rol	r25		;
 | 
			
		||||
	rol	r26		;
 | 
			
		||||
	cp	r26, r20	;
 | 
			
		||||
	brcs	3f		;
 | 
			
		||||
	sub	r26, r20	;
 | 
			
		||||
	inc	r22		;
 | 
			
		||||
3:	dec	r21		;
 | 
			
		||||
	brne	2b		;/
 | 
			
		||||
	cpi	r26, 10		;r26 is a numeral digit '0'-'F'
 | 
			
		||||
	brcs	4f		;
 | 
			
		||||
	subi	r26, -7		;
 | 
			
		||||
4:	subi	r26, -'0'	;/
 | 
			
		||||
	push	r26		;Stack it
 | 
			
		||||
	inc	r31		;/
 | 
			
		||||
	cp	r22, r1		;Repeat until r25:r22 gets zero
 | 
			
		||||
	cpc	r23, r1		;
 | 
			
		||||
	cpc	r24, r1		;
 | 
			
		||||
	cpc	r25, r1		;
 | 
			
		||||
	brne	1b		;/
 | 
			
		||||
 | 
			
		||||
	cpi	r30, '-'	;Minus sign if needed
 | 
			
		||||
	brne	5f		;
 | 
			
		||||
	push	r30		;
 | 
			
		||||
	inc	r31		;/
 | 
			
		||||
5:	cp	r31, r18	;Filler
 | 
			
		||||
	brcc	6f		;
 | 
			
		||||
	push	r19		;
 | 
			
		||||
	inc	r31		;
 | 
			
		||||
	rjmp	5b		;/
 | 
			
		||||
 | 
			
		||||
6:	pop	r24		;Flush stacked digits and exit
 | 
			
		||||
	rcall	xputc		;
 | 
			
		||||
	dec	r31		;
 | 
			
		||||
	brne	6b		;/
 | 
			
		||||
 | 
			
		||||
	ret
 | 
			
		||||
.endfunc
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
;---------------------------------------------------------------------------;
 | 
			
		||||
; Formatted string output (16/32bit version)
 | 
			
		||||
;
 | 
			
		||||
;Prototype:
 | 
			
		||||
; void xprintf (const prog_char *format, ...);
 | 
			
		||||
; void xsprintf(char*, const prog_char *format, ...);
 | 
			
		||||
; void xfprintf(void(*func)(char), const prog_char *format, ...);
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
#if USE_XPRINTF
 | 
			
		||||
 | 
			
		||||
.func xvprintf
 | 
			
		||||
xvprintf:
 | 
			
		||||
	ld	ZL, Y+		;Z = pointer to format string
 | 
			
		||||
	ld	ZH, Y+		;/
 | 
			
		||||
 | 
			
		||||
0:	_LPMI	r24		;Get a format char
 | 
			
		||||
	cpi	r24, 0		;End of format string?
 | 
			
		||||
	breq	90f		;/
 | 
			
		||||
	cpi	r24, '%'	;Is format?
 | 
			
		||||
	breq	20f		;/
 | 
			
		||||
1:	rcall	xputc		;Put a normal character
 | 
			
		||||
	rjmp	0b		;/
 | 
			
		||||
90:	ret
 | 
			
		||||
 | 
			
		||||
20:	ldi	r18, 0		;r18: digits
 | 
			
		||||
	clt			;T: filler
 | 
			
		||||
	_LPMI	r21		;Get flags
 | 
			
		||||
	cpi	r21, '%'	;Is a %?
 | 
			
		||||
	breq	1b		;/
 | 
			
		||||
	cpi	r21, '0'	;Zero filled?
 | 
			
		||||
	brne	23f		;
 | 
			
		||||
	set			;/
 | 
			
		||||
22:	_LPMI	r21		;Get width
 | 
			
		||||
23:	cpi	r21, '9'+1	;
 | 
			
		||||
	brcc	24f		;
 | 
			
		||||
	subi	r21, '0'	;
 | 
			
		||||
	brcs	90b		;
 | 
			
		||||
	lsl	r18		;
 | 
			
		||||
	mov	r0, r18		;
 | 
			
		||||
	lsl	r18		;
 | 
			
		||||
	lsl	r18		;
 | 
			
		||||
	add	r18, r0		;
 | 
			
		||||
	add	r18, r21	;
 | 
			
		||||
	rjmp	22b		;/
 | 
			
		||||
 | 
			
		||||
24:	brtc	25f		;get value (low word)
 | 
			
		||||
	neg	r18		;
 | 
			
		||||
25:	ld	r24, Y+		;
 | 
			
		||||
	ld	r25, Y+		;/
 | 
			
		||||
	cpi	r21, 'c'	;Is type character?
 | 
			
		||||
	breq	1b		;/
 | 
			
		||||
	cpi	r21, 's'	;Is type RAM string?
 | 
			
		||||
	breq	50f		;/
 | 
			
		||||
	cpi	r21, 'S'	;Is type ROM string?
 | 
			
		||||
	breq	60f		;/
 | 
			
		||||
	_MOVW	r23,r22,r25,r24	;r25:r22 = value
 | 
			
		||||
	clr	r24		;
 | 
			
		||||
	clr	r25		;
 | 
			
		||||
	clt			;/
 | 
			
		||||
	cpi	r21, 'l'	;Is long int?
 | 
			
		||||
	brne	26f		;
 | 
			
		||||
	ld	r24, Y+		;get value (high word)
 | 
			
		||||
	ld	r25, Y+		;
 | 
			
		||||
	set			;
 | 
			
		||||
	_LPMI	r21		;/
 | 
			
		||||
26:	cpi	r21, 'd'	;Is type signed decimal?
 | 
			
		||||
	brne	27f		;/
 | 
			
		||||
	ldi	r20, -10	;
 | 
			
		||||
	brts	40f		;
 | 
			
		||||
	sbrs	r23, 7		;
 | 
			
		||||
	rjmp	40f		;
 | 
			
		||||
	ldi	r24, -1		;
 | 
			
		||||
	ldi	r25, -1		;
 | 
			
		||||
	rjmp	40f		;/
 | 
			
		||||
27:	cpi	r21, 'u'	;Is type unsigned decimal?
 | 
			
		||||
	ldi	r20, 10		;
 | 
			
		||||
	breq	40f		;/
 | 
			
		||||
	cpi	r21, 'X'	;Is type hexdecimal?
 | 
			
		||||
	ldi	r20, 16		;
 | 
			
		||||
	breq	40f		;/
 | 
			
		||||
	cpi	r21, 'b'	;Is type binary?
 | 
			
		||||
	ldi	r20, 2		;
 | 
			
		||||
	breq	40f		;/
 | 
			
		||||
	ret			;abort
 | 
			
		||||
40:	push	ZH		;Output the value
 | 
			
		||||
	push	ZL		;
 | 
			
		||||
	rcall	xitoa		;
 | 
			
		||||
42:	pop	ZL		;
 | 
			
		||||
	pop	ZH		;
 | 
			
		||||
	rjmp	0b		;/
 | 
			
		||||
 | 
			
		||||
50:	push	ZH		;Put a string on the RAM
 | 
			
		||||
	push	ZL
 | 
			
		||||
	_MOVW	ZH,ZL, r25,r24
 | 
			
		||||
51:	ld	r24, Z+
 | 
			
		||||
	cpi	r24, 0
 | 
			
		||||
	breq	42b
 | 
			
		||||
	rcall	xputc
 | 
			
		||||
	rjmp	51b
 | 
			
		||||
 | 
			
		||||
60:	push	ZH		;Put a string on the ROM
 | 
			
		||||
	push	ZL
 | 
			
		||||
	rcall	xputs
 | 
			
		||||
	rjmp	42b
 | 
			
		||||
.endfunc
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.func __xprintf
 | 
			
		||||
.global __xprintf
 | 
			
		||||
__xprintf:
 | 
			
		||||
	push	YH
 | 
			
		||||
	push	YL
 | 
			
		||||
	in	YL, _SFR_IO_ADDR(SPL)
 | 
			
		||||
#ifdef SPH
 | 
			
		||||
	in	YH, _SFR_IO_ADDR(SPH)
 | 
			
		||||
#else
 | 
			
		||||
	clr	YH
 | 
			
		||||
#endif
 | 
			
		||||
	adiw	YL, 5		;Y = pointer to arguments
 | 
			
		||||
	rcall	xvprintf
 | 
			
		||||
	pop	YL
 | 
			
		||||
	pop	YH
 | 
			
		||||
	ret
 | 
			
		||||
.endfunc
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if USE_XSPRINTF
 | 
			
		||||
 | 
			
		||||
.func __xsprintf
 | 
			
		||||
putram:
 | 
			
		||||
	_MOVW	ZH,ZL, r15,r14
 | 
			
		||||
	st	Z+, r24
 | 
			
		||||
	_MOVW	r15,r14, ZH,ZL
 | 
			
		||||
	ret
 | 
			
		||||
.global __xsprintf
 | 
			
		||||
__xsprintf:
 | 
			
		||||
	push	YH
 | 
			
		||||
	push	YL
 | 
			
		||||
	in	YL, _SFR_IO_ADDR(SPL)
 | 
			
		||||
#ifdef SPH
 | 
			
		||||
	in	YH, _SFR_IO_ADDR(SPH)
 | 
			
		||||
#else
 | 
			
		||||
	clr	YH
 | 
			
		||||
#endif
 | 
			
		||||
	adiw	YL, 5		;Y = pointer to arguments
 | 
			
		||||
	lds	ZL, xfunc_out+0	;Save registered output function
 | 
			
		||||
	lds	ZH, xfunc_out+1	;
 | 
			
		||||
	push	ZL		;
 | 
			
		||||
	push	ZH		;/
 | 
			
		||||
	ldi	ZL, lo8(pm(putram));Set local output function
 | 
			
		||||
	ldi	ZH, hi8(pm(putram));
 | 
			
		||||
	sts	xfunc_out+0, ZL	;
 | 
			
		||||
	sts	xfunc_out+1, ZH	;/
 | 
			
		||||
	push	r15		;Initialize pointer to string buffer
 | 
			
		||||
	push	r14		;
 | 
			
		||||
	ld	r14, Y+		;
 | 
			
		||||
	ld	r15, Y+		;/
 | 
			
		||||
	rcall	xvprintf
 | 
			
		||||
	_MOVW	ZH,ZL, r15,r14	;Terminate string
 | 
			
		||||
	st	Z, r1		;
 | 
			
		||||
	pop	r14		;
 | 
			
		||||
	pop	r15		;/
 | 
			
		||||
	pop	ZH		;Restore registered output function
 | 
			
		||||
	pop	ZL		;
 | 
			
		||||
	sts	xfunc_out+0, ZL	;
 | 
			
		||||
	sts	xfunc_out+1, ZH	;/
 | 
			
		||||
	pop	YL
 | 
			
		||||
	pop	YH
 | 
			
		||||
	ret
 | 
			
		||||
.endfunc
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if USE_XFPRINTF
 | 
			
		||||
.func __xfprintf
 | 
			
		||||
.global __xfprintf
 | 
			
		||||
__xfprintf:
 | 
			
		||||
	push	YH
 | 
			
		||||
	push	YL
 | 
			
		||||
	in	YL, _SFR_IO_ADDR(SPL)
 | 
			
		||||
#ifdef SPH
 | 
			
		||||
	in	YH, _SFR_IO_ADDR(SPH)
 | 
			
		||||
#else
 | 
			
		||||
	clr	YH
 | 
			
		||||
#endif
 | 
			
		||||
	adiw	YL, 5		;Y = pointer to arguments
 | 
			
		||||
	lds	ZL, xfunc_out+0	;Save registered output function
 | 
			
		||||
	lds	ZH, xfunc_out+1	;
 | 
			
		||||
	push	ZL		;
 | 
			
		||||
	push	ZH		;/
 | 
			
		||||
	ld	ZL, Y+		;Set output function
 | 
			
		||||
	ld	ZH, Y+		;
 | 
			
		||||
	sts	xfunc_out+0, ZL	;
 | 
			
		||||
	sts	xfunc_out+1, ZH	;/
 | 
			
		||||
	rcall	xvprintf
 | 
			
		||||
	pop	ZH		;Restore registered output function
 | 
			
		||||
	pop	ZL		;
 | 
			
		||||
	sts	xfunc_out+0, ZL	;
 | 
			
		||||
	sts	xfunc_out+1, ZH	;/
 | 
			
		||||
	pop	YL
 | 
			
		||||
	pop	YH
 | 
			
		||||
	ret
 | 
			
		||||
.endfunc
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
;---------------------------------------------------------------------------
 | 
			
		||||
; Extended numeral string input
 | 
			
		||||
;
 | 
			
		||||
;Prototype:
 | 
			
		||||
; char xatoi (           /* 1: Successful, 0: Failed */
 | 
			
		||||
;      const char **str, /* pointer to pointer to source string */
 | 
			
		||||
;      long *res         /* result */
 | 
			
		||||
; );
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#if USE_XATOI
 | 
			
		||||
.func xatoi
 | 
			
		||||
.global xatoi
 | 
			
		||||
xatoi:
 | 
			
		||||
	_MOVW	r1, r0, r23, r22
 | 
			
		||||
	_MOVW	XH, XL, r25, r24
 | 
			
		||||
	ld	ZL, X+
 | 
			
		||||
	ld	ZH, X+
 | 
			
		||||
	clr	r18		;r21:r18 = 0;
 | 
			
		||||
	clr	r19		;
 | 
			
		||||
	clr	r20		;
 | 
			
		||||
	clr	r21		;/
 | 
			
		||||
	clt			;T = 0;
 | 
			
		||||
 | 
			
		||||
	ldi	r25, 10		;r25 = 10;
 | 
			
		||||
	rjmp	41f		;/
 | 
			
		||||
40:	adiw	ZL, 1		;Z++;
 | 
			
		||||
41:	ld	r22, Z		;r22 = *Z;
 | 
			
		||||
	cpi	r22, ' '	;if(r22 == ' ') continue
 | 
			
		||||
	breq	40b		;/
 | 
			
		||||
	brcs	70f		;if(r22 < ' ') error;
 | 
			
		||||
	cpi	r22, '-'	;if(r22 == '-') {
 | 
			
		||||
	brne	42f		; T = 1;
 | 
			
		||||
	set			; continue;
 | 
			
		||||
	rjmp	40b		;}
 | 
			
		||||
42:	cpi	r22, '9'+1	;if(r22 > '9') error;
 | 
			
		||||
	brcc	70f		;/
 | 
			
		||||
	cpi	r22, '0'	;if(r22 < '0') error;
 | 
			
		||||
	brcs	70f		;/
 | 
			
		||||
	brne	51f		;if(r22 > '0') cv_start;
 | 
			
		||||
	ldi	r25, 8		;r25 = 8;
 | 
			
		||||
	adiw	ZL, 1		;r22 = *(++Z);
 | 
			
		||||
	ld	r22, Z		;/
 | 
			
		||||
	cpi	r22, ' '+1	;if(r22 <= ' ') exit;
 | 
			
		||||
	brcs	80f		;/
 | 
			
		||||
	cpi	r22, 'b'	;if(r22 == 'b') {
 | 
			
		||||
	brne	43f		; r25 = 2;
 | 
			
		||||
	ldi	r25, 2		; cv_start;
 | 
			
		||||
	rjmp	50f		;}
 | 
			
		||||
43:	cpi	r22, 'x'	;if(r22 != 'x') error;
 | 
			
		||||
	brne	51f		;/
 | 
			
		||||
	ldi	r25, 16		;r25 = 16;
 | 
			
		||||
 | 
			
		||||
50:	adiw	ZL, 1		;Z++;
 | 
			
		||||
	ld	r22, Z		;r22 = *Z;
 | 
			
		||||
51:	cpi	r22, ' '+1	;if(r22 <= ' ') break;
 | 
			
		||||
	brcs	80f		;/
 | 
			
		||||
	cpi	r22, 'a'	;if(r22 >= 'a') r22 =- 0x20;
 | 
			
		||||
	brcs	52f		;
 | 
			
		||||
	subi	r22, 0x20	;/
 | 
			
		||||
52:	subi	r22, '0'	;if((r22 -= '0') < 0) error;
 | 
			
		||||
	brcs	70f		;/
 | 
			
		||||
	cpi	r22, 10		;if(r22 >= 10) {
 | 
			
		||||
	brcs	53f		; r22 -= 7;
 | 
			
		||||
	subi	r22, 7		; if(r22 < 10) 
 | 
			
		||||
	cpi	r22, 10		;
 | 
			
		||||
	brcs	70f		;}
 | 
			
		||||
53:	cp	r22, r25	;if(r22 >= r25) error;
 | 
			
		||||
	brcc	70f		;/
 | 
			
		||||
60:	ldi	r24, 33		;r21:r18 *= r25;
 | 
			
		||||
	sub	r23, r23	;
 | 
			
		||||
61:	brcc	62f		;
 | 
			
		||||
	add	r23, r25	;
 | 
			
		||||
62:	lsr	r23		;
 | 
			
		||||
	ror	r21		;
 | 
			
		||||
	ror	r20		;
 | 
			
		||||
	ror	r19		;
 | 
			
		||||
	ror	r18		;
 | 
			
		||||
	dec	r24		;
 | 
			
		||||
	brne	61b		;/
 | 
			
		||||
	add	r18, r22	;r21:r18 += r22;
 | 
			
		||||
	adc	r19, r24	;
 | 
			
		||||
	adc	r20, r24	;
 | 
			
		||||
	adc	r21, r24	;/
 | 
			
		||||
	rjmp	50b		;repeat
 | 
			
		||||
 | 
			
		||||
70:	ldi	r24, 0
 | 
			
		||||
	rjmp	81f
 | 
			
		||||
80:	ldi	r24, 1
 | 
			
		||||
81:	brtc	82f
 | 
			
		||||
	clr	r22
 | 
			
		||||
	com	r18
 | 
			
		||||
	com	r19
 | 
			
		||||
	com	r20
 | 
			
		||||
	com	r21
 | 
			
		||||
	adc	r18, r22
 | 
			
		||||
	adc	r19, r22
 | 
			
		||||
	adc	r20, r22
 | 
			
		||||
	adc	r21, r22
 | 
			
		||||
82:	st	-X, ZH
 | 
			
		||||
	st	-X, ZL
 | 
			
		||||
	_MOVW	XH, XL, r1, r0
 | 
			
		||||
	st	X+, r18
 | 
			
		||||
	st	X+, r19
 | 
			
		||||
	st	X+, r20
 | 
			
		||||
	st	X+, r21
 | 
			
		||||
	clr	r1
 | 
			
		||||
	ret
 | 
			
		||||
.endfunc
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										103
									
								
								common/xprintf.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								common/xprintf.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,103 @@
 | 
			
		|||
/*---------------------------------------------------------------------------
 | 
			
		||||
   Extended itoa, puts and printf                    (C)ChaN, 2011
 | 
			
		||||
-----------------------------------------------------------------------------*/
 | 
			
		||||
 | 
			
		||||
#ifndef XPRINTF_H
 | 
			
		||||
#define XPRINTF_H
 | 
			
		||||
 | 
			
		||||
#include <inttypes.h>
 | 
			
		||||
#include <avr/pgmspace.h>
 | 
			
		||||
 | 
			
		||||
extern void (*xfunc_out)(uint8_t);
 | 
			
		||||
#define xdev_out(func) xfunc_out = (void(*)(uint8_t))(func)
 | 
			
		||||
 | 
			
		||||
/* This is a pointer to user defined output function. It must be initialized
 | 
			
		||||
   before using this modle.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
void xputc(char chr);
 | 
			
		||||
 | 
			
		||||
/* This is a stub function to forward outputs to user defined output function.
 | 
			
		||||
   All outputs from this module are output via this function.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------------*/
 | 
			
		||||
void xputs(const prog_char *string);
 | 
			
		||||
 | 
			
		||||
/*  The string placed in the ROM is forwarded to xputc() directly.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------------*/
 | 
			
		||||
void xitoa(long value, char radix, char width);
 | 
			
		||||
 | 
			
		||||
/* Extended itoa().
 | 
			
		||||
 | 
			
		||||
      value  radix  width   output
 | 
			
		||||
        100     10      6   "   100"
 | 
			
		||||
        100     10     -6   "000100"
 | 
			
		||||
        100     10      0   "100"
 | 
			
		||||
 4294967295     10      0   "4294967295"
 | 
			
		||||
 4294967295    -10      0   "-1"
 | 
			
		||||
     655360     16     -8   "000A0000"
 | 
			
		||||
       1024     16      0   "400"
 | 
			
		||||
       0x55      2     -8   "01010101"
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------------*/
 | 
			
		||||
#define xprintf(format, ...)            __xprintf(PSTR(format), ##__VA_ARGS__)
 | 
			
		||||
#define xsprintf(str, format, ...)      __xsprintf(str, PSTR(format), ##__VA_ARGS__)
 | 
			
		||||
#define xfprintf(func, format, ...)     __xfprintf(func, PSTR(format), ##__VA_ARGS__)
 | 
			
		||||
 | 
			
		||||
void __xprintf(const prog_char *format, ...);	/* Send formatted string to the registered device */
 | 
			
		||||
void __xsprintf(char*, const prog_char *format, ...);	/* Put formatted string to the memory */
 | 
			
		||||
void __xfprintf(void(*func)(uint8_t), const prog_char *format, ...); /* Send formatted string to the specified device */
 | 
			
		||||
 | 
			
		||||
/* Format string is placed in the ROM. The format flags is similar to printf().
 | 
			
		||||
 | 
			
		||||
   %[flag][width][size]type
 | 
			
		||||
 | 
			
		||||
   flag
 | 
			
		||||
     A '0' means filled with '0' when output is shorter than width.
 | 
			
		||||
     ' ' is used in default. This is effective only numeral type.
 | 
			
		||||
   width
 | 
			
		||||
     Minimum width in decimal number. This is effective only numeral type.
 | 
			
		||||
     Default width is zero.
 | 
			
		||||
   size
 | 
			
		||||
     A 'l' means the argument is long(32bit). Default is short(16bit).
 | 
			
		||||
     This is effective only numeral type.
 | 
			
		||||
   type
 | 
			
		||||
     'c' : Character, argument is the value
 | 
			
		||||
     's' : String placed on the RAM, argument is the pointer
 | 
			
		||||
     'S' : String placed on the ROM, argument is the pointer
 | 
			
		||||
     'd' : Signed decimal, argument is the value
 | 
			
		||||
     'u' : Unsigned decimal, argument is the value
 | 
			
		||||
     'X' : Hexdecimal, argument is the value
 | 
			
		||||
     'b' : Binary, argument is the value
 | 
			
		||||
     '%' : '%'
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*-----------------------------------------------------------------------------*/
 | 
			
		||||
char xatoi(char **str, long *ret);
 | 
			
		||||
 | 
			
		||||
/* Get value of the numeral string. 
 | 
			
		||||
 | 
			
		||||
  str
 | 
			
		||||
    Pointer to pointer to source string
 | 
			
		||||
 | 
			
		||||
    "0b11001010" binary
 | 
			
		||||
    "0377" octal
 | 
			
		||||
    "0xff800" hexdecimal
 | 
			
		||||
    "1250000" decimal
 | 
			
		||||
    "-25000" decimal
 | 
			
		||||
 | 
			
		||||
  ret
 | 
			
		||||
    Pointer to return value
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue