esp_idf_hal/
usb_serial.rs1#![allow(non_camel_case_types)]
5
6use core::marker::PhantomData;
7
8use crate::io::EspIOError;
9use crate::sys::{
10 esp, usb_serial_jtag_driver_config_t, usb_serial_jtag_driver_install,
11 usb_serial_jtag_driver_uninstall, usb_serial_jtag_is_connected, usb_serial_jtag_read_bytes,
12 usb_serial_jtag_write_bytes, EspError, TickType_t,
13};
14use crate::{delay, gpio};
15
16pub type UsbSerialConfig = config::Config;
18
19#[cfg(esp32c3)]
21pub type UsbDMinGpio<'d> = gpio::Gpio18<'d>;
22#[cfg(esp32c3)]
24pub type UsbDPlusGpio<'d> = gpio::Gpio19<'d>;
25#[cfg(esp32c5)]
27pub type UsbDMinGpio<'d> = gpio::Gpio13<'d>;
28#[cfg(esp32c5)]
30pub type UsbDPlusGpio<'d> = gpio::Gpio14<'d>;
31#[cfg(any(esp32c6, esp32c61))]
33pub type UsbDMinGpio<'d> = gpio::Gpio12<'d>;
34#[cfg(any(esp32c6, esp32c61))]
36pub type UsbDPlusGpio<'d> = gpio::Gpio13<'d>;
37#[cfg(esp32h2)]
39pub type UsbDMinGpio<'d> = gpio::Gpio26<'d>;
40#[cfg(esp32h2)]
42pub type UsbDPlusGpio<'d> = gpio::Gpio27<'d>;
43#[cfg(esp32p4)]
45pub type UsbDMinGpio<'d> = gpio::Gpio24<'d>;
46#[cfg(esp32p4)]
48pub type UsbDPlusGpio<'d> = gpio::Gpio25<'d>;
49#[cfg(esp32s3)]
56pub type UsbDMinGpio<'d> = gpio::Gpio19<'d>;
57#[cfg(esp32s3)]
59pub type UsbDPlusGpio<'d> = gpio::Gpio20<'d>;
60
61pub mod config {
63 #[derive(Debug, Clone)]
65 #[non_exhaustive]
66 pub struct Config {
67 pub tx_buffer_size: usize,
68 pub rx_buffer_size: usize,
69 }
70
71 impl Config {
72 pub const fn new() -> Self {
74 Self {
75 tx_buffer_size: 256,
76 rx_buffer_size: 256,
77 }
78 }
79
80 #[must_use]
82 pub fn tx_buffer_size(mut self, tx_buffer_size: usize) -> Self {
83 self.tx_buffer_size = tx_buffer_size;
84 self
85 }
86
87 #[must_use]
89 pub fn rx_buffer_size(mut self, rx_buffer_size: usize) -> Self {
90 self.rx_buffer_size = rx_buffer_size;
91 self
92 }
93 }
94
95 impl Default for Config {
96 fn default() -> Self {
97 Self::new()
98 }
99 }
100}
101
102pub struct UsbSerialDriver<'d>(PhantomData<&'d mut ()>);
104
105impl<'d> UsbSerialDriver<'d> {
106 pub fn new(
114 _usb_serial: USB_SERIAL<'d>,
115 _usb_d_min: UsbDMinGpio<'d>,
116 _usb_d_plus: UsbDPlusGpio<'d>,
117 config: &config::Config,
118 ) -> Result<Self, EspError> {
119 #[allow(clippy::needless_update)]
120 let mut config = usb_serial_jtag_driver_config_t {
121 tx_buffer_size: config.tx_buffer_size as _,
122 rx_buffer_size: config.rx_buffer_size as _,
123 ..Default::default()
124 };
125
126 esp!(unsafe { usb_serial_jtag_driver_install(&mut config) })?;
127
128 Ok(Self(PhantomData))
129 }
130
131 pub fn is_connected(&self) -> bool {
133 unsafe { usb_serial_jtag_is_connected() }
134 }
135
136 pub fn read(&mut self, buf: &mut [u8], timeout: TickType_t) -> Result<usize, EspError> {
145 let len = unsafe {
146 usb_serial_jtag_read_bytes(buf.as_mut_ptr() as *mut _, buf.len() as _, timeout)
147 };
148
149 Ok(len as _)
150 }
151
152 pub fn write(&mut self, bytes: &[u8], timeout: TickType_t) -> Result<usize, EspError> {
161 let len = unsafe {
162 usb_serial_jtag_write_bytes(bytes.as_ptr() as *const _, bytes.len() as _, timeout)
163 };
164
165 Ok(len as _)
166 }
167}
168
169impl Drop for UsbSerialDriver<'_> {
170 fn drop(&mut self) {
171 esp!(unsafe { usb_serial_jtag_driver_uninstall() }).unwrap();
172 }
173}
174
175unsafe impl Send for UsbSerialDriver<'_> {}
176
177impl embedded_io::ErrorType for UsbSerialDriver<'_> {
178 type Error = EspIOError;
179}
180
181impl embedded_io::Read for UsbSerialDriver<'_> {
182 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
183 UsbSerialDriver::read(self, buf, delay::BLOCK).map_err(EspIOError)
184 }
185}
186
187impl embedded_io::Write for UsbSerialDriver<'_> {
188 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
189 UsbSerialDriver::write(self, buf, delay::BLOCK).map_err(EspIOError)
190 }
191
192 fn flush(&mut self) -> Result<(), Self::Error> {
193 Ok(())
194 }
195}
196
197impl embedded_hal_0_2::serial::Write<u8> for UsbSerialDriver<'_> {
198 type Error = EspError;
199
200 fn flush(&mut self) -> nb::Result<(), Self::Error> {
201 Ok(())
202 }
203
204 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
205 UsbSerialDriver::write(self, &[byte], delay::BLOCK)?;
206
207 Ok(())
208 }
209}
210
211impl core::fmt::Write for UsbSerialDriver<'_> {
212 fn write_str(&mut self, s: &str) -> core::fmt::Result {
213 let buf = s.as_bytes();
214 let mut offset = 0;
215
216 while offset < buf.len() {
217 offset += self
218 .write(buf, delay::BLOCK)
219 .map_err(|_| core::fmt::Error)?
220 }
221
222 Ok(())
223 }
224}
225
226crate::impl_peripheral!(USB_SERIAL);