forked from mirrors/qmk_userspace
		
	Merge ChibiOS and LUFA descriptor support (#2362)
* Move lufa descriptor to protocol/usb_descriptor * Try to compile usb_descriptor on ChibiOS * Add lufa_utils for ChibiOS Lufa USB descriptors for ChibiOS * More lufa_util compatibility fixes * First compiling version of shared USB descriptor * Send the usb descriptors * Fix the CONSOLE output on ChibiOS * Add errors for unsupported interfaces * Enable support for vitual serial port USB descriptors * Implement virtual serial port for ChibiOS * Cleanup the lufa_utils Use the default lufa header files * Add raw hid support for ChibiOS This is completely untested * Enable midi compilation on ChibiOS * Move midi functionality out of lufa.c * Don't register sysex callback when not needed * ChibiOS compilation fixes * Update ChibiOS submodule * Fix the Midi USB descriptor It didn't work properly when both Midi and Virtual serial port was enabled. * Add MIDI support for ChibiOS * Fix USB descriptor strings on ChibiOS * Use serial usb driver for raw hid * Generalize the ChibiOS stream like drivers This makes the initialization much more simple and eliminates a lot of the code duplication. * Convert console output to chibios stream driver * Fixes for ChibiOS update * Update the ChibiOS contrib submodule To include the usb data toggle synchronization fixes * Fix duplicate reset enumeration on ChibiOS * Add missing include * Add number of endpoints check for ChibiOS * Enable serial USB driver on all keyboards * Add missing includes when API is enabled withot midi * Add another missing inlcude
This commit is contained in:
		
					parent
					
						
							
								63c16f4b63
							
						
					
				
			
			
				commit
				
					
						53ff8a31b6
					
				
			
		
					 38 changed files with 761 additions and 1237 deletions
				
			
		| 
						 | 
				
			
			@ -121,7 +121,6 @@ else
 | 
			
		|||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(PLATFORM),CHIBIOS)
 | 
			
		||||
    include $(TMK_PATH)/protocol/chibios.mk
 | 
			
		||||
    include $(TMK_PATH)/chibios.mk
 | 
			
		||||
    OPT_OS = chibios
 | 
			
		||||
    ifneq ("$(wildcard $(KEYBOARD_PATH_5)/bootloader_defs.h)","")
 | 
			
		||||
| 
						 | 
				
			
			@ -247,6 +246,10 @@ endif
 | 
			
		|||
    include $(TMK_PATH)/avr.mk
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(PLATFORM),CHIBIOS)
 | 
			
		||||
    include $(TMK_PATH)/protocol/chibios.mk
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
ifeq ($(strip $(VISUALIZER_ENABLE)), yes)
 | 
			
		||||
    VISUALIZER_DIR = $(QUANTUM_DIR)/visualizer
 | 
			
		||||
    VISUALIZER_PATH = $(QUANTUM_PATH)/visualizer
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,11 +24,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define DEVICE_VER      0x0001
 | 
			
		||||
/* in python2: list(u"whatever".encode('utf-16-le')) */
 | 
			
		||||
/*   at most 32 characters or the ugly hack in usb_main.c borks */
 | 
			
		||||
#define MANUFACTURER "QMK"
 | 
			
		||||
#define USBSTR_MANUFACTURER    'T', '\x00', 'M', '\x00', 'K', '\x00', ' ', '\x00', '\xc6', '\x00'
 | 
			
		||||
#define PRODUCT "ChibiOS QMK test"
 | 
			
		||||
#define USBSTR_PRODUCT         'C', '\x00', 'h', '\x00', 'i', '\x00', 'b', '\x00', 'i', '\x00', 'O', '\x00', 'S', '\x00', ' ', '\x00', 'Q', '\x00', 'M', '\x00', 'K', '\x00', ' ', '\x00', 't', '\x00', 'e', '\x00', 's', '\x00', 't', '\x00'
 | 
			
		||||
#define DESCRIPTION "QMK keyboard firmware test for ChibiOS"
 | 
			
		||||
#define MANUFACTURER QMK
 | 
			
		||||
#define PRODUCT ChibiOS QMK test
 | 
			
		||||
#define DESCRIPTION QMK keyboard firmware test for ChibiOS
 | 
			
		||||
 | 
			
		||||
/* key matrix size */
 | 
			
		||||
#define MATRIX_ROWS 1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,7 +139,7 @@
 | 
			
		|||
 * @brief   Enables the SERIAL over USB subsystem.
 | 
			
		||||
 */
 | 
			
		||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
 | 
			
		||||
#define HAL_USE_SERIAL_USB          FALSE
 | 
			
		||||
#define HAL_USE_SERIAL_USB          TRUE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,7 +139,7 @@
 | 
			
		|||
 * @brief   Enables the SERIAL over USB subsystem.
 | 
			
		||||
 */
 | 
			
		||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
 | 
			
		||||
#define HAL_USE_SERIAL_USB          FALSE
 | 
			
		||||
#define HAL_USE_SERIAL_USB          TRUE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,7 +139,7 @@
 | 
			
		|||
 * @brief   Enables the SERIAL over USB subsystem.
 | 
			
		||||
 */
 | 
			
		||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
 | 
			
		||||
#define HAL_USE_SERIAL_USB          FALSE
 | 
			
		||||
#define HAL_USE_SERIAL_USB          TRUE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,11 +22,9 @@
 | 
			
		|||
#define VENDOR_ID       0xC1ED
 | 
			
		||||
#define PRODUCT_ID      0x2350
 | 
			
		||||
#define DEVICE_VER      0x0001
 | 
			
		||||
#define MANUFACTURER    "Clueboard"
 | 
			
		||||
#define USBSTR_MANUFACTURER 'C', '\x00', 'l', '\x00', 'u', '\x00', 'e', '\x00', 'b', '\x00', 'o', '\x00', 'a', '\x00', 'r', '\x00', 'd', '\x00'
 | 
			
		||||
#define PRODUCT         "Clueboard60"
 | 
			
		||||
#define USBSTR_PRODUCT 'C', '\x00', 'l', '\x00', 'u', '\x00', 'e', '\x00', 'b', '\x00', 'o', '\x00', 'a', '\x00', 'r', '\x00', 'd', '\x00', ' ', '\x00', '6', '\x00', '0', '\x00', '%', '\x00'
 | 
			
		||||
#define DESCRIPTION     "Clueboard 60%"
 | 
			
		||||
#define MANUFACTURER    Clueboard
 | 
			
		||||
#define PRODUCT         Clueboard 60%
 | 
			
		||||
#define DESCRIPTION     Clueboard 60%
 | 
			
		||||
 | 
			
		||||
/* key matrix size */
 | 
			
		||||
#define MATRIX_ROWS 5
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,12 +23,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define VENDOR_ID       0xFEED
 | 
			
		||||
#define PRODUCT_ID      0x6464
 | 
			
		||||
#define DEVICE_VER      0x0001
 | 
			
		||||
/* in python2: list(u"whatever".encode('utf-16-le')) */
 | 
			
		||||
/*   at most 32 characters or the ugly hack in usb_main.c borks */
 | 
			
		||||
#define MANUFACTURER "TMK"
 | 
			
		||||
#define USBSTR_MANUFACTURER    'T', '\x00', 'M', '\x00', 'K', '\x00', ' ', '\x00'
 | 
			
		||||
#define PRODUCT "Infinity keyboard/TMK"
 | 
			
		||||
#define USBSTR_PRODUCT         'I', '\x00', 'n', '\x00', 'f', '\x00', 'i', '\x00', 'n', '\x00', 'i', '\x00', 't', '\x00', 'y', '\x00', ' ', '\x00', 'k', '\x00', 'e', '\x00', 'y', '\x00', 'b', '\x00', 'o', '\x00', 'a', '\x00', 'r', '\x00', 'd', '\x00', '/', '\x00', 'T', '\x00', 'M', '\x00', 'K', '\x00'
 | 
			
		||||
#define MANUFACTURER Input Club
 | 
			
		||||
#define PRODUCT Ergodox Infinity (QMK)
 | 
			
		||||
 | 
			
		||||
#define MOUSEKEY_INTERVAL       20
 | 
			
		||||
#define MOUSEKEY_DELAY          0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,10 +26,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define DEVICE_VER      0x0001
 | 
			
		||||
/* in python2: list(u"whatever".encode('utf-16-le')) */
 | 
			
		||||
/*   at most 32 characters or the ugly hack in usb_main.c borks */
 | 
			
		||||
#define MANUFACTURER "Input Club"
 | 
			
		||||
#define USBSTR_MANUFACTURER    'I', '\x00', 'n', '\x00', 'p', '\x00', 'u', '\x00', 't', '\x00', ' ', '\x00', 'C', '\x00', 'l', '\x00', 'u', '\x00', 'b', '\x00'
 | 
			
		||||
#define PRODUCT "Infinity keyboard/QMK"
 | 
			
		||||
#define USBSTR_PRODUCT         'I', '\x00', 'n', '\x00', 'f', '\x00', 'i', '\x00', 'n', '\x00', 'i', '\x00', 't', '\x00', 'y', '\x00', ' ', '\x00', 'k', '\x00', 'e', '\x00', 'y', '\x00', 'b', '\x00', 'o', '\x00', 'a', '\x00', 'r', '\x00', 'd', '\x00', '/', '\x00', 'Q', '\x00', 'M', '\x00', 'K', '\x00'
 | 
			
		||||
#define MANUFACTURER Input Club
 | 
			
		||||
#define PRODUCT Infinity 60% keyboard (QMK)
 | 
			
		||||
/* key matrix size */
 | 
			
		||||
#define MATRIX_ROWS 9
 | 
			
		||||
#define MATRIX_COLS 7
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,7 +139,7 @@
 | 
			
		|||
 * @brief   Enables the SERIAL over USB subsystem.
 | 
			
		||||
 */
 | 
			
		||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
 | 
			
		||||
#define HAL_USE_SERIAL_USB          FALSE
 | 
			
		||||
#define HAL_USE_SERIAL_USB          TRUE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,11 +26,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define DEVICE_VER      0x0001
 | 
			
		||||
/* in python2: list(u"whatever".encode('utf-16-le')) */
 | 
			
		||||
/*   at most 32 characters or the ugly hack in usb_main.c borks */
 | 
			
		||||
#define MANUFACTURER "JMWS"
 | 
			
		||||
#define USBSTR_MANUFACTURER    'J', '\x00', 'M', '\x00', 'W', '\x00', 'S', '\x00'
 | 
			
		||||
#define PRODUCT "JM60 RGB Keyboard(QMK)"
 | 
			
		||||
#define USBSTR_PRODUCT 'J', '\x00', 'M', '\x00', '6', '\x00', '0', '\x00', ' ', '\x00', 'R', '\x00', 'G', '\x00', 'B', '\x00', ' ', '\x00', 'K', '\x00', 'e', '\x00', 'y', '\x00', 'b', '\x00', 'o', '\x00', 'a', '\x00', 'r', '\x00', 'd', '\x00', '(', '\x00', 'Q', '\x00', 'M', '\x00', 'K', '\x00', ')', '\x00'
 | 
			
		||||
#define DESCRIPTION "QMK keyboard firmware for JM60 RGB Keyboard"
 | 
			
		||||
#define MANUFACTURER JMWS
 | 
			
		||||
#define PRODUCT JM60 RGB Keyboard(QMK)
 | 
			
		||||
#define DESCRIPTION QMK keyboard firmware for JM60 RGB Keyboard
 | 
			
		||||
 | 
			
		||||
/* key matrix size */
 | 
			
		||||
#define MATRIX_ROWS 5
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,7 +139,7 @@
 | 
			
		|||
 * @brief   Enables the SERIAL over USB subsystem.
 | 
			
		||||
 */
 | 
			
		||||
#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__)
 | 
			
		||||
#define HAL_USE_SERIAL_USB          FALSE
 | 
			
		||||
#define HAL_USE_SERIAL_USB          TRUE
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,10 +26,8 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#define DEVICE_VER      0x0001
 | 
			
		||||
/* in python2: list(u"whatever".encode('utf-16-le')) */
 | 
			
		||||
/*   at most 32 characters or the ugly hack in usb_main.c borks */
 | 
			
		||||
#define MANUFACTURER "Input Club"
 | 
			
		||||
#define USBSTR_MANUFACTURER    'I', '\x00', 'n', '\x00', 'p', '\x00', 'u', '\x00', 't', '\x00', ' ', '\x00', 'C', '\x00', 'l', '\x00', 'u', '\x00', 'b', '\x00'
 | 
			
		||||
#define PRODUCT "WhiteFox/QMK"
 | 
			
		||||
#define USBSTR_PRODUCT         'W', '\x00', 'h', '\x00', 'i', '\x00', 't', '\x00', 'e', '\x00', 'F', '\x00', 'o', '\x00', 'x', '\x00', ' ', '\x00'
 | 
			
		||||
#define MANUFACTURER Input Club
 | 
			
		||||
#define PRODUCT WhiteFox (QMK)
 | 
			
		||||
 | 
			
		||||
/* key matrix size */
 | 
			
		||||
#define MATRIX_ROWS 9
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
Subproject commit e26cb16a7296a196d7c74eae22cbee00989cb7b6
 | 
			
		||||
Subproject commit 587968d6cbc2b0e1c7147540872f2a67e59ca18b
 | 
			
		||||
| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
Subproject commit 432bc1762f17eb7b506e8fbca8ec30a3d61629b8
 | 
			
		||||
Subproject commit ede48346eee4b8d6847c19bc01420bee76a5e486
 | 
			
		||||
| 
						 | 
				
			
			@ -16,6 +16,7 @@
 | 
			
		|||
#include "api_sysex.h"
 | 
			
		||||
#include "sysex_tools.h"
 | 
			
		||||
#include "print.h"
 | 
			
		||||
#include "qmk_midi.h"
 | 
			
		||||
 | 
			
		||||
void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length) {
 | 
			
		||||
    // SEND_STRING("\nTX: ");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#include "action.h"
 | 
			
		||||
#if defined(__AVR__)
 | 
			
		||||
#include <avr/pgmspace.h>
 | 
			
		||||
#elif defined PROTOCOL_CHIBIOS
 | 
			
		||||
//We need to ensure that chibios is include before redefining reset
 | 
			
		||||
#include "ch.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include "keycode.h"
 | 
			
		||||
#include "action_macro.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,9 @@
 | 
			
		|||
#include "process_midi.h"
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
#include <LUFA/Drivers/USB/USB.h>
 | 
			
		||||
#include "midi.h"
 | 
			
		||||
#include "qmk_midi.h"
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_BASIC
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +48,7 @@ static uint8_t tone_status[MIDI_TONE_COUNT];
 | 
			
		|||
static uint8_t midi_modulation;
 | 
			
		||||
static int8_t midi_modulation_step;
 | 
			
		||||
static uint16_t midi_modulation_timer;
 | 
			
		||||
midi_config_t midi_config;
 | 
			
		||||
 | 
			
		||||
inline uint8_t compute_velocity(uint8_t setting)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -70,30 +73,6 @@ void midi_init(void)
 | 
			
		|||
    midi_modulation_timer = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void midi_task(void)
 | 
			
		||||
{
 | 
			
		||||
    if (timer_elapsed(midi_modulation_timer) < midi_config.modulation_interval)
 | 
			
		||||
        return;
 | 
			
		||||
    midi_modulation_timer = timer_read();
 | 
			
		||||
 | 
			
		||||
    if (midi_modulation_step != 0)
 | 
			
		||||
    {
 | 
			
		||||
        dprintf("midi modulation %d\n", midi_modulation);
 | 
			
		||||
        midi_send_cc(&midi_device, midi_config.channel, 0x1, midi_modulation);
 | 
			
		||||
 | 
			
		||||
        if (midi_modulation_step < 0 && midi_modulation < -midi_modulation_step) {
 | 
			
		||||
            midi_modulation = 0;
 | 
			
		||||
            midi_modulation_step = 0;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        midi_modulation += midi_modulation_step;
 | 
			
		||||
 | 
			
		||||
        if (midi_modulation > 127)
 | 
			
		||||
            midi_modulation = 127;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint8_t midi_compute_note(uint16_t keycode)
 | 
			
		||||
{
 | 
			
		||||
    return 12 * midi_config.octave + (keycode - MIDI_TONE_MIN) + midi_config.transpose;
 | 
			
		||||
| 
						 | 
				
			
			@ -250,4 +229,33 @@ bool process_midi(uint16_t keycode, keyrecord_t *record)
 | 
			
		|||
 | 
			
		||||
#endif // MIDI_ADVANCED
 | 
			
		||||
 | 
			
		||||
void midi_task(void)
 | 
			
		||||
{
 | 
			
		||||
    midi_device_process(&midi_device);
 | 
			
		||||
#ifdef MIDI_ADVANCED
 | 
			
		||||
    if (timer_elapsed(midi_modulation_timer) < midi_config.modulation_interval)
 | 
			
		||||
        return;
 | 
			
		||||
    midi_modulation_timer = timer_read();
 | 
			
		||||
 | 
			
		||||
    if (midi_modulation_step != 0)
 | 
			
		||||
    {
 | 
			
		||||
        dprintf("midi modulation %d\n", midi_modulation);
 | 
			
		||||
        midi_send_cc(&midi_device, midi_config.channel, 0x1, midi_modulation);
 | 
			
		||||
 | 
			
		||||
        if (midi_modulation_step < 0 && midi_modulation < -midi_modulation_step) {
 | 
			
		||||
            midi_modulation = 0;
 | 
			
		||||
            midi_modulation_step = 0;
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        midi_modulation += midi_modulation_step;
 | 
			
		||||
 | 
			
		||||
        if (midi_modulation > 127)
 | 
			
		||||
            midi_modulation = 127;
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif // MIDI_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,8 @@ void process_midi_basic_noteoff(uint8_t note);
 | 
			
		|||
void process_midi_all_notes_off(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void midi_task(void);
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ADVANCED
 | 
			
		||||
typedef union {
 | 
			
		||||
  uint32_t raw;
 | 
			
		||||
| 
						 | 
				
			
			@ -39,10 +41,9 @@ typedef union {
 | 
			
		|||
  };
 | 
			
		||||
} midi_config_t;
 | 
			
		||||
 | 
			
		||||
midi_config_t midi_config;
 | 
			
		||||
extern midi_config_t midi_config;
 | 
			
		||||
 | 
			
		||||
void midi_init(void);
 | 
			
		||||
void midi_task(void);
 | 
			
		||||
bool process_midi(uint16_t keycode, keyrecord_t *record);
 | 
			
		||||
 | 
			
		||||
#define MIDI_INVALID_NOTE 0xFF
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,14 @@ extern backlight_config_t backlight_config;
 | 
			
		|||
#include "fauxclicky.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef API_ENABLE
 | 
			
		||||
#include "api.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
#include "process_midi.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef AUDIO_ENABLE
 | 
			
		||||
  #ifndef GOODBYE_SONG
 | 
			
		||||
    #define GOODBYE_SONG SONG(GOODBYE_SOUND)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,7 +49,6 @@ extern uint32_t default_layer_state;
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
	#include <lufa.h>
 | 
			
		||||
#ifdef MIDI_ADVANCED
 | 
			
		||||
	#include "process_midi.h"
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,6 +149,7 @@ COMPILEFLAGS += -falign-functions=16
 | 
			
		|||
COMPILEFLAGS += -ffunction-sections
 | 
			
		||||
COMPILEFLAGS += -fdata-sections
 | 
			
		||||
COMPILEFLAGS += -fno-common
 | 
			
		||||
COMPILEFLAGS += -fshort-wchar
 | 
			
		||||
COMPILEFLAGS += $(THUMBFLAGS)
 | 
			
		||||
 | 
			
		||||
CFLAGS += $(COMPILEFLAGS)
 | 
			
		||||
| 
						 | 
				
			
			@ -159,6 +160,7 @@ CPPFLAGS += $(COMPILEFLAGS)
 | 
			
		|||
CPPFLAGS += -fno-rtti
 | 
			
		||||
 | 
			
		||||
LDFLAGS +=-Wl,--gc-sections
 | 
			
		||||
LDFLAGS +=-Wl,--no-wchar-size-warning
 | 
			
		||||
LDFLAGS += -mno-thumb-interwork -mthumb
 | 
			
		||||
LDSYMBOLS =,--defsym=__process_stack_size__=$(USE_PROCESS_STACKSIZE)
 | 
			
		||||
LDSYMBOLS :=$(LDSYMBOLS),--defsym=__main_stack_size__=$(USE_EXCEPTIONS_STACKSIZE)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,11 +30,6 @@ typedef struct {
 | 
			
		|||
    void (*send_mouse)(report_mouse_t *);
 | 
			
		||||
    void (*send_system)(uint16_t);
 | 
			
		||||
    void (*send_consumer)(uint16_t);
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
    void (*usb_send_func)(MidiDevice *, uint16_t, uint8_t, uint8_t, uint8_t);
 | 
			
		||||
    void (*usb_get_midi)(MidiDevice *);
 | 
			
		||||
    void (*midi_usb_init)(MidiDevice *);
 | 
			
		||||
#endif
 | 
			
		||||
} host_driver_t;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,6 +66,9 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
#ifdef POINTING_DEVICE_ENABLE
 | 
			
		||||
#   include "pointing_device.h"
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
#   include "process_midi.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MATRIX_HAS_GHOST
 | 
			
		||||
extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS];
 | 
			
		||||
| 
						 | 
				
			
			@ -260,6 +263,10 @@ MATRIX_LOOP_END:
 | 
			
		|||
    pointing_device_task();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
    midi_task();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    // update LED
 | 
			
		||||
    if (led_status != host_keyboard_leds()) {
 | 
			
		||||
        led_status = host_keyboard_leds();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,22 +73,20 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
/* key report size(NKRO or boot mode) */
 | 
			
		||||
#if defined(PROTOCOL_PJRC) && defined(NKRO_ENABLE)
 | 
			
		||||
#   include "usb.h"
 | 
			
		||||
#   define KEYBOARD_REPORT_SIZE KBD2_SIZE
 | 
			
		||||
#   define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
 | 
			
		||||
#   define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
 | 
			
		||||
 | 
			
		||||
#elif defined(PROTOCOL_LUFA) && defined(NKRO_ENABLE)
 | 
			
		||||
#   include "protocol/lufa/descriptor.h"
 | 
			
		||||
#   define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
 | 
			
		||||
#   define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
 | 
			
		||||
#   define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
 | 
			
		||||
#elif defined(PROTOCOL_CHIBIOS) && defined(NKRO_ENABLE)
 | 
			
		||||
#   include "protocol/chibios/usb_main.h"
 | 
			
		||||
#   define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
 | 
			
		||||
#   define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
 | 
			
		||||
#   define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
 | 
			
		||||
#if defined(NKRO_ENABLE)
 | 
			
		||||
  #if defined(PROTOCOL_PJRC)
 | 
			
		||||
    #include "usb.h"
 | 
			
		||||
    #define KEYBOARD_REPORT_SIZE KBD2_SIZE
 | 
			
		||||
    #define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
 | 
			
		||||
    #define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
 | 
			
		||||
  #elif defined(PROTOCOL_LUFA) || defined(PROTOCOL_CHIBIOS)
 | 
			
		||||
    #include "protocol/usb_descriptor.h"
 | 
			
		||||
    #define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
 | 
			
		||||
    #define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
 | 
			
		||||
    #define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
 | 
			
		||||
  #else
 | 
			
		||||
    #error "NKRO not supported with this protocol"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
#   define KEYBOARD_REPORT_SIZE 8
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,16 @@ CHIBIOS_DIR = $(PROTOCOL_DIR)/chibios
 | 
			
		|||
 | 
			
		||||
SRC += $(CHIBIOS_DIR)/usb_main.c
 | 
			
		||||
SRC += $(CHIBIOS_DIR)/main.c
 | 
			
		||||
SRC += usb_descriptor.c
 | 
			
		||||
 | 
			
		||||
VPATH += $(TMK_PATH)/$(PROTOCOL_DIR)
 | 
			
		||||
VPATH += $(TMK_PATH)/$(CHIBIOS_DIR)
 | 
			
		||||
VPATH += $(TMK_PATH)/$(CHIBIOS_DIR)/lufa_utils
 | 
			
		||||
 | 
			
		||||
OPT_DEFS += -DFIXED_CONTROL_ENDPOINT_SIZE=64
 | 
			
		||||
OPT_DEFS += -DFIXED_NUM_CONFIGURATIONS=1
 | 
			
		||||
 | 
			
		||||
ifeq ($(strip $(MIDI_ENABLE)), yes)
 | 
			
		||||
  include $(TMK_PATH)/protocol/midi.mk
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										42
									
								
								tmk_core/protocol/chibios/lufa_utils/LUFA/Drivers/USB/USB.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								tmk_core/protocol/chibios/lufa_utils/LUFA/Drivers/USB/USB.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,42 @@
 | 
			
		|||
#include "progmem.h"
 | 
			
		||||
#include "stddef.h"
 | 
			
		||||
#include "inttypes.h"
 | 
			
		||||
 | 
			
		||||
#define ATTR_PACKED                      __attribute__ ((packed))
 | 
			
		||||
/** Concatenates the given input into a single token, via the C Preprocessor.
 | 
			
		||||
 *
 | 
			
		||||
 *  \param[in] x  First item to concatenate.
 | 
			
		||||
 *  \param[in] y  Second item to concatenate.
 | 
			
		||||
 *
 | 
			
		||||
 *  \return Concatenated version of the input.
 | 
			
		||||
 */
 | 
			
		||||
#define CONCAT(x, y)            x ## y
 | 
			
		||||
 | 
			
		||||
/** CConcatenates the given input into a single token after macro expansion, via the C Preprocessor.
 | 
			
		||||
 *
 | 
			
		||||
 *  \param[in] x  First item to concatenate.
 | 
			
		||||
 *  \param[in] y  Second item to concatenate.
 | 
			
		||||
 *
 | 
			
		||||
 *  \return Concatenated version of the expanded input.
 | 
			
		||||
 */
 | 
			
		||||
#define CONCAT_EXPANDED(x, y)   CONCAT(x, y)
 | 
			
		||||
#define CPU_TO_LE16(x)           (x)
 | 
			
		||||
 | 
			
		||||
// We don't need anything from the following files, or we have defined it already
 | 
			
		||||
#define __LUFA_COMMON_H__
 | 
			
		||||
#define __USBMODE_H__
 | 
			
		||||
#define __USBEVENTS_H__
 | 
			
		||||
#define __HIDPARSER_H__
 | 
			
		||||
#define __USBCONTROLLER_AVR8_H__
 | 
			
		||||
 | 
			
		||||
#define __INCLUDE_FROM_USB_DRIVER
 | 
			
		||||
#define __INCLUDE_FROM_HID_DRIVER
 | 
			
		||||
#define __INCLUDE_FROM_CDC_DRIVER
 | 
			
		||||
#define __INCLUDE_FROM_AUDIO_DRIVER
 | 
			
		||||
#define __INCLUDE_FROM_MIDI_DRIVER
 | 
			
		||||
#include "lib/lufa/LUFA/Drivers/USB/Class/Common/HIDClassCommon.h"
 | 
			
		||||
#include "lib/lufa/LUFA/Drivers/USB/Class/Common/HIDReportData.h"
 | 
			
		||||
#include "lib/lufa/LUFA/Drivers/USB/Class/Common/CDCClassCommon.h"
 | 
			
		||||
#include "lib/lufa/LUFA/Drivers/USB/Class/Common/AudioClassCommon.h"
 | 
			
		||||
#include "lib/lufa/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h"
 | 
			
		||||
#include "lib/lufa/LUFA/Drivers/USB/Core/USBController.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +41,9 @@
 | 
			
		|||
#ifdef VISUALIZER_ENABLE
 | 
			
		||||
#include "visualizer/visualizer.h"
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
#include "qmk_midi.h"
 | 
			
		||||
#endif
 | 
			
		||||
#include "suspend.h"
 | 
			
		||||
#include "wait.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -65,6 +68,17 @@ host_driver_t chibios_driver = {
 | 
			
		|||
  send_consumer
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
void virtser_task(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef RAW_HID_ENABLE
 | 
			
		||||
void raw_hid_task(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
void console_task(void);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* TESTING
 | 
			
		||||
 * Amber LED blinker thread, times are in milliseconds.
 | 
			
		||||
| 
						 | 
				
			
			@ -104,6 +118,10 @@ int main(void) {
 | 
			
		|||
  /* init printf */
 | 
			
		||||
  init_printf(NULL,sendchar_pf);
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
  setup_midi();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef SERIAL_LINK_ENABLE
 | 
			
		||||
  init_serial_link();
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -182,5 +200,14 @@ int main(void) {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    keyboard_task();
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
    console_task();
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
    virtser_task();
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef RAW_HID_ENABLE
 | 
			
		||||
    raw_hid_task();
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							| 
						 | 
				
			
			@ -41,20 +41,6 @@ void init_usb_driver(USBDriver *usbp);
 | 
			
		|||
 * ---------------
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/* main keyboard (6kro) */
 | 
			
		||||
#define KBD_INTERFACE   0
 | 
			
		||||
#define KBD_ENDPOINT    1
 | 
			
		||||
#define KBD_EPSIZE      8
 | 
			
		||||
#define KBD_REPORT_KEYS (KBD_EPSIZE - 2)
 | 
			
		||||
 | 
			
		||||
/* secondary keyboard */
 | 
			
		||||
#ifdef NKRO_ENABLE
 | 
			
		||||
#define NKRO_INTERFACE    4
 | 
			
		||||
#define NKRO_ENDPOINT     5
 | 
			
		||||
#define NKRO_EPSIZE       16
 | 
			
		||||
#define NKRO_REPORT_KEYS  (NKRO_EPSIZE - 1)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* extern report_keyboard_t keyboard_report_sent; */
 | 
			
		||||
 | 
			
		||||
/* keyboard IN request callback handler */
 | 
			
		||||
| 
						 | 
				
			
			@ -75,10 +61,6 @@ void nkro_in_cb(USBDriver *usbp, usbep_t ep);
 | 
			
		|||
 | 
			
		||||
#ifdef MOUSE_ENABLE
 | 
			
		||||
 | 
			
		||||
#define MOUSE_INTERFACE         1
 | 
			
		||||
#define MOUSE_ENDPOINT          2
 | 
			
		||||
#define MOUSE_EPSIZE            8
 | 
			
		||||
 | 
			
		||||
/* mouse IN request callback handler */
 | 
			
		||||
void mouse_in_cb(USBDriver *usbp, usbep_t ep);
 | 
			
		||||
#endif /* MOUSE_ENABLE */
 | 
			
		||||
| 
						 | 
				
			
			@ -90,10 +72,6 @@ void mouse_in_cb(USBDriver *usbp, usbep_t ep);
 | 
			
		|||
 | 
			
		||||
#ifdef EXTRAKEY_ENABLE
 | 
			
		||||
 | 
			
		||||
#define EXTRA_INTERFACE         3
 | 
			
		||||
#define EXTRA_ENDPOINT          4
 | 
			
		||||
#define EXTRA_EPSIZE            8
 | 
			
		||||
 | 
			
		||||
/* extrakey IN request callback handler */
 | 
			
		||||
void extra_in_cb(USBDriver *usbp, usbep_t ep);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -111,24 +89,12 @@ typedef struct {
 | 
			
		|||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
 | 
			
		||||
#define CONSOLE_INTERFACE      2
 | 
			
		||||
#define CONSOLE_ENDPOINT       3
 | 
			
		||||
#define CONSOLE_EPSIZE         16
 | 
			
		||||
 | 
			
		||||
/* Number of IN reports that can be stored inside the output queue */
 | 
			
		||||
#define CONSOLE_QUEUE_CAPACITY 4
 | 
			
		||||
 | 
			
		||||
/* Console flush time */
 | 
			
		||||
#define CONSOLE_FLUSH_MS 50
 | 
			
		||||
 | 
			
		||||
/* Putchar over the USB console */
 | 
			
		||||
int8_t sendchar(uint8_t c);
 | 
			
		||||
 | 
			
		||||
/* Flush output (send everything immediately) */
 | 
			
		||||
void console_flush_output(void);
 | 
			
		||||
 | 
			
		||||
/* console IN request callback handler */
 | 
			
		||||
void console_in_cb(USBDriver *usbp, usbep_t ep);
 | 
			
		||||
#endif /* CONSOLE_ENABLE */
 | 
			
		||||
 | 
			
		||||
void sendchar_pf(void *p, char c);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ else
 | 
			
		|||
endif
 | 
			
		||||
 | 
			
		||||
LUFA_SRC = lufa.c \
 | 
			
		||||
	   descriptor.c \
 | 
			
		||||
	   usb_descriptor.c \
 | 
			
		||||
	   outputselect.c \
 | 
			
		||||
	   $(LUFA_SRC_USB)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,7 +49,7 @@
 | 
			
		|||
#endif
 | 
			
		||||
#include "suspend.h"
 | 
			
		||||
 | 
			
		||||
#include "descriptor.h"
 | 
			
		||||
#include "usb_descriptor.h"
 | 
			
		||||
#include "lufa.h"
 | 
			
		||||
#include "quantum.h"
 | 
			
		||||
#include <util/atomic.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -83,7 +83,7 @@
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
  #include "sysex_tools.h"
 | 
			
		||||
  #include "qmk_midi.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef RAW_ENABLE
 | 
			
		||||
| 
						 | 
				
			
			@ -97,12 +97,6 @@ static uint8_t keyboard_led_stats = 0;
 | 
			
		|||
 | 
			
		||||
static report_keyboard_t keyboard_report_sent;
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
 | 
			
		||||
static void usb_get_midi(MidiDevice * device);
 | 
			
		||||
static void midi_usb_init(MidiDevice * device);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* Host driver */
 | 
			
		||||
static uint8_t keyboard_leds(void);
 | 
			
		||||
static void send_keyboard(report_keyboard_t *report);
 | 
			
		||||
| 
						 | 
				
			
			@ -115,48 +109,8 @@ host_driver_t lufa_driver = {
 | 
			
		|||
    send_mouse,
 | 
			
		||||
    send_system,
 | 
			
		||||
    send_consumer,
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
    usb_send_func,
 | 
			
		||||
    usb_get_midi,
 | 
			
		||||
    midi_usb_init
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * MIDI
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
 | 
			
		||||
{
 | 
			
		||||
  .Config =
 | 
			
		||||
  {
 | 
			
		||||
    .StreamingInterfaceNumber = AS_INTERFACE,
 | 
			
		||||
    .DataINEndpoint           =
 | 
			
		||||
    {
 | 
			
		||||
      .Address          = MIDI_STREAM_IN_EPADDR,
 | 
			
		||||
      .Size             = MIDI_STREAM_EPSIZE,
 | 
			
		||||
      .Banks            = 1,
 | 
			
		||||
    },
 | 
			
		||||
    .DataOUTEndpoint          =
 | 
			
		||||
    {
 | 
			
		||||
      .Address          = MIDI_STREAM_OUT_EPADDR,
 | 
			
		||||
      .Size             = MIDI_STREAM_EPSIZE,
 | 
			
		||||
      .Banks            = 1,
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define SYSEX_START_OR_CONT 0x40
 | 
			
		||||
#define SYSEX_ENDS_IN_1 0x50
 | 
			
		||||
#define SYSEX_ENDS_IN_2 0x60
 | 
			
		||||
#define SYSEX_ENDS_IN_3 0x70
 | 
			
		||||
 | 
			
		||||
#define SYS_COMMON_1 0x50
 | 
			
		||||
#define SYS_COMMON_2 0x20
 | 
			
		||||
#define SYS_COMMON_3 0x30
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
USB_ClassInfo_CDC_Device_t cdc_device =
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -853,170 +807,32 @@ int8_t sendchar(uint8_t c)
 | 
			
		|||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
 | 
			
		||||
  MIDI_EventPacket_t event;
 | 
			
		||||
  event.Data1 = byte0;
 | 
			
		||||
  event.Data2 = byte1;
 | 
			
		||||
  event.Data3 = byte2;
 | 
			
		||||
 | 
			
		||||
  uint8_t cable = 0;
 | 
			
		||||
 | 
			
		||||
// Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPNUM);
 | 
			
		||||
 | 
			
		||||
  //if the length is undefined we assume it is a SYSEX message
 | 
			
		||||
  if (midi_packet_length(byte0) == UNDEFINED) {
 | 
			
		||||
    switch(cnt) {
 | 
			
		||||
      case 3:
 | 
			
		||||
        if (byte2 == SYSEX_END)
 | 
			
		||||
          event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
 | 
			
		||||
        else
 | 
			
		||||
          event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
 | 
			
		||||
        break;
 | 
			
		||||
      case 2:
 | 
			
		||||
        if (byte1 == SYSEX_END)
 | 
			
		||||
          event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
 | 
			
		||||
        else
 | 
			
		||||
          event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
 | 
			
		||||
        break;
 | 
			
		||||
      case 1:
 | 
			
		||||
        if (byte0 == SYSEX_END)
 | 
			
		||||
          event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
 | 
			
		||||
        else
 | 
			
		||||
          event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        return; //invalid cnt
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    //deal with 'system common' messages
 | 
			
		||||
    //TODO are there any more?
 | 
			
		||||
    switch(byte0 & 0xF0){
 | 
			
		||||
      case MIDI_SONGPOSITION:
 | 
			
		||||
        event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
 | 
			
		||||
        break;
 | 
			
		||||
      case MIDI_SONGSELECT:
 | 
			
		||||
      case MIDI_TC_QUARTERFRAME:
 | 
			
		||||
        event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        event.Event = MIDI_EVENT(cable, byte0);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
// Endpoint_Write_Stream_LE(&event, sizeof(event), NULL);
 | 
			
		||||
// Endpoint_ClearIN();
 | 
			
		||||
 | 
			
		||||
  MIDI_Device_SendEventPacket(&USB_MIDI_Interface, &event);
 | 
			
		||||
  MIDI_Device_Flush(&USB_MIDI_Interface);
 | 
			
		||||
  MIDI_Device_USBTask(&USB_MIDI_Interface);
 | 
			
		||||
  USB_USBTask();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void usb_get_midi(MidiDevice * device) {
 | 
			
		||||
  MIDI_EventPacket_t event;
 | 
			
		||||
  while (MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, &event)) {
 | 
			
		||||
 | 
			
		||||
    midi_packet_length_t length = midi_packet_length(event.Data1);
 | 
			
		||||
    uint8_t input[3];
 | 
			
		||||
    input[0] = event.Data1;
 | 
			
		||||
    input[1] = event.Data2;
 | 
			
		||||
    input[2] = event.Data3;
 | 
			
		||||
    if (length == UNDEFINED) {
 | 
			
		||||
      //sysex
 | 
			
		||||
      if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
 | 
			
		||||
        length = 3;
 | 
			
		||||
      } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
 | 
			
		||||
        length = 2;
 | 
			
		||||
      } else if(event.Event ==  MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
 | 
			
		||||
        length = 1;
 | 
			
		||||
      } else {
 | 
			
		||||
        //XXX what to do?
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //pass the data to the device input function
 | 
			
		||||
    if (length != UNDEFINED)
 | 
			
		||||
      midi_device_input(device, length, input);
 | 
			
		||||
  }
 | 
			
		||||
  MIDI_Device_USBTask(&USB_MIDI_Interface);
 | 
			
		||||
  USB_USBTask();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void midi_usb_init(MidiDevice * device){
 | 
			
		||||
  midi_device_init(device);
 | 
			
		||||
  midi_device_set_send_func(device, usb_send_func);
 | 
			
		||||
  midi_device_set_pre_input_process_func(device, usb_get_midi);
 | 
			
		||||
 | 
			
		||||
  // SetupHardware();
 | 
			
		||||
  sei();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void MIDI_Task(void)
 | 
			
		||||
USB_ClassInfo_MIDI_Device_t USB_MIDI_Interface =
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    /* Device must be connected and configured for the task to run */
 | 
			
		||||
    dprint("in MIDI_TASK\n");
 | 
			
		||||
    if (USB_DeviceState != DEVICE_STATE_Configured)
 | 
			
		||||
      return;
 | 
			
		||||
    dprint("continuing in MIDI_TASK\n");
 | 
			
		||||
 | 
			
		||||
    Endpoint_SelectEndpoint(MIDI_STREAM_IN_EPADDR);
 | 
			
		||||
 | 
			
		||||
    if (Endpoint_IsINReady())
 | 
			
		||||
  .Config =
 | 
			
		||||
  {
 | 
			
		||||
    .StreamingInterfaceNumber = AS_INTERFACE,
 | 
			
		||||
    .DataINEndpoint           =
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        dprint("Endpoint is ready\n");
 | 
			
		||||
 | 
			
		||||
        uint8_t MIDICommand = 0;
 | 
			
		||||
        uint8_t MIDIPitch;
 | 
			
		||||
 | 
			
		||||
        /* Get board button status - if pressed use channel 10 (percussion), otherwise use channel 1 */
 | 
			
		||||
        uint8_t Channel = MIDI_CHANNEL(1);
 | 
			
		||||
 | 
			
		||||
        MIDICommand = MIDI_COMMAND_NOTE_ON;
 | 
			
		||||
        MIDIPitch   = 0x3E;
 | 
			
		||||
 | 
			
		||||
        /* Check if a MIDI command is to be sent */
 | 
			
		||||
        if (MIDICommand)
 | 
			
		||||
        {
 | 
			
		||||
            dprint("Command exists\n");
 | 
			
		||||
            MIDI_EventPacket_t MIDIEvent = (MIDI_EventPacket_t)
 | 
			
		||||
                {
 | 
			
		||||
                    .Event       = MIDI_EVENT(0, MIDICommand),
 | 
			
		||||
 | 
			
		||||
                    .Data1       = MIDICommand | Channel,
 | 
			
		||||
                    .Data2       = MIDIPitch,
 | 
			
		||||
                    .Data3       = MIDI_STANDARD_VELOCITY,
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
            /* Write the MIDI event packet to the endpoint */
 | 
			
		||||
            Endpoint_Write_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
 | 
			
		||||
 | 
			
		||||
            /* Send the data in the endpoint to the host */
 | 
			
		||||
            Endpoint_ClearIN();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /* Select the MIDI OUT stream */
 | 
			
		||||
    Endpoint_SelectEndpoint(MIDI_STREAM_OUT_EPADDR);
 | 
			
		||||
 | 
			
		||||
    /* Check if a MIDI command has been received */
 | 
			
		||||
    if (Endpoint_IsOUTReceived())
 | 
			
		||||
      .Address          = MIDI_STREAM_IN_EPADDR,
 | 
			
		||||
      .Size             = MIDI_STREAM_EPSIZE,
 | 
			
		||||
      .Banks            = 1,
 | 
			
		||||
    },
 | 
			
		||||
    .DataOUTEndpoint          =
 | 
			
		||||
    {
 | 
			
		||||
        MIDI_EventPacket_t MIDIEvent;
 | 
			
		||||
      .Address          = MIDI_STREAM_OUT_EPADDR,
 | 
			
		||||
      .Size             = MIDI_STREAM_EPSIZE,
 | 
			
		||||
      .Banks            = 1,
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
        /* Read the MIDI event packet from the endpoint */
 | 
			
		||||
        Endpoint_Read_Stream_LE(&MIDIEvent, sizeof(MIDIEvent), NULL);
 | 
			
		||||
void send_midi_packet(MIDI_EventPacket_t* event) {
 | 
			
		||||
  MIDI_Device_SendEventPacket(&USB_MIDI_Interface, event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
        /* If the endpoint is now empty, clear the bank */
 | 
			
		||||
        if (!(Endpoint_BytesInEndpoint()))
 | 
			
		||||
        {
 | 
			
		||||
            /* Clear the endpoint ready for new packet */
 | 
			
		||||
            Endpoint_ClearOUT();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
bool recv_midi_packet(MIDI_EventPacket_t* const event) {
 | 
			
		||||
  return MIDI_Device_ReceiveEventPacket(&USB_MIDI_Interface, event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1105,26 +921,6 @@ static void setup_usb(void)
 | 
			
		|||
    print_set_sendchar(sendchar);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
void fallthrough_callback(MidiDevice * device,
 | 
			
		||||
    uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2);
 | 
			
		||||
void cc_callback(MidiDevice * device,
 | 
			
		||||
    uint8_t chan, uint8_t num, uint8_t val);
 | 
			
		||||
void sysex_callback(MidiDevice * device,
 | 
			
		||||
    uint16_t start, uint8_t length, uint8_t * data);
 | 
			
		||||
 | 
			
		||||
void setup_midi(void)
 | 
			
		||||
{
 | 
			
		||||
#ifdef MIDI_ADVANCED
 | 
			
		||||
	midi_init();
 | 
			
		||||
#endif
 | 
			
		||||
	midi_device_init(&midi_device);
 | 
			
		||||
    midi_device_set_send_func(&midi_device, usb_send_func);
 | 
			
		||||
    midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
int main(void)  __attribute__ ((weak));
 | 
			
		||||
int main(void)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1137,18 +933,6 @@ int main(void)
 | 
			
		|||
    setup_usb();
 | 
			
		||||
    sei();
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
    midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
 | 
			
		||||
    midi_register_cc_callback(&midi_device, cc_callback);
 | 
			
		||||
    midi_register_sysex_callback(&midi_device, sysex_callback);
 | 
			
		||||
 | 
			
		||||
    // init_notes();
 | 
			
		||||
    // midi_send_cc(&midi_device, 0, 1, 2);
 | 
			
		||||
    // midi_send_cc(&midi_device, 15, 1, 0);
 | 
			
		||||
    // midi_send_noteon(&midi_device, 0, 64, 127);
 | 
			
		||||
    // midi_send_noteoff(&midi_device, 0, 64, 127);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42)
 | 
			
		||||
    serial_init();
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -1193,10 +977,7 @@ int main(void)
 | 
			
		|||
        keyboard_task();
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
        midi_device_process(&midi_device);
 | 
			
		||||
#ifdef MIDI_ADVANCED
 | 
			
		||||
        midi_task();
 | 
			
		||||
#endif
 | 
			
		||||
        MIDI_Device_USBTask(&USB_MIDI_Interface);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined(RGBLIGHT_ANIMATIONS) & defined(RGBLIGHT_ENABLE)
 | 
			
		||||
| 
						 | 
				
			
			@ -1223,71 +1004,10 @@ int main(void)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
void fallthrough_callback(MidiDevice * device,
 | 
			
		||||
    uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
 | 
			
		||||
 | 
			
		||||
#ifdef AUDIO_ENABLE
 | 
			
		||||
  if (cnt == 3) {
 | 
			
		||||
    switch (byte0 & 0xF0) {
 | 
			
		||||
        case MIDI_NOTEON:
 | 
			
		||||
            play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
 | 
			
		||||
            break;
 | 
			
		||||
        case MIDI_NOTEOFF:
 | 
			
		||||
            stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (byte0 == MIDI_STOP) {
 | 
			
		||||
    stop_all_notes();
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
 | 
			
		||||
                                    const uint16_t wIndex,
 | 
			
		||||
                                    const void** const DescriptorAddress)
 | 
			
		||||
{
 | 
			
		||||
  return get_usb_descriptor(wValue, wIndex, DescriptorAddress);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void cc_callback(MidiDevice * device,
 | 
			
		||||
    uint8_t chan, uint8_t num, uint8_t val) {
 | 
			
		||||
  //sending it back on the next channel
 | 
			
		||||
  // midi_send_cc(device, (chan + 1) % 16, num, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef API_SYSEX_ENABLE
 | 
			
		||||
uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) {
 | 
			
		||||
    #ifdef API_SYSEX_ENABLE
 | 
			
		||||
        // SEND_STRING("\n");
 | 
			
		||||
        // send_word(start);
 | 
			
		||||
        // SEND_STRING(": ");
 | 
			
		||||
        // Don't store the header
 | 
			
		||||
        int16_t pos = start - 4;
 | 
			
		||||
        for (uint8_t place = 0; place < length; place++) {
 | 
			
		||||
            // send_byte(*data);
 | 
			
		||||
            if (pos >= 0) {
 | 
			
		||||
                if (*data == 0xF7) {
 | 
			
		||||
                    // SEND_STRING("\nRD: ");
 | 
			
		||||
                    // for (uint8_t i = 0; i < start + place + 1; i++){
 | 
			
		||||
                    //     send_byte(midi_buffer[i]);
 | 
			
		||||
                    // SEND_STRING(" ");
 | 
			
		||||
                    // }
 | 
			
		||||
                    const unsigned decoded_length = sysex_decoded_length(pos);
 | 
			
		||||
                    uint8_t decoded[API_SYSEX_MAX_SIZE];
 | 
			
		||||
                    sysex_decode(decoded, midi_buffer, pos);
 | 
			
		||||
                    process_api(decoded_length, decoded);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                else if (pos >= MIDI_SYSEX_BUFFER) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                midi_buffer[pos] = *data;
 | 
			
		||||
            }
 | 
			
		||||
            // SEND_STRING(" ");
 | 
			
		||||
            data++;
 | 
			
		||||
            pos++;
 | 
			
		||||
        }
 | 
			
		||||
    #endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,9 +48,6 @@
 | 
			
		|||
#include <LUFA/Version.h>
 | 
			
		||||
#include <LUFA/Drivers/USB/USB.h>
 | 
			
		||||
#include "host.h"
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
  #include "process_midi.h"
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -67,11 +64,6 @@ typedef struct {
 | 
			
		|||
    uint16_t usage;
 | 
			
		||||
} __attribute__ ((packed)) report_extra_t;
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
  void MIDI_Task(void);
 | 
			
		||||
  MidiDevice midi_device;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef API_ENABLE
 | 
			
		||||
  #include "api.h"
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,6 +5,7 @@ SRC += midi.c \
 | 
			
		|||
	   bytequeue/bytequeue.c \
 | 
			
		||||
	   bytequeue/interrupt_setting.c \
 | 
			
		||||
	   sysex_tools.c \
 | 
			
		||||
     qmk_midi.c \
 | 
			
		||||
	   $(LUFA_SRC_USBCLASS)
 | 
			
		||||
 | 
			
		||||
VPATH += $(TMK_PATH)/$(MIDI_DIR)
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +22,7 @@
 | 
			
		|||
//implementations of the typedef and these functions
 | 
			
		||||
 | 
			
		||||
#include "interrupt_setting.h"
 | 
			
		||||
#if defined(__AVR__)
 | 
			
		||||
#include <avr/interrupt.h>
 | 
			
		||||
 | 
			
		||||
interrupt_setting_t store_and_clear_interrupt(void) {
 | 
			
		||||
| 
						 | 
				
			
			@ -33,4 +34,16 @@ interrupt_setting_t store_and_clear_interrupt(void) {
 | 
			
		|||
void restore_interrupt_setting(interrupt_setting_t setting) {
 | 
			
		||||
   SREG = setting;
 | 
			
		||||
}
 | 
			
		||||
#elif defined(__arm__)
 | 
			
		||||
#include "ch.h"
 | 
			
		||||
 | 
			
		||||
interrupt_setting_t store_and_clear_interrupt(void) {
 | 
			
		||||
  chSysLock();
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void restore_interrupt_setting(interrupt_setting_t setting) {
 | 
			
		||||
   chSysUnlock();
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										184
									
								
								tmk_core/protocol/midi/qmk_midi.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								tmk_core/protocol/midi/qmk_midi.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,184 @@
 | 
			
		|||
#include <LUFA/Drivers/USB/USB.h>
 | 
			
		||||
#include "qmk_midi.h"
 | 
			
		||||
#include "sysex_tools.h"
 | 
			
		||||
#include "midi.h"
 | 
			
		||||
#include "usb_descriptor.h"
 | 
			
		||||
#include "process_midi.h"
 | 
			
		||||
#if API_SYSEX_ENABLE
 | 
			
		||||
#include "api.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * MIDI
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
 | 
			
		||||
MidiDevice midi_device;
 | 
			
		||||
 | 
			
		||||
#define SYSEX_START_OR_CONT 0x40
 | 
			
		||||
#define SYSEX_ENDS_IN_1 0x50
 | 
			
		||||
#define SYSEX_ENDS_IN_2 0x60
 | 
			
		||||
#define SYSEX_ENDS_IN_3 0x70
 | 
			
		||||
 | 
			
		||||
#define SYS_COMMON_1 0x50
 | 
			
		||||
#define SYS_COMMON_2 0x20
 | 
			
		||||
#define SYS_COMMON_3 0x30
 | 
			
		||||
 | 
			
		||||
static void usb_send_func(MidiDevice * device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) {
 | 
			
		||||
  MIDI_EventPacket_t event;
 | 
			
		||||
  event.Data1 = byte0;
 | 
			
		||||
  event.Data2 = byte1;
 | 
			
		||||
  event.Data3 = byte2;
 | 
			
		||||
 | 
			
		||||
  uint8_t cable = 0;
 | 
			
		||||
 | 
			
		||||
  //if the length is undefined we assume it is a SYSEX message
 | 
			
		||||
  if (midi_packet_length(byte0) == UNDEFINED) {
 | 
			
		||||
    switch(cnt) {
 | 
			
		||||
      case 3:
 | 
			
		||||
        if (byte2 == SYSEX_END)
 | 
			
		||||
          event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3);
 | 
			
		||||
        else
 | 
			
		||||
          event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
 | 
			
		||||
        break;
 | 
			
		||||
      case 2:
 | 
			
		||||
        if (byte1 == SYSEX_END)
 | 
			
		||||
          event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2);
 | 
			
		||||
        else
 | 
			
		||||
          event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
 | 
			
		||||
        break;
 | 
			
		||||
      case 1:
 | 
			
		||||
        if (byte0 == SYSEX_END)
 | 
			
		||||
          event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1);
 | 
			
		||||
        else
 | 
			
		||||
          event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT);
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        return; //invalid cnt
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    //deal with 'system common' messages
 | 
			
		||||
    //TODO are there any more?
 | 
			
		||||
    switch(byte0 & 0xF0){
 | 
			
		||||
      case MIDI_SONGPOSITION:
 | 
			
		||||
        event.Event = MIDI_EVENT(cable, SYS_COMMON_3);
 | 
			
		||||
        break;
 | 
			
		||||
      case MIDI_SONGSELECT:
 | 
			
		||||
      case MIDI_TC_QUARTERFRAME:
 | 
			
		||||
        event.Event = MIDI_EVENT(cable, SYS_COMMON_2);
 | 
			
		||||
        break;
 | 
			
		||||
      default:
 | 
			
		||||
        event.Event = MIDI_EVENT(cable, byte0);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  send_midi_packet(&event);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void usb_get_midi(MidiDevice * device) {
 | 
			
		||||
  MIDI_EventPacket_t event;
 | 
			
		||||
  while (recv_midi_packet(&event)) {
 | 
			
		||||
 | 
			
		||||
    midi_packet_length_t length = midi_packet_length(event.Data1);
 | 
			
		||||
    uint8_t input[3];
 | 
			
		||||
    input[0] = event.Data1;
 | 
			
		||||
    input[1] = event.Data2;
 | 
			
		||||
    input[2] = event.Data3;
 | 
			
		||||
    if (length == UNDEFINED) {
 | 
			
		||||
      //sysex
 | 
			
		||||
      if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) {
 | 
			
		||||
        length = 3;
 | 
			
		||||
      } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) {
 | 
			
		||||
        length = 2;
 | 
			
		||||
      } else if(event.Event ==  MIDI_EVENT(0, SYSEX_ENDS_IN_1)) {
 | 
			
		||||
        length = 1;
 | 
			
		||||
      } else {
 | 
			
		||||
        //XXX what to do?
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //pass the data to the device input function
 | 
			
		||||
    if (length != UNDEFINED)
 | 
			
		||||
      midi_device_input(device, length, input);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void fallthrough_callback(MidiDevice * device,
 | 
			
		||||
    uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2){
 | 
			
		||||
 | 
			
		||||
#ifdef AUDIO_ENABLE
 | 
			
		||||
  if (cnt == 3) {
 | 
			
		||||
    switch (byte0 & 0xF0) {
 | 
			
		||||
        case MIDI_NOTEON:
 | 
			
		||||
            play_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0), (byte2 & 0x7F) / 8);
 | 
			
		||||
            break;
 | 
			
		||||
        case MIDI_NOTEOFF:
 | 
			
		||||
            stop_note(((double)261.6)*pow(2.0, -4.0)*pow(2.0,(byte1 & 0x7F)/12.0));
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  if (byte0 == MIDI_STOP) {
 | 
			
		||||
    stop_all_notes();
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void cc_callback(MidiDevice * device,
 | 
			
		||||
    uint8_t chan, uint8_t num, uint8_t val) {
 | 
			
		||||
  //sending it back on the next channel
 | 
			
		||||
  // midi_send_cc(device, (chan + 1) % 16, num, val);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef API_SYSEX_ENABLE
 | 
			
		||||
uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0};
 | 
			
		||||
 | 
			
		||||
static void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) {
 | 
			
		||||
  // SEND_STRING("\n");
 | 
			
		||||
  // send_word(start);
 | 
			
		||||
  // SEND_STRING(": ");
 | 
			
		||||
  // Don't store the header
 | 
			
		||||
  int16_t pos = start - 4;
 | 
			
		||||
  for (uint8_t place = 0; place < length; place++) {
 | 
			
		||||
      // send_byte(*data);
 | 
			
		||||
      if (pos >= 0) {
 | 
			
		||||
          if (*data == 0xF7) {
 | 
			
		||||
              // SEND_STRING("\nRD: ");
 | 
			
		||||
              // for (uint8_t i = 0; i < start + place + 1; i++){
 | 
			
		||||
              //     send_byte(midi_buffer[i]);
 | 
			
		||||
              // SEND_STRING(" ");
 | 
			
		||||
              // }
 | 
			
		||||
              const unsigned decoded_length = sysex_decoded_length(pos);
 | 
			
		||||
              uint8_t decoded[API_SYSEX_MAX_SIZE];
 | 
			
		||||
              sysex_decode(decoded, midi_buffer, pos);
 | 
			
		||||
              process_api(decoded_length, decoded);
 | 
			
		||||
              return;
 | 
			
		||||
          }
 | 
			
		||||
          else if (pos >= MIDI_SYSEX_BUFFER) {
 | 
			
		||||
              return;
 | 
			
		||||
          }
 | 
			
		||||
          midi_buffer[pos] = *data;
 | 
			
		||||
      }
 | 
			
		||||
      // SEND_STRING(" ");
 | 
			
		||||
      data++;
 | 
			
		||||
      pos++;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
void midi_init(void);
 | 
			
		||||
 | 
			
		||||
void setup_midi(void)
 | 
			
		||||
{
 | 
			
		||||
#ifdef MIDI_ADVANCED
 | 
			
		||||
	midi_init();
 | 
			
		||||
#endif
 | 
			
		||||
	midi_device_init(&midi_device);
 | 
			
		||||
  midi_device_set_send_func(&midi_device, usb_send_func);
 | 
			
		||||
  midi_device_set_pre_input_process_func(&midi_device, usb_get_midi);
 | 
			
		||||
  midi_register_fallthrough_callback(&midi_device, fallthrough_callback);
 | 
			
		||||
  midi_register_cc_callback(&midi_device, cc_callback);
 | 
			
		||||
#ifdef API_SYSEX_ENABLE
 | 
			
		||||
  midi_register_sysex_callback(&midi_device, sysex_callback);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										9
									
								
								tmk_core/protocol/midi/qmk_midi.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								tmk_core/protocol/midi/qmk_midi.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,9 @@
 | 
			
		|||
#pragma once
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
  #include "midi.h"
 | 
			
		||||
  extern MidiDevice midi_device;
 | 
			
		||||
  void setup_midi(void);
 | 
			
		||||
  void send_midi_packet(MIDI_EventPacket_t* event);
 | 
			
		||||
  bool recv_midi_packet(MIDI_EventPacket_t* const event);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -38,7 +38,7 @@
 | 
			
		|||
 | 
			
		||||
#include "util.h"
 | 
			
		||||
#include "report.h"
 | 
			
		||||
#include "descriptor.h"
 | 
			
		||||
#include "usb_descriptor.h"
 | 
			
		||||
 | 
			
		||||
#ifndef USB_MAX_POWER_CONSUMPTION
 | 
			
		||||
#define USB_MAX_POWER_CONSUMPTION 500
 | 
			
		||||
| 
						 | 
				
			
			@ -571,6 +571,19 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
    .Audio_Interface_Association =
 | 
			
		||||
        {
 | 
			
		||||
            .Header                   = {.Size = sizeof(USB_Descriptor_Interface_Association_t), .Type = DTYPE_InterfaceAssociation},
 | 
			
		||||
 | 
			
		||||
            .FirstInterfaceIndex      = AC_INTERFACE,
 | 
			
		||||
            .TotalInterfaces          = 2,
 | 
			
		||||
 | 
			
		||||
            .Class                    = AUDIO_CSCP_AudioClass,
 | 
			
		||||
            .SubClass                 = AUDIO_CSCP_ControlSubclass,
 | 
			
		||||
            .Protocol                 = AUDIO_CSCP_ControlProtocol,
 | 
			
		||||
 | 
			
		||||
            .IADStrIndex              = NO_DESCRIPTOR,
 | 
			
		||||
        },
 | 
			
		||||
    .Audio_ControlInterface =
 | 
			
		||||
        {
 | 
			
		||||
            .Header                   = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
 | 
			
		||||
| 
						 | 
				
			
			@ -622,8 +635,9 @@ const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
 | 
			
		|||
 | 
			
		||||
            .AudioSpecification       = VERSION_BCD(1,0,0),
 | 
			
		||||
 | 
			
		||||
            .TotalLength              = (sizeof(USB_Descriptor_Configuration_t) -
 | 
			
		||||
                                         offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC))
 | 
			
		||||
            .TotalLength              = offsetof(USB_Descriptor_Configuration_t, MIDI_Out_Jack_Endpoint_SPC)
 | 
			
		||||
                                        + sizeof(USB_MIDI_Descriptor_Jack_Endpoint_t)
 | 
			
		||||
                                        - offsetof(USB_Descriptor_Configuration_t, Audio_StreamInterface_SPC)
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
    .MIDI_In_Jack_Emb =
 | 
			
		||||
| 
						 | 
				
			
			@ -879,9 +893,9 @@ const USB_Descriptor_String_t PROGMEM SerialNumberString =
 | 
			
		|||
 *  is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
 | 
			
		||||
 *  USB host.
 | 
			
		||||
 */
 | 
			
		||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
 | 
			
		||||
                                    const uint16_t wIndex,
 | 
			
		||||
                                    const void** const DescriptorAddress)
 | 
			
		||||
uint16_t get_usb_descriptor(const uint16_t wValue,
 | 
			
		||||
                            const uint16_t wIndex,
 | 
			
		||||
                            const void** const DescriptorAddress)
 | 
			
		||||
{
 | 
			
		||||
    const uint8_t  DescriptorType   = (wValue >> 8);
 | 
			
		||||
    const uint8_t  DescriptorIndex  = (wValue & 0xFF);
 | 
			
		||||
| 
						 | 
				
			
			@ -45,8 +45,9 @@
 | 
			
		|||
#define _DESCRIPTORS_H_
 | 
			
		||||
 | 
			
		||||
#include <LUFA/Drivers/USB/USB.h>
 | 
			
		||||
#include <avr/pgmspace.h>
 | 
			
		||||
 | 
			
		||||
#ifdef PROTOCOL_CHIBIOS
 | 
			
		||||
#include "hal.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -95,25 +96,26 @@ typedef struct
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MIDI_ENABLE
 | 
			
		||||
      // MIDI Audio Control Interface
 | 
			
		||||
      USB_Descriptor_Interface_t                Audio_ControlInterface;
 | 
			
		||||
      USB_Audio_Descriptor_Interface_AC_t       Audio_ControlInterface_SPC;
 | 
			
		||||
    USB_Descriptor_Interface_Association_t    Audio_Interface_Association;
 | 
			
		||||
    // MIDI Audio Control Interface
 | 
			
		||||
    USB_Descriptor_Interface_t                Audio_ControlInterface;
 | 
			
		||||
    USB_Audio_Descriptor_Interface_AC_t       Audio_ControlInterface_SPC;
 | 
			
		||||
 | 
			
		||||
      // MIDI Audio Streaming Interface
 | 
			
		||||
      USB_Descriptor_Interface_t                Audio_StreamInterface;
 | 
			
		||||
      USB_MIDI_Descriptor_AudioInterface_AS_t   Audio_StreamInterface_SPC;
 | 
			
		||||
      USB_MIDI_Descriptor_InputJack_t           MIDI_In_Jack_Emb;
 | 
			
		||||
      USB_MIDI_Descriptor_InputJack_t           MIDI_In_Jack_Ext;
 | 
			
		||||
      USB_MIDI_Descriptor_OutputJack_t          MIDI_Out_Jack_Emb;
 | 
			
		||||
      USB_MIDI_Descriptor_OutputJack_t          MIDI_Out_Jack_Ext;
 | 
			
		||||
      USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint;
 | 
			
		||||
      USB_MIDI_Descriptor_Jack_Endpoint_t       MIDI_In_Jack_Endpoint_SPC;
 | 
			
		||||
      USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint;
 | 
			
		||||
      USB_MIDI_Descriptor_Jack_Endpoint_t       MIDI_Out_Jack_Endpoint_SPC;
 | 
			
		||||
    // MIDI Audio Streaming Interface
 | 
			
		||||
    USB_Descriptor_Interface_t                Audio_StreamInterface;
 | 
			
		||||
    USB_MIDI_Descriptor_AudioInterface_AS_t   Audio_StreamInterface_SPC;
 | 
			
		||||
    USB_MIDI_Descriptor_InputJack_t           MIDI_In_Jack_Emb;
 | 
			
		||||
    USB_MIDI_Descriptor_InputJack_t           MIDI_In_Jack_Ext;
 | 
			
		||||
    USB_MIDI_Descriptor_OutputJack_t          MIDI_Out_Jack_Emb;
 | 
			
		||||
    USB_MIDI_Descriptor_OutputJack_t          MIDI_Out_Jack_Ext;
 | 
			
		||||
    USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_In_Jack_Endpoint;
 | 
			
		||||
    USB_MIDI_Descriptor_Jack_Endpoint_t       MIDI_In_Jack_Endpoint_SPC;
 | 
			
		||||
    USB_Audio_Descriptor_StreamEndpoint_Std_t MIDI_Out_Jack_Endpoint;
 | 
			
		||||
    USB_MIDI_Descriptor_Jack_Endpoint_t       MIDI_Out_Jack_Endpoint_SPC;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef VIRTSER_ENABLE
 | 
			
		||||
        USB_Descriptor_Interface_Association_t   CDC_Interface_Association;
 | 
			
		||||
  USB_Descriptor_Interface_Association_t   CDC_Interface_Association;
 | 
			
		||||
 | 
			
		||||
	// CDC Control Interface
 | 
			
		||||
	USB_Descriptor_Interface_t               CDC_CCI_Interface;
 | 
			
		||||
| 
						 | 
				
			
			@ -208,8 +210,14 @@ typedef struct
 | 
			
		|||
 | 
			
		||||
#ifdef CONSOLE_ENABLE
 | 
			
		||||
#   define CONSOLE_IN_EPNUM         (RAW_OUT_EPNUM + 1)
 | 
			
		||||
//#   define CONSOLE_OUT_EPNUM        (RAW_OUT_EPNUM + 2)
 | 
			
		||||
#ifdef PROTOCOL_CHIBIOS
 | 
			
		||||
// ChibiOS has enough memory and descriptor to actually enable the endpoint
 | 
			
		||||
// It could use the same endpoint numbers, as that's supported by ChibiOS
 | 
			
		||||
// But the QMK code currently assumes that the endpoint numbers are different
 | 
			
		||||
#   define CONSOLE_OUT_EPNUM        (RAW_OUT_EPNUM + 2)
 | 
			
		||||
#else
 | 
			
		||||
#   define CONSOLE_OUT_EPNUM        (RAW_OUT_EPNUM + 1)
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
#   define CONSOLE_OUT_EPNUM        RAW_OUT_EPNUM
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -241,27 +249,24 @@ typedef struct
 | 
			
		|||
#   define CDC_OUT_EPNUM	MIDI_STREAM_OUT_EPNUM
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if (defined(__AVR_ATmega32U2__) && CDC_OUT_EPNUM > 4) || \
 | 
			
		||||
    (defined(__AVR_ATmega32U4__) && CDC_OUT_EPNUM > 6)
 | 
			
		||||
# error "Endpoints are not available enough to support all functions. Remove some in Makefile.(MOUSEKEY, EXTRAKEY, CONSOLE, NKRO, MIDI, SERIAL)"
 | 
			
		||||
#if (defined(PROTOCOL_LUFA) && CDC_OUT_EPNUM > (ENDPOINT_TOTAL_ENDPOINTS - 1)) || \
 | 
			
		||||
  (defined(PROTOCOL_CHIBIOS) && CDC_OUT_EPNUM > USB_MAX_ENDPOINTS)
 | 
			
		||||
# error "There are not enough available endpoints to support all functions. Remove some in the rules.mk file.(MOUSEKEY, EXTRAKEY, CONSOLE, NKRO, MIDI, SERIAL, STENO)"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define KEYBOARD_EPSIZE             8
 | 
			
		||||
#define MOUSE_EPSIZE                8
 | 
			
		||||
#define EXTRAKEY_EPSIZE             8
 | 
			
		||||
#define RAW_EPSIZE              	32
 | 
			
		||||
#define RAW_EPSIZE              	  32
 | 
			
		||||
#define CONSOLE_EPSIZE              32
 | 
			
		||||
#define NKRO_EPSIZE                 32
 | 
			
		||||
#define MIDI_STREAM_EPSIZE          64
 | 
			
		||||
#define CDC_NOTIFICATION_EPSIZE     8
 | 
			
		||||
#define CDC_NOTIFICATION_EPSIZE     32
 | 
			
		||||
#define CDC_EPSIZE                  16
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
 | 
			
		||||
                                    const uint16_t wIndex,
 | 
			
		||||
                                    const void** const DescriptorAddress)
 | 
			
		||||
                                    ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
 | 
			
		||||
 | 
			
		||||
uint16_t get_usb_descriptor(const uint16_t wValue,
 | 
			
		||||
                            const uint16_t wIndex,
 | 
			
		||||
                            const void** const DescriptorAddress);
 | 
			
		||||
 | 
			
		||||
/* new API */
 | 
			
		||||
#if LUFA_VERSION_INTEGER < 0x140302
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue