From a4c5c56b6d02d87857e44dd2e9f3ea67db79e163 Mon Sep 17 00:00:00 2001 From: Russell Gallop Date: Thu, 25 Aug 2011 18:05:18 +0100 Subject: [PATCH] Jam iAP into usb_midi. --- module_usb_midi/src/usb_midi.h | 4 +- module_usb_midi/src/usb_midi.xc | 128 ++++++++++++++++++++++++++++++-- 2 files changed, 123 insertions(+), 9 deletions(-) diff --git a/module_usb_midi/src/usb_midi.h b/module_usb_midi/src/usb_midi.h index 215def1d..da87cd21 100644 --- a/module_usb_midi/src/usb_midi.h +++ b/module_usb_midi/src/usb_midi.h @@ -17,7 +17,9 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out, clock ?clk_midi, chanend c_midi, - unsigned cable_number); + unsigned cable_number, +chanend c_iap, chanend ?c_i2c // iOS stuff +); #define MAX_USB_MIDI_PACKET_SIZE 1024 #define MIDI_USB_BUFFER_FROM_HOST_FIFO_SIZE (512+1024) diff --git a/module_usb_midi/src/usb_midi.xc b/module_usb_midi/src/usb_midi.xc index a50cdb47..3b51de14 100644 --- a/module_usb_midi/src/usb_midi.xc +++ b/module_usb_midi/src/usb_midi.xc @@ -5,6 +5,8 @@ #include "midiinparse.h" #include "midioutparse.h" #include "queue.h" +#include "port32A.h" +#include "iAP.h" //#define MIDI_LOOPBACK 1 @@ -54,10 +56,37 @@ static inline void handle_byte_from_uart(chanend c_midi, struct midi_in_parse_ int uout_count = 0; // UART bytes out int uin_count = 0; // UART bytes in -void usb_midi(in port ?p_midi_in, out port ?p_midi_out, +extern int ith_count; // Count of things sent to host + +//// state for iAP +extern char iap_buffer[513]; // This should be just enough to hold a maximum size RetDevAuthenticationInfo (plus one for checksum when using transaction id as well) but this exceeds wMaxPacketSize +extern int iap_bufferlen; +extern int data_to_send; +// +//// state for GetDevAuthenticationInfo (global because returned on several RetDevAuthenticationInfos) +//char major = 0xf; +//char minor = 0xb; +//char cert[1920]; +//unsigned short certLen = 0; +//int currentSectionIndex; +//int maxSectionIndex; +// +//// state for GetDevAuthenticationSignature +//int startup = 1; +extern unsigned authenticating; + +extern port p_i2c_scl; +extern port p_i2c_sda; +#define p_midi_out p_i2c_scl +#define p_midi_in p_i2c_sda + +void usb_midi(in port ?p_midi_inj, out port ?p_midi_outj, clock ?clk_midi, chanend c_midi, - unsigned cable_number) { + unsigned cable_number, +chanend c_iap, chanend ?c_i2c // iOS stuff +) + { unsigned symbol = 0x0; // Symbol in progress of being sent out unsigned isTX = 0; // Guard when outputting data unsigned txT; // Timer value used for outputting @@ -86,6 +115,19 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out, unsigned rxPT, txPT; int midi_from_host_overflow = 0; + // iAP declarations + + // Buffers + queue to_host_fifo; + unsigned to_host_arr[256]; + queue from_host_fifo; + unsigned from_host_arr[256]; + // State + unsigned expecting_length = 1; // Expecting the next data item to be a length + unsigned expected_data_length = 0; // The length of data we are expecting + + + //configure_clock_rate(clk_midi, 100, 1); init_queue(symbol_fifo, symbol_fifo_arr, USB_MIDI_DEVICE_OUT_FIFO_SIZE); init_queue(midi_to_host_fifo, midi_to_host_fifo_arr, 1); @@ -102,11 +144,30 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out, t :> txT; t2 :> rxT; + //port32A_unset(P32A_I2C_NOTMIDI); #ifndef MIDI_LOOPBACK p_midi_out <: 1; // Start with high bit. // printstr("mout0"); #endif + + // iAP initialisation + // Initialise buffers + init_queue(to_host_fifo, to_host_arr, 256); + init_queue(from_host_fifo, from_host_arr, 256); + // Start buffer with StartIDPS message in + iap_bufferlen = StartIDPS(iap_buffer); + port32A_set(P32A_I2C_NOTMIDI); + for (int i = 0; i != iap_bufferlen; i++) { + enqueue(to_host_fifo, iap_buffer[i]); + } + //dump(to_host_fifo); + // Start the ball rolling (so I will be expecting an ack) + outuint(c_iap, dequeue(to_host_fifo)); + ith_count++; + + + while (1) { int is_ack; unsigned int datum; @@ -114,9 +175,9 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out, // Input to read the start bit #ifndef MIDI_LOOPBACK #ifdef MIDI_IN_4BIT_PORT - case !isRX => p_midi_in when pinseq(0xE) :> void @ rxPT: + case (!authenticating && !isRX) => p_midi_in when pinseq(0xE) :> void @ rxPT: #else - case !isRX => p_midi_in when pinseq(0) :> void @ rxPT: + case (!authenticating && !isRX) => p_midi_in when pinseq(0) :> void @ rxPT: #endif isRX = 1; t2 :> rxT; @@ -127,7 +188,7 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out, asm("setpt res[%0],%1"::"r"(p_midi_in),"r"(rxPT)); break; // Input to read the remaining bits - case isRX => t2 when timerafter(rxT) :> int _ : + case (!authenticating && isRX) => t2 when timerafter(rxT) :> int _ : { unsigned bit; p_midi_in :> bit; @@ -176,7 +237,7 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out, // If isTX then feed the bits out one at a time // until symbol is zero expect pattern like 10'b1dddddddd0 // This code will leave the output high afterwards due to the stop bit added with makeSymbol - case isTX => t when timerafter(txT) :> int _: + case (!authenticating && isTX) => t when timerafter(txT) :> int _: if (symbol == 0) { // Got something to output but not mid-symbol. // Start sending symbol. @@ -217,7 +278,7 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out, break; #endif - case midi_get_ack_or_data(c_midi, is_ack, datum): + case !authenticating => midi_get_ack_or_data(c_midi, is_ack, datum): if (is_ack) { // have we got more data to send //printstr("ack\n"); @@ -268,7 +329,58 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out, #endif } break; - } + case !(isTX || isRX) => iap_get_ack_or_data(c_iap, is_ack, datum): + //printstrln("iap_get_ack_or_data"); + if (is_ack) { + // have we got more data to send + //printstr("ack\n"); + if (!isempty(to_host_fifo)) { + //printstr("iap->decouple\n"); + outuint(c_iap, dequeue(to_host_fifo)); + ith_count++; + } else { + //printintln(ith_count); + } + } else { + if (expecting_length) { + expected_data_length = datum; + expecting_length = 0; + // iap_send_ack(c_iap); // Don't send ack as I don't expect it at the other end! + } else { + // Expecting data + int fullness; + enqueue(from_host_fifo, datum); + iap_send_ack(c_iap); + fullness = items(from_host_fifo); + if (fullness == expected_data_length) { + // Received whole message. Transfer to iap_buffer for parse + for (int i = 0; i != fullness; i++) { + iap_buffer[i] = dequeue(from_host_fifo); + } + iap_bufferlen = expected_data_length; + // Parse iAP from host + parseiAP(c_i2c); + // Start the ball rolling + if (data_to_send) { + for (int i = 0; i != iap_bufferlen; i++) { + enqueue(to_host_fifo, iap_buffer[i]); + //printhexln(dequeue(from_host_fifo)); + } + outuint(c_iap, dequeue(to_host_fifo)); + ith_count++; + data_to_send = 0; // In this usage data_to_send is just used to kick off the data. The rest is pulled by ACKs. + } + expecting_length = 1; + } + } + } + if (!authenticating) { + // printstrln("Completed authentication"); + p_midi_in :> void; // Change port around to input again after authenticating + } + + break; + } } }