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
extern crate spidev;
use std::io::prelude::*;
use self::spidev::{Spidev, SpidevOptions, SPI_MODE_0};
use std::usize;

pub const PANEL_LINE_SIZE: usize = 32;
pub const PANEL_LINE_COUNT: usize = 32;
pub const PANEL_COUNT: usize = 6;
pub const LEDS_PER_PIXEL: usize = 3;

pub const LINE_BUFFER_SIZE: usize = PANEL_LINE_SIZE * LEDS_PER_PIXEL;
pub const PANEL_BUFFER_SIZE: usize = LINE_BUFFER_SIZE * PANEL_LINE_COUNT;
pub const FRAME_BUFFER_SIZE: usize = PANEL_BUFFER_SIZE * PANEL_COUNT;

// Commands:
// 0x01: Line mode
// 0x02: Panel mode
// 0x03: Frame mode
// 0x20: Flush (switch) buffer 

const LINE_MODE: u8 = 0x01;
const PANEL_MODE: u8 = 0x02;
const FRAME_MODE: u8 = 0x03;
const FLUSH: u8 = 0x20;

pub struct Display {
    spi: Spidev
}

impl Display {

    pub fn new(device: &str) -> Display {
        let options = SpidevOptions::new()
            .mode(SPI_MODE_0)
            .bits_per_word(8)
            .max_speed_hz(16_000_000)
            .build();
        let mut spidev = Spidev::open(&device).unwrap();
        spidev.configure(&options).unwrap();
        Display { spi: spidev }
    }

    pub fn write_line(&mut self, panel: u8, line: u8, data: &[u8; LINE_BUFFER_SIZE]) {
        const HEADER_SIZE: usize = 3;
        
        let mut buffer = Vec::with_capacity(HEADER_SIZE + LINE_BUFFER_SIZE);
        let header = [LINE_MODE, panel, line];
        buffer.extend_from_slice(&header);
        buffer.extend_from_slice(&data[..]);

        self.spi.write(&buffer).unwrap();
    }

    // pub fn write_frame(&mut self, data: &[u8; FRAME_BUFFER_SIZE]) {
    pub fn write_frame(&mut self, data: &[u8]) {
        const HEADER_SIZE: usize = 1;
        
        let mut buffer = Vec::with_capacity(HEADER_SIZE + FRAME_BUFFER_SIZE);
        let header = [FRAME_MODE];
        buffer.extend_from_slice(&header);
        buffer.extend_from_slice(&data[..]);

        self.spi.write(&buffer).unwrap();
    }

    pub fn flush(&mut self) {
        self.spi.write(&[FLUSH]).unwrap();
    }
}