diff --git a/ArduinoKeyboard.ino b/ArduinoKeyboard.ino index 4627e023..9a0dc24b 100644 --- a/ArduinoKeyboard.ino +++ b/ArduinoKeyboard.ino @@ -18,6 +18,7 @@ #include "ArduinoKeyboard.h" #include // Don't need this for CLI compilation, but do need it in the IDE +#include void setup_matrix() { @@ -70,11 +71,11 @@ void scan_matrix() { //scan the Keyboard matrix looking for connections for (byte row = 0; row < ROWS; row++) { - digitalWrite(rowPins[row], LOW); + digitalWriteFast(rowPins[row], LOW); for (byte col = 0; col < COLS; col++) { //If we see an electrical connection on I->J, - if (digitalRead(colPins[col])) { + if (digitalReadFast(colPins[col])) { matrixState[row][col] |= 0; } else { matrixState[row][col] |= 1; @@ -89,7 +90,7 @@ void scan_matrix() set_keymap(keymaps[active_keymap][row][col], matrixState[row][col]); } - digitalWrite(rowPins[row], HIGH); + digitalWriteFast(rowPins[row], HIGH); } } @@ -468,12 +469,12 @@ void setup_pins() //set up the row pins as outputs for (byte row = 0; row < ROWS; row++) { pinMode(rowPins[row], OUTPUT); - digitalWrite(rowPins[row], HIGH); + digitalWriteFast(rowPins[row], HIGH); } for (byte col = 0; col < COLS; col++) { pinMode(colPins[col], INPUT); - digitalWrite(colPins[col], HIGH); + digitalWriteFast(colPins[col], HIGH); //drive em high by default s it seems to be more reliable than driving em low } diff --git a/digitalWriteFast.h b/digitalWriteFast.h new file mode 100644 index 00000000..71c5cf7b --- /dev/null +++ b/digitalWriteFast.h @@ -0,0 +1,174 @@ +#if ARDUINO >= 100 +#include +#else +#include "WProgram.h" +#include +#endif + +#define BIT_READ(value, bit) (((value) >> (bit)) & 0x01) +#define BIT_SET(value, bit) ((value) |= (1UL << (bit))) +#define BIT_CLEAR(value, bit) ((value) &= ~(1UL << (bit))) +#define BIT_WRITE(value, bit, bitvalue) (bitvalue ? BIT_SET(value, bit) : BIT_CLEAR(value, bit)) + +#if !defined(digitalPinToPortReg) +#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) +// Arduino Mega Pins +#define digitalPinToPortReg(P) \ +(((P) >= 22 && (P) <= 29) ? &PORTA : \ +((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PORTB : \ +(((P) >= 30 && (P) <= 37) ? &PORTC : \ +((((P) >= 18 && (P) <= 21) || (P) == 38 || ((P) >= 78 && (P) <= 80)) ? &PORTD : \ +((((P) >= 0 && (P) <= 3) || (P) == 5 || ((P) >= 83 && (P) <= 85)) ? &PORTE : \ +(((P) >= 54 && (P) <= 61) ? &PORTF : \ +((((P) >= 39 && (P) <= 41) || (P) == 4 || (P) == 81 || (P) == 82) ? &PORTG : \ +((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17 || (P) == 70 || (P) == 71) ? &PORTH : \ +(((P) == 14 || (P) == 15 || ((P) >= 72 && (P) <= 77)) ? &PORTJ : \ +(((P) >= 62 && (P) <= 69) ? &PORTK : &PORTL)))))))))) + +#define digitalPinToDDRReg(P) \ +(((P) >= 22 && (P) <= 29) ? &DDRA : \ +((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &DDRB : \ +(((P) >= 30 && (P) <= 37) ? &DDRC : \ +((((P) >= 18 && (P) <= 21) || (P) == 38 || ((P) >= 78 && (P) <= 80)) ? &DDRD : \ +((((P) >= 0 && (P) <= 3) || (P) == 5 || ((P) >= 83 && (P) <= 85)) ? &DDRE : \ +(((P) >= 54 && (P) <= 61) ? &DDRF : \ +((((P) >= 39 && (P) <= 41) || (P) == 4 || (P) == 81 || (P) == 82) ? &DDRG : \ +((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17 || (P) == 70 || (P) == 71) ? &DDRH : \ +(((P) == 14 || (P) == 15 || ((P) >= 72 && (P) <= 77)) ? &DDRJ : \ +(((P) >= 62 && (P) <= 69) ? &DDRK : &DDRL)))))))))) + +#define digitalPinToPINReg(P) \ +(((P) >= 22 && (P) <= 29) ? &PINA : \ +((((P) >= 10 && (P) <= 13) || ((P) >= 50 && (P) <= 53)) ? &PINB : \ +(((P) >= 30 && (P) <= 37) ? &PINC : \ +((((P) >= 18 && (P) <= 21) || (P) == 38 || ((P) >= 78 && (P) <= 80)) ? &PIND : \ +((((P) >= 0 && (P) <= 3) || (P) == 5 || ((P) >= 83 && (P) <= 85)) ? &PINE : \ +(((P) >= 54 && (P) <= 61) ? &PINF : \ +((((P) >= 39 && (P) <= 41) || (P) == 4 || (P) == 81 || (P) == 82) ? &PING : \ +((((P) >= 6 && (P) <= 9) || (P) == 16 || (P) == 17 || (P) == 70 || (P) == 71) ? &PINH : \ +(((P) == 14 || (P) == 15 || ((P) >= 72 && (P) <= 77)) ? &PINJ : \ +(((P) >= 62 && (P) <= 69) ? &PINK : &PINL)))))))))) + + +#define __digitalPinToBit(P) \ +(((P) >= 7 && (P) <= 9) ? (P) - 3 : \ +(((P) >= 10 && (P) <= 13) ? (P) - 6 : \ +(((P) >= 22 && (P) <= 29) ? (P) - 22 : \ +(((P) >= 30 && (P) <= 37) ? 37 - (P) : \ +(((P) >= 39 && (P) <= 41) ? 41 - (P) : \ +(((P) >= 42 && (P) <= 49) ? 49 - (P) : \ +(((P) >= 50 && (P) <= 53) ? 53 - (P) : \ +(((P) >= 54 && (P) <= 61) ? (P) - 54 : \ +(((P) >= 62 && (P) <= 69) ? (P) - 62 : \ +(((P) == 70) ? 2 : \ +(((P) == 71) ? 7 : \ +(((P) >= 72 && (P) <= 77) ? (P) - 70 : \ +(((P) >= 78 && (P) <= 80) ? (P) - 74 : \ +(((P) == 81) ? 4 : \ +(((P) == 82) ? 3 : \ +(((P) == 83) ? 7 : \ +(((P) == 84) ? 6 : \ +(((P) == 85) ? 2 : \ +(((P) == 0 || (P) == 15 || (P) == 17 || (P) == 21) ? 0 : \ +(((P) == 1 || (P) == 14 || (P) == 16 || (P) == 20) ? 1 : \ +(((P) == 19) ? 2 : \ +(((P) == 5 || (P) == 6 || (P) == 18) ? 3 : \ +(((P) == 2) ? 4 : \ +(((P) == 3 || (P) == 4) ? 5 : 7)))))))))))))))))))))))) + +// 15 PWM +#define __digitalPinToTimer(P) \ +(((P) == 13 || (P) == 4) ? &TCCR0A : \ +(((P) == 11 || (P) == 12) ? &TCCR1A : \ +(((P) == 10 || (P) == 9) ? &TCCR2A : \ +(((P) == 5 || (P) == 2 || (P) == 3) ? &TCCR3A : \ +(((P) == 6 || (P) == 7 || (P) == 8) ? &TCCR4A : \ +(((P) == 46 || (P) == 45 || (P) == 44) ? &TCCR5A : 0)))))) +#define __digitalPinToTimerBit(P) \ +(((P) == 13) ? COM0A1 : (((P) == 4) ? COM0B1 : \ +(((P) == 11) ? COM1A1 : (((P) == 12) ? COM1B1 : \ +(((P) == 10) ? COM2A1 : (((P) == 9) ? COM2B1 : \ +(((P) == 5) ? COM3A1 : (((P) == 2) ? COM3B1 : (((P) == 3) ? COM3C1 : \ +(((P) == 6) ? COM4A1 : (((P) == 7) ? COM4B1 : (((P) == 8) ? COM4C1 : \ +(((P) == 46) ? COM5A1 : (((P) == 45) ? COM5B1 : COM5C1)))))))))))))) + +#else + +// Standard Arduino Pins +#define digitalPinToPortReg(P) \ +(((P) >= 0 && (P) <= 7) ? &PORTD : (((P) >= 8 && (P) <= 13) ? &PORTB : &PORTC)) +#define digitalPinToDDRReg(P) \ +(((P) >= 0 && (P) <= 7) ? &DDRD : (((P) >= 8 && (P) <= 13) ? &DDRB : &DDRC)) +#define digitalPinToPINReg(P) \ +(((P) >= 0 && (P) <= 7) ? &PIND : (((P) >= 8 && (P) <= 13) ? &PINB : &PINC)) +#define __digitalPinToBit(P) \ +(((P) >= 0 && (P) <= 7) ? (P) : (((P) >= 8 && (P) <= 13) ? (P) - 8 : (P) - 14)) + +#if defined(__AVR_ATmega8__) +// 3 PWM +#define __digitalPinToTimer(P) \ +(((P) == 9 || (P) == 10) ? &TCCR1A : (((P) == 11) ? &TCCR2 : 0)) +#define __digitalPinToTimerBit(P) \ +(((P) == 9) ? COM1A1 : (((P) == 10) ? COM1B1 : COM21)) +#else //168,328 + +// 6 PWM +#define __digitalPinToTimer(P) \ +(((P) == 6 || (P) == 5) ? &TCCR0A : \ +(((P) == 9 || (P) == 10) ? &TCCR1A : \ +(((P) == 11 || (P) == 3) ? &TCCR2A : 0))) +#define __digitalPinToTimerBit(P) \ +(((P) == 6) ? COM0A1 : (((P) == 5) ? COM0B1 : \ +(((P) == 9) ? COM1A1 : (((P) == 10) ? COM1B1 : \ +(((P) == 11) ? COM2A1 : COM2B1))))) +#endif //defined(__AVR_ATmega8__) + + +#endif //mega +#endif //#if !defined(digitalPinToPortReg) + + + + +#define __atomicWrite__(A,P,V) \ +if ( (int)(A) < 0x40) { bitWrite(*(A), __digitalPinToBit(P), (V) );} \ +else { \ +uint8_t register saveSreg = SREG; \ +cli(); \ +bitWrite(*(A), __digitalPinToBit(P), (V) ); \ +SREG=saveSreg; \ +} + + +#ifndef digitalWriteFast +#define digitalWriteFast(P, V) \ +do { \ +if (__builtin_constant_p(P) && __builtin_constant_p(V)) __atomicWrite__((uint8_t*) digitalPinToPortReg(P),P,V) \ +else digitalWrite((P), (V)); \ +}while (0) +#endif //#ifndef digitalWriteFast2 + +#if !defined(pinModeFast) +#define pinModeFast(P, V) \ +do {if (__builtin_constant_p(P) && __builtin_constant_p(V)) __atomicWrite__((uint8_t*) digitalPinToDDRReg(P),P,V) \ +else pinMode((P), (V)); \ +} while (0) +#endif + + +#ifndef noAnalogWrite +#define noAnalogWrite(P) \ + do {if (__builtin_constant_p(P) ) __atomicWrite((uint8_t*) __digitalPinToTimer(P),P,0) \ + else turnOffPWM((P)); \ +} while (0) +#endif + + +#ifndef digitalReadFast + #define digitalReadFast(P) ( (int) _digitalReadFast_((P)) ) + #define _digitalReadFast_(P ) \ + (__builtin_constant_p(P) ) ? ( \ + ( BIT_READ(*digitalPinToPINReg(P), __digitalPinToBit(P))) ) : \ + digitalRead((P)) +#endif +