-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenwaves.py
More file actions
97 lines (73 loc) · 3.49 KB
/
genwaves.py
File metadata and controls
97 lines (73 loc) · 3.49 KB
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import argparse
import math
from datetime import date
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--device', type=str, default='something', help='The name of the waveform device')
parser.add_argument('-p', '--period', type=int, default=1, help='Period of waveform in milliseconds (ms)')
subparsers = parser.add_subparsers(dest='mode', required=True)
sporadic_parser = subparsers.add_parser('sporadic')
sporadic_parser.add_argument('-l', '--list', type=int, default=[], nargs='+', help='A list of sporadic interrupts')
periodic_parser = subparsers.add_parser('periodic')
periodic_parser.add_argument('-i', '--interrupt-period', type=int, required=True, help='The period to generate interrupts in microseconds (us)')
args = parser.parse_args()
NOW = date.today()
NSAMPLES = 32768 # The maximum number of samples Waveforms allows
LOGIC_HIGH_VOLTAGE = 5 # 5V is logic high
INTERRUPT_STABLE_TIME_US = 10 # How long an interrupt must remain long for
TIME_PER_SAMPLE = (args.period / 1e3) / NSAMPLES
INTERRUPT_STABLE_NSAMPLES = math.ceil((INTERRUPT_STABLE_TIME_US / 1e6) / TIME_PER_SAMPLE)
PREAMBLE = f"""
#Digilent WaveForms Wavegen Custom data
#Device Name: {args.device}
#Serial Number: DEMO
#Date Time: {NOW.isoformat()} 00:00:00.000
"""
def gen_interrupt_waveform(interrupt_points: list[int]) -> str:
"""
Generate a waveform file (.csv) which is zero at all points except for the
input points provided in a list.
"""
int_points_idx = 0
int_high_nsamples = 0
out = PREAMBLE
for i in range(NSAMPLES):
if int_points_idx < len(interrupt_points) and interrupt_points[int_points_idx] == i:
# If assertion is not correct, another interrupt is provided while
# an interrupt already is high
assert(int_high_nsamples == 0)
int_high_nsamples = max(1, INTERRUPT_STABLE_NSAMPLES)
int_points_idx += 1
elif int_high_nsamples > 0:
int_high_nsamples -= 1
if int_high_nsamples > 0:
out += str(LOGIC_HIGH_VOLTAGE) + '\n'
else:
out += '0\n'
return out
print(f"""Configuration is:
Period: {args.period} (ms)
Samples: {NSAMPLES} (max)
Sample rate: {NSAMPLES / args.period} kHz
Device: {args.device}
Mode: {args.mode}
{f'* List: {args.list}' if args.mode == 'sporadic' else
f'* Period: {args.interrupt_period} us'}
Logic high: {LOGIC_HIGH_VOLTAGE} V
Interrupt stable samples: {INTERRUPT_STABLE_NSAMPLES}
""")
if args.mode == 'sporadic':
# List of interrupts is already passed from command line; use it directly
with open('wave/interrupts-sporadic.csv', 'w') as f:
f.write(gen_interrupt_waveform(args.list))
elif args.mode == 'periodic':
# Generate list of interrupts from interrupt period parameter
NSAMPLES_BETWEEN_INTERRUPTS = ((args.interrupt_period / 1e6) / ((args.period / 1e3) / NSAMPLES))
if (args.period * 1000) % args.interrupt_period != 0:
print(f'''WARNING:
The interrupt period ({args.interrupt_period} us) and waveform period ({args.period * 1000} us) are not divisible.
This means there will be some discrepencies if the waveform is run multiple times consequtively.
''')
ninterrupts = math.floor((args.period * 1000) / args.interrupt_period)
intlist = [math.floor(NSAMPLES_BETWEEN_INTERRUPTS * i) for i in range(ninterrupts)]
with open('wave/interrupts-periodic.csv', 'w') as f:
f.write(gen_interrupt_waveform(intlist))