def test_exported_line(self): with gpiod.Chip(mockup.chip_path(0)) as chip: line = chip.get_line(4) line.request(consumer=default_consumer, type=gpiod.LINE_REQ_DIR_OUT, flags=gpiod.LINE_REQ_FLAG_ACTIVE_LOW) self.assertEqual(line.offset(), 4) self.assertEqual(line.name(), 'gpio-mockup-A-4') self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) self.assertTrue(line.is_active_low()) self.assertEqual(line.consumer(), default_consumer) self.assertTrue(line.is_used()) self.assertTrue(line.is_requested())
def chip_init(): # Validate the existence of a gpio character device validate_gpio_dev_exists() # This is hardcoded for now but that may change soon (or not) try: _State.chip = gpiod.Chip("gpiochip0") except PermissionError: print( "Unable to access /dev/gpiochip0. Are you sure you have permission?" ) sys.exit() Dprint("state chip has value:", _State.chip)
def line_event_single_line(): chip = gpiod.Chip('gpiochip0') line = chip.get_line(1) print('requesting line for events') line.request(consumer=sys.argv[0], type=gpiod.LINE_REQ_EV_BOTH_EDGES) print('generating a line event') fire_line_event('gpiochip0', 1, True) assert line.event_wait(sec=1), 'Expected a line event to occur' print('event received') event = line.event_read() print_event(event)
def prepare(self) -> None: assert self.__reader is None self.__reader = aiogp.AioReader( path=env.GPIO_DEVICE_PATH, consumer="kvmd::ugpio-gpio::inputs", pins=self.__input_pins, notifier=self._notifier, ) self.__chip = gpiod.Chip(env.GPIO_DEVICE_PATH) for (pin, initial) in self.__output_pins.items(): line = self.__chip.get_line(pin) line.request("kvmd::ugpio-gpio::outputs", gpiod.LINE_REQ_DIR_OUT, default_vals=[int(initial or False)]) self.__output_lines[pin] = line
def set_value_single_line(): chip = gpiod.Chip('gpiochip0') line = chip.get_line(3) line.request(consumer=sys.argv[0], type=gpiod.LINE_REQ_DIR_IN) print('line value before: {}'.format(line.get_value())) line.release() line.request(consumer=sys.argv[0], type=gpiod.LINE_REQ_DIR_OUT) line.set_value(1) line.release() line.request(consumer=sys.argv[0], type=gpiod.LINE_REQ_DIR_IN) print('line value after: {}'.format(line.get_value())) chip.close()
def request_line_incorrect_number_of_def_vals(): with gpiod.Chip('gpiochip0') as chip: lines = chip.get_lines((1, 2, 3, 4, 5)) print('requesting lines with incorrect number of default values') try: lines.request(consumer='gpiod_test.py', type=gpiod.LINE_REQ_DIR_OUT, default_vals=(1, 0, 1, 0)) except TypeError: print('TypeError raised as expected') return assert False, 'TypeError expected'
def test_single_line_both_edges_events(self): with EventThread(0, 4, 200): with gpiod.Chip(mockup.chip_name(0)) as chip: line = chip.get_line(4) line.request(consumer=default_consumer, type=gpiod.LINE_REQ_EV_BOTH_EDGES) self.assertTrue(line.event_wait(sec=1)) event = line.event_read() self.assertEqual(event.type, gpiod.LineEvent.RISING_EDGE) self.assertEqual(event.source.offset(), 4) self.assertTrue(line.event_wait(sec=1)) event = line.event_read() self.assertEqual(event.type, gpiod.LineEvent.FALLING_EDGE) self.assertEqual(event.source.offset(), 4)
def test_set_value_multiple_lines(self): with gpiod.Chip(mockup.chip_name(0)) as chip: lines = chip.get_lines((0, 3, 4, 6)) lines.request(consumer=default_consumer, type=gpiod.LINE_REQ_DIR_OUT) lines.set_values((1, 0, 1, 1)) self.assertEqual(mockup.chip_get_value(0, 0), 1) self.assertEqual(mockup.chip_get_value(0, 3), 0) self.assertEqual(mockup.chip_get_value(0, 4), 1) self.assertEqual(mockup.chip_get_value(0, 6), 1) lines.set_values((0, 0, 1, 0)) self.assertEqual(mockup.chip_get_value(0, 0), 0) self.assertEqual(mockup.chip_get_value(0, 3), 0) self.assertEqual(mockup.chip_get_value(0, 4), 1) self.assertEqual(mockup.chip_get_value(0, 6), 0)
def test_set_config_bulk_output_no_values(self): with gpiod.Chip(mockup.chip_name(0)) as chip: lines = chip.get_lines((0, 3, 4, 6)) lines.request(consumer=default_consumer, type=gpiod.LINE_REQ_DIR_OUT, default_vals=(1, 1, 1, 1)) self.assertEqual(mockup.chip_get_value(0, 0), 1) self.assertEqual(mockup.chip_get_value(0, 3), 1) self.assertEqual(mockup.chip_get_value(0, 4), 1) self.assertEqual(mockup.chip_get_value(0, 6), 1) lines.set_config(gpiod.LINE_REQ_DIR_OUT, 0) self.assertEqual(mockup.chip_get_value(0, 0), 0) self.assertEqual(mockup.chip_get_value(0, 3), 0) self.assertEqual(mockup.chip_get_value(0, 4), 0) self.assertEqual(mockup.chip_get_value(0, 6), 0)
def open(self) -> None: assert self.__chip is None assert self.__target_line is None assert self.__reset_line is None self.__chip = gpiod.Chip(aiogp.DEVICE_PATH) self.__target_line = self.__chip.get_line(self.__target_pin) self.__target_line.request("kvmd::msd-relay::target", gpiod.LINE_REQ_DIR_OUT, default_val=0) self.__reset_line = self.__chip.get_line(self.__reset_pin) self.__reset_line.request("kvmd::msd-relay::reset", gpiod.LINE_REQ_DIR_OUT, default_val=0)
def test_exported_bias_pull_up_line(self): with gpiod.Chip(mockup.chip_path(0)) as chip: line = chip.get_line(4) flags = gpiod.LINE_REQ_FLAG_BIAS_PULL_UP line.request(consumer=default_consumer, type=gpiod.LINE_REQ_DIR_OUT, flags=flags) self.assertEqual(line.offset(), 4) self.assertEqual(line.name(), 'gpio-mockup-A-4') self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) self.assertFalse(line.is_active_low()) self.assertEqual(line.consumer(), default_consumer) self.assertTrue(line.is_used()) self.assertTrue(line.is_requested()) self.assertEqual(line.drive(), gpiod.Line.DRIVE_PUSH_PULL) self.assertEqual(line.bias(), gpiod.Line.BIAS_PULL_UP)
def open(self) -> None: assert self.__chip is None assert self.__target_line is None assert self.__reset_line is None self.__chip = gpiod.Chip(self.__device_path) self.__target_line = self.__chip.get_line(self.__target_pin) self.__target_line.request("kvmd::msd::target", gpiod.LINE_REQ_DIR_OUT, default_vals=[0]) self.__reset_line = self.__chip.get_line(self.__reset_pin) self.__reset_line.request("kvmd::msd::reset", gpiod.LINE_REQ_DIR_OUT, default_vals=[int(self.__reset_inverted)])
def open(self) -> None: assert self.__chip is None assert self.__target_line is None assert self.__reset_line is None self.__chip = gpiod.Chip(env.GPIO_DEVICE_PATH) self.__target_line = self.__chip.get_line(self.__target_pin) self.__target_line.request("kvmd::msd::target", gpiod.LINE_REQ_DIR_OUT, default_vals=[0]) self.__reset_line = self.__chip.get_line(self.__reset_pin) self.__reset_line.request("kvmd::msd::reset", gpiod.LINE_REQ_DIR_OUT, default_vals=[0])
def test_exported_bias_pull_down_line(self): with gpiod.Chip(mockup.chip_name(0)) as chip: line = chip.get_line(4) flags = gpiod.LINE_REQ_FLAG_BIAS_PULL_DOWN line.request(consumer=default_consumer, type=gpiod.LINE_REQ_DIR_OUT, flags=flags) self.assertEqual(line.offset(), 4) self.assertEqual(line.name(), 'gpio-mockup-A-4') self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) self.assertEqual(line.active_state(), gpiod.Line.ACTIVE_HIGH) self.assertEqual(line.consumer(), default_consumer) self.assertTrue(line.is_used()) self.assertTrue(line.is_requested()) self.assertFalse(line.is_open_drain()) self.assertFalse(line.is_open_source()) self.assertEqual(line.bias(), gpiod.Line.BIAS_PULL_DOWN)
def chip_use_after_close(): chip = gpiod.Chip('gpiochip0') line = chip.get_line(2) chip.close() try: chip.name() except ValueError as ex: print('Error as expected: {}'.format(ex)) try: line = chip.get_line(3) except ValueError as ex: print('Error as expected: {}'.format(ex)) return assert False, 'ValueError expected'
def test_exported_line_with_flags(self): with gpiod.Chip(mockup.chip_name(0)) as chip: line = chip.get_line(4) flags = (gpiod.LINE_REQ_FLAG_ACTIVE_LOW | gpiod.LINE_REQ_FLAG_OPEN_DRAIN) line.request(consumer=default_consumer, type=gpiod.LINE_REQ_DIR_OUT, flags=flags) self.assertEqual(line.offset(), 4) self.assertEqual(line.name(), 'gpio-mockup-A-4') self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) self.assertEqual(line.active_state(), gpiod.Line.ACTIVE_LOW) self.assertEqual(line.consumer(), default_consumer) self.assertTrue(line.is_used()) self.assertTrue(line.is_requested()) self.assertTrue(line.is_open_drain()) self.assertFalse(line.is_open_source())
def test_set_direction(self): with gpiod.Chip(mockup.chip_name(0)) as chip: line = chip.get_line(3) line.request(consumer=default_consumer, type=gpiod.LINE_REQ_DIR_OUT) self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) line.set_direction_input() self.assertEqual(line.direction(), gpiod.Line.DIRECTION_INPUT) line.set_direction_output(0) self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) self.assertEqual(mockup.chip_get_value(0, 3), 0) line.set_direction_output(1) self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) self.assertEqual(mockup.chip_get_value(0, 3), 1) line.set_direction_output() self.assertEqual(line.direction(), gpiod.Line.DIRECTION_OUTPUT) self.assertEqual(mockup.chip_get_value(0, 3), 0)
def sysprep(self) -> None: assert self.__chip is None assert self.__power_switch_line is None assert self.__reset_switch_line is None self.__chip = gpiod.Chip(self.__device_path) self.__power_switch_line = self.__chip.get_line( self.__power_switch_pin) self.__power_switch_line.request("kvmd::atx::power_switch", gpiod.LINE_REQ_DIR_OUT, default_vals=[0]) self.__reset_switch_line = self.__chip.get_line( self.__reset_switch_pin) self.__reset_switch_line.request("kvmd::atx::reset_switch", gpiod.LINE_REQ_DIR_OUT, default_vals=[0])
def sysprep(self) -> None: assert self.__chip is None assert self.__power_switch_line is None assert self.__reset_switch_line is None self.__chip = gpiod.Chip(aiogp.DEVICE_PATH) self.__power_switch_line = self.__chip.get_line( self.__power_switch_pin) self.__power_switch_line.request("kvmd::atx-gpio::power_switch", gpiod.LINE_REQ_DIR_OUT, default_val=0) self.__reset_switch_line = self.__chip.get_line( self.__reset_switch_pin) self.__reset_switch_line.request("kvmd::atx-gpio::reset_switch", gpiod.LINE_REQ_DIR_OUT, default_val=0)
def test_event_fd_polling(self): with EventThread(0, 2, 200): with gpiod.Chip(mockup.chip_name(0)) as chip: lines = chip.get_lines((0, 1, 2, 3, 4, 5, 6)) lines.request(consumer=default_consumer, type=gpiod.LINE_REQ_EV_BOTH_EDGES) inputs = [] for line in lines: inputs.append(line.event_get_fd()) readable, writable, exceptional = select.select( inputs, [], inputs, 1.0) self.assertEqual(len(readable), 1) event = lines.to_list()[2].event_read() self.assertEqual(event.type, gpiod.LineEvent.RISING_EDGE) self.assertEqual(event.source.offset(), 2)
def test_watch_multiple_lines_for_events(self): with EventThread(0, 2, 200): with gpiod.Chip(mockup.chip_name(0)) as chip: lines = chip.get_lines((0, 1, 2, 3, 4)) lines.request(consumer=default_consumer, type=gpiod.LINE_REQ_EV_BOTH_EDGES) event_lines = lines.event_wait(sec=1) self.assertEqual(len(event_lines), 1) line = event_lines[0] event = line.event_read() self.assertEqual(event.type, gpiod.LineEvent.RISING_EDGE) self.assertEqual(event.source.offset(), 2) event_lines = lines.event_wait(sec=1) self.assertEqual(len(event_lines), 1) line = event_lines[0] event = line.event_read() self.assertEqual(event.type, gpiod.LineEvent.FALLING_EDGE) self.assertEqual(event.source.offset(), 2)
def __init__(self, width, chipno=0, system_offset=0): """ Create a new bus instance for a set of gpiod pins on a specified bus at a specified offset. :param width: The number of concurrent pins to be referenced by this bus :param chipno: The number of the relevant gpio chip in /dev/gpiochip* :param system_offset: The offset of this bus from GPIO 0. In the case of Xilinx Zynq this is due to numbering reserved for MIO lines rather than EMIO. """ # Check width is valid if not width > 0: raise GPIOException( "Width supplied is invalid. Please specify a bus width above 0" ) # Select the specified GPIO chip try: self._gpio_chip = gpiod.Chip("/dev/gpiochip" + str(chipno)) except FileNotFoundError: raise GPIOException( "gpiochip not found, check /dev/gpiochip* for chip numbers present" ) # Place the chosen lines into a bulk for offset removal. Not requested until use. self._system_offset = system_offset self._width = width try: self._master_linebulk = self._gpio_chip.get_lines( range(system_offset, system_offset + width)) except OSError: raise GPIOException( "Selected lines were not available for this chip. " "Check if numbering is out of range") # Set the consumer name self._consumer_name = "odin_gpio_bus" # Set up for concurrency if available self._executor = None # Will manage futures for events being awaited self._monitors = { } # Will hold references to futures and related lines self._monitor_remove_pending = [ ] # List of pin indexes that should stop monitoring
def line_event_multiple_lines(): chip = gpiod.Chip('gpiochip0') lines = chip.get_lines((1, 2, 3, 4, 5)) print('requesting lines for events') lines.request(consumer=sys.argv[0], type=gpiod.LINE_REQ_EV_BOTH_EDGES) print('generating two line events') fire_line_event('gpiochip0', 1, True) fire_line_event('gpiochip0', 2, True) events = lines.event_wait(sec=1) assert events is not None and len( events) == 2, 'Expected to receive two line events' print('events received:') for line in events: event = line.event_read() print_event(event)
def line_flags(): chip = gpiod.Chip('gpiochip0') line = chip.get_line(3) print('line is used: {}'.format(line.is_used())) print('line is requested: {}'.format(line.is_requested())) print('requesting line') line.request(consumer=sys.argv[0], type=gpiod.LINE_REQ_DIR_OUT, flags=(gpiod.LINE_REQ_FLAG_OPEN_DRAIN | gpiod.LINE_REQ_FLAG_ACTIVE_LOW)) print('line is used: {}'.format(line.is_used())) print('line is open drain: {}'.format(line.is_open_drain())) print('line is open source: {}'.format(line.is_open_source())) print('line is requested: {}'.format(line.is_requested())) print('line is active-low: {}'.format("True" if line.active_state() == gpiod.Line.ACTIVE_LOW else "False"))
def test_single_line_read_multiple_events(self): with gpiod.Chip(mockup.chip_name(0)) as chip: line = chip.get_line(4) line.request(consumer=default_consumer, type=gpiod.LINE_REQ_EV_BOTH_EDGES) mockup.chip_set_pull(0, 4, 1) time.sleep(0.01) mockup.chip_set_pull(0, 4, 0) time.sleep(0.01) mockup.chip_set_pull(0, 4, 1) time.sleep(0.01) self.assertTrue(line.event_wait(sec=1)) events = line.event_read_multiple() self.assertEqual(len(events), 3) self.assertEqual(events[0].type, gpiod.LineEvent.RISING_EDGE) self.assertEqual(events[1].type, gpiod.LineEvent.FALLING_EDGE) self.assertEqual(events[2].type, gpiod.LineEvent.RISING_EDGE) self.assertEqual(events[0].source.offset(), 4) self.assertEqual(events[1].source.offset(), 4) self.assertEqual(events[2].source.offset(), 4)
def test_set_flags_bulk(self): with gpiod.Chip(mockup.chip_name(0)) as chip: lines = chip.get_lines((0, 3, 4, 6)) lines.request(consumer=default_consumer, type=gpiod.LINE_REQ_DIR_OUT, default_vals=(1, 1, 1, 1)) self.assertEqual(mockup.chip_get_value(0, 0), 1) self.assertEqual(mockup.chip_get_value(0, 3), 1) self.assertEqual(mockup.chip_get_value(0, 4), 1) self.assertEqual(mockup.chip_get_value(0, 6), 1) lines.set_flags(gpiod.LINE_REQ_FLAG_ACTIVE_LOW) self.assertEqual(mockup.chip_get_value(0, 0), 0) self.assertEqual(mockup.chip_get_value(0, 3), 0) self.assertEqual(mockup.chip_get_value(0, 4), 0) self.assertEqual(mockup.chip_get_value(0, 6), 0) lines.set_flags(0) self.assertEqual(mockup.chip_get_value(0, 0), 1) self.assertEqual(mockup.chip_get_value(0, 3), 1) self.assertEqual(mockup.chip_get_value(0, 4), 1) self.assertEqual(mockup.chip_get_value(0, 6), 1)
def cfg_to_line(cfg): if 'name' in cfg: name = cfg['name'] line = gpiod.find_line(name) if not line: raise FileNotFoundError(errno.ENOENT, "No such GPIO line", name) else: try: chip = gpiod.Chip(cfg['chip'], gpiod.Chip.OPEN_LOOKUP) line = chip.get_line(cfg['line']) except FileNotFoundError as e: e.strerror = "No such GPIO chip" e.filename = cfg['chip'] raise e except OSError as e: if e.errno == errno.EINVAL: raise FileNotFoundError( errno.ENOENT, "GPIO chip '%s' has no line %d" % (cfg['chip'], cfg['line'])) raise e return line
def __init__(self, chip_name: str): self._board_rev = BoardRevision.UNKNOWN self._chip = gpiod.Chip(chip_name) self._lines = self._initialize()
def test_open_chip_by_num(self): with gpiod.Chip('{}'.format(mockup.chip_num(1)), gpiod.Chip.OPEN_BY_NUMBER) as chip: self.assertEqual(chip.name(), mockup.chip_name(1))
def test_open_chip_by_path(self): with gpiod.Chip(mockup.chip_path(1), gpiod.Chip.OPEN_BY_PATH) as chip: self.assertEqual(chip.name(), mockup.chip_name(1))