bluetooth
This commit is contained in:
parent
40148c430e
commit
c966e7982c
@ -68,6 +68,10 @@ ifdef BACKLIGHT_ENABLE
|
||||
OPT_DEFS += -DBACKLIGHT_ENABLE
|
||||
endif
|
||||
|
||||
ifdef BLUETOOTH_ENABLE
|
||||
OPT_DEFS += -DBLUETOOTH_ENABLE
|
||||
endif
|
||||
|
||||
ifdef KEYMAP_SECTION_ENABLE
|
||||
OPT_DEFS += -DKEYMAP_SECTION_ENABLE
|
||||
EXTRALDFLAGS = -Wl,-L$(TOP_DIR),-Tldscript_keymap_avr5.x
|
||||
|
@ -39,7 +39,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
// ┌─ 2u ────────────┐
|
||||
// │ X │
|
||||
// └─────────────────┘
|
||||
{ KC_LCTL, KC_LGUI, KC_LALT, KC_LGUI, KC_LCTL, KC_SPC, KC_SPC, KC_RALT, KC_RGUI, KC_RALT, KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT },
|
||||
{ BL_STEP, KC_LCTL, KC_LALT, KC_LGUI, KC_LGUI, KC_SPC, KC_SPC, KC_RGUI, KC_RGUI, KC_RALT, KC_RCTL, BL_STEP, KC_LEFT, KC_DOWN, KC_RGHT },
|
||||
// ┌────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
|
||||
// │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │
|
||||
// └────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
|
||||
|
@ -1,3 +1,3 @@
|
||||
dfu-programmer atmega32u4 erase --force
|
||||
dfu-programmer atmega32u4 flash planck_pcb.hex
|
||||
dfu-programmer atmega32u4 flash atomic_pcb.hex
|
||||
dfu-programmer atmega32u4 reset
|
@ -121,15 +121,16 @@ EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
|
||||
CONSOLE_ENABLE = yes # Console for debug(+400)
|
||||
COMMAND_ENABLE = yes # Commands for debug and configuration
|
||||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
||||
#SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
|
||||
# SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend
|
||||
# NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA
|
||||
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
|
||||
MIDI_ENABLE = YES # MIDI controls
|
||||
# MIDI_ENABLE = YES # MIDI controls
|
||||
# UNICODE_ENABLE = YES # Unicode
|
||||
# BLUETOOTH_ENABLE = yes # Enable Bluetooth with the Adafruit EZ-Key HID
|
||||
|
||||
ifdef MIDI_ENABLE
|
||||
SRC += keymap_midi.c \
|
||||
beeps.c
|
||||
SRC += keymap_midi.c
|
||||
# beeps.c
|
||||
endif
|
||||
|
||||
ifdef UNICODE_ENABLE
|
||||
@ -143,7 +144,18 @@ endif
|
||||
VPATH += $(TARGET_DIR)
|
||||
VPATH += $(TOP_DIR)
|
||||
|
||||
include $(TOP_DIR)/protocol/lufa.mk
|
||||
|
||||
|
||||
ifdef BLUETOOTH_ENABLE
|
||||
BLUEFRUIT_TRACE_SERIAL=true
|
||||
|
||||
include $(TOP_DIR)/protocol.mk
|
||||
include $(TOP_DIR)/protocol/bluefruit.mk
|
||||
include $(TOP_DIR)/protocol.mk
|
||||
else
|
||||
include $(TOP_DIR)/protocol/lufa.mk
|
||||
endif
|
||||
|
||||
include $(TOP_DIR)/common.mk
|
||||
include $(TOP_DIR)/rules.mk
|
||||
|
||||
|
@ -58,16 +58,83 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
|
||||
)
|
||||
|
||||
#ifdef BLUETOOTH_ENABLE
|
||||
#ifdef __AVR_ATmega32U4__
|
||||
#define SERIAL_UART_BAUD 9600
|
||||
#define SERIAL_UART_DATA UDR1
|
||||
#define SERIAL_UART_UBRR ((F_CPU/(16UL*SERIAL_UART_BAUD))-1)
|
||||
#define SERIAL_UART_RXD_VECT USART1_RX_vect
|
||||
#define SERIAL_UART_TXD_READY (UCSR1A&(1<<UDRE1))
|
||||
#define SERIAL_UART_INIT() do { \
|
||||
UBRR1L = (uint8_t) SERIAL_UART_UBRR; /* baud rate */ \
|
||||
UBRR1H = (uint8_t) (SERIAL_UART_UBRR>>8); /* baud rate */ \
|
||||
UCSR1B = (1<<TXEN1); /* TX: enable */ \
|
||||
UCSR1C = (0<<UPM11) | (0<<UPM10) | /* parity: none(00), even(01), odd(11) */ \
|
||||
(0<<UCSZ12) | (1<<UCSZ11) | (1<<UCSZ10); /* data-8bit(011) */ \
|
||||
sei(); \
|
||||
} while(0)
|
||||
#else
|
||||
# error "USART configuration is needed."
|
||||
#endif
|
||||
|
||||
|
||||
// I'm fairly sure these aren't needed, but oh well - Jack
|
||||
|
||||
/*
|
||||
* PS/2 Interrupt configuration
|
||||
*/
|
||||
#ifdef PS2_USE_INT
|
||||
/* uses INT1 for clock line(ATMega32U4) */
|
||||
#define PS2_CLOCK_PORT PORTD
|
||||
#define PS2_CLOCK_PIN PIND
|
||||
#define PS2_CLOCK_DDR DDRD
|
||||
#define PS2_CLOCK_BIT 1
|
||||
|
||||
#define PS2_DATA_PORT PORTD
|
||||
#define PS2_DATA_PIN PIND
|
||||
#define PS2_DATA_DDR DDRD
|
||||
#define PS2_DATA_BIT 0
|
||||
|
||||
#define PS2_INT_INIT() do { \
|
||||
EICRA |= ((1<<ISC11) | \
|
||||
(0<<ISC10)); \
|
||||
} while (0)
|
||||
#define PS2_INT_ON() do { \
|
||||
EIMSK |= (1<<INT1); \
|
||||
} while (0)
|
||||
#define PS2_INT_OFF() do { \
|
||||
EIMSK &= ~(1<<INT1); \
|
||||
} while (0)
|
||||
#define PS2_INT_VECT INT1_vect
|
||||
#endif
|
||||
|
||||
/*
|
||||
* PS/2 Busywait configuration
|
||||
*/
|
||||
#ifdef PS2_USE_BUSYWAIT
|
||||
#define PS2_CLOCK_PORT PORTD
|
||||
#define PS2_CLOCK_PIN PIND
|
||||
#define PS2_CLOCK_DDR DDRD
|
||||
#define PS2_CLOCK_BIT 1
|
||||
|
||||
#define PS2_DATA_PORT PORTD
|
||||
#define PS2_DATA_PIN PIND
|
||||
#define PS2_DATA_DDR DDRD
|
||||
#define PS2_DATA_BIT 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Feature disable options
|
||||
* These options are also useful to firmware size reduction.
|
||||
*/
|
||||
|
||||
/* disable debug print */
|
||||
#define NO_DEBUG
|
||||
// #define NO_DEBUG
|
||||
|
||||
/* disable print */
|
||||
#define NO_PRINT
|
||||
// #define NO_PRINT
|
||||
|
||||
/* disable action features */
|
||||
//#define NO_ACTION_LAYER
|
||||
|
@ -35,7 +35,7 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
|
||||
if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) {
|
||||
if (record->event.pressed) {
|
||||
starting_note++;
|
||||
// play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
|
||||
play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
|
||||
midi_send_cc(&midi_device, 0, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 1, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 2, 0x7B, 0);
|
||||
@ -43,15 +43,15 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
|
||||
midi_send_cc(&midi_device, 4, 0x7B, 0);
|
||||
return;
|
||||
} else {
|
||||
// stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)));
|
||||
// stop_all_notes();
|
||||
stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)));
|
||||
stop_all_notes();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) {
|
||||
if (record->event.pressed) {
|
||||
starting_note--;
|
||||
// play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
|
||||
play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
|
||||
midi_send_cc(&midi_device, 0, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 1, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 2, 0x7B, 0);
|
||||
@ -59,8 +59,8 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
|
||||
midi_send_cc(&midi_device, 4, 0x7B, 0);
|
||||
return;
|
||||
} else {
|
||||
// stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)));
|
||||
// stop_all_notes();
|
||||
stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)));
|
||||
stop_all_notes();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -72,13 +72,13 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
|
||||
midi_send_cc(&midi_device, 2, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 3, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 4, 0x7B, 0);
|
||||
// stop_all_notes();
|
||||
// for (int i = 0; i <= 7; i++) {
|
||||
// play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
|
||||
// _delay_us(80000);
|
||||
// stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)));
|
||||
// _delay_us(8000);
|
||||
// }
|
||||
stop_all_notes();
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
|
||||
_delay_us(80000);
|
||||
stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)));
|
||||
_delay_us(8000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
|
||||
@ -88,23 +88,23 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
|
||||
midi_send_cc(&midi_device, 2, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 3, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 4, 0x7B, 0);
|
||||
// stop_all_notes();
|
||||
// for (int i = 0; i <= 7; i++) {
|
||||
// play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
|
||||
// _delay_us(80000);
|
||||
// stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)));
|
||||
// _delay_us(8000);
|
||||
// }
|
||||
stop_all_notes();
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
|
||||
_delay_us(80000);
|
||||
stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)));
|
||||
_delay_us(8000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (record->event.pressed) {
|
||||
// midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
|
||||
midi_send_noteon(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127);
|
||||
// play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF);
|
||||
play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF);
|
||||
} else {
|
||||
// midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
|
||||
midi_send_noteoff(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127);
|
||||
// stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)));
|
||||
stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)));
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@
|
||||
#include "backlight.h"
|
||||
#include "action_layer.h"
|
||||
#include "keymap_midi.h"
|
||||
#include "beeps.h"
|
||||
#include <avr/boot.h>
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = { /* Qwerty */
|
||||
@ -53,6 +53,16 @@ const uint16_t PROGMEM fn_actions[] = {
|
||||
|
||||
};
|
||||
|
||||
uint16_t hextokeycode(int hex) {
|
||||
if (hex == 0x0) {
|
||||
return KC_0;
|
||||
} else if (hex < 0xA) {
|
||||
return KC_1 + (hex - 0x1);
|
||||
} else {
|
||||
return KC_A + (hex - 0xA);
|
||||
}
|
||||
}
|
||||
|
||||
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
|
||||
{
|
||||
// MACRODOWN only works in this function
|
||||
@ -64,6 +74,35 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
|
||||
backlight_set(BACKLIGHT_LEVELS);
|
||||
default_layer_and(0);
|
||||
default_layer_or((1<<5));
|
||||
|
||||
uint8_t low = boot_lock_fuse_bits_get(0x0000);
|
||||
uint8_t high = boot_lock_fuse_bits_get(0x0003);
|
||||
uint8_t ext = boot_lock_fuse_bits_get(0x0002);
|
||||
uint8_t lock = boot_lock_fuse_bits_get(0x0001);
|
||||
|
||||
register_code(hextokeycode((low & 0xF0) >> 4));
|
||||
unregister_code(hextokeycode((low & 0xF0) >> 4));
|
||||
register_code(hextokeycode((low & 0x0F)));
|
||||
unregister_code(hextokeycode((low & 0x0F)));
|
||||
|
||||
|
||||
register_code(hextokeycode((high & 0xF0) >> 4));
|
||||
unregister_code(hextokeycode((high & 0xF0) >> 4));
|
||||
register_code(hextokeycode((high & 0x0F)));
|
||||
unregister_code(hextokeycode((high & 0x0F)));
|
||||
|
||||
|
||||
register_code(hextokeycode((ext & 0xF0) >> 4));
|
||||
unregister_code(hextokeycode((ext & 0xF0) >> 4));
|
||||
register_code(hextokeycode((ext & 0x0F)));
|
||||
unregister_code(hextokeycode((ext & 0x0F)));
|
||||
|
||||
|
||||
register_code(hextokeycode((lock & 0xF0) >> 4));
|
||||
unregister_code(hextokeycode((lock & 0xF0) >> 4));
|
||||
register_code(hextokeycode((lock & 0x0F)));
|
||||
unregister_code(hextokeycode((lock & 0x0F)));
|
||||
|
||||
// note(0+12, 20);
|
||||
// note(0+24, 20);
|
||||
} else {
|
||||
|
1796
keyboard/planck/planck_with_bootloader.hex
Executable file
1796
keyboard/planck/planck_with_bootloader.hex
Executable file
File diff suppressed because it is too large
Load Diff
@ -127,7 +127,8 @@ MIDI_ENABLE = yes # MIDI controls
|
||||
BACKLIGHT_ENABLE = yes
|
||||
|
||||
ifdef MIDI_ENABLE
|
||||
SRC += keymap_midi.c
|
||||
SRC += keymap_midi.c \
|
||||
beeps.c
|
||||
endif
|
||||
|
||||
# Optimize size but this may cause error "relocation truncated to fit"
|
||||
|
@ -5,31 +5,6 @@
|
||||
#include <avr/io.h>
|
||||
|
||||
#define PI 3.14159265
|
||||
#define CHANNEL OCR1C
|
||||
|
||||
volatile uint16_t sample;
|
||||
uint16_t lastSample;
|
||||
|
||||
const int sounddata_length=200;
|
||||
|
||||
const unsigned char sounddata_data[] PROGMEM = {128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
|
||||
128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 129, 127, 129, 128, 127, 133,
|
||||
117, 109, 125, 121, 116, 132, 140, 126, 114, 114, 116, 120, 114, 93, 73, 66, 76, 116, 142, 129,
|
||||
128, 129, 120, 119, 118, 104, 87, 123, 181, 194, 196, 198, 189, 176, 160, 162, 172, 164, 164, 183,
|
||||
197, 188, 168, 167, 170, 165, 185, 209, 206, 196, 196, 199, 185, 162, 156, 167, 176, 173, 170, 166,
|
||||
151, 142, 140, 134, 130, 127, 113, 86, 67, 66, 69, 75, 73, 75, 86, 90, 91, 84, 65, 48,
|
||||
41, 30, 26, 56, 91, 88, 72, 70, 73, 82, 89, 73, 57, 60, 74, 89, 92, 77, 63, 60,
|
||||
53, 47, 56, 64, 63, 61, 56, 54, 52, 36, 16, 22, 51, 66, 67, 70, 76, 88, 99, 92,
|
||||
77, 74, 85, 100, 106, 97, 83, 85, 96, 108, 133, 160, 164};
|
||||
|
||||
void delay_us(int count) {
|
||||
while(count--) {
|
||||
@ -37,202 +12,235 @@ void delay_us(int count) {
|
||||
}
|
||||
}
|
||||
|
||||
int voices = 0;
|
||||
double frequency = 0;
|
||||
int volume = 0;
|
||||
int position = 0;
|
||||
|
||||
double frequencies[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
int volumes[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
bool sliding = false;
|
||||
#define RANGE 1000
|
||||
volatile int i=0; //elements of the wave
|
||||
|
||||
|
||||
void beeps() {
|
||||
// DDRB |= (1<<7);
|
||||
// PORTB &= ~(1<<7);
|
||||
|
||||
// // Use full 16-bit resolution.
|
||||
// ICR1 = 0xFFFF;
|
||||
|
||||
// // I could write a wall of text here to explain... but TL;DW
|
||||
// // Go read the ATmega32u4 datasheet.
|
||||
// // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on
|
||||
|
||||
// // Pin PB7 = OCR1C (Timer 1, Channel C)
|
||||
// // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0
|
||||
// // (i.e. start high, go low when counter matches.)
|
||||
// // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0
|
||||
// // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1
|
||||
|
||||
// TCCR1A = _BV(COM1C1) | _BV(WGM11); // = 0b00001010;
|
||||
// TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
|
||||
|
||||
|
||||
// // Turn off PWM control on PB7, revert to output low.
|
||||
// // TCCR1A &= ~(_BV(COM1C1));
|
||||
// // CHANNEL = ((1 << level) - 1);
|
||||
|
||||
// // Turn on PWM control of PB7
|
||||
// TCCR1A |= _BV(COM1C1);
|
||||
// // CHANNEL = level << OFFSET | 0x0FFF;
|
||||
// // CHANNEL = 0b1010101010101010;
|
||||
|
||||
// float x = 12;
|
||||
// float y = 24;
|
||||
// float length = 50;
|
||||
// float scale = 1;
|
||||
|
||||
// // int f1 = 1000000/440;
|
||||
// // int f2 = 1000000/880;
|
||||
// // for (uint32_t i = 0; i < length * 1000; i++) {
|
||||
// // // int frequency = 1/((sin(PI*2*i*scale*pow(2, x/12.0))*.5+1 + sin(PI*2*i*scale*pow(2, y/12.0))*.5+1) / 2);
|
||||
|
||||
// // ICR1 = f1; // Set max to the period
|
||||
// // OCR1C = f1 >> 1; // Set compare to half the period
|
||||
// // // _delay_us(10);
|
||||
// // }
|
||||
// int frequency = 1000000/440;
|
||||
// ICR1 = frequency; // Set max to the period
|
||||
// OCR1C = frequency >> 1; // Set compare to half the period
|
||||
// _delay_us(500000);
|
||||
|
||||
// TCCR1A &= ~(_BV(COM1C1));
|
||||
// CHANNEL = 0;
|
||||
play_notes();
|
||||
|
||||
|
||||
// play_note(55*pow(2, 0/12.0), 1);
|
||||
// play_note(55*pow(2, 12/12.0), 1);
|
||||
// play_note(55*pow(2, 24/12.0), 1);
|
||||
// play_note(55*pow(2, 0/12.0), 1);
|
||||
// play_note(55*pow(2, 12/12.0), 1);
|
||||
// play_note(55*pow(2, 24/12.0), 1);
|
||||
|
||||
// play_note(0, 4);
|
||||
|
||||
// play_note(55*pow(2, 0/12.0), 8);
|
||||
// play_note(55*pow(2, 12/12.0), 4);
|
||||
// play_note(55*pow(2, 10/12.0), 4);
|
||||
// play_note(55*pow(2, 12/12.0), 8);
|
||||
// play_note(55*pow(2, 10/12.0), 4);
|
||||
// play_note(55*pow(2, 7/12.0), 2);
|
||||
// play_note(55*pow(2, 8/12.0), 2);
|
||||
// play_note(55*pow(2, 7/12.0), 16);
|
||||
// play_note(0, 4);
|
||||
// play_note(55*pow(2, 3/12.0), 8);
|
||||
// play_note(55*pow(2, 5/12.0), 4);
|
||||
// play_note(55*pow(2, 7/12.0), 4);
|
||||
// play_note(55*pow(2, 7/12.0), 8);
|
||||
// play_note(55*pow(2, 5/12.0), 4);
|
||||
// play_note(55*pow(2, 3/12.0), 4);
|
||||
// play_note(55*pow(2, 2/12.0), 16);
|
||||
|
||||
|
||||
play_notes();
|
||||
}
|
||||
|
||||
void play_note(float freq, int length) {
|
||||
DDRB |= (1<<7);
|
||||
PORTB &= ~(1<<7);
|
||||
void send_freq(double freq, int vol) {
|
||||
int duty = (((double)F_CPU) / freq);
|
||||
ICR3 = duty; // Set max to the period
|
||||
OCR3A = duty >> (0x10 - vol); // Set compare to half the period
|
||||
}
|
||||
|
||||
void stop_all_notes() {
|
||||
voices = 0;
|
||||
TCCR3A = 0;
|
||||
TCCR3B = 0;
|
||||
frequency = 0;
|
||||
volume = 0;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
frequencies[i] = 0;
|
||||
volumes[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void stop_note(double freq) {
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
if (frequencies[i] == freq) {
|
||||
frequencies[i] = 0;
|
||||
volumes[i] = 0;
|
||||
for (int j = i; (j < 7); j++) {
|
||||
frequencies[j] = frequencies[j+1];
|
||||
frequencies[j+1] = 0;
|
||||
volumes[j] = volumes[j+1];
|
||||
volumes[j+1] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
voices--;
|
||||
if (voices < 0)
|
||||
voices = 0;
|
||||
if (voices == 0) {
|
||||
TCCR3A = 0;
|
||||
TCCR3B = 0;
|
||||
frequency = 0;
|
||||
volume = 0;
|
||||
} else {
|
||||
double freq = frequencies[voices - 1];
|
||||
int vol = volumes[voices - 1];
|
||||
if (frequency < freq) {
|
||||
sliding = true;
|
||||
for (double f = frequency; f <= freq; f += ((freq - frequency) / 500.0)) {
|
||||
send_freq(f, vol);
|
||||
}
|
||||
sliding = false;
|
||||
} else if (frequency > freq) {
|
||||
sliding = true;
|
||||
for (double f = frequency; f >= freq; f -= ((frequency - freq) / 500.0)) {
|
||||
send_freq(f, vol);
|
||||
}
|
||||
sliding = false;
|
||||
}
|
||||
send_freq(freq, vol);
|
||||
frequency = freq;
|
||||
volume = vol;
|
||||
}
|
||||
}
|
||||
|
||||
void init_notes() {
|
||||
// TCCR1A = (1 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (1 << WGM10);
|
||||
// TCCR1B = (1 << COM1B1) | (0 << COM1A0) | (1 << WGM13) | (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10);
|
||||
|
||||
// DDRC |= (1<<6);
|
||||
|
||||
// TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
|
||||
// TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (0 << CS31) | (1 << CS30);
|
||||
|
||||
// ICR3 = 0xFFFF;
|
||||
// OCR3A = (int)((float)wave[i]*ICR3/RANGE); //go to next array element
|
||||
|
||||
|
||||
// cli();
|
||||
|
||||
// /* Enable interrupt on timer2 == 127, with clk/8 prescaler. At 16MHz,
|
||||
// this gives a timer interrupt at 15625Hz. */
|
||||
// TIMSK3 = (1 << OCIE3A);
|
||||
|
||||
// /* clear/reset timer on match */
|
||||
// // TCCR3A = 1<<WGM31 | 0<<WGM30; CTC mode, reset on match
|
||||
// // TCCR3B = 0<<CS32 | 1<<CS31 | 0<<CS30; /* clk, /8 prescaler */
|
||||
|
||||
// TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
|
||||
// TCCR3B = (0 << WGM33) | (0 << WGM32) | (0 << CS32) | (0 << CS31) | (1 << CS30);
|
||||
|
||||
|
||||
// TCCR1A = (1 << COM1A1) | (0 << COM1A0) | (1 << WGM11) | (0 << WGM10);
|
||||
// TCCR1B = (1 << WGM12) | (0 << CS12) | (0 << CS11) | (1 << CS10);
|
||||
// // SPCR = 0x50;
|
||||
// // SPSR = 0x01;
|
||||
// DDRC |= (1<<6);
|
||||
// // ICR3 = 0xFFFF;
|
||||
// // OCR3A=80;
|
||||
// PORTC |= (1<<6);
|
||||
|
||||
// sei();
|
||||
}
|
||||
|
||||
// #define highByte(c) ((c >> 8) & 0x00FF)
|
||||
// #define lowByte(c) (c & 0x00FF)
|
||||
|
||||
ISR(TIMER3_COMPA_vect) {
|
||||
|
||||
if (ICR3 > 0 && !sliding) {
|
||||
switch (position) {
|
||||
case 0: {
|
||||
int duty = (((double)F_CPU) / (frequency));
|
||||
ICR3 = duty; // Set max to the period
|
||||
OCR3A = duty >> 1; // Set compare to half the period
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
int duty = (((double)F_CPU) / (frequency*2));
|
||||
ICR3 = duty; // Set max to the period
|
||||
OCR3A = duty >> 1; // Set compare to half the period
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
int duty = (((double)F_CPU) / (frequency*3));
|
||||
ICR3 = duty; // Set max to the period
|
||||
OCR3A = duty >> 1; // Set compare to half the period
|
||||
break;
|
||||
}
|
||||
}
|
||||
position = (position + 1) % 3;
|
||||
}
|
||||
// /* OCR2A has been cleared, per TCCR2A above */
|
||||
// // OCR3A = 127;
|
||||
|
||||
// // pos1 += incr1;
|
||||
// // pos2 += incr2;
|
||||
// // pos3 += incr3;
|
||||
|
||||
// // sample = sinewave[highByte(pos1)] + sinewave[highByte(pos2)] + sinewave[highByte(pos3)];
|
||||
|
||||
// // OCR3A = sample;
|
||||
|
||||
|
||||
// OCR3A=pgm_read_byte(&sinewave[pos1]);
|
||||
// pos1++;
|
||||
// // PORTC &= ~(1<<6);
|
||||
|
||||
// /* buffered, 1x gain, active mode */
|
||||
// // SPDR = highByte(sample) | 0x70;
|
||||
// // while (!(SPSR & (1<<SPIF)));
|
||||
|
||||
// // SPDR = lowByte(sample);
|
||||
// // while (!(SPSR & (1<<SPIF)));
|
||||
|
||||
// // PORTC |= (1<<6);
|
||||
}
|
||||
|
||||
void play_note(double freq, int vol) {
|
||||
|
||||
if (freq > 0) {
|
||||
int frequency = 1000000/freq;
|
||||
ICR1 = frequency; // Set max to the period
|
||||
OCR1C = frequency >> 1; // Set compare to half the period
|
||||
DDRC |= (1<<6);
|
||||
|
||||
TCCR1A = _BV(COM1C1) | _BV(WGM11); // = 0b00001010;
|
||||
TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001;
|
||||
}
|
||||
TCCR3A = (1 << COM3A1) | (0 << COM3A0) | (1 << WGM31) | (0 << WGM30);
|
||||
TCCR3B = (1 << WGM33) | (1 << WGM32) | (0 << CS32) | (1 << CS31) | (0 << CS30);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
_delay_us(50000);
|
||||
}
|
||||
|
||||
TCCR1A &= ~(_BV(COM1C1));
|
||||
}
|
||||
|
||||
// This is called at 8000 Hz to load the next sample.
|
||||
ISR(TIMER1_COMPA_vect) {
|
||||
if (sample >= sounddata_length) {
|
||||
if (sample == sounddata_length + lastSample) {
|
||||
TIMSK1 &= ~_BV(OCIE1A);
|
||||
|
||||
// Disable the per-sample timer completely.
|
||||
TCCR1B &= ~_BV(CS10);
|
||||
if (frequency != 0) {
|
||||
if (frequency < freq) {
|
||||
for (double f = frequency; f <= freq; f += ((freq - frequency) / 500.0)) {
|
||||
send_freq(f, vol);
|
||||
}
|
||||
} else if (frequency > freq) {
|
||||
for (double f = frequency; f >= freq; f -= ((frequency - freq) / 500.0)) {
|
||||
send_freq(f, vol);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
OCR1C = sounddata_length + lastSample - sample;
|
||||
}
|
||||
}
|
||||
else {
|
||||
OCR1C = pgm_read_byte(&sounddata_data[sample]);
|
||||
}
|
||||
send_freq(freq, vol);
|
||||
frequency = freq;
|
||||
volume = vol;
|
||||
|
||||
++sample;
|
||||
frequencies[voices] = frequency;
|
||||
volumes[voices] = volume;
|
||||
voices++;
|
||||
}
|
||||
// ICR3 = 0xFFFF;
|
||||
// for (int i = 0; i < 10000; i++) {
|
||||
// OCR3A = round((sin(i*freq)*.5)+.5)*0xFFFF;
|
||||
// // _delay_us(50);
|
||||
// }
|
||||
|
||||
// TCCR3A = 0;
|
||||
// TCCR3B = 0;
|
||||
}
|
||||
|
||||
void play_notes() {
|
||||
// void note(int x, float length) {
|
||||
// DDRC |= (1<<6);
|
||||
// int t = (int)(440*pow(2,-x/12.0)); // starting note
|
||||
// for (int y = 0; y < length*1000/t; y++) { // note length
|
||||
// PORTC |= (1<<6);
|
||||
// delay_us(t);
|
||||
// PORTC &= ~(1<<6);
|
||||
// delay_us(t);
|
||||
// }
|
||||
// PORTC &= ~(1<<6);
|
||||
// }
|
||||
|
||||
|
||||
// Set up Timer 2 to do pulse width modulation on the speaker
|
||||
// pin.
|
||||
|
||||
DDRB |= (1<<7);
|
||||
PORTB &= ~(1<<7);
|
||||
|
||||
// Use internal clock (datasheet p.160)
|
||||
// ASSR &= ~(_BV(EXCLK) | _BV(AS2));
|
||||
|
||||
// Set fast PWM mode (p.157)
|
||||
TCCR1A |= _BV(WGM21) | _BV(WGM20);
|
||||
TCCR1B &= ~_BV(WGM22);
|
||||
|
||||
// Do non-inverting PWM on pin OC2A (p.155)
|
||||
// On the Arduino this is pin 11.
|
||||
TCCR1A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
|
||||
TCCR1A &= ~(_BV(COM2B1) | _BV(COM2B0));
|
||||
// No prescaler (p.158)
|
||||
TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
|
||||
|
||||
// Set initial pulse width to the first sample.
|
||||
OCR1A = pgm_read_byte(&sounddata_data[0]);
|
||||
|
||||
|
||||
|
||||
|
||||
cli();
|
||||
|
||||
// Set CTC mode (Clear Timer on Compare Match) (p.133)
|
||||
// Have to set OCR1A *after*, otherwise it gets reset to 0!
|
||||
TCCR2B = (TCCR2B & ~_BV(WGM13)) | _BV(WGM12);
|
||||
TCCR2A = TCCR2A & ~(_BV(WGM11) | _BV(WGM10));
|
||||
|
||||
// No prescaler (p.134)
|
||||
TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
|
||||
|
||||
// Set the compare register (OCR1A).
|
||||
// OCR1A is a 16-bit register, so we have to do this with
|
||||
// interrupts disabled to be safe.
|
||||
// OCR2A = F_CPU / SAMPLE_RATE; // 16e6 / 8000 = 2000
|
||||
OCR2A = 2000;
|
||||
|
||||
// Enable interrupt when TCNT1 == OCR1A (p.136)
|
||||
TIMSK1 |= _BV(OCIE2A);
|
||||
|
||||
sample = 0;
|
||||
sei();
|
||||
}
|
||||
|
||||
void note(int x, float length) {
|
||||
DDRB |= (1<<1);
|
||||
int t = (int)(440*pow(2,-x/12.0)); // starting note
|
||||
for (int y = 0; y < length*1000/t; y++) { // note length
|
||||
PORTB |= (1<<1);
|
||||
delay_us(t);
|
||||
PORTB &= ~(1<<1);
|
||||
delay_us(t);
|
||||
}
|
||||
PORTB &= ~(1<<1);
|
||||
}
|
||||
|
||||
void true_note(float x, float y, float length) {
|
||||
for (uint32_t i = 0; i < length * 50; i++) {
|
||||
uint32_t v = (uint32_t) (round(sin(PI*2*i*640000*pow(2, x/12.0))*.5+1 + sin(PI*2*i*640000*pow(2, y/12.0))*.5+1) / 2 * pow(2, 8));
|
||||
for (int u = 0; u < 8; u++) {
|
||||
if (v & (1 << u) && !(PORTB&(1<<1)))
|
||||
PORTB |= (1<<1);
|
||||
else if (PORTB&(1<<1))
|
||||
PORTB &= ~(1<<1);
|
||||
}
|
||||
}
|
||||
PORTB &= ~(1<<1);
|
||||
}
|
||||
// void true_note(float x, float y, float length) {
|
||||
// for (uint32_t i = 0; i < length * 50; i++) {
|
||||
// uint32_t v = (uint32_t) (round(sin(PI*2*i*640000*pow(2, x/12.0))*.5+1 + sin(PI*2*i*640000*pow(2, y/12.0))*.5+1) / 2 * pow(2, 8));
|
||||
// for (int u = 0; u < 8; u++) {
|
||||
// if (v & (1 << u) && !(PORTC&(1<<6)))
|
||||
// PORTC |= (1<<6);
|
||||
// else if (PORTC&(1<<6))
|
||||
// PORTC &= ~(1<<6);
|
||||
// }
|
||||
// }
|
||||
// PORTC &= ~(1<<6);
|
||||
// }
|
@ -6,4 +6,7 @@
|
||||
void note(int x, float length);
|
||||
void beeps();
|
||||
void true_note(float x, float y, float length);
|
||||
void play_note(float freq, int length);
|
||||
void play_note(double freq, int vol);
|
||||
void stop_note(double freq);
|
||||
void stop_all_notes();
|
||||
void init_notes();
|
@ -1,8 +1,8 @@
|
||||
#include "extended_keymap_common.h"
|
||||
#include "backlight.h"
|
||||
#include "action_layer.h"
|
||||
#include "lufa.h"
|
||||
#include "keymap_midi.h"
|
||||
#include "beeps.h"
|
||||
|
||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||
[0] = { /* Qwerty */
|
||||
|
@ -20,37 +20,91 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <lufa.h>
|
||||
|
||||
uint8_t starting_note = 0x0C;
|
||||
int offset = 7;
|
||||
|
||||
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt)
|
||||
{
|
||||
if (id != 0) {
|
||||
if (record->event.pressed) {
|
||||
midi_send_noteon(&midi_device, opt, (id & 0xFF), 127);
|
||||
} else {
|
||||
midi_send_noteoff(&midi_device, opt, (id & 0xFF), 127);
|
||||
}
|
||||
}
|
||||
|
||||
if (record->event.key.col == 11 && record->event.key.row == 4 && record->event.pressed) {
|
||||
starting_note++;
|
||||
midi_send_cc(&midi_device, 0, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 1, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 2, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 3, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 4, 0x7B, 0);
|
||||
if (id != 0) {
|
||||
if (record->event.pressed) {
|
||||
midi_send_noteon(&midi_device, opt, (id & 0xFF), 127);
|
||||
} else {
|
||||
midi_send_noteoff(&midi_device, opt, (id & 0xFF), 127);
|
||||
}
|
||||
}
|
||||
if (record->event.key.col == 8 && record->event.key.row == 4 && record->event.pressed) {
|
||||
starting_note--;
|
||||
|
||||
if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) {
|
||||
if (record->event.pressed) {
|
||||
starting_note++;
|
||||
play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
|
||||
midi_send_cc(&midi_device, 0, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 1, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 2, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 3, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 4, 0x7B, 0);
|
||||
return;
|
||||
} else {
|
||||
stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)));
|
||||
stop_all_notes();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) {
|
||||
if (record->event.pressed) {
|
||||
starting_note--;
|
||||
play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
|
||||
midi_send_cc(&midi_device, 0, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 1, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 2, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 3, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 4, 0x7B, 0);
|
||||
return;
|
||||
} else {
|
||||
stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[0 + offset])/12.0+(MATRIX_ROWS - 1)));
|
||||
stop_all_notes();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
|
||||
offset++;
|
||||
midi_send_cc(&midi_device, 0, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 1, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 2, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 3, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 4, 0x7B, 0);
|
||||
stop_all_notes();
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
|
||||
_delay_us(80000);
|
||||
stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)));
|
||||
_delay_us(8000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) {
|
||||
offset--;
|
||||
midi_send_cc(&midi_device, 0, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 1, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 2, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 3, 0x7B, 0);
|
||||
midi_send_cc(&midi_device, 4, 0x7B, 0);
|
||||
stop_all_notes();
|
||||
for (int i = 0; i <= 7; i++) {
|
||||
play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)), 0xC);
|
||||
_delay_us(80000);
|
||||
stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[i + offset])/12.0+(MATRIX_ROWS - 1)));
|
||||
_delay_us(8000);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (record->event.pressed) {
|
||||
midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
|
||||
// midi_send_noteon(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
|
||||
midi_send_noteon(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127);
|
||||
play_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF);
|
||||
} else {
|
||||
midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
|
||||
// midi_send_noteoff(&midi_device, record->event.key.row, starting_note + SCALE[record->event.key.col], 127);
|
||||
midi_send_noteoff(&midi_device, 0, (starting_note + SCALE[record->event.key.col + offset])+12*(MATRIX_ROWS - record->event.key.row), 127);
|
||||
stop_note(((double)261.6)*pow(2.0, -1.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)));
|
||||
}
|
||||
}
|
@ -23,7 +23,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#define CHNL(note, channel) (note + (channel << 8))
|
||||
|
||||
#define SCALE (int []){ 0, 2, 4, 5, 7, 9, 11, 12, 14, 16, 17, 19, 21, 23, 24, 26, 28, 29, 31, 33, 35, 36}
|
||||
#define SCALE (int []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \
|
||||
0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \
|
||||
0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \
|
||||
0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \
|
||||
0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), }
|
||||
|
||||
#define N_CN1 (0x600C + (12 * -1) + 0 )
|
||||
#define N_CN1S (0x600C + (12 * -1) + 1 )
|
||||
|
@ -3,7 +3,7 @@ PJRC_DIR = protocol/pjrc
|
||||
|
||||
SRC += $(BLUEFRUIT_DIR)/main.c \
|
||||
$(BLUEFRUIT_DIR)/bluefruit.c \
|
||||
serial_uart.c \
|
||||
../serial_uart.c \
|
||||
$(PJRC_DIR)/pjrc.c \
|
||||
$(PJRC_DIR)/usb_keyboard.c \
|
||||
$(PJRC_DIR)/usb_debug.c \
|
||||
|
@ -2,20 +2,16 @@
|
||||
Bluefruit Protocol for TMK firmware
|
||||
Author: Benjamin Gould, 2013
|
||||
Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
@ -76,6 +72,13 @@ static void send_mouse(report_mouse_t *report);
|
||||
static void send_system(uint16_t data);
|
||||
static void send_consumer(uint16_t data);
|
||||
|
||||
|
||||
void sendString(char string[], int length) {
|
||||
for(int i = 0; i < length; i++) {
|
||||
serial_send(string[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static host_driver_t driver = {
|
||||
keyboard_leds,
|
||||
send_keyboard,
|
||||
@ -100,6 +103,7 @@ static void send_keyboard(report_keyboard_t *report)
|
||||
#endif
|
||||
bluefruit_serial_send(0xFD);
|
||||
for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) {
|
||||
|
||||
bluefruit_serial_send(report->raw[i]);
|
||||
}
|
||||
#ifdef BLUEFRUIT_TRACE_SERIAL
|
||||
@ -198,5 +202,4 @@ static void send_consumer(uint16_t data)
|
||||
#ifdef BLUEFRUIT_TRACE_SERIAL
|
||||
bluefruit_trace_footer();
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
@ -2,17 +2,14 @@
|
||||
Bluefruit Protocol for TMK firmware
|
||||
Author: Benjamin Gould, 2013
|
||||
Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
@ -25,4 +22,4 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
host_driver_t *bluefruit_driver(void);
|
||||
|
||||
#endif
|
||||
#endif
|
@ -22,7 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/sleep.h>
|
||||
#include <util/delay.h>
|
||||
#include "serial.h"
|
||||
#include "../serial.h"
|
||||
#include "keyboard.h"
|
||||
#include "usb.h"
|
||||
#include "host.h"
|
||||
@ -40,23 +40,26 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define BLUEFRUIT_HOST_DRIVER 1
|
||||
#define PJRC_HOST_DRIVER 2
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
CPU_PRESCALE(0);
|
||||
|
||||
DDRD = _BV(PD5);
|
||||
DDRB = _BV(PB0);
|
||||
// DDRD = _BV(PD5);
|
||||
// DDRB = _BV(PB0);
|
||||
|
||||
PORTD = _BV(PD5);
|
||||
PORTB = _BV(PB0);
|
||||
// PORTD = _BV(PD5);
|
||||
// PORTB = _BV(PB0);
|
||||
|
||||
print_set_sendchar(sendchar);
|
||||
|
||||
usb_init();
|
||||
_delay_ms(2000);
|
||||
// usb_init();
|
||||
// _delay_ms(2000);
|
||||
// while (!usb_configured()) /* wait */
|
||||
|
||||
|
||||
|
||||
dprintf("Initializing keyboard...\n");
|
||||
keyboard_init();
|
||||
|
||||
@ -64,53 +67,72 @@ int main(void)
|
||||
// is not configured, choose the Bluefruit, otherwise use USB
|
||||
// Definitely would prefer to have this driven by an input pin and make
|
||||
// it switch dynamically - BCG
|
||||
if (!usb_configured()) {
|
||||
// if (!usb_configured()) {
|
||||
|
||||
// Send power to Bluefruit... Adafruit says it takes 27 mA, I think
|
||||
// the pins should provide 40 mA, but just in case I switch the
|
||||
// Bluefruit using a transistor - BCG
|
||||
DDRB = _BV(PB6);
|
||||
PORTB |= _BV(PB6);
|
||||
// // Send power to Bluefruit... Adafruit says it takes 27 mA, I think
|
||||
// // the pins should provide 40 mA, but just in case I switch the
|
||||
// // Bluefruit using a transistor - BCG
|
||||
// DDRB = _BV(PB6);
|
||||
// PORTB |= _BV(PB6);
|
||||
|
||||
dprintf("Setting host driver to bluefruit...\n");
|
||||
host_set_driver(bluefruit_driver());
|
||||
|
||||
dprintf("Initializing serial...\n");
|
||||
serial_init();
|
||||
|
||||
|
||||
// char swpa[] = "+++\r\n";
|
||||
// for (int i = 0; i < 5; i++) {
|
||||
// serial_send(swpa[i]);
|
||||
// }
|
||||
|
||||
// char ble_enable[] = "AT+BLEKEYBOARDEN=1\r\n";
|
||||
// for (int i = 0; i < 20; i++) {
|
||||
// serial_send(ble_enable[i]);
|
||||
// }
|
||||
|
||||
// char reset[] = "ATZ\r\n";
|
||||
// for (int i = 0; i < 5; i++) {
|
||||
// serial_send(reset[i]);
|
||||
// }
|
||||
|
||||
// for (int i = 0; i < 5; i++) {
|
||||
// serial_send(swpa[i]);
|
||||
// }
|
||||
|
||||
// wait an extra second for the PC's operating system
|
||||
// to load drivers and do whatever it does to actually
|
||||
// be ready for input
|
||||
_delay_ms(1000);
|
||||
PORTD = ~_BV(PD5);
|
||||
// PORTD = ~_BV(PD5);
|
||||
dprintf("Starting main loop");
|
||||
while (1) {
|
||||
keyboard_task();
|
||||
}
|
||||
|
||||
} else {
|
||||
// } else {
|
||||
|
||||
// I'm not smart enough to get this done with LUFA - BCG
|
||||
dprintf("Setting host driver to PJRC...\n");
|
||||
host_set_driver(pjrc_driver());
|
||||
#ifdef SLEEP_LED_ENABLE
|
||||
sleep_led_init();
|
||||
#endif
|
||||
// wait an extra second for the PC's operating system
|
||||
// to load drivers and do whatever it does to actually
|
||||
// be ready for input
|
||||
_delay_ms(1000);
|
||||
PORTB = ~_BV(PB0);
|
||||
dprintf("Starting main loop");
|
||||
while (1) {
|
||||
while (suspend) {
|
||||
suspend_power_down();
|
||||
if (remote_wakeup && suspend_wakeup_condition()) {
|
||||
usb_remote_wakeup();
|
||||
}
|
||||
}
|
||||
keyboard_task();
|
||||
}
|
||||
}
|
||||
// // I'm not smart enough to get this done with LUFA - BCG
|
||||
// dprintf("Setting host driver to PJRC...\n");
|
||||
// host_set_driver(pjrc_driver());
|
||||
// #ifdef SLEEP_LED_ENABLE
|
||||
// sleep_led_init();
|
||||
// #endif
|
||||
// // wait an extra second for the PC's operating system
|
||||
// // to load drivers and do whatever it does to actually
|
||||
// // be ready for input
|
||||
// _delay_ms(1000);
|
||||
// PORTB = ~_BV(PB0);
|
||||
// dprintf("Starting main loop");
|
||||
// while (1) {
|
||||
// while (suspend) {
|
||||
// suspend_power_down();
|
||||
// if (remote_wakeup && suspend_wakeup_condition()) {
|
||||
// usb_remote_wakeup();
|
||||
// }
|
||||
// }
|
||||
// keyboard_task();
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
|
||||
|
||||
.ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_REMOTEWAKEUP),
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(500)
|
||||
},
|
||||
|
||||
/*
|
||||
|
@ -840,13 +840,13 @@ int main(void)
|
||||
|
||||
|
||||
/* wait for USB startup & debug output */
|
||||
// while (USB_DeviceState != DEVICE_STATE_Configured) {
|
||||
while (USB_DeviceState != DEVICE_STATE_Configured) {
|
||||
// #if defined(INTERRUPT_CONTROL_ENDPOINT)
|
||||
// ;
|
||||
// #else
|
||||
USB_USBTask();
|
||||
// #endif
|
||||
// }
|
||||
}
|
||||
print("USB configured.\n");
|
||||
|
||||
/* init modules */
|
||||
|
Loading…
Reference in New Issue
Block a user