| Norman James | 6bbe0b5 | 2015-10-27 09:18:05 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python | 
 | 2 |  | 
 | 3 | import sys | 
 | 4 | import os | 
 | 5 | import getopt | 
| Adriana Kobylak | 7e48038 | 2018-09-24 11:01:42 -0500 | [diff] [blame] | 6 | from glob import glob | 
 | 7 | from os.path import join | 
| Brad Bishop | 0b380f7 | 2016-06-10 00:29:50 -0400 | [diff] [blame] | 8 | import obmc_system_config as System | 
| Norman James | 6bbe0b5 | 2015-10-27 09:18:05 -0500 | [diff] [blame] | 9 |  | 
 | 10 |  | 
 | 11 | def printUsage(): | 
 | 12 | 	print '\nUsage:' | 
| Brad Bishop | 0b380f7 | 2016-06-10 00:29:50 -0400 | [diff] [blame] | 13 | 	print 'gpioutil -n GPIO_NAME  [-v value]' | 
 | 14 | 	print 'gpioutil -i GPIO_NUM  -d <DIRECTION = in,out,falling,rising,both> [-v value]' | 
 | 15 | 	print 'gpioutil -p PIN_NAME  -d <DIRECTION = in,out,falling,rising,both> [-v value]' | 
 | 16 | 	print 'gpioutil -l PIN_NAME     (lookup pin name only)' | 
| Norman James | 6bbe0b5 | 2015-10-27 09:18:05 -0500 | [diff] [blame] | 17 | 	exit(1) | 
 | 18 |  | 
 | 19 |  | 
 | 20 |  | 
| Brad Bishop | 0b380f7 | 2016-06-10 00:29:50 -0400 | [diff] [blame] | 21 | if (len(sys.argv) < 2): | 
| Norman James | 6bbe0b5 | 2015-10-27 09:18:05 -0500 | [diff] [blame] | 22 | 	printUsage() | 
 | 23 |  | 
| Adriana Kobylak | ff47af2 | 2016-06-16 09:27:37 -0500 | [diff] [blame] | 24 | # Pop the command name and point to the args | 
 | 25 | sys.argv.pop(0) | 
 | 26 |  | 
| Norman James | 6bbe0b5 | 2015-10-27 09:18:05 -0500 | [diff] [blame] | 27 | GPIO_SYSFS = '/sys/class/gpio/' | 
 | 28 |  | 
| Adriana Kobylak | 7e48038 | 2018-09-24 11:01:42 -0500 | [diff] [blame] | 29 |  | 
 | 30 | def find_gpio_base(path="/sys/class/gpio/"): | 
 | 31 | 	pattern = "gpiochip*" | 
 | 32 | 	for gc in glob(join(path, pattern)): | 
 | 33 | 		with open(join(gc, "label")) as f: | 
 | 34 | 			label = f.readline().strip() | 
 | 35 | 		if label == "1e780000.gpio": | 
 | 36 | 			with open(join(gc, "base")) as f: | 
 | 37 | 				return int(f.readline().strip()) | 
 | 38 | 	# trigger a file not found exception | 
 | 39 | 	open(join(path, "gpiochip")) | 
 | 40 |  | 
 | 41 |  | 
 | 42 | GPIO_BASE = find_gpio_base() | 
 | 43 |  | 
 | 44 |  | 
 | 45 | def convertGpio(name): | 
 | 46 | 	offset = int(''.join(list(filter(str.isdigit, name)))) | 
 | 47 | 	port = list(filter(str.isalpha, name.upper())) | 
 | 48 | 	a = ord(port[-1]) - ord('A') | 
 | 49 | 	if len(port) > 1: | 
 | 50 | 		a += 26 | 
 | 51 | 	base = a * 8 + GPIO_BASE | 
 | 52 | 	return base + offset | 
 | 53 |  | 
 | 54 |  | 
| Norman James | 6bbe0b5 | 2015-10-27 09:18:05 -0500 | [diff] [blame] | 55 | class Gpio: | 
 | 56 | 	def __init__(self,gpio_num): | 
 | 57 | 		self.gpio_num = str(gpio_num) | 
 | 58 | 		self.direction = '' | 
 | 59 | 		self.interrupt = '' | 
 | 60 | 		self.exported = False | 
 | 61 |  | 
 | 62 | 	def getPath(self,name): | 
 | 63 | 		return GPIO_SYSFS+'gpio'+self.gpio_num+'/'+name | 
 | 64 | 	 | 
 | 65 | 	def export(self): | 
 | 66 | 		if (os.path.exists(GPIO_SYSFS+'export') == False): | 
 | 67 | 			raise Exception("ERROR - GPIO_SYSFS path does not exist.  Does this platform support GPIOS?") | 
 | 68 | 		if (os.path.exists(GPIO_SYSFS+'gpio'+self.gpio_num) == False): | 
 | 69 | 			self.write(GPIO_SYSFS+'export',self.gpio_num) | 
 | 70 | 			 | 
 | 71 | 		self.exported = True | 
 | 72 |  | 
 | 73 | 	def setDirection(self,dir): | 
 | 74 | 		if (self.exported == False): | 
 | 75 | 			raise Exception("ERROR - Not exported: "+self.getPath()) | 
 | 76 |  | 
 | 77 | 		self.direction = '' | 
 | 78 | 		self.interrupt = '' | 
 | 79 | 		if (dir == 'in' or dir == 'out'): | 
 | 80 | 			self.direction = dir | 
 | 81 | 		elif (dir == 'rising' or  | 
 | 82 | 		      dir == 'falling' or | 
 | 83 | 		      dir == 'both'): | 
 | 84 | 			self.direction = 'in' | 
 | 85 | 			self.interrupt = dir | 
 | 86 | 			self.write(self.getPath('edge'),self.interrupt) | 
 | 87 | 		else: | 
 | 88 | 			raise Exception("ERROR - Invalid Direction: "+dir) | 
| Xo Wang | 5d4a54e | 2016-12-02 10:26:15 -0800 | [diff] [blame] | 89 |  | 
 | 90 | 		current_direction = self.read(self.getPath('direction')) | 
 | 91 | 		if current_direction != self.direction: | 
 | 92 | 			self.write(self.getPath('direction'),self.direction) | 
 | 93 |  | 
| Norman James | 6bbe0b5 | 2015-10-27 09:18:05 -0500 | [diff] [blame] | 94 | 	def setValue(self,value): | 
 | 95 | 		if (value == '0'): | 
 | 96 | 			self.write(self.getPath('value'),'0') | 
 | 97 | 		elif (value == '1'): | 
 | 98 | 			self.write(self.getPath('value'),'1') | 
 | 99 | 		else: | 
 | 100 | 			raise Exception("ERROR - Invalid value: "+value) | 
 | 101 | 	 | 
 | 102 | 	def getValue(self): | 
| Xo Wang | 3045be3 | 2016-12-02 10:47:43 -0800 | [diff] [blame] | 103 | 		return self.read(self.getPath('value')) | 
| Norman James | 6bbe0b5 | 2015-10-27 09:18:05 -0500 | [diff] [blame] | 104 |  | 
 | 105 | 	def write(self,path,data): | 
 | 106 | 		f = open(path,'w') | 
 | 107 | 		f.write(data) | 
 | 108 | 		f.close() | 
 | 109 |  | 
 | 110 |  | 
 | 111 | 	def read(self,path): | 
 | 112 | 		f = open(path,'r') | 
| Xo Wang | 3045be3 | 2016-12-02 10:47:43 -0800 | [diff] [blame] | 113 | 		data = f.readline().strip() | 
| Norman James | 6bbe0b5 | 2015-10-27 09:18:05 -0500 | [diff] [blame] | 114 | 		f.close() | 
 | 115 | 		return data | 
 | 116 |  | 
 | 117 |  | 
 | 118 |  | 
 | 119 | if __name__ == '__main__': | 
 | 120 |  | 
 | 121 | 	try: | 
 | 122 | 		opts, args = getopt.getopt(sys.argv,"hn:i:d:v:p:l:") | 
 | 123 |  	except getopt.GetoptError: | 
 | 124 |  		printUsage() | 
 | 125 |  | 
 | 126 |  | 
 | 127 |  | 
 | 128 | 	lookup = False | 
 | 129 | 	gpio_name = "" | 
 | 130 | 	value = "" | 
 | 131 | 	direction = "" | 
 | 132 | 	for opt, arg in opts: | 
 | 133 |  		if opt == '-h': | 
 | 134 | 			printUsage() | 
 | 135 |  | 
 | 136 |  		elif opt in ("-n"): | 
 | 137 |  			gpio_name = arg | 
 | 138 | 			lookup = True | 
 | 139 |  		elif opt in ("-i"): | 
 | 140 |  			gpio_name = arg | 
 | 141 |  		elif opt in ("-d"): | 
 | 142 | 			direction = arg | 
 | 143 |  		elif opt in ("-v"): | 
 | 144 | 			value = arg | 
 | 145 | 		elif opt in ("-p"): | 
| Adriana Kobylak | 7e48038 | 2018-09-24 11:01:42 -0500 | [diff] [blame] | 146 | 			gpio_name = convertGpio(arg) | 
| Norman James | 6bbe0b5 | 2015-10-27 09:18:05 -0500 | [diff] [blame] | 147 | 		elif opt in ("-l"): | 
| Adriana Kobylak | 7e48038 | 2018-09-24 11:01:42 -0500 | [diff] [blame] | 148 | 			gpio_name = convertGpio(arg) | 
| Norman James | 6bbe0b5 | 2015-10-27 09:18:05 -0500 | [diff] [blame] | 149 | 			print gpio_name | 
 | 150 | 			exit(0)  | 
 | 151 |  | 
 | 152 | 	gpio_info = {} | 
 | 153 | 	if (lookup == True): | 
 | 154 | 		if (System.GPIO_CONFIG.has_key(gpio_name) == False): | 
 | 155 | 			print "ERROR - GPIO Name doesn't exist" | 
 | 156 | 			print "Valid names: " | 
 | 157 | 			for n in System.GPIO_CONFIG: | 
 | 158 | 				print "\t"+n | 
 | 159 | 			exit(0) | 
 | 160 | 		gpio_info = System.GPIO_CONFIG[gpio_name] | 
 | 161 | 		direction = gpio_info['direction'] | 
| Norman James | 0db7297 | 2015-10-28 13:07:04 -0500 | [diff] [blame] | 162 | 		if (gpio_info.has_key('gpio_num')): | 
 | 163 | 			gpio_name = str(gpio_info['gpio_num']) | 
 | 164 | 		else: | 
| Adriana Kobylak | 7e48038 | 2018-09-24 11:01:42 -0500 | [diff] [blame] | 165 | 			gpio_name = str(convertGpio(gpio_info['gpio_pin'])) | 
| Norman James | 6bbe0b5 | 2015-10-27 09:18:05 -0500 | [diff] [blame] | 166 | 		print "GPIO ID: "+gpio_name+"; DIRECTION: "+direction | 
 | 167 |  | 
 | 168 |  | 
 | 169 | 	## Rules | 
 | 170 | 	if (gpio_name == ""): | 
 | 171 | 		print "ERROR - Gpio not specified" | 
 | 172 | 		printUsage() | 
 | 173 |  | 
 | 174 | 	if (direction == "in" and value != ""): | 
 | 175 | 		print "ERROR - Value cannot be specified when direction = in" | 
 | 176 | 		printUsage() | 
 | 177 |  | 
 | 178 | 	gpio = Gpio(gpio_name) | 
 | 179 | 	try: | 
 | 180 | 		gpio.export() | 
 | 181 | 		if (direction != ""): | 
 | 182 | 			gpio.setDirection(direction) | 
 | 183 |  | 
 | 184 | 		if (value == ""): | 
 | 185 | 			print gpio.getValue() | 
 | 186 | 		else: | 
 | 187 | 			gpio.setValue(value) | 
 | 188 |  | 
 | 189 | 	except Exception as e: | 
 | 190 | 		print e | 
 | 191 | 		 |