Skip to content

Instantly share code, notes, and snippets.

@kuon
Last active September 2, 2019 21:27
Show Gist options
  • Save kuon/00c4631ad22b78e0c93e2f000af8a286 to your computer and use it in GitHub Desktop.
Save kuon/00c4631ad22b78e0c93e2f000af8a286 to your computer and use it in GitHub Desktop.
Porting C code to rust
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#define FATAL(msg) \
do { \
printf(msg); \
exit(1); \
} while (0)
#define GPIO0_REGISTER 0x44E07000
#define GPIO1_REGISTER 0x4804C000
#define GPIO2_REGISTER 0x481AC000
#define GPIO_REGISTER_SIZE 0xFFF
#define GPIO_OE_REGISTER 0x134
#define GPIO_DATAOUT_REGISTER 0x13C
int main(void)
{
int fd = open("/dev/mem", O_RDWR);
if (!fd) {
FATAL("Cannot open memory device");
}
volatile void* gpio1 = mmap(0, GPIO_REGISTER_SIZE, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, GPIO1_REGISTER);
if (!gpio1) {
FATAL("Cannot map GPIO memory");
}
volatile uint32_t* gpio1_oe = gpio1 + GPIO_OE_REGISTER;
volatile uint32_t* gpio1_dataout = gpio1 + GPIO_DATAOUT_REGISTER;
*gpio1_oe = 0x00000000;
while (1) {
*gpio1_dataout = (1 << 12); // pin 12
*gpio1_dataout = 0;
}
return 0;
}
extern crate sysfs_gpio;
use libc::c_int;
use std::convert::TryInto;
use std::ffi::CString;
pub const GPIO_BASE_REGISTERS: (c_int, c_int, c_int) = (0x44E0_7000, 0x4804_C000, 0x481A_C000);
pub const GPIO_REGISTER_SIZE: usize = 0xFFF;
pub const GPIO_OE_REGISTER: isize = 0x134;
pub const GPIO_DATAOUT_REGISTER: isize = 0x13C;
pub const SDI_PIN: (u8, u8) = (1, 12);
fn main() {
let path = CString::new("/dev/mem").unwrap();
unsafe {
let fd = libc::open(path.as_ptr(), libc::O_RDWR);
if fd < 0 {
panic!("Cannot open memory device");
}
let gpio1: *mut u32 = libc::mmap(
std::ptr::null_mut(),
GPIO_REGISTER_SIZE,
libc::PROT_READ | libc::PROT_WRITE,
libc::MAP_SHARED,
fd,
GPIO_BASE_REGISTERS.1.try_into().unwrap(),
) as *mut u32;
if gpio1.is_null() {
panic!("Cannot map GPIO memory");
}
let gpio1_oe: *mut u32 = gpio1.offset(GPIO_OE_REGISTER);
let gpio1_dataout: *mut u32 = gpio1.offset(GPIO_DATAOUT_REGISTER);
std::ptr::write_volatile(gpio1_oe, 0);
loop {
std::ptr::write_volatile(gpio1_dataout, 1 << 12);
std::ptr::write_volatile(gpio1_dataout, 0);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment