pokeys-lib 1.0.4

Pure Rust core library for PoKeys device control - USB/Network connectivity, I/O, PWM, encoders, SPI/I2C protocols
Documentation
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
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
---
import '../../styles/global.css';
---

<html lang="en">
	<head>
		<meta charset="utf-8" />
		<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
		<meta name="viewport" content="width=device-width" />
		<meta name="generator" content={Astro.generator} />
		<title>Digital I/O API - PoKeys Core Library</title>
		<style>
			aside .sidebar-nav a {
				display: block !important;
				width: 100% !important;
			}
			aside .sidebar-nav {
				display: flex !important;
				flex-direction: column !important;
			}
		</style>
	</head>
	<body class="bg-gray-900 text-white">
		<!-- Navigation -->
		<nav class="fixed top-0 left-0 right-0 z-50 bg-gray-900/80 backdrop-blur-md border-b border-gray-800 h-16">
			<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-full">
				<div class="flex justify-between items-center h-full">
					<a href="/core/" class="text-2xl font-bold bg-gradient-to-r from-blue-400 to-purple-500 bg-clip-text text-transparent">
						PoKeys
					</a>
					<div class="hidden md:flex space-x-8">
						<a href="/core/" class="text-gray-300 hover:text-white transition-colors">Home</a>
						<a href="/core/getting-started" class="text-gray-300 hover:text-white transition-colors">Getting Started</a>
						<a href="/core/examples/" class="text-gray-300 hover:text-white transition-colors">Examples</a>
						<a href="/core/api/" class="text-white font-semibold">API Reference</a>
					</div>
				</div>
			</div>
		</nav>

		<!-- Main Content -->
		<div class="flex min-h-screen pt-16">
			<!-- Sidebar -->
			<aside class="w-80 bg-gray-800/50 border-r border-gray-700 overflow-y-auto flex-shrink-0">
				<div class="p-6">
					<a href="/core/api/" class="text-blue-400 hover:text-blue-300 mb-4 inline-block">← Back to API Reference</a>
					<h2 class="text-xl font-bold mb-6 text-white">API Reference</h2>
					
					<!-- Core APIs -->
					<div class="mb-6">
						<h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-3">Core APIs</h3>
						<div class="space-y-1 sidebar-nav">
							<a href="/core/api/device" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Device Management
							</a>
							<a href="/core/api/connection" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Connection & Enumeration
							</a>
							<a href="/core/api/models" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Device Models
							</a>
						</div>
					</div>

					<!-- I/O Operations -->
					<div class="mb-6">
						<h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-3">I/O Operations</h3>
						<div class="space-y-1 sidebar-nav">
							<a href="/core/api/digital-io" class="block px-3 py-2 text-white bg-gray-700/50 rounded-md transition-colors">
								Digital I/O
							</a>
							<a href="/core/api/analog-io" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Analog I/O
							</a>
							<a href="/core/api/pin-functions" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Pin Functions
							</a>
						</div>
					</div>

					<!-- Control Systems -->
					<div class="mb-6">
						<h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-3">Control Systems</h3>
						<div class="space-y-1 sidebar-nav">
							<a href="/core/api/pwm" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								PWM Control
							</a>
							<a href="/core/api/encoders" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Encoders
							</a>
							<a href="/core/api/pulse-engine" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Pulse Engine v2
							</a>
							<a href="/core/api/servo-control" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Servo Control
							</a>
						</div>
					</div>

					<!-- Communication -->
					<div class="mb-6">
						<h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-3">Communication</h3>
						<div class="space-y-1 sidebar-nav">
							<a href="/core/api/spi" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								SPI Protocol
							</a>
							<a href="/core/api/i2c" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								I2C Protocol
							</a>
							<a href="/core/api/uart" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								UART Serial
							</a>
							<a href="/core/api/can" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								CAN Bus
							</a>
							<a href="/core/api/onewire" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								1-Wire Protocol
							</a>
						</div>
					</div>

					<!-- Matrix Operations -->
					<div class="mb-6">
						<h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-3">Matrix Operations</h3>
						<div class="space-y-1 sidebar-nav">
							<a href="/core/api/matrix-keyboard" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Matrix Keyboard
							</a>
							<a href="/core/api/led-matrix" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								LED Matrix
							</a>
						</div>
					</div>

					<!-- Display & Sensors -->
					<div class="mb-6">
						<h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-3">Display & Sensors</h3>
						<div class="space-y-1 sidebar-nav">
							<a href="/core/api/lcd" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								LCD Display
							</a>
							<a href="/core/api/sensors" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								EasySensors
							</a>
							<a href="/core/api/rtc" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Real-Time Clock
							</a>
						</div>
					</div>

					<!-- Error Handling -->
					<div class="mb-6">
						<h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-3">Error Handling</h3>
						<div class="space-y-1 sidebar-nav">
							<a href="/core/api/errors" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Error Types
							</a>
							<a href="/core/api/result-handling" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Result Handling
							</a>
						</div>
					</div>

					<!-- Types & Utilities -->
					<div class="mb-6">
						<h3 class="text-sm font-semibold text-gray-400 uppercase tracking-wider mb-3">Types & Utilities</h3>
						<div class="space-y-1 sidebar-nav">
							<a href="/core/api/types" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Core Types
							</a>
							<a href="/core/api/constants" class="block px-3 py-2 text-gray-300 hover:text-white hover:bg-gray-700/50 rounded-md transition-colors">
								Constants
							</a>
						</div>
					</div>
				</div>
			</aside>

			<!-- Main Content Area -->
			<main class="flex-1 p-8 min-h-screen">
				<div class="max-w-4xl">
					<!-- Header -->
					<div class="mb-12">
						<div class="flex items-center gap-4 mb-6">
							<span class="px-3 py-1 bg-green-600/20 text-green-300 text-sm rounded-full">Digital I/O</span>
						</div>
						<h1 class="text-4xl font-bold mb-4 bg-gradient-to-r from-green-400 to-blue-500 bg-clip-text text-transparent">
							Digital I/O API
						</h1>
						<p class="text-xl text-gray-400">
							Digital input/output operations and pin configuration for PoKeys devices
						</p>
					</div>

					<!-- Overview -->
					<section class="mb-12">
						<h2 class="text-2xl font-bold mb-4 text-white">Overview</h2>
						<div class="bg-gray-800 rounded-lg p-6">
							<p class="text-gray-300 mb-4">
								The Digital I/O API provides comprehensive control over digital pins, supporting input reading, 
								output control, and digital counting functionality with both individual and bulk operations.
							</p>
							<div class="grid md:grid-cols-2 gap-6">
								<div>
									<h3 class="text-lg font-semibold mb-2 text-green-400">Key Features</h3>
									<ul class="text-gray-300 space-y-1 text-sm">
										<li>• Individual pin control and reading</li>
										<li>• Bulk operations for performance</li>
										<li>• Digital counter functionality</li>
										<li>• Pin function validation</li>
										<li>• Thread-safe operations</li>
									</ul>
								</div>
								<div>
									<h3 class="text-lg font-semibold mb-2 text-blue-400">Pin Functions</h3>
									<ul class="text-gray-300 space-y-1 text-sm">
										<li><code>DigitalInput</code> - Read digital signals</li>
										<li><code>DigitalOutput</code> - Control digital outputs</li>
										<li><code>DigitalCounter</code> - Count digital pulses</li>
										<li><code>AnalogInput</code> - Read analog values</li>
										<li><code>PWM</code> - Generate PWM signals</li>
									</ul>
								</div>
							</div>
						</div>
					</section>

					<!-- Pin Functions -->
					<section id="pin-functions" class="mb-12">
						<h2 class="text-2xl font-bold mb-6 text-white">Pin Functions</h2>
						
						<!-- set_pin_function -->
						<div class="bg-gray-800 rounded-lg p-6 mb-6">
							<h3 class="text-xl font-semibold mb-4 text-green-400">set_pin_function</h3>
							<div class="mb-4">
								<pre class="bg-gray-900 rounded p-4 overflow-x-auto"><code class="text-gray-300">pub fn set_pin_function(&mut self, pin: u32, function: PinFunction) -> Result&lt;(u32, PinFunction)&gt;</code></pre>
							</div>
							<p class="text-gray-300 mb-4">
								Configures a pin for a specific function. The pin must support the requested capability.
								Thin wrapper around <code class="bg-gray-700 px-1 rounded">set_pin_function_with_invert</code> with <code class="bg-gray-700 px-1 rounded">inverted = false</code>.
							</p>
							<div class="grid md:grid-cols-2 gap-4 mb-4">
								<div>
									<h4 class="font-semibold text-blue-400 mb-2">Parameters</h4>
									<ul class="text-gray-300 text-sm space-y-1">
										<li><code>pin</code> - Pin number (1-55 depending on device)</li>
										<li><code>function</code> - Desired pin function</li>
									</ul>
								</div>
								<div>
									<h4 class="font-semibold text-red-400 mb-2">Errors</h4>
									<ul class="text-gray-300 text-sm space-y-1">
										<li><code>PoKeysError::Parameter</code> - Pin out of range</li>
										<li><code>PoKeysError::UnsupportedPinCapability</code> - Function not supported on this pin</li>
									</ul>
								</div>
							</div>
							<div class="bg-gray-900 rounded p-4">
								<h4 class="font-semibold text-yellow-400 mb-2">Example</h4>
								<pre class="text-gray-300"><code>// Configure pin 1 as digital output
device.set_pin_function(1, PinFunction::DigitalOutput)?;

// Configure pin 2 as digital input
device.set_pin_function(2, PinFunction::DigitalInput)?;</code></pre>
							</div>
						</div>

						<!-- set_pin_function_with_invert -->
						<div class="bg-gray-800 rounded-lg p-6 mb-6 border border-blue-500/30">
							<h3 class="text-xl font-semibold mb-4 text-green-400">
								set_pin_function_with_invert
								<span class="text-xs text-blue-300 bg-blue-900/40 px-2 py-0.5 rounded ml-2 align-middle">since 0.21.8</span>
							</h3>
							<div class="mb-4">
								<pre class="bg-gray-900 rounded p-4 overflow-x-auto"><code class="text-gray-300">pub fn set_pin_function_with_invert(
    &mut self,
    pin: u32,
    function: PinFunction,
    inverted: bool,
) -> Result&lt;(u32, PinFunction)&gt;</code></pre>
							</div>
							<p class="text-gray-300 mb-4">
								Configures a pin with an optional hardware invert flag. When
								<code class="bg-gray-700 px-1 rounded">inverted = true</code>, bit 7
								(<code class="bg-gray-700 px-1 rounded">0x80</code>) of protocol byte 4 is set, so the firmware
								reports/drives the logical complement of the electrical state at no CPU cost.
							</p>
							<div class="grid md:grid-cols-2 gap-4 mb-4">
								<div>
									<h4 class="font-semibold text-green-400 mb-2">Honors invert flag</h4>
									<ul class="text-gray-300 text-sm space-y-1">
										<li><code>DigitalInput</code></li>
										<li><code>DigitalOutput</code></li>
										<li><code>TriggeredInput</code></li>
									</ul>
								</div>
								<div>
									<h4 class="font-semibold text-gray-400 mb-2">Ignores invert flag (firmware drops bit 7)</h4>
									<ul class="text-gray-300 text-sm space-y-1">
										<li><code>AnalogInput</code>, <code>AnalogOutput</code></li>
										<li><code>DigitalCounter</code></li>
										<li><code>PinRestricted</code>, <code>Reserved</code></li>
									</ul>
								</div>
							</div>
							<p class="text-gray-300 text-sm mb-4">
								When <code class="bg-gray-700 px-1 rounded">inverted = true</code> is combined with a function
								the firmware ignores, the method emits a <code class="bg-gray-700 px-1 rounded">log::warn!</code>
								and still sends the byte.
							</p>
							<div class="bg-gray-900 rounded p-4">
								<h4 class="font-semibold text-yellow-400 mb-2">Example</h4>
								<pre class="text-gray-300"><code>// Active-low switch: get_digital_input(5) returns `true` when pin is LOW
device.set_pin_function_with_invert(5, PinFunction::DigitalInput, true)?;

// Active-low LED: set_digital_output(10, true) drives pin LOW electrically
device.set_pin_function_with_invert(10, PinFunction::DigitalOutput, true)?;</code></pre>
							</div>
						</div>

						<!-- get_pin_function -->
						<div class="bg-gray-800 rounded-lg p-6 mb-6">
							<h3 class="text-xl font-semibold mb-4 text-green-400">get_pin_function</h3>
							<div class="mb-4">
								<pre class="bg-gray-900 rounded p-4 overflow-x-auto"><code class="text-gray-300">pub fn get_pin_function(&self, pin: u32) -> Result&lt;PinFunction&gt;</code></pre>
							</div>
							<p class="text-gray-300 mb-4">
								Returns the base function of a pin. Bit 7 (the invert flag) is masked off
								before decoding — use <code class="bg-gray-700 px-1 rounded">get_pin_invert</code> to read the flag separately.
							</p>
							<div class="bg-gray-900 rounded p-4">
								<h4 class="font-semibold text-yellow-400 mb-2">Example</h4>
								<pre class="text-gray-300"><code>let function = device.get_pin_function(1)?;
match function {`{`}
    PinFunction::DigitalOutput =&gt; println!("Pin 1 is configured as output"),
    PinFunction::DigitalInput  =&gt; println!("Pin 1 is configured as input"),
    _ =&gt; println!("Pin 1 has other function"),
{`}`}</code></pre>
							</div>
						</div>

						<!-- get_pin_invert -->
						<div class="bg-gray-800 rounded-lg p-6 mb-6 border border-blue-500/30">
							<h3 class="text-xl font-semibold mb-4 text-green-400">
								get_pin_invert
								<span class="text-xs text-blue-300 bg-blue-900/40 px-2 py-0.5 rounded ml-2 align-middle">since 0.21.8</span>
							</h3>
							<div class="mb-4">
								<pre class="bg-gray-900 rounded p-4 overflow-x-auto"><code class="text-gray-300">pub fn get_pin_invert(&self, pin: u32) -> Result&lt;bool&gt;</code></pre>
							</div>
							<p class="text-gray-300 mb-4">
								Returns <code class="bg-gray-700 px-1 rounded">true</code> if bit 7 (the hardware invert flag) is set on the
								pin's cached configuration byte. This is a local cache read — call
								<code class="bg-gray-700 px-1 rounded">read_all_pin_functions</code> or
								<code class="bg-gray-700 px-1 rounded">read_all_pin_settings_raw</code> first for the device's current state.
							</p>
							<div class="bg-gray-900 rounded p-4">
								<h4 class="font-semibold text-yellow-400 mb-2">Example</h4>
								<pre class="text-gray-300"><code>device.set_pin_function_with_invert(5, PinFunction::DigitalInput, true)?;
assert!(device.get_pin_invert(5)?);</code></pre>
							</div>
						</div>
					</section>

					<!-- Digital Input -->
					<section id="digital-input" class="mb-12">
						<h2 class="text-2xl font-bold mb-6 text-white">Digital Input</h2>
						
						<!-- get_digital_input -->
						<div class="bg-gray-800 rounded-lg p-6 mb-6">
							<h3 class="text-xl font-semibold mb-4 text-green-400">get_digital_input</h3>
							<div class="mb-4">
								<pre class="bg-gray-900 rounded p-4 overflow-x-auto"><code class="text-gray-300">pub fn get_digital_input(&mut self, pin: u32) -> Result&lt;bool&gt;</code></pre>
							</div>
							<p class="text-gray-300 mb-4">
								Reads the current state of a digital input pin. Returns <code class="bg-gray-700 px-1 rounded">true</code>
								for HIGH, <code class="bg-gray-700 px-1 rounded">false</code> for LOW. If the pin was configured with the
								invert flag (via <code class="bg-gray-700 px-1 rounded">set_pin_function_with_invert</code>), the
								firmware reports the logical complement of the electrical state — an electrically LOW pin reads as
								<code class="bg-gray-700 px-1 rounded">true</code>.
							</p>
							<div class="grid md:grid-cols-2 gap-4 mb-4">
								<div>
									<h4 class="font-semibold text-green-400 mb-2">Returns</h4>
									<ul class="text-gray-300 text-sm space-y-1">
										<li><code>true</code> - Logical HIGH (or electrically LOW if inverted)</li>
										<li><code>false</code> - Logical LOW (or electrically HIGH if inverted)</li>
									</ul>
								</div>
								<div>
									<h4 class="font-semibold text-blue-400 mb-2">Requirements</h4>
									<ul class="text-gray-300 text-sm space-y-1">
										<li>• Pin must be configured as DigitalInput</li>
										<li>• Pin must support digital input capability</li>
									</ul>
								</div>
							</div>
							<div class="bg-gray-900 rounded p-4">
								<h4 class="font-semibold text-yellow-400 mb-2">Example</h4>
								<pre class="text-gray-300"><code>// Read button state on pin 2
let button_pressed = device.get_digital_input(2)?;
if button_pressed {`{`}
    println!(\"Button is pressed\");
{`}`}</code></pre>
							</div>
						</div>

						<!-- get_digital_inputs -->
						<div class="bg-gray-800 rounded-lg p-6 mb-6">
							<h3 class="text-xl font-semibold mb-4 text-green-400">get_digital_inputs</h3>
							<div class="mb-4">
								<pre class="bg-gray-900 rounded p-4 overflow-x-auto"><code class="text-gray-300">pub fn get_digital_inputs(&mut self) -> Result&lt;()&gt;</code></pre>
							</div>
							<p class="text-gray-300 mb-4">
								Reads all digital input pins in a single operation. Results are stored in the device's pin data structure.
							</p>
							<div class="bg-blue-900/20 border border-blue-500/30 rounded p-4 mb-4">
								<p class="text-blue-300 text-sm">
									<strong>Performance:</strong> This bulk operation is significantly faster than reading pins individually.
								</p>
							</div>
							<div class="bg-gray-900 rounded p-4">
								<h4 class="font-semibold text-yellow-400 mb-2">Example</h4>
								<pre class="text-gray-300"><code>// Read all inputs at once
device.get_digital_inputs()?;

// Access individual pin states
for pin in 1..=10 {`{`}
    if device.pins[pin - 1].digital_input {`{`}
        println!(\"Pin {`{`}{`}`} is HIGH\", pin);
    {`}`}
{`}`}</code></pre>
							</div>
						</div>
					</section>

					<!-- Digital Output -->
					<section id="digital-output" class="mb-12">
						<h2 class="text-2xl font-bold mb-6 text-white">Digital Output</h2>
						
						<!-- set_digital_output -->
						<div class="bg-gray-800 rounded-lg p-6 mb-6">
							<h3 class="text-xl font-semibold mb-4 text-green-400">set_digital_output</h3>
							<div class="mb-4">
								<pre class="bg-gray-900 rounded p-4 overflow-x-auto"><code class="text-gray-300">pub fn set_digital_output(&mut self, pin: u32, value: bool) -> Result&lt;bool&gt;</code></pre>
							</div>
							<p class="text-gray-300 mb-4">
								Sets the state of a digital output pin. Returns the previous state.
							</p>
							<div class="grid md:grid-cols-2 gap-4 mb-4">
								<div>
									<h4 class="font-semibold text-blue-400 mb-2">Parameters</h4>
									<ul class="text-gray-300 text-sm space-y-1">
										<li><code>pin</code> - Pin number</li>
										<li><code>value</code> - true for HIGH, false for LOW</li>
									</ul>
								</div>
								<div>
									<h4 class="font-semibold text-green-400 mb-2">Returns</h4>
									<ul class="text-gray-300 text-sm space-y-1">
										<li>• Previous pin state</li>
									</ul>
								</div>
							</div>
							<div class="bg-gray-900 rounded p-4">
								<h4 class="font-semibold text-yellow-400 mb-2">Example</h4>
								<pre class="text-gray-300"><code>// Turn on LED on pin 1
device.set_digital_output(1, true)?;

// Toggle pin state
let current_state = device.get_digital_input(1)?;
device.set_digital_output(1, !current_state)?;</code></pre>
							</div>
						</div>

						<!-- write_digital_outputs -->
						<div class="bg-gray-800 rounded-lg p-6 mb-6">
							<h3 class="text-xl font-semibold mb-4 text-green-400">write_digital_outputs</h3>
							<div class="mb-4">
								<pre class="bg-gray-900 rounded p-4 overflow-x-auto"><code class="text-gray-300">pub fn write_digital_outputs(&mut self) -> Result&lt;()&gt;</code></pre>
							</div>
							<p class="text-gray-300 mb-4">
								Writes all digital output states to the device in a single operation. Use this after modifying multiple pin states.
							</p>
							<div class="bg-gray-900 rounded p-4">
								<h4 class="font-semibold text-yellow-400 mb-2">Example</h4>
								<pre class="text-gray-300"><code>// Set multiple outputs
device.pins[0].digital_output = true;  // Pin 1
device.pins[1].digital_output = false; // Pin 2
device.pins[2].digital_output = true;  // Pin 3

// Write all changes at once
device.write_digital_outputs()?;</code></pre>
							</div>
						</div>
					</section>

					<!-- Bulk Operations -->
					<section id="bulk-operations" class="mb-12">
						<h2 class="text-2xl font-bold mb-6 text-white">Bulk Operations</h2>
						
						<!-- read_all_pin_functions -->
						<div class="bg-gray-800 rounded-lg p-6 mb-6">
							<h3 class="text-xl font-semibold mb-4 text-green-400">read_all_pin_functions</h3>
							<div class="mb-4">
								<pre class="bg-gray-900 rounded p-4 overflow-x-auto"><code class="text-gray-300">pub fn read_all_pin_functions(&mut self) -> Result&lt;[PinFunction; 55]&gt;</code></pre>
							</div>
							<p class="text-gray-300 mb-4">
								Reads all pin function configurations in a single operation. Provides 55x performance improvement over individual reads.
							</p>
							<div class="bg-green-900/20 border border-green-500/30 rounded p-4 mb-4">
								<p class="text-green-300 text-sm">
									<strong>Performance:</strong> 55x fewer commands compared to reading pins individually.
								</p>
							</div>
							<div class="bg-gray-900 rounded p-4">
								<h4 class="font-semibold text-yellow-400 mb-2">Example</h4>
								<pre class="text-gray-300"><code>let functions = device.read_all_pin_functions()?;
for (pin, function) in functions.iter().enumerate() {`{`}
    println!(\"Pin {`{`}{`}`}: {`{`}:?{`}`}\", pin + 1, function);
{`}`}</code></pre>
							</div>
						</div>

						<!-- set_all_pin_functions -->
						<div class="bg-gray-800 rounded-lg p-6 mb-6">
							<h3 class="text-xl font-semibold mb-4 text-green-400">set_all_pin_functions</h3>
							<div class="mb-4">
								<pre class="bg-gray-900 rounded p-4 overflow-x-auto"><code class="text-gray-300">pub fn set_all_pin_functions(&mut self, functions: &[PinFunction; 55]) -> Result&lt;()&gt;</code></pre>
							</div>
							<p class="text-gray-300 mb-4">
								Sets all pin functions in a bulk operation. Ideal for device initialization and configuration restoration.
							</p>
							<div class="bg-gray-900 rounded p-4">
								<h4 class="font-semibold text-yellow-400 mb-2">Example</h4>
								<pre class="text-gray-300"><code>let mut functions = [PinFunction::Disabled; 55];
functions[0] = PinFunction::DigitalOutput; // Pin 1
functions[1] = PinFunction::DigitalInput;  // Pin 2
functions[21] = PinFunction::PWM;          // Pin 22

device.set_all_pin_functions(&functions)?;</code></pre>
							</div>
						</div>
					</section>

					<!-- Digital Counters -->
					<section id="digital-counters" class="mb-12">
						<h2 class="text-2xl font-bold mb-6 text-white">Digital Counters</h2>
						
						<!-- get_digital_counter -->
						<div class="bg-gray-800 rounded-lg p-6 mb-6">
							<h3 class="text-xl font-semibold mb-4 text-green-400">get_digital_counter</h3>
							<div class="mb-4">
								<pre class="bg-gray-900 rounded p-4 overflow-x-auto"><code class="text-gray-300">pub fn get_digital_counter(&mut self, pin: u32) -> Result&lt;u32&gt;</code></pre>
							</div>
							<p class="text-gray-300 mb-4">
								Reads the current value of a digital counter. Counters increment on rising edges.
							</p>
							<div class="bg-gray-900 rounded p-4">
								<h4 class="font-semibold text-yellow-400 mb-2">Example</h4>
								<pre class="text-gray-300"><code>// Read pulse count on pin 3
let pulse_count = device.get_digital_counter(3)?;
println!(\"Received {`{`}{`}`} pulses\", pulse_count);</code></pre>
							</div>
						</div>

						<!-- reset_digital_counter -->
						<div class="bg-gray-800 rounded-lg p-6 mb-6">
							<h3 class="text-xl font-semibold mb-4 text-green-400">reset_digital_counter</h3>
							<div class="mb-4">
								<pre class="bg-gray-900 rounded p-4 overflow-x-auto"><code class="text-gray-300">pub fn reset_digital_counter(&mut self, pin: u32) -> Result&lt;()&gt;</code></pre>
							</div>
							<p class="text-gray-300 mb-4">
								Resets a digital counter to zero.
							</p>
							<div class="bg-gray-900 rounded p-4">
								<h4 class="font-semibold text-yellow-400 mb-2">Example</h4>
								<pre class="text-gray-300"><code>// Reset counter before measurement
device.reset_digital_counter(3)?;

// ... wait for pulses ...

let new_count = device.get_digital_counter(3)?;</code></pre>
							</div>
						</div>

						<!-- read_digital_counters -->
						<div class="bg-gray-800 rounded-lg p-6 mb-6">
							<h3 class="text-xl font-semibold mb-4 text-green-400">read_digital_counters</h3>
							<div class="mb-4">
								<pre class="bg-gray-900 rounded p-4 overflow-x-auto"><code class="text-gray-300">pub fn read_digital_counters(&mut self) -> Result&lt;()&gt;</code></pre>
							</div>
							<p class="text-gray-300 mb-4">
								Reads all digital counters in a single operation for improved performance.
							</p>
						</div>
					</section>

					<!-- Performance Tips -->
					<section id="performance" class="mb-12">
						<h2 class="text-2xl font-bold mb-6 text-white">Performance Tips</h2>
						<div class="bg-gray-800 rounded-lg p-6">
							<div class="space-y-6">
								<div>
									<h3 class="text-lg font-semibold mb-3 text-green-400">Bulk Operations</h3>
									<div class="grid md:grid-cols-2 gap-4">
										<div class="bg-gray-900 rounded p-4">
											<h4 class="text-red-400 font-semibold mb-2">❌ Slow</h4>
											<pre class="text-gray-300 text-xs"><code>// Individual operations
for pin in 1..=10 {`{`}
    device.set_pin_function(pin, 
        PinFunction::DigitalInput)?;
{`}`}</code></pre>
										</div>
										<div class="bg-gray-900 rounded p-4">
											<h4 class="text-green-400 font-semibold mb-2">✅ Fast</h4>
											<pre class="text-gray-300 text-xs"><code>// Bulk operation
let mut functions = [PinFunction::Disabled; 55];
for i in 0..10 {`{`}
    functions[i] = PinFunction::DigitalInput;
{`}`}
device.set_all_pin_functions(&functions)?;</code></pre>
										</div>
									</div>
								</div>
								
								<div>
									<h3 class="text-lg font-semibold mb-3 text-blue-400">Reading Inputs</h3>
									<ul class="text-gray-300 space-y-1 text-sm">
										<li>• Use <code>get_digital_inputs()</code> for reading multiple pins</li>
										<li>• Cache pin states when possible to avoid repeated reads</li>
										<li>• Use interrupts or polling strategies based on update frequency needs</li>
									</ul>
								</div>

								<div>
									<h3 class="text-lg font-semibold mb-3 text-purple-400">Pin Configuration</h3>
									<ul class="text-gray-300 space-y-1 text-sm">
										<li>• Validate pin capabilities before configuration</li>
										<li>• Group pin function changes and apply in bulk</li>
										<li>• Save configuration after setup to persist across resets</li>
									</ul>
								</div>
							</div>
						</div>
					</section>

					<!-- Best Practices -->
					<section class="mb-12">
						<h2 class="text-2xl font-bold mb-4 text-white">Best Practices</h2>
						<div class="bg-gray-800 rounded-lg p-6">
							<div class="space-y-4">
								<div>
									<h3 class="text-lg font-semibold mb-2 text-green-400">Configuration</h3>
									<ul class="text-gray-300 space-y-1 text-sm">
										<li>• Always validate pin capabilities before setting functions</li>
										<li>• Use device model information to check supported features</li>
										<li>• Configure all pins during initialization for predictable behavior</li>
									</ul>
								</div>
								<div>
									<h3 class="text-lg font-semibold mb-2 text-blue-400">Error Handling</h3>
									<ul class="text-gray-300 space-y-1 text-sm">
										<li>• Handle pin range errors gracefully</li>
										<li>• Check for unsupported capability errors</li>
										<li>• Implement retry logic for critical operations</li>
									</ul>
								</div>
								<div>
									<h3 class="text-lg font-semibold mb-2 text-purple-400">Performance</h3>
									<ul class="text-gray-300 space-y-1 text-sm">
										<li>• Use bulk operations for multiple pin operations</li>
										<li>• Minimize individual pin reads in tight loops</li>
										<li>• Consider using digital counters for pulse counting applications</li>
									</ul>
								</div>
							</div>
						</div>
					</section>
				</div>
			</main>
		</div>
	</body>
</html>