You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Note that even if this method returns Ok, data may still be in hardware buffers on either side.
I don't fully understand how USB works.
Would it be enough to check if write_state == WriteState::Idle?
Also do I understand correctly that usb_device.poll(&mut [&mut serial_port]) needs to be called to make progress in flushing the hardware buffers?
The text was updated successfully, but these errors were encountered:
Transactions on a USB are all driven by the host side, and usually the device side has dedicated hardware that handles some fraction of the work. The poll() method needs to be called periodically to check the USB hardware, to see if the host has done anything that might need to be handled by the device firmware. So, yes your understanding is correct, and the most efficient approach is probably to call poll() from within a USB ISR.
Yes, if write_state == WriteState::Idle, then there is no data waiting in the device's write buffer, however that field is private - you're looking for SerialPort::flush(), which returns Ok(()) when the write buffer is empty. Ed to add: I think this is the best that can be done in a device-agnostic way, at least on the ATSAMD parts I've been working on, I'm pretty sure it means that the data has been copied out of the device.
The reason for WriteState has to do with the implementation details of USB bulk transactions, which can involve more than one data packet; basically if you have a 64B bulk IN endpoint in a device (for moving data from the device to the host) the host knows that a transaction is complete when the device sends a packet with between 0 (a Zero-Length Packet aka ZLP) and 63B of data. If the device sends a full 64B packet, the host can't tell if the device meant to send exactly 64B in the whole transaction, or if it has more data to write. The application that initiated the USB read from the device will only see data after a transaction has completed, so the device limits the number of full packets it'll write in a given transaction to SHORT_PACKET_INTERVAL, once it hits the limit it will write one less than the endpoint size, say 63B, to signal an end of that particular transaction. It makes a sort of upper bound on the latency between some data being written in to SerialPort::write(), and coming out in the application running on the host - it's not a deterministic limit, because bulk transfers are scheduled according to available bandwidth on the bus.
The docs of
SerialPort::flush
metion that:I don't fully understand how USB works.
Would it be enough to check if
write_state == WriteState::Idle
?Also do I understand correctly that
usb_device.poll(&mut [&mut serial_port])
needs to be called to make progress in flushing the hardware buffers?The text was updated successfully, but these errors were encountered: