rp_cvideo/
lib.rs

1//! Generate a binary/monochrome composite video signal on the RP2040 and RP235x MCUs
2//!
3//! ## Features
4//! - Clock cycle consistent timing
5//! - Supports progressive and interlaced video
6//! - Supports single and double buffering
7//! - Supports non-standard stuff like:
8//!   - Different number of display lines
9//!   - Bigger or smaller front/back porch (horizontal margins)
10//!   - Fewer or more blank lines on top and bottom
11//!   - Non-square pixels
12//!   - Different frame-rates
13//!   - And more
14//!   - These options can be useful when you're using one of those old 80's CRT monitors with adjustment knobs, which allows
15//!     you - for example - to trade a bit of framerate for vertical resolution or the other way around.
16//! - Uses one only one PIO state-machine (and 13 instructions)
17//! - Supports non-standard system clock frequencies
18//! - Optional [embedded_graphics](https://crates.io/crates/embedded-graphics) driver, which allows you
19//!   to draw common shapes and text.
20//! - Stores pixel data efficiently using 1 bit per pixel. To give an idea, in single-buffer / progressive mode,
21//!   with a resolution of 400x250 you need about 21kb. There is some overhead for all the non visible
22//!   portions of the composite signal.
23//! - Const time configuration. Allows for perfectly sized static buffer allocation and catching
24//!   many configuration mistakes at compile time.
25//!
26//! ## Limitations
27//!  (PR's welcome)
28//! - No colors
29//! - Currently only supports 2 level black/white level monochrome. More levels might be possible with some modifications
30//! - No per line-buffering, it has to keep at least one whole frame/field in memory
31//! - No feedback on being too late with commiting the next frame, other than seeing glitches on your monitor
32//! - No async support
33//!
34//! ## Known issues
35//!  - The (optional) embedded graphics driver doesn't draw correctly in combination with
36//!    the semi-double buffering mode. See example `semi_double_buffered.rs`
37//!
38//! ## Examples
39//! You can find some examples in the directory
40//! [rp-cvideo-examples](https://gitlab.com/kasper256/rust-rp-cvideo/-/tree/main/rp-cvideo-examples)
41//! in the root of the repository.
42//!
43//! ## Hardware
44//! Two digital pins of the MCU are used to generate an analog signal containing 3 discrete voltage levels:
45//! 0.0, 0.3 and 1.0 volt, respectively meaning *sync*, *black* and *white*. The easiest way to make this work is
46//! with the following example schematic:
47//! ```text
48//! ┌─────────────────┐ ┌──────┐
49//! │        GP0(sync)├─┤ 560Ω ├───┐
50//! │ RP              │ └──────┘   │
51//! │ Pico            │ ┌──────┐   │
52//! │       GP1(video)├─┤ 220Ω ├───┴──► composite
53//! │                 │ └──────┘        video
54//! │                 │                 plug
55//! │              GND├───────────────►
56//! └─────────────────┘
57//! ```
58//! *Note* These resistor values are for 3.2v digital pins!
59//!
60//! ## Thanks
61//! * Thanks to the [rp-rs](https://github.com/rp-rs) team for their excellent work that makes this library possible
62//! * Thanks for [batsocks](https://www.batsocks.co.uk/readme/video_timing.htm) for his/hers great reference on the composite video signal
63
64#![no_std]
65#![warn(missing_docs)]
66
67mod cvideo;
68pub use cvideo::{CVideo, CVideoInitResult, CVideoPeripherals};
69pub use rp_cvideo_core::config::{
70    BufferingMode, CVideoConfig, HorizontalConstraint, HorizontalTiming, NTSC_STD_DURATIONS,
71    PAL_STD_DURATIONS, StandardDurations, VerticalConstraint, VerticalTiming,
72};
73pub use rp_cvideo_core::display_buffer::{Canvas, DisplayBuffer, OneField, TwoFields};