From b0eacf0eecbef48ac526da6bce250189e4999ce5 Mon Sep 17 00:00:00 2001 From: Dániel Buga Date: Thu, 17 Apr 2025 22:29:15 +0200 Subject: Add optional trace endpoint --- embassy-usb/src/class/cmsis_dap_v2.rs | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'embassy-usb') diff --git a/embassy-usb/src/class/cmsis_dap_v2.rs b/embassy-usb/src/class/cmsis_dap_v2.rs index 41f6be5dd..a94e3ddb7 100644 --- a/embassy-usb/src/class/cmsis_dap_v2.rs +++ b/embassy-usb/src/class/cmsis_dap_v2.rs @@ -39,13 +39,17 @@ impl State { pub struct CmsisDapV2Class<'d, D: Driver<'d>> { read_ep: D::EndpointOut, write_ep: D::EndpointIn, + trace_ep: Option, max_packet_size: u16, } impl<'d, D: Driver<'d>> CmsisDapV2Class<'d, D> { /// Creates a new CmsisDapV2Class with the provided UsbBus and `max_packet_size` in bytes. For /// full-speed devices, `max_packet_size` has to be 64. - pub fn new(builder: &mut Builder<'d, D>, state: &'d mut State, max_packet_size: u16) -> Self { + /// + /// The `trace` parameter enables the trace output endpoint. This is optional and can be + /// disabled if the probe does not support trace output. + pub fn new(builder: &mut Builder<'d, D>, state: &'d mut State, max_packet_size: u16, trace: bool) -> Self { // DAP - Custom Class 0 let iface_string = builder.string(); let mut function = builder.function(0xFF, 0, 0); @@ -59,6 +63,11 @@ impl<'d, D: Driver<'d>> CmsisDapV2Class<'d, D> { let mut alt = interface.alt_setting(0xFF, 0, 0, Some(iface_string)); let read_ep = alt.endpoint_bulk_out(max_packet_size); let write_ep = alt.endpoint_bulk_in(max_packet_size); + let trace_ep = if trace { + Some(alt.endpoint_bulk_in(max_packet_size)) + } else { + None + }; drop(function); builder.handler(state.control.write(Control { iface_string })); @@ -66,6 +75,7 @@ impl<'d, D: Driver<'d>> CmsisDapV2Class<'d, D> { CmsisDapV2Class { read_ep, write_ep, + trace_ep, max_packet_size, } } @@ -86,6 +96,23 @@ impl<'d, D: Driver<'d>> CmsisDapV2Class<'d, D> { Ok(()) } + /// Write data to the host via the trace output endpoint. + /// + /// Returns `EndpointError::Disabled` if the trace output endpoint is not enabled. + pub async fn write_trace(&mut self, data: &[u8]) -> Result<(), EndpointError> { + let Some(ep) = self.trace_ep.as_mut() else { + return Err(EndpointError::Disabled); + }; + + for chunk in data.chunks(self.max_packet_size as usize) { + ep.write(chunk).await?; + } + if data.len() % self.max_packet_size as usize == 0 { + ep.write(&[]).await?; + } + Ok(()) + } + /// Read data from the host. pub async fn read_packet(&mut self, data: &mut [u8]) -> Result { let mut n = 0; -- cgit