Skip to content

Instantly share code, notes, and snippets.

@wendlers wendlers/nio.py
Created Nov 9, 2014

Embed
What would you like to do?
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

This comment has been minimized.

Copy link
Owner 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

This comment has been minimized.

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
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.