This method will flush the current queue of data to the usb host. It is invoked automatically based on interrupts, but you can manually flush too if you'd like. It will short-cirucit if all the transfer queues are still active or if the USB host hasn't finished connecting. Returns how many bytes were written.
()
| 228 | /// |
| 229 | /// Returns how many bytes were written. |
| 230 | pub fn usb_serial_flush() -> u32 { |
| 231 | // Verify we are in a good, configured state. |
| 232 | if unsafe { CONFIGURED == false } { |
| 233 | return 0; |
| 234 | } |
| 235 | |
| 236 | // Prepare |
| 237 | if unsafe { TX_BUFFER_TRANSIENT.size() } > 0 { |
| 238 | let dtd = unsafe { &mut TX_DTD }; |
| 239 | |
| 240 | if (dtd.status & 0x80) > 0 { |
| 241 | return 0; |
| 242 | } |
| 243 | |
| 244 | // Check for error condition |
| 245 | if (dtd.status & 0xFF) > 0 { |
| 246 | // This is actually kinda ok probably. |
| 247 | // Some data may have been lost, idk, but |
| 248 | // You can keep going and it'll magically |
| 249 | // fix itself. |
| 250 | |
| 251 | // Returning zero on the other hand seems |
| 252 | // to brick it because the error persists |
| 253 | // until you prepare another queue. |
| 254 | |
| 255 | // return 0; |
| 256 | } |
| 257 | |
| 258 | // Copy the data. |
| 259 | let len = unsafe { TX_BUFFER_TRANSIENT.size() } as u32; |
| 260 | let src_ptr = unsafe { TX_BUFFER_TRANSIENT.data.as_ptr() } as u32; |
| 261 | let dst_ptr = unsafe { TX_BUFFER.as_ptr() } as u32; |
| 262 | |
| 263 | mem::copy(src_ptr, dst_ptr, len); |
| 264 | |
| 265 | unsafe { |
| 266 | // Clear buffer |
| 267 | TX_BUFFER_TRANSIENT.clear(); |
| 268 | } |
| 269 | |
| 270 | usb_prepare_transfer(dtd, dst_ptr, len, true); |
| 271 | usb_transmit(CDC_TX_ENDPOINT as usize, dtd); |
| 272 | return len; |
| 273 | } |
| 274 | |
| 275 | return 0; |
| 276 | } |
| 277 | |
| 278 | fn setup_cdc_descriptors() { |
| 279 | let descriptors = usb_get_descriptors(); |
no test coverage detected