diff --git a/firmware/asdf/src/Arch/asdf_arch_atmega328p.c b/firmware/asdf/src/Arch/asdf_arch_atmega328p.c
index 6434c63..9b87545 100644
--- a/firmware/asdf/src/Arch/asdf_arch_atmega328p.c
+++ b/firmware/asdf/src/Arch/asdf_arch_atmega328p.c
@@ -243,7 +243,8 @@ void asdf_arch_led1_set(uint8_t value)
{
if (value) {
clear_bit(&ASDF_LED1_PORT, ASDF_LED1_BIT);
- } else {
+ }
+ else {
set_bit(&ASDF_LED1_PORT, ASDF_LED1_BIT);
}
}
@@ -267,7 +268,8 @@ void asdf_arch_led2_set(uint8_t value)
{
if (value) {
set_bit(&ASDF_LED2_PORT, ASDF_LED2_BIT);
- } else {
+ }
+ else {
clear_bit(&ASDF_LED2_PORT, ASDF_LED2_BIT);
}
}
@@ -291,7 +293,8 @@ void asdf_arch_led3_set(uint8_t value)
{
if (value) {
set_bit(&ASDF_LED3_PORT, ASDF_LED3_BIT);
- } else {
+ }
+ else {
clear_bit(&ASDF_LED3_PORT, ASDF_LED3_BIT);
}
}
@@ -314,7 +317,8 @@ void asdf_arch_out1_set(uint8_t value)
{
if (value) {
set_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
- } else {
+ }
+ else {
clear_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
}
set_bit(&ASDF_OUT1_DDR, ASDF_OUT1_BIT);
@@ -339,7 +343,8 @@ void asdf_arch_out1_hi_z_set(uint8_t value)
if (value) {
clear_bit(&ASDF_OUT1_DDR, ASDF_OUT1_BIT);
set_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
- } else {
+ }
+ else {
clear_bit(&ASDF_OUT1_PORT, ASDF_OUT1_BIT);
set_bit(&ASDF_OUT1_DDR, ASDF_OUT1_BIT);
}
@@ -353,7 +358,8 @@ void asdf_arch_out1_hi_z_set(uint8_t value)
//
// SIDE EFFECTS: See above.
//
-// NOTES: OUT2 is inverted by the 7404 buffer, so clearing the bit sets the output high. OUT2 cannot be high impedance.
+// NOTES: OUT2 is inverted by the 7404 buffer, so clearing the bit sets the output high. OUT2
+// cannot be high impedance.
//
// SCOPE: public
//
@@ -363,12 +369,51 @@ void asdf_arch_out2_set(uint8_t value)
{
if (value) {
clear_bit(&ASDF_OUT2_PORT, ASDF_OUT1_BIT);
- } else {
+ }
+ else {
set_bit(&ASDF_OUT2_PORT, ASDF_OUT1_BIT);
}
set_bit(&ASDF_OUT2_DDR, ASDF_OUT2_BIT);
}
+// PROCEDURE: asdf_arch_null_output
+// INPUTS: (uint8_t) value - ignored
+// OUTPUTS: none
+//
+// DESCRIPTION: Does nothing.
+//
+// SIDE EFFECTS: See above.
+//
+// NOTES:
+//
+// SCOPE: public
+//
+// COMPLEXITY: 2
+//
+void asdf_arch_null_output(uint8_t value)
+{
+ (void) value;
+}
+
+// PROCEDURE: asdf_arch_out2_hi_z_set
+// INPUTS: (uint8_t) value
+// OUTPUTS: none
+//
+// DESCRIPTION: Sets the OUT2 bit to hi-z if value is true, and low if value is false.
+//
+// SIDE EFFECTS: See above.
+//
+// NOTES: Not supported for the ATMega-328 ASCII interface.
+//
+// SCOPE: public
+//
+// COMPLEXITY: 2
+//
+void asdf_arch_out2_hi_z_set(uint8_t value)
+{
+ asdf_arch_null_output(value);
+}
+
// PROCEDURE: asdf_arch_out3_set
// INPUTS: (uint8_t) value
// OUTPUTS: none
@@ -387,7 +432,8 @@ void asdf_arch_out3_set(uint8_t value)
{
if (value) {
set_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
- } else {
+ }
+ else {
clear_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
}
set_bit(&ASDF_OUT3_DDR, ASDF_OUT3_BIT);
@@ -412,7 +458,8 @@ void asdf_arch_out3_hi_z_set(uint8_t value)
if (value) {
clear_bit(&ASDF_OUT3_DDR, ASDF_OUT3_BIT);
set_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
- } else {
+ }
+ else {
clear_bit(&ASDF_OUT3_PORT, ASDF_OUT3_BIT);
set_bit(&ASDF_OUT3_DDR, ASDF_OUT3_BIT);
}
@@ -508,50 +555,68 @@ static void asdf_arch_init_row_outputs(void)
ASDF_ROW_DDR |= ASDF_ROW_MASK;
}
+// PROCEDURE: asdf_arch_pulse_delay
+// INPUTS: none
+// OUTPUTS: none
+//
+// DESCRIPTION: Delays a fixed amount of time for keyboard output pulses.
+//
+// SIDE EFFECTS: see above.
+//
+// NOTES: Set ASDF_PULSE_DELAY_US in asdf_config.h
+//
+// SCOPE: public
+//
+// COMPLEXITY: 1
+//
+void asdf_arch_pulse_delay(void)
+{
+ _delay_us(ASDF_PULSE_DELAY_US);
+}
- // PROCEDURE: asdf_arch_init
- // INPUTS: none
- // OUTPUTS: none
- //
- // DESCRIPTION: sets up all the hardware for the keyboard
- //
- // SIDE EFFECTS: see DESCRIPTION
- //
- // SCOPE: public
- //
- // COMPLEXITY: 1
- //
- void asdf_arch_init(void)
- {
- // disable interrupts:
- cli();
+// PROCEDURE: asdf_arch_init
+// INPUTS: none
+// OUTPUTS: none
+//
+// DESCRIPTION: sets up all the hardware for the keyboard
+//
+// SIDE EFFECTS: see DESCRIPTION
+//
+// SCOPE: public
+//
+// COMPLEXITY: 1
+//
+void asdf_arch_init(void)
+{
+ // disable interrupts:
+ cli();
- // clear the 1ms timer flag;
- tick = 0;
+ // clear the 1ms timer flag;
+ tick = 0;
- // set up timers for 1 msec intervals
- asdf_arch_init_clock();
- asdf_arch_tick_timer_init();
+ // set up timers for 1 msec intervals
+ asdf_arch_init_clock();
+ asdf_arch_tick_timer_init();
- // set up ASCII output port
- asdf_arch_init_ascii_output();
+ // set up ASCII output port
+ asdf_arch_init_ascii_output();
- // initialize keyboard data and strobe to positive polairy
- data_polarity = ASDF_DEFAULT_DATA_POLARITY;
- strobe_polarity = ASDF_DEFAULT_STROBE_POLARITY;
+ // initialize keyboard data and strobe to positive polairy
+ data_polarity = ASDF_DEFAULT_DATA_POLARITY;
+ strobe_polarity = ASDF_DEFAULT_STROBE_POLARITY;
- asdf_arch_init_strobe();
- asdf_arch_init_leds();
+ asdf_arch_init_strobe();
+ asdf_arch_init_leds();
- // set up row output port
- asdf_arch_init_row_outputs();
+ // set up row output port
+ asdf_arch_init_row_outputs();
- // set up column control lines
- asdf_arch_init_column_control();
+ // set up column control lines
+ asdf_arch_init_column_control();
- // enable interrupts:
- sei();
- }
+ // enable interrupts:
+ sei();
+}
// PROCEDURE: asdf_arch_read_row
diff --git a/firmware/asdf/src/Arch/asdf_arch_atmega328p.h b/firmware/asdf/src/Arch/asdf_arch_atmega328p.h
index f3448b7..756f45e 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
+// PROCEDURE: asdf_arch_null_output
+// INPUTS: (uint8_t) value - ignored
+// OUTPUTS: none
+// DESCRIPTION: null/dummy output function
+// NOTES: Not supported for the ATMega-328 ASCII interface.
+void asdf_arch_null_output(uint8_t value);
+
// PROCEDURE: asdf_arch_led1_set
// INPUTS: (uint8_t) value
// OUTPUTS: none
@@ -290,6 +297,14 @@ void asdf_arch_out2_set(uint8_t value);
// DESCRIPTION: Sets the OUT3 bit if value is true, and clear OUT3 if value is false.
void asdf_arch_out3_set(uint8_t value);
+// PROCEDURE: asdf_arch_out2_hi_z_set
+// INPUTS: (uint8_t) value
+// OUTPUTS: none
+// DESCRIPTION: Sets the OUT2 bit to hi-z if value is true, and low if value is false.
+// NOTES: Not supported for the ATMega-328 ASCII interface.
+void asdf_arch_out2_hi_z_set(uint8_t value);
+
+
// PROCEDURE: asdf_arch_out3_hi_z_set
// INPUTS: (uint8_t) value
// OUTPUTS: none
@@ -304,6 +319,13 @@ void asdf_arch_out3_hi_z_set(uint8_t value);
// pressed within the row, with 1=pressed, 0=released.
asdf_cols_t asdf_arch_read_row(uint8_t row);
+// PROCEDURE: asdf_arch_pulse_delay
+// INPUTS: none
+// OUTPUTS: none
+// DESCRIPTION: Delays a fixed amount of time for keyboard output pulses.
+// NOTES: Set ASDF_PULSE_DELAY_US in asdf_config.h
+void asdf_arch_pulse_delay(void);
+
// PROCEDURE: asdf_arch_tick
// INPUTS: none
// OUTPUTS: returns a 1 if the 1ms timer timed out, 0 otherwise
diff --git a/firmware/asdf/src/Arch/asdf_arch_test.c b/firmware/asdf/src/Arch/asdf_arch_test.c
index 27ddb5d..f2474b9 100644
--- a/firmware/asdf/src/Arch/asdf_arch_test.c
+++ b/firmware/asdf/src/Arch/asdf_arch_test.c
@@ -39,10 +39,154 @@
#include "asdf_config.h"
#include "asdf_virtual.h"
#include "asdf_arch.h"
-// this is to get rid of "unused variable" warnings.
-volatile static uint32_t junk_variable;
+typedef enum {
+ INITIAL_STATE,
+ STABLE_LOW,
+ STABLE_HIGH,
+ TRANSITION_LOW,
+ TRANSITION_HIGH,
+ PULSE_DELAY_LOW,
+ PULSE_DELAY_HIGH,
+ PULSE_HIGH_DETECTED,
+ PULSE_LOW_DETECTED,
+ NUM_VALID_PULSE_STATES, // error states below this
+ ERROR_DOUBLE_DELAY,
+ ERROR_DOUBLE_SET,
+ ERROR_NO_TRANSITION_BEFORE_DELAY,
+ ERROR_NO_TRANSITION_AFTER_DELAY,
+ ERROR_DOUBLE_TRANSITION, // fast pulse without delay
+ ERROR_DOUBLE_PULSE,
+} pulse_state_t;
+
+typedef enum { SET_HIGH, SET_LOW, PULSE_DELAY, NUM_PULSE_STATE_INPUTS } pulse_state_event_t;
+
+static pulse_state_t pulse_transition_table[NUM_VALID_PULSE_STATES][NUM_PULSE_STATE_INPUTS] =
+ {
+ [STABLE_LOW] =
+ {
+ [SET_HIGH] = TRANSITION_HIGH,
+ [SET_LOW] = ERROR_DOUBLE_SET,
+ [PULSE_DELAY] = ERROR_NO_TRANSITION_BEFORE_DELAY,
+ },
+ [STABLE_HIGH] =
+ {
+ [SET_HIGH] = ERROR_DOUBLE_SET,
+ [SET_LOW] = TRANSITION_LOW,
+ [PULSE_DELAY] = ERROR_NO_TRANSITION_BEFORE_DELAY,
+ },
+ [TRANSITION_LOW] =
+ {
+ [SET_HIGH] = ERROR_DOUBLE_TRANSITION,
+ [SET_LOW] = ERROR_DOUBLE_SET,
+ [PULSE_DELAY] = PULSE_DELAY_LOW,
+ },
+ [TRANSITION_HIGH] =
+ {
+ [SET_HIGH] = ERROR_DOUBLE_SET,
+ [SET_LOW] = ERROR_DOUBLE_TRANSITION,
+ [PULSE_DELAY] = PULSE_DELAY_HIGH,
+ },
+ [PULSE_DELAY_LOW] =
+ {
+ [SET_HIGH] = PULSE_LOW_DETECTED,
+ [SET_LOW] = ERROR_NO_TRANSITION_AFTER_DELAY,
+ [PULSE_DELAY] = ERROR_DOUBLE_PULSE,
+ },
+ [PULSE_DELAY_HIGH] =
+ {
+ [SET_HIGH] = ERROR_NO_TRANSITION_AFTER_DELAY,
+ [SET_LOW] = PULSE_HIGH_DETECTED,
+ [PULSE_DELAY] = ERROR_DOUBLE_PULSE,
+ },
+ [PULSE_HIGH_DETECTED] =
+ {
+ [SET_HIGH] = STABLE_HIGH,
+ [SET_LOW] = STABLE_LOW,
+ [PULSE_DELAY] = ERROR_NO_TRANSITION_BEFORE_DELAY
+ },
+ [PULSE_LOW_DETECTED] =
+ {
+ [SET_HIGH] = STABLE_HIGH,
+ [SET_LOW] = STABLE_LOW,
+ [PULSE_DELAY] = ERROR_NO_TRANSITION_BEFORE_DELAY
+ },
+ };
+
static uint8_t outputs[NUM_REAL_OUTPUTS];
+static pulse_state_t pulses[NUM_REAL_OUTPUTS];
+
+// PROCEDURE: asdf_arch_null_output
+// INPUTS: (uint8_t) value - ignored
+// OUTPUTS: none
+//
+// DESCRIPTION: Does nothing.
+//
+// SIDE EFFECTS: See above.
+//
+// NOTES:
+//
+// SCOPE: public
+//
+// COMPLEXITY: 2
+//
+void asdf_arch_null_output(uint8_t value)
+{
+ (void) value;
+}
+
+// PROCEDURE: pulse_detect
+// INPUTS: (pulse_state_t) current_state
+// (pulse_event_t) event - current input to the state machine
+// OUTPUTS: returns new pulse detector state for the output.
+//
+// DESCRIPTION: Given an output and a new value for the output, calculate the
+// next state of the pulse detector for the output.
+//
+// SIDE EFFECTS: none.
+//
+// NOTES:
+//
+// SCOPE: private
+//
+// COMPLEXITY: 2
+//
+static pulse_state_t pulse_detect(pulse_state_t current_state, pulse_state_event_t event)
+{
+ pulse_state_t next_state = current_state;
+
+ // advance state if current state is valid (not an error state)
+ if (current_state < NUM_VALID_PULSE_STATES) {
+ next_state = pulse_transition_table[current_state][event];
+ }
+ return next_state;
+}
+
+
+// PROCEDURE: set_output
+// INPUTS: (asdf_virtual_real_dev_t) output_dev - the output to set
+// (uint8_t) value - value to assert on the output
+// OUTPUTS: none
+//
+// DESCRIPTION: Given an output and a new value for the output, set the output
+// and advance the pulse detector state for the output.
+//
+// SIDE EFFECTS: see above.
+//
+// NOTES:
+//
+// SCOPE: private
+//
+// COMPLEXITY: 1
+//
+static void set_output(asdf_virtual_real_dev_t output_dev, uint8_t value)
+{
+ pulse_state_event_t pulse_event = value ? SET_HIGH : SET_LOW;
+
+ outputs[output_dev] = value;
+ pulses[output_dev] = pulse_detect(pulses[output_dev], pulse_event);
+}
+
// PROCEDURE: asdf_arch_led1_set
// INPUTS: (uint8_t) value
@@ -58,7 +202,7 @@ static uint8_t outputs[NUM_REAL_OUTPUTS];
//
void asdf_arch_led1_set(uint8_t value)
{
- outputs[VMAP_LED1] = value;
+ set_output(VMAP_LED1, value);
}
// PROCEDURE: asdf_arch_led2_set
@@ -75,7 +219,7 @@ void asdf_arch_led1_set(uint8_t value)
//
void asdf_arch_led2_set(uint8_t value)
{
- outputs[VMAP_LED2] = value;
+ set_output(VMAP_LED2, value);
}
// PROCEDURE: asdf_arch_led3_set
@@ -92,7 +236,7 @@ void asdf_arch_led2_set(uint8_t value)
//
void asdf_arch_led3_set(uint8_t value)
{
- outputs[VMAP_LED3] = value;
+ set_output(VMAP_LED3, value);
}
// PROCEDURE: asdf_arch_out1_set
@@ -111,7 +255,7 @@ void asdf_arch_led3_set(uint8_t value)
//
void asdf_arch_out1_set(uint8_t value)
{
- outputs[VMAP_OUT1] = value;
+ set_output(VMAP_OUT1, value);
}
// PROCEDURE: asdf_arch_out1_hi_z_set
@@ -130,7 +274,7 @@ void asdf_arch_out1_set(uint8_t value)
//
void asdf_arch_out1_hi_z_set(uint8_t value)
{
- outputs[VMAP_OUT1_OC] = value;
+ set_output(VMAP_OUT1_OC, value);
}
// PROCEDURE: asdf_arch_out2_set
@@ -147,7 +291,27 @@ void asdf_arch_out1_hi_z_set(uint8_t value)
//
void asdf_arch_out2_set(uint8_t value)
{
- outputs[VMAP_OUT2] = value;
+ set_output(VMAP_OUT2, value);
+}
+
+
+// PROCEDURE: asdf_arch_out2_hi_z_set
+// INPUTS: (uint8_t) value
+// OUTPUTS: none
+//
+// DESCRIPTION: Sets the OUT2 bit to hi-z if value is true, and low if value is false.
+//
+// SIDE EFFECTS: See above.
+//
+// NOTES:
+//
+// SCOPE: public
+//
+// COMPLEXITY: 1
+//
+void asdf_arch_out2_hi_z_set(uint8_t value)
+{
+ set_output(VMAP_OUT2_OC, value);
}
// PROCEDURE: asdf_arch_out3_set
@@ -166,9 +330,10 @@ void asdf_arch_out2_set(uint8_t value)
//
void asdf_arch_out3_set(uint8_t value)
{
- outputs[VMAP_OUT3] = value;
+ set_output(VMAP_OUT3, value);
}
+
// PROCEDURE: asdf_arch_out3_hi_z_set
// INPUTS: (uint8_t) value
// OUTPUTS: none
@@ -185,7 +350,7 @@ void asdf_arch_out3_set(uint8_t value)
//
void asdf_arch_out3_hi_z_set(uint8_t value)
{
- outputs[VMAP_OUT3_OC] = value;
+ set_output(VMAP_OUT3_OC, value);
}
// PROCEDURE: asdf_arch_check_output
@@ -207,6 +372,28 @@ uint8_t asdf_arch_check_output(asdf_virtual_real_dev_t device)
return outputs[device];
}
+// PROCEDURE: asdf_arch_pulse_delay
+// INPUTS: none
+// OUTPUTS: none
+//
+// DESCRIPTION: Emulates a delay by advancing the pulse detector state machine
+// for each output.
+//
+// SIDE EFFECTS: see above.
+//
+// NOTES: Set ASDF_PULSE_DELAY_US in asdf_config.h
+//
+// SCOPE: public
+//
+// COMPLEXITY: 1
+//
+void asdf_arch_pulse_delay(void)
+{
+ for (uint8_t i = 0; i < NUM_REAL_OUTPUTS; i++) {
+ pulses[i] = pulse_detect(pulses[i], PULSE_DELAY);
+ }
+}
+
// PROCEDURE: asdf_arch_init
// INPUTS: none
// OUTPUTS: none
@@ -223,6 +410,7 @@ void asdf_arch_init(void)
{
for (uint8_t i = 0; i < NUM_REAL_OUTPUTS; i++) {
outputs[i] = 0;
+ pulses[i] = INITIAL_STATE;
}
}
diff --git a/firmware/asdf/src/Arch/asdf_arch_test.h b/firmware/asdf/src/Arch/asdf_arch_test.h
index 0571559..5a25cc8 100644
--- a/firmware/asdf/src/Arch/asdf_arch_test.h
+++ b/firmware/asdf/src/Arch/asdf_arch_test.h
@@ -32,25 +32,123 @@
#define FLASH_READ (a) (*(a))
#define FLASH_READ_MATRIX_ELEMENT(mat,row,col) (mat)[(row)][(col)]
-// PROCEDURE: asdf_arch_read_row
-// INPUTS: (uint8_t) row: the row number to be scanned
-// OUTPUTS: returns a word containing the active (pressed) columns
-// DESCRIPTION: Outputs the argument to the ROW port, then reads the column port
-// and returns the value. The value is a binary representation of the keys
-// pressed within the row, with 1=pressed, 0=released.
-asdf_cols_t asdf_arch_read_row(uint8_t row);
+// -*- 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 .
-// PROCEDURE: asdf_arch_send_screen_clear
+
+// 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_keymap_defs.h"
+#include "asdf_config.h"
+#include "asdf_virtual.h"
+#include "asdf_arch.h"
+
+static uint8_t outputs[NUM_REAL_OUTPUTS];
+
+// PROCEDURE: asdf_arch_null_output
+// INPUTS: (uint8_t) value - ignored
+// OUTPUTS: none
+// DESCRIPTION: Does nothing.
+void asdf_arch_null_output(uint8_t value);
+
+// PROCEDURE: asdf_arch_led1_set
+// INPUTS: (uint8_t) value
+// OUTPUTS: none
+// DESCRIPTION: If value is true, turn on LED1. If value is false, turn off LED1
+void asdf_arch_led1_set(uint8_t value);
+
+// PROCEDURE: asdf_arch_led2_set
+// INPUTS: (uint8_t) value
+// OUTPUTS: none
+// DESCRIPTION: If value is true, turn on LED2. If value is false, turn off LED2
+void asdf_arch_led2_set(uint8_t value);
+
+// PROCEDURE: asdf_arch_led3_set
+// INPUTS: (uint8_t) value
+// OUTPUTS: none
+// DESCRIPTION: If value is true, turn on LED3. If value is false, turn off LED3
+void asdf_arch_led3_set(uint8_t value);
+
+// PROCEDURE: asdf_arch_out1_set
+// INPUTS: (uint8_t) value
+// OUTPUTS: none
+// DESCRIPTION: Sets the OUT1 bit if value is true, and clear OUT1 if value is false.
+void asdf_arch_out1_set(uint8_t value);
+
+// PROCEDURE: asdf_arch_out1_hi_z_set
+// INPUTS: (uint8_t) value
+// OUTPUTS: none
+// DESCRIPTION: Sets the OUT1 bit to hi-z if value is true, and low if value is false.
+void asdf_arch_out1_hi_z_set(uint8_t value);
+
+// PROCEDURE: asdf_arch_out2_set
+// INPUTS: (uint8_t) value
+// OUTPUTS: none
+// DESCRIPTION: Sets the OUT2 bit if value is true, and clear OUT2 if value is false.
+void asdf_arch_out2_set(uint8_t value);
+
+// PROCEDURE: asdf_arch_out2_hi_z_set
+// INPUTS: (uint8_t) value
+// OUTPUTS: none
+// DESCRIPTION: Sets the OUT2 bit to hi-z if value is true, and low if value is false.
+void asdf_arch_out2_hi_z_set(uint8_t value);
+
+// PROCEDURE: asdf_arch_out3_set
+// INPUTS: (uint8_t) value
+// OUTPUTS: none
+// DESCRIPTION: Sets the OUT3 bit if value is true, and clear OUT3 if value is false.
+void asdf_arch_out3_set(uint8_t value);
+
+// PROCEDURE: asdf_arch_out3_hi_z_set
+// INPUTS: (uint8_t) value
+// OUTPUTS: none
+// DESCRIPTION: Sets the OUT3 bit to hi-z if value is true, and low if value is false.
+void asdf_arch_out3_hi_z_set(uint8_t value);
+
+// PROCEDURE: asdf_arch_check_output
+// INPUTS:(asdf_virtual_real_dev_t) device - which device to check
+// OUTPUTS: the value of the device setting.
+// DESCRIPTION: For a given real device, return the current setting (true or false)
+uint8_t asdf_arch_check_output(asdf_virtual_real_dev_t device);
+
+// PROCEDURE: asdf_arch_pulse_delay
// INPUTS: none
// OUTPUTS: none
-// DESCRIPTION: Toggles the SCREEN_CLEAR output.
-void asdf_arch_send_screen_clear(void);
+// DESCRIPTION: Emulates a delay by advancing the pulse detector state machine
+// for each output.
+void asdf_arch_pulse_delay(void);
-// PROCEDURE: asdf_arch_send_reset
-// INPUTS: none
-// OUTPUTS: none
-// DESCRIPTION: Toggles the SCREEN_CLEAR output.
-void asdf_arch_send_reset(void);
// PROCEDURE: asdf_arch_init
// INPUTS: none
@@ -58,11 +156,11 @@ void asdf_arch_send_reset(void);
// DESCRIPTION: sets up all the hardware for the keyboard
void asdf_arch_init(void);
-// PROCEDURE: asdf_arch_caps_led
-// INPUTS: (uint8_t) led_state: nonzero value turns on LED, zero turns off LED
-// OUTPUTS: none
-// DESCRIPTION: Controls the CAPSLOCK LED. Test version is empty.
-void asdf_arch_caps_led(uint8_t led_status);
+
+
+//-------|---------|---------+---------+---------+---------+---------+---------+
+// Above line is 80 columns, and should display completely in the editor.
+//
#endif // !defined (ASDF_ARCH_H)
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 57977f7..703082b 100644
--- a/firmware/asdf/src/Keymaps/asdf_all_keymap_defs_production.h
+++ b/firmware/asdf/src/Keymaps/asdf_all_keymap_defs_production.h
@@ -40,6 +40,8 @@
#define ASDF_KEYMAP_DEFS { ASDF_ASCII_ALL_MAPS , ASDF_APPLE2_ALL_MAPS }
#define ASDF_KEYMAP_DECLARATIONS ASDF_ASCII_MAP_DECLARATIONS ASDF_APPLE2_MAP_DECLARATIONS
+#define ASDF_KEYMAP_INITIALIZERS { ASDF_ASCII_KEYMAP_INITIALIZER , ASDF_APPLE2_KEYMAP_INITIALIZER }
+
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 dab40b0..fa6fe74 100644
--- a/firmware/asdf/src/Keymaps/asdf_all_keymap_defs_test.h
+++ b/firmware/asdf/src/Keymaps/asdf_all_keymap_defs_test.h
@@ -45,7 +45,7 @@
#define ASDF_KEYMAP_DECLARATIONS ASDF_TEST_DECLARATIONS ASDF_TEST2_DECLARATIONS
-#define ASDF_KEYMAP_INITIALIZERS { ASDF_TEST_KEYMAP_INITIALIZER , ASDF_TEST2_KEYMAP_INTIALIZER }
+#define ASDF_KEYMAP_INITIALIZERS { ASDF_TEST_KEYMAP_INITIALIZER , ASDF_TEST2_KEYMAP_INITIALIZER }
typedef asdf_keycode_t keycode_matrix_t[ASDF_NUM_ROWS][ASDF_NUM_COLS];
diff --git a/firmware/asdf/src/Keymaps/asdf_keymap_defs_apple2.h b/firmware/asdf/src/Keymaps/asdf_keymap_defs_apple2.h
index 868a606..b091694 100644
--- a/firmware/asdf/src/Keymaps/asdf_keymap_defs_apple2.h
+++ b/firmware/asdf/src/Keymaps/asdf_keymap_defs_apple2.h
@@ -47,15 +47,38 @@
#define ASDF_APPLE2_NUM_ROWS 16 // DIP switches are row 15.
#define ASDF_APPLE2_NUM_COLS 8
-#if !defined(ASDF_NUM_ROWS) || (ASDF_NUM_ROWS < ASDF_APPLE2_NUM_ROWS)
-#undef ASDF_NUM_ROWS
-#define ASDF_NUM_ROWS ASDF_APPLE2_NUM_ROWS
-#endif
+#define ASDF_ASCII_NUM_ROWS 16 // DIP switches are row 15.
+#define ASDF_ASCII_NUM_COLS 8
-#if !defined(ASDF_NUM_COLS) || (ASDF_NUM_COLS < ASDF_APPLE2_NUM_COLS)
-#undef ASDF_NUM_COLS
-#define ASDF_NUM_COLS ASDF_APPLE2_NUM_COLS
-#endif
+#define VIRTUAL_RESET VOUT1
+#define RESET_OUTPUT VMAP_OUT3_OC
+#define RESET_ACTIVE_VALUE 0
+
+#define VIRTUAL_CLR_SCR VOUT2
+#define CLR_SCR_OUT VMAP_OUT1
+#define CLR_SCR_ACTIVE_VALUE 1
+
+#define VIRTUAL_POWER_LED VLED1
+#define POWER_LED VMAP_LED1
+#define POWER_LED_INIT_VALUE 1
+
+#define ASDF_APPLE2_KEYMAP_INITIALIZER_LENGTH 4
+#define ASDF_APPLE2_KEYMAP_INITIALIZER \
+ { \
+ { .virtual_device = VIRTUAL_POWER_LED, \
+ .real_device = POWER_LED, \
+ .initial_value = POWER_LED_INIT_VALUE }, \
+ { .virtual_device = VCAPS_LED, \
+ .real_device = VMAP_LED3 }, \
+ { .virtual_device = RESET_OUTPUT, \
+ .real_device = VMAP_OUT1, \
+ .function = V_PULSE, \
+ .initial_value = !CLR_SCR_ACTIVE_VALUE }, \
+ { .virtual_device = CLR_SCR_OUT, \
+ .real_device = VMAP_OUT3, \
+ .function = V_PULSE, \
+ .initial_value = !RESET_ACTIVE_VALUE } \
+ }
// TO ensure consistent DIP switch operation within the keymap, a
// ASDF_APPLE2_DIP_SWITCHES macro is defined. Keeping the ACTION_MAPSEL0-3
@@ -187,6 +210,21 @@
#define ASDF_APPLE2_ALL_MAPS_COUNT 2
+#if !defined(ASDF_NUM_ROWS) || (ASDF_NUM_ROWS < ASDF_APPLE2_NUM_ROWS)
+#undef ASDF_NUM_ROWS
+#define ASDF_NUM_ROWS ASDF_APPLE2_NUM_ROWS
+#endif
+
+#if !defined(ASDF_NUM_COLS) || (ASDF_NUM_COLS < ASDF_APPLE2_NUM_COLS)
+#undef ASDF_NUM_COLS
+#define ASDF_NUM_COLS ASDF_APPLE2_NUM_COLS
+#endif
+
+#if !defined(ASDF_KEYMAP_INITIALIZER_LENGTH) || (ASDF_KEYMAP_INITIALIZER_LENGTH < ASDF_APPLE2_KEYMAP_INITIALIZER_LENGTH)
+#undef ASDF_KEYMAP_INITIALIZER_LENGTH
+#define ASDF_KEYMAP_INITIALIZER_LENGTH ASDF_APPLE2_KEYMAP_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 46147e9..b8436ad 100644
--- a/firmware/asdf/src/Keymaps/asdf_keymap_defs_ascii.h
+++ b/firmware/asdf/src/Keymaps/asdf_keymap_defs_ascii.h
@@ -39,15 +39,36 @@
#define ASDF_ASCII_NUM_ROWS 16 // DIP switches are row 15.
#define ASDF_ASCII_NUM_COLS 8
-#if !defined(ASDF_NUM_ROWS) || (ASDF_NUM_ROWS < ASDF_ASCII_NUM_ROWS)
-#undef ASDF_NUM_ROWS
-#define ASDF_NUM_ROWS ASDF_ASCII_NUM_ROWS
-#endif
+#define VIRTUAL_RESET VOUT1
+#define RESET_OUTPUT VMAP_OUT3_OC
+#define RESET_ACTIVE_VALUE 0
+
+#define VIRTUAL_CLR_SCR VOUT2
+#define CLR_SCR_OUT VMAP_OUT1
+#define CLR_SCR_ACTIVE_VALUE 1
+
+#define VIRTUAL_POWER_LED VLED1
+#define POWER_LED VMAP_LED1
+#define POWER_LED_INIT_VALUE 1
+
+#define ASDF_ASCII_KEYMAP_INITIALIZER_LENGTH 4
+#define ASDF_ASCII_KEYMAP_INITIALIZER \
+ { \
+ { .virtual_device = VIRTUAL_POWER_LED, \
+ .real_device = POWER_LED, \
+ .initial_value = POWER_LED_INIT_VALUE }, \
+ { .virtual_device = VCAPS_LED, \
+ .real_device = VMAP_LED3 }, \
+ { .virtual_device = RESET_OUTPUT, \
+ .real_device = VMAP_OUT1, \
+ .function = V_PULSE, \
+ .initial_value = !CLR_SCR_ACTIVE_VALUE }, \
+ { .virtual_device = CLR_SCR_OUT, \
+ .real_device = VMAP_OUT3, \
+ .function = V_PULSE, \
+ .initial_value = !RESET_ACTIVE_VALUE } \
+ }
-#if !defined(ASDF_NUM_COLS) || (ASDF_NUM_COLS < ASDF_ASCII_NUM_COLS)
-#undef ASDF_NUM_COLS
-#define ASDF_NUM_COLS ASDF_ASCII_NUM_COLS
-#endif
// TO ensure consistent DIP switch operation within the keymap, a
// ASDF_ASCII_DIP_SWITCHES macro is defined. Keeping the ACTION_MAPSEL0-3
@@ -159,6 +180,21 @@
#define ASDF_ASCII_ALL_MAPS_COUNT 2
+#if !defined(ASDF_NUM_ROWS) || (ASDF_NUM_ROWS < ASDF_ASCII_NUM_ROWS)
+#undef ASDF_NUM_ROWS
+#define ASDF_NUM_ROWS ASDF_ASCII_NUM_ROWS
+#endif
+
+#if !defined(ASDF_NUM_COLS) || (ASDF_NUM_COLS < ASDF_ASCII_NUM_COLS)
+#undef ASDF_NUM_COLS
+#define ASDF_NUM_COLS ASDF_ASCII_NUM_COLS
+#endif
+
+#if !defined(ASDF_KEYMAP_INITIALIZER_LENGTH) || (ASDF_KEYMAP_INITIALIZER_LENGTH < ASDF_ASCII_KEYMAP_INITIALIZER_LENGTH)
+#undef ASDF_KEYMAP_INITIALIZER_LENGTH
+#define ASDF_KEYMAP_INITIALIZER_LENGTH ASDF_ASCII_KEYMAP_INITIALIZER_LENGTH
+#endif
+
#endif /* !defined (ASDF_KEYMAP_DEFS_ASCII_H) */
//-------|---------|---------+---------+---------+---------+---------+---------+
diff --git a/firmware/asdf/src/Keymaps/asdf_keymap_defs_test.h b/firmware/asdf/src/Keymaps/asdf_keymap_defs_test.h
index 04dca7c..0c7d142 100644
--- a/firmware/asdf/src/Keymaps/asdf_keymap_defs_test.h
+++ b/firmware/asdf/src/Keymaps/asdf_keymap_defs_test.h
@@ -148,11 +148,23 @@
#define ASDF_TEST_CAPS_MAP_INDEX ASDF_TEST_BASE + 1
#define ASDF_TEST_KEYMAP_INITIALIZER_LENGTH 3
-#define ASDF_TEST_KEYMAP_INITIALIZER \
- { \
- { .virtual_device = VCAPS_LED, .device = VMAP_LED1, .initial_value = 1 }, \
- { .virtual_device = VOUT1, .device = VMAP_OUT1, .initial_value = 1 }, \
- { .virtual_device = VOUT2, .device = VMAP_OUT3, .initial_value = 1 } \
+#define ASDF_TEST_KEYMAP_INITIALIZER \
+ { \
+ { \
+ .virtual_device = VCAPS_LED, \
+ .real_device = VMAP_LED1, \
+ .function = V_NOFUNC, \
+ .initial_value = 1, \
+ }, \
+ { \
+ .virtual_device = VOUT1, \
+ .real_device = VMAP_OUT1, \
+ .function = V_TOGGLE, \
+ .initial_value = 1, \
+ }, \
+ { \
+ .virtual_device = VOUT2, .real_device = VMAP_OUT3, .function = V_PULSE, .initial_value = 1, \
+ } \
}
@@ -174,7 +186,8 @@
#define ASDF_NUM_COLS ASDF_TEST_NUM_COLS
#endif
-#if !defined(ASDF_KEYMAP_INITIALIZER_LENGTH) || (ASDF_KEYMAP_INITIALIZER_LENGTH < ASDF_TEST_KEYMAP_INITIALIZER_LENGTH)
+#if !defined(ASDF_KEYMAP_INITIALIZER_LENGTH) \
+ || (ASDF_KEYMAP_INITIALIZER_LENGTH < ASDF_TEST_KEYMAP_INITIALIZER_LENGTH)
#undef ASDF_KEYMAP_INITIALIZER_LENGTH
#define ASDF_KEYMAP_INITIALIZER_LENGTH ASDF_TEST_KEYMAP_INITIALIZER_LENGTH
#endif
diff --git a/firmware/asdf/src/Keymaps/asdf_keymap_defs_test2.h b/firmware/asdf/src/Keymaps/asdf_keymap_defs_test2.h
index 155a576..653a4e3 100644
--- a/firmware/asdf/src/Keymaps/asdf_keymap_defs_test2.h
+++ b/firmware/asdf/src/Keymaps/asdf_keymap_defs_test2.h
@@ -149,12 +149,14 @@
#define ASDF_TEST2_CAPS_MAP_INDEX (ASDF_TEST2_BASE + 1)
#define ASDF_TEST2_KEYMAP_INITIALIZER_LENGTH 4
-#define ASDF_TEST2_KEYMAP_INITIALIZER \
- { \
- { .virtual_device = VCAPS_LED, .device = VMAP_LED2, .initial_value = 1 }, \
- { .virtual_device = VOUT1, .device = VMAP_OUT2, .initial_value = 1 }, \
- { .virtual_device = VOUT2, .device = VMAP_OUT3, .initial_value = 0 }, \
- { .virtual_device = VOUT2, .device = NUM_VIRTUAL_OUTPUTS, .initial_value = 0 } \
+#define ASDF_TEST2_KEYMAP_INITIALIZER \
+ { \
+ { .virtual_device = VCAPS_LED, .real_device = VMAP_LED2, .initial_value = 1 }, \
+ { .virtual_device = VOUT1, .real_device = VMAP_OUT2, .initial_value = 1 }, \
+ { .virtual_device = VOUT2, .real_device = VMAP_OUT3, .initial_value = 0 }, \
+ { \
+ .virtual_device = VOUT2, .real_device = NUM_REAL_OUTPUTS, .initial_value = 0 \
+ } \
}
diff --git a/firmware/asdf/src/Makefile.app b/firmware/asdf/src/Makefile.app
index 83a7aa0..a6aba56 100644
--- a/firmware/asdf/src/Makefile.app
+++ b/firmware/asdf/src/Makefile.app
@@ -68,7 +68,7 @@ MAKEDEPEND = $(CPP) $(DEPFLAGS) $(CPPFLAGS) $< \
| sort -u > $*.d
SRC_FILES = main.c asdf.c asdf_modifiers.c asdf_repeat.c asdf_keymaps.c
-SRC_FILES += asdf_buffer.c asdf_arch.c asdf_actions.c
+SRC_FILES += asdf_buffer.c asdf_arch.c asdf_virtual.c
OBJ_FILES := $(SRC_FILES:.c=.o)
DEP_FILES := $(SRC_FILES:%.c=$(DEP_DIR)/%.d)
@@ -141,7 +141,7 @@ 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_actions.o: asdf_actions.h asdf.h asdf_arch.h
+asdf_virtual.o: asdf_virtual.c asdf_virtual.h asdf_arch.h
tags: $(SRC_FILES)
etags $(SRC_FILES)
diff --git a/firmware/asdf/src/Makefile.test b/firmware/asdf/src/Makefile.test
index cdbe4f9..0acc034 100644
--- a/firmware/asdf/src/Makefile.test
+++ b/firmware/asdf/src/Makefile.test
@@ -41,7 +41,7 @@ OBJ_FILES = $(SRC_FILES:.c=.o)
ARCH_FILES = asdf_arch.c asdf_arch.h
CLEAN_FILES += ARCH_FILES
-TESTS = repeat modifiers keymaps interface keyscan
+TESTS = repeat modifiers keymaps interface keyscan virtual
TEST1 = asdf_repeat
TEST1_SRC = $(TEST_DIR)/test_$(TEST1).c
@@ -49,13 +49,13 @@ TEST1_DEPS = ./$(TEST1).c $(UNITY_DIR)/unity.c
TEST1_BUILD = $(BUILD_DIR)/test_$(TEST1)
TEST2 = asdf_modifiers
-TEST2_SRC = $(TEST_DIR)/test_$(TEST2).c ./asdf_arch.c
+TEST2_SRC = $(TEST_DIR)/test_$(TEST2).c ./asdf_arch.c ./asdf_virtual.c
TEST2_DEPS = ./$(TEST2).c $(UNITY_DIR)/unity.c
TEST2_BUILD = $(BUILD_DIR)/test_$(TEST2)
TEST3 = asdf_keymaps
TEST3_SRC = $(TEST_DIR)/test_$(TEST3).c
-TEST3_DEPS = ./$(TEST3).c $(UNITY_DIR)/unity.c
+TEST3_DEPS = ./$(TEST3).c $(UNITY_DIR)/unity.c ./asdf_virtual.c ./asdf_arch.c
TEST3_BUILD = $(BUILD_DIR)/test_$(TEST3)
TEST4 = asdf_buffer
@@ -63,10 +63,15 @@ TEST4_SRC = $(TEST_DIR)/test_$(TEST4).c
TEST4_DEPS = ./$(TEST4).c $(UNITY_DIR)/unity.c
TEST4_BUILD = $(BUILD_DIR)/test_$(TEST4)
-TEST5 = asdf
-TEST5_SRC = $(TEST_DIR)/test_$(TEST5).c
-TEST5_DEPS = ./$(TEST5).c $(UNITY_DIR)/unity.c ./asdf_actions.c ./asdf_arch.c ./$(TEST1).c $(TEST2).c $(TEST3).c $(TEST4).c
-TEST5_BUILD = $(BUILD_DIR)/test_$(TEST5)
+TEST5 = asdf_virtual
+TEST5_SRC = $(TEST_DIR)/test_$(TEST4).c
+TEST5_DEPS = ./$(TEST4).c $(UNITY_DIR)/unity.c
+TEST5_BUILD = $(BUILD_DIR)/test_$(TEST4)
+
+TEST6 = asdf
+TEST6_SRC = $(TEST_DIR)/test_$(TEST5).c
+TEST6_DEPS = ./$(TEST5).c $(UNITY_DIR)/unity.c ./asdf_arch.c ./$(TEST1).c $(TEST2).c $(TEST3).c $(TEST4).c
+TEST6_BUILD = $(BUILD_DIR)/test_$(TEST5)
.SUFFIXES:
.SUFFIXES: .c .o .bin .hex
@@ -96,12 +101,13 @@ $(ARCH_TOKEN):
asdf_keymaps.c: asdf.h asdf_ascii.h asdf_modifiers.h asdf_arch.h asdf_keymaps.h asdf_keymap_defs.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
tags: $(SRC_FILES)
etags $(SRC_FILES)
.PHONY: test
-test: test1 test2 test3 test4 test5
+test: test1 test2 test3 test4 test6 test5
.PHONY: test1
test1: $(TEST1_BUILD)
@@ -123,6 +129,10 @@ test4: $(TEST4_BUILD)
test5: $(TEST5_BUILD)
$(TEST5_BUILD)
+.PHONY: test6
+test5: $(TEST6_BUILD)
+ $(TEST6_BUILD)
+
$(TEST1_BUILD): $(TEST1_SRC) $(TEST1_DEPS)
$(CC) -o $@ -I. -I$(TEST_DIR) -I$(UNITY_DIR) $(CFLAGS) $(TEST1_SRC) $(TEST1_DEPS)
@@ -139,7 +149,10 @@ $(TEST4_BUILD): $(TEST4_SRC) $(TEST4_DEPS)
$(TEST5_BUILD): $(TEST5_SRC) $(TEST5_DEPS)
$(CC) -o $@ -I. -I$(TEST_DIR) -I$(UNITY_DIR) $(CFLAGS) $(TEST5_SRC) $(TEST5_DEPS)
-TEST_BUILD_FILES += $(TEST1_BUILD) $(TEST2_BUILD) $(TEST3_BUILD) $(TEST4_BUILD) $(TEST5_BUILD)
+$(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)
CLEAN_FILES += $(TEST_BUILD_FILES) _Arch_* *.o
CLEAN_FILES += ~* *\#
diff --git a/firmware/asdf/src/asdf.c b/firmware/asdf/src/asdf.c
index 04b8969..a7a6071 100644
--- a/firmware/asdf/src/asdf.c
+++ b/firmware/asdf/src/asdf.c
@@ -33,6 +33,7 @@
#include
#include "asdf.h"
#include "asdf_ascii.h"
+#include "asdf_virtual.h"
#include "asdf_keymaps.h"
#include "asdf_keymap_defs.h"
#include "asdf_repeat.h"
@@ -136,6 +137,7 @@ asdf_keycode_t asdf_lookup_keycode(uint8_t row, uint8_t col)
static void asdf_activate_action(action_t keycode)
{
switch (keycode) {
+
case ACTION_SHIFT: {
asdf_modifier_shift_activate();
break;
@@ -156,14 +158,6 @@ static void asdf_activate_action(action_t keycode)
asdf_repeat_activate();
break;
}
- case ACTION_CLEAR: {
- asdf_send_screen_clear();
- break;
- }
- case ACTION_RESET: {
- asdf_send_reset();
- break;
- }
case ACTION_MAPSEL_0: {
asdf_keymaps_map_select_0_set();
break;
@@ -180,6 +174,42 @@ static void asdf_activate_action(action_t keycode)
asdf_keymaps_map_select_3_set();
break;
}
+ case ACTION_VLED1: {
+ asdf_virtual_activate(VLED1);
+ break;
+ }
+ case ACTION_VLED2: {
+ asdf_virtual_activate(VLED2);
+ break;
+ }
+ case ACTION_VLED3: {
+ asdf_virtual_activate(VLED3);
+ break;
+ }
+ case ACTION_VOUT1: {
+ asdf_virtual_activate(VOUT1);
+ break;
+ }
+ case ACTION_VOUT2: {
+ asdf_virtual_activate(VOUT2);
+ break;
+ }
+ case ACTION_VOUT3: {
+ asdf_virtual_activate(VOUT3);
+ break;
+ }
+ case ACTION_VOUT4: {
+ asdf_virtual_activate(VOUT4);
+ break;
+ }
+ case ACTION_VOUT5: {
+ asdf_virtual_activate(VOUT5);
+ break;
+ }
+ case ACTION_VOUT6: {
+ asdf_virtual_activate(VOUT6);
+ break;
+ }
case ACTION_NOTHING:
case ACTION_LOCAL:
case ACTION_BREAK:
diff --git a/firmware/asdf/src/asdf.h b/firmware/asdf/src/asdf.h
index 4a7d193..b6250b4 100644
--- a/firmware/asdf/src/asdf.h
+++ b/firmware/asdf/src/asdf.h
@@ -54,6 +54,15 @@ typedef enum {
ACTION_MAPSEL_1,
ACTION_MAPSEL_2,
ACTION_MAPSEL_3,
+ ACTION_VLED1,
+ ACTION_VLED2,
+ ACTION_VLED3,
+ ACTION_VOUT1,
+ ACTION_VOUT2,
+ ACTION_VOUT3,
+ ACTION_VOUT4,
+ ACTION_VOUT5,
+ ACTION_VOUT6,
ACTION_FN_1,
ACTION_FN_2,
ACTION_FN_3,
@@ -79,7 +88,7 @@ typedef enum {
RESERVED_13,
RESERVED_14,
RESERVED_15,
- RESERVED_16
+ RESERVED_16,
} action_t;
diff --git a/firmware/asdf/src/asdf_config.h b/firmware/asdf/src/asdf_config.h
index bd2739a..c4331c1 100644
--- a/firmware/asdf/src/asdf_config.h
+++ b/firmware/asdf/src/asdf_config.h
@@ -63,6 +63,12 @@
// time between repeats of a character with repeat key held, or in autorepeat (milliseconds)
#define ASDF_REPEAT_TIME_MS (1000 / 15) // l5 characters per sec.
+// duration of keyboard output pulses (RESET, SCREEN CLEAR, BREAK, etc.)
+#define ASDF_PULSE_DELAY_US 100
+
+// DEFAULT value of keyboard outputs
+#define ASDF_VIRTUAL_OUT_DEFAULT_VALUE 1 // High if not used.
+
#endif /* !defined (CONFIG_H) */
//-------|---------|---------+---------+---------+---------+---------+---------+
diff --git a/firmware/asdf/src/asdf_keymaps.c b/firmware/asdf/src/asdf_keymaps.c
index 97c612e..a082ce8 100644
--- a/firmware/asdf/src/asdf_keymaps.c
+++ b/firmware/asdf/src/asdf_keymaps.c
@@ -43,7 +43,7 @@ static keycode_matrix_t const *keymap_matrix[ASDF_NUM_KEYMAPS][ASDF_MOD_NUM_MODI
ASDF_KEYMAP_DEFS;
-static const FLASH virtual_initializer_t keymap_initializer_list[ASDF_NUM_KEYMAPS][ASDF_INITIALIZER_LENGTH] =
+static const asdf_virtual_initializer_t keymap_initializer_list[ASDF_NUM_KEYMAPS][ASDF_KEYMAP_INITIALIZER_LENGTH] =
ASDF_KEYMAP_INITIALIZERS;
static uint8_t keymap_index;
@@ -68,7 +68,7 @@ void asdf_keymaps_select_keymap(uint8_t index)
{
if (index < ASDF_NUM_KEYMAPS) {
keymap_index = index;
- asdf_virtual_init(keymap_initializer_list[keymap_index]);
+ asdf_virtual_init((asdf_virtual_initializer_t *const) keymap_initializer_list[keymap_index]);
}
}
diff --git a/firmware/asdf/src/asdf_keymaps.h b/firmware/asdf/src/asdf_keymaps.h
index d681830..21e195d 100644
--- a/firmware/asdf/src/asdf_keymaps.h
+++ b/firmware/asdf/src/asdf_keymaps.h
@@ -34,7 +34,7 @@
#define ASDF_KEYMAP_BIT_2 4
#define ASDF_KEYMAP_BIT_3 8
-typdef enum {
+typedef enum {
CLEAR_OUT1,
SET_OUT1,
CLEAR_OUT2,
@@ -73,7 +73,7 @@ typdef enum {
SET_VLED2_LED3,
SET_VLED3_LED3,
-} keymap_init_t
+} keymap_init_t;
diff --git a/firmware/asdf/src/asdf_modifiers.c b/firmware/asdf/src/asdf_modifiers.c
index 4dcb963..b21a3f0 100644
--- a/firmware/asdf/src/asdf_modifiers.c
+++ b/firmware/asdf/src/asdf_modifiers.c
@@ -26,6 +26,7 @@
#include
#include "asdf_modifiers.h"
+#include "asdf_virtual.h"
#include "asdf_arch.h"
static shift_state_t shift_state;
@@ -45,7 +46,7 @@ static const modifier_index_t modifier_indices[] = {
};
-// PROCEDURE: set_shiftlock_state
+// PROCEDURE: set_shift_state
// INPUTS: (uint8_t) state: the new shift state
// OUTPUTS: none
//
@@ -55,10 +56,13 @@ static const modifier_index_t modifier_indices[] = {
//
// COMPLEXITY: 1
//
-void asdf_modifier_set_shiftlock_state(uint8_t new_state)
+void asdf_modifier_set_shift_state(uint8_t new_state)
{
+ uint8_t shiftlock_status = new_state & SHIFT_LOCKED_ST;
+
shift_state = new_state;
- asdf_virtual_action(VSHIFT_LED, (shift_state ? V_SET_HI : V_SET_LO));
+
+ asdf_virtual_action(VSHIFT_LED, (shiftlock_status ? V_SET_HI : V_SET_LO));
}
// PROCEDURE: asdf_modifier_shift_activate
@@ -100,7 +104,7 @@ void asdf_modifier_shift_activate(void)
//
// COMPLEXITY: 2
//
-void asdf_modifier_shiftlock_activate();
+void asdf_modifier_shiftlock_activate(void)
{
if (asdf_toggle_shiftlock) {
asdf_modifier_set_shift_state(shift_state ^ SHIFT_LOCKED_ST);
@@ -120,17 +124,17 @@ void asdf_modifier_shiftlock_activate();
//
// COMPLEXITY: 1
//
-static void asdf_modifier_set_caps_state(uint8_t new_state);
+static void asdf_modifier_set_caps_state(uint8_t new_state)
{
- uint8_t caps_state = new_state;
- asdf_virtual_action(VCAPS_LED, (caps_state ? V_SET_HI : V_SET_LO );
+ caps_state = new_state;
+ asdf_virtual_action(VCAPS_LED, (caps_state ? V_SET_HI : V_SET_LO ));
}
// PROCEDURE: asdf_modifier_capslock_activate
// INPUTS: none
// OUTPUTS: none
//
-// DESCRIPTION: Turns on Capslock state
+// DESCRIPTION: Toggles Capslock state
//
// SIDE EFFECTS: see DESCRIPTION
//
diff --git a/firmware/asdf/src/asdf_virtual.c b/firmware/asdf/src/asdf_virtual.c
index 04ad71a..0aac4de 100644
--- a/firmware/asdf/src/asdf_virtual.c
+++ b/firmware/asdf/src/asdf_virtual.c
@@ -27,8 +27,10 @@
// this program. If not, see .
//
-
+#include
#include "asdf_virtual.h"
+#include "asdf_keymap_defs.h"
+#include "asdf_config.h"
#include "asdf_arch.h"
// For each virtual out, maintain a "shadow" register for the output value. This
@@ -55,17 +57,17 @@ static real_dev_t real_device_table[NUM_REAL_OUTPUTS];
// vout_set[] contains the set() function for each real output device.
-static const void (*vout_set[])(uint8_t) = {
- [VMAP_NO_OUT] = NULL, //
+static void (*const vout_set[])(uint8_t) = {
+ [VMAP_NO_OUT] = &asdf_arch_null_output, //
[VMAP_OUT1] = &asdf_arch_out1_set, //
[VMAP_OUT2] = &asdf_arch_out2_set, //
[VMAP_OUT3] = &asdf_arch_out3_set, //
[VMAP_OUT1_OC] = &asdf_arch_out1_hi_z_set, //
[VMAP_OUT2_OC] = &asdf_arch_out2_hi_z_set, //
[VMAP_OUT3_OC] = &asdf_arch_out3_hi_z_set, //
- [VMAP_VLED1] = &asdf_arch_led1_set, //
- [VMAP_VLED2] = &asdf_arch_led2_set, //
- [VMAP_VLED3] = &asdf_arch_led3_set //
+ [VMAP_LED1] = &asdf_arch_led1_set, //
+ [VMAP_LED2] = &asdf_arch_led2_set, //
+ [VMAP_LED3] = &asdf_arch_led3_set //
};
// virtual_out[] contains all the virtual outputs. An asdf_virtual_output_t
@@ -94,7 +96,7 @@ static virtual_dev_t virtual_device_table[NUM_VIRTUAL_OUTPUTS];
static void asdf_virtual_real_set(asdf_virtual_real_dev_t real_out, uint8_t value)
{
vout_set[real_out](value);
- shadow_out[real_out] = value;
+ real_device_table[real_out].shadow = value;
}
@@ -113,7 +115,7 @@ static void asdf_virtual_real_set(asdf_virtual_real_dev_t real_out, uint8_t valu
//
// COMPLEXITY: 1
//
-static void asdf_virtual_real_assert(asdf_virtual_real_dev_t real_out);
+static void asdf_virtual_real_assert(asdf_virtual_real_dev_t real_out)
{
uint8_t value = real_device_table[real_out].shadow;
vout_set[real_out](value);
@@ -134,7 +136,7 @@ static void asdf_virtual_real_assert(asdf_virtual_real_dev_t real_out);
//
// COMPLEXITY: 1
//
-static void asdf_virtual_real_toggle(asdf_virtual_real_dev_t real_out);
+static void asdf_virtual_real_toggle(asdf_virtual_real_dev_t real_out)
{
uint8_t value = real_device_table[real_out].shadow;
@@ -160,7 +162,7 @@ static void asdf_virtual_real_toggle(asdf_virtual_real_dev_t real_out);
//
void asdf_virtual_action(asdf_virtual_output_t virtual_out, asdf_virtual_function_t function)
{
- real_dev_t device = virtual_device_table[virtual_out].real_device;
+ asdf_virtual_real_dev_t device = virtual_device_table[virtual_out].real_device;
while (VMAP_NO_OUT != device) {
switch (function) {
@@ -192,6 +194,26 @@ void asdf_virtual_action(asdf_virtual_output_t virtual_out, asdf_virtual_functio
}
}
+// PROCEDURE: asdf_virtual_activate
+// INPUTS: asdf_virtual_output_t: The virtual device to be activated
+// OUTPUTS: none
+//
+// DESCRIPTION: for each real output mapped to the virtual output, apply the
+// function assigned to the virtual output at initialization.
+//
+// SIDE EFFECTS: see above
+//
+// NOTES: The virtual output points to a linked list of real devices.
+//
+// SCOPE: public
+//
+// COMPLEXITY: 1
+//
+void asdf_virtual_activate(asdf_virtual_output_t virtual_out)
+{
+ asdf_virtual_action(virtual_out, virtual_device_table[virtual_out].function);
+}
+
// PROCEDURE: asdf_virtual_assign
// INPUTS: (asdf_vout_t) virtual_out
// (uint8_t) real_out
@@ -209,9 +231,9 @@ void asdf_virtual_action(asdf_virtual_output_t virtual_out, asdf_virtual_functio
// COMPLEXITY: 2
//
static void asdf_virtual_assign(asdf_virtual_output_t virtual_out, asdf_virtual_real_dev_t real_out,
- asdf_virtual_function_t function, uint8_t initial_value)
+ asdf_virtual_function_t function, uint8_t initial_value)
{
- virtual_device_table[virtual_device].function = function;
+ virtual_device_table[virtual_out].function = function;
// add real device to the list associated with the virtual device:
@@ -220,25 +242,25 @@ static void asdf_virtual_assign(asdf_virtual_output_t virtual_out, asdf_virtual_
// The real device shadow value is set here. The shadow values are asserted to
// the outputs only after all the assignments have been performed.
- real_device_table[real_out].shadow = value;
+ real_device_table[real_out].shadow = initial_value;
}
// PROCEDURE: asdf_virtual_init
-// INPUTS: initializers
+// INPUTS: (asdf_virtual_initializer_t *) initializer_list - contains the
+// initializer list for the selected keymap.
// OUTPUTS: none
//
// DESCRIPTION: Initializes the LED and output mapping
//
// SIDE EFFECTS: see above
//
-// NOTES: The table of real devices is initialized as a linked list of available
-// devices.
+// NOTES: 1) // 2) ASDF_VIRTUAL_OUT_DEFAULT_VALUE is defined in asdf_config.h
//
// SCOPE: public
//
// COMPLEXITY: 2
//
-void asdf_virtual_init(virtual_initializer_t *initializer_list)
+void asdf_virtual_init(asdf_virtual_initializer_t *const initializer_list)
{
// initialize list of virtual outputs
@@ -250,19 +272,19 @@ void asdf_virtual_init(virtual_initializer_t *initializer_list)
// initialize the linked list of free devices
for (uint8_t i = 0; i < NUM_REAL_OUTPUTS; i++) {
real_device_table[i].shadow = ASDF_VIRTUAL_OUT_DEFAULT_VALUE;
- real_device_table[i].next = i + 1 // initialize pointer to next in table
+ real_device_table[i].next = i + 1; // initialize pointer to next in table
}
// The last item in the table is left with a bogus next pointer (beyond the
// end of the array) after the above loop. Make the last element point to
- // NULL.
+ // V_NULL.
real_device_table[NUM_REAL_OUTPUTS - 1].next = VMAP_NO_OUT; // end of list.
// run through the keymap specific setup
for (uint8_t i = 0; //
- i < NUM_INITIALIZERS && initializers[i].virtual_device != V_NULL; i++) {
+ i < ASDF_KEYMAP_INITIALIZER_LENGTH && initializer_list[i].virtual_device != V_NULL; i++) {
- asdf_virtual_assign(intializer_list[i].virtual_device, intializer_list[i].real_device,
+ asdf_virtual_assign(initializer_list[i].virtual_device, initializer_list[i].real_device,
initializer_list[i].function, initializer_list[i].initial_value);
}
diff --git a/firmware/asdf/src/asdf_virtual.h b/firmware/asdf/src/asdf_virtual.h
index 448d817..6c9b0af 100644
--- a/firmware/asdf/src/asdf_virtual.h
+++ b/firmware/asdf/src/asdf_virtual.h
@@ -54,6 +54,7 @@ typedef enum {
VMAP_OUT1,
VMAP_OUT1_OC,
VMAP_OUT2,
+ VMAP_OUT2_OC,
VMAP_OUT3,
VMAP_OUT3_OC,
VMAP_LED1,
@@ -62,7 +63,14 @@ typedef enum {
NUM_REAL_OUTPUTS
} asdf_virtual_real_dev_t;
-typedef enum { V_NOFUNC, V_SET_HI, V_SET_LO, V_PULSE, V_TOGGLE, NUM_VIRTUAL_FUNCTIONS } asdf_virtual_function_t;
+typedef enum {
+ V_NOFUNC,
+ V_SET_HI,
+ V_SET_LO,
+ V_PULSE,
+ V_TOGGLE,
+ NUM_VIRTUAL_FUNCTIONS
+} asdf_virtual_function_t;
// Each keymap specifies an array of initializer structs to configure virtual
// devices, specifying the mapped real device and initial value.
@@ -71,7 +79,7 @@ typedef struct {
asdf_virtual_real_dev_t real_device;
asdf_virtual_function_t function;
uint8_t initial_value;
-} virtual_initializer_t;
+} asdf_virtual_initializer_t;
// PROCEDURE: asdf_virtual_action
// INPUTS: (asdf_virtual_output_t) virtual_out: which virtual output to modify
@@ -81,11 +89,19 @@ typedef struct {
// specified function.
void asdf_virtual_action(asdf_virtual_output_t virtual_out, asdf_virtual_function_t function);
+// PROCEDURE: asdf_virtual_activate
+// INPUTS: asdf_virtual_output_t: The virtual device to be activated
+// OUTPUTS: none
+// DESCRIPTION: for each real output mapped to the virtual output, apply the
+// function assigned to the virtual output at initialization.
+void asdf_virtual_activate(asdf_virtual_output_t virtual_out);
+
// PROCEDURE: asdf_virtual_init
// INPUTS: initializers
// OUTPUTS: none
// DESCRIPTION: Initializes the LED and output mapping
-void asdf_virtual_init(virtual_initializer_t *initializer_list);
+void asdf_virtual_init(asdf_virtual_initializer_t *const initializer_list);
+
#endif /* !defined (ASDF_VIRTUAL_H) */
diff --git a/firmware/asdf/test/test_asdf_keymaps.c b/firmware/asdf/test/test_asdf_keymaps.c
index 243ebe9..6c21371 100644
--- a/firmware/asdf/test/test_asdf_keymaps.c
+++ b/firmware/asdf/test/test_asdf_keymaps.c
@@ -82,24 +82,6 @@ static coord_t alpha_sample;
static coord_t num_sample;
static coord_t keymap_tag;
-// Array of zeros which will be initialized to specific values on keymap changes.
-static keycode_t init_testvals[ASDF_NUM_INITIALIZERS] = {};
-static keycode_t initializers[ASDF_NUM_KEYMAPS][ASDF_NUM_INITIALIZERS] = ASDF_KEYMAP_INITIALIZERS;
-
-void reset_testvals(void)
-{
- for(int i = 0; i < ASDF_NUM_INITIALIZERS; i++) {
- init_testvals[i] = 0;
- }
-}
-
-
-
-
-
-
-
-
uint32_t max(uint8_t first, uint8_t second)
{
uint32_t max = first;
@@ -131,8 +113,6 @@ void setUp(void)
{
coord_t *temp;
- reset_testvals();
-
asdf_keymaps_init();
temp = find_code(TESTALPHA);
@@ -348,14 +328,6 @@ void dip_switch_invalid_keymap_has_no_effect(void)
}
-void keymap_initializers_run_on_startup(void)
-{
- for (int i = 0; i < NUM_INITIALIZERS; i++)
- {
- TEST_ASSERT_EQUAL_INT32((int32_t) )
- }
-}
-
int main(void)
{
UNITY_BEGIN();
diff --git a/firmware/asdf/test/test_asdf_modifiers.c b/firmware/asdf/test/test_asdf_modifiers.c
index ad0c63a..e244212 100644
--- a/firmware/asdf/test/test_asdf_modifiers.c
+++ b/firmware/asdf/test/test_asdf_modifiers.c
@@ -279,82 +279,6 @@ void ctrl_double_shiftlock_returns_to_ctrl_map(void)
TESTMAP(MOD_CTRL_MAP);
}
-// CAPS give caps
-void caps_gives_caps(void)
-{
- asdf_modifier_caps_activate();
- TESTMAP(MOD_CAPS_MAP);
-}
-
-// CAPS and release gives plain
-void caps_and_release_gives_plain(void)
-{
- asdf_modifier_caps_activate();
- TESTMAP(MOD_CAPS_MAP);
- asdf_modifier_caps_deactivate();
- TESTMAP(MOD_PLAIN_MAP);
-}
-
-
-// CAPSLOCK and CAPS gives caps
-void capslock_and_caps_gives_caps(void)
-{
- asdf_modifier_capslock_activate();
- asdf_modifier_capslock_deactivate();
- TESTMAP(MOD_CAPS_MAP);
- asdf_modifier_caps_activate();
- TESTMAP(MOD_CAPS_MAP);
-}
-
-// CAPSLOCK and CAPS and release CAPS gives caps
-void capslock_and_caps_and_release_gives_caps(void)
-{
- asdf_modifier_capslock_activate();
- asdf_modifier_capslock_deactivate();
- TESTMAP(MOD_CAPS_MAP);
- asdf_modifier_caps_activate();
- TESTMAP(MOD_CAPS_MAP);
- asdf_modifier_caps_deactivate();
- TESTMAP(MOD_CAPS_MAP);
-}
-
-// CAPS and CAPSLOCK gives caps
-void caps_and_capslock_gives_caps(void)
-{
- asdf_modifier_caps_activate();
- TESTMAP(MOD_CAPS_MAP);
- asdf_modifier_capslock_activate();
- asdf_modifier_capslock_deactivate();
- TESTMAP(MOD_CAPS_MAP);
-}
-
-// CAPS and CAPSLOCK and release CAPS gives caps
-void caps_and_capslock_and_release_gives_caps(void)
-{
- asdf_modifier_caps_activate();
- TESTMAP(MOD_CAPS_MAP);
- asdf_modifier_capslock_activate();
- TESTMAP(MOD_CAPS_MAP);
- asdf_modifier_caps_deactivate();
- TESTMAP(MOD_CAPS_MAP);
-}
-
-// CAPS and CAPSLOCK and release CAPS then CAPSLOCK gives plain
-void caps_and_capslock_and_release_and_capslock_gives_plain(void)
-{
- asdf_modifier_caps_activate();
- TESTMAP(MOD_CAPS_MAP);
- asdf_modifier_capslock_activate();
- asdf_modifier_capslock_deactivate();
- TESTMAP(MOD_CAPS_MAP);
- asdf_modifier_caps_deactivate();
- TESTMAP(MOD_CAPS_MAP);
- asdf_modifier_capslock_activate();
- asdf_modifier_capslock_deactivate();
- TESTMAP(MOD_PLAIN_MAP);
-}
-
-
int main(void)
{
UNITY_BEGIN();
@@ -381,13 +305,6 @@ int main(void)
RUN_TEST(ctrl_shiftlock_gives_ctrl_map);
RUN_TEST(ctrl_double_caps_returns_to_ctrl_map);
RUN_TEST(ctrl_double_shiftlock_returns_to_ctrl_map);
- RUN_TEST(caps_gives_caps);
- RUN_TEST(caps_and_release_gives_plain);
- RUN_TEST(capslock_and_caps_gives_caps);
- RUN_TEST(capslock_and_caps_and_release_gives_caps);
- RUN_TEST(caps_and_capslock_gives_caps);
- RUN_TEST(caps_and_capslock_and_release_gives_caps);
- RUN_TEST(caps_and_capslock_and_release_and_capslock_gives_plain);
// toggle shiftlock_mode switches the shiftlock behavior to toggle_mode
// calling toggle_shiftlock_mode twice leaves shiftlock behavior in hold mode
// calling toggle_shiftlock_mode three times leaves shiftlock behavior in toggle mode