diff --git a/src/kaleidoscope/driver/MCU.h b/src/kaleidoscope/driver/MCU.h new file mode 100644 index 00000000..e04d76e1 --- /dev/null +++ b/src/kaleidoscope/driver/MCU.h @@ -0,0 +1,59 @@ +/* -*- mode: c++ -*- + * kaleidoscope::driver::mcu -- Various MCU drivers + * Copyright (C) 2019 Keyboard.io, Inc + * + * 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, version 3. + * + * 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 . + */ + +#pragma once + +namespace kaleidoscope { +namespace driver { +namespace mcu { + +class ATMega32U4 { + public: + ATMega32U4() {} + + static inline void disableJTAG() { + /* These two lines here are the result of many hours spent chasing ghosts. + * These are great lines, and we love them dearly, for they make a set of + * pins that would otherwise be reserved for JTAG accessible from the + * firmware. + * + * Most AVR chips that get put into keyboards have the JTAG port disabled in + * fuses, but some do not. When they're used for JTAG, then no matter what + * we do in the firmware, they will not be affected. So in case JTAG is not + * disabled in fuses, we want to do that in the firmware. Luckily for us, + * that's doable, we just have to write the JTD bit into MCUCR twice within + * four cycles. These two lines do just that. + * + * For more information, see the ATMega16U4/ATMega32U4 datasheet, the + * following sections: + * - 2.2.7 (PIN Descriptions; PIN F) + * - 7.8.7 (On-chip Debug System) + * - 26.5.1 (MCU Control Register – MCUCR) + */ + MCUCR |= (1 << JTD); + MCUCR |= (1 << JTD); + } + + static inline void disableClockDivision() { + CLKPR = (1 << CLKPCE); + CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); + } +}; + +} +} +} diff --git a/src/kaleidoscope/hardware/ATMegaKeyboard.h b/src/kaleidoscope/hardware/ATMegaKeyboard.h index 88320fe4..32191883 100644 --- a/src/kaleidoscope/hardware/ATMegaKeyboard.h +++ b/src/kaleidoscope/hardware/ATMegaKeyboard.h @@ -40,6 +40,7 @@ struct cRGB { #endif #include "kaleidoscope/Hardware.h" +#include "kaleidoscope/driver/MCU.h" #define ROW_PIN_LIST(...) __VA_ARGS__ #define COL_PIN_LIST(...) __VA_ARGS__ @@ -92,6 +93,9 @@ class ATMegaKeyboard : public kaleidoscope::Hardware { static bool do_scan_; + protected: + kaleidoscope::driver::mcu::ATMega32U4 mcu_; + private: uint16_t readCols(); diff --git a/src/kaleidoscope/hardware/kbdfans/KBD4x.h b/src/kaleidoscope/hardware/kbdfans/KBD4x.h index 11951015..439b2404 100644 --- a/src/kaleidoscope/hardware/kbdfans/KBD4x.h +++ b/src/kaleidoscope/hardware/kbdfans/KBD4x.h @@ -34,30 +34,8 @@ namespace kbdfans { class KBD4x: public kaleidoscope::hardware::ATMegaKeyboard { public: KBD4x(void) { - /* These two lines here are the result of many hours spent chasing ghosts. - * These are great lines, and we love them dearly, for they make a set of - * pins that would otherwise be reserved for JTAG accessible from the - * firmware. - * - * Most AVR chips that get put into keyboards have the JTAG port disabled in - * fuses, but some do not. When they're used for JTAG, then no matter what - * we do in the firmware, they will not be affected. So in case JTAG is not - * disabled in fuses, we want to do that in the firmware. Luckily for us, - * that's doable, we just have to write the JTD bit into MCUCR twice within - * four cycles. These two lines do just that. - * - * For more information, see the ATMega16U4/ATMega32U4 datasheet, the - * following sections: - * - 2.2.7 (PIN Descriptions; PIN F) - * - 7.8.7 (On-chip Debug System) - * - 26.5.1 (MCU Control Register – MCUCR) - */ - MCUCR |= (1 << JTD); - MCUCR |= (1 << JTD); - - // Disable Clock division - CLKPR = (1 << CLKPCE); - CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0); + mcu_.disableJTAG(); + mcu_.disableClockDivision(); } ATMEGA_KEYBOARD_CONFIG( diff --git a/src/kaleidoscope/hardware/softhruf/Splitography.h b/src/kaleidoscope/hardware/softhruf/Splitography.h index 01d42b77..073d3c0a 100644 --- a/src/kaleidoscope/hardware/softhruf/Splitography.h +++ b/src/kaleidoscope/hardware/softhruf/Splitography.h @@ -41,26 +41,7 @@ namespace softhruf { class Splitography: public kaleidoscope::hardware::ATMegaKeyboard { public: Splitography(void) { - /* These two lines here are the result of many hours spent chasing ghosts. - * These are great lines, and we love them dearly, for they make a set of - * pins that would otherwise be reserved for JTAG accessible from the - * firmware. - * - * Most AVR chips that get put into keyboards have the JTAG port disabled in - * fuses, but some do not. When they're used for JTAG, then no matter what - * we do in the firmware, they will not be affected. So in case JTAG is not - * disabled in fuses, we want to do that in the firmware. Luckily for us, - * that's doable, we just have to write the JTD bit into MCUCR twice within - * four cycles. These two lines do just that. - * - * For more information, see the ATMega16U4/ATMega32U4 datasheet, the - * following sections: - * - 2.2.7 (PIN Descriptions; PIN F) - * - 7.8.7 (On-chip Debug System) - * - 26.5.1 (MCU Control Register – MCUCR) - */ - MCUCR |= (1 << JTD); - MCUCR |= (1 << JTD); + mcu_.disableJTAG(); } ATMEGA_KEYBOARD_CONFIG(