From cf35a48ff946666257144e652c7e3023b5dd2a25 Mon Sep 17 00:00:00 2001 From: enesbcs Date: Wed, 15 Apr 2020 20:06:40 +0200 Subject: [PATCH] Modifing internal GPIO handling to support alternative hardwares --- RPIEasy.py | 41 +- Settings.py | 4 +- gpios.py | 1300 +--------------------------------------- lib/lib_opigpios.py | 1392 +++++++++++++++++++++++++++++++++++++++++++ lib/lib_rpigpios.py | 1305 ++++++++++++++++++++++++++++++++++++++++ linux_os.py | 61 +- plugindeps.py | 107 ++-- rpieGlobals.py | 2 +- webserver.py | 47 +- 9 files changed, 2886 insertions(+), 1373 deletions(-) create mode 100644 lib/lib_opigpios.py create mode 100644 lib/lib_rpigpios.py diff --git a/RPIEasy.py b/RPIEasy.py index e4124ea..b3b1998 100755 --- a/RPIEasy.py +++ b/RPIEasy.py @@ -29,7 +29,10 @@ def signal_handler(signal, frame): init_ok = False commands.doCleanup() webserver.WebServer.stop() - gpios.HWPorts.cleanup() + try: + gpios.HWPorts.cleanup() + except: + pass time.sleep(1) print("\nProgram exiting gracefully") sys.exit(0) @@ -56,11 +59,16 @@ def hardwareInit(): Settings.NetMan = Network.NetworkManager() if len(OS.getsounddevs())>0: Settings.SoundSystem["usable"]=True - if rpieGlobals.ossubtype == 10: + if rpieGlobals.ossubtype == 10: # rpi rpv = OS.getRPIVer() if rpv: pinout = rpv["pins"] misc.addLog(rpieGlobals.LOG_LEVEL_DEBUG,str(rpv["name"])+" "+str(rpv["pins"])+" pins") + elif rpieGlobals.ossubtype == 3: # opi + opv = OS.getarmbianinfo() + if opv: + pinout = opv["pins"] + misc.addLog(rpieGlobals.LOG_LEVEL_DEBUG,str(opv["name"])+" "+str(opv["pins"])+" pins") print("Load network settings...") Settings.loadnetsettings() Settings.NetMan.networkinit() @@ -68,26 +76,23 @@ def hardwareInit(): print("Load GPIO settings...") if pinout != "0": Settings.loadpinout() - if pinout == "40" and len(Settings.Pinout)!=41: - Settings.Pinout=gpios.PINOUT40 - elif pinout == "26R1" and len(Settings.Pinout)!=27: - for p in range(27): - Settings.Pinout.append(gpios.PINOUT40[p]) - for p in range(len(gpios.PINOUT26R1_DELTA)): - pi = int(gpios.PINOUT26R1_DELTA[p]["ID"]) - Settings.Pinout[pi] = gpios.PINOUT26R1_DELTA[p] - elif pinout == "26R2" and len(Settings.Pinout)!=27: - for p in range(27): - Settings.Pinout.append(gpios.PINOUT40[p]) - for p in range(len(gpios.PINOUT26R2_DELTA)): - pi = int(gpios.PINOUT26R2_DELTA[p]["ID"]) - Settings.Pinout[pi] = gpios.PINOUT26R2_DELTA[p] + try: + gpios.preinit(rpieGlobals.ossubtype) # create HWPorts variable + except Exception as e: + print("init",e) + if (("40" in pinout) and (len(Settings.Pinout)<41)) or (("26" in pinout) and (len(Settings.Pinout)<27)): + print("Creating new pinout") + try: + gpios.HWPorts.createpinout(pinout) + except Exception as e: + print("cp:",e) perror = False try: gpios.HWPorts.readconfig() - except: + except Exception as e: +# print(e) # debug perror = True - if perror or len(Settings.Pinout)<26: + if perror or len(Settings.Pinout)<8: misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"Your GPIO can not be identified!") Settings.Pinout = [] else: diff --git a/Settings.py b/Settings.py index 12b72f9..7895747 100644 --- a/Settings.py +++ b/Settings.py @@ -140,10 +140,12 @@ def loadsettings(): def loadtasks(): global Tasks, tasksfile success = 1 + tTasks = [False] try: f = open(tasksfile) settingjson = f.read() - Tasks = jsonpickle.decode(settingjson) + tTasks = jsonpickle.decode(settingjson) + Tasks = tTasks except: success = 0 return success diff --git a/gpios.py b/gpios.py index f101cce..2cc11ad 100644 --- a/gpios.py +++ b/gpios.py @@ -3,343 +3,11 @@ ################## Helper Library for GPIO handling ######################### ############################################################################# # -# Copyright (C) 2018-2019 by Alexander Nagy - https://bitekmindenhol.blog.hu/ +# Copyright (C) 2020 by Alexander Nagy - https://bitekmindenhol.blog.hu/ # import Settings import os import time -import lib.lib_syspwm as syspwm -try: - import linux_os as OS -except: - print("Linux OS functions can not be imported!") -try: - import RPi.GPIO as GPIO -except: - print("RPi.GPIO not installed!") -try: - import smbus -except: - print("I2C smbus not installed!") - -PINOUT40 = [ -{"ID":0, -"BCM":-1, -"name":["None"], -"canchange":2, -"altfunc": 0}, -{"ID":1, -"BCM":-1, -"name":["3V3"], -"canchange":0, -"altfunc": 0}, -{"ID":2, -"BCM":-1, -"name":["5V"], -"canchange":0, -"altfunc": 0}, -{"ID":3, -"BCM":2, -"name":["GPIO2","I2C1-SDA"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":4, -"BCM":-1, -"name":["5V"], -"canchange":0, -"altfunc": 0}, -{"ID":5, -"BCM":3, -"name":["GPIO3","I2C1-SCL"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":6, -"BCM":-1, -"name":["GND"], -"canchange":0, -"altfunc": 0}, -{"ID":7, -"BCM":4, -"name":["GPIO4"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":8, -"BCM":14, -"name":["GPIO14","UART-TX","BT-TX"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":9, -"BCM":-1, -"name":["GND"], -"canchange":0, -"altfunc": 0}, -{"ID":10, -"BCM":15, -"name":["GPIO15","UART-RX","BT-RX"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":11, -"BCM":17, -"name":["GPIO17","SPI1-CE1"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":12, -"BCM":18, -"name":["GPIO18/PWM0","SPI1-CE0","PCM-CLK"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":13, -"BCM":27, -"name":["GPIO27"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":14, -"BCM":-1, -"name":["GND"], -"canchange":0, -"altfunc": 0}, -{"ID":15, -"BCM":22, -"name":["GPIO22"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":16, -"BCM":23, -"name":["GPIO23"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":17, -"BCM":-1, -"name":["3V3"], -"canchange":0, -"altfunc": 0}, -{"ID":18, -"BCM":24, -"name":["GPIO24"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":19, -"BCM":10, -"name":["GPIO10","SPI0-MOSI"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":20, -"BCM":-1, -"name":["GND"], -"canchange":0, -"altfunc": 0}, -{"ID":21, -"BCM":9, -"name":["GPIO9","SPI0-MISO"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":22, -"BCM":25, -"name":["GPIO25"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":23, -"BCM":11, -"name":["GPIO11","SPI0-SCLK"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":24, -"BCM":8, -"name":["GPIO8","SPI0-CE0"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":25, -"BCM":-1, -"name":["GND"], -"canchange":0, -"altfunc": 0}, -{"ID":26, -"BCM":7, -"name":["GPIO7","SPI0-CE1"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":27, -"BCM":0, -"name":["ID_SD"], -"canchange":0, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":28, -"BCM":1, -"name":["ID_SC"], -"canchange":0, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":29, -"BCM":5, -"name":["GPIO5"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":30, -"BCM":-1, -"name":["GND"], -"canchange":0, -"altfunc": 0}, -{"ID":31, -"BCM":6, -"name":["GPIO6"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":32, -"BCM":12, -"name":["GPIO12/PWM0"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":33, -"BCM":13, -"name":["GPIO13/PWM1"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":34, -"BCM":-1, -"name":["GND"], -"canchange":0, -"altfunc": 0}, -{"ID":35, -"BCM":19, -"name":["GPIO19/PWM1","SPI1-MISO","PCM-FS"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":36, -"BCM":16, -"name":["GPIO16","SPI1-CE2"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":37, -"BCM":26, -"name":["GPIO26"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":38, -"BCM":20, -"name":["GPIO20","SPI1-MOSI","PCM-DIN"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":39, -"BCM":-1, -"name":["GND"], -"canchange":0, -"altfunc": 0}, -{"ID":40, -"BCM":21, -"name":["GPIO21","SPI1-SCLK","PCM-DOUT"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1} -] - -PINOUT26R2_DELTA = [ -{"ID":11, -"BCM":17, -"name":["GPIO17"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":12, -"BCM":18, -"name":["GPIO18/PWM0"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1} -] - -PINOUT26R1_DELTA = [ -{"ID":3, -"BCM":0, -"name":["GPIO0","I2C0-SDA"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":5, -"BCM":1, -"name":["GPIO1","I2C0-SCL"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":11, -"BCM":17, -"name":["GPIO17"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":12, -"BCM":18, -"name":["GPIO18/PWM0"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -{"ID":13, -"BCM":21, -"name":["GPIO21"], -"canchange":1, -"altfunc": 0, -"startupstate":-1, -"actualstate":-1}, -] I2CDevices = [ {"name": "MCP9808 Temp sensor", @@ -407,947 +75,6 @@ GPIOStatus = [] -try: - BOTH=GPIO.BOTH - RISING=GPIO.RISING - FALLING=GPIO.FALLING -except: - BOTH=3 - RISING=1 - FALLING=2 - -class hwports: - config_file_name = "/boot/config.txt" # /boot/config.txt - CONFIG_ENABLE_I2C="dtparam=i2c_arm=on" - CONFIG_ENABLE_I2C0="dtparam=i2c0=on" - CONFIG_ENABLE_I2C1="dtparam=i2c1=on" - CONFIG_ENABLE_SPI0="dtparam=spi=on" - CONFIG_ENABLE_SPI1_1="dtoverlay=spi1-1cs" - CONFIG_ENABLE_SPI1_2="dtoverlay=spi1-2cs" - CONFIG_ENABLE_SPI1_3="dtoverlay=spi1-3cs" - CONFIG_ENABLE_I2S="dtparams=i2s=on" - CONFIG_DISABLE_UART="enable_uart=0" #0/1 - CONFIG_ENABLE_UART="enable_uart=1" - CONFIG_DISABLE_UART2="dtparam=uart0=off" - CONFIG_BT_SWUART="dtoverlay=pi3-miniuart-bt" - CONFIG_DISABLE_BT="dtoverlay=pi3-disable-bt" - CONFIG_DISABLE_WIFI="dtoverlay=pi3-disable-wifi" - CONFIG_PWM0="dtoverlay=pwm" - CONFIG_PWM0_1="dtoverlay=pwm-2chan" - CONFIG_ENABLE_AUDIO="dtparam=audio=on" #on/off - CONFIG_DISABLE_AUDIO="dtparam=audio=off" #on/off - CONFIG_ONEWIRE="dtoverlay=w1-gpio" - CONFIG_IR="dtoverlay=gpio-ir" - CONFIG_PWMIR="dtoverlay=pwm-ir-tx" - CONFIG_GPIO="gpio=" - CONFIG_GPUMEM="gpu_mem" - COMMAND_DISABLE_BT="sudo systemctl disable hciuart" - CONFIG_ENABLE_RTC="dtoverlay=i2c-rtc," # ds1307, pcf8523, ds3231 - - def __init__(self): # general init - self.i2c_channels = [] # 0,1 - self.i2c_initialized = False - self.i2cbus = None - self.spi_channels = [] # 0,1 - self.spi_cs = [0,0] - self.serial = 0 - self.bluetooth = 0 # 0:disabled,1:enabled with SW miniUART,2:enabled with HW UART - self.wifi = 0 # 0:disabled,1:enabled - self.audio = 0 - self.i2s = 0 - self.pwm = [0,0] # 0.byte:pwm0 pin, 1.byte:pwm1 pin, no more - self.rtc = "" # /lib/udev/hwclock-set - self.pwmo = [] - for p in range(22): - self.pwmo.append({"pin":0,"o":False}) - try: - rpitype = OS.getRPIVer() - except: - rpitype=[] - try: - po = rpitype["pins"] - except: - po = "0" - try: - bta = int(rpitype["bt"]) - except: - bta = 0 - try: - wf = int(rpitype["wlan"]) - except: - wf = 0 - try: - iram = rpitype["ram"] - except: - iram = "0" - try: - GPIO.setwarnings(False) - GPIO.setmode(GPIO.BCM) - self.gpioinit = True - except: - print("GPIO init failed") - self.gpioinit = False - - self.pinnum = po - self.internalwlan = (wf==1) - self.internalbt = (bta==1) - self.gpumin = 16 - self.gpumax = self.gpumin - if "256m" in iram.lower(): - self.gpumax = 192 - elif "512m" in iram.lower(): - self.gpumax = 448 - elif "1m" in iram.lower(): - self.gpumax = 944 - self.gpumem = self.gpumin - - def __del__(self): - try: - self.cleanup() - except: - pass - - def cleanup(self): - if self.gpioinit: - for p in range(len(self.pwmo)): - try: - if (self.pwmo[p]["o"] != False) and not (self.pwmo[p]["o"] is None): - self.pwmo[p]["o"].stop() - except: - pass - GPIO.cleanup() - - def gpio_function_name(self,func): - typestr = "Unknown" - try: - typeint = int(func) - if GPIO.IN==typeint: - typestr = "Input" - elif GPIO.OUT==typeint: - typestr = "Output" - elif GPIO.SPI==typeint: - typestr = "SPI" - elif GPIO.I2C==typeint: - typestr = "I2C" - elif GPIO.HARD_PWM==typeint: - typestr = "HardPWM" - elif GPIO.SERIAL==typeint: - typestr = "Serial" - except: - typestr = "Unknown" - return typestr - - def gpio_function_name_from_pin(self,gpio): - typestr = "Unknown" - try: - pinnum = int(gpio) - if pinnum>0: - typeint = GPIO.gpio_function(pinnum) - typestr = self.gpio_function_name(typeint) - except Exception as e: - typestr = "Unknown" - return typestr - - def gpio_function(self,bcmpin): - return GPIO.gpio_function(bcmpin) - - def input(self,bcmpin): - return GPIO.input(bcmpin) - - def output(self,pin,value,Force=False): - if Force: - for b in range(len(Settings.Pinout)): - if str(Settings.Pinout[b]["BCM"])==str(pin).strip(): - if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: - if Settings.Pinout[b]["startupstate"]<4: - self.setpinstate(b,4) - break - return GPIO.output(pin,value) - - def add_event_detect(self,pin, detection, pcallback,pbouncetime=0): - for b in range(len(Settings.Pinout)): - if str(Settings.Pinout[b]["BCM"])==str(pin).strip(): - if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: - if Settings.Pinout[b]["startupstate"]<4: - self.setpinstate(b,Settings.Pinout[b]["startupstate"]) - else: - pass # i am lazy and not sure if is it can happen anyday... - break - if pbouncetime==0: - GPIO.add_event_detect(pin,detection,callback=pcallback) - else: - GPIO.add_event_detect(pin,detection,callback=pcallback,bouncetime=pbouncetime) - - def remove_event_detect(self,pin): - GPIO.remove_event_detect(pin) - - def i2c_init(self): - if self.i2c_initialized == False: - if self.is_i2c_usable(1): - self.i2cbus = smbus.SMBus(1) - self.i2c_initialized = True - elif self.is_i2c_usable(0): - self.i2cbus = smbus.SMBus(0) - self.i2c_initialized = True - return self.i2c_initialized - - def i2c_read_block(self,address,cmd): - retval = None - if self.i2c_initialized: - try: - retval = self.i2cbus.read_i2c_block_data(address,cmd) - except: - retval = None - return retval - - def is_i2c_usable(self,channel): - result = False - if channel==0: - if self.pinnum=="26R1": - result = True - else: - if self.pinnum=="26R2" or self.pinnum=="40": - result = True - return result - - def is_i2c_enabled(self,channel): - if channel in self.i2c_channels: - return True - else: - return False - - def enable_i2c(self,channel): - if self.is_i2c_usable(channel) and (self.is_i2c_enabled(channel)==False): - self.i2c_channels.append(channel) - Settings.Pinout[3]["altfunc"] = 1 - Settings.Pinout[5]["altfunc"] = 1 - - def disable_i2c(self,channel): - if self.is_i2c_enabled(channel): - self.i2c_channels.remove(channel) - Settings.Pinout[3]["altfunc"] = 0 - Settings.Pinout[5]["altfunc"] = 0 - - def is_spi_usable(self,channel): - result = False - try: - channel = int(channel) - except: - return False - if channel==0: - if str(self.pinnum)=="26R1" or str(self.pinnum)=="26R2" or str(self.pinnum)=="40": - result = True - else: - if str(self.pinnum)=="40": - result = True - return result - - def is_spi_enabled(self,channel): - if channel in self.spi_channels: - return True - else: - return False - - def enable_spi(self,channel,cs=3): # cs can 1,2,3 for spi1, 2 for spi0 - try: - channel=int(channel) - cs=int(cs) - except: - return False - if self.is_spi_usable(channel): - if (self.is_spi_enabled(channel)==False): - self.spi_channels.append(channel) - if channel==0: - self.spi_cs[0] = 2 - Settings.Pinout[19]["altfunc"] = 1 - Settings.Pinout[21]["altfunc"] = 1 - Settings.Pinout[23]["altfunc"] = 1 - Settings.Pinout[24]["altfunc"] = 1 - Settings.Pinout[26]["altfunc"] = 1 - else: - self.spi_cs[1] = int(cs) - Settings.Pinout[35]["altfunc"] = 1 - Settings.Pinout[38]["altfunc"] = 1 - Settings.Pinout[40]["altfunc"] = 1 - Settings.Pinout[12]["altfunc"] = 1 - Settings.Pinout[11]["altfunc"] = 0 - Settings.Pinout[36]["altfunc"] = 0 - if self.spi_cs[1]>1: - Settings.Pinout[11]["altfunc"] = 1 - if self.spi_cs[1]>2: - Settings.Pinout[36]["altfunc"] = 1 - - def disable_spi(self,channel): - try: - channel=int(channel) - except: - return False - if self.is_spi_enabled(channel): - self.spi_channels.remove(channel) - if channel==0: - Settings.Pinout[19]["altfunc"] = 0 - Settings.Pinout[21]["altfunc"] = 0 - Settings.Pinout[23]["altfunc"] = 0 - Settings.Pinout[24]["altfunc"] = 0 - Settings.Pinout[26]["altfunc"] = 0 - else: - if Settings.Pinout[12]["altfunc"] == 1: - Settings.Pinout[35]["altfunc"] = 0 - Settings.Pinout[38]["altfunc"] = 0 - Settings.Pinout[40]["altfunc"] = 0 - Settings.Pinout[12]["altfunc"] = 0 - Settings.Pinout[11]["altfunc"] = 0 - Settings.Pinout[36]["altfunc"] = 0 - - def is_serial_enabled(self): - return (self.serial==1) - - def set_serial(self,status): - if (status==0) or (status==False): - self.serial = 0 - if Settings.Pinout[8]["altfunc"]==1 or self.bluetooth==0: - Settings.Pinout[8]["altfunc"] = 0 - Settings.Pinout[10]["altfunc"] = 0 - else: - self.serial = 1 - Settings.Pinout[8]["altfunc"] = 1 - Settings.Pinout[10]["altfunc"] = 1 - - def is_internal_bt_usable(self): - return self.internalbt - - def get_internal_bt_level(self): - return self.bluetooth - - def set_internal_bt(self,uartlevel): #1=sw,2=hw - if self.is_internal_bt_usable(): - self.bluetooth=uartlevel - if uartlevel>1: - Settings.Pinout[8]["altfunc"] = 2 - Settings.Pinout[10]["altfunc"] = 2 - else: - if Settings.Pinout[8]["altfunc"]==2: - if self.serial==1: - Settings.Pinout[8]["altfunc"] = 1 - Settings.Pinout[10]["altfunc"] = 1 - else: - Settings.Pinout[8]["altfunc"] = 0 - Settings.Pinout[10]["altfunc"] = 0 - elif self.serial ==0: - Settings.Pinout[8]["altfunc"] = 0 - Settings.Pinout[10]["altfunc"] = 0 - else: - self.bluetooth=0 - - def is_audio_enabled(self): - return (self.audio==1) - - def is_internal_wifi_usable(self): - return self.internalwlan - - def set_wifi(self,status): - self.wifi = 0 - if self.is_internal_wifi_usable(): - if (status==1) or (status==True): - self.wifi = 1 - - def is_wifi_enabled(self): - return (self.wifi==1) - - def set_audio(self,status): - if (status==0) or (status==False): - self.audio = 0 - else: - self.audio = 1 - - def is_audio_enabled(self): - return (self.audio==1) - - def enable_pwm_pin(self,channel,pin,FirstRead=False): - if channel>=0 and channel<=1: - pid = 0 - for p in range(len(Settings.Pinout)): - if int(Settings.Pinout[p]["BCM"])==int(pin): - pid = p - break - pch = "PWM"+str(channel) - if (Settings.Pinout[pid]["altfunc"] == 0) and (pch in Settings.Pinout[pid]["name"][0]): - if self.pwm[channel] > 0 and pin != self.pwm[channel]: - for p in range(len(Settings.Pinout)): - if int(Settings.Pinout[p]["BCM"])==int(self.pwm[channel]) and int(Settings.Pinout[p]["startupstate"])==7: - Settings.Pinout[p]["startupstate"] = -1 - break - self.pwm[channel]=pin - Settings.Pinout[pid]["startupstate"] = 7 # set to H-PWM - if FirstRead: - Settings.Pinout[pid]["actualstate"]=Settings.Pinout[pid]["startupstate"] - try: - if channel==0: - self.pwmo[0]["o"] = syspwm.HPWM(0) - self.pwmo[0]["pin"] = pin - else: - self.pwmo[1]["o"] = syspwm.HPWM(1) - self.pwmo[1]["pin"] = pin - except Exception as e: - print("PWM error: ",e) - - def disable_pwm_pin(self,channel): - if channel>=0 and channel<=1: - if self.pwm[channel] > 0: - for p in range(len(Settings.Pinout)): - if int(Settings.Pinout[p]["BCM"])==int(self.pwm[channel]) and int(Settings.Pinout[p]["startupstate"])==7: - Settings.Pinout[p]["startupstate"] = -1 - break - self.pwm[channel]=0 - try: - if channel==0: - if self.pwmo[0]["o"]: - self.pwmo[0]["o"].stop() - else: - if self.pwmo[1]["o"]: - self.pwmo[1]["o"].stop() - except: - pass - - def output_pwm(self,bcmpin,pprop,pfreq=1000): # default 1000Hz - pin = int(bcmpin) - prop = int(pprop) - freq = int(pfreq) - if pin in self.pwm: # hardpwm - pid = 0 - if self.pwm[0] == pin: - pid = 0 - else: - pid = 1 - if prop<=0: - self.pwmo[pid]["o"].stop() - else: - self.pwmo[pid]["pin"]=pin - self.pwmo[pid]["o"].set_frequency(freq) - self.pwmo[pid]["o"].set_duty_prop(prop) - self.pwmo[pid]["o"].enable() - return True - else: # softpwm - pfound = False - for p in range(len(Settings.Pinout)): - if int(Settings.Pinout[p]["BCM"])==pin : - if (int(Settings.Pinout[p]["startupstate"]) not in [4,5,6]): - return False # if not output skip - - if len(self.pwmo)>2: - for p in range(2,len(self.pwmo)): - if int(self.pwmo[p]["pin"])==pin: - if (self.pwmo[p]["o"]): - if prop<=0: - self.pwmo[p]["o"].stop() - else: - self.pwmo[p]["o"].start(prop) - self.pwmo[p]["o"].ChangeFrequency(freq) - self.pwmo[p]["o"].ChangeDutyCycle(prop) - pfound = True - break - if pfound==False: - self.pwmo[p]["pin"] = pin - self.pwmo[p]["o"] = GPIO.PWM(pin,freq) - self.pwmo[p]["o"].start(prop) - return True - - def pwm_get_func(self,pin): - func = 0 - if pin==12 or pin==13: - func=4 - elif pin==18 or pin==19: - func=2 - return str(func) - - def is_i2s_usable(self): - result = False - if self.pinnum=="40": - result = True - return result - - def set_i2s(self,state): - if self.is_i2s_usable(): - if state==1 or state==True: - self.i2s=1 - if self.is_spi_enabled(1): - self.disable_spi(1) # collision resolving - Settings.Pinout[12]["altfunc"] = 2 - Settings.Pinout[35]["altfunc"] = 2 - Settings.Pinout[38]["altfunc"] = 2 - Settings.Pinout[40]["altfunc"] = 2 - else: - self.i2s=0 - if Settings.Pinout[12]["altfunc"]==2: - Settings.Pinout[12]["altfunc"] = 0 - Settings.Pinout[35]["altfunc"] = 0 - Settings.Pinout[38]["altfunc"] = 0 - Settings.Pinout[40]["altfunc"] = 0 - - def set1wgpio(self,bcmpin,FirstRead=False): - for b in range(len(Settings.Pinout)): - if str(Settings.Pinout[b]["BCM"])==str(bcmpin).strip(): - if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: - Settings.Pinout[b]["startupstate"] = 8 - if FirstRead: - Settings.Pinout[b]["actualstate"]=Settings.Pinout[b]["startupstate"] - break - - def setirgpio(self,bcmpin,FirstRead=False,mode=0): - for b in range(len(Settings.Pinout)): - if str(Settings.Pinout[b]["BCM"])==str(bcmpin).strip(): - if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: - pmode = (int(mode)+10) - if mode==2: - if ("PWM" not in Settings.Pinout[b]["name"][0]): - break - Settings.Pinout[b]["startupstate"] = pmode - if FirstRead: - Settings.Pinout[b]["actualstate"]=Settings.Pinout[b]["startupstate"] - break - - def setpinstartstate(self,bcmpin,state): - for b in range(len(Settings.Pinout)): - if str(Settings.Pinout[b]["BCM"])==str(bcmpin).strip(): - if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: - self.setpinstate(b,state,True) - break - - def setpinactualstate(self,pinid,state): - if Settings.Pinout[pinid]["actualstate"]==7: - bcmpin = int(Settings.Pinout[pinid]["BCM"]) - if bcmpin == self.pwm[0]: - self.disable_pwm_pin(0) - elif bcmpin == self.pwm[1]: - self.disable_pwm_pin(1) - if Settings.Pinout[pinid]["actualstate"]<7 and state<7: - Settings.Pinout[pinid]["actualstate"]=state - - def setpinstate(self,PINID,state,force=False): - if (force==False): - if Settings.Pinout[PINID]["altfunc"]>0 or Settings.Pinout[PINID]["canchange"]!=1 or Settings.Pinout[PINID]["BCM"]<0: - return False -# if (int(state)<=0 and int(Settings.Pinout[PINID]["startupstate"])>0): - if int(state)<=0: -# pass # revert to default input - Settings.Pinout[PINID]["startupstate"] = -1 - if self.gpioinit: - GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.IN) - self.setpinactualstate(PINID,99) # ugly hack - return True - elif state==1: - pass # input - Settings.Pinout[PINID]["startupstate"] = state - if self.gpioinit: - GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.IN) - self.setpinactualstate(PINID,1) - return True - elif state==2: - pass # input pulldown - Settings.Pinout[PINID]["startupstate"] = state - if self.gpioinit: - GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.IN, pull_up_down=GPIO.PUD_DOWN) - self.setpinactualstate(PINID,state) - return True - elif state==3: - pass # input pullup - Settings.Pinout[PINID]["startupstate"] = state - if self.gpioinit: - GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.IN, pull_up_down=GPIO.PUD_UP) - self.setpinactualstate(PINID,state) - return True - elif state==4 or state==5 or state==6: - if state==5: - if self.gpioinit: - GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.OUT, initial=GPIO.LOW) - elif state==6: - if self.gpioinit: - GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.OUT, initial=GPIO.HIGH) - else: - if self.gpioinit: - GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.OUT) - Settings.Pinout[PINID]["startupstate"] = state - self.setpinactualstate(PINID,4) - return True - elif state==7: - self.enable_pwm_pin(0,int(Settings.Pinout[PINID]["BCM"])) - if Settings.Pinout[PINID]["startupstate"] != 7: - self.enable_pwm_pin(1,int(Settings.Pinout[PINID]["BCM"])) - return True - elif state==8: - self.setpinactualstate(PINID,-1) - self.set1wgpio(int(Settings.Pinout[PINID]["BCM"])) - return True - elif state in [10,11,12]: - self.setpinactualstate(PINID,-1) - self.setirgpio(int(Settings.Pinout[PINID]["BCM"]),mode=(state-10)) - return True - return False - - def initpinstates(self): - if self.gpioinit: - for b in range(len(Settings.Pinout)): - if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: - if int(Settings.Pinout[b]["BCM"])>=0: - if int(Settings.Pinout[b]["startupstate"])<7 and int(Settings.Pinout[b]["startupstate"])>=0: - self.setpinstate(b,Settings.Pinout[b]["startupstate"],True) - - def readconfig(self): - self.i2c_channels = [] # 0,1 - self.spi_channels = [] # 0,1 - self.spi_cs = [0,0] - self.set_serial(1) - self.i2s = 0 - if self.internalbt: - self.bluetooth = 2 - if self.internalwlan: - self.wifi = 1 - self.audio = 1 - self.pwm = [0,0] # 0.byte:pwm0 pin, 1.byte:pwm1 pin, no more -# read config.txt - try: - with open(self.config_file_name) as f: - for line in f: - line = line.strip() - if len(line)>0 and line[0] == "#": - line = "" - if self.CONFIG_ENABLE_I2C in line.lower(): - if self.is_i2c_usable(1): - self.enable_i2c(1) - else: - self.enable_i2c(0) - elif self.CONFIG_ENABLE_I2C0 in line.lower(): - self.enable_i2c(0) - elif self.CONFIG_ENABLE_I2C1 in line.lower(): - self.enable_i2c(1) - elif self.CONFIG_ENABLE_SPI0 in line.lower(): - self.enable_spi(0,2) - elif self.CONFIG_ENABLE_SPI1_1 in line.lower(): - self.enable_spi(1,1) - elif self.CONFIG_ENABLE_SPI1_2 in line.lower(): - self.enable_spi(1,2) - elif self.CONFIG_ENABLE_SPI1_3 in line.lower(): - self.enable_spi(1,3) - elif self.CONFIG_ENABLE_I2S in line.lower(): - self.set_i2s(1) - elif self.CONFIG_DISABLE_UART in line.lower(): - self.set_serial(0) - elif self.CONFIG_DISABLE_UART2 in line.lower(): - self.set_serial(0) - elif self.CONFIG_ENABLE_UART in line.lower(): - self.set_serial(1) - elif self.CONFIG_BT_SWUART in line.lower(): - self.set_internal_bt(1) - elif self.CONFIG_DISABLE_BT in line.lower(): - self.set_internal_bt(0) - elif self.CONFIG_DISABLE_WIFI in line.lower(): - self.wifi=0 - elif self.CONFIG_DISABLE_AUDIO in line.lower(): - self.audio=0 - elif self.CONFIG_ENABLE_RTC in line.lower(): - params = line.split(",") - if len(params)>1: - self.rtc=params[1].strip() - elif line.lower().startswith(self.CONFIG_GPUMEM): - params = line.split("=") - try: - self.gpumem=int(params[1].strip()) - except: - self.gpumem=self.gpumin - elif self.CONFIG_ONEWIRE in line.lower(): - pinfound = False - params = line.split(",") - for p in range(len(params)): - pin = 0 - if "gpiopin" in params[p]: - params2 = params[p].split('=') - try: - pin = int(params2[1].strip()) - pinfound = True - except: - pin = 0 - if pin!= 0: - self.set1wgpio(pin,True) - if pinfound==False: - self.set1wgpio(4,True) - elif self.CONFIG_IR in line.lower(): - pinfound = False - params = line.split(",") - for p in range(len(params)): - pin = 0 - if "gpio_pin" in params[p]: - params2 = params[p].split('=') - try: - pin = int(params2[1].strip()) - pinfound = True - except: - pin = 0 - if ("-tx" in line): - mode = 1 - else: - mode = 0 - if pin!= 0: - self.setirgpio(pin,True,mode) - if pinfound==False: - self.setirgpio(18,True,mode) - elif self.CONFIG_PWMIR in line.lower(): - pinfound = False - params = line.split(",") - for p in range(len(params)): - pin = 0 - if "gpio_pin" in params[p]: - params2 = params[p].split('=') - try: - pin = int(params2[1].strip()) - pinfound = True - except: - pin = 0 - if pin!= 0: - self.setirgpio(pin,True,2) - if pinfound==False: - self.setirgpio(18,True,2) - elif line.lower().startswith(self.CONFIG_GPIO): - params = line.split("=") - bcmpin = -1 - try: - bcmpin = int(params[1].strip()) - except: - bcmpin = -1 - if bcmpin != -1: - pstate = -1 - if "ip" in params[2]: - pstate = 1 - if "pd" in params[2]: - pstate = 2 - if "pu" in params[2]: - pstate = 3 - if "pn" in params[2] or "np" in params[2]: - pstate = 1 - if "op" in params[2]: - pstate = 4 - if "dl" in params[2]: - pstate = 5 - if "dh" in params[2]: - pstate = 6 - if pstate != -1: - self.setpinstartstate(bcmpin,pstate) - elif self.CONFIG_PWM0 in line.lower() or self.CONFIG_PWM0_1 in line.lower(): - params = line.split(",") - if self.CONFIG_PWM0_1 in line.lower(): - self.pwm = [18,19] - else: - self.pwm = [18,0] - try: - pwmi = 0 - for p in range(len(params)): - params2 = params[p].split("=") - if "pin" in params2[0].lower(): - self.enable_pwm_pin(pwmi,int(params2[1].strip()),True) - pwmi=pwmi+1 - except: - pass - self.enable_pwm_pin(0,self.pwm[0],True) - self.enable_pwm_pin(1,self.pwm[1],True) - except Exception as e: - print(e) - - if self.get_internal_bt_level()>1: - self.set_serial(0) - self.set_internal_bt(2) # uart collision resolving - if self.i2s==1: - self.set_i2s(1) - for b in range(len(Settings.Pinout)): - if Settings.Pinout[b]["altfunc"] != 0 and Settings.Pinout[b]["startupstate"]>0 and Settings.Pinout[b]["startupstate"]<9: - Settings.Pinout[b]["startupstate"] = -1 # set to default - - def saveconfig(self): - # save config.txt - contents = [] - use_ir = False - try: - with open(self.config_file_name) as f: - for line in f: - line = line.strip() - if len(line)>0 and line[0] == "#": - line = "" - if self.CONFIG_ENABLE_I2C in line.lower(): - line = "" - elif self.CONFIG_ENABLE_I2C0 in line.lower(): - line = "" - elif self.CONFIG_ENABLE_I2C1 in line.lower(): - line = "" - elif self.CONFIG_ENABLE_SPI0 in line.lower(): - line = "" - elif self.CONFIG_ENABLE_SPI1_1 in line.lower(): - line = "" - elif self.CONFIG_ENABLE_SPI1_2 in line.lower(): - line = "" - elif self.CONFIG_ENABLE_SPI1_3 in line.lower(): - line = "" - elif self.CONFIG_ENABLE_I2S in line.lower(): - line = "" - elif self.CONFIG_DISABLE_UART in line.lower(): - line = "" - elif self.CONFIG_DISABLE_UART2 in line.lower(): - line = "" - elif self.CONFIG_ENABLE_UART in line.lower(): - line = "" - elif self.CONFIG_BT_SWUART in line.lower(): - line = "" - elif self.CONFIG_DISABLE_BT in line.lower(): - line = "" - elif self.CONFIG_DISABLE_WIFI in line.lower(): - line = "" - elif self.CONFIG_DISABLE_AUDIO in line.lower() or self.CONFIG_ENABLE_AUDIO in line.lower(): - line = "" - elif self.CONFIG_PWM0 in line.lower(): - line = "" - elif self.CONFIG_ENABLE_RTC in line.lower(): - line = "" - elif self.CONFIG_PWM0_1 in line.lower(): - line = "" - elif self.CONFIG_ONEWIRE in line.lower(): - line = "" - elif self.CONFIG_IR in line.lower(): - line = "" - elif self.CONFIG_PWMIR in line.lower(): - line = "" - elif line.lower().startswith(self.CONFIG_GPIO): - line = "" - elif line.lower().startswith(self.CONFIG_GPUMEM): - line = "" - if line != "": - contents.append(line) - except: - pass - with open(self.config_file_name,"w") as f: - for c in range(len(contents)): - f.write(contents[c]+"\n") - if len(self.i2c_channels)>0: - f.write(self.CONFIG_ENABLE_I2C+"\n") - if self.is_i2c_enabled(1): - f.write(self.CONFIG_ENABLE_I2C1+"\n") - if self.is_i2c_enabled(0): - f.write(self.CONFIG_ENABLE_I2C0+"\n") - if self.is_spi_enabled(0): - f.write(self.CONFIG_ENABLE_SPI0+"\n") - if self.i2s==1: - f.write(self.CONFIG_ENABLE_I2S+"\n") - if self.is_spi_enabled(1): - if self.spi_cs[1] == 1: - f.write(self.CONFIG_ENABLE_SPI1_1+"\n") - elif self.spi_cs[1] == 2: - f.write(self.CONFIG_ENABLE_SPI1_2+"\n") - elif self.spi_cs[1] == 3: - f.write(self.CONFIG_ENABLE_SPI1_3+"\n") - if self.is_serial_enabled()==False: - f.write(self.CONFIG_DISABLE_UART+"\n") - else: - f.write(self.CONFIG_ENABLE_UART+"\n") - if self.is_internal_bt_usable(): - if self.get_internal_bt_level()==1: - f.write(self.CONFIG_BT_SWUART+"\n") - elif self.get_internal_bt_level()==0: - f.write(self.CONFIG_DISABLE_BT+"\n") - if self.is_internal_wifi_usable(): - if self.is_wifi_enabled()==False: - f.write(self.CONFIG_DISABLE_WIFI+"\n") - if self.rtc!="": - f.write(self.CONFIG_ENABLE_RTC+self.rtc+"\n") - if self.is_audio_enabled(): - f.write(self.CONFIG_ENABLE_AUDIO+"\n") - else: - f.write(self.CONFIG_DISABLE_AUDIO+"\n") - f.write(self.CONFIG_GPUMEM+"="+str(self.gpumem)+"\n") - line = "" - if sum(self.pwm)>0: - if self.pwm[0] != 0: - ppin = self.pwm[0] - else: - ppin = self.pwm[1] - if self.pwm[0] > 0 and self.pwm[1] > 0: - line += self.CONFIG_PWM0_1+",pin="+str(self.pwm[0])+",func="+self.pwm_get_func(self.pwm[0])+",pin2="+str(self.pwm[1])+",func2="+self.pwm_get_func(self.pwm[1]) - else: - line += self.CONFIG_PWM0+",pin="+str(ppin)+",func="+self.pwm_get_func(ppin) - if line != "": - f.write(line+"\n") - for b in range(len(Settings.Pinout)): - if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1 and Settings.Pinout[b]["startupstate"]>0 and Settings.Pinout[b]["startupstate"]=0x30 and device<=0x37) or (device>=0x50 and device<=0x5f): - bus.read_byte(device) - else: - bus.write_quick(device) - devices.append(device) # hex(number)? - except: - pass - if (0x5c not in devices): # 0x5c has to be checked twice as Am2320 auto-shutdown itself? - try: - bus.read_byte(0x5c) - devices.append(0x5c) - except: - pass - if (0x7f not in devices): # 0x7f is non-standard used by PME - try: - bus.read_byte(0x7f) - devices.append(0x7f) - except: - pass - - try: - bus.close() - except: - pass - bus = None - return devices - def geti2cdevname(devaddr): global I2CDevices name = "" @@ -1428,7 +155,24 @@ def GPIO_get_status(gpionum): # input: BCM GPIO num, output: GPIOStatus string result = result.replace("{","{\n").replace("}","\n}") return result -#Init Hardware GLOBAL ports -HWPorts = hwports() -if os.path.exists("/DietPi/config.txt"): # DietPi FIX! - HWPorts.config_file_name = "/DietPi/config.txt" +def preinit(gpiotype): + global HWPorts, BOTH, RISING, FALLING + #Init Hardware GLOBAL ports + if gpiotype==10: # RPI + import lib.lib_rpigpios as GPIOHW + from lib.lib_rpigpios import hwports + BOTH=GPIOHW.BOTH + RISING=GPIOHW.RISING + FALLING=GPIOHW.FALLING + HWPorts = hwports() + if os.path.exists("/DietPi/config.txt"): # DietPi FIX! + HWPorts.config_file_name = "/DietPi/config.txt" + elif gpiotype==3: # OPI + import lib.lib_opigpios as GPIOHW + from lib.lib_opigpios import hwports + BOTH=GPIOHW.BOTH + RISING=GPIOHW.RISING + FALLING=GPIOHW.FALLING + HWPorts = hwports() + +#HWPorts = None diff --git a/lib/lib_opigpios.py b/lib/lib_opigpios.py new file mode 100644 index 0000000..f67cd27 --- /dev/null +++ b/lib/lib_opigpios.py @@ -0,0 +1,1392 @@ +#!/usr/bin/env python3 +############################################################################# +################ Helper Library for OPI GPIO handling ####################### +############################################################################# +# +# Copyright (C) 2020 by Alexander Nagy - https://bitekmindenhol.blog.hu/ +# +import Settings +import os +import time +try: + import linux_os as OS +except: + print("Linux OS functions can not be imported!") +try: + import OPi.GPIO as GPIO +except: + print("OPi.GPIO not installed!") +try: + import smbus +except: + print("I2C smbus not installed!") +import webserver +import threading +import misc +import rpieGlobals + +PINOUT40 = [ +{"ID":0, +"BCM":-1, +"name":["None"], # reserved +"canchange":2, +"altfunc": 0}, +{"ID":1, +"BCM":-1, +"name":["3V3"], +"canchange":0, +"altfunc": 0}, +{"ID":2, +"BCM":-1, +"name":["5V"], +"canchange":0, +"altfunc": 0}, +{"ID":3, +"BCM":3, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":4, +"BCM":-1, +"name":["5V"], +"canchange":0, +"altfunc": 0}, +{"ID":5, +"BCM":5, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":6, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":7, +"BCM":7, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":8, +"BCM":8, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":9, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":10, +"BCM":10, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":11, +"BCM":11, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":12, +"BCM":12, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":13, +"BCM":13, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":14, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":15, +"BCM":15, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":16, +"BCM":16, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":17, +"BCM":-1, +"name":["3V3"], +"canchange":0, +"altfunc": 0}, +{"ID":18, +"BCM":18, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":19, +"BCM":19, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":20, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":21, +"BCM":21, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":22, +"BCM":22, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":23, +"BCM":23, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":24, +"BCM":24, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":25, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":26, +"BCM":26, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":27, +"BCM":27, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":28, +"BCM":28, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":29, +"BCM":29, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":30, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":31, +"BCM":31, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":32, +"BCM":32, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":33, +"BCM":33, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":34, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":35, +"BCM":35, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":36, +"BCM":36, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":37, +"BCM":37, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":38, +"BCM":38, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":39, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":40, +"BCM":40, +"name":[], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1} +] + +try: + BOTH=GPIO.BOTH + RISING=GPIO.RISING + FALLING=GPIO.FALLING +except: + BOTH=3 + RISING=1 + FALLING=2 + +class OrangePwm(threading.Thread): + #https://github.com/evergreen-it-dev/orangepwm + def __init__(self, frequency, gpioPin): + self.baseTime = 1.0 / frequency + self.maxCycle = 100.0 + self.sliceTime = self.baseTime / self.maxCycle + self.gpioPin = gpioPin + self.terminated = False + self.toTerminate = False + self.thread = None + + def start(self, dutyCycle): + """ + Start PWM output. Expected parameter is : + - dutyCycle : percentage of a single pattern to set HIGH output on the GPIO pin + + Example : with a frequency of 1 Hz, and a duty cycle set to 25, GPIO pin will + stay HIGH for 1*(25/100) seconds on HIGH output, and 1*(75/100) seconds on LOW output. + """ + if self.thread is not None: + self.stop() + self.toTerminate = False + self.terminated = False + self.dutyCycle = dutyCycle + self.thread = threading.Thread(None, self.run, None, (), {}) + self.thread.start() + + def run(self): + """ + Run the PWM pattern into a background thread. This function should not be called outside of this class. + """ + while self.toTerminate == False: + if self.dutyCycle > 0: + GPIO.output(self.gpioPin, GPIO.HIGH) + time.sleep(self.dutyCycle * self.sliceTime) + if self.dutyCycle < self.maxCycle: + GPIO.output(self.gpioPin, GPIO.LOW) + time.sleep((self.maxCycle - self.dutyCycle) * self.sliceTime) + self.terminated = True + + def changeDutyCycle(self, dutyCycle): + """ + Change the duration of HIGH output of the pattern. Expected parameter is : + - dutyCycle : percentage of a single pattern to set HIGH output on the GPIO pin + + Example : with a frequency of 1 Hz, and a duty cycle set to 25, GPIO pin will + stay HIGH for 1*(25/100) seconds on HIGH output, and 1*(75/100) seconds on LOW output. + """ + self.dutyCycle = dutyCycle + + def changeFrequency(self, frequency): + """ + Change the frequency of the PWM pattern. Expected parameter is : + - frequency : the frequency in Hz for the PWM pattern. A correct value may be 100. + + Example : with a frequency of 1 Hz, and a duty cycle set to 25, GPIO pin will + stay HIGH for 1*(25/100) seconds on HIGH output, and 1*(75/100) seconds on LOW output. + """ + self.baseTime = 1.0 / frequency + self.sliceTime = self.baseTime / self.maxCycle + + def stop(self): + """ + Stops PWM output. + """ + self.toTerminate = True + while self.terminated == False: + # Just wait + time.sleep(0.01) + GPIO.output(self.gpioPin, GPIO.LOW) + +class hwports: + config_file_name = "/boot/armbianEnv.txt" + CONFIG_OVERLAYS = "overlays=" + CONFIG_SPI = "param_spidev_spi_bus=" + COMMAND_DISABLE_BT="sudo systemctl disable hciuart" + + def __init__(self): # general init + self.i2c_channels = [] # 0,1 + self.i2c_channels_init = [] # 0,1 + self.i2c_initialized = False + self.i2cbus = None + self.spi_channels = [] # 0,1 + self.spi_cs = [0,0] + self.serial = [] + self.pwmo = [] + self.BOARD = [] + for p in range(22): + self.pwmo.append({"pin":0,"o":False}) + opv = OS.getarmbianinfo() + if opv: + pinout = opv["pins"] + try: + if pinout=="26z+2": + from orangepi.zeroplus2 import BOARD + elif pinout=="26z+": + from orangepi.zeroplus import BOARD + elif pinout=="26pi3": + from orangepi.pi3 import BOARD + elif pinout=="26o+": + from orangepi.oneplus import BOARD + elif pinout=="40w+": + from orangepi.winplus import BOARD + elif pinout=="40pr": + from orangepi.prime import BOARD + elif pinout=="40pc2": + from orangepi.pc2 import BOARD + elif pinout=="40pc": + from orangepi.pc import BOARD + else: + pinout = "0" + except Exception as e: + pinout = "0" + if pinout != "" and pinout != "0": + try: +# GPIO.setmode(GPIO.BOARD) + GPIO.setmode(BOARD) + self.BOARD=BOARD + except Exception as e: + print("GPIO set:",e) + try: + GPIO.setwarnings(False) + self.gpioinit = True + except: + print("GPIO init failed") + self.gpioinit = False + + def __del__(self): + try: + self.cleanup() + except: + pass + + def cleanup(self): + if self.gpioinit: + GPIO.cleanup() + + def gpio_function_name(self,func): + typestr = "Unknown" + try: + func = int(func) + if GPIO.IN==func: + typestr = "Input" + elif GPIO.OUT==func: + typestr = "Output" + except Exception as e: + typestr = "Unknown" + return typestr + + def gpio_function_name_from_pin(self,gpio): + typestr = "Unknown" + try: + pinnum = int(gpio) + if pinnum>0: + typeint = self.gpio_function(pinnum) + typestr = self.gpio_function_name(typeint) + except Exception as e: + typestr = "Unknown" + return typestr + + def gpio_function(self,bpin): + func = -1 + try: + if os.path.exists("/sys/class/gpio/gpio"+str(self.BOARD[bpin])+"/direction"): + func = os.popen("/bin/cat /sys/class/gpio/gpio"+str(self.BOARD[bpin])+"/direction 2>/dev/null").read() + if "in" in func: + func = GPIO.IN + elif "out" in func: + func = GPIO.OUT + except: + func = -1 + return func + + def input(self,bcmpin): + return GPIO.input(bcmpin) + + def output(self,pin,value,Force=False): + if Force: + for b in range(len(Settings.Pinout)): + if str(Settings.Pinout[b]["BCM"])==str(pin).strip(): + if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: + if Settings.Pinout[b]["startupstate"]<4: + self.setpinstate(b,4) + break + return GPIO.output(pin,value) + + def add_event_detect(self,pin, detection, pcallback,pbouncetime=0): + for b in range(len(Settings.Pinout)): + if str(Settings.Pinout[b]["BCM"])==str(pin).strip(): + if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: + if Settings.Pinout[b]["startupstate"]<4: + self.setpinstate(b,Settings.Pinout[b]["startupstate"]) + else: + pass # i am lazy and not sure if is it can happen anyday... + break + if pbouncetime==0: + GPIO.add_event_detect(pin,detection,callback=pcallback) + else: + GPIO.add_event_detect(pin,detection,callback=pcallback,bouncetime=pbouncetime) + + def remove_event_detect(self,pin): + GPIO.remove_event_detect(pin) + + def get_first_i2c(self): + if len(self.i2c_channels_init)>0: + return self.i2c_channels_init[0] + for i in range(0,3): # get first + if self.is_i2c_usable(i): + return i + return -1 + + def i2c_init(self,channel=-1): + if channel==-1: + channel = self.get_first_i2c() + if not(channel in self.i2c_channels_init): + if self.is_i2c_usable(channel)==False: + channel = -1 + if channel ==-1: + return False + self.i2cbus = smbus.SMBus(channel) + self.i2c_channels_init.append(channel) + return True + + def i2c_read_block(self,address,cmd,channel=-1): + retval = None + if channel==-1: + channel = self.get_first_i2c() + if (channel in self.i2c_channels_init): + try: + retval = self.i2cbus.read_i2c_block_data(address,cmd) + except: + retval = None + return retval + + def is_i2c_usable(self,channel): + result = False + for p in range(len(Settings.Pinout)): + n = Settings.Pinout[p]["name"] + for tn in range(len(n)): + if "I2C"+str(channel) in n[tn]: + return True + return result + + def is_i2c_enabled(self,channel): + res = False + if channel in self.i2c_channels: + res = True + if res==False: + try: + for p in range(len(Settings.Pinout)): + if "I2C"+str(channel) in Settings.Pinout[p]["name"][ Settings.Pinout[p]["altfunc"] ]: + res = True + break + except: + pass + return res + + def enable_i2c(self,channel): + if self.is_i2c_usable(channel) and (self.is_i2c_enabled(channel)==False): + self.i2c_channels.append(channel) + try: + for p in range(len(Settings.Pinout)): + n = Settings.Pinout[p]["name"] + for tn in range(len(n)): + if "I2C"+str(channel) in n[tn]: + Settings.Pinout[p]["altfunc"] = tn + except: + pass + + def disable_i2c(self,channel): + if self.is_i2c_enabled(channel): + try: + self.i2c_channels.remove(channel) + except: + pass + try: + for p in range(len(Settings.Pinout)): + n = Settings.Pinout[p]["name"] + for tn in range(len(n)): + if "I2C"+str(channel) in n[tn]: + Settings.Pinout[p]["altfunc"] = 0 + except: + pass + + def is_spi_usable(self,channel): + result = False + for p in range(len(Settings.Pinout)): + n = Settings.Pinout[p]["name"] + for tn in range(len(n)): + if "SPI"+str(channel) in n[tn]: + return True + return result + + def is_spi_enabled(self,channel): + res = False + if channel in self.spi_channels: + res = True + if res==False: + try: + for p in range(len(Settings.Pinout)): + if "SPI"+str(channel) in Settings.Pinout[p]["name"][ Settings.Pinout[p]["altfunc"] ]: + res = True + break + except: + pass + return res + + def enable_spi(self,channel,cs=-1): + if self.is_spi_usable(channel) and (self.is_spi_enabled(channel)==False): + self.spi_channels.append(channel) + try: + for p in range(len(Settings.Pinout)): + n = Settings.Pinout[p]["name"] + for tn in range(len(n)): + if "SPI"+str(channel) in n[tn]: + Settings.Pinout[p]["altfunc"] = tn + except: + pass + + def disable_spi(self,channel): + if self.is_spi_enabled(channel): + try: + self.spi_channels.remove(channel) + except: + pass + try: + for p in range(len(Settings.Pinout)): + n = Settings.Pinout[p]["name"] + for tn in range(len(n)): + if "SPI"+str(channel) in n[tn]: + Settings.Pinout[p]["altfunc"] = 0 + except: + pass + + def is_serial_usable(self,channel=0): + result = False + for p in range(len(Settings.Pinout)): + n = Settings.Pinout[p]["name"] + for tn in range(len(n)): + if "UART"+str(channel) in n[tn]: + return True + return result + + def is_serial_enabled(self,channel=0): + res = False + if channel in self.serial: + res = True + if res==False: + try: + for p in range(len(Settings.Pinout)): + if "UART"+str(channel) in Settings.Pinout[p]["name"][ Settings.Pinout[p]["altfunc"] ]: + res = True + break + except: + pass + return res + + def enable_serial(self,channel=0): + if self.is_serial_usable(channel) and (self.is_serial_enabled(channel)==False): + self.serial.append(channel) + try: + for p in range(len(Settings.Pinout)): + n = Settings.Pinout[p]["name"] + for tn in range(len(n)): + if "UART"+str(channel) in n[tn]: + Settings.Pinout[p]["altfunc"] = tn + except: + pass + + def disable_serial(self,channel): + if self.is_serial_enabled(channel): + try: + self.serial.remove(channel) + except: + pass + try: + for p in range(len(Settings.Pinout)): + n = Settings.Pinout[p]["name"] + for tn in range(len(n)): + if "UART"+str(channel) in n[tn]: + Settings.Pinout[p]["altfunc"] = 0 + except: + pass + + def set_serial(self,status,channel=0): + if (status==0) or (status==False): + self.disable_serial(channel) + else: + self.enable_serial(channel) + + def output_pwm(self,bcmpin,pprop,pfreq=1000): # default 1000Hz + pin = int(bcmpin) + prop = int(pprop) + freq = int(pfreq) + + for p in range(len(Settings.Pinout)): + if int(Settings.Pinout[p]["BCM"])==pin : + if (int(Settings.Pinout[p]["startupstate"]) not in [4]): + return False # if not output skip + + pfound = False + if len(self.pwmo)>0: + for p in range(0,len(self.pwmo)): + if int(self.pwmo[p]["pin"])==pin: + if (self.pwmo[p]["o"]): + if prop<=0: + self.pwmo[p]["o"].stop() + else: + self.pwmo[p]["o"].start(prop) + self.pwmo[p]["o"].changeFrequency(freq) + self.pwmo[p]["o"].changeDutyCycle(prop) + pfound = True + break + if pfound==False: + self.pwmo[p]["pin"] = pin + self.pwmo[p]["o"] = OrangePwm(freq,pin) + self.pwmo[p]["o"].start(prop) + return True + + def is_i2s_usable(self): + result = False + if self.pinnum=="40": + result = True + return result + + def set_i2s(self,state): + if self.is_i2s_usable(): + if state==1 or state==True: + self.i2s=1 + if self.is_spi_enabled(1): + self.disable_spi(1) # collision resolving + else: + self.i2s=0 + + def set1wgpio(self,bcmpin,FirstRead=False): + for b in range(len(Settings.Pinout)): + if str(Settings.Pinout[b]["BCM"])==str(bcmpin).strip(): + if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: + Settings.Pinout[b]["startupstate"] = 5 + if FirstRead: + Settings.Pinout[b]["actualstate"]=Settings.Pinout[b]["startupstate"] + break + + def setpinstartstate(self,bcmpin,state): + for b in range(len(Settings.Pinout)): + if str(Settings.Pinout[b]["BCM"])==str(bcmpin).strip(): + if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: + self.setpinstate(b,state,True) + break + + def setpinactualstate(self,pinid,state): + if Settings.Pinout[pinid]["actualstate"]<5 and state<5: + Settings.Pinout[pinid]["actualstate"]=state + + def setpinstate(self,PINID,state,force=False): + if (force==False): + if Settings.Pinout[PINID]["altfunc"]>0 or Settings.Pinout[PINID]["canchange"]!=1 or Settings.Pinout[PINID]["BCM"]<0: + return False +# if (int(state)<=0 and int(Settings.Pinout[PINID]["startupstate"])>0): + if int(state)<=0: +# pass # revert to default input + pass # do nothing + Settings.Pinout[PINID]["startupstate"] = -1 +# if self.gpioinit: +# try: +# GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.IN) +# except: +# pass +# self.setpinactualstate(PINID,99) # ugly hack + return True + elif state==1: + pass # input + Settings.Pinout[PINID]["startupstate"] = state + if self.gpioinit: + try: + GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.IN) + except: + pass + self.setpinactualstate(PINID,1) + return True + elif state==4: #output + if self.gpioinit: + try: + GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.OUT) + except: + pass + Settings.Pinout[PINID]["startupstate"] = state + self.setpinactualstate(PINID,4) + return True + elif state==5: #1wire + self.setpinactualstate(PINID,-1) + self.set1wgpio(int(Settings.Pinout[PINID]["BCM"])) + return True + return False + + def initpinstates(self): + if self.gpioinit: + for b in range(len(Settings.Pinout)): + if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: + if int(Settings.Pinout[b]["BCM"])>=0: + if int(Settings.Pinout[b]["startupstate"])<6 and int(Settings.Pinout[b]["startupstate"])>=0: + self.setpinstate(b,Settings.Pinout[b]["startupstate"],True) + + def readconfig(self): + self.i2c_channels = [] # 0,1 + self.spi_channels = [] # 0,1 + self.serial = [] + self.spi_cs = [0,0] +# self.set_serial(1) +# self.audio = 1 + + try: + import plugindeps + for i in range(len(plugindeps.modulelist)): + if plugindeps.modulelist[i]['name']=="GPIO": + plugindeps.modulelist[i]["pip"] = ["OPi.GPIO"] + plugindeps.modulelist[i]["testcmd"] = "import OPi.GPIO as GPIO" + elif plugindeps.modulelist[i]['name']=="Adafruit_DHT": + plugindeps.modulelist[i]["pip"] = [""] # only RPI supported! + elif plugindeps.modulelist[i]['name']=="ws2812": + plugindeps.modulelist[i]["pip"] = [""] # only RPI supported! + elif plugindeps.modulelist[i]['name']=="LCD": + plugindeps.modulelist[i]["pip"] = [""] # only RPI supported! + elif plugindeps.modulelist[i]['name']=="tm1637": + plugindeps.modulelist[i]["pip"] = [""] # only RPI supported! + elif plugindeps.modulelist[i]['name']=="ina219": + plugindeps.modulelist[i]["pip"] = [""] # only RPI supported! + elif plugindeps.modulelist[i]['name']=="pylora": + plugindeps.modulelist[i]["pip"] = [""] # only RPI supported! + elif plugindeps.modulelist[i]['name']=="epd": + plugindeps.modulelist[i]["pip"] = [""] # only RPI supported! + elif plugindeps.modulelist[i]['name']=="amg": + plugindeps.modulelist[i]["pip"] = [""] # only RPI supported! + elif plugindeps.modulelist[i]['name']=="wpi": + plugindeps.modulelist[i]["installcmd"] = [""] # only RPI supported! + except: + pass + Settings.PinStatesMax = 7 + Settings.PinStates = ["Default","Input","Reserved","Reserved","Output","1WIRE","Special","Reserved"] + try: + with open(self.config_file_name) as f: + for line in f: + line = line.strip().lower() + if line.startswith(self.CONFIG_OVERLAYS): + for i in range(0,3): + dn = "i2c"+str(i) + if dn in line: + self.enable_i2c(i) + for i in range(0,5): + dn = "uart"+str(i) + if dn in line: + self.enable_serial(i) + if line.startswith(self.CONFIG_SPI): + for i in range(0,3): + if str(i) in line: + self.enable_spi(i) + except Exception as e: + print(e) + + for b in range(len(Settings.Pinout)): + if Settings.Pinout[b]["altfunc"] != 0 and Settings.Pinout[b]["startupstate"]>0 and Settings.Pinout[b]["startupstate"]<7: + Settings.Pinout[b]["startupstate"] = -1 # set to default + + return True + + def saveconfig(self): + # save config.txt + contents = [] + ostr = "" + w1enabled = False + for p in range(len(Settings.Pinout)): + try: + if w1enabled==False and (Settings.Pinout[p]['startupstate']==5 or Settings.Pinout[p]['actualstate']==5): + w1enabled = True + except: + pass + try: + mstr = [] + spis = [] + for p in range(len(Settings.Pinout)): + n = Settings.Pinout[p]["name"] + sn = Settings.Pinout[p]["altfunc"] + if "I2C" in n[sn] or "SPI" in n[sn] or "UART" in n[sn]: + for i in range(0,5): + if "I2C"+str(i) in n[sn]: + if not "i2c"+str(i) in mstr: + mstr.append("i2c"+str(i)) + for i in range(0,3): + if "SPI"+str(i) in n[sn] and not (i in spis): + spis.append(i) + for i in range(0,7): + if "UART"+str(i) in n[sn]: + if not "uart"+str(i) in mstr: + mstr.append("uart"+str(i)) + except Exception as e: + pass + try: + with open(self.config_file_name) as f: + for line in f: + line = line.strip() + if line.startswith(self.CONFIG_OVERLAYS): + ostr = line + line = "" + elif line.startswith(self.CONFIG_SPI): + line = "" + if line != "": + contents.append(line) + except: + pass + tostr = ostr.split("=") + tstr2 = tostr[1].split() + if len(spis)>0: + mstr.append("spi-spidev") + else: + try: + tstr2.remove("spi-spidev") + except: + pass + if w1enabled: + mstr.append("w1-gpio") + else: + try: + tstr2.remove("w1-gpio") + except: + pass + + for o in tstr2: + if ("i2c" in o or "uart" in o): + if not (o in mstr): + tstr2.remove(o) + for o in mstr: + if not(o in tstr2): + tstr2.append(o) + newstr = " ".join(tstr2) + if newstr.strip()!="": + contents.append(self.CONFIG_OVERLAYS+newstr) + if len(spis)>0: + for i in range(len(spis)): + contents.append("param_spidev_spi_bus="+str(spis[i])) + with open(self.config_file_name,"w") as f: + for c in range(len(contents)): + f.write(contents[c]+"\n") + + return True + + + def is_i2c_lib_available(self): + res = False + try: + import smbus + res = True + except: + res = False + return res + + def i2cscan(self,bus_number): + devices = [] + try: + bus = smbus.SMBus(bus_number) + except: + devices = [] + for device in range(3, 125): + try: + if (device>=0x30 and device<=0x37) or (device>=0x50 and device<=0x5f): + bus.read_byte(device) + else: + bus.write_quick(device) + devices.append(device) # hex(number)? + except: + pass + if (0x5c not in devices): # 0x5c has to be checked twice as Am2320 auto-shutdown itself? + try: + bus.read_byte(0x5c) + devices.append(0x5c) + except: + pass + if (0x7f not in devices): # 0x7f is non-standard used by PME + try: + bus.read_byte(0x7f) + devices.append(0x7f) + except: + pass + + try: + bus.close() + except: + pass + bus = None + return devices + + def createpinout(self,pinout): + global PINOUT40 + if ("40" in pinout and len(Settings.Pinout)<41) or ("26" in pinout and len(Settings.Pinout)<27): + if "26" in pinout: + for p in range(27): + Settings.Pinout.append(PINOUT40[p]) + else: + Settings.Pinout=PINOUT40 + try: + if pinout=="26z+2": + from orangepi.zeroplus2 import BOARD + elif pinout=="26z+": + from orangepi.zeroplus import BOARD + elif pinout=="26pi3": + from orangepi.pi3 import BOARD + elif pinout=="26o+": + from orangepi.oneplus import BOARD + elif pinout=="40w+": + from orangepi.winplus import BOARD + elif pinout=="40pr": + from orangepi.prime import BOARD + elif pinout=="40pc2": + from orangepi.pc2 import BOARD + elif pinout=="40pc": + from orangepi.pc import BOARD + else: + Settings.Pinout = [] # unknown board + except Exception as e: + Settings.Pinout = [] # unknown board + if len(Settings.Pinout)>0: + try: + GPIO.setmode(BOARD) + except Exception as e: + print("GPIO set:",e) +# print(BOARD)#debug + for p in BOARD: + pt = BOARD[p] # pin type id + name = [] + name.append(str(pt)) + if pt == 0: + name = ["PA0","UART2-TX"] + elif pt == 1: + name = ["PA1","UART2-RX"] + elif pt == 2: + name = ["PA2","UART2-RTS"] + elif pt == 3: + name = ["PA3","UART2-CTS"] + elif pt == 6: + name = ["PA6"] + elif pt == 7: + name = ["PA7"] + elif pt == 8: + name = ["PA8"] + elif pt == 9: + name = ["PA9"] + elif pt == 10: + name = ["PA10"] + elif pt == 11: + name = ["PA11","I2C0-SCL"] + elif pt == 12: + name = ["PA12","I2C0-SDA"] + elif pt == 13: + name = ["PA13","SPI1-CE0","UART3-TX"] + elif pt == 14: + name = ["PA14","SPI1-SCLK","UART3-RX"] + elif pt == 15: + name = ["PA15","SPI1-MOSI","UART3-RTS"] + elif pt == 16: + name = ["PA16","SPI1-MISO","UART3-CTS"] + elif pt == 18: + name = ["PA18","PCM0-SYN","I2C1-SCL"] + elif pt == 19: + name = ["PA19","PCM0-CLK","I2C1-SDA"] + elif pt == 20: + name = ["PA20","PCM0-DOUT"] + elif pt == 21: + name = ["PA21","PCM0-DIN"] + elif pt == 32: + name = ["PB0","UART2-TX"] + elif pt == 33: + name = ["PB1","UART2-RX"] + elif pt == 34: + name = ["PB2","UART2-RTS"] + elif pt == 35: + name = ["PB3","UART2-CTS","I2S0"] + elif pt == 36: + name = ["PB4","PCM0-SYNC"] + elif pt == 37: + name = ["PB5","PCM0-BCLK"] + elif pt == 38: + name = ["PB6","PCM0-DOUT"] + elif pt == 39: + name = ["PB7"] + elif pt == 64: + if pinout=="40pc": + name = ["PC0","SPI0-MOSI"] + else: + name = ["PC0","NAND","SPI0-SCLK"] + elif pt == 65: + name = ["PC1","SPI0-MISO"] + elif pt == 66: + if pinout=="40pc": + name = ["PC2","SPI0-SCLK"] + else: + name = ["PC2","NAND","SPI0-MOSI"] + elif pt == 67: + if pinout=="40pc": + name = ["PC3","SPI0-CE0"] + else: + name = ["PC3","NAND","SPI0-MISO"] + elif pt == 68: + name = ["PC4","NAND"] + elif pt == 69: + name = ["PC5","NAND","SPI0-CE0"] + elif pt == 70: + name = ["PC6","NAND"] + elif pt == 71: + name = ["PC7","NAND"] + elif pt == 72: + name = ["PC8","NAND"] + elif pt == 73: + name = ["PC9","NAND"] + elif pt == 74: + name = ["PC10","NAND"] + elif pt == 75: + name = ["PC11","NAND"] + elif pt == 76: + name = ["PC12","NAND"] + elif pt == 96: + name = ["PD0","UART3-TX","SPI1-CE0","LCD-D2"] + elif pt == 97: + name = ["PD1","UART3-RX","SPI1-CLK","LCD-D3"] + elif pt == 98: + name = ["PD2","UART4-TX","SPI1-MOSI","LCD-D4"] + elif pt == 99: + name = ["PD3","UART4-RX","SPI1-MISO","LCD-D5"] + elif pt == 100: + name = ["PD4","UART4-RTS","LCD-D6"] + elif pt == 101: + name = ["PD5","UART4-CTS","LCD-D7"] + elif pt == 102: + name = ["PD6","LCD-D10"] + elif pt == 107: + name = ["PD11","MII"] + elif pt == 110: + name = ["PD14","MII"] + elif pt == 111: + name = ["PD15","LCD0-D21","TS1-DVLD"] + elif pt == 112: + name = ["PD16","LCD0-D22","TS1-D0"] + elif pt == 113: + name = ["PD18","LCD0-CLK","TS2-ERR"] + elif pt == 117: + name = ["PD21","LCD0-VSYNC","UART2-RTS","TS2-D0"] + elif pt == 118: + name = ["PD22","UART2-CTS","TS3-CLK"] + elif pt == 119: + name = ["PD23","I2C2-SCL","UART3-RX","TS3-ERR"] + elif pt == 120: + name = ["PD24","I2C2-SDA","UART3-RX","TS3-SYNC"] + elif pt == 121: + name = ["PD25","I2C0-SCL","UART3-RTS","TS3-DVLD"] + elif pt == 122: + name = ["PD26","I2C0-SDA","UART3-CTS","TS3-D0"] + elif pt == 142: + name = ["PE14","I2C2-SCL"] + elif pt == 143: + name = ["PE15","I2C2-SDA"] + elif pt == 198: + name = ["PG6","UART1-TX"] + elif pt == 199: + name = ["PG7","UART1-RX"] + elif pt == 200: + name = ["PG8","UART1-RTS"] + elif pt == 201: + name = ["PG9","UART1-CTS"] + elif pt == 226: + name = ["PH2","I2C1-SCL"] + elif pt == 227: + if "26" in pinout: + name = ["PH3","SPI1-CS","PCM0-DIN"] + else: + name = ["PH3","I2C1-SDA"] + elif pt == 228: + if "26" in pinout: + name = ["PH4","SPI1-SCLK","PCM0-MCLK"] + else: + name = ["PH4","UART3-TX"] + elif pt == 229: + if "26" in pinout: + name = ["PH5","SPI1-MOSI","I2C1-SCL","SPDIF-MCLK"] + else: + name = ["PH5","UART3-RX"] + elif pt == 230: + if "26" in pinout: + name = ["PH6","SPI1-MISO","I2C1-SDA","SPDIF-IN"] + else: + name = ["PH6","UART3-RTS"] + elif pt == 231: + name = ["PH7","UART3-CTS"] + elif pt == 352: + name = ["PL0","I2CS-SCL"] + elif pt == 353: + name = ["PL1","I2CS-SDA"] + elif pt == 354: + name = ["PL2","UARTS-TX"] + elif pt == 355: + name = ["PL3","UARTS-RX"] + elif pt == 360: + name = ["PL8"] + elif pt == 361: + name = ["PL9","I2CS-SDA"] + elif pt == 362: + name = ["PL10"] + + if pinout=="40pc": + try: + name.remove("NAND") + except: + pass + Settings.Pinout[p]["name"] = name +# print(p,BOARD[p]) + return True +# print(Settings.Pinout) + + def webform_load(self): + try: + import OPi.GPIO as GPIO + except: + webserver.TXBuffer +="

OPi.GPIO not installed!" + return False + webserver.TXBuffer += "

" + webserver.TXBuffer += "" + webserver.addHtml("") + for p in range(len(Settings.Pinout)): + if Settings.Pinout[p]["canchange"] != 2: + idnum = int(Settings.Pinout[p]["ID"]) + if bool(idnum & 1): # left + webserver.TXBuffer += "" # actual state + else: + webserver.TXBuffer += "-" + if Settings.Pinout[p]["canchange"]==1 and Settings.Pinout[p]["altfunc"]==0: + webserver.addHtml("") + else: + webserver.TXBuffer += "" + try: + funcorder = int(Settings.Pinout[p]["altfunc"]) + except: + funcorder = 0 + if funcorder>0 and len(Settings.Pinout[p]["name"])>funcorder: + webserver.TXBuffer += "" + else: + webserver.TXBuffer += "" + webserver.TXBuffer += "" + webserver.TXBuffer += "" # add pin value + else: + webserver.TXBuffer += "-" + else: # right + pinfunc = -1 + if Settings.Pinout[p]["canchange"]==1 and Settings.Pinout[p]["BCM"]>0: + webserver.TXBuffer += "" # add pin value + else: + webserver.TXBuffer += "" + webserver.TXBuffer += "" + try: + funcorder = int(Settings.Pinout[p]["altfunc"]) + except: + funcorder = 0 + if funcorder>0 and len(Settings.Pinout[p]["name"])>funcorder: + webserver.TXBuffer += "" + else: + webserver.TXBuffer += "" + webserver.TXBuffer += "") + else: + webserver.TXBuffer += "-" + webserver.addHtml("" # actual state + else: + webserver.TXBuffer += "" + webserver.TXBuffer += "" + webserver.TXBuffer += "
GPIO pinout
Detected functionRequested functionPin name#ValueValue#Pin nameRequested functionDetected function
" +# if Settings.Pinout[p]["canchange"]==1 and Settings.Pinout[p]["altfunc"]==0: + if Settings.Pinout[p]["canchange"]==1 and Settings.Pinout[p]["BCM"]>0: + # print pin setup infos + astate = Settings.Pinout[p]["actualstate"] + if astate<0: + astate=0 + astate = Settings.PinStates[astate] + pinfunc = -1 + if self.gpioinit: + pinfunc = self.gpio_function(int(Settings.Pinout[p]["BCM"])) + astate = str(self.gpio_function_name(pinfunc)) + webserver.TXBuffer += astate + webserver.TXBuffer += "") # startupstate + webserver.addSelector("pinstate"+str(p),Settings.PinStatesMax,Settings.PinStates,False,None,Settings.Pinout[p]["startupstate"],False) + webserver.addHtml("-"+ Settings.Pinout[p]["name"][funcorder] +""+ Settings.Pinout[p]["name"][0] +""+ str(Settings.Pinout[p]["ID"]) +"" + if Settings.Pinout[p]["canchange"]==1 and pinfunc in [0,1] and (astate in ["Input","Output"]): + if self.gpioinit: + self.setpinstate(p,int(Settings.Pinout[p]["startupstate"])) + try: + webserver.TXBuffer += "("+str(self.input(int(Settings.Pinout[p]["BCM"])))+")" + except: + webserver.TXBuffer += "E" + else: + webserver.TXBuffer += "X" + webserver.TXBuffer += "" + if self.gpioinit: + pinfunc = self.gpio_function(int(Settings.Pinout[p]["BCM"])) + if pinfunc in [0,1] and Settings.Pinout[p]["altfunc"]==0: + self.setpinstate(p,int(Settings.Pinout[p]["startupstate"])) + try: + webserver.TXBuffer += "("+str(self.input(int(Settings.Pinout[p]["BCM"])))+")" + except: + webserver.TXBuffer += "E" + else: + webserver.TXBuffer += "X" + webserver.TXBuffer += "-"+ str(Settings.Pinout[p]["ID"]) +""+ Settings.Pinout[p]["name"][funcorder] +""+ Settings.Pinout[p]["name"][0] +"" + if Settings.Pinout[p]["canchange"]==1 and Settings.Pinout[p]["altfunc"]==0: + # print pin setup infos + webserver.addSelector("pinstate"+str(p),Settings.PinStatesMax,Settings.PinStates,False,None,Settings.Pinout[p]["startupstate"],False) + webserver.addHtml("") # startupstate + if Settings.Pinout[p]["canchange"]==1 and Settings.Pinout[p]["BCM"]>0: + astate = Settings.Pinout[p]["actualstate"] + if astate<0: + astate=0 + astate = Settings.PinStates[astate] + if self.gpioinit: + astate = str(self.gpio_function_name(pinfunc)) + webserver.TXBuffer += str(astate)+"-
" + + webserver.TXBuffer += "" + webserver.addFormHeader("Advanced features") + for i in range(0,5): + if self.is_i2c_usable(i): + webserver.addFormCheckBox("Enable I2C-"+str(i),"i2c"+str(i),self.is_i2c_enabled(i)) + for i in range(0,3): + if self.is_spi_usable(i): + webserver.addFormCheckBox("Enable SPI-"+str(i),"spi"+str(i),self.is_spi_enabled(i)) + for i in range(0,7): + if self.is_serial_usable(i): + webserver.addFormCheckBox("Enable UART-"+str(i),"uart"+str(i),self.is_serial_enabled(i)) + webserver.addFormSeparator(2) + webserver.TXBuffer += "" + if OS.check_permission(): + if OS.checkboot_ro(): + webserver.addFormNote("WARNING: Your /boot partition is mounted READONLY! Changes could not be saved! Run 'sudo mount -o remount,rw /boot' or whatever necessary to solve it!") + webserver.addFormNote("WARNING: Some changes needed to reboot after submitting changes! And most changes requires root permission.") + webserver.addHtml("
" + if OS.check_permission(): + webserver.addSubmitButton() + webserver.addSubmitButton("Set without save","set") + webserver.addSubmitButton("Reread config","reread") + webserver.TXBuffer += "
") + + return True + + def webform_save(self,params): + submit = webserver.arg("Submit",params) + setbtn = webserver.arg("set",params) + if (submit=='Submit') or (setbtn!=''): + for i in range(0,5): + wset = webserver.arg("i2c"+str(i),params) + if wset=="on": + self.enable_i2c(i) + else: + self.disable_i2c(i) + for i in range(0,3): + wset = webserver.arg("spi"+str(i),params) + if wset=="on": + self.enable_spi(i) + else: + self.disable_spi(i) + for i in range(0,7): + wset = webserver.arg("uart"+str(i),params) + if wset=="on": + self.enable_serial(i) + else: + self.disable_serial(i) + for p in range(len(Settings.Pinout)): + pins = webserver.arg("pinstate"+str(p),params).strip() +# print(p,pins) + if pins and pins!="" and p!= "": + try: + self.setpinstate(p,int(pins)) + except Exception as e: + misc.addLog(rpieGlobals.LOG_LEVEL_DEBUG,"Pin "+str(p)+" "+str(e)) + if OS.check_permission() and setbtn=='': + try: + self.saveconfig() + except Exception as e: + misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,str(e)) + try: + Settings.savepinout() + except Exception as e: + misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,str(e)) + + + return True + +#Init Hardware GLOBAL ports +#HWPorts = hwports() +#if os.path.exists("/DietPi/config.txt"): # DietPi FIX! +# HWPorts.config_file_name = "/DietPi/config.txt" diff --git a/lib/lib_rpigpios.py b/lib/lib_rpigpios.py new file mode 100644 index 0000000..781b374 --- /dev/null +++ b/lib/lib_rpigpios.py @@ -0,0 +1,1305 @@ +#!/usr/bin/env python3 +############################################################################# +################ Helper Library for RPI GPIO handling ####################### +############################################################################# +# +# Copyright (C) 2020 by Alexander Nagy - https://bitekmindenhol.blog.hu/ +# +import Settings +import os +import time +import lib.lib_syspwm as syspwm +try: + import linux_os as OS +except: + print("Linux OS functions can not be imported!") +try: + import RPi.GPIO as GPIO +except: + print("RPi.GPIO not installed!") +try: + import smbus +except: + print("I2C smbus not installed!") + +PINOUT40 = [ +{"ID":0, +"BCM":-1, +"name":["None"], +"canchange":2, +"altfunc": 0}, +{"ID":1, +"BCM":-1, +"name":["3V3"], +"canchange":0, +"altfunc": 0}, +{"ID":2, +"BCM":-1, +"name":["5V"], +"canchange":0, +"altfunc": 0}, +{"ID":3, +"BCM":2, +"name":["GPIO2","I2C1-SDA"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":4, +"BCM":-1, +"name":["5V"], +"canchange":0, +"altfunc": 0}, +{"ID":5, +"BCM":3, +"name":["GPIO3","I2C1-SCL"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":6, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":7, +"BCM":4, +"name":["GPIO4"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":8, +"BCM":14, +"name":["GPIO14","UART-TX","BT-TX"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":9, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":10, +"BCM":15, +"name":["GPIO15","UART-RX","BT-RX"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":11, +"BCM":17, +"name":["GPIO17","SPI1-CE1"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":12, +"BCM":18, +"name":["GPIO18/PWM0","SPI1-CE0","PCM-CLK"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":13, +"BCM":27, +"name":["GPIO27"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":14, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":15, +"BCM":22, +"name":["GPIO22"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":16, +"BCM":23, +"name":["GPIO23"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":17, +"BCM":-1, +"name":["3V3"], +"canchange":0, +"altfunc": 0}, +{"ID":18, +"BCM":24, +"name":["GPIO24"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":19, +"BCM":10, +"name":["GPIO10","SPI0-MOSI"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":20, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":21, +"BCM":9, +"name":["GPIO9","SPI0-MISO"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":22, +"BCM":25, +"name":["GPIO25"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":23, +"BCM":11, +"name":["GPIO11","SPI0-SCLK"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":24, +"BCM":8, +"name":["GPIO8","SPI0-CE0"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":25, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":26, +"BCM":7, +"name":["GPIO7","SPI0-CE1"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":27, +"BCM":0, +"name":["ID_SD"], +"canchange":0, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":28, +"BCM":1, +"name":["ID_SC"], +"canchange":0, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":29, +"BCM":5, +"name":["GPIO5"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":30, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":31, +"BCM":6, +"name":["GPIO6"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":32, +"BCM":12, +"name":["GPIO12/PWM0"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":33, +"BCM":13, +"name":["GPIO13/PWM1"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":34, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":35, +"BCM":19, +"name":["GPIO19/PWM1","SPI1-MISO","PCM-FS"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":36, +"BCM":16, +"name":["GPIO16","SPI1-CE2"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":37, +"BCM":26, +"name":["GPIO26"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":38, +"BCM":20, +"name":["GPIO20","SPI1-MOSI","PCM-DIN"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":39, +"BCM":-1, +"name":["GND"], +"canchange":0, +"altfunc": 0}, +{"ID":40, +"BCM":21, +"name":["GPIO21","SPI1-SCLK","PCM-DOUT"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1} +] + +PINOUT26R2_DELTA = [ +{"ID":11, +"BCM":17, +"name":["GPIO17"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":12, +"BCM":18, +"name":["GPIO18/PWM0"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1} +] + +PINOUT26R1_DELTA = [ +{"ID":3, +"BCM":0, +"name":["GPIO0","I2C0-SDA"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":5, +"BCM":1, +"name":["GPIO1","I2C0-SCL"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":11, +"BCM":17, +"name":["GPIO17"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":12, +"BCM":18, +"name":["GPIO18/PWM0"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +{"ID":13, +"BCM":21, +"name":["GPIO21"], +"canchange":1, +"altfunc": 0, +"startupstate":-1, +"actualstate":-1}, +] + +try: + BOTH=GPIO.BOTH + RISING=GPIO.RISING + FALLING=GPIO.FALLING +except: + BOTH=3 + RISING=1 + FALLING=2 + +class hwports: + config_file_name = "/boot/config.txt" # /boot/config.txt + CONFIG_ENABLE_I2C="dtparam=i2c_arm=on" + CONFIG_ENABLE_I2C0="dtparam=i2c0=on" + CONFIG_ENABLE_I2C1="dtparam=i2c1=on" + CONFIG_ENABLE_SPI0="dtparam=spi=on" + CONFIG_ENABLE_SPI1_1="dtoverlay=spi1-1cs" + CONFIG_ENABLE_SPI1_2="dtoverlay=spi1-2cs" + CONFIG_ENABLE_SPI1_3="dtoverlay=spi1-3cs" + CONFIG_ENABLE_I2S="dtparams=i2s=on" + CONFIG_DISABLE_UART="enable_uart=0" #0/1 + CONFIG_ENABLE_UART="enable_uart=1" + CONFIG_DISABLE_UART2="dtparam=uart0=off" + CONFIG_BT_SWUART="dtoverlay=pi3-miniuart-bt" + CONFIG_DISABLE_BT="dtoverlay=pi3-disable-bt" + CONFIG_DISABLE_WIFI="dtoverlay=pi3-disable-wifi" + CONFIG_PWM0="dtoverlay=pwm" + CONFIG_PWM0_1="dtoverlay=pwm-2chan" + CONFIG_ENABLE_AUDIO="dtparam=audio=on" #on/off + CONFIG_DISABLE_AUDIO="dtparam=audio=off" #on/off + CONFIG_ONEWIRE="dtoverlay=w1-gpio" + CONFIG_IR="dtoverlay=gpio-ir" + CONFIG_PWMIR="dtoverlay=pwm-ir-tx" + CONFIG_GPIO="gpio=" + CONFIG_GPUMEM="gpu_mem" + COMMAND_DISABLE_BT="sudo systemctl disable hciuart" + CONFIG_ENABLE_RTC="dtoverlay=i2c-rtc," # ds1307, pcf8523, ds3231 + + def __init__(self): # general init + self.i2c_channels = [] # 0,1 + self.i2c_initialized = False + self.i2cbus = None + self.spi_channels = [] # 0,1 + self.spi_cs = [0,0] + self.serial = 0 + self.bluetooth = 0 # 0:disabled,1:enabled with SW miniUART,2:enabled with HW UART + self.wifi = 0 # 0:disabled,1:enabled + self.audio = 0 + self.i2s = 0 + self.pwm = [0,0] # 0.byte:pwm0 pin, 1.byte:pwm1 pin, no more + self.rtc = "" # /lib/udev/hwclock-set + self.pwmo = [] + for p in range(22): + self.pwmo.append({"pin":0,"o":False}) + try: + rpitype = OS.getRPIVer() + except: + rpitype=[] + try: + po = rpitype["pins"] + except: + po = "0" + try: + bta = int(rpitype["bt"]) + except: + bta = 0 + try: + wf = int(rpitype["wlan"]) + except: + wf = 0 + try: + iram = rpitype["ram"] + except: + iram = "0" + try: + GPIO.setwarnings(False) + GPIO.setmode(GPIO.BCM) + self.gpioinit = True + except: + print("GPIO init failed") + self.gpioinit = False + + self.pinnum = po + self.internalwlan = (wf==1) + self.internalbt = (bta==1) + self.gpumin = 16 + self.gpumax = self.gpumin + if "256m" in iram.lower(): + self.gpumax = 192 + elif "512m" in iram.lower(): + self.gpumax = 448 + elif "1m" in iram.lower(): + self.gpumax = 944 + self.gpumem = self.gpumin + + def __del__(self): + try: + self.cleanup() + except: + pass + + def cleanup(self): + if self.gpioinit: + for p in range(len(self.pwmo)): + try: + if (self.pwmo[p]["o"] != False) and not (self.pwmo[p]["o"] is None): + self.pwmo[p]["o"].stop() + except: + pass + GPIO.cleanup() + + def gpio_function_name(self,func): + typestr = "Unknown" + try: + typeint = int(func) + if GPIO.IN==typeint: + typestr = "Input" + elif GPIO.OUT==typeint: + typestr = "Output" + elif GPIO.SPI==typeint: + typestr = "SPI" + elif GPIO.I2C==typeint: + typestr = "I2C" + elif GPIO.HARD_PWM==typeint: + typestr = "HardPWM" + elif GPIO.SERIAL==typeint: + typestr = "Serial" + except: + typestr = "Unknown" + return typestr + + def gpio_function_name_from_pin(self,gpio): + typestr = "Unknown" + try: + pinnum = int(gpio) + if pinnum>0: + typeint = GPIO.gpio_function(pinnum) + typestr = self.gpio_function_name(typeint) + except Exception as e: + typestr = "Unknown" + return typestr + + def gpio_function(self,bcmpin): + return GPIO.gpio_function(bcmpin) + + def input(self,bcmpin): + return GPIO.input(bcmpin) + + def output(self,pin,value,Force=False): + if Force: + for b in range(len(Settings.Pinout)): + if str(Settings.Pinout[b]["BCM"])==str(pin).strip(): + if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: + if Settings.Pinout[b]["startupstate"]<4: + self.setpinstate(b,4) + break + return GPIO.output(pin,value) + + def add_event_detect(self,pin, detection, pcallback,pbouncetime=0): + for b in range(len(Settings.Pinout)): + if str(Settings.Pinout[b]["BCM"])==str(pin).strip(): + if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: + if Settings.Pinout[b]["startupstate"]<4: + self.setpinstate(b,Settings.Pinout[b]["startupstate"]) + else: + pass # i am lazy and not sure if is it can happen anyday... + break + if pbouncetime==0: + GPIO.add_event_detect(pin,detection,callback=pcallback) + else: + GPIO.add_event_detect(pin,detection,callback=pcallback,bouncetime=pbouncetime) + + def remove_event_detect(self,pin): + GPIO.remove_event_detect(pin) + + def i2c_init(self): + if self.i2c_initialized == False: + if self.is_i2c_usable(1): + self.i2cbus = smbus.SMBus(1) + self.i2c_initialized = True + elif self.is_i2c_usable(0): + self.i2cbus = smbus.SMBus(0) + self.i2c_initialized = True + return self.i2c_initialized + + def i2c_read_block(self,address,cmd): + retval = None + if self.i2c_initialized: + try: + retval = self.i2cbus.read_i2c_block_data(address,cmd) + except: + retval = None + return retval + + def is_i2c_usable(self,channel): + result = False + if channel==0: + if self.pinnum=="26R1": + result = True + else: + if self.pinnum=="26R2" or self.pinnum=="40": + result = True + return result + + def is_i2c_enabled(self,channel): + if channel in self.i2c_channels: + return True + else: + return False + + def enable_i2c(self,channel): + if self.is_i2c_usable(channel) and (self.is_i2c_enabled(channel)==False): + self.i2c_channels.append(channel) + Settings.Pinout[3]["altfunc"] = 1 + Settings.Pinout[5]["altfunc"] = 1 + + def disable_i2c(self,channel): + if self.is_i2c_enabled(channel): + self.i2c_channels.remove(channel) + Settings.Pinout[3]["altfunc"] = 0 + Settings.Pinout[5]["altfunc"] = 0 + + def is_spi_usable(self,channel): + result = False + try: + channel = int(channel) + except: + return False + if channel==0: + if str(self.pinnum)=="26R1" or str(self.pinnum)=="26R2" or str(self.pinnum)=="40": + result = True + else: + if str(self.pinnum)=="40": + result = True + return result + + def is_spi_enabled(self,channel): + if channel in self.spi_channels: + return True + else: + return False + + def enable_spi(self,channel,cs=3): # cs can 1,2,3 for spi1, 2 for spi0 + try: + channel=int(channel) + cs=int(cs) + except: + return False + if self.is_spi_usable(channel): + if (self.is_spi_enabled(channel)==False): + self.spi_channels.append(channel) + if channel==0: + self.spi_cs[0] = 2 + Settings.Pinout[19]["altfunc"] = 1 + Settings.Pinout[21]["altfunc"] = 1 + Settings.Pinout[23]["altfunc"] = 1 + Settings.Pinout[24]["altfunc"] = 1 + Settings.Pinout[26]["altfunc"] = 1 + else: + self.spi_cs[1] = int(cs) + Settings.Pinout[35]["altfunc"] = 1 + Settings.Pinout[38]["altfunc"] = 1 + Settings.Pinout[40]["altfunc"] = 1 + Settings.Pinout[12]["altfunc"] = 1 + Settings.Pinout[11]["altfunc"] = 0 + Settings.Pinout[36]["altfunc"] = 0 + if self.spi_cs[1]>1: + Settings.Pinout[11]["altfunc"] = 1 + if self.spi_cs[1]>2: + Settings.Pinout[36]["altfunc"] = 1 + + def disable_spi(self,channel): + try: + channel=int(channel) + except: + return False + if self.is_spi_enabled(channel): + self.spi_channels.remove(channel) + if channel==0: + Settings.Pinout[19]["altfunc"] = 0 + Settings.Pinout[21]["altfunc"] = 0 + Settings.Pinout[23]["altfunc"] = 0 + Settings.Pinout[24]["altfunc"] = 0 + Settings.Pinout[26]["altfunc"] = 0 + else: + if Settings.Pinout[12]["altfunc"] == 1: + Settings.Pinout[35]["altfunc"] = 0 + Settings.Pinout[38]["altfunc"] = 0 + Settings.Pinout[40]["altfunc"] = 0 + Settings.Pinout[12]["altfunc"] = 0 + Settings.Pinout[11]["altfunc"] = 0 + Settings.Pinout[36]["altfunc"] = 0 + + def is_serial_enabled(self): + return (self.serial==1) + + def set_serial(self,status): + if (status==0) or (status==False): + self.serial = 0 + if Settings.Pinout[8]["altfunc"]==1 or self.bluetooth==0: + Settings.Pinout[8]["altfunc"] = 0 + Settings.Pinout[10]["altfunc"] = 0 + else: + self.serial = 1 + Settings.Pinout[8]["altfunc"] = 1 + Settings.Pinout[10]["altfunc"] = 1 + + def is_internal_bt_usable(self): + return self.internalbt + + def get_internal_bt_level(self): + return self.bluetooth + + def set_internal_bt(self,uartlevel): #1=sw,2=hw + if self.is_internal_bt_usable(): + self.bluetooth=uartlevel + if uartlevel>1: + Settings.Pinout[8]["altfunc"] = 2 + Settings.Pinout[10]["altfunc"] = 2 + else: + if Settings.Pinout[8]["altfunc"]==2: + if self.serial==1: + Settings.Pinout[8]["altfunc"] = 1 + Settings.Pinout[10]["altfunc"] = 1 + else: + Settings.Pinout[8]["altfunc"] = 0 + Settings.Pinout[10]["altfunc"] = 0 + elif self.serial ==0: + Settings.Pinout[8]["altfunc"] = 0 + Settings.Pinout[10]["altfunc"] = 0 + else: + self.bluetooth=0 + + def is_audio_enabled(self): + return (self.audio==1) + + def is_internal_wifi_usable(self): + return self.internalwlan + + def set_wifi(self,status): + self.wifi = 0 + if self.is_internal_wifi_usable(): + if (status==1) or (status==True): + self.wifi = 1 + + def is_wifi_enabled(self): + return (self.wifi==1) + + def set_audio(self,status): + if (status==0) or (status==False): + self.audio = 0 + else: + self.audio = 1 + + def is_audio_enabled(self): + return (self.audio==1) + + def enable_pwm_pin(self,channel,pin,FirstRead=False): + if channel>=0 and channel<=1: + pid = 0 + for p in range(len(Settings.Pinout)): + if int(Settings.Pinout[p]["BCM"])==int(pin): + pid = p + break + pch = "PWM"+str(channel) + if (Settings.Pinout[pid]["altfunc"] == 0) and (pch in Settings.Pinout[pid]["name"][0]): + if self.pwm[channel] > 0 and pin != self.pwm[channel]: + for p in range(len(Settings.Pinout)): + if int(Settings.Pinout[p]["BCM"])==int(self.pwm[channel]) and int(Settings.Pinout[p]["startupstate"])==7: + Settings.Pinout[p]["startupstate"] = -1 + break + self.pwm[channel]=pin + Settings.Pinout[pid]["startupstate"] = 7 # set to H-PWM + if FirstRead: + Settings.Pinout[pid]["actualstate"]=Settings.Pinout[pid]["startupstate"] + try: + if channel==0: + self.pwmo[0]["o"] = syspwm.HPWM(0) + self.pwmo[0]["pin"] = pin + else: + self.pwmo[1]["o"] = syspwm.HPWM(1) + self.pwmo[1]["pin"] = pin + except Exception as e: + print("PWM error: ",e) + + def disable_pwm_pin(self,channel): + if channel>=0 and channel<=1: + if self.pwm[channel] > 0: + for p in range(len(Settings.Pinout)): + if int(Settings.Pinout[p]["BCM"])==int(self.pwm[channel]) and int(Settings.Pinout[p]["startupstate"])==7: + Settings.Pinout[p]["startupstate"] = -1 + break + self.pwm[channel]=0 + try: + if channel==0: + if self.pwmo[0]["o"]: + self.pwmo[0]["o"].stop() + else: + if self.pwmo[1]["o"]: + self.pwmo[1]["o"].stop() + except: + pass + + def output_pwm(self,bcmpin,pprop,pfreq=1000): # default 1000Hz + pin = int(bcmpin) + prop = int(pprop) + freq = int(pfreq) + if pin in self.pwm: # hardpwm + pid = 0 + if self.pwm[0] == pin: + pid = 0 + else: + pid = 1 + if prop<=0: + self.pwmo[pid]["o"].stop() + else: + self.pwmo[pid]["pin"]=pin + self.pwmo[pid]["o"].set_frequency(freq) + self.pwmo[pid]["o"].set_duty_prop(prop) + self.pwmo[pid]["o"].enable() + return True + else: # softpwm + pfound = False + for p in range(len(Settings.Pinout)): + if int(Settings.Pinout[p]["BCM"])==pin : + if (int(Settings.Pinout[p]["startupstate"]) not in [4,5,6]): + return False # if not output skip + + if len(self.pwmo)>2: + for p in range(2,len(self.pwmo)): + if int(self.pwmo[p]["pin"])==pin: + if (self.pwmo[p]["o"]): + if prop<=0: + self.pwmo[p]["o"].stop() + else: + self.pwmo[p]["o"].start(prop) + self.pwmo[p]["o"].ChangeFrequency(freq) + self.pwmo[p]["o"].ChangeDutyCycle(prop) + pfound = True + break + if pfound==False: + self.pwmo[p]["pin"] = pin + self.pwmo[p]["o"] = GPIO.PWM(pin,freq) + self.pwmo[p]["o"].start(prop) + return True + + def pwm_get_func(self,pin): + func = 0 + if pin==12 or pin==13: + func=4 + elif pin==18 or pin==19: + func=2 + return str(func) + + def is_i2s_usable(self): + result = False + if self.pinnum=="40": + result = True + return result + + def set_i2s(self,state): + if self.is_i2s_usable(): + if state==1 or state==True: + self.i2s=1 + if self.is_spi_enabled(1): + self.disable_spi(1) # collision resolving + Settings.Pinout[12]["altfunc"] = 2 + Settings.Pinout[35]["altfunc"] = 2 + Settings.Pinout[38]["altfunc"] = 2 + Settings.Pinout[40]["altfunc"] = 2 + else: + self.i2s=0 + if Settings.Pinout[12]["altfunc"]==2: + Settings.Pinout[12]["altfunc"] = 0 + Settings.Pinout[35]["altfunc"] = 0 + Settings.Pinout[38]["altfunc"] = 0 + Settings.Pinout[40]["altfunc"] = 0 + + def set1wgpio(self,bcmpin,FirstRead=False): + for b in range(len(Settings.Pinout)): + if str(Settings.Pinout[b]["BCM"])==str(bcmpin).strip(): + if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: + Settings.Pinout[b]["startupstate"] = 8 + if FirstRead: + Settings.Pinout[b]["actualstate"]=Settings.Pinout[b]["startupstate"] + break + + def setirgpio(self,bcmpin,FirstRead=False,mode=0): + for b in range(len(Settings.Pinout)): + if str(Settings.Pinout[b]["BCM"])==str(bcmpin).strip(): + if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: + pmode = (int(mode)+10) + if mode==2: + if ("PWM" not in Settings.Pinout[b]["name"][0]): + break + Settings.Pinout[b]["startupstate"] = pmode + if FirstRead: + Settings.Pinout[b]["actualstate"]=Settings.Pinout[b]["startupstate"] + break + + def setpinstartstate(self,bcmpin,state): + for b in range(len(Settings.Pinout)): + if str(Settings.Pinout[b]["BCM"])==str(bcmpin).strip(): + if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: + self.setpinstate(b,state,True) + break + + def setpinactualstate(self,pinid,state): + if Settings.Pinout[pinid]["actualstate"]==7: + bcmpin = int(Settings.Pinout[pinid]["BCM"]) + if bcmpin == self.pwm[0]: + self.disable_pwm_pin(0) + elif bcmpin == self.pwm[1]: + self.disable_pwm_pin(1) + if Settings.Pinout[pinid]["actualstate"]<7 and state<7: + Settings.Pinout[pinid]["actualstate"]=state + + def setpinstate(self,PINID,state,force=False): + if (force==False): + if Settings.Pinout[PINID]["altfunc"]>0 or Settings.Pinout[PINID]["canchange"]!=1 or Settings.Pinout[PINID]["BCM"]<0: + return False +# if (int(state)<=0 and int(Settings.Pinout[PINID]["startupstate"])>0): + if int(state)<=0: +# pass # revert to default input + Settings.Pinout[PINID]["startupstate"] = -1 + if self.gpioinit: + GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.IN) + self.setpinactualstate(PINID,99) # ugly hack + return True + elif state==1: + pass # input + Settings.Pinout[PINID]["startupstate"] = state + if self.gpioinit: + GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.IN) + self.setpinactualstate(PINID,1) + return True + elif state==2: + pass # input pulldown + Settings.Pinout[PINID]["startupstate"] = state + if self.gpioinit: + GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.IN, pull_up_down=GPIO.PUD_DOWN) + self.setpinactualstate(PINID,state) + return True + elif state==3: + pass # input pullup + Settings.Pinout[PINID]["startupstate"] = state + if self.gpioinit: + GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.IN, pull_up_down=GPIO.PUD_UP) + self.setpinactualstate(PINID,state) + return True + elif state==4 or state==5 or state==6: + if state==5: + if self.gpioinit: + GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.OUT, initial=GPIO.LOW) + elif state==6: + if self.gpioinit: + GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.OUT, initial=GPIO.HIGH) + else: + if self.gpioinit: + GPIO.setup(int(Settings.Pinout[PINID]["BCM"]), GPIO.OUT) + Settings.Pinout[PINID]["startupstate"] = state + self.setpinactualstate(PINID,4) + return True + elif state==7: + self.enable_pwm_pin(0,int(Settings.Pinout[PINID]["BCM"])) + if Settings.Pinout[PINID]["startupstate"] != 7: + self.enable_pwm_pin(1,int(Settings.Pinout[PINID]["BCM"])) + return True + elif state==8: + self.setpinactualstate(PINID,-1) + self.set1wgpio(int(Settings.Pinout[PINID]["BCM"])) + return True + elif state in [10,11,12]: + self.setpinactualstate(PINID,-1) + self.setirgpio(int(Settings.Pinout[PINID]["BCM"]),mode=(state-10)) + return True + return False + + def initpinstates(self): + if self.gpioinit: + for b in range(len(Settings.Pinout)): + if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1: + if int(Settings.Pinout[b]["BCM"])>=0: + if int(Settings.Pinout[b]["startupstate"])<7 and int(Settings.Pinout[b]["startupstate"])>=0: + self.setpinstate(b,Settings.Pinout[b]["startupstate"],True) + + def readconfig(self): + self.i2c_channels = [] # 0,1 + self.spi_channels = [] # 0,1 + self.spi_cs = [0,0] + self.set_serial(1) + self.i2s = 0 + if self.internalbt: + self.bluetooth = 2 + if self.internalwlan: + self.wifi = 1 + self.audio = 1 + self.pwm = [0,0] # 0.byte:pwm0 pin, 1.byte:pwm1 pin, no more +# read config.txt + try: + with open(self.config_file_name) as f: + for line in f: + line = line.strip() + if len(line)>0 and line[0] == "#": + line = "" + if self.CONFIG_ENABLE_I2C in line.lower(): + if self.is_i2c_usable(1): + self.enable_i2c(1) + else: + self.enable_i2c(0) + elif self.CONFIG_ENABLE_I2C0 in line.lower(): + self.enable_i2c(0) + elif self.CONFIG_ENABLE_I2C1 in line.lower(): + self.enable_i2c(1) + elif self.CONFIG_ENABLE_SPI0 in line.lower(): + self.enable_spi(0,2) + elif self.CONFIG_ENABLE_SPI1_1 in line.lower(): + self.enable_spi(1,1) + elif self.CONFIG_ENABLE_SPI1_2 in line.lower(): + self.enable_spi(1,2) + elif self.CONFIG_ENABLE_SPI1_3 in line.lower(): + self.enable_spi(1,3) + elif self.CONFIG_ENABLE_I2S in line.lower(): + self.set_i2s(1) + elif self.CONFIG_DISABLE_UART in line.lower(): + self.set_serial(0) + elif self.CONFIG_DISABLE_UART2 in line.lower(): + self.set_serial(0) + elif self.CONFIG_ENABLE_UART in line.lower(): + self.set_serial(1) + elif self.CONFIG_BT_SWUART in line.lower(): + self.set_internal_bt(1) + elif self.CONFIG_DISABLE_BT in line.lower(): + self.set_internal_bt(0) + elif self.CONFIG_DISABLE_WIFI in line.lower(): + self.wifi=0 + elif self.CONFIG_DISABLE_AUDIO in line.lower(): + self.audio=0 + elif self.CONFIG_ENABLE_RTC in line.lower(): + params = line.split(",") + if len(params)>1: + self.rtc=params[1].strip() + elif line.lower().startswith(self.CONFIG_GPUMEM): + params = line.split("=") + try: + self.gpumem=int(params[1].strip()) + except: + self.gpumem=self.gpumin + elif self.CONFIG_ONEWIRE in line.lower(): + pinfound = False + params = line.split(",") + for p in range(len(params)): + pin = 0 + if "gpiopin" in params[p]: + params2 = params[p].split('=') + try: + pin = int(params2[1].strip()) + pinfound = True + except: + pin = 0 + if pin!= 0: + self.set1wgpio(pin,True) + if pinfound==False: + self.set1wgpio(4,True) + elif self.CONFIG_IR in line.lower(): + pinfound = False + params = line.split(",") + for p in range(len(params)): + pin = 0 + if "gpio_pin" in params[p]: + params2 = params[p].split('=') + try: + pin = int(params2[1].strip()) + pinfound = True + except: + pin = 0 + if ("-tx" in line): + mode = 1 + else: + mode = 0 + if pin!= 0: + self.setirgpio(pin,True,mode) + if pinfound==False: + self.setirgpio(18,True,mode) + elif self.CONFIG_PWMIR in line.lower(): + pinfound = False + params = line.split(",") + for p in range(len(params)): + pin = 0 + if "gpio_pin" in params[p]: + params2 = params[p].split('=') + try: + pin = int(params2[1].strip()) + pinfound = True + except: + pin = 0 + if pin!= 0: + self.setirgpio(pin,True,2) + if pinfound==False: + self.setirgpio(18,True,2) + elif line.lower().startswith(self.CONFIG_GPIO): + params = line.split("=") + bcmpin = -1 + try: + bcmpin = int(params[1].strip()) + except: + bcmpin = -1 + if bcmpin != -1: + pstate = -1 + if "ip" in params[2]: + pstate = 1 + if "pd" in params[2]: + pstate = 2 + if "pu" in params[2]: + pstate = 3 + if "pn" in params[2] or "np" in params[2]: + pstate = 1 + if "op" in params[2]: + pstate = 4 + if "dl" in params[2]: + pstate = 5 + if "dh" in params[2]: + pstate = 6 + if pstate != -1: + self.setpinstartstate(bcmpin,pstate) + elif self.CONFIG_PWM0 in line.lower() or self.CONFIG_PWM0_1 in line.lower(): + params = line.split(",") + if self.CONFIG_PWM0_1 in line.lower(): + self.pwm = [18,19] + else: + self.pwm = [18,0] + try: + pwmi = 0 + for p in range(len(params)): + params2 = params[p].split("=") + if "pin" in params2[0].lower(): + self.enable_pwm_pin(pwmi,int(params2[1].strip()),True) + pwmi=pwmi+1 + except: + pass + self.enable_pwm_pin(0,self.pwm[0],True) + self.enable_pwm_pin(1,self.pwm[1],True) + except Exception as e: + print(e) + + if self.get_internal_bt_level()>1: + self.set_serial(0) + self.set_internal_bt(2) # uart collision resolving + if self.i2s==1: + self.set_i2s(1) + for b in range(len(Settings.Pinout)): + if Settings.Pinout[b]["altfunc"] != 0 and Settings.Pinout[b]["startupstate"]>0 and Settings.Pinout[b]["startupstate"]<9: + Settings.Pinout[b]["startupstate"] = -1 # set to default + + def saveconfig(self): + # save config.txt + contents = [] + use_ir = False + try: + with open(self.config_file_name) as f: + for line in f: + line = line.strip() + if len(line)>0 and line[0] == "#": + line = "" + if self.CONFIG_ENABLE_I2C in line.lower(): + line = "" + elif self.CONFIG_ENABLE_I2C0 in line.lower(): + line = "" + elif self.CONFIG_ENABLE_I2C1 in line.lower(): + line = "" + elif self.CONFIG_ENABLE_SPI0 in line.lower(): + line = "" + elif self.CONFIG_ENABLE_SPI1_1 in line.lower(): + line = "" + elif self.CONFIG_ENABLE_SPI1_2 in line.lower(): + line = "" + elif self.CONFIG_ENABLE_SPI1_3 in line.lower(): + line = "" + elif self.CONFIG_ENABLE_I2S in line.lower(): + line = "" + elif self.CONFIG_DISABLE_UART in line.lower(): + line = "" + elif self.CONFIG_DISABLE_UART2 in line.lower(): + line = "" + elif self.CONFIG_ENABLE_UART in line.lower(): + line = "" + elif self.CONFIG_BT_SWUART in line.lower(): + line = "" + elif self.CONFIG_DISABLE_BT in line.lower(): + line = "" + elif self.CONFIG_DISABLE_WIFI in line.lower(): + line = "" + elif self.CONFIG_DISABLE_AUDIO in line.lower() or self.CONFIG_ENABLE_AUDIO in line.lower(): + line = "" + elif self.CONFIG_PWM0 in line.lower(): + line = "" + elif self.CONFIG_ENABLE_RTC in line.lower(): + line = "" + elif self.CONFIG_PWM0_1 in line.lower(): + line = "" + elif self.CONFIG_ONEWIRE in line.lower(): + line = "" + elif self.CONFIG_IR in line.lower(): + line = "" + elif self.CONFIG_PWMIR in line.lower(): + line = "" + elif line.lower().startswith(self.CONFIG_GPIO): + line = "" + elif line.lower().startswith(self.CONFIG_GPUMEM): + line = "" + if line != "": + contents.append(line) + except: + pass + with open(self.config_file_name,"w") as f: + for c in range(len(contents)): + f.write(contents[c]+"\n") + if len(self.i2c_channels)>0: + f.write(self.CONFIG_ENABLE_I2C+"\n") + if self.is_i2c_enabled(1): + f.write(self.CONFIG_ENABLE_I2C1+"\n") + if self.is_i2c_enabled(0): + f.write(self.CONFIG_ENABLE_I2C0+"\n") + if self.is_spi_enabled(0): + f.write(self.CONFIG_ENABLE_SPI0+"\n") + if self.i2s==1: + f.write(self.CONFIG_ENABLE_I2S+"\n") + if self.is_spi_enabled(1): + if self.spi_cs[1] == 1: + f.write(self.CONFIG_ENABLE_SPI1_1+"\n") + elif self.spi_cs[1] == 2: + f.write(self.CONFIG_ENABLE_SPI1_2+"\n") + elif self.spi_cs[1] == 3: + f.write(self.CONFIG_ENABLE_SPI1_3+"\n") + if self.is_serial_enabled()==False: + f.write(self.CONFIG_DISABLE_UART+"\n") + else: + f.write(self.CONFIG_ENABLE_UART+"\n") + if self.is_internal_bt_usable(): + if self.get_internal_bt_level()==1: + f.write(self.CONFIG_BT_SWUART+"\n") + elif self.get_internal_bt_level()==0: + f.write(self.CONFIG_DISABLE_BT+"\n") + if self.is_internal_wifi_usable(): + if self.is_wifi_enabled()==False: + f.write(self.CONFIG_DISABLE_WIFI+"\n") + if self.rtc!="": + f.write(self.CONFIG_ENABLE_RTC+self.rtc+"\n") + if self.is_audio_enabled(): + f.write(self.CONFIG_ENABLE_AUDIO+"\n") + else: + f.write(self.CONFIG_DISABLE_AUDIO+"\n") + f.write(self.CONFIG_GPUMEM+"="+str(self.gpumem)+"\n") + line = "" + if sum(self.pwm)>0: + if self.pwm[0] != 0: + ppin = self.pwm[0] + else: + ppin = self.pwm[1] + if self.pwm[0] > 0 and self.pwm[1] > 0: + line += self.CONFIG_PWM0_1+",pin="+str(self.pwm[0])+",func="+self.pwm_get_func(self.pwm[0])+",pin2="+str(self.pwm[1])+",func2="+self.pwm_get_func(self.pwm[1]) + else: + line += self.CONFIG_PWM0+",pin="+str(ppin)+",func="+self.pwm_get_func(ppin) + if line != "": + f.write(line+"\n") + for b in range(len(Settings.Pinout)): + if Settings.Pinout[b]["altfunc"] == 0 and Settings.Pinout[b]["canchange"]==1 and Settings.Pinout[b]["startupstate"]>0 and Settings.Pinout[b]["startupstate"]=0x30 and device<=0x37) or (device>=0x50 and device<=0x5f): + bus.read_byte(device) + else: + bus.write_quick(device) + devices.append(device) # hex(number)? + except: + pass + if (0x5c not in devices): # 0x5c has to be checked twice as Am2320 auto-shutdown itself? + try: + bus.read_byte(0x5c) + devices.append(0x5c) + except: + pass + if (0x7f not in devices): # 0x7f is non-standard used by PME + try: + bus.read_byte(0x7f) + devices.append(0x7f) + except: + pass + + try: + bus.close() + except: + pass + bus = None + return devices + + def createpinout(self,pinout): + global PINOUT40, PINOUT26R1_DELTA, PINOUT26R2_DELTA + if pinout == "40" and len(Settings.Pinout)!=41: + Settings.Pinout=PINOUT40 + elif pinout == "26R1" and len(Settings.Pinout)!=27: + for p in range(27): + Settings.Pinout.append(PINOUT40[p]) + for p in range(len(PINOUT26R1_DELTA)): + pi = int(PINOUT26R1_DELTA[p]["ID"]) + Settings.Pinout[pi] = PINOUT26R1_DELTA[p] + elif pinout == "26R2" and len(Settings.Pinout)!=27: + for p in range(27): + Settings.Pinout.append(PINOUT40[p]) + for p in range(len(PINOUT26R2_DELTA)): + pi = int(PINOUT26R2_DELTA[p]["ID"]) + Settings.Pinout[pi] = PINOUT26R2_DELTA[p] + +#Init Hardware GLOBAL ports +#HWPorts = hwports() +#if os.path.exists("/DietPi/config.txt"): # DietPi FIX! +# HWPorts.config_file_name = "/DietPi/config.txt" diff --git a/linux_os.py b/linux_os.py index 1edbbff..6214ba0 100644 --- a/linux_os.py +++ b/linux_os.py @@ -66,7 +66,7 @@ def saveconfig(self): f.write(self.ENABLE_RPIAUTOSTART+"\n") else: f.write(self.ENABLE_RPIAUTOSTART2+"\n") - if self.hdmienabled == False: + if self.hdmienabled == False and rpieGlobals.ossubtype==10: f.write(self.DISABLE_HDMI+"\n") f.write(self.RC_ENDMARKER+"\n") except: @@ -191,7 +191,7 @@ def gethardware(): return rs.strip() def is_package_installed(pkgname): - if rpieGlobals.ossubtype in [1,10]: + if rpieGlobals.ossubtype in [1,3,10]: output = os.popen('dpkg -s {}'.format(pkgname) +' 2>/dev/null').read() match = re.search(r'Status: (\w+.)*', output) if match and 'installed' in match.group(0).lower(): @@ -673,7 +673,10 @@ def checkOPI(): def getarmbianinfo(): hwarr = { "name": "Unknown model", - "pins": "" + "shortname":"unknown", + "version":"0.0", + "pinout":"", + "pins": "0" } try: with open('/etc/armbian-release') as f: @@ -682,8 +685,39 @@ def getarmbianinfo(): if line.startswith('BOARD_NAME'): pname = line.split('"') hwarr["name"] = pname[1] + if line.startswith('BOARD='): + pname = line.split('=') + hwarr["shortname"] = pname[1] + if line.startswith('VERSION='): + pname = line.split('=') + hwarr["version"] = pname[1] except: pass + if "orangepi" in hwarr["shortname"]: + if "zeroplus2" in hwarr["shortname"]: + hwarr["pinout"] = "zeroplus2" + hwarr["pins"] = "26z+2" + elif ("zeroplus" in hwarr["shortname"]) or ("pizero" in hwarr["shortname"]) or ("r1" in hwarr["shortname"]): + hwarr["pinout"] = "zeroplus" + hwarr["pins"] = "26z+" + elif "pi3" in hwarr["shortname"]: + hwarr["pinout"] = "pi3" + hwarr["pins"] = "26pi3" + elif ("oneplus" in hwarr["shortname"]) or ("pilite2" in hwarr["shortname"]): + hwarr["pinout"] = "oneplus" + hwarr["pins"] = "26o+" + elif "winplus" in hwarr["shortname"]: + hwarr["pinout"] = "winplus" + hwarr["pins"] = "40w+" + elif "prime" in hwarr["shortname"]: + hwarr["pinout"] = "prime" + hwarr["pins"] = "40pr" + elif "pc2" in hwarr["shortname"]: + hwarr["pinout"] = "pc2" + hwarr["pins"] = "40pc2" + elif ("pipc" in hwarr["shortname"]) or ("pilite" in hwarr["shortname"]) or ("pione" in hwarr["shortname"]) or ("piplus2" in hwarr["shortname"]): + hwarr["pinout"] = "pc" + hwarr["pins"] = "40pc" return hwarr soundmixer = "" @@ -701,7 +735,7 @@ def getsoundmixer(): cc = 1 return soundmixer except Exception as e: - print(e) + print("Sound mixer error:",e) return soundmixer def getvolume(): # volume in percentage @@ -714,8 +748,8 @@ def getvolume(): # volume in percentage lc = line2.split("%") vol = str(lc[1]).strip() return vol - except: - pass + except Exception as e: + print("GetVolume:",e) return vol def setvolume(volume): # volume in percentage @@ -728,3 +762,18 @@ def setvolume(volume): # volume in percentage pass except: pass + +def detectNM(): + nm = False + nmpath = "/etc/NetworkManager/NetworkManager.conf" + if os.path.exists(nmpath): + try: + with open(nmpath) as f: + for line in f: + line = line.strip().lower() + if line.startswith("managed"): + if "true" in line: + nm = True + except: + pass + return nm diff --git a/plugindeps.py b/plugindeps.py index 22affcc..002220f 100644 --- a/plugindeps.py +++ b/plugindeps.py @@ -36,11 +36,6 @@ "apt": ["python3-smbus","i2c-tools"], "testcmd":"import smbus", "installed":-1}, -{"name":"DHT", - "apt": ["python3-pip","python3-setuptools"], - "pip": ["Adafruit_DHT"], - "testcmd": "import Adafruit_DHT\ntest=Adafruit_DHT.DHT22", - "installed":-1}, {"name":"apds", "apt": ["python3-pip","python3-setuptools"], "pip": ["apds9960"], @@ -272,16 +267,16 @@ plugindependencies = [ {"pluginid": "1", #Switch - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["GPIO"]}, {"pluginid": "2", #PiAnalog - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["GPIO"]}, {"pluginid": "3", #Pulse - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["GPIO"]}, {"pluginid": "4", #DS18b20 - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["linux-kernel"]}, {"pluginid": "5", # DHT "supported_os_level": [10], @@ -290,145 +285,145 @@ "supported_os_level": [10], "modules":["GPIO","wpi","wiegand_io2"]}, {"pluginid": "7", # PCF8591 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "9", # MCP - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["GPIO","i2c","MCP"]}, {"pluginid": "10", # BH1750 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "11", # PME - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "12", # LCD "supported_os_level": [10], "modules":["i2c","LCD"]}, {"pluginid": "13", #SR04 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["GPIO"]}, {"pluginid": "14", # Si7021 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "15", # tsl2561 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "16", #IR "supported_os_level": [1,2,10], "modules":["irkey"]}, {"pluginid": "17", # PN532 - "supported_os_level": [10], + "supported_os_level": [10], #rpigpio "modules":["GPIO","i2c"]}, {"pluginid": "19", # PCF8574 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["GPIO","i2c"]}, {"pluginid": "22", # PCA9685 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["GPIO","i2c","pca9685"]}, {"pluginid": "23", # OLED - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c","OLED"]}, {"pluginid": "24", # mlx90614 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "25", # ADS1x15 "supported_os_level": [10], "modules":["i2c","Adafruit_ADS1x15"]}, {"pluginid": "26", #SysInfo - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["linux-kernel"]}, {"pluginid": "27", # INA219 "supported_os_level": [10], "modules":["i2c","ina219"]}, {"pluginid": "28", # BMP280 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "29", # DomoOutput nem csak gpio?? - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["GPIO"]}, {"pluginid": "35", #IRTrans "supported_os_level": [1,2,10], "modules":["irkey"]}, {"pluginid": "36", # FramedOLED - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c","OLED"]}, {"pluginid": "38", # Neopixel "supported_os_level": [10], "modules":["GPIO","ws2812"]}, {"pluginid": "45", # MPU6050 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c","mpu6050"]}, {"pluginid": "49", #MH-Z19 - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["pyserial"]}, {"pluginid": "51", # AM2320 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "57", # HT16K33 LED - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "58", # HT16K33 Key - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "59", #Rotary - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["GPIO"]}, {"pluginid": "62", # MPR121 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["GPIO","i2c"]}, {"pluginid": "64", # APDS9960 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c","apds"]}, {"pluginid": "69", # LM75 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "73", # 7DGT "supported_os_level": [10], "modules":["wpi","tm1637"]}, {"pluginid": "82", #GPS - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["pyserial"]}, {"pluginid": "111", #RF433 receiver "supported_os_level": [10], "modules":["GPIO","wpi","rcswitch"]}, {"pluginid": "112", #RF433 sender "supported_os_level": [10], - "modules":["GPIO","rcswitch"]}, + "modules":["GPIO","wpi","rcswitch"]}, {"pluginid": "126", #Ping - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["ping"]}, {"pluginid": "133", # VL53L0X - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "153", # MAX44009 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "200", #Dual Switch - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["GPIO"]}, {"pluginid": "201", #Generic Serial - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["pyserial"]}, {"pluginid": "202", # MCP9808 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "203", # MCP4725 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c"]}, {"pluginid": "204", #Stepper motor - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["GPIO"]}, {"pluginid": "205", #E-paper SPI "supported_os_level": [10], "modules":["epd"]}, {"pluginid": "206", #PZEM016 - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["pyserial","modbus"]}, {"pluginid": "207", # MPU9250 - "supported_os_level": [10], + "supported_os_level": [3,10], "modules":["i2c","rtimu"]}, {"pluginid": "208", #PFM - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["pyserial","pfm","pil"]}, {"pluginid": "209", # AMG "supported_os_level": [10], @@ -436,19 +431,19 @@ {"pluginid": "501", # USB relay "modules":["hidapi"]}, {"pluginid": "502", # pygame play wav/mp3 - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["pygame"]}, {"pluginid": "503", # pygame play wav/mp3 - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["pygame"]}, {"pluginid": "505", # vlc radio play - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["vlc"]}, {"pluginid": "506", # pocketsphinx - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["pocketsphinx"]}, {"pluginid": "508", #Temper - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["pyserial","linux-kernel"]}, {"pluginid": "509", # EVDEV "modules":["linux-kernel"]}, @@ -459,7 +454,7 @@ {"pluginid": "513", # BLE LYWSD02 "modules":["lywsd"]}, {"pluginid": "514", # USB-Dallas - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["pyserial","pydigitemp"]}, {"pluginid": "515", # BLE MiFlora "modules":["bluepy"]}, @@ -470,12 +465,12 @@ {"pluginid": "518", # BLE CGG1 "modules":["bluepy"]}, {"pluginid": "519", #Volume - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["linux-kernel"]}, {"pluginid": "520", # BLE Scan "modules":["bluepy"]}, {"pluginid": "521", # GoogleTTS - "supported_os_level": [1,2,10], + "supported_os_level": [1,2,3,10], "modules":["gtts","pygame"]}, ] @@ -525,7 +520,7 @@ def installdeps2(modulename): if "python3-pip" in modulelist[i]["apt"][j]: modulelist[i]["apt"][j].replace("python3-pip","python-pip") installprog += modulelist[i]["apt"][j] + " " - if rpieGlobals.ossubtype in [1,10]: + if rpieGlobals.ossubtype in [1,3,10]: installprog = OS.cmdline_rootcorrect("sudo apt-get update && sudo apt-get install -y "+ installprog.strip()) elif rpieGlobals.ossubtype==2: installprog = OS.cmdline_rootcorrect("yes | sudo pacman -S "+ installprog.strip()) diff --git a/rpieGlobals.py b/rpieGlobals.py index 1a820f3..227c3dc 100644 --- a/rpieGlobals.py +++ b/rpieGlobals.py @@ -6,7 +6,7 @@ # Copyright (C) 2018-2020 by Alexander Nagy - https://bitekmindenhol.blog.hu/ # PROGNAME = "RPIEasy" -BUILD = 20105 +BUILD = 20106 PROGVER = str(BUILD)[:1]+"."+str(BUILD)[1:2]+"."+str(BUILD)[2:] gpMenu = [] diff --git a/webserver.py b/webserver.py index 72910e6..580c781 100644 --- a/webserver.py +++ b/webserver.py @@ -369,13 +369,16 @@ def handle_config(self): TXBuffer += "" addSubmitButton() - + netmanager = OS.detectNM() oslvl = misc.getsupportlevel(1) if oslvl in [1,2,3,10]: # maintain supported system list!!! addFormSeparator(2) if oslvl != 2: - addFormCheckBox("I have root rights and i really want to manage network settings below","netman", netmanage) - addFormNote("If not enabled, OS config files will not be overwritten!") + if netmanager: + addFormNote("NetworkManager is currently not supported!") + else: + addFormCheckBox("I have root rights and i really want to manage network settings below","netman", netmanage) + addFormNote("If this checkbox not enabled, OS config files will not be overwritten!") addFormSubHeader("Wifi Settings") #/etc/wpa_supplicant/wpa_supplicant.conf addFormTextBox( "SSID", "ssid", Settings.NetMan.WifiSSID, 32) @@ -461,7 +464,8 @@ def handle_config(self): addFormNote("If DHCP enabled these fields will not be saved or used!") TXBuffer += "" - addSubmitButton() + if netmanager==False: + addSubmitButton() TXBuffer += "" sendHeadandTail("TmplStd",_TAIL); @@ -709,18 +713,21 @@ def handle_hardware(self): rstr = ""+rstr+" (system-wide settings are only for root)" TXBuffer += "Root access:"+rstr TXBuffer += "Sound playback device:" - sounddevs = OS.getsounddevs() - defaultdev = OS.getsoundsel() + try: + sounddevs = OS.getsounddevs() + defaultdev = OS.getsoundsel() + except Exception as e: + print("Sound device:",e) if len(sounddevs)>0: addSelector_Head('snddev',False) - for i in range(0,len(sounddevs)): + for i in range(0,len(sounddevs)): addSelector_Item(sounddevs[i][1],int(sounddevs[i][0]),(int(sounddevs[i][0])==int(defaultdev)),False) addSelector_Foot() vol = 100 try: vol = OS.getvolume() except Exception as e: - print(e) + print("GetVolume:",e) TXBuffer += 'Sound volume:' else: TXBuffer += "No device" @@ -785,6 +792,13 @@ def handle_pinout(self): except Exception as e: misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,"Config read error="+str(e)) + if ((rpieGlobals.ossubtype!=10) and (submit=="Submit") or (setbtn!='')): + try: + gpios.HWPorts.webform_save(responsearr) + except Exception as e: + print(e) + submit="" + setbtn="" if (submit=="Submit") or (setbtn!=''): try: stat = arg("i2c0",responsearr) @@ -889,7 +903,7 @@ def handle_pinout(self): except Exception as e: misc.addLog(rpieGlobals.LOG_LEVEL_ERROR,str(e)) - if (len(Settings.Pinout)>1): + if ((rpieGlobals.ossubtype==10) and (len(Settings.Pinout)>1)): # RPI only TXBuffer += "
" TXBuffer += "" addHtml("") @@ -1029,7 +1043,11 @@ def handle_pinout(self): addFormNote("WARNING: Some changes needed to reboot after submitting changes! And most changes requires root permission.") addHtml("
GPIO pinout
Detected functionRequested functionPin name#ValueValue#Pin nameRequested functionDetected function
") else: - addHtml('This hardware is currently not supported!') + try: + gpios.HWPorts.webform_load() + except Exception as e: + addHtml("

This hardware has unknown GPIO.") + misc.addLog(rpieGlobals.LOG_LEVEL_ERROR, str(e)) sendHeadandTail("TmplStd",_TAIL) return TXBuffer @@ -2017,13 +2035,14 @@ def handle_i2cscanner(self): i2cenabled = 0 i2cdevs = 0 for i in range(0,2): + try: if gpios.HWPorts.is_i2c_usable(i) and gpios.HWPorts.is_i2c_enabled(i): i2cenabled += 1 addFormSubHeader("I2C-"+str(i)) TXBuffer += "" - i2cl = gpios.is_i2c_lib_available() + i2cl = gpios.HWPorts.is_i2c_lib_available() if i2cl: - i2ca = gpios.i2cscan(i) + i2ca = gpios.HWPorts.i2cscan(i) for d in range(len(i2ca)): i2cdevs += 1 TXBuffer += ""+str(hex(i2ca[d]))+"" @@ -2031,6 +2050,8 @@ def handle_i2cscanner(self): TXBuffer += "" else: TXBuffer += "I2C supporting SMBus library not found. Please install smbus." + except Exception as e: + print(e) # debug if i2cenabled==0: TXBuffer += "Usable I2C bus not found" elif i2cdevs==0: @@ -3643,7 +3664,7 @@ def handle_update(self): t.daemon = True t.start() elif updmode == "aptupgrade": - print("apt upgrade")#debug +# print("apt upgrade")#debug t = threading.Thread(target=Updater.upgrade_apt) t.daemon = True t.start()