This commit is contained in:
Jack Humbert
2015-08-20 00:42:28 -04:00
parent e528087ee5
commit fb4fe52c0a
13 changed files with 2432 additions and 0 deletions
+93
View File
@@ -0,0 +1,93 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2012.
dean [at] fourwalledcubicle [dot] com
www.lufa-lib.org
*/
/*
Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice appear in
all copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim 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, 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.
*/
/** \file
* \brief LUFA Library Configuration Header File
*
* This header file is used to configure LUFA's compile time options,
* as an alternative to the compile time constants supplied through
* a makefile.
*
* For information on what each token does, refer to the LUFA
* manual section "Summary of Compile Tokens".
*/
#ifndef _LUFA_CONFIG_H_
#define _LUFA_CONFIG_H_
#if (ARCH == ARCH_AVR8)
/* Non-USB Related Configuration Tokens: */
// #define DISABLE_TERMINAL_CODES
/* USB Class Driver Related Tokens: */
// #define HID_HOST_BOOT_PROTOCOL_ONLY
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
// #define HID_MAX_COLLECTIONS {Insert Value Here}
// #define HID_MAX_REPORTITEMS {Insert Value Here}
// #define HID_MAX_REPORT_IDS {Insert Value Here}
// #define NO_CLASS_DRIVER_AUTOFLUSH
/* General USB Driver Related Tokens: */
// #define ORDERED_EP_CONFIG
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
#define USB_DEVICE_ONLY
// #define USB_HOST_ONLY
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
// #define NO_LIMITED_CONTROLLER_CONNECT
// #define NO_SOF_EVENTS
/* USB Device Mode Driver Related Tokens: */
// #define USE_RAM_DESCRIPTORS
#define USE_FLASH_DESCRIPTORS
// #define USE_EEPROM_DESCRIPTORS
// #define NO_INTERNAL_SERIAL
#define FIXED_CONTROL_ENDPOINT_SIZE 8
// #define DEVICE_STATE_AS_GPIOR {Insert Value Here}
#define FIXED_NUM_CONFIGURATIONS 1
// #define CONTROL_ONLY_DEVICE
// #define INTERRUPT_CONTROL_ENDPOINT
// #define NO_DEVICE_REMOTE_WAKEUP
// #define NO_DEVICE_SELF_POWER
/* USB Host Mode Driver Related Tokens: */
// #define HOST_STATE_AS_GPIOR {Insert Value Here}
// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
// #define NO_AUTO_VBUS_MANAGEMENT
// #define INVERTED_VBUS_ENABLE_LINE
#else
#error Unsupported architecture for this LUFA configuration file.
#endif
#endif
File diff suppressed because it is too large Load Diff
+65
View File
@@ -0,0 +1,65 @@
//this is a single reader [maybe multiple writer?] byte queue
//Copyright 2008 Alex Norman
//writen by Alex Norman
//
//This file is part of avr-bytequeue.
//
//avr-bytequeue is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//avr-bytequeue is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with avr-bytequeue. If not, see <http://www.gnu.org/licenses/>.
#include "bytequeue.h"
#include "interrupt_setting.h"
void bytequeue_init(byteQueue_t * queue, uint8_t * dataArray, byteQueueIndex_t arrayLen){
queue->length = arrayLen;
queue->data = dataArray;
queue->start = queue->end = 0;
}
bool bytequeue_enqueue(byteQueue_t * queue, uint8_t item){
interrupt_setting_t setting = store_and_clear_interrupt();
//full
if(((queue->end + 1) % queue->length) == queue->start){
restore_interrupt_setting(setting);
return false;
} else {
queue->data[queue->end] = item;
queue->end = (queue->end + 1) % queue->length;
restore_interrupt_setting(setting);
return true;
}
}
byteQueueIndex_t bytequeue_length(byteQueue_t * queue){
byteQueueIndex_t len;
interrupt_setting_t setting = store_and_clear_interrupt();
if(queue->end >= queue->start)
len = queue->end - queue->start;
else
len = (queue->length - queue->start) + queue->end;
restore_interrupt_setting(setting);
return len;
}
//we don't need to avoid interrupts if there is only one reader
uint8_t bytequeue_get(byteQueue_t * queue, byteQueueIndex_t index){
return queue->data[(queue->start + index) % queue->length];
}
//we just update the start index to remove elements
void bytequeue_remove(byteQueue_t * queue, byteQueueIndex_t numToRemove){
interrupt_setting_t setting = store_and_clear_interrupt();
queue->start = (queue->start + numToRemove) % queue->length;
restore_interrupt_setting(setting);
}
+59
View File
@@ -0,0 +1,59 @@
//this is a single reader [maybe multiple writer?] byte queue
//Copyright 2008 Alex Norman
//writen by Alex Norman
//
//This file is part of avr-bytequeue.
//
//avr-bytequeue is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//avr-bytequeue is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with avr-bytequeue. If not, see <http://www.gnu.org/licenses/>.
#ifndef BYTEQUEUE_H
#define BYTEQUEUE_H
#ifdef __cplusplus
extern "C" {
#endif
#include <inttypes.h>
#include <stdbool.h>
typedef uint8_t byteQueueIndex_t;
typedef struct {
byteQueueIndex_t start;
byteQueueIndex_t end;
byteQueueIndex_t length;
uint8_t * data;
} byteQueue_t;
//you must have a queue, an array of data which the queue will use, and the length of that array
void bytequeue_init(byteQueue_t * queue, uint8_t * dataArray, byteQueueIndex_t arrayLen);
//add an item to the queue, returns false if the queue is full
bool bytequeue_enqueue(byteQueue_t * queue, uint8_t item);
//get the length of the queue
byteQueueIndex_t bytequeue_length(byteQueue_t * queue);
//this grabs data at the index given [starting at queue->start]
uint8_t bytequeue_get(byteQueue_t * queue, byteQueueIndex_t index);
//update the index in the queue to reflect data that has been dealt with
void bytequeue_remove(byteQueue_t * queue, byteQueueIndex_t numToRemove);
#ifdef __cplusplus
}
#endif
#endif
+36
View File
@@ -0,0 +1,36 @@
//Copyright 20010 Alex Norman
//writen by Alex Norman
//
//This file is part of avr-bytequeue.
//
//avr-bytequeue is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//avr-bytequeue is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with avr-bytequeue. If not, see <http://www.gnu.org/licenses/>.
//AVR specific code
//should be able to port to other systems by simply providing chip specific
//implementations of the typedef and these functions
#include "interrupt_setting.h"
#include <avr/interrupt.h>
interrupt_setting_t store_and_clear_interrupt(void) {
uint8_t sreg = SREG;
cli();
return sreg;
}
void restore_interrupt_setting(interrupt_setting_t setting) {
SREG = setting;
}
+39
View File
@@ -0,0 +1,39 @@
//Copyright 20010 Alex Norman
//writen by Alex Norman
//
//This file is part of avr-bytequeue.
//
//avr-bytequeue is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//avr-bytequeue is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with avr-bytequeue. If not, see <http://www.gnu.org/licenses/>.
#ifndef INTERRUPT_SETTING_H
#define INTERRUPT_SETTING_H
#ifdef __cplusplus
extern "C" {
#endif
#include <inttypes.h>
//AVR specific typedef
typedef uint8_t interrupt_setting_t;
interrupt_setting_t store_and_clear_interrupt(void);
void restore_interrupt_setting(interrupt_setting_t setting);
#ifdef __cplusplus
}
#endif
#endif
+277
View File
File diff suppressed because it is too large Load Diff
+498
View File
File diff suppressed because it is too large Load Diff
+291
View File
File diff suppressed because it is too large Load Diff
+156
View File
@@ -0,0 +1,156 @@
//midi for embedded chips,
//Copyright 2010 Alex Norman
//
//This file is part of avr-midi.
//
//avr-midi is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//avr-midi is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
/**
* @file
* @brief Device implementation functions
*/
#ifndef MIDI_DEVICE_H
#define MIDI_DEVICE_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup midi_device Functions used when implementing your own midi device.
*
* You use the functions when you are implementing your own midi device.
*
* You set a send function to actually send bytes via your device, this method
* is called when you call a send function with this device, for instance
* midi_send_cc
*
* You use the midi_device_input to process input data from the device and pass
* it through the device's associated callbacks.
*
* You use the midi_device_set_pre_input_process_func if you want to have a
* function called at the beginning of the device's process function, generally
* to poll for input and pass that into midi_device_input
*
* @{
*/
#include "midi_function_types.h"
#include "bytequeue/bytequeue.h"
#define MIDI_INPUT_QUEUE_LENGTH 192
typedef enum {
IDLE,
ONE_BYTE_MESSAGE = 1,
TWO_BYTE_MESSAGE = 2,
THREE_BYTE_MESSAGE = 3,
SYSEX_MESSAGE} input_state_t;
typedef void (* midi_no_byte_func_t)(MidiDevice * device);
/**
* \struct _midi_device
*
* @brief This structure represents the input and output functions and
* processing data for a midi device.
*
* A device can represent an actual physical device [serial port, usb port] or
* something virtual.
* You should not need to modify this structure directly.
*/
struct _midi_device {
//output send function
midi_var_byte_func_t send_func;
//********input callbacks
//three byte funcs
midi_three_byte_func_t input_cc_callback;
midi_three_byte_func_t input_noteon_callback;
midi_three_byte_func_t input_noteoff_callback;
midi_three_byte_func_t input_aftertouch_callback;
midi_three_byte_func_t input_pitchbend_callback;
midi_three_byte_func_t input_songposition_callback;
//two byte funcs
midi_two_byte_func_t input_progchange_callback;
midi_two_byte_func_t input_chanpressure_callback;
midi_two_byte_func_t input_songselect_callback;
midi_two_byte_func_t input_tc_quarterframe_callback;
//one byte funcs
midi_one_byte_func_t input_realtime_callback;
midi_one_byte_func_t input_tunerequest_callback;
//sysex
midi_sysex_func_t input_sysex_callback;
//only called if more specific callback is not matched
midi_var_byte_func_t input_fallthrough_callback;
//called if registered, independent of other callbacks
midi_var_byte_func_t input_catchall_callback;
//pre input processing function
midi_no_byte_func_t pre_input_process_callback;
//for internal input processing
uint8_t input_buffer[3];
input_state_t input_state;
uint16_t input_count;
//for queueing data between the input and the processing functions
uint8_t input_queue_data[MIDI_INPUT_QUEUE_LENGTH];
byteQueue_t input_queue;
};
/**
* @brief Process input bytes. This function parses bytes and calls the
* appropriate callbacks associated with the given device. You use this
* function if you are creating a custom device and you want to have midi
* input.
*
* @param device the midi device to associate the input with
* @param cnt the number of bytes you are processing
* @param input the bytes to process
*/
void midi_device_input(MidiDevice * device, uint8_t cnt, uint8_t * input);
/**
* @brief Set the callback function that will be used for sending output
* data bytes. This is only used if you're creating a custom device.
* You'll most likely want the callback function to disable interrupts so
* that you can call the various midi send functions without worrying about
* locking.
*
* \param device the midi device to associate this callback with
* \param send_func the callback function that will do the sending
*/
void midi_device_set_send_func(MidiDevice * device, midi_var_byte_func_t send_func);
/**
* @brief Set a callback which is called at the beginning of the
* midi_device_process call. This can be used to poll for input
* data and send the data through the midi_device_input function.
* You'll probably only use this if you're creating a custom device.
*
* \param device the midi device to associate this callback with
* \param midi_no_byte_func_t the actual callback function
*/
void midi_device_set_pre_input_process_func(MidiDevice * device, midi_no_byte_func_t pre_process_func);
/**@}*/
#ifdef __cplusplus
}
#endif
#endif
+50
View File
@@ -0,0 +1,50 @@
//midi for embedded chips,
//Copyright 2010 Alex Norman
//
//This file is part of avr-midi.
//
//avr-midi is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//avr-midi is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
/**
* @file
* @brief Function signature definitions
*/
#ifndef MIDI_FUNCTION_TYPES_H
#define MIDI_FUNCTION_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
#include <inttypes.h>
#include <stdbool.h>
//forward declaration
typedef struct _midi_device MidiDevice;
typedef void (* midi_one_byte_func_t)(MidiDevice * device, uint8_t byte);
typedef void (* midi_two_byte_func_t)(MidiDevice * device, uint8_t byte0, uint8_t byte1);
typedef void (* midi_three_byte_func_t)(MidiDevice * device, uint8_t byte0, uint8_t byte1, uint8_t byte2);
//all bytes after count bytes should be ignored
typedef void (* midi_var_byte_func_t)(MidiDevice * device, uint16_t count, uint8_t byte0, uint8_t byte1, uint8_t byte2);
//the start byte tells you how far into the sysex message you are, the data_length tells you how many bytes data is
typedef void (* midi_sysex_func_t)(MidiDevice * device, uint16_t start_byte, uint8_t data_length, uint8_t *data);
#ifdef __cplusplus
}
#endif
#endif
+99
View File
@@ -0,0 +1,99 @@
//midi for embedded chips,
//Copyright 2010 Alex Norman
//
//This file is part of avr-midi.
//
//avr-midi is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//avr-midi is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
#include "sysex_tools.h"
uint16_t sysex_encoded_length(uint16_t decoded_length){
uint8_t remainder = decoded_length % 7;
if (remainder)
return (decoded_length / 7) * 8 + remainder + 1;
else
return (decoded_length / 7) * 8;
}
uint16_t sysex_decoded_length(uint16_t encoded_length){
uint8_t remainder = encoded_length % 8;
if (remainder)
return (encoded_length / 8) * 7 + remainder - 1;
else
return (encoded_length / 8) * 7;
}
uint16_t sysex_encode(uint8_t *encoded, const uint8_t *source, const uint16_t length){
uint16_t encoded_full = length / 7; //number of full 8 byte sections from 7 bytes of input
uint16_t i,j;
//fill out the fully encoded sections
for(i = 0; i < encoded_full; i++) {
uint16_t encoded_msb_idx = i * 8;
uint16_t input_start_idx = i * 7;
encoded[encoded_msb_idx] = 0;
for(j = 0; j < 7; j++){
uint8_t current = source[input_start_idx + j];
encoded[encoded_msb_idx] |= (0x80 & current) >> (1 + j);
encoded[encoded_msb_idx + 1 + j] = 0x7F & current;
}
}
//fill out the rest if there is any more
uint8_t remainder = length % 7;
if (remainder) {
uint16_t encoded_msb_idx = encoded_full * 8;
uint16_t input_start_idx = encoded_full * 7;
encoded[encoded_msb_idx] = 0;
for(j = 0; j < remainder; j++){
uint8_t current = source[input_start_idx + j];
encoded[encoded_msb_idx] |= (0x80 & current) >> (1 + j);
encoded[encoded_msb_idx + 1 + j] = 0x7F & current;
}
return encoded_msb_idx + remainder + 1;
} else {
return encoded_full * 8;
}
}
uint16_t sysex_decode(uint8_t *decoded, const uint8_t *source, const uint16_t length){
uint16_t decoded_full = length / 8;
uint16_t i,j;
if (length < 2)
return 0;
//fill out the fully encoded sections
for(i = 0; i < decoded_full; i++) {
uint16_t encoded_msb_idx = i * 8;
uint16_t output_start_index = i * 7;
for(j = 0; j < 7; j++){
decoded[output_start_index + j] = 0x7F & source[encoded_msb_idx + j + 1];
decoded[output_start_index + j] |= (0x80 & (source[encoded_msb_idx] << (1 + j)));
}
}
uint8_t remainder = length % 8;
if (remainder) {
uint16_t encoded_msb_idx = decoded_full * 8;
uint16_t output_start_index = decoded_full * 7;
for(j = 0; j < (remainder - 1); j++) {
decoded[output_start_index + j] = 0x7F & source[encoded_msb_idx + j + 1];
decoded[output_start_index + j] |= (0x80 & (source[encoded_msb_idx] << (1 + j)));
}
return decoded_full * 7 + remainder - 1;
} else {
return decoded_full * 7;
}
}
+95
View File
@@ -0,0 +1,95 @@
//midi for embedded chips,
//Copyright 2010 Alex Norman
//
//This file is part of avr-midi.
//
//avr-midi is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.
//
//avr-midi is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with avr-midi. If not, see <http://www.gnu.org/licenses/>.
#ifndef SYSEX_TOOLS_H
#define SYSEX_TOOLS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <inttypes.h>
/**
* @file
* @brief Sysex utility functions
*
* These functions are for converting data to and from a "midi-safe" format,
* which can be use to send data with sysex messages. Sysex messages may only
* contain data where the to bit is not set.
*
* An "encoded" midi message is one that contains all of the data from its
* original state, but does not have any of the top bits set.
*
* Every 7 bytes of decoded data is converted into 8 bytes of encoded data and
* visa-versa. If you'd like to operate on small segments, make sure that you
* encode in 7 byte increments and decode in 8 byte increments.
*
*/
/** @defgroup sysex_tools Sysex utility functions
* @{
*/
/**
* @brief Compute the length of a message after it is encoded.
*
* @param decoded_length The length, in bytes, of the message to encode.
*
* @return The length, in bytes, of the message after encodeing.
*/
uint16_t sysex_encoded_length(uint16_t decoded_length);
/**
* @brief Compute the length of a message after it is decoded.
*
* @param encoded_length The length, in bytes, of the encoded message.
*
* @return The length, in bytes, of the message after it is decoded.
*/
uint16_t sysex_decoded_length(uint16_t encoded_length);
/**
* @brief Encode data so that it can be transmitted safely in a sysex message.
*
* @param encoded The output data buffer, must be at least sysex_encoded_length(length) bytes long.
* @param source The input buffer of data to be encoded.
* @param length The number of bytes from the input buffer to encode.
*
* @return number of bytes encoded.
*/
uint16_t sysex_encode(uint8_t *encoded, const uint8_t *source, uint16_t length);
/**
* @brief Decode encoded data.
*
* @param decoded The output data buffer, must be at least sysex_decoded_length(length) bytes long.
* @param source The input buffer of data to be decoded.
* @param length The number of bytes from the input buffer to decode.
*
* @return number of bytes decoded.
*/
uint16_t sysex_decode(uint8_t *decoded, const uint8_t *source, uint16_t length);
/**@}*/
#ifdef __cplusplus
}
#endif
#endif