Browse Source

T4 USB MIDI auto flush output at start of microframe

teensy4-core
PaulStoffregen 5 years ago
parent
commit
41cec678f2
4 changed files with 43 additions and 10 deletions
  1. +30
    -5
      teensy4/usb.c
  2. +1
    -1
      teensy4/usb_desc.c
  3. +3
    -0
      teensy4/usb_dev.h
  4. +9
    -4
      teensy4/usb_midi.c

+ 30
- 5
teensy4/usb.c View File

@@ -85,6 +85,7 @@ static uint32_t endpointN_notify_mask=0;
volatile uint8_t usb_configuration = 0; // non-zero when USB host as configured device
volatile uint8_t usb_high_speed = 0; // non-zero if running at 480 Mbit/sec speed
static uint8_t endpoint0_buffer[8];
static uint8_t sof_usage = 0;
static uint8_t usb_reboot_timer = 0;

extern uint8_t usb_descriptor_buffer[]; // defined in usb_desc.c
@@ -303,16 +304,40 @@ static void isr(void)
printf("sof %d\n", usb_reboot_timer);
if (usb_reboot_timer) {
if (--usb_reboot_timer == 0) {
usb_stop_sof_interrupts(NUM_INTERFACE);
asm("bkpt #251"); // run bootloader
}
} else {
// turn off the SOF interrupt if nothing using it
USB1_USBINTR &= ~USB_USBINTR_SRE;
}
#ifdef MIDI_INTERFACE
usb_midi_flush_output();
#endif
}
}


void usb_start_sof_interrupts(int interface)
{
__disable_irq();
sof_usage |= (1 << interface);
uint32_t intr = USB1_USBINTR;
if (!(intr & USB_USBINTR_SRE)) {
USB1_USBSTS = USB_USBSTS_SRI; // clear prior SOF before SOF IRQ enable
USB1_USBINTR = intr | USB_USBINTR_SRE;
}
__enable_irq();
}

void usb_stop_sof_interrupts(int interface)
{
sof_usage &= ~(1 << interface);
if (sof_usage == 0) {
USB1_USBINTR &= ~USB_USBINTR_SRE;
}
}




/*
struct transfer_struct { // table 55-60, pg 3159
uint32_t next;
@@ -587,7 +612,7 @@ static void endpoint0_complete(void)
memcpy(usb_cdc_line_coding, endpoint0_buffer, 7);
printf("usb_cdc_line_coding, baud=%u\n", usb_cdc_line_coding[0]);
if (usb_cdc_line_coding[0] == 134) {
USB1_USBINTR |= USB_USBINTR_SRE;
usb_start_sof_interrupts(NUM_INTERFACE);
usb_reboot_timer = 80; // TODO: 10 if only 12 Mbit/sec
}
}
@@ -597,7 +622,7 @@ static void endpoint0_complete(void)
&& endpoint0_buffer[0] == 0xA9 && endpoint0_buffer[1] == 0x45
&& endpoint0_buffer[2] == 0xC2 && endpoint0_buffer[3] == 0x6B) {
printf("seremu reboot request\n");
USB1_USBINTR |= USB_USBINTR_SRE;
usb_start_sof_interrupts(NUM_INTERFACE);
usb_reboot_timer = 80; // TODO: 10 if only 12 Mbit/sec
}
#endif

+ 1
- 1
teensy4/usb_desc.c View File

@@ -2269,7 +2269,7 @@ PROGMEM const uint8_t usb_config_descriptor_12[CONFIG_DESC_SIZE] = {


__attribute__ ((section(".dmabuffers"), aligned(32)))
uint8_t usb_descriptor_buffer[CONFIG_DESC_SIZE + 4096];
uint8_t usb_descriptor_buffer[CONFIG_DESC_SIZE];




+ 3
- 0
teensy4/usb_dev.h View File

@@ -24,6 +24,9 @@ void usb_transmit(int endpoint_number, transfer_t *transfer);
void usb_receive(int endpoint_number, transfer_t *transfer);
uint32_t usb_transfer_status(const transfer_t *transfer);

void usb_start_sof_interrupts(int interface);
void usb_stop_sof_interrupts(int interface);

extern void (*usb_timer0_callback)(void);
extern void (*usb_timer1_callback)(void);


+ 9
- 4
teensy4/usb_midi.c View File

@@ -117,8 +117,8 @@ void usb_midi_configure(void)
rx_tail = 0;
rx_available = 0;
usb_config_rx(MIDI_RX_ENDPOINT, rx_packet_size, 0, rx_event);
usb_config_tx(MIDI_TX_ENDPOINT, tx_packet_size, 1, NULL);
int i;
usb_config_tx(MIDI_TX_ENDPOINT, tx_packet_size, 0, NULL); // TODO: is ZLP needed?
//int i;
//for (i=0; i < RX_NUM; i++) rx_queue_transfer(i);
// TODO: set up SOF interrupt....
transmit_previous_timeout = 0;
@@ -166,13 +166,16 @@ void usb_midi_write_packed(uint32_t n)
usb_transmit(MIDI_TX_ENDPOINT, xfer);
if (++head >= TX_NUM) head = 0;
tx_head = head;
usb_stop_sof_interrupts(MIDI_INTERFACE);
} else {
usb_start_sof_interrupts(MIDI_INTERFACE);
}
tx_noautoflush = 0;
}

void usb_midi_flush_output(void)
{
printf("usb_midi_flush_output\n");
//printf("usb_midi_flush_output\n");
if (tx_noautoflush == 0 && tx_available > 0) {
printf(" tx, %d %d\n", tx_packet_size, tx_available);
uint32_t head = tx_head;
@@ -185,6 +188,7 @@ void usb_midi_flush_output(void)
if (++head >= TX_NUM) head = 0;
tx_head = head;
tx_available = 0;
usb_stop_sof_interrupts(MIDI_INTERFACE);
}
}

@@ -305,7 +309,8 @@ uint32_t usb_midi_read_message(void)

int usb_midi_read(uint32_t channel)
{
uint32_t n, index, ch, type1, type2, b1;
//uint32_t n, index, ch, type1, type2, b1;
uint32_t n, ch, type1, type2, b1;
return 0;
#if 0

Loading…
Cancel
Save