# THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
# APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
# HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
# OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
# IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
# ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

# IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
# WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
# THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
# GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
# USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
# DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
# PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
# EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGES.

# Copyright (c) 2018 Dr. Oliver Barth <info@drb-electronic.de>
# driver for RPI GPIO

import RPi.GPIO as GPIO
from threading import Lock

DIN = [4, 17, 27, 22, 5, 6, 13, 19]
DOUT = [18, 23, 24, 25, 12, 16, 20, 21]

DigitalIO_keywords = ['self.dio.setOutput(channel,on)', 'self.dio.getInput(n)', 'self.dio.getInputs()']

#
class DigitalIO():
	def __init__(self):
		print "GPIO revision:", GPIO.RPI_REVISION
		print "GPIO version:", GPIO.VERSION
		GPIO.setmode(GPIO.BCM) # set board mode to Broadcom
		for i in range (0, 8):
			GPIO.setup(DIN[i], GPIO.IN)
			GPIO.setup(DOUT[i], GPIO.OUT)
		GPIO.setup(26, GPIO.IN)
		self.inByte = 0x00
		self.din = [False, False, False, False, False, False, False, False]
		self.mutex = Lock()

	#
	# sets a single digital output
	#
	def setOutput(self, channel, on):
		GPIO.output(DOUT[channel], on)

	#
	def update(self):
		self.mutex.acquire()
		self.inByte = 0x00
		self.din = [False, False, False, False, False, False, False, False]
		for i in range(0, 8):
			if (GPIO.input(DIN[i]) == GPIO.HIGH):
				self.din[i] = True
				self.inByte |= 1 << i
		self.mutex.release()

	#
	# return single digital input as bool
	#
	def getInput(self, n):
		self.mutex.acquire()
		ret = self.din[n] 
		self.mutex.release()
		return ret

	#
	# return all digital inputs as bool array
	#
	def getInputs(self):
		self.mutex.acquire()
		ret = self.din
		self.mutex.release()
		return ret

	#
	# return digital input as byte
	#
	def getInputAsByte(self):
		self.mutex.acquire()
		ret = self.inByte 
		self.mutex.release()
		return ret

	#
	def close(self):
		GPIO.cleanup()
