dap_rs/usb/
dap_v2.rs

1use super::Request;
2use super::DAP2_PACKET_SIZE;
3use usb_device::class_prelude::*;
4use usb_device::Result;
5
6pub struct CmsisDapV2<'a, B: UsbBus> {
7    interface: InterfaceNumber,
8    name: StringIndex,
9    read_ep: EndpointOut<'a, B>,
10    write_ep: EndpointIn<'a, B>,
11    trace_ep: EndpointIn<'a, B>,
12    trace_busy: bool,
13}
14
15impl<B: UsbBus> CmsisDapV2<'_, B> {
16    pub fn new(max_packet_size: u16, alloc: &UsbBusAllocator<B>) -> CmsisDapV2<B> {
17        CmsisDapV2 {
18            interface: alloc.interface(),
19            name: alloc.string(),
20            read_ep: alloc.bulk(max_packet_size),
21            write_ep: alloc.bulk(max_packet_size),
22            trace_ep: alloc.bulk(max_packet_size),
23            trace_busy: false,
24        }
25    }
26
27    pub fn process(&mut self) -> Option<Request> {
28        let mut buf = [0u8; DAP2_PACKET_SIZE as usize];
29        match self.read_ep.read(&mut buf) {
30            Ok(size) if size > 0 => Some(Request::DAP2Command((buf, size))),
31            _ => None,
32        }
33    }
34
35    pub fn write_packet(&mut self, data: &[u8]) -> Result<()> {
36        if data.len() > self.write_ep.max_packet_size() as usize {
37            return Err(UsbError::BufferOverflow);
38        }
39        self.write_ep.write(&data).map(|_| ())
40    }
41
42    pub fn trace_busy(&self) -> bool {
43        self.trace_busy
44    }
45
46    pub fn trace_write(&mut self, data: &[u8]) -> Result<()> {
47        if data.len() > self.trace_ep.max_packet_size() as usize {
48            return Err(UsbError::BufferOverflow);
49        }
50        self.trace_ep.write(&data).map(|_| ())?;
51        self.trace_busy = true;
52        Ok(())
53    }
54}
55
56impl<B: UsbBus> UsbClass<B> for CmsisDapV2<'_, B> {
57    fn get_configuration_descriptors(&self, writer: &mut DescriptorWriter) -> Result<()> {
58        writer.interface_alt(self.interface, 0, 0xff, 0, 0, Some(self.name))?;
59
60        writer.endpoint(&self.read_ep)?;
61        writer.endpoint(&self.write_ep)?;
62        writer.endpoint(&self.trace_ep)?;
63
64        Ok(())
65    }
66
67    fn get_string(&self, index: StringIndex, _lang_id: LangID) -> Option<&str> {
68        if index == self.name {
69            Some("CMSIS-DAP v2 Interface")
70        } else {
71            None
72        }
73    }
74
75    fn reset(&mut self) {
76        self.trace_busy = false;
77    }
78
79    fn endpoint_in_complete(&mut self, addr: EndpointAddress) {
80        if addr == self.trace_ep.address() {
81            self.trace_busy = false;
82        }
83    }
84}