bluetooth
This commit is contained in:
		
							parent
							
								
									40148c430e
								
							
						
					
					
						commit
						c966e7982c
					
				
					 20 changed files with 2329 additions and 319 deletions
				
			
		| 
						 | 
				
			
			@ -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 )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue