mirror of
https://github.com/hathach/tinyusb.git
synced 2026-03-12 10:34:48 +00:00
Merge branch 'master' into dwc2_deinit
This commit is contained in:
@ -168,6 +168,108 @@ uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, ui
|
||||
return total_read;
|
||||
}
|
||||
|
||||
// Note: this function shares stream->buffer with tud_midi_n_stream_read().
|
||||
// Do not mix calls to both functions on the same interface.
|
||||
uint32_t tud_midi_n_demux_stream_read(uint8_t itf, uint8_t *p_cable_num, void *buffer, uint32_t bufsize) {
|
||||
TU_VERIFY(p_cable_num != NULL && buffer != NULL && bufsize > 0, 0);
|
||||
|
||||
midid_interface_t *p_midi = &_midid_itf[itf];
|
||||
midi_driver_stream_t *stream = &p_midi->stream_read;
|
||||
tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx;
|
||||
|
||||
uint8_t *buf8 = (uint8_t *)buffer;
|
||||
uint32_t total_read = 0;
|
||||
|
||||
// Initialize to invalid cable so callers can detect "no data" even when
|
||||
// the return value is 0.
|
||||
*p_cable_num = 0xff;
|
||||
|
||||
// If there are leftover bytes from a previous partial read, return them first
|
||||
if (stream->total > 0) {
|
||||
*p_cable_num = (stream->buffer[0] >> 4) & 0x0f;
|
||||
const uint8_t count = (uint8_t)tu_min32((uint32_t)(stream->total - stream->index), bufsize);
|
||||
TU_VERIFY(0 == tu_memcpy_s(buf8, bufsize, stream->buffer + 1 + stream->index, count));
|
||||
|
||||
total_read += count;
|
||||
stream->index += count;
|
||||
buf8 += count;
|
||||
bufsize -= count;
|
||||
|
||||
if (stream->total == stream->index) {
|
||||
stream->index = 0;
|
||||
stream->total = 0;
|
||||
}
|
||||
|
||||
if (bufsize == 0) {
|
||||
return total_read;
|
||||
}
|
||||
}
|
||||
|
||||
while (bufsize > 0) {
|
||||
// Peek at next packet header to get cable number without consuming
|
||||
uint8_t one_byte;
|
||||
if (!tu_edpt_stream_peek(ep_str, &one_byte)) {
|
||||
break;
|
||||
}
|
||||
|
||||
const uint8_t next_cable = (one_byte >> 4) & 0x0f;
|
||||
|
||||
// Stop if cable changed (covers both leftover-originated reads and
|
||||
// freshly consumed packets — total_read > 0 in either case)
|
||||
if (total_read > 0 && next_cable != *p_cable_num) {
|
||||
break;
|
||||
}
|
||||
*p_cable_num = next_cable;
|
||||
|
||||
// Consume the packet
|
||||
if (!tud_midi_n_packet_read(itf, stream->buffer)) {
|
||||
break;
|
||||
}
|
||||
|
||||
const uint8_t code_index = stream->buffer[0] & 0x0f;
|
||||
uint8_t msg_bytes;
|
||||
|
||||
// MIDI 1.0 Table 4-1: Code Index Number Classifications
|
||||
switch (code_index) {
|
||||
case MIDI_CIN_MISC:
|
||||
case MIDI_CIN_CABLE_EVENT:
|
||||
// Reserved and unused, skip this packet
|
||||
continue;
|
||||
|
||||
case MIDI_CIN_SYSEX_END_1BYTE:
|
||||
case MIDI_CIN_1BYTE_DATA:
|
||||
msg_bytes = 1;
|
||||
break;
|
||||
|
||||
case MIDI_CIN_SYSCOM_2BYTE:
|
||||
case MIDI_CIN_SYSEX_END_2BYTE:
|
||||
case MIDI_CIN_PROGRAM_CHANGE:
|
||||
case MIDI_CIN_CHANNEL_PRESSURE:
|
||||
msg_bytes = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
msg_bytes = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
const uint8_t count = (uint8_t)tu_min32((uint32_t)msg_bytes, bufsize);
|
||||
TU_VERIFY(0 == tu_memcpy_s(buf8, bufsize, stream->buffer + 1, count));
|
||||
|
||||
total_read += count;
|
||||
buf8 += count;
|
||||
bufsize -= count;
|
||||
|
||||
if (count < msg_bytes) {
|
||||
// Output buffer full, save remaining for next call
|
||||
stream->total = msg_bytes;
|
||||
stream->index = count;
|
||||
}
|
||||
}
|
||||
|
||||
return total_read;
|
||||
}
|
||||
|
||||
bool tud_midi_n_packet_read(uint8_t itf, uint8_t packet[4]) {
|
||||
midid_interface_t *p_midi = &_midid_itf[itf];
|
||||
tu_edpt_stream_t *ep_str = &p_midi->ep_stream.rx;
|
||||
|
||||
@ -66,6 +66,13 @@ uint32_t tud_midi_n_available(uint8_t itf, uint8_t cable_num);
|
||||
// Read byte stream (legacy)
|
||||
uint32_t tud_midi_n_stream_read(uint8_t itf, uint8_t cable_num, void *buffer, uint32_t bufsize);
|
||||
|
||||
// Read byte stream with cable demultiplexing: returns the cable number of the
|
||||
// data that was read. Reads from a single cable per call; stops when the next
|
||||
// packet belongs to a different cable so the caller can dispatch per-cable.
|
||||
// Note: shares internal state with tud_midi_n_stream_read(); do not mix both
|
||||
// on the same interface.
|
||||
uint32_t tud_midi_n_demux_stream_read(uint8_t itf, uint8_t *p_cable_num, void *buffer, uint32_t bufsize);
|
||||
|
||||
// Write byte Stream (legacy)
|
||||
uint32_t tud_midi_n_stream_write(uint8_t itf, uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize);
|
||||
|
||||
@ -96,6 +103,11 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_midi_stream_read(void *buffer,
|
||||
return tud_midi_n_stream_read(0, 0, buffer, bufsize);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t
|
||||
tud_midi_demux_stream_read(uint8_t *p_cable_num, void *buffer, uint32_t bufsize) {
|
||||
return tud_midi_n_demux_stream_read(0, p_cable_num, buffer, bufsize);
|
||||
}
|
||||
|
||||
TU_ATTR_ALWAYS_INLINE static inline uint32_t
|
||||
tud_midi_stream_write(uint8_t cable_num, const uint8_t *buffer, uint32_t bufsize) {
|
||||
return tud_midi_n_stream_write(0, cable_num, buffer, bufsize);
|
||||
|
||||
@ -539,34 +539,38 @@ void dcd_remote_wakeup(uint8_t rhport) {
|
||||
}
|
||||
|
||||
void dcd_connect(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
|
||||
|
||||
#ifdef TUP_USBIP_DWC2_ESP32
|
||||
usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf;
|
||||
conf.pad_pull_override = 0;
|
||||
conf.dp_pullup = 0;
|
||||
conf.dp_pulldown = 0;
|
||||
conf.dm_pullup = 0;
|
||||
conf.dm_pulldown = 0;
|
||||
USB_WRAP.otg_conf = conf;
|
||||
// On ESP32-P4 HS PHY, do not write to USB_WRAP register which belongs to FS PHY
|
||||
if (rhport == 0) {
|
||||
usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf;
|
||||
conf.pad_pull_override = 0;
|
||||
conf.dp_pullup = 0;
|
||||
conf.dp_pulldown = 0;
|
||||
conf.dm_pullup = 0;
|
||||
conf.dm_pulldown = 0;
|
||||
USB_WRAP.otg_conf = conf;
|
||||
}
|
||||
#endif
|
||||
|
||||
dwc2->dctl &= ~DCTL_SDIS;
|
||||
}
|
||||
|
||||
void dcd_disconnect(uint8_t rhport) {
|
||||
(void) rhport;
|
||||
dwc2_regs_t* dwc2 = DWC2_REG(rhport);
|
||||
|
||||
#ifdef TUP_USBIP_DWC2_ESP32
|
||||
usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf;
|
||||
conf.pad_pull_override = 1;
|
||||
conf.dp_pullup = 0;
|
||||
conf.dp_pulldown = 1;
|
||||
conf.dm_pullup = 0;
|
||||
conf.dm_pulldown = 1;
|
||||
USB_WRAP.otg_conf = conf;
|
||||
// On ESP32-P4 HS PHY, do not write to USB_WRAP register which belongs to FS PHY
|
||||
if (rhport == 0) {
|
||||
usb_wrap_otg_conf_reg_t conf = USB_WRAP.otg_conf;
|
||||
conf.pad_pull_override = 1;
|
||||
conf.dp_pullup = 0;
|
||||
conf.dp_pulldown = 1;
|
||||
conf.dm_pullup = 0;
|
||||
conf.dm_pulldown = 1;
|
||||
USB_WRAP.otg_conf = conf;
|
||||
}
|
||||
#endif
|
||||
|
||||
dwc2->dctl |= DCTL_SDIS;
|
||||
|
||||
Reference in New Issue
Block a user