forked from PAWPAW-Mirror/lib_xua
Updated iap stuff
This commit is contained in:
@@ -889,6 +889,14 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, SetupPacket &sp, chanend
|
|||||||
storeFreq(buffer, i, 192000);
|
storeFreq(buffer, i, 192000);
|
||||||
num_freqs++;
|
num_freqs++;
|
||||||
#endif
|
#endif
|
||||||
|
#if MAX_FREQ >= 352800
|
||||||
|
storeFreq(buffer, i, 352800);
|
||||||
|
num_freqs++;
|
||||||
|
#endif
|
||||||
|
#if MAX_FREQ >= 384000
|
||||||
|
storeFreq(buffer, i, 384000);
|
||||||
|
num_freqs++;
|
||||||
|
#endif
|
||||||
storeShort(buffer, 0, num_freqs);
|
storeShort(buffer, 0, num_freqs);
|
||||||
// break;
|
// break;
|
||||||
//}
|
//}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
* \param cable_number the cable number of the MIDI implementation.
|
* \param cable_number the cable number of the MIDI implementation.
|
||||||
* This should be set to 0.
|
* This should be set to 0.
|
||||||
**/
|
**/
|
||||||
void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
void usb_midi(port ?p_midi_in, port ?p_midi_out,
|
||||||
clock ?clk_midi,
|
clock ?clk_midi,
|
||||||
chanend c_midi,
|
chanend c_midi,
|
||||||
unsigned cable_number,
|
unsigned cable_number,
|
||||||
@@ -61,5 +61,7 @@ INLINE void midi_send_ack(chanend c) {
|
|||||||
outuchar(c, 0);
|
outuchar(c, 0);
|
||||||
outuchar(c, 0);
|
outuchar(c, 0);
|
||||||
}
|
}
|
||||||
|
#define MIDI_RATE (31250)
|
||||||
|
#define MIDI_BITTIME (XS1_TIMER_MHZ * 1000000 / MIDI_RATE)
|
||||||
|
#define MIDI_BITTIME_2 (MIDI_BITTIME>>1)
|
||||||
#endif // __usb_midi_h__
|
#endif // __usb_midi_h__
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
#include "midiinparse.h"
|
#include "midiinparse.h"
|
||||||
#include "midioutparse.h"
|
#include "midioutparse.h"
|
||||||
#include "queue.h"
|
#include "queue.h"
|
||||||
//#include "port32A.h"
|
|
||||||
#ifdef IAP
|
#ifdef IAP
|
||||||
#include "iAP.h"
|
#include "iAP.h"
|
||||||
|
#include "iapuser.h"
|
||||||
#endif
|
#endif
|
||||||
//#define MIDI_LOOPBACK 1
|
//#define MIDI_LOOPBACK 1
|
||||||
|
|
||||||
static unsigned makeSymbol(unsigned data) {
|
static unsigned makeSymbol(unsigned data)
|
||||||
|
{
|
||||||
// Start and stop bits to the data packet
|
// Start and stop bits to the data packet
|
||||||
// like 10'b1dddddddd0
|
// like 10'b1dddddddd0
|
||||||
return (data << 1) | 0x200;
|
return (data << 1) | 0x200;
|
||||||
@@ -34,22 +35,26 @@ static inline void handle_byte_from_uart(chanend c_midi, struct midi_in_parse_
|
|||||||
int valid;
|
int valid;
|
||||||
unsigned event;
|
unsigned event;
|
||||||
{valid, event} = midi_in_parse(mips, cable_number, byte);
|
{valid, event} = midi_in_parse(mips, cable_number, byte);
|
||||||
if (valid && !got_next_event) {
|
if (valid && !got_next_event)
|
||||||
|
{
|
||||||
// data to send to host
|
// data to send to host
|
||||||
if (!waiting_for_ack) {
|
if (!waiting_for_ack)
|
||||||
|
{
|
||||||
// send data
|
// send data
|
||||||
event = byterev(event);
|
event = byterev(event);
|
||||||
outuint(c_midi, event);
|
outuint(c_midi, event);
|
||||||
th_count++;
|
th_count++;
|
||||||
waiting_for_ack = 1;
|
waiting_for_ack = 1;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
event = byterev(event);
|
event = byterev(event);
|
||||||
next_event = event;
|
next_event = event;
|
||||||
got_next_event = 1;
|
got_next_event = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (valid) {
|
else if (valid)
|
||||||
|
{
|
||||||
// printstr("g\n");
|
// printstr("g\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,27 +73,11 @@ unsigned authenticating = 0;
|
|||||||
// state for auto-selecting dock or USB B
|
// state for auto-selecting dock or USB B
|
||||||
extern unsigned polltime;
|
extern unsigned polltime;
|
||||||
|
|
||||||
#ifdef IO_EXPANSION
|
#ifdef IAP
|
||||||
extern port p_i2c_scl;
|
|
||||||
extern port p_i2c_sda;
|
|
||||||
#define p_midi_out p_i2c_scl
|
|
||||||
#define p_midi_in p_i2c_sda
|
|
||||||
#else
|
|
||||||
//extern out port p_midi_tx;
|
|
||||||
//extern port p_midi_rx;
|
|
||||||
#define p_midi_out p_midi_tx
|
|
||||||
#define p_midi_in p_midi_rx
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//#ifdef IO_EXPANSION
|
|
||||||
#if 0
|
|
||||||
extern timer i2ctimer;
|
|
||||||
#define iAPTimer i2ctimer
|
|
||||||
#else
|
|
||||||
timer iAPTimer;
|
timer iAPTimer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
void usb_midi(port ?p_midi_in, port ?p_midi_out,
|
||||||
clock ?clk_midi,
|
clock ?clk_midi,
|
||||||
chanend c_midi,
|
chanend c_midi,
|
||||||
unsigned cable_number,
|
unsigned cable_number,
|
||||||
@@ -142,39 +131,41 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
|||||||
|
|
||||||
#ifndef MIDI_LOOPBACK
|
#ifndef MIDI_LOOPBACK
|
||||||
#ifdef IAP
|
#ifdef IAP
|
||||||
#ifdef IO_EXPANSION
|
CoProcessorDisable();
|
||||||
port32A_unset(P32A_I2C_NOTMIDI);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
p_midi_out <: 1; // Start with high bit.
|
p_midi_out <: 1; // Start with high bit.
|
||||||
#ifdef IAP
|
#ifdef IAP
|
||||||
#ifdef IO_EXPANSION
|
CoProcessorEnable();
|
||||||
port32A_set(P32A_I2C_NOTMIDI);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IAP
|
#ifdef IAP
|
||||||
|
/* Check for special case where MIDI and i2c ports are shared... */
|
||||||
|
if(isnull(c_i2c) && isnull(p_scl) && isnull(p_sda))
|
||||||
|
{
|
||||||
|
init_iAP(c_i2c, p_midi_out, p_midi_in); // uses timer for i2c initialisation pause..
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
init_iAP(c_i2c, p_scl, p_sda); // uses timer for i2c initialisation pause..
|
init_iAP(c_i2c, p_scl, p_sda); // uses timer for i2c initialisation pause..
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
#ifdef IAP
|
#ifdef IAP
|
||||||
iAPTimer :> polltime;
|
iAPTimer :> polltime;
|
||||||
polltime + XS1_TIMER_HZ / 2;
|
polltime += XS1_TIMER_HZ / 2;
|
||||||
#endif
|
#endif
|
||||||
while (1) {
|
while (1)
|
||||||
|
{
|
||||||
int is_ack;
|
int is_ack;
|
||||||
int is_reset;
|
int is_reset;
|
||||||
unsigned int datum;
|
unsigned int datum;
|
||||||
select {
|
select
|
||||||
|
{
|
||||||
// Input to read the start bit
|
// Input to read the start bit
|
||||||
#ifndef MIDI_LOOPBACK
|
#ifndef MIDI_LOOPBACK
|
||||||
#ifdef MIDI_IN_4BIT_PORT
|
|
||||||
case (!authenticating && !isRX) => p_midi_in when pinseq(0xE) :> void @ rxPT:
|
|
||||||
#else
|
|
||||||
case (!authenticating && !isRX) => p_midi_in when pinseq(0) :> void @ rxPT:
|
case (!authenticating && !isRX) => p_midi_in when pinseq(0) :> void @ rxPT:
|
||||||
#endif
|
|
||||||
isRX = 1;
|
isRX = 1;
|
||||||
t2 :> rxT;
|
t2 :> rxT;
|
||||||
rxT += (bit_time + bit_time_2);
|
rxT += (bit_time + bit_time_2);
|
||||||
@@ -183,20 +174,25 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
|||||||
asm("setc res[%0],1"::"r"(p_midi_in));
|
asm("setc res[%0],1"::"r"(p_midi_in));
|
||||||
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 (!authenticating && 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;
|
||||||
if (rxI++ < 8) {
|
if (rxI++ < 8)
|
||||||
|
{
|
||||||
// shift in bits into the high end of a word
|
// shift in bits into the high end of a word
|
||||||
rxByte = (bit << 31) | (rxByte >> 1);
|
rxByte = (bit << 31) | (rxByte >> 1);
|
||||||
rxT += bit_time;
|
rxT += bit_time;
|
||||||
rxPT += bit_time;
|
rxPT += bit_time;
|
||||||
asm("setpt res[%0],%1"::"r"(p_midi_in),"r"(rxPT));
|
asm("setpt res[%0],%1"::"r"(p_midi_in),"r"(rxPT));
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// rcv and check stop bit
|
// rcv and check stop bit
|
||||||
if ((bit & 0x1) == 1) {
|
if ((bit & 0x1) == 1)
|
||||||
|
{
|
||||||
unsigned valid = 0;
|
unsigned valid = 0;
|
||||||
unsigned event = 0;
|
unsigned event = 0;
|
||||||
uin_count++;
|
uin_count++;
|
||||||
@@ -208,19 +204,25 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
{valid, event} = midi_in_parse(mips, cable_number, rxByte);
|
{valid, event} = midi_in_parse(mips, cable_number, rxByte);
|
||||||
if (valid && isempty(midi_to_host_fifo)) {
|
if (valid && isempty(midi_to_host_fifo))
|
||||||
|
{
|
||||||
event = byterev(event);
|
event = byterev(event);
|
||||||
// data to send to host - add to fifo
|
// data to send to host - add to fifo
|
||||||
if (!waiting_for_ack) {
|
if (!waiting_for_ack)
|
||||||
|
{
|
||||||
// send data
|
// send data
|
||||||
// printstr("uart->decouple: ");
|
// printstr("uart->decouple: ");
|
||||||
outuint(c_midi, event);
|
outuint(c_midi, event);
|
||||||
waiting_for_ack = 1;
|
waiting_for_ack = 1;
|
||||||
th_count++;
|
th_count++;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
enqueue(midi_to_host_fifo, event);
|
enqueue(midi_to_host_fifo, event);
|
||||||
}
|
}
|
||||||
} else if (valid) {
|
}
|
||||||
|
else if (valid)
|
||||||
|
{
|
||||||
// printstr("g");
|
// printstr("g");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -234,7 +236,8 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
|||||||
// 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 (!authenticating && 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.
|
||||||
// This case is reached when a symbol has been received from the host but not started AND
|
// This case is reached when a symbol has been received from the host but not started AND
|
||||||
@@ -244,7 +247,8 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
|||||||
outputting_symbol = dequeue(symbol_fifo);
|
outputting_symbol = dequeue(symbol_fifo);
|
||||||
symbol = makeSymbol(outputting_symbol);
|
symbol = makeSymbol(outputting_symbol);
|
||||||
|
|
||||||
if (space(symbol_fifo) > 3 && midi_from_host_overflow) {
|
if (space(symbol_fifo) > 3 && midi_from_host_overflow)
|
||||||
|
{
|
||||||
midi_from_host_overflow = 0;
|
midi_from_host_overflow = 0;
|
||||||
midi_send_ack(c_midi);
|
midi_send_ack(c_midi);
|
||||||
}
|
}
|
||||||
@@ -255,18 +259,22 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
|||||||
txT += bit_time;
|
txT += bit_time;
|
||||||
txPT += bit_time;
|
txPT += bit_time;
|
||||||
isTX = 1;
|
isTX = 1;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Mid-symbol
|
// Mid-symbol
|
||||||
txT += bit_time; // Should this be after the output otherwise be double the length of the high before the start bit
|
txT += bit_time; // Should this be after the output otherwise be double the length of the high before the start bit
|
||||||
txPT += bit_time;
|
txPT += bit_time;
|
||||||
p_midi_out @ txPT <: (symbol & 1);
|
p_midi_out @ txPT <: (symbol & 1);
|
||||||
// printstr("mout2\n");
|
// printstr("mout2\n");
|
||||||
symbol >>= 1;
|
symbol >>= 1;
|
||||||
if (symbol == 0) {
|
if (symbol == 0)
|
||||||
|
{
|
||||||
// Finished sending byte
|
// Finished sending byte
|
||||||
uout_count++;
|
uout_count++;
|
||||||
outputted_symbol = outputting_symbol;
|
outputted_symbol = outputting_symbol;
|
||||||
if (isempty(symbol_fifo)) { // FIFO empty
|
if (isempty(symbol_fifo))
|
||||||
|
{ // FIFO empty
|
||||||
isTX = 0;
|
isTX = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -275,50 +283,66 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
case !authenticating => 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");
|
||||||
if (!isempty(midi_to_host_fifo)) {
|
if (!isempty(midi_to_host_fifo))
|
||||||
|
{
|
||||||
//printstr("uart->decouple\n");
|
//printstr("uart->decouple\n");
|
||||||
outuint(c_midi, dequeue(midi_to_host_fifo));
|
outuint(c_midi, dequeue(midi_to_host_fifo));
|
||||||
th_count++;
|
th_count++;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
waiting_for_ack = 0;
|
waiting_for_ack = 0;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
unsigned midi[3];
|
unsigned midi[3];
|
||||||
unsigned size;
|
unsigned size;
|
||||||
// received data from host
|
// received data from host
|
||||||
int event = byterev(datum);
|
int event = byterev(datum);
|
||||||
mr_count++;
|
mr_count++;
|
||||||
#ifdef MIDI_LOOPBACK
|
#ifdef MIDI_LOOPBACK
|
||||||
if (isempty(midi_to_host_fifo)) {
|
if (isempty(midi_to_host_fifo))
|
||||||
|
{
|
||||||
// data to send to host
|
// data to send to host
|
||||||
if (!waiting_for_ack) {
|
if (!waiting_for_ack)
|
||||||
|
{
|
||||||
// send data
|
// send data
|
||||||
event = byterev(event);
|
event = byterev(event);
|
||||||
outuint(c_midi, event);
|
outuint(c_midi, event);
|
||||||
th_count++;
|
th_count++;
|
||||||
waiting_for_ack = 1;
|
waiting_for_ack = 1;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
event = byterev(event);
|
event = byterev(event);
|
||||||
enqueue(midi_to_host_fifo, event);
|
enqueue(midi_to_host_fifo, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
{midi[0], midi[1], midi[2], size} = midi_out_parse(event);
|
{midi[0], midi[1], midi[2], size} = midi_out_parse(event);
|
||||||
for (int i = 0; i != size; i++) {
|
for (int i = 0; i != size; i++)
|
||||||
|
{
|
||||||
// add symbol to fifo
|
// add symbol to fifo
|
||||||
enqueue(symbol_fifo, midi[i]);
|
enqueue(symbol_fifo, midi[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (space(symbol_fifo) > 3) {
|
if (space(symbol_fifo) > 3)
|
||||||
|
{
|
||||||
midi_send_ack(c_midi);
|
midi_send_ack(c_midi);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
midi_from_host_overflow = 1;
|
midi_from_host_overflow = 1;
|
||||||
}
|
}
|
||||||
// Drop through to the isTX guarded case
|
// Drop through to the isTX guarded case
|
||||||
if (!isTX) {
|
if (!isTX)
|
||||||
|
{
|
||||||
t :> txT; // Should be enough to trigger the other case
|
t :> txT; // Should be enough to trigger the other case
|
||||||
isTX = 1;
|
isTX = 1;
|
||||||
}
|
}
|
||||||
@@ -327,13 +351,24 @@ void usb_midi(in port ?p_midi_in, out port ?p_midi_out,
|
|||||||
break;
|
break;
|
||||||
#ifdef IAP
|
#ifdef IAP
|
||||||
case !(isTX || isRX) => iap_get_ack_or_reset_or_data(c_iap, is_ack, is_reset, datum):
|
case !(isTX || isRX) => iap_get_ack_or_reset_or_data(c_iap, is_ack, is_reset, datum):
|
||||||
|
|
||||||
|
/* Check for special case where MIDI ports are shared with i2c ports */
|
||||||
|
if(isnull(c_i2c) && isnull(p_scl) && isnull(p_sda))
|
||||||
|
{
|
||||||
|
handle_iap_case(is_ack, is_reset, datum, c_iap, c_i2c, p_midi_out, p_midi_in);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
handle_iap_case(is_ack, is_reset, datum, c_iap, c_i2c, p_scl, p_sda);
|
handle_iap_case(is_ack, is_reset, datum, c_iap, c_i2c, p_scl, p_sda);
|
||||||
|
}
|
||||||
if (!authenticating)
|
if (!authenticating)
|
||||||
{
|
{
|
||||||
// printstrln("Completed authentication");
|
// printstrln("Completed authentication");
|
||||||
p_midi_in :> void; // Change port around to input again after authenticating (unique to midi+iAP case)
|
p_midi_in :> void; // Change port around to input again after authenticating (unique to midi+iAP case)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Slow timer looking for IDevice plug/unplug event */
|
||||||
case iAPTimer when timerafter(polltime) :> void:
|
case iAPTimer when timerafter(polltime) :> void:
|
||||||
handle_poll_dev_det(iAPTimer);
|
handle_poll_dev_det(iAPTimer);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user