From 543ab89bbf746b199c8d60b7556c2b89557c61af Mon Sep 17 00:00:00 2001 From: Necroware Date: Mon, 7 Feb 2022 22:58:40 +0100 Subject: [PATCH 1/3] DigitalPin wait() optimizations --- firmware/gameport-adapter/DigitalPin.h | 54 ++++++++++--------- .../gameport-adapter/gameport-adapter.ino | 2 +- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/firmware/gameport-adapter/DigitalPin.h b/firmware/gameport-adapter/DigitalPin.h index a57b293..d095013 100644 --- a/firmware/gameport-adapter/DigitalPin.h +++ b/firmware/gameport-adapter/DigitalPin.h @@ -101,46 +101,31 @@ class DigitalInput { /// Gets the value of the input. bool get() const { - return m_input & m_pin.mask; + return read(); } /// Checks if the input is high. bool isHigh() const { - return get(); + return read(); } /// Checks if the input is low bool isLow() const { - return !get(); + return !read(); } /// Waits for an edge with given timeout. /// @param[in] edge is the type of edge to wait for /// @param[in] timeount is the timeout in microseconds uint16_t wait(Edge edge, uint16_t timeout) const { - auto last = get(); - for (; timeout; timeout--) { - const auto next = get(); - if (last == next) { - continue; - } - switch (edge) { - case Edge::falling: - if (last > next) { - return timeout; - } - break; - case Edge::rising: - if (last < next) { - return timeout; - } - break; - case Edge::any: - return timeout; - } - last = next; + if (edge == Edge::falling) { + return waitImpl(timeout, [](uint8_t a, uint8_t) {return a;}); } - return 0u; + if (edge == Edge::rising) { + return waitImpl(timeout, [](uint8_t, uint8_t b) {return b;}); + } + // edge == Edge::rising + return waitImpl(timeout, [](uint8_t a, uint8_t b) {return a|b;}); } /// Waits for a state with given timeout. @@ -155,4 +140,23 @@ class DigitalInput { private: DigitalPin m_pin; volatile typename DigitalPin::RegType &m_input; + + uint8_t read() const { + return m_input & m_pin.mask; + } + + template + uint16_t waitImpl(uint16_t timeout, T compare) const { + auto last = read(); + for (; timeout; timeout--) { + const auto next = read(); + if (last != next) { + if (compare(last, next)) { + return timeout; + } + last = next; + } + } + return 0u; + } }; diff --git a/firmware/gameport-adapter/gameport-adapter.ino b/firmware/gameport-adapter/gameport-adapter.ino index 2c9b9a1..1dceade 100644 --- a/firmware/gameport-adapter/gameport-adapter.ino +++ b/firmware/gameport-adapter/gameport-adapter.ino @@ -49,7 +49,7 @@ static Joystick *createJoystick(byte sw) { static HidJoystick hidJoystick; void setup() { - //Serial.begin(9600); + Serial.begin(9600); //while(!Serial); const auto sw1 = DigitalInput<14, true>{}.isLow(); const auto sw2 = DigitalInput<15, true>{}.isLow(); From 3449948d15a915bee7b78d9abd0d6880e8edbfe8 Mon Sep 17 00:00:00 2001 From: Necroware Date: Mon, 7 Feb 2022 23:16:05 +0100 Subject: [PATCH 2/3] Reverted some unneeded changes --- firmware/gameport-adapter/DigitalPin.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/gameport-adapter/DigitalPin.h b/firmware/gameport-adapter/DigitalPin.h index d095013..2b762b6 100644 --- a/firmware/gameport-adapter/DigitalPin.h +++ b/firmware/gameport-adapter/DigitalPin.h @@ -106,12 +106,12 @@ class DigitalInput { /// Checks if the input is high. bool isHigh() const { - return read(); + return get(); } /// Checks if the input is low bool isLow() const { - return !read(); + return !get(); } /// Waits for an edge with given timeout. From 4e5c81255e7af782aab8c76239a49beb2d331b5b Mon Sep 17 00:00:00 2001 From: Necroware Date: Tue, 8 Feb 2022 16:11:13 +0100 Subject: [PATCH 3/3] Reduced bit read delay further --- firmware/gameport-adapter/DigitalPin.h | 16 ++++++---------- firmware/gameport-adapter/GrIP.h | 2 +- firmware/gameport-adapter/Logitech.h | 4 +++- firmware/gameport-adapter/Sidewinder.h | 8 ++++---- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/firmware/gameport-adapter/DigitalPin.h b/firmware/gameport-adapter/DigitalPin.h index 2b762b6..c2e70ff 100644 --- a/firmware/gameport-adapter/DigitalPin.h +++ b/firmware/gameport-adapter/DigitalPin.h @@ -99,19 +99,19 @@ class DigitalInput { } } - /// Gets the value of the input. - bool get() const { - return read(); + /// Read raw bit data + uint8_t read() const { + return m_input & m_pin.mask; } /// Checks if the input is high. bool isHigh() const { - return get(); + return read(); } /// Checks if the input is low bool isLow() const { - return !get(); + return !read(); } /// Waits for an edge with given timeout. @@ -132,7 +132,7 @@ class DigitalInput { /// @param[in] state is the state to wait for /// @param[in] timeount is the timeout in microseconds uint16_t wait(bool state, uint16_t timeout) const { - for (; state != get() && timeout; timeout--) + for (; state != isHigh() && timeout; timeout--) ; return timeout; } @@ -141,10 +141,6 @@ class DigitalInput { DigitalPin m_pin; volatile typename DigitalPin::RegType &m_input; - uint8_t read() const { - return m_input & m_pin.mask; - } - template uint16_t waitImpl(uint16_t timeout, T compare) const { auto last = read(); diff --git a/firmware/gameport-adapter/GrIP.h b/firmware/gameport-adapter/GrIP.h index 67977eb..4a43048 100644 --- a/firmware/gameport-adapter/GrIP.h +++ b/firmware/gameport-adapter/GrIP.h @@ -103,7 +103,7 @@ class GrIP : public Joystick { if (!m_clock.wait(Edge::falling, 100)) { return 0u; } - result |= uint32_t(m_data.get()) << i; + result |= uint32_t(m_data.isHigh()) << i; } // alighn the bits to have the binary tag in front. This code diff --git a/firmware/gameport-adapter/Logitech.h b/firmware/gameport-adapter/Logitech.h index bfe8d74..a8892aa 100644 --- a/firmware/gameport-adapter/Logitech.h +++ b/firmware/gameport-adapter/Logitech.h @@ -175,7 +175,9 @@ class Logitech : public Joystick { } byte readData() const { - return m_data0.get() | m_data1.get() << 1; + const auto b0 = m_data0.read(); + const auto b1 = m_data1.read(); + return bool(b0) | bool(b1) << 1; } Packet readPacket() const { diff --git a/firmware/gameport-adapter/Sidewinder.h b/firmware/gameport-adapter/Sidewinder.h index be533b0..3e5d556 100644 --- a/firmware/gameport-adapter/Sidewinder.h +++ b/firmware/gameport-adapter/Sidewinder.h @@ -173,10 +173,10 @@ class Sidewinder : public Joystick { if (!m_clock.wait(Edge::rising, wait_duration)) { break; } - const uint8_t b1 = m_data0.get(); - const uint8_t b2 = m_data1.get(); - const uint8_t b3 = m_data2.get(); - packet.data[packet.size] = b1 | (b2 << 1) | (b3 << 2); + const auto b1 = m_data0.read(); + const auto b2 = m_data1.read(); + const auto b3 = m_data2.read(); + packet.data[packet.size] = bool(b1) | bool(b2) << 1 | bool(b3) << 2; } } m_trigger.setLow();