1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
//! # xum1541
//!
//! This crate provides a Rust interface for communicating with Commodore disk drives via the XUM1541
//! USB adapter (also known as the `ZoomFloppy`). It enables modern computers to interact with vintage
//! Commodore hardware through a clean, safe, and idiomatic Rust API.
//!
//! ## Overview
//!
//! The xum1541 crate is structured around two main components:
//!
//! - A high-level [`Bus`] interface for IEC/IEEE-488 bus operations
//! - A lower-level [`Device`] interface for direct USB communication
//!
//! ### Key Features
//!
//! - Safe Rust interface for XUM1541 USB adapter communication
//! - Support for both IEC and IEEE-488 protocols
//! - Comprehensive error handling
//! - Built-in device discovery and initialization
//! - Automatic USB resource management
//! - Support for multiple XUM1541 devices through serial number selection
//! - Configurable USB timeouts and debug logging
//!
//! ## Architecture
//!
//! ### Bus Layer
//!
//! The [`Bus`] struct is the primary interface most users should interact with. It provides:
//!
//! - High-level IEC/IEEE-488 bus operations (talk, listen, open, close)
//! - Data transfer primitives (read, write)
//! - Bus state management
//! - Pattern-based reading capabilities
//! - Safe state transitions between bus modes
//!
//! The Bus layer enforces correct protocol usage by tracking the current bus state and validating
//! operations against that state.
//!
//! ### Device Layer
//!
//! The `Device` struct provides low-level USB communication with the XUM1541 hardware:
//!
//! - Direct USB control transfers
//! - Bulk data transfers
//! - Device initialization and configuration
//! - Firmware version verification
//! - Device capability detection
//! - Debug information access (for firmware version 8+)
//!
//! ## Getting Started
//!
//! The recommended way to create a new xum1541 interface is using
//! [`BusBuilder`].
//!
//! ```rust,no_run
//! use xum1541::BusBuilder;
//!
//! let mut bus = BusBuilder::new()
//! .build()
//! .unwrap();
//!
//! bus.initialize().unwrap();
//! ```
//!
//! ## Error Handling
//!
//! The library uses a custom `Error` type that covers:
//!
//! - Device access errors (not found, firmware version mismatch, serial number mismatch)
//! - Communication failures (USB errors, timeouts)
//! - Protocol violations (invalid state transitions)
//! - Resource exhaustion (buffer overflows)
//! - Invalid parameters (zero-length transfers, invalid patterns)
//!
//! ## Key Types
//!
//! ### `DeviceChannel`
//!
//! Represents a combination of device number and channel (secondary address) on the Commodore bus.
//!
//! ### `BusMode`
//!
//! Tracks the current state of the bus:
//! - Idle
//! - Talking (a specific device talking using a specific channel)
//! - Listening (a specific device listening using a specific channel)
//!
//! ### `DeviceInfo`
//!
//! Contains information about the XUM1541 device:
//! - Firmware version
//! - Hardware capabilities
//! - Device status
//! - Debug information (firmware v8+)
//!
//! ## Advanced Usage
//!
//! ### Custom USB Context
//!
//! For applications needing fine-grained control over USB behavior:
//!
//! ```rust,no_run
//! use rusb::{Context, UsbContext};
//! use xum1541::BusBuilder;
//!
//! let mut context = Context::new().unwrap();
//! context.set_log_level(rusb::LogLevel::Debug);
//!
//! let bus = BusBuilder::new()
//! .context(context)
//! .build()
//! .unwrap();
//! ```
//!
//! ### Reading with Patterns
//!
//! The library provides sophisticated pattern-based reading capabilities:
//!
//! ```rust,ignore
//! // Read until specific byte pattern, including the pattern itself
//! let mut buffer = vec![0u8; 256];
//! // Will read until 0x0D is found, and include the 0x0D in the buffer
//! let bytes_read = bus.read_until(&mut buffer, &[0x0D])?;
//!
//! // Read until multiple byte pattern
//! let mut buffer = vec![0u8; 256];
//! // Will read until the sequence 0x31, 0x32 is found, including both bytes
//! let bytes_read = bus.read_until(&mut buffer, &[0x31, 0x32])?;
//!
//! // Read until any byte from set is found (inclusive)
//! let mut buffer = vec![0u8; 256];
//! // Will read until either 0x0D or 0x20 is found, including the matching byte
//! let bytes_read = bus.read_until_any(&mut buffer, &[0x0D, 0x20])?;
//! ```
//!
//! ## Examples
//!
//! See
//! * [`examples/readme.rs`](examples/readme.rs) - A very simple app which queries a drive's status. This is also included below.
//! * [`examples/basic.rs`](examples/basic.rs) - A more complex example which enables logging (run with `RUST_LOG=info` for example) queries the device's capabilities and drive status.
//!
//! ```rust,no_run
//! use xum1541::{BusBuilder, DeviceChannel, Error};
//!
//! fn main() -> Result<(), Error> {
//! // Connect to the XUM1541 device
//! let mut bus = BusBuilder::new().build()?;
//!
//! // Initialize the bus
//! bus.initialize()?;
//!
//! // Reset the IEC
//! bus.reset()?;
//!
//! // Instuct device 8 to talk using channel 15
//! bus.talk(DeviceChannel::new(8, 15)?)?;
//!
//! // Read up to 256 bytes of data from the drive
//! let mut data = vec![0u8; 256];
//! bus.read(&mut data)?;
//!
//! // Print it out (this should be the drive status)
//! println!(
//! "Retrieved data from drive: {}",
//! std::str::from_utf8(&data).unwrap()
//! );
//!
//! // Tell the drive to stop talking
//! bus.untalk()?;
//!
//! // No need to close the XUM1541 device, it will be closed when bus goes
//! // out of scope
//!
//! Ok(())
//! }
//! ```
//!
//! ## Thread Safety
//!
//! The library is not inherently thread-safe but can be accessed from multiple
//! threads, and from futures/async code, with some considerations:
//!
//! 1. Wrap the [`Bus`] instance in a mutex
//! 2. Consider how to allocate/deallocate channels for device communication
//! 3. Be aware of USB timeout implications in threaded contexts
//!
//! ## Logging
//!
//! The library uses the `log` crate for diagnostic output:
//!
//! - Error: Critical failures requiring immediate attention
//! - Warn: Potential issues or deprecated usage
//! - Info: Important state changes
//! - Debug: Detailed operation information
//! - Trace: Function entry/exit and protocol-level details
//!
//! To enable logging, use [`env_logger::init`](https://docs.rs/env_logger/latest/env_logger/index.html) and set the `RUST_LOG` environment variable:
//!
//! ## Technical Details
//!
//! ### USB Protocol
//!
//! - Vendor ID: 0x16D0
//! - Product ID: 0x0504
//! - Interface: Bulk transfers
//! - Endpoints: IN and OUT for data/status
//! - Control transfers for device management
//!
//! ### XUM1541 Firmware Compatibility
//!
//! - Minimum supported firmware: Version 7
//! - Enhanced debugging: Version 8+
//!
//! ## Contributing
//!
//! When extending the library:
//!
//! 1. Maintain the state machine model for bus operations
//! 2. Follow the error handling patterns
//! 3. Add appropriate logging at each level
//! 4. Document public interfaces thoroughly
//! 5. Add tests for new functionality
//!
//! ## License
//!
//! This library is licensed under the GNU General Public License Version 3 (GPLv3).
//! ## Acknowledgments
//! - Original [OpenCBM](https://github.com/OpenCbm/OpenCbm) project and xum1541 plugin developers. `OpenCbm` is licensed under the GPLv2
//! - `ZoomFloppy` hardware developers
use ;
pub use crateCommunication as CommunicationError;
pub use crateDeviceAccess as DeviceAccessError;
/// Error types
pub use crateError;
pub use crateInternal as InternalError;
/// Constants
pub use crate;
/// Bus types
pub use crateDEFAULT_TIMEOUT as BUS_DEFAULT_TIMEOUT;
pub use crate;
pub use crate;
pub use crate;
/// Device types
pub use crate;
/// Struct holding device and channel numbers. Used by [`crate::Bus`] functions
/// which require the device and channel to be specified.