Added HID etc code

This commit is contained in:
Roger Clark 2016-07-18 17:35:02 +10:00
parent 388e8efeb6
commit ff15d4815a
36 changed files with 3560 additions and 55 deletions

View File

@ -1,5 +1,7 @@
# STM32 Boards
menu.usb = USB Type
menu.device_variant=Variant
menu.bootloader_version=Bootloader version
menu.upload_method=Upload method
@ -12,7 +14,7 @@ mapleMini.build.board=MAPLE_MINI
mapleMini.vid.0=0x1EAF
mapleMini.pid.0=0x0004
mapleMini.build.core=maple
mapleMini.build.cpu_flags=-DMCU_STM32F103CB -DSERIAL_USB
mapleMini.build.cpu_flags=-DMCU_STM32F103CB -DUSB_HARDWARE
mapleMini.build.variant=maple_mini
mapleMini.upload.usbID=1EAF:0003
@ -21,6 +23,18 @@ mapleMini.upload.protocol=maple_dfu
mapleMini.upload.use_1200bps_touch=false
mapleMini.upload.file_type=bin
mapleMini.upload.auto_reset=true
mapleMini.menu.usb.serial=Serial
mapleMini.menu.usb.serial.build.usbtype=USB_SERIAL
mapleMini.menu.usb.hid_kmj=Keyboard + Mouse + Joystick
mapleMini.menu.usb.hid_kmj.build.usbtype=USB_HID_KMJ
mapleMini.menu.usb.hid_km=Keyboard + Mouse
mapleMini.menu.usb.hid_km.build.usbtype=USB_HID_KM
mapleMini.menu.usb.hid_j=Joystick
mapleMini.menu.usb.hid_j.build.usbtype=USB_HID_J
mapleMini.menu.usb.midi=MIDI
mapleMini.menu.usb.midi.build.usbtype=USB_MIDI
mapleMini.menu.usb.no_usb=No USB
mapleMini.menu.usb.no_usb.build.usbtype=NO_USB
mapleMini.menu.bootloader_version.original = Original (17k RAM,108k Flash)
mapleMini.menu.bootloader_version.original.build.vect=VECT_TAB_ADDR=0x8005000
@ -56,7 +70,7 @@ maple.upload.auto_reset=true
maple.build.board=MAPLE_REV3
maple.build.core=maple
maple.build.cpu_flags=-DMCU_STM32F103RB -DSERIAL_USB
maple.build.cpu_flags=-DMCU_STM32F103RB -DUSB_HARDWARE
maple.build.ldscript=ld/flash.ld
maple.build.variant=maple
maple.build.vect=VECT_TAB_ADDR=0x8005000
@ -68,7 +82,7 @@ mapleRET6.vid.0=0x1EAF
mapleRET6.pid.0=0x0004
mapleRET6.build.board=MAPLE_RET6
mapleRET6.build.core=maple
mapleRET6.build.cpu_flags=-DMCU_STM32F103RE -DSERIAL_USB
mapleRET6.build.cpu_flags=-DMCU_STM32F103RE -DUSB_HARDWARE
mapleRET6.build.ldscript=ld/stm32f103re-bootloader.ld
mapleRET6.build.variant=maple_ret6
@ -106,7 +120,7 @@ microduino32_flash.build.mcu=cortex-m3
microduino32_flash.build.f_cpu=72000000L
microduino32_flash.build.board=MICRODUINO_CORE_STM32
microduino32_flash.build.core=maple
microduino32_flash.build.extra_flags=-DMCU_STM32F103CB -mthumb -DSERIAL_USB -march=armv7-m -D__STM32F1__
microduino32_flash.build.extra_flags=-DMCU_STM32F103CB -mthumb -DUSB_HARDWARE -march=armv7-m -D__STM32F1__
microduino32_flash.build.ldscript=ld/flash.ld
microduino32_flash.build.variant=microduino
microduino32_flash.build.variant_system_lib=libmaple.a
@ -169,6 +183,13 @@ genericSTM32F103C.upload.use_1200bps_touch=false
genericSTM32F103C.upload.file_type=bin
genericSTM32F103C.upload.auto_reset=true
## STM32F103CB -------------------------
genericSTM32F103C.menu.device_variant.STM32F103CB=STM32F103CB (20k RAM. 128k Flash)
genericSTM32F103C.menu.device_variant.STM32F103CB.build.cpu_flags=-DMCU_STM32F103CB
genericSTM32F103C.menu.device_variant.STM32F103CB.build.ldscript=ld/jtag.ld
genericSTM32F103C.menu.device_variant.STM32F103CB.upload.maximum_size=131072
genericSTM32F103C.menu.device_variant.STM32F103CB.upload.ram.maximum_size=20480
genericSTM32F103C.menu.device_variant.STM32F103CB.upload.flash.maximum_size=131072
## STM32F103C8 -------------------------
genericSTM32F103C.menu.device_variant.STM32F103C8=STM32F103C8 (20k RAM. 64k Flash)
genericSTM32F103C.menu.device_variant.STM32F103C8.build.cpu_flags=-DMCU_STM32F103C8
@ -177,20 +198,12 @@ genericSTM32F103C.menu.device_variant.STM32F103C8.upload.maximum_size=65536
genericSTM32F103C.menu.device_variant.STM32F103C8.upload.ram.maximum_size=20480
genericSTM32F103C.menu.device_variant.STM32F103C8.upload.flash.maximum_size=65536
## STM32F103CB -------------------------
genericSTM32F103C.menu.device_variant.STM32F103CB=STM32F103CB (20k RAM. 128k Flash)
genericSTM32F103C.menu.device_variant.STM32F103CB.build.cpu_flags=-DMCU_STM32F103CB
genericSTM32F103C.menu.device_variant.STM32F103CB.build.ldscript=ld/jtag.ld
genericSTM32F103C.menu.device_variant.STM32F103CB.upload.maximum_size=131072
genericSTM32F103C.menu.device_variant.STM32F103CB.upload.ram.maximum_size=20480
genericSTM32F103C.menu.device_variant.STM32F103CB.upload.flash.maximum_size=131072
#---------------------------- UPLOAD METHODS ---------------------------
genericSTM32F103C.menu.upload_method.DFUUploadMethod=STM32duino bootloader
genericSTM32F103C.menu.upload_method.DFUUploadMethod.upload.protocol=maple_dfu
genericSTM32F103C.menu.upload_method.DFUUploadMethod.upload.tool=maple_upload
genericSTM32F103C.menu.upload_method.DFUUploadMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER
genericSTM32F103C.menu.upload_method.DFUUploadMethod.build.upload_flags=-DUSB_HARDWARE -DGENERIC_BOOTLOADER
genericSTM32F103C.menu.upload_method.DFUUploadMethod.build.vect=VECT_TAB_ADDR=0x8002000
genericSTM32F103C.menu.upload_method.DFUUploadMethod.build.ldscript=ld/bootloader_20.ld
genericSTM32F103C.menu.upload_method.DFUUploadMethod.upload.usbID=1EAF:0003
@ -199,18 +212,30 @@ genericSTM32F103C.menu.upload_method.DFUUploadMethod.upload.altID=2
genericSTM32F103C.menu.upload_method.serialMethod=Serial
genericSTM32F103C.menu.upload_method.serialMethod.upload.protocol=maple_serial
genericSTM32F103C.menu.upload_method.serialMethod.upload.tool=serial_upload
genericSTM32F103C.menu.upload_method.serialMethod.build.upload_flags=-DUSB_HARDWARE
genericSTM32F103C.menu.upload_method.STLinkMethod=STLink
genericSTM32F103C.menu.upload_method.STLinkMethod.upload.protocol=STLink
genericSTM32F103C.menu.upload_method.STLinkMethod.upload.tool=stlink_upload
genericSTM32F103C.menu.upload_method.STLinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DSERIAL_USB -DGENERIC_BOOTLOADER
genericSTM32F103C.menu.upload_method.STLinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DUSB_HARDWARE -DGENERIC_BOOTLOADER
genericSTM32F103C.menu.upload_method.BMPMethod=BMP (Black Magic Probe)
genericSTM32F103C.menu.upload_method.BMPMethod.upload.protocol=gdb_bmp
genericSTM32F103C.menu.upload_method.BMPMethod.upload.tool=bmp_upload
genericSTM32F103C.menu.upload_method.BMPMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG
genericSTM32F103C.menu.upload_method.BMPMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG -DUSB_HARDWARE
#--USB
genericSTM32F103C.menu.usb.serial=Serial
genericSTM32F103C.menu.usb.serial.build.usbtype=USB_SERIAL
genericSTM32F103C.menu.usb.hid_kmj=Keyboard + Mouse + Joystick
genericSTM32F103C.menu.usb.hid_kmj.build.usbtype=USB_HID_KMJ
genericSTM32F103C.menu.usb.hid_km=Keyboard + Mouse
genericSTM32F103C.menu.usb.hid_km.build.usbtype=USB_HID_KM
genericSTM32F103C.menu.usb.hid_j=Joystick
genericSTM32F103C.menu.usb.hid_j.build.usbtype=USB_HID_J
genericSTM32F103C.menu.usb.midi=MIDI
genericSTM32F103C.menu.usb.midi.build.usbtype=USB_MIDI
########################### Generic STM32F103R ###########################
genericSTM32F103R.name=Generic STM32F103R series
@ -261,7 +286,7 @@ genericSTM32F103R.menu.device_variant.STM32F103RE.build.ldscript=ld/stm32f103re.
genericSTM32F103R.menu.upload_method.DFUUploadMethod=STM32duino bootloader
genericSTM32F103R.menu.upload_method.DFUUploadMethod.upload.protocol=maple_dfu
genericSTM32F103R.menu.upload_method.DFUUploadMethod.upload.tool=maple_upload
genericSTM32F103R.menu.upload_method.DFUUploadMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER
genericSTM32F103R.menu.upload_method.DFUUploadMethod.build.upload_flags=-DUSB_HARDWARE -DGENERIC_BOOTLOADER
genericSTM32F103R.menu.upload_method.DFUUploadMethod.build.vect=VECT_TAB_ADDR=0x8002000
genericSTM32F103R.menu.upload_method.DFUUploadMethod.build.ldscript=ld/bootloader.ld
genericSTM32F103R.menu.upload_method.DFUUploadMethod.upload.usbID=1EAF:0003
@ -274,7 +299,7 @@ genericSTM32F103R.menu.upload_method.serialMethod.upload.tool=serial_upload
genericSTM32F103R.menu.upload_method.STLinkMethod=STLink
genericSTM32F103R.menu.upload_method.STLinkMethod.upload.protocol=STLink
genericSTM32F103R.menu.upload_method.STLinkMethod.upload.tool=stlink_upload
genericSTM32F103R.menu.upload_method.STLinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DSERIAL_USB -DGENERIC_BOOTLOADER
genericSTM32F103R.menu.upload_method.STLinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DUSB_HARDWARE -DGENERIC_BOOTLOADER
genericSTM32F103R.menu.upload_method.BMPMethod=BMP (Black Magic Probe)
genericSTM32F103R.menu.upload_method.BMPMethod.upload.protocol=gdb_bmp
@ -315,7 +340,7 @@ genericSTM32F103T.menu.device_variant.STM32F103TB.upload.flash.maximum_size=1310
genericSTM32F103T.menu.upload_method.DFUUploadMethod=STM32duino bootloader
genericSTM32F103T.menu.upload_method.DFUUploadMethod.upload.protocol=maple_dfu
genericSTM32F103T.menu.upload_method.DFUUploadMethod.upload.tool=maple_upload
genericSTM32F103T.menu.upload_method.DFUUploadMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER
genericSTM32F103T.menu.upload_method.DFUUploadMethod.build.upload_flags=-DUSB_HARDWARE -DGENERIC_BOOTLOADER
genericSTM32F103T.menu.upload_method.DFUUploadMethod.build.vect=VECT_TAB_ADDR=0x8002000
genericSTM32F103T.menu.upload_method.DFUUploadMethod.build.ldscript=ld/bootloader_20.ld
genericSTM32F103T.menu.upload_method.DFUUploadMethod.upload.usbID=1EAF:0003
@ -328,7 +353,7 @@ genericSTM32F103T.menu.upload_method.serialMethod.upload.tool=serial_upload
genericSTM32F103T.menu.upload_method.STLinkMethod=STLink
genericSTM32F103T.menu.upload_method.STLinkMethod.upload.protocol=STLink
genericSTM32F103T.menu.upload_method.STLinkMethod.upload.tool=stlink_upload
genericSTM32F103T.menu.upload_method.STLinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DSERIAL_USB -DGENERIC_BOOTLOADER
genericSTM32F103T.menu.upload_method.STLinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DUSB_HARDWARE -DGENERIC_BOOTLOADER
genericSTM32F103T.menu.upload_method.BMPMethod=BMP (Black Magic Probe)
genericSTM32F103T.menu.upload_method.BMPMethod.upload.protocol=gdb_bmp
@ -377,7 +402,7 @@ genericSTM32F103V.menu.device_variant.STM32F103VE.build.ldscript=ld/stm32f103ve.
genericSTM32F103V.menu.upload_method.DFUUploadMethod=STM32duino bootloader
genericSTM32F103V.menu.upload_method.DFUUploadMethod.upload.protocol=maple_dfu
genericSTM32F103V.menu.upload_method.DFUUploadMethod.upload.tool=maple_upload
genericSTM32F103V.menu.upload_method.DFUUploadMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER
genericSTM32F103V.menu.upload_method.DFUUploadMethod.build.upload_flags=-DUSB_HARDWARE -DGENERIC_BOOTLOADER
genericSTM32F103V.menu.upload_method.DFUUploadMethod.build.vect=VECT_TAB_ADDR=0x8002000
genericSTM32F103V.menu.upload_method.DFUUploadMethod.build.ldscript=ld/stm32f103veDFU.ld
genericSTM32F103V.menu.upload_method.DFUUploadMethod.upload.usbID=1EAF:0003
@ -390,7 +415,7 @@ genericSTM32F103V.menu.upload_method.serialMethod.upload.tool=serial_upload
genericSTM32F103V.menu.upload_method.STLinkMethod=STLink
genericSTM32F103V.menu.upload_method.STLinkMethod.upload.protocol=STLink
genericSTM32F103V.menu.upload_method.STLinkMethod.upload.tool=stlink_upload
genericSTM32F103V.menu.upload_method.STLinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DSERIAL_USB -DGENERIC_BOOTLOADER
genericSTM32F103V.menu.upload_method.STLinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DUSB_HARDWARE -DGENERIC_BOOTLOADER
genericSTM32F103V.menu.upload_method.BMPMethod=BMP (Black Magic Probe)
genericSTM32F103V.menu.upload_method.BMPMethod.upload.protocol=gdb_bmp
@ -436,7 +461,7 @@ genericSTM32F103Z.menu.device_variant.STM32F103ZE.build.ldscript=ld/stm32f103ze.
genericSTM32F103Z.menu.upload_method.DFUUploadMethod=STM32duino bootloader
genericSTM32F103Z.menu.upload_method.DFUUploadMethod.upload.protocol=maple_dfu
genericSTM32F103Z.menu.upload_method.DFUUploadMethod.upload.tool=maple_upload
genericSTM32F103Z.menu.upload_method.DFUUploadMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER
genericSTM32F103Z.menu.upload_method.DFUUploadMethod.build.upload_flags=-DUSB_HARDWARE -DGENERIC_BOOTLOADER
genericSTM32F103Z.menu.upload_method.DFUUploadMethod.build.vect=VECT_TAB_ADDR=0x8002000
genericSTM32F103Z.menu.upload_method.DFUUploadMethod.build.ldscript=ld/stm32f103z_dfu.ld
genericSTM32F103Z.menu.upload_method.DFUUploadMethod.upload.usbID=1EAF:0003
@ -449,7 +474,7 @@ genericSTM32F103Z.menu.upload_method.serialMethod.upload.tool=serial_upload
genericSTM32F103Z.menu.upload_method.STLinkMethod=STLink
genericSTM32F103Z.menu.upload_method.STLinkMethod.upload.protocol=STLink
genericSTM32F103Z.menu.upload_method.STLinkMethod.upload.tool=stlink_upload
genericSTM32F103Z.menu.upload_method.STLinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DSERIAL_USB -DGENERIC_BOOTLOADER
genericSTM32F103Z.menu.upload_method.STLinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DUSB_HARDWARE -DGENERIC_BOOTLOADER
genericSTM32F103Z.menu.upload_method.BMPMethod=BMP (Black Magic Probe)
genericSTM32F103Z.menu.upload_method.BMPMethod.upload.protocol=gdb_bmp
@ -490,7 +515,7 @@ genericGD32F103C.menu.upload_method.DFUUploadMethod=GD32duino bootloader
genericGD32F103C.menu.upload_method.DFUUploadMethod.upload.protocol=maple_dfu
genericGD32F103C.menu.upload_method.DFUUploadMethod.upload.tool=maple_upload
genericGD32F103C.menu.upload_method.DFUUploadMethod.build.upload_flags=-DSERIAL_USB -DGENERIC_BOOTLOADER
genericGD32F103C.menu.upload_method.DFUUploadMethod.build.upload_flags=-DUSB_HARDWARE -DGENERIC_BOOTLOADER
genericGD32F103C.menu.upload_method.DFUUploadMethod.build.vect=VECT_TAB_ADDR=0x8002000
genericGD32F103C.menu.upload_method.DFUUploadMethod.build.ldscript=ld/bootloader_20.ld
genericGD32F103C.menu.upload_method.DFUUploadMethod.upload.usbID=1EAF:0003
@ -504,7 +529,7 @@ genericGD32F103C.menu.upload_method.serialMethod.upload.tool=serial_upload
genericGD32F103C.menu.upload_method.STLinkMethod=STLink
genericGD32F103C.menu.upload_method.STLinkMethod.upload.protocol=STLink
genericGD32F103C.menu.upload_method.STLinkMethod.upload.tool=stlink_upload
genericGD32F103C.menu.upload_method.STLinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DSERIAL_USB -DGENERIC_BOOTLOADER
genericGD32F103C.menu.upload_method.STLinkMethod.build.upload_flags=-DCONFIG_MAPLE_MINI_NO_DISABLE_DEBUG=1 -DUSB_HARDWARE -DGENERIC_BOOTLOADER
genericGD32F103C.menu.upload_method.BMPMethod=BMP (Black Magic Probe)

View File

@ -49,7 +49,7 @@
BOARD_USART##n##_TX_PIN, \
BOARD_USART##n##_RX_PIN)
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
#if BOARD_HAVE_USART1
DEFINE_HWSERIAL(Serial1, 1);
#endif

View File

@ -181,7 +181,7 @@ private:
#endif
};
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
#if BOARD_HAVE_USART1
extern HardwareSerial Serial1;
#endif

View File

@ -0,0 +1,303 @@
//
// MinSysex.c
// LibMaple4Midi
//
// Created by Donald D Davis on 4/11/13.
// Copyright (c) 2013 Suspect Devices. All rights reserved.
// Modified BSD Liscense
/*
0xF0 SysEx
0x7E Non-Realtime
0x7F The SysEx channel. Could be from 0x00 to 0x7F.
Here we set it to "disregard channel".
0x06 Sub-ID -- General Information
0x01 Sub-ID2 -- Identity Request
0xF7 End of SysEx
---- response
0xF0 SysEx
0x7E Non-Realtime
0x7F The SysEx channel. Could be from 0x00 to 0x7F.
Here we set it to "disregard channel".
0x06 Sub-ID -- General Information
0x02 Sub-ID2 -- Identity Reply
0xID Manufacturer's ID
0xf1 The f1 and f2 bytes make up the family code. Each
0xf2 manufacturer assigns different family codes to his products.
0xp1 The p1 and p2 bytes make up the model number. Each
0xp2 manufacturer assigns different model numbers to his products.
0xv1 The v1, v2, v3 and v4 bytes make up the version number.
0xv2
0xv3
0xv4
0xF7 End of SysEx
*/
#ifdef USB_MIDI
// change this to packets
#define STANDARD_ID_RESPONSE_LENGTH 7
#include <libmaple/usb_midi_device.h>
#include <libmaple/nvic.h>
#include <libmaple/delay.h>
#include <MinSysex.h>
//#include <wirish/wirish.h>
#define MAX_SYSEX_SIZE 256
/********************************* ACHTUNG! ignores usbmidi cable ********************************/
/*const MIDI_EVENT_PACKET_t standardIDResponse[]={
{ DEFAULT_MIDI_CABLE,
CIN_SYSEX,
MIDIv1_SYSEX_START,
USYSEX_NON_REAL_TIME,
USYSEX_ALL_CHANNELS},
{ DEFAULT_MIDI_CABLE,
CIN_SYSEX,
USYSEX_GENERAL_INFO,
USYSEX_GI_ID_RESPONSE,
LEAFLABS_MMA_VENDOR_1},
{ DEFAULT_MIDI_CABLE,
CIN_SYSEX,
LEAFLABS_MMA_VENDOR_2, // extended ID
LEAFLABS_MMA_VENDOR_3, // extended ID
1}, // family #1
{ DEFAULT_MIDI_CABLE,
CIN_SYSEX,
2, // family #2
1, // part #1
2}, // part #2
{ DEFAULT_MIDI_CABLE,
CIN_SYSEX,
0, // version 1
0, // version 2
1}, // version 3
{ DEFAULT_MIDI_CABLE,
CIN_SYSEX_ENDS_IN_2,
'!', // lgl compatible
MIDIv1_SYSEX_END,
0}
};
*/
const uint8 standardIDResponse[]={
CIN_SYSEX,
MIDIv1_SYSEX_START,
USYSEX_NON_REAL_TIME,
USYSEX_ALL_CHANNELS,
CIN_SYSEX,
USYSEX_GENERAL_INFO,
USYSEX_GI_ID_RESPONSE,
LEAFLABS_MMA_VENDOR_1,
CIN_SYSEX,
LEAFLABS_MMA_VENDOR_2, // extended ID
LEAFLABS_MMA_VENDOR_3, // extended ID
1, // family #1
CIN_SYSEX,
2, // family #2
1, // part #1
2, // part #2
CIN_SYSEX,
0, // version 1
0, // version 2
1, // version 3
CIN_SYSEX_ENDS_IN_2,
'!', // lgl compatible
MIDIv1_SYSEX_END,
0
};
//#define STANDARD_ID_RESPONSE_LENGTH (sizeof(standardIDResponse))
typedef enum {NOT_IN_SYSEX=0,COULD_BE_MY_SYSEX,YUP_ITS_MY_SYSEX,ITS_NOT_MY_SYSEX} sysexStates;
volatile uint8 sysexBuffer[MAX_SYSEX_SIZE];
volatile sysexStates sysexState;
volatile int sysexFinger=0;
/*
0xF0 SysEx
0x?? LEAFLABS_MMA_VENDOR_1
0x?? LEAFLABS_MMA_VENDOR_2
0x?? LEAFLABS_MMA_VENDOR_3
0x10 LGL_DEVICE_NUMBER
0xLE CMD: REBOOT
0xf7 EOSysEx
*/
#define STACK_TOP 0x20000800
#define EXC_RETURN 0xFFFFFFF9
#define DEFAULT_CPSR 0x61000000
#define RESET_DELAY 100000
static void wait_reset(void) {
delay_us(RESET_DELAY);
nvic_sys_reset();
}
/* -----------------------------------------------------------------------------dealWithItQuickly()
* Note: at this point we have established that the sysex belongs to us.
* So we need to respond to any generic requests like information requests.
* We also need to handle requests which are meant for us. At the moment this is just the
* reset request.
*
*/
void dealWithItQuickly(){
switch (sysexBuffer[1]) {
case USYSEX_NON_REAL_TIME:
switch (sysexBuffer[3]) {
case USYSEX_GENERAL_INFO:
if (sysexBuffer[4]==USYSEX_GI_ID_REQUEST) {
usb_midi_tx((uint32 *) standardIDResponse, STANDARD_ID_RESPONSE_LENGTH);
}
}
case USYSEX_REAL_TIME:
break;
case LEAFLABS_MMA_VENDOR_1:
if (sysexBuffer[5]==LGL_RESET_CMD) {
uintptr_t target = (uintptr_t)wait_reset | 0x1;
asm volatile("mov r0, %[stack_top] \n\t" // Reset stack
"mov sp, r0 \n\t"
"mov r0, #1 \n\t"
"mov r1, %[target_addr] \n\t"
"mov r2, %[cpsr] \n\t"
"push {r2} \n\t" // Fake xPSR
"push {r1} \n\t" // PC target addr
"push {r0} \n\t" // Fake LR
"push {r0} \n\t" // Fake R12
"push {r0} \n\t" // Fake R3
"push {r0} \n\t" // Fake R2
"push {r0} \n\t" // Fake R1
"push {r0} \n\t" // Fake R0
"mov lr, %[exc_return] \n\t"
"bx lr"
:
: [stack_top] "r" (STACK_TOP),
[target_addr] "r" (target),
[exc_return] "r" (EXC_RETURN),
[cpsr] "r" (DEFAULT_CPSR)
: "r0", "r1", "r2");
/* Can't happen. */
ASSERT_FAULT(0);
}
default:
break;
}
;//turn the led on?
}
/* -----------------------------------------------------------------------------LglSysexHandler()
* The idea here is to identify which Sysex's belong to us and deal with them.
*/
void LglSysexHandler(uint32 *midiBufferRx, uint32 *rx_offset, uint32 *n_unread_packets) {
MIDI_EVENT_PACKET_t * midiPackets = (MIDI_EVENT_PACKET_t *) (midiBufferRx+(*rx_offset));
uint8 nPackets=((*n_unread_packets)-(*rx_offset));
int cPacket;
uint8 soPackets=0;
/********************************* ACHTUNG! ignores usbmidi cable ********************************/
MIDI_EVENT_PACKET_t *packet;
for (cPacket=0;cPacket<nPackets;cPacket++){
packet=midiPackets+cPacket;
if (!CIN_IS_SYSEX(packet->cin)) {
continue;
} // else {
if (!soPackets) {
soPackets=cPacket*4;
}
if ((sysexState==YUP_ITS_MY_SYSEX) && ((sysexFinger+3)>=MAX_SYSEX_SIZE)){
sysexState=ITS_NOT_MY_SYSEX; //eisenhower policy. Even if its mine I cant deal with it.
}
switch (packet->cin) {
case CIN_SYSEX:
switch (sysexState) {
case NOT_IN_SYSEX : // new sysex.
sysexFinger=0;
if (packet->midi0 == MIDIv1_SYSEX_START) {
if (packet->midi1==USYSEX_REAL_TIME
||packet->midi1==USYSEX_NON_REAL_TIME) {
if ((packet->midi2==myMidiChannel)
||(packet->midi2==USYSEX_ALL_CHANNELS)
) {
sysexState=YUP_ITS_MY_SYSEX;
sysexBuffer[sysexFinger++]=MIDIv1_SYSEX_START;
sysexBuffer[sysexFinger++]=packet->midi1;
sysexBuffer[sysexFinger++]=packet->midi2;
break;
}
} else if ((packet->midi1==myMidiID[0])
&& (packet->midi2==myMidiID[1])
){
sysexState=COULD_BE_MY_SYSEX;
sysexBuffer[sysexFinger++]=MIDIv1_SYSEX_START;
sysexBuffer[sysexFinger++]=packet->midi1;
sysexBuffer[sysexFinger++]=packet->midi2;
break;
}
}
break;
case COULD_BE_MY_SYSEX:
if (packet->midi0==myMidiID[2]) {
sysexState=YUP_ITS_MY_SYSEX;
sysexBuffer[sysexFinger++]=packet->midi0;
sysexBuffer[sysexFinger++]=packet->midi1;
sysexBuffer[sysexFinger++]=packet->midi2;
} else {
sysexState=ITS_NOT_MY_SYSEX;
sysexFinger=0;
}
break;
default:
break;
}
break;
case CIN_SYSEX_ENDS_IN_1:
case CIN_SYSEX_ENDS_IN_2:
case CIN_SYSEX_ENDS_IN_3:
sysexBuffer[sysexFinger++]=packet->midi0;
sysexBuffer[sysexFinger++]=packet->midi1;
sysexBuffer[sysexFinger++]=packet->midi2;
if (sysexState==YUP_ITS_MY_SYSEX) {
if(cPacket>=(*n_unread_packets)){
*n_unread_packets = soPackets;
*rx_offset = soPackets;
} else {
uint8 c = cPacket;
uint32 *s;
uint32 *d = midiBufferRx + soPackets;
for (s = midiBufferRx+c;
((*n_unread_packets) && (s <= midiBufferRx+(USB_MIDI_RX_EPSIZE/4)));
d++,s++
) {
(*d)=(*s);
(*n_unread_packets)--;
(*rx_offset)++;
}
// we need to reset the for loop variables to re process remaining data.
nPackets=((*n_unread_packets)-(*rx_offset));
cPacket=(*rx_offset);
}
dealWithItQuickly();
}
sysexFinger=0;
sysexState=NOT_IN_SYSEX;
break;
default:
return;
}
//}
}
// its our sysex and we will cry if we want to
return;
}
#endif

View File

@ -0,0 +1,41 @@
//
// lgl_min_sysex.h
// LibMaple4Midi
//
// Created by Donald D Davis on 4/11/13.
// Copyright (c) 2013 Suspect Devices. All rights reserved.
//
#ifdef USB_MIDI
#ifndef __LGL_MIN_SYSEX_H__
#define __LGL_MIN_SYSEX_H__ 1
#include "MidiSpecs.h"
//#include "LGL.h"
#define LEAFLABS_MMA_VENDOR_1 0x7D
#define LEAFLABS_MMA_VENDOR_2 0x1E
#define LEAFLABS_MMA_VENDOR_3 0x4F
// move to LGL.h
#define LGL_RESET_CMD 0x1e
#define DEFAULT_MIDI_CHANNEL 0x0A
#define DEFAULT_MIDI_DEVICE 0x0A
#define DEFAULT_MIDI_CABLE 0x00
// eventually all of this should be in a place for settings which can be written to flash.
extern volatile uint8 myMidiChannel;
extern volatile uint8 myMidiDevice;
extern volatile uint8 myMidiCable;
extern volatile uint8 myMidiID[];
void LglSysexHandler(uint32 *midiBufferRx,uint32 *rx_offset,uint32 *n_unread_bytes);
#endif
#endif

View File

@ -33,6 +33,8 @@
* the result made cleaner.
*/
#ifdef USB_SERIAL
#include <libmaple/usb_cdcacm.h>
#include <libmaple/usb.h>
@ -749,3 +751,5 @@ static void usbSetConfiguration(void) {
static void usbSetDeviceAddress(void) {
USBLIB->state = USB_ADDRESSED;
}
#endif

View File

@ -0,0 +1,746 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @file libmaple/usb/stm32f1/usb_hid.c
* @brief USB HID (human interface device) support
*
* FIXME: this works on the STM32F1 USB peripherals, and probably no
* place else. Nonportable bits really need to be factored out, and
* the result made cleaner.
*/
#if defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J)
#include <libmaple/usb_hid.h>
#include <libmaple/usb.h>
#include <libmaple/nvic.h>
#include <libmaple/delay.h>
/* Private headers */
#include "usb_lib_globals.h"
#include "usb_reg_map.h"
/* usb_lib headers */
#include "usb_type.h"
#include "usb_core.h"
#include "usb_def.h"
/******************************************************************************
******************************************************************************
***
*** HACK ALERT! FIXME FIXME FIXME FIXME!
***
*** A bunch of LeafLabs-specific configuration lives in here for
*** now. This mess REALLY needs to get teased apart, with
*** appropriate pieces moved into Wirish.
***
******************************************************************************
*****************************************************************************/
#if !(defined(BOARD_maple) || defined(BOARD_maple_RET6) || \
defined(BOARD_maple_mini) || defined(BOARD_maple_native))
#warning USB HID relies on LeafLabs board-specific configuration.\
You may have problems on non-LeafLabs boards.
#endif
uint32 ProtocolValue;
static void hidDataTxCb(void);
static void hidDataRxCb(void);
static void usbInit(void);
static void usbReset(void);
static RESULT usbDataSetup(uint8 request);
static RESULT usbNoDataSetup(uint8 request);
static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting);
static uint8* usbGetDeviceDescriptor(uint16 length);
static uint8* usbGetConfigDescriptor(uint16 length);
static uint8* usbGetStringDescriptor(uint16 length);
static void usbSetConfiguration(void);
static void usbSetDeviceAddress(void);
/*
* Descriptors
*/
const uint8_t hid_report_descriptor[] = {
#if defined(USB_HID_KMJ) || defined(USB_HID_KM)
// Mouse
0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 54
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x01, // REPORT_ID (1)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xc0, // END_COLLECTION
// Keyboard
0x05, 0x01, // USAGE_PAGE (Generic Desktop) // 47
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x85, 0x02, // REPORT_ID (2)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x95, 0x06, // REPORT_COUNT (6)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x65, // LOGICAL_MAXIMUM (101)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0, // END_COLLECTION
#endif
#if defined(USB_HID_KMJ) || defined(USB_HID_J)
// Joystick
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x04, // Usage (Joystick)
0xA1, 0x01, // Collection (Application)
0x85, 0x03, // REPORT_ID (3)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x75, 0x01, // Report Size (1)
0x95, 0x20, // Report Count (32)
0x05, 0x09, // Usage Page (Button)
0x19, 0x01, // Usage Minimum (Button #1)
0x29, 0x20, // Usage Maximum (Button #32)
0x81, 0x02, // Input (variable,absolute)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x07, // Logical Maximum (7)
0x35, 0x00, // Physical Minimum (0)
0x46, 0x3B, 0x01, // Physical Maximum (315)
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x65, 0x14, // Unit (20)
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x39, // Usage (Hat switch)
0x81, 0x42, // Input (variable,absolute,null_state)
0x05, 0x01, //Usage Page (Generic Desktop)
0x09, 0x01, //Usage (Pointer)
0xA1, 0x00, //Collection ()
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x03, // Logical Maximum (1023)
0x75, 0x0A, // Report Size (10)
0x95, 0x04, // Report Count (4)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x32, // Usage (Z)
0x09, 0x35, // Usage (Rz)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x03, // Logical Maximum (1023)
0x75, 0x0A, // Report Size (10)
0x95, 0x02, // Report Count (2)
0x09, 0x36, // Usage (Slider)
0x09, 0x36, // Usage (Slider)
0x81, 0x02, // Input (variable,absolute)
0xC0, // End Collection
#endif
#ifdef USB_RAWHID
// RAW HID
0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), // 30
0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE),
0xA1, 0x01, // Collection 0x01
0x85, 0x03, // REPORT_ID (3)
0x75, 0x08, // report size = 8 bits
0x15, 0x00, // logical minimum = 0
0x26, 0xFF, 0x00, // logical maximum = 255
0x95, 64, // report count TX
0x09, 0x01, // usage
0x81, 0x02, // Input (array)
0x95, 64, // report count RX
0x09, 0x02, // usage
0x91, 0x02, // Output (array)
0xC0 // end collection
#endif
};
/* FIXME move to Wirish */
#define LEAFLABS_ID_VENDOR 0x1EAF
#define MAPLE_ID_PRODUCT 0x0024
static const usb_descriptor_device usbHIDDescriptor_Device =
USB_HID_DECLARE_DEV_DESC(LEAFLABS_ID_VENDOR, MAPLE_ID_PRODUCT);
typedef struct {
usb_descriptor_config_header Config_Header;
usb_descriptor_interface HID_Interface;
HIDDescriptor HID_Descriptor;
usb_descriptor_endpoint DataInEndpoint;
usb_descriptor_endpoint DataOutEndpoint;
} __packed usb_descriptor_config;
#define MAX_POWER (100 >> 1)
static const usb_descriptor_config usbHIDDescriptor_Config =
{
.Config_Header = {
.bLength = sizeof(usb_descriptor_config_header),
.bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION,
.wTotalLength = sizeof(usb_descriptor_config),//0,
.bNumInterfaces = 0x01,
.bConfigurationValue = 0x01,
.iConfiguration = 0x00,
.bmAttributes = (USB_CONFIG_ATTR_BUSPOWERED |
USB_CONFIG_ATTR_SELF_POWERED),
.bMaxPower = MAX_POWER,
},
.HID_Interface = {
.bLength = sizeof(usb_descriptor_interface),
.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
.bInterfaceNumber = 0x00,
.bAlternateSetting = 0x00,
.bNumEndpoints = 0x02,
.bInterfaceClass = USB_INTERFACE_CLASS_HID,
.bInterfaceSubClass = USB_INTERFACE_SUBCLASS_HID,
.bInterfaceProtocol = 0x00, /* Common AT Commands */
.iInterface = 0x00,
},
.HID_Descriptor = {
.len = 9,//sizeof(HIDDescDescriptor),
.dtype = HID_DESCRIPTOR_TYPE,
.versionL = 0x10,
.versionH = 0x01,
.country = 0x00,
.numDesc = 0x01,
.desctype = REPORT_DESCRIPTOR,//0x22,
.descLenL = sizeof(hid_report_descriptor),
.descLenH = 0x00,
},
.DataInEndpoint = {
.bLength = sizeof(usb_descriptor_endpoint),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | USB_HID_TX_ENDP),//0x81,//USB_HID_TX_ADDR,
.bmAttributes = USB_ENDPOINT_TYPE_INTERRUPT,
.wMaxPacketSize = USB_HID_TX_EPSIZE,//0x40,//big enough for a keyboard 9 byte packet and for a mouse 5 byte packet
.bInterval = 0x0A,
},
.DataOutEndpoint = {
.bLength = sizeof(usb_descriptor_endpoint),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_OUT | USB_HID_RX_ENDP),
.bmAttributes = USB_EP_TYPE_BULK,
.wMaxPacketSize = USB_HID_RX_EPSIZE,
.bInterval = 0x00,
},
};
/*
String Descriptors:
we may choose to specify any or none of the following string
identifiers:
iManufacturer: LeafLabs
iProduct: Maple
iSerialNumber: NONE
iConfiguration: NONE
iInterface(CCI): NONE
iInterface(DCI): NONE
*/
/* Unicode language identifier: 0x0409 is US English */
/* FIXME move to Wirish */
static const usb_descriptor_string usbHIDDescriptor_LangID = {
.bLength = USB_DESCRIPTOR_STRING_LEN(1),
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
.bString = {0x09, 0x04},
};
/* FIXME move to Wirish */
static const usb_descriptor_string usbHIDDescriptor_iManufacturer = {
.bLength = USB_DESCRIPTOR_STRING_LEN(8),
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
.bString = {'L', 0, 'e', 0, 'a', 0, 'f', 0,
'L', 0, 'a', 0, 'b', 0, 's', 0},
};
/* FIXME move to Wirish */
static const usb_descriptor_string usbHIDDescriptor_iProduct = {
.bLength = USB_DESCRIPTOR_STRING_LEN(5),
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
.bString = {'M', 0, 'a', 0, 'p', 0, 'l', 0, 'e', 0},
};
/* FIXME move to Wirish */
static const usb_descriptor_string usbHIDDescriptor_iInterface = {
.bLength = USB_DESCRIPTOR_STRING_LEN(3),
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
.bString = {'H', 0, 'I', 0, 'D', 0},
};
static ONE_DESCRIPTOR Device_Descriptor = {
(uint8*)&usbHIDDescriptor_Device,
sizeof(usb_descriptor_device)
};
static ONE_DESCRIPTOR Config_Descriptor = {
(uint8*)&usbHIDDescriptor_Config,
sizeof(usbHIDDescriptor_Config)
};
static ONE_DESCRIPTOR HID_Report_Descriptor = {
(uint8*)&hid_report_descriptor,
sizeof(hid_report_descriptor)
};
#define N_STRING_DESCRIPTORS 3
static ONE_DESCRIPTOR String_Descriptor[N_STRING_DESCRIPTORS] = {
{(uint8*)&usbHIDDescriptor_LangID, USB_DESCRIPTOR_STRING_LEN(1)},
{(uint8*)&usbHIDDescriptor_iManufacturer,USB_DESCRIPTOR_STRING_LEN(8)},
{(uint8*)&usbHIDDescriptor_iProduct, USB_DESCRIPTOR_STRING_LEN(5)},
{(uint8*)&usbHIDDescriptor_iInterface, USB_DESCRIPTOR_STRING_LEN(3)}
};
/*
* Etc.
*/
/* I/O state */
#define HID_BUFFER_SIZE 512
/* Received data */
static volatile uint8 hidBufferRx[HID_BUFFER_SIZE];
/* Read index into hidBufferRx */
static volatile uint32 rx_offset = 0;
/* Number of bytes left to transmit */
static volatile uint32 n_unsent_bytes = 0;
/* Are we currently sending an IN packet? */
static volatile uint8 transmitting = 0;
/* Number of unread bytes */
static volatile uint32 n_unread_bytes = 0;
/*
* Endpoint callbacks
*/
static void (*ep_int_in[7])(void) =
{hidDataTxCb,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process};
static void (*ep_int_out[7])(void) =
{NOP_Process,
hidDataRxCb,//NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process};
/*
* Globals required by usb_lib/
*
* Mark these weak so they can be overriden to implement other USB
* functionality.
*/
#define NUM_ENDPTS 0x02
__weak DEVICE Device_Table = {
.Total_Endpoint = NUM_ENDPTS,
.Total_Configuration = 1
};
#define MAX_PACKET_SIZE 0x40 /* 64B, maximum for USB FS Devices */
__weak DEVICE_PROP Device_Property = {
.Init = usbInit,
.Reset = usbReset,
.Process_Status_IN = NOP_Process,
.Process_Status_OUT = NOP_Process,
.Class_Data_Setup = usbDataSetup,
.Class_NoData_Setup = usbNoDataSetup,
.Class_Get_Interface_Setting = usbGetInterfaceSetting,
.GetDeviceDescriptor = usbGetDeviceDescriptor,
.GetConfigDescriptor = usbGetConfigDescriptor,
.GetStringDescriptor = usbGetStringDescriptor,
.RxEP_buffer = NULL,
.MaxPacketSize = MAX_PACKET_SIZE
};
__weak USER_STANDARD_REQUESTS User_Standard_Requests = {
.User_GetConfiguration = NOP_Process,
.User_SetConfiguration = usbSetConfiguration,
.User_GetInterface = NOP_Process,
.User_SetInterface = NOP_Process,
.User_GetStatus = NOP_Process,
.User_ClearFeature = NOP_Process,
.User_SetEndPointFeature = NOP_Process,
.User_SetDeviceFeature = NOP_Process,
.User_SetDeviceAddress = usbSetDeviceAddress
};
/*
* HID interface
*/
void usb_hid_enable(gpio_dev *disc_dev, uint8 disc_bit) {
/* Present ourselves to the host. Writing 0 to "disc" pin must
* pull USB_DP pin up while leaving USB_DM pulled down by the
* transceiver. See USB 2.0 spec, section 7.1.7.3. */
gpio_set_mode(disc_dev, disc_bit, GPIO_OUTPUT_PP);
gpio_write_bit(disc_dev, disc_bit, 0);
/* Initialize the USB peripheral. */
usb_init_usblib(USBLIB, ep_int_in, ep_int_out);
}
void usb_hid_disable(gpio_dev *disc_dev, uint8 disc_bit) {
/* Turn off the interrupt and signal disconnect (see e.g. USB 2.0
* spec, section 7.1.7.3). */
nvic_irq_disable(NVIC_USB_LP_CAN_RX0);
gpio_write_bit(disc_dev, disc_bit, 1);
}
void usb_hid_putc(char ch) {
while (!usb_hid_tx((uint8*)&ch, 1))
;
}
/* This function is non-blocking.
*
* It copies data from a usercode buffer into the USB peripheral TX
* buffer, and returns the number of bytes copied. */
uint32 usb_hid_tx(const uint8* buf, uint32 len) {
/* Last transmission hasn't finished, so abort. */
if (usb_hid_is_transmitting()) {
return 0;
}
/* We can only put USB_HID_TX_EPSIZE bytes in the buffer. */
if (len > USB_HID_TX_EPSIZE) {
len = USB_HID_TX_EPSIZE;
}
/* Queue bytes for sending. */
if (len) {
usb_copy_to_pma(buf, len, GetEPTxAddr(USB_HID_TX_ENDP));//USB_HID_TX_ADDR);
}
// We still need to wait for the interrupt, even if we're sending
// zero bytes. (Sending zero-size packets is useful for flushing
// host-side buffers.)
usb_set_ep_tx_count(USB_HID_TX_ENDP, len);
n_unsent_bytes = len;
transmitting = 1;
usb_set_ep_tx_stat(USB_HID_TX_ENDP, USB_EP_STAT_TX_VALID);
return len;
}
uint32 usb_hid_data_available(void) {
return n_unread_bytes;
}
uint8 usb_hid_is_transmitting(void) {
return transmitting;
}
uint16 usb_hid_get_pending(void) {
return n_unsent_bytes;
}
/* Nonblocking byte receive.
*
* Copies up to len bytes from our private data buffer (*NOT* the PMA)
* into buf and deq's the FIFO. */
uint32 usb_hid_rx(uint8* buf, uint32 len) {
/* Copy bytes to buffer. */
uint32 n_copied = usb_hid_peek(buf, len);
/* Mark bytes as read. */
n_unread_bytes -= n_copied;
rx_offset = (rx_offset + n_copied) % HID_BUFFER_SIZE;
/* If all bytes have been read, re-enable the RX endpoint, which
* was set to NAK when the current batch of bytes was received. */
if (n_unread_bytes <= (HID_BUFFER_SIZE - USB_HID_RX_EPSIZE)) {
usb_set_ep_rx_count(USB_HID_RX_ENDP, USB_HID_RX_EPSIZE);
usb_set_ep_rx_stat(USB_HID_RX_ENDP, USB_EP_STAT_RX_VALID);
rx_offset = 0;
}
return n_copied;
}
/*
* Callbacks
*/
static void hidDataTxCb(void) {
n_unsent_bytes = 0;
transmitting = 0;
}
static void hidDataRxCb(void) {
uint32 ep_rx_size;
uint32 tail = (rx_offset + n_unread_bytes) % HID_BUFFER_SIZE;
uint8 ep_rx_data[USB_HID_RX_EPSIZE];
uint32 i;
usb_set_ep_rx_stat(USB_HID_RX_ENDP, USB_EP_STAT_RX_NAK);
ep_rx_size = usb_get_ep_rx_count(USB_HID_RX_ENDP);
/* This copy won't overwrite unread bytes, since we've set the RX
* endpoint to NAK, and will only set it to VALID when all bytes
* have been read. */
usb_copy_from_pma((uint8*)ep_rx_data, ep_rx_size,
USB_HID_RX_ADDR);
for (i = 0; i < ep_rx_size; i++) {
hidBufferRx[tail] = ep_rx_data[i];
tail = (tail + 1) % HID_BUFFER_SIZE;
}
n_unread_bytes += ep_rx_size;
if (n_unread_bytes <= (HID_BUFFER_SIZE - USB_HID_RX_EPSIZE)) {
usb_set_ep_rx_count(USB_HID_RX_ENDP, USB_HID_RX_EPSIZE);
usb_set_ep_rx_stat(USB_HID_RX_ENDP, USB_EP_STAT_RX_VALID);
}
}
static void usbInit(void) {
pInformation->Current_Configuration = 0;
USB_BASE->CNTR = USB_CNTR_FRES;
USBLIB->irq_mask = 0;
USB_BASE->CNTR = USBLIB->irq_mask;
USB_BASE->ISTR = 0;
USBLIB->irq_mask = USB_CNTR_RESETM | USB_CNTR_SUSPM | USB_CNTR_WKUPM;
USB_BASE->CNTR = USBLIB->irq_mask;
USB_BASE->ISTR = 0;
USBLIB->irq_mask = USB_ISR_MSK;
USB_BASE->CNTR = USBLIB->irq_mask;
nvic_irq_enable(NVIC_USB_LP_CAN_RX0);
USBLIB->state = USB_UNCONNECTED;
}
#define BTABLE_ADDRESS 0x00
static void usbReset(void) {
pInformation->Current_Configuration = 0;
/* current feature is current bmAttributes */
pInformation->Current_Feature = (USB_CONFIG_ATTR_BUSPOWERED |
USB_CONFIG_ATTR_SELF_POWERED);
USB_BASE->BTABLE = BTABLE_ADDRESS;
/* setup control endpoint 0 */
usb_set_ep_type(USB_EP0, USB_EP_EP_TYPE_CONTROL);
usb_set_ep_tx_stat(USB_EP0, USB_EP_STAT_TX_STALL);
usb_set_ep_rx_addr(USB_EP0, USB_HID_CTRL_RX_ADDR);
usb_set_ep_tx_addr(USB_EP0, USB_HID_CTRL_TX_ADDR);
usb_clear_status_out(USB_EP0);
usb_set_ep_rx_count(USB_EP0, pProperty->MaxPacketSize);
usb_set_ep_rx_stat(USB_EP0, USB_EP_STAT_RX_VALID);
/* TODO figure out differences in style between RX/TX EP setup */
/* set up data endpoint OUT (RX) */
usb_set_ep_type(USB_HID_RX_ENDP, USB_EP_EP_TYPE_BULK);
usb_set_ep_rx_addr(USB_HID_RX_ENDP, USB_HID_RX_ADDR);
usb_set_ep_rx_count(USB_HID_RX_ENDP, USB_HID_RX_EPSIZE);
usb_set_ep_rx_stat(USB_HID_RX_ENDP, USB_EP_STAT_RX_VALID);
/* set up data endpoint IN (TX) */
usb_set_ep_type(USB_HID_TX_ENDP, USB_EP_EP_TYPE_BULK);
usb_set_ep_tx_addr(USB_HID_TX_ENDP, USB_HID_TX_ADDR);
usb_set_ep_tx_stat(USB_HID_TX_ENDP, USB_EP_STAT_TX_NAK);
usb_set_ep_rx_stat(USB_HID_TX_ENDP, USB_EP_STAT_RX_DISABLED);
USBLIB->state = USB_ATTACHED;
SetDeviceAddress(0);
/* Reset the RX/TX state */
n_unread_bytes = 0;
n_unsent_bytes = 0;
rx_offset = 0;
transmitting = 0;
}
static RESULT usbDataSetup(uint8 request) {
uint8* (*CopyRoutine)(uint16) = 0;
if ((request == GET_DESCRIPTOR)
&& (Type_Recipient == (STANDARD_REQUEST | INTERFACE_RECIPIENT))
&& (pInformation->USBwIndex0 == 0)){
if (pInformation->USBwValue1 == REPORT_DESCRIPTOR){
CopyRoutine = HID_GetReportDescriptor;
} else if (pInformation->USBwValue1 == HID_DESCRIPTOR_TYPE){
CopyRoutine = HID_GetHIDDescriptor;
}
} /* End of GET_DESCRIPTOR */
/*** GET_PROTOCOL ***/
else if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))//){
&& request == GET_PROTOCOL){
CopyRoutine = HID_GetProtocolValue;
}
if (CopyRoutine == NULL){
return USB_UNSUPPORT;
}
pInformation->Ctrl_Info.CopyData = CopyRoutine;
pInformation->Ctrl_Info.Usb_wOffset = 0;
(*CopyRoutine)(0);
return USB_SUCCESS;
}
static RESULT usbNoDataSetup(uint8 request) {
if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
&& (request == SET_PROTOCOL)){
uint8 wValue0 = pInformation->USBwValue0;
ProtocolValue = wValue0;
return USB_SUCCESS;
//return HID_SetProtocol();
}else{
return USB_UNSUPPORT;
}
}
static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting) {
if (alt_setting > 0) {
return USB_UNSUPPORT;
} else if (interface > 1) {
return USB_UNSUPPORT;
}
return USB_SUCCESS;
}
static uint8* usbGetDeviceDescriptor(uint16 length) {
return Standard_GetDescriptorData(length, &Device_Descriptor);
}
static uint8* usbGetConfigDescriptor(uint16 length) {
return Standard_GetDescriptorData(length, &Config_Descriptor);
}
static uint8* usbGetStringDescriptor(uint16 length) {
uint8 wValue0 = pInformation->USBwValue0;
if (wValue0 > N_STRING_DESCRIPTORS) {
return NULL;
}
return Standard_GetDescriptorData(length, &String_Descriptor[wValue0]);
}
/*
static RESULT HID_SetProtocol(void){
uint8 wValue0 = pInformation->USBwValue0;
ProtocolValue = wValue0;
return USB_SUCCESS;
}
*/
static uint8* HID_GetProtocolValue(uint16 Length){
if (Length == 0){
pInformation->Ctrl_Info.Usb_wLength = 1;
return NULL;
} else {
return (uint8 *)(&ProtocolValue);
}
}
static uint8* HID_GetReportDescriptor(uint16 Length){
return Standard_GetDescriptorData(Length, &HID_Report_Descriptor);
}
static uint8* HID_GetHIDDescriptor(uint16 Length)
{
return Standard_GetDescriptorData(Length, &Config_Descriptor);
}
static void usbSetConfiguration(void) {
if (pInformation->Current_Configuration != 0) {
USBLIB->state = USB_CONFIGURED;
}
}
static void usbSetDeviceAddress(void) {
USBLIB->state = USB_ADDRESSED;
}
#endif

View File

@ -0,0 +1,768 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 LeafLabs LLC.
* Copyright (c) 2013 Magnus Lundin.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @file libmaple/usb/stm32f1/usb_midi_device.c
* @brief USB MIDI.
*
* FIXME: this works on the STM32F1 USB peripherals, and probably no
* place else. Nonportable bits really need to be factored out, and
* the result made cleaner.
*/
#ifdef USB_MIDI
#include <libmaple/usb_midi_device.h>
#include <MidiSpecs.h>
#include <MinSysex.h>
#include <libmaple/usb.h>
#include <libmaple/nvic.h>
#include <libmaple/delay.h>
/* Private headers */
#include "usb_lib_globals.h"
#include "usb_reg_map.h"
/* usb_lib headers */
#include "usb_type.h"
#include "usb_core.h"
#include "usb_def.h"
/******************************************************************************
******************************************************************************
***
*** HACK ALERT! FIXME FIXME FIXME FIXME!
***
*** A bunch of LeafLabs-specific configuration lives in here for
*** now. This mess REALLY needs to get teased apart, with
*** appropriate pieces moved into Wirish.
***
******************************************************************************
*****************************************************************************/
#warning passt alles
#if !(defined(BOARD_maple) || defined(BOARD_maple_RET6) || \
defined(BOARD_maple_mini) || defined(BOARD_maple_native))
#warning USB MIDI relies on LeafLabs board-specific configuration.\
You may have problems on non-LeafLabs boards.
#endif
static void midiDataTxCb(void);
static void midiDataRxCb(void);
static void usbInit(void);
static void usbReset(void);
static RESULT usbDataSetup(uint8 request);
static RESULT usbNoDataSetup(uint8 request);
static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting);
static uint8* usbGetDeviceDescriptor(uint16 length);
static uint8* usbGetConfigDescriptor(uint16 length);
static uint8* usbGetStringDescriptor(uint16 length);
static void usbSetConfiguration(void);
static void usbSetDeviceAddress(void);
/*
* Descriptors
*/
/* FIXME move to Wirish */
#define LEAFLABS_ID_VENDOR 0x1EAF
#define MAPLE_ID_PRODUCT 0x0014
/* 0x7D = ED/FREE next two DIGITS MUST BE LESS THAN 0x7f */
static const usb_descriptor_device usbMIDIDescriptor_Device =
USB_MIDI_DECLARE_DEV_DESC(LEAFLABS_ID_VENDOR, MAPLE_ID_PRODUCT);
typedef struct {
usb_descriptor_config_header Config_Header;
/* Control Interface */
usb_descriptor_interface AC_Interface;
AC_CS_INTERFACE_DESCRIPTOR(1) AC_CS_Interface;
/* Control Interface */
usb_descriptor_interface MS_Interface;
MS_CS_INTERFACE_DESCRIPTOR MS_CS_Interface;
MIDI_IN_JACK_DESCRIPTOR MIDI_IN_JACK_1;
MIDI_IN_JACK_DESCRIPTOR MIDI_IN_JACK_2;
MIDI_OUT_JACK_DESCRIPTOR(1) MIDI_OUT_JACK_3;
MIDI_OUT_JACK_DESCRIPTOR(1) MIDI_OUT_JACK_4;
usb_descriptor_endpoint DataOutEndpoint;
MS_CS_BULK_ENDPOINT_DESCRIPTOR(1) MS_CS_DataOutEndpoint;
usb_descriptor_endpoint DataInEndpoint;
MS_CS_BULK_ENDPOINT_DESCRIPTOR(1) MS_CS_DataInEndpoint;
} __packed usb_descriptor_config;
#define MAX_POWER (100 >> 1)
static const usb_descriptor_config usbMIDIDescriptor_Config = {
.Config_Header = {
.bLength = sizeof(usb_descriptor_config_header),
.bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION,
.wTotalLength = sizeof(usb_descriptor_config),
.bNumInterfaces = 0x02,
.bConfigurationValue = 0x01,
.iConfiguration = 0x00,
.bmAttributes = (USB_CONFIG_ATTR_BUSPOWERED |
USB_CONFIG_ATTR_SELF_POWERED),
.bMaxPower = MAX_POWER,
},
.AC_Interface = {
.bLength = sizeof(usb_descriptor_interface),
.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
.bInterfaceNumber = 0x00,
.bAlternateSetting = 0x00,
.bNumEndpoints = 0x00,
.bInterfaceClass = USB_INTERFACE_CLASS_AUDIO,
.bInterfaceSubClass = USB_INTERFACE_AUDIOCONTROL,
.bInterfaceProtocol = 0x00,
.iInterface = 0x00,
},
.AC_CS_Interface = {
.bLength = AC_CS_INTERFACE_DESCRIPTOR_SIZE(1),
.bDescriptorType = USB_DESCRIPTOR_TYPE_CS_INTERFACE,
.SubType = 0x01,
.bcdADC = 0x0100,
.wTotalLength = AC_CS_INTERFACE_DESCRIPTOR_SIZE(1),
.bInCollection = 0x01,
.baInterfaceNr = {0x01},
},
.MS_Interface = {
.bLength = sizeof(usb_descriptor_interface),
.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
.bInterfaceNumber = 0x01,
.bAlternateSetting = 0x00,
.bNumEndpoints = 0x02,
.bInterfaceClass = USB_INTERFACE_CLASS_AUDIO,
.bInterfaceSubClass = USB_INTERFACE_MIDISTREAMING,
.bInterfaceProtocol = 0x00,
.iInterface = 0x04,
},
.MS_CS_Interface = {
.bLength = sizeof(MS_CS_INTERFACE_DESCRIPTOR),
.bDescriptorType = USB_DESCRIPTOR_TYPE_CS_INTERFACE,
.SubType = 0x01,
.bcdADC = 0x0100,
.wTotalLength = sizeof(MS_CS_INTERFACE_DESCRIPTOR)
+sizeof(MIDI_IN_JACK_DESCRIPTOR)
+sizeof(MIDI_IN_JACK_DESCRIPTOR)
+MIDI_OUT_JACK_DESCRIPTOR_SIZE(1)
+MIDI_OUT_JACK_DESCRIPTOR_SIZE(1)
+sizeof(usb_descriptor_endpoint)
+MS_CS_BULK_ENDPOINT_DESCRIPTOR_SIZE(1)
+sizeof(usb_descriptor_endpoint)
+MS_CS_BULK_ENDPOINT_DESCRIPTOR_SIZE(1)
/* 0x41-4 */,
},
.MIDI_IN_JACK_1 = {
.bLength = sizeof(MIDI_IN_JACK_DESCRIPTOR),
.bDescriptorType = USB_DESCRIPTOR_TYPE_CS_INTERFACE,
.SubType = MIDI_IN_JACK,
.bJackType = MIDI_JACK_EMBEDDED,
.bJackId = 0x01,
.iJack = 0x05,
},
.MIDI_IN_JACK_2 = {
.bLength = sizeof(MIDI_IN_JACK_DESCRIPTOR),
.bDescriptorType = USB_DESCRIPTOR_TYPE_CS_INTERFACE,
.SubType = MIDI_IN_JACK,
.bJackType = MIDI_JACK_EXTERNAL,
.bJackId = 0x02,
.iJack = 0x00,
},
.MIDI_OUT_JACK_3 = {
.bLength = MIDI_OUT_JACK_DESCRIPTOR_SIZE(1),
.bDescriptorType = USB_DESCRIPTOR_TYPE_CS_INTERFACE,
.SubType = MIDI_OUT_JACK,
.bJackType = MIDI_JACK_EMBEDDED,
.bJackId = 0x03,
.bNrInputPins = 0x01,
.baSourceId = {0x02},
.baSourcePin = {0x01},
.iJack = 0x00,
},
.MIDI_OUT_JACK_4 = {
.bLength = MIDI_OUT_JACK_DESCRIPTOR_SIZE(1),
.bDescriptorType = USB_DESCRIPTOR_TYPE_CS_INTERFACE,
.SubType = MIDI_OUT_JACK,
.bJackType = MIDI_JACK_EXTERNAL,
.bJackId = 0x04,
.bJackId = 0x03,
.bNrInputPins = 0x01,
.baSourceId = {0x01},
.baSourcePin = {0x01},
.iJack = 0x00,
},
.DataOutEndpoint = {
.bLength = sizeof(usb_descriptor_endpoint),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_OUT |
USB_MIDI_RX_ENDP),
.bmAttributes = USB_EP_TYPE_BULK,
.wMaxPacketSize = USB_MIDI_RX_EPSIZE,
.bInterval = 0x00,
},
.MS_CS_DataOutEndpoint = {
.bLength = MS_CS_BULK_ENDPOINT_DESCRIPTOR_SIZE(1),
.bDescriptorType = USB_DESCRIPTOR_TYPE_CS_ENDPOINT,
.SubType = 0x01,
.bNumEmbMIDIJack = 0x01,
.baAssocJackID = {0x01},
},
.DataInEndpoint = {
.bLength = sizeof(usb_descriptor_endpoint),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | USB_MIDI_TX_ENDP),
.bmAttributes = USB_EP_TYPE_BULK,
.wMaxPacketSize = USB_MIDI_TX_EPSIZE,
.bInterval = 0x00,
},
.MS_CS_DataInEndpoint = {
.bLength = MS_CS_BULK_ENDPOINT_DESCRIPTOR_SIZE(1),
.bDescriptorType = USB_DESCRIPTOR_TYPE_CS_ENDPOINT,
.SubType = 0x01,
.bNumEmbMIDIJack = 0x01,
.baAssocJackID = {0x03},
},
};
/*
String Descriptors:
we may choose to specify any or none of the following string
identifiers:
iManufacturer: LeafLabs
iProduct: Maple
iSerialNumber: NONE
iConfiguration: NONE
iInterface(CCI): NONE
iInterface(DCI): NONE
*/
/* Unicode language identifier: 0x0409 is US English */
/* FIXME move to Wirish */
static const usb_descriptor_string usbMIDIDescriptor_LangID = {
.bLength = USB_DESCRIPTOR_STRING_LEN(1),
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
.bString = {0x09, 0x04},
};
/* FIXME move to Wirish */
static const usb_descriptor_string usbMIDIDescriptor_iManufacturer = {
.bLength = USB_DESCRIPTOR_STRING_LEN(8),
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
.bString = {'D', 0, 'i', 0, 'r', 0, 'o', 0,
' ', 0, ' ', 0, ' ', 0, ' ', 0},
};
/* FIXME move to Wirish */
static const usb_descriptor_string usbMIDIDescriptor_iProduct = {
.bLength = USB_DESCRIPTOR_STRING_LEN(10),
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
// .bString = {'M', 0, 'a', 0, 'p', 0, 'l', 0, 'e', 0, ' ', 0, 'M', 0, 'I', 0, 'D', 0, 'I', 0},
.bString = {'D', 0, 'i', 0, 'r', 0, 'o', 0, ' ', 0, 'S', 0, 'y', 0, 'n', 0, 't', 0, 'h', 0},
};
/* FIXME move to Wirish */
static const usb_descriptor_string usbMIDIDescriptor_iInterface = {
.bLength = USB_DESCRIPTOR_STRING_LEN(4),
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
.bString = {'M', 0, 'I', 0, 'D', 0, 'I', 0},
};
/* FIXME move to Wirish */
static const usb_descriptor_string usbMIDIDescriptor_iJack1 = {
.bLength = USB_DESCRIPTOR_STRING_LEN(5),
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
.bString = {'J', 0, 'a', 0, 'c', 0, 'k', 0, '1', 0},
};
static ONE_DESCRIPTOR Device_Descriptor = {
(uint8*)&usbMIDIDescriptor_Device,
sizeof(usb_descriptor_device)
};
static ONE_DESCRIPTOR Config_Descriptor = {
(uint8*)&usbMIDIDescriptor_Config,
sizeof(usb_descriptor_config)
};
#define N_STRING_DESCRIPTORS 5
static ONE_DESCRIPTOR String_Descriptor[N_STRING_DESCRIPTORS] = {
{(uint8*)&usbMIDIDescriptor_LangID, USB_DESCRIPTOR_STRING_LEN(1)},
{(uint8*)&usbMIDIDescriptor_iManufacturer,USB_DESCRIPTOR_STRING_LEN(8)},
{(uint8*)&usbMIDIDescriptor_iProduct, USB_DESCRIPTOR_STRING_LEN(10)},
{(uint8*)&usbMIDIDescriptor_iInterface, USB_DESCRIPTOR_STRING_LEN(4)},
{(uint8*)&usbMIDIDescriptor_iJack1, USB_DESCRIPTOR_STRING_LEN(5)}
};
/*
* Etc.
*/
/* I/O state */
/* Received data */
static volatile uint32 midiBufferRx[USB_MIDI_RX_EPSIZE/4];
/* Read index into midiBufferRx */
static volatile uint32 rx_offset = 0;
/* Transmit data */
static volatile uint32 midiBufferTx[USB_MIDI_TX_EPSIZE/4];
/* Write index into midiBufferTx */
static volatile uint32 tx_offset = 0;
/* Number of bytes left to transmit */
static volatile uint32 n_unsent_packets = 0;
/* Are we currently sending an IN packet? */
static volatile uint8 transmitting = 0;
/* Number of unread bytes */
static volatile uint32 n_unread_packets = 0;
// eventually all of this should be in a place for settings which can be written to flash.
volatile uint8 myMidiChannel = DEFAULT_MIDI_CHANNEL;
volatile uint8 myMidiDevice = DEFAULT_MIDI_DEVICE;
volatile uint8 myMidiCable = DEFAULT_MIDI_CABLE;
volatile uint8 myMidiID[] = { LEAFLABS_MMA_VENDOR_1,LEAFLABS_MMA_VENDOR_2,LEAFLABS_MMA_VENDOR_3,0};
/*
* Endpoint callbacks
*/
static void (*ep_int_in[7])(void) =
{midiDataTxCb,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process};
static void (*ep_int_out[7])(void) =
{NOP_Process,
midiDataRxCb,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process};
/*
* Globals required by usb_lib/
*
* Mark these weak so they can be overriden to implement other USB
* functionality.
*/
#define NUM_ENDPTS 0x04
__weak DEVICE Device_Table = {
.Total_Endpoint = NUM_ENDPTS,
.Total_Configuration = 1
};
#define MAX_PACKET_SIZE 0x40 /* 64B, maximum for USB FS Devices */
__weak DEVICE_PROP Device_Property = {
.Init = usbInit,
.Reset = usbReset,
.Process_Status_IN = NOP_Process,
.Process_Status_OUT = NOP_Process,
.Class_Data_Setup = usbDataSetup,
.Class_NoData_Setup = usbNoDataSetup,
.Class_Get_Interface_Setting = usbGetInterfaceSetting,
.GetDeviceDescriptor = usbGetDeviceDescriptor,
.GetConfigDescriptor = usbGetConfigDescriptor,
.GetStringDescriptor = usbGetStringDescriptor,
.RxEP_buffer = NULL,
.MaxPacketSize = MAX_PACKET_SIZE
};
__weak USER_STANDARD_REQUESTS User_Standard_Requests = {
.User_GetConfiguration = NOP_Process,
.User_SetConfiguration = usbSetConfiguration,
.User_GetInterface = NOP_Process,
.User_SetInterface = NOP_Process,
.User_GetStatus = NOP_Process,
.User_ClearFeature = NOP_Process,
.User_SetEndPointFeature = NOP_Process,
.User_SetDeviceFeature = NOP_Process,
.User_SetDeviceAddress = usbSetDeviceAddress
};
/*
* MIDI interface
*/
void usb_midi_enable(gpio_dev *disc_dev, uint8 disc_bit) {
/* Present ourselves to the host. Writing 0 to "disc" pin must
* pull USB_DP pin up while leaving USB_DM pulled down by the
* transceiver. See USB 2.0 spec, section 7.1.7.3. */
gpio_set_mode(disc_dev, disc_bit, GPIO_OUTPUT_PP);
gpio_write_bit(disc_dev, disc_bit, 0);
/* Initialize the USB peripheral. */
usb_init_usblib(USBLIB, ep_int_in, ep_int_out);
}
void usb_midi_disable(gpio_dev *disc_dev, uint8 disc_bit) {
/* Turn off the interrupt and signal disconnect (see e.g. USB 2.0
* spec, section 7.1.7.3). */
nvic_irq_disable(NVIC_USB_LP_CAN_RX0);
gpio_write_bit(disc_dev, disc_bit, 1);
}
//void usb_midi_putc(char ch) {
// while (!usb_midi_tx((uint8*)&ch, 1))
// ;
//}
/* This function is non-blocking.
*
* It copies data from a usercode buffer into the USB peripheral TX
* buffer, and returns the number of bytes copied. */
uint32 usb_midi_tx(const uint32* buf, uint32 packets) {
uint32 bytes=packets*4;
/* Last transmission hasn't finished, so abort. */
if (usb_midi_is_transmitting()) {
/* Copy to TxBuffer */
return 0; /* return len */
}
/* We can only put USB_MIDI_TX_EPSIZE bytes in the buffer. */
if (bytes > USB_MIDI_TX_EPSIZE) {
bytes = USB_MIDI_TX_EPSIZE;
packets=bytes/4;
}
/* Queue bytes for sending. */
if (packets) {
usb_copy_to_pma((uint8 *)buf, bytes, USB_MIDI_TX_ADDR);
}
// We still need to wait for the interrupt, even if we're sending
// zero bytes. (Sending zero-size packets is useful for flushing
// host-side buffers.)
usb_set_ep_tx_count(USB_MIDI_TX_ENDP, bytes);
n_unsent_packets = packets;
transmitting = 1;
usb_set_ep_tx_stat(USB_MIDI_TX_ENDP, USB_EP_STAT_TX_VALID);
return packets;
}
uint32 usb_midi_data_available(void) {
return n_unread_packets;
}
uint8 usb_midi_is_transmitting(void) {
return transmitting;
}
uint16 usb_midi_get_pending(void) {
return n_unsent_packets;
}
/* Nonblocking byte receive.
*
* Copies up to len bytes from our private data buffer (*NOT* the PMA)
* into buf and deq's the FIFO. */
uint32 usb_midi_rx(uint32* buf, uint32 packets) {
/* Copy bytes to buffer. */
uint32 n_copied = usb_midi_peek(buf, packets);
/* Mark bytes as read. */
n_unread_packets -= n_copied;
rx_offset += n_copied;
/* If all bytes have been read, re-enable the RX endpoint, which
* was set to NAK when the current batch of bytes was received. */
if (n_unread_packets == 0) {
usb_set_ep_rx_count(USB_MIDI_RX_ENDP, USB_MIDI_RX_EPSIZE);
usb_set_ep_rx_stat(USB_MIDI_RX_ENDP, USB_EP_STAT_RX_VALID);
rx_offset = 0;
}
return n_copied;
}
/* Nonblocking byte lookahead.
*
* Looks at unread bytes without marking them as read. */
uint32 usb_midi_peek(uint32* buf, uint32 packets) {
int i;
if (packets > n_unread_packets) {
packets = n_unread_packets;
}
for (i = 0; i < packets; i++) {
buf[i] = midiBufferRx[i + rx_offset];
}
return packets;
}
/*
* Callbacks
*/
static void midiDataTxCb(void) {
n_unsent_packets = 0;
transmitting = 0;
}
static void midiDataRxCb(void) {
usb_set_ep_rx_stat(USB_MIDI_RX_ENDP, USB_EP_STAT_RX_NAK);
n_unread_packets = usb_get_ep_rx_count(USB_MIDI_RX_ENDP) / 4;
/* This copy won't overwrite unread bytes, since we've set the RX
* endpoint to NAK, and will only set it to VALID when all bytes
* have been read. */
usb_copy_from_pma((uint8*)midiBufferRx, n_unread_packets * 4,
USB_MIDI_RX_ADDR);
LglSysexHandler(midiBufferRx,&rx_offset,&n_unread_packets);
if (n_unread_packets == 0) {
usb_set_ep_rx_count(USB_MIDI_RX_ENDP, USB_MIDI_RX_EPSIZE);
usb_set_ep_rx_stat(USB_MIDI_RX_ENDP, USB_EP_STAT_RX_VALID);
rx_offset = 0;
}
}
/* NOTE: Nothing specific to this device class in this function, move to usb_lib */
static void usbInit(void) {
pInformation->Current_Configuration = 0;
USB_BASE->CNTR = USB_CNTR_FRES;
USBLIB->irq_mask = 0;
USB_BASE->CNTR = USBLIB->irq_mask;
USB_BASE->ISTR = 0;
USBLIB->irq_mask = USB_CNTR_RESETM | USB_CNTR_SUSPM | USB_CNTR_WKUPM;
USB_BASE->CNTR = USBLIB->irq_mask;
USB_BASE->ISTR = 0;
USBLIB->irq_mask = USB_ISR_MSK;
USB_BASE->CNTR = USBLIB->irq_mask;
nvic_irq_enable(NVIC_USB_LP_CAN_RX0);
USBLIB->state = USB_UNCONNECTED;
}
#define BTABLE_ADDRESS 0x00
static void usbReset(void) {
pInformation->Current_Configuration = 0;
/* current feature is current bmAttributes */
pInformation->Current_Feature = (USB_CONFIG_ATTR_BUSPOWERED |
USB_CONFIG_ATTR_SELF_POWERED);
USB_BASE->BTABLE = BTABLE_ADDRESS;
/* setup control endpoint 0 */
usb_set_ep_type(USB_EP0, USB_EP_EP_TYPE_CONTROL);
usb_set_ep_tx_stat(USB_EP0, USB_EP_STAT_TX_STALL);
usb_set_ep_rx_addr(USB_EP0, USB_MIDI_CTRL_RX_ADDR);
usb_set_ep_tx_addr(USB_EP0, USB_MIDI_CTRL_TX_ADDR);
usb_clear_status_out(USB_EP0);
usb_set_ep_rx_count(USB_EP0, pProperty->MaxPacketSize);
usb_set_ep_rx_stat(USB_EP0, USB_EP_STAT_RX_VALID);
/* TODO figure out differences in style between RX/TX EP setup */
/* set up data endpoint OUT (RX) */
usb_set_ep_type(USB_MIDI_RX_ENDP, USB_EP_EP_TYPE_BULK);
usb_set_ep_rx_addr(USB_MIDI_RX_ENDP, USB_MIDI_RX_ADDR);
usb_set_ep_rx_count(USB_MIDI_RX_ENDP, USB_MIDI_RX_EPSIZE);
usb_set_ep_rx_stat(USB_MIDI_RX_ENDP, USB_EP_STAT_RX_VALID);
/* set up data endpoint IN (TX) */
usb_set_ep_type(USB_MIDI_TX_ENDP, USB_EP_EP_TYPE_BULK);
usb_set_ep_tx_addr(USB_MIDI_TX_ENDP, USB_MIDI_TX_ADDR);
usb_set_ep_tx_stat(USB_MIDI_TX_ENDP, USB_EP_STAT_TX_NAK);
usb_set_ep_rx_stat(USB_MIDI_TX_ENDP, USB_EP_STAT_RX_DISABLED);
USBLIB->state = USB_ATTACHED;
SetDeviceAddress(0);
/* Reset the RX/TX state */
n_unread_packets = 0;
n_unsent_packets = 0;
rx_offset = 0;
}
static RESULT usbDataSetup(uint8 request) {
uint8* (*CopyRoutine)(uint16) = 0;
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) {
}
if (CopyRoutine == NULL) {
return USB_UNSUPPORT;
}
pInformation->Ctrl_Info.CopyData = CopyRoutine;
pInformation->Ctrl_Info.Usb_wOffset = 0;
(*CopyRoutine)(0);
return USB_SUCCESS;
}
static RESULT usbNoDataSetup(uint8 request) {
RESULT ret = USB_UNSUPPORT;
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) {
}
return ret;
}
static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting) {
if (alt_setting > 0) {
return USB_UNSUPPORT;
} else if (interface > 1) {
return USB_UNSUPPORT;
}
return USB_SUCCESS;
}
static uint8* usbGetDeviceDescriptor(uint16 length) {
return Standard_GetDescriptorData(length, &Device_Descriptor);
}
static uint8* usbGetConfigDescriptor(uint16 length) {
return Standard_GetDescriptorData(length, &Config_Descriptor);
}
static uint8* usbGetStringDescriptor(uint16 length) {
uint8 wValue0 = pInformation->USBwValue0;
if (wValue0 > N_STRING_DESCRIPTORS) {
return NULL;
}
return Standard_GetDescriptorData(length, &String_Descriptor[wValue0]);
}
static void usbSetConfiguration(void) {
if (pInformation->Current_Configuration != 0) {
USBLIB->state = USB_CONFIGURED;
}
}
static void usbSetDeviceAddress(void) {
USBLIB->state = USB_ADDRESSED;
}
// .............THIS IS NOT WORKING YET................
// send debugging information to
static uint8_t sysexbuffer[80]={CIN_SYSEX,0xF0,0x7D,0x33,CIN_SYSEX,0x33,0x00,0xf7}; // !!!bad hardcoded number foo !!!
uint8_t iSysHexLine(uint8_t rectype, uint16_t address, uint8_t *payload,uint8_t payloadlength, uint8_t *buffer);
void sendThroughSysex(char *printbuffer, int bufferlength) {
int i,n;
n = iSysHexLine(1, 0 , (uint8_t *) printbuffer, (uint8_t) bufferlength , sysexbuffer+6);
usb_midi_tx((uint32*)sysexbuffer,n/4);
}
#define HIGHBYTE(x) ((uint8_t) (((x) >> 8) & 0x00ff) )
#define LOWBYTE(x) ((uint8_t) ((x) & 0x00ff) )
#define HIGHNIBBLE(x) ((((uint8_t)(x)) & 0xF0) >> 4)
#define LOWNIBBLE(x) (((uint8_t)(x)) & 0x0F)
#define HEXCHAR(c) ((c>9)?55+c:48+c)
uint8_t iSysHexLine(uint8_t rectype, uint16_t address, uint8_t *payload,uint8_t payloadlength, uint8_t *buffer) {
int i=0; int j; int thirdone;
uint8_t n=0;
uint16_t checksum=0;
//uint16_t length=0;
buffer[i++]=':';
checksum+=payloadlength;
buffer[i++]=HEXCHAR(HIGHNIBBLE(payloadlength));
buffer[i++]=HEXCHAR(LOWNIBBLE(payloadlength));
buffer[i++]=CIN_SYSEX;
n=HIGHBYTE(address);
checksum+=n;
buffer[i++]=HEXCHAR(HIGHNIBBLE(n));
buffer[i++]=HEXCHAR(LOWNIBBLE(n));
n=LOWBYTE(address);
checksum+=n;
buffer[i++]=HEXCHAR(HIGHNIBBLE(n));
buffer[i++]=CIN_SYSEX;
buffer[i++]=HEXCHAR(LOWNIBBLE(n));
n=rectype;
checksum+=n;
buffer[i++]=HEXCHAR(HIGHNIBBLE(n));
buffer[i++]=HEXCHAR(LOWNIBBLE(n));
buffer[i++]=CIN_SYSEX;
thirdone=0;
for (j=0; j<payloadlength ; j++) {
n=payload[j];
checksum+=n;
buffer[i++]=HEXCHAR(HIGHNIBBLE(n));
if (++thirdone==3) {
buffer[i++]=CIN_SYSEX;
thirdone=0;
}
buffer[i++]=HEXCHAR(LOWNIBBLE(n));
if (++thirdone==3) {
buffer[i++]=CIN_SYSEX;
thirdone=0;
}
}
if (thirdone==0) {
buffer[i-1]=CIN_SYSEX_ENDS_IN_3;
}
n=~((uint8_t) checksum&0x00ff)+1;
buffer[i++]=HEXCHAR(HIGHNIBBLE(n));
if (thirdone==1) {
buffer[i++]=CIN_SYSEX_ENDS_IN_2;
}
buffer[i++]=HEXCHAR(LOWNIBBLE(n));
if (thirdone==2) {
buffer[i++]=CIN_SYSEX_ENDS_IN_1;
}
buffer[i++]=0xf7;
return i+thirdone;
}
#endif

View File

@ -31,6 +31,8 @@ cppSRCS_$(d) += Print.cpp
cppSRCS_$(d) += pwm.cpp
ifeq ($(MCU_SERIES), stm32f1)
cppSRCS_$(d) += usb_serial.cpp # HACK: this is currently STM32F1 only.
cppSRCS_$(d) += usb_hid_device.cpp # HACK: this is currently STM32F1 only.
cppSRCS_$(d) += usb_midi.cpp # HACK: this is currently STM32F1 only.
cppSRCS_$(d) += HardwareSPI.cpp # FIXME: port to F2 and fix wirish.h
endif
cppSRCS_$(d) += wirish_analog.cpp

View File

@ -0,0 +1,454 @@
/* Copyright (c) 2011, Peter Barrett
**
** Permission to use, copy, modify, and/or distribute this software for
** any purpose with or without fee is hereby granted, provided that the
** above copyright notice and this permission notice appear in all copies.
**
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
** SOFTWARE.
*/
/**
* @brief USB HID Keyboard device
*/
#if defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J)
#include <usb_hid_device.h>
#include <string.h>
#include <stdint.h>
#include <libmaple/nvic.h>
#include <libmaple/usb_hid.h>
#include <libmaple/usb.h>
#include <wirish.h>
/*
* USB HID interface
*/
#define USB_TIMEOUT 50
HIDDevice::HIDDevice(void){
}
void HIDDevice::begin(void){
if(!enabled){
usb_hid_enable(BOARD_USB_DISC_DEV, BOARD_USB_DISC_BIT);
enabled = true;
}
}
void HIDDevice::end(void){
if(enabled){
usb_hid_disable(BOARD_USB_DISC_DEV, BOARD_USB_DISC_BIT);
enabled = false;
}
}
//================================================================================
//================================================================================
// Mouse
HIDMouse::HIDMouse(void) : _buttons(0){
}
void HIDMouse::begin(void){
HID.begin();
}
void HIDMouse::end(void){
HID.end();
}
void HIDMouse::click(uint8_t b)
{
_buttons = b;
while (usb_hid_is_transmitting() != 0) {
}
move(0,0,0);
_buttons = 0;
while (usb_hid_is_transmitting() != 0) {
}
move(0,0,0);
}
void HIDMouse::move(signed char x, signed char y, signed char wheel)
{
uint8_t m[4];
m[0] = _buttons;
m[1] = x;
m[2] = y;
m[3] = wheel;
uint8_t buf[1+sizeof(m)];
buf[0] = 1;//report id
uint8_t i;
for(i=0;i<sizeof(m);i++){
buf[i+1] = m[i];
}
usb_hid_tx(buf, sizeof(buf));
while (usb_hid_is_transmitting() != 0) {
}
/* flush out to avoid having the pc wait for more data */
usb_hid_tx(NULL, 0);
}
void HIDMouse::buttons(uint8_t b)
{
if (b != _buttons)
{
_buttons = b;
while (usb_hid_is_transmitting() != 0) {
}
move(0,0,0);
}
}
void HIDMouse::press(uint8_t b)
{
while (usb_hid_is_transmitting() != 0) {
}
buttons(_buttons | b);
}
void HIDMouse::release(uint8_t b)
{
while (usb_hid_is_transmitting() != 0) {
}
buttons(_buttons & ~b);
}
bool HIDMouse::isPressed(uint8_t b)
{
if ((b & _buttons) > 0)
return true;
return false;
}
//================================================================================
//================================================================================
// Keyboard
HIDKeyboard::HIDKeyboard(void){
}
void HIDKeyboard::sendReport(KeyReport* keys)
{
//HID_SendReport(2,keys,sizeof(KeyReport));
uint8_t buf[9];//sizeof(_keyReport)+1;
buf[0] = 2; //report id;
buf[1] = _keyReport.modifiers;
buf[2] = _keyReport.reserved;
uint8_t i;
for(i=0;i<sizeof(_keyReport.keys);i++){
buf[i+3] = _keyReport.keys[i];
}
usb_hid_tx(buf, sizeof(buf));
while (usb_hid_is_transmitting() != 0) {
}
/* flush out to avoid having the pc wait for more data */
usb_hid_tx(NULL, 0);
}
void HIDKeyboard::begin(void){
HID.begin();
}
void HIDKeyboard::end(void) {
HID.end();
}
size_t HIDKeyboard::press(uint8_t k)
{
uint8_t i;
if (k >= 136) { // it's a non-printing key (not a modifier)
k = k - 136;
} else if (k >= 128) { // it's a modifier key
_keyReport.modifiers |= (1<<(k-128));
k = 0;
} else { // it's a printing key
k = _asciimap[k];
if (!k) {
//setWriteError();
return 0;
}
if (k & SHIFT) { // it's a capital letter or other character reached with shift
_keyReport.modifiers |= 0x02; // the left shift modifier
k &= 0x7F;
}
}
// Add k to the key report only if it's not already present
// and if there is an empty slot.
if (_keyReport.keys[0] != k && _keyReport.keys[1] != k &&
_keyReport.keys[2] != k && _keyReport.keys[3] != k &&
_keyReport.keys[4] != k && _keyReport.keys[5] != k) {
for (i=0; i<6; i++) {
if (_keyReport.keys[i] == 0x00) {
_keyReport.keys[i] = k;
break;
}
}
if (i == 6) {
//setWriteError();
return 0;
}
}
while (usb_hid_is_transmitting() != 0) {
}
sendReport(&_keyReport);
return 1;
}
// release() takes the specified key out of the persistent key report and
// sends the report. This tells the OS the key is no longer pressed and that
// it shouldn't be repeated any more.
size_t HIDKeyboard::release(uint8_t k)
{
uint8_t i;
if (k >= 136) { // it's a non-printing key (not a modifier)
k = k - 136;
} else if (k >= 128) { // it's a modifier key
_keyReport.modifiers &= ~(1<<(k-128));
k = 0;
} else { // it's a printing key
k = _asciimap[k];
if (!k) {
return 0;
}
if (k & 0x80) { // it's a capital letter or other character reached with shift
_keyReport.modifiers &= ~(0x02); // the left shift modifier
k &= 0x7F;
}
}
// Test the key report to see if k is present. Clear it if it exists.
// Check all positions in case the key is present more than once (which it shouldn't be)
for (i=0; i<6; i++) {
if (0 != k && _keyReport.keys[i] == k) {
_keyReport.keys[i] = 0x00;
}
}
while (usb_hid_is_transmitting() != 0) {
}
sendReport(&_keyReport);
return 1;
}
void HIDKeyboard::releaseAll(void)
{
_keyReport.keys[0] = 0;
_keyReport.keys[1] = 0;
_keyReport.keys[2] = 0;
_keyReport.keys[3] = 0;
_keyReport.keys[4] = 0;
_keyReport.keys[5] = 0;
_keyReport.modifiers = 0;
while (usb_hid_is_transmitting() != 0) {
}
sendReport(&_keyReport);
}
size_t HIDKeyboard::write(uint8_t c)
{
uint8_t p = 0;
p = press(c); // Keydown
release(c); // Keyup
return (p); // Just return the result of press() since release() almost always returns 1
}
//================================================================================
//================================================================================
// Joystick
void HIDJoystick::sendReport(void){
usb_hid_tx(joystick_Report, sizeof(joystick_Report));
while (usb_hid_is_transmitting() != 0) {
}
/* flush out to avoid having the pc wait for more data */
usb_hid_tx(NULL, 0);
}
HIDJoystick::HIDJoystick(void){
}
void HIDJoystick::begin(void){
HID.begin();
}
void HIDJoystick::end(void){
HID.end();
}
void HIDJoystick::button(uint8_t button, bool val){
button--;
uint8_t mask = (1 << (button & 7));
if (val) {
if (button < 8) joystick_Report[1] |= mask;
else if (button < 16) joystick_Report[2] |= mask;
else if (button < 24) joystick_Report[3] |= mask;
else if (button < 32) joystick_Report[4] |= mask;
} else {
mask = ~mask;
if (button < 8) joystick_Report[1] &= mask;
else if (button < 16) joystick_Report[2] &= mask;
else if (button < 24) joystick_Report[3] &= mask;
else if (button < 32) joystick_Report[4] &= mask;
}
while (usb_hid_is_transmitting() != 0) {
}
sendReport();
}
void HIDJoystick::X(uint16_t val){
if (val > 1023) val = 1023;
joystick_Report[5] = (joystick_Report[5] & 0x0F) | (val << 4);
joystick_Report[6] = (joystick_Report[6] & 0xC0) | (val >> 4);
while (usb_hid_is_transmitting() != 0) {
}
sendReport();
}
void HIDJoystick::Y(uint16_t val){
if (val > 1023) val = 1023;
joystick_Report[6] = (joystick_Report[6] & 0x3F) | (val << 6);
joystick_Report[7] = (val >> 2);
while (usb_hid_is_transmitting() != 0) {
}
sendReport();
}
void HIDJoystick::position(uint16_t x, uint16_t y){
if (x > 1023) x = 1023;
if (y > 1023) y = 1023;
joystick_Report[5] = (joystick_Report[5] & 0x0F) | (x << 4);
joystick_Report[6] = (x >> 4) | (y << 6);
joystick_Report[7] = (y >> 2);
while (usb_hid_is_transmitting() != 0) {
}
sendReport();
}
void HIDJoystick::Z(uint16_t val){
if (val > 1023) val = 1023;
joystick_Report[8] = val;
joystick_Report[9] = (joystick_Report[9] & 0xFC) | (val >> 8);
while (usb_hid_is_transmitting() != 0) {
}
sendReport();
}
void HIDJoystick::Zrotate(uint16_t val){
if (val > 1023) val = 1023;
joystick_Report[9] = (joystick_Report[9] & 0x03) | (val << 2);
joystick_Report[10] = (joystick_Report[10] & 0xF0) | (val >> 6);
while (usb_hid_is_transmitting() != 0) {
}
sendReport();
}
void HIDJoystick::sliderLeft(uint16_t val){
if (val > 1023) val = 1023;
joystick_Report[10] = (joystick_Report[10] & 0x0F) | (val << 4);
joystick_Report[11] = (joystick_Report[11] & 0xC0) | (val >> 4);
while (usb_hid_is_transmitting() != 0) {
}
sendReport();
}
void HIDJoystick::sliderRight(uint16_t val){
if (val > 1023) val = 1023;
joystick_Report[11] = (joystick_Report[11] & 0x3F) | (val << 6);
joystick_Report[12] = (val >> 2);
while (usb_hid_is_transmitting() != 0) {
}
sendReport();
}
void HIDJoystick::slider(uint16_t val){
if (val > 1023) val = 1023;
joystick_Report[10] = (joystick_Report[10] & 0x0F) | (val << 4);
joystick_Report[11] = (val >> 4) | (val << 6);
joystick_Report[12] = (val >> 2);
while (usb_hid_is_transmitting() != 0) {
}
sendReport();
}
void HIDJoystick::hat(int16_t dir){
uint8_t val;
if (dir < 0) val = 15;
else if (dir < 23) val = 0;
else if (dir < 68) val = 1;
else if (dir < 113) val = 2;
else if (dir < 158) val = 3;
else if (dir < 203) val = 4;
else if (dir < 245) val = 5;
else if (dir < 293) val = 6;
else if (dir < 338) val = 7;
joystick_Report[5] = (joystick_Report[5] & 0xF0) | val;
while (usb_hid_is_transmitting() != 0) {
}
sendReport();
}
HIDDevice HID;
#if defined(USB_HID_KMJ) || defined(USB_HID_KM)
HIDMouse Mouse;
HIDKeyboard Keyboard;
#endif
#if defined(USB_HID_KMJ) || defined(USB_HID_J)
HIDJoystick Joystick;
#endif
#endif

View File

@ -0,0 +1,293 @@
/*
Copyright (c) 2012 Arduino. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @brief Wirish USB HID port (HID USB).
*/
#if defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J)
#ifndef _WIRISH_USB_HID_H_
#define _WIRISH_USB_HID_H_
#include <Print.h>
#include <boards.h>
class HIDDevice{
private:
bool enabled = false;
public:
HIDDevice(void);
void begin(void);
void end(void);
};
//================================================================================
//================================================================================
// Mouse
#define MOUSE_LEFT 1
#define MOUSE_RIGHT 2
#define MOUSE_MIDDLE 4
#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE)
class HIDMouse{
private:
uint8_t _buttons;
void buttons(uint8_t b);
public:
HIDMouse(void);
void begin(void);
void end(void);
void click(uint8_t b = MOUSE_LEFT);
void move(signed char x, signed char y, signed char wheel = 0);
void press(uint8_t b = MOUSE_LEFT); // press LEFT by default
void release(uint8_t b = MOUSE_LEFT); // release LEFT by default
bool isPressed(uint8_t b = MOUSE_ALL); // check all buttons by default
};
//================================================================================
//================================================================================
// Keyboard
#define SHIFT 0x80
const uint8_t _asciimap[128] =
{
0x00, // NUL
0x00, // SOH
0x00, // STX
0x00, // ETX
0x00, // EOT
0x00, // ENQ
0x00, // ACK
0x00, // BEL
0x2a, // BS Backspace
0x2b, // TAB Tab
0x28, // LF Enter
0x00, // VT
0x00, // FF
0x00, // CR
0x00, // SO
0x00, // SI
0x00, // DEL
0x00, // DC1
0x00, // DC2
0x00, // DC3
0x00, // DC4
0x00, // NAK
0x00, // SYN
0x00, // ETB
0x00, // CAN
0x00, // EM
0x00, // SUB
0x00, // ESC
0x00, // FS
0x00, // GS
0x00, // RS
0x00, // US
0x2c, // ' '
0x1e|SHIFT, // !
0x34|SHIFT, // "
0x20|SHIFT, // #
0x21|SHIFT, // $
0x22|SHIFT, // %
0x24|SHIFT, // &
0x34, // '
0x26|SHIFT, // (
0x27|SHIFT, // )
0x25|SHIFT, // *
0x2e|SHIFT, // +
0x36, // ,
0x2d, // -
0x37, // .
0x38, // /
0x27, // 0
0x1e, // 1
0x1f, // 2
0x20, // 3
0x21, // 4
0x22, // 5
0x23, // 6
0x24, // 7
0x25, // 8
0x26, // 9
0x33|SHIFT, // :
0x33, // ;
0x36|SHIFT, // <
0x2e, // =
0x37|SHIFT, // >
0x38|SHIFT, // ?
0x1f|SHIFT, // @
0x04|SHIFT, // A
0x05|SHIFT, // B
0x06|SHIFT, // C
0x07|SHIFT, // D
0x08|SHIFT, // E
0x09|SHIFT, // F
0x0a|SHIFT, // G
0x0b|SHIFT, // H
0x0c|SHIFT, // I
0x0d|SHIFT, // J
0x0e|SHIFT, // K
0x0f|SHIFT, // L
0x10|SHIFT, // M
0x11|SHIFT, // N
0x12|SHIFT, // O
0x13|SHIFT, // P
0x14|SHIFT, // Q
0x15|SHIFT, // R
0x16|SHIFT, // S
0x17|SHIFT, // T
0x18|SHIFT, // U
0x19|SHIFT, // V
0x1a|SHIFT, // W
0x1b|SHIFT, // X
0x1c|SHIFT, // Y
0x1d|SHIFT, // Z
0x2f, // [
0x31, // bslash
0x30, // ]
0x23|SHIFT, // ^
0x2d|SHIFT, // _
0x35, // `
0x04, // a
0x05, // b
0x06, // c
0x07, // d
0x08, // e
0x09, // f
0x0a, // g
0x0b, // h
0x0c, // i
0x0d, // j
0x0e, // k
0x0f, // l
0x10, // m
0x11, // n
0x12, // o
0x13, // p
0x14, // q
0x15, // r
0x16, // s
0x17, // t
0x18, // u
0x19, // v
0x1a, // w
0x1b, // x
0x1c, // y
0x1d, // z
0x2f|SHIFT, //
0x31|SHIFT, // |
0x30|SHIFT, // }
0x35|SHIFT, // ~
0 // DEL
};
#define KEY_LEFT_CTRL 0x80
#define KEY_LEFT_SHIFT 0x81
#define KEY_LEFT_ALT 0x82
#define KEY_LEFT_GUI 0x83
#define KEY_RIGHT_CTRL 0x84
#define KEY_RIGHT_SHIFT 0x85
#define KEY_RIGHT_ALT 0x86
#define KEY_RIGHT_GUI 0x87
#define KEY_UP_ARROW 0xDA
#define KEY_DOWN_ARROW 0xD9
#define KEY_LEFT_ARROW 0xD8
#define KEY_RIGHT_ARROW 0xD7
#define KEY_BACKSPACE 0xB2
#define KEY_TAB 0xB3
#define KEY_RETURN 0xB0
#define KEY_ESC 0xB1
#define KEY_INSERT 0xD1
#define KEY_DELETE 0xD4
#define KEY_PAGE_UP 0xD3
#define KEY_PAGE_DOWN 0xD6
#define KEY_HOME 0xD2
#define KEY_END 0xD5
#define KEY_CAPS_LOCK 0xC1
#define KEY_F1 0xC2
#define KEY_F2 0xC3
#define KEY_F3 0xC4
#define KEY_F4 0xC5
#define KEY_F5 0xC6
#define KEY_F6 0xC7
#define KEY_F7 0xC8
#define KEY_F8 0xC9
#define KEY_F9 0xCA
#define KEY_F10 0xCB
#define KEY_F11 0xCC
#define KEY_F12 0xCD
typedef struct{
uint8_t modifiers;
uint8_t reserved;
uint8_t keys[6];
} KeyReport;
class HIDKeyboard : public Print{
private:
KeyReport _keyReport;
void sendReport(KeyReport* keys);
public:
HIDKeyboard(void);
void begin(void);
void end(void);
virtual size_t write(uint8_t k);
virtual size_t press(uint8_t k);
virtual size_t release(uint8_t k);
virtual void releaseAll(void);
};
//================================================================================
//================================================================================
// Joystick
class HIDJoystick{
private:
uint8_t joystick_Report[13] = {3,0,0,0,0,0x0F,0x20,0x80,0x00,0x02,0x08,0x20,0x80};
void sendReport(void);
public:
HIDJoystick(void);
void begin(void);
void end(void);
void button(uint8_t button, bool val);
void X(uint16_t val);
void Y(uint16_t val);
void position(uint16_t x, uint16_t y);
void Z(uint16_t val);
void Zrotate(uint16_t val);
void sliderLeft(uint16_t val);
void sliderRight(uint16_t val);
void slider(uint16_t val);
void hat(int16_t dir);
};
extern HIDDevice HID;
#if defined(USB_HID_KMJ) || defined(USB_HID_KM)
extern HIDMouse Mouse;
extern HIDKeyboard Keyboard;
#endif
#if defined(USB_HID_KMJ) || defined(USB_HID_J)
extern HIDJoystick Joystick;
#endif
#endif
#endif

View File

@ -0,0 +1,533 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2013 Magnus Lundin.
* Copyright (c) 2013 Donald Delmar Davis, Suspect Devices.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* This is a munging of Tymm's arduino Midi Library into the Libusb class.
* I am not sure this is the right way to go especially since its licensed differently.
*
* Midi.cpp: Code for MIDI processing library, Arduino version
*
* (c) 2003-2008 Tymm Twillman <tymm@booyaka.com>
*
* This file is part of Tymm's Arduino Midi Library.
*
* Tymm's Arduino Midi Library is free software: you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either version 2.1
* of the License, or (at your option) any later version.
*
* Tymm's Arduino Midi Library is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Tymm's Arduino Midi Library. If not, see
* <http://www.gnu.org/licenses/>.
*
*
*****************************************************************************/
/**
* @brief USB MIDI device with a class compatible with maplemidi
*/
#ifdef USB_MIDI
#include <usb_midi.h>
#include <string.h>
#include <stdint.h>
#include <libmaple/nvic.h>
#include <libmaple/usb_midi_device.h>
#include <libmaple/usb.h>
#include <wirish.h>
/*
* USBMidi interface
*/
#define USB_TIMEOUT 50
USBMidi::USBMidi(void) {
}
// Constructor -- set up defaults for variables, get ready for use (but don't
// take over serial port yet)
void USBMidi::begin(unsigned int channel) {
usb_midi_enable(BOARD_USB_DISC_DEV, BOARD_USB_DISC_BIT);
/* Not in proprietary stream */
recvMode_ = 0;
/* No bytes recevied */
recvByteCount_ = 0;
/* Not processing an event */
recvEvent_ = 0;
/* No arguments to the event we haven't received */
recvArg0_ = 0;
/* Not waiting for bytes to complete a message */
recvBytesNeeded_ = 0;
// There was no last event.
lastStatusSent_ = false;
// Don't send the extra bytes; just send deltas
sendFullCommands_ = false;
}
void USBMidi::end(void) {
usb_midi_disable(BOARD_USB_DISC_DEV, BOARD_USB_DISC_BIT);
}
void USBMidi::writePacket(uint32 p) {
this->writePackets(&p, 1);
}
void USBMidi::writePackets(const void *buf, uint32 len) {
if (!this->isConnected() || !buf) {
return;
}
uint32 txed = 0;
uint32 old_txed = 0;
uint32 start = millis();
uint32 sent = 0;
while (txed < len && (millis() - start < USB_TIMEOUT)) {
sent = usb_midi_tx((const uint32*)buf + txed, len - txed);
txed += sent;
if (old_txed != txed) {
start = millis();
}
old_txed = txed;
}
if (sent == USB_MIDI_TX_EPSIZE) {
while (usb_midi_is_transmitting() != 0) {
}
/* flush out to avoid having the pc wait for more data */
usb_midi_tx(NULL, 0);
}
}
uint32 USBMidi::available(void) {
return usb_midi_data_available();
}
uint32 USBMidi::readPackets(void *buf, uint32 len) {
if (!buf) {
return 0;
}
uint32 rxed = 0;
while (rxed < len) {
rxed += usb_midi_rx((uint32*)buf + rxed, len - rxed);
}
return rxed;
}
/* Blocks forever until 1 byte is received */
uint32 USBMidi::readPacket(void) {
uint32 p;
this->readPackets(&p, 1);
return p;
}
uint8 USBMidi::pending(void) {
return usb_midi_get_pending();
}
uint8 USBMidi::isConnected(void) {
return usb_is_connected(USBLIB) && usb_is_configured(USBLIB);
}
USBMidi MidiUSB;
// This is used for tracking when we're processing a proprietary stream of data
// The assigned value is arbitrary; just for internal use.
static const int MODE_PROPRIETARY = 0xff;
// These are midi status message types are defined in MidiSpec.h
union EVENT_t {
uint32 i;
uint8 b[4];
MIDI_EVENT_PACKET_t p;
};
// Handle decoding incoming MIDI traffic a byte at a time -- remembers
// what it needs to from one call to the next.
//
// This is a private function & not meant to be called from outside this class.
// It's used whenever data is available from the serial port.
//
void USBMidi::dispatchPacket(uint32 p)
{
union EVENT_t e;
e.i=p;
// !!!!!!!!!!!!!!!! Add a sysex handler FIX THIS VERY VERY SHORTLY !!!!!!!!!!!!!!
if (recvMode_ & MODE_PROPRIETARY
&& CIN_IS_SYSEX(e.p.cin))
{
/* If sysex handling compiled in, just pass all data received
* to the sysex handler
*/
#ifdef CONFIG_MIDI_PROPRIETARY
// handleSysex(p);
#endif
return;
}
switch (e.p.cin) {
case CIN_3BYTE_SYS_COMMON:
if (e.p.midi0 == MIDIv1_SONG_POSITION_PTR) {
handleSongPosition(((uint16)e.p.midi2)<<7|((uint16)e.p.midi1));
}
break;
case CIN_2BYTE_SYS_COMMON:
switch (e.p.midi0) {
case MIDIv1_SONG_SELECT:
handleSongSelect(e.p.midi1);
break;
case MIDIv1_MTC_QUARTER_FRAME:
// reference library doesnt handle quarter frame.
break;
}
break;
case CIN_NOTE_OFF:
handleNoteOff(MIDIv1_VOICE_CHANNEL(e.p.midi0), e.p.midi1, e.p.midi2);
break;
case CIN_NOTE_ON:
handleNoteOn(MIDIv1_VOICE_CHANNEL(e.p.midi0), e.p.midi1, e.p.midi2);
break;
case CIN_AFTER_TOUCH:
handleVelocityChange(MIDIv1_VOICE_CHANNEL(e.p.midi0), e.p.midi1, e.p.midi2);
break;
case CIN_CONTROL_CHANGE:
handleControlChange(MIDIv1_VOICE_CHANNEL(e.p.midi0), e.p.midi1, e.p.midi2);
break;
case CIN_PROGRAM_CHANGE:
handleProgramChange(MIDIv1_VOICE_CHANNEL(e.p.midi0), e.p.midi1);
break;
case CIN_CHANNEL_PRESSURE:
handleAfterTouch(MIDIv1_VOICE_CHANNEL(e.p.midi0), e.p.midi1);
break;
case CIN_PITCH_WHEEL:
handlePitchChange(((uint16)e.p.midi2)<<7|((uint16)e.p.midi1));
break;
case CIN_1BYTE:
switch (e.p.midi0) {
case MIDIv1_CLOCK:
handleSync();
break;
case MIDIv1_TICK:
break;
case MIDIv1_START:
handleStart();
break;
case MIDIv1_CONTINUE:
handleContinue();
break;
case MIDIv1_STOP:
handleStop();
break;
case MIDIv1_ACTIVE_SENSE:
handleActiveSense();
break;
case MIDIv1_RESET:
handleReset();
break;
case MIDIv1_TUNE_REQUEST:
handleTuneRequest();
break;
default:
break;
}
break;
}
}
// Try to read data at serial port & pass anything read to processing function
void USBMidi::poll(void)
{ while(available()) {
dispatchPacket(readPacket());
}
}
static union EVENT_t outPacket; // since we only use one at a time no point in reallocating it
// Send Midi NOTE OFF message to a given channel, with note 0-127 and velocity 0-127
void USBMidi::sendNoteOff(unsigned int channel, unsigned int note, unsigned int velocity)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_NOTE_OFF;
outPacket.p.midi0=MIDIv1_NOTE_OFF|(channel & 0x0f);
outPacket.p.midi1=note;
outPacket.p.midi2=velocity;
writePacket(outPacket.i);
}
// Send Midi NOTE ON message to a given channel, with note 0-127 and velocity 0-127
void USBMidi::sendNoteOn(unsigned int channel, unsigned int note, unsigned int velocity)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_NOTE_ON;
outPacket.p.midi0=MIDIv1_NOTE_ON|(channel & 0x0f);
outPacket.p.midi1=note;
outPacket.p.midi2=velocity;
writePacket(outPacket.i);
}
// Send a Midi VELOCITY CHANGE message to a given channel, with given note 0-127,
// and new velocity 0-127
// Note velocity change == polyphonic aftertouch.
// Note aftertouch == channel pressure.
void USBMidi::sendVelocityChange(unsigned int channel, unsigned int note, unsigned int velocity)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_AFTER_TOUCH;
outPacket.p.midi0=MIDIv1_AFTER_TOUCH |(channel & 0x0f);
outPacket.p.midi1=note;
outPacket.p.midi2=velocity;
writePacket(outPacket.i);
}
// Send a Midi CC message to a given channel, as a given controller 0-127, with given
// value 0-127
void USBMidi::sendControlChange(unsigned int channel, unsigned int controller, unsigned int value)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_CONTROL_CHANGE;
outPacket.p.midi0=MIDIv1_CONTROL_CHANGE |(channel & 0x0f);
outPacket.p.midi1=controller;
outPacket.p.midi2=value;
writePacket(outPacket.i);
}
// Send a Midi PROGRAM CHANGE message to given channel, with program ID 0-127
void USBMidi::sendProgramChange(unsigned int channel, unsigned int program)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_PROGRAM_CHANGE;
outPacket.p.midi0=MIDIv1_PROGRAM_CHANGE |(channel & 0x0f);
outPacket.p.midi1=program;
writePacket(outPacket.i);
}
// Send a Midi AFTER TOUCH message to given channel, with velocity 0-127
void USBMidi::sendAfterTouch(unsigned int channel, unsigned int velocity)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_CHANNEL_PRESSURE;
outPacket.p.midi0=MIDIv1_CHANNEL_PRESSURE |(channel & 0x0f);
outPacket.p.midi1=velocity;
writePacket(outPacket.i);
}
// Send a Midi PITCH CHANGE message, with a 14-bit pitch (always for all channels)
void USBMidi::sendPitchChange(unsigned int pitch)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_PITCH_WHEEL;
outPacket.p.midi0=MIDIv1_PITCH_WHEEL;
outPacket.p.midi1= (uint8) pitch & 0x07F;
outPacket.p.midi2= (uint8) (pitch<<7) & 0x7f;
writePacket(outPacket.i);
}
// Send a Midi SONG POSITION message, with a 14-bit position (always for all channels)
void USBMidi::sendSongPosition(unsigned int position)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_3BYTE_SYS_COMMON;
outPacket.p.midi0=MIDIv1_SONG_POSITION_PTR;
outPacket.p.midi1= (uint8) position & 0x07F;
outPacket.p.midi2= (uint8) (position<<7) & 0x7f;
writePacket(outPacket.i);
}
// Send a Midi SONG SELECT message, with a song ID of 0-127 (always for all channels)
void USBMidi::sendSongSelect(unsigned int song)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_2BYTE_SYS_COMMON;
outPacket.p.midi0=MIDIv1_SONG_SELECT;
outPacket.p.midi1= (uint8) song & 0x07F;
writePacket(outPacket.i);
}
// Send a Midi TUNE REQUEST message (TUNE REQUEST is always for all channels)
void USBMidi::sendTuneRequest(void)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_1BYTE;
outPacket.p.midi0=MIDIv1_TUNE_REQUEST;
writePacket(outPacket.i);
}
// Send a Midi SYNC message (SYNC is always for all channels)
void USBMidi::sendSync(void)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_1BYTE;
outPacket.p.midi0=MIDIv1_CLOCK;
writePacket(outPacket.i);
}
// Send a Midi START message (START is always for all channels)
void USBMidi::sendStart(void)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_1BYTE;
outPacket.p.midi0=MIDIv1_START ;
writePacket(outPacket.i);
}
// Send a Midi CONTINUE message (CONTINUE is always for all channels)
void USBMidi::sendContinue(void)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_1BYTE;
outPacket.p.midi0=MIDIv1_CONTINUE ;
writePacket(outPacket.i);
}
// Send a Midi STOP message (STOP is always for all channels)
void USBMidi::sendStop(void)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_1BYTE;
outPacket.p.midi0=MIDIv1_STOP ;
writePacket(outPacket.i);
}
// Send a Midi ACTIVE SENSE message (ACTIVE SENSE is always for all channels)
void USBMidi::sendActiveSense(void)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_1BYTE;
outPacket.p.midi0=MIDIv1_ACTIVE_SENSE ;
writePacket(outPacket.i);
}
// Send a Midi RESET message (RESET is always for all channels)
void USBMidi::sendReset(void)
{
outPacket.p.cable=DEFAULT_MIDI_CABLE;
outPacket.p.cin=CIN_1BYTE;
outPacket.p.midi0=MIDIv1_RESET ;
writePacket(outPacket.i);
}
// Set (package-specific) parameters for the Midi instance
void USBMidi::setParam(unsigned int param, unsigned int val)
{
if (param == PARAM_SEND_FULL_COMMANDS) {
if (val) {
sendFullCommands_ = true;
} else {
sendFullCommands_ = false;
}
} else if (param == PARAM_CHANNEL_IN) {
channelIn_ = val;
}
}
// Get (package-specific) parameters for the Midi instance
unsigned int USBMidi::getParam(unsigned int param)
{
if (param == PARAM_SEND_FULL_COMMANDS) {
return sendFullCommands_;
} else if (param == PARAM_CHANNEL_IN) {
return channelIn_;
}
return 0;
}
// Placeholders. You should subclass the Midi base class and define these to have your
// version called.
/*
void USBMidi::handleNoteOff(unsigned int channel, unsigned int note, unsigned int velocity) {
digitalWrite(33,0);
}
void USBMidi::handleNoteOn(unsigned int channel, unsigned int note, unsigned int velocity) {
digitalWrite(33,1);
}
void USBMidi::handleVelocityChange(unsigned int channel, unsigned int note, unsigned int velocity) {}
void USBMidi::handleControlChange(unsigned int channel, unsigned int controller, unsigned int value) {}
void USBMidi::handleProgramChange(unsigned int channel, unsigned int program) {}
void USBMidi::handleAfterTouch(unsigned int channel, unsigned int velocity) {}
void USBMidi::handlePitchChange(unsigned int pitch) {}
void USBMidi::handleSongPosition(unsigned int position) {}
void USBMidi::handleSongSelect(unsigned int song) {}
void USBMidi::handleTuneRequest(void) {}
void USBMidi::handleSync(void) {}
void USBMidi::handleStart(void) {}
void USBMidi::handleContinue(void) {}
void USBMidi::handleStop(void) {}
void USBMidi::handleActiveSense(void) {}
void USBMidi::handleReset(void) {}
*/
#endif

View File

@ -0,0 +1,222 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2010 Perry Hung.
* Copyright (c) 2013 Magnus Lundin.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @brief Wirish USB MIDI port (MidiUSB).
*/
#ifdef USB_MIDI
#ifndef _WIRISH_USB_MIDI_H_
#define _WIRISH_USB_MIDI_H_
#include <Print.h>
#include <boards.h>
/*
* This is the Midi class. If you are just sending Midi data, you only need to make an
* instance of the class, passing it your serial port -- in most cases it looks like
*
* USBMidi midi(channel);
*
* then you don't need to do anything else; you can start using it to send Midi messages,
* e.g.
*
* midi.sendNoteOn(1, note, velocity);
*
* If you are using it to receive Midi data, it's a little more complex & you will need
* to subclass the Midi class.
*
* For people not used to C++ this may look confusing, but it's actually pretty easy.
* Note that you only need to write the functions for event types you want to handle.
* They should match the names & prototypes of the functions in the class; look at
* the functions in the Midi class below that have the keyword "virtual" to see which
* ones you can use.
*
* Here's an example of one that takes NOTE ON, NOTE OFF, and CONTROL CHANGE:
*
* class MyMidi : public USBMidi {
* public:
*
* // Need this to compile; it just hands things off to the Midi class.
* MyMidi() : USBMidi(s) {}
*
* void handleNoteOn(unsigned int channel, unsigned int note, unsigned int velocity)
* {
* if (note == 40) {digitalWrite(13, HIGH); }
* }
*
* void handleNoteOff(unsigned int channel, unsigned int note, unsigned int velocity)
* {
* if (note == 40) { digitalWrite(13, LOW); }
* }
*
* void handleControlChange(unsigned int channel, unsigned int controller,
* unsigned int value)
* {
* analogWrite(6, value * 2);
* }
*
* Then you need to make an instance of this class:
*
* MyMidi midi();
*
* If receiving Midi data, you also need to call the poll function every time through
* loop(); e.g.
*
* void loop() {
* midi.poll();
* }
*
* This causes the Midi class to read data from the serial port and process it.
*/
class USBMidi {
private:
// The serial port used by this Midi instance (it takes complete control over the port)
/* Private Receive Parameters */
// The channel this Midi instance receives data for (0 means all channels)
int channelIn_;
// These are for keeping track of partial Midi messages as bytes come in
int recvMode_;
int recvByteCount_;
int recvEvent_;
int recvArg0_;
int recvBytesNeeded_;
int lastStatusSent_;
/* Private Send Parameters */
// This controls whether every Midi message gets a command byte sent with it
// (Midi can just send a single command byte and then stream events without
// sending the command each time)
bool sendFullCommands_;
/* Internal functions */
// Called whenever data is read from the serial port
void dispatchPacket(uint32 packet);
// This doesn't work -- by making it private, we ensure nobody ever calls it
//Midi();
public:
// Set this parameter to anything other than 0 to cause every MIDI update to
// include a copy of the current event (e.g. for every note off to include
// the NOTE OFF event) -- by default, if an event is the same type of event as
// the last one sent, the event byte isn't sent; just the new note/velocity
static const unsigned int PARAM_SEND_FULL_COMMANDS = 0x1000;
// Use this parameter to update the channel the MIDI code is looking for messages
// to. 0 means "all channels".
static const unsigned int PARAM_CHANNEL_IN = 0x1001;
// Constructor -- generally just use e.g. "Midi midi(Serial);"
USBMidi();
// Call to start the serial port, at given baud. For many applications
// the default parameters are just fine (which will cause messages for all
// MIDI channels to be delivered)
void begin(unsigned int channel = 0);
//void begin();
void end();
uint32 available(void);
uint32 readPackets(void *buf, uint32 len);
uint32 readPacket(void);
void writePacket(uint32);
// void write(const char *str);
void writePackets(const void*, uint32);
uint8 isConnected();
uint8 pending();
// Changes the updateable parameters (params are Midi::PARAM_SEND_FULL_COMMANDS or
// Midi::PARAM_CHANNEL_IN -- see above for what they mean)
void setParam(unsigned int param, unsigned int val);
// Get current values for the user updateable parameters (params, etc same as above)
unsigned int getParam(unsigned int param);
// poll() should be called every time through loop() IF dealing with incoming MIDI
// (if you're only SENDING MIDI events from the Arduino, you don't need to call
// poll); it causes data to be read from the serial port and processed.
void poll();
// Call these to send MIDI messages of the given types
void sendNoteOff(unsigned int channel, unsigned int note, unsigned int velocity);
void sendNoteOn(unsigned int channel, unsigned int note, unsigned int velocity);
void sendVelocityChange(unsigned int channel, unsigned int note, unsigned int velocity);
void sendControlChange(unsigned int channel, unsigned int controller, unsigned int value);
void sendProgramChange(unsigned int channel, unsigned int program);
void sendAfterTouch(unsigned int channel, unsigned int velocity);
void sendPitchChange(unsigned int pitch);
void sendSongPosition(unsigned int position);
void sendSongSelect(unsigned int song);
void sendTuneRequest(void);
void sendSync(void);
void sendStart(void);
void sendContinue(void);
void sendStop(void);
void sendActiveSense(void);
void sendReset(void);
// Overload these in a subclass to get MIDI messages when they come in
virtual void handleNoteOff(unsigned int channel, unsigned int note, unsigned int velocity);
virtual void handleNoteOn(unsigned int channel, unsigned int note, unsigned int velocity);
virtual void handleVelocityChange(unsigned int channel, unsigned int note, unsigned int velocity);
virtual void handleControlChange(unsigned int channel, unsigned int controller, unsigned int value);
virtual void handleProgramChange(unsigned int channel, unsigned int program);
virtual void handleAfterTouch(unsigned int channel, unsigned int velocity);
virtual void handlePitchChange(unsigned int pitch);
virtual void handleSongPosition(unsigned int position);
virtual void handleSongSelect(unsigned int song);
virtual void handleTuneRequest(void);
virtual void handleSync(void);
virtual void handleStart(void);
virtual void handleContinue(void);
virtual void handleStop(void);
virtual void handleActiveSense(void);
virtual void handleReset(void);
};
extern USBMidi MidiUSB;
#endif
#endif

View File

@ -28,6 +28,8 @@
* @brief USB virtual serial terminal
*/
#ifdef USB_SERIAL
#include "usb_serial.h"
#include "string.h"
@ -216,7 +218,7 @@ uint8 USBSerial::getRTS(void) {
}
#if BOARD_HAVE_SERIALUSB
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
USBSerial Serial;
#endif
#endif
@ -244,7 +246,7 @@ static void ifaceSetupHook(unsigned hook, void *requestvp) {
return;
}
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
// We need to see a negative edge on DTR before we start looking
// for the in-band magic reset byte sequence.
uint8 dtr = usb_cdcacm_get_dtr();
@ -280,7 +282,7 @@ static void ifaceSetupHook(unsigned hook, void *requestvp) {
}
#define RESET_DELAY 100000
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
static void wait_reset(void) {
delay_us(RESET_DELAY);
nvic_sys_reset();
@ -298,7 +300,7 @@ static void rxHook(unsigned hook, void *ignored) {
if (usb_cdcacm_data_available() >= 4) {
// The magic reset sequence is "1EAF".
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
static const uint8 magic[4] = {'1', 'E', 'A', 'F'};
#else
#if defined(BOOTLOADER_robotis)
@ -319,7 +321,7 @@ static void rxHook(unsigned hook, void *ignored) {
}
}
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
// Got the magic sequence -> reset, presumably into the bootloader.
// Return address is wait_reset, but we must set the thumb bit.
uintptr_t target = (uintptr_t)wait_reset | 0x1;
@ -357,3 +359,5 @@ static void rxHook(unsigned hook, void *ignored) {
}
#endif // BOARD_HAVE_SERIALUSB
#endif //USB_SERIAL

View File

@ -28,6 +28,8 @@
* @brief Wirish USB virtual serial port (SerialUSB).
*/
#ifdef USB_SERIAL
#ifndef _WIRISH_USB_SERIAL_H_
#define _WIRISH_USB_SERIAL_H_
@ -73,9 +75,11 @@ public:
uint8 pending();
};
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
extern USBSerial Serial;
#endif
#endif
#endif

View File

@ -69,6 +69,8 @@
#include <HardwareSerial.h>
#include <HardwareTimer.h>
#include <usb_serial.h>
#include <usb_hid_device.h>
#include <usb_midi.h>
#include <wirish_types.h>
#include <libmaple/libmaple.h>

View File

@ -47,6 +47,8 @@ build.upload_flags=
build.extra_flags= {build.upload_flags} {build.cpu_flags} {build.hs_flag} {build.common_flags}
# added this line so the compiler receives a valid argument for usb type even if the selected board has no usb type menu
build.usbtype=NO_USB
# These can be overridden in platform.local.txt
compiler.c.extra_flags=
@ -75,10 +77,10 @@ compiler.libs.c.flags="-I{build.system.path}/libmaple" "-I{build.system.path}/li
# ---------------------
## Compile c files
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}"
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -D{build.usbtype} {compiler.c.extra_flags} {build.extra_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}"
## Compile c++ files
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {build.cpu_flags} {build.hs_flag} {build.common_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}"
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} -D{build.usbtype} {compiler.cpp.extra_flags} {build.extra_flags} {build.cpu_flags} {build.hs_flag} {build.common_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}"
## Compile S files
recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {build.cpu_flags} {build.hs_flag} {build.common_flags} {compiler.libs.c.flags} {includes} "{source_file}" -o "{object_file}"

View File

@ -124,7 +124,7 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = {
* Maps to which hardware serial port on the microprocessor
*/
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
DEFINE_HWSERIAL(Serial1, 1);
DEFINE_HWSERIAL(Serial2, 2);

View File

@ -41,6 +41,8 @@
#include <boards.h>
#include <usb_serial.h>
#include <usb_hid_device.h>
#include <usb_midi.h>
// Generic GD32 boards seem to have a 12Mhz crystal rather than the 8Mhz common on STM32 boards, hence the PLL multiplier settings are different.
// Additionally the GD32 has a 4 USB PLL divider settings, rather than the 2 settings in the STM32, which allow it to operate on frequencies of 48,72,96 and 120Mhz and still have USB functioning
@ -89,7 +91,6 @@ namespace wirish {
}
__weak void board_setup_usb(void) {
#ifdef SERIAL_USB
#ifdef GENERIC_BOOTLOADER
//Reset the USB interface on generic boards - developed by Victor PV
@ -99,7 +100,16 @@ namespace wirish {
for(volatile unsigned int i=0;i<512;i++);// Only small delay seems to be needed, and USB pins will get configured in Serial.begin
gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_INPUT_FLOATING);
#endif
#ifdef USB_HARDWARE
#ifdef USB_SERIAL
Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility
#endif
#if defined(USB_HARDWARE) && (defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J))
HID.begin();
#endif
#ifdef USB_MIDI
MidiUSB.begin();
#endif
#endif
}

View File

@ -124,7 +124,7 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = {
* Maps to which hardware serial port on the microprocessor
*/
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
DEFINE_HWSERIAL(Serial1, 1);
DEFINE_HWSERIAL(Serial2, 2);

View File

@ -80,7 +80,7 @@ namespace wirish {
}
__weak void board_setup_usb(void) {
#ifdef SERIAL_USB
#ifdef GENERIC_BOOTLOADER
//Reset the USB interface on generic boards - developed by Victor PV
@ -90,7 +90,16 @@ namespace wirish {
for(volatile unsigned int i=0;i<512;i++);// Only small delay seems to be needed, and USB pins will get configured in Serial.begin
gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_INPUT_FLOATING);
#endif
#ifdef USB_HARDWARE
#ifdef USB_SERIAL
Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility
#endif
#if defined(USB_HARDWARE) && (defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J))
HID.begin();
#endif
#ifdef USB_MIDI
MidiUSB.begin();
#endif
#endif
}

View File

@ -155,7 +155,7 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = {
};
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
DEFINE_HWSERIAL(Serial1, 1);
DEFINE_HWSERIAL(Serial2, 2);
DEFINE_HWSERIAL(Serial3, 3);

View File

@ -80,7 +80,7 @@ namespace wirish {
}
__weak void board_setup_usb(void) {
#ifdef SERIAL_USB
#ifdef GENERIC_BOOTLOADER
//Reset the USB interface on generic boards - developed by Victor PV
@ -91,8 +91,18 @@ namespace wirish {
gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_INPUT_FLOATING);
#endif
#ifdef USB_HARDWARE
#ifdef USB_SERIAL
Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility
#endif
#if defined(USB_HARDWARE) && (defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J))
HID.begin();
#endif
#ifdef USB_MIDI
MidiUSB.begin();
#endif
#endif
}
__weak void series_init(void) {

View File

@ -139,7 +139,7 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = {
* Maps to which hardware serial port on the microprocessor
*/
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
DEFINE_HWSERIAL(Serial1, 1);
DEFINE_HWSERIAL(Serial2, 2);

View File

@ -80,7 +80,7 @@ namespace wirish {
}
__weak void board_setup_usb(void) {
#ifdef SERIAL_USB
#ifdef GENERIC_BOOTLOADER
//Reset the USB interface on generic boards - developed by Victor PV
@ -89,9 +89,18 @@ namespace wirish {
for(volatile unsigned int i=0;i<512;i++);// Only small delay seems to be needed, and USB pins will get configured in Serial.begin
gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_INPUT_FLOATING);
#endif
#ifdef USB_HARDWARE
#ifdef USB_SERIAL
Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility
#endif
#if defined(USB_HARDWARE) && (defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J))
HID.begin();
#endif
#ifdef USB_MIDI
MidiUSB.begin();
#endif
#endif
}
__weak void series_init(void) {

View File

@ -109,7 +109,7 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = {
* Maps to which hardware serial port on the microprocessor
*/
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
DEFINE_HWSERIAL(Serial1, 1);
DEFINE_HWSERIAL(Serial2, 2);

View File

@ -80,7 +80,6 @@ namespace wirish {
}
__weak void board_setup_usb(void) {
#ifdef SERIAL_USB
#ifdef GENERIC_BOOTLOADER
//Reset the USB interface on generic boards - developed by Victor PV
@ -90,7 +89,16 @@ namespace wirish {
for(volatile unsigned int i=0;i<512;i++);// Only small delay seems to be needed, and USB pins will get configured in Serial.begin
gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_INPUT_FLOATING);
#endif
#ifdef USB_HARDWARE
#ifdef USB_SERIAL
Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility
#endif
#if defined(USB_HARDWARE) && (defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J))
HID.begin();
#endif
#ifdef USB_MIDI
MidiUSB.begin();
#endif
#endif
}

View File

@ -184,7 +184,7 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = {
};
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
DEFINE_HWSERIAL(Serial1, 1);
DEFINE_HWSERIAL(Serial2, 2);
DEFINE_HWSERIAL(Serial3, 3);

View File

@ -80,7 +80,7 @@ namespace wirish {
}
__weak void board_setup_usb(void) {
#ifdef SERIAL_USB
#ifdef GENERIC_BOOTLOADER
@ -91,8 +91,18 @@ namespace wirish {
for(volatile unsigned int i=0;i<512;i++);// Only small delay seems to be needed, and USB pins will get configured in Serial.begin
gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_INPUT_FLOATING);
#endif
#ifdef USB_HARDWARE
#ifdef USB_SERIAL
Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility
#endif
#if defined(USB_HARDWARE) && (defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J))
HID.begin();
#endif
#ifdef USB_MIDI
MidiUSB.begin();
#endif
#endif
}
__weak void series_init(void) {

View File

@ -219,7 +219,7 @@ extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = {
};
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
DEFINE_HWSERIAL(Serial1, 1);
DEFINE_HWSERIAL(Serial2, 2);
DEFINE_HWSERIAL(Serial3, 3);

View File

@ -93,8 +93,18 @@ namespace wirish {
gpio_set_mode(PIN_MAP[PA12].gpio_device, PIN_MAP[PA12].gpio_bit, GPIO_INPUT_FLOATING);
#endif
#ifdef USB_HARDWARE
#ifdef USB_SERIAL
Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility
#endif
#if defined(USB_HARDWARE) && (defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J))
HID.begin();
#endif
#ifdef USB_MIDI
MidiUSB.begin();
#endif
#endif
}
__weak void series_init(void) {

View File

@ -80,9 +80,18 @@ namespace wirish {
}
__weak void board_setup_usb(void) {
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
#ifdef USB_SERIAL
Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility
#endif
#if defined(USB_HARDWARE) && (defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J))
HID.begin();
#endif
#ifdef USB_MIDI
MidiUSB.begin();
#endif
#endif
}
__weak void series_init(void) {

View File

@ -41,6 +41,8 @@
#include <boards.h>
#include <usb_serial.h>
#include <usb_hid_device.h>
#include <usb_midi.h>
// Allow boards to provide a PLL multiplier. This is useful for
// e.g. STM32F100 value line MCUs, which use slower multipliers.
@ -80,9 +82,16 @@ namespace wirish {
}
__weak void board_setup_usb(void) {
#ifdef SERIAL_USB
// SerialUSB.begin();
#ifdef USB_HARDWARE
#ifdef USB_SERIAL
Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility
#endif
#if defined(USB_HARDWARE) && (defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J))
HID.begin();
#endif
#ifdef USB_MIDI
MidiUSB.begin();
#endif
#endif
}

View File

@ -80,9 +80,18 @@ namespace wirish {
}
__weak void board_setup_usb(void) {
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
#ifdef USB_SERIAL
Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility
#endif
#if defined(USB_HARDWARE) && (defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J))
HID.begin();
#endif
#ifdef USB_MIDI
MidiUSB.begin();
#endif
#endif
}
__weak void series_init(void) {

View File

@ -248,7 +248,7 @@ MOSI alternate functions on the GPIO ports.
* Maps to which hardware serial port on the microprocessor
*/
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
DEFINE_HWSERIAL(Serial1, 1);
DEFINE_HWSERIAL(Serial2, 2);
DEFINE_HWSERIAL(Serial3, 3);

View File

@ -88,9 +88,18 @@ namespace wirish {
}
__weak void board_setup_usb(void) {
#ifdef SERIAL_USB
#ifdef USB_HARDWARE
#ifdef USB_SERIAL
Serial.begin();// Roger Clark. Changed SerialUSB to Serial for Arduino sketch compatibility
#endif
#if defined(USB_HARDWARE) && (defined(USB_HID_KMJ) || defined(USB_HID_KM) || defined(USB_HID_J))
HID.begin();
#endif
#ifdef USB_MIDI
MidiUSB.begin();
#endif
#endif
}
__weak void series_init(void) {