rpi_ws281x_sys/
lib.rs

1#![no_std]
2#![allow(non_upper_case_globals)]
3#![allow(non_camel_case_types)]
4#![allow(non_snake_case)]
5
6pub const RPI_HWVER_TYPE_UNKNOWN: u32 = 0;
7pub const RPI_HWVER_TYPE_PI1: u32 = 1;
8pub const RPI_HWVER_TYPE_PI2: u32 = 2;
9pub const RPI_HWVER_TYPE_PI4: u32 = 3;
10pub const RPI_PWM_CHANNELS: u32 = 2;
11pub const RPI_PWM_CTL_MSEN2: u32 = 32768;
12pub const RPI_PWM_CTL_USEF2: u32 = 8192;
13pub const RPI_PWM_CTL_POLA2: u32 = 4096;
14pub const RPI_PWM_CTL_SBIT2: u32 = 2048;
15pub const RPI_PWM_CTL_RPTL2: u32 = 1024;
16pub const RPI_PWM_CTL_MODE2: u32 = 512;
17pub const RPI_PWM_CTL_PWEN2: u32 = 256;
18pub const RPI_PWM_CTL_MSEN1: u32 = 128;
19pub const RPI_PWM_CTL_CLRF1: u32 = 64;
20pub const RPI_PWM_CTL_USEF1: u32 = 32;
21pub const RPI_PWM_CTL_POLA1: u32 = 16;
22pub const RPI_PWM_CTL_SBIT1: u32 = 8;
23pub const RPI_PWM_CTL_RPTL1: u32 = 4;
24pub const RPI_PWM_CTL_MODE1: u32 = 2;
25pub const RPI_PWM_CTL_PWEN1: u32 = 1;
26pub const RPI_PWM_STA_STA4: u32 = 4096;
27pub const RPI_PWM_STA_STA3: u32 = 2048;
28pub const RPI_PWM_STA_STA2: u32 = 1024;
29pub const RPI_PWM_STA_STA1: u32 = 512;
30pub const RPI_PWM_STA_BERR: u32 = 256;
31pub const RPI_PWM_STA_GAP04: u32 = 128;
32pub const RPI_PWM_STA_GAP03: u32 = 64;
33pub const RPI_PWM_STA_GAP02: u32 = 32;
34pub const RPI_PWM_STA_GAP01: u32 = 16;
35pub const RPI_PWM_STA_RERR1: u32 = 8;
36pub const RPI_PWM_STA_WERR1: u32 = 4;
37pub const RPI_PWM_STA_EMPT1: u32 = 2;
38pub const RPI_PWM_STA_FULL1: u32 = 1;
39pub const RPI_PWM_DMAC_ENAB: u32 = 2147483648;
40pub const PWM_OFFSET: u32 = 2146304;
41pub const PWM_PERIPH_PHYS: u32 = 2116075520;
42pub const WS2811_TARGET_FREQ: u32 = 800000;
43pub const SK6812_STRIP_RGBW: u32 = 403703808;
44pub const SK6812_STRIP_RBGW: u32 = 403701768;
45pub const SK6812_STRIP_GRBW: u32 = 403181568;
46pub const SK6812_STRIP_GBRW: u32 = 403177488;
47pub const SK6812_STRIP_BRGW: u32 = 402657288;
48pub const SK6812_STRIP_BGRW: u32 = 402655248;
49pub const SK6812_SHIFT_WMASK: u32 = 4026531840;
50pub const WS2811_STRIP_RGB: u32 = 1050624;
51pub const WS2811_STRIP_RBG: u32 = 1048584;
52pub const WS2811_STRIP_GRB: u32 = 528384;
53pub const WS2811_STRIP_GBR: u32 = 524304;
54pub const WS2811_STRIP_BRG: u32 = 4104;
55pub const WS2811_STRIP_BGR: u32 = 2064;
56pub const WS2812_STRIP: u32 = 528384;
57pub const SK6812_STRIP: u32 = 528384;
58pub const SK6812W_STRIP: u32 = 403181568;
59
60pub type ws2811_led_t = u32;
61
62#[repr(C)]
63#[derive(Debug, Copy, Clone)]
64pub struct rpi_hw_t {
65    pub type_: u32,
66    pub hwver: u32,
67    pub periph_base: u32,
68    pub videocore_base: u32,
69    pub desc: *mut libc::c_char,
70}
71#[repr(C)]
72#[derive(Debug, Copy, Clone)]
73pub struct videocore_mbox_t {
74    pub handle: libc::c_int,
75    pub mem_ref: libc::c_uint,
76    pub bus_addr: libc::c_uint,
77    pub size: libc::c_uint,
78    pub virt_addr: *mut u8,
79}
80#[repr(C)]
81#[derive(Debug, Copy, Clone)]
82pub struct ws2811_device {
83    pub driver_mode: libc::c_int,
84    pub pxl_raw: *mut u8,
85    pub dma: *mut libc::c_void,
86    pub pwm: *mut libc::c_void,
87    pub pcm: *mut libc::c_void,
88    pub spi_fd: libc::c_int,
89    pub dma_cb: *mut libc::c_void,
90    pub dma_cb_addr: u32,
91    pub gpio: *mut libc::c_void,
92    pub cm_clk: *mut libc::c_void,
93    pub mbox: videocore_mbox_t,
94    pub max_count: libc::c_int,
95}
96#[repr(C)]
97#[derive(Debug, Copy, Clone)]
98pub struct ws2811_channel_t {
99    pub gpionum: ::libc::c_int,
100    pub invert: ::libc::c_int,
101    pub count: ::libc::c_int,
102    pub strip_type: ::libc::c_int,
103    pub leds: *mut ws2811_led_t,
104    pub brightness: u8,
105    pub wshift: u8,
106    pub rshift: u8,
107    pub gshift: u8,
108    pub bshift: u8,
109    pub gamma: *mut u8,
110}
111#[repr(C)]
112#[derive(Debug, Copy, Clone)]
113pub struct ws2811_t {
114    pub render_wait_time: u64,
115    pub device: *mut ws2811_device,
116    pub rpi_hw: *const rpi_hw_t,
117    pub freq: u32,
118    pub dmanum: ::libc::c_int,
119    pub channel: [ws2811_channel_t; RPI_PWM_CHANNELS as usize],
120}
121
122#[repr(i32)]
123#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
124pub enum ws2811_return_t {
125    WS2811_SUCCESS = 0,
126    WS2811_ERROR_GENERIC = -1,
127    WS2811_ERROR_OUT_OF_MEMORY = -2,
128    WS2811_ERROR_HW_NOT_SUPPORTED = -3,
129    WS2811_ERROR_MEM_LOCK = -4,
130    WS2811_ERROR_MMAP = -5,
131    WS2811_ERROR_MAP_REGISTERS = -6,
132    WS2811_ERROR_GPIO_INIT = -7,
133    WS2811_ERROR_PWM_SETUP = -8,
134    WS2811_ERROR_MAILBOX_DEVICE = -9,
135    WS2811_ERROR_DMA = -10,
136    WS2811_ERROR_ILLEGAL_GPIO = -11,
137    WS2811_ERROR_PCM_SETUP = -12,
138    WS2811_ERROR_SPI_SETUP = -13,
139    WS2811_ERROR_SPI_TRANSFER = -14,
140}
141
142impl ws2811_return_t {
143    #[inline]
144    ///Gets textual representation of error.
145    ///
146    ///Returns empty string on encoding error.
147    pub fn as_str(self) -> &'static str {
148        let bytes = unsafe {
149            let c_str = ws2811_get_return_t_str(self);
150            let len = libc::strlen(c_str);
151            core::slice::from_raw_parts(c_str as *const u8, len as usize)
152        };
153
154        match core::str::from_utf8(bytes) {
155            Ok(result) => result,
156            Err(_) => "",
157        }
158    }
159}
160
161impl core::fmt::Display for ws2811_return_t {
162    #[inline(always)]
163    fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
164        fmt.write_str(self.as_str())
165    }
166}
167
168extern "C" {
169    ///Allocate and initialize memory, buffers, pages, PWM, DMA, and GPIO.
170    ///
171    ///Initialize following fields before passing to this function
172    ///```c++
173    ///
174    ///const int GPIO_PIN = 18; //PWM
175    ///const int WIDTH = 8;
176    ///const int HEIGHT = 8;
177    ///const int LED_COUNT = WIDTH * HEIGHT;
178    ///const int STRIP_TYPE = WS2811_STRIP_RGB;
179    ///
180    ///ws2811_t ledstring =
181    ///{
182    ///    .freq = WS2811_TARGET_FREQ,
183    ///    .dmanum = 10,
184    ///    .channel =
185    ///    {
186    ///        [0] =
187    ///        {
188    ///            .gpionum = GPIO_PIN,
189    ///            .invert = 0,
190    ///            .count = LED_COUNT,
191    ///            .strip_type = STRIP_TYPE,
192    ///            .brightness = 255,
193    ///        },
194    ///        [1] =
195    ///        {
196    ///            .gpionum = 0,
197    ///            .invert = 0,
198    ///            .count = 0,
199    ///            .brightness = 0,
200    ///        },
201    ///    },
202    ///};
203    ///```
204    ///
205    ///On success returns WS2811_SUCCESS
206    pub fn ws2811_init(ws2811: *mut ws2811_t) -> ws2811_return_t;
207    ///Shut down DMA, PWM, and cleanup memory.
208    pub fn ws2811_fini(ws2811: *mut ws2811_t);
209    ///Renders LEDs onto device.
210    ///
211    ///Can only fail due to DMA/SPI transfer errors
212    pub fn ws2811_render(ws2811: *mut ws2811_t) -> ws2811_return_t;
213    ///Wait for any executing DMA operation to complete before returning.
214    pub fn ws2811_wait(ws2811: *mut ws2811_t) -> ws2811_return_t;
215    ///Gets textual description of error.
216    pub fn ws2811_get_return_t_str(state: ws2811_return_t) -> *const ::libc::c_char;
217    ///Sets gamma factor
218    pub fn ws2811_set_custom_gamma_factor(ws2811: *mut ws2811_t, gamma_factor: f64);
219    ///Determines raspberry pi version
220    pub fn rpi_hw_detect() -> *const rpi_hw_t;
221}