Commit ecb77a01 authored by rnd's avatar rnd
Browse files

[Sys] Introduce card10-sys as pure binding wrapper.

parent 5dc11ba9
[submodule "c"]
path = c
[submodule "card10-sys/firmware"]
path = card10-sys/firmware
url = https://git.card10.badge.events.ccc.de/card10/firmware.git
......@@ -87,6 +87,16 @@ dependencies = [
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "card10-sys"
version = "0.1.0"
dependencies = [
"bindgen 0.51.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"panic-abort 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cc"
version = "1.0.37"
......
[workspace]
members = [
"card10-sys",
"l0dable",
"example",
"rkanoid",
]
default-members = [
"example",
"rkanoid",
......
Subproject commit 45c228ac4887d2a838dcbb563c45182e579c5e35
[package]
name = "card10-sys"
version = "0.1.0"
authors = ["Astro <astro@spaceboyz.net>", "Kloenk <me@kloenk.de>"]
license = "MIT/Apache-2.0"
edition = "2018"
description = "Rust bindings for card10"
repository = "https://git.card10.badge.events.ccc.de/astro/rust-card10"
homepage = "https://git.card10.badge.events.ccc.de/astro/rust-card10"
categories = ["external-ffi-bindings", "no-std"]
keywords = [
"CCC",
"CCCamp2019",
"CCCamp19",
"card10",
"l0dable",
]
[dependencies]
panic-abort = "^0.3"
r0 = "^0.2"
[build-dependencies]
bindgen = "^0.51"
cc = "^1.0"
use std::{env, error::Error, fs, path::PathBuf};
fn main() -> Result<(), Box<dyn Error>> {
let out = env::var_os("OUT_DIR")
.map(|path| PathBuf::from(path))
.ok_or("OUT_DIR definition missing")?;
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=vendor/l0dable.ld");
println!("cargo:rerun-if-changed=vendor/client.c");
println!("cargo:rerun-if-changed=vendor/wrapper.h");
println!("cargo:rustc-link-search={}", out.display());
// Linker script
fs::copy("vendor/crt.s", out.join("crt.s"))?;
fs::copy("vendor/l0dable.ld", out.join("l0dable.ld"))?;
// Link against C code
cc::Build::new()
.target("thumbv7em-none-eabi")
.compiler("arm-none-eabi-gcc")
.opt_level_str("s")
.debug(true)
.define("TARGET", "MAX32665")
.define("TARGET_UC", "MAX32665")
.define("TARGET_LC", "max32665")
.define("TARGET_REV", "0x4131")
.define("BOARD", "card10")
.flag("-fPIE")
.flag("-pie")
.include("firmware/epicardium")
.include("firmware/lib/sdk/Libraries/CMSIS/Device/Maxim/MAX32665/Include")
.include("firmware/lib/sdk/Libraries/CMSIS/Include")
.include("firmware/lib/sdk/Libraries/MAX32665PeriphDriver/Include")
.file("firmware/lib/sdk/Libraries/MAX32665PeriphDriver/Source/sema.c")
.file("firmware/lib/sdk/Libraries/MAX32665PeriphDriver/Source/mxc_assert.c")
.file("firmware/l0dables/lib/hardware.c")
.file("firmware/epicardium/api/caller.c")
.file("firmware/lib/gfx/Fonts/font12.c")
.file("firmware/lib/gfx/Fonts/font16.c")
.file("firmware/lib/gfx/Fonts/font20.c")
.file("firmware/lib/gfx/Fonts/font24.c")
.file("firmware/lib/gfx/Fonts/font8.c")
.file("vendor/client.c")
.compile("card10");
// Generate bindings to C code
let bindings = bindgen::Builder::default()
.use_core()
.clang_arg("-Isrc")
.clang_arg("-Ifirmware/epicardium")
.clang_arg("-Ifirmware/lib/sdk/Libraries/CMSIS/Device/Maxim/MAX32665/Include")
.clang_arg("-Ifirmware/lib/sdk/Libraries/CMSIS/Include")
.clang_arg("-Ifirmware/lib/sdk/Libraries/MAX32665PeriphDriver/Include")
.header("vendor/wrapper.h")
.ctypes_prefix("ctypes")
.generate()
.map_err(|_| "Couldn't generate bindings")?;
bindings.write_to_file(out.join("bindings.rs"))?;
Ok(())
}
Subproject commit 1d21f7c120e75320185b6f62001e7e91bd8e8cea
#![no_std]
#![feature(global_asm)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
#![allow(non_snake_case)]
use panic_abort as _;
global_asm!(include_str!(concat!(env!("OUT_DIR"), "/crt.s")));
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
/// Type check the user-supplied entry function.
#[macro_export]
macro_rules! main {
($path:path) => {
#[export_name = "main"]
pub unsafe fn __main() {
// type check the given path
let f: fn() = $path;
f()
}
};
}
#[link_section = ".text.boot"]
#[no_mangle]
pub unsafe extern "C" fn Reset_Handler() -> ! {
extern "C" {
fn SystemInit();
// Boundaries of the .bss section, provided by the linker script
static mut __bss_start: u64;
static mut __bss_end: u64;
}
// Zeroes the .bss section
r0::zero_bss(&mut __bss_start, &mut __bss_end);
SystemInit();
extern "Rust" {
fn main();
}
main();
epic_exit(0);
unreachable!()
}
pub mod ctypes {
pub type c_short = i16;
pub type c_ushort = u16;
pub type c_int = i32;
pub type c_uint = u32;
pub type c_long = i32;
pub type c_ulong = u32;
pub type c_longlong = i64;
pub type c_ulonglong = u64;
pub type c_char = u8;
pub type c_schar = i8;
pub type c_uchar = u8;
pub use core::ffi::c_void;
}
pub mod errno {
use crate::ctypes::c_int;
pub const EPERM: c_int = 1; // Operation not permitted
pub const ENOENT: c_int = 2; // No such file or directory
pub const ESRCH: c_int = 3; // No such process
pub const EINTR: c_int = 4; // Interrupted system call
pub const EIO: c_int = 5; // I/O error
pub const ENXIO: c_int = 6; // No such device or address
pub const E2BIG: c_int = 7; // Argument list too long
pub const ENOEXEC: c_int = 8; // Exec format error
pub const EBADF: c_int = 9; // Bad file number
pub const ECHILD: c_int = 10; // No child processes
pub const EAGAIN: c_int = 11; // Try again
pub const ENOMEM: c_int = 12; //Out of memory
pub const EACCES: c_int = 13; //Permission denied
pub const EFAULT: c_int = 14; //Bad address
pub const ENOTBLK: c_int = 15; //Block device required
pub const EBUSY: c_int = 16; //Device or resource busy
pub const EEXIST: c_int = 17; //File exists
pub const EXDEV: c_int = 18; //Cross-device link
pub const ENODEV: c_int = 19; //No such device
pub const ENOTDIR: c_int = 20; //Not a directory
pub const EISDIR: c_int = 21; //Is a directory
pub const EINVAL: c_int = 22; //Invalid argument
pub const ENFILE: c_int = 23; //File table overflow
pub const EMFILE: c_int = 24; //Too many open files
pub const ENOTTY: c_int = 25; //Not a typewriter
pub const ETXTBSY: c_int = 26; //Text file busy
pub const EFBIG: c_int = 27; //File too large
pub const ENOSPC: c_int = 28; //No space left on device
pub const ESPIPE: c_int = 29; //Illegal seek
pub const EROFS: c_int = 30; //Read-only file system
pub const EMLINK: c_int = 31; //Too many links
pub const EPIPE: c_int = 32; //Broken pipe
pub const EDOM: c_int = 33; //Math argument out of domain of func
pub const ERANGE: c_int = 34; //Math result not representable
pub const EAFNOSUPPORT: c_int = 97; //Address family not supported by protocol
pub const ECONNRESET: c_int = 104; //Connection timed out
pub const ETIMEDOUT: c_int = 110; //Connection timed out
pub const EINPROGRESS: c_int = 115; //Operation now in progress
}
......@@ -866,6 +866,19 @@ int epic_light_sensor_stop()
return *(int*)_api_call_transact(epc__apistub_buffer);
}
/* Autogenerated stub for API_LIGHT_SENSOR_READ */
uint16_t epic_light_sensor_read(void)
{
const int epc__apistub_size = 0;
void*epc__apistub_buffer;
epc__apistub_buffer = _api_call_start(API_LIGHT_SENSOR_READ, epc__apistub_size);
/* TODO: Check if epc__apistub_buffer is not NULL */
return *(uint16_t*)_api_call_transact(epc__apistub_buffer);
}
/* Autogenerated stub for API_FILE_OPEN */
int epic_file_open( const char* filename, const char* modeString )
{
......@@ -1154,6 +1167,45 @@ int epic_max30001_disable_sensor( void )
return *(int*)_api_call_transact(epc__apistub_buffer);
}
/* Autogenerated stub for API_USB_SHUTDOWN */
int epic_usb_shutdown(void)
{
const int epc__apistub_size = 0;
void*epc__apistub_buffer;
epc__apistub_buffer = _api_call_start(API_USB_SHUTDOWN, epc__apistub_size);
/* TODO: Check if epc__apistub_buffer is not NULL */
return *(int*)_api_call_transact(epc__apistub_buffer);
}
/* Autogenerated stub for API_USB_STORAGE */
int epic_usb_storage(void)
{
const int epc__apistub_size = 0;
void*epc__apistub_buffer;
epc__apistub_buffer = _api_call_start(API_USB_STORAGE, epc__apistub_size);
/* TODO: Check if epc__apistub_buffer is not NULL */
return *(int*)_api_call_transact(epc__apistub_buffer);
}
/* Autogenerated stub for API_USB_CDCACM */
int epic_usb_cdcacm(void)
{
const int epc__apistub_size = 0;
void*epc__apistub_buffer;
epc__apistub_buffer = _api_call_start(API_USB_CDCACM, epc__apistub_size);
/* TODO: Check if epc__apistub_buffer is not NULL */
return *(int*)_api_call_transact(epc__apistub_buffer);
}
/* Weakly linked stubs for ISRs */
void epic_isr_bhi160_accelerometer(api_int_id_t id)
......
#include "modules/log.h"
#include "epicardium.h"
void __api_dispatch_call(uint32_t id, void*epc__apistub_buffer)
{
switch (id) {
case API_INTERRUPT_ENABLE:
*((int*)epc__apistub_buffer) = epic_interrupt_enable(
*(api_int_id_t*)(epc__apistub_buffer + 0)
);
break;
case API_INTERRUPT_DISABLE:
*((int*)epc__apistub_buffer) = epic_interrupt_disable(
*(api_int_id_t*)(epc__apistub_buffer + 0)
);
break;
case API_SYSTEM_EXIT:
__epic_exit(
*(int*)(epc__apistub_buffer + 0)
);
break;
case API_SYSTEM_EXEC:
*((int*)epc__apistub_buffer) = __epic_exec(
*(char **)(epc__apistub_buffer + 0)
);
break;
case API_SYSTEM_RESET:
epic_system_reset(
);
break;
case API_BATTERY_VOLTAGE:
*((int*)epc__apistub_buffer) = epic_read_battery_voltage(
*(float **)(epc__apistub_buffer + 0)
);
break;
case API_BATTERY_CURRENT:
*((int*)epc__apistub_buffer) = epic_read_battery_current(
*(float **)(epc__apistub_buffer + 0)
);
break;
case API_CHARGEIN_VOLTAGE:
*((int*)epc__apistub_buffer) = epic_read_chargein_voltage(
*(float **)(epc__apistub_buffer + 0)
);
break;
case API_CHARGEIN_CURRENT:
*((int*)epc__apistub_buffer) = epic_read_chargein_current(
*(float **)(epc__apistub_buffer + 0)
);
break;
case API_SYSTEM_VOLTAGE:
*((int*)epc__apistub_buffer) = epic_read_system_voltage(
*(float **)(epc__apistub_buffer + 0)
);
break;
case API_THERMISTOR_VOLTAGE:
*((int*)epc__apistub_buffer) = epic_read_thermistor_voltage(
*(float **)(epc__apistub_buffer + 0)
);
break;
case API_UART_WRITE_STR:
epic_uart_write_str(
*(const char **)(epc__apistub_buffer + 0),
*(intptr_t*)(epc__apistub_buffer + sizeof(const char *))
);
break;
case API_UART_READ_CHAR:
*((int*)epc__apistub_buffer) = epic_uart_read_char(
);
break;
case API_UART_READ_STR:
*((int*)epc__apistub_buffer) = epic_uart_read_str(
*(char **)(epc__apistub_buffer + 0),
*(size_t*)(epc__apistub_buffer + sizeof(char *))
);
break;
case API_BUTTONS_READ:
*((uint8_t*)epc__apistub_buffer) = epic_buttons_read(
*(uint8_t*)(epc__apistub_buffer + 0)
);
break;
case API_GPIO_SET_PIN_MODE:
*((int*)epc__apistub_buffer) = epic_gpio_set_pin_mode(
*(uint8_t*)(epc__apistub_buffer + 0),
*(uint8_t*)(epc__apistub_buffer + sizeof(uint8_t))
);
break;
case API_GPIO_GET_PIN_MODE:
*((int*)epc__apistub_buffer) = epic_gpio_get_pin_mode(
*(uint8_t*)(epc__apistub_buffer + 0)
);
break;
case API_GPIO_WRITE_PIN:
*((int*)epc__apistub_buffer) = epic_gpio_write_pin(
*(uint8_t*)(epc__apistub_buffer + 0),
*(_Bool*)(epc__apistub_buffer + sizeof(uint8_t))
);
break;
case API_GPIO_READ_PIN:
*((int*)epc__apistub_buffer) = epic_gpio_read_pin(
*(uint8_t*)(epc__apistub_buffer + 0)
);
break;
case API_LEDS_SET:
epic_leds_set(
*(int*)(epc__apistub_buffer + 0),
*(uint8_t*)(epc__apistub_buffer + sizeof(int)),
*(uint8_t*)(epc__apistub_buffer + sizeof(int) + sizeof(uint8_t)),
*(uint8_t*)(epc__apistub_buffer + sizeof(int) + sizeof(uint8_t) + sizeof(uint8_t))
);
break;
case API_LEDS_SET_HSV:
epic_leds_set_hsv(
*(int*)(epc__apistub_buffer + 0),
*(float*)(epc__apistub_buffer + sizeof(int)),
*(float*)(epc__apistub_buffer + sizeof(int) + sizeof(float)),
*(float*)(epc__apistub_buffer + sizeof(int) + sizeof(float) + sizeof(float))
);
break;
case API_LEDS_SET_ALL:
epic_leds_set_all(
*(uint8_t **)(epc__apistub_buffer + 0),
*(uint8_t*)(epc__apistub_buffer + sizeof(uint8_t *))
);
break;
case API_LEDS_SET_ALL_HSV:
epic_leds_set_all_hsv(
*(float **)(epc__apistub_buffer + 0),
*(uint8_t*)(epc__apistub_buffer + sizeof(float *))
);
break;
case API_LEDS_PREP:
epic_leds_prep(
*(int*)(epc__apistub_buffer + 0),
*(uint8_t*)(epc__apistub_buffer + sizeof(int)),
*(uint8_t*)(epc__apistub_buffer + sizeof(int) + sizeof(uint8_t)),
*(uint8_t*)(epc__apistub_buffer + sizeof(int) + sizeof(uint8_t) + sizeof(uint8_t))
);
break;
case API_LEDS_PREP_HSV:
epic_leds_prep_hsv(
*(int*)(epc__apistub_buffer + 0),
*(float*)(epc__apistub_buffer + sizeof(int)),
*(float*)(epc__apistub_buffer + sizeof(int) + sizeof(float)),
*(float*)(epc__apistub_buffer + sizeof(int) + sizeof(float) + sizeof(float))
);
break;
case API_LEDS_DIM_BOTTOM:
epic_leds_dim_bottom(
*(uint8_t*)(epc__apistub_buffer + 0)
);
break;
case API_LEDS_DIM_TOP:
epic_leds_dim_top(
*(uint8_t*)(epc__apistub_buffer + 0)
);
break;
case API_LEDS_SET_POWERSAVE:
epic_leds_set_powersave(
*(_Bool*)(epc__apistub_buffer + 0)
);
break;
case API_LEDS_UPDATE:
epic_leds_update(
);
break;
case API_LEDS_SET_ROCKET:
epic_leds_set_rocket(
*(int*)(epc__apistub_buffer + 0),
*(uint8_t*)(epc__apistub_buffer + sizeof(int))
);
break;
case API_LEDS_SET_FLASHLIGHT:
epic_set_flashlight(
*(_Bool*)(epc__apistub_buffer + 0)
);
break;
case API_LEDS_SET_GAMMA_TABLE:
epic_leds_set_gamma_table(
*(uint8_t*)(epc__apistub_buffer + 0),
*(uint8_t **)(epc__apistub_buffer + sizeof(uint8_t))
);
break;
case API_LEDS_CLEAR_ALL:
epic_leds_clear_all(
*(uint8_t*)(epc__apistub_buffer + 0),
*(uint8_t*)(epc__apistub_buffer + sizeof(uint8_t)),
*(uint8_t*)(epc__apistub_buffer + sizeof(uint8_t) + sizeof(uint8_t))
);
break;
case API_BME680_INIT:
*((int*)epc__apistub_buffer) = epic_bme680_init(
);
break;
case API_BME680_DEINIT:
*((int*)epc__apistub_buffer) = epic_bme680_deinit(
);
break;
case API_BME680_GET_DATA:
*((int*)epc__apistub_buffer) = epic_bme680_read_sensors(
*(struct bme680_sensor_data **)(epc__apistub_buffer + 0)
);
break;
case API_PERSONAL_STATE_SET:
*((int*)epc__apistub_buffer) = epic_personal_state_set(
*(uint8_t*)(epc__apistub_buffer + 0),
*(_Bool*)(epc__apistub_buffer + sizeof(uint8_t))
);
break;
case API_PERSONAL_STATE_GET:
*((int*)epc__apistub_buffer) = epic_personal_state_get(
);
break;
case API_PERSONAL_STATE_IS_PERSISTENT:
*((int*)epc__apistub_buffer) = epic_personal_state_is_persistent(
);
break;
case API_STREAM_READ:
*((int*)epc__apistub_buffer) = epic_stream_read(
*(int*)(epc__apistub_buffer + 0),
*(void **)(epc__apistub_buffer + sizeof(int)),
*(size_t*)(epc__apistub_buffer + sizeof(int) + sizeof(void *))
);
break;
case API_BHI160_ENABLE:
*((int*)epc__apistub_buffer) = epic_bhi160_enable_sensor(
*(enum bhi160_sensor_type*)(epc__apistub_buffer + 0),
*(struct bhi160_sensor_config **)(epc__apistub_buffer + sizeof(enum bhi160_sensor_type))
);
break;
case API_BHI160_DISABLE:
*((int*)epc__apistub_buffer) = epic_bhi160_disable_sensor(
*(enum bhi160_sensor_type*)(epc__apistub_buffer + 0)
);
break;
case API_BHI160_DISABLE_ALL:
epic_bhi160_disable_all_sensors(
);
break;
case API_VIBRA_SET:
epic_vibra_set(
*(int*)(epc__apistub_buffer + 0)
);
break;
case API_VIBRA_VIBRATE:
epic_vibra_vibrate(
*(int*)(epc__apistub_buffer + 0)
);
break;
case API_DISP_OPEN:
*((int*)epc__apistub_buffer) = epic_disp_open(
);
break;
case API_DISP_CLOSE:
*((int*)epc__apistub_buffer) = epic_disp_close(
);
break;
case API_DISP_UPDATE:
*((int*)epc__apistub_buffer) = epic_disp_update(
);
break;
case API_DISP_PRINT:
*((int*)epc__apistub_buffer) = epic_disp_print(
*(uint16_t*)(epc__apistub_buffer + 0),
*(uint16_t*)(epc__apistub_buffer + sizeof(uint16_t)),
*(const char **)(epc__apistub_buffer + sizeof(uint16_t) + sizeof(uint16_t)),
*(uint16_t*)(epc__apistub_buffer + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(const char *)),
*(uint16_t*)(epc__apistub_buffer + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(const char *) + sizeof(uint16_t))
);
break;
case API_DISP_CLEAR:
*((int*)epc__apistub_buffer) = epic_disp_clear(
*(uint16_t*)(epc__apistub_buffer + 0)
);
break;
case API_DISP_PIXEL:
*((int*)epc__apistub_buffer) = epic_disp_pixel(
*(uint16_t*)(epc__apistub_buffer + 0),
*(uint16_t*)(epc__apistub_buffer + sizeof(uint16_t)),
*(uint16_t*)(epc__apistub_buffer + sizeof(uint16_t) + sizeof(uint16_t))
);
break;
case API_DISP_LINE:
*((int*)epc__apistub_buffer) = epic_disp_line(
*(uint16_t*)(epc__apistub_buffer + 0),
*(uint16_t*)(epc__apistub_buffer + sizeof(uint16_t)),
*(uint16_t*)(epc__apistub_buffer + sizeof(uint16_t) + sizeof(uint16_t)),
*(uint16_t*)(epc__apistub_buffer + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t)),
*(uint16_t*)(epc__apistub_buffer + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t)),
*(enum disp_linestyle*)(epc__apistub_buffer + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t)),
*(uint16_t*)(epc__apistub_buffer + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(uint16_t) + sizeof(enum disp_linestyle))
);
break;
case API_DISP_RECT:
*((int*)epc__apistub_buffer) = epic_disp_rect(