commit 9f6f2eb198c2329cba5a957e51dc50294555c17c Author: Ondřej Hruška Date: Mon Jun 18 07:57:09 2018 +0200 code import diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d5d1e77 --- /dev/null +++ b/.gitignore @@ -0,0 +1,107 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +__javascript__/ +*.py[cod] +*$py.class + +#*.wav +.idea/ +#*.npy +#*.npz + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# dotenv +.env + +# virtualenv +.venv +venv/ +ENV/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..26f1292 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "gex"] + path = gex + url = https://git.ondrovo.com/gex/gex-client-py.git diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..669bc54 --- /dev/null +++ b/LICENSE @@ -0,0 +1,9 @@ +MIT License + +Copyright (c) 2018 Ondřej Hruška + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/demo_adc_lightnings.py b/demo_adc_lightnings.py new file mode 100644 index 0000000..970b274 --- /dev/null +++ b/demo_adc_lightnings.py @@ -0,0 +1,49 @@ +#!/bin/env python3 +import time + +import gex +import numpy as np +from matplotlib import pyplot as plt +import datetime + +from scipy.io import wavfile + +# this script captures lightnings and stores them to npy files + +# ADC channel 1 -> 100n -> o -> long wire (antenna) +# | +# '-> 10k -> GND + +led = None + +def capture(tr): + now=datetime.datetime.now() + now.isoformat() + data = tr.data + print("Capture! ") + print(data) + np.save("lightnings/lightning-%s"%now.isoformat(), data) + led.pulse_ms(1000, confirm=False) + +with gex.Client(gex.TrxRawUSB()) as client: + adc = gex.ADC(client, 'adc') + led = gex.DOut(client, 'led') + + adc.set_sample_rate(60000) + + adc.on_trigger(capture) + adc.setup_trigger(1, + level=2600, + count=5000, + edge='rising', + pretrigger=500, + holdoff=500, + auto=True) + + adc.arm() + + sec = 0 + while True: + print('%d s' % sec) + sec += 1 + time.sleep(1) diff --git a/demo_dot_matrix_phat.py b/demo_dot_matrix_phat.py new file mode 100644 index 0000000..1834038 --- /dev/null +++ b/demo_dot_matrix_phat.py @@ -0,0 +1,36 @@ +#!/bin/env python3 +import gex +import time + +# simple demo with the dot matrix phat + +ADDR = 0x61 +MODE = 0b00011000 +OPTS = 0b00001110 # 1110 = 35mA, 0000 = 40mA + +CMD_BRIGHTNESS = 0x19 +CMD_MODE = 0x00 +CMD_UPDATE = 0x0C +CMD_OPTIONS = 0x0D + +CMD_MATRIX_1 = 0x01 +CMD_MATRIX_2 = 0x0E + +with gex.Client(gex.TrxRawUSB()) as client: + bus = gex.I2C(client, 'i2c') + addr = 0x61 + bus.write_reg(addr, CMD_MODE, MODE) + bus.write_reg(addr, CMD_OPTIONS, OPTS) + bus.write_reg(addr, CMD_BRIGHTNESS, 64) + + bus.write(addr, [CMD_MATRIX_1, + 0xAA,0x55,0xAA,0x55, + 0xAA,0x55,0xAA,0x55, + ]) + + bus.write(addr, [CMD_MATRIX_2, + 0xFF, 0, 0xFF, 0, + 0xFF, 0, 0xFF, 0, + ]) + + bus.write_reg(addr, CMD_UPDATE, 0x01) \ No newline at end of file diff --git a/demo_dot_matrix_phat2.py b/demo_dot_matrix_phat2.py new file mode 100644 index 0000000..2cbefd0 --- /dev/null +++ b/demo_dot_matrix_phat2.py @@ -0,0 +1,200 @@ +#!/bin/env python3 +import random + +import gex +import time + +# This is an adaptation of the micro dot phat library +# - the only change needed was replacing the smbus class with the GEX unit driver + +ADDR = 0x61 +MODE = 0b00011000 +OPTS = 0b00001110 # 1110 = 35mA, 0000 = 40mA + +CMD_BRIGHTNESS = 0x19 +CMD_MODE = 0x00 +CMD_UPDATE = 0x0C +CMD_OPTIONS = 0x0D + +CMD_MATRIX_1 = 0x01 +CMD_MATRIX_2 = 0x0E + +MATRIX_1 = 0 +MATRIX_2 = 1 + +class NanoMatrix: + ''' + _BUF_MATRIX_1 = [ # Green +#Col 1 2 3 4 5 + 0b00000000, # Row 1 + 0b00000000, # Row 2 + 0b00000000, # Row 3 + 0b00000000, # Row 4 + 0b00000000, # Row 5 + 0b00000000, # Row 6 + 0b10000000, # Row 7, bit 8 = decimal place + 0b00000000 +] + _BUF_MATRIX_2 = [ # Red +#Row 8 7 6 5 4 3 2 1 + 0b01111111, # Col 1, bottom to top + 0b01111111, # Col 2 + 0b01111111, # Col 3 + 0b01111111, # Col 4 + 0b01111111, # Col 5 + 0b00000000, + 0b00000000, + 0b01000000 # bit 7, decimal place +] + _BUF_MATRIX_1 = [0] * 8 + _BUF_MATRIX_2 = [0] * 8 +''' + + def __init__(self, bus:gex.I2C, address=ADDR): + self.address = address + self._brightness = 127 + + self.bus = bus + + self.bus.write_byte_data(self.address, CMD_MODE, MODE) + self.bus.write_byte_data(self.address, CMD_OPTIONS, OPTS) + self.bus.write_byte_data(self.address, CMD_BRIGHTNESS, self._brightness) + + self._BUF_MATRIX_1 = [0] * 8 + self._BUF_MATRIX_2 = [0] * 8 + + def set_brightness(self, brightness): + self._brightness = int(brightness * 127) + if self._brightness > 127: self._brightness = 127 + + self.bus.write_byte_data(self.address, CMD_BRIGHTNESS, self._brightness) + + def set_decimal(self, m, c): + + if m == MATRIX_1: + if c == 1: + self._BUF_MATRIX_1[6] |= 0b10000000 + else: + self._BUF_MATRIX_1[6] &= 0b01111111 + + elif m == MATRIX_2: + + if c == 1: + self._BUF_MATRIX_2[7] |= 0b01000000 + else: + self._BUF_MATRIX_2[7] &= 0b10111111 + + #self.update() + + def set(self, m, data): + for y in range(7): + self.set_row(m, y, data[y]) + + def set_row(self, m, r, data): + for x in range(5): + self.set_pixel(m, x, r, (data & (1 << (4-x))) > 0) + + def set_col(self, m, c, data): + for y in range(7): + self.set_pixel(m, c, y, (data & (1 << y)) > 0) + + def set_pixel(self, m, x, y, c): + + if m == MATRIX_1: + if c == 1: + self._BUF_MATRIX_1[y] |= (0b1 << x) + else: + self._BUF_MATRIX_1[y] &= ~(0b1 << x) + elif m == MATRIX_2: + if c == 1: + self._BUF_MATRIX_2[x] |= (0b1 << y) + else: + self._BUF_MATRIX_2[x] &= ~(0b1 << y) + + #self.update() + + def clear(self, m): + if m == MATRIX_1: + self._BUF_MATRIX_1 = [0] * 8 + elif m == MATRIX_2: + self._BUF_MATRIX_2 = [0] * 8 + + self.update() + + def update(self): + for x in range(10): + try: + self.bus.write_i2c_block_data(self.address, CMD_MATRIX_1, self._BUF_MATRIX_1) + self.bus.write_i2c_block_data(self.address, CMD_MATRIX_2, self._BUF_MATRIX_2) + + self.bus.write_byte_data(self.address, CMD_UPDATE, 0x01) + break + except IOError: + print("IO Error") + + + + +with gex.Client(gex.TrxRawUSB()) as client: + bus = gex.I2C(client, 'i2c') + + n1 = NanoMatrix(bus, 0x61) + n2 = NanoMatrix(bus, 0x62) + n3 = NanoMatrix(bus, 0x63) + + n1.set_pixel(0, 0, 0, 1) + n1.set_pixel(0, 4, 0, 1) + n1.set_pixel(0, 0, 6, 1) + n1.set_pixel(0, 4, 6, 1) + + n1.set_pixel(1, 0, 0, 1) + n1.set_pixel(1, 4, 0, 1) + n1.set_pixel(1, 0, 3, 1) + n1.set_pixel(1, 4, 3, 1) + + n2.set_pixel(0, 0, 2, 1) + n2.set_pixel(0, 4, 2, 1) + n2.set_pixel(0, 0, 5, 1) + n2.set_pixel(0, 4, 5, 1) + + n2.set_pixel(1, 0, 0, 1) + n2.set_pixel(1, 4, 0, 1) + n2.set_pixel(1, 0, 6, 1) + n2.set_pixel(1, 4, 6, 1) + + + n3.set_pixel(0, 1, 0, 1) + n3.set_pixel(0, 3, 0, 1) + n3.set_pixel(0, 1, 6, 1) + n3.set_pixel(0, 3, 6, 1) + + n3.set_pixel(1, 1, 1, 1) + n3.set_pixel(1, 3, 1, 1) + n3.set_pixel(1, 1, 5, 1) + n3.set_pixel(1, 3, 5, 1) + + n1.update() + n2.update() + n3.update() + + b1 = 64 + b2 = 64 + b3 = 64 + + while True: + b1 += random.randint(-20, 15) + b2 += random.randint(-20, 18) + b3 += random.randint(-15, 13) + + if b1 < 0: b1 = 0 + if b2 < 0: b2 = 0 + if b3 < 0: b3 = 0 + if b1 > 127: b1 = 127 + if b2 > 127: b2 = 127 + if b3 > 127: b3 = 127 + + n1.set_brightness(b1) + n2.set_brightness(b2) + n3.set_brightness(b3) + + time.sleep(0.05) diff --git a/demo_freq_response.py b/demo_freq_response.py new file mode 100644 index 0000000..d6d3726 --- /dev/null +++ b/demo_freq_response.py @@ -0,0 +1,35 @@ +#!/bin/env python3 +import gex +import numpy as np +from matplotlib import pyplot as plt + +# frequency response measurement + +with gex.Client(gex.TrxRawUSB()) as client: + dac = gex.DAC(client, 'dac') + adc = gex.ADC(client, 'adc') + + dac.waveform(1, 'SINE') + adc.set_sample_rate(50000) + + table = [] + + for i in range(100, 10000, 100): + dac.set_frequency(1, i) + data = adc.capture(10000) + # convert to floats + samples = data.astype(float) + amplitude = np.max(samples) - np.min(samples) + print("%d Hz ... rms %d" % (i, amplitude)) + table.append(i) + table.append(amplitude) + + dac.dc(1, 0) + + t = np.reshape(np.array(table), [int(len(table)/2),2]) + hz = t[:,0] + am = t[:,1] + + plt.plot(hz, am, 'r-', lw=1) + plt.grid() + plt.show() diff --git a/demo_i2c_dotmatrix.py b/demo_i2c_dotmatrix.py new file mode 100644 index 0000000..52fe73b --- /dev/null +++ b/demo_i2c_dotmatrix.py @@ -0,0 +1,23 @@ +#!/bin/env python3 +import gex + +# experiment with the dot matrix driver + +with gex.Client(gex.TrxRawUSB()) as client: + bus = gex.I2C(client, 'i2c') + addr = 0x61 + bus.write_reg(addr, 0x00, 0b00011000) # dual matrix + bus.write_reg(addr, 0x0D, 0b00001110) # 34 mA + bus.write_reg(addr, 0x19, 64) # set brightness + # matrix 1 + bus.write_reg(addr, 0x01, [ + 0xAA, 0x55, 0xAA, 0x55, + 0xAA, 0x55, 0xAA, 0x55 + ]) + # matrix 2 + bus.write_reg(addr, 0x0E, [ + 0xFF, 0x00, 0xFF, 0x00, + 0xFF, 0x00, 0xFF, 0x00 + ]) + # update display + bus.write_reg(addr, 0x0C, 0x01) diff --git a/demo_lora.py b/demo_lora.py new file mode 100644 index 0000000..ffc93fc --- /dev/null +++ b/demo_lora.py @@ -0,0 +1,213 @@ +import time + +import gex +import sx_fsk as sx + + +# we're demonstrating the use of the GFSK mode of the SX1278 +# this is an example of how GEX can be used to control a peripheral module - in this case evaluating +# it for use in GEX remote + + +class LoRa: + def __init__(self, + rst: gex.DOut, + spi: gex.SPI, ssnum): + self.ss = ssnum + self.rst = rst + self.spi = spi + + def reset(self): + self.rst.pulse_us(100, active=False) + time.sleep(0.005) + + def rd(self, addr): + return self.spi.query(self.ss, [addr], 1)[0] + + def wr(self, addr, value): + self.spi.write(self.ss, [addr | 0x80, value]) + + def rds(self, start, count=1): + return self.spi.query(self.ss, [start], count) + + def wrs(self, start, values): + ba = bytearray() + ba.append(start | 0x80) + ba.extend(values) + self.spi.write(self.ss, ba) + + def rmw(self, addr, keep, set): + """ rmw, first and-ing the register with mask and then oring with set """ + val = self.rd(addr) + self.wr(addr, (val & keep) | set) + + def waitModeSwitch(self): + while 0 == (self.rd(sx.REG_IRQFLAGS1) & sx.RF_IRQFLAGS1_MODEREADY): + time.sleep(0.001) + + def waitSent(self): + while 0 == (self.rd(sx.REG_IRQFLAGS2) & sx.RF_IRQFLAGS2_PACKETSENT): + time.sleep(0.001) + + def fsk_set_defaults(self): + # Set default values (semtech patches: * in DS) + self.rmw(sx.REG_RXCONFIG, + sx.RF_RXCONFIG_RXTRIGER_MASK, + sx.RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT) + + self.wr(sx.REG_PREAMBLEDETECT, + sx.RF_PREAMBLEDETECT_DETECTOR_ON | + sx.RF_PREAMBLEDETECT_DETECTORSIZE_2 | + sx.RF_PREAMBLEDETECT_DETECTORTOL_10) + + self.rmw(sx.REG_OSC, sx.RF_OSC_CLKOUT_MASK, sx.RF_OSC_CLKOUT_OFF) + + self.rmw(sx.REG_FIFOTHRESH, + sx.RF_FIFOTHRESH_TXSTARTCONDITION_MASK, + sx.RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY) + + self.rmw(sx.REG_IMAGECAL, + sx.RF_IMAGECAL_AUTOIMAGECAL_MASK, + sx.RF_IMAGECAL_AUTOIMAGECAL_OFF) + + def configure_for_fsk(self, address): + self.rmw(sx.REG_OPMODE, + sx.RF_OPMODE_LONGRANGEMODE_MASK & sx.RF_OPMODE_MODULATIONTYPE_MASK & sx.RF_OPMODE_MASK, + sx.RF_OPMODE_LONGRANGEMODE_OFF | + sx.RF_OPMODE_MODULATIONTYPE_FSK | + sx.RF_OPMODE_STANDBY) + self.waitModeSwitch() + + self.fsk_set_defaults() + self.wr(sx.REG_NODEADRS, address) + self.wr(sx.REG_BROADCASTADRS, 0xFF) + # use whitening and force address matching + self.rmw(sx.REG_PACKETCONFIG1, + sx.RF_PACKETCONFIG1_DCFREE_MASK & sx.RF_PACKETCONFIG1_ADDRSFILTERING_MASK, + sx.RF_PACKETCONFIG1_DCFREE_WHITENING | + sx.RF_PACKETCONFIG1_ADDRSFILTERING_NODEBROADCAST) + + self.wr(sx.REG_RXCONFIG, + sx.RF_RXCONFIG_AFCAUTO_ON | + sx.RF_RXCONFIG_AGCAUTO_ON | + sx.RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT) + + XTAL_FREQ = 32000000 + FREQ_STEP = 61.03515625 + FSK_FDEV = 60000 # Hz NOTE: originally: 25000, seems to help increasing + FSK_DATARATE = 200000 # bps - originally 50000 + + MAX_RFPOWER = 0 # 0-7 boost - this doesnt seem to have a huge impact + + FSK_PREAMBLE_LENGTH = 5 # Same for Tx and Rx + + fdev = round(FSK_FDEV / FREQ_STEP) + self.wr(sx.REG_FDEVMSB, fdev >> 8) + self.wr(sx.REG_FDEVLSB, fdev & 0xFF) + + datarate = round(XTAL_FREQ / FSK_DATARATE) + print("dr=%d"%datarate) + self.wr(sx.REG_BITRATEMSB, datarate >> 8) + self.wr(sx.REG_BITRATELSB, datarate & 0xFF) + + preamblelen = FSK_PREAMBLE_LENGTH + self.wr(sx.REG_PREAMBLEMSB, preamblelen >> 8) + self.wr(sx.REG_PREAMBLELSB, preamblelen & 0xFF) + + # bandwidths - 1 MHz + self.wr(sx.REG_RXBW, 0x0A) # FSK_BANDWIDTH + self.wr(sx.REG_AFCBW, 0x0A) # FSK_AFC_BANDWIDTH + + # max payload len to rx + self.wr(sx.REG_PAYLOADLENGTH, 0xFF) + + self.rmw(sx.REG_PARAMP, 0x9F, 0x40) # enable gauss 0.5 + + # pick the sync word size + self.rmw(sx.REG_SYNCCONFIG, + sx.RF_SYNCCONFIG_SYNCSIZE_MASK, + sx.RF_SYNCCONFIG_SYNCSIZE_3) + + # sync word (network ID) + self.wrs(sx.REG_SYNCVALUE1, [ + 0xe7, 0x3d, 0xfa, 0x01, 0x5e, 0xa1, 0xc9, 0x98 # something random + ]) + + # enable LNA boost (?) + self.rmw(sx.REG_LNA, + sx.RF_LNA_BOOST_MASK, + sx.RF_LNA_BOOST_ON) + + # experiments with the pa config + self.rmw(sx.REG_PACONFIG, + sx.RF_PACONFIG_PASELECT_MASK|0x8F, # max power mask + sx.RF_PACONFIG_PASELECT_PABOOST | MAX_RFPOWER<<4) + + # we could also possibly adjust the Tx power + + + +with gex.Client(gex.TrxRawUSB()) as client: + spi = gex.SPI(client, 'spi') + rst1 = gex.DOut(client, 'rst1') + rst2 = gex.DOut(client, 'rst2') + + a = LoRa(rst1, spi, 0) + b = LoRa(rst2, spi, 1) + + # reset the two transceivers to ensure they start in a defined state + a.reset() + b.reset() + + # go to sleep mode, select FSK + a.configure_for_fsk(0x33) + b.configure_for_fsk(0x44) + + print("Devices configured") + + for j in range(0, 240): + if(j>0 and j%60==0): + print() + + # --- Send a message from 1 to 2 --- + msg = [ + 51, # len + 0x44, # address + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 0, 1, 2, 3, 4, 5, 6, 7, 8, j + ] + + a.wrs(sx.REG_FIFO, msg) + + b.rmw(sx.REG_OPMODE, sx.RF_OPMODE_MASK, sx.RF_OPMODE_RECEIVER) + # time.sleep(0.005) + + # trigger A + a.rmw(sx.REG_OPMODE, sx.RF_OPMODE_MASK, sx.RF_OPMODE_TRANSMITTER) + a.waitModeSwitch() + a.waitSent() + # time.sleep(0.02) + + # print("a irq flags = ", ["0x%02x"%x for x in a.rds(sx.REG_IRQFLAGS1, 2)]) + # print("b irq flags = ", ["0x%02x"%x for x in b.rds(sx.REG_IRQFLAGS1, 2)]) + + rxd = [b.rd(sx.REG_FIFO) for x in range(0,len(msg))] + if rxd == msg: + print("\x1b[32;1m+\x1b[0m", end="", flush=True) + else: + print("\x1b[31m-\x1b[0m", end="", flush=True) + # + # for i in range(0,8): + # print("0x%02x" % rxd[i],end=" ") + # print() + # print() + print() + + # good night + a.rmw(sx.REG_OPMODE, sx.RF_OPMODE_MASK, sx.RF_OPMODE_SLEEP) + b.rmw(sx.REG_OPMODE, sx.RF_OPMODE_MASK, sx.RF_OPMODE_SLEEP) + + diff --git a/demo_ndir_leds.py b/demo_ndir_leds.py new file mode 100644 index 0000000..069db3f --- /dev/null +++ b/demo_ndir_leds.py @@ -0,0 +1,37 @@ +import time + +import gex + +# NDIR CO2 sensor showing the concentration on a SIPO-based LED display + +with gex.Client(gex.TrxRawUSB()) as client: + ser = gex.USART(client, 'ser') + leds = gex.SIPO(client, 'leds') + + while True: + ser.clear_buffer() + ser.write([0xFF, 0x01, 0x86, 0, 0, 0, 0, 0, 0x79]) + data = ser.receive(9, decode=None) + + pp = gex.PayloadParser(data, endian="big").skip(2) + ppm = pp.u16() + + # The LEDs are connected to two 595's, interleaved R,G,R,G... + nl = (ppm-300)/1700.0 + print("%d ppm CO₂, numleds %f" % (ppm, nl*8)) + + numb = 0 + for i in range(0,8): + if nl >= i*0.125: + if i < 3: + numb |= 2<<(i*2) + elif i < 6: + numb |= 3<<(i*2) + else: + numb |= 1<<(i*2) + + leds.load([(numb&0xFF00)>>8,numb&0xFF]) + + + time.sleep(1) + diff --git a/demo_ndir_usart.py b/demo_ndir_usart.py new file mode 100644 index 0000000..0e98d89 --- /dev/null +++ b/demo_ndir_usart.py @@ -0,0 +1,18 @@ +import time + +import gex + +# basic NDIR CO2 sensor readout + +with gex.Client(gex.TrxRawUSB()) as client: + ser = gex.USART(client, 'ser') + + while True: + ser.clear_buffer() + ser.write([0xFF, 0x01, 0x86, 0, 0, 0, 0, 0, 0x79]) + data = ser.receive(9, decode=None) + + pp = gex.PayloadParser(data, endian="big").skip(2) + print("%d ppm CO₂" % pp.u16()) + + time.sleep(1) diff --git a/demo_neo2.py b/demo_neo2.py new file mode 100644 index 0000000..3e00be7 --- /dev/null +++ b/demo_neo2.py @@ -0,0 +1,17 @@ +#!/bin/env python3 +import gex +import time + +# play a little neopixel animation as a demo + +with gex.Client(gex.TrxRawUSB()) as client: + # Neopixel strip + strip = gex.Neopixel(client, 'npx') + # Load RGB to the strip + strip.load([0xFF0000, 0xFFFF00, 0x00FF00, 0x0000FF, 0xFF00FF]) + + for i in range(0,255): + strip.load([0xFF0000+i, 0xFFFF00, 0x00FF00, 0x0000FF, 0xFF00FF]) + time.sleep(0.01) + + strip.clear() diff --git a/demo_neo3.py b/demo_neo3.py new file mode 100644 index 0000000..ea9aadd --- /dev/null +++ b/demo_neo3.py @@ -0,0 +1,39 @@ +#!/bin/env python3 +import gex +import time + +# this shows a spinny animation on a 30-pixel strip forming a circle + +def draw_comet(buf, index): + r = 0xFF + g = 0x22 + b = 0x00 + steps = 5 + fades = [0.05, 1, 0.5, 0.1, 0.05] + + for i in range(steps): + fade = fades[i] + buf[(len(buf) + index - i)%len(buf)] = \ + round(r * fade)<<16 | \ + round(g * fade)<<8 | \ + round(b * fade) + +with gex.Client(gex.TrxRawUSB()) as client: + # Neopixel strip + strip = gex.Neopixel(client, 'npx') + + markers = [0, 15] + for i in range(1000): + buf = [0]*30 + for j in range(len(markers)): + n = markers[j] + + draw_comet(buf, n) + + n = n + 1 if n < len(buf)-1 else 0 + markers[j] = n + + strip.load(buf) + time.sleep(0.02) + + strip.clear() diff --git a/demo_neopixel.py b/demo_neopixel.py new file mode 100644 index 0000000..5eb8a96 --- /dev/null +++ b/demo_neopixel.py @@ -0,0 +1,11 @@ +#!/bin/env python3 +import gex + +# the most basic neopixel demo + +with gex.Client(gex.TrxRawUSB()) as client: + # Neopixel strip + strip = gex.Neopixel(client, 'npx') + # Load RGB to the strip + strip.load([0xFF0000, 0x00FF00, 0x0000FF, 0xFF00FF]) + diff --git a/demo_nrf24.py b/demo_nrf24.py new file mode 100644 index 0000000..3329876 --- /dev/null +++ b/demo_nrf24.py @@ -0,0 +1,136 @@ +import time + +import gex +import sx_fsk as sx + + +# this is a demo with two NRF24L01+ modules connected to SPI and some GPIO. + +class Nrf: + def __init__(self, ce: gex.DOut, irq: gex.DIn, spi: gex.SPI, num): + self.snum = num + self.ce = ce + self.irq = irq + self.spi = spi + + def rd(self, addr, count=1): + # addr 0-31 + return self.spi.query(self.snum, [addr&0x1F], rlen=count) + + def wr(self, addr, vals): + if type(vals) == int: + vals = [vals] + + # addr 0-31 + ba = bytearray() + ba.append(addr | 0x20) + ba.extend(vals) + self.spi.write(self.snum, ba) + + def rd_payload(self, count): + """ Read a received payload """ + return self.spi.query(self.snum, [0x61], rlen=count) + + def wr_payload(self, pld): + """ Write a payload """ + ba = bytearray() + ba.append(0xA0) + ba.extend(pld) + self.spi.write(self.snum, ba) + + def flush_tx(self): + self.spi.write(self.snum, [0xE1]) + + def flush_rx(self): + self.spi.write(self.snum, [0xE2]) + + def reuse_tx_pld(self): + self.spi.write(self.snum, [0xE3]) + + def get_pld_len(self): + """ Read length of the first Rx payload in the FIFO - available only if dyn len enabled """ + return self.spi.query(self.snum, [0x60], rlen=1)[0] + + def wr_ack_payload(self, pipe, pld): + """ Write a payload to be attached to the next sent ACK """ + ba = bytearray() + ba.append(0xA8|(pipe&0x7)) + ba.extend(pld) + self.spi.write(self.snum, ba) + + def wr_payload_noack(self, pld): + """ Send a payload without ACK """ + ba = bytearray() + ba.append(0xB0) + ba.extend(pld) + self.spi.write(self.snum, ba) + + def status(self): + """ Send a payload without ACK """ + return self.spi.query(self.snum, [0xFF], rlen=1, rskip=0)[0] + + +with gex.Client(gex.TrxRawUSB()) as client: + spi = gex.SPI(client, 'spi') + ce = gex.DOut(client, 'ce') + irq = gex.DIn(client, 'irq') + + a = Nrf(ce, irq, spi, 0) + b = Nrf(ce, irq, spi, 1) + a.flush_tx() + a.flush_rx() + b.flush_tx() + b.flush_rx() + + # transmit demo + # a is PTX, b is PRX + ce.clear(0b11) + + # a_adr = [0xA1,0xA2,0xA3,0xA4,0x01] + b_pipe0_adr = [0xA1, 0xA2, 0xA3, 0xA4, 0x02] + + # --- Configure A for Tx of a 32-long payload --- + + # PWR DN - simulate reset + a.wr(0x00, 0) + b.wr(0x00, 0) + time.sleep(0.001) + + a.wr(0x00, 0b00001010) # set PWR_ON=1, EN_CRC=1, all irq enabled + a.wr_payload([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31]) + + chnl = 5 + + # Set B's address as target and also pipe 0 Rx (used for ack) + a.wr(0x10, b_pipe0_adr) # target addr + a.wr(0x0A, b_pipe0_adr) # pipe 0 rx addr for ACK + a.wr(0x04, 0b00101111) # configure retransmit + a.wr(0x05, chnl) + + # --- Configure B for Rx --- + + b.wr(0x00, 0b00001011) # set PWR_ON=1, PRIM_RX=1, EN_CRC=1, all irq enabled + b.wr(0x02, 0b000001) # enable pipe 0 + b.wr(0x11, 32) # set pipe 0 len to 11 + b.wr(0x0A, b_pipe0_adr) # set pipe 0's address + b.wr(0x05, chnl) + + ce.set(0b10) # CE high for B + time.sleep(0.01) + + ce.pulse_us(us=10, pins=0b01) # Pulse A's CE + # + # testing B's FIFO by sending another payload... + a.wr_payload([0xFF, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30]) + ce.pulse_us(us=20, pins=0b01) # Pulse A's CE + + time.sleep(0.01) + + print("A's status after Tx: %02x" % a.status()) + print("B's status after Tx: %02x" % b.status()) + + ce.clear(0b11) + + # read the two payloads + print(b.rd_payload(32)) + print(b.rd_payload(32)) diff --git a/demo_pulse.py b/demo_pulse.py new file mode 100644 index 0000000..95481a0 --- /dev/null +++ b/demo_pulse.py @@ -0,0 +1,11 @@ +#!/bin/env python3 +import gex +import time + +# generating a pulse on gpio, test of the unit + +with gex.Client(gex.TrxRawUSB()) as client: + out = gex.DOut(client, 'out') + + out.pulse_us([0], 20) + out.pulse_us([3], 10) \ No newline at end of file diff --git a/demo_pymodoro.py b/demo_pymodoro.py new file mode 100644 index 0000000..322194f --- /dev/null +++ b/demo_pymodoro.py @@ -0,0 +1,126 @@ +import time +import gex + +# GEX pomodoro timer + +# button btn +# neopixel neo + +# this is an example of using GEX as a user interface. +# for practical use it would be better to make this into a standalone device with a custom firmware. + +WK_TIME = 25 +BK_TIME = 5 +LIGHT_CNT = 30 + +PH_BREAK = 'Break' +PH_BREAK_OVER = 'BreakOver' +PH_WORK = 'Work' +PH_WORK_OVER = 'WorkOver' + +class Pymodoro: + def __init__(self): + self.phase = PH_BREAK_OVER + self.work_s = 0 + self.break_s = 0 + self.color = 0x000000 + self.colors = [0x000000 for _ in range(0, LIGHT_CNT)] + + self.client = gex.Client(gex.TrxRawUSB()) + self.btn = gex.DIn(self.client, 'btn') + self.neo = gex.Neopixel(self.client, 'neo') + self.btn.on_trigger([0], self.on_btn) + + self.switch(PH_BREAK_OVER) + self.display() + + def display(self): + self.neo.load(self.colors) + + def on_btn(self, snapshot, timestamp): + if self.phase == PH_BREAK_OVER: + self.switch(PH_WORK) + + elif self.phase == PH_WORK: + self.switch(PH_WORK) # restart + + elif self.phase == PH_WORK_OVER: + self.switch(PH_BREAK) + + def switch(self, phase): + print("Switch to %s" % phase) + + if phase == PH_BREAK: + self.color = 0x009900 + self.break_s = BK_TIME * 60 + + elif phase == PH_BREAK_OVER: + self.color = 0x662200 + + elif phase == PH_WORK: + self.color = 0x990000 + self.work_s = WK_TIME * 60 + + elif phase == PH_WORK_OVER: + self.color = 0x113300 + + self.colors = [self.color for _ in range(0, LIGHT_CNT)] + self.phase = phase + + def show_progress(self, dark, total): + per_light = total / LIGHT_CNT + lights = dark / per_light + + lights /= 2 + + remainder = float(lights - int(lights)) + if remainder == 0: + remainder = 1 + + # print("lights %f, remainder %f" % (lights, remainder)) + for i in range(0, int(LIGHT_CNT/2)): + if i < int((LIGHT_CNT/2)-lights): + c = 0x000000 + elif i == int((LIGHT_CNT/2)-lights): + r = (self.color&0xFF0000)>>16 + g = (self.color&0xFF00)>>8 + b = self.color&0xFF + c = (int(r*remainder))<<16 | (int(g*remainder))<<8 | (int(b*remainder)) + else: + c = self.color + + self.colors[i] = c + self.colors[LIGHT_CNT - 1 - i] = c + + def tick(self, elapsed): + if self.phase == PH_BREAK: + self.break_s -= elapsed + # print("Break remain: %d s" % self.break_s) + self.show_progress(self.break_s, BK_TIME * 60) + + if self.break_s <= 0: + self.switch(PH_BREAK_OVER) + + elif self.phase == PH_WORK: + self.work_s -= elapsed + # print("Work remain: %d s" % self.work_s) + self.show_progress(self.work_s, WK_TIME * 60) + + if self.work_s <= 0: + self.switch(PH_WORK_OVER) + + self.display() + + def run(self): + step=0.5 + try: + while True: + time.sleep(step) + self.tick(step) + except KeyboardInterrupt: + self.client.close() + print() # this puts the ^C on its own line + + +a = Pymodoro() +a.run() diff --git a/demo_transient.py b/demo_transient.py new file mode 100644 index 0000000..8eac4ce --- /dev/null +++ b/demo_transient.py @@ -0,0 +1,37 @@ +#!/bin/env python3 +import time + +import gex +import numpy as np +from matplotlib import pyplot as plt + +from scipy.io import wavfile + +# catching a transient + +with gex.Client(gex.TrxRawUSB()) as client: + adc = gex.ADC(client, 'adc') + + rate=50000 + fs = adc.set_sample_rate(rate) + + d = None + + def x(report): + global d + print("capt") + d = report + + adc.on_trigger(x) + adc.setup_trigger(0, 50, 600, edge='rising', pretrigger=100) + adc.arm() + + time.sleep(2) + + if d is not None: + plt.plot(d.data, 'r-', lw=1) + plt.grid() + plt.show() + else: + print("Nothing rx") + diff --git a/file.wav b/file.wav new file mode 100644 index 0000000..87fd659 Binary files /dev/null and b/file.wav differ diff --git a/gex b/gex new file mode 160000 index 0000000..3a5ac05 --- /dev/null +++ b/gex @@ -0,0 +1 @@ +Subproject commit 3a5ac05d9db965f86188929f8f56a68ee994827d diff --git a/lightnings/lightning-2018-04-23T22:16:46.261627.npy b/lightnings/lightning-2018-04-23T22:16:46.261627.npy new file mode 100644 index 0000000..69f69fb Binary files /dev/null and b/lightnings/lightning-2018-04-23T22:16:46.261627.npy differ diff --git a/lightnings/lightning-2018-04-23T22:34:32.534488.npy b/lightnings/lightning-2018-04-23T22:34:32.534488.npy new file mode 100644 index 0000000..acdb9f5 Binary files /dev/null and b/lightnings/lightning-2018-04-23T22:34:32.534488.npy differ diff --git a/lightnings/lightning-2018-04-23T22:35:42.852678.npy b/lightnings/lightning-2018-04-23T22:35:42.852678.npy new file mode 100644 index 0000000..ae5bca4 Binary files /dev/null and b/lightnings/lightning-2018-04-23T22:35:42.852678.npy differ diff --git a/lightnings/lightning-2018-04-23T22:41:39.330784.npy b/lightnings/lightning-2018-04-23T22:41:39.330784.npy new file mode 100644 index 0000000..1879096 Binary files /dev/null and b/lightnings/lightning-2018-04-23T22:41:39.330784.npy differ diff --git a/lightnings/lightning-2018-04-23T22:41:42.047079.npy b/lightnings/lightning-2018-04-23T22:41:42.047079.npy new file mode 100644 index 0000000..2cae050 Binary files /dev/null and b/lightnings/lightning-2018-04-23T22:41:42.047079.npy differ diff --git a/lightnings/lightning-2018-04-23T22:48:26.142246.npy b/lightnings/lightning-2018-04-23T22:48:26.142246.npy new file mode 100644 index 0000000..9c9490b Binary files /dev/null and b/lightnings/lightning-2018-04-23T22:48:26.142246.npy differ diff --git a/lightnings/lightning-2018-04-23T22:51:43.018760.npy b/lightnings/lightning-2018-04-23T22:51:43.018760.npy new file mode 100644 index 0000000..3b84422 Binary files /dev/null and b/lightnings/lightning-2018-04-23T22:51:43.018760.npy differ diff --git a/lightnings/lightning-2018-04-23T22:55:34.559141.npy b/lightnings/lightning-2018-04-23T22:55:34.559141.npy new file mode 100644 index 0000000..be5be99 Binary files /dev/null and b/lightnings/lightning-2018-04-23T22:55:34.559141.npy differ diff --git a/lightnings/lightning-2018-04-23T22:59:13.545024.npy b/lightnings/lightning-2018-04-23T22:59:13.545024.npy new file mode 100644 index 0000000..fdb3332 Binary files /dev/null and b/lightnings/lightning-2018-04-23T22:59:13.545024.npy differ diff --git a/lightnings/lightning-2018-04-23T23:02:38.393510.npy b/lightnings/lightning-2018-04-23T23:02:38.393510.npy new file mode 100644 index 0000000..89e49f6 Binary files /dev/null and b/lightnings/lightning-2018-04-23T23:02:38.393510.npy differ diff --git a/lightnings/lightning-2018-04-23T23:02:58.074542.npy b/lightnings/lightning-2018-04-23T23:02:58.074542.npy new file mode 100644 index 0000000..33e4878 Binary files /dev/null and b/lightnings/lightning-2018-04-23T23:02:58.074542.npy differ diff --git a/lightnings/lightning-2018-04-23T23:03:58.234612.npy b/lightnings/lightning-2018-04-23T23:03:58.234612.npy new file mode 100644 index 0000000..fb80be3 Binary files /dev/null and b/lightnings/lightning-2018-04-23T23:03:58.234612.npy differ diff --git a/lightnings/lightning-2018-04-23T23:06:25.165868.npy b/lightnings/lightning-2018-04-23T23:06:25.165868.npy new file mode 100644 index 0000000..856813e Binary files /dev/null and b/lightnings/lightning-2018-04-23T23:06:25.165868.npy differ diff --git a/lightnings/lightning-2018-04-23T23:07:45.789655.npy b/lightnings/lightning-2018-04-23T23:07:45.789655.npy new file mode 100644 index 0000000..8cbceda Binary files /dev/null and b/lightnings/lightning-2018-04-23T23:07:45.789655.npy differ diff --git a/lightnings/lightning-2018-04-23T23:10:08.713982.npy b/lightnings/lightning-2018-04-23T23:10:08.713982.npy new file mode 100644 index 0000000..ab8879e Binary files /dev/null and b/lightnings/lightning-2018-04-23T23:10:08.713982.npy differ diff --git a/lightnings/lightning-2018-04-23T23:14:20.084082.npy b/lightnings/lightning-2018-04-23T23:14:20.084082.npy new file mode 100644 index 0000000..266aa06 Binary files /dev/null and b/lightnings/lightning-2018-04-23T23:14:20.084082.npy differ diff --git a/lightnings/lightning-2018-04-23T23:22:11.489806.npy b/lightnings/lightning-2018-04-23T23:22:11.489806.npy new file mode 100644 index 0000000..d0b6cd8 Binary files /dev/null and b/lightnings/lightning-2018-04-23T23:22:11.489806.npy differ diff --git a/loratest.txt b/loratest.txt new file mode 100644 index 0000000..683c7c9 --- /dev/null +++ b/loratest.txt @@ -0,0 +1,78 @@ +## UNITS.INI +## GEX v0.0.1 on STM32F072-HUB +## built Mar 17 2018 at 17:53:15 + +[UNITS] +# Create units by adding their names next to a type (e.g. DO=A,B), +# remove the same way. Reload to update the unit sections below. + +# Digital output +DO=rst1,rst2 +# Digital input with triggers +DI= +# Neopixel RGB LED strip +NPX= +# I2C master +I2C= +# SPI master +SPI=spi +# Serial port +USART= +# 1-Wire master +1WIRE= +# Analog/digital converter +ADC= +# Shift register driver (595, 4094) +SIPO= +# Frequency and pulse measurement +FCAP= +# Capacitive touch sensing +TOUCH= +# Simple PWM output +PWMDIM= +# Two-channel analog output with waveforms +DAC= + +[DO:rst1@2] +# Port name +port=B +# Pins (comma separated, supports ranges) +pins=2 +# Initially high pins +initial=2 +# Open-drain pins +open-drain= + +[DO:rst2@3] +# Port name +port=B +# Pins (comma separated, supports ranges) +pins=6 +# Initially high pins +initial=6 +# Open-drain pins +open-drain= + +[SPI:spi@1] +# Peripheral number (SPIx) +device=1 +# Pin mappings (SCK,MISO,MOSI) +# SPI1: (0) A5,A6,A7 (1) B3,B4,B5 +# SPI2: (0) B13,B14,B15 +remap=1 + +# Prescaller: 2,4,8,...,256 +prescaller=64 +# Clock polarity: 0,1 (clock idle level) +cpol=0 +# Clock phase: 0,1 (active edge, 0-first, 1-second) +cpha=0 +# Transmit only, disable MISO +tx-only=N +# Bit order (LSB or MSB first) +first-bit=MSB + +# SS port name +port=B +# SS pins (comma separated, supports ranges) +pins=1-0 diff --git a/mat_sampling.m b/mat_sampling.m new file mode 100644 index 0000000..7a42985 --- /dev/null +++ b/mat_sampling.m @@ -0,0 +1,24 @@ +% this is an example of sampling the ADC from Matlab and then plotting a +% FFT graph. The ADC unit called 'adc' is configured to use PA1 as Ch. 0 + +%transport = py.gex.TrxSerialThread(pyargs('port', '/dev/ttyUSB1', 'baud', 57600)); +transport = py.gex.TrxRawUSB(); +client = py.gex.Client(transport); +adc = py.gex.ADC(client, 'adc'); + +L=1000; +Fs=1000; + +adc.set_sample_rate(uint32(Fs)); +data = adc.capture(uint32(L)); +data = double(py.array.array('f',data)); + +Y = fft(data); +P2 = abs(Y/L); +P1 = P2(1:L/2+1); +P1(2:end-1) = 2*P1(2:end-1); + +f = Fs*(0:(L/2))/L; +plot(f,P1) + +client.close() diff --git a/misc.py b/misc.py new file mode 100644 index 0000000..3aaa213 --- /dev/null +++ b/misc.py @@ -0,0 +1,309 @@ +#!/bin/env python3 +import time + +import numpy as np +from matplotlib import pyplot as plt + +import gex + +transport = gex.TrxRawUSB(sn='0029002F-42365711-32353530') +#transport = gex.TrxSerialSync(port='/dev/ttyACM0') + +with gex.Client(transport) as client: + # + # if True: + # s = client.ini_read() + # print(s) + # client.ini_write(s) + + if True: + sipo = gex.SIPO(client, 'sipo') + sipo.load([[0xA5], [0xFF]]) + + if False: + adc = gex.ADC(client, 'adc') + print("Enabled channels:", adc.get_channels()) + + adc.set_smoothing_factor(0.9) + + while True: + raw = adc.read_raw() + smooth = adc.read_smooth() + print("IN1 = %d (%.2f), Tsens = %d (%.2f), Vrefint = %d (%.2f)" % (raw[1], smooth[1], + raw[16], smooth[16], + raw[17], smooth[17])) + time.sleep(0.5) + + if False: + adc = gex.ADC(client, 'adc') + + adc.set_active_channels([1]) + fs = adc.set_sample_rate(1000) + + data = adc.capture(1000) + + if data is not None: + plt.plot(data, 'r-', lw=1) + plt.show() + else: + print("Nothing rx") + + + # for r in range(0,8): + # adc.set_sample_time(r) + # data = adc.capture(10000) + # print("sr = %d" % r) + # std = np.std(data) + # print(std) + + + # + # global data + # data = None + # + # def capture(rpt): + # global data + # print("trig'd, %s" % rpt) + # data = rpt.data + # # + # # adc.setup_trigger(channel=1, + # # level=700, + # # count=20000, + # # pretrigger=100, + # # auto=False, + # # edge="falling", + # # holdoff=200, + # # handler=capture) + # + # # adc.arm() + # + # data = adc.capture(1000) + # + # if data is not None: + # plt.plot(data, 'r.', lw=1) + # plt.show() + # else: + # print("Nothing rx") + + # plt.magnitude_spectrum(data[:,0], Fs=fs, scale='dB', color='C1') + # plt.show() + + # def lst(data): + # if data is not None: + # print("Rx OK") #data + # else: + # print("Closed.") + + # adc.stream_start(lst) + # time.sleep(3) + # adc.stream_stop() + # print("Done.") + + + + + # time.sleep(.1) + # print(adc.get_sample_rate()) + # time.sleep(.1) + + # adc.stream_stop() + # time.sleep(5) + + # print(adc.capture(200, 5)) + + # adc.setup_trigger(channel=1, + # level=700, + # count=100, + # pretrigger=15, + # auto=True, + # edge="falling", + # holdoff=200, + # handler=lambda rpt: print("Report: %s" % rpt)) + # + # print("Armed") + # adc.arm() + # print("Sleep...") + # # adc.force() + # # + # # # adc.disarm() + # time.sleep(5) + # adc.disarm() + + # print(adc.capture(200, 50)) + + # adc.stream_start(lambda data: print(data)) + # time.sleep(20) + # adc.stream_stop() + + + # print(adc.read_raw()) + + # time.sleep(1) + # print("Rx: ", resp) + # adc.abort() + + if False: + s = client.ini_read() + print(s) + client.ini_write(s) + + # search the bus + if False: + ow = gex.OneWire(client, 'ow') + print("Devices:", ow.search()) + + # search the bus for alarm + if False: + ow = gex.OneWire(client, 'ow') + print("Presence: ", ow.test_presence()) + print("Devices w alarm:", ow.search(alarm=True)) + + # simple 1w check + if False: + ow = gex.OneWire(client, 'ow') + print("Presence: ", ow.test_presence()) + print("ROM: 0x%016x" % ow.read_address()) + print("Scratch:", ow.query([0xBE], rcount=9, addr=0x7100080104c77610, as_array=True)) + + # testing ds1820 temp meas without polling + if False: + ow = gex.OneWire(client, 'ow') + print("Presence: ", ow.test_presence()) + print("Starting measure...") + ow.write([0x44]) + time.sleep(1) + print("Scratch:", ow.query([0xBE], 9)) + + # testing ds1820 temp meas with polling + if False: + ow = gex.OneWire(client, 'ow') + print("Presence: ", ow.test_presence()) + print("Starting measure...") + ow.write([0x44]) + ow.wait_ready() + data = ow.query([0xBE], 9) + + pp = gex.PayloadParser(data) + + temp = pp.i16()/2.0 + th = pp.i8() + tl = pp.i8() + reserved = pp.i16() + remain = float(pp.u8()) + perc = float(pp.u8()) + + realtemp = temp - 0.25+(perc-remain)/perc + print("Temperature = %f °C (th %d, tl %d)" % (realtemp, th, tl)) + + + if False: + buf = client.bulk_read(gex.MSG_INI_READ) + print(buf.decode('utf-8')) + + pb = gex.PayloadBuilder() + pb.u32(len(buf)) + + client.bulk_write(gex.MSG_INI_WRITE, pld=pb.close(), bulk=buf) + + if False: + leds = gex.DOut(client, 'strip') + + nn = 3 + for i in range(0,20): + leds.write(nn) + time.sleep(.05) + nn<<=1 + nn|=(nn&0x40)>>6 + nn=nn&0x3F + leds.clear(0xFF) + + if False: + leds = gex.DOut(client, 'bargraph') + + for i in range(0,0x41): + leds.write(i&0x3F) + time.sleep(.1) + + if False: + leds = gex.DOut(client, 'TST') + + for i in range(0, 0x41): + #leds.write(i & 0x3F) + leds.toggle(0xFF) + time.sleep(.1) + + if False: + btn = gex.DIn(client, 'btn') + strip = gex.DOut(client, 'strip') + + for i in range(0, 10000): + b = btn.read() + strip.write((b << 2) | ((~b) & 1)) + time.sleep(.02) + + if False: + neo = gex.Neopixel(client, 'npx') + + print('We have %d neopixels.\n' % neo.get_len()) + + #neo.load([0xF0F0F0,0,0,0xFF0000]) + + # generate a little animation... + for i in range(0,512): + j = i if i < 256 else 255-(i-256) + neo.load([0x660000+j, 0x3300FF-j, 0xFFFF00-(j<<8), 0x0000FF+(j<<8)-j]) + time.sleep(.001) + + neo.load([0,0,0,0]) + + if False: + i2c = gex.I2C(client, 'i2c') + + # i2c.write(0x76, payload=[0xD0]) + # print(i2c.read(0x76, count=1)) + + print(i2c.read_reg(0x76, 0xD0)) + print("%x" % i2c.read_reg(0x76, 0xF9, width=3, endian='big')) + + i2c.write_reg(0x76, 0xF4, 0xFA) + print(i2c.read_reg(0x76, 0xF4)) + + if False: + spi = gex.SPI(client, 'spi') + spi.multicast(1, [0xDE, 0xAD, 0xBE, 0xEF]) + print(spi.query(0, [0xDE, 0xAD, 0xBE, 0xEF], rlen=4, rskip=1))# + + if False: + usart = gex.USART(client, 'serial') + usart.listen(lambda x: print("RX >%s<" % x)) + for i in range(0,100): + # Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque ac bibendum lectus, ut pellentesque sem. Suspendisse ultrices felis eu laoreet luctus. Nam sollicitudin ultrices leo, ac condimentum enim vulputate quis. Suspendisse cursus tortor nibh, ac consectetur eros dapibus quis. Aliquam erat volutpat. Duis sagittis eget nunc nec condimentum. Aliquam erat volutpat. Phasellus molestie sem vitae quam semper convallis. + + usart.write("""_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n_.-"_.-"_.-"_.-"_.-"_.-"_.-"_.\r\n""".encode(), sync=True) + + # time.sleep(.001) + + if False: + usart = gex.USART(client, 'serial') + usart.listen(lambda x: print(x, end='',flush=True)) + while True: + client.poll() + + if False: + print(client.ini_read()) + + trig = gex.DIn(client, 'trig') + print(trig.read()) + + # Two pins are defined, PA10 and PA7. PA10 is the trigger, in the order from smallest to highest number 1 + trig.arm(0b10) + trig.on_trigger(0b10, lambda snap,ts: print("snap 0x%X, ts %d" % (snap,ts))) + + while True: + client.poll() + + # + # for n in range(0,100): + # print(n) + # s = client.ini_read() + # client.ini_write(s) diff --git a/nrf_config.ini b/nrf_config.ini new file mode 100644 index 0000000..02624fc --- /dev/null +++ b/nrf_config.ini @@ -0,0 +1,86 @@ +## UNITS.INI +## GEX v0.1.0 on STM32F072-HUB +## built Mar 28 2018 at 00:42:03 + +[UNITS] +# Create units by adding their names next to a type (e.g. DO=A,B), +# remove the same way. Reload to update the unit sections below. + +# Digital output +DO=ce +# Digital input with triggers +DI=irq +# Neopixel RGB LED strip +NPX= +# I2C master +I2C= +# SPI master +SPI=spi +# Serial port +USART= +# 1-Wire master +1WIRE= +# Analog/digital converter +ADC= +# Shift register driver (595, 4094) +SIPO= +# Frequency and pulse measurement +FCAP= +# Capacitive touch sensing +TOUCH= +# Simple PWM output +PWMDIM= +# Two-channel analog output with waveforms +DAC= + +[DO:ce@2] +# Port name +port=B +# Pins (comma separated, supports ranges) +pins=6, 2 +# Initially high pins +initial= +# Open-drain pins +open-drain= + +[DI:irq@3] +# Port name +port=B +# Pins (comma separated, supports ranges) +pins=8-7 +# Pins with pull-up +pull-up= +# Pins with pull-down +pull-down= + +# Trigger pins activated by rising/falling edge +trig-rise= +trig-fall= +# Trigger pins auto-armed by default +auto-trigger= +# Triggers hold-off time (ms) +hold-off=100 + +[SPI:spi@1] +# Peripheral number (SPIx) +device=1 +# Pin mappings (SCK,MISO,MOSI) +# SPI1: (0) A5,A6,A7 (1) B3,B4,B5 +# SPI2: (0) B13,B14,B15 +remap=1 + +# Prescaller: 2,4,8,...,256 +prescaller=64 +# Clock polarity: 0,1 (clock idle level) +cpol=0 +# Clock phase: 0,1 (active edge, 0-first, 1-second) +cpha=1 +# Transmit only, disable MISO +tx-only=N +# Bit order (LSB or MSB first) +first-bit=MSB + +# SS port name +port=B +# SS pins (comma separated, supports ranges) +pins=1-0 diff --git a/show_nparray.py b/show_nparray.py new file mode 100755 index 0000000..d7f4774 --- /dev/null +++ b/show_nparray.py @@ -0,0 +1,15 @@ +#!/bin/env python3 +import time + +import sys + +import gex +import numpy as np +from matplotlib import pyplot as plt +import datetime + +from scipy.io import wavfile + +data = np.load(sys.argv[1]) +plt.plot(data, 'r-', lw=1) +plt.show() diff --git a/sx_fsk.py b/sx_fsk.py new file mode 100644 index 0000000..7cf39cd --- /dev/null +++ b/sx_fsk.py @@ -0,0 +1,1109 @@ +REG_FIFO = 0x00 +# Common settings +REG_OPMODE = 0x01 +REG_BITRATEMSB = 0x02 +REG_BITRATELSB = 0x03 +REG_FDEVMSB = 0x04 +REG_FDEVLSB = 0x05 +REG_FRFMSB = 0x06 +REG_FRFMID = 0x07 +REG_FRFLSB = 0x08 +# Tx settings +REG_PACONFIG = 0x09 +REG_PARAMP = 0x0A +REG_OCP = 0x0B +# Rx settings +REG_LNA = 0x0C +REG_RXCONFIG = 0x0D +REG_RSSICONFIG = 0x0E +REG_RSSICOLLISION = 0x0F +REG_RSSITHRESH = 0x10 +REG_RSSIVALUE = 0x11 +REG_RXBW = 0x12 +REG_AFCBW = 0x13 +REG_OOKPEAK = 0x14 +REG_OOKFIX = 0x15 +REG_OOKAVG = 0x16 +REG_RES17 = 0x17 +REG_RES18 = 0x18 +REG_RES19 = 0x19 +REG_AFCFEI = 0x1A +REG_AFCMSB = 0x1B +REG_AFCLSB = 0x1C +REG_FEIMSB = 0x1D +REG_FEILSB = 0x1E +REG_PREAMBLEDETECT = 0x1F +REG_RXTIMEOUT1 = 0x20 +REG_RXTIMEOUT2 = 0x21 +REG_RXTIMEOUT3 = 0x22 +REG_RXDELAY = 0x23 +# Oscillator settings +REG_OSC = 0x24 +# Packet handler settings +REG_PREAMBLEMSB = 0x25 +REG_PREAMBLELSB = 0x26 +REG_SYNCCONFIG = 0x27 +REG_SYNCVALUE1 = 0x28 +REG_SYNCVALUE2 = 0x29 +REG_SYNCVALUE3 = 0x2A +REG_SYNCVALUE4 = 0x2B +REG_SYNCVALUE5 = 0x2C +REG_SYNCVALUE6 = 0x2D +REG_SYNCVALUE7 = 0x2E +REG_SYNCVALUE8 = 0x2F +REG_PACKETCONFIG1 = 0x30 +REG_PACKETCONFIG2 = 0x31 +REG_PAYLOADLENGTH = 0x32 +REG_NODEADRS = 0x33 +REG_BROADCASTADRS = 0x34 +REG_FIFOTHRESH = 0x35 +# SM settings +REG_SEQCONFIG1 = 0x36 +REG_SEQCONFIG2 = 0x37 +REG_TIMERRESOL = 0x38 +REG_TIMER1COEF = 0x39 +REG_TIMER2COEF = 0x3A +# Service settings +REG_IMAGECAL = 0x3B +REG_TEMP = 0x3C +REG_LOWBAT = 0x3D +# Status +REG_IRQFLAGS1 = 0x3E +REG_IRQFLAGS2 = 0x3F +# I/O settings +REG_DIOMAPPING1 = 0x40 +REG_DIOMAPPING2 = 0x41 +# Version +REG_VERSION = 0x42 +# Additional settings +REG_AGCREF = 0x43 +REG_AGCTHRESH1 = 0x44 +REG_AGCTHRESH2 = 0x45 +REG_AGCTHRESH3 = 0x46 +REG_PLLHOP = 0x4B +REG_TCXO = 0x58 +REG_PADAC = 0x5A +REG_PLL = 0x5C +REG_PLLLOWPN = 0x5E +REG_FORMERTEMP = 0x6C +REG_BITRATEFRAC = 0x70 + +""" + * ============================================================================ + * SX1272 FSK bits control definition + * ============================================================================ +""" + +""" + * RegFifo +""" + +""" + * RegOpMode +""" +RF_OPMODE_LONGRANGEMODE_MASK = 0x7F +RF_OPMODE_LONGRANGEMODE_OFF = 0x00 +RF_OPMODE_LONGRANGEMODE_ON = 0x80 + +RF_OPMODE_MODULATIONTYPE_MASK = 0x9F +RF_OPMODE_MODULATIONTYPE_FSK = 0x00 # Default +RF_OPMODE_MODULATIONTYPE_OOK = 0x20 + +RF_OPMODE_MODULATIONSHAPING_MASK = 0xE7 +RF_OPMODE_MODULATIONSHAPING_00 = 0x00 # Default +RF_OPMODE_MODULATIONSHAPING_01 = 0x08 +RF_OPMODE_MODULATIONSHAPING_10 = 0x10 +RF_OPMODE_MODULATIONSHAPING_11 = 0x18 + +RF_OPMODE_MASK = 0xF8 +RF_OPMODE_SLEEP = 0x00 +RF_OPMODE_STANDBY = 0x01 # Default +RF_OPMODE_SYNTHESIZER_TX = 0x02 +RF_OPMODE_TRANSMITTER = 0x03 +RF_OPMODE_SYNTHESIZER_RX = 0x04 +RF_OPMODE_RECEIVER = 0x05 + +""" + * RegBitRate (bits/sec) +""" +RF_BITRATEMSB_1200_BPS = 0x68 +RF_BITRATELSB_1200_BPS = 0x2B +RF_BITRATEMSB_2400_BPS = 0x34 +RF_BITRATELSB_2400_BPS = 0x15 +RF_BITRATEMSB_4800_BPS = 0x1A # Default +RF_BITRATELSB_4800_BPS = 0x0B # Default +RF_BITRATEMSB_9600_BPS = 0x0D +RF_BITRATELSB_9600_BPS = 0x05 +RF_BITRATEMSB_15000_BPS = 0x08 +RF_BITRATELSB_15000_BPS = 0x55 +RF_BITRATEMSB_19200_BPS = 0x06 +RF_BITRATELSB_19200_BPS = 0x83 +RF_BITRATEMSB_38400_BPS = 0x03 +RF_BITRATELSB_38400_BPS = 0x41 +RF_BITRATEMSB_76800_BPS = 0x01 +RF_BITRATELSB_76800_BPS = 0xA1 +RF_BITRATEMSB_153600_BPS = 0x00 +RF_BITRATELSB_153600_BPS = 0xD0 +RF_BITRATEMSB_57600_BPS = 0x02 +RF_BITRATELSB_57600_BPS = 0x2C +RF_BITRATEMSB_115200_BPS = 0x01 +RF_BITRATELSB_115200_BPS = 0x16 +RF_BITRATEMSB_12500_BPS = 0x0A +RF_BITRATELSB_12500_BPS = 0x00 +RF_BITRATEMSB_25000_BPS = 0x05 +RF_BITRATELSB_25000_BPS = 0x00 +RF_BITRATEMSB_50000_BPS = 0x02 +RF_BITRATELSB_50000_BPS = 0x80 +RF_BITRATEMSB_100000_BPS = 0x01 +RF_BITRATELSB_100000_BPS = 0x40 +RF_BITRATEMSB_150000_BPS = 0x00 +RF_BITRATELSB_150000_BPS = 0xD5 +RF_BITRATEMSB_200000_BPS = 0x00 +RF_BITRATELSB_200000_BPS = 0xA0 +RF_BITRATEMSB_250000_BPS = 0x00 +RF_BITRATELSB_250000_BPS = 0x80 +RF_BITRATEMSB_32768_BPS = 0x03 +RF_BITRATELSB_32768_BPS = 0xD1 + +""" + * RegFdev (Hz) +""" +RF_FDEVMSB_2000_HZ = 0x00 +RF_FDEVLSB_2000_HZ = 0x21 +RF_FDEVMSB_5000_HZ = 0x00 # Default +RF_FDEVLSB_5000_HZ = 0x52 # Default +RF_FDEVMSB_10000_HZ = 0x00 +RF_FDEVLSB_10000_HZ = 0xA4 +RF_FDEVMSB_15000_HZ = 0x00 +RF_FDEVLSB_15000_HZ = 0xF6 +RF_FDEVMSB_20000_HZ = 0x01 +RF_FDEVLSB_20000_HZ = 0x48 +RF_FDEVMSB_25000_HZ = 0x01 +RF_FDEVLSB_25000_HZ = 0x9A +RF_FDEVMSB_30000_HZ = 0x01 +RF_FDEVLSB_30000_HZ = 0xEC +RF_FDEVMSB_35000_HZ = 0x02 +RF_FDEVLSB_35000_HZ = 0x3D +RF_FDEVMSB_40000_HZ = 0x02 +RF_FDEVLSB_40000_HZ = 0x8F +RF_FDEVMSB_45000_HZ = 0x02 +RF_FDEVLSB_45000_HZ = 0xE1 +RF_FDEVMSB_50000_HZ = 0x03 +RF_FDEVLSB_50000_HZ = 0x33 +RF_FDEVMSB_55000_HZ = 0x03 +RF_FDEVLSB_55000_HZ = 0x85 +RF_FDEVMSB_60000_HZ = 0x03 +RF_FDEVLSB_60000_HZ = 0xD7 +RF_FDEVMSB_65000_HZ = 0x04 +RF_FDEVLSB_65000_HZ = 0x29 +RF_FDEVMSB_70000_HZ = 0x04 +RF_FDEVLSB_70000_HZ = 0x7B +RF_FDEVMSB_75000_HZ = 0x04 +RF_FDEVLSB_75000_HZ = 0xCD +RF_FDEVMSB_80000_HZ = 0x05 +RF_FDEVLSB_80000_HZ = 0x1F +RF_FDEVMSB_85000_HZ = 0x05 +RF_FDEVLSB_85000_HZ = 0x71 +RF_FDEVMSB_90000_HZ = 0x05 +RF_FDEVLSB_90000_HZ = 0xC3 +RF_FDEVMSB_95000_HZ = 0x06 +RF_FDEVLSB_95000_HZ = 0x14 +RF_FDEVMSB_100000_HZ = 0x06 +RF_FDEVLSB_100000_HZ = 0x66 +RF_FDEVMSB_110000_HZ = 0x07 +RF_FDEVLSB_110000_HZ = 0x0A +RF_FDEVMSB_120000_HZ = 0x07 +RF_FDEVLSB_120000_HZ = 0xAE +RF_FDEVMSB_130000_HZ = 0x08 +RF_FDEVLSB_130000_HZ = 0x52 +RF_FDEVMSB_140000_HZ = 0x08 +RF_FDEVLSB_140000_HZ = 0xF6 +RF_FDEVMSB_150000_HZ = 0x09 +RF_FDEVLSB_150000_HZ = 0x9A +RF_FDEVMSB_160000_HZ = 0x0A +RF_FDEVLSB_160000_HZ = 0x3D +RF_FDEVMSB_170000_HZ = 0x0A +RF_FDEVLSB_170000_HZ = 0xE1 +RF_FDEVMSB_180000_HZ = 0x0B +RF_FDEVLSB_180000_HZ = 0x85 +RF_FDEVMSB_190000_HZ = 0x0C +RF_FDEVLSB_190000_HZ = 0x29 +RF_FDEVMSB_200000_HZ = 0x0C +RF_FDEVLSB_200000_HZ = 0xCD + +""" + * RegFrf (MHz) +""" +RF_FRFMSB_863_MHZ = 0xD7 +RF_FRFMID_863_MHZ = 0xC0 +RF_FRFLSB_863_MHZ = 0x00 +RF_FRFMSB_864_MHZ = 0xD8 +RF_FRFMID_864_MHZ = 0x00 +RF_FRFLSB_864_MHZ = 0x00 +RF_FRFMSB_865_MHZ = 0xD8 +RF_FRFMID_865_MHZ = 0x40 +RF_FRFLSB_865_MHZ = 0x00 +RF_FRFMSB_866_MHZ = 0xD8 +RF_FRFMID_866_MHZ = 0x80 +RF_FRFLSB_866_MHZ = 0x00 +RF_FRFMSB_867_MHZ = 0xD8 +RF_FRFMID_867_MHZ = 0xC0 +RF_FRFLSB_867_MHZ = 0x00 +RF_FRFMSB_868_MHZ = 0xD9 +RF_FRFMID_868_MHZ = 0x00 +RF_FRFLSB_868_MHZ = 0x00 +RF_FRFMSB_869_MHZ = 0xD9 +RF_FRFMID_869_MHZ = 0x40 +RF_FRFLSB_869_MHZ = 0x00 +RF_FRFMSB_870_MHZ = 0xD9 +RF_FRFMID_870_MHZ = 0x80 +RF_FRFLSB_870_MHZ = 0x00 + +RF_FRFMSB_902_MHZ = 0xE1 +RF_FRFMID_902_MHZ = 0x80 +RF_FRFLSB_902_MHZ = 0x00 +RF_FRFMSB_903_MHZ = 0xE1 +RF_FRFMID_903_MHZ = 0xC0 +RF_FRFLSB_903_MHZ = 0x00 +RF_FRFMSB_904_MHZ = 0xE2 +RF_FRFMID_904_MHZ = 0x00 +RF_FRFLSB_904_MHZ = 0x00 +RF_FRFMSB_905_MHZ = 0xE2 +RF_FRFMID_905_MHZ = 0x40 +RF_FRFLSB_905_MHZ = 0x00 +RF_FRFMSB_906_MHZ = 0xE2 +RF_FRFMID_906_MHZ = 0x80 +RF_FRFLSB_906_MHZ = 0x00 +RF_FRFMSB_907_MHZ = 0xE2 +RF_FRFMID_907_MHZ = 0xC0 +RF_FRFLSB_907_MHZ = 0x00 +RF_FRFMSB_908_MHZ = 0xE3 +RF_FRFMID_908_MHZ = 0x00 +RF_FRFLSB_908_MHZ = 0x00 +RF_FRFMSB_909_MHZ = 0xE3 +RF_FRFMID_909_MHZ = 0x40 +RF_FRFLSB_909_MHZ = 0x00 +RF_FRFMSB_910_MHZ = 0xE3 +RF_FRFMID_910_MHZ = 0x80 +RF_FRFLSB_910_MHZ = 0x00 +RF_FRFMSB_911_MHZ = 0xE3 +RF_FRFMID_911_MHZ = 0xC0 +RF_FRFLSB_911_MHZ = 0x00 +RF_FRFMSB_912_MHZ = 0xE4 +RF_FRFMID_912_MHZ = 0x00 +RF_FRFLSB_912_MHZ = 0x00 +RF_FRFMSB_913_MHZ = 0xE4 +RF_FRFMID_913_MHZ = 0x40 +RF_FRFLSB_913_MHZ = 0x00 +RF_FRFMSB_914_MHZ = 0xE4 +RF_FRFMID_914_MHZ = 0x80 +RF_FRFLSB_914_MHZ = 0x00 +RF_FRFMSB_915_MHZ = 0xE4 # Default +RF_FRFMID_915_MHZ = 0xC0 # Default +RF_FRFLSB_915_MHZ = 0x00 # Default +RF_FRFMSB_916_MHZ = 0xE5 +RF_FRFMID_916_MHZ = 0x00 +RF_FRFLSB_916_MHZ = 0x00 +RF_FRFMSB_917_MHZ = 0xE5 +RF_FRFMID_917_MHZ = 0x40 +RF_FRFLSB_917_MHZ = 0x00 +RF_FRFMSB_918_MHZ = 0xE5 +RF_FRFMID_918_MHZ = 0x80 +RF_FRFLSB_918_MHZ = 0x00 +RF_FRFMSB_919_MHZ = 0xE5 +RF_FRFMID_919_MHZ = 0xC0 +RF_FRFLSB_919_MHZ = 0x00 +RF_FRFMSB_920_MHZ = 0xE6 +RF_FRFMID_920_MHZ = 0x00 +RF_FRFLSB_920_MHZ = 0x00 +RF_FRFMSB_921_MHZ = 0xE6 +RF_FRFMID_921_MHZ = 0x40 +RF_FRFLSB_921_MHZ = 0x00 +RF_FRFMSB_922_MHZ = 0xE6 +RF_FRFMID_922_MHZ = 0x80 +RF_FRFLSB_922_MHZ = 0x00 +RF_FRFMSB_923_MHZ = 0xE6 +RF_FRFMID_923_MHZ = 0xC0 +RF_FRFLSB_923_MHZ = 0x00 +RF_FRFMSB_924_MHZ = 0xE7 +RF_FRFMID_924_MHZ = 0x00 +RF_FRFLSB_924_MHZ = 0x00 +RF_FRFMSB_925_MHZ = 0xE7 +RF_FRFMID_925_MHZ = 0x40 +RF_FRFLSB_925_MHZ = 0x00 +RF_FRFMSB_926_MHZ = 0xE7 +RF_FRFMID_926_MHZ = 0x80 +RF_FRFLSB_926_MHZ = 0x00 +RF_FRFMSB_927_MHZ = 0xE7 +RF_FRFMID_927_MHZ = 0xC0 +RF_FRFLSB_927_MHZ = 0x00 +RF_FRFMSB_928_MHZ = 0xE8 +RF_FRFMID_928_MHZ = 0x00 +RF_FRFLSB_928_MHZ = 0x00 + +""" + * RegPaConfig +""" +RF_PACONFIG_PASELECT_MASK = 0x7F +RF_PACONFIG_PASELECT_PABOOST = 0x80 +RF_PACONFIG_PASELECT_RFO = 0x00 # Default + +RF_PACONFIG_OUTPUTPOWER_MASK = 0xF0 + +""" + * RegPaRamp +""" +RF_PARAMP_LOWPNTXPLL_MASK = 0xEF +RF_PARAMP_LOWPNTXPLL_OFF = 0x10 # Default +RF_PARAMP_LOWPNTXPLL_ON = 0x00 + +RF_PARAMP_MASK = 0xF0 +RF_PARAMP_3400_US = 0x00 +RF_PARAMP_2000_US = 0x01 +RF_PARAMP_1000_US = 0x02 +RF_PARAMP_0500_US = 0x03 +RF_PARAMP_0250_US = 0x04 +RF_PARAMP_0125_US = 0x05 +RF_PARAMP_0100_US = 0x06 +RF_PARAMP_0062_US = 0x07 +RF_PARAMP_0050_US = 0x08 +RF_PARAMP_0040_US = 0x09 # Default +RF_PARAMP_0031_US = 0x0A +RF_PARAMP_0025_US = 0x0B +RF_PARAMP_0020_US = 0x0C +RF_PARAMP_0015_US = 0x0D +RF_PARAMP_0012_US = 0x0E +RF_PARAMP_0010_US = 0x0F + +""" + * RegOcp +""" +RF_OCP_MASK = 0xDF +RF_OCP_ON = 0x20 # Default +RF_OCP_OFF = 0x00 + +RF_OCP_TRIM_MASK = 0xE0 +RF_OCP_TRIM_045_MA = 0x00 +RF_OCP_TRIM_050_MA = 0x01 +RF_OCP_TRIM_055_MA = 0x02 +RF_OCP_TRIM_060_MA = 0x03 +RF_OCP_TRIM_065_MA = 0x04 +RF_OCP_TRIM_070_MA = 0x05 +RF_OCP_TRIM_075_MA = 0x06 +RF_OCP_TRIM_080_MA = 0x07 +RF_OCP_TRIM_085_MA = 0x08 +RF_OCP_TRIM_090_MA = 0x09 +RF_OCP_TRIM_095_MA = 0x0A +RF_OCP_TRIM_100_MA = 0x0B # Default +RF_OCP_TRIM_105_MA = 0x0C +RF_OCP_TRIM_110_MA = 0x0D +RF_OCP_TRIM_115_MA = 0x0E +RF_OCP_TRIM_120_MA = 0x0F +RF_OCP_TRIM_130_MA = 0x10 +RF_OCP_TRIM_140_MA = 0x11 +RF_OCP_TRIM_150_MA = 0x12 +RF_OCP_TRIM_160_MA = 0x13 +RF_OCP_TRIM_170_MA = 0x14 +RF_OCP_TRIM_180_MA = 0x15 +RF_OCP_TRIM_190_MA = 0x16 +RF_OCP_TRIM_200_MA = 0x17 +RF_OCP_TRIM_210_MA = 0x18 +RF_OCP_TRIM_220_MA = 0x19 +RF_OCP_TRIM_230_MA = 0x1A +RF_OCP_TRIM_240_MA = 0x1B + +""" + * RegLna +""" +RF_LNA_GAIN_MASK = 0x1F +RF_LNA_GAIN_G1 = 0x20 # Default +RF_LNA_GAIN_G2 = 0x40 +RF_LNA_GAIN_G3 = 0x60 +RF_LNA_GAIN_G4 = 0x80 +RF_LNA_GAIN_G5 = 0xA0 +RF_LNA_GAIN_G6 = 0xC0 + +RF_LNA_BOOST_MASK = 0xFC +RF_LNA_BOOST_OFF = 0x00 # Default +RF_LNA_BOOST_ON = 0x03 + +""" + * RegRxConfig +""" +RF_RXCONFIG_RESTARTRXONCOLLISION_MASK = 0x7F +RF_RXCONFIG_RESTARTRXONCOLLISION_ON = 0x80 +RF_RXCONFIG_RESTARTRXONCOLLISION_OFF = 0x00 # Default + +RF_RXCONFIG_RESTARTRXWITHOUTPLLLOCK = 0x40 # Write only + +RF_RXCONFIG_RESTARTRXWITHPLLLOCK = 0x20 # Write only + +RF_RXCONFIG_AFCAUTO_MASK = 0xEF +RF_RXCONFIG_AFCAUTO_ON = 0x10 +RF_RXCONFIG_AFCAUTO_OFF = 0x00 # Default + +RF_RXCONFIG_AGCAUTO_MASK = 0xF7 +RF_RXCONFIG_AGCAUTO_ON = 0x08 # Default +RF_RXCONFIG_AGCAUTO_OFF = 0x00 + +RF_RXCONFIG_RXTRIGER_MASK = 0xF8 +RF_RXCONFIG_RXTRIGER_OFF = 0x00 +RF_RXCONFIG_RXTRIGER_RSSI = 0x01 +RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT = 0x06 # Default +RF_RXCONFIG_RXTRIGER_RSSI_PREAMBLEDETECT = 0x07 + +""" + * RegRssiConfig +""" +RF_RSSICONFIG_OFFSET_MASK = 0x07 +RF_RSSICONFIG_OFFSET_P_00_DB = 0x00 # Default +RF_RSSICONFIG_OFFSET_P_01_DB = 0x08 +RF_RSSICONFIG_OFFSET_P_02_DB = 0x10 +RF_RSSICONFIG_OFFSET_P_03_DB = 0x18 +RF_RSSICONFIG_OFFSET_P_04_DB = 0x20 +RF_RSSICONFIG_OFFSET_P_05_DB = 0x28 +RF_RSSICONFIG_OFFSET_P_06_DB = 0x30 +RF_RSSICONFIG_OFFSET_P_07_DB = 0x38 +RF_RSSICONFIG_OFFSET_P_08_DB = 0x40 +RF_RSSICONFIG_OFFSET_P_09_DB = 0x48 +RF_RSSICONFIG_OFFSET_P_10_DB = 0x50 +RF_RSSICONFIG_OFFSET_P_11_DB = 0x58 +RF_RSSICONFIG_OFFSET_P_12_DB = 0x60 +RF_RSSICONFIG_OFFSET_P_13_DB = 0x68 +RF_RSSICONFIG_OFFSET_P_14_DB = 0x70 +RF_RSSICONFIG_OFFSET_P_15_DB = 0x78 +RF_RSSICONFIG_OFFSET_M_16_DB = 0x80 +RF_RSSICONFIG_OFFSET_M_15_DB = 0x88 +RF_RSSICONFIG_OFFSET_M_14_DB = 0x90 +RF_RSSICONFIG_OFFSET_M_13_DB = 0x98 +RF_RSSICONFIG_OFFSET_M_12_DB = 0xA0 +RF_RSSICONFIG_OFFSET_M_11_DB = 0xA8 +RF_RSSICONFIG_OFFSET_M_10_DB = 0xB0 +RF_RSSICONFIG_OFFSET_M_09_DB = 0xB8 +RF_RSSICONFIG_OFFSET_M_08_DB = 0xC0 +RF_RSSICONFIG_OFFSET_M_07_DB = 0xC8 +RF_RSSICONFIG_OFFSET_M_06_DB = 0xD0 +RF_RSSICONFIG_OFFSET_M_05_DB = 0xD8 +RF_RSSICONFIG_OFFSET_M_04_DB = 0xE0 +RF_RSSICONFIG_OFFSET_M_03_DB = 0xE8 +RF_RSSICONFIG_OFFSET_M_02_DB = 0xF0 +RF_RSSICONFIG_OFFSET_M_01_DB = 0xF8 + +RF_RSSICONFIG_SMOOTHING_MASK = 0xF8 +RF_RSSICONFIG_SMOOTHING_2 = 0x00 +RF_RSSICONFIG_SMOOTHING_4 = 0x01 +RF_RSSICONFIG_SMOOTHING_8 = 0x02 # Default +RF_RSSICONFIG_SMOOTHING_16 = 0x03 +RF_RSSICONFIG_SMOOTHING_32 = 0x04 +RF_RSSICONFIG_SMOOTHING_64 = 0x05 +RF_RSSICONFIG_SMOOTHING_128 = 0x06 +RF_RSSICONFIG_SMOOTHING_256 = 0x07 + +""" + * RegRssiCollision +""" +RF_RSSICOLISION_THRESHOLD = 0x0A # Default + +""" + * RegRssiThresh +""" +RF_RSSITHRESH_THRESHOLD = 0xFF # Default + +""" + * RegRssiValue (Read Only) +""" + +""" + * RegRxBw +""" +RF_RXBW_MANT_MASK = 0xE7 +RF_RXBW_MANT_16 = 0x00 +RF_RXBW_MANT_20 = 0x08 +RF_RXBW_MANT_24 = 0x10 # Default + +RF_RXBW_EXP_MASK = 0xF8 +RF_RXBW_EXP_0 = 0x00 +RF_RXBW_EXP_1 = 0x01 +RF_RXBW_EXP_2 = 0x02 +RF_RXBW_EXP_3 = 0x03 +RF_RXBW_EXP_4 = 0x04 +RF_RXBW_EXP_5 = 0x05 # Default +RF_RXBW_EXP_6 = 0x06 +RF_RXBW_EXP_7 = 0x07 + +""" + * RegAfcBw +""" +RF_AFCBW_MANTAFC_MASK = 0xE7 +RF_AFCBW_MANTAFC_16 = 0x00 +RF_AFCBW_MANTAFC_20 = 0x08 # Default +RF_AFCBW_MANTAFC_24 = 0x10 + +RF_AFCBW_EXPAFC_MASK = 0xF8 +RF_AFCBW_EXPAFC_0 = 0x00 +RF_AFCBW_EXPAFC_1 = 0x01 +RF_AFCBW_EXPAFC_2 = 0x02 +RF_AFCBW_EXPAFC_3 = 0x03 # Default +RF_AFCBW_EXPAFC_4 = 0x04 +RF_AFCBW_EXPAFC_5 = 0x05 +RF_AFCBW_EXPAFC_6 = 0x06 +RF_AFCBW_EXPAFC_7 = 0x07 + +""" + * RegOokPeak +""" +RF_OOKPEAK_BITSYNC_MASK = 0xDF # Default +RF_OOKPEAK_BITSYNC_ON = 0x20 # Default +RF_OOKPEAK_BITSYNC_OFF = 0x00 + +RF_OOKPEAK_OOKTHRESHTYPE_MASK = 0xE7 +RF_OOKPEAK_OOKTHRESHTYPE_FIXED = 0x00 +RF_OOKPEAK_OOKTHRESHTYPE_PEAK = 0x08 # Default +RF_OOKPEAK_OOKTHRESHTYPE_AVERAGE = 0x10 + +RF_OOKPEAK_OOKPEAKTHRESHSTEP_MASK = 0xF8 +RF_OOKPEAK_OOKPEAKTHRESHSTEP_0_5_DB = 0x00 # Default +RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_0_DB = 0x01 +RF_OOKPEAK_OOKPEAKTHRESHSTEP_1_5_DB = 0x02 +RF_OOKPEAK_OOKPEAKTHRESHSTEP_2_0_DB = 0x03 +RF_OOKPEAK_OOKPEAKTHRESHSTEP_3_0_DB = 0x04 +RF_OOKPEAK_OOKPEAKTHRESHSTEP_4_0_DB = 0x05 +RF_OOKPEAK_OOKPEAKTHRESHSTEP_5_0_DB = 0x06 +RF_OOKPEAK_OOKPEAKTHRESHSTEP_6_0_DB = 0x07 + +""" + * RegOokFix +""" +RF_OOKFIX_OOKFIXEDTHRESHOLD = 0x0C # Default + +""" + * RegOokAvg +""" +RF_OOKAVG_OOKPEAKTHRESHDEC_MASK = 0x1F +RF_OOKAVG_OOKPEAKTHRESHDEC_000 = 0x00 # Default +RF_OOKAVG_OOKPEAKTHRESHDEC_001 = 0x20 +RF_OOKAVG_OOKPEAKTHRESHDEC_010 = 0x40 +RF_OOKAVG_OOKPEAKTHRESHDEC_011 = 0x60 +RF_OOKAVG_OOKPEAKTHRESHDEC_100 = 0x80 +RF_OOKAVG_OOKPEAKTHRESHDEC_101 = 0xA0 +RF_OOKAVG_OOKPEAKTHRESHDEC_110 = 0xC0 +RF_OOKAVG_OOKPEAKTHRESHDEC_111 = 0xE0 + +RF_OOKAVG_AVERAGEOFFSET_MASK = 0xF3 +RF_OOKAVG_AVERAGEOFFSET_0_DB = 0x00 # Default +RF_OOKAVG_AVERAGEOFFSET_2_DB = 0x04 +RF_OOKAVG_AVERAGEOFFSET_4_DB = 0x08 +RF_OOKAVG_AVERAGEOFFSET_6_DB = 0x0C + +RF_OOKAVG_OOKAVERAGETHRESHFILT_MASK = 0xFC +RF_OOKAVG_OOKAVERAGETHRESHFILT_00 = 0x00 +RF_OOKAVG_OOKAVERAGETHRESHFILT_01 = 0x01 +RF_OOKAVG_OOKAVERAGETHRESHFILT_10 = 0x02 # Default +RF_OOKAVG_OOKAVERAGETHRESHFILT_11 = 0x03 + +""" + * RegAfcFei +""" +RF_AFCFEI_AGCSTART = 0x10 + +RF_AFCFEI_AFCCLEAR = 0x02 + +RF_AFCFEI_AFCAUTOCLEAR_MASK = 0xFE +RF_AFCFEI_AFCAUTOCLEAR_ON = 0x01 +RF_AFCFEI_AFCAUTOCLEAR_OFF = 0x00 # Default + +""" + * RegAfcMsb (Read Only) +""" + +""" + * RegAfcLsb (Read Only) +""" + +""" + * RegFeiMsb (Read Only) +""" + +""" + * RegFeiLsb (Read Only) +""" + +""" + * RegPreambleDetect +""" +RF_PREAMBLEDETECT_DETECTOR_MASK = 0x7F +RF_PREAMBLEDETECT_DETECTOR_ON = 0x80 # Default +RF_PREAMBLEDETECT_DETECTOR_OFF = 0x00 + +RF_PREAMBLEDETECT_DETECTORSIZE_MASK = 0x9F +RF_PREAMBLEDETECT_DETECTORSIZE_1 = 0x00 +RF_PREAMBLEDETECT_DETECTORSIZE_2 = 0x20 # Default +RF_PREAMBLEDETECT_DETECTORSIZE_3 = 0x40 +RF_PREAMBLEDETECT_DETECTORSIZE_4 = 0x60 + +RF_PREAMBLEDETECT_DETECTORTOL_MASK = 0xE0 +RF_PREAMBLEDETECT_DETECTORTOL_0 = 0x00 +RF_PREAMBLEDETECT_DETECTORTOL_1 = 0x01 +RF_PREAMBLEDETECT_DETECTORTOL_2 = 0x02 +RF_PREAMBLEDETECT_DETECTORTOL_3 = 0x03 +RF_PREAMBLEDETECT_DETECTORTOL_4 = 0x04 +RF_PREAMBLEDETECT_DETECTORTOL_5 = 0x05 +RF_PREAMBLEDETECT_DETECTORTOL_6 = 0x06 +RF_PREAMBLEDETECT_DETECTORTOL_7 = 0x07 +RF_PREAMBLEDETECT_DETECTORTOL_8 = 0x08 +RF_PREAMBLEDETECT_DETECTORTOL_9 = 0x09 +RF_PREAMBLEDETECT_DETECTORTOL_10 = 0x0A # Default +RF_PREAMBLEDETECT_DETECTORTOL_11 = 0x0B +RF_PREAMBLEDETECT_DETECTORTOL_12 = 0x0C +RF_PREAMBLEDETECT_DETECTORTOL_13 = 0x0D +RF_PREAMBLEDETECT_DETECTORTOL_14 = 0x0E +RF_PREAMBLEDETECT_DETECTORTOL_15 = 0x0F +RF_PREAMBLEDETECT_DETECTORTOL_16 = 0x10 +RF_PREAMBLEDETECT_DETECTORTOL_17 = 0x11 +RF_PREAMBLEDETECT_DETECTORTOL_18 = 0x12 +RF_PREAMBLEDETECT_DETECTORTOL_19 = 0x13 +RF_PREAMBLEDETECT_DETECTORTOL_20 = 0x14 +RF_PREAMBLEDETECT_DETECTORTOL_21 = 0x15 +RF_PREAMBLEDETECT_DETECTORTOL_22 = 0x16 +RF_PREAMBLEDETECT_DETECTORTOL_23 = 0x17 +RF_PREAMBLEDETECT_DETECTORTOL_24 = 0x18 +RF_PREAMBLEDETECT_DETECTORTOL_25 = 0x19 +RF_PREAMBLEDETECT_DETECTORTOL_26 = 0x1A +RF_PREAMBLEDETECT_DETECTORTOL_27 = 0x1B +RF_PREAMBLEDETECT_DETECTORTOL_28 = 0x1C +RF_PREAMBLEDETECT_DETECTORTOL_29 = 0x1D +RF_PREAMBLEDETECT_DETECTORTOL_30 = 0x1E +RF_PREAMBLEDETECT_DETECTORTOL_31 = 0x1F + +""" + * RegRxTimeout1 +""" +RF_RXTIMEOUT1_TIMEOUTRXRSSI = 0x00 # Default + +""" + * RegRxTimeout2 +""" +RF_RXTIMEOUT2_TIMEOUTRXPREAMBLE = 0x00 # Default + +""" + * RegRxTimeout3 +""" +RF_RXTIMEOUT3_TIMEOUTSIGNALSYNC = 0x00 # Default + +""" + * RegRxDelay +""" +RF_RXDELAY_INTERPACKETRXDELAY = 0x00 # Default + +""" + * RegOsc +""" +RF_OSC_RCCALSTART = 0x08 + +RF_OSC_CLKOUT_MASK = 0xF8 +RF_OSC_CLKOUT_32_MHZ = 0x00 +RF_OSC_CLKOUT_16_MHZ = 0x01 +RF_OSC_CLKOUT_8_MHZ = 0x02 +RF_OSC_CLKOUT_4_MHZ = 0x03 +RF_OSC_CLKOUT_2_MHZ = 0x04 +RF_OSC_CLKOUT_1_MHZ = 0x05 +RF_OSC_CLKOUT_RC = 0x06 +RF_OSC_CLKOUT_OFF = 0x07 # Default + +""" + * RegPreambleMsb/RegPreambleLsb +""" +RF_PREAMBLEMSB_SIZE = 0x00 # Default +RF_PREAMBLELSB_SIZE = 0x03 # Default + +""" + * RegSyncConfig +""" +RF_SYNCCONFIG_AUTORESTARTRXMODE_MASK = 0x3F +RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_ON = 0x80 # Default +RF_SYNCCONFIG_AUTORESTARTRXMODE_WAITPLL_OFF = 0x40 +RF_SYNCCONFIG_AUTORESTARTRXMODE_OFF = 0x00 + +RF_SYNCCONFIG_PREAMBLEPOLARITY_MASK = 0xDF +RF_SYNCCONFIG_PREAMBLEPOLARITY_55 = 0x20 +RF_SYNCCONFIG_PREAMBLEPOLARITY_AA = 0x00 # Default + +RF_SYNCCONFIG_SYNC_MASK = 0xEF +RF_SYNCCONFIG_SYNC_ON = 0x10 # Default +RF_SYNCCONFIG_SYNC_OFF = 0x00 + +RF_SYNCCONFIG_FIFOFILLCONDITION_MASK = 0xF7 +RF_SYNCCONFIG_FIFOFILLCONDITION_AUTO = 0x00 # Default +RF_SYNCCONFIG_FIFOFILLCONDITION_MANUAL = 0x08 + +RF_SYNCCONFIG_SYNCSIZE_MASK = 0xF8 +RF_SYNCCONFIG_SYNCSIZE_1 = 0x00 +RF_SYNCCONFIG_SYNCSIZE_2 = 0x01 +RF_SYNCCONFIG_SYNCSIZE_3 = 0x02 +RF_SYNCCONFIG_SYNCSIZE_4 = 0x03 # Default +RF_SYNCCONFIG_SYNCSIZE_5 = 0x04 +RF_SYNCCONFIG_SYNCSIZE_6 = 0x05 +RF_SYNCCONFIG_SYNCSIZE_7 = 0x06 +RF_SYNCCONFIG_SYNCSIZE_8 = 0x07 + +""" + * RegSyncValue1-8 +""" +RF_SYNCVALUE1_SYNCVALUE = 0x01 # Default +RF_SYNCVALUE2_SYNCVALUE = 0x01 # Default +RF_SYNCVALUE3_SYNCVALUE = 0x01 # Default +RF_SYNCVALUE4_SYNCVALUE = 0x01 # Default +RF_SYNCVALUE5_SYNCVALUE = 0x01 # Default +RF_SYNCVALUE6_SYNCVALUE = 0x01 # Default +RF_SYNCVALUE7_SYNCVALUE = 0x01 # Default +RF_SYNCVALUE8_SYNCVALUE = 0x01 # Default + +""" + * RegPacketConfig1 +""" +RF_PACKETCONFIG1_PACKETFORMAT_MASK = 0x7F +RF_PACKETCONFIG1_PACKETFORMAT_FIXED = 0x00 +RF_PACKETCONFIG1_PACKETFORMAT_VARIABLE = 0x80 # Default + +RF_PACKETCONFIG1_DCFREE_MASK = 0x9F +RF_PACKETCONFIG1_DCFREE_OFF = 0x00 # Default +RF_PACKETCONFIG1_DCFREE_MANCHESTER = 0x20 +RF_PACKETCONFIG1_DCFREE_WHITENING = 0x40 + +RF_PACKETCONFIG1_CRC_MASK = 0xEF +RF_PACKETCONFIG1_CRC_ON = 0x10 # Default +RF_PACKETCONFIG1_CRC_OFF = 0x00 + +RF_PACKETCONFIG1_CRCAUTOCLEAR_MASK = 0xF7 +RF_PACKETCONFIG1_CRCAUTOCLEAR_ON = 0x00 # Default +RF_PACKETCONFIG1_CRCAUTOCLEAR_OFF = 0x08 + +RF_PACKETCONFIG1_ADDRSFILTERING_MASK = 0xF9 +RF_PACKETCONFIG1_ADDRSFILTERING_OFF = 0x00 # Default +RF_PACKETCONFIG1_ADDRSFILTERING_NODE = 0x02 +RF_PACKETCONFIG1_ADDRSFILTERING_NODEBROADCAST = 0x04 + +RF_PACKETCONFIG1_CRCWHITENINGTYPE_MASK = 0xFE +RF_PACKETCONFIG1_CRCWHITENINGTYPE_CCITT = 0x00 # Default +RF_PACKETCONFIG1_CRCWHITENINGTYPE_IBM = 0x01 + +""" + * RegPacketConfig2 +""" +RF_PACKETCONFIG2_DATAMODE_MASK = 0xBF +RF_PACKETCONFIG2_DATAMODE_CONTINUOUS = 0x00 +RF_PACKETCONFIG2_DATAMODE_PACKET = 0x40 # Default + +RF_PACKETCONFIG2_IOHOME_MASK = 0xDF +RF_PACKETCONFIG2_IOHOME_ON = 0x20 +RF_PACKETCONFIG2_IOHOME_OFF = 0x00 # Default + +RF_PACKETCONFIG2_BEACON_MASK = 0xF7 +RF_PACKETCONFIG2_BEACON_ON = 0x08 +RF_PACKETCONFIG2_BEACON_OFF = 0x00 # Default + +RF_PACKETCONFIG2_PAYLOADLENGTH_MSB_MASK = 0xF8 + +""" + * RegPayloadLength +""" +RF_PAYLOADLENGTH_LENGTH = 0x40 # Default + +""" + * RegNodeAdrs +""" +RF_NODEADDRESS_ADDRESS = 0x00 + +""" + * RegBroadcastAdrs +""" +RF_BROADCASTADDRESS_ADDRESS = 0x00 + +""" + * RegFifoThresh +""" +RF_FIFOTHRESH_TXSTARTCONDITION_MASK = 0x7F +RF_FIFOTHRESH_TXSTARTCONDITION_FIFOTHRESH = 0x00 +RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY = 0x80 # Default + +RF_FIFOTHRESH_FIFOTHRESHOLD_MASK = 0xC0 +RF_FIFOTHRESH_FIFOTHRESHOLD_THRESHOLD = 0x0F # Default + +""" + * RegSeqConfig1 +""" +RF_SEQCONFIG1_SEQUENCER_START = 0x80 + +RF_SEQCONFIG1_SEQUENCER_STOP = 0x40 + +RF_SEQCONFIG1_IDLEMODE_MASK = 0xDF +RF_SEQCONFIG1_IDLEMODE_SLEEP = 0x20 +RF_SEQCONFIG1_IDLEMODE_STANDBY = 0x00 # Default + +RF_SEQCONFIG1_FROMSTART_MASK = 0xE7 +RF_SEQCONFIG1_FROMSTART_TOLPS = 0x00 # Default +RF_SEQCONFIG1_FROMSTART_TORX = 0x08 +RF_SEQCONFIG1_FROMSTART_TOTX = 0x10 +RF_SEQCONFIG1_FROMSTART_TOTX_ONFIFOLEVEL = 0x18 + +RF_SEQCONFIG1_LPS_MASK = 0xFB +RF_SEQCONFIG1_LPS_SEQUENCER_OFF = 0x00 # Default +RF_SEQCONFIG1_LPS_IDLE = 0x04 + +RF_SEQCONFIG1_FROMIDLE_MASK = 0xFD +RF_SEQCONFIG1_FROMIDLE_TOTX = 0x00 # Default +RF_SEQCONFIG1_FROMIDLE_TORX = 0x02 + +RF_SEQCONFIG1_FROMTX_MASK = 0xFE +RF_SEQCONFIG1_FROMTX_TOLPS = 0x00 # Default +RF_SEQCONFIG1_FROMTX_TORX = 0x01 + +""" + * RegSeqConfig2 +""" +RF_SEQCONFIG2_FROMRX_MASK = 0x1F +RF_SEQCONFIG2_FROMRX_TOUNUSED_000 = 0x00 # Default +RF_SEQCONFIG2_FROMRX_TORXPKT_ONPLDRDY = 0x20 +RF_SEQCONFIG2_FROMRX_TOLPS_ONPLDRDY = 0x40 +RF_SEQCONFIG2_FROMRX_TORXPKT_ONCRCOK = 0x60 +RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONRSSI = 0x80 +RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONSYNC = 0xA0 +RF_SEQCONFIG2_FROMRX_TOSEQUENCEROFF_ONPREAMBLE = 0xC0 +RF_SEQCONFIG2_FROMRX_TOUNUSED_111 = 0xE0 + +RF_SEQCONFIG2_FROMRXTIMEOUT_MASK = 0xE7 +RF_SEQCONFIG2_FROMRXTIMEOUT_TORXRESTART = 0x00 # Default +RF_SEQCONFIG2_FROMRXTIMEOUT_TOTX = 0x08 +RF_SEQCONFIG2_FROMRXTIMEOUT_TOLPS = 0x10 +RF_SEQCONFIG2_FROMRXTIMEOUT_TOSEQUENCEROFF = 0x18 + +RF_SEQCONFIG2_FROMRXPKT_MASK = 0xF8 +RF_SEQCONFIG2_FROMRXPKT_TOSEQUENCEROFF = 0x00 # Default +RF_SEQCONFIG2_FROMRXPKT_TOTX_ONFIFOEMPTY = 0x01 +RF_SEQCONFIG2_FROMRXPKT_TOLPS = 0x02 +RF_SEQCONFIG2_FROMRXPKT_TOSYNTHESIZERRX = 0x03 +RF_SEQCONFIG2_FROMRXPKT_TORX = 0x04 + +""" + * RegTimerResol +""" +RF_TIMERRESOL_TIMER1RESOL_MASK = 0xF3 +RF_TIMERRESOL_TIMER1RESOL_OFF = 0x00 # Default +RF_TIMERRESOL_TIMER1RESOL_000064_US = 0x04 +RF_TIMERRESOL_TIMER1RESOL_004100_US = 0x08 +RF_TIMERRESOL_TIMER1RESOL_262000_US = 0x0C + +RF_TIMERRESOL_TIMER2RESOL_MASK = 0xFC +RF_TIMERRESOL_TIMER2RESOL_OFF = 0x00 # Default +RF_TIMERRESOL_TIMER2RESOL_000064_US = 0x01 +RF_TIMERRESOL_TIMER2RESOL_004100_US = 0x02 +RF_TIMERRESOL_TIMER2RESOL_262000_US = 0x03 + +""" + * RegTimer1Coef +""" +RF_TIMER1COEF_TIMER1COEFFICIENT = 0xF5 # Default + +""" + * RegTimer2Coef +""" +RF_TIMER2COEF_TIMER2COEFFICIENT = 0x20 # Default + +""" + * RegImageCal +""" +RF_IMAGECAL_AUTOIMAGECAL_MASK = 0x7F +RF_IMAGECAL_AUTOIMAGECAL_ON = 0x80 +RF_IMAGECAL_AUTOIMAGECAL_OFF = 0x00 # Default + +RF_IMAGECAL_IMAGECAL_MASK = 0xBF +RF_IMAGECAL_IMAGECAL_START = 0x40 + +RF_IMAGECAL_IMAGECAL_RUNNING = 0x20 +RF_IMAGECAL_IMAGECAL_DONE = 0x00 # Default + +RF_IMAGECAL_TEMPCHANGE_HIGHER = 0x08 +RF_IMAGECAL_TEMPCHANGE_LOWER = 0x00 + +RF_IMAGECAL_TEMPTHRESHOLD_MASK = 0xF9 +RF_IMAGECAL_TEMPTHRESHOLD_05 = 0x00 +RF_IMAGECAL_TEMPTHRESHOLD_10 = 0x02 # Default +RF_IMAGECAL_TEMPTHRESHOLD_15 = 0x04 +RF_IMAGECAL_TEMPTHRESHOLD_20 = 0x06 + +RF_IMAGECAL_TEMPMONITOR_MASK = 0xFE +RF_IMAGECAL_TEMPMONITOR_ON = 0x00 # Default +RF_IMAGECAL_TEMPMONITOR_OFF = 0x01 + +""" + * RegTemp (Read Only) +""" + +""" + * RegLowBat +""" +RF_LOWBAT_MASK = 0xF7 +RF_LOWBAT_ON = 0x08 +RF_LOWBAT_OFF = 0x00 # Default + +RF_LOWBAT_TRIM_MASK = 0xF8 +RF_LOWBAT_TRIM_1695 = 0x00 +RF_LOWBAT_TRIM_1764 = 0x01 +RF_LOWBAT_TRIM_1835 = 0x02 # Default +RF_LOWBAT_TRIM_1905 = 0x03 +RF_LOWBAT_TRIM_1976 = 0x04 +RF_LOWBAT_TRIM_2045 = 0x05 +RF_LOWBAT_TRIM_2116 = 0x06 +RF_LOWBAT_TRIM_2185 = 0x07 + +""" + * RegIrqFlags1 +""" +RF_IRQFLAGS1_MODEREADY = 0x80 + +RF_IRQFLAGS1_RXREADY = 0x40 + +RF_IRQFLAGS1_TXREADY = 0x20 + +RF_IRQFLAGS1_PLLLOCK = 0x10 + +RF_IRQFLAGS1_RSSI = 0x08 + +RF_IRQFLAGS1_TIMEOUT = 0x04 + +RF_IRQFLAGS1_PREAMBLEDETECT = 0x02 + +RF_IRQFLAGS1_SYNCADDRESSMATCH = 0x01 + +""" + * RegIrqFlags2 +""" +RF_IRQFLAGS2_FIFOFULL = 0x80 + +RF_IRQFLAGS2_FIFOEMPTY = 0x40 + +RF_IRQFLAGS2_FIFOLEVEL = 0x20 + +RF_IRQFLAGS2_FIFOOVERRUN = 0x10 + +RF_IRQFLAGS2_PACKETSENT = 0x08 + +RF_IRQFLAGS2_PAYLOADREADY = 0x04 + +RF_IRQFLAGS2_CRCOK = 0x02 + +RF_IRQFLAGS2_LOWBAT = 0x01 + +""" + * RegDioMapping1 +""" +RF_DIOMAPPING1_DIO0_MASK = 0x3F +RF_DIOMAPPING1_DIO0_00 = 0x00 # Default +RF_DIOMAPPING1_DIO0_01 = 0x40 +RF_DIOMAPPING1_DIO0_10 = 0x80 +RF_DIOMAPPING1_DIO0_11 = 0xC0 + +RF_DIOMAPPING1_DIO1_MASK = 0xCF +RF_DIOMAPPING1_DIO1_00 = 0x00 # Default +RF_DIOMAPPING1_DIO1_01 = 0x10 +RF_DIOMAPPING1_DIO1_10 = 0x20 +RF_DIOMAPPING1_DIO1_11 = 0x30 + +RF_DIOMAPPING1_DIO2_MASK = 0xF3 +RF_DIOMAPPING1_DIO2_00 = 0x00 # Default +RF_DIOMAPPING1_DIO2_01 = 0x04 +RF_DIOMAPPING1_DIO2_10 = 0x08 +RF_DIOMAPPING1_DIO2_11 = 0x0C + +RF_DIOMAPPING1_DIO3_MASK = 0xFC +RF_DIOMAPPING1_DIO3_00 = 0x00 # Default +RF_DIOMAPPING1_DIO3_01 = 0x01 +RF_DIOMAPPING1_DIO3_10 = 0x02 +RF_DIOMAPPING1_DIO3_11 = 0x03 + +""" + * RegDioMapping2 +""" +RF_DIOMAPPING2_DIO4_MASK = 0x3F +RF_DIOMAPPING2_DIO4_00 = 0x00 # Default +RF_DIOMAPPING2_DIO4_01 = 0x40 +RF_DIOMAPPING2_DIO4_10 = 0x80 +RF_DIOMAPPING2_DIO4_11 = 0xC0 + +RF_DIOMAPPING2_DIO5_MASK = 0xCF +RF_DIOMAPPING2_DIO5_00 = 0x00 # Default +RF_DIOMAPPING2_DIO5_01 = 0x10 +RF_DIOMAPPING2_DIO5_10 = 0x20 +RF_DIOMAPPING2_DIO5_11 = 0x30 + +RF_DIOMAPPING2_MAP_MASK = 0xFE +RF_DIOMAPPING2_MAP_PREAMBLEDETECT = 0x01 +RF_DIOMAPPING2_MAP_RSSI = 0x00 # Default + +""" + * RegVersion (Read Only) +""" + +""" + * RegAgcRef +""" + +""" + * RegAgcThresh1 +""" + +""" + * RegAgcThresh2 +""" + +""" + * RegAgcThresh3 +""" + +""" + * RegPllHop +""" +RF_PLLHOP_FASTHOP_MASK = 0x7F +RF_PLLHOP_FASTHOP_ON = 0x80 +RF_PLLHOP_FASTHOP_OFF = 0x00 # Default + +""" + * RegTcxo +""" +RF_TCXO_TCXOINPUT_MASK = 0xEF +RF_TCXO_TCXOINPUT_ON = 0x10 +RF_TCXO_TCXOINPUT_OFF = 0x00 # Default + +""" + * RegPaDac +""" +RF_PADAC_20DBM_MASK = 0xF8 +RF_PADAC_20DBM_ON = 0x07 +RF_PADAC_20DBM_OFF = 0x04 # Default + +""" + * RegPll +""" +RF_PLL_BANDWIDTH_MASK = 0x3F +RF_PLL_BANDWIDTH_75 = 0x00 +RF_PLL_BANDWIDTH_150 = 0x40 +RF_PLL_BANDWIDTH_225 = 0x80 +RF_PLL_BANDWIDTH_300 = 0xC0 # Default + +""" + * RegPllLowPn +""" +RF_PLLLOWPN_BANDWIDTH_MASK = 0x3F +RF_PLLLOWPN_BANDWIDTH_75 = 0x00 +RF_PLLLOWPN_BANDWIDTH_150 = 0x40 +RF_PLLLOWPN_BANDWIDTH_225 = 0x80 +RF_PLLLOWPN_BANDWIDTH_300 = 0xC0 # Default + +""" + * RegFormerTemp +""" + +""" + * RegBitrateFrac +""" +RF_BITRATEFRAC_MASK = 0xF0 diff --git a/test_adc.py b/test_adc.py new file mode 100644 index 0000000..be70183 --- /dev/null +++ b/test_adc.py @@ -0,0 +1,38 @@ +#!/bin/env python3 +import time + +import gex +import numpy as np +from matplotlib import pyplot as plt + +from scipy.io import wavfile + +with gex.Client(gex.TrxRawUSB()) as client: + adc = gex.ADC(client, 'adc') + + print(adc.get_calibration_data()) + print(adc.get_channels()) + + adc.set_active_channels([1]) + rate=50000 + fs = adc.set_sample_rate(rate) + + time.sleep(0.1) + count = 5000 + data = adc.capture(count) + + print("rx, %d samples" % len(data)) + data = np.add(data / 4096, -0.5) + + adc.set_sample_rate(1000) + + # + if data is not None: + # wavfile.write('file.wav', rate, data) + # print("Ok") + + plt.plot(data, 'r-', lw=1) + plt.show() + else: + print("Nothing rx") + diff --git a/test_adc2.py b/test_adc2.py new file mode 100644 index 0000000..32ccbf8 --- /dev/null +++ b/test_adc2.py @@ -0,0 +1,17 @@ +#!/bin/env python3 +import time + +import gex +import numpy as np +from matplotlib import pyplot as plt + +from scipy.io import wavfile + +with gex.Client(gex.TrxRawUSB()) as client: + adc = gex.ADC(client, 'adc') + + print(adc.capture(100)) + + # for i in range(1000): + # print(adc.read_raw()) + diff --git a/test_dac.py b/test_dac.py new file mode 100644 index 0000000..d4b1bc1 --- /dev/null +++ b/test_dac.py @@ -0,0 +1,49 @@ +#!/bin/env python3 +import time +import math + +import gex + +from scipy.io import wavfile + +with gex.Client(gex.TrxRawUSB()) as client: + dac = gex.DAC(client, 'dac') + + # dac.set_dither(1, 'TRI', 8) + # # dac.set_dither(3, 'NONE', 8) + # # # + # # # dac.set_frequency(2, 1) + # # # dac.set_frequency(1, 10.01) + # dac.set_waveform(1, 'SIN') + # # dac.set_waveform(2, 'RAMP') + # + # dac.rectangle(2, 0.5, 4095, 0) + # + # dac.set_frequency(1, 100) + # dac.set_frequency(2, 50) + # # + # dac.sync() + + # for i in range(0, 1000): + # dac.set_frequency(1, i) + # time.sleep(0.001) + + dac.waveform(1, 'SIN') + dac.set_frequency(1, 1000) + time.sleep(2) + dac.dc(1, 2047) + + # dac.waveform(1, 'SIN') + # # dac.set_frequency(1, 1000) + # # dac.dc(1,1000) + # dac.dc(2,1000) + + # + # for i in range(0,360*5, 3): + # dac.dc_dual(round(2047+math.cos(((i*3.01)/180)*math.pi)*1900), + # round(2047+math.sin(((i*2.01)/180)*math.pi)*1900), + # confirm=False) + # time.sleep(0.01) + # + # dac.dc_dual(2047,2047) + diff --git a/test_dongle.py b/test_dongle.py new file mode 100644 index 0000000..b266e71 --- /dev/null +++ b/test_dongle.py @@ -0,0 +1,32 @@ +#!/bin/env python3 +import time + +import gex + +# test with the radio gw + +with gex.DongleAdapter(gex.TrxRawUSB(remote=True), 0x10) as transport: +# with gex.TrxRawUSB() as transport: + + # connect GEX client library to the remote slave + client = gex.Client(transport) + + while True: + client.query_raw(type=gex.MSG_PING) + print("ok") + time.sleep(0.1) + + # do = gex.DOut(client, "led") + # adc = gex.ADC(client, "adc") + # + # while True: + # do.toggle(confirm=True) + # print(adc.read_smooth()) + # time.sleep(0.2) + + # adc = gex.ADC(client, "adc") + # for j in range(10): + # try: + # print(adc.read_smooth()) + # except: + # print("Failed") diff --git a/test_freq_cap.py b/test_freq_cap.py new file mode 100644 index 0000000..ca38a66 --- /dev/null +++ b/test_freq_cap.py @@ -0,0 +1,43 @@ +import time + +import gex + +with gex.Client(gex.TrxRawUSB()) as client: + fcap = gex.FCAP(client, 'fcap') + + fcap.stop() + + fcap.indirect_start() + # + time.sleep(2) + print(fcap.indirect_read()) + + # fcap.stop() + # #print(fcap.indirect_burst(3, timeout=20)) + + # r=fcap.indirect_burst(1000, timeout=5) + # print(r) + # print(r.period_raw) + + # fcap.configure(filter=0) + + # print(fcap.measure_pulse()) + + # print(fcap.direct_burst(10)) + # + # fcap.direct_start(1000, 0) + # time.sleep(2) + # + # print(fcap.direct_read()) + # + # fcap.counter_start() + # time.sleep(1) + # print(fcap.counter_clear()) + # time.sleep(1) + # print(fcap.counter_read()) + # time.sleep(1) + # print(fcap.counter_clear()) + # time.sleep(1) + # print(fcap.counter_clear()) + + diff --git a/test_ini.py b/test_ini.py new file mode 100644 index 0000000..0e61d4a --- /dev/null +++ b/test_ini.py @@ -0,0 +1,9 @@ +#!/bin/env python3 +import time + +import gex + +# with gex.Client(gex.TrxRawUSB()) as client: +with gex.DongleAdapter(gex.TrxRawUSB(remote=True), 0x10) as transport: + client = gex.Client(transport) + print(client.ini_read(0)) diff --git a/test_onewire.py b/test_onewire.py new file mode 100644 index 0000000..d0a051a --- /dev/null +++ b/test_onewire.py @@ -0,0 +1,81 @@ +#!/bin/env python3 +import time + +import gex + +with gex.Client(gex.TrxRawUSB()) as client: + ow = gex.OneWire(client, 'ow') + # print("Presence: ", ow.test_presence()) + print("Devices:", ow.search()) + + def meas(addr): + ow.write([0x44], addr=addr) + ow.wait_ready() + data = ow.query([0xBE], 9, addr=addr) + pp = gex.PayloadParser(data) + return pp.i16() * 0.0625 + + def meas2(addr, addr2): + ow.write([0x44], addr=addr) + ow.write([0x44], addr=addr2) + ow.wait_ready() + + data = ow.query([0xBE], 9, addr=addr) + pp = gex.PayloadParser(data) + a = pp.i16() * 0.0625 + + data = ow.query([0xBE], 9, addr=addr2) + pp = gex.PayloadParser(data) + b = pp.i16() * 0.0625 + return a, b + + while True: + (a, b) = meas2(6558392391241695016, 1802309978572980008) + # a = meas(6558392391241695016) + # b = meas(1802309978572980008) + print("in: %.2f °C, out: %f °C" % (a, b)) + + + + # # search the bus for alarm + # if False: + # ow = gex.OneWire(client, 'ow') + # print("Presence: ", ow.test_presence()) + # print("Devices w alarm:", ow.search(alarm=True)) + # + # # simple 1w check + # if False: + # ow = gex.OneWire(client, 'ow') + # print("Presence: ", ow.test_presence()) + # print("ROM: 0x%016x" % ow.read_address()) + # print("Scratch:", ow.query([0xBE], rcount=9, addr=0x7100080104c77610, as_array=True)) + # + # # testing ds1820 temp meas without polling + # if False: + # ow = gex.OneWire(client, 'ow') + # print("Presence: ", ow.test_presence()) + # print("Starting measure...") + # ow.write([0x44]) + # time.sleep(1) + # print("Scratch:", ow.query([0xBE], 9)) + # + # # testing ds1820 temp meas with polling + # if False: + # ow = gex.OneWire(client, 'ow') + # print("Presence: ", ow.test_presence()) + # print("Starting measure...") + # ow.write([0x44]) + # ow.wait_ready() + # data = ow.query([0xBE], 9) + # + # pp = gex.PayloadParser(data) + # + # temp = pp.i16()/2.0 + # th = pp.i8() + # tl = pp.i8() + # reserved = pp.i16() + # remain = float(pp.u8()) + # perc = float(pp.u8()) + # + # realtemp = temp - 0.25+(perc-remain)/perc + # print("Temperature = %f °C (th %d, tl %d)" % (realtemp, th, tl)) diff --git a/test_ping.py b/test_ping.py new file mode 100644 index 0000000..b4118b8 --- /dev/null +++ b/test_ping.py @@ -0,0 +1,7 @@ +#!/bin/env python3 +import time + +import gex + +with gex.Client(gex.TrxSerialThread(port='/dev/ttyACM0')) as client: + pass diff --git a/test_pwmdim_music.py b/test_pwmdim_music.py new file mode 100644 index 0000000..44c150d --- /dev/null +++ b/test_pwmdim_music.py @@ -0,0 +1,47 @@ +import time + +import gex + +# beeping music with PWM (square wave) + +C3 = 130.81; Cx3 = 138.59; D3 = 146.83; Dx3 = 155.56; E3 = 164.81; F3 = 174.61 +Fx3 = 185.00; G3 = 196.00; Gx3 = 207.65; A3 = 220.00; Ax3 = 233.08; B3 = 246.94 +C4 = 261.63; Cx4 = 277.18; D4 = 293.66; Dx4 = 311.13; E4 = 329.63; F4 = 349.23 +Fx4 = 369.99; G4 = 392.00; Gx4 = 415.30; A4 = 440.00; Ax4 = 466.16; B4 = 493.88 +C5 = 523.25; Cx5 = 554.37; D5 = 587.33; Dx5 = 622.25; E5 = 659.25; F5 = 698.46 +Fx5 = 739.99; G5 = 783.99; Gx5 = 830.61; A5 = 880.00; Ax5 = 932.33; B5 = 987.77 + +with gex.Client(gex.TrxRawUSB()) as client: + pwm = gex.PWMDim(client, 'dim') + + # O O/ #/ #~ #= + # 16, 8, 4, 2, 1 + notes = [ + (G3, 2), + (G4, 2), (E4, 6), (G4, 2), (E4, 2), (A4, 6), (0, 2), (B4, 2), + (G4, 2), (E4, 6), (A4, 2), (G4, 2), (D4, 6), (0, 2), (G3, 2), + + (G4, 2), (E4, 6), (D4, 2), (C4, 2), (C5, 6), (0, 2), (A4, 2), + (G4, 2), (E4, 4), (0, 2), (D4, 2), (A3, 2), (C4, 6), (0, 2), (G3, 2), + + #rep + (G4, 2), (E4, 6), (G4, 2), (E4, 2), (A4, 6), (0, 2), (B4, 2), + (G4, 2), (E4, 6), (A4, 2), (G4, 2), (D4, 6), (0, 2), (G3, 2), + + (G4, 2), (E4, 6), (D4, 2), (C4, 2), (C5, 6), (0, 2), (A4, 2), + + (G4, 2), (E4, 6), (D4, 2), (A3, 2), (C4, 6), (0, 2), #(C4, 2), + ] + + for p in notes: + pwm.stop() + time.sleep(0.01) + f = round(p[0]) + print(f) + if f > 0: + pwm.set_frequency(f) + pwm.start() + time.sleep(0.1*p[1]) + + pwm.stop() + diff --git a/test_pwmdim_sweep.py b/test_pwmdim_sweep.py new file mode 100644 index 0000000..ad2606b --- /dev/null +++ b/test_pwmdim_sweep.py @@ -0,0 +1,17 @@ +import time + +import gex + +# pwm frequency sweep + +with gex.Client(gex.TrxRawUSB()) as client: + pwm = gex.PWMDim(client, 'dim') + + pwm.start() + pwm.set_duty_single(1, 500) + for i in range(2000, 200, -15): + pwm.set_frequency(i) + time.sleep(0.05) + + pwm.stop() + diff --git a/test_sipo_omicron.py b/test_sipo_omicron.py new file mode 100644 index 0000000..97c4f78 --- /dev/null +++ b/test_sipo_omicron.py @@ -0,0 +1,21 @@ +import time + +import gex + +# sipo example + +with gex.Client(gex.TrxRawUSB()) as client: + sipo = gex.SIPO(client, 'sipo') + d4 = gex.DOut(client, 'd4') + + # Jort the lights + sipo.load([ + [0x0a, 0x0f], + [0xF8, 0xFC], + [0x00, 0x00], + [0x02, 0x00], + ], end=0x04) + + d4.write(1) + # sipo.set_data(0x04) + # sipo.store() diff --git a/test_touch.py b/test_touch.py new file mode 100644 index 0000000..14d7b2b --- /dev/null +++ b/test_touch.py @@ -0,0 +1,20 @@ +import time + +import gex + +# toush sensing test + +with gex.Client(gex.TrxRawUSB()) as client: + tsc = gex.TOUCH(client, 'tsc') + + print("There are %d touch channels." % tsc.get_channel_count()) + + tsc.set_button_thresholds([1225, 1440, 1440]) + + tsc.listen(0, lambda state, ts: print("Pad 1: %d" % state)) + tsc.listen(1, lambda state, ts: print("Pad 2: %d" % state)) + tsc.listen(2, lambda state, ts: print("Pad 3: %d" % state)) + + while True: + print(tsc.read()) + time.sleep(0.5)