aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf-examples/src/bin/uart.rs11
-rw-r--r--embassy-nrf/src/buffered_uarte.rs8
-rw-r--r--embassy-nrf/src/uarte.rs86
-rw-r--r--embassy-stm32/src/f4/serial.rs45
-rw-r--r--embassy-traits/src/uart.rs9
5 files changed, 72 insertions, 87 deletions
diff --git a/embassy-nrf-examples/src/bin/uart.rs b/embassy-nrf-examples/src/bin/uart.rs
index b3d32814b..23fc89312 100644
--- a/embassy-nrf-examples/src/bin/uart.rs
+++ b/embassy-nrf-examples/src/bin/uart.rs
@@ -15,7 +15,6 @@ use embassy::traits::uart::{Read, Write};
15use embassy::util::Steal; 15use embassy::util::Steal;
16use embassy_nrf::gpio::NoPin; 16use embassy_nrf::gpio::NoPin;
17use embassy_nrf::{interrupt, uarte, Peripherals}; 17use embassy_nrf::{interrupt, uarte, Peripherals};
18use futures::pin_mut;
19 18
20#[embassy::main] 19#[embassy::main]
21async fn main(spawner: Spawner) { 20async fn main(spawner: Spawner) {
@@ -26,8 +25,8 @@ async fn main(spawner: Spawner) {
26 config.baudrate = uarte::Baudrate::BAUD115200; 25 config.baudrate = uarte::Baudrate::BAUD115200;
27 26
28 let irq = interrupt::take!(UARTE0_UART0); 27 let irq = interrupt::take!(UARTE0_UART0);
29 let uart = unsafe { uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, NoPin, NoPin, config) }; 28 let mut uart =
30 pin_mut!(uart); 29 unsafe { uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, NoPin, NoPin, config) };
31 30
32 info!("uarte initialized!"); 31 info!("uarte initialized!");
33 32
@@ -35,14 +34,14 @@ async fn main(spawner: Spawner) {
35 let mut buf = [0; 8]; 34 let mut buf = [0; 8];
36 buf.copy_from_slice(b"Hello!\r\n"); 35 buf.copy_from_slice(b"Hello!\r\n");
37 36
38 unwrap!(uart.as_mut().write(&buf).await); 37 unwrap!(uart.write(&buf).await);
39 info!("wrote hello in uart!"); 38 info!("wrote hello in uart!");
40 39
41 loop { 40 loop {
42 info!("reading..."); 41 info!("reading...");
43 unwrap!(uart.as_mut().read(&mut buf).await); 42 unwrap!(uart.read(&mut buf).await);
44 info!("writing..."); 43 info!("writing...");
45 unwrap!(uart.as_mut().write(&buf).await); 44 unwrap!(uart.write(&buf).await);
46 45
47 /* 46 /*
48 // `receive()` doesn't return until the buffer has been completely filled with 47 // `receive()` doesn't return until the buffer has been completely filled with
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index 702ccde0e..9e67aaef6 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -78,7 +78,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
78 ) -> Self { 78 ) -> Self {
79 unborrow!(uarte, timer, ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts); 79 unborrow!(uarte, timer, ppi_ch1, ppi_ch2, irq, rxd, txd, cts, rts);
80 80
81 let r = uarte.regs(); 81 let r = U::regs();
82 let rt = timer.regs(); 82 let rt = timer.regs();
83 83
84 rxd.conf().write(|w| w.input().connect().drive().h0h1()); 84 rxd.conf().write(|w| w.input().connect().drive().h0h1());
@@ -178,7 +178,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> {
178 178
179 pub fn set_baudrate(self: Pin<&mut Self>, baudrate: Baudrate) { 179 pub fn set_baudrate(self: Pin<&mut Self>, baudrate: Baudrate) {
180 self.inner().with(|state, _irq| { 180 self.inner().with(|state, _irq| {
181 let r = state.uarte.regs(); 181 let r = U::regs();
182 let rt = state.timer.regs(); 182 let rt = state.timer.regs();
183 183
184 let timeout = 0x8000_0000 / (baudrate as u32 / 40); 184 let timeout = 0x8000_0000 / (baudrate as u32 / 40);
@@ -265,7 +265,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> AsyncWrite for BufferedUarte<'d, U,
265 265
266impl<'a, U: UarteInstance, T: TimerInstance> Drop for State<'a, U, T> { 266impl<'a, U: UarteInstance, T: TimerInstance> Drop for State<'a, U, T> {
267 fn drop(&mut self) { 267 fn drop(&mut self) {
268 let r = self.uarte.regs(); 268 let r = U::regs();
269 let rt = self.timer.regs(); 269 let rt = self.timer.regs();
270 270
271 // TODO this probably deadlocks. do like Uarte instead. 271 // TODO this probably deadlocks. do like Uarte instead.
@@ -290,7 +290,7 @@ impl<'a, U: UarteInstance, T: TimerInstance> PeripheralState for State<'a, U, T>
290 type Interrupt = U::Interrupt; 290 type Interrupt = U::Interrupt;
291 fn on_interrupt(&mut self) { 291 fn on_interrupt(&mut self) {
292 trace!("irq: start"); 292 trace!("irq: start");
293 let r = self.uarte.regs(); 293 let r = U::regs();
294 let rt = self.timer.regs(); 294 let rt = self.timer.regs();
295 295
296 loop { 296 loop {
diff --git a/embassy-nrf/src/uarte.rs b/embassy-nrf/src/uarte.rs
index 957fa4c71..9e485907c 100644
--- a/embassy-nrf/src/uarte.rs
+++ b/embassy-nrf/src/uarte.rs
@@ -2,12 +2,11 @@
2 2
3use core::future::Future; 3use core::future::Future;
4use core::marker::PhantomData; 4use core::marker::PhantomData;
5use core::pin::Pin; 5use core::sync::atomic::{compiler_fence, Ordering};
6use core::sync::atomic::{compiler_fence, AtomicBool, Ordering};
7use core::task::Poll; 6use core::task::Poll;
7use embassy::interrupt::InterruptExt;
8use embassy::traits::uart::{Error, Read, Write}; 8use embassy::traits::uart::{Error, Read, Write};
9use embassy::util::{AtomicWaker, OnDrop, PeripheralBorrow}; 9use embassy::util::{AtomicWaker, OnDrop, PeripheralBorrow};
10use embassy_extras::peripheral_shared::{Peripheral, PeripheralState};
11use embassy_extras::unborrow; 10use embassy_extras::unborrow;
12use futures::future::poll_fn; 11use futures::future::poll_fn;
13 12
@@ -38,16 +37,9 @@ impl Default for Config {
38 } 37 }
39} 38}
40 39
41struct State<T: Instance> {
42 peri: T,
43
44 endrx_waker: AtomicWaker,
45 endtx_waker: AtomicWaker,
46}
47
48/// Interface to the UARTE peripheral 40/// Interface to the UARTE peripheral
49pub struct Uarte<'d, T: Instance> { 41pub struct Uarte<'d, T: Instance> {
50 inner: Peripheral<State<T>>, 42 peri: T,
51 phantom: PhantomData<&'d mut T>, 43 phantom: PhantomData<&'d mut T>,
52} 44}
53 45
@@ -72,7 +64,7 @@ impl<'d, T: Instance> Uarte<'d, T> {
72 ) -> Self { 64 ) -> Self {
73 unborrow!(uarte, irq, rxd, txd, cts, rts); 65 unborrow!(uarte, irq, rxd, txd, cts, rts);
74 66
75 let r = uarte.regs(); 67 let r = T::regs();
76 68
77 assert!(r.enable.read().enable().is_disabled()); 69 assert!(r.enable.read().enable().is_disabled());
78 70
@@ -115,38 +107,29 @@ impl<'d, T: Instance> Uarte<'d, T> {
115 r.events_rxstarted.reset(); 107 r.events_rxstarted.reset();
116 r.events_txstarted.reset(); 108 r.events_txstarted.reset();
117 109
110 irq.set_handler(Self::on_interrupt);
111 irq.unpend();
112 irq.enable();
113
118 // Enable 114 // Enable
119 r.enable.write(|w| w.enable().enabled()); 115 r.enable.write(|w| w.enable().enabled());
120 116
121 Self { 117 Self {
122 inner: Peripheral::new( 118 peri: uarte,
123 irq,
124 State {
125 peri: uarte,
126 endrx_waker: AtomicWaker::new(),
127 endtx_waker: AtomicWaker::new(),
128 },
129 ),
130 phantom: PhantomData, 119 phantom: PhantomData,
131 } 120 }
132 } 121 }
133 122
134 fn inner(self: Pin<&mut Self>) -> Pin<&mut Peripheral<State<T>>> { 123 fn on_interrupt(_: *mut ()) {
135 unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().inner) } 124 let r = T::regs();
136 } 125 let s = T::state();
137}
138
139impl<T: Instance> PeripheralState for State<T> {
140 type Interrupt = T::Interrupt;
141 126
142 fn on_interrupt(&self) {
143 let r = self.peri.regs();
144 if r.events_endrx.read().bits() != 0 { 127 if r.events_endrx.read().bits() != 0 {
145 self.endrx_waker.wake(); 128 s.endrx_waker.wake();
146 r.intenclr.write(|w| w.endrx().clear()); 129 r.intenclr.write(|w| w.endrx().clear());
147 } 130 }
148 if r.events_endtx.read().bits() != 0 { 131 if r.events_endtx.read().bits() != 0 {
149 self.endtx_waker.wake(); 132 s.endtx_waker.wake();
150 r.intenclr.write(|w| w.endtx().clear()); 133 r.intenclr.write(|w| w.endtx().clear());
151 } 134 }
152 135
@@ -163,8 +146,7 @@ impl<'a, T: Instance> Drop for Uarte<'a, T> {
163 fn drop(&mut self) { 146 fn drop(&mut self) {
164 info!("uarte drop"); 147 info!("uarte drop");
165 148
166 let s = unsafe { Pin::new_unchecked(&mut self.inner) }.state(); 149 let r = T::regs();
167 let r = s.peri.regs();
168 150
169 let did_stoprx = r.events_rxstarted.read().bits() != 0; 151 let did_stoprx = r.events_rxstarted.read().bits() != 0;
170 let did_stoptx = r.events_txstarted.read().bits() != 0; 152 let did_stoptx = r.events_txstarted.read().bits() != 0;
@@ -194,16 +176,14 @@ impl<'d, T: Instance> Read for Uarte<'d, T> {
194 #[rustfmt::skip] 176 #[rustfmt::skip]
195 type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a; 177 type ReadFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a;
196 178
197 fn read<'a>(mut self: Pin<&'a mut Self>, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> { 179 fn read<'a>(&'a mut self, rx_buffer: &'a mut [u8]) -> Self::ReadFuture<'a> {
198 self.as_mut().inner().register_interrupt();
199
200 async move { 180 async move {
201 let ptr = rx_buffer.as_ptr(); 181 let ptr = rx_buffer.as_ptr();
202 let len = rx_buffer.len(); 182 let len = rx_buffer.len();
203 assert!(len <= EASY_DMA_SIZE); 183 assert!(len <= EASY_DMA_SIZE);
204 184
205 let s = self.inner().state(); 185 let r = T::regs();
206 let r = s.peri.regs(); 186 let s = T::state();
207 187
208 let drop = OnDrop::new(move || { 188 let drop = OnDrop::new(move || {
209 info!("read drop: stopping"); 189 info!("read drop: stopping");
@@ -250,17 +230,15 @@ impl<'d, T: Instance> Write for Uarte<'d, T> {
250 #[rustfmt::skip] 230 #[rustfmt::skip]
251 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a; 231 type WriteFuture<'a> where Self: 'a = impl Future<Output = Result<(), Error>> + 'a;
252 232
253 fn write<'a>(mut self: Pin<&'a mut Self>, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> { 233 fn write<'a>(&'a mut self, tx_buffer: &'a [u8]) -> Self::WriteFuture<'a> {
254 self.as_mut().inner().register_interrupt();
255
256 async move { 234 async move {
257 let ptr = tx_buffer.as_ptr(); 235 let ptr = tx_buffer.as_ptr();
258 let len = tx_buffer.len(); 236 let len = tx_buffer.len();
259 assert!(len <= EASY_DMA_SIZE); 237 assert!(len <= EASY_DMA_SIZE);
260 // TODO: panic if buffer is not in SRAM 238 // TODO: panic if buffer is not in SRAM
261 239
262 let s = self.inner().state(); 240 let r = T::regs();
263 let r = s.peri.regs(); 241 let s = T::state();
264 242
265 let drop = OnDrop::new(move || { 243 let drop = OnDrop::new(move || {
266 info!("write drop: stopping"); 244 info!("write drop: stopping");
@@ -306,8 +284,22 @@ impl<'d, T: Instance> Write for Uarte<'d, T> {
306mod sealed { 284mod sealed {
307 use super::*; 285 use super::*;
308 286
287 pub struct State {
288 pub endrx_waker: AtomicWaker,
289 pub endtx_waker: AtomicWaker,
290 }
291 impl State {
292 pub const fn new() -> Self {
293 Self {
294 endrx_waker: AtomicWaker::new(),
295 endtx_waker: AtomicWaker::new(),
296 }
297 }
298 }
299
309 pub trait Instance { 300 pub trait Instance {
310 fn regs(&self) -> &pac::uarte0::RegisterBlock; 301 fn regs() -> &'static pac::uarte0::RegisterBlock;
302 fn state() -> &'static State;
311 } 303 }
312} 304}
313 305
@@ -318,9 +310,13 @@ pub trait Instance: sealed::Instance + 'static {
318macro_rules! impl_instance { 310macro_rules! impl_instance {
319 ($type:ident, $irq:ident) => { 311 ($type:ident, $irq:ident) => {
320 impl sealed::Instance for peripherals::$type { 312 impl sealed::Instance for peripherals::$type {
321 fn regs(&self) -> &pac::uarte0::RegisterBlock { 313 fn regs() -> &'static pac::uarte0::RegisterBlock {
322 unsafe { &*pac::$type::ptr() } 314 unsafe { &*pac::$type::ptr() }
323 } 315 }
316 fn state() -> &'static sealed::State {
317 static STATE: sealed::State = sealed::State::new();
318 &STATE
319 }
324 } 320 }
325 impl Instance for peripherals::$type { 321 impl Instance for peripherals::$type {
326 type Interrupt = interrupt::$irq; 322 type Interrupt = interrupt::$irq;
diff --git a/embassy-stm32/src/f4/serial.rs b/embassy-stm32/src/f4/serial.rs
index 7539abf51..78aaa8944 100644
--- a/embassy-stm32/src/f4/serial.rs
+++ b/embassy-stm32/src/f4/serial.rs
@@ -2,7 +2,6 @@
2 2
3use core::future::Future; 3use core::future::Future;
4use core::marker::PhantomData; 4use core::marker::PhantomData;
5use core::pin::Pin;
6use embassy::interrupt::Interrupt; 5use embassy::interrupt::Interrupt;
7use embassy::traits::uart::{Error, Read, ReadUntilIdle, Write}; 6use embassy::traits::uart::{Error, Read, ReadUntilIdle, Write};
8use embassy::util::InterruptFuture; 7use embassy::util::InterruptFuture;
@@ -101,13 +100,12 @@ where
101 /// Receives serial data. 100 /// Receives serial data.
102 /// 101 ///
103 /// The future is pending until the buffer is completely filled. 102 /// The future is pending until the buffer is completely filled.
104 fn read<'a>(self: Pin<&'a mut Self>, buf: &'a mut [u8]) -> Self::ReadFuture<'a> { 103 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a> {
105 let this = unsafe { self.get_unchecked_mut() };
106 let static_buf = unsafe { core::mem::transmute::<&'a mut [u8], &'static mut [u8]>(buf) }; 104 let static_buf = unsafe { core::mem::transmute::<&'a mut [u8], &'static mut [u8]>(buf) };
107 105
108 async move { 106 async move {
109 let rx_stream = this.rx_stream.take().unwrap(); 107 let rx_stream = self.rx_stream.take().unwrap();
110 let usart = this.usart.take().unwrap(); 108 let usart = self.usart.take().unwrap();
111 109
112 let mut rx_transfer = Transfer::init( 110 let mut rx_transfer = Transfer::init(
113 rx_stream, 111 rx_stream,
@@ -120,13 +118,13 @@ where
120 .double_buffer(false), 118 .double_buffer(false),
121 ); 119 );
122 120
123 let fut = InterruptFuture::new(&mut this.rx_int); 121 let fut = InterruptFuture::new(&mut self.rx_int);
124 rx_transfer.start(|_usart| {}); 122 rx_transfer.start(|_usart| {});
125 fut.await; 123 fut.await;
126 124
127 let (rx_stream, usart, _, _) = rx_transfer.free(); 125 let (rx_stream, usart, _, _) = rx_transfer.free();
128 this.rx_stream.replace(rx_stream); 126 self.rx_stream.replace(rx_stream);
129 this.usart.replace(usart); 127 self.usart.replace(usart);
130 128
131 Ok(()) 129 Ok(())
132 } 130 }
@@ -148,14 +146,13 @@ where
148 type WriteFuture<'a> = impl Future<Output = Result<(), Error>> + 'a; 146 type WriteFuture<'a> = impl Future<Output = Result<(), Error>> + 'a;
149 147
150 /// Sends serial data. 148 /// Sends serial data.
151 fn write<'a>(self: Pin<&'a mut Self>, buf: &'a [u8]) -> Self::WriteFuture<'a> { 149 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a> {
152 let this = unsafe { self.get_unchecked_mut() };
153 #[allow(mutable_transmutes)] 150 #[allow(mutable_transmutes)]
154 let static_buf = unsafe { core::mem::transmute::<&'a [u8], &'static mut [u8]>(buf) }; 151 let static_buf = unsafe { core::mem::transmute::<&'a [u8], &'static mut [u8]>(buf) };
155 152
156 async move { 153 async move {
157 let tx_stream = this.tx_stream.take().unwrap(); 154 let tx_stream = self.tx_stream.take().unwrap();
158 let usart = this.usart.take().unwrap(); 155 let usart = self.usart.take().unwrap();
159 156
160 let mut tx_transfer = Transfer::init( 157 let mut tx_transfer = Transfer::init(
161 tx_stream, 158 tx_stream,
@@ -168,15 +165,15 @@ where
168 .double_buffer(false), 165 .double_buffer(false),
169 ); 166 );
170 167
171 let fut = InterruptFuture::new(&mut this.tx_int); 168 let fut = InterruptFuture::new(&mut self.tx_int);
172 169
173 tx_transfer.start(|_usart| {}); 170 tx_transfer.start(|_usart| {});
174 fut.await; 171 fut.await;
175 172
176 let (tx_stream, usart, _buf, _) = tx_transfer.free(); 173 let (tx_stream, usart, _buf, _) = tx_transfer.free();
177 174
178 this.tx_stream.replace(tx_stream); 175 self.tx_stream.replace(tx_stream);
179 this.usart.replace(usart); 176 self.usart.replace(usart);
180 177
181 Ok(()) 178 Ok(())
182 } 179 }
@@ -202,16 +199,12 @@ where
202 /// The future is pending until either the buffer is completely full, or the RX line falls idle after receiving some data. 199 /// The future is pending until either the buffer is completely full, or the RX line falls idle after receiving some data.
203 /// 200 ///
204 /// Returns the number of bytes read. 201 /// Returns the number of bytes read.
205 fn read_until_idle<'a>( 202 fn read_until_idle<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadUntilIdleFuture<'a> {
206 self: Pin<&'a mut Self>,
207 buf: &'a mut [u8],
208 ) -> Self::ReadUntilIdleFuture<'a> {
209 let this = unsafe { self.get_unchecked_mut() };
210 let static_buf = unsafe { core::mem::transmute::<&'a mut [u8], &'static mut [u8]>(buf) }; 203 let static_buf = unsafe { core::mem::transmute::<&'a mut [u8], &'static mut [u8]>(buf) };
211 204
212 async move { 205 async move {
213 let rx_stream = this.rx_stream.take().unwrap(); 206 let rx_stream = self.rx_stream.take().unwrap();
214 let usart = this.usart.take().unwrap(); 207 let usart = self.usart.take().unwrap();
215 208
216 unsafe { 209 unsafe {
217 /* __HAL_UART_ENABLE_IT(&uart->UartHandle, UART_IT_IDLE); */ 210 /* __HAL_UART_ENABLE_IT(&uart->UartHandle, UART_IT_IDLE); */
@@ -235,8 +228,8 @@ where
235 228
236 let total_bytes = RSTREAM::get_number_of_transfers() as usize; 229 let total_bytes = RSTREAM::get_number_of_transfers() as usize;
237 230
238 let fut = InterruptFuture::new(&mut this.rx_int); 231 let fut = InterruptFuture::new(&mut self.rx_int);
239 let fut_idle = InterruptFuture::new(&mut this.usart_int); 232 let fut_idle = InterruptFuture::new(&mut self.usart_int);
240 233
241 rx_transfer.start(|_usart| {}); 234 rx_transfer.start(|_usart| {});
242 235
@@ -249,8 +242,8 @@ where
249 unsafe { 242 unsafe {
250 (*USART::ptr()).cr1.modify(|_, w| w.idleie().clear_bit()); 243 (*USART::ptr()).cr1.modify(|_, w| w.idleie().clear_bit());
251 } 244 }
252 this.rx_stream.replace(rx_stream); 245 self.rx_stream.replace(rx_stream);
253 this.usart.replace(usart); 246 self.usart.replace(usart);
254 247
255 Ok(total_bytes - remaining_bytes) 248 Ok(total_bytes - remaining_bytes)
256 } 249 }
diff --git a/embassy-traits/src/uart.rs b/embassy-traits/src/uart.rs
index 5676e3fca..9e76306b0 100644
--- a/embassy-traits/src/uart.rs
+++ b/embassy-traits/src/uart.rs
@@ -13,7 +13,7 @@ pub trait Read {
13 where 13 where
14 Self: 'a; 14 Self: 'a;
15 15
16 fn read<'a>(self: Pin<&'a mut Self>, buf: &'a mut [u8]) -> Self::ReadFuture<'a>; 16 fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadFuture<'a>;
17} 17}
18 18
19pub trait ReadUntilIdle { 19pub trait ReadUntilIdle {
@@ -23,10 +23,7 @@ pub trait ReadUntilIdle {
23 23
24 /// Receive into the buffer until the buffer is full or the line is idle after some bytes are received 24 /// Receive into the buffer until the buffer is full or the line is idle after some bytes are received
25 /// Return the number of bytes received 25 /// Return the number of bytes received
26 fn read_until_idle<'a>( 26 fn read_until_idle<'a>(&'a mut self, buf: &'a mut [u8]) -> Self::ReadUntilIdleFuture<'a>;
27 self: Pin<&'a mut Self>,
28 buf: &'a mut [u8],
29 ) -> Self::ReadUntilIdleFuture<'a>;
30} 27}
31 28
32pub trait Write { 29pub trait Write {
@@ -34,5 +31,5 @@ pub trait Write {
34 where 31 where
35 Self: 'a; 32 Self: 'a;
36 33
37 fn write<'a>(self: Pin<&'a mut Self>, buf: &'a [u8]) -> Self::WriteFuture<'a>; 34 fn write<'a>(&'a mut self, buf: &'a [u8]) -> Self::WriteFuture<'a>;
38} 35}