Skip to content

Commit f2d97af

Browse files
authored
Add USB max packet size parameters to eusb v5 to support HS usb (#140)
* Add USB max packet size parameters to eusb v5 * Add USB max packet size to examples
1 parent 5855252 commit f2d97af

5 files changed

Lines changed: 79 additions & 20 deletions

File tree

example/firmware/src/bin/comms-01.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use postcard_rpc::{
1212
server::{
1313
impls::embassy_usb_v0_5::{
1414
dispatch_impl::{WireRxBuf, WireRxImpl, WireSpawnImpl, WireStorage, WireTxImpl},
15-
PacketBuffers,
15+
PacketBuffers, USB_FS_MAX_PACKET_SIZE,
1616
},
1717
Dispatch, Server,
1818
},
@@ -88,7 +88,12 @@ async fn main(spawner: Spawner) {
8888
let config = usb_config();
8989

9090
let context = Context;
91-
let (device, tx_impl, rx_impl) = STORAGE.init(driver, config, pbufs.tx_buf.as_mut_slice());
91+
let (device, tx_impl, rx_impl) = STORAGE.init(
92+
driver,
93+
config,
94+
pbufs.tx_buf.as_mut_slice(),
95+
USB_FS_MAX_PACKET_SIZE,
96+
);
9297
let dispatcher = MyApp::new(context, spawner.into());
9398
let vkk = dispatcher.min_key_len();
9499
let mut server: AppServer = Server::new(

example/firmware/src/bin/comms-02.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use postcard_rpc::{
2424
dispatch_impl::{
2525
spawn_fn, WireRxBuf, WireRxImpl, WireSpawnImpl, WireStorage, WireTxImpl,
2626
},
27-
PacketBuffers,
27+
PacketBuffers, USB_FS_MAX_PACKET_SIZE,
2828
},
2929
Dispatch, Sender, Server, SpawnContext,
3030
},
@@ -162,7 +162,12 @@ async fn main(spawner: Spawner) {
162162
accel: accel_ref,
163163
};
164164

165-
let (device, tx_impl, rx_impl) = STORAGE.init(driver, config, pbufs.tx_buf.as_mut_slice());
165+
let (device, tx_impl, rx_impl) = STORAGE.init(
166+
driver,
167+
config,
168+
pbufs.tx_buf.as_mut_slice(),
169+
USB_FS_MAX_PACKET_SIZE,
170+
);
166171

167172
// Set timeout to 4ms/frame, instead of the default 2ms/frame
168173
tx_impl.set_timeout_ms_per_frame(4).await;

example/firmware/src/bin/logging.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use postcard_rpc::{
1212
server::{
1313
impls::embassy_usb_v0_5::{
1414
dispatch_impl::{WireRxBuf, WireRxImpl, WireSpawnImpl, WireStorage, WireTxImpl},
15-
PacketBuffers,
15+
PacketBuffers, USB_FS_MAX_PACKET_SIZE,
1616
},
1717
Dispatch, Sender, Server,
1818
},
@@ -87,7 +87,12 @@ async fn main(spawner: Spawner) {
8787

8888
let context = Context {};
8989

90-
let (device, tx_impl, rx_impl) = STORAGE.init(driver, config, pbufs.tx_buf.as_mut_slice());
90+
let (device, tx_impl, rx_impl) = STORAGE.init(
91+
driver,
92+
config,
93+
pbufs.tx_buf.as_mut_slice(),
94+
USB_FS_MAX_PACKET_SIZE,
95+
);
9196
let dispatcher = MyApp::new(context, spawner.into());
9297
let vkk = dispatcher.min_key_len();
9398
let server: AppServer = Server::new(

example/firmware/src/bin/minimal.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use postcard_rpc::{
1414
server::{
1515
impls::embassy_usb_v0_5::{
1616
dispatch_impl::{WireRxBuf, WireRxImpl, WireSpawnImpl, WireStorage, WireTxImpl},
17-
PacketBuffers,
17+
PacketBuffers, USB_FS_MAX_PACKET_SIZE,
1818
},
1919
Dispatch, Server,
2020
},
@@ -90,7 +90,12 @@ async fn main(spawner: Spawner) {
9090

9191
let context = Context {};
9292

93-
let (device, tx_impl, rx_impl) = STORAGE.init(driver, config, pbufs.tx_buf.as_mut_slice());
93+
let (device, tx_impl, rx_impl) = STORAGE.init(
94+
driver,
95+
config,
96+
pbufs.tx_buf.as_mut_slice(),
97+
USB_FS_MAX_PACKET_SIZE,
98+
);
9499
let dispatcher = MyApp::new(context, spawner.into());
95100
let vkk = dispatcher.min_key_len();
96101
let server: AppServer = Server::new(

source/postcard-rpc/src/server/impls/embassy_usb_v0_5.rs

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ static HDLR: ConstStaticCell<PoststationHandler> = ConstStaticCell::new(Poststat
2222

2323
/// Default time in milliseconds to wait for the completion of sending
2424
pub const DEFAULT_TIMEOUT_MS_PER_FRAME: usize = 2;
25+
/// Default max packet size for USB Full Speed
26+
pub const USB_FS_MAX_PACKET_SIZE: usize = 64;
27+
/// Default max packet size for USB High Speed
28+
pub const USB_HS_MAX_PACKET_SIZE: usize = 512;
2529

2630
impl embassy_usb_0_5::Handler for PoststationHandler {
2731
fn get_string(
@@ -110,6 +114,7 @@ pub mod dispatch_impl {
110114
driver: D,
111115
config: Config<'static>,
112116
tx_buf: &'static mut [u8],
117+
max_usb_frame_size: usize,
113118
) -> (UsbDevice<'static, D>, WireTxImpl<M, D>, WireRxImpl<D>) {
114119
let bufs = self.bufs_usb.take();
115120

@@ -156,6 +161,7 @@ pub mod dispatch_impl {
156161
tx_buf,
157162
pending_frame: false,
158163
timeout_ms_per_frame: DEFAULT_TIMEOUT_MS_PER_FRAME,
164+
max_usb_frame_size: max_usb_frame_size,
159165
}));
160166

161167
// Build the builder.
@@ -172,8 +178,10 @@ pub mod dispatch_impl {
172178
driver: D,
173179
config: Config<'static>,
174180
tx_buf: &'static mut [u8],
181+
max_usb_frame_size: usize,
175182
) -> (UsbDevice<'static, D>, WireTxImpl<M, D>, WireRxImpl<D>) {
176-
let (builder, wtx, wrx) = self.init_without_build(driver, config, tx_buf);
183+
let (builder, wtx, wrx) =
184+
self.init_without_build(driver, config, tx_buf, max_usb_frame_size);
177185
let usb = builder.build();
178186
(usb, wtx, wrx)
179187
}
@@ -185,7 +193,9 @@ pub mod dispatch_impl {
185193
driver: D,
186194
config: Config<'static>,
187195
tx_buf: &'static mut [u8],
196+
max_usb_frame_size: usize,
188197
) -> (Builder<'static, D>, WireTxImpl<M, D>, WireRxImpl<D>) {
198+
assert!(max_usb_frame_size.is_power_of_two());
189199
let bufs = self.bufs_usb.take();
190200

191201
let mut builder = Builder::new(
@@ -215,8 +225,8 @@ pub mod dispatch_impl {
215225
let mut function = builder.function(0xFF, 0, 0);
216226
let mut interface = function.interface();
217227
let mut alt = interface.alt_setting(0xFF, 0, 0, None);
218-
let ep_out = alt.endpoint_bulk_out(None, 64);
219-
let ep_in = alt.endpoint_bulk_in(None, 64);
228+
let ep_out = alt.endpoint_bulk_out(None, max_usb_frame_size as u16);
229+
let ep_in = alt.endpoint_bulk_in(None, max_usb_frame_size as u16);
220230
drop(function);
221231

222232
let wtx = self.cell.init(Mutex::new(EUsbWireTxInner {
@@ -225,6 +235,7 @@ pub mod dispatch_impl {
225235
tx_buf,
226236
pending_frame: false,
227237
timeout_ms_per_frame: DEFAULT_TIMEOUT_MS_PER_FRAME,
238+
max_usb_frame_size: max_usb_frame_size,
228239
}));
229240

230241
(builder, EUsbWireTx { inner: wtx }, EUsbWireRx { ep_out })
@@ -243,6 +254,7 @@ pub struct EUsbWireTxInner<D: Driver<'static>> {
243254
tx_buf: &'static mut [u8],
244255
pending_frame: bool,
245256
timeout_ms_per_frame: usize,
257+
max_usb_frame_size: usize,
246258
}
247259

248260
/// A [`WireTx`] implementation for embassy-usb 0.4.
@@ -313,14 +325,22 @@ impl<M: RawMutex + 'static, D: Driver<'static> + 'static> WireTx for EUsbWireTx<
313325
tx_buf,
314326
pending_frame,
315327
timeout_ms_per_frame,
328+
max_usb_frame_size,
316329
}: &mut EUsbWireTxInner<D> = &mut inner;
317330

318331
let (hdr_used, remain) = hdr.write_to_slice(tx_buf).ok_or(WireTxErrorKind::Other)?;
319332
let bdy_used = postcard::to_slice(msg, remain).map_err(|_| WireTxErrorKind::Other)?;
320333
let used_ttl = hdr_used.len() + bdy_used.len();
321334

322335
if let Some(used) = tx_buf.get(..used_ttl) {
323-
send_all::<D>(ep_in, used, pending_frame, *timeout_ms_per_frame).await
336+
send_all::<D>(
337+
ep_in,
338+
used,
339+
pending_frame,
340+
*timeout_ms_per_frame,
341+
*max_usb_frame_size,
342+
)
343+
.await
324344
} else {
325345
Err(WireTxErrorKind::Other)
326346
}
@@ -332,9 +352,17 @@ impl<M: RawMutex + 'static, D: Driver<'static> + 'static> WireTx for EUsbWireTx<
332352
ep_in,
333353
pending_frame,
334354
timeout_ms_per_frame,
355+
max_usb_frame_size,
335356
..
336357
}: &mut EUsbWireTxInner<D> = &mut inner;
337-
send_all::<D>(ep_in, buf, pending_frame, *timeout_ms_per_frame).await
358+
send_all::<D>(
359+
ep_in,
360+
buf,
361+
pending_frame,
362+
*timeout_ms_per_frame,
363+
*max_usb_frame_size,
364+
)
365+
.await
338366
}
339367

340368
async fn send_log_str(&self, kkind: VarKeyKind, s: &str) -> Result<(), Self::Error> {
@@ -346,6 +374,7 @@ impl<M: RawMutex + 'static, D: Driver<'static> + 'static> WireTx for EUsbWireTx<
346374
tx_buf,
347375
pending_frame,
348376
timeout_ms_per_frame,
377+
max_usb_frame_size,
349378
}: &mut EUsbWireTxInner<D> = &mut inner;
350379

351380
let key = match kkind {
@@ -366,7 +395,14 @@ impl<M: RawMutex + 'static, D: Driver<'static> + 'static> WireTx for EUsbWireTx<
366395
let used_ttl = hdr_used.len() + bdy_used.len();
367396

368397
if let Some(used) = tx_buf.get(..used_ttl) {
369-
send_all::<D>(ep_in, used, pending_frame, *timeout_ms_per_frame).await
398+
send_all::<D>(
399+
ep_in,
400+
used,
401+
pending_frame,
402+
*timeout_ms_per_frame,
403+
*max_usb_frame_size,
404+
)
405+
.await
370406
} else {
371407
Err(WireTxErrorKind::Other)
372408
}
@@ -385,6 +421,7 @@ impl<M: RawMutex + 'static, D: Driver<'static> + 'static> WireTx for EUsbWireTx<
385421
tx_buf,
386422
pending_frame,
387423
timeout_ms_per_frame,
424+
max_usb_frame_size,
388425
}: &mut EUsbWireTxInner<D> = &mut inner;
389426
let ttl_len = tx_buf.len();
390427

@@ -460,6 +497,7 @@ impl<M: RawMutex + 'static, D: Driver<'static> + 'static> WireTx for EUsbWireTx<
460497
&tx_buf[..act_used],
461498
pending_frame,
462499
*timeout_ms_per_frame,
500+
*max_usb_frame_size,
463501
)
464502
.await
465503
}
@@ -471,6 +509,7 @@ async fn send_all<D>(
471509
out: &[u8],
472510
pending_frame: &mut bool,
473511
timeout_ms_per_frame: usize,
512+
max_usb_frame_size: usize,
474513
) -> Result<(), WireTxErrorKind>
475514
where
476515
D: Driver<'static>,
@@ -481,7 +520,7 @@ where
481520

482521
// Calculate an estimated timeout based on the number of frames we need to send
483522
// For now, we use 2ms/frame by default, rounded UP
484-
let frames = (out.len() + 63) / 64;
523+
let frames = out.len().div_ceil(max_usb_frame_size);
485524
let timeout_ms = frames * timeout_ms_per_frame;
486525

487526
let send_fut = async {
@@ -492,17 +531,17 @@ where
492531
}
493532
*pending_frame = true;
494533

495-
// write in segments of 64. The last chunk may
496-
// be 0 < len <= 64.
497-
for ch in out.chunks(64) {
534+
// write in segments of max_usb_frame_size. The last chunk may
535+
// be 0 < len <= max_usb_frame_size.
536+
for ch in out.chunks(max_usb_frame_size) {
498537
if ep_in.write(ch).await.is_err() {
499538
return Err(WireTxErrorKind::ConnectionClosed);
500539
}
501540
}
502-
// If the total we sent was a multiple of 64, send an
541+
// If the total we sent was a multiple of max_usb_frame_size, send an
503542
// empty message to "flush" the transaction. We already checked
504543
// above that the len != 0.
505-
if (out.len() & (64 - 1)) == 0 && ep_in.write(&[]).await.is_err() {
544+
if (out.len() & (max_usb_frame_size - 1)) == 0 && ep_in.write(&[]).await.is_err() {
506545
return Err(WireTxErrorKind::ConnectionClosed);
507546
}
508547

0 commit comments

Comments
 (0)