From c1b5b69b96fbdab4b8f24d714b5b45bc6d55330f Mon Sep 17 00:00:00 2001 From: Kloenk Date: Fri, 30 Aug 2019 22:00:41 +0200 Subject: [PATCH 1/7] create api --- example/src/main.rs | 39 +- l0dable/build.rs | 3 +- l0dable/src/api/RTC.rs | 56 ++ l0dable/src/api/TRNG.rs | 32 + l0dable/src/api/code.rs | 213 +++++ l0dable/src/api/display.rs | 234 +++++ l0dable/src/api/err.rs | 16 + l0dable/src/api/file.rs | 82 ++ l0dable/src/api/mod.rs | 29 + l0dable/src/api/power.rs | 152 +++ l0dable/src/api/sensors.rs | 58 ++ l0dable/src/bme680.rs | 6 +- l0dable/src/buttons.rs | 11 +- l0dable/src/display.rs | 89 +- l0dable/src/fmt_buffer.rs | 11 +- l0dable/src/framebuffer/font.rs | 9 +- l0dable/src/framebuffer/mod.rs | 35 +- l0dable/src/framebuffer/text.rs | 4 +- l0dable/src/fs.rs | 34 +- l0dable/src/lib.rs | 15 +- l0dable/src/light_sensor.rs | 4 +- l0dable/src/rtc.rs | 2 +- l0dable/src/vibra.rs | 8 +- l0dable/test/bindgen.rs | 1436 +++++++++++++++++++++++++++++ l0dable/test/card10-l0dable-0.1.1 | Bin 0 -> 47104 bytes rkanoid/src/main.rs | 177 ++-- 26 files changed, 2588 insertions(+), 167 deletions(-) create mode 100644 l0dable/src/api/RTC.rs create mode 100644 l0dable/src/api/TRNG.rs create mode 100644 l0dable/src/api/code.rs create mode 100644 l0dable/src/api/display.rs create mode 100644 l0dable/src/api/err.rs create mode 100644 l0dable/src/api/file.rs create mode 100644 l0dable/src/api/mod.rs create mode 100644 l0dable/src/api/power.rs create mode 100644 l0dable/src/api/sensors.rs create mode 100644 l0dable/test/bindgen.rs create mode 100644 l0dable/test/card10-l0dable-0.1.1 diff --git a/example/src/main.rs b/example/src/main.rs index e0a9179..16bb9f6 100644 --- a/example/src/main.rs +++ b/example/src/main.rs @@ -15,6 +15,31 @@ fn main() { fn run() -> Result<(), Error> { writeln!(UART, "Hello from Rust\r")?; + println!( + "battery voltage: {}", + card10_l0dable::api::power::battery_voltage() + ); + println!( + "battery current: {}", + card10_l0dable::api::power::battery_current() + ); + println!( + "charge current: {}", + card10_l0dable::api::power::chargein_current() + ); + println!( + "charge voltage: {}", + card10_l0dable::api::power::chargein_voltage() + ); + println!( + "system voltage: {}", + card10_l0dable::api::power::system_voltage() + ); + println!( + "thermistor voltage: {}", + card10_l0dable::api::power::thermistor_voltage() + ); + let bme = BME680::start(); let a = BHI160::::start()?; let g = BHI160::::start()?; @@ -23,6 +48,8 @@ fn run() -> Result<(), Error> { let display = Display::open(); let light = LightSensor::start(); + let mut on = true; + for t in 0..Display::W { writeln!(UART, "BME: {:?}\r", bme.read())?; writeln!(UART, "A:\r")?; @@ -42,25 +69,25 @@ fn run() -> Result<(), Error> { } display.clear(Color::yellow()); - display.print(160 - t, 10, b"Hello Rust\0", Color::white(), Color::black()); + display.print(160 - t, 10, "Hello Rust\0", Color::white(), Color::black()); let b = Buttons::read(); if b.left_bottom() { - display.print(0, 60, b"LB\0", Color::red(), Color::black()); + display.print(0, 60, "LB\0", Color::red(), Color::black()); vibra::set(true); } if b.right_bottom() { - display.print(80, 60, b"RB\0", Color::red(), Color::black()); + display.print(80, 60, "RB\0", Color::red(), Color::black()); vibra::set(false); } if b.left_top() { - display.print(0, 10, b"LT\0", Color::red(), Color::black()); + display.print(0, 10, "LT\0", Color::red(), Color::black()); } if b.right_top() { - display.print(80, 10, b"RT\0", Color::red(), Color::black()); + display.print(80, 10, "RT\0", Color::red(), Color::black()); } if b.right_top() { - display.print(80, 30, b"Reset\0", Color::red(), Color::black()); + display.print(80, 30, "Reset\0", Color::red(), Color::black()); } writeln!(UART, "Light: {:?}\r", light.get())?; diff --git a/l0dable/build.rs b/l0dable/build.rs index ca52d6b..081febb 100644 --- a/l0dable/build.rs +++ b/l0dable/build.rs @@ -26,7 +26,8 @@ fn main() { .define("BOARD", "card10") .opt_level_str("s") .debug(true) - .flag("-fPIE").flag("-pie") + .flag("-fPIE") + .flag("-pie") .include("../c/epicardium") .include("../c/lib/sdk/Libraries/CMSIS/Device/Maxim/MAX32665/Include") .include("../c/lib/sdk/Libraries/CMSIS/Include") diff --git a/l0dable/src/api/RTC.rs b/l0dable/src/api/RTC.rs new file mode 100644 index 0000000..eb2ff41 --- /dev/null +++ b/l0dable/src/api/RTC.rs @@ -0,0 +1,56 @@ +use super::super::bindings; + +/// Read the current RTC value. +/// +/// # return +/// Unix time in seconds +/// +pub fn get_seconds() -> u32 { + unsafe { bindings::epic_rtc_get_seconds() } +} + +/// Read the current RTC value in ms. +/// +/// # return +/// +/// Unix time in milliseconds +/// +pub fn get_milliseconds() -> u64 { + unsafe { bindings::epic_rtc_get_milliseconds() } +} + +/// Sets the current RTC time in milliseconds +/// +pub fn set_milliseconds(ms: u64) { + unsafe { bindings::epic_rtc_set_milliseconds(ms) } +} + +/// Schedule the RTC alarm for the given timestamp. +/// +/// # Parameters +/// +/// timestamp (uint32_t) – When to schedule the IRQ +/// +/// # return +/// +/// 0 on success or a negative value if an error occured. Possible errors: +/// +/// -EINVAL: RTC is in a bad state +/// +pub fn schedule_alarm(timestamp: u32) -> i32 { + unsafe { bindings::epic_rtc_schedule_alarm(timestamp) } +} + +/// Type check the user-supplied entry function. +#[macro_export] +macro_rules! rtc_isr { + ($path:path) => { + #[export_name = "epic_isr_rtc_alarm"] + pub unsafe fn __epic_isr_rtc_alarm() { + // type check the given path + let f: fn() = $path; + + f() + } + }; +} diff --git a/l0dable/src/api/TRNG.rs b/l0dable/src/api/TRNG.rs new file mode 100644 index 0000000..c64fee3 --- /dev/null +++ b/l0dable/src/api/TRNG.rs @@ -0,0 +1,32 @@ +use super::super::bindings; +use super::code; +use super::err::Error; +pub use super::err::Result; + +/// default size of random numbers to generate +pub const BUFFER_SIZE: usize = 256; + +/// Read random bytes from the TRNG. +/// +/// Parameters +/// +/// * dest (uint8_t) – Destination buffer +/// +/// size – Number of bytes to read. +/// +/// Returns +/// +/// 0 on success or a negative value if an error occured. Possible errors: +/// +/// -EFAULT: Invalid destination address. +/// +pub fn read() -> Result<[u8; BUFFER_SIZE]> { + let mut buffer: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE]; + + let return_code = unsafe { bindings::epic_trng_read(buffer.as_mut_ptr(), BUFFER_SIZE) }; + + if return_code < 0 { + return Err(Error::new_syscal(code::API_TRNG_READ, return_code)); + } + Ok(buffer) +} diff --git a/l0dable/src/api/code.rs b/l0dable/src/api/code.rs new file mode 100644 index 0000000..e8c33e9 --- /dev/null +++ b/l0dable/src/api/code.rs @@ -0,0 +1,213 @@ +pub const API_SYSTEM_EXIT: u32 = 1; +pub const API_SYSTEM_EXEC: u32 = 2; +pub const API_SYSTEM_RESET: u32 = 3; +pub const API_BATTERY_VOLTAGE: u32 = 4; +pub const API_INTERRUPT_ENABLE: u32 = 10; +pub const API_INTERRUPT_DISABLE: u32 = 11; +pub const API_UART_WRITE_STR: u32 = 16; +pub const API_UART_READ_CHAR: u32 = 17; +pub const API_UART_READ_STR: u32 = 18; +pub const API_STREAM_READ: u32 = 31; +pub const API_DISP_OPEN: u32 = 32; +pub const API_DISP_CLOSE: u32 = 33; +pub const API_DISP_PRINT: u32 = 34; +pub const API_DISP_CLEAR: u32 = 35; +pub const API_DISP_UPDATE: u32 = 36; +pub const API_DISP_LINE: u32 = 37; +pub const API_DISP_RECT: u32 = 38; +pub const API_DISP_CIRC: u32 = 39; +pub const API_DISP_PIXEL: u32 = 40; +pub const API_DISP_FRAMEBUFFER: u32 = 41; +pub const API_DISP_BACKLIGHT: u32 = 42; +pub const API_BATTERY_CURRENT: u32 = 49; +pub const API_CHARGEIN_VOLTAGE: u32 = 50; +pub const API_CHARGEIN_CURRENT: u32 = 51; +pub const API_SYSTEM_VOLTAGE: u32 = 52; +pub const API_THERMISTOR_VOLTAGE: u32 = 53; +pub const API_FILE_OPEN: u32 = 64; +pub const API_FILE_CLOSE: u32 = 65; +pub const API_FILE_READ: u32 = 66; +pub const API_FILE_WRITE: u32 = 68; +pub const API_FILE_FLUSH: u32 = 69; +pub const API_FILE_SEEK: u32 = 70; +pub const API_FILE_TELL: u32 = 71; +pub const API_FILE_STAT: u32 = 72; +pub const API_FILE_OPENDIR: u32 = 73; +pub const API_FILE_READDIR: u32 = 74; +pub const API_FILE_UNLINK: u32 = 75; +pub const API_FILE_RENAME: u32 = 76; +pub const API_FILE_MKDIR: u32 = 77; +pub const API_RTC_GET_SECONDS: u32 = 80; +pub const API_RTC_SCHEDULE_ALARM: u32 = 81; +pub const API_RTC_SET_MILLISECONDS: u32 = 82; +pub const API_RTC_GET_MILLISECONDS: u32 = 83; +pub const API_LEDS_SET: u32 = 96; +pub const API_LEDS_SET_HSV: u32 = 97; +pub const API_LEDS_PREP: u32 = 98; +pub const API_LEDS_PREP_HSV: u32 = 99; +pub const API_LEDS_UPDATE: u32 = 100; +pub const API_LEDS_SET_POWERSAVE: u32 = 101; +pub const API_LEDS_SET_ROCKET: u32 = 102; +pub const API_LEDS_SET_FLASHLIGHT: u32 = 103; +pub const API_LEDS_DIM_TOP: u32 = 104; +pub const API_LEDS_DIM_BOTTOM: u32 = 105; +pub const API_LEDS_SET_ALL: u32 = 106; +pub const API_LEDS_SET_ALL_HSV: u32 = 107; +pub const API_LEDS_SET_GAMMA_TABLE: u32 = 108; +pub const API_LEDS_CLEAR_ALL: u32 = 109; +pub const API_VIBRA_SET: u32 = 112; +pub const API_VIBRA_VIBRATE: u32 = 113; +pub const API_LIGHT_SENSOR_RUN: u32 = 128; +pub const API_LIGHT_SENSOR_GET: u32 = 129; +pub const API_LIGHT_SENSOR_STOP: u32 = 130; +pub const API_BUTTONS_READ: u32 = 144; +pub const API_GPIO_SET_PIN_MODE: u32 = 160; +pub const API_GPIO_GET_PIN_MODE: u32 = 161; +pub const API_GPIO_WRITE_PIN: u32 = 162; +pub const API_GPIO_READ_PIN: u32 = 163; +pub const API_TRNG_READ: u32 = 176; +pub const API_PERSONAL_STATE_SET: u32 = 192; +pub const API_PERSONAL_STATE_GET: u32 = 193; +pub const API_PERSONAL_STATE_IS_PERSISTENT: u32 = 194; +pub const API_BME680_INIT: u32 = 208; +pub const API_BME680_DEINIT: u32 = 209; +pub const API_BME680_GET_DATA: u32 = 210; +pub const API_BHI160_ENABLE: u32 = 224; +pub const API_BHI160_DISABLE: u32 = 225; +pub const API_BHI160_DISABLE_ALL: u32 = 226; + +//TODO: Create type and +pub const EPERM: u32 = 1; +pub const ENOENT: u32 = 2; +pub const ESRCH: u32 = 3; +pub const EINTR: u32 = 4; +pub const EIO: u32 = 5; +pub const ENXIO: u32 = 6; +pub const E2BIG: u32 = 7; +pub const ENOEXEC: u32 = 8; +pub const EBADF: u32 = 9; +pub const ECHILD: u32 = 10; +pub const EAGAIN: u32 = 11; +pub const ENOMEM: u32 = 12; +pub const EACCES: u32 = 13; +pub const EFAULT: u32 = 14; +pub const ENOTBLK: u32 = 15; +pub const EBUSY: u32 = 16; +pub const EEXIST: u32 = 17; +pub const EXDEV: u32 = 18; +pub const ENODEV: u32 = 19; +pub const ENOTDIR: u32 = 20; +pub const EISDIR: u32 = 21; +pub const EINVAL: u32 = 22; +pub const ENFILE: u32 = 23; +pub const EMFILE: u32 = 24; +pub const ENOTTY: u32 = 25; +pub const ETXTBSY: u32 = 26; +pub const EFBIG: u32 = 27; +pub const ENOSPC: u32 = 28; +pub const ESPIPE: u32 = 29; +pub const EROFS: u32 = 30; +pub const EMLINK: u32 = 31; +pub const EPIPE: u32 = 32; +pub const EDOM: u32 = 33; +pub const ERANGE: u32 = 34; +pub const EDEADLK: u32 = 35; +pub const ENAMETOOLONG: u32 = 36; +pub const ENOLCK: u32 = 37; +pub const ENOSYS: u32 = 38; +pub const ENOTEMPTY: u32 = 39; +pub const ELOOP: u32 = 40; +pub const EWOULDBLOCK: u32 = 11; +pub const ENOMSG: u32 = 42; +pub const EIDRM: u32 = 43; +pub const ECHRNG: u32 = 44; +pub const EL2NSYNC: u32 = 45; +pub const EL3HLT: u32 = 46; +pub const EL3RST: u32 = 47; +pub const ELNRNG: u32 = 48; +pub const EUNATCH: u32 = 49; +pub const ENOCSI: u32 = 50; +pub const EL2HLT: u32 = 51; +pub const EBADE: u32 = 52; +pub const EBADR: u32 = 53; +pub const EXFULL: u32 = 54; +pub const ENOANO: u32 = 55; +pub const EBADRQC: u32 = 56; +pub const EBADSLT: u32 = 57; +pub const EDEADLOCK: u32 = 35; +pub const EBFONT: u32 = 59; +pub const ENOSTR: u32 = 60; +pub const ENODATA: u32 = 61; +pub const ETIME: u32 = 62; +pub const ENOSR: u32 = 63; +pub const ENONET: u32 = 64; +pub const ENOPKG: u32 = 65; +pub const EREMOTE: u32 = 66; +pub const ENOLINK: u32 = 67; +pub const EADV: u32 = 68; +pub const ESRMNT: u32 = 69; +pub const ECOMM: u32 = 70; +pub const EPROTO: u32 = 71; +pub const EMULTIHOP: u32 = 72; +pub const EDOTDOT: u32 = 73; +pub const EBADMSG: u32 = 74; +pub const EOVERFLOW: u32 = 75; +pub const ENOTUNIQ: u32 = 76; +pub const EBADFD: u32 = 77; +pub const EREMCHG: u32 = 78; +pub const ELIBACC: u32 = 79; +pub const ELIBBAD: u32 = 80; +pub const ELIBSCN: u32 = 81; +pub const ELIBMAX: u32 = 82; +pub const ELIBEXEC: u32 = 83; +pub const EILSEQ: u32 = 84; +pub const ERESTART: u32 = 85; +pub const ESTRPIPE: u32 = 86; +pub const EUSERS: u32 = 87; +pub const ENOTSOCK: u32 = 88; +pub const EDESTADDRREQ: u32 = 89; +pub const EMSGSIZE: u32 = 90; +pub const EPROTOTYPE: u32 = 91; +pub const ENOPROTOOPT: u32 = 92; +pub const EPROTONOSUPPORT: u32 = 93; +pub const ESOCKTNOSUPPORT: u32 = 94; +pub const EOPNOTSUPP: u32 = 95; +pub const EPFNOSUPPORT: u32 = 96; +pub const EAFNOSUPPORT: u32 = 97; +pub const EADDRINUSE: u32 = 98; +pub const EADDRNOTAVAIL: u32 = 99; +pub const ENETDOWN: u32 = 100; +pub const ENETUNREACH: u32 = 101; +pub const ENETRESET: u32 = 102; +pub const ECONNABORTED: u32 = 103; +pub const ECONNRESET: u32 = 104; +pub const ENOBUFS: u32 = 105; +pub const EISCONN: u32 = 106; +pub const ENOTCONN: u32 = 107; +pub const ESHUTDOWN: u32 = 108; +pub const ETOOMANYREFS: u32 = 109; +pub const ETIMEDOUT: u32 = 110; +pub const ECONNREFUSED: u32 = 111; +pub const EHOSTDOWN: u32 = 112; +pub const EHOSTUNREACH: u32 = 113; +pub const EALREADY: u32 = 114; +pub const EINPROGRESS: u32 = 115; +pub const ESTALE: u32 = 116; +pub const EUCLEAN: u32 = 117; +pub const ENOTNAM: u32 = 118; +pub const ENAVAIL: u32 = 119; +pub const EISNAM: u32 = 120; +pub const EREMOTEIO: u32 = 121; +pub const EDQUOT: u32 = 122; +pub const ENOMEDIUM: u32 = 123; +pub const EMEDIUMTYPE: u32 = 124; +pub const ECANCELED: u32 = 125; +pub const ENOKEY: u32 = 126; +pub const EKEYEXPIRED: u32 = 127; +pub const EKEYREVOKED: u32 = 128; +pub const EKEYREJECTED: u32 = 129; +pub const EOWNERDEAD: u32 = 130; +pub const ENOTRECOVERABLE: u32 = 131; +pub const ERFKILL: u32 = 132; +pub const EHWPOISON: u32 = 133; +pub const ENOTSUP: u32 = 95; diff --git a/l0dable/src/api/display.rs b/l0dable/src/api/display.rs new file mode 100644 index 0000000..f83504b --- /dev/null +++ b/l0dable/src/api/display.rs @@ -0,0 +1,234 @@ +use super::super::bindings; +use super::err::{Error, Result}; + +/// open display for use +/// +/// # return +/// 0 on success or a negative value in case of an error: +/// +/// -EBUSY: Display was already locked from another task. +/// +pub fn open() -> i32 { + let ret = unsafe { bindings::epic_disp_open() }; + return ret; +} + +/// Unlocks the display again. +/// +/// # return +/// +/// 0 on success or a negative value in case of an error: +/// +/// -EBUSY: Display was already locked from another task. +/// +pub fn close() -> i32 { + unsafe { bindings::epic_disp_close() } +} + +/// Causes the changes that have been written to the +/// framebuffer to be shown on the display +/// +/// # return +/// 0 on success or a negative value in case of an error: +/// +/// -EBUSY: Display was already locked from another task. +/// +pub fn update() -> i32 { + unsafe { bindings::epic_disp_update() } +} + +/// Fills the whole screen with one color +/// +/// # Parameters +/// +/// color – fill color in rgb565 +/// +/// # return +/// +/// 0 on success or a negative value in case of an error: +/// +/// -EBUSY: Display was already locked from another task. +pub fn clear(color: u16) -> i32 { + unsafe { bindings::epic_disp_clear(color) } +} + +/// Set the backlight brightness value +/// +/// # Parameters +/// +/// brightness – brightness from 0 - 100 +/// +/// # return +/// +/// 0 on success or negative value in case of an error: +/// +/// -EBUSY: Display was already locked from another task. +pub fn backlight(brightness: u16) -> i32 { + unsafe { bindings::epic_disp_backlight(brightness) } +} + +/// Draws a pixel on the display +/// +/// # Parameters +/// +/// x – x position; 0 <= x <= 160 +/// +/// y – y position; 0 <= y <= 80 +/// +/// color – pixel color in rgb565 +/// +/// # return +/// +/// 0 on success or a negative value in case of an error: +/// +/// -EBUSY: Display was already locked from another task. +/// +pub fn pixel(x: u16, y: u16, color: u16) -> i32 { + unsafe { bindings::epic_disp_pixel(x, y, color) } +} + +/// Draws a line on the display +/// +/// # Parameters +/// +/// xstart – x starting position; 0 <= x <= 160 +/// +/// ystart – y starting position; 0 <= y <= 80 +/// +/// xend – x ending position; 0 <= x <= 160 +/// +/// yend – y ending position; 0 <= y <= 80 +/// +/// color – line color in rgb565 +/// +/// linestyle – 0 for solid, 1 for dottet (almost no visual difference) +/// +/// pixelsize – thickness of the line; 1 <= pixelsize <= 8 +/// +/// # return +/// +/// 0 on success or a negative value in case of an error: +/// +/// -EBUSY: Display was already locked from another task. +/// +pub fn line( + xstart: u16, + ystart: u16, + xend: u16, + yend: u16, + color: u16, + linestyle: u32, + pixelsize: u16, +) -> i32 { + unsafe { bindings::epic_disp_line(xstart, ystart, xend, yend, color, linestyle, pixelsize) } +} + +/// Draws a rectangle on the display +/// +/// # Parameters +/// +/// xstart – x coordinate of top left corner; 0 <= x <= 160 +/// +/// ystart – y coordinate of top left corner; 0 <= y <= 80 +/// +/// xend – x coordinate of bottom right corner; 0 <= x <= 160 +/// +/// yend – y coordinate of bottom right corner; 0 <= y <= 80 +/// +/// color – line color in rgb565 +/// +/// fillstyle – 0 for empty, 1 for filled +/// +/// pixelsize – thickness of the rectangle outline; 1 <= pixelsize <= 8 +/// +/// # return +/// +/// 0 on success or a negative value in case of an error: +/// +/// -EBUSY: Display was already locked from another task. +/// +pub fn rect( + xstart: u16, + ystart: u16, + xend: u16, + yend: u16, + color: u16, + fillstyle: u32, + pixelsize: u16, +) -> i32 { + unsafe { bindings::epic_disp_rect(xstart, xend, ystart, yend, color, fillstyle, pixelsize) } +} + +/// Draws a circle on the display +/// +/// # Parameters +/// +/// x – x coordinate of the center; 0 <= x <= 160 +/// +/// y – y coordinate of the center; 0 <= y <= 80 +/// +/// rad – radius of the circle +/// +/// color – fill and outline color of the circle (rgb565) +/// +/// fillstyle – 0 for empty, 1 for filled +/// +/// pixelsize – thickness of the circle outline; 1 <= pixelsize <= 8 +/// +/// # return +/// +/// 0 on success or a negative value in case of an error: +/// +/// -EBUSY: Display was already locked from another task. +/// +pub fn circ(x: u16, y: u16, rad: u16, color: u16, fillstyle: u32, pixelsize: u16) -> i32 { + unsafe { bindings::epic_disp_circ(x, y, rad, color, fillstyle, pixelsize) } +} + +/// Prints a string into the display framebuffer +/// +/// # Parameters +/// +/// posx – x position to print to. 0 <= x <= 160 +/// +/// posy – y position to print to. 0 <= y <= 80 +/// +/// pString – string to print (null pointer terminated) +/// +/// fg – foreground color in rgb565 +/// +/// bg – background color in rgb565 +/// +/// # return +/// +/// 0 on success or a negative value in case of an error: +/// +/// -EBUSY: Display was already locked from another task. +/// +pub fn print(posx: u16, posy: u16, pString: &str, fg: u16, bg: u16) -> i32 { + unsafe { bindings::epic_disp_print(posx, posy, pString.as_ptr(), fg, bg) } +} + +/// Prints a u8 array into the display framebuffer +/// +/// # Parameters +/// +/// posx – x position to print to. 0 <= x <= 160 +/// +/// posy – y position to print to. 0 <= y <= 80 +/// +/// pString – string to print +/// +/// fg – foreground color in rgb565 +/// +/// bg – background color in rgb565 +/// +/// # return +/// +/// 0 on success or a negative value in case of an error: +/// +/// -EBUSY: Display was already locked from another task. +/// +pub fn print_u8(posx: u16, posy: u16, pString: &[u8], fg: u16, bg: u16) -> i32 { + unsafe { bindings::epic_disp_print(posx, posy, pString.as_ptr(), fg, bg) } +} diff --git a/l0dable/src/api/err.rs b/l0dable/src/api/err.rs new file mode 100644 index 0000000..0a9117a --- /dev/null +++ b/l0dable/src/api/err.rs @@ -0,0 +1,16 @@ +pub type Result = core::result::Result; + +pub struct Error { + syscall: u32, + error: i32, +} + +impl Error { + pub fn new_syscal(syscall: u32, error: i32) -> Self { + Self { syscall, error } + } + + pub fn is_ok(&self) -> bool { + self.error != 0 + } +} diff --git a/l0dable/src/api/file.rs b/l0dable/src/api/file.rs new file mode 100644 index 0000000..961e3c3 --- /dev/null +++ b/l0dable/src/api/file.rs @@ -0,0 +1,82 @@ +use super::super::bindings; +use super::code; +use super::err::Error; +pub use super::err::Result; + +/// The open() function opens the file whose name is +/// the string pointed to by pathname and associates a +/// stream with it. +/// +/// The argument mode points to a string beginning with +/// one of the following sequences (possibly followed +/// by additional characters, as described below): +/// +/// r +/// +/// Open text file for reading. The stream is positioned at the beginning of the file. +/// r+ +/// +/// Open for reading and writing. The stream is positioned at the beginning of the file. +/// w +/// +/// Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file. +/// w+ +/// +/// Open for reading and writing. The file is created if it does not exist, otherwise it is truncated. The stream is positioned at the beginning of the file. +/// a +/// +/// Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned at the end of the file. +/// a+ +/// +/// Open for reading and appending (writing at end of file). The file is created if it does not exist. Output is always appended to the end of the file. POSIX is silent on what the initial read position is when using this mode. For glibc, the initial file position for reading is at the beginning of the file, but for Android/BSD/MacOS, the initial file position for reading is at the end of the file. +/// +pub fn open(filename: &str, mode: &str) -> i32 { + unsafe { bindings::epic_file_open(filename.as_ptr(), mode.as_ptr()) } +} + +/// Close file descriptor +pub fn close(fd: i32) -> i32 { + unsafe { bindings::epic_file_close(fd) } +} + +/// buffer size for read function +pub const BUFFER_SIZE: usize = 512; + +/// read from file iwith `BUFFER_SIZE` +pub fn read(fd: i32) -> Result<[u8; BUFFER_SIZE]> { + let mut buf: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE]; + let ptr = buf.as_mut_ptr(); + let ptr: *mut core::ffi::c_void = ptr as *mut core::ffi::c_void; + let return_code = unsafe { bindings::epic_file_read(fd, ptr, BUFFER_SIZE) }; + if return_code < 0 { + return Err(Error::new_syscal(code::API_FILE_READ, return_code)); + } + Ok(buf) +} + +/// write to file +pub fn write_u8(fd: i32, buf: &[u8]) -> i32 { + unsafe { bindings::epic_file_write(fd, buf.as_ptr() as *const core::ffi::c_void, buf.len()) } +} + +/// write to file +pub fn write(fd: i32, pString: &str) -> i32 { + write_u8(fd, pString.as_bytes()) +} + +/// flush file +pub fn flush(fd: i32) -> i32 { + unsafe { bindings::epic_file_flush(fd) } +} + +/// seek in file +pub fn seek(fd: i32, offset: i32, whence: i32) -> i32 { + unsafe { bindings::epic_file_seek(fd, offset, whence) } +} + +/// tell file +pub fn tell(fd: i32) -> i32 { + unsafe { bindings::epic_file_tell(fd) } +} + +// FIXME: state foo implement diff --git a/l0dable/src/api/mod.rs b/l0dable/src/api/mod.rs new file mode 100644 index 0000000..d1ec093 --- /dev/null +++ b/l0dable/src/api/mod.rs @@ -0,0 +1,29 @@ +/// codes for syscalls +pub mod code; + +// power related funtions like battery, charger and reset +pub mod power; + +/// display functions +/// +/// This is only intended for internal use. please use `display` +pub mod display; + +/// sensors module +pub mod sensors; + +///Except for epic_file_open(), which models C stdio’s fopen function, +///close, read and write model close(2), read(2) and write(2). All +/// file-related functions return >= 0 on success and -Exyz on failure, +/// with error codes from errno.h (EIO, EINVAL etc.) +pub mod file; + +/// RTC +pub mod RTC; + +/// True Random Number Generator (TRNG) +pub mod TRNG; + +pub mod err; + +pub use err::Result; diff --git a/l0dable/src/api/power.rs b/l0dable/src/api/power.rs new file mode 100644 index 0000000..e1d63bd --- /dev/null +++ b/l0dable/src/api/power.rs @@ -0,0 +1,152 @@ +use super::super::bindings; +use super::code::*; +use super::Result; + +/// read battery voltage +/// +/// # return +/// returns the Voltage of the Battery as a f32 +/// +/// ## Panic +/// This founction should not panic acording to epicardium.h, +/// but will panic if the return value from epicardium is not 0. +pub fn battery_voltage() -> f32 { + let mut ret: f32 = 0.0; + + let return_value = unsafe { bindings::epic_read_battery_voltage(&mut ret) }; + if return_value != 0 { + panic!("battery_voltage() syscall failed: {}", return_value); + } + + ret +} + +/// read battery current +/// +/// # return +/// This function returns the current battery current as f32 +/// +/// ## Panic +/// This founction should not panic acording to epicardium.h, +/// but will panic if the return value from epicardium is not 0. +pub fn battery_current() -> f32 { + let mut ret: f32 = 0.0; + + let return_value = unsafe { bindings::epic_read_battery_current(&mut ret) }; + if return_value != 0 { + panic!("battery_current() syscall failed: {}", return_value); + } + + ret +} + +/// read charge in voltage of the battery +/// +/// # return +/// return a f32 with the current voltag on the usb port +/// +/// ## Panic +/// This founction should not panic acording to epicardium.h, +/// but will panic if the return value from epicardium is not 0. +pub fn chargein_voltage() -> f32 { + let mut ret: f32 = 0.0; + + let return_value = unsafe { bindings::epic_read_chargein_voltage(&mut ret) }; + if return_value != 0 { + panic!("chargein_voltage() syscall failed: {}", return_value); + } + + ret +} + +/// read current of attached charger +/// +/// # return +/// - return a f32 with the current of the charger +/// +/// ## Panic +/// This founction should not panic acording to epicardium.h, +/// but will panic if the return value from epicardium is not 0. +pub fn chargein_current() -> f32 { + let mut ret: f32 = 0.0; + + let return_value = unsafe { bindings::epic_read_chargein_current(&mut ret) }; + if return_value != 0 { + panic!("chargein_current() syscall failed: {}", return_value); + } + + ret +} + +/// read sysem voltage +/// +/// # return +/// - system voltage as f32 +/// +/// ## Panic +/// This founction should not panic acording to epicardium.h, +/// but will panic if the return value from epicardium is not 0. +pub fn system_voltage() -> f32 { + let mut ret: f32 = 0.0; + + let return_value = unsafe { bindings::epic_read_system_voltage(&mut ret) }; + if return_value != 0 { + panic!("system_voltage() syscall failed: {}", return_value); + } + + ret +} + +/// read thermistor voltage +/// +/// # return +/// - system voltage as f32 +/// +/// ## Panic +/// This founction should not panic acording to epicardium.h, +/// but will panic if the return value from epicardium is not 0. +pub fn thermistor_voltage() -> f32 { + let mut ret: f32 = 0.0; + + let return_value = unsafe { bindings::epic_read_thermistor_voltage(&mut ret) }; + if return_value != 0 { + panic!("thermistor_voltage() syscall failed: {}", return_value); + } + + ret +} + +/// reset card10 system completly +/// +/// +pub fn system_reset() { + unsafe { + bindings::epic_system_reset(); + } +} + +/// Stop execution of the current payload and immediately start another payload. +/// +/// # Parameters +/// +/// name (&str) – +/// +/// Name (path) of the new payload to start. This can either be: +/// +/// A path to an .elf file (l0dable). +/// +/// A path to a .py file (will be loaded using Pycardium). +/// +/// A path to a directory (assumed to be a Python module, execution starts with __init__.py in this folder). +/// +/// # return +/// +/// epic_exec() will only return in case loading went wrong. The following error codes can be returned: +/// +/// -ENOENT: File not found. +/// +/// -ENOEXEC: File not a loadable format. +/// +pub fn exec(name: &str) -> i32 { + unsafe { bindings::epic_exec(name.as_ptr() as *mut u8) } +} diff --git a/l0dable/src/api/sensors.rs b/l0dable/src/api/sensors.rs new file mode 100644 index 0000000..3a144af --- /dev/null +++ b/l0dable/src/api/sensors.rs @@ -0,0 +1,58 @@ +use super::super::bindings; + +pub mod light { + use super::super::code; + use super::super::err::Error; + pub use super::super::err::Result; + use super::bindings; + + ///Start continuous readout of the light sensor. Will read light level at preconfigured interval and make it available via epic_light_sensor_get(). + /// + /// If the continuous readout was already running, this function will silently pass. + /// + /// # return + /// + /// 0 if the start was successful or a negative error value if an error occured. Possible errors: + /// + /// -EBUSY: The timer could not be scheduled. + /// + pub fn run() -> i32 { + unsafe { bindings::epic_light_sensor_run() } + } + + /// Get the last light level measured by the continuous readout. + /// + /// # Parameters + /// + /// value (uint16_t*) – where the last light level should be written. + /// + /// # return + /// + /// 0 if the readout was successful or a negative error value. Possible errors: + /// + /// -ENODATA: Continuous readout not currently running. + /// + pub fn get() -> Result { + let mut ret: u16 = 0; + + let return_code = unsafe { bindings::epic_light_sensor_get(&mut ret) }; + if return_code != 0 { + return Err(Error::new_syscal(code::API_LIGHT_SENSOR_GET, return_code)); + } + Ok(ret) + } + + ///Stop continuous readout of the light sensor. + /// + /// If the continuous readout wasn’t running, this function will silently pass. + /// + /// # return + /// + /// 0 if the stop was sucessful or a negative error value if an error occured. Possible errors: + /// + /// -EBUSY: The timer stop could not be scheduled. + /// + pub fn stop() -> i32 { + unsafe { bindings::epic_light_sensor_stop() } + } +} diff --git a/l0dable/src/bme680.rs b/l0dable/src/bme680.rs index d2e3af2..9008349 100644 --- a/l0dable/src/bme680.rs +++ b/l0dable/src/bme680.rs @@ -1,5 +1,5 @@ -use core::mem::uninitialized; use super::bindings::*; +use core::mem::uninitialized; pub struct BME680; pub type SensorData = bme680_sensor_data; @@ -24,6 +24,8 @@ impl BME680 { impl Drop for BME680 { fn drop(&mut self) { - unsafe { epic_bme680_deinit(); } + unsafe { + epic_bme680_deinit(); + } } } diff --git a/l0dable/src/buttons.rs b/l0dable/src/buttons.rs index 5bb633f..9ab3daa 100644 --- a/l0dable/src/buttons.rs +++ b/l0dable/src/buttons.rs @@ -6,12 +6,11 @@ pub struct Buttons { impl Buttons { pub fn read() -> Self { - let mask = - epic_button_BUTTON_LEFT_BOTTOM | - epic_button_BUTTON_RIGHT_BOTTOM | - epic_button_BUTTON_LEFT_TOP | - epic_button_BUTTON_RIGHT_TOP | - epic_button_BUTTON_RESET; + let mask = epic_button_BUTTON_LEFT_BOTTOM + | epic_button_BUTTON_RIGHT_BOTTOM + | epic_button_BUTTON_LEFT_TOP + | epic_button_BUTTON_RIGHT_TOP + | epic_button_BUTTON_RESET; let state = unsafe { epic_buttons_read(mask as u8) }.into(); Buttons { state } } diff --git a/l0dable/src/display.rs b/l0dable/src/display.rs index 84994cb..219fc4a 100644 --- a/l0dable/src/display.rs +++ b/l0dable/src/display.rs @@ -1,3 +1,4 @@ +use super::api; use super::bindings::*; use super::framebuffer::FrameBuffer; @@ -32,9 +33,7 @@ impl Color { pub fn rgb8(r8: u8, g8: u8, b8: u8) -> Self { let c = - ((u16::from(r8) & 0xF8) << 8) | - ((u16::from(g8) & 0xFA) << 3) | - (u16::from(b8) & 0xF8); + ((u16::from(r8) & 0xF8) << 8) | ((u16::from(g8) & 0xFA) << 3) | (u16::from(b8) & 0xF8); Color(c) } @@ -84,46 +83,92 @@ impl Display { pub const FONT_H: u16 = 20; pub fn open() -> Self { - unsafe { epic_disp_open(); } + // return result so it can be blocked by another thread + if api::display::open() != 0 { + unimplemented!(); + } Display } pub fn update(&self) { - unsafe { epic_disp_update(); } + // return error + if api::display::update() != 0 { + panic!(); + } } pub fn clear(&self, color: Color) { - unsafe { epic_disp_clear(color.0); } + if api::display::clear(color.0) != 0 { + panic!(); + } + } + + pub fn backlight(brightness: u16) { + if api::display::backlight(brightness) != 0 { + panic!(); + } } /// s must be 0-terminated - pub fn print(&self, x: u16, y: u16, s: &[u8], fg: Color, bg: Color) { - unsafe { - epic_disp_print(x, y, s.as_ptr(), fg.0, bg.0); + pub fn print(&self, x: u16, y: u16, s: &str, fg: Color, bg: Color) { + if api::display::print(x, y, s, fg.0, bg.0) != 0 { + panic!(); + } + } + + pub fn print_u8(&self, x: u16, y: u16, s: &[u8], fg: Color, bg: Color) { + if api::display::print_u8(x, y, s, fg.0, bg.0) != 0 { + panic!(); } } pub fn pixel(&self, x: u16, y: u16, color: Color) { - unsafe { - epic_disp_pixel(x, y, color.0); + if api::display::pixel(x, y, color.0) != 0 { + panic!(); } } - pub fn line(&self, x1: u16, y1: u16, x2: u16, y2: u16, color: Color, linestyle: LineStyle, pixelsize: u16) { - unsafe { - epic_disp_line(x1, y1, x2, y2, color.0, linestyle as u32, pixelsize); + pub fn line( + &self, + x1: u16, + y1: u16, + x2: u16, + y2: u16, + color: Color, + linestyle: LineStyle, + pixelsize: u16, + ) { + if api::display::line(x1, y1, x2, y2, color.0, linestyle as u32, pixelsize) != 0 { + panic!(); } } - pub fn rect(&self, x1: u16, y1: u16, x2: u16, y2: u16, color: Color, fillstyle: FillStyle, pixelsize: u16) { - unsafe { - epic_disp_rect(x1, y1, x2, y2, color.0, fillstyle as u32, pixelsize); + pub fn rect( + &self, + x1: u16, + y1: u16, + x2: u16, + y2: u16, + color: Color, + fillstyle: FillStyle, + pixelsize: u16, + ) { + if api::display::rect(x1, y1, x2, y2, color.0, fillstyle as u32, pixelsize) != 0 { + panic!(); } } - pub fn circ(&self, x: u16, y: u16, rad: u16, color: Color, fillstyle: FillStyle, pixelsize: u16) { - unsafe { - epic_disp_circ(x, y, rad, color.0, fillstyle as u32, pixelsize); + pub fn circ( + &self, + x: u16, + y: u16, + rad: u16, + color: Color, + fillstyle: FillStyle, + pixelsize: u16, + ) { + if api::display::circ(x, y, rad, color.0, fillstyle as u32, pixelsize) != 0 { + panic!(); } } @@ -134,6 +179,8 @@ impl Display { impl Drop for Display { fn drop(&mut self) { - unsafe { epic_disp_close(); } + if api::display::close() != 0 { + unimplemented!(); + } } } diff --git a/l0dable/src/fmt_buffer.rs b/l0dable/src/fmt_buffer.rs index a9b6878..4461756 100644 --- a/l0dable/src/fmt_buffer.rs +++ b/l0dable/src/fmt_buffer.rs @@ -24,7 +24,9 @@ impl<'a> fmt::Write for FmtBuffer<'a> { // Skip over already-copied data let remainder = &mut self.buf[self.offset..]; // Check if there is space remaining (return error instead of panicking) - if remainder.len() < bytes.len() { return Err(core::fmt::Error); } + if remainder.len() < bytes.len() { + return Err(core::fmt::Error); + } // Make the two slices the same length let remainder = &mut remainder[..bytes.len()]; // Copy @@ -47,10 +49,7 @@ pub fn str_to_cstr(s: &str) -> [u8; 256] { impl AsRef for FmtBuffer<'_> { fn as_ref(&self) -> &str { - let len = self.buf.iter().position(|b| *b == 0) - .unwrap_or(0); - unsafe { - from_utf8_unchecked(&self.buf[0..len]) - } + let len = self.buf.iter().position(|b| *b == 0).unwrap_or(0); + unsafe { from_utf8_unchecked(&self.buf[0..len]) } } } diff --git a/l0dable/src/framebuffer/font.rs b/l0dable/src/framebuffer/font.rs index 6875046..d061049 100644 --- a/l0dable/src/framebuffer/font.rs +++ b/l0dable/src/framebuffer/font.rs @@ -31,16 +31,19 @@ impl Font { pub fn font24() -> &'static Self { unsafe { &Font24 } } - + fn bytes_per_row(&self) -> usize { self.w as usize / 8 + 1 } - + pub fn get_glyph(&self, c: char) -> Option { let h = self.h as usize; let bytes_per_row = self.bytes_per_row(); let table = unsafe { - from_raw_parts(self.table, ('~' as usize - (' ' as usize) - 1) * bytes_per_row * h) + from_raw_parts( + self.table, + ('~' as usize - (' ' as usize) - 1) * bytes_per_row * h, + ) }; let offset = (c as usize - (' ' as usize)) * bytes_per_row * h; if offset < table.len() { diff --git a/l0dable/src/framebuffer/mod.rs b/l0dable/src/framebuffer/mod.rs index 2794369..a1d1b5f 100644 --- a/l0dable/src/framebuffer/mod.rs +++ b/l0dable/src/framebuffer/mod.rs @@ -1,7 +1,7 @@ -use core::mem::{transmute, uninitialized}; -use core::ops::{Index, IndexMut}; use crate::bindings::*; use crate::Display; +use core::mem::{transmute, uninitialized}; +use core::ops::{Index, IndexMut}; mod font; pub use font::*; @@ -13,14 +13,11 @@ pub struct FrameBuffer<'d> { buffer: disp_framebuffer, } - impl<'d> FrameBuffer<'d> { pub fn uninitialized(display: &'d Display) -> Self { FrameBuffer { _display: display, - buffer: unsafe { - uninitialized() - }, + buffer: unsafe { uninitialized() }, } } @@ -33,18 +30,26 @@ impl<'d> FrameBuffer<'d> { pub fn clear(&mut self, color: RawColor) { for y in 0..Display::H { for x in 0..Display::W { - let bytes: &mut RawColor = unsafe { - transmute(&mut self.buffer.fb[y as usize][x as usize]) - }; + let bytes: &mut RawColor = + unsafe { transmute(&mut self.buffer.fb[y as usize][x as usize]) }; *bytes = color; } } } - pub fn text<'a, 'f>(&'a mut self, x: isize, y: isize, font: &'f Font, color: RawColor) -> TextRenderer<'a, 'd, 'f> { + pub fn text<'a, 'f>( + &'a mut self, + x: isize, + y: isize, + font: &'f Font, + color: RawColor, + ) -> TextRenderer<'a, 'd, 'f> { TextRenderer { framebuffer: self, - x, y, font, color, + x, + y, + font, + color, } } } @@ -54,9 +59,7 @@ impl<'d> Index<(u16, u16)> for FrameBuffer<'d> { fn index(&self, (x, y): (u16, u16)) -> &Self::Output { let x = usize::from(Display::W - 1 - x); let y = usize::from(Display::H - 1 - y); - unsafe { - transmute(&self.buffer.fb[y][x]) - } + unsafe { transmute(&self.buffer.fb[y][x]) } } } @@ -64,9 +67,7 @@ impl<'d> IndexMut<(u16, u16)> for FrameBuffer<'d> { fn index_mut(&mut self, (x, y): (u16, u16)) -> &mut Self::Output { let x = usize::from(Display::W - 1 - x); let y = usize::from(Display::H - 1 - y); - unsafe { - transmute(&mut self.buffer.fb[y][x]) - } + unsafe { transmute(&mut self.buffer.fb[y][x]) } } } diff --git a/l0dable/src/framebuffer/text.rs b/l0dable/src/framebuffer/text.rs index 118e775..cb30d1f 100644 --- a/l0dable/src/framebuffer/text.rs +++ b/l0dable/src/framebuffer/text.rs @@ -1,6 +1,6 @@ +use super::{Font, FrameBuffer, RawColor}; +use crate::Display; use core::fmt::Write; -use super::{FrameBuffer, Font, RawColor}; -use crate::{Display}; pub struct TextRenderer<'a, 'd, 'f> { pub framebuffer: &'a mut FrameBuffer<'d>, diff --git a/l0dable/src/fs.rs b/l0dable/src/fs.rs index d5f89f2..e32db8f 100644 --- a/l0dable/src/fs.rs +++ b/l0dable/src/fs.rs @@ -1,6 +1,6 @@ -use core::str::from_utf8_unchecked; -use core::mem::uninitialized; use super::bindings::*; +use core::mem::uninitialized; +use core::str::from_utf8_unchecked; type Result = core::result::Result; @@ -28,9 +28,7 @@ impl From for Error { pub fn read_dir(path: &str) -> Result { let pathbuf = crate::str_to_cstr(path); - Error::check(|| unsafe { - epic_file_opendir(pathbuf.as_ptr()) - }).map(|fd| ReadDir { fd }) + Error::check(|| unsafe { epic_file_opendir(pathbuf.as_ptr()) }).map(|fd| ReadDir { fd }) } pub struct ReadDir { @@ -97,20 +95,15 @@ impl DirStat { } pub fn name(&self) -> &str { - let len = self.entry.name.iter().position(|b| *b == 0) - .unwrap_or(0); - unsafe { - from_utf8_unchecked(&self.entry.name[0..len]) - } + let len = self.entry.name.iter().position(|b| *b == 0).unwrap_or(0); + unsafe { from_utf8_unchecked(&self.entry.name[0..len]) } } } pub fn rename(from: &str, to: &str) -> Result<()> { let frombuf = crate::str_to_cstr(from); let tobuf = crate::str_to_cstr(to); - Error::check(|| unsafe { - epic_file_rename(frombuf.as_ptr(), tobuf.as_ptr()) - }).map(|_| ()) + Error::check(|| unsafe { epic_file_rename(frombuf.as_ptr(), tobuf.as_ptr()) }).map(|_| ()) } pub struct File { @@ -121,21 +114,22 @@ impl File { pub fn open(path: &str) -> Result { let pathbuf = crate::str_to_cstr(path); let modebuf = b"r\0"; - Error::check(|| unsafe { - epic_file_open(pathbuf.as_ptr(), modebuf.as_ptr()) - }).map(|fd| File { fd }) + Error::check(|| unsafe { epic_file_open(pathbuf.as_ptr(), modebuf.as_ptr()) }) + .map(|fd| File { fd }) } pub fn read<'a>(&mut self, buf: &'a mut [u8]) -> Result<&'a [u8]> { - let bytes = Error::check(|| unsafe { - epic_file_read(self.fd, buf.as_ptr() as *mut _, buf.len()) - })? as usize; + let bytes = + Error::check(|| unsafe { epic_file_read(self.fd, buf.as_ptr() as *mut _, buf.len()) })? + as usize; Ok(&buf[0..bytes]) } } impl Drop for File { fn drop(&mut self) { - unsafe { epic_file_close(self.fd); } + unsafe { + epic_file_close(self.fd); + } } } diff --git a/l0dable/src/lib.rs b/l0dable/src/lib.rs index b844408..0b73f6a 100644 --- a/l0dable/src/lib.rs +++ b/l0dable/src/lib.rs @@ -113,20 +113,20 @@ pub mod bindings { mod os; pub use os::*; mod display; -pub use display::{Display, Color, LineStyle, FillStyle}; -pub mod framebuffer; +pub use display::{Color, Display, FillStyle, LineStyle}; mod buttons; +pub mod framebuffer; pub use buttons::Buttons; pub mod uart; pub const UART: uart::Uart = uart::Uart; mod light_sensor; pub use light_sensor::LightSensor; -pub mod vibra; -pub mod trng; mod rtc; -pub use rtc::{Seconds, MilliSeconds, Time}; +pub mod trng; +pub mod vibra; +pub use rtc::{MilliSeconds, Seconds, Time}; mod fmt_buffer; -pub use fmt_buffer::{FmtBuffer, str_to_cstr}; +pub use fmt_buffer::{str_to_cstr, FmtBuffer}; mod bme680; pub use bme680::BME680; mod bhi160; @@ -135,3 +135,6 @@ pub use bhi160::{ SensorData as BHI160Data, }; pub mod fs; + +/// api calls to epicardium +pub mod api; diff --git a/l0dable/src/light_sensor.rs b/l0dable/src/light_sensor.rs index a6aa167..1a39c75 100644 --- a/l0dable/src/light_sensor.rs +++ b/l0dable/src/light_sensor.rs @@ -25,6 +25,8 @@ impl LightSensor { impl Drop for LightSensor { fn drop(&mut self) { - unsafe { epic_light_sensor_stop(); } + unsafe { + epic_light_sensor_stop(); + } } } diff --git a/l0dable/src/rtc.rs b/l0dable/src/rtc.rs index d7741f4..7c6188a 100644 --- a/l0dable/src/rtc.rs +++ b/l0dable/src/rtc.rs @@ -1,5 +1,5 @@ -use core::ops::Sub; use super::bindings::*; +use core::ops::Sub; pub trait Time { fn time() -> Self; diff --git a/l0dable/src/vibra.rs b/l0dable/src/vibra.rs index 963634c..9fbe19b 100644 --- a/l0dable/src/vibra.rs +++ b/l0dable/src/vibra.rs @@ -1,9 +1,13 @@ use super::bindings::*; pub fn set(status: bool) { - unsafe { epic_vibra_set(status.into()); } + unsafe { + epic_vibra_set(status.into()); + } } pub fn vibrate(millis: i32) { - unsafe { epic_vibra_vibrate(millis); } + unsafe { + epic_vibra_vibrate(millis); + } } diff --git a/l0dable/test/bindgen.rs b/l0dable/test/bindgen.rs new file mode 100644 index 0000000..5ee4017 --- /dev/null +++ b/l0dable/test/bindgen.rs @@ -0,0 +1,1436 @@ +/* automatically generated by rust-bindgen */ + +pub const _STDINT_H: u32 = 1; +pub const _FEATURES_H: u32 = 1; +pub const _DEFAULT_SOURCE: u32 = 1; +pub const __USE_ISOC11: u32 = 1; +pub const __USE_ISOC99: u32 = 1; +pub const __USE_ISOC95: u32 = 1; +pub const __USE_POSIX_IMPLICITLY: u32 = 1; +pub const _POSIX_SOURCE: u32 = 1; +pub const _POSIX_C_SOURCE: f64 = 200809.0; +pub const __USE_POSIX: u32 = 1; +pub const __USE_POSIX2: u32 = 1; +pub const __USE_POSIX199309: u32 = 1; +pub const __USE_POSIX199506: u32 = 1; +pub const __USE_XOPEN2K: u32 = 1; +pub const __USE_XOPEN2K8: u32 = 1; +pub const _ATFILE_SOURCE: u32 = 1; +pub const __USE_MISC: u32 = 1; +pub const __USE_ATFILE: u32 = 1; +pub const __USE_FORTIFY_LEVEL: u32 = 0; +pub const __GLIBC_USE_DEPRECATED_GETS: u32 = 0; +pub const _STDC_PREDEF_H: u32 = 1; +pub const __STDC_IEC_559__: u32 = 1; +pub const __STDC_IEC_559_COMPLEX__: u32 = 1; +pub const __STDC_ISO_10646__: f64 = 201706.0; +pub const __STDC_NO_THREADS__: u32 = 1; +pub const __GNU_LIBRARY__: u32 = 6; +pub const __GLIBC__: u32 = 2; +pub const __GLIBC_MINOR__: u32 = 27; +pub const _SYS_CDEFS_H: u32 = 1; +pub const __glibc_c99_flexarr_available: u32 = 1; +pub const __WORDSIZE: u32 = 64; +pub const __WORDSIZE_TIME64_COMPAT32: u32 = 1; +pub const __SYSCALL_WORDSIZE: u32 = 64; +pub const __HAVE_GENERIC_SELECTION: u32 = 1; +pub const __GLIBC_USE_LIB_EXT2: u32 = 0; +pub const __GLIBC_USE_IEC_60559_BFP_EXT: u32 = 0; +pub const __GLIBC_USE_IEC_60559_FUNCS_EXT: u32 = 0; +pub const __GLIBC_USE_IEC_60559_TYPES_EXT: u32 = 0; +pub const _BITS_TYPES_H: u32 = 1; +pub const _BITS_TYPESIZES_H: u32 = 1; +pub const __OFF_T_MATCHES_OFF64_T: u32 = 1; +pub const __INO_T_MATCHES_INO64_T: u32 = 1; +pub const __RLIM_T_MATCHES_RLIM64_T: u32 = 1; +pub const __FD_SETSIZE: u32 = 1024; +pub const _BITS_WCHAR_H: u32 = 1; +pub const _BITS_STDINT_INTN_H: u32 = 1; +pub const _BITS_STDINT_UINTN_H: u32 = 1; +pub const INT8_MIN: i32 = -128; +pub const INT16_MIN: i32 = -32768; +pub const INT32_MIN: i32 = -2147483648; +pub const INT8_MAX: u32 = 127; +pub const INT16_MAX: u32 = 32767; +pub const INT32_MAX: u32 = 2147483647; +pub const UINT8_MAX: u32 = 255; +pub const UINT16_MAX: u32 = 65535; +pub const UINT32_MAX: u32 = 4294967295; +pub const INT_LEAST8_MIN: i32 = -128; +pub const INT_LEAST16_MIN: i32 = -32768; +pub const INT_LEAST32_MIN: i32 = -2147483648; +pub const INT_LEAST8_MAX: u32 = 127; +pub const INT_LEAST16_MAX: u32 = 32767; +pub const INT_LEAST32_MAX: u32 = 2147483647; +pub const UINT_LEAST8_MAX: u32 = 255; +pub const UINT_LEAST16_MAX: u32 = 65535; +pub const UINT_LEAST32_MAX: u32 = 4294967295; +pub const INT_FAST8_MIN: i32 = -128; +pub const INT_FAST16_MIN: f64 = -9223372036854776000.0; +pub const INT_FAST32_MIN: f64 = -9223372036854776000.0; +pub const INT_FAST8_MAX: u32 = 127; +pub const INT_FAST16_MAX: f64 = 9223372036854776000.0; +pub const INT_FAST32_MAX: f64 = 9223372036854776000.0; +pub const UINT_FAST8_MAX: u32 = 255; +pub const UINT_FAST16_MAX: i32 = -1; +pub const UINT_FAST32_MAX: i32 = -1; +pub const INTPTR_MIN: f64 = -9223372036854776000.0; +pub const INTPTR_MAX: f64 = 9223372036854776000.0; +pub const UINTPTR_MAX: i32 = -1; +pub const PTRDIFF_MIN: f64 = -9223372036854776000.0; +pub const PTRDIFF_MAX: f64 = 9223372036854776000.0; +pub const SIG_ATOMIC_MIN: i32 = -2147483648; +pub const SIG_ATOMIC_MAX: u32 = 2147483647; +pub const SIZE_MAX: i32 = -1; +pub const WINT_MIN: u32 = 0; +pub const WINT_MAX: u32 = 4294967295; +pub const _ERRNO_H: u32 = 1; +pub const _BITS_ERRNO_H: u32 = 1; +pub const EPERM: u32 = 1; +pub const ENOENT: u32 = 2; +pub const ESRCH: u32 = 3; +pub const EINTR: u32 = 4; +pub const EIO: u32 = 5; +pub const ENXIO: u32 = 6; +pub const E2BIG: u32 = 7; +pub const ENOEXEC: u32 = 8; +pub const EBADF: u32 = 9; +pub const ECHILD: u32 = 10; +pub const EAGAIN: u32 = 11; +pub const ENOMEM: u32 = 12; +pub const EACCES: u32 = 13; +pub const EFAULT: u32 = 14; +pub const ENOTBLK: u32 = 15; +pub const EBUSY: u32 = 16; +pub const EEXIST: u32 = 17; +pub const EXDEV: u32 = 18; +pub const ENODEV: u32 = 19; +pub const ENOTDIR: u32 = 20; +pub const EISDIR: u32 = 21; +pub const EINVAL: u32 = 22; +pub const ENFILE: u32 = 23; +pub const EMFILE: u32 = 24; +pub const ENOTTY: u32 = 25; +pub const ETXTBSY: u32 = 26; +pub const EFBIG: u32 = 27; +pub const ENOSPC: u32 = 28; +pub const ESPIPE: u32 = 29; +pub const EROFS: u32 = 30; +pub const EMLINK: u32 = 31; +pub const EPIPE: u32 = 32; +pub const EDOM: u32 = 33; +pub const ERANGE: u32 = 34; +pub const EDEADLK: u32 = 35; +pub const ENAMETOOLONG: u32 = 36; +pub const ENOLCK: u32 = 37; +pub const ENOSYS: u32 = 38; +pub const ENOTEMPTY: u32 = 39; +pub const ELOOP: u32 = 40; +pub const EWOULDBLOCK: u32 = 11; +pub const ENOMSG: u32 = 42; +pub const EIDRM: u32 = 43; +pub const ECHRNG: u32 = 44; +pub const EL2NSYNC: u32 = 45; +pub const EL3HLT: u32 = 46; +pub const EL3RST: u32 = 47; +pub const ELNRNG: u32 = 48; +pub const EUNATCH: u32 = 49; +pub const ENOCSI: u32 = 50; +pub const EL2HLT: u32 = 51; +pub const EBADE: u32 = 52; +pub const EBADR: u32 = 53; +pub const EXFULL: u32 = 54; +pub const ENOANO: u32 = 55; +pub const EBADRQC: u32 = 56; +pub const EBADSLT: u32 = 57; +pub const EDEADLOCK: u32 = 35; +pub const EBFONT: u32 = 59; +pub const ENOSTR: u32 = 60; +pub const ENODATA: u32 = 61; +pub const ETIME: u32 = 62; +pub const ENOSR: u32 = 63; +pub const ENONET: u32 = 64; +pub const ENOPKG: u32 = 65; +pub const EREMOTE: u32 = 66; +pub const ENOLINK: u32 = 67; +pub const EADV: u32 = 68; +pub const ESRMNT: u32 = 69; +pub const ECOMM: u32 = 70; +pub const EPROTO: u32 = 71; +pub const EMULTIHOP: u32 = 72; +pub const EDOTDOT: u32 = 73; +pub const EBADMSG: u32 = 74; +pub const EOVERFLOW: u32 = 75; +pub const ENOTUNIQ: u32 = 76; +pub const EBADFD: u32 = 77; +pub const EREMCHG: u32 = 78; +pub const ELIBACC: u32 = 79; +pub const ELIBBAD: u32 = 80; +pub const ELIBSCN: u32 = 81; +pub const ELIBMAX: u32 = 82; +pub const ELIBEXEC: u32 = 83; +pub const EILSEQ: u32 = 84; +pub const ERESTART: u32 = 85; +pub const ESTRPIPE: u32 = 86; +pub const EUSERS: u32 = 87; +pub const ENOTSOCK: u32 = 88; +pub const EDESTADDRREQ: u32 = 89; +pub const EMSGSIZE: u32 = 90; +pub const EPROTOTYPE: u32 = 91; +pub const ENOPROTOOPT: u32 = 92; +pub const EPROTONOSUPPORT: u32 = 93; +pub const ESOCKTNOSUPPORT: u32 = 94; +pub const EOPNOTSUPP: u32 = 95; +pub const EPFNOSUPPORT: u32 = 96; +pub const EAFNOSUPPORT: u32 = 97; +pub const EADDRINUSE: u32 = 98; +pub const EADDRNOTAVAIL: u32 = 99; +pub const ENETDOWN: u32 = 100; +pub const ENETUNREACH: u32 = 101; +pub const ENETRESET: u32 = 102; +pub const ECONNABORTED: u32 = 103; +pub const ECONNRESET: u32 = 104; +pub const ENOBUFS: u32 = 105; +pub const EISCONN: u32 = 106; +pub const ENOTCONN: u32 = 107; +pub const ESHUTDOWN: u32 = 108; +pub const ETOOMANYREFS: u32 = 109; +pub const ETIMEDOUT: u32 = 110; +pub const ECONNREFUSED: u32 = 111; +pub const EHOSTDOWN: u32 = 112; +pub const EHOSTUNREACH: u32 = 113; +pub const EALREADY: u32 = 114; +pub const EINPROGRESS: u32 = 115; +pub const ESTALE: u32 = 116; +pub const EUCLEAN: u32 = 117; +pub const ENOTNAM: u32 = 118; +pub const ENAVAIL: u32 = 119; +pub const EISNAM: u32 = 120; +pub const EREMOTEIO: u32 = 121; +pub const EDQUOT: u32 = 122; +pub const ENOMEDIUM: u32 = 123; +pub const EMEDIUMTYPE: u32 = 124; +pub const ECANCELED: u32 = 125; +pub const ENOKEY: u32 = 126; +pub const EKEYEXPIRED: u32 = 127; +pub const EKEYREVOKED: u32 = 128; +pub const EKEYREJECTED: u32 = 129; +pub const EOWNERDEAD: u32 = 130; +pub const ENOTRECOVERABLE: u32 = 131; +pub const ERFKILL: u32 = 132; +pub const EHWPOISON: u32 = 133; +pub const ENOTSUP: u32 = 95; +pub const true_: u32 = 1; +pub const false_: u32 = 0; +pub const __bool_true_false_are_defined: u32 = 1; +pub const API_SYSTEM_EXIT: u32 = 1; +pub const API_SYSTEM_EXEC: u32 = 2; +pub const API_SYSTEM_RESET: u32 = 3; +pub const API_BATTERY_VOLTAGE: u32 = 4; +pub const API_INTERRUPT_ENABLE: u32 = 10; +pub const API_INTERRUPT_DISABLE: u32 = 11; +pub const API_UART_WRITE_STR: u32 = 16; +pub const API_UART_READ_CHAR: u32 = 17; +pub const API_UART_READ_STR: u32 = 18; +pub const API_STREAM_READ: u32 = 31; +pub const API_DISP_OPEN: u32 = 32; +pub const API_DISP_CLOSE: u32 = 33; +pub const API_DISP_PRINT: u32 = 34; +pub const API_DISP_CLEAR: u32 = 35; +pub const API_DISP_UPDATE: u32 = 36; +pub const API_DISP_LINE: u32 = 37; +pub const API_DISP_RECT: u32 = 38; +pub const API_DISP_CIRC: u32 = 39; +pub const API_DISP_PIXEL: u32 = 40; +pub const API_DISP_FRAMEBUFFER: u32 = 41; +pub const API_DISP_BACKLIGHT: u32 = 42; +pub const API_BATTERY_CURRENT: u32 = 49; +pub const API_CHARGEIN_VOLTAGE: u32 = 50; +pub const API_CHARGEIN_CURRENT: u32 = 51; +pub const API_SYSTEM_VOLTAGE: u32 = 52; +pub const API_THERMISTOR_VOLTAGE: u32 = 53; +pub const API_FILE_OPEN: u32 = 64; +pub const API_FILE_CLOSE: u32 = 65; +pub const API_FILE_READ: u32 = 66; +pub const API_FILE_WRITE: u32 = 68; +pub const API_FILE_FLUSH: u32 = 69; +pub const API_FILE_SEEK: u32 = 70; +pub const API_FILE_TELL: u32 = 71; +pub const API_FILE_STAT: u32 = 72; +pub const API_FILE_OPENDIR: u32 = 73; +pub const API_FILE_READDIR: u32 = 74; +pub const API_FILE_UNLINK: u32 = 75; +pub const API_FILE_RENAME: u32 = 76; +pub const API_FILE_MKDIR: u32 = 77; +pub const API_RTC_GET_SECONDS: u32 = 80; +pub const API_RTC_SCHEDULE_ALARM: u32 = 81; +pub const API_RTC_SET_MILLISECONDS: u32 = 82; +pub const API_RTC_GET_MILLISECONDS: u32 = 83; +pub const API_LEDS_SET: u32 = 96; +pub const API_LEDS_SET_HSV: u32 = 97; +pub const API_LEDS_PREP: u32 = 98; +pub const API_LEDS_PREP_HSV: u32 = 99; +pub const API_LEDS_UPDATE: u32 = 100; +pub const API_LEDS_SET_POWERSAVE: u32 = 101; +pub const API_LEDS_SET_ROCKET: u32 = 102; +pub const API_LEDS_SET_FLASHLIGHT: u32 = 103; +pub const API_LEDS_DIM_TOP: u32 = 104; +pub const API_LEDS_DIM_BOTTOM: u32 = 105; +pub const API_LEDS_SET_ALL: u32 = 106; +pub const API_LEDS_SET_ALL_HSV: u32 = 107; +pub const API_LEDS_SET_GAMMA_TABLE: u32 = 108; +pub const API_LEDS_CLEAR_ALL: u32 = 109; +pub const API_VIBRA_SET: u32 = 112; +pub const API_VIBRA_VIBRATE: u32 = 113; +pub const API_LIGHT_SENSOR_RUN: u32 = 128; +pub const API_LIGHT_SENSOR_GET: u32 = 129; +pub const API_LIGHT_SENSOR_STOP: u32 = 130; +pub const API_BUTTONS_READ: u32 = 144; +pub const API_GPIO_SET_PIN_MODE: u32 = 160; +pub const API_GPIO_GET_PIN_MODE: u32 = 161; +pub const API_GPIO_WRITE_PIN: u32 = 162; +pub const API_GPIO_READ_PIN: u32 = 163; +pub const API_TRNG_READ: u32 = 176; +pub const API_PERSONAL_STATE_SET: u32 = 192; +pub const API_PERSONAL_STATE_GET: u32 = 193; +pub const API_PERSONAL_STATE_IS_PERSISTENT: u32 = 194; +pub const API_BME680_INIT: u32 = 208; +pub const API_BME680_DEINIT: u32 = 209; +pub const API_BME680_GET_DATA: u32 = 210; +pub const API_BHI160_ENABLE: u32 = 224; +pub const API_BHI160_DISABLE: u32 = 225; +pub const API_BHI160_DISABLE_ALL: u32 = 226; +pub const API_MAX30001_ENABLE: u32 = 240; +pub const API_MAX30001_DISABLE: u32 = 241; +pub const API_MAX86150_INIT: u32 = 256; +pub const API_MAX86150_GET_DATA: u32 = 257; +pub const API_MAX86150_SET_LED_AMPLITUDE: u32 = 258; +pub const EPIC_INT_RESET: u32 = 0; +pub const EPIC_INT_CTRL_C: u32 = 1; +pub const EPIC_INT_UART_RX: u32 = 2; +pub const EPIC_INT_RTC_ALARM: u32 = 3; +pub const EPIC_INT_BHI160_ACCELEROMETER: u32 = 4; +pub const EPIC_INT_BHI160_ORIENTATION: u32 = 5; +pub const EPIC_INT_BHI160_GYROSCOPE: u32 = 6; +pub const EPIC_INT_MAX30001_ECG: u32 = 7; +pub const EPIC_INT_NUM: u32 = 8; +pub const DISP_WIDTH: u32 = 160; +pub const DISP_HEIGHT: u32 = 80; +pub const EPICSTAT_MAX_PATH: u32 = 255; +pub const _API_SEMAPHORE: u32 = 0; +pub const _CONTROL_SEMAPHORE: u32 = 1; +pub const _API_FLAG_IDLE: u32 = 0; +pub const _API_FLAG_CALLING: u32 = 1; +pub const _API_FLAG_RETURNED: u32 = 2; +pub type __u_char = super::ctypes::c_uchar; +pub type __u_short = super::ctypes::c_ushort; +pub type __u_int = super::ctypes::c_uint; +pub type __u_long = super::ctypes::c_ulong; +pub type __int8_t = super::ctypes::c_schar; +pub type __uint8_t = super::ctypes::c_uchar; +pub type __int16_t = super::ctypes::c_short; +pub type __uint16_t = super::ctypes::c_ushort; +pub type __int32_t = super::ctypes::c_int; +pub type __uint32_t = super::ctypes::c_uint; +pub type __int64_t = super::ctypes::c_long; +pub type __uint64_t = super::ctypes::c_ulong; +pub type __quad_t = super::ctypes::c_long; +pub type __u_quad_t = super::ctypes::c_ulong; +pub type __intmax_t = super::ctypes::c_long; +pub type __uintmax_t = super::ctypes::c_ulong; +pub type __dev_t = super::ctypes::c_ulong; +pub type __uid_t = super::ctypes::c_uint; +pub type __gid_t = super::ctypes::c_uint; +pub type __ino_t = super::ctypes::c_ulong; +pub type __ino64_t = super::ctypes::c_ulong; +pub type __mode_t = super::ctypes::c_uint; +pub type __nlink_t = super::ctypes::c_ulong; +pub type __off_t = super::ctypes::c_long; +pub type __off64_t = super::ctypes::c_long; +pub type __pid_t = super::ctypes::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct __fsid_t { + pub __val: [super::ctypes::c_int; 2usize], +} +#[test] +fn bindgen_test_layout___fsid_t() { + assert_eq!( + ::std::mem::size_of::<__fsid_t>(), + 8usize, + concat!("Size of: ", stringify!(__fsid_t)) + ); + assert_eq!( + ::std::mem::align_of::<__fsid_t>(), + 4usize, + concat!("Alignment of ", stringify!(__fsid_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::<__fsid_t>())).__val as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(__fsid_t), + "::", + stringify!(__val) + ) + ); +} +pub type __clock_t = super::ctypes::c_long; +pub type __rlim_t = super::ctypes::c_ulong; +pub type __rlim64_t = super::ctypes::c_ulong; +pub type __id_t = super::ctypes::c_uint; +pub type __time_t = super::ctypes::c_long; +pub type __useconds_t = super::ctypes::c_uint; +pub type __suseconds_t = super::ctypes::c_long; +pub type __daddr_t = super::ctypes::c_int; +pub type __key_t = super::ctypes::c_int; +pub type __clockid_t = super::ctypes::c_int; +pub type __timer_t = *mut super::ctypes::c_void; +pub type __blksize_t = super::ctypes::c_long; +pub type __blkcnt_t = super::ctypes::c_long; +pub type __blkcnt64_t = super::ctypes::c_long; +pub type __fsblkcnt_t = super::ctypes::c_ulong; +pub type __fsblkcnt64_t = super::ctypes::c_ulong; +pub type __fsfilcnt_t = super::ctypes::c_ulong; +pub type __fsfilcnt64_t = super::ctypes::c_ulong; +pub type __fsword_t = super::ctypes::c_long; +pub type __ssize_t = super::ctypes::c_long; +pub type __syscall_slong_t = super::ctypes::c_long; +pub type __syscall_ulong_t = super::ctypes::c_ulong; +pub type __loff_t = __off64_t; +pub type __caddr_t = *mut super::ctypes::c_char; +pub type __intptr_t = super::ctypes::c_long; +pub type __socklen_t = super::ctypes::c_uint; +pub type __sig_atomic_t = super::ctypes::c_int; +pub type int_least8_t = super::ctypes::c_schar; +pub type int_least16_t = super::ctypes::c_short; +pub type int_least32_t = super::ctypes::c_int; +pub type int_least64_t = super::ctypes::c_long; +pub type uint_least8_t = super::ctypes::c_uchar; +pub type uint_least16_t = super::ctypes::c_ushort; +pub type uint_least32_t = super::ctypes::c_uint; +pub type uint_least64_t = super::ctypes::c_ulong; +pub type int_fast8_t = super::ctypes::c_schar; +pub type int_fast16_t = super::ctypes::c_long; +pub type int_fast32_t = super::ctypes::c_long; +pub type int_fast64_t = super::ctypes::c_long; +pub type uint_fast8_t = super::ctypes::c_uchar; +pub type uint_fast16_t = super::ctypes::c_ulong; +pub type uint_fast32_t = super::ctypes::c_ulong; +pub type uint_fast64_t = super::ctypes::c_ulong; +pub type intmax_t = __intmax_t; +pub type uintmax_t = __uintmax_t; +extern "C" { + pub fn __errno_location() -> *mut super::ctypes::c_int; +} +pub type wchar_t = super::ctypes::c_int; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct max_align_t { + pub __max_align_ll: super::ctypes::c_longlong, + pub __bindgen_padding_0: u64, + pub __max_align_ld: f64, +} +#[test] +fn bindgen_test_layout_max_align_t() { + assert_eq!( + ::std::mem::size_of::(), + 32usize, + concat!("Size of: ", stringify!(max_align_t)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__max_align_ll as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(max_align_t), + "::", + stringify!(__max_align_ll) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).__max_align_ld as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(max_align_t), + "::", + stringify!(__max_align_ld) + ) + ); +} +pub type api_int_id_t = u32; +extern "C" { + pub fn epic_interrupt_enable(int_id: api_int_id_t) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_interrupt_disable(int_id: api_int_id_t) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_isr_bhi160_accelerometer(); +} +extern "C" { + pub fn epic_isr_bhi160_orientation(); +} +extern "C" { + pub fn epic_isr_bhi160_gyroscope(); +} +extern "C" { + pub fn epic_isr_max30001_ecg(); +} +extern "C" { + pub fn __epic_isr_reset(); +} +extern "C" { + /// Stop execution of the current payload and return to the menu. + /// + /// :param int ret: Return code. + /// :return: :c:func:`epic_exit` will never return. + pub fn epic_exit(ret: super::ctypes::c_int); +} +extern "C" { + pub fn __epic_exit(ret: super::ctypes::c_int); +} +extern "C" { + /// Stop execution of the current payload and immediately start another payload. + /// + /// :param char* name: Name (path) of the new payload to start. This can either + /// be: + /// + /// - A path to an ``.elf`` file (l0dable). + /// - A path to a ``.py`` file (will be loaded using Pycardium). + /// - A path to a directory (assumed to be a Python module, execution starts + /// with ``__init__.py`` in this folder). + /// + /// :return: :c:func:`epic_exec` will only return in case loading went wrong. + /// The following error codes can be returned: + /// + /// - ``-ENOENT``: File not found. + /// - ``-ENOEXEC``: File not a loadable format. + pub fn epic_exec(name: *mut super::ctypes::c_char) -> super::ctypes::c_int; +} +extern "C" { + pub fn __epic_exec(name: *mut super::ctypes::c_char) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_system_reset(); +} +extern "C" { + pub fn epic_read_battery_voltage(result: *mut f32) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_read_battery_current(result: *mut f32) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_read_chargein_voltage(result: *mut f32) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_read_chargein_current(result: *mut f32) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_read_system_voltage(result: *mut f32) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_read_thermistor_voltage(result: *mut f32) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_uart_write_str(str: *const super::ctypes::c_char, length: isize); +} +extern "C" { + pub fn epic_uart_read_char() -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_uart_read_str(buf: *mut super::ctypes::c_char, cnt: usize) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_isr_uart_rx(); +} +extern "C" { + pub fn epic_isr_ctrl_c(); +} +/// ``1``, Bottom left button (bit 0). +pub const epic_button_BUTTON_LEFT_BOTTOM: epic_button = 1; +/// ``2``, Bottom right button (bit 1). +pub const epic_button_BUTTON_RIGHT_BOTTOM: epic_button = 2; +/// ``4``, Top right button (bit 2). +pub const epic_button_BUTTON_RIGHT_TOP: epic_button = 4; +/// ``8``, Top left (power) button (bit 3). +pub const epic_button_BUTTON_LEFT_TOP: epic_button = 8; +/// ``8``, Top left (power) button (bit 3). +pub const epic_button_BUTTON_RESET: epic_button = 8; +/// Button IDs +pub type epic_button = u32; +extern "C" { + pub fn epic_buttons_read(mask: u8) -> u8; +} +/// ``1``, Wristband connector 1 +pub const gpio_pin_EPIC_GPIO_WRISTBAND_1: gpio_pin = 1; +/// ``2``, Wristband connector 2 +pub const gpio_pin_EPIC_GPIO_WRISTBAND_2: gpio_pin = 2; +/// ``3``, Wristband connector 3 +pub const gpio_pin_EPIC_GPIO_WRISTBAND_3: gpio_pin = 3; +/// ``4``, Wristband connector 4 +pub const gpio_pin_EPIC_GPIO_WRISTBAND_4: gpio_pin = 4; +/// GPIO pins IDs +pub type gpio_pin = u32; +/// Configure the pin as input +pub const gpio_mode_EPIC_GPIO_MODE_IN: gpio_mode = 1; +/// Configure the pin as output +pub const gpio_mode_EPIC_GPIO_MODE_OUT: gpio_mode = 2; +/// Enable the internal pull-up resistor +pub const gpio_mode_EPIC_GPIO_PULL_UP: gpio_mode = 64; +/// Enable the internal pull-down resistor +pub const gpio_mode_EPIC_GPIO_PULL_DOWN: gpio_mode = 128; +/// GPIO pin modes +pub type gpio_mode = u32; +extern "C" { + pub fn epic_gpio_set_pin_mode(pin: u8, mode: u8) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_gpio_get_pin_mode(pin: u8) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_gpio_write_pin(pin: u8, on: bool) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_gpio_read_pin(pin: u8) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_leds_set(led: super::ctypes::c_int, r: u8, g: u8, b: u8); +} +extern "C" { + pub fn epic_leds_set_hsv(led: super::ctypes::c_int, h: f32, s: f32, v: f32); +} +extern "C" { + pub fn epic_leds_set_all(pattern: *mut u8, len: u8); +} +extern "C" { + pub fn epic_leds_set_all_hsv(pattern: *mut f32, len: u8); +} +extern "C" { + pub fn epic_leds_prep(led: super::ctypes::c_int, r: u8, g: u8, b: u8); +} +extern "C" { + pub fn epic_leds_prep_hsv(led: super::ctypes::c_int, h: f32, s: f32, v: f32); +} +extern "C" { + pub fn epic_leds_dim_bottom(value: u8); +} +extern "C" { + pub fn epic_leds_dim_top(value: u8); +} +extern "C" { + pub fn epic_leds_set_powersave(eco: bool); +} +extern "C" { + pub fn epic_leds_update(); +} +extern "C" { + pub fn epic_leds_set_rocket(led: super::ctypes::c_int, value: u8); +} +extern "C" { + pub fn epic_set_flashlight(power: bool); +} +extern "C" { + pub fn epic_leds_set_gamma_table(rgb_channel: u8, gamma_table: *mut u8); +} +extern "C" { + pub fn epic_leds_clear_all(r: u8, g: u8, b: u8); +} +/// BME680 Sensor Data +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bme680_sensor_data { + /// Temperature in degree celsius + pub temperature: f32, + /// Humidity in % relative humidity + pub humidity: f32, + /// Pressure in hPa + pub pressure: f32, + /// Gas resistance in Ohms + pub gas_resistance: f32, +} +#[test] +fn bindgen_test_layout_bme680_sensor_data() { + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(bme680_sensor_data)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(bme680_sensor_data)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).temperature as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bme680_sensor_data), + "::", + stringify!(temperature) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).humidity as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(bme680_sensor_data), + "::", + stringify!(humidity) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).pressure as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(bme680_sensor_data), + "::", + stringify!(pressure) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).gas_resistance as *const _ as usize + }, + 12usize, + concat!( + "Offset of field: ", + stringify!(bme680_sensor_data), + "::", + stringify!(gas_resistance) + ) + ); +} +extern "C" { + pub fn epic_bme680_init() -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_bme680_deinit() -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_bme680_read_sensors(data: *mut bme680_sensor_data) -> super::ctypes::c_int; +} +/// ``0``, No personal state - LED is under regular application control. +pub const personal_state_STATE_NONE: personal_state = 0; +/// ``1``, "no contact, please!" - I am overloaded. Please leave me be - red led, continuously on. +pub const personal_state_STATE_NO_CONTACT: personal_state = 1; +/// ``2``, "chaos" - Adventure time - blue led, short blink, long blink. +pub const personal_state_STATE_CHAOS: personal_state = 2; +/// ``3``, "communication" - want to learn something or have a nice conversation - yellow led, long blinks. +pub const personal_state_STATE_COMMUNICATION: personal_state = 3; +/// ``4``, "camp" - I am focussed on self-, camp-, or community maintenance - green led, fade on and off. +pub const personal_state_STATE_CAMP: personal_state = 4; +/// STATE_MAX gives latest value and count of possible STATEs +pub const personal_state_STATE_MAX: personal_state = 5; +/// Possible personal states. +pub type personal_state = u32; +extern "C" { + pub fn epic_personal_state_set(state: u8, persistent: bool) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_personal_state_get() -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_personal_state_is_persistent() -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_stream_read( + sd: super::ctypes::c_int, + buf: *mut super::ctypes::c_void, + count: usize, + ) -> super::ctypes::c_int; +} +/// Accelerometer +/// +/// - Data type: :c:type:`bhi160_data_vector` +/// - Dynamic range: g's (1x Earth Gravity, ~9.81m*s^-2) +pub const bhi160_sensor_type_BHI160_ACCELEROMETER: bhi160_sensor_type = 0; +/// Magnetometer (**Unimplemented**) +pub const bhi160_sensor_type_BHI160_MAGNETOMETER: bhi160_sensor_type = 1; +/// Orientation +pub const bhi160_sensor_type_BHI160_ORIENTATION: bhi160_sensor_type = 2; +/// Gyroscope +pub const bhi160_sensor_type_BHI160_GYROSCOPE: bhi160_sensor_type = 3; +/// Gravity (**Unimplemented**) +pub const bhi160_sensor_type_BHI160_GRAVITY: bhi160_sensor_type = 4; +/// Linear acceleration (**Unimplemented**) +pub const bhi160_sensor_type_BHI160_LINEAR_ACCELERATION: bhi160_sensor_type = 5; +/// Rotation vector (**Unimplemented**) +pub const bhi160_sensor_type_BHI160_ROTATION_VECTOR: bhi160_sensor_type = 6; +/// Uncalibrated magnetometer (**Unimplemented**) +pub const bhi160_sensor_type_BHI160_UNCALIBRATED_MAGNETOMETER: bhi160_sensor_type = 7; +/// Game rotation vector (whatever that is supposed to be) +pub const bhi160_sensor_type_BHI160_GAME_ROTATION_VECTOR: bhi160_sensor_type = 8; +/// Uncalibrated gyroscrope (**Unimplemented**) +pub const bhi160_sensor_type_BHI160_UNCALIBRATED_GYROSCOPE: bhi160_sensor_type = 9; +/// Geomagnetic rotation vector (**Unimplemented**) +pub const bhi160_sensor_type_BHI160_GEOMAGNETIC_ROTATION_VECTOR: bhi160_sensor_type = 10; +/// BHI160 virtual sensor type. +pub type bhi160_sensor_type = u32; +pub const bhi160_data_type_BHI160_DATA_TYPE_VECTOR: bhi160_data_type = 0; +pub type bhi160_data_type = u32; +/// Vector Data. The scaling of these values is dependent on the chosen dynamic +/// range. See the individual sensor's documentation for details. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bhi160_data_vector { + pub data_type: bhi160_data_type, + /// X + pub x: i16, + /// Y + pub y: i16, + /// Z + pub z: i16, + /// Status + pub status: u8, +} +#[test] +fn bindgen_test_layout_bhi160_data_vector() { + assert_eq!( + ::std::mem::size_of::(), + 12usize, + concat!("Size of: ", stringify!(bhi160_data_vector)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(bhi160_data_vector)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).data_type as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bhi160_data_vector), + "::", + stringify!(data_type) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).x as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(bhi160_data_vector), + "::", + stringify!(x) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).y as *const _ as usize }, + 6usize, + concat!( + "Offset of field: ", + stringify!(bhi160_data_vector), + "::", + stringify!(y) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).z as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(bhi160_data_vector), + "::", + stringify!(z) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).status as *const _ as usize }, + 10usize, + concat!( + "Offset of field: ", + stringify!(bhi160_data_vector), + "::", + stringify!(status) + ) + ); +} +/// Configuration for a BHI160 sensor. +/// +/// This struct is used when enabling a sensor using +/// :c:func:`epic_bhi160_enable_sensor`. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct bhi160_sensor_config { + /// Number of samples Epicardium should keep for this sensor. Do not set + /// this number too high as the sample buffer will eat RAM. + pub sample_buffer_len: usize, + /// Sample rate for the sensor in Hz. Maximum data rate is limited + /// to 200 Hz for all sensors though some might be limited at a lower + /// rate. + pub sample_rate: u16, + /// Dynamic range. Interpretation of this value depends on + /// the sensor type. Please refer to the specific sensor in + /// :c:type:`bhi160_sensor_type` for details. + pub dynamic_range: u16, + /// Always zero. Reserved for future parameters. + pub _padding: [u8; 8usize], +} +#[test] +fn bindgen_test_layout_bhi160_sensor_config() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(bhi160_sensor_config)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(bhi160_sensor_config)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).sample_buffer_len as *const _ as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(bhi160_sensor_config), + "::", + stringify!(sample_buffer_len) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).sample_rate as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(bhi160_sensor_config), + "::", + stringify!(sample_rate) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).dynamic_range as *const _ as usize + }, + 10usize, + concat!( + "Offset of field: ", + stringify!(bhi160_sensor_config), + "::", + stringify!(dynamic_range) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::()))._padding as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(bhi160_sensor_config), + "::", + stringify!(_padding) + ) + ); +} +extern "C" { + pub fn epic_bhi160_enable_sensor( + sensor_type: bhi160_sensor_type, + config: *mut bhi160_sensor_config, + ) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_bhi160_disable_sensor(sensor_type: bhi160_sensor_type) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_bhi160_disable_all_sensors(); +} +extern "C" { + pub fn epic_vibra_set(status: super::ctypes::c_int); +} +extern "C" { + pub fn epic_vibra_vibrate(millis: super::ctypes::c_int); +} + +pub const disp_linestyle_LINESTYLE_FULL: disp_linestyle = 0; + +pub const disp_linestyle_LINESTYLE_DOTTED: disp_linestyle = 1; +/// Line-Style +pub type disp_linestyle = u32; + +pub const disp_fillstyle_FILLSTYLE_EMPTY: disp_fillstyle = 0; + +pub const disp_fillstyle_FILLSTYLE_FILLED: disp_fillstyle = 1; +/// Fill-Style +pub type disp_fillstyle = u32; +/// Framebuffer +/// +/// The frambuffer stores pixels as RGB565, but byte swapped. That is, for every ``(x, y)`` coordinate, there are two ``uint8_t``\ s storing 16 bits of pixel data. +/// +/// .. todo:: +/// +/// Document (x, y) in relation to chirality. +/// +/// **Example**: Fill framebuffer with red +/// +/// .. code-block:: cpp +/// +/// union disp_framebuffer fb; +/// uint16_t red = 0b1111100000000000; +/// for (int y = 0; y < DISP_HEIGHT; y++) { +/// for (int x = 0; x < DISP_WIDTH; x++) { +/// fb.fb[y][x][0] = red >> 8; +/// fb.fb[y][x][1] = red & 0xFF; +/// } +/// } +/// epic_disp_framebuffer(&fb); +#[repr(C)] +#[derive(Copy, Clone)] +pub union disp_framebuffer { + /// Coordinate based access (as shown in the example above). + pub fb: [[[u8; 2usize]; 160usize]; 80usize], + /// Raw byte-indexed access. + pub raw: [u8; 25600usize], + _bindgen_union_align: [u8; 25600usize], +} +#[test] +fn bindgen_test_layout_disp_framebuffer() { + assert_eq!( + ::std::mem::size_of::(), + 25600usize, + concat!("Size of: ", stringify!(disp_framebuffer)) + ); + assert_eq!( + ::std::mem::align_of::(), + 1usize, + concat!("Alignment of ", stringify!(disp_framebuffer)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).fb as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(disp_framebuffer), + "::", + stringify!(fb) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).raw as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(disp_framebuffer), + "::", + stringify!(raw) + ) + ); +} +extern "C" { + pub fn epic_disp_open() -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_disp_close() -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_disp_update() -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_disp_print( + posx: u16, + posy: u16, + pString: *const super::ctypes::c_char, + fg: u16, + bg: u16, + ) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_disp_clear(color: u16) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_disp_pixel(x: u16, y: u16, color: u16) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_disp_line( + xstart: u16, + ystart: u16, + xend: u16, + yend: u16, + color: u16, + linestyle: disp_linestyle, + pixelsize: u16, + ) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_disp_rect( + xstart: u16, + ystart: u16, + xend: u16, + yend: u16, + color: u16, + fillstyle: disp_fillstyle, + pixelsize: u16, + ) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_disp_circ( + x: u16, + y: u16, + rad: u16, + color: u16, + fillstyle: disp_fillstyle, + pixelsize: u16, + ) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_disp_framebuffer(fb: *mut disp_framebuffer) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_disp_backlight(brightness: u16) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_light_sensor_run() -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_light_sensor_get(value: *mut u16) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_light_sensor_stop() -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_file_open( + filename: *const super::ctypes::c_char, + modeString: *const super::ctypes::c_char, + ) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_file_close(fd: super::ctypes::c_int) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_file_read( + fd: super::ctypes::c_int, + buf: *mut super::ctypes::c_void, + nbytes: usize, + ) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_file_write( + fd: super::ctypes::c_int, + buf: *const super::ctypes::c_void, + nbytes: usize, + ) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_file_flush(fd: super::ctypes::c_int) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_file_seek( + fd: super::ctypes::c_int, + offset: super::ctypes::c_long, + whence: super::ctypes::c_int, + ) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_file_tell(fd: super::ctypes::c_int) -> super::ctypes::c_int; +} +/// Basically ``ENOENT``. Although :c:func:`epic_file_stat` returns an +/// error for 'none', the type will still be set to none additionally. +/// +/// This is also used internally to track open FS objects, where we use +/// ``EPICSTAT_NONE`` to mark free objects. +pub const epic_stat_type_EPICSTAT_NONE: epic_stat_type = 0; +/// normal file +pub const epic_stat_type_EPICSTAT_FILE: epic_stat_type = 1; +/// directory +pub const epic_stat_type_EPICSTAT_DIR: epic_stat_type = 2; + +pub type epic_stat_type = u32; + +#[repr(C)] +#[derive(Copy, Clone)] +pub struct epic_stat { + /// Entity Type: file, directory or none + pub type_: epic_stat_type, + /// Size in bytes. + pub size: u32, + /// File Name. + pub name: [super::ctypes::c_char; 256usize], + pub _reserved: [u8; 12usize], +} +#[test] +fn bindgen_test_layout_epic_stat() { + assert_eq!( + ::std::mem::size_of::(), + 276usize, + concat!("Size of: ", stringify!(epic_stat)) + ); + assert_eq!( + ::std::mem::align_of::(), + 4usize, + concat!("Alignment of ", stringify!(epic_stat)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).type_ as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(epic_stat), + "::", + stringify!(type_) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).size as *const _ as usize }, + 4usize, + concat!( + "Offset of field: ", + stringify!(epic_stat), + "::", + stringify!(size) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).name as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(epic_stat), + "::", + stringify!(name) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::()))._reserved as *const _ as usize }, + 264usize, + concat!( + "Offset of field: ", + stringify!(epic_stat), + "::", + stringify!(_reserved) + ) + ); +} +extern "C" { + pub fn epic_file_stat( + path: *const super::ctypes::c_char, + stat: *mut epic_stat, + ) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_file_opendir(path: *const super::ctypes::c_char) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_file_readdir( + fd: super::ctypes::c_int, + stat: *mut epic_stat, + ) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_file_unlink(path: *const super::ctypes::c_char) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_file_rename( + oldp: *const super::ctypes::c_char, + newp: *const super::ctypes::c_char, + ) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_file_mkdir(dirname: *const super::ctypes::c_char) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_rtc_get_seconds() -> u32; +} +extern "C" { + pub fn epic_rtc_get_milliseconds() -> u64; +} +extern "C" { + pub fn epic_rtc_set_milliseconds(milliseconds: u64); +} +extern "C" { + pub fn epic_rtc_schedule_alarm(timestamp: u32) -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_isr_rtc_alarm(); +} +extern "C" { + pub fn epic_trng_read(dest: *mut u8, size: usize) -> super::ctypes::c_int; +} +/// Configuration for a MAX30001 sensor. +/// +/// This struct is used when enabling the sensor using +/// :c:func:`epic_max30001_enable_sensor`. +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct max30001_sensor_config { + /// Number of samples Epicardium should keep for this sensor. Do not set + /// this number too high as the sample buffer will eat RAM. + pub sample_buffer_len: usize, + /// Sample rate for the sensor in Hz. + pub sample_rate: u16, + /// Set to true if the second lead comes from USB-C + pub usb: bool, + /// Set to true if the interal lead bias of the MAX30001 is to be used. + pub bias: bool, + /// Always zero. Reserved for future parameters. + pub _padding: [u8; 8usize], +} +#[test] +fn bindgen_test_layout_max30001_sensor_config() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(max30001_sensor_config)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(max30001_sensor_config)) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).sample_buffer_len as *const _ + as usize + }, + 0usize, + concat!( + "Offset of field: ", + stringify!(max30001_sensor_config), + "::", + stringify!(sample_buffer_len) + ) + ); + assert_eq!( + unsafe { + &(*(::std::ptr::null::())).sample_rate as *const _ as usize + }, + 8usize, + concat!( + "Offset of field: ", + stringify!(max30001_sensor_config), + "::", + stringify!(sample_rate) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).usb as *const _ as usize }, + 10usize, + concat!( + "Offset of field: ", + stringify!(max30001_sensor_config), + "::", + stringify!(usb) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).bias as *const _ as usize }, + 11usize, + concat!( + "Offset of field: ", + stringify!(max30001_sensor_config), + "::", + stringify!(bias) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::()))._padding as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(max30001_sensor_config), + "::", + stringify!(_padding) + ) + ); +} +extern "C" { + pub fn epic_max30001_enable_sensor(config: *mut max30001_sensor_config) + -> super::ctypes::c_int; +} +extern "C" { + pub fn epic_max30001_disable_sensor() -> super::ctypes::c_int; +} +pub type api_id_t = u32; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct api_call_mem { + pub reset_stub: ::std::option::Option, + pub call_flag: u8, + pub id: api_id_t, + pub int_id: api_int_id_t, + pub buffer: [u8; 1usize], +} +#[test] +fn bindgen_test_layout_api_call_mem() { + assert_eq!( + ::std::mem::size_of::(), + 24usize, + concat!("Size of: ", stringify!(api_call_mem)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(api_call_mem)) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).reset_stub as *const _ as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(api_call_mem), + "::", + stringify!(reset_stub) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).call_flag as *const _ as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(api_call_mem), + "::", + stringify!(call_flag) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).id as *const _ as usize }, + 12usize, + concat!( + "Offset of field: ", + stringify!(api_call_mem), + "::", + stringify!(id) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).int_id as *const _ as usize }, + 16usize, + concat!( + "Offset of field: ", + stringify!(api_call_mem), + "::", + stringify!(int_id) + ) + ); + assert_eq!( + unsafe { &(*(::std::ptr::null::())).buffer as *const _ as usize }, + 20usize, + concat!( + "Offset of field: ", + stringify!(api_call_mem), + "::", + stringify!(buffer) + ) + ); +} +extern "C" { + #[link_name = "\u{1}API_CALL_MEM"] + pub static mut API_CALL_MEM: *mut api_call_mem; +} +extern "C" { + pub fn _api_call_start(id: api_id_t, size: usize) -> *mut super::ctypes::c_void; +} +extern "C" { + pub fn _api_call_transact(buffer: *mut super::ctypes::c_void) -> *mut super::ctypes::c_void; +} +extern "C" { + pub fn api_fetch_args(buf: *mut super::ctypes::c_char, cnt: usize) -> super::ctypes::c_int; +} diff --git a/l0dable/test/card10-l0dable-0.1.1 b/l0dable/test/card10-l0dable-0.1.1 new file mode 100644 index 0000000000000000000000000000000000000000..91f81cb93f9be09caa4c7e0da502de8dd1ac393a GIT binary patch literal 47104 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 rHMX{%cDh^MU)TP+*<1H Self { - Blocks { blocks: [[None; BLOCKS_X as usize]; BLOCKS_Y as usize], } + Blocks { + blocks: [[None; BLOCKS_X as usize]; BLOCKS_Y as usize], + } } pub fn generate(rand_max: u8) -> Self { @@ -28,11 +30,7 @@ impl Blocks { let mut buf = [0, 0, 0, 0]; trng::read(&mut buf); if buf[0] <= rand_max { - *block = Some(Color::rgb8( - 0x80 | buf[1], - 0x80 | buf[2], - 0x80 | buf[3], - )); + *block = Some(Color::rgb8(0x80 | buf[1], 0x80 | buf[2], 0x80 | buf[3])); count += 1; } } @@ -57,7 +55,9 @@ impl Blocks { } fn is_finished(&self) -> bool { - self.blocks.iter().all(|line| line.iter().all(|block| block.is_none())) + self.blocks + .iter() + .all(|line| line.iter().all(|block| block.is_none())) } } @@ -100,8 +100,8 @@ impl Direction { } fn bounce(&mut self, bounce: Bounce) { - use Direction::*; use Bounce::*; + use Direction::*; match (*self, bounce) { (UR, Vertical) => *self = UL, (UL, Vertical) => *self = UR, @@ -189,73 +189,84 @@ fn game(level: u16, mut score: u32) -> GameResult { } let mut check_finish = false; let speed_steps = 2 + (Seconds::time() - start_time).0 / 15; - let speed_steps = (speed_steps >> 1) + - (speed_steps & tick & 1); + let speed_steps = (speed_steps >> 1) + (speed_steps & tick & 1); for _ in 0..speed_steps { ball_direction.motion(&mut ball_x, &mut ball_y); - if (ball_direction.is_left() && ball_x <= BALL_RADIUS) || - (ball_direction.is_right() && ball_x >= Display::W - BALL_RADIUS) { - // Bounce on left/right border - ball_direction.bounce(Bounce::Vertical); - vibra::vibrate(10); + if (ball_direction.is_left() && ball_x <= BALL_RADIUS) + || (ball_direction.is_right() && ball_x >= Display::W - BALL_RADIUS) + { + // Bounce on left/right border + ball_direction.bounce(Bounce::Vertical); + vibra::vibrate(10); } if ball_direction.is_up() && ball_y <= BALL_RADIUS { // Bounce on top border ball_direction.bounce(Bounce::Horizontal); vibra::vibrate(10); } - if ball_direction.is_down() && - ball_y >= Display::H - PADDLE_HEIGHT - BALL_RADIUS && - ball_x >= paddle - paddle_size && - ball_x <= paddle + paddle_size { - // Bounce on paddle - if paddle_moving && input.left_bottom() { - ball_direction = Direction::UL; - vibra::vibrate(50); - } else if paddle_moving && input.right_bottom() { - ball_direction = Direction::UR; - vibra::vibrate(50); - } else { - ball_direction.bounce(Bounce::Horizontal); - vibra::vibrate(20); - } + if ball_direction.is_down() + && ball_y >= Display::H - PADDLE_HEIGHT - BALL_RADIUS + && ball_x >= paddle - paddle_size + && ball_x <= paddle + paddle_size + { + // Bounce on paddle + if paddle_moving && input.left_bottom() { + ball_direction = Direction::UL; + vibra::vibrate(50); + } else if paddle_moving && input.right_bottom() { + ball_direction = Direction::UR; + vibra::vibrate(50); + } else { + ball_direction.bounce(Bounce::Horizontal); + vibra::vibrate(20); } + } if ball_y >= Display::H - BALL_RADIUS { return GameResult::Over(score); } - if blocks.collides(ball_x - BALL_RADIUS, ball_y) || - blocks.collides(ball_x + BALL_RADIUS, ball_y) { - ball_direction.bounce(Bounce::Vertical); - score += 3; - // paddle_size += 2; - check_finish = true; - vibra::vibrate(60); - } - if blocks.collides(ball_x, ball_y - BALL_RADIUS) || - blocks.collides(ball_x, ball_y + BALL_RADIUS) { - ball_direction.bounce(Bounce::Horizontal); - score += 2; - // paddle_size += 1; - check_finish = true; - vibra::vibrate(40); - } + if blocks.collides(ball_x - BALL_RADIUS, ball_y) + || blocks.collides(ball_x + BALL_RADIUS, ball_y) + { + ball_direction.bounce(Bounce::Vertical); + score += 3; + // paddle_size += 2; + check_finish = true; + vibra::vibrate(60); + } + if blocks.collides(ball_x, ball_y - BALL_RADIUS) + || blocks.collides(ball_x, ball_y + BALL_RADIUS) + { + ball_direction.bounce(Bounce::Horizontal); + score += 2; + // paddle_size += 1; + check_finish = true; + vibra::vibrate(40); + } } if check_finish && blocks.is_finished() { return GameResult::LevelFinish(score + 100); } - + display.clear(Color::black()); // Paddle display.rect( - paddle - paddle_size, Display::H - PADDLE_HEIGHT, - paddle + paddle_size, Display::H - 1, - Color::rgb8(0x7f, 0xff, 0x7f), FillStyle::Filled, 1 + paddle - paddle_size, + Display::H - PADDLE_HEIGHT, + paddle + paddle_size, + Display::H - 1, + Color::rgb8(0x7f, 0xff, 0x7f), + FillStyle::Filled, + 1, ); // Ball display.circ( - ball_x, ball_y, BALL_RADIUS, - Color::rgb8(0x7f, 0x7f, 0xff), FillStyle::Filled, 1 + ball_x, + ball_y, + BALL_RADIUS, + Color::rgb8(0x7f, 0x7f, 0xff), + FillStyle::Filled, + 1, ); // Blocks for (lineno, line) in blocks.blocks.iter_mut().enumerate() { @@ -268,7 +279,9 @@ fn game(level: u16, mut score: u32) -> GameResult { lineno * BLOCK_H, (colno + 1) * BLOCK_W - 1, (lineno + 1) * BLOCK_H - 1, - color, FillStyle::Filled, 1 + color, + FillStyle::Filled, + 1, ); }); } @@ -281,10 +294,16 @@ fn game(level: u16, mut score: u32) -> GameResult { fn title_screen() { let display = Display::open(); display.clear(Color::red()); - display.print(30, 15, b"Rkanoid\0", Color::white(), Color::red()); - display.print(30, 30, b"in Rust\0", Color::white(), Color::red()); - display.print(20, 45, b"by Astro\0", Color::white(), Color::red()); - display.print(Display::W - 2 * Display::FONT_W, Display::H - Display::FONT_H, b"Go\0", Color::yellow(), Color::blue()); + display.print(30, 15, "Rkanoid\0", Color::white(), Color::red()); + display.print(30, 30, "in Rust\0", Color::white(), Color::red()); + display.print(20, 45, "by Astro\0", Color::white(), Color::red()); + display.print( + Display::W - 2 * Display::FONT_W, + Display::H - Display::FONT_H, + "Go\0", + Color::yellow(), + Color::blue(), + ); display.update(); while !Buttons::read().right_bottom() {} } @@ -292,21 +311,27 @@ fn title_screen() { fn game_over(score: u32) -> bool { let display = Display::open(); display.clear(Color::red()); - display.print(30, 0, b"Rkanoid\0", Color::white(), Color::red()); - display.print(0, 25, b"Game over!\0", Color::white(), Color::red()); + display.print(30, 0, "Rkanoid\0", Color::white(), Color::red()); + display.print(0, 25, "Game over!\0", Color::white(), Color::red()); let mut score_str = [0u8; 32]; write!(FmtBuffer::new(&mut score_str), "Score {}\0", score).unwrap(); - display.print(0, 60, &score_str, Color::white(), Color::red()); - display.print(0, 0, b"Q\0", Color::yellow(), Color::blue()); - display.print(Display::W - Display::FONT_W, Display::H - 2 * Display::FONT_H, b"S\0", Color::yellow(), Color::blue()); + display.print_u8(0, 60, &score_str, Color::white(), Color::red()); + display.print(0, 0, "Q\0", Color::yellow(), Color::blue()); + display.print( + Display::W - Display::FONT_W, + Display::H - 2 * Display::FONT_H, + "S\0", + Color::yellow(), + Color::blue(), + ); display.update(); loop { let buttons = Buttons::read(); if buttons.left_top() { - return false + return false; } if buttons.right_top() { - return true + return true; } } } @@ -314,23 +339,29 @@ fn game_over(score: u32) -> bool { fn level_finish(level: u16, score: u32) -> bool { let display = Display::open(); display.clear(Color::red()); - display.print(30, 0, b"Rkanoid\0", Color::white(), Color::red()); + display.print(30, 0, "Rkanoid\0", Color::white(), Color::red()); let mut level_str = [0u8; 32]; write!(FmtBuffer::new(&mut level_str), "Lvl {} done!\0", level + 1).unwrap(); - display.print(0, 25, &level_str, Color::white(), Color::red()); + display.print_u8(0, 25, &level_str, Color::white(), Color::red()); let mut score_str = [0u8; 32]; write!(FmtBuffer::new(&mut score_str), "Score {}\0", score).unwrap(); - display.print(0, 60, &score_str, Color::white(), Color::red()); - display.print(0, 0, b"Q\0", Color::yellow(), Color::blue()); - display.print(Display::W - Display::FONT_W, Display::H - 2 * Display::FONT_H, b"S\0", Color::yellow(), Color::blue()); + display.print_u8(0, 60, &score_str, Color::white(), Color::red()); + display.print(0, 0, "Q\0", Color::yellow(), Color::blue()); + display.print( + Display::W - Display::FONT_W, + Display::H - 2 * Display::FONT_H, + "S\0", + Color::yellow(), + Color::blue(), + ); display.update(); loop { let buttons = Buttons::read(); if buttons.left_top() { - return false + return false; } if buttons.right_top() { - return true + return true; } } } @@ -338,7 +369,7 @@ fn level_finish(level: u16, score: u32) -> bool { main!(main); fn main() { title_screen(); - + let mut quit = false; let mut level = 0; let mut score = 0; -- GitLab From fa1508ef3579288b95c7eab68bce9e6c83646c2f Mon Sep 17 00:00:00 2001 From: Kloenk Date: Fri, 30 Aug 2019 22:20:44 +0200 Subject: [PATCH 2/7] implement set functions --- l0dable/src/rtc.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/l0dable/src/rtc.rs b/l0dable/src/rtc.rs index 7c6188a..ad4da9b 100644 --- a/l0dable/src/rtc.rs +++ b/l0dable/src/rtc.rs @@ -1,4 +1,5 @@ use super::bindings::*; +use super::api; use core::ops::Sub; pub trait Time { @@ -17,11 +18,12 @@ impl From for Seconds { impl Time for Seconds { fn time() -> Self { - let s = unsafe { epic_rtc_get_seconds() }; + let s = api::RTC::get_seconds(); Seconds(s) } fn set_time(&self) { - // TODO + let ms: MilliSeconds = MilliSeconds::from(self.clone()); + ms.set_time(); } } @@ -43,11 +45,11 @@ impl From for MilliSeconds { impl Time for MilliSeconds { fn time() -> Self { - let ms = unsafe { epic_rtc_get_milliseconds() }; + let ms = api::RTC::get_milliseconds(); MilliSeconds(ms) } fn set_time(&self) { - // TODO + api::RTC::set_milliseconds(self.0); } } -- GitLab From d75cf0c1125cc588097a6913c7bc1c71f0aa0c41 Mon Sep 17 00:00:00 2001 From: Kloenk Date: Fri, 30 Aug 2019 22:30:36 +0200 Subject: [PATCH 3/7] make use of api in light_sensor --- l0dable/src/light_sensor.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/l0dable/src/light_sensor.rs b/l0dable/src/light_sensor.rs index 1a39c75..78fd196 100644 --- a/l0dable/src/light_sensor.rs +++ b/l0dable/src/light_sensor.rs @@ -1,3 +1,4 @@ +use super::api; use super::bindings::*; pub struct LightSensor { @@ -7,26 +8,27 @@ pub struct LightSensor { impl LightSensor { pub fn start() -> Self { - if unsafe { epic_light_sensor_run() } != 0 { + if api::sensors::light::run() != 0 { panic!("Cannot start light sensor"); } LightSensor { _private: () } } - pub fn get(&self) -> Option { - let mut result = 0; - if unsafe { epic_light_sensor_get(&mut result) } == 0 { - Some(result) - } else { - None + /// get light level + /// + /// # panics + /// This function panics if the underlying api reports an error (should not happen) + pub fn get(&self) -> u16 { + let light = api::sensors::light::get(); + if let Ok(light) = light { + return light; } + panic!("could not get light"); } } impl Drop for LightSensor { fn drop(&mut self) { - unsafe { - epic_light_sensor_stop(); - } + api::sensors::light::stop(); } } -- GitLab From 5484f1a71f9ddc487a449952cd3f9bde3c1ba35c Mon Sep 17 00:00:00 2001 From: Kloenk Date: Fri, 30 Aug 2019 22:33:54 +0200 Subject: [PATCH 4/7] remove bindings --- l0dable/src/light_sensor.rs | 3 +-- l0dable/src/rtc.rs | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/l0dable/src/light_sensor.rs b/l0dable/src/light_sensor.rs index 78fd196..743bce1 100644 --- a/l0dable/src/light_sensor.rs +++ b/l0dable/src/light_sensor.rs @@ -1,5 +1,4 @@ use super::api; -use super::bindings::*; pub struct LightSensor { // Prevent creation of this struct by all but this module. @@ -15,7 +14,7 @@ impl LightSensor { } /// get light level - /// + /// /// # panics /// This function panics if the underlying api reports an error (should not happen) pub fn get(&self) -> u16 { diff --git a/l0dable/src/rtc.rs b/l0dable/src/rtc.rs index ad4da9b..ca7c29d 100644 --- a/l0dable/src/rtc.rs +++ b/l0dable/src/rtc.rs @@ -1,4 +1,3 @@ -use super::bindings::*; use super::api; use core::ops::Sub; -- GitLab From 12615fcd05b6f74752b4bdeb2da32e46d1e8d6e3 Mon Sep 17 00:00:00 2001 From: Kloenk Date: Fri, 30 Aug 2019 22:42:30 +0200 Subject: [PATCH 5/7] make trng safe (api) --- l0dable/src/api/TRNG.rs | 18 ++++++++++++++++++ l0dable/src/trng.rs | 9 ++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/l0dable/src/api/TRNG.rs b/l0dable/src/api/TRNG.rs index c64fee3..557e201 100644 --- a/l0dable/src/api/TRNG.rs +++ b/l0dable/src/api/TRNG.rs @@ -30,3 +30,21 @@ pub fn read() -> Result<[u8; BUFFER_SIZE]> { } Ok(buffer) } + +/// Read random bytes from the TRNG. +/// +/// Parameters +/// +/// * dest (uint8_t) – Destination buffer +/// +/// size – Number of bytes to read. +/// +/// Returns +/// +/// 0 on success or a negative value if an error occured. Possible errors: +/// +/// -EFAULT: Invalid destination address. +/// +pub fn read_buf(dest: &mut [u8]) -> i32 { + unsafe { bindings::epic_trng_read(dest.as_mut_ptr(), dest.len()) } +} diff --git a/l0dable/src/trng.rs b/l0dable/src/trng.rs index b4635fa..e6eccd2 100644 --- a/l0dable/src/trng.rs +++ b/l0dable/src/trng.rs @@ -1,5 +1,8 @@ -use super::bindings::*; +use super::api; -pub fn read(dest: &mut [u8]) -> bool { - unsafe { epic_trng_read(dest.as_mut_ptr(), dest.len()) != 0 } +pub fn read_buf(dest: &mut [u8]) -> bool { + api::TRNG::read_buf(dest) != 0 } + +pub use api::TRNG::BUFFER_SIZE; +pub use api::TRNG::read; -- GitLab From 72b235556ddeb62d74ee1ec6400c4d3e2c0567ea Mon Sep 17 00:00:00 2001 From: Kloenk Date: Fri, 30 Aug 2019 23:14:35 +0200 Subject: [PATCH 6/7] create vibra api --- l0dable/src/api/gpio.rs | 12 ++++++++++++ l0dable/src/api/mod.rs | 3 +++ l0dable/src/rtc.rs | 20 ++++++++++++++++++++ l0dable/src/vibra.rs | 15 +++++++++------ 4 files changed, 44 insertions(+), 6 deletions(-) create mode 100644 l0dable/src/api/gpio.rs diff --git a/l0dable/src/api/gpio.rs b/l0dable/src/api/gpio.rs new file mode 100644 index 0000000..007e3a9 --- /dev/null +++ b/l0dable/src/api/gpio.rs @@ -0,0 +1,12 @@ +use super::super::bindings; + +pub mod vibra { + use super::bindings; + pub fn set(state: bool) { + unsafe { bindings::epic_vibra_set(state as i32) } + } + + pub fn vibrate(ms: i32) { + unsafe { bindings::epic_vibra_vibrate(ms) } + } +} diff --git a/l0dable/src/api/mod.rs b/l0dable/src/api/mod.rs index d1ec093..b5be9ad 100644 --- a/l0dable/src/api/mod.rs +++ b/l0dable/src/api/mod.rs @@ -4,6 +4,9 @@ pub mod code; // power related funtions like battery, charger and reset pub mod power; +/// gpio reltaed functions +pub mod gpio; + /// display functions /// /// This is only intended for internal use. please use `display` diff --git a/l0dable/src/rtc.rs b/l0dable/src/rtc.rs index ca7c29d..f06e077 100644 --- a/l0dable/src/rtc.rs +++ b/l0dable/src/rtc.rs @@ -4,6 +4,7 @@ use core::ops::Sub; pub trait Time { fn time() -> Self; fn set_time(&self); + fn millis(&self) -> i32; } #[derive(Clone, Copy, Debug)] @@ -24,6 +25,10 @@ impl Time for Seconds { let ms: MilliSeconds = MilliSeconds::from(self.clone()); ms.set_time(); } + + fn millis(&self) -> i32 { + (self.0 * 1000) as i32 + } } impl Sub for Seconds { @@ -50,6 +55,9 @@ impl Time for MilliSeconds { fn set_time(&self) { api::RTC::set_milliseconds(self.0); } + fn millis(&self) -> i32 { + self.0 as i32 + } } impl Sub for MilliSeconds { @@ -58,3 +66,15 @@ impl Sub for MilliSeconds { MilliSeconds(self.0 - rhs.0) } } + +impl Time for i32 { + fn time() -> Self { + api::RTC::get_milliseconds() as i32 + } + fn set_time(&self) { + api::RTC::set_milliseconds(*self as u64) + } + fn millis(&self) -> i32 { + *self + } +} \ No newline at end of file diff --git a/l0dable/src/vibra.rs b/l0dable/src/vibra.rs index 9fbe19b..835034d 100644 --- a/l0dable/src/vibra.rs +++ b/l0dable/src/vibra.rs @@ -1,13 +1,16 @@ -use super::bindings::*; +use super::rtc::Time; +use super::api; pub fn set(status: bool) { - unsafe { - epic_vibra_set(status.into()); - } + api::gpio::vibra::set(status); } -pub fn vibrate(millis: i32) { +/* pub fn vibrate(millis: i32) { unsafe { epic_vibra_vibrate(millis); } -} +} */ + +pub fn vibrate(t: &T) { + api::gpio::vibra::vibrate(t.millis()) +} \ No newline at end of file -- GitLab From 4e7677eaa980a396f3b1671b290ba4dbf642228e Mon Sep 17 00:00:00 2001 From: Kloenk Date: Fri, 30 Aug 2019 23:22:10 +0200 Subject: [PATCH 7/7] make os safe --- l0dable/src/api/power.rs | 17 +++++++++++++++++ l0dable/src/os.rs | 15 ++++----------- l0dable/src/vibra.rs | 6 ------ 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/l0dable/src/api/power.rs b/l0dable/src/api/power.rs index e1d63bd..72f7d92 100644 --- a/l0dable/src/api/power.rs +++ b/l0dable/src/api/power.rs @@ -150,3 +150,20 @@ pub fn system_reset() { pub fn exec(name: &str) -> i32 { unsafe { bindings::epic_exec(name.as_ptr() as *mut u8) } } + + +/// Stop execution of the current payload and return to the menu. +/// +/// # Parameters +/// +/// ret (int) – Return code. +/// +/// # return +/// +/// epic_exit() will never return. +/// +pub fn exit(ret: i32) -> ! { + unsafe { bindings::epic_exit(ret) } + unreachable!() +} + diff --git a/l0dable/src/os.rs b/l0dable/src/os.rs index af7a228..aa88319 100644 --- a/l0dable/src/os.rs +++ b/l0dable/src/os.rs @@ -1,23 +1,16 @@ -use super::bindings::*; +use super::api; pub fn exec(path: &str) -> ! { - let mut pathbuf = super::str_to_cstr(path); - unsafe { - epic_exec(pathbuf.as_mut_ptr()); - } + api::power::exec(path); unreachable!() } pub fn exit(ret: i32) -> ! { - unsafe { - epic_exit(ret); - } + api::power::exit(ret); unreachable!() } pub fn system_reset() -> ! { - unsafe { - epic_system_reset(); - } + api::power::system_reset(); unreachable!() } diff --git a/l0dable/src/vibra.rs b/l0dable/src/vibra.rs index 835034d..6063f4d 100644 --- a/l0dable/src/vibra.rs +++ b/l0dable/src/vibra.rs @@ -5,12 +5,6 @@ pub fn set(status: bool) { api::gpio::vibra::set(status); } -/* pub fn vibrate(millis: i32) { - unsafe { - epic_vibra_vibrate(millis); - } -} */ - pub fn vibrate(t: &T) { api::gpio::vibra::vibrate(t.millis()) } \ No newline at end of file -- GitLab