From 4a784b998a62555cf67811929a653f4eb369f168 Mon Sep 17 00:00:00 2001 From: tmk Date: Sun, 6 Feb 2022 16:40:22 +0900 Subject: [PATCH] ibmpc: Naked ISR with Fixed register:r2 #717 --- converter/ibmpc_usb/Makefile | 3 +++ tmk_core/protocol/ibmpc.cpp | 36 ++++++++++++++++++++++++++++-------- tmk_core/protocol/ibmpc.hpp | 1 - 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/converter/ibmpc_usb/Makefile b/converter/ibmpc_usb/Makefile index 3cb7a7600a..fa6182bc93 100644 --- a/converter/ibmpc_usb/Makefile +++ b/converter/ibmpc_usb/Makefile @@ -88,6 +88,9 @@ IBMPC_MOUSE_ENABLE ?= yes # enable mouse support(+2000) # Optimize size but this may cause error "relocation truncated to fit" #EXTRALDFLAGS = -Wl,--relax +# Fixed register r2 for reading data line +EXTRAFLAGS ?= -ffixed-r2 + # # Keymap file diff --git a/tmk_core/protocol/ibmpc.cpp b/tmk_core/protocol/ibmpc.cpp index e9af15c653..ca13a2c28d 100644 --- a/tmk_core/protocol/ibmpc.cpp +++ b/tmk_core/protocol/ibmpc.cpp @@ -206,8 +206,7 @@ void IBMPC::host_isr_clear(void) void IBMPC::isr(void) { - uint8_t dbit; - dbit = IBMPC_DATA_PIN&(1<>1; - if (dbit) isr_state |= 0x8000; + if (STORED_PIN & data_mask) isr_state |= 0x8000; // isr_state: state of receiving data from keyboard // @@ -392,17 +391,38 @@ void IBMPC::host_set_led(uint8_t led) } -// NOTE: With this ISR data line should be read within 5us after clock falling edge. -// Confirmed that ATmega32u4 can read data line in 2.5us from interrupt after -// ISR prologue pushs r18, r19, r20, r21, r24, r25 r30 and r31 with GCC 5.4.0 -ISR(IBMPC_INT_VECT) +// This generates prologue/epilogue code just like one for not-naked ISR +extern "C" void ibmpc_isr(void) __attribute__ ((signal,__INTR_ATTRS)); +void ibmpc_isr(void) { IBMPC::interface0.isr(); } +// This reads data line and store in r2 immediately without prologue code +ISR(IBMPC_INT_VECT, ISR_NAKED) +{ + asm volatile ( + "in r2, %[pin]" "\n\t" + "rjmp ibmpc_isr" "\n\t" + : + : [pin] "I" (_SFR_IO_ADDR(IBMPC_DATA_PIN)) + ); +} + #if defined(IBMPC_CLOCK_BIT1) && defined(IBMPC_DATA_BIT1) && defined(IBMPC_INT_VECT1) -ISR(IBMPC_INT_VECT1) +extern "C" void ibmpc_isr1(void) __attribute__ ((signal,__INTR_ATTRS)); +void ibmpc_isr1(void) { IBMPC::interface1.isr(); } + +ISR(IBMPC_INT_VECT1, ISR_NAKED) +{ + asm volatile ( + "in r2, %[pin]" "\n\t" + "rjmp ibmpc_isr1" "\n\t" + : + : [pin] "I" (_SFR_IO_ADDR(IBMPC_DATA_PIN)) + ); +} #endif diff --git a/tmk_core/protocol/ibmpc.hpp b/tmk_core/protocol/ibmpc.hpp index d1765e7f09..522df35a68 100644 --- a/tmk_core/protocol/ibmpc.hpp +++ b/tmk_core/protocol/ibmpc.hpp @@ -90,7 +90,6 @@ POSSIBILITY OF SUCH DAMAGE. #define IBMPC_LED_NUM_LOCK 1 #define IBMPC_LED_CAPS_LOCK 2 - class IBMPC { public: