diff --git a/firmware/asdf/src/Arch/asdf_arch_atmega2560.h b/firmware/asdf/src/Arch/asdf_arch_atmega2560.h
index 78859d9..19ce63d 100644
--- a/firmware/asdf/src/Arch/asdf_arch_atmega2560.h
+++ b/firmware/asdf/src/Arch/asdf_arch_atmega2560.h
@@ -342,6 +342,13 @@
// For 1 ms tick, (16000000 / 64(prescale)) / 1000(usec) - 1 = 249
#define TICK_COUNT 249
+// Default key matrix row scanner
+#define ASDF_ARCH_DEFAULT_SCANNER asdf_arch_read_row
+
+// Default keyboard output
+#define ASDF_ARCH_DEFAULT_OUTPUT asdf_arch_send_code
+
+
// PROCEDURE: asdf_arch_null_output
// INPUTS: (uint8_t) value - ignored
// OUTPUTS: none
diff --git a/firmware/asdf/src/Arch/asdf_arch_atmega328p.h b/firmware/asdf/src/Arch/asdf_arch_atmega328p.h
index d38ba48..fe61051 100644
--- a/firmware/asdf/src/Arch/asdf_arch_atmega328p.h
+++ b/firmware/asdf/src/Arch/asdf_arch_atmega328p.h
@@ -248,6 +248,13 @@
// For 1 ms tick, (8000000 / 64(prescale)) / 1000(usec) - 1 = 124
#define TICK_COUNT 124
+
+// Default key matrix row scanner
+#define ASDF_ARCH_DEFAULT_SCANNER asdf_arch_read_row
+
+// Default keyboard output
+#define ASDF_ARCH_DEFAULT_OUTPUT asdf_arch_send_code
+
// PROCEDURE: asdf_arch_null_output
// INPUTS: (uint8_t) value - ignored
// OUTPUTS: none
diff --git a/firmware/asdf/src/Arch/asdf_arch_test.c b/firmware/asdf/src/Arch/asdf_arch_test.c
index 0ac6489..b697d7e 100644
--- a/firmware/asdf/src/Arch/asdf_arch_test.c
+++ b/firmware/asdf/src/Arch/asdf_arch_test.c
@@ -110,6 +110,68 @@ static uint8_t outputs[ASDF_PHYSICAL_NUM_RESOURCES];
static pulse_state_t pulses[ASDF_PHYSICAL_NUM_RESOURCES];
+
+static asdf_keycode_t code_register;
+static uint8_t code_sent;
+
+// PROCEDURE: asdf_arch_send_code
+// INPUTS: asdf_keycode_t code
+// OUTPUTS: none
+// DESCRIPTION: emulates sending a code, by copying code to a register that can
+// be tested.
+//
+// SIDE_EFFECTS: sets code_sent variable and alters code_register
+//
+// NOTES:
+//
+// SCOPE: public
+//
+// COMPLEXITY: 1
+//
+void asdf_arch_send_code(asdf_keycode_t code)
+{
+ code_register = code;
+ code_sent = 1;
+}
+
+// PROCEDURE: asdf_arch_get_sent_code
+// INPUTS: none
+// OUTPUTS: returns type (asdf_keycode_t) in register and zeros the register.
+// DESCRIPTION: faciliates test of sending a code, by reporting contents of the
+// "sent register". Resets code_sent variable.
+//
+// SIDE_EFFECTS: alters code_sent variable
+//
+// NOTES:
+//
+// SCOPE: public
+//
+// COMPLEXITY: 1
+//
+asdf_keycode_t asdf_arch_get_sent_code(void)
+{
+ code_sent = 0;
+ return code_register;
+}
+
+// PROCEDURE: asdf_arch_was_code_sent
+// INPUTS: none
+// OUTPUTS: returns TRUE if a code was sent, FALSE otherwise.
+// DESCRIPTION: returns status of code_sent variable.
+//
+// SIDE_EFFECTS: sets code_sent variable and alters code_register
+//
+// NOTES:
+//
+// SCOPE: public
+//
+// COMPLEXITY: 1
+//
+uint8_t asdf_arch_was_code_sent(void){
+ return code_sent;
+}
+
+
// PROCEDURE: pulse_detect
// INPUTS: (pulse_state_t) current_state
// (pulse_event_t) event - current input to the state machine
@@ -521,6 +583,9 @@ void asdf_arch_init(void)
outputs[i] = 0;
pulses[i] = PD_ST_INITIAL_STATE;
}
+
+ // initially, no keycodes have been sent via asdf_arch_send_code:
+ code_sent = 0;
}
diff --git a/firmware/asdf/src/Arch/asdf_arch_test.h b/firmware/asdf/src/Arch/asdf_arch_test.h
index 6f1eaab..5f4d824 100644
--- a/firmware/asdf/src/Arch/asdf_arch_test.h
+++ b/firmware/asdf/src/Arch/asdf_arch_test.h
@@ -26,49 +26,8 @@
#if !defined (ASDF_ARCH_H)
#define ASDF_ARCH_H
-#include "asdf.h"
-
-#define FLASH
-#define FLASH_READ (a) (*(a))
-#define FLASH_READ_MATRIX_ELEMENT(mat,row,col) (mat)[(row)][(col)]
-
-// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
-//
-// Unfified Keyboard Project
-// ASDF keyboard firmware
-//
-// asdf_arch.c
-//
-// This file contains all the architecture dependent code, including register
-// setup, I/O, timers, etc.
-//
-// Copyright 2019 David Fenyes
-//
-// 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 3 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 .
-
-
-// Wiring Information:
-// Chip: {Microcontroller type and version}
-//
-// Example:
-// PIN NAME FUNCTION
-// 14-19,9,10 PORTB COLUMN inputs (1 bit per column)
-// 23-25 PORTC0-2 ROW outputs (row number)
-// 27 PORTC4
-
-
#include
+#include "asdf.h"
#include "asdf_keymap_defs.h"
#include "asdf_config.h"
#include "asdf_physical.h"
@@ -76,6 +35,7 @@
#include "asdf_arch.h"
+
typedef enum {
PD_ST_INITIAL_STATE = 0,
PD_ST_STABLE_LOW = 1,
@@ -95,6 +55,12 @@ typedef enum {
PD_ST_ERROR_PULSE_FROM_INITIAL_STATE = 15,
} pulse_state_t;
+#define FLASH
+#define FLASH_READ (a) (*(a))
+#define FLASH_READ_MATRIX_ELEMENT(mat,row,col) (mat)[(row)][(col)]
+#define ASDF_ARCH_DEFAULT_SCANNER asdf_arch_read_row
+#define ASDF_ARCH_DEFAULT_OUTPUT asdf_arch_send_code
+
// PROCEDURE: asdf_arch_null_output
// INPUTS: (uint8_t) value - ignored
// OUTPUTS: none
@@ -213,6 +179,24 @@ void asdf_arch_pulse_delay_long(void);
// the row, with 1=pressed, 0=released.
asdf_cols_t asdf_arch_read_row(uint8_t row);
+// PROCEDURE: asdf_arch_send_code
+// INPUTS: asdf_keycode_t code
+// OUTPUTS: none
+// DESCRIPTION: emulates sending a code, by copying code to a register that can
+// be tested.
+void asdf_arch_send_code(asdf_keycode_t);
+
+// PROCEDURE: asdf_arch_get_sent_code
+// INPUTS: none
+// OUTPUTS: returns type (asdf_keycode_t) in register and zeros the register.
+// DESCRIPTION: faciliates test of sending a code, by reporting contents of the
+// "sent register"
+asdf_keycode_t asdf_arch_get_sent_code(void);
+
+// PROCEDURE: asdf_arch_was_code_sent
+// INPUTS: none
+// OUTPUTS: returns TRUE if a code was sent, FALSE otherwise.
+uint8_t asdf_arch_was_code_sent(void);
// PROCEDURE: asdf_arch_init
// INPUTS: none
diff --git a/firmware/asdf/src/Keymaps/asdf_all_keymap_defs_production.h b/firmware/asdf/src/Keymaps/asdf_all_keymap_defs_production.h
index dcd0497..f0c8e0c 100644
--- a/firmware/asdf/src/Keymaps/asdf_all_keymap_defs_production.h
+++ b/firmware/asdf/src/Keymaps/asdf_all_keymap_defs_production.h
@@ -42,12 +42,12 @@
#define ASDF_NUM_KEYMAPS \
(ASDF_ASCII_ALL_MAPS_COUNT + ASDF_APPLE2_ALL_MAPS_COUNT + ASDF_SOL_ALL_MAPS_COUNT)
-#define ASDF_KEYMAP_DEFS \
+#define ASDF_KEYMAP_DEFS \
{ \
ASDF_ASCII_ALL_MAPS, ASDF_APPLE2_ALL_MAPS, ASDF_SOL_ALL_MAPS \
}
-#define ASDF_KEYMAP_DECLARATIONS \
+#define ASDF_KEYMAP_DECLARATIONS \
ASDF_ASCII_MAP_DECLARATIONS ASDF_APPLE2_MAP_DECLARATIONS ASDF_SOL_MAP_DECLARATIONS
#define ASDF_KEYMAP_INITIALIZERS \
@@ -55,6 +55,14 @@
ASDF_ASCII_KEYMAP_INITIALIZER, ASDF_APPLE2_KEYMAP_INITIALIZER, ASDF_SOL_KEYMAP_INITIALIZER \
}
+#define ASDF_KEYMAP_HOOK_INITIALIZERS \
+ { \
+ ASDF_ASCII_KEYMAP_HOOK_INITIALIZER, ASDF_APPLE2_KEYMAP_HOOK_INITIALIZER, \
+ ASDF_SOL_KEYMAP_HOOK_INITIALIZER \
+ }
+
+typedef asdf_keycode_t keycode_matrix_t[ASDF_NUM_ROWS][ASDF_NUM_COLS];
+
typedef asdf_keycode_t keycode_matrix_t[ASDF_NUM_ROWS][ASDF_NUM_COLS];
diff --git a/firmware/asdf/src/Keymaps/asdf_all_keymap_defs_test.h b/firmware/asdf/src/Keymaps/asdf_all_keymap_defs_test.h
index fa6fe74..1ee4747 100644
--- a/firmware/asdf/src/Keymaps/asdf_all_keymap_defs_test.h
+++ b/firmware/asdf/src/Keymaps/asdf_all_keymap_defs_test.h
@@ -30,6 +30,7 @@
#define ASDF_KEYMAP_DEFS_H
#include "asdf.h"
+#include "test_asdf_lib.h"
#include "asdf_ascii.h"
#include "asdf_modifiers.h"
#include "Keymaps/asdf_keymap_defs_test.h"
@@ -41,16 +42,26 @@
#define ASDF_NUM_KEYMAPS (ASDF_TEST_BASE + ASDF_TEST_KEYMAPS_COUNT + ASDF_TEST2_KEYMAPS_COUNT)
-#define ASDF_KEYMAP_DEFS { ASDF_TEST_KEYMAPS, ASDF_TEST2_KEYMAPS }
+#define ASDF_KEYMAP_DEFS \
+ { \
+ ASDF_TEST_KEYMAPS, ASDF_TEST2_KEYMAPS \
+ }
#define ASDF_KEYMAP_DECLARATIONS ASDF_TEST_DECLARATIONS ASDF_TEST2_DECLARATIONS
-#define ASDF_KEYMAP_INITIALIZERS { ASDF_TEST_KEYMAP_INITIALIZER , ASDF_TEST2_KEYMAP_INITIALIZER }
+#define ASDF_KEYMAP_INITIALIZERS \
+ { \
+ ASDF_TEST_KEYMAP_INITIALIZER, ASDF_TEST2_KEYMAP_INITIALIZER \
+ }
+
+#define ASDF_KEYMAP_HOOK_INITIALIZERS \
+ { \
+ ASDF_TEST_KEYMAP_HOOK_INITIALIZER, ASDF_TEST2_KEYMAP_HOOK_INITIALIZER \
+ }
typedef asdf_keycode_t keycode_matrix_t[ASDF_NUM_ROWS][ASDF_NUM_COLS];
-
#endif /* !defined (ASDF_KEYMAP_DEFS_H) */
//-------|---------|---------+---------+---------+---------+---------+---------+
diff --git a/firmware/asdf/src/Keymaps/asdf_keymap_defs_apple2.h b/firmware/asdf/src/Keymaps/asdf_keymap_defs_apple2.h
index d6d4c07..b2695ea 100644
--- a/firmware/asdf/src/Keymaps/asdf_keymap_defs_apple2.h
+++ b/firmware/asdf/src/Keymaps/asdf_keymap_defs_apple2.h
@@ -109,7 +109,15 @@
#define ASDF_APPLE2_KEYMAP_INITIALIZER ASDF_APPLE2_PLAIN_KEYMAP_INITIALIZER, ASDF_APPLE2_CAPS_KEYMAP_INITIALIZER
-// Key Matrix for combination of ASCII controller (ATMega328P version) and Classic ASCII matrix
+// Structure to initialize hooks. No hook functions are needed for APPLE2 keyboard.
+#define ASDF_APPLE2_KEYMAP_HOOK_INITIALIZER_LENGTH 0
+#define ASDF_APPLE2_PLAIN_KEYMAP_HOOK_INITIALIZER {}
+#define ASDF_APPLE2_CAPS_KEYMAP_HOOK_INITIALIZER {}
+#define ASDF_APPLE2_KEYMAP_HOOK_INITIALIZER ASDF_APPLE2_PLAIN_KEYMAP_HOOK_INITIALIZER, ASDF_APPLE2_CAPS_KEYMAP_HOOK_INITIALIZER
+
+
+
+// Key Matrix for combination of ASCII controller and Classic ASCII matrix
//
// Col-> 0 1 2 3 4 5 6 7
// Row 0 POWER R-Shift L-Shift (no key) ESC TAB CTRL \(backslash)
@@ -279,6 +287,11 @@
#define ASDF_KEYMAP_INITIALIZER_LENGTH ASDF_APPLE2_KEYMAP_INITIALIZER_LENGTH
#endif
+#if !defined(ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH) || (ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH < ASDF_APPLE2_KEYMAP_HOOK_INITIALIZER_LENGTH)
+#undef ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH
+#define ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH ASDF_APPLE2_KEYMAP_HOOK_INITIALIZER_LENGTH
+#endif
+
#endif /* !defined (ASDF_KEYMAP_DEFS_APPLE2_H) */
//-------|---------|---------+---------+---------+---------+---------+---------+
diff --git a/firmware/asdf/src/Keymaps/asdf_keymap_defs_ascii.h b/firmware/asdf/src/Keymaps/asdf_keymap_defs_ascii.h
index cc8af28..f1c172e 100644
--- a/firmware/asdf/src/Keymaps/asdf_keymap_defs_ascii.h
+++ b/firmware/asdf/src/Keymaps/asdf_keymap_defs_ascii.h
@@ -103,7 +103,13 @@
#define ASDF_ASCII_KEYMAP_INITIALIZER ASDF_ASCII_PLAIN_KEYMAP_INITIALIZER, ASDF_ASCII_CAPS_KEYMAP_INITIALIZER
-// Key Matrix for combination of ASCII controller (ATMega328P version) and Classic ASCII matrix
+// Structure to initialize hooks. No hook functions are needed for ASCII keyboard.
+#define ASDF_ASCII_KEYMAP_HOOK_INITIALIZER_LENGTH 0
+#define ASDF_ASCII_PLAIN_KEYMAP_HOOK_INITIALIZER {}
+#define ASDF_ASCII_CAPS_KEYMAP_HOOK_INITIALIZER {}
+#define ASDF_ASCII_KEYMAP_HOOK_INITIALIZER ASDF_ASCII_PLAIN_KEYMAP_HOOK_INITIALIZER, ASDF_ASCII_CAPS_KEYMAP_HOOK_INITIALIZER
+
+// Key Matrix for combination of ASCII controller and Classic ASCII matrix
//
// Col-> 0 1 2 3 4 5 6 7
// Row 0 POWER R-Shift L-Shift (no key) ESC TAB CTRL \(backslash)
@@ -254,6 +260,11 @@
#define ASDF_KEYMAP_INITIALIZER_LENGTH ASDF_ASCII_KEYMAP_INITIALIZER_LENGTH
#endif
+#if !defined(ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH) || (ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH < ASDF_ASCII_KEYMAP_HOOK_INITIALIZER_LENGTH)
+#undef ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH
+#define ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH ASDF_ASCII_KEYMAP_HOOK_INITIALIZER_LENGTH
+#endif
+
#endif /* !defined (ASDF_KEYMAP_DEFS_ASCII_H) */
//-------|---------|---------+---------+---------+---------+---------+---------+
diff --git a/firmware/asdf/src/Keymaps/asdf_keymap_defs_sol.h b/firmware/asdf/src/Keymaps/asdf_keymap_defs_sol.h
index 6309a8a..57a01c5 100644
--- a/firmware/asdf/src/Keymaps/asdf_keymap_defs_sol.h
+++ b/firmware/asdf/src/Keymaps/asdf_keymap_defs_sol.h
@@ -84,7 +84,7 @@
// The weird C preprocessor expansion behavior requires one dereference for each
// expansion.
-#define SOL_KBD_VIRTUAL_SUB1(SOL_VDEVICE) ACTION_ ## SOL_VDEVICE
+#define SOL_KBD_VIRTUAL_SUB1(SOL_VDEVICE) ACTION_##SOL_VDEVICE
#define SOL_KBD_VIRTUAL_SUB(SOL_VDEVICE) SOL_KBD_VIRTUAL_SUB1(SOL_VDEVICE)
#define SOL_KBD_LOCAL_ACTION SOL_KBD_VIRTUAL_SUB(SOL_KBD_VLOCAL)
@@ -137,6 +137,18 @@
.initial_value = SOL_KBD_TTL_HIGH }, \
}
+// function hooks for the SOL keyboard. At Setup, activate CAPSLOCK to emulate
+// original keyboard.
+#define ASDF_SOL_KEYMAP_HOOK_INITIALIZER_LENGTH 1
+#define ASDF_SOL_KEYMAP_HOOK_INITIALIZER \
+ { \
+ { \
+ .hook_id = ASDF_HOOK_KEYMAP_SETUP, \
+ .hook_func = asdf_modifier_capslock_activate, \
+ }, \
+ }
+
+
#define DIP_SWITCH_ROW 15
#define ASDF_SOL_DIP_SWITCHES \
@@ -283,6 +295,12 @@
#define ASDF_KEYMAP_INITIALIZER_LENGTH ASDF_SOL_KEYMAP_INITIALIZER_LENGTH
#endif
+#if !defined(ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH) \
+ || (ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH < ASDF_SOL_KEYMAP_HOOK_INITIALIZER_LENGTH)
+#undef ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH
+#define ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH ASDF_SOL_KEYMAP_HOOK_INITIALIZER_LENGTH
+#endif
+
#endif /* !defined (ASDF_KEYMAP_DEFS_SOL20_H) */
//-------|---------|---------+---------+---------+---------+---------+---------+
diff --git a/firmware/asdf/src/Keymaps/asdf_keymap_defs_test.h b/firmware/asdf/src/Keymaps/asdf_keymap_defs_test.h
index 4f88072..35598dd 100644
--- a/firmware/asdf/src/Keymaps/asdf_keymap_defs_test.h
+++ b/firmware/asdf/src/Keymaps/asdf_keymap_defs_test.h
@@ -63,10 +63,10 @@
{ PLAIN_MATRIX_1, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
ACTION_CAPS, ASCII_ESC, ACTION_CTRL, ASCII_BACKSLASH }, \
{ ACTION_NOTHING, 'p', ';', '/', ASCII_SPACE, 'z', 'a', 'q' }, \
- { ACTION_NOTHING, ASCII_COMMA, 'm', 'n', 'b', 'v', 'c', 'x' }, \
+ { ACTION_NOTHING, ASCII_COMMA, 'm', 'n', 'b', 'v', 'c', 'x' }, \
{ ACTION_NOTHING, 'k', 'j', 'h', 'g', 'f', 'd', 's' }, \
{ ACTION_NOTHING, 'i', 'u', 'y', 't', 'r', 'e', 'w' }, \
- /**/ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'o', \
+ /**/ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'o', \
'l', ASCII_PERIOD }, \
{ ASCII_TILDE, ASCII_RT_SQUARE_BRACE, ASCII_LT_SQUARE_BRACE, '-', ':', '0', '9', '8' }, \
{ ACTION_NOTHING, '7', '6', '5', '4', '3', '2', '1' }, ASDF_TEST_MAP_DIP_SWITCHES \
@@ -77,10 +77,10 @@
{ CAPS_MATRIX_1, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, ASCII_BACKSLASH }, \
{ ACTION_NOTHING, 'P', ';', '/', ASCII_SPACE, 'Z', 'A', 'Q' }, \
- { ACTION_NOTHING, ASCII_COMMA, 'M', 'N', 'B', 'V', 'C', 'X' }, \
+ { ACTION_NOTHING, ASCII_COMMA, 'M', 'N', 'B', 'V', 'C', 'X' }, \
{ ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' }, \
{ ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' }, \
- /**/ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'O', \
+ /**/ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'O', \
'L', ASCII_PERIOD }, \
{ ASCII_TILDE, ASCII_RT_SQUARE_BRACE, ASCII_LT_SQUARE_BRACE, '-', ':', '0', '9', '8' }, \
{ ACTION_NOTHING, '7', '6', '5', '4', '3', '2', '1' }, ASDF_TEST_MAP_DIP_SWITCHES \
@@ -92,10 +92,10 @@
{ SHIFT_MATRIX_1, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, ASCII_VERT_BAR }, \
{ ACTION_NOTHING, 'P', '+', '?', ASCII_SPACE, 'Z', 'A', 'Q' }, \
- { ACTION_NOTHING, '>', 'M', 'N', 'B', 'V', 'C', 'X' }, \
+ { ACTION_NOTHING, '>', 'M', 'N', 'B', 'V', 'C', 'X' }, \
{ ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' }, \
{ ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' }, \
- { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'O', 'L', '<' }, \
+ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'O', 'L', '<' }, \
{ ASCII_TILDE, ASCII_RT_CURLY_BRACE, ASCII_LT_CURLY_BRACE, '=', '*', \
'0', ASCII_RT_PAREN, ASCII_LT_PAREN }, \
{ ACTION_NOTHING, ASCII_SINGLE_QUOTE, '&', '%', '$', '#', ASCII_DOUBLE_QUOTE, '!' }, \
@@ -109,14 +109,14 @@
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, 0x1c }, \
{ ACTION_NOTHING, ASCII_CTRL_P, ACTION_NOTHING, ACTION_NOTHING, \
ASCII_SPACE, ASCII_CTRL_Z, ASCII_CTRL_A, ASCII_CTRL_Q }, \
- { ACTION_NOTHING, ASCII_COMMA, ASCII_CTRL_M, ASCII_CTRL_N, \
- ASCII_CTRL_B, ASCII_CTRL_V, ASCII_CTRL_C, ASCII_CTRL_X }, \
+ { ACTION_NOTHING, ASCII_COMMA, ASCII_CTRL_M, ASCII_CTRL_N, \
+ ASCII_CTRL_B, ASCII_CTRL_V, ASCII_CTRL_C, ASCII_CTRL_X }, \
{ ACTION_NOTHING, ASCII_CTRL_K, ASCII_CTRL_J, ASCII_CTRL_H, \
ASCII_CTRL_G, ASCII_CTRL_F, ASCII_CTRL_D, ASCII_CTRL_S }, \
{ ACTION_NOTHING, ASCII_CTRL_I, ASCII_CTRL_U, ASCII_CTRL_Y, \
ASCII_CTRL_T, ASCII_CTRL_R, ASCII_CTRL_E, ASCII_CTRL_W }, \
- { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, \
- ASCII_LF, ASCII_CTRL_O, ASCII_CTRL_L, ACTION_NOTHING }, \
+ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, \
+ ASCII_LF, ASCII_CTRL_O, ASCII_CTRL_L, ACTION_NOTHING }, \
{ ACTION_NOTHING, 0x1d, ASCII_ESC, ACTION_NOTHING, \
ACTION_NOTHING, ACTION_FN_1, ACTION_FN_9, ACTION_FN_8 }, \
{ ACTION_NOTHING, ACTION_FN_7, ACTION_FN_6, ACTION_FN_5, \
@@ -158,31 +158,31 @@
{ \
/* Single assignment */ \
.virtual_device = VOUT1, \
- .physical_device = PHYSICAL_OUT1, \
+ .physical_device = PHYSICAL_OUT1, \
.function = V_NOFUNC, \
.initial_value = 0, \
}, \
{ \
/* single toggle */ \
.virtual_device = VOUT2, \
- .physical_device = PHYSICAL_OUT2, \
+ .physical_device = PHYSICAL_OUT2, \
.function = V_TOGGLE, \
.initial_value = 0, \
}, \
{ \
/* single pulse */ \
.virtual_device = VOUT3, \
- .physical_device = PHYSICAL_OUT3, \
- .function = V_PULSE_SHORT, \
+ .physical_device = PHYSICAL_OUT3, \
+ .function = V_PULSE_SHORT, \
.initial_value = 0, \
}, \
{ /* first of double assignment attempt */ \
.virtual_device = VOUT4, \
- .physical_device = PHYSICAL_LED1, \
+ .physical_device = PHYSICAL_LED1, \
.initial_value = 0 \
}, \
{ /* second of double assignment attempt */ \
- .virtual_device = VOUT5, .physical_device = PHYSICAL_LED1, .initial_value = 1 \
+ .virtual_device = VOUT5, .physical_device = PHYSICAL_LED1, .initial_value = 1 \
} \
}
@@ -191,23 +191,54 @@
{ \
/* Triple assignment */ \
.virtual_device = VOUT1, \
- .physical_device = PHYSICAL_OUT1, \
+ .physical_device = PHYSICAL_OUT1, \
.function = V_TOGGLE, \
.initial_value = 0, \
}, \
{ \
.virtual_device = VOUT1, \
- .physical_device = PHYSICAL_OUT2, \
+ .physical_device = PHYSICAL_OUT2, \
.function = V_TOGGLE, \
.initial_value = 1, \
}, \
{ \
- .virtual_device = VOUT1, .physical_device = PHYSICAL_OUT3, .function = V_TOGGLE, .initial_value = 0, \
+ .virtual_device = VOUT1, .physical_device = PHYSICAL_OUT3, .function = V_TOGGLE, \
+ .initial_value = 0, \
} \
}
#define ASDF_TEST_KEYMAP_INITIALIZER ASDF_TEST_KEYMAP_INITIALIZER_1, ASDF_TEST_KEYMAP_INITIALIZER_2
+#define ASDF_TEST_KEYMAP_HOOK_INITIALIZER_LENGTH 2
+
+#define ASDF_TEST_KEYMAP_HOOK_INITIALIZER_1 \
+ { \
+ { \
+ .hook_id = ASDF_HOOK_KEYMAP_SETUP, \
+ .hook_func = &test_hook_1, \
+ }, \
+ { \
+ .hook_id = ASDF_HOOK_KEYMAP_SETUP, \
+ .hook_func = &test_hook_2, \
+ }, \
+ }
+
+#define ASDF_TEST_KEYMAP_HOOK_INITIALIZER_2 \
+ { \
+ { \
+ .hook_id = ASDF_HOOK_KEYMAP_SETUP, \
+ .hook_func = &test_hook_3, \
+ }, \
+ { \
+ .hook_id = ASDF_HOOK_KEYMAP_SETUP, \
+ .hook_func = &test_hook_4, \
+ }, \
+ }
+
+#define ASDF_TEST_KEYMAP_HOOK_INITIALIZER \
+ ASDF_TEST_KEYMAP_HOOK_INITIALIZER_1, ASDF_TEST_KEYMAP_HOOK_INITIALIZER_2
+
+
// The following preprocessor "code" permits various keymaps to be created and
// included without generating a lot of complicating code dependencies. The use
// of macros in this way is a bit ugly, I realize, and stretches the intention
@@ -232,6 +263,12 @@
#define ASDF_KEYMAP_INITIALIZER_LENGTH ASDF_TEST_KEYMAP_INITIALIZER_LENGTH
#endif
+#if !defined(ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH) \
+ || (ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH < ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_LENGTH)
+#undef ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH
+#define ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_LENGTH
+#endif
+
#endif /* !defined (ASDF_KEYMAP_DEFS_TEST_H) */
//-------|---------|---------+---------+---------+---------+---------+---------+
diff --git a/firmware/asdf/src/Keymaps/asdf_keymap_defs_test2.h b/firmware/asdf/src/Keymaps/asdf_keymap_defs_test2.h
index 2e142d2..a26512d 100644
--- a/firmware/asdf/src/Keymaps/asdf_keymap_defs_test2.h
+++ b/firmware/asdf/src/Keymaps/asdf_keymap_defs_test2.h
@@ -64,10 +64,10 @@
{ PLAIN_MATRIX_2, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
ACTION_CAPS, ASCII_ESC, ACTION_CTRL, ASCII_BACKSLASH }, \
{ ACTION_NOTHING, 'p', ';', '/', ASCII_SPACE, 'z', 'a', 'q' }, \
- { ACTION_NOTHING, ASCII_COMMA, 'm', 'n', 'b', 'v', 'c', 'x' }, \
+ { ACTION_NOTHING, ASCII_COMMA, 'm', 'n', 'b', 'v', 'c', 'x' }, \
{ ACTION_NOTHING, 'k', 'j', 'h', 'g', 'f', 'd', 's' }, \
{ ACTION_NOTHING, 'i', 'u', 'y', 't', 'r', 'e', 'w' }, \
- /**/ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'o', \
+ /**/ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'o', \
'l', ASCII_PERIOD }, \
{ ASCII_TILDE, ASCII_RT_SQUARE_BRACE, ASCII_LT_SQUARE_BRACE, '-', ':', '0', '9', '8' }, \
{ ACTION_NOTHING, '7', '6', '5', '4', '3', '2', '1' }, ASDF_TEST_MAP_DIP_SWITCHES \
@@ -78,10 +78,10 @@
{ CAPS_MATRIX_2, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, ASCII_BACKSLASH }, \
{ ACTION_NOTHING, 'P', ';', '/', ASCII_SPACE, 'Z', 'A', 'Q' }, \
- { ACTION_NOTHING, ASCII_COMMA, 'M', 'N', 'B', 'V', 'C', 'X' }, \
+ { ACTION_NOTHING, ASCII_COMMA, 'M', 'N', 'B', 'V', 'C', 'X' }, \
{ ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' }, \
{ ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' }, \
- /**/ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'O', \
+ /**/ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'O', \
'L', ASCII_PERIOD }, \
{ ASCII_TILDE, ASCII_RT_SQUARE_BRACE, ASCII_LT_SQUARE_BRACE, '-', ':', '0', '9', '8' }, \
{ ACTION_NOTHING, '7', '6', '5', '4', '3', '2', '1' }, ASDF_TEST_MAP_DIP_SWITCHES \
@@ -93,10 +93,10 @@
{ SHIFT_MATRIX_2, ACTION_SHIFT, ACTION_SHIFT, ACTION_NOTHING, \
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, ASCII_VERT_BAR }, \
{ ACTION_NOTHING, 'P', '+', '?', ASCII_SPACE, 'Z', 'A', 'Q' }, \
- { ACTION_NOTHING, '>', 'M', 'N', 'B', 'V', 'C', 'X' }, \
+ { ACTION_NOTHING, '>', 'M', 'N', 'B', 'V', 'C', 'X' }, \
{ ACTION_NOTHING, 'K', 'J', 'H', 'G', 'F', 'D', 'S' }, \
{ ACTION_NOTHING, 'I', 'U', 'Y', 'T', 'R', 'E', 'W' }, \
- { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'O', 'L', '<' }, \
+ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, ASCII_LF, 'O', 'L', '<' }, \
{ ASCII_TILDE, ASCII_RT_CURLY_BRACE, ASCII_LT_CURLY_BRACE, '=', '*', \
'0', ASCII_RT_PAREN, ASCII_LT_PAREN }, \
{ ACTION_NOTHING, ASCII_SINGLE_QUOTE, '&', '%', '$', '#', ASCII_DOUBLE_QUOTE, '!' }, \
@@ -110,14 +110,14 @@
ACTION_NOTHING, ASCII_ESC, ACTION_CTRL, 0x1c }, \
{ ACTION_NOTHING, ASCII_CTRL_P, ACTION_NOTHING, ACTION_NOTHING, \
ASCII_SPACE, ASCII_CTRL_Z, ASCII_CTRL_A, ASCII_CTRL_Q }, \
- { ACTION_NOTHING, ASCII_COMMA, ASCII_CTRL_M, ASCII_CTRL_N, \
- ASCII_CTRL_B, ASCII_CTRL_V, ASCII_CTRL_C, ASCII_CTRL_X }, \
+ { ACTION_NOTHING, ASCII_COMMA, ASCII_CTRL_M, ASCII_CTRL_N, \
+ ASCII_CTRL_B, ASCII_CTRL_V, ASCII_CTRL_C, ASCII_CTRL_X }, \
{ ACTION_NOTHING, ASCII_CTRL_K, ASCII_CTRL_J, ASCII_CTRL_H, \
ASCII_CTRL_G, ASCII_CTRL_F, ASCII_CTRL_D, ASCII_CTRL_S }, \
{ ACTION_NOTHING, ASCII_CTRL_I, ASCII_CTRL_U, ASCII_CTRL_Y, \
ASCII_CTRL_T, ASCII_CTRL_R, ASCII_CTRL_E, ASCII_CTRL_W }, \
- { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, \
- ASCII_LF, ASCII_CTRL_O, ASCII_CTRL_L, ACTION_NOTHING }, \
+ { ACTION_REPEAT, ACTION_HERE_IS, ACTION_SHIFTLOCK_ON, ASCII_CR, \
+ ASCII_LF, ASCII_CTRL_O, ASCII_CTRL_L, ACTION_NOTHING }, \
{ ACTION_NOTHING, 0x1d, ASCII_ESC, ACTION_NOTHING, \
ACTION_NOTHING, ACTION_FN_1, ACTION_FN_9, ACTION_FN_8 }, \
{ ACTION_NOTHING, ACTION_FN_7, ACTION_FN_6, ACTION_FN_5, \
@@ -147,34 +147,62 @@
#define ASDF_TEST2_KEYMAPS_COUNT 2
#define ASDF_TEST2_PLAIN_MAP_INDEX (ASDF_TEST2_BASE + 0)
#define ASDF_TEST2_CAPS_MAP_INDEX (ASDF_TEST2_BASE + 1)
-
#define VCAPS_TEST_KEYMAP ASDF_TEST2_PLAIN_MAP_INDEX
#define VSHIFT_TEST_KEYMAP ASDF_TEST2_PLAIN_MAP_INDEX
#define ASDF_TEST2_KEYMAP_INITIALIZER_LENGTH 4
#define ASDF_TEST2_KEYMAP_INITIALIZER_1 \
{ \
- { .virtual_device = VCAPS_LED, .physical_device = PHYSICAL_LED1, .initial_value = 0 }, \
- { .virtual_device = VSHIFT_LED, .physical_device = PHYSICAL_LED2, .initial_value = 0 }, \
- { .virtual_device = VOUT2, .physical_device = PHYSICAL_OUT3, .initial_value = 0 }, \
+ { .virtual_device = VCAPS_LED, .physical_device = PHYSICAL_LED1, .initial_value = 0 }, \
+ { .virtual_device = VSHIFT_LED, .physical_device = PHYSICAL_LED2, .initial_value = 0 }, \
+ { .virtual_device = VOUT2, .physical_device = PHYSICAL_OUT3, .initial_value = 0 }, \
{ \
- .virtual_device = VOUT2, .physical_device = ASDF_PHYSICAL_NUM_RESOURCES, .initial_value = 0 \
+ .virtual_device = VOUT2, .physical_device = ASDF_PHYSICAL_NUM_RESOURCES, .initial_value = 0 \
} \
}
#define ASDF_TEST2_KEYMAP_INITIALIZER_2 \
{ \
- { .virtual_device = VCAPS_LED, .physical_device = PHYSICAL_LED1, .initial_value = 0 }, \
- { .virtual_device = VSHIFT_LED, .physical_device = PHYSICAL_LED2, .initial_value = 0 }, \
- { .virtual_device = VOUT2, .physical_device = PHYSICAL_OUT3, .initial_value = 0 }, \
+ { .virtual_device = VCAPS_LED, .physical_device = PHYSICAL_LED1, .initial_value = 0 }, \
+ { .virtual_device = VSHIFT_LED, .physical_device = PHYSICAL_LED2, .initial_value = 0 }, \
+ { .virtual_device = VOUT2, .physical_device = PHYSICAL_OUT3, .initial_value = 0 }, \
{ \
- .virtual_device = VOUT2, .physical_device = ASDF_PHYSICAL_NUM_RESOURCES, .initial_value = 0 \
+ .virtual_device = VOUT2, .physical_device = ASDF_PHYSICAL_NUM_RESOURCES, .initial_value = 0 \
} \
}
#define ASDF_TEST2_KEYMAP_INITIALIZER \
ASDF_TEST2_KEYMAP_INITIALIZER_1, ASDF_TEST2_KEYMAP_INITIALIZER_2
+
+#define ASDF_TEST_ALTERNATE_SCANNER_MAP (ASDF_TEST2_BASE + 0)
+#define ASDF_TEST_ALTERNATE_OUTPUT_MAP (ASDF_TEST2_BASE + 0)
+#define ASDF_TEST_EACH_SCAN_MAP (ASDF_TEST2_BASE + 1)
+#define ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_LENGTH 2
+#define ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_1 \
+ { \
+ { \
+ .hook_id = ASDF_HOOK_SCANNER, \
+ .hook_func = (asdf_hook_function_t) test_hook_read_row, \
+ }, \
+ { \
+ .hook_id = ASDF_HOOK_OUTPUT, \
+ .hook_func = (asdf_hook_function_t) test_hook_output, \
+ }, \
+ }
+
+#define ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_2 \
+ { \
+ { \
+ .hook_id = ASDF_HOOK_EACH_SCAN, \
+ .hook_func = (asdf_hook_function_t) test_hook_each_scan, \
+ }, \
+ }
+
+#define ASDF_TEST2_KEYMAP_HOOK_INITIALIZER \
+ ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_1, ASDF_TEST2_KEYMAP_HOOK_INITIALIZER_2
+
+
// The following preprocessor "code" permits various keymaps to be created and
// included without generating a lot of complicating code dependencies. The use
// of macros in this way is a bit ugly, I realize, and stretches the intention
@@ -199,6 +227,11 @@
#define ASDF_KEYMAP_INITIALIZER_LENGTH ASDF_TEST2_KEYMAP_INITIALIZER_LENGTH
#endif
+#if !defined(ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH) \
+ || (ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH < ASDF_TEST_KEYMAP_HOOK_INITIALIZER_LENGTH)
+#undef ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH
+#define ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH ASDF_TEST_KEYMAP_HOOK_INITIALIZER_LENGTH
+#endif
#endif /* !defined (ASDF_KEYMAP_DEFS_TEST2_H) */
diff --git a/firmware/asdf/src/Makefile b/firmware/asdf/src/Makefile
index 5140620..f53b351 100644
--- a/firmware/asdf/src/Makefile
+++ b/firmware/asdf/src/Makefile
@@ -1,6 +1,6 @@
# -*- makefile -*-
-ARCH ?= atmega2560
+ARCH ?= atmega328p
TARGET_KEYMAP ?= production
TARGET_MAKEFILE ?= Makefile.$(ARCH)
diff --git a/firmware/asdf/src/Makefile.atmega328p b/firmware/asdf/src/Makefile.atmega328p
index 048d0d0..9fcbe44 100644
--- a/firmware/asdf/src/Makefile.atmega328p
+++ b/firmware/asdf/src/Makefile.atmega328p
@@ -69,6 +69,7 @@ MAKEDEPEND = $(CPP) $(DEPFLAGS) $(CPPFLAGS) $< \
SRC_FILES = main.c asdf.c asdf_modifiers.c asdf_repeat.c asdf_keymaps.c
SRC_FILES += asdf_buffer.c asdf_arch.c asdf_virtual.c asdf_physical.c
+SRC_FILES += asdf_hook.c
OBJ_FILES := $(SRC_FILES:.c=.o)
DEP_FILES := $(SRC_FILES:%.c=$(DEP_DIR)/%.d)
@@ -141,8 +142,9 @@ asdf.o: asdf.c asdf.h asdf_arch.h asdf_keymaps.h asdf_config.h asdf_keymap_defs.
asdf_repeat.o: asdf_repeat.c asdf_repeat.h asdf_config.h
asdf_buffer.o: asdf_buffer.c asdf.h asdf_config.h
asdf_modifiers.o: asdf_modifiers.c asdf_modifiers.h
-asdf_virtual.o: asdf_virtual.c asdf_virtual.h asdf_arch.h asdf_physical.h
+asdf_virtual.o: asdf_virtual.c asdf_virtual.h asdf_arch.h asdf_physical.h asdf_keymap_defs.h
asdf_physical.o: asdf_physical.c asdf_virtual.h asdf_arch.h
+asdf_hook.o: asdf_hook.c asdf_hook.h asdf_arch.h asdf_keymap_defs.h
tags: $(SRC_FILES)
etags $(SRC_FILES)
diff --git a/firmware/asdf/src/Makefile.test b/firmware/asdf/src/Makefile.test
index dd56cdd..146c66e 100644
--- a/firmware/asdf/src/Makefile.test
+++ b/firmware/asdf/src/Makefile.test
@@ -55,7 +55,9 @@ TEST2_BUILD = $(BUILD_DIR)/test_$(TEST2)
TEST3 = asdf_keymaps
TEST3_SRC = $(TEST_DIR)/test_$(TEST3).c
-TEST3_DEPS = ./$(TEST3).c $(UNITY_DIR)/unity.c ./asdf_physical.c ./asdf_virtual.c ./asdf_modifiers.c ./asdf_arch.c
+TEST3_DEPS = ./$(TEST3).c $(UNITY_DIR)/unity.c ./asdf_physical.c \
+ $(TEST_DIR)/test_asdf_lib.c ./asdf_virtual.c \
+ ./asdf_hook.c ./asdf_modifiers.c ./asdf_arch.c
TEST3_BUILD = $(BUILD_DIR)/test_$(TEST3)
TEST4 = asdf_buffer
@@ -65,13 +67,16 @@ TEST4_BUILD = $(BUILD_DIR)/test_$(TEST4)
TEST5 = asdf_virtual
TEST5_SRC = $(TEST_DIR)/test_$(TEST5).c
-TEST5_DEPS = ./$(TEST5).c $(UNITY_DIR)/unity.c ./asdf_physical.c ./asdf_modifiers.c ./asdf_arch.c ./asdf_keymaps.c
+TEST5_DEPS = ./$(TEST5).c $(UNITY_DIR)/unity.c ./asdf_physical.c ./asdf_modifiers.c \
+ ./asdf_hook.c ./asdf_arch.c ./asdf_keymaps.c $(TEST_DIR)/test_asdf_lib.c
TEST5_BUILD = $(BUILD_DIR)/test_$(TEST5)
-TEST6 = asdf
-TEST6_SRC = $(TEST_DIR)/test_$(TEST6).c ./asdf_arch.c ./$(TEST1).c $(TEST2).c $(TEST3).c $(TEST4).c $(TEST5).c ./asdf_physical.c
-TEST6_DEPS = ./$(TEST6).c $(UNITY_DIR)/unity.c
-TEST6_BUILD = $(BUILD_DIR)/test_$(TEST6)
+TEST7 = asdf_hook
+TEST7_SRC = $(TEST_DIR)/test_$(TEST7).c ./asdf_arch.c $(TEST_DIR)/test_asdf_lib.c
+TEST7_DEPS = ./$(TEST7).c $(UNITY_DIR)/unity.c ./asdf_keymaps.c ./asdf.c \
+ ./asdf_modifiers.c ./asdf_buffer.c \
+ ./asdf_virtual.c ./asdf_physical.c ./asdf_repeat.c
+TEST7_BUILD = $(BUILD_DIR)/test_$(TEST7)
.SUFFIXES:
.SUFFIXES: .c .o .bin .hex
@@ -102,12 +107,13 @@ asdf_keymaps.c: asdf.h asdf_ascii.h asdf_modifiers.h asdf_arch.h asdf_keymaps.h
asdf_modifiers.c: asdf_modifiers.h asdf_arch.h asdf_keymap_defs.h
asdf_arch.h: asdf_arch.h
asdf_virtual.c: asdf_virtual.h asdf_arch.h asdf_keymap_defs.h
+asdf_hook.c: asdf_hook.h asdf_keymap_defs.h asdf_arch.h
tags: $(SRC_FILES)
etags $(SRC_FILES)
.PHONY: test
-test: test1 test2 test3 test4 test6 test5
+test: test1 test2 test3 test4 test6 test5 test7
.PHONY: test1
test1: $(TEST1_BUILD)
@@ -133,6 +139,10 @@ test5: $(TEST5_BUILD)
test6: $(TEST6_BUILD)
$(TEST6_BUILD)
+.PHONY: test7
+test7: $(TEST7_BUILD)
+ $(TEST7_BUILD)
+
$(TEST1_BUILD): $(TEST1_SRC) $(TEST1_DEPS)
$(CC) -o $@ -I. -I$(TEST_DIR) -I$(UNITY_DIR) $(CFLAGS) $(TEST1_SRC) $(TEST1_DEPS)
@@ -152,7 +162,10 @@ $(TEST5_BUILD): $(TEST5_SRC) $(TEST5_DEPS)
$(TEST6_BUILD): $(TEST6_SRC) $(TEST6_DEPS)
$(CC) -o $@ -I. -I$(TEST_DIR) -I$(UNITY_DIR) $(CFLAGS) $(TEST6_SRC) $(TEST6_DEPS)
-TEST_BUILD_FILES += $(TEST1_BUILD) $(TEST2_BUILD) $(TEST3_BUILD) $(TEST4_BUILD) $(TEST5_BUILD) $(TEST6_BUILD)
+$(TEST7_BUILD): $(TEST7_SRC) $(TEST7_DEPS)
+ $(CC) -o $@ -I. -I$(TEST_DIR) -I$(UNITY_DIR) $(CFLAGS) $(TEST7_SRC) $(TEST7_DEPS)
+
+TEST_BUILD_FILES += $(TEST1_BUILD) $(TEST2_BUILD) $(TEST3_BUILD) $(TEST4_BUILD) $(TEST5_BUILD) $(TEST6_BUILD) $(TEST7_BUILD)
CLEAN_FILES += $(TEST_BUILD_FILES) _Arch_* *.o
CLEAN_FILES += ~* *\#
diff --git a/firmware/asdf/src/asdf.c b/firmware/asdf/src/asdf.c
index f81b10f..560f9cd 100644
--- a/firmware/asdf/src/asdf.c
+++ b/firmware/asdf/src/asdf.c
@@ -41,7 +41,7 @@
#include "asdf_modifiers.h"
#include "asdf_buffer.h"
#include "asdf_arch.h"
-
+#include "asdf_hook.h"
// The key scanner keeps track of the last stable (debounced) state of each key
// in the matrix, one bit per key, 8 bits per row.
@@ -380,13 +380,13 @@ void asdf_init(void)
asdf_repeat_init(); // initialize the repeat counters
asdf_keymaps_init(); // initialize keymaps. This also initializes the modifier
// key states.
- asdf_buffer_init(); // initialize the buffers
+ asdf_buffer_init(); // initialize the buffers
// reserve a buffer for the ASCII output:
asdf_keycode_buffer = asdf_buffer_new(ASDF_KEYCODE_BUFFER_SIZE);
// Initialize all the keys to the unpressed state, and initialze the debounce
- // counters.
+ // counters.
for (uint8_t row = 0; row < ASDF_NUM_ROWS; row++) {
last_stable_key_state[row] = 0;
for (uint8_t col = 0; col < ASDF_NUM_COLS; col++) {
@@ -496,8 +496,12 @@ static void asdf_handle_key_held_pressed(uint8_t row, uint8_t col)
//
void asdf_keyscan(void)
{
+ //asdf_hook_get(ASDF_HOOK_EACH_SCAN)();
for (uint8_t row = 0; row < ASDF_NUM_ROWS; row++) {
- asdf_cols_t row_key_state = asdf_arch_read_row(row);
+ //asdf_cols_t (*row_reader)(uint8_t) =
+ //(asdf_cols_t (*) (uint8_t)) asdf_hook_get(ASDF_HOOK_SCANNER);
+ //asdf_cols_t row_key_state = (*row_reader)(row);
+
asdf_cols_t changed = row_key_state ^ last_stable_key_state[row];
// loop over the bits until all changed or pressed keys in the row are handled.
diff --git a/firmware/asdf/src/asdf_hook.c b/firmware/asdf/src/asdf_hook.c
new file mode 100644
index 0000000..1b4bc59
--- /dev/null
+++ b/firmware/asdf/src/asdf_hook.c
@@ -0,0 +1,192 @@
+// -*- mode: C; tab-width: 2 ; indent-tabs-mode: nil -*-
+//
+// Unified Keyboard Project
+// ASDF keyboard firmware
+//
+// asdf_hook.c
+//
+// This file contains code to allow function "hooks" to be specified in the
+// keymap files, so that the keymap can determine the handline of certain
+// functions, such as keyboard scanner, output (parallel, serial, USB, etc.),
+// keyboard setup (e.g., set capslock or emulate other keypresses), or specify
+// functions to be run at every keyscan. The keyboard logic code access the
+// functionality via the hooks module rather than directly calling scanning
+// functions, etc.
+//
+// Copyright 2019 David Fenyes
+//
+// 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 3 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 .
+//
+
+#include
+#include
+#include "asdf_arch.h"
+#include "asdf_hook.h"
+#include "asdf_keymap_defs.h"
+
+
+
+
+// hooks_table[] contains all the function hooks. The entry for each ID contains
+// a pointer to the first in the list of functions (if any) assigned to the hook
+// ID.
+asdf_hook_function_t hook_map[ASDF_NUM_HOOKS];
+
+// PROCEDURE: asdf_hook_null_func
+// INPUTS: none
+// OUTPUTS: none
+//
+// DESCRIPTION: dummy function, default hook for all but output and scanner.
+//
+// SIDE EFFECTS: none
+//
+// NOTES:
+//
+// SCOPE: private
+//
+// COMPLEXITY: 1
+//
+void asdf_hook_null_func(void) {}
+
+
+// PROCEDURE: asdf_hook_valid_id
+// INPUTS: (asdf_hook_id_t) hook_it: ID of the hook to be tested
+// OUTPUTS: returns true (1) if the hook ID is valid, false (0) if not valid.
+//
+// DESCRIPTION: test to see if hooks ID is valid (i.e., within the valid range)
+//
+// SIDE EFFECTS: none
+//
+// NOTES:
+//
+// SCOPE: private
+//
+// COMPLEXITY: 1
+//
+static uint8_t asdf_hook_valid_id(asdf_hook_id_t id)
+{
+ return (id < ASDF_NUM_HOOKS);
+}
+
+// PROCEDURE: asdf_hook_do
+// INPUTS: (asdf_hook_id_t) hook_id: The hook for which to execute the attached
+// function.
+//
+// OUTPUTS: none
+
+// DESCRIPTION: if the hook ID is valid, then execute the function attached to the hook.
+//
+// SIDE EFFECTS: variable depending on the hooks.
+//
+// NOTES:
+//
+// SCOPE: public
+//
+// COMPLEXITY: 2
+//
+void asdf_hook_do(asdf_hook_id_t hook_id)
+{
+ if (asdf_hook_valid_id(hook_id)) {
+ hook_map[hook_id]();
+ }
+}
+
+// PROCEDURE: asdf_hook_get
+// INPUTS: (asdf_hook_id_t) hook_id: The hook for which to retrieve the attached
+// function.
+// OUTPUTS: none
+
+// DESCRIPTION: if the hook ID is valid, then retrieve the function attached to the hook.
+//
+// SIDE EFFECTS: variable depending on the hooks.
+//
+// NOTES:
+//
+// SCOPE: public
+//
+// COMPLEXITY: 2
+//
+asdf_hook_function_t asdf_hook_get(asdf_hook_id_t hook_id)
+{
+ return asdf_hook_valid_id(hook_id) ? hook_map[hook_id] : asdf_hook_null_func;
+}
+
+// PROCEDURE: asdf_hook_assign
+// INPUTS: (asdf_hook_id_t) hook_id: The hook for which to execute attache functions.
+// (asdf_hook_function_t) func: function to be attached to the hook.
+//
+// OUTPUTS: none
+//
+// DESCRIPTION: If the hook ID is valid, map the function to the hook ID.
+// Ignore if not valid.
+//
+// SIDE EFFECTS: see above.
+//
+// NOTES:
+//
+// SCOPE: private
+//
+// COMPLEXITY: 2
+//
+static void asdf_hook_assign(asdf_hook_id_t hook_id, asdf_hook_function_t func)
+{
+ if (asdf_hook_valid_id(hook_id)) {
+ hook_map[hook_id] = func;
+ }
+}
+
+// PROCEDURE: asdf_hook_init
+// INPUTS: (asdf_hook_initializer_t *) initializer_list - contains the hook
+// initializer list for the selected keymap.
+//
+// OUTPUTS: none
+//
+// DESCRIPTION: Initializes function hooks for the selected keymap. If a
+// function is assigned to the "KEYMAP_SETUP" hook, then execute the function.
+// There is no actual slot where KEYMAP_SETUP functions are stored.
+//
+// SIDE EFFECTS: see above
+//
+// NOTES:
+//
+// SCOPE: public
+//
+// COMPLEXITY: 4
+//
+void asdf_hook_init(asdf_hook_initializer_t *const initializer_list)
+{
+
+ // initialize hooks to NULL
+ for (uint8_t i = 0; i < ASDF_NUM_HOOKS; i++) {
+ hook_map[i] = asdf_hook_null_func;
+ }
+
+ hook_map[ASDF_HOOK_SCANNER] = (asdf_hook_function_t) ASDF_ARCH_DEFAULT_SCANNER;
+ hook_map[ASDF_HOOK_OUTPUT] = (asdf_hook_function_t) ASDF_ARCH_DEFAULT_OUTPUT;
+
+ // run through the keymap specific setup
+ for (uint8_t i = 0; i < ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH; i++) {
+ asdf_hook_id_t id = initializer_list[i].hook_id;
+
+ if (ASDF_HOOK_KEYMAP_SETUP == id) {
+ initializer_list[i].hook_func();
+ }
+ else {
+ asdf_hook_assign(initializer_list[i].hook_id, initializer_list[i].hook_func);
+ }
+ }
+}
+
+//-------|---------|---------+---------+---------+---------+---------+---------+
+// Above line is 80 columns, and should display completely in the editor.
diff --git a/firmware/asdf/src/asdf_hook.h b/firmware/asdf/src/asdf_hook.h
new file mode 100644
index 0000000..da92b93
--- /dev/null
+++ b/firmware/asdf/src/asdf_hook.h
@@ -0,0 +1,77 @@
+// -*- mode: C; tab-width: 4 ; indent-tabs-mode: nil -*-
+//
+// Unfified Keyboard Project
+// ASDF keyboard firmware
+//
+// asdf_hook.h
+//
+// Definitions and prototypes for configurable function hooks
+//
+// Copyright 2019 David Fenyes
+// 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 3 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 .
+//
+
+#if !defined(ASDF_HOOKS_H)
+#define ASDF_HOOKS_H
+
+// These are "hooks" output identifiers that can be mapped to the real outputs using
+// keymap initializer commands.
+typedef enum {
+ ASDF_HOOK_SCANNER,
+ ASDF_HOOK_OUTPUT,
+ ASDF_HOOK_EACH_SCAN,
+ ASDF_NUM_HOOKS,
+} asdf_hook_id_t;
+
+#define ASDF_HOOK_KEYMAP_SETUP ASDF_NUM_HOOKS
+
+// Each keymap specifies an array of initializer structs to configure function hooks,
+// specifying the hook ID and mapped function.
+
+typedef void (*asdf_hook_function_t)(void);
+
+typedef struct {
+ asdf_hook_id_t hook_id;
+ asdf_hook_function_t hook_func;
+} asdf_hook_initializer_t;
+
+
+// PROCEDURE: asdf_hook_do
+// INPUTS: (asdf_hook_id_t) hook_id: The hook for which to execute attache functions.
+// OUTPUTS: none
+// DESCRIPTION: if the hook ID is valid, then execute the function attached to the hook.
+// SIDE EFFECTS: variable depending on the hooks.
+void asdf_hook_do(asdf_hook_id_t hook_id);
+
+// PROCEDURE: asdf_hook_get
+// INPUTS: (asdf_hook_id_t) hook_id: The hook for which to retrieve the attached
+// function.
+// OUTPUTS: none
+// DESCRIPTION: if the hook ID is valid, then retrieve the function attached to the hook.
+// SIDE EFFECTS: none
+asdf_hook_function_t asdf_hook_get(asdf_hook_id_t hook_id);
+
+// PROCEDURE: asdf_hook_init
+// INPUTS: (asdf_hook_initializer_t *) initializer_list - contains the hook
+// initializer list for the selected keymap.
+// OUTPUTS: none
+// DESCRIPTION: Initializes function hooks for the selected keymap. If a
+// function is assigned to the "KEYMAP_SETUP" hook, then execute the function.
+// There is no actual slot where KEYMAP_SETUP functions are stored.
+void asdf_hook_init(asdf_hook_initializer_t *const initializer_list);
+
+#endif /* !defined (ASDF_HOOKS_H) */
+
+//-------|---------|---------+---------+---------+---------+---------+---------+
+// Above line is 80 columns, and should display completely in the editor.
diff --git a/firmware/asdf/src/asdf_keymaps.c b/firmware/asdf/src/asdf_keymaps.c
index d6368b3..a6b1f5e 100644
--- a/firmware/asdf/src/asdf_keymaps.c
+++ b/firmware/asdf/src/asdf_keymaps.c
@@ -25,6 +25,7 @@
#include "asdf_arch.h"
#include "asdf_physical.h"
#include "asdf_virtual.h"
+#include "asdf_hook.h"
#include "asdf_keymaps.h"
#include "asdf_keymap_defs.h"
@@ -50,14 +51,20 @@ static keycode_matrix_t const *keymap_matrix[ASDF_NUM_KEYMAPS][ASDF_MOD_NUM_MODI
// Each keymap (representing a keyboard configuration) has an associated set of
-// keyboard initializers that set up the I/O and LED lines for the keyboard, and
-// other configuration unique to the keyboard defined by the map. This builds
-// the keymap initializer array from the initializer definitions in the keymap
-// definitino files.
+// virtual device initializers that set up the I/O and LED lines for the
+// keyboard, unique to each keymap. This builds the virtual device initializer
+// array from the initializer definitions in the keymap definition files.
static const asdf_virtual_initializer_t keymap_initializer_list[ASDF_NUM_KEYMAPS]
[ASDF_KEYMAP_INITIALIZER_LENGTH] =
ASDF_KEYMAP_INITIALIZERS;
+// Each keymap (representing a keyboard configuration) has an associated set of
+// function hooks unique to the keyboard defined by the map. This builds the
+// function hook initializer array from the definitions in the keymap definition
+// files.
+static const asdf_hook_initializer_t keymap_hook_initializer_list[ASDF_NUM_KEYMAPS] [ASDF_KEYMAP_HOOK_INITIALIZER_LENGTH] =
+ ASDF_KEYMAP_HOOK_INITIALIZERS;
+
// Index of the currently active keymap, initialized to zero in the init
// routine.
static uint8_t keymap_index;
@@ -86,6 +93,7 @@ void asdf_keymaps_select_keymap(uint8_t index)
if (index < ASDF_NUM_KEYMAPS) {
keymap_index = index;
asdf_virtual_init((asdf_virtual_initializer_t *const) keymap_initializer_list[keymap_index]);
+ asdf_hook_init((asdf_hook_initializer_t *const) keymap_hook_initializer_list[keymap_index]);
asdf_modifiers_init();
}
}
diff --git a/firmware/asdf/src/asdf_physical.c b/firmware/asdf/src/asdf_physical.c
index ec557b1..52c7d1e 100644
--- a/firmware/asdf/src/asdf_physical.c
+++ b/firmware/asdf/src/asdf_physical.c
@@ -204,7 +204,7 @@ asdf_physical_dev_t asdf_physical_next_device(asdf_physical_dev_t device)
}
// PROCEDURE: asdf_physical_allocate
-
+//
// INPUTS: (asdf_physical_out_t) physical_out - the desired physical resource to allocate.
// (asdf_physical_out_t) tail - the list of physical resources to tack on
// to the requested resource, if available.
diff --git a/firmware/asdf/src/main.c b/firmware/asdf/src/main.c
index da28aa4..4369e9e 100644
--- a/firmware/asdf/src/main.c
+++ b/firmware/asdf/src/main.c
@@ -26,6 +26,7 @@
#include "asdf.h"
#include "asdf_arch.h"
#include "asdf_buffer.h"
+#include "asdf_hook.h"
// PROCEDURE: main
// INPUTS: none
@@ -72,8 +73,10 @@ int main(void)
if (code != ASDF_INVALID_CODE) {
asdf_arch_send_code(code);
+ // void (*output_function)(asdf_keycode_t) =
+ // (void (*)(asdf_keycode_t)) asdf_hook_get(ASDF_HOOK_OUTPUT);
+ //(*output_function)(code);
}
-
asdf_keyscan();
}
}
diff --git a/firmware/asdf/test/test_asdf_hook.c b/firmware/asdf/test/test_asdf_hook.c
new file mode 100644
index 0000000..56b822c
--- /dev/null
+++ b/firmware/asdf/test/test_asdf_hook.c
@@ -0,0 +1,111 @@
+#include
+#include
+#include
+
+#include "unity.h"
+#include "asdf.h"
+#include "asdf_arch.h"
+#include "asdf_ascii.h"
+#include "asdf_modifiers.h"
+#include "asdf_keymaps.h"
+#include "asdf_keymap_defs.h"
+#include "asdf_buffer.h"
+#include "asdf_repeat.h"
+#include "asdf_hook.h"
+#include "test_asdf_lib.h"
+
+//ASDF_TEST_DECLARATIONS;
+
+// emulates arch_read_row function, used mainly to see that the read_row hook is
+// getting called.
+asdf_cols_t asdf_arch_read_row(uint8_t row)
+{
+ return (asdf_keycode_t) (row + 1);
+}
+
+
+void setUp(void)
+{
+ test_hook_clear();
+ asdf_keymaps_init();
+ asdf_init();
+}
+
+void tearDown(void) {}
+
+
+typedef asdf_cols_t (*scanner_func_t)(uint8_t);
+
+void test_default_scan_hook_is_default_scanner(void)
+{
+ scanner_func_t testfunc = (scanner_func_t) asdf_hook_get(ASDF_HOOK_SCANNER);
+ asdf_cols_t testval = 0;
+
+ // make sure the pointer points to the correct function
+ TEST_ASSERT_EQUAL_PTR(testfunc, &asdf_arch_read_row);
+
+ // Now try calling the function
+ testval = (*testfunc)(100);
+ TEST_ASSERT_EQUAL_INT((int) asdf_arch_read_row(100), (int) testval);
+}
+
+// test_alternate_scan_hook
+void test_alternate_scan_hook(void)
+{
+ asdf_keymaps_select_keymap(ASDF_TEST_ALTERNATE_SCANNER_MAP);
+ scanner_func_t testfunc = (scanner_func_t) asdf_hook_get(ASDF_HOOK_SCANNER);
+ asdf_cols_t testval = 0;
+
+ // make sure the pointer points to the correct function
+ TEST_ASSERT_EQUAL_PTR(testfunc, &test_hook_read_row);
+
+ // Now try calling the function
+ testval = (*testfunc)(100);
+ TEST_ASSERT_EQUAL_INT((int) test_hook_read_row(100), (int) testval);
+}
+
+#define NUM_SCAN_TEST_REPS 101
+
+void test_each_scan_hook_is_executed_each_scan(void)
+{
+
+ test_hook_clear();
+ asdf_keymaps_select_keymap(ASDF_TEST_EACH_SCAN_MAP);
+ TEST_ASSERT_EQUAL_INT(0, test_hook_readback());
+ for (int i = 0; i < NUM_SCAN_TEST_REPS; i++) {
+ asdf_keyscan();
+ }
+ TEST_ASSERT_EQUAL_INT(NUM_SCAN_TEST_REPS, test_hook_readback());
+}
+
+// Check that setup hooks are executed immediately
+void test_setup_hook_is_executed_immediately(void)
+{
+ test_hook_clear();
+ asdf_keymaps_select_keymap(0);
+ uint32_t expected = TEST_HOOK_VAL1 | TEST_HOOK_VAL2;
+ TEST_ASSERT_EQUAL_INT(expected, test_hook_readback());
+}
+
+// Check that setup hooks are executed properly after selecting nonzero map
+void test_setup_hook_is_executed_immediately_when_selecting_nonzero_map(void)
+{
+ test_hook_clear();
+ asdf_keymaps_select_keymap(1);
+ uint32_t expected = TEST_HOOK_VAL3 | TEST_HOOK_VAL4;
+ TEST_ASSERT_EQUAL_INT(expected, test_hook_readback());
+}
+
+
+
+
+int main(void)
+{
+ UNITY_BEGIN();
+ RUN_TEST(test_default_scan_hook_is_default_scanner);
+ RUN_TEST(test_alternate_scan_hook);
+ RUN_TEST(test_setup_hook_is_executed_immediately);
+ RUN_TEST(test_setup_hook_is_executed_immediately_when_selecting_nonzero_map);
+ RUN_TEST(test_each_scan_hook_is_executed_each_scan);
+ return UNITY_END();
+}
diff --git a/firmware/asdf/test/test_asdf_keymaps.c b/firmware/asdf/test/test_asdf_keymaps.c
index 6c21371..a6623e2 100644
--- a/firmware/asdf/test/test_asdf_keymaps.c
+++ b/firmware/asdf/test/test_asdf_keymaps.c
@@ -82,15 +82,6 @@ static coord_t alpha_sample;
static coord_t num_sample;
static coord_t keymap_tag;
-uint32_t max(uint8_t first, uint8_t second)
-{
- uint32_t max = first;
- if (second > max) {
- max = second;
- }
- return max;
-}
-
coord_t *find_code(asdf_keycode_t code)
{
uint32_t done = 0;
@@ -148,6 +139,12 @@ void complicated_set_keymap(uint8_t mapnum)
}
}
+// dummy function, to resolve reference in keymap hook initialization.
+asdf_cols_t asdf_arch_read_row(uint8_t row)
+{
+ return (asdf_cols_t) (row+1);
+}
+
// the next two test check the preprocessor mechanism for allocating space for
// the largest defined keymap
diff --git a/firmware/asdf/test/test_asdf_lib.c b/firmware/asdf/test/test_asdf_lib.c
new file mode 100644
index 0000000..80d9612
--- /dev/null
+++ b/firmware/asdf/test/test_asdf_lib.c
@@ -0,0 +1,68 @@
+#include
+#include "asdf.h"
+#include "asdf_keymaps.h"
+#include "asdf_keymap_defs.h"
+#include "asdf_arch.h"
+#include "asdf_hook.h"
+#include "test_asdf_lib.h"
+
+uint32_t hook_register;
+
+uint32_t max(uint8_t first, uint8_t second)
+{
+ uint32_t max = first;
+ if (second > max) {
+ max = second;
+ }
+ return max;
+}
+
+void test_hook_clear(void)
+{
+ hook_register = 0;
+}
+
+uint32_t test_hook_readback(void)
+{
+ return hook_register;
+}
+
+void test_hook_1(void)
+{
+ hook_register |= TEST_HOOK_VAL1;
+}
+
+void test_hook_2(void)
+{
+ hook_register |= TEST_HOOK_VAL2;
+}
+
+void test_hook_3(void)
+{
+ hook_register |= TEST_HOOK_VAL3;
+}
+
+void test_hook_4(void)
+{
+ hook_register |= TEST_HOOK_VAL4;
+}
+
+void test_hook_5(void)
+{
+ hook_register |= TEST_HOOK_VAL5;
+}
+
+uint8_t test_hook_read_row(uint8_t val)
+{
+ return (uint8_t) val+2;
+}
+
+void test_hook_output(uint8_t val)
+{
+ hook_register = val;
+}
+
+void test_hook_each_scan(void)
+{
+ hook_register++;
+}
diff --git a/firmware/asdf/test/test_asdf_lib.h b/firmware/asdf/test/test_asdf_lib.h
new file mode 100644
index 0000000..45fb05f
--- /dev/null
+++ b/firmware/asdf/test/test_asdf_lib.h
@@ -0,0 +1,23 @@
+#if !defined(TEST_ASDF_LIB_H)
+
+#define TEST_HOOK_VAL1 1
+#define TEST_HOOK_VAL2 2
+#define TEST_HOOK_VAL3 4
+#define TEST_HOOK_VAL4 8
+#define TEST_HOOK_VAL5 16
+
+uint32_t max(uint8_t first, uint8_t second);
+void test_hook_clear(void);
+uint32_t test_hook_readback(void);
+void test_hook_1(void);
+void test_hook_2(void);
+void test_hook_3(void);
+void test_hook_4(void);
+void test_hook_5(void);
+void test_hook_each_scan(void);
+uint8_t test_hook_read_row(uint8_t val);
+void test_hook_output(uint8_t val);
+
+
+#define TEST_ASDF_LIB_H
+#endif // if !defined(TEST_ASDF_LIB_H)
diff --git a/firmware/asdf/test/test_asdf_virtual.c b/firmware/asdf/test/test_asdf_virtual.c
index 58eefd8..d281dc9 100644
--- a/firmware/asdf/test/test_asdf_virtual.c
+++ b/firmware/asdf/test/test_asdf_virtual.c
@@ -8,18 +8,10 @@
#include "asdf_keymaps.h"
#include "asdf_keymap_defs.h"
#include "asdf_config.h"
+#include "test_asdf_lib.h"
-uint32_t max(uint8_t first, uint8_t second)
-{
- uint32_t max = first;
- if (second > max) {
- max = second;
- }
- return max;
-}
-
void setUp(void)
{
asdf_arch_init();
@@ -28,6 +20,11 @@ void setUp(void)
void tearDown(void) {}
+// needed for keymap.
+asdf_cols_t asdf_arch_read_row(uint8_t row)
+{
+ return (asdf_cols_t) row;
+}
// check to see that the longest keymap initializer sequence initia is detected.
void test_inizializer_length_is_max_length(void)