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
use embedded_hal;
use crate::{
    result::*,
    hw::hal,
    kernel::os,
};

/// Rust Embedded HAL interface for Mynewt SPI
impl SPI {
    /// Create a new SPI port
    pub fn new() -> Self {
        SPI {
            spi_num: 0,
            cs_pin:  0,
        }
    }

    /// Initiaise the SPI port
    pub fn init(&mut self, spi_num: i32, cs_pin: i32, spi_settings: *mut hal::hal_spi_settings) 
        -> MynewtResult<()> {
        let rc = unsafe { hal::hal_spi_config(spi_num, spi_settings) };
        assert_eq!(rc, 0, "spi config fail");

        let rc = unsafe { hal::hal_spi_enable(spi_num) };
        assert_eq!(rc, 0, "spi enable fail");

        let rc = unsafe { hal::hal_gpio_init_out(cs_pin, 1) };
        assert_eq!(rc, 0, "spi init fail");
        self.spi_num = spi_num;
        self.cs_pin  = cs_pin;
        Ok(())
    }
}

/// Rust Embedded HAL interface for Mynewt SPI
impl embedded_hal::blocking::spi::Write<u8> for SPI {
    /// Write to the SPI port
    fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
        //  Select the device
        unsafe { hal::hal_gpio_write(self.cs_pin, 0) };
        //  Send the data
        unsafe { hal::hal_spi_txrx(self.spi_num, 
            core::mem::transmute(words.as_ptr()),  //  TX Buffer
            core::ptr::null_mut(),                 //  RX Buffer (don't receive)
            words.len() as i32) };                 //  Length
        //  De-select the device
        unsafe { hal::hal_gpio_write(self.cs_pin, 1) };
        Ok(())
    }

    /// Reuse Mynewt error codes
    type Error = crate::result::MynewtError;
}

/// Rust Embedded HAL interface for Mynewt GPIO
impl GPIO {
    /// Create a new output GPIO pin
    pub fn new() -> Self {
        GPIO {
            pin: 0,
        }
    }

    /// Initialise the output GPIO pin
    pub fn init(&mut self, pin: i32) -> MynewtResult<()> {
        //  TODO: let dc = pins.d0.into_push_pull_output(&mut pins.port);
        //  TODO: let rst = pins.d1.into_push_pull_output(&mut pins.port);
        let rc = unsafe { hal::hal_gpio_init_out(pin, 0) };
        assert_eq!(rc, 0, "gpio fail");
        self.pin = pin;
        Ok(())
    }
}

/// Rust Embedded HAL interface for Mynewt GPIO
impl embedded_hal::digital::v2::OutputPin for GPIO {
    /// Set the GPIO pin to low
    fn set_low(&mut self) -> Result<(), Self::Error> {
        unsafe { hal::hal_gpio_write(self.pin, 0) };
        Ok(())
    }

    /// Set the GPIO pin to high
    fn set_high(&mut self) -> Result<(), Self::Error> {
        unsafe { hal::hal_gpio_write(self.pin, 1) };
        Ok(())
    }

    /// Reuse Mynewt error codes
    type Error = crate::result::MynewtError;
}

/// Rust Embedded HAL interface for Mynewt Delay
impl Delay {
    /// Create a new delay
    pub fn new() -> Self {
        Delay {
        }
    }
}

/// Rust Embedded HAL interface for Mynewt Delay
impl embedded_hal::blocking::delay::DelayMs<u8> for Delay {
    /// Sleep for the specified number of milliseconds
    fn delay_ms(&mut self, ms: u8) {
        //  TODO: Get this constant from Mynewt
        const OS_TICKS_PER_SEC: u32 = 1000;
        let delay_ticks = (ms as u32) * OS_TICKS_PER_SEC / 1000;
        unsafe { os::os_time_delay(delay_ticks) };
    }
}

/// Rust Embedded HAL interface for Mynewt SPI
pub struct SPI {
    /// Mynewt SPI port number
    spi_num: i32,
    /// Mynewt GPIO pin number for Chip Select
    cs_pin: i32,
}

/// Rust Embedded HAL interface for Mynewt GPIO
pub struct GPIO {
    /// Mynewt GPIO pin number
    pin: i32,
}

/// Rust Embedded HAL interface for Mynewt Delay
pub struct Delay {}