aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--quantum/api/api_sysex.c60
-rw-r--r--quantum/config_common.h2
-rw-r--r--tmk_core/protocol/lufa/lufa.c32
-rw-r--r--tmk_core/protocol/lufa/lufa.h4
4 files changed, 71 insertions, 27 deletions
diff --git a/quantum/api/api_sysex.c b/quantum/api/api_sysex.c
index a4a554e76..868f854b9 100644
--- a/quantum/api/api_sysex.c
+++ b/quantum/api/api_sysex.c
@@ -1,4 +1,6 @@
1#include "api_sysex.h" 1#include "api_sysex.h"
2#include "sysex_tools.h"
3#include "print.h"
2 4
3void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length) { 5void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes, uint16_t length) {
4 // SEND_STRING("\nTX: "); 6 // SEND_STRING("\nTX: ");
@@ -6,24 +8,50 @@ void send_bytes_sysex(uint8_t message_type, uint8_t data_type, uint8_t * bytes,
6 // send_byte(bytes[i]); 8 // send_byte(bytes[i]);
7 // SEND_STRING(" "); 9 // SEND_STRING(" ");
8 // } 10 // }
9 uint8_t * precode = malloc(sizeof(uint8_t) * (length + 2)); 11 if (length > API_SYSEX_MAX_SIZE) {
10 precode[0] = message_type; 12 xprintf("Sysex msg too big %d %d %d", message_type, data_type, length);
11 precode[1] = data_type; 13 return;
12 memcpy(precode + 2, bytes, length); 14 }
13 uint8_t * encoded = malloc(sizeof(uint8_t) * (sysex_encoded_length(length + 2))); 15
14 uint16_t encoded_length = sysex_encode(encoded, precode, length + 2); 16
15 uint8_t * array = malloc(sizeof(uint8_t) * (encoded_length + 5)); 17 // The buffer size required is calculated as the following
16 array[0] = 0xF0; 18 // API_SYSEX_MAX_SIZE is the maximum length
17 array[1] = 0x00; 19 // In addition to that we have a two byte message header consisting of the message_type and data_type
18 array[2] = 0x00; 20 // This has to be encoded with an additional overhead of one byte for every starting 7 bytes
19 array[3] = 0x00; 21 // We just add one extra byte in case it's not divisible by 7
20 array[encoded_length + 4] = 0xF7; 22 // Then we have an unencoded header consisting of 4 bytes
21 memcpy(array + 4, encoded, encoded_length); 23 // Plus a one byte terminator
22 midi_send_array(&midi_device, encoded_length + 5, array); 24 const unsigned message_header = 2;
25 const unsigned unencoded_message = API_SYSEX_MAX_SIZE + message_header;
26 const unsigned encoding_overhead = unencoded_message / 7 + 1;
27 const unsigned encoded_size = unencoded_message + encoding_overhead;
28 const unsigned unencoded_header = 4;
29 const unsigned terminator = 1;
30 const unsigned buffer_size = encoded_size + unencoded_header + terminator;
31 uint8_t buffer[encoded_size + unencoded_header + terminator];
32 // The unencoded header
33 buffer[0] = 0xF0;
34 buffer[1] = 0x00;
35 buffer[2] = 0x00;
36 buffer[3] = 0x00;
37
38 // We copy the message to the end of the array, this way we can do an inplace encoding, using the same
39 // buffer for both input and output
40 const unsigned message_size = length + message_header;
41 uint8_t* unencoded_start = buffer + buffer_size - message_size;
42 uint8_t* ptr = unencoded_start;
43 *(ptr++) = message_type;
44 *(ptr++) = data_type;
45 memcpy(ptr, bytes, length);
46
47 unsigned encoded_length = sysex_encode(buffer + unencoded_header, unencoded_start, message_size);
48 unsigned final_size = unencoded_header + encoded_length + terminator;
49 buffer[final_size - 1] = 0xF7;
50 midi_send_array(&midi_device, final_size, buffer);
23 51
24 // SEND_STRING("\nTD: "); 52 // SEND_STRING("\nTD: ");
25 // for (uint8_t i = 0; i < encoded_length + 5; i++) { 53 // for (uint8_t i = 0; i < encoded_length + 5; i++) {
26 // send_byte(array[i]); 54 // send_byte(buffer[i]);
27 // SEND_STRING(" "); 55 // SEND_STRING(" ");
28 // } 56 // }
29} \ No newline at end of file 57}
diff --git a/quantum/config_common.h b/quantum/config_common.h
index 17c11faeb..4bdb2065d 100644
--- a/quantum/config_common.h
+++ b/quantum/config_common.h
@@ -80,4 +80,6 @@
80# endif 80# endif
81#endif 81#endif
82 82
83#define API_SYSEX_MAX_SIZE 32
84
83#endif 85#endif
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 097189770..6dd5959dc 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -1252,28 +1252,40 @@ void cc_callback(MidiDevice * device,
1252 // midi_send_cc(device, (chan + 1) % 16, num, val); 1252 // midi_send_cc(device, (chan + 1) % 16, num, val);
1253} 1253}
1254 1254
1255#ifdef API_SYSEX_ENABLE
1255uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0}; 1256uint8_t midi_buffer[MIDI_SYSEX_BUFFER] = {0};
1257#endif
1256 1258
1257void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) { 1259void sysex_callback(MidiDevice * device, uint16_t start, uint8_t length, uint8_t * data) {
1258 #ifdef API_SYSEX_ENABLE 1260 #ifdef API_SYSEX_ENABLE
1259 // SEND_STRING("\n"); 1261 // SEND_STRING("\n");
1260 // send_word(start); 1262 // send_word(start);
1261 // SEND_STRING(": "); 1263 // SEND_STRING(": ");
1264 // Don't store the header
1265 int16_t pos = start - 4;
1262 for (uint8_t place = 0; place < length; place++) { 1266 for (uint8_t place = 0; place < length; place++) {
1263 // send_byte(*data); 1267 // send_byte(*data);
1264 midi_buffer[start + place] = *data; 1268 if (pos >= 0) {
1265 if (*data == 0xF7) { 1269 if (*data == 0xF7) {
1266 // SEND_STRING("\nRD: "); 1270 // SEND_STRING("\nRD: ");
1267 // for (uint8_t i = 0; i < start + place + 1; i++){ 1271 // for (uint8_t i = 0; i < start + place + 1; i++){
1268 // send_byte(midi_buffer[i]); 1272 // send_byte(midi_buffer[i]);
1269 // SEND_STRING(" "); 1273 // SEND_STRING(" ");
1270 // } 1274 // }
1271 uint8_t * decoded = malloc(sizeof(uint8_t) * (sysex_decoded_length(start + place - 4))); 1275 const unsigned decoded_length = sysex_decoded_length(pos);
1272 uint16_t decode_length = sysex_decode(decoded, midi_buffer + 4, start + place - 4); 1276 uint8_t decoded[API_SYSEX_MAX_SIZE];
1273 process_api(decode_length, decoded); 1277 sysex_decode(decoded, midi_buffer, pos);
1278 process_api(decoded_length, decoded);
1279 return;
1280 }
1281 else if (pos >= MIDI_SYSEX_BUFFER) {
1282 return;
1283 }
1284 midi_buffer[pos] = *data;
1274 } 1285 }
1275 // SEND_STRING(" "); 1286 // SEND_STRING(" ");
1276 data++; 1287 data++;
1288 pos++;
1277 } 1289 }
1278 #endif 1290 #endif
1279} 1291}
diff --git a/tmk_core/protocol/lufa/lufa.h b/tmk_core/protocol/lufa/lufa.h
index b11854101..a049fd43c 100644
--- a/tmk_core/protocol/lufa/lufa.h
+++ b/tmk_core/protocol/lufa/lufa.h
@@ -70,7 +70,6 @@ typedef struct {
70#ifdef MIDI_ENABLE 70#ifdef MIDI_ENABLE
71 void MIDI_Task(void); 71 void MIDI_Task(void);
72 MidiDevice midi_device; 72 MidiDevice midi_device;
73 #define MIDI_SYSEX_BUFFER 32
74#endif 73#endif
75 74
76#ifdef API_ENABLE 75#ifdef API_ENABLE
@@ -79,6 +78,9 @@ typedef struct {
79 78
80#ifdef API_SYSEX_ENABLE 79#ifdef API_SYSEX_ENABLE
81 #include "api_sysex.h" 80 #include "api_sysex.h"
81 // Allocate space for encoding overhead.
82 //The header and terminator are not stored to save a few bytes of precious ram
83 #define MIDI_SYSEX_BUFFER (API_SYSEX_MAX_SIZE + API_SYSEX_MAX_SIZE / 7 + (API_SYSEX_MAX_SIZE % 7 ? 1 : 0))
82#endif 84#endif
83 85
84// #if LUFA_VERSION_INTEGER < 0x120730 86// #if LUFA_VERSION_INTEGER < 0x120730