Browse Source

cleaning and updated readme

Ondřej Hruška 1 year ago
parent
commit
3a5ac05d9d
Signed by: Ondřej Hruška <ondra@ondrovo.com> GPG key ID: 2C5FD5035250423D
56 changed files with 72 additions and 3209 deletions
  1. 0 0
      Client.py
  2. 0 0
      PayloadBuilder.py
  3. 0 0
      PayloadParser.py
  4. 72 10
      README.md
  5. 0 0
      TinyFrame.py
  6. 0 0
      Unit.py
  7. 0 0
      __init__.py
  8. 0 49
      examples/demo_adc_lightnings.py
  9. 0 36
      examples/demo_dot_matrix_phat.py
  10. 0 200
      examples/demo_dot_matrix_phat2.py
  11. 0 35
      examples/demo_freq_response.py
  12. 0 23
      examples/demo_i2c_dotmatrix.py
  13. 0 213
      examples/demo_lora.py
  14. 0 37
      examples/demo_ndir_leds.py
  15. 0 18
      examples/demo_ndir_usart.py
  16. 0 17
      examples/demo_neo2.py
  17. 0 39
      examples/demo_neo3.py
  18. 0 11
      examples/demo_neopixel.py
  19. 0 136
      examples/demo_nrf24.py
  20. 0 11
      examples/demo_pulse.py
  21. 0 126
      examples/demo_pymodoro.py
  22. 0 37
      examples/demo_transient.py
  23. 0 78
      examples/loratest.txt
  24. 0 309
      examples/main.py
  25. 0 24
      examples/mat_sampling.m
  26. 0 86
      examples/nrf_config.ini
  27. 0 15
      examples/show_nparray.py
  28. 0 1109
      examples/sx_fsk.py
  29. 0 38
      examples/test_adc.py
  30. 0 17
      examples/test_adc2.py
  31. 0 49
      examples/test_dac.py
  32. 0 32
      examples/test_dongle.py
  33. 0 43
      examples/test_freq_cap.py
  34. 0 9
      examples/test_ini.py
  35. 0 81
      examples/test_onewire.py
  36. 0 7
      examples/test_ping.py
  37. 0 47
      examples/test_pwmdim_music.py
  38. 0 17
      examples/test_pwmdim_sweep.py
  39. 0 21
      examples/test_sipo_omicron.py
  40. 0 20
      examples/test_touch.py
  41. 0 128
      gexync.py
  42. 0 81
      ini_syntax.py
  43. 0 0
      transport.py
  44. 0 0
      units/ADC.py
  45. 0 0
      units/DAC.py
  46. 0 0
      units/DIn.py
  47. 0 0
      units/DOut.py
  48. 0 0
      units/FCAP.py
  49. 0 0
      units/I2C.py
  50. 0 0
      units/Neopixel.py
  51. 0 0
      units/OneWire.py
  52. 0 0
      units/PWMDim.py
  53. 0 0
      units/SIPO.py
  54. 0 0
      units/SPI.py
  55. 0 0
      units/TOUCH.py
  56. 0 0
      units/USART.py

gex/Client.py → Client.py View File


gex/PayloadBuilder.py → PayloadBuilder.py View File


gex/PayloadParser.py → PayloadParser.py View File


+ 72 - 10
README.md View File

@@ -1,9 +1,52 @@
1 1
 # Python client for GEX
2 2
 
3
-This is the primary GEX front-end for user scripting.
3
+This is the primary GEX front-end for user scripting. It may be used natively with python3,
4
+or integrated in MATLAB through the Python call API.
4 5
 
5
-GEX configuration can be persisted on-chip or loaded dynamically using 
6
-the client from a INI file or string.
6
+## Installation
7
+
8
+Add this library as a git submodule 'gex' to your project (or simply copy it there).
9
+
10
+### Linux
11
+
12
+You may want to create this file in `/etc/udev/rules.d/98-gex.rules` and add your user to 
13
+the `plugdev` group.
14
+
15
+```
16
+SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="4c60", GROUP="plugdev", MODE="0660"
17
+SUBSYSTEM=="usb", ATTR{idVendor}=="1209", ATTR{idProduct}=="4c61", GROUP="plugdev", MODE="0660"
18
+```
19
+
20
+
21
+### BSD
22
+
23
+Not tested, may be similar to Linux
24
+
25
+
26
+### Mac
27
+
28
+Not tested
29
+
30
+
31
+### Windows 8.1 and older
32
+
33
+You need to attach the [STM32 Virtual COM Port Driver](http://www.st.com/en/development-tools/stsw-stm32102.html) 
34
+to the GEX device using the Device Manager, if they want to use the Virtual COM port attachment 
35
+method (the Serial transport options, see below).
36
+
37
+Additionally, they may have to configure the Mass Storage endpoint to use the Mass Storage system driver,
38
+because older Windows are not smart enough to figure it out (we're using the standard device class and 
39
+everything, but still).
40
+
41
+The Python scripts can be run with Cygwin, or the Windows Python port.
42
+
43
+
44
+### Windows 10
45
+
46
+It should Just Work™ without any special configuration needed.
47
+
48
+
49
+## Example
7 50
 
8 51
 A sample GEX script could look like this:
9 52
 
@@ -13,16 +56,35 @@ A sample GEX script could look like this:
13 56
 import time
14 57
 import gex
15 58
 
16
-client = gex.Client()
17
-
18
-led = gex.Pin(client, 'LED')
19
-
20
-for i in range(0,10):
59
+with gex.Client() as client:
60
+  led = gex.DOut(client, 'led')
61
+  for i in range(0,10):
21 62
     led.toggle()
22 63
     time.sleep(.1)
23 64
 
24 65
 ```
25 66
 
26
-The client instance can be used to send control commands directly, bypassing the unit drivers.
27
-Writing new unit drivers is simple and straightforward. See any of the existing units for reference.
67
+The client object can be used to send control commands directly, bypassing unit drivers.
68
+
69
+Writing new unit drivers is simple, just extend the Unit class and add the unit-specific 
70
+methods and logic.
71
+
72
+## Transports
73
+
74
+The CLient class takes a Transport instance as a constructor parameter. There are three
75
+transports defined:
76
+
77
+- `TrxSerialSync` - VCOM, blocking (with a polling loop)
78
+
79
+- `TrxSerialThread` - VCOM, asynchronous
80
+
81
+- `TrxRawUSB` - PyUSB, the default and usually the best transport 
82
+
83
+  Pass the device serial ID as am argument to match it if you have multiple 
84
+  GEX modules attached at once.
85
+
86
+Additionally, either transport can be wrapped in `DongleAdapter` when the _Wireless Gateway_ 
87
+dongle is used. The `TrxRawUSB` further needs the second argument, `remote`, set to true in 
88
+this case, to look for devices with the Gateway vid:pid value 1209:4c61. 
89
+GEX modules themselves have 1209:4c60.
28 90
 

gex/TinyFrame.py → TinyFrame.py View File


gex/Unit.py → Unit.py View File


gex/__init__.py → __init__.py View File


+ 0 - 49
examples/demo_adc_lightnings.py View File

@@ -1,49 +0,0 @@
1
-#!/bin/env python3
2
-import time
3
-
4
-import gex
5
-import numpy as np
6
-from matplotlib import pyplot as plt
7
-import datetime
8
-
9
-from scipy.io import wavfile
10
-
11
-# this script captures lightnings and stores them to npy files
12
-
13
-# ADC channel 1 -> 100n -> o -> long wire (antenna)
14
-#                          |
15
-#                          '-> 10k -> GND
16
-
17
-led = None
18
-
19
-def capture(tr):
20
-    now=datetime.datetime.now()
21
-    now.isoformat()
22
-    data = tr.data
23
-    print("Capture! ")
24
-    print(data)
25
-    np.save("lightning-%s"%now.isoformat(), data)
26
-    led.pulse_ms(1000, confirm=False)
27
-
28
-with gex.Client(gex.TrxRawUSB()) as client:
29
-    adc = gex.ADC(client, 'adc')
30
-    led = gex.DOut(client, 'led')
31
-
32
-    adc.set_sample_rate(60000)
33
-
34
-    adc.on_trigger(capture)
35
-    adc.setup_trigger(1,
36
-                      level=2600,
37
-                      count=5000,
38
-                      edge='rising',
39
-                      pretrigger=500,
40
-                      holdoff=500,
41
-                      auto=True)
42
-
43
-    adc.arm()
44
-
45
-    sec = 0
46
-    while True:
47
-        print('%d s' % sec)
48
-        sec += 1
49
-        time.sleep(1)

+ 0 - 36
examples/demo_dot_matrix_phat.py View File

@@ -1,36 +0,0 @@
1
-#!/bin/env python3
2
-import gex
3
-import time
4
-
5
-# simple demo with the dot matrix phat
6
-
7
-ADDR = 0x61
8
-MODE = 0b00011000
9
-OPTS = 0b00001110 # 1110 = 35mA, 0000 = 40mA
10
-
11
-CMD_BRIGHTNESS = 0x19
12
-CMD_MODE = 0x00
13
-CMD_UPDATE = 0x0C
14
-CMD_OPTIONS = 0x0D
15
-
16
-CMD_MATRIX_1 = 0x01
17
-CMD_MATRIX_2 = 0x0E
18
-
19
-with gex.Client(gex.TrxRawUSB()) as client:
20
-    bus = gex.I2C(client, 'i2c')
21
-    addr = 0x61
22
-    bus.write_reg(addr, CMD_MODE, MODE)
23
-    bus.write_reg(addr, CMD_OPTIONS, OPTS)
24
-    bus.write_reg(addr, CMD_BRIGHTNESS, 64)
25
-
26
-    bus.write(addr, [CMD_MATRIX_1,
27
-                     0xAA,0x55,0xAA,0x55,
28
-                     0xAA,0x55,0xAA,0x55,
29
-                     ])
30
-
31
-    bus.write(addr, [CMD_MATRIX_2,
32
-                     0xFF, 0, 0xFF, 0,
33
-                     0xFF, 0, 0xFF, 0,
34
-                     ])
35
-
36
-    bus.write_reg(addr, CMD_UPDATE, 0x01)

+ 0 - 200
examples/demo_dot_matrix_phat2.py View File

@@ -1,200 +0,0 @@
1
-#!/bin/env python3
2
-import random
3
-
4
-import gex
5
-import time
6
-
7
-# This is an adaptation of the micro dot phat library
8
-# - the only change needed was replacing the smbus class with the GEX unit driver
9
-
10
-ADDR = 0x61
11
-MODE = 0b00011000
12
-OPTS = 0b00001110 # 1110 = 35mA, 0000 = 40mA
13
-
14
-CMD_BRIGHTNESS = 0x19
15
-CMD_MODE = 0x00
16
-CMD_UPDATE = 0x0C
17
-CMD_OPTIONS = 0x0D
18
-
19
-CMD_MATRIX_1 = 0x01
20
-CMD_MATRIX_2 = 0x0E
21
-
22
-MATRIX_1 = 0
23
-MATRIX_2 = 1
24
-
25
-class NanoMatrix:
26
-    '''
27
-    _BUF_MATRIX_1 = [ # Green
28
-#Col   1 2 3 4 5
29
-    0b00000000, # Row 1
30
-    0b00000000, # Row 2
31
-    0b00000000, # Row 3
32
-    0b00000000, # Row 4
33
-    0b00000000, # Row 5
34
-    0b00000000, # Row 6
35
-    0b10000000, # Row 7, bit 8 =  decimal place
36
-    0b00000000
37
-]
38
-    _BUF_MATRIX_2 = [ # Red
39
-#Row 8 7 6 5 4 3 2 1
40
-    0b01111111, # Col 1, bottom to top
41
-    0b01111111, # Col 2
42
-    0b01111111, # Col 3
43
-    0b01111111, # Col 4
44
-    0b01111111, # Col 5
45
-    0b00000000,
46
-    0b00000000,
47
-    0b01000000  # bit 7, decimal place
48
-]
49
-    _BUF_MATRIX_1 = [0] * 8
50
-    _BUF_MATRIX_2 = [0] * 8
51
-'''
52
-
53
-    def __init__(self, bus:gex.I2C, address=ADDR):
54
-        self.address = address
55
-        self._brightness = 127
56
-
57
-        self.bus = bus
58
-
59
-        self.bus.write_byte_data(self.address, CMD_MODE, MODE)
60
-        self.bus.write_byte_data(self.address, CMD_OPTIONS, OPTS)
61
-        self.bus.write_byte_data(self.address, CMD_BRIGHTNESS, self._brightness)
62
-
63
-        self._BUF_MATRIX_1 = [0] * 8
64
-        self._BUF_MATRIX_2 = [0] * 8
65
-
66
-    def set_brightness(self, brightness):
67
-        self._brightness = int(brightness * 127)
68
-        if self._brightness > 127: self._brightness = 127
69
-
70
-        self.bus.write_byte_data(self.address, CMD_BRIGHTNESS, self._brightness)
71
-
72
-    def set_decimal(self, m, c):
73
-
74
-        if m == MATRIX_1:
75
-           if c == 1:
76
-               self._BUF_MATRIX_1[6] |= 0b10000000
77
-           else:
78
-               self._BUF_MATRIX_1[6] &= 0b01111111
79
-
80
-        elif m == MATRIX_2:
81
-
82
-           if c == 1:
83
-               self._BUF_MATRIX_2[7] |= 0b01000000
84
-           else:
85
-               self._BUF_MATRIX_2[7] &= 0b10111111
86
-
87
-        #self.update()
88
-
89
-    def set(self, m, data):
90
-        for y in range(7):
91
-            self.set_row(m, y, data[y])
92
-
93
-    def set_row(self, m, r, data):
94
-        for x in range(5):
95
-            self.set_pixel(m, x, r, (data & (1 << (4-x))) > 0)
96
-
97
-    def set_col(self, m, c, data):
98
-        for y in range(7):
99
-            self.set_pixel(m, c, y, (data & (1 << y)) > 0)
100
-
101
-    def set_pixel(self, m, x, y, c):
102
-
103
-        if m == MATRIX_1:
104
-            if c == 1:
105
-                self._BUF_MATRIX_1[y] |= (0b1 << x)
106
-            else:
107
-                self._BUF_MATRIX_1[y] &= ~(0b1 << x)
108
-        elif m == MATRIX_2:
109
-            if c == 1:
110
-                self._BUF_MATRIX_2[x] |= (0b1 << y)
111
-            else:
112
-                self._BUF_MATRIX_2[x] &= ~(0b1 << y)
113
-
114
-        #self.update()
115
-
116
-    def clear(self, m):
117
-        if m == MATRIX_1:
118
-            self._BUF_MATRIX_1 = [0] * 8
119
-        elif m == MATRIX_2:
120
-            self._BUF_MATRIX_2 = [0] * 8
121
-
122
-        self.update()
123
-
124
-    def update(self):
125
-        for x in range(10):
126
-            try:
127
-                self.bus.write_i2c_block_data(self.address, CMD_MATRIX_1, self._BUF_MATRIX_1)
128
-                self.bus.write_i2c_block_data(self.address, CMD_MATRIX_2, self._BUF_MATRIX_2)
129
-
130
-                self.bus.write_byte_data(self.address, CMD_UPDATE, 0x01)
131
-                break
132
-            except IOError:
133
-                print("IO Error")
134
-
135
-
136
-
137
-
138
-with gex.Client(gex.TrxRawUSB()) as client:
139
-    bus = gex.I2C(client, 'i2c')
140
-
141
-    n1 = NanoMatrix(bus, 0x61)
142
-    n2 = NanoMatrix(bus, 0x62)
143
-    n3 = NanoMatrix(bus, 0x63)
144
-
145
-    n1.set_pixel(0, 0, 0, 1)
146
-    n1.set_pixel(0, 4, 0, 1)
147
-    n1.set_pixel(0, 0, 6, 1)
148
-    n1.set_pixel(0, 4, 6, 1)
149
-
150
-    n1.set_pixel(1, 0, 0, 1)
151
-    n1.set_pixel(1, 4, 0, 1)
152
-    n1.set_pixel(1, 0, 3, 1)
153
-    n1.set_pixel(1, 4, 3, 1)
154
-
155
-    n2.set_pixel(0, 0, 2, 1)
156
-    n2.set_pixel(0, 4, 2, 1)
157
-    n2.set_pixel(0, 0, 5, 1)
158
-    n2.set_pixel(0, 4, 5, 1)
159
-
160
-    n2.set_pixel(1, 0, 0, 1)
161
-    n2.set_pixel(1, 4, 0, 1)
162
-    n2.set_pixel(1, 0, 6, 1)
163
-    n2.set_pixel(1, 4, 6, 1)
164
-
165
-
166
-    n3.set_pixel(0, 1, 0, 1)
167
-    n3.set_pixel(0, 3, 0, 1)
168
-    n3.set_pixel(0, 1, 6, 1)
169
-    n3.set_pixel(0, 3, 6, 1)
170
-
171
-    n3.set_pixel(1, 1, 1, 1)
172
-    n3.set_pixel(1, 3, 1, 1)
173
-    n3.set_pixel(1, 1, 5, 1)
174
-    n3.set_pixel(1, 3, 5, 1)
175
-
176
-    n1.update()
177
-    n2.update()
178
-    n3.update()
179
-
180
-    b1 = 64
181
-    b2 = 64
182
-    b3 = 64
183
-
184
-    while True:
185
-        b1 += random.randint(-20, 15)
186
-        b2 += random.randint(-20, 18)
187
-        b3 += random.randint(-15, 13)
188
-
189
-        if b1 < 0: b1 = 0
190
-        if b2 < 0: b2 = 0
191
-        if b3 < 0: b3 = 0
192
-        if b1 > 127: b1 = 127
193
-        if b2 > 127: b2 = 127
194
-        if b3 > 127: b3 = 127
195
-
196
-        n1.set_brightness(b1)
197
-        n2.set_brightness(b2)
198
-        n3.set_brightness(b3)
199
-
200
-        time.sleep(0.05)

+ 0 - 35
examples/demo_freq_response.py View File

@@ -1,35 +0,0 @@
1
-#!/bin/env python3
2
-import gex
3
-import numpy as np
4
-from matplotlib import pyplot as plt
5
-
6
-# frequency response measurement
7
-
8
-with gex.Client(gex.TrxRawUSB()) as client:
9
-    dac = gex.DAC(client, 'dac')
10
-    adc = gex.ADC(client, 'adc')
11
-
12
-    dac.waveform(1, 'SINE')
13
-    adc.set_sample_rate(50000)
14
-
15
-    table = []
16
-
17
-    for i in range(100, 10000, 100):
18
-        dac.set_frequency(1, i)
19
-        data = adc.capture(10000)
20
-        # convert to floats
21
-        samples = data.astype(float)
22
-        amplitude = np.max(samples) - np.min(samples)
23
-        print("%d Hz ... rms %d" % (i, amplitude))
24
-        table.append(i)
25
-        table.append(amplitude)
26
-
27
-    dac.dc(1, 0)
28
-
29
-    t = np.reshape(np.array(table), [int(len(table)/2),2])
30
-    hz = t[:,0]
31
-    am = t[:,1]
32
-
33
-    plt.plot(hz, am, 'r-', lw=1)
34
-    plt.grid()
35
-    plt.show()

+ 0 - 23
examples/demo_i2c_dotmatrix.py View File

@@ -1,23 +0,0 @@
1
-#!/bin/env python3
2
-import gex
3
-
4
-# experiment with the dot matrix driver
5
-
6
-with gex.Client(gex.TrxRawUSB()) as client:
7
-    bus = gex.I2C(client, 'i2c')
8
-    addr = 0x61
9
-    bus.write_reg(addr, 0x00, 0b00011000) # dual matrix
10
-    bus.write_reg(addr, 0x0D, 0b00001110) # 34 mA
11
-    bus.write_reg(addr, 0x19, 64) # set brightness
12
-    # matrix 1
13
-    bus.write_reg(addr, 0x01, [
14
-        0xAA, 0x55, 0xAA, 0x55,
15
-        0xAA, 0x55, 0xAA, 0x55
16
-    ])
17
-    # matrix 2
18
-    bus.write_reg(addr, 0x0E, [
19
-        0xFF, 0x00, 0xFF, 0x00,
20
-        0xFF, 0x00, 0xFF, 0x00
21
-    ])
22
-    # update display
23
-    bus.write_reg(addr, 0x0C, 0x01)

+ 0 - 213
examples/demo_lora.py View File

@@ -1,213 +0,0 @@
1
-import time
2
-
3
-import gex
4
-import sx_fsk as sx
5
-
6
-
7
-# we're demonstrating the use of the GFSK mode of the SX1278
8
-# this is an example of how GEX can be used to control a peripheral module - in this case evaluating
9
-#  it for use in GEX remote
10
-
11
-
12
-class LoRa:
13
-    def __init__(self,
14
-                 rst: gex.DOut,
15
-                 spi: gex.SPI, ssnum):
16
-        self.ss = ssnum
17
-        self.rst = rst
18
-        self.spi = spi
19
-
20
-    def reset(self):
21
-        self.rst.pulse_us(100, active=False)
22
-        time.sleep(0.005)
23
-
24
-    def rd(self, addr):
25
-        return self.spi.query(self.ss, [addr], 1)[0]
26
-
27
-    def wr(self, addr, value):
28
-        self.spi.write(self.ss, [addr | 0x80, value])
29
-
30
-    def rds(self, start, count=1):
31
-        return self.spi.query(self.ss, [start], count)
32
-
33
-    def wrs(self, start, values):
34
-        ba = bytearray()
35
-        ba.append(start | 0x80)
36
-        ba.extend(values)
37
-        self.spi.write(self.ss, ba)
38
-
39
-    def rmw(self, addr, keep, set):
40
-        """ rmw, first and-ing the register with mask and then oring with set """
41
-        val = self.rd(addr)
42
-        self.wr(addr, (val & keep) | set)
43
-
44
-    def waitModeSwitch(self):
45
-        while 0 == (self.rd(sx.REG_IRQFLAGS1) & sx.RF_IRQFLAGS1_MODEREADY):
46
-            time.sleep(0.001)
47
-
48
-    def waitSent(self):
49
-        while 0 == (self.rd(sx.REG_IRQFLAGS2) & sx.RF_IRQFLAGS2_PACKETSENT):
50
-            time.sleep(0.001)
51
-
52
-    def fsk_set_defaults(self):
53
-        # Set default values (semtech patches: * in DS)
54
-        self.rmw(sx.REG_RXCONFIG,
55
-                 sx.RF_RXCONFIG_RXTRIGER_MASK,
56
-                 sx.RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT)
57
-
58
-        self.wr(sx.REG_PREAMBLEDETECT,
59
-             sx.RF_PREAMBLEDETECT_DETECTOR_ON |
60
-             sx.RF_PREAMBLEDETECT_DETECTORSIZE_2 |
61
-             sx.RF_PREAMBLEDETECT_DETECTORTOL_10)
62
-
63
-        self.rmw(sx.REG_OSC, sx.RF_OSC_CLKOUT_MASK, sx.RF_OSC_CLKOUT_OFF)
64
-
65
-        self.rmw(sx.REG_FIFOTHRESH,
66
-                 sx.RF_FIFOTHRESH_TXSTARTCONDITION_MASK,
67
-                 sx.RF_FIFOTHRESH_TXSTARTCONDITION_FIFONOTEMPTY)
68
-
69
-        self.rmw(sx.REG_IMAGECAL,
70
-                 sx.RF_IMAGECAL_AUTOIMAGECAL_MASK,
71
-                 sx.RF_IMAGECAL_AUTOIMAGECAL_OFF)
72
-
73
-    def configure_for_fsk(self, address):
74
-        self.rmw(sx.REG_OPMODE,
75
-              sx.RF_OPMODE_LONGRANGEMODE_MASK & sx.RF_OPMODE_MODULATIONTYPE_MASK & sx.RF_OPMODE_MASK,
76
-                 sx.RF_OPMODE_LONGRANGEMODE_OFF |
77
-                 sx.RF_OPMODE_MODULATIONTYPE_FSK |
78
-                 sx.RF_OPMODE_STANDBY)
79
-        self.waitModeSwitch()
80
-
81
-        self.fsk_set_defaults()
82
-        self.wr(sx.REG_NODEADRS, address)
83
-        self.wr(sx.REG_BROADCASTADRS, 0xFF)
84
-        # use whitening and force address matching
85
-        self.rmw(sx.REG_PACKETCONFIG1,
86
-              sx.RF_PACKETCONFIG1_DCFREE_MASK & sx.RF_PACKETCONFIG1_ADDRSFILTERING_MASK,
87
-                 sx.RF_PACKETCONFIG1_DCFREE_WHITENING |
88
-                 sx.RF_PACKETCONFIG1_ADDRSFILTERING_NODEBROADCAST)
89
-
90
-        self.wr(sx.REG_RXCONFIG,
91
-                sx.RF_RXCONFIG_AFCAUTO_ON |
92
-                sx.RF_RXCONFIG_AGCAUTO_ON |
93
-                sx.RF_RXCONFIG_RXTRIGER_PREAMBLEDETECT)
94
-
95
-        XTAL_FREQ = 32000000
96
-        FREQ_STEP = 61.03515625
97
-        FSK_FDEV = 60000  # Hz NOTE: originally: 25000, seems to help increasing
98
-        FSK_DATARATE = 200000  # bps - originally 50000
99
-
100
-        MAX_RFPOWER = 0 # 0-7 boost - this doesnt seem to have a huge impact
101
-
102
-        FSK_PREAMBLE_LENGTH = 5  # Same for Tx and Rx
103
-
104
-        fdev = round(FSK_FDEV / FREQ_STEP)
105
-        self.wr(sx.REG_FDEVMSB, fdev >> 8)
106
-        self.wr(sx.REG_FDEVLSB, fdev & 0xFF)
107
-
108
-        datarate = round(XTAL_FREQ / FSK_DATARATE)
109
-        print("dr=%d"%datarate)
110
-        self.wr(sx.REG_BITRATEMSB, datarate >> 8)
111
-        self.wr(sx.REG_BITRATELSB, datarate & 0xFF)
112
-
113
-        preamblelen = FSK_PREAMBLE_LENGTH
114
-        self.wr(sx.REG_PREAMBLEMSB, preamblelen >> 8)
115
-        self.wr(sx.REG_PREAMBLELSB, preamblelen & 0xFF)
116
-
117
-        # bandwidths - 1 MHz
118
-        self.wr(sx.REG_RXBW, 0x0A) # FSK_BANDWIDTH
119
-        self.wr(sx.REG_AFCBW, 0x0A) # FSK_AFC_BANDWIDTH
120
-
121
-        # max payload len to rx
122
-        self.wr(sx.REG_PAYLOADLENGTH, 0xFF)
123
-
124
-        self.rmw(sx.REG_PARAMP, 0x9F, 0x40) # enable gauss 0.5
125
-
126
-        # pick the sync word size
127
-        self.rmw(sx.REG_SYNCCONFIG,
128
-                 sx.RF_SYNCCONFIG_SYNCSIZE_MASK,
129
-                 sx.RF_SYNCCONFIG_SYNCSIZE_3)
130
-
131
-        # sync word (network ID)
132
-        self.wrs(sx.REG_SYNCVALUE1, [
133
-            0xe7, 0x3d, 0xfa, 0x01, 0x5e, 0xa1, 0xc9, 0x98 # something random
134
-        ])
135
-
136
-        # enable LNA boost (?)
137
-        self.rmw(sx.REG_LNA,
138
-                 sx.RF_LNA_BOOST_MASK,
139
-                 sx.RF_LNA_BOOST_ON)
140
-
141
-        # experiments with the pa config
142
-        self.rmw(sx.REG_PACONFIG,
143
-                 sx.RF_PACONFIG_PASELECT_MASK|0x8F, # max power mask
144
-                 sx.RF_PACONFIG_PASELECT_PABOOST | MAX_RFPOWER<<4)
145
-
146
-        # we could also possibly adjust the Tx power
147
-
148
-
149
-
150
-with gex.Client(gex.TrxRawUSB()) as client:
151
-    spi = gex.SPI(client, 'spi')
152
-    rst1 = gex.DOut(client, 'rst1')
153
-    rst2 = gex.DOut(client, 'rst2')
154
-
155
-    a = LoRa(rst1, spi, 0)
156
-    b = LoRa(rst2, spi, 1)
157
-
158
-    # reset the two transceivers to ensure they start in a defined state
159
-    a.reset()
160
-    b.reset()
161
-
162
-    # go to sleep mode, select FSK
163
-    a.configure_for_fsk(0x33)
164
-    b.configure_for_fsk(0x44)
165
-
166
-    print("Devices configured")
167
-
168
-    for j in range(0, 240):
169
-        if(j>0 and j%60==0):
170
-            print()
171
-
172
-        # --- Send a message from 1 to 2 ---
173
-        msg = [
174
-            51, # len
175
-            0x44, # address
176
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
177
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
178
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
179
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
180
-            0, 1, 2, 3, 4, 5, 6, 7, 8, j
181
-        ]
182
-
183
-        a.wrs(sx.REG_FIFO, msg)
184
-
185
-        b.rmw(sx.REG_OPMODE, sx.RF_OPMODE_MASK, sx.RF_OPMODE_RECEIVER)
186
-        # time.sleep(0.005)
187
-
188
-        # trigger A
189
-        a.rmw(sx.REG_OPMODE, sx.RF_OPMODE_MASK, sx.RF_OPMODE_TRANSMITTER)
190
-        a.waitModeSwitch()
191
-        a.waitSent()
192
-        # time.sleep(0.02)
193
-
194
-        # print("a irq flags = ", ["0x%02x"%x for x in a.rds(sx.REG_IRQFLAGS1, 2)])
195
-        # print("b irq flags = ", ["0x%02x"%x for x in b.rds(sx.REG_IRQFLAGS1, 2)])
196
-
197
-        rxd = [b.rd(sx.REG_FIFO) for x in range(0,len(msg))]
198
-        if rxd == msg:
199
-            print("\x1b[32;1m+\x1b[0m", end="", flush=True)
200
-        else:
201
-            print("\x1b[31m-\x1b[0m", end="", flush=True)
202
-        #
203
-        # for i in range(0,8):
204
-        #     print("0x%02x" % rxd[i],end=" ")
205
-        # print()
206
-        # print()
207
-    print()
208
-
209
-    # good night
210
-    a.rmw(sx.REG_OPMODE, sx.RF_OPMODE_MASK, sx.RF_OPMODE_SLEEP)
211
-    b.rmw(sx.REG_OPMODE, sx.RF_OPMODE_MASK, sx.RF_OPMODE_SLEEP)
212
-
213
-

+ 0 - 37
examples/demo_ndir_leds.py View File

@@ -1,37 +0,0 @@
1
-import time
2
-
3
-import gex
4
-
5
-# NDIR CO2 sensor showing the concentration on a SIPO-based LED display
6
-
7
-with gex.Client(gex.TrxRawUSB()) as client:
8
-    ser = gex.USART(client, 'ser')
9
-    leds = gex.SIPO(client, 'leds')
10
-
11
-    while True:
12
-        ser.clear_buffer()
13
-        ser.write([0xFF, 0x01, 0x86, 0, 0, 0, 0, 0, 0x79])
14
-        data = ser.receive(9, decode=None)
15
-
16
-        pp = gex.PayloadParser(data, endian="big").skip(2)
17
-        ppm = pp.u16()
18
-        
19
-        # The LEDs are connected to two 595's, interleaved R,G,R,G...
20
-        nl = (ppm-300)/1700.0
21
-        print("%d ppm CO₂, numleds %f" % (ppm, nl*8))
22
-        
23
-        numb = 0
24
-        for i in range(0,8):
25
-          if nl >= i*0.125:
26
-            if i < 3:
27
-              numb |= 2<<(i*2)
28
-            elif i < 6:
29
-              numb |= 3<<(i*2)
30
-            else:
31
-              numb |= 1<<(i*2)
32
-        
33
-        leds.load([(numb&0xFF00)>>8,numb&0xFF])
34
-        
35
-
36
-        time.sleep(1)
37
-

+ 0 - 18
examples/demo_ndir_usart.py View File

@@ -1,18 +0,0 @@
1
-import time
2
-
3
-import gex
4
-
5
-# basic NDIR CO2 sensor readout
6
-
7
-with gex.Client(gex.TrxRawUSB()) as client:
8
-    ser = gex.USART(client, 'ser')
9
-
10
-    while True:
11
-        ser.clear_buffer()
12
-        ser.write([0xFF, 0x01, 0x86, 0, 0, 0, 0, 0, 0x79])
13
-        data = ser.receive(9, decode=None)
14
-
15
-        pp = gex.PayloadParser(data, endian="big").skip(2)
16
-        print("%d ppm CO₂" % pp.u16())
17
-
18
-        time.sleep(1)

+ 0 - 17
examples/demo_neo2.py View File

@@ -1,17 +0,0 @@
1
-#!/bin/env python3
2
-import gex
3
-import time
4
-
5
-# play a little neopixel animation as a demo
6
-
7
-with gex.Client(gex.TrxRawUSB()) as client:
8
-    # Neopixel strip
9
-    strip = gex.Neopixel(client, 'npx')
10
-    # Load RGB to the strip
11
-    strip.load([0xFF0000, 0xFFFF00, 0x00FF00, 0x0000FF, 0xFF00FF])
12
-    
13
-    for i in range(0,255):
14
-        strip.load([0xFF0000+i, 0xFFFF00, 0x00FF00, 0x0000FF, 0xFF00FF])
15
-        time.sleep(0.01)
16
-        
17
-    strip.clear()

+ 0 - 39
examples/demo_neo3.py View File

@@ -1,39 +0,0 @@
1
-#!/bin/env python3
2
-import gex
3
-import time
4
-
5
-# this shows a spinny animation on a 30-pixel strip forming a circle
6
-
7
-def draw_comet(buf, index):
8
-    r = 0xFF
9
-    g = 0x22
10
-    b = 0x00
11
-    steps = 5
12
-    fades = [0.05, 1, 0.5, 0.1, 0.05]
13
-
14
-    for i in range(steps):
15
-        fade = fades[i]
16
-        buf[(len(buf) + index - i)%len(buf)] = \
17
-            round(r * fade)<<16 | \
18
-            round(g * fade)<<8 | \
19
-            round(b * fade)
20
-
21
-with gex.Client(gex.TrxRawUSB()) as client:
22
-    # Neopixel strip
23
-    strip = gex.Neopixel(client, 'npx')
24
-
25
-    markers = [0, 15]
26
-    for i in range(1000):
27
-        buf = [0]*30
28
-        for j in range(len(markers)):
29
-            n = markers[j]
30
-
31
-            draw_comet(buf, n)
32
-
33
-            n = n + 1 if n < len(buf)-1 else 0
34
-            markers[j] = n
35
-
36
-        strip.load(buf)
37
-        time.sleep(0.02)
38
-        
39
-    strip.clear()

+ 0 - 11
examples/demo_neopixel.py View File

@@ -1,11 +0,0 @@
1
-#!/bin/env python3
2
-import gex
3
-
4
-# the most basic neopixel demo
5
-
6
-with gex.Client(gex.TrxRawUSB()) as client:
7
-    # Neopixel strip
8
-    strip = gex.Neopixel(client, 'npx')
9
-    # Load RGB to the strip
10
-    strip.load([0xFF0000, 0x00FF00, 0x0000FF, 0xFF00FF])
11
-

+ 0 - 136
examples/demo_nrf24.py View File

@@ -1,136 +0,0 @@
1
-import time
2
-
3
-import gex
4
-import sx_fsk as sx
5
-
6
-
7
-# this is a demo with two NRF24L01+ modules connected to SPI and some GPIO.
8
-
9
-class Nrf:
10
-    def __init__(self, ce: gex.DOut, irq: gex.DIn, spi: gex.SPI, num):
11
-        self.snum = num
12
-        self.ce = ce
13
-        self.irq = irq
14
-        self.spi = spi
15
-
16
-    def rd(self, addr, count=1):
17
-        # addr 0-31
18
-        return self.spi.query(self.snum, [addr&0x1F], rlen=count)
19
-
20
-    def wr(self, addr, vals):
21
-        if type(vals) == int:
22
-            vals = [vals]
23
-
24
-        # addr 0-31
25
-        ba = bytearray()
26
-        ba.append(addr | 0x20)
27
-        ba.extend(vals)
28
-        self.spi.write(self.snum, ba)
29
-
30
-    def rd_payload(self, count):
31
-        """ Read a received payload """
32
-        return self.spi.query(self.snum, [0x61], rlen=count)
33
-
34
-    def wr_payload(self, pld):
35
-        """ Write a payload """
36
-        ba = bytearray()
37
-        ba.append(0xA0)
38
-        ba.extend(pld)
39
-        self.spi.write(self.snum, ba)
40
-
41
-    def flush_tx(self):
42
-        self.spi.write(self.snum, [0xE1])
43
-
44
-    def flush_rx(self):
45
-        self.spi.write(self.snum, [0xE2])
46
-
47
-    def reuse_tx_pld(self):
48
-        self.spi.write(self.snum, [0xE3])
49
-
50
-    def get_pld_len(self):
51
-        """ Read length of the first Rx payload in the FIFO - available only if dyn len enabled """
52
-        return self.spi.query(self.snum, [0x60], rlen=1)[0]
53
-
54
-    def wr_ack_payload(self, pipe, pld):
55
-        """ Write a payload to be attached to the next sent ACK """
56
-        ba = bytearray()
57
-        ba.append(0xA8|(pipe&0x7))
58
-        ba.extend(pld)
59
-        self.spi.write(self.snum, ba)
60
-
61
-    def wr_payload_noack(self, pld):
62
-        """ Send a payload without ACK """
63
-        ba = bytearray()
64
-        ba.append(0xB0)
65
-        ba.extend(pld)
66
-        self.spi.write(self.snum, ba)
67
-
68
-    def status(self):
69
-        """ Send a payload without ACK """
70
-        return self.spi.query(self.snum, [0xFF], rlen=1, rskip=0)[0]
71
-
72
-
73
-with gex.Client(gex.TrxRawUSB()) as client:
74
-    spi = gex.SPI(client, 'spi')
75
-    ce = gex.DOut(client, 'ce')
76
-    irq = gex.DIn(client, 'irq')
77
-
78
-    a = Nrf(ce, irq, spi, 0)
79
-    b = Nrf(ce, irq, spi, 1)
80
-    a.flush_tx()
81
-    a.flush_rx()
82
-    b.flush_tx()
83
-    b.flush_rx()
84
-
85
-    # transmit demo
86
-    # a is PTX, b is PRX
87
-    ce.clear(0b11)
88
-
89
-    # a_adr = [0xA1,0xA2,0xA3,0xA4,0x01]
90
-    b_pipe0_adr = [0xA1, 0xA2, 0xA3, 0xA4, 0x02]
91
-
92
-    # --- Configure A for Tx of a 32-long payload ---
93
-
94
-    # PWR DN - simulate reset
95
-    a.wr(0x00, 0)
96
-    b.wr(0x00, 0)
97
-    time.sleep(0.001)
98
-
99
-    a.wr(0x00, 0b00001010) # set PWR_ON=1, EN_CRC=1, all irq enabled
100
-    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])
101
-
102
-    chnl = 5
103
-
104
-    # Set B's address as target and also pipe 0 Rx (used for ack)
105
-    a.wr(0x10, b_pipe0_adr) # target addr
106
-    a.wr(0x0A, b_pipe0_adr) # pipe 0 rx addr for ACK
107
-    a.wr(0x04, 0b00101111) # configure retransmit
108
-    a.wr(0x05, chnl)
109
-
110
-    # --- Configure B for Rx ---
111
-
112
-    b.wr(0x00, 0b00001011)  # set PWR_ON=1, PRIM_RX=1, EN_CRC=1, all irq enabled
113
-    b.wr(0x02,   0b000001)  # enable pipe 0
114
-    b.wr(0x11, 32) # set pipe 0 len to 11
115
-    b.wr(0x0A, b_pipe0_adr) # set pipe 0's address
116
-    b.wr(0x05, chnl)
117
-
118
-    ce.set(0b10) # CE high for B
119
-    time.sleep(0.01)
120
-
121
-    ce.pulse_us(us=10, pins=0b01) # Pulse A's CE
122
-    #
123
-    # testing B's FIFO by sending another payload...
124
-    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])
125
-    ce.pulse_us(us=20, pins=0b01) # Pulse A's CE
126
-
127
-    time.sleep(0.01)
128
-
129
-    print("A's status after Tx: %02x" % a.status())
130
-    print("B's status after Tx: %02x" % b.status())
131
-
132
-    ce.clear(0b11)
133
-
134
-    # read the two payloads
135
-    print(b.rd_payload(32))
136
-    print(b.rd_payload(32))

+ 0 - 11
examples/demo_pulse.py View File

@@ -1,11 +0,0 @@
1
-#!/bin/env python3
2
-import gex
3
-import time
4
-
5
-# generating a pulse on gpio, test of the unit
6
-
7
-with gex.Client(gex.TrxRawUSB()) as client:
8
-    out = gex.DOut(client, 'out')
9
-
10
-    out.pulse_us([0], 20)
11
-    out.pulse_us([3], 10)

+ 0 - 126
examples/demo_pymodoro.py View File

@@ -1,126 +0,0 @@
1
-import time
2
-import gex
3
-
4
-# GEX pomodoro timer
5
-
6
-# button btn
7
-# neopixel neo
8
-
9
-# this is an example of using GEX as a user interface.
10
-# for practical use it would be better to make this into a standalone device with a custom firmware.
11
-
12
-WK_TIME = 25
13
-BK_TIME = 5
14
-LIGHT_CNT = 30
15
-
16
-PH_BREAK = 'Break'
17
-PH_BREAK_OVER = 'BreakOver'
18
-PH_WORK = 'Work'
19
-PH_WORK_OVER = 'WorkOver'
20
-
21
-class Pymodoro:
22
-    def __init__(self):
23
-        self.phase = PH_BREAK_OVER
24
-        self.work_s = 0
25
-        self.break_s = 0
26
-        self.color = 0x000000
27
-        self.colors = [0x000000 for _ in range(0, LIGHT_CNT)]
28
-
29
-        self.client = gex.Client(gex.TrxRawUSB())
30
-        self.btn = gex.DIn(self.client, 'btn')
31
-        self.neo = gex.Neopixel(self.client, 'neo')
32
-        self.btn.on_trigger([0], self.on_btn)
33
-
34
-        self.switch(PH_BREAK_OVER)
35
-        self.display()
36
-
37
-    def display(self):
38
-        self.neo.load(self.colors)
39
-
40
-    def on_btn(self, snapshot, timestamp):
41
-        if self.phase == PH_BREAK_OVER:
42
-            self.switch(PH_WORK)
43
-            
44
-        elif self.phase == PH_WORK:
45
-            self.switch(PH_WORK) # restart
46
-
47
-        elif self.phase == PH_WORK_OVER:
48
-            self.switch(PH_BREAK)
49
-
50
-    def switch(self, phase):
51
-        print("Switch to %s" % phase)
52
-
53
-        if phase == PH_BREAK:
54
-            self.color = 0x009900
55
-            self.break_s = BK_TIME * 60
56
-
57
-        elif phase == PH_BREAK_OVER:
58
-            self.color = 0x662200
59
-
60
-        elif phase == PH_WORK:
61
-            self.color = 0x990000
62
-            self.work_s = WK_TIME * 60
63
-
64
-        elif phase == PH_WORK_OVER:
65
-            self.color = 0x113300
66
-
67
-        self.colors = [self.color for _ in range(0, LIGHT_CNT)]
68
-        self.phase = phase
69
-
70
-    def show_progress(self, dark, total):
71
-        per_light = total / LIGHT_CNT
72
-        lights = dark / per_light
73
-
74
-        lights /= 2
75
-
76
-        remainder = float(lights - int(lights))
77
-        if remainder == 0:
78
-            remainder = 1
79
-
80
-        # print("lights %f, remainder %f" % (lights, remainder))
81
-        for i in range(0, int(LIGHT_CNT/2)):
82
-            if i < int((LIGHT_CNT/2)-lights):
83
-                c = 0x000000
84
-            elif i == int((LIGHT_CNT/2)-lights):
85
-                r = (self.color&0xFF0000)>>16
86
-                g = (self.color&0xFF00)>>8
87
-                b = self.color&0xFF
88
-                c = (int(r*remainder))<<16 | (int(g*remainder))<<8 | (int(b*remainder))
89
-            else:
90
-                c = self.color
91
-
92
-            self.colors[i] = c
93
-            self.colors[LIGHT_CNT - 1 - i] = c
94
-
95
-    def tick(self, elapsed):
96
-        if self.phase == PH_BREAK:
97
-            self.break_s -= elapsed
98
-            # print("Break remain: %d s" % self.break_s)
99
-            self.show_progress(self.break_s, BK_TIME * 60)
100
-
101
-            if self.break_s <= 0:
102
-                self.switch(PH_BREAK_OVER)
103
-
104
-        elif self.phase == PH_WORK:
105
-            self.work_s -= elapsed
106
-            # print("Work remain: %d s" % self.work_s)
107
-            self.show_progress(self.work_s, WK_TIME * 60)
108
-
109
-            if self.work_s <= 0:
110
-                self.switch(PH_WORK_OVER)
111
-
112
-        self.display()
113
-
114
-    def run(self):
115
-        step=0.5
116
-        try:
117
-            while True:
118
-                time.sleep(step)
119
-                self.tick(step)
120
-        except KeyboardInterrupt:
121
-            self.client.close()
122
-            print() # this puts the ^C on its own line
123
-
124
-
125
-a = Pymodoro()
126
-a.run()

+ 0 - 37
examples/demo_transient.py View File

@@ -1,37 +0,0 @@
1
-#!/bin/env python3
2
-import time
3
-
4
-import gex
5
-import numpy as np
6
-from matplotlib import pyplot as plt
7
-
8
-from scipy.io import wavfile
9
-
10
-# catching a transient
11
-
12
-with gex.Client(gex.TrxRawUSB()) as client:
13
-    adc = gex.ADC(client, 'adc')
14
-
15
-    rate=50000
16
-    fs = adc.set_sample_rate(rate)
17
-
18
-    d = None
19
-
20
-    def x(report):
21
-        global d
22
-        print("capt")
23
-        d = report
24
-
25
-    adc.on_trigger(x)
26
-    adc.setup_trigger(0, 50, 600, edge='rising', pretrigger=100)
27
-    adc.arm()
28
-
29
-    time.sleep(2)
30
-
31
-    if d is not None:
32
-        plt.plot(d.data, 'r-', lw=1)
33
-        plt.grid()
34
-        plt.show()
35
-    else:
36
-        print("Nothing rx")
37
-

+ 0 - 78
examples/loratest.txt View File

@@ -1,78 +0,0 @@
1
-## UNITS.INI
2
-## GEX v0.0.1 on STM32F072-HUB
3
-## built Mar 17 2018 at 17:53:15
4
-
5
-[UNITS]
6
-# Create units by adding their names next to a type (e.g. DO=A,B),
7
-# remove the same way. Reload to update the unit sections below.
8
-
9
-# Digital output
10
-DO=rst1,rst2
11
-# Digital input with triggers
12
-DI=
13
-# Neopixel RGB LED strip
14
-NPX=
15
-# I2C master
16
-I2C=
17
-# SPI master
18
-SPI=spi
19
-# Serial port
20
-USART=
21
-# 1-Wire master
22
-1WIRE=
23
-# Analog/digital converter
24
-ADC=
25
-# Shift register driver (595, 4094)
26
-SIPO=
27
-# Frequency and pulse measurement
28
-FCAP=
29
-# Capacitive touch sensing
30
-TOUCH=
31
-# Simple PWM output
32
-PWMDIM=
33
-# Two-channel analog output with waveforms
34
-DAC=
35
-
36
-[DO:rst1@2]
37
-# Port name
38
-port=B
39
-# Pins (comma separated, supports ranges)
40
-pins=2
41
-# Initially high pins
42
-initial=2
43
-# Open-drain pins
44
-open-drain=
45
-
46
-[DO:rst2@3]
47
-# Port name
48
-port=B
49
-# Pins (comma separated, supports ranges)
50
-pins=6
51
-# Initially high pins
52
-initial=6
53
-# Open-drain pins
54
-open-drain=
55
-
56
-[SPI:spi@1]
57
-# Peripheral number (SPIx)
58
-device=1
59
-# Pin mappings (SCK,MISO,MOSI)
60
-#  SPI1: (0) A5,A6,A7     (1) B3,B4,B5
61
-#  SPI2: (0) B13,B14,B15
62
-remap=1
63
-
64
-# Prescaller: 2,4,8,...,256
65
-prescaller=64
66
-# Clock polarity: 0,1 (clock idle level)
67
-cpol=0
68
-# Clock phase: 0,1 (active edge, 0-first, 1-second)
69
-cpha=0
70
-# Transmit only, disable MISO
71
-tx-only=N
72
-# Bit order (LSB or MSB first)
73
-first-bit=MSB
74
-
75
-# SS port name
76
-port=B
77
-# SS pins (comma separated, supports ranges)
78
-pins=1-0

+ 0 - 309
examples/main.py View File

@@ -1,309 +0,0 @@
1
-#!/bin/env python3
2
-import time
3
-
4
-import numpy as np
5
-from matplotlib import pyplot as plt
6
-
7
-import gex
8
-
9
-transport = gex.TrxRawUSB(sn='0029002F-42365711-32353530')
10
-#transport = gex.TrxSerialSync(port='/dev/ttyACM0')
11
-
12
-with gex.Client(transport) as client:
13
-    #
14
-    # if True:
15
-    #     s = client.ini_read()
16
-    #     print(s)
17
-    #     client.ini_write(s)
18
-
19
-    if True:
20
-        sipo = gex.SIPO(client, 'sipo')
21
-        sipo.load([[0xA5], [0xFF]])
22
-
23
-    if False:
24
-        adc = gex.ADC(client, 'adc')
25
-        print("Enabled channels:", adc.get_channels())
26
-
27
-        adc.set_smoothing_factor(0.9)
28
-
29
-        while True:
30
-            raw = adc.read_raw()
31
-            smooth = adc.read_smooth()
32
-            print("IN1 = %d (%.2f), Tsens = %d (%.2f), Vrefint = %d (%.2f)" % (raw[1], smooth[1],
33
-                                                                               raw[16], smooth[16],
34
-                                                                               raw[17], smooth[17]))
35
-            time.sleep(0.5)
36
-
37
-    if False:
38
-        adc = gex.ADC(client, 'adc')
39
-
40
-        adc.set_active_channels([1])
41
-        fs = adc.set_sample_rate(1000)
42
-
43
-        data = adc.capture(1000)
44
-
45
-        if data is not None:
46
-            plt.plot(data, 'r-', lw=1)
47
-            plt.show()
48
-        else:
49
-            print("Nothing rx")
50
-
51
-
52
-        # for r in range(0,8):
53
-        #     adc.set_sample_time(r)
54
-        #     data = adc.capture(10000)
55
-        #     print("sr = %d" % r)
56
-        #     std = np.std(data)
57
-        #     print(std)
58
-
59
-
60
-        #
61
-        # global data
62
-        # data = None
63
-        #
64
-        # def capture(rpt):
65
-        #     global data
66
-        #     print("trig'd, %s" % rpt)
67
-        #     data = rpt.data
68
-        # #
69
-        # # adc.setup_trigger(channel=1,
70
-        # #                   level=700,
71
-        # #                   count=20000,
72
-        # #                   pretrigger=100,
73
-        # #                   auto=False,
74
-        # #                   edge="falling",
75
-        # #                   holdoff=200,
76
-        # #                   handler=capture)
77
-        #
78
-        # # adc.arm()
79
-        #
80
-        # data = adc.capture(1000)
81
-        #
82
-        # if data is not None:
83
-        #     plt.plot(data, 'r.', lw=1)
84
-        #     plt.show()
85
-        # else:
86
-        #     print("Nothing rx")
87
-
88
-        # plt.magnitude_spectrum(data[:,0], Fs=fs, scale='dB', color='C1')
89
-        # plt.show()
90
-
91
-        # def lst(data):
92
-        #     if data is not None:
93
-        #         print("Rx OK") #data
94
-        #     else:
95
-        #         print("Closed.")
96
-
97
-        # adc.stream_start(lst)
98
-        # time.sleep(3)
99
-        # adc.stream_stop()
100
-        # print("Done.")
101
-
102
-
103
-
104
-
105
-        # time.sleep(.1)
106
-        # print(adc.get_sample_rate())
107
-        # time.sleep(.1)
108
-
109
-        # adc.stream_stop()
110
-        # time.sleep(5)
111
-
112
-        # print(adc.capture(200, 5))
113
-
114
-        # adc.setup_trigger(channel=1,
115
-        #                   level=700,
116
-        #                   count=100,
117
-        #                   pretrigger=15,
118
-        #                   auto=True,
119
-        #                   edge="falling",
120
-        #                   holdoff=200,
121
-        #                   handler=lambda rpt: print("Report: %s" % rpt))
122
-        #
123
-        # print("Armed")
124
-        # adc.arm()
125
-        # print("Sleep...")
126
-        # # adc.force()
127
-        # #
128
-        # # # adc.disarm()
129
-        # time.sleep(5)
130
-        # adc.disarm()
131
-
132
-        # print(adc.capture(200, 50))
133
-
134
-        # adc.stream_start(lambda data: print(data))
135
-        # time.sleep(20)
136
-        # adc.stream_stop()
137
-
138
-
139
-        # print(adc.read_raw())
140
-
141
-        # time.sleep(1)
142
-        # print("Rx: ", resp)
143
-        # adc.abort()
144
-
145
-    if False:
146
-        s = client.ini_read()
147
-        print(s)
148
-        client.ini_write(s)
149
-
150
-    # search the bus
151
-    if False:
152
-        ow = gex.OneWire(client, 'ow')
153
-        print("Devices:", ow.search())
154
-
155
-    # search the bus for alarm
156
-    if False:
157
-        ow = gex.OneWire(client, 'ow')
158
-        print("Presence: ", ow.test_presence())
159
-        print("Devices w alarm:", ow.search(alarm=True))
160
-
161
-    # simple 1w check
162
-    if False:
163
-        ow = gex.OneWire(client, 'ow')
164
-        print("Presence: ", ow.test_presence())
165
-        print("ROM: 0x%016x" % ow.read_address())
166
-        print("Scratch:", ow.query([0xBE], rcount=9, addr=0x7100080104c77610, as_array=True))
167
-
168
-    # testing ds1820 temp meas without polling
169
-    if False:
170
-        ow = gex.OneWire(client, 'ow')
171
-        print("Presence: ", ow.test_presence())
172
-        print("Starting measure...")
173
-        ow.write([0x44])
174
-        time.sleep(1)
175
-        print("Scratch:", ow.query([0xBE], 9))
176
-
177
-    # testing ds1820 temp meas with polling
178
-    if False:
179
-        ow = gex.OneWire(client, 'ow')
180
-        print("Presence: ", ow.test_presence())
181
-        print("Starting measure...")
182
-        ow.write([0x44])
183
-        ow.wait_ready()
184
-        data = ow.query([0xBE], 9)
185
-
186
-        pp = gex.PayloadParser(data)
187
-
188
-        temp = pp.i16()/2.0
189
-        th = pp.i8()
190
-        tl = pp.i8()
191
-        reserved = pp.i16()
192
-        remain = float(pp.u8())
193
-        perc = float(pp.u8())
194
-
195
-        realtemp = temp - 0.25+(perc-remain)/perc
196
-        print("Temperature = %f °C (th %d, tl %d)" % (realtemp, th, tl))
197
-
198
-
199
-    if False:
200
-        buf = client.bulk_read(gex.MSG_INI_READ)
201
-        print(buf.decode('utf-8'))
202
-
203
-        pb = gex.PayloadBuilder()
204
-        pb.u32(len(buf))
205
-
206
-        client.bulk_write(gex.MSG_INI_WRITE, pld=pb.close(), bulk=buf)
207
-
208
-    if False:
209
-        leds = gex.DOut(client, 'strip')
210
-
211
-        nn = 3
212
-        for i in range(0,20):
213
-            leds.write(nn)
214
-            time.sleep(.05)
215
-            nn<<=1
216
-            nn|=(nn&0x40)>>6
217
-            nn=nn&0x3F
218
-        leds.clear(0xFF)
219
-
220
-    if False:
221
-        leds = gex.DOut(client, 'bargraph')
222
-
223
-        for i in range(0,0x41):
224
-            leds.write(i&0x3F)
225
-            time.sleep(.1)
226
-
227
-    if False:
228
-        leds = gex.DOut(client, 'TST')
229
-
230
-        for i in range(0, 0x41):
231
-            #leds.write(i & 0x3F)
232
-            leds.toggle(0xFF)
233
-            time.sleep(.1)
234
-
235
-    if False:
236
-        btn = gex.DIn(client, 'btn')
237
-        strip = gex.DOut(client, 'strip')
238
-
239
-        for i in range(0, 10000):
240
-            b = btn.read()
241
-            strip.write((b << 2) | ((~b) & 1))
242
-            time.sleep(.02)
243
-
244
-    if False:
245
-        neo = gex.Neopixel(client, 'npx')
246
-
247
-        print('We have %d neopixels.\n' % neo.get_len())
248
-
249
-        #neo.load([0xF0F0F0,0,0,0xFF0000])
250
-
251
-        # generate a little animation...
252
-        for i in range(0,512):
253
-            j = i if i < 256 else 255-(i-256)
254
-            neo.load([0x660000+j, 0x3300FF-j, 0xFFFF00-(j<<8), 0x0000FF+(j<<8)-j])
255
-            time.sleep(.001)
256
-
257
-        neo.load([0,0,0,0])
258
-
259
-    if False:
260
-        i2c = gex.I2C(client, 'i2c')
261
-
262
-        # i2c.write(0x76, payload=[0xD0])
263
-        # print(i2c.read(0x76, count=1))
264
-
265
-        print(i2c.read_reg(0x76, 0xD0))
266
-        print("%x" % i2c.read_reg(0x76, 0xF9, width=3, endian='big'))
267
-
268
-        i2c.write_reg(0x76, 0xF4, 0xFA)
269
-        print(i2c.read_reg(0x76, 0xF4))
270
-
271
-    if False:
272
-        spi = gex.SPI(client, 'spi')
273
-        spi.multicast(1, [0xDE, 0xAD, 0xBE, 0xEF])
274
-        print(spi.query(0, [0xDE, 0xAD, 0xBE, 0xEF], rlen=4, rskip=1))#
275
-
276
-    if False:
277
-        usart = gex.USART(client, 'serial')
278
-        usart.listen(lambda x: print("RX >%s<" % x))
279
-        for i in range(0,100):
280
-            #             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.
281
-
282
-            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)
283
-
284
-            # time.sleep(.001)
285
-
286
-    if False:
287
-        usart = gex.USART(client, 'serial')
288
-        usart.listen(lambda x: print(x, end='',flush=True))
289
-        while True:
290
-            client.poll()
291
-
292
-    if False:
293
-        print(client.ini_read())
294
-
295
-        trig = gex.DIn(client, 'trig')
296
-        print(trig.read())
297
-
298
-        # Two pins are defined, PA10 and PA7. PA10 is the trigger, in the order from smallest to highest number 1
299
-        trig.arm(0b10)
300
-        trig.on_trigger(0b10, lambda snap,ts: print("snap 0x%X, ts %d" % (snap,ts)))
301
-
302
-        while True:
303
-            client.poll()
304
-
305
-    #
306
-    # for n in range(0,100):
307
-    #     print(n)
308
-    #     s = client.ini_read()
309
-    #     client.ini_write(s)

+ 0 - 24
examples/mat_sampling.m View File

@@ -1,24 +0,0 @@
1
-% this is an example of sampling the ADC from Matlab and then plotting a
2
-% FFT graph. The ADC unit called 'adc' is configured to use PA1 as Ch. 0
3
-
4
-%transport = py.gex.TrxSerialThread(pyargs('port', '/dev/ttyUSB1', 'baud', 57600));
5
-transport = py.gex.TrxRawUSB();
6
-client = py.gex.Client(transport);
7
-adc = py.gex.ADC(client, 'adc');
8
-
9
-L=1000;
10
-Fs=1000;
11
-
12
-adc.set_sample_rate(uint32(Fs));
13
-data = adc.capture(uint32(L));
14
-data = double(py.array.array('f',data));
15
-
16
-Y = fft(data);
17
-P2 = abs(Y/L);
18
-P1 = P2(1:L/2+1);
19
-P1(2:end-1) = 2*P1(2:end-1);
20
-
21
-f = Fs*(0:(L/2))/L;
22
-plot(f,P1)
23
-
24
-client.close()

+ 0 - 86
examples/nrf_config.ini View File

@@ -1,86 +0,0 @@
1
-## UNITS.INI
2
-## GEX v0.1.0 on STM32F072-HUB
3
-## built Mar 28 2018 at 00:42:03
4
-
5
-[UNITS]
6
-# Create units by adding their names next to a type (e.g. DO=A,B),
7
-# remove the same way. Reload to update the unit sections below.
8
-
9
-# Digital output
10
-DO=ce
11
-# Digital input with triggers
12
-DI=irq
13
-# Neopixel RGB LED strip
14
-NPX=
15
-# I2C master
16
-I2C=
17
-# SPI master
18
-SPI=spi
19
-# Serial port
20
-USART=
21
-# 1-Wire master
22
-1WIRE=
23
-# Analog/digital converter
24
-ADC=
25
-# Shift register driver (595, 4094)
26
-SIPO=
27
-# Frequency and pulse measurement
28
-FCAP=
29
-# Capacitive touch sensing
30
-TOUCH=
31
-# Simple PWM output
32
-PWMDIM=
33
-# Two-channel analog output with waveforms
34
-DAC=
35
-
36
-[DO:ce@2]
37
-# Port name
38
-port=B
39
-# Pins (comma separated, supports ranges)
40
-pins=6, 2
41
-# Initially high pins
42
-initial=
43
-# Open-drain pins
44
-open-drain=
45
-
46
-[DI:irq@3]
47
-# Port name
48
-port=B
49
-# Pins (comma separated, supports ranges)
50
-pins=8-7
51
-# Pins with pull-up
52
-pull-up=
53
-# Pins with pull-down
54
-pull-down=
55
-
56
-# Trigger pins activated by rising/falling edge
57
-trig-rise=
58
-trig-fall=
59
-# Trigger pins auto-armed by default
60
-auto-trigger=
61
-# Triggers hold-off time (ms)
62
-hold-off=100
63
-
64
-[SPI:spi@1]
65
-# Peripheral number (SPIx)
66
-device=1
67
-# Pin mappings (SCK,MISO,MOSI)
68
-#  SPI1: (0) A5,A6,A7     (1) B3,B4,B5
69
-#  SPI2: (0) B13,B14,B15
70
-remap=1
71
-
72
-# Prescaller: 2,4,8,...,256
73
-prescaller=64
74
-# Clock polarity: 0,1 (clock idle level)
75
-cpol=0
76
-# Clock phase: 0,1 (active edge, 0-first, 1-second)
77
-cpha=1
78
-# Transmit only, disable MISO
79
-tx-only=N
80
-# Bit order (LSB or MSB first)
81
-first-bit=MSB
82
-
83
-# SS port name
84
-port=B
85
-# SS pins (comma separated, supports ranges)
86
-pins=1-0

+ 0 - 15
examples/show_nparray.py View File

@@ -1,15 +0,0 @@
1
-#!/bin/env python3
2
-import time
3
-
4
-import sys
5
-
6
-import gex
7
-import numpy as np
8
-from matplotlib import pyplot as plt
9
-import datetime
10
-
11
-from scipy.io import wavfile
12
-
13
-data = np.load(sys.argv[1])
14
-plt.plot(data, 'r-', lw=1)
15
-plt.show()

File diff suppressed because it is too large
+ 0 - 1109
examples/sx_fsk.py


+ 0 - 38
examples/test_adc.py View File

@@ -1,38 +0,0 @@
1
-#!/bin/env python3
2
-import time
3
-
4
-import gex
5
-import numpy as np
6
-from matplotlib import pyplot as plt
7
-
8
-from scipy.io import wavfile
9
-
10
-with gex.Client(gex.TrxRawUSB()) as client:
11
-    adc = gex.ADC(client, 'adc')
12
-
13
-    print(adc.get_calibration_data())
14
-    print(adc.get_channels())
15
-
16
-    adc.set_active_channels([1])
17
-    rate=50000
18
-    fs = adc.set_sample_rate(rate)
19
-
20
-    time.sleep(0.1)
21
-    count = 5000
22
-    data = adc.capture(count)
23
-
24
-    print("rx, %d samples" % len(data))
25
-    data = np.add(data / 4096, -0.5)
26
-
27
-    adc.set_sample_rate(1000)
28
-
29
-    #
30
-    if data is not None:
31
-        # wavfile.write('file.wav', rate, data)
32
-        # print("Ok")
33
-
34
-        plt.plot(data, 'r-', lw=1)
35
-        plt.show()
36
-    else:
37
-        print("Nothing rx")
38
-

+ 0 - 17
examples/test_adc2.py View File

@@ -1,17 +0,0 @@
1
-#!/bin/env python3
2
-import time
3
-
4
-import gex
5
-import numpy as np
6
-from matplotlib import pyplot as plt
7
-
8
-from scipy.io import wavfile
9
-
10
-with gex.Client(gex.TrxRawUSB()) as client:
11
-    adc = gex.ADC(client, 'adc')
12
-
13
-    print(adc.capture(100))
14
-
15
-    # for i in range(1000):
16
-    #     print(adc.read_raw())
17
-

+ 0 - 49
examples/test_dac.py View File

@@ -1,49 +0,0 @@
1
-#!/bin/env python3
2
-import time
3
-import math
4
-
5
-import gex
6
-
7
-from scipy.io import wavfile
8
-
9
-with gex.Client(gex.TrxRawUSB()) as client:
10
-    dac = gex.DAC(client, 'dac')
11
-
12
-    # dac.set_dither(1, 'TRI', 8)
13
-    # # dac.set_dither(3, 'NONE', 8)
14
-    # # #
15
-    # # # dac.set_frequency(2, 1)
16
-    # # # dac.set_frequency(1, 10.01)
17
-    # dac.set_waveform(1, 'SIN')
18
-    # # dac.set_waveform(2, 'RAMP')
19
-    #
20
-    # dac.rectangle(2, 0.5, 4095, 0)
21
-    #
22
-    # dac.set_frequency(1, 100)
23
-    # dac.set_frequency(2, 50)
24
-    # #
25
-    # dac.sync()
26
-
27
-    # for i in range(0, 1000):
28
-    #     dac.set_frequency(1, i)
29
-    #     time.sleep(0.001)
30
-
31
-    dac.waveform(1, 'SIN')
32
-    dac.set_frequency(1, 1000)
33
-    time.sleep(2)
34
-    dac.dc(1, 2047)
35
-
36
-    # dac.waveform(1, 'SIN')
37
-    # # dac.set_frequency(1, 1000)
38
-    # # dac.dc(1,1000)
39
-    # dac.dc(2,1000)
40
-
41
-    #
42
-    # for i in range(0,360*5, 3):
43
-    #     dac.dc_dual(round(2047+math.cos(((i*3.01)/180)*math.pi)*1900),
44
-    #                    round(2047+math.sin(((i*2.01)/180)*math.pi)*1900),
45
-    #                    confirm=False)
46
-    #     time.sleep(0.01)
47
-    #
48
-    # dac.dc_dual(2047,2047)
49
-

+ 0 - 32
examples/test_dongle.py View File

@@ -1,32 +0,0 @@
1
-#!/bin/env python3
2
-import time
3
-
4
-import gex
5
-
6
-# test with the radio gw
7
-
8
-with gex.DongleAdapter(gex.TrxRawUSB(remote=True), 0x10) as transport:
9
-# with gex.TrxRawUSB() as transport:
10
-
11
-    # connect GEX client library to the remote slave
12
-    client = gex.Client(transport)
13
-
14
-    while True:
15
-        client.query_raw(type=gex.MSG_PING)
16
-        print("ok")
17
-        time.sleep(0.1)
18
-
19
-    # do = gex.DOut(client, "led")
20
-    # adc = gex.ADC(client, "adc")
21
-    #
22
-    # while True:
23
-    #     do.toggle(confirm=True)
24
-    #     print(adc.read_smooth())
25
-    #     time.sleep(0.2)
26
-
27
-    # adc = gex.ADC(client, "adc")
28
-    # for j in range(10):
29
-    #     try:
30
-    #         print(adc.read_smooth())
31
-    #     except:
32
-    #         print("Failed")

+ 0 - 43
examples/test_freq_cap.py View File

@@ -1,43 +0,0 @@
1
-import time
2
-
3
-import gex
4
-
5
-with gex.Client(gex.TrxRawUSB()) as client:
6
-    fcap = gex.FCAP(client, 'fcap')
7
-
8
-    fcap.stop()
9
-
10
-    fcap.indirect_start()
11
-    #
12
-    time.sleep(2)
13
-    print(fcap.indirect_read())
14
-
15
-    # fcap.stop()
16
-    # #print(fcap.indirect_burst(3, timeout=20))
17
-
18
-    # r=fcap.indirect_burst(1000, timeout=5)
19
-    # print(r)
20
-    # print(r.period_raw)
21
-
22
-    # fcap.configure(filter=0)
23
-
24
-    # print(fcap.measure_pulse())
25
-
26
-    # print(fcap.direct_burst(10))
27
-    #
28
-    # fcap.direct_start(1000, 0)
29
-    # time.sleep(2)
30
-    #
31
-    # print(fcap.direct_read())
32
-    #
33
-    # fcap.counter_start()
34
-    # time.sleep(1)
35
-    # print(fcap.counter_clear())
36
-    # time.sleep(1)
37
-    # print(fcap.counter_read())
38
-    # time.sleep(1)
39
-    # print(fcap.counter_clear())
40
-    # time.sleep(1)
41
-    # print(fcap.counter_clear())
42
-
43
-

+ 0 - 9
examples/test_ini.py View File

@@ -1,9 +0,0 @@
1
-#!/bin/env python3
2
-import time
3
-
4
-import gex
5
-
6
-# with gex.Client(gex.TrxRawUSB()) as client:
7
-with gex.DongleAdapter(gex.TrxRawUSB(remote=True), 0x10) as transport:
8
-    client = gex.Client(transport)
9
-    print(client.ini_read(0))

+ 0 - 81
examples/test_onewire.py View File

@@ -1,81 +0,0 @@
1
-#!/bin/env python3
2
-import time
3
-
4
-import gex
5
-
6
-with gex.Client(gex.TrxRawUSB()) as client:
7
-    ow = gex.OneWire(client, 'ow')
8
-    # print("Presence: ", ow.test_presence())
9
-    print("Devices:", ow.search())
10
-
11
-    def meas(addr):
12
-        ow.write([0x44], addr=addr)
13
-        ow.wait_ready()
14
-        data = ow.query([0xBE], 9, addr=addr)
15
-        pp = gex.PayloadParser(data)
16
-        return pp.i16() * 0.0625
17
-
18
-    def meas2(addr, addr2):
19
-        ow.write([0x44], addr=addr)
20
-        ow.write([0x44], addr=addr2)
21
-        ow.wait_ready()
22
-
23
-        data = ow.query([0xBE], 9, addr=addr)
24
-        pp = gex.PayloadParser(data)
25
-        a = pp.i16() * 0.0625
26
-
27
-        data = ow.query([0xBE], 9, addr=addr2)
28
-        pp = gex.PayloadParser(data)
29
-        b = pp.i16() * 0.0625
30
-        return a, b
31
-
32
-    while True:
33
-        (a, b) = meas2(6558392391241695016, 1802309978572980008)
34
-        # a = meas(6558392391241695016)
35
-        # b = meas(1802309978572980008)
36
-        print("in: %.2f °C, out: %f °C" % (a, b))
37
-
38
-
39
-
40
-    # # search the bus for alarm
41
-    # if False:
42
-    #     ow = gex.OneWire(client, 'ow')
43
-    #     print("Presence: ", ow.test_presence())
44
-    #     print("Devices w alarm:", ow.search(alarm=True))
45
-    #
46
-    # # simple 1w check
47
-    # if False:
48
-    #     ow = gex.OneWire(client, 'ow')
49
-    #     print("Presence: ", ow.test_presence())
50
-    #     print("ROM: 0x%016x" % ow.read_address())
51
-    #     print("Scratch:", ow.query([0xBE], rcount=9, addr=0x7100080104c77610, as_array=True))
52
-    #
53
-    # # testing ds1820 temp meas without polling
54
-    # if False:
55
-    #     ow = gex.OneWire(client, 'ow')
56
-    #     print("Presence: ", ow.test_presence())
57
-    #     print("Starting measure...")
58
-    #     ow.write([0x44])
59
-    #     time.sleep(1)
60
-    #     print("Scratch:", ow.query([0xBE], 9))
61
-    #
62
-    # # testing ds1820 temp meas with polling
63
-    # if False:
64
-    #     ow = gex.OneWire(client, 'ow')
65
-    #     print("Presence: ", ow.test_presence())
66
-    #     print("Starting measure...")
67
-    #     ow.write([0x44])
68
-    #     ow.wait_ready()
69
-    #     data = ow.query([0xBE], 9)
70
-    #
71
-    #     pp = gex.PayloadParser(data)
72
-    #
73
-    #     temp = pp.i16()/2.0
74
-    #     th = pp.i8()
75
-    #     tl = pp.i8()
76
-    #     reserved = pp.i16()
77
-    #     remain = float(pp.u8())
78
-    #     perc = float(pp.u8())
79
-    #
80
-    #     realtemp = temp - 0.25+(perc-remain)/perc
81
-    #     print("Temperature = %f °C (th %d, tl %d)" % (realtemp, th, tl))

+ 0 - 7
examples/test_ping.py View File

@@ -1,7 +0,0 @@
1
-#!/bin/env python3
2
-import time
3
-
4
-import gex
5
-
6
-with gex.Client(gex.TrxSerialThread(port='/dev/ttyACM0')) as client:
7
-    pass

+ 0 - 47
examples/test_pwmdim_music.py View File

@@ -1,47 +0,0 @@
1
-import time
2
-
3
-import gex
4
-
5
-# beeping music with PWM (square wave)
6
-
7
-C3  = 130.81; Cx3 = 138.59; D3  = 146.83; Dx3 = 155.56; E3  = 164.81; F3  = 174.61
8
-Fx3 = 185.00; G3  = 196.00; Gx3 = 207.65; A3  = 220.00; Ax3 = 233.08; B3  = 246.94
9
-C4  = 261.63; Cx4 = 277.18; D4  = 293.66; Dx4 = 311.13; E4  = 329.63; F4  = 349.23
10
-Fx4 = 369.99; G4  = 392.00; Gx4 = 415.30; A4  = 440.00; Ax4 = 466.16; B4  = 493.88
11
-C5  = 523.25; Cx5 = 554.37; D5  = 587.33; Dx5 = 622.25; E5  = 659.25; F5  = 698.46
12
-Fx5 = 739.99; G5  = 783.99; Gx5 = 830.61; A5  = 880.00; Ax5 = 932.33; B5  = 987.77
13
-
14
-with gex.Client(gex.TrxRawUSB()) as client:
15
-    pwm = gex.PWMDim(client, 'dim')
16
-
17
-    # O   O/ #/ #~ #=
18
-    # 16, 8, 4, 2, 1
19
-    notes = [
20
-        (G3, 2),
21
-        (G4, 2), (E4, 6), (G4, 2), (E4, 2), (A4, 6), (0, 2), (B4, 2),
22
-        (G4, 2), (E4, 6), (A4, 2), (G4, 2), (D4, 6), (0, 2), (G3, 2),
23
-
24
-        (G4, 2), (E4, 6), (D4, 2), (C4, 2), (C5, 6), (0, 2), (A4, 2),
25
-        (G4, 2), (E4, 4), (0, 2), (D4, 2), (A3, 2), (C4, 6), (0, 2), (G3, 2),
26
-
27
-        #rep
28
-        (G4, 2), (E4, 6), (G4, 2), (E4, 2), (A4, 6), (0, 2), (B4, 2),
29
-        (G4, 2), (E4, 6), (A4, 2), (G4, 2), (D4, 6), (0, 2), (G3, 2),
30
-
31
-        (G4, 2), (E4, 6), (D4, 2), (C4, 2), (C5, 6), (0, 2), (A4, 2),
32
-
33
-        (G4, 2), (E4, 6), (D4, 2), (A3, 2), (C4, 6), (0, 2), #(C4, 2),
34
-    ]
35
-
36
-    for p in notes:
37
-        pwm.stop()
38
-        time.sleep(0.01)
39
-        f = round(p[0])
40
-        print(f)
41
-        if f > 0:
42
-            pwm.set_frequency(f)
43
-            pwm.start()
44
-        time.sleep(0.1*p[1])
45
-
46
-    pwm.stop()
47
-

+ 0 - 17
examples/test_pwmdim_sweep.py View File

@@ -1,17 +0,0 @@
1
-import time
2
-
3
-import gex
4
-
5
-# pwm frequency sweep
6
-
7
-with gex.Client(gex.TrxRawUSB()) as client:
8
-    pwm = gex.PWMDim(client, 'dim')
9
-
10
-    pwm.start()
11
-    pwm.set_duty_single(1, 500)
12
-    for i in range(2000, 200, -15):
13
-        pwm.set_frequency(i)
14
-        time.sleep(0.05)
15
-
16
-    pwm.stop()
17
-

+ 0 - 21
examples/test_sipo_omicron.py View File

@@ -1,21 +0,0 @@
1
-import time
2
-
3
-import gex
4
-
5
-# sipo example
6
-
7
-with gex.Client(gex.TrxRawUSB()) as client:
8
-    sipo = gex.SIPO(client, 'sipo')
9
-    d4 = gex.DOut(client, 'd4')
10
-
11
-    # Jort the lights
12
-    sipo.load([
13
-        [0x0a, 0x0f],
14
-        [0xF8, 0xFC],
15
-        [0x00, 0x00],
16
-        [0x02, 0x00],
17
-    ], end=0x04)
18
-
19
-    d4.write(1)
20
-    # sipo.set_data(0x04)
21
-    # sipo.store()

+ 0 - 20
examples/test_touch.py View File

@@ -1,20 +0,0 @@
1
-import time
2
-
3
-import gex
4
-
5
-# toush sensing test
6
-
7
-with gex.Client(gex.TrxRawUSB()) as client:
8
-    tsc = gex.TOUCH(client, 'tsc')
9
-
10
-    print("There are %d touch channels." % tsc.get_channel_count())
11
-
12
-    tsc.set_button_thresholds([1225, 1440, 1440])
13
-
14
-    tsc.listen(0, lambda state, ts: print("Pad 1: %d" % state))
15
-    tsc.listen(1, lambda state, ts: print("Pad 2: %d" % state))
16
-    tsc.listen(2, lambda state, ts: print("Pad 3: %d" % state))
17
-
18
-    while True:
19
-        print(tsc.read())
20
-        time.sleep(0.5)

+ 0 - 128
gexync.py View File

@@ -1,128 +0,0 @@
1
-#!/bin/env python3
2
-
3
-import gex
4
-
5
-import sys
6
-from PyQt4 import QtGui, QtCore
7
-import ini_syntax
8
-
9
-class GexIniEditor(QtGui.QMainWindow):
10
-    """
11
-    Gexync is a GEX ini file editor.
12
-    The editor loads the INI file through the communication interface
13
-    without having to mount the virtual filesystem, which is unreliable
14
-    on some systems.
15
-
16
-    This utility allows live editing of the UNITS.INI file.
17
-
18
-    On save, a new version is loaded with formatting and error messages
19
-    generated by GEX, as if the virtual config filesystem was re-mounted.
20
-
21
-    The editor does not keep GEX claimed, instead does so only when needed.
22
-    This allows testing of the current configuration without having to close
23
-    and reopen the editor.
24
-    """
25
-
26
-    def __init__(self, xferLambda):
27
-        self.xferLambda = xferLambda
28
-
29
-        self.filenum = int(sys.argv[1]) if len(sys.argv)>1 else 0
30
-
31
-        super().__init__()
32
-        self.initUI()
33
-        # TODO let user pick GEX device if multiple
34
-
35
-    def initToolbar(self):
36
-        icon = self.style().standardIcon(QtGui.QStyle.SP_BrowserReload)
37
-        loadAction = QtGui.QAction(icon, 'Reload', self)
38
-        loadAction.setShortcut('Ctrl+O')
39
-        loadAction.triggered.connect(self.gexLoad)
40
-
41
-        icon = self.style().standardIcon(QtGui.QStyle.SP_DialogSaveButton)
42
-        syncAction = QtGui.QAction(icon, 'Write Changes', self)
43
-        syncAction.setShortcut('Ctrl+S')
44
-        syncAction.triggered.connect(self.gexSync)
45
-
46
-        icon = self.style().standardIcon(QtGui.QStyle.SP_DialogOkButton)
47
-        persAction = QtGui.QAction(icon, 'Persist', self)
48
-        persAction.setShortcut('Ctrl+P')
49
-        persAction.triggered.connect(self.gexPersist)
50
-
51
-        self.toolbar = self.addToolBar('Toolbar')
52
-        self.toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
53
-        self.toolbar.addAction(loadAction)
54
-        self.toolbar.addAction(syncAction)
55
-        self.toolbar.addSeparator()
56
-        self.toolbar.addAction(persAction)
57
-
58
-    def initEditor(self):
59
-        self.editor = QtGui.QPlainTextEdit()
60
-
61
-        # Editor background and text color
62
-        pal = QtGui.QPalette()
63
-        bgc = QtGui.QColor(0xFFFFF6)
64
-        pal.setColor(QtGui.QPalette.Base, bgc)
65
-        textc = QtGui.QColor(0x000000)
66
-        pal.setColor(QtGui.QPalette.Text, textc)
67
-        self.editor.setPalette(pal)
68
-        # Font
69
-        font = QtGui.QFont('Liberation Mono', 12)
70
-        font.setStyleHint(QtGui.QFont.TypeWriter)
71
-        self.editor.setFont(font)
72
-        # Initial size
73
-        self.highlight = ini_syntax.IniHighlighter(self.editor.document())
74
-
75
-    def initUI(self):
76
-        self.setWindowTitle('GEX config file editor')
77
-        self.initToolbar()
78
-        self.initEditor()
79
-        self.setCentralWidget(self.editor)
80
-        self.show()
81
-
82
-        self.gexLoad()
83
-
84
-    def gexLoad(self):
85
-        self.editor.setPlainText("")
86
-        self.editor.repaint()
87
-
88
-        client = gex.Client(self.xferLambda(), load_units=False)
89
-        read_ini = client.ini_read(self.filenum)
90
-        client.close()
91
-
92
-        self.editor.setPlainText(read_ini)
93
-        self.highlight.rehighlight()
94
-        self.setWindowTitle('GEX config file editor')
95
-
96
-    def gexSync(self):
97
-        new_txt = self.editor.toPlainText()
98
-        self.editor.setPlainText("")
99
-        self.editor.repaint()
100
-
101
-        client = gex.Client(self.xferLambda(), load_units=False)
102
-        client.ini_write(new_txt)
103
-        read_ini = client.ini_read(self.filenum)
104
-        client.close()
105
-
106
-        self.editor.setPlainText(read_ini)
107
-        self.highlight.rehighlight()
108
-        self.setWindowTitle('*GEX config file editor')
109
-
110
-    def gexPersist(self):
111
-        client = gex.Client(self.xferLambda(), load_units=False)
112
-        client.ini_persist()
113
-        client.close()
114
-        self.setWindowTitle('GEX config file editor')
115
-
116
-if __name__ == '__main__':
117
-    app = QtGui.QApplication(sys.argv)
118
-    editor = GexIniEditor(lambda: gex.TrxRawUSB())
119
-    # editor = GexIniEditor(lambda: gex.TrxSerialThread(port='/dev/ttyUSB1',
120
-    #                                                   baud=57600))
121
-
122
-    # centered resize
123
-    w = 800
124
-    h = 900
125
-    ss = app.desktop().availableGeometry().size()
126
-    editor.setGeometry(int(ss.width() / 2 - w / 2), int(ss.height() / 2 - h / 2), w, h)
127
-
128
-    sys.exit(app.exec_())

+ 0 - 81
ini_syntax.py View File

@@ -1,81 +0,0 @@
1
-# syntax.py
2
-
3
-# This is a companion file to gexync.py
4
-
5
-# based on https://wiki.python.org/moin/PyQt/Python%20syntax%20highlighting
6
-
7
-from PyQt4.QtCore import QRegExp
8
-from PyQt4.QtGui import QColor, QTextCharFormat, QFont, QSyntaxHighlighter
9
-
10
-def format(color, style=''):
11
-    """Return a QTextCharFormat with the given attributes.
12
-    """
13
-    _color = QColor()
14
-    _color.setNamedColor(color)
15
-
16
-    _format = QTextCharFormat()
17
-    _format.setForeground(_color)
18
-    if 'bold' in style:
19
-        _format.setFontWeight(QFont.Bold)
20
-    if 'italic' in style:
21
-        _format.setFontItalic(True)
22
-
23
-    return _format
24
-
25
-
26
-# Syntax styles that can be shared by all languages
27
-STYLES = {
28
-    'operator': format('red'),
29
-    'string': format('magenta'),
30
-    'comment': format('#6C8A70', 'italic'),
31
-    'key': format('#008AFF'),
32
-    'numbers': format('brown'),
33
-    'section': format('black', 'bold'),
34
-}
35
-
36
-class IniHighlighter (QSyntaxHighlighter):
37
-    # Python braces
38
-    def __init__(self, document):
39
-        QSyntaxHighlighter.__init__(self, document)
40
-
41
-        rules = [
42
-            (r'=', 0, STYLES['operator']),
43
-            (r'\b[YN]\b', 0, STYLES['numbers']),
44
-
45
-            # Double-quoted string, possibly containing escape sequences
46
-            (r'"[^"\\]*(\\.[^"\\]*)*"', 0, STYLES['string']),
47
-            # Single-quoted string, possibly containing escape sequences
48
-            (r"'[^'\\]*(\\.[^'\\]*)*'", 0, STYLES['string']),
49
-
50
-            # Numeric literals
51
-            (r'\b[+-]?[0-9]+\b', 0, STYLES['numbers']),
52
-            (r'\b[+-]?0[xX][0-9A-Fa-f]+\b', 0, STYLES['numbers']),
53
-            (r'\b[+-]?[0-9]+(?:\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\b', 0, STYLES['numbers']),
54
-
55
-            # From '#' until a newline
56
-            (r'#[^\n]*', 0, STYLES['comment']),
57
-
58
-            (r'^\[.+\]', 0, STYLES['section']),
59
-
60
-            (r'^[a-zA-Z0-9_-]+\s?=', 0, STYLES['key']),
61
-        ]
62
-
63
-        # Build a QRegExp for each pattern
64
-        self.rules = [(QRegExp(pat), index, fmt)
65
-            for (pat, index, fmt) in rules]
66
-
67
-    def highlightBlock(self, text):
68
-        """Apply syntax highlighting to the given block of text.
69
-        """
70
-        # Do other syntax formatting
71
-        for expression, nth, format in self.rules:
72
-            index = expression.indexIn(text, 0)
73
-
74
-            while index >= 0:
75
-                # We actually want the index of the nth match
76
-                index = expression.pos(nth)
77
-                length = len(expression.cap(nth))
78
-                self.setFormat(index, length, format)
79
-                index = expression.indexIn(text, index + length)
80
-
81
-        self.setCurrentBlockState(0)

gex/transport.py → transport.py View File


gex/units/ADC.py → units/ADC.py View File


gex/units/DAC.py → units/DAC.py View File


gex/units/DIn.py → units/DIn.py View File


gex/units/DOut.py → units/DOut.py View File


gex/units/FCAP.py → units/FCAP.py View File


gex/units/I2C.py → units/I2C.py View File


gex/units/Neopixel.py → units/Neopixel.py View File


gex/units/OneWire.py → units/OneWire.py View File


gex/units/PWMDim.py → units/PWMDim.py View File


gex/units/SIPO.py → units/SIPO.py View File


gex/units/SPI.py → units/SPI.py View File


gex/units/TOUCH.py → units/TOUCH.py View File


gex/units/USART.py → units/USART.py View File