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

volatile uint8_t usb_configuration = 0; // non-zero when USB host as configured device 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 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 endpoint0_buffer[8];
static uint8_t sof_usage = 0;
static uint8_t usb_reboot_timer = 0; static uint8_t usb_reboot_timer = 0;


extern uint8_t usb_descriptor_buffer[]; // defined in usb_desc.c extern uint8_t usb_descriptor_buffer[]; // defined in usb_desc.c
printf("sof %d\n", usb_reboot_timer); printf("sof %d\n", usb_reboot_timer);
if (usb_reboot_timer) { if (usb_reboot_timer) {
if (--usb_reboot_timer == 0) { if (--usb_reboot_timer == 0) {
usb_stop_sof_interrupts(NUM_INTERFACE);
asm("bkpt #251"); // run bootloader 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 struct transfer_struct { // table 55-60, pg 3159
uint32_t next; uint32_t next;
memcpy(usb_cdc_line_coding, endpoint0_buffer, 7); memcpy(usb_cdc_line_coding, endpoint0_buffer, 7);
printf("usb_cdc_line_coding, baud=%u\n", usb_cdc_line_coding[0]); printf("usb_cdc_line_coding, baud=%u\n", usb_cdc_line_coding[0]);
if (usb_cdc_line_coding[0] == 134) { 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 usb_reboot_timer = 80; // TODO: 10 if only 12 Mbit/sec
} }
} }
&& endpoint0_buffer[0] == 0xA9 && endpoint0_buffer[1] == 0x45 && endpoint0_buffer[0] == 0xA9 && endpoint0_buffer[1] == 0x45
&& endpoint0_buffer[2] == 0xC2 && endpoint0_buffer[3] == 0x6B) { && endpoint0_buffer[2] == 0xC2 && endpoint0_buffer[3] == 0x6B) {
printf("seremu reboot request\n"); 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 usb_reboot_timer = 80; // TODO: 10 if only 12 Mbit/sec
} }
#endif #endif

+ 1
- 1
teensy4/usb_desc.c View File





__attribute__ ((section(".dmabuffers"), aligned(32))) __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

void usb_receive(int endpoint_number, transfer_t *transfer); void usb_receive(int endpoint_number, transfer_t *transfer);
uint32_t usb_transfer_status(const 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_timer0_callback)(void);
extern void (*usb_timer1_callback)(void); extern void (*usb_timer1_callback)(void);



+ 9
- 4
teensy4/usb_midi.c View File

rx_tail = 0; rx_tail = 0;
rx_available = 0; rx_available = 0;
usb_config_rx(MIDI_RX_ENDPOINT, rx_packet_size, 0, rx_event); 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); //for (i=0; i < RX_NUM; i++) rx_queue_transfer(i);
// TODO: set up SOF interrupt.... // TODO: set up SOF interrupt....
transmit_previous_timeout = 0; transmit_previous_timeout = 0;
usb_transmit(MIDI_TX_ENDPOINT, xfer); usb_transmit(MIDI_TX_ENDPOINT, xfer);
if (++head >= TX_NUM) head = 0; if (++head >= TX_NUM) head = 0;
tx_head = head; tx_head = head;
usb_stop_sof_interrupts(MIDI_INTERFACE);
} else {
usb_start_sof_interrupts(MIDI_INTERFACE);
} }
tx_noautoflush = 0; tx_noautoflush = 0;
} }


void usb_midi_flush_output(void) 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) { if (tx_noautoflush == 0 && tx_available > 0) {
printf(" tx, %d %d\n", tx_packet_size, tx_available); printf(" tx, %d %d\n", tx_packet_size, tx_available);
uint32_t head = tx_head; uint32_t head = tx_head;
if (++head >= TX_NUM) head = 0; if (++head >= TX_NUM) head = 0;
tx_head = head; tx_head = head;
tx_available = 0; tx_available = 0;
usb_stop_sof_interrupts(MIDI_INTERFACE);
} }
} }




int usb_midi_read(uint32_t channel) 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; return 0;
#if 0 #if 0

Loading…
Cancel
Save