From c68e596f32c5d450a714627871408407e9988ef7 Mon Sep 17 00:00:00 2001 From: Priyadi Iman Nurcahyo Date: Mon, 13 Feb 2017 08:03:07 +0700 Subject: Implement faux-clicky feature --- quantum/fauxclicky.c | 68 ++++++++++++++++++++++++++++++++++++ quantum/fauxclicky.h | 87 +++++++++++++++++++++++++++++++++++++++++++++++ quantum/template/rules.mk | 1 + 3 files changed, 156 insertions(+) create mode 100644 quantum/fauxclicky.c create mode 100644 quantum/fauxclicky.h (limited to 'quantum') diff --git a/quantum/fauxclicky.c b/quantum/fauxclicky.c new file mode 100644 index 0000000000..13273e7058 --- /dev/null +++ b/quantum/fauxclicky.c @@ -0,0 +1,68 @@ +/* +Copyright 2017 Priyadi Iman Nurcahyo + +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 2 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 . +*/ + +#include +#include +#include +#include +#include +#include + +__attribute__ ((weak)) +float fauxclicky_pressed_note[2] = MUSICAL_NOTE(_F3, 2); +__attribute__ ((weak)) +float fauxclicky_released_note[2] = MUSICAL_NOTE(_A3, 2); +__attribute__ ((weak)) +float fauxclicky_beep_note[2] = MUSICAL_NOTE(_C3, 2); + +bool fauxclicky_enabled = true; +uint16_t note_start = 0; +bool note_playing = false; +uint16_t note_period = 0; + +void fauxclicky_init() +{ + // Set port PC6 (OC3A and /OC4A) as output + DDRC |= _BV(PORTC6); + + // TCCR3A / TCCR3B: Timer/Counter #3 Control Registers + TCCR3A = (0 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30); + TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30); +} + +void fauxclicky_stop() +{ + FAUXCLICKY_DISABLE_OUTPUT; + note_playing = false; +} + +void fauxclicky_play(float note[2]) { + if (!fauxclicky_enabled) return; + if (note_playing) fauxclicky_stop(); + FAUXCLICKY_TIMER_PERIOD = (uint16_t)(((float)F_CPU) / (note[0] * FAUXCLICKY_CPU_PRESCALER)); + FAUXCLICKY_DUTY_CYCLE = (uint16_t)((((float)F_CPU) / (note[0] * FAUXCLICKY_CPU_PRESCALER)) / 2); + note_playing = true; + note_period = (note[1] / 16) * (60 / (float)FAUXCLICKY_TEMPO) * 100; // check this + note_start = timer_read(); + FAUXCLICKY_ENABLE_OUTPUT; +} + +void fauxclicky_check() { + if (!note_playing) return; + + if (timer_elapsed(note_start) > note_period) { + fauxclicky_stop(); + } +} diff --git a/quantum/fauxclicky.h b/quantum/fauxclicky.h new file mode 100644 index 0000000000..6cfc291c05 --- /dev/null +++ b/quantum/fauxclicky.h @@ -0,0 +1,87 @@ +/* +Copyright 2017 Priyadi Iman Nurcahyo + +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 2 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 . +*/ + +#ifdef AUDIO_ENABLE +#error "AUDIO_ENABLE and FAUXCLICKY_ENABLE cannot be both enabled" +#endif + +#include "musical_notes.h" + +__attribute__ ((weak)) +float fauxclicky_pressed_note[2]; +__attribute__ ((weak)) +float fauxclicky_released_note[2]; +__attribute__ ((weak)) +float fauxclicky_beep_note[2]; + +// +// tempo in BPM +// + +#ifndef FAUXCLICKY_TEMPO +#define FAUXCLICKY_TEMPO TEMPO_DEFAULT +#endif + +// beep on press +#define FAUXCLICKY_ACTION_PRESS fauxclicky_play(fauxclicky_pressed_note) + +// beep on release +#define FAUXCLICKY_ACTION_RELEASE fauxclicky_play(fauxclicky_released_note) + +// general purpose beep +#define FAUXCLICKY_BEEP fauxclicky_play(fauxclicky_beep_note) + +// enable +#define FAUXCLICKY_ON fauxclicky_enabled = true + +// disable +#define FAUXCLICKY_OFF do { \ + fauxclicky_enabled = false; \ + fauxclicky_stop(); \ +} while (0) + +// +// pin configuration +// + +#ifndef FAUXCLICKY_CPU_PRESCALER +#define FAUXCLICKY_CPU_PRESCALER 8 +#endif + +#ifndef FAUXCLICKY_ENABLE_OUTPUT +#define FAUXCLICKY_ENABLE_OUTPUT TCCR3A |= _BV(COM3A1); +#endif + +#ifndef FAUXCLICKY_DISABLE_OUTPUT +#define FAUXCLICKY_DISABLE_OUTPUT TCCR3A &= ~(_BV(COM3A1) | _BV(COM3A0)); +#endif + +#ifndef FAUXCLICKY_TIMER_PERIOD +#define FAUXCLICKY_TIMER_PERIOD ICR3 +#endif + +#ifndef FAUXCLICKY_DUTY_CYCLE +#define FAUXCLICKY_DUTY_CYCLE OCR3A +#endif + +// +// definitions +// + +void fauxclicky_init(void); +void fauxclicky_stop(void); +void fauxclicky_play(float note[2]); +void fauxclicky_check(void); + diff --git a/quantum/template/rules.mk b/quantum/template/rules.mk index 55898147dd..bad3387bf4 100644 --- a/quantum/template/rules.mk +++ b/quantum/template/rules.mk @@ -65,3 +65,4 @@ MIDI_ENABLE ?= no # MIDI controls UNICODE_ENABLE ?= no # Unicode BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID AUDIO_ENABLE ?= no # Audio output on port C6 +FAUXCLICKY_ENABLE ?= no # Use buzzer to emulate clicky switches -- cgit v1.2.3