Skip to content

Instantly share code, notes, and snippets.

@wendlers
Created November 9, 2014 20:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wendlers/304f97df09fd17bc10a3 to your computer and use it in GitHub Desktop.
Save wendlers/304f97df09fd17bc10a3 to your computer and use it in GitHub Desktop.
sysfsdiomp.py
##
# The MIT License (MIT)
#
# Copyright (c) 2014 Stefan Wendler
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
##
"""
Simple wrapper to libc open/read/write functions using FFI on
micropython.
"""
__author__ = 'Stefan Wendler, sw@kaltpost.de'
import ffi
import _libc
libc = _libc.get()
open = libc.func("i", "open", "si")
close = libc.func("i", "close", "i")
read = libc.func("i", "read", "isi")
write = libc.func("i", "write", "isi")
lseek = libc.func("i", "lseek", "iii")
'''
Open Flags
'''
O_ACCMODE = 3
O_RDONLY = 0
O_WRONLY = 1
O_RDWR = 2
O_CREAT = 100
O_EXCL = 200
O_NOCTTY = 400
O_TRUNC = 1000
O_APPEND = 2000
O_NONBLOCK = 4000
O_NDELAY = O_NONBLOCK
O_SYNC = 4010000
O_FSYNC = O_SYNC
O_ASYNC = 20000
'''
Some common error codes
'''
EPERM = 1 # Operation not permitted
ENOENT = 2 # No such file or directory
EIO = 5 # I/O error
EAGAIN = 11 # Try again
ENOMEM = 12 # Out of memory
EACCES = 13 # Permission denied
EEXIST = 17 # File exists
EISDIR = 21 # Is a directory
EMFILE = 24 # Too many open files
ETXTBSY = 26 # Text file busy
EFBIG = 27 # File too large
ENOSPC = 28 # No space left on device
EROFS= 30 # Read-only file system
'''
Seek values
'''
SEEK_SET = 0
SEEK_CUR = 1
SEEK_END = 2
def bytebuffer(size):
'''
Create a bytebuffer of given size (e.g. for use with read)
'''
return ('\0' * size)
##
# The MIT License (MIT)
#
# Copyright (c) 2014 Stefan Wendler
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
##
"""
Digital IO on VoCode Board using SYSFS
This is the version which runs with micropython
by using FFI to directely call libc open/read/write
functions.
"""
__author__ = 'Stefan Wendler, sw@kaltpost.de'
import nio
# Available pins on th VoCore
GPIO0 = 0
GPIO7 = 7
GPIO8 = 8
GPIO9 = 9
GPIO12 = 12
GPIO13 = 13
GPIO14 = 14
GPIO17 = 17
GPIO18 = 18
GPIO19 = 19
GPIO20 = 20
GPIO21 = 21
GPIO22 = 22
GPIO23 = 23
GPIO24 = 24
GPIO25 = 25
GPIO26 = 26
class Pin:
pinId = None
pinDir = ""
stateBuf = "\0"
def __init__(self, pinId):
self.pinId = pinId
self.export()
def __del__(self):
self.unexport()
def state(self):
f = nio.open(self.pinDir + "value", nio.O_RDONLY)
nio.read(f, self.stateBuf, 1)
nio.close(f)
if self.stateBuf[0] == "1":
return 1
return 0
def export(self):
f = nio.open("/sys/class/gpio/export", nio.O_WRONLY)
s = "%d" % self.pinId
nio.write(f, s, len(s))
nio.close(f)
self.pinDir = "/sys/class/gpio/gpio%d/" % self.pinId
def unexport(self):
f = nio.open("/sys/class/gpio/unexport", nio.O_WRONLY)
s = "%d" % self.pinId
nio.write(f, s, len(s))
nio.close(f)
def __str__(self):
return ("P_%d" % self.pinId)
class PinIn(Pin):
def __init__(self, pinId):
Pin.__init__(self, pinId)
f = nio.open(self.pinDir + "direction", nio.O_WRONLY)
s = "in"
nio.write(f, s, len(s))
nio.close(f)
class PinOut(Pin):
def __init__(self, pinId):
Pin.__init__(self, pinId)
f = nio.open(self.pinDir + "direction", nio.O_WRONLY)
s = "out"
nio.write(f, s, len(s))
nio.close(f)
def set(self):
f = nio.open(self.pinDir + "value", nio.O_WRONLY)
s = "1"
nio.write(f, s, len(s))
nio.close(f)
def clear(self):
f = nio.open(self.pinDir + "value", nio.O_WRONLY)
s = "0"
nio.write(f, s, len(s))
nio.close(f)
def toggle(self):
if self.state() == 1:
self.clear()
else:
self.set()
class DigitalIO:
def __init__(self):
pass
@staticmethod
def get_input(self, pinId):
return PinIn(pinId)
@staticmethod
def get_output(pinId):
return PinOut(pinId)
@staticmethod
def release(self, pin):
del pin
def main():
import time
pin = DigitalIO.get_output(GPIO12)
while True:
pin.toggle()
time.sleep(0.25)
if __name__ == "__main__":
main()
@wendlers
Copy link
Author

wendlers commented Nov 9, 2014

Simple Python program to drive GPIOs on the VoCore/MIPS using sysfs and micropython.

Note: I was not able to get micropython read/write the GPIO sysfs entries on the MIPS with Kernel 3.14 with it's build in open/read/write methods. Thus, I used FFI to wrap the libc's open/read/write methods to micropython which works.

@blark
Copy link

blark commented Feb 24, 2015

My micropython install throws an ImportError: no module named '_libc'

If I do libc = ffi.open("libc.so.0") it seems to work. I found this line here: https://github.com/micropython/micropython/blob/master/examples/unix/ffi_example.py

Am I missing something? My micropython is "Micro Python on 2015-02-23; linux version" from opkg on the VoCore.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment