Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 0 additions & 35 deletions .github/workflows/python-feature-test.yml

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/python-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ on:
- 'dev'

jobs:
build:

lint:
name: Linter
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/python-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ on:
- 'dev'

jobs:
build:

test:
name: Test on Self-Hosted
runs-on: self-hosted
strategy:
fail-fast: false
Expand Down
28 changes: 28 additions & 0 deletions src/edgepi/gpio/edgepi_gpio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'''
Provides a class for interacting with the GPIO pins through I2C and GPIO peripheral
'''

import logging
import time

from edgepi.peripherals.gpio import GpioDevice
from edgepi.peripherals.i2c import I2CDevice
from edgepi.gpio.gpio_commands import *

_logger = logging.getLogger(__name__)

class EdgePiGPIO(I2CDevice):
'''
A class used to represent the GPIO. This class will be imported to each module
that requires GPIO manipulation. It is not intended for user.
'''

def __init__(self, config: str = None):
if config is None:
_logger.error(f'Config is not chosen, please choose a configuration')
self.config = getPeriphConfig(config)
_logger.debug(f'{self.config.name} Configuration Selected: {self.config}')
if self.config is not None and 'i2c' in self.config.dev_path:
super().__init__(self.config.dev_path)
_logger.info(f'GPIO expander up and running')
self.pinList = generate_pin_info(self.config.name)
28 changes: 7 additions & 21 deletions src/edgepi/gpio/gpio_commands.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,9 @@
from edgepi.peripherals.gpio import GpioDevice
from edgepi.peripherals.i2c import I2CDevice
from edgepi.gpio.gpio_constants import *
from edgepi.gpio.gpio_configs import *

class GPIOCommands(I2CDevice):
def __init__(self, pinList: list = None):
self.gpioPinDict = {}
self.i2cPinList = {}
for pin in pinList:
if GPIOCommands._gpioSettings[pin][0] == 'gpio':
self.gpioPinList[pin] = GpioDevice(pin_num=GPIOCommands._gpioSettings[pin][1],
pin_dir=GPIOCommands._gpioSettings[pin][2],
pin_bias=GPIOCommands._gpioSettings[pin][3])
else:
self.i2cPinList[pin] = GPIOCommands._gpioSettings[pin]
self.i2cDev = super().__init__(fd='/dev/i2c-10') if self.i2cPinList else None
self.setDefaults()

def _read_regs_map(self):
reg_map = {}
if 'PORTA' in self.i2cPinList

def setDefaults(self):
def getPeriphConfig(config: str = None):
''' Used to get proper config dataclass to configure neccessary peripheral configuration '''
for perpheryConfig in GpioConfigs:
if config == perpheryConfig.value.name:
return perpheryConfig.value
return None
75 changes: 68 additions & 7 deletions src/edgepi/gpio/gpio_configs.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from enum import Enum, unique
from dataclasses import dataclass
from edgepi.gpio.gpio_constants import *

@dataclass(frozen = True)
class GpioDACConfig:
class GpioExpanderConfig:
''' Represents peripheral information for GPIOs used DAC

Attributes:
Expand All @@ -17,11 +18,18 @@ class GpioDACConfig:
dev_path (str): device path to the peripheral device file
'''

name: str = 'dac'
device: str = 'i2c'
num_pins: int = 9
address: GpioExpanderAddress = GpioExpanderAddress
dev_path: str = '/dev/i2c-10'
name: str = None
device: str = None
num_pins: int = None
address: GpioExpanderAddress = None
dev_path: str = None

@unique
class GpioConfigs(Enum):
DAC = GpioExpanderConfig(name = 'dac', device='i2c', num_pins=9, address=GpioExpanderAddress.EXP_ONE, dev_path='/dev/i2c-10')
ADC = GpioExpanderConfig(name = 'adc', device='i2c', num_pins=2, address=GpioExpanderAddress.EXP_TWO, dev_path='/dev/i2c-10')
RTD = GpioExpanderConfig(name = 'rtd', device='i2c', num_pins=1, address=GpioExpanderAddress.EXP_TWO, dev_path='/dev/i2c-10')
LED = GpioExpanderConfig(name = 'led', device='i2c', num_pins=8, address=GpioExpanderAddress.EXP_ONE, dev_path='/dev/i2c-10')

@dataclass
class I2cPinInfo:
Expand All @@ -44,6 +52,11 @@ class I2cPinInfo:
# TODO: add more configs and list of pins for different modules

_list_of_DAC_gpios = ['AO_EN1','AO_EN4','AO_EN3','AO_EN2','AO_EN5','AO_EN6','AO_EN7','AO_EN8', 'DAC_GAIN']
_list_of_ADC_gpios = ['GNDSW_IN1', 'GNDSW_IN2']
_list_of_RTD_gpios = ['RTD_EN']
_list_of_LED_gpios = ['LED_OVR1', 'LED_OVR2' 'LED_OVR3' 'LED_OVR4''LED_OVR5''LED_OVR6', 'LED_OVR7', 'LED_OVR8']



def _generate_dac_pins():
''' Generates a list I2cPinInfo dataclasses for DAC pins
Expand All @@ -60,11 +73,53 @@ def _generate_dac_pins():
pin_list[8] = I2cPinInfo(_list_of_DAC_gpios[8], GpioAOutputSet.SET_OUTPUT_1.value, GpioAOutputClear.CLEAR_OUTPUT_1.value, GpioExpanderAddress.EXP_TWO.value)
return pin_list

def _generate_LED_pins():
''' Generates a list I2cPinInfo dataclasses for LED pins

Args:
N/A

Returns:
a list of dataclass with gpio information
'''
pin_list = []
for pin, set, clear in zip(_list_of_LED_gpios, GpioBOutputSet, GpioBOutputClear):
pin_list.append(I2cPinInfo(pin, set.value, clear.value, GpioExpanderAddress.EXP_ONE.value))
return pin_list

def _generate_ADC_pins():
''' Generates a list I2cPinInfo dataclasses for ADC pins

Args:
N/A

Returns:
a list of dataclass with gpio information
'''
pin_list = []
pin_list.append(I2cPinInfo(_list_of_ADC_gpios[0], GpioBOutputSet.SET_OUTPUT_2.value, GpioBOutputClear.CLEAR_OUTPUT_2.value, GpioExpanderAddress.EXP_TWO.value))
pin_list.append(I2cPinInfo(_list_of_ADC_gpios[1], GpioBOutputSet.SET_OUTPUT_3.value, GpioBOutputClear.CLEAR_OUTPUT_3.value, GpioExpanderAddress.EXP_TWO.value))
return pin_list

def _generate_RTD_pins():
''' Generates a list I2cPinInfo dataclasses for RTD pins

Args:
N/A

Returns:
a list of dataclass with gpio information
'''
pin_list = []
pin_list.append(I2cPinInfo(_list_of_RTD_gpios[0], GpioBOutputSet.SET_OUTPUT_1.value, GpioBOutputClear.CLEAR_OUTPUT_1.value, GpioExpanderAddress.EXP_TWO.value))
return pin_list


def generate_pin_info(config:str):
''' Generates a list pin info dataclasses

Args:
config (str): name of the module to configure the gpio pins for
config (str): name of the module to configure the gpio pins fors

Returns:
a list of dataclass with gpio information
Expand All @@ -73,5 +128,11 @@ def generate_pin_info(config:str):

if config == 'dac':
pin_list = _generate_dac_pins()
if config == 'led':
pin_list = _generate_LED_pins()
if config == 'adc':
pin_list = _generate_ADC_pins()
if config == 'rtd':
pin_list = _generate_RTD_pins()

return pin_list
1 change: 0 additions & 1 deletion src/edgepi/gpio/gpio_constants.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from enum import Enum, unique
from edgepi.reg_helper.reg_helper import OpCode

@unique
class GpioExpanderAddress(Enum):
EXP_ONE = 32
EXP_TWO = 33
Expand Down
22 changes: 22 additions & 0 deletions src/edgepi/peripherals/i2c.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,27 @@ def __init__(self, fd: str = None):
self.fd = fd
self.i2cdev = I2C(fd)

'''
set Read message to be sent through I2C.
Attributes:
addr: Register address to read from
Msg: list of place holder bytes
Return:
MsgList: list of I2C.Message() objects containing Msg to be sent
'''
def setReadMsg(self, addr:int = None, Msg:list = None):
return [I2C.Message([addr]), I2C.Message(Msg, read=True)]

'''
set Write message to be sent through I2C.
Attributes:
addr: Register address to write to
Msg: list of Msg bytes
Return:
MsgList: list of I2C.Message() objects containing Msg to be sent
'''
def setWriteMsg(self, addr:int = None, Msg:list = None):
return [I2C.Message([addr]+Msg)]

def close(self):
self.i2cdev.close()
2 changes: 0 additions & 2 deletions src/edgepi/reg_helper/reg_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ def apply_opcodes(register_values:dict, opcodes:list):

# apply each opcode to its corresponding register
for opcode in opcodes:
if opcode is None:
continue
register_entry = register_values.get(opcode.reg_address)
# if this opcode maps to a valid register address
if register_entry is not None:
Expand Down
2 changes: 1 addition & 1 deletion src/edgepi/tc/edgepi_tc.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def set_config(
cj_offset_decimals (DecBits): set cold junction temperature offset decimal value.
'''
# filter out self from args
args_dict = filter_dict(locals(), 'self')
args_dict = filter_dict(locals(), 'self', None)
_logger.debug(f'set_config args list: \n\n {args_dict}\n\n')

# extract opcodes from Enums
Expand Down
13 changes: 9 additions & 4 deletions src/edgepi/utilities/utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@
filter_dict(dict, any)
'''

def filter_dict(dictionary:dict, keyword) -> dict:
''' use for filtering an entry from a dictionary by key
def filter_dict(dictionary:dict, entry_key='', entry_val='') -> dict:
''' use for filtering an entry from a dictionary by key or value

Args:
dictionary (dict): any dictionary whose entries are to be filtered

entry_key (any): the key of the entry to filter out

entry_val (any): the value of the entry or entries to filter out

Returns:
a dictionary of entries from the original dictionary, after filtering out the entry whose key is the keyword.
a dictionary of entries from the original dictionary, after filtering out entries whose
key or value matches either the entry_key or entry_val, respectively.
'''
filtered_args = { key:value for (key,value) in dictionary.items() if key != keyword }
filtered_args = { key:value for (key,value) in dictionary.items() if key != entry_key and value != entry_val }
return(filtered_args)
25 changes: 25 additions & 0 deletions src/test_edgepi/test_gpio/test_edgepi_gpio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import pytest
from unittest import mock
from unittest.mock import patch
import sys
if sys.platform != 'linux':
sys.modules['periphery'] = mock.MagicMock()
from edgepi.gpio.gpio_configs import *
from edgepi.gpio.edgepi_gpio import EdgePiGPIO

@pytest.fixture(name='gpio')
def fixture_test_edgepi_tc(mocker):
mocker.patch('edgepi.peripherals.i2c.I2C')
mocker.patch('edgepi.peripherals.gpio.GPIO')

@pytest.mark.parametrize("mock_expect,config, result",
[(['/dev/i2c-10'],'dac',[GpioConfigs.DAC.value]),
(['/dev/i2c-10'],'adc',[GpioConfigs.ADC.value]),
(['/dev/i2c-10'],'rtd',[GpioConfigs.RTD.value]),
(['/dev/i2c-10'],'led',[GpioConfigs.LED.value]),
])
@patch('edgepi.peripherals.i2c.I2CDevice')
def test_edgepi_gpio_init(i2c_mock, mock_expect, config, result):
i2c_mock.fd = mock_expect[0]
gpioCtrl = EdgePiGPIO(config)
assert gpioCtrl.config == result[0]
14 changes: 14 additions & 0 deletions src/test_edgepi/test_gpio/test_gpio_command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import pytest
from edgepi.gpio.gpio_commands import *
from edgepi.gpio.gpio_configs import *

@pytest.mark.parametrize('config, result',
[('dac', GpioConfigs.DAC.value),
('adc', GpioConfigs.ADC.value),
('rtd', GpioConfigs.RTD.value),
('din', None),
('dout', None),
('led', GpioConfigs.LED.value),
( None, None)])
def test_getPeriphConfig(config, result):
assert getPeriphConfig(config) == result
Loading