1use super::Request;
2use super::DAP1_PACKET_SIZE;
3use usb_device::class_prelude::*;
4use usb_device::control::{Recipient, RequestType};
5use usb_device::{device, Result};
6
7const INTERFACE_CLASS_HID: u8 = 0x03;
8
9#[derive(Debug, Clone, Copy)]
10#[repr(u8)]
11pub enum DescriptorType {
12 Hid = 0x21,
13 Report = 0x22,
14}
15
16const REPORT_DESCRIPTOR: &[u8] = &[
17 0x06, 0x00, 0xFF, 0x09, 0x01, 0xA1, 0x01, 0x15, 0x00, 0x25, 0xFF, 0x75, 0x08, 0x95, 0x40, 0x09, 0x01, 0x81, 0x02, 0x95, 0x40, 0x09, 0x01, 0x91,
29 0x02, 0x95, 0x01, 0x09, 0x01, 0xB1,
33 0x02, 0xC0, ];
38
39pub struct CmsisDapV1<'a, B: UsbBus> {
40 interface: InterfaceNumber,
41 name: StringIndex,
42 read_ep: EndpointOut<'a, B>,
43 write_ep: EndpointIn<'a, B>,
44}
45
46impl<B: UsbBus> CmsisDapV1<'_, B> {
47 pub fn new(max_packet_size: u16, alloc: &UsbBusAllocator<B>) -> CmsisDapV1<B> {
48 CmsisDapV1 {
49 interface: alloc.interface(),
50 name: alloc.string(),
51 read_ep: alloc.interrupt(max_packet_size, 1),
52 write_ep: alloc.interrupt(max_packet_size, 1),
53 }
54 }
55
56 pub fn process(&mut self) -> Option<Request> {
57 let mut buf = [0u8; DAP1_PACKET_SIZE as usize];
58 match self.read_ep.read(&mut buf) {
59 Ok(size) if size > 0 => Some(Request::DAP1Command((buf, size))),
60 _ => None,
61 }
62 }
63
64 pub fn write_packet(&mut self, data: &[u8]) -> Result<()> {
65 if data.len() > self.write_ep.max_packet_size() as usize {
66 return Err(UsbError::BufferOverflow);
67 }
68 self.write_ep.write(&data).map(|_| ())
69 }
70}
71
72impl<B: UsbBus> UsbClass<B> for CmsisDapV1<'_, B> {
73 fn get_configuration_descriptors(&self, writer: &mut DescriptorWriter) -> Result<()> {
74 writer.interface_alt(
75 self.interface,
76 device::DEFAULT_ALTERNATE_SETTING,
77 INTERFACE_CLASS_HID,
78 0,
79 0,
80 Some(self.name),
81 )?;
82
83 let descriptor_len = REPORT_DESCRIPTOR.len();
84 if descriptor_len > u16::max_value() as usize {
85 return Err(UsbError::InvalidState);
86 }
87 let descriptor_len = (descriptor_len as u16).to_le_bytes();
88 writer.write(
89 DescriptorType::Hid as u8,
90 &[
91 0x11, 0x01, 0x00, 0x01, DescriptorType::Report as u8, descriptor_len[0], descriptor_len[1], ],
99 )?;
100
101 writer.endpoint(&self.read_ep)?;
102 writer.endpoint(&self.write_ep)?;
103
104 Ok(())
105 }
106
107 fn get_string(&self, index: StringIndex, _lang_id: LangID) -> Option<&str> {
108 if index == self.name {
109 Some("CMSIS-DAP v1 Interface")
110 } else {
111 None
112 }
113 }
114
115 fn control_in(&mut self, xfer: ControlIn<B>) {
116 let req = xfer.request();
117 if !(req.request_type == RequestType::Standard
118 && req.recipient == Recipient::Interface
119 && req.index == u8::from(self.interface) as u16)
120 {
121 return;
122 }
123
124 if req.request == control::Request::GET_DESCRIPTOR {
125 let (dtype, index) = req.descriptor_type_index();
126 if dtype == DescriptorType::Report as u8 && index == 0 {
127 xfer.accept_with(REPORT_DESCRIPTOR).ok();
128 }
129 }
130 }
131}