alles ums licht im Keller und Sommerschein
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
5.6 KiB

4 months ago
/*
* SPDX-FileCopyrightText: 2019 Ha Thach (tinyusb.org)
*
* SPDX-License-Identifier: MIT
*
* SPDX-FileContributor: 2022-2023 Espressif Systems (Shanghai) CO LTD
*/
#include <stdlib.h>
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "tinyusb.h"
#include "esp_timer.h"
#include "controls.h"
static const char *TAG = "example";
/** Helper defines **/
// Interface counter
enum interface_count {
#if CFG_TUD_MIDI
ITF_NUM_MIDI = 0,
ITF_NUM_MIDI_STREAMING,
#endif
ITF_COUNT
};
// USB Endpoint numbers
enum usb_endpoints {
// Available USB Endpoints: 5 IN/OUT EPs and 1 IN EP
EP_EMPTY = 0,
#if CFG_TUD_MIDI
EPNUM_MIDI,
#endif
};
/** TinyUSB descriptors **/
#define TUSB_DESCRIPTOR_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_MIDI * TUD_MIDI_DESC_LEN)
// Basic MIDI Messages
#define NOTE_OFF 0x80
#define NOTE_ON 0x90
#define SET_CONTROL 0xB0
/**
* @brief String descriptor
*/
static const char* s_str_desc[5] = {
// array of pointer to string descriptors
(char[]){0x09, 0x04}, // 0: is supported language is English (0x0409)
"TinyUSB", // 1: Manufacturer
"TinyUSB Device", // 2: Product
"123456", // 3: Serials, should use chip ID
"Example MIDI device", // 4: MIDI
};
/**
* @brief Configuration descriptor
*
* This is a simple configuration descriptor that defines 1 configuration and a MIDI interface
*/
static const uint8_t s_midi_cfg_desc[] = {
// Configuration number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_COUNT, 0, TUSB_DESCRIPTOR_TOTAL_LEN, 0, 100),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 4, EPNUM_MIDI, (0x80 | EPNUM_MIDI), 64),
};
static void midi_task_read_example(void *arg)
{
// The MIDI interface always creates input and output port/jack descriptors
// regardless of these being used or not. Therefore incoming traffic should be read
// (possibly just discarded) to avoid the sender blocking in IO
uint8_t packet[4];
bool read = false;
for (;;) {
vTaskDelay(1);
while (tud_midi_available()) {
read = tud_midi_packet_read(packet);
if (read) {
if(packet[1] == SET_CONTROL){
setControl(packet[2], packet[3]<<1);
ESP_LOGI(TAG, "setControl(packet[2]%i, packet[3]%i<1/%i)", packet[2], packet[3],packet[3]<<1);
}
ESP_LOGI(TAG, "Read - Time (ms since boot): %lld, Data: %02hhX %02hhX %02hhX %02hhX",
esp_timer_get_time(), packet[0], packet[1], packet[2], packet[3]);
}
}
}
}
static void periodic_midi_write_example_cb(void *arg)
{
// Example melody stored as an array of note values
uint8_t const note_sequence[] = {
74, 78, 81, 86, 90, 93, 98, 102, 57, 61, 66, 69, 73, 78, 81, 85, 88, 92, 97, 100, 97, 92, 88, 85, 81, 78,
74, 69, 66, 62, 57, 62, 66, 69, 74, 78, 81, 86, 90, 93, 97, 102, 97, 93, 90, 85, 81, 78, 73, 68, 64, 61,
56, 61, 64, 68, 74, 78, 81, 86, 90, 93, 98, 102
};
static uint8_t const cable_num = 0; // MIDI jack associated with USB endpoint
static uint8_t const channel = 0; // 0 for channel 1
static uint32_t note_pos = 0;
// Previous positions in the note sequence.
int previous = note_pos - 1;
// If we currently are at position 0, set the
// previous position to the last note in the sequence.
if (previous < 0) {
previous = sizeof(note_sequence) - 1;
}
// Send Note On for current position at full velocity (127) on channel 1.
ESP_LOGI(TAG, "Writing MIDI data %d", note_sequence[note_pos]);
if (tud_midi_mounted()) {
uint8_t note_on[3] = {NOTE_ON | channel, note_sequence[note_pos], 127};
tud_midi_stream_write(cable_num, note_on, 3);
// Send Note Off for previous note.
uint8_t note_off[3] = {NOTE_OFF | channel, note_sequence[previous], 0};
tud_midi_stream_write(cable_num, note_off, 3);
}
// Increment position
note_pos++;
// If we are at the end of the sequence, start over.
if (note_pos >= sizeof(note_sequence)) {
note_pos = 0;
}
}
void app_main(void)
{
ESP_LOGI(TAG, "USB initialization");
tinyusb_config_t const tusb_cfg = {
.device_descriptor = NULL, // If device_descriptor is NULL, tinyusb_driver_install() will use Kconfig
.string_descriptor = s_str_desc,
.external_phy = false,
.configuration_descriptor = s_midi_cfg_desc,
};
// .string_descriptor_count = sizeof(s_str_desc) / sizeof(s_str_desc[0]),
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
ESP_LOGI(TAG, "USB initialization DONE");
// // Periodically send MIDI packets
// int const tempo = 286;
// const esp_timer_create_args_t periodic_midi_args = {
// .callback = &periodic_midi_write_example_cb,
// /* name is optional, but may help identify the timer when debugging */
// .name = "periodic_midi"
// };
// ESP_LOGI(TAG, "MIDI write task init");
// esp_timer_handle_t periodic_midi_timer;
// ESP_ERROR_CHECK(esp_timer_create(&periodic_midi_args, &periodic_midi_timer));
// ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_midi_timer, tempo * 1000));
// Read recieved MIDI packets
ESP_LOGI(TAG, "MIDI read task init");
xTaskCreate(midi_task_read_example, "midi_task_read_example", 8 * 1024, NULL, 5, NULL);
ESP_LOGI(TAG, "read inputs task init");
xTaskCreate(task_read_all, "task_read_all", 8 * 1024, NULL, 21, NULL);
}