Skip to content

Commit a4e7fb6

Browse files
committed
Issue a status stage when the transfer data is fully written
1 parent 2528def commit a4e7fb6

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

mod.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ enum TransferState {
6262
#[derive(Copy, Clone)]
6363
struct EP0State {
6464
direction: UsbDirection,
65+
remaining_size: u16,
6566
in_transfer_state: TransferState,
6667
is_set_address: bool,
6768
}
@@ -109,6 +110,7 @@ impl<'c> Usbd<'c> {
109110
iso_out_used: false,
110111
ep0_state: Mutex::new(Cell::new(EP0State {
111112
direction: UsbDirection::Out,
113+
remaining_size: 0,
112114
in_transfer_state: TransferState::NoTransfer,
113115
is_set_address: false,
114116
})),
@@ -193,7 +195,7 @@ impl<'c> Usbd<'c> {
193195
false => UsbDirection::In,
194196
true => UsbDirection::Out,
195197
};
196-
198+
ep0_state.remaining_size = (buf[6] as u16) | ((buf[7] as u16) << 8);
197199
ep0_state.is_set_address = (buf[0] == 0x00) && (buf[1] == 0x05);
198200

199201
if ep0_state.direction == UsbDirection::Out {
@@ -435,6 +437,14 @@ impl UsbBus for Usbd<'_> {
435437
return true;
436438
}
437439

440+
if ep0_state.direction == UsbDirection::In && ep0_state.remaining_size == 0 {
441+
// Device sent all the requested data, no need to send ZLP.
442+
// Host will issue an OUT transfer in this case, device should
443+
// respond with a status stage.
444+
regs.tasks_ep0status.write(|w| w.tasks_ep0status().set_bit());
445+
return true;
446+
}
447+
438448
false
439449
});
440450

@@ -499,6 +509,10 @@ impl UsbBus for Usbd<'_> {
499509
}
500510
});
501511

512+
let mut ep0_state = self.ep0_state.borrow(cs).get();
513+
ep0_state.remaining_size = ep0_state.remaining_size.saturating_sub(buf.len() as u16);
514+
self.ep0_state.borrow(cs).set(ep0_state);
515+
502516
// Hack: trigger status stage if the IN transfer is not acknowledged after a few frames,
503517
// so record the current frame here; the actual test and status stage activation happens
504518
// in the poll method.

0 commit comments

Comments
 (0)