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 let mut config = usb_serial_jtag_driver_config_t {
120 tx_buffer_size: config.tx_buffer_size as _,
121 rx_buffer_size: config.rx_buffer_size as _,
122 };
123
124 esp!(unsafe { usb_serial_jtag_driver_install(&mut config) })?;
125
126 Ok(Self(PhantomData))
127 }
128
129 pub fn is_connected(&self) -> bool {
131 unsafe { usb_serial_jtag_is_connected() }
132 }
133
134 pub fn read(&mut self, buf: &mut [u8], timeout: TickType_t) -> Result<usize, EspError> {
143 let len = unsafe {
144 usb_serial_jtag_read_bytes(buf.as_mut_ptr() as *mut _, buf.len() as _, timeout)
145 };
146
147 Ok(len as _)
148 }
149
150 pub fn write(&mut self, bytes: &[u8], timeout: TickType_t) -> Result<usize, EspError> {
159 let len = unsafe {
160 usb_serial_jtag_write_bytes(bytes.as_ptr() as *const _, bytes.len() as _, timeout)
161 };
162
163 Ok(len as _)
164 }
165}
166
167impl Drop for UsbSerialDriver<'_> {
168 fn drop(&mut self) {
169 esp!(unsafe { usb_serial_jtag_driver_uninstall() }).unwrap();
170 }
171}
172
173unsafe impl Send for UsbSerialDriver<'_> {}
174
175impl embedded_io::ErrorType for UsbSerialDriver<'_> {
176 type Error = EspIOError;
177}
178
179impl embedded_io::Read for UsbSerialDriver<'_> {
180 fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
181 UsbSerialDriver::read(self, buf, delay::BLOCK).map_err(EspIOError)
182 }
183}
184
185impl embedded_io::Write for UsbSerialDriver<'_> {
186 fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
187 UsbSerialDriver::write(self, buf, delay::BLOCK).map_err(EspIOError)
188 }
189
190 fn flush(&mut self) -> Result<(), Self::Error> {
191 Ok(())
192 }
193}
194
195impl embedded_hal_0_2::serial::Write<u8> for UsbSerialDriver<'_> {
196 type Error = EspError;
197
198 fn flush(&mut self) -> nb::Result<(), Self::Error> {
199 Ok(())
200 }
201
202 fn write(&mut self, byte: u8) -> nb::Result<(), Self::Error> {
203 UsbSerialDriver::write(self, &[byte], delay::BLOCK)?;
204
205 Ok(())
206 }
207}
208
209impl core::fmt::Write for UsbSerialDriver<'_> {
210 fn write_str(&mut self, s: &str) -> core::fmt::Result {
211 let buf = s.as_bytes();
212 let mut offset = 0;
213
214 while offset < buf.len() {
215 offset += self
216 .write(buf, delay::BLOCK)
217 .map_err(|_| core::fmt::Error)?
218 }
219
220 Ok(())
221 }
222}
223
224crate::impl_peripheral!(USB_SERIAL);