Skip to content

Instantly share code, notes, and snippets.

@MitchRatquest
Last active January 23, 2018 03:06
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 MitchRatquest/7ef8bc6173d9650c5f27792be98c1898 to your computer and use it in GitHub Desktop.
Save MitchRatquest/7ef8bc6173d9650c5f27792be98c1898 to your computer and use it in GitHub Desktop.
ncurses-hardware-helper
#!/usr/bin/python
import subprocess, curses, curses.panel, os
from time import sleep
from menus import * #get all those stats
#################################################
#AVAILABLE BOARDS: opipc, opiz, opione, neo
board = neo
############################################
COLUMNS=79 #default tty size - 1
LINES=24
def make_panel(h,l, y,x, str):
win = curses.newwin(h,l, y,x)
win.erase()
win.box()
win.addstr(2, 10, str)
panel = curses.panel.new_panel(win)
return win, panel
def test(stdscr,board):
setupScreen(stdscr)
menuitems=getBoardMenu(board) #return array of menu item strings
currentMenuItem=menuitems[0] #declare starting point
highlightMenu(currentMenuItem,stdscr,board)
try:
mainMenu(stdscr, currentMenuItem, menuitems)
except KeyboardInterrupt:
curses.endwin()
quit()
def gpioMenu(screen, board):
helpwin,helppanel = make_panel(20,45,3,20, 'AVAILABLE COMMANDS:')
helppanel.hide()
defwin,defpanel = make_panel(24,75,0,0, 'DEFINITIONS:')
defpanel.hide()
screen.erase()
warning="White arrow on board always points to pin 1"
screen.addstr(0,COLUMNS/2-len(warning)/2,warning,curses.A_BOLD)
pinNumbers=board[3]
pinNames=board[2]
offset=1
for x in range(0,len(pinNumbers)+1): #create pin numbers
if x % 2==1: #right side
screen.addstr((x+offset-(x/2)), (COLUMNS/2-1), str(x), curses.A_BOLD) #put even numbers on right side
screen.addstr((x+offset-(x/2)), (COLUMNS/2-4)-len(pinNames[x]), pinNames[x]) #names on right side at the right offset
else:
screen.addstr((x+offset-(x/2)), (COLUMNS/2+2), str(x), curses.A_BOLD) #put odd numbers on left side
screen.addstr((x+offset-(x/2)), (COLUMNS/2+7), pinNames[x]) #names on left side
#now draw a box
screen.addstr(offset,36,'.-------.') #top bar
screen.addstr(offset+len(pinNumbers)/2+1,36,"'-------'") #bottom bar
screen.vline(offset+1,36,'|',len(pinNumbers)/2) #left side
screen.vline(offset+1,44,'|',len(pinNumbers)/2) #right side
index=4 #place on screen to draw
screen.chgat(index/2,15,25,curses.A_STANDOUT) #first pin
while True:
pinStats(index, screen)
c = screen.getch()
if c == curses.KEY_RIGHT:
helppanel.hide()
defpanel.hide()
screen.hline(24,0," ",COLUMNS)
index=index+1
#if index >=44:
if index >= len(pinNumbers)+4: #out of bounds on bottom
index=4 #wrap to top left
for x in range(0,LINES):
screen.chgat(x,0,curses.A_NORMAL)
if index %2==1: #right side
screen.chgat(index-(index/2)-1,41,COLUMNS/2,curses.A_STANDOUT)
else:
screen.chgat(index/2,15,25,curses.A_STANDOUT)
if c == curses.KEY_LEFT:
helppanel.hide()
defpanel.hide()
screen.hline(24,0," ",COLUMNS)
if index <5: #out of bounds on top
index= len(pinNumbers)+4 #wrap selection to bottom right
index = index-1
for x in range(0,LINES):
screen.chgat(x,0,curses.A_NORMAL)
if index %2==1: #right side
screen.chgat(index-(index/2)-1,41,COLUMNS/2,curses.A_STANDOUT)
else:
screen.chgat(index/2,15,25,curses.A_STANDOUT)
if c == curses.KEY_UP:
helppanel.hide()
defpanel.hide()
screen.hline(24,0," ",COLUMNS)
index = index-2
if index <4: #out of bounds on the top
index=len(pinNumbers)+3 #wrap selection to bottom right
for x in range(0,LINES):
screen.chgat(x,0,curses.A_NORMAL)
if index %2==1: #right side
screen.chgat(index-(index/2)-1,41,COLUMNS/2,curses.A_STANDOUT)
else:
screen.chgat(index/2,15,25,curses.A_STANDOUT)
if c == curses.KEY_DOWN:
helppanel.hide()
defpanel.hide()
screen.hline(24,0," ",COLUMNS)
index = index+2
if index >=len(pinNumbers)+4: #out of bottom bounds
index=4 #wrap selection to top left
for x in range(0,LINES):
screen.chgat(x,0,curses.A_NORMAL)
if index %2==1: #right side
screen.chgat(index-(index/2)-1,41,COLUMNS/2,curses.A_STANDOUT)
else:
screen.chgat(index/2,15,25,curses.A_STANDOUT)
if c == 27: #escape key to quit
clearScreen(screen)
return
###########################################
#
# s = intitialize
# u = uninitialize
# i = input
# o = output
# 1 = set high
# 0 = set low
# r = read pin value
#
# h = help menu, basically this prompt
#
###############################################
if c == 115: # ord('s')
screen.hline(24,0," ",79) #clear line completely
if pinNumbers[(index-4)] == -1:
response = "cannot init this pin"
pass
elif createPinsysfs(pinNumbers[(index-4)]) == 0:
response = "successfully initialized pin " + str((index+3)/2)
screen.addstr(24,80/2-len(response)/2,response,curses.A_STANDOUT)
if c == 117: # 'u'
screen.hline(24,0," ",79) #clear line completely
if pinNumbers[(index-4)] == -1:
response = "cannot uninit this pin"
pass
elif removePinsysfs(pinNumbers[(index-4)]) == 0:
response = "successfully uninitialized pin " + str((index+3)/2)
screen.addstr(24,80/2-len(response)/2,response,curses.A_STANDOUT)
if c == 114: # 'r'
if pinNumbers[(index-4)] == -1:
response = "This pin's state is not able to be changed"
pass
else:
screen.hline(24,0," ",79)
value = readPinsysfs(pinNumbers[(index-4)])
if value is None:
response = "This pin is not initialized"
else:
response = "Pin "+str(index-3)+"'s value is "+str(value)
screen.addstr(24,80/2-len(response)/2,response,curses.A_STANDOUT)
if c == 105: # 'i'
screen.hline(24,0," ",79) #clear line completely
if pinNumbers[(index-4)] == -1:
response = "This pin's state is not able to be changed"
pass
else:
value = directionPinsysfs(pinNumbers[(index-4)],'in')
if value == 0:
response = "Pin "+str(index-3)+" is an input pin and can sink up to 10 milliamps"
if value == -1:
response = "Pin is already set to input"
screen.addstr(24,80/2-len(response)/2,response,curses.A_STANDOUT)
if c == 111: # 'o'
if pinNumbers[(index-4)] == -1:
response = "This pin's state is not able to be changed"
screen.addstr(24,80/2-len(response)/2,response,curses.A_STANDOUT)
pass
else:
screen.hline(24,0," ",79) #clear line completely
value = directionPinsysfs(orangepiPCPins[(index-3)*2-1],'out')
if value == 0:
response = "Pin "+str(index-3)+" is an output pin and can source up to 10 milliamps"
if value == -1:
response = "Pin is already set to output"
screen.addstr(24,80/2-len(response)/2,response,curses.A_STANDOUT)
if c == 49: # '1'
screen.hline(24,0," ",79) #clear line completely
response=''
if orangepiPCPins[(index-3)*2-1] == -1:
response = "This pin's state is not able to be changed"
elif os.path.isdir('/sys/class/gpio/gpio'+str(orangepiPCPins[(index-3)*2-1])) == False: #not configured
createPinsysfs(orangepiPCPins[(index-3)*2-1])
elif readSysfs(orangepiPCPins[(index-3)*2-1], 'direction') == 'in':
response = "This pin is an input and cannot be set to 1 (3.3 volts)"
screen.addstr(24,80/2-len(response)/2,response,curses.A_STANDOUT)
else:
value = valuePinsysfs(orangepiPCPins[(index-3)*2-1],'On')
if value == 0:
response = "Pin "+str(index-3)+"'s value is set to 1 (3.3 volts)"
if value == -1:
response = "Pin's value is already at 1"
screen.addstr(24,80/2-len(response)/2,response,curses.A_STANDOUT)
if c == 48: # '0'
screen.hline(24,0," ",79) #clear line completely
if orangepiPCPins[(index-3)*2-1] == -1:
response = "This pin's state is not able to be changed"
elif os.path.isdir('/sys/class/gpio/gpio'+str(orangepiPCPins[(index-3)*2-1])) == False: #not configured
createPinsysfs(orangepiPCPins[(index-3)*2-1])
elif readSysfs(orangepiPCPins[(index-3)*2-1],'direction').strip('\n')=='in':
response = "This is set to input and cannot be pulled low"
else:
value = valuePinsysfs(orangepiPCPins[(index-3)*2-1],0)
if value == 0:
response = "Pin "+str(index-3)+"'s value is set to 0 (ground)"
if value == -1:
response = "Pin's value is already at 0"
screen.addstr(24,80/2-len(response)/2,response,curses.A_STANDOUT)
if c == 104: # 'h'
#helpwin.erase()
#helpwin,helppanel = make_panel(20,45,3,20, 'AVAILABLE COMMANDS:')
helpwin.addstr(2,10,"AVAIALBLE COMMANDS: ")
helpwin.addstr(4,10,"s - initialize pin")
helpwin.addstr(5,10,"u - unitialiaze pin")
helpwin.addstr(6,10,"r - read pin's current value")
helpwin.addstr(7,10,"i - set pin direction input")
helpwin.addstr(8,10,"o - set pin direction output")
helpwin.addstr(9,10,"1 - set pin high")
helpwin.addstr(10,10,"0 - set pin low")
helpwin.addstr(12,2,"press any arrow key to close this window")
helpwin.addstr(14,2,"press m if this you need more help", curses.A_BOLD)
helppanel.show()
helpwin.refresh()
updateScreen(screen)
c = helpwin.getch()
if c == 109: #'m'
#defwin,defpanel = make_panel(24,75,0,0, 'DEFINITIONS:')
#defwin.erase()
defwin.addstr(2,10, "DEFINITIONS:")
defwin.addstr(3,4,"The row of pins on the board have several functions", curses.A_BOLD)
defwin.addstr(4,4,"The ones marked Ground, 5 volts, and 3.3 volts can't be changed", curses.A_BOLD)
defwin.addstr(5,4,"The other ones can either be general purpose inputs or outputs", curses.A_BOLD)
defwin.addstr(6,4,"They are called GPIO", curses.A_BOLD)
defwin.addstr(7,4,"Some GPIO are part of other systems, such as SPI, I2C, and I2S", curses.A_BOLD)
defwin.addstr(8,4,"----------------------------------------------------------------",curses.A_BOLD)
defwin.addstr(9,4,"Pin names are derived from a formula based on the H3 CPU:",curses.A_BOLD)
defwin.addstr(10,4,"(position of letter in alphabet - 1) * 32 + pin number",curses.A_BOLD)
defwin.addstr(11,4,"So PG14 would be pin number 206",curses.A_BOLD)
defwin.addstr(12,4,"Pins have to be initialized before they can be used",curses.A_BOLD)
defwin.addstr(13,4,"Echo your calculated pin number to /sys/class/gpio/export",curses.A_BOLD)
defwin.addstr(14,4,"This creates the directory /sys/class/gpio/gpio206",curses.A_BOLD)
defwin.addstr(15,4,"Now you can change the properties of the pins",curses.A_BOLD)
defwin.addstr(16,4,"By echoing values to the files in that directory",curses.A_BOLD)
defwin.addstr(17,4,"----------------------------------------------------------------",curses.A_BOLD)
defwin.addstr(18,4,"For more information, google 'gpio with sysfs'",curses.A_BOLD)
defwin.addstr(19,4,"With patience, you can learn it. Believe in yourself",curses.A_BOLD)
defwin.addstr(21,4,"PRESS ANY ARROW KEY TO EXIT THIS PROMPT", curses.A_STANDOUT)
defwin.refresh()
defpanel.show()
updateScreen(screen)
helpwin.timeout(-1)
def mainMenu(stdscr, currentMenuItem, menuitems):
while True:
changed=0
c = 0
c = stdscr.getch() #get a character
if c == curses.KEY_RIGHT:
try:
currentMenuItem=menuitems[menuitems.index(currentMenuItem)+1]
except:
currentMenuItem=menuitems[0] #loop it
changed=1
if c == curses.KEY_LEFT:
try:
currentMenuItem=menuitems[menuitems.index(currentMenuItem)-1]
except:
currentMenuItem=menuitems[0] #loop it
changed=1
if c == 32: #enter or spacebar for selection
stdscr.addstr(10,20,"YOU HAVE SELECTED: %s" %currentMenuItem, curses.A_BOLD)
if currentMenuItem=="GPIO":
gpioMenu(stdscr,board)
currentMenuItem=menuitems[0]
#highlightMenu(currentMenuItem,stdscr,board)
if currentMenuItem=="USB":
#manually plug things into these ports and figure out their lsusb bus id
#then tell the user what is plugged in and at what speed
#same thing with USB2.0, but maybe use one of those cool cube things from asciio
pass
if currentMenuItem=="ETH0":
#display ifconfig?
#make sure its active with dmesg | grep
#state speed
#options like nmtui for setting up a static ip
#dnsmasq configs?
pass
if currentMenuItem=="USBX2":
#same as USB
pass
if currentMenuItem=="AUDIO":
#alsamixer prompt (not sure how do swing that)
#speaker-test
#TV out does not work on mainline
pass
if currentMenuItem=="MIC":
#arecord
#simple visualizer? with alsa api?
pass
if currentMenuItem=="HDMI":
#h3disp? does that work on mainline?
#check /boot/boot.cmd to make sure sane settings
# Recompile with:
# mkimage -C none -A arm -T script -d /boot/boot.cmd /boot/boot.scr
#check device tree
#make sure dtc is installed
#fancy string search sed -i stuff
pass
if currentMenuItem=="CSI":
pass
if currentMenuItem=="USBOTG":
usbMenu(stdscr)
'''
possible legacy drivers:
g_ether
g_serial
warning that this already is set up
g_mass_storage
cdrom=y, for booting ISOs
g_hid
g_midi
possible configfs stuff:
literally anything
options for dns server with g_ethernet
options for iptables routing to use device as usb-ethernet dongle
directions for possible network sharing setups on linux, windows, mac
modify /etc/modules
'''
updateScreen(stdscr)
if(changed==1):
highlightMenu(currentMenuItem,stdscr,board) #display selection
if c == 27: #escape key to quit
curses.endwin()
quit()
def pinStats(pin,screen):
for x in range(0,5):
screen.addstr(x,0,' ')
actualpin = orangepiPCPins[(pin-3)*2-1] #get actual pin number, aka PC7=71 or whatever
if actualpin == -1:
slot1="cant change"
screen.addstr(0,0,slot1,curses.A_STANDOUT)
updateScreen(screen)
return
else:
slot1='sysfs#: '
screen.addstr(0,0,slot1+str(actualpin),curses.A_STANDOUT)
if os.path.isdir('/sys/class/gpio/gpio'+str(actualpin)) == False:#no config dir
configured1="This pin not"
configured2="configured"
screen.addstr(1,0,configured1,curses.A_STANDOUT)
screen.addstr(2,1,configured2,curses.A_STANDOUT)
else:
success="configured"
screen.addstr(1,0,success,curses.A_STANDOUT)
#file = '/sys/class/gpio/gpio'+str(actualpin)+'/value'
#p = subprocess.Popen(["cat",file],stdout=subprocess.PIPE)
#out, err = p.communicate()
status = "cur val: " + str(readPinsysfs(actualpin))
screen.addstr(2,0,status,curses.A_STANDOUT)
status2 = "cur dir: "
file = '/sys/class/gpio/gpio'+str(actualpin)+'/direction'
p = subprocess.Popen(['cat',file],stdout=subprocess.PIPE)
out, err = p.communicate()
status2 += out.strip('\n')
screen.addstr(3,0,status2,curses.A_STANDOUT)
status3= "activelow: "
activelow=str(readSysfs(actualpin,'active_low').strip('\n'))
screen.addstr(4,0,status3+activelow,curses.A_STANDOUT)
updateScreen(screen)
def highlightMenu(menuitem,screen,board): #need to pass it stdscr
'''
takes a string which is in an array and highlights the element it is referring to as described in the array
"STRING"[starty,startx,endy,endx]
startx
starty-> .------------------.
| |
| |
.------------------. <---endy
^endx
'''
for x in range(0,len(board[0].split('\n'))): #redraw screen with outline
screen.addstr(x,0,board[0].split('\n')[x])
counter = 0
for x in range(board[1][board[1].index(menuitem)+1][0],board[1][board[1].index(menuitem)+1][2]+1): #only highlight the areas that need it
screen.addstr((board[1][board[1].index(menuitem)+1][0])+counter,board[1][board[1].index(menuitem)+1][1],board[0].split('\n')[x][board[1][board[1].index(menuitem)+1][1]:board[1][board[1].index(menuitem)+1][3]], curses.A_BOLD | curses.A_STANDOUT)
counter=counter+1
updateScreen(screen)
def setupScreen(screen):
try:
curses.curs_set(0)
screen.nodelay(1)
except:
pass
curses.start_color()
curses.use_default_colors()
for i in range(0, curses.COLORS):
curses.init_pair(i+1, i, 0)
#screen.bkgd(' ', curses.color_pair(0 ) )
def clearScreen(screen):
for x in range(0,25):
screen.hline(x,0,' ',COLUMNS) #erase entire screen
screen.chgat(x,0,curses.A_NORMAL) #reset to normal attributes
def updateScreen(screen):
curses.panel.update_panels()
screen.refresh()
def getBoardMenu(board):
menuitems=[]
for x in range(0,len(board[1]),2): #get menu item titles
menuitems.append(board[1][x])
return menuitems
def createPinsysfs(pin):
if os.path.isdir('/sys/class/gpio/gpio'+str(pin)) == False:
command = 'echo ' + str(pin) + ' > /sys/class/gpio/export'
subprocess.call(command,shell=True)
return 0
else:
return -1
def removePinsysfs(pin):
if os.path.isdir('/sys/class/gpio/gpio'+str(pin)) == True:
command = 'echo ' + str(pin) + ' > /sys/class/gpio/unexport'
subprocess.call(command,shell=True)
return 0
else:
return -1
def directionPinsysfs(pin,direction):
if os.path.isdir('/sys/class/gpio/gpio'+str(pin)) == True:
command = 'echo ' + str(direction) + ' > /sys/class/gpio/gpio' + str(pin) + '/direction'
subprocess.call(command, shell=True)
return 0
else:
return -1
def valuePinsysfs(pin, value):
if os.path.isdir('/sys/class/gpio/gpio'+str(pin)) == True:
if value == "True" or value == "On" or value == 1:
value = 1
else:
value = 0
command = 'echo ' + str(value) + ' > /sys/class/gpio/gpio'+str(pin)+'/value'
subprocess.call(command,shell=True)
if readSysfs(pin, 'direction') == 'in': #can't set input high
return -1
return 0
else:
return -1
def readPinsysfs(pin):
if os.path.isdir('/sys/class/gpio/gpio'+str(pin)) == True:
file = '/sys/class/gpio/gpio'+str(pin)+'/value'
p = subprocess.Popen(["cat",file],stdout=subprocess.PIPE)
out, err = p.communicate()
return out.strip('\n')
def readSysfs(pin, filename):
file = '/sys/class/gpio/gpio'+str(pin)+'/'+str(filename)
p = subprocess.Popen(["cat",file],stdout=subprocess.PIPE)
out, err = p.communicate()
return out.strip('\n')
def readFile(filename):
with open(filename,"r+") as a:
lines = a.readlines()
return lines
def writeFile(filename,strings):
with open(filename,"w+") as a:
a.write(strings)
a.close()
def replaceModules(replace): #modify boot modules
original = readfile('/etc/modules')
newstring = ''
for line in original:
if line.strip('\n') == replace:
newstring += replace + '\n'
newstring += line
writefile('/etc/modules',newstring)
#modprobe ir_lirc_codec
def runCommand(command):
command=command.split(' ')
p = subprocess.Popen(command,stdout=subprocess.PIPE)
out, err = p.communicate()
return out
help = subprocess.Popen(command,stdout=subprocess.PIPE)
out = p.communicate
for line in out[0].split('\n'):
print line
def Bash(command):
return subprocess.check_output(['bash','-c',command]).strip('\n').split('\n')
def findThis(command,pattern):
try:
Bash(command).index(pattern)
return 1
except:
return -1
def usbMenu(screen):
screen.erase()
#lsmod | grep -m1 g_
currentGadget = "Current loaded gadget: "
currentGadget += Bash("lsmod | grep -m1 g_ | awk '{print $1}'")[0] #current module loaded
kernel = Bash("uname -r")[0]
directory = "/lib/modules/" + kernel + "/kernel/drivers/usb/gadget/legacy"
try:
functionsSupported = Bash("ls "+directory)
for x in range(len(functionsSupported)):
functionsSupported[x] = functionsSupported[x].strip('.ko') #now its a nice list of gadgets
except:
functionsSupported = ["no usb gadget modules in your kernel"]
title = "microUSB / USB OTG functions"
screen.addstr(0,80/2-len(title)/2,title,curses.A_BOLD)
screen.hline(1,0,'-',79)
screen.addstr(2,80/2-len(currentGadget)/2,currentGadget,curses.A_BOLD)
for x in range(len(functionsSupported)):
screen.addstr(5+x,80/2-len(functionsSupported[x]),functionsSupported[x], curses.A_BOLD)
#gadgetfs setup:
try:
Bash("modprobe libcomposite")
Bash("mount -t configfs none /sys/kernel/config")#mount none cfg -t configfs?
if findThis("ls /sys/kernel/config","usb_gadget") == 1:
gadgetfs = "gadgetFS supported on this kernel"
except:
gadgetfs = "no gadgetFS support available"
FUNCTIONS_USER_ENABLED=[]
#setup -> go through list of gadgets -> finish
#https://www.kernel.org/doc/Documentation/usb/gadget_configfs.txt
#https://www.kernel.org/doc/Documentation/ABI/testing/configfs-usb-gadget-ecm
#https://www.kernel.org/doc/Documentation/ABI/testing/configfs-usb-gadget-acm
#https://www.kernel.org/doc/Documentation/ABI/testing/configfs-usb-gadget-mass-storage
#this is where i got the initial stuff from:
#https://github.com/ckuethe/usbarmory/wiki/USB-Gadgets
#http://isticktoit.net/?p=1383
#https://www.kernel.org/doc/Documentation/ABI/testing/
#nice demo here: https://s3.amazonaws.com/connect.linaro.org/sfo15/Presentations/09-23-Wednesday/SFO15-311-%20ConfigFS%20Gadgets-%20An%20Introduction.pdf
def setupGadget(serial=8349982, manuf="testing", product="multigadget"):
topdir = "/sys/kernel/config/usb_gadget"
Bash("mkdir -p "+topdir+"/g1")
Bash("echo 0x1d6b > "+topdir+"/g1/idVendor") # Linux Foundation
Bash("echo 0x104 > "+topdir+"/g1/idProduct") # Multifunction Composite Gadget
Bash("echo 0x0100 > "+topdir+"/g1/bcdDevice") # v1.0.0
Bash("echo 0x0200 > "+topdir+"/g1/bcdUSB") # USB2
Bash("mkdir -p "+topdir+"/g1/strings/0x409") #0x409 for english language strings
Bash("echo "+str(serial)+" > "+topdir+"/g1/strings/0x409/serialnumber")
Bash("echo "+str(manuf)+" > "+topdir+"/g1/strings/0x409/manufacturer")
Bash("echo "+str(product)+" > "+topdir+"/g1/strings/0x409/product")
def gadgetRNDIS():
topdir = "/sys/kernel/config/usb_gadget/g1/"
Bash("mkdir -p "+topdir+"functions/rndis.usb0")
Bash("mkdir -p "+topdir+"configs/c.1")
Bash("mkdir -p "+topdir+"configs/c.1/strings/0x409")
Bash("echo 'Config 1: RNDIS network' > "+topdir+"configs/c.1/strings/0x409/configuration")
Bash("echo 500 > "+topdir+"configs/c.1/MaxPower")
Bash("ln -s "+topdir+"functions/rndis.usb0 "+topdir+"configs/c.1")
#check for /etc/network/interfaces for a usb0 device and set that up according to user input
#ex: static, dhcp, static but dnsmasq enabled, brctl, iptables for weird usb/ethernet dongle
#static: address netmask
#dhcp: ifup usb0
#static, but dnsmasq being served from 0.0.0.0
#ifconfig usb0 0.0.0.0; ifconfig eth0 0.0.0.0; brctl addbr br0; brctl addif br0 eth0; brctl addif br0 usb0; ifup br0
#iface br0 inet dhcp
# bridge_ports eth0 usb0
#ifup br0
def finishGadget():
topdir = "/sys/kernel/config/usb_gadget/g1/"
Bash("echo 500 > "+topdir+"configs/c.1/MaxPower") # not until after right before attachment
Bash("ls /sys/class/udc > "+topdir+"UDC") #finally attach functions to the hardware
#if 'ethernet' in FUNCTIONS_USER_ENABLED:
#ifup usb0
def disableGadget():
Bash("echo '' > "+topdir+"UDC") #unlink
if __name__ == '__main__':
curses.wrapper(test,board)
'''
basicinfo = [
outline, #initial ascii drawing on screen
menu, #describes all selectable elements by name and area
pinsEnglish, #human readable pins and functions
pinsBGA, #sysfs pin numbers on H3 chip
]
'''
nanopineoMenu=[ #areas to highlight
"ETH0",[0,11,8,25],
"USB0",[0,27,8,33],
"AUDIO",[3,35,7,36],
"UART",[5,38,9,39],
"USB/I2S",[5,40,19,45],
"MICROSD",[16,23,22,38],
"USBOTG",[20,11,23,19],
"GPIO",[4,3,20,10]
]
nanopineoOutline=""" .------------. .----.
.-------| |--| |-----------.
| | | | | |
| | | | U | A |
.-----. | ETH0 | | S | U |
| | | | | B | D U .---.
| | | | | | I A | |
| | | | | | O R | |
| | '------------' '----' T | |
| | | U |
| G | | S |
| P | | B |
| I | NANOPI NEO | / |
| O | | I |
| | | 2 |
| | | S |
| | .-------------. | |
| | | | | |
| | | | | |
| | <PIN 1 | MICROSD | '---'
'-----' .------. | | |
| | USB | | | |
'-------| OTG |----'-------------'------'
'------' """
nanopineoPinsEnglish=[ '',#need dummy first string?
'3.3 volts', '5 volts',
'I2C0-SDA / PA12', '5 volts',
'I2C0-SCK /PA11', 'Ground',
'PMW1 / PA6', 'SPI1-CS / PA13',
'Ground', 'SPI1-CLK / PA14',
'UART2-RX / PA1', 'PD14',
'UART2-TX / PA0', 'Ground',
'UART2-CTS / PA3', 'PC4',
'3.3 volts', 'PC7',
'SPI0-MOSI / PC0', 'Ground',
'SPI0-MISO / PC1', 'UART2_RTS / PA2',
'SPI0-CLK / PC2', 'SPI0-CS / PC3'
]
nanopineoPinsBGA=[
-1,-1,
12,-1,
11,-1,
6,13,
-1,14,
1,110,
0,-1,
3,68,
-1,71,
64,-1,
65,2,
66,67
]
nanopineoSmallPinsEnglish=['',
'5 volts',
'USB-DP1',
'USB-DM1',
'USB-DP2',
'USB-DM2',
'GPIOL11 / IR-RX',
'SPDIF-OUT / GPIOA17',
'PCM0-SYNC / I2S0-LRC',
'PCM0-CLK / I2S0-BCK',
'PCM0-DOUT / I2S0-SDOUT',
'PCM0-DIN / I2S0-DIN',
'Ground'
]
nanopineoPinsAudio=[
'Mic-in Positive',
'Mic-in Negative',
'Line out Right',
'Ground',
'Line out left'
]
nanopineoUART=[
'Ground',
'5 volts',
'TX',
'RX'
]
neo = []
neo.append(nanopineoOutline)
neo.append(nanopineoMenu)
neo.append(nanopineoPinsEnglish)
neo.append(nanopineoPinsBGA)
neo.append(nanopineoSmallPinsEnglish)
neo.append(nanopineoPinsAudio)
neo.append(nanopineoUART)
########################################################
orangepiOneMenu=[
"GPIO",[0,10,3,62],
"MICROSD",[12,36,19,51],
"HDMI",[16,16,22,31],
"USBOTG",[17,6,20,13],
"UART",[15,7,15,11],
"ETH0",[8,1,14,17],
"USB",[5,2,7,15]
]
orangepiOneOutline=""" .-----.--------------------------------------------------.-------.
| | GPIO | <PIN 1|
| | | |
| '--------------------------------------------------' |
| |
.-----------. |
| USB | |
'-----------' |
.--------------. ORANGE PI ONE |
| | |
| | |
| ETH0 | |
| | .-------------. |
| | | | |
'--------------' | | .----. |
| UART | | | D | |
| .-------------. | MICROSD | | C | |
| .-----. | | | | | - | |
| | USB | | HDMI | | | | I | |
'-| OTG |---| |-----'-------------'------| N |------'
'-----' | | '----'
'-------------' """
orangepiOnePinsEnglish=['',
'3.3 volts', '5 volts',
'I2C0-SDA / PA12', '5 volts',
'I2C0-SCK /PA11', 'Ground',
'PMW1 / PA6', 'SPI1-CS / PA13',
'Ground', 'SPI1-CLK / PA14',
'UART2-RX / PA1', 'PD14',
'UART2-TX / PA0', 'Ground',
'UART2-CTS / PA3', 'PC4',
'3.3 volts', 'PC7',
'SPI0-MOSI / PC0', 'Ground',
'SPI0-MISO / PC1', 'UART2_RTS / PA2',
'SPI0-CLK / PC2', 'SPI0-CS / PC3',
'Ground', 'PCM0-DIN / PA21',
'PCM0-CLK / I2C1-SDA / PA19', 'PCM0-SYNC / I2C1-SCK / PA18',
'PA7', 'Ground',
'PA8', 'PG8',
'PA9', 'Ground',
'PA10', 'PG9',
'PA20', 'PG6',
'Ground', 'PG7'
]
orangepiOnePinsBGA=[
-1,-1,
12,-1,
11,-1,
6,13,
-1,14,
1,110,
0,-1,
3,68,
-1,71,
64,-1,
65,2,
66,67,
-1,21,
19,18,
7,1,
8,200,
9,-1,
10,201,
20,196,
-1,197
]
orangepiOneUART=[
'Ground',
'RX',
'TX'
]
opione=[]
opione.append(orangepiOneOutline)
opione.append(orangepiOneMenu)
opione.append(orangepiOnePinsEnglish)
opione.append(orangepiOnePinsBGA)
opione.append(orangepiOneUART)
####################################################################
orangepiPCMenu=[
"GPIO",[0,7,3,65],
"IR",[0,66,2,71],
"USB",[4,63,6,80],
"ETH0",[7,61,13,80],
"USBX2",[14,63,19,80],
"AUDIO",[17,54,23,60],
"MIC",[20,42,22,47],
"HDMI",[18,24,23,39],
"UART",[21,17,21,21],
"CSI",[9,2,17,7],
"USBOTG",[4,1,8,6]
]
orangepiPCOutline=""" .----.--------------------------------------------------------.-.---.---.
| | | |IR | |
| | GPIO | '---' |
| '--------------------------------------------------------' |
.---. ^PIN 1 .---------------.
|U | <- USE ARROW KEYS -> | USB |
|S | SPACEBAR TO SELECT '---------------'
|B | .-----------------.
'---' ORANGE PI PC | |
.---. | |
| | | ETH0 |
| | | |
| C | | |
| S | '-----------------'
| I | .---------------.
| | | |
| | | USB |
'---' .----. | X2 |
| .---. .-------------. | A | | |
| | D | | | | U | '---------------'
| | C | | | .---. | D | |
| | I | UART | HDMI | |MIC| | I | |
'-----| N |-----------| |---'---'-------| O |--------------'
'---' '-------------' '----' """
'''
pins:
direction in out
value 0 1
gnd
5v
3v
spi
i2c
pin=raw_input();((ord(pin[1].lower())-97)*32)+int(pin[2:])
'''
orangepiPCPins=[
'3.3 volts' ,-1,'5 volts' ,-1,
'I2C0-SDA / PA12' ,12,'5 volts' ,-1,
'I2C0-SCK /PA11' ,11,'Ground' ,-1,
'PMW1 / PA6' ,6, 'SPI1-CS / PA13' ,13,
'Ground' ,-1,'SPI1-CLK / PA14' ,14,
'UART2-RX / PA1' ,1, 'PD14' ,110,
'UART2-TX / PA0' ,0, 'Ground' ,-1,
'UART2-CTS / PA3' ,3, 'PC4' ,68,
'3.3 volts' ,-1,'PC7' ,71,
'SPI0-MOSI / PC0' ,64,'Ground' ,-1,
'SPI0-MISO / PC1' ,65,'UART2_RTS / PA2' ,2,
'SPI0-CLK / PC2' ,66,'SPI0-CS / PC3' ,67,
'Ground' ,-1,'PCM0-DIN / PA21' ,21,
'PCM0-CLK / I2C1-SDA / PA19',19,'PCM0-SYNC / I2C1-SCK / PA18' ,18,
'PA7' ,7, 'Ground' ,-1,
'PA8' ,8, 'PG8' ,200,
'PA9' ,9, 'Ground' ,-1,
'PA10' ,10,'PG9' ,201,
'PA20' ,20,'PG6' ,196,
'Ground' ,-1,'PG7' ,197
]
orangepiPCPinsEnglish=['',
'3.3 volts', '5 volts',
'I2C0-SDA / PA12', '5 volts',
'I2C0-SCK /PA11', 'Ground',
'PMW1 / PA6', 'SPI1-CS / PA13',
'Ground', 'SPI1-CLK / PA14',
'UART2-RX / PA1', 'PD14',
'UART2-TX / PA0', 'Ground',
'UART2-CTS / PA3', 'PC4',
'3.3 volts', 'PC7',
'SPI0-MOSI / PC0', 'Ground',
'SPI0-MISO / PC1', 'UART2_RTS / PA2',
'SPI0-CLK / PC2', 'SPI0-CS / PC3',
'Ground', 'PCM0-DIN / PA21',
'PCM0-CLK / I2C1-SDA / PA19', 'PCM0-SYNC / I2C1-SCK / PA18',
'PA7', 'Ground',
'PA8', 'PG8',
'PA9', 'Ground',
'PA10', 'PG9',
'PA20', 'PG6',
'Ground', 'PG7'
]
orangepiPCPinsBGA=[
-1,-1,
12,-1,
11,-1,
6,13,
-1,14,
1,110,
0,-1,
3,68,
-1,71,
64,-1,
65,2,
66,67,
-1,21,
19,18,
7,1,
8,200,
9,-1,
10,201,
20,196,
-1,197
]
orangepiPCUART=[
'Ground', #nearest the DC barrel
'RX',
'TX' #nearest the HDMI
]
coolUSB=""" .------.
/ /|
.------. |
| USB2 | |
|------| '
| USB1 |/
'------'
"""
opipc=[]
opipc.append(orangepiPCOutline)
opipc.append(orangepiPCMenu)
opipc.append(orangepiPCPinsEnglish)
opipc.append(orangepiPCPinsBGA)
opipc.append(orangepiPCUART)
PINS=""" .-------.
3.3 volts | 1 2 | 5 volts
I2C_SDA / PA12 | 3 4 | 5 volts
I2C_SCK / PA11 | 5 6 | GND
PWM1 / PA6 | 7 8 | PA13 / SPI1_CS / UART3_TX
GND | 9 10 | PA14 / SPI1_CLK / UART3_RX
UART2_RX / PA1 | 11 12 | PD14
UART2_TX / PA0 | 13 14 | GND
UART2_CTS / PA3 | 15 16 | PC4
3.3 volts | 17 18 | PC7
SPI0-MOSI / PC0 | 19 20 | GND
SPI0-MISO / PC1 | 21 22 | PA2 / UART2_RTS
SPI0-CLK / PC2 | 23 24 | PC3 / SPI0_CS
GND | 25 26 | PA21 / PCM0_DIN
PCM0-CLK / I2C1-SDA / PA19 | 27 28 | PA18 / PCM0_SYNC / SDA1_SCK
PA7 | 29 30 | GND
PA8 | 31 32 | PG8 / UART1_RTS
PA9 | 33 34 | GND
PA10 | 35 36 | PG9 / UART1_CTS
PA20 | 37 38 | PG6 / UART1_TX
GND | 39 40 | PG7 / UART1_RX
'-------'
"""
###############################################################
orangepiZeroOutline=""" .----. .---------------.
.-------| |--| |--------------.
| | | | | U |
.--. |USB | | ETH0 | A .-----.
| | | | | | R | |
| | | | | | T | |
| | '----' | | | |
|U | | | | |
|S | '---------------' | |
|B | .-----. | |
|/ | |WIFI | USE ARROW KEYS TO MOVE | G |
|A | | | SPACEBAR TO SELECT | P |
|U | '-----' | I |
|D | .---------------. | O |
|I | | | .------. | |
|O | | | | | | |
|/ | | | | | | |
|T | |ORANGE PI ZERO | | | | |
|V | | | | | | |
| | | | | | | |
| | | | | | | |
|--' .------.----------' '------' '-----'
| | USB | PIN 1^|
'------| OTG |--------------------------------'
'------' """
orangepiZeroMenu=[ #areas to highlight indexed at top left = 0,0 = y,x
"USB",[0,9,6,15],
"ETH0",[0,17,8,34],
"UART",[2,37,5,38],
"GPIO",[3,42,21,49],
"USBOTG",[21,8,24,16],
"USB/AUDIO",[3,1,22,5],
"WIFI",[9,8,12,15]
]
orangepiZeroPinsEnglish=['',
'3.3 volts', '5 volts',
'I2C0-SDA / PA12', '5 volts',
'I2C0-SCK /PA11', 'Ground',
'PMW1 / PA6', 'UART1-RX / PG7',
'Ground', 'UART1-TX / PG6',
'UART2-RX / PA1', 'PA7',
'UART2-TX / PA0', 'Ground',
'UART2-CTS / PA3', 'IC21-SCK / PA15',
'3.3 volts', 'I2C1-SDA / PA19',
'SPI1-MOSI / PA15', 'Ground',
'SPI1-MISO / PA16', 'UART2_RTS / PA2',
'SPI1-CLK / PA14', 'SPI1-CS / PA13',
'Ground', 'PA10',
]
orangepiZeroPinsBGA=[
-1,-1,
12,-1,
11,-1,
6,199,
-1,198,
1,7,
0,-1,
3,15,
-1,19,
15,-1,
16,2,
14,13,
-1,10
]
orangepiZeroPinsUSB=[
'5 volts',
'Ground',
'USB-DM2',
'USB-DP2',
'USB-DM3',
'USB-DP3',
'Line out Right',
'Line out Left',
'TV out',
'Mic bias',
'Mic in Positive',
'Mic in Negative',
'IR-RX'
]
orangepiZeroUART=[
'Ground',
'RX',
'TX'
]
opiz=[]
opiz.append(orangepiZeroOutline)
opiz.append(orangepiZeroMenu)
opiz.append(orangepiZeroPinsEnglish)
opiz.append(orangepiZeroPinsBGA)
opiz.append(orangepiZeroPinsUSB)
opiz.append(orangepiZeroUART)
#####################################################################
#for line in orangepiPCOutline.split('\n'):
# print line
#for x in range(0,24):
# print orangepiPCOutline.split('\n')[x]orangepiPCMenu[orangepiPCMenu.index("GPIO")+1][2]
#gpio is from 1,8 to 4, 64 inclusive so that means
#draw 1,8 through 1-64
#draw 2,8 through 2-64
#draw 3,8 through 3-64
#
#for x in range(orangepiPCMenu[orangepiPCMenu.index("GPIO")+1][0]-1,orangepiPCMenu[orangepiPCMenu.index("GPIO")+1][2]):
# print orangepiPCOutline.split('\n')[x][orangepiPCMenu[orangepiPCMenu.index("GPIO")+1][1]-1:orangepiPCMenu[orangepiPCMenu.index("GPIO")+1][3]]
#only in range x, print out active area as described by [starty,startx,endy,endx]
@MitchRatquest
Copy link
Author

Currently a rush job on feasibility for a 'small' python interactive interface using curses to control and monitor the hardware aspects of some small Allwinner H3 based single board computers. Started working on the Orangepi PC model, moving towards the Orangepi One, Zero, and Nanopi Neo, which I can verify as I have the hardware.

Can initialize/unititialize GPIO using the sysfs interface, and toggle the value and direction.

Currently working on displaying USB OTG information in a sane manner, and modularizing the configfs manner of creating custom interfaces. Still working on solutions for the RNDIS interface, which some less experienced people may find hard to 1) figure out the IP address 2) assign an IP address or 3) ssh into the machine using the USB cable.

Ideal finished script will have all functions working and will save all setup done as a script, or output a systemd/init.d script to provision any future boards.

Ascii art made with asciio.

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