forked from PAWPAW-Mirror/lib_xua
Jam iAP into usb_midi.
This commit is contained in:
@@ -17,7 +17,9 @@
|
|||||||
void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
||||||
clock ?clk_midi,
|
clock ?clk_midi,
|
||||||
chanend c_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 MAX_USB_MIDI_PACKET_SIZE 1024
|
||||||
#define MIDI_USB_BUFFER_FROM_HOST_FIFO_SIZE (512+1024)
|
#define MIDI_USB_BUFFER_FROM_HOST_FIFO_SIZE (512+1024)
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#include "midiinparse.h"
|
#include "midiinparse.h"
|
||||||
#include "midioutparse.h"
|
#include "midioutparse.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
|
#include "port32A.h"
|
||||||
|
#include "iAP.h"
|
||||||
|
|
||||||
//#define MIDI_LOOPBACK 1
|
//#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 uout_count = 0; // UART bytes out
|
||||||
int uin_count = 0; // UART bytes in
|
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,
|
clock ?clk_midi,
|
||||||
chanend c_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 symbol = 0x0; // Symbol in progress of being sent out
|
||||||
unsigned isTX = 0; // Guard when outputting data
|
unsigned isTX = 0; // Guard when outputting data
|
||||||
unsigned txT; // Timer value used for outputting
|
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;
|
unsigned rxPT, txPT;
|
||||||
int midi_from_host_overflow = 0;
|
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);
|
//configure_clock_rate(clk_midi, 100, 1);
|
||||||
init_queue(symbol_fifo, symbol_fifo_arr, USB_MIDI_DEVICE_OUT_FIFO_SIZE);
|
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);
|
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;
|
t :> txT;
|
||||||
t2 :> rxT;
|
t2 :> rxT;
|
||||||
|
|
||||||
|
//port32A_unset(P32A_I2C_NOTMIDI);
|
||||||
#ifndef MIDI_LOOPBACK
|
#ifndef MIDI_LOOPBACK
|
||||||
p_midi_out <: 1; // Start with high bit.
|
p_midi_out <: 1; // Start with high bit.
|
||||||
// printstr("mout0");
|
// printstr("mout0");
|
||||||
#endif
|
#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) {
|
while (1) {
|
||||||
int is_ack;
|
int is_ack;
|
||||||
unsigned int datum;
|
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
|
// Input to read the start bit
|
||||||
#ifndef MIDI_LOOPBACK
|
#ifndef MIDI_LOOPBACK
|
||||||
#ifdef MIDI_IN_4BIT_PORT
|
#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
|
#else
|
||||||
case !isRX => p_midi_in when pinseq(0) :> void @ rxPT:
|
case (!authenticating && !isRX) => p_midi_in when pinseq(0) :> void @ rxPT:
|
||||||
#endif
|
#endif
|
||||||
isRX = 1;
|
isRX = 1;
|
||||||
t2 :> rxT;
|
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));
|
asm("setpt res[%0],%1"::"r"(p_midi_in),"r"(rxPT));
|
||||||
break;
|
break;
|
||||||
// Input to read the remaining bits
|
// Input to read the remaining bits
|
||||||
case isRX => t2 when timerafter(rxT) :> int _ :
|
case (!authenticating && isRX) => t2 when timerafter(rxT) :> int _ :
|
||||||
{
|
{
|
||||||
unsigned bit;
|
unsigned bit;
|
||||||
p_midi_in :> 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
|
// If isTX then feed the bits out one at a time
|
||||||
// until symbol is zero expect pattern like 10'b1dddddddd0
|
// 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
|
// 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) {
|
if (symbol == 0) {
|
||||||
// Got something to output but not mid-symbol.
|
// Got something to output but not mid-symbol.
|
||||||
// Start sending symbol.
|
// Start sending symbol.
|
||||||
@@ -217,7 +278,7 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
|||||||
break;
|
break;
|
||||||
#endif
|
#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) {
|
if (is_ack) {
|
||||||
// have we got more data to send
|
// have we got more data to send
|
||||||
//printstr("ack\n");
|
//printstr("ack\n");
|
||||||
@@ -268,7 +329,58 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user