MikrofonSensor und TemperaturSenor die zwei Python programme funktionieren. mit den jeweiligen 2 json Datein. Beim TemperaturSensor wird im Terminal keine Wertre ausgegeben aber in der json Datei kann man die Temp und Hum sehen.
This commit is contained in:
parent
4c654ec969
commit
1751076592
2614 changed files with 349009 additions and 0 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,57 @@
|
|||
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""
|
||||
`analogio` - Analog input and output control
|
||||
=================================================
|
||||
See `CircuitPython:analogio` in CircuitPython for more details.
|
||||
* Author(s): Carter Nelson
|
||||
"""
|
||||
|
||||
from adafruit_blinka.microcontroller.nxp_lpc4330.pin import Pin
|
||||
from adafruit_blinka import ContextManaged
|
||||
|
||||
|
||||
class AnalogIn(ContextManaged):
|
||||
"""Analog Input Class"""
|
||||
|
||||
def __init__(self, pin):
|
||||
self._pin = Pin(pin.id)
|
||||
self._pin.init(mode=Pin.ADC)
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
"""Read the ADC and return the value"""
|
||||
return self._pin.value()
|
||||
|
||||
# pylint: disable=no-self-use
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
# emulate what CircuitPython does
|
||||
raise AttributeError("'AnalogIn' object has no attribute 'value'")
|
||||
|
||||
# pylint: enable=no-self-use
|
||||
|
||||
def deinit(self):
|
||||
del self._pin
|
||||
|
||||
|
||||
class AnalogOut(ContextManaged):
|
||||
"""Analog Output Class"""
|
||||
|
||||
def __init__(self, pin):
|
||||
self._pin = Pin(pin.id)
|
||||
self._pin.init(mode=Pin.DAC)
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
"""Return an error. This is output only."""
|
||||
# emulate what CircuitPython does
|
||||
raise AttributeError("unreadable attribute")
|
||||
|
||||
@value.setter
|
||||
def value(self, value):
|
||||
self._pin.value(value)
|
||||
|
||||
def deinit(self):
|
||||
del self._pin
|
|
@ -0,0 +1,51 @@
|
|||
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""I2C Class for NXP LPC4330"""
|
||||
from greatfet import GreatFET
|
||||
|
||||
|
||||
class I2C:
|
||||
"""Custom I2C Class for NXP LPC4330"""
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def __init__(self, *, frequency=100000):
|
||||
self._gf = GreatFET()
|
||||
|
||||
def scan(self):
|
||||
"""Perform an I2C Device Scan"""
|
||||
return [index for index, dev in enumerate(self._gf.i2c.scan()) if dev[0]]
|
||||
|
||||
def writeto(self, address, buffer, *, start=0, end=None, stop=True):
|
||||
"""Write data from the buffer to an address"""
|
||||
if end is None:
|
||||
end = len(buffer)
|
||||
self._gf.i2c.write(address, buffer[start:end])
|
||||
|
||||
def readfrom_into(self, address, buffer, *, start=0, end=None, stop=True):
|
||||
"""Read data from an address and into the buffer"""
|
||||
if end is None:
|
||||
end = len(buffer)
|
||||
readin = self._gf.i2c.read(address, end - start)
|
||||
for i in range(end - start):
|
||||
buffer[i + start] = readin[i]
|
||||
|
||||
# pylint: enable=unused-argument
|
||||
|
||||
def writeto_then_readfrom(
|
||||
self,
|
||||
address,
|
||||
buffer_out,
|
||||
buffer_in,
|
||||
*,
|
||||
out_start=0,
|
||||
out_end=None,
|
||||
in_start=0,
|
||||
in_end=None,
|
||||
stop=False,
|
||||
):
|
||||
"""Write data from buffer_out to an address and then
|
||||
read data from an address and into buffer_in
|
||||
"""
|
||||
self.writeto(address, buffer_out, start=out_start, end=out_end, stop=stop)
|
||||
self.readfrom_into(address, buffer_in, start=in_start, end=in_end, stop=stop)
|
|
@ -0,0 +1,213 @@
|
|||
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""NXP LPC4330 pin names"""
|
||||
try:
|
||||
from greatfet import GreatFET
|
||||
from greatfet.interfaces.adc import ADC
|
||||
|
||||
gf = GreatFET()
|
||||
except ModuleNotFoundError:
|
||||
raise RuntimeError(
|
||||
"Unable to create GreatFET object. Make sure library is "
|
||||
"installed and the device is connected."
|
||||
) from ModuleNotFoundError
|
||||
|
||||
|
||||
class Pin:
|
||||
"""A basic Pin class for the NXP LPC4330 that
|
||||
acts as a wrapper for the GreatFET api.
|
||||
"""
|
||||
|
||||
# pin modes
|
||||
OUT = gf.gpio.DIRECTION_OUT
|
||||
IN = gf.gpio.DIRECTION_IN
|
||||
ADC = 2
|
||||
DAC = 3
|
||||
|
||||
# pin values
|
||||
LOW = 0
|
||||
HIGH = 1
|
||||
|
||||
def __init__(self, pin_id=None):
|
||||
self.id = pin_id
|
||||
self._mode = None
|
||||
self._pin = None
|
||||
|
||||
def init(self, mode=IN, pull=None):
|
||||
"""Initialize the Pin"""
|
||||
if self.id is None:
|
||||
raise RuntimeError("Can not init a None type pin.")
|
||||
if pull is not None:
|
||||
raise NotImplementedError("Internal pullups and pulldowns not supported")
|
||||
if mode in (Pin.IN, Pin.OUT):
|
||||
if self.id not in gf.GPIO_MAPPINGS:
|
||||
raise ValueError("Pin does not have GPIO capabilities")
|
||||
self._pin = gf.gpio.get_pin(self.id)
|
||||
self._pin.set_direction(mode)
|
||||
elif mode == Pin.ADC:
|
||||
# ADC only available on these pins
|
||||
if self.id not in gf.ADC_MAPPINGS:
|
||||
raise ValueError("Pin does not have ADC capabilities")
|
||||
self._pin = ADC(gf, self.id)
|
||||
elif mode == Pin.DAC:
|
||||
# DAC only available on these pins
|
||||
if self.id != "J2_P5":
|
||||
raise ValueError("Pin does not have DAC capabilities")
|
||||
self._pin = gf.apis.dac
|
||||
self._pin.initialize()
|
||||
else:
|
||||
raise ValueError("Incorrect pin mode: {}".format(mode))
|
||||
self._mode = mode
|
||||
|
||||
def value(self, val=None):
|
||||
"""Set or return the Pin Value"""
|
||||
# Digital In / Out
|
||||
if self._mode in (Pin.IN, Pin.OUT):
|
||||
# digital read
|
||||
if val is None:
|
||||
return self._pin.get_state()
|
||||
# digital write
|
||||
if val in (Pin.LOW, Pin.HIGH):
|
||||
self._pin.set_state(val)
|
||||
return None
|
||||
# nope
|
||||
raise ValueError("Invalid value for pin.")
|
||||
# Analog In
|
||||
if self._mode == Pin.ADC:
|
||||
if val is None:
|
||||
# Read ADC here
|
||||
return self._pin.read_samples()[0]
|
||||
# read only
|
||||
raise AttributeError("'AnalogIn' object has no attribute 'value'")
|
||||
# Analog Out
|
||||
if self._mode == Pin.DAC:
|
||||
if val is None:
|
||||
# write only
|
||||
raise AttributeError("unreadable attribute")
|
||||
# Set DAC Here
|
||||
self._pin.set_value(int(val))
|
||||
return None
|
||||
raise RuntimeError(
|
||||
"No action for mode {} with value {}".format(self._mode, val)
|
||||
)
|
||||
|
||||
|
||||
# create pin instances for each pin
|
||||
# J1 Header Pins
|
||||
J1_P3 = Pin("J1_P3")
|
||||
J1_P4 = Pin("J1_P4")
|
||||
J1_P5 = Pin("J1_P5")
|
||||
J1_P6 = Pin("J1_P6")
|
||||
J1_P7 = Pin("J1_P7")
|
||||
J1_P8 = Pin("J1_P8")
|
||||
J1_P9 = Pin("J1_P9")
|
||||
J1_P10 = Pin("J1_P10")
|
||||
J1_P12 = Pin("J1_P12")
|
||||
J1_P13 = Pin("J1_P13")
|
||||
J1_P14 = Pin("J1_P14")
|
||||
J1_P15 = Pin("J1_P15")
|
||||
J1_P16 = Pin("J1_P16")
|
||||
J1_P17 = Pin("J1_P17")
|
||||
J1_P18 = Pin("J1_P18")
|
||||
J1_P19 = Pin("J1_P19")
|
||||
J1_P20 = Pin("J1_P20")
|
||||
J1_P21 = Pin("J1_P21")
|
||||
J1_P22 = Pin("J1_P22")
|
||||
J1_P23 = Pin("J1_P23")
|
||||
J1_P24 = Pin("J1_P24")
|
||||
J1_P25 = Pin("J1_P25")
|
||||
J1_P26 = Pin("J1_P26")
|
||||
J1_P27 = Pin("J1_P27")
|
||||
J1_P28 = Pin("J1_P28")
|
||||
J1_P29 = Pin("J1_P29")
|
||||
J1_P30 = Pin("J1_P30")
|
||||
J1_P31 = Pin("J1_P31")
|
||||
J1_P32 = Pin("J1_P32")
|
||||
J1_P33 = Pin("J1_P33")
|
||||
J1_P34 = Pin("J1_P34")
|
||||
J1_P35 = Pin("J1_P35")
|
||||
J1_P37 = Pin("J1_P37")
|
||||
J1_P39 = Pin("J1_P39") # MOSI
|
||||
J1_P40 = Pin("J1_P40") # MISO
|
||||
|
||||
|
||||
# J2 Header Pins
|
||||
J2_P3 = Pin("J2_P3")
|
||||
J2_P4 = Pin("J2_P4")
|
||||
J2_P5 = Pin("J2_P5") # ADC, ADC, DAC
|
||||
J2_P6 = Pin("J2_P6")
|
||||
J2_P7 = Pin("J2_P7")
|
||||
J2_P8 = Pin("J2_P8")
|
||||
J2_P9 = Pin("J2_P9") # ADC, GPIO
|
||||
J2_P10 = Pin("J2_P10")
|
||||
J2_P13 = Pin("J2_P13")
|
||||
J2_P14 = Pin("J2_P14")
|
||||
J2_P15 = Pin("J2_P15")
|
||||
J2_P16 = Pin("J2_P16") # GPIO, ADC
|
||||
J2_P18 = Pin("J2_P18")
|
||||
J2_P19 = Pin("J2_P19")
|
||||
J2_P20 = Pin("J2_P20")
|
||||
J2_P22 = Pin("J2_P22")
|
||||
J2_P23 = Pin("J2_P23")
|
||||
J2_P24 = Pin("J2_P24")
|
||||
J2_P25 = Pin("J2_P25")
|
||||
J2_P27 = Pin("J2_P27")
|
||||
J2_P28 = Pin("J2_P28")
|
||||
J2_P29 = Pin("J2_P29")
|
||||
J2_P30 = Pin("J2_P30")
|
||||
J2_P31 = Pin("J2_P31")
|
||||
J2_P33 = Pin("J2_P33")
|
||||
J2_P34 = Pin("J2_P34")
|
||||
J2_P35 = Pin("J2_P35")
|
||||
J2_P36 = Pin("J2_P36")
|
||||
J2_P37 = Pin("J2_P37")
|
||||
J2_P38 = Pin("J2_P38")
|
||||
|
||||
# Bonus Row Pins
|
||||
J7_P2 = Pin("J7_P2")
|
||||
J7_P3 = Pin("J7_P3")
|
||||
J7_P4 = Pin("J7_P4") # ADC, ADC
|
||||
J7_P5 = Pin("J7_P5") # ADC, ADC
|
||||
J7_P6 = Pin("J7_P6")
|
||||
J7_P7 = Pin("J7_P7")
|
||||
J7_P8 = Pin("J7_P8")
|
||||
J7_P13 = Pin("J7_P13")
|
||||
J7_P14 = Pin("J7_P14")
|
||||
J7_P15 = Pin("J7_P15")
|
||||
J7_P16 = Pin("J7_P16")
|
||||
J7_P17 = Pin("J7_P17")
|
||||
J7_P18 = Pin("J7_P18")
|
||||
|
||||
SCL = Pin()
|
||||
SDA = Pin()
|
||||
|
||||
SCK = Pin()
|
||||
MOSI = J1_P39
|
||||
MISO = J1_P40
|
||||
|
||||
TX = J1_P33
|
||||
RX = J1_P34
|
||||
|
||||
# ordered as uartId, txId, rxId
|
||||
uartPorts = ((0, TX, RX),)
|
||||
|
||||
# pwm outputs: pwm channel and pin
|
||||
pwmOuts = (
|
||||
(0, J1_P4),
|
||||
(1, J1_P6),
|
||||
(2, J1_P28),
|
||||
(3, J1_P30),
|
||||
(4, J2_P36),
|
||||
(5, J2_P34),
|
||||
(6, J2_P33),
|
||||
(7, J1_P34),
|
||||
(8, J2_P9),
|
||||
(9, J1_P6),
|
||||
(10, J1_P25),
|
||||
(11, J1_P32),
|
||||
(12, J1_P31),
|
||||
(13, J2_P3),
|
||||
(14, J1_P3),
|
||||
(15, J1_P5),
|
||||
)
|
|
@ -0,0 +1,214 @@
|
|||
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""PWMOut Class for NXP LPC4330"""
|
||||
|
||||
from greatfet import GreatFET
|
||||
|
||||
try:
|
||||
from microcontroller.pin import pwmOuts
|
||||
except ImportError:
|
||||
raise RuntimeError("No PWM outputs defined for this board") from ImportError
|
||||
|
||||
|
||||
# pylint: disable=unnecessary-pass
|
||||
class PWMError(IOError):
|
||||
"""Base class for PWM errors."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
# pylint: enable=unnecessary-pass
|
||||
class PWMOut:
|
||||
"""Pulse Width Modulation Output Class"""
|
||||
|
||||
MAX_CYCLE_LEVEL = 1024
|
||||
|
||||
def __init__(self, pin, *, frequency=750, duty_cycle=0, variable_frequency=False):
|
||||
"""This class makes use of the GreatFET One's Pattern Generator to create a
|
||||
Simulated Pulse width modulation. The way that the Pattern Generator works is that
|
||||
takes a pattern in the form of bytes and will repeat the output. The trick to simulate
|
||||
PWM is to generate the correct byte pattern for the correct channel.
|
||||
|
||||
Args:
|
||||
pin (Pin): CircuitPython Pin object to output to
|
||||
duty_cycle (int) : The fraction of each pulse which is high. 16-bit
|
||||
frequency (int) : target frequency in Hertz (32-bit)
|
||||
|
||||
Returns:
|
||||
PWMOut: PWMOut object.
|
||||
|
||||
Raises:
|
||||
PWMError: if an I/O or OS error occurs.
|
||||
TypeError: if `channel` or `pin` types are invalid.
|
||||
ValueError: if PWM channel does not exist.
|
||||
"""
|
||||
self._gf = GreatFET()
|
||||
|
||||
if variable_frequency:
|
||||
raise NotImplementedError("Variable Frequency is not currently supported.")
|
||||
|
||||
self._pattern = None
|
||||
self._channel = None
|
||||
self._enable = False
|
||||
self._frequency = 500
|
||||
self._duty_cycle = 0
|
||||
self._open(pin, duty_cycle, frequency)
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, t, value, traceback):
|
||||
self.deinit()
|
||||
|
||||
def _open(self, pin, duty=0, freq=500):
|
||||
self._channel = None
|
||||
for pwmpair in pwmOuts:
|
||||
if pwmpair[1] == pin:
|
||||
self._channel = pwmpair[0]
|
||||
|
||||
self._pin = pin
|
||||
if self._channel is None:
|
||||
raise RuntimeError("No PWM channel found for this Pin")
|
||||
|
||||
# set duty
|
||||
self.duty_cycle = duty
|
||||
|
||||
# set frequency
|
||||
self.frequency = freq
|
||||
|
||||
self._set_enabled(True)
|
||||
|
||||
def deinit(self):
|
||||
"""Deinit the GreatFET One PWM."""
|
||||
# pylint: disable=broad-except
|
||||
try:
|
||||
if self._channel is not None:
|
||||
# self.duty_cycle = 0
|
||||
self._set_enabled(False)
|
||||
except Exception as e:
|
||||
# due to a race condition for which I have not yet been
|
||||
# able to find the root cause, deinit() often fails
|
||||
# but it does not effect future usage of the pwm pin
|
||||
print(
|
||||
"warning: failed to deinitialize pwm pin {0} due to: {1}\n".format(
|
||||
self._channel, type(e).__name__
|
||||
)
|
||||
)
|
||||
finally:
|
||||
self._pattern = None
|
||||
self._channel = None
|
||||
# pylint: enable=broad-except
|
||||
|
||||
def _is_deinited(self):
|
||||
if self._pattern is None:
|
||||
raise ValueError(
|
||||
"Object has been deinitialize and can no longer "
|
||||
"be used. Create a new object."
|
||||
)
|
||||
|
||||
# Mutable properties
|
||||
|
||||
def _get_period(self):
|
||||
return 1.0 / self._get_frequency()
|
||||
|
||||
def _set_period(self, period):
|
||||
"""Get or set the PWM's output period in seconds.
|
||||
|
||||
Raises:
|
||||
PWMError: if an I/O or OS error occurs.
|
||||
TypeError: if value type is not int or float.
|
||||
|
||||
:type: int, float
|
||||
"""
|
||||
if not isinstance(period, (int, float)):
|
||||
raise TypeError("Invalid period type, should be int or float.")
|
||||
|
||||
self._set_frequency(1.0 / period)
|
||||
|
||||
period = property(_get_period, _set_period)
|
||||
|
||||
def _get_duty_cycle(self):
|
||||
"""Get or set the PWM's output duty cycle as a ratio from 0.0 to 1.0.
|
||||
|
||||
Raises:
|
||||
PWMError: if an I/O or OS error occurs.
|
||||
TypeError: if value type is not int or float.
|
||||
ValueError: if value is out of bounds of 0.0 to 1.0.
|
||||
|
||||
:type: int, float
|
||||
"""
|
||||
return self._duty_cycle
|
||||
|
||||
def _set_duty_cycle(self, duty_cycle):
|
||||
if not isinstance(duty_cycle, (int, float)):
|
||||
raise TypeError("Invalid duty cycle type, should be int or float.")
|
||||
|
||||
# convert from 16-bit
|
||||
if isinstance(duty_cycle, int):
|
||||
duty_cycle /= 65535.0
|
||||
if not 0.0 <= duty_cycle <= 1.0:
|
||||
raise ValueError("Invalid duty cycle value, should be between 0.0 and 1.0.")
|
||||
|
||||
# Generate a pattern for 1024 samples of the duty cycle
|
||||
pattern = [(1 << self._channel)] * round(PWMOut.MAX_CYCLE_LEVEL * duty_cycle)
|
||||
pattern += [(0 << self._channel)] * round(
|
||||
PWMOut.MAX_CYCLE_LEVEL * (1.0 - duty_cycle)
|
||||
)
|
||||
|
||||
self._pattern = pattern
|
||||
self._duty_cycle = duty_cycle
|
||||
if self._enable:
|
||||
self._set_enabled(True)
|
||||
|
||||
duty_cycle = property(_get_duty_cycle, _set_duty_cycle)
|
||||
|
||||
def _get_frequency(self):
|
||||
return self._frequency
|
||||
|
||||
def _set_frequency(self, frequency):
|
||||
"""Get or set the PWM's output frequency in Hertz.
|
||||
|
||||
Raises:
|
||||
PWMError: if an I/O or OS error occurs.
|
||||
TypeError: if value type is not int or float.
|
||||
|
||||
:type: int, float
|
||||
"""
|
||||
if not isinstance(frequency, (int, float)):
|
||||
raise TypeError("Invalid frequency type, should be int or float.")
|
||||
|
||||
# We are sending 1024 samples per second already
|
||||
self._gf.pattern_generator.set_sample_rate(frequency * len(self._pattern))
|
||||
self._frequency = frequency
|
||||
|
||||
frequency = property(_get_frequency, _set_frequency)
|
||||
|
||||
def _get_enabled(self):
|
||||
enabled = self._enable
|
||||
|
||||
if enabled == "1":
|
||||
return True
|
||||
if enabled == "0":
|
||||
return False
|
||||
|
||||
raise PWMError(None, 'Unknown enabled value: "%s"' % enabled)
|
||||
|
||||
def _set_enabled(self, value):
|
||||
"""Get or set the PWM's output enabled state.
|
||||
|
||||
Raises:
|
||||
PWMError: if an I/O or OS error occurs.
|
||||
TypeError: if value type is not bool.
|
||||
|
||||
:type: bool
|
||||
"""
|
||||
if not isinstance(value, bool):
|
||||
raise TypeError("Invalid enabled type, should be string.")
|
||||
self._enable = value
|
||||
if self._gf:
|
||||
if self._enable:
|
||||
if self._pattern:
|
||||
self._gf.pattern_generator.scan_out_pattern(self._pattern)
|
||||
else:
|
||||
self._gf.pattern_generator.stop()
|
|
@ -0,0 +1,143 @@
|
|||
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""SPI Class for NXP LPC4330"""
|
||||
from greatfet import GreatFET
|
||||
|
||||
|
||||
class SPI:
|
||||
"""Custom I2C Class for NXP LPC4330"""
|
||||
|
||||
MSB = 0
|
||||
|
||||
def __init__(self):
|
||||
self._gf = GreatFET()
|
||||
self._frequency = None
|
||||
self.buffer_size = 255
|
||||
self._mode = 0
|
||||
self._spi = None
|
||||
self._presets = {
|
||||
204000: (100, 9),
|
||||
408000: (100, 4),
|
||||
680000: (100, 2),
|
||||
1020000: (100, 1),
|
||||
2040000: (50, 1),
|
||||
4250000: (24, 1),
|
||||
8500000: (12, 1),
|
||||
12750000: (8, 1),
|
||||
17000000: (6, 1),
|
||||
20400000: (2, 4),
|
||||
25500000: (4, 1),
|
||||
34000000: (2, 2),
|
||||
51000000: (2, 1),
|
||||
102000000: (2, 0),
|
||||
}
|
||||
|
||||
# pylint: disable=too-many-arguments,unused-argument
|
||||
def init(
|
||||
self,
|
||||
baudrate=100000,
|
||||
polarity=0,
|
||||
phase=0,
|
||||
bits=8,
|
||||
firstbit=MSB,
|
||||
sck=None,
|
||||
mosi=None,
|
||||
miso=None,
|
||||
):
|
||||
"""Initialize the Port"""
|
||||
# Figure out the mode based on phase and polarity
|
||||
polarity = int(polarity)
|
||||
phase = int(phase)
|
||||
self._mode = (polarity << 1) | phase
|
||||
|
||||
# Using API due to possible interface change
|
||||
self._spi = self._gf.apis.spi
|
||||
# Check baudrate against presets and adjust to the closest one
|
||||
if self._frequency is None:
|
||||
preset = self._find_closest_preset(baudrate)
|
||||
else:
|
||||
preset = self._presets[self._frequency]
|
||||
clock_prescale_rate, serial_clock_rate = preset
|
||||
self._spi.init(serial_clock_rate, clock_prescale_rate)
|
||||
|
||||
# Set the polarity and phase (the "SPI mode").
|
||||
self._spi.set_clock_polarity_and_phase(self._mode)
|
||||
|
||||
# pylint: enable=too-many-arguments
|
||||
|
||||
def _find_closest_preset(self, target_frequency):
|
||||
"""Loop through self._frequencies and find the closest
|
||||
setting. Return the preset values and set the frequency
|
||||
to the found value
|
||||
"""
|
||||
closest_preset = None
|
||||
for frequency, preset in self._presets.items():
|
||||
if self._frequency is None or abs(frequency - target_frequency) < abs(
|
||||
self._frequency - target_frequency
|
||||
):
|
||||
self._frequency = frequency
|
||||
closest_preset = preset
|
||||
|
||||
return closest_preset
|
||||
|
||||
@property
|
||||
def frequency(self):
|
||||
"""Return the current frequency"""
|
||||
return self._frequency
|
||||
|
||||
def write(self, buf, start=0, end=None):
|
||||
"""Write data from the buffer to SPI"""
|
||||
end = end if end else len(buf)
|
||||
self._transmit(buf[start:end])
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def readinto(self, buf, start=0, end=None, write_value=0):
|
||||
"""Read data from SPI and into the buffer"""
|
||||
end = end if end else len(buf)
|
||||
result = self._transmit([write_value] * (end - start), end - start)
|
||||
for i, b in enumerate(result):
|
||||
buf[start + i] = b
|
||||
|
||||
# pylint: enable=unused-argument
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
def write_readinto(
|
||||
self, buffer_out, buffer_in, out_start=0, out_end=None, in_start=0, in_end=None
|
||||
):
|
||||
"""Perform a half-duplex write from buffer_out and then
|
||||
read data into buffer_in
|
||||
"""
|
||||
out_end = out_end if out_end else len(buffer_out)
|
||||
in_end = in_end if in_end else len(buffer_in)
|
||||
|
||||
result = self._transmit(buffer_out[out_start:out_end], in_end - in_start)
|
||||
for i, b in enumerate(result):
|
||||
buffer_in[in_start + i] = b
|
||||
|
||||
# pylint: enable=too-many-arguments
|
||||
|
||||
def _transmit(self, data, receive_length=None):
|
||||
data_to_transmit = bytearray(data)
|
||||
data_received = bytearray()
|
||||
|
||||
if receive_length is None:
|
||||
receive_length = len(data)
|
||||
|
||||
# If we need to receive more than we've transmitted, extend the data out.
|
||||
if receive_length > len(data):
|
||||
padding = receive_length - len(data)
|
||||
data_to_transmit.extend([0] * padding)
|
||||
|
||||
# Transmit our data in chunks of the buffer size.
|
||||
while data_to_transmit:
|
||||
# Extract a single data chunk from the transmit buffer.
|
||||
chunk = data_to_transmit[0 : self.buffer_size]
|
||||
del data_to_transmit[0 : self.buffer_size]
|
||||
|
||||
# Finally, exchange the data.
|
||||
response = self._spi.clock_data(len(chunk), bytes(chunk))
|
||||
data_received.extend(response)
|
||||
|
||||
# Once we're done, return the data received.
|
||||
return bytes(data_received)
|
|
@ -0,0 +1,77 @@
|
|||
# SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
|
||||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
"""UART Class for NXP LPC4330"""
|
||||
from greatfet import GreatFET
|
||||
from greatfet.interfaces.uart import UART as _UART
|
||||
|
||||
|
||||
class UART:
|
||||
"""Custom UART Class for NXP LPC4330"""
|
||||
|
||||
PARITY_NONE = 0
|
||||
PARITY_ODD = 1
|
||||
PARITY_EVEN = 2
|
||||
PARITY_STUCK_AT_ONE = 3
|
||||
PARITY_STUCK_AT_ZERO = 4
|
||||
|
||||
# pylint: disable=too-many-arguments,unused-argument
|
||||
def __init__(
|
||||
self,
|
||||
portid,
|
||||
baudrate=9600,
|
||||
bits=8,
|
||||
parity=None,
|
||||
stop=1,
|
||||
timeout=1000,
|
||||
read_buf_len=None,
|
||||
flow=None,
|
||||
):
|
||||
self._gf = GreatFET()
|
||||
self._uart = _UART(
|
||||
self._gf,
|
||||
baud=baudrate,
|
||||
data_bits=bits,
|
||||
stop_bits=stop,
|
||||
parity=parity,
|
||||
uart_number=portid,
|
||||
)
|
||||
|
||||
if flow is not None: # default None
|
||||
raise NotImplementedError(
|
||||
"Parameter '{}' unsupported on GreatFET One".format("flow")
|
||||
)
|
||||
|
||||
# pylint: enable=too-many-arguments,unused-argument
|
||||
|
||||
def deinit(self):
|
||||
"""Deinitialize"""
|
||||
self._uart.initialized = False
|
||||
|
||||
def read(self, nbytes=None):
|
||||
"""Read data from UART and return it"""
|
||||
if nbytes is None:
|
||||
return None
|
||||
return self._uart.read(nbytes)
|
||||
|
||||
def readinto(self, buf, nbytes=None):
|
||||
"""Read data from UART and into the buffer"""
|
||||
if nbytes is None:
|
||||
return None
|
||||
result = self.read(nbytes)
|
||||
for _ in range(nbytes):
|
||||
buf.append(result)
|
||||
return buf
|
||||
|
||||
def readline(self):
|
||||
"""Read a single line of data from UART"""
|
||||
out = self.read(nbytes=1)
|
||||
line = out
|
||||
while out != "\r":
|
||||
out = self.read(nbytes=1)
|
||||
line += out
|
||||
return line
|
||||
|
||||
def write(self, buf):
|
||||
"""Write data from the buffer to UART"""
|
||||
return self._uart.write(buf)
|
Loading…
Add table
Add a link
Reference in a new issue