Skip to content

Commit 35a55f8

Browse files
committed
Multi-shuttle first boot and factory test support
1 parent 06a963f commit 35a55f8

File tree

8 files changed

+170
-43
lines changed

8 files changed

+170
-43
lines changed

src/config.ini

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
[DEFAULT]
1515
# project: project to load by default
16-
project = tt_um_test
16+
project = tt_um_factory_test
1717

1818
# start in reset (bool)
1919
start_in_reset = no
@@ -41,7 +41,10 @@ clock_frequency = 10
4141
start_in_reset = no
4242
input_byte = 1
4343

44-
44+
[tt_um_factory_test]
45+
clock_frequency = 10
46+
start_in_reset = no
47+
input_byte = 1
4548

4649

4750
[tt_um_psychogenic_neptuneproportional]

src/first_boot.ini

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
# - ERROR
99
log_level = INFO
1010

11-
1211
# if 'no', go through all tests
1312
abort_runs_on_error = no
1413

@@ -28,18 +27,29 @@ command = setup_somehow()
2827

2928
[run_01_bidir_test]
3029
message = Basic comms, mux, bidir and output pin test
31-
command = test_bidirs(0xff)
30+
command = test_bidirs_03p5(0xff)
31+
shuttle = tt03p5
32+
3233

3334
[run_02_test_clocking]
3435
message = Test clocking a project manual style
35-
command = test_clocking(0x42)
36+
command = test_clocking_03p5(0x42)
37+
shuttle = tt03p5
38+
39+
[run_01_factory_test]
40+
message = TT04 factory test
41+
command = test_clocking_04(0x42)
42+
shuttle = tt04
43+
44+
3645

3746
## SUCCESS ##
3847
[onsuccess]
3948
# runs if all previous operations succeeded
4049
message = All good: running on success command
4150
command = firstboot_completed()
4251

52+
4353
## FAILURE ###
4454
[onfail]
4555
message = Issue with first boot

src/ttboard/boot/first.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,14 @@ def run(self):
179179
keep_running_tests = True
180180
for section in sorted(self.config.sections):
181181
if keep_running_tests and section.startswith('run_'):
182+
if self.config.has_option(section, 'shuttle'):
183+
shuttle = self.config.get(section, 'shuttle')
184+
if shuttle is not None and len(shuttle) and shuttle != demoboard.chip_ROM.shuttle:
185+
self.log_message(f'Section {section} is for shuttle {shuttle}, we are {demoboard.chip_ROM.shuttle}: skipping')
186+
continue
187+
188+
self.log_message(f'Found section {section} to run')
189+
182190
context['tests'][section] = True
183191
if not RunOperation(demoboard, section, self.config).execute(context):
184192
self.log_error(f'Execution of {section} failed')
@@ -187,6 +195,7 @@ def run(self):
187195
if abort_runs_on_err:
188196
self.log_error(f'And abort_runs_on_error is set, aborting.')
189197
keep_running_tests = False
198+
190199

191200
if num_fails:
192201
if self.config.has_section('onfail'):
@@ -195,6 +204,7 @@ def run(self):
195204

196205
if self.config.has_section('onsuccess'):
197206
should_delete_op = RunOperation(demoboard, 'onsuccess', self.config)
207+
self.log_message('Running onsuccess')
198208
if not should_delete_op.execute(context):
199209
self.log_error('Could not execute onsuccess???')
200210
self.run_complete(False)

src/ttboard/boot/firstboot_operations.py

Lines changed: 73 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,14 @@ def firstboot_completed():
5151
# can only happen if all tests ([run_*] sections)
5252
# run and return True
5353
print("Done first boot")
54-
say_hello(180, times=2)
54+
tt = get_demoboard()
55+
if tt.chip_ROM.shuttle == 'tt03p5':
56+
print("CHIPROM shuttle is 03p5, saying hello")
57+
say_hello_03p5(180, times=2)
58+
else:
59+
print(f"CHIPROM shuttle {tt.chip_ROM.shuttle}, saying hello")
60+
say_hello(180, times=2)
61+
5562
return True
5663

5764

@@ -68,11 +75,11 @@ def firstboot_failure():
6875
print()
6976

7077

71-
def test_bidirs(max_idx:int, delay_interval_ms:int=1):
78+
def test_bidirs_03p5(max_idx:int, delay_interval_ms:int=1):
7279
# a test, must return True to consider a pass
7380
tt = get_demoboard()
7481
print(f'Testing bidirs up to {max_idx} on {tt}')
75-
err = shut_tests.factory_test_bidirs(tt, max_idx, delay_interval_ms)
82+
err = shut_tests.factory_test_bidirs_03p5(tt, max_idx, delay_interval_ms)
7683

7784
if err is not None:
7885
log.error(err)
@@ -81,12 +88,21 @@ def test_bidirs(max_idx:int, delay_interval_ms:int=1):
8188
return True
8289

8390

91+
def test_clocking_04(max_idx:int=30, delay_interval_ms:int=50):
92+
tt = get_demoboard()
93+
print(f'Testing manual clocking up to {max_idx} on {tt}')
94+
err = shut_tests.factory_test_clocking_04(tt, max_idx, delay_interval_ms)
95+
if err is not None:
96+
log.error(err)
97+
return False
98+
99+
return True
84100

85-
def test_clocking(max_idx:int=30, delay_interval_ms:int=50):
101+
def test_clocking_03p5(max_idx:int=30, delay_interval_ms:int=50):
86102
# a test, must return True to consider a pass
87103
tt = get_demoboard()
88104
print(f'Testing manual clocking up to {max_idx} on {tt}')
89-
err = shut_tests.factory_test_clocking(tt, max_idx, delay_interval_ms)
105+
err = shut_tests.factory_test_clocking_03p5(tt, max_idx, delay_interval_ms)
90106
if err is not None:
91107
log.error(err)
92108
return False
@@ -96,27 +112,70 @@ def test_clocking(max_idx:int=30, delay_interval_ms:int=50):
96112

97113

98114

115+
def say_hello(delay_interval_ms:int=200, times:int=1):
116+
117+
hello_values = [0x74, 0x79, 0x30, 0x30, 0x5c, 0, 0]
118+
tt = get_demoboard()
119+
try:
120+
tt.shuttle.factory_test.enable()
121+
except:
122+
print('Failed to load factory test?')
123+
return
124+
125+
126+
tt.mode = RPMode.ASIC_RP_CONTROL # make sure we're controlling everything
127+
128+
tt.in0(0) # want this low
129+
tt.clock_project_PWM(1e3) # clock it real good
130+
131+
log.info('First boot: saying hello')
132+
# for bp in tt.bidirs:
133+
# bp.mode = Pins.OUT
134+
# bp(0) # start low
135+
for _i in range(times):
136+
for v in hello_values:
137+
tt.input_byte = v
138+
time.sleep_ms(delay_interval_ms)
139+
140+
tt.input_byte = 0
141+
time.sleep_ms(int(delay_interval_ms/10))
142+
143+
tt.input_byte = 0
144+
time.sleep_ms(int(delay_interval_ms/2))
145+
146+
tt.clock_project_stop()
147+
148+
return True
149+
99150

100-
def say_hello(delay_interval_ms:int=100, times:int=1):
151+
def say_hello_03p5(delay_interval_ms:int=200, times:int=1):
101152
# a test, must return True to consider a pass
102-
print(f'Saying hello')
103-
104-
hello_values = [0x74, 0x79, 0x30, 0x30, 0x5c, 0, 0x50, 0x10, 0x78, 0x77]
153+
hello_values = [0x74, 0x79, 0x30, 0x30, 0x5c, 0, 0]
105154
tt = get_demoboard()
106-
tt.shuttle.tt_um_test.enable()
155+
try:
156+
tt.shuttle.factory_test.enable()
157+
except:
158+
print('Failed to load factory test?')
159+
return
160+
161+
107162
tt.mode = RPMode.ASIC_RP_CONTROL # make sure we're controlling everything
108163

109164
tt.in0(0) # want this low
110165
tt.clock_project_PWM(1e3) # clock it real good
111166

112167
log.info('First boot: saying hello')
113-
for bp in tt.bidirs:
114-
bp.mode = Pins.OUT
115-
bp(0) # start low
168+
# for bp in tt.bidirs:
169+
# bp.mode = Pins.OUT
170+
# bp(0) # start low
171+
172+
tt.bidir_mode = [Pins.OUT] * 8
173+
tt.bidir_byte = 0
116174

117175
for _i in range(times):
118176
for v in hello_values:
119177
tt.bidir_byte = v
178+
log.warn(f'Wrote {v} to bidir, waiting {delay_interval_ms}')
120179
time.sleep_ms(delay_interval_ms)
121180

122181
tt.bidir_byte = 0
@@ -128,8 +187,7 @@ def say_hello(delay_interval_ms:int=100, times:int=1):
128187

129188

130189
# reset everything
131-
for bp in tt.bidirs:
132-
bp.mode = Pins.IN
190+
tt.bidir_mode = [Pins.IN] * 8
133191

134192
tt.clock_project_stop()
135193

src/ttboard/boot/post.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def write_pin(cls, pin:str, value:int):
7878

7979
@classmethod
8080
def dotest_buttons_held(cls):
81-
cls.write_pin('hk_csb', 1)
81+
cls.write_pin('hk_csb', 1) # make sure mux is pointed right way
8282
if cls.read_pin('rp_projclk') and not cls.read_pin('sdi_nprojectrst'):
8383
log.info('POST "do test" buttons held')
8484
return True

src/ttboard/demoboard.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ def load_default_project(self):
127127
log.warn(f'Default project is unknown "{self.user_config.default_project}"')
128128

129129

130+
@property
131+
def chip_ROM(self):
132+
return self.shuttle.chip_ROM
133+
130134
@property
131135
def mode(self):
132136
return self.pins.mode

src/ttboard/project_mux.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ def __init__(self, pins:Pins, shuttle_index_file:str=None):
8181
self.enabled = None
8282
self.design_enabled_callback = None
8383
self.shuttle_index_file = shuttle_index_file
84+
self._chip_rom = None
8485

8586
def reset(self):
8687
log.debug('Resetting project mux')
@@ -126,12 +127,33 @@ def reset_and_clock_mux(self, count:int):
126127
@property
127128
def pins(self) -> Pins:
128129
return self.p
130+
131+
@property
132+
def chip_ROM(self) -> ChipROM:
133+
if self._chip_rom is None:
134+
self._chip_rom = ChipROM(self)
135+
136+
return self._chip_rom
137+
138+
139+
@property
140+
def factory_test(self) -> Design:
141+
try:
142+
shuttle = self.chip_ROM.shuttle
143+
if shuttle == 'tt03p5':
144+
return self.tt_um_test
145+
return self.tt_um_factory_test
146+
147+
except:
148+
pass
149+
return None
150+
129151
@property
130152
def projects(self):
131153
if self._design_index is None:
132154
if self.shuttle_index_file is None:
133155
log.debug('No shuttle index file specified, loading rom')
134-
rom = ChipROM(self)
156+
rom = self.chip_ROM
135157
log.info(f'Chip reported by ROM is {rom.shuttle} commit {rom.commit}')
136158
shuttle_file = f'/shuttles/{rom.shuttle}.json'
137159
self.shuttle_index_file = shuttle_file

src/ttboard/util/shuttle_tests.py

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import ttboard.logging as logging
1313
log = logging.getLogger(__name__)
1414

15-
def factory_test_bidirs(tt:DemoBoard, max_idx:int=255, delay_interval_ms:int=1):
15+
def factory_test_bidirs_03p5(tt:DemoBoard, max_idx:int=255, delay_interval_ms:int=1):
1616
'''
1717
Tests project comms and bidir pins by using tt_um_test to reflect
1818
bidir to output.
@@ -62,7 +62,31 @@ def factory_test_bidirs(tt:DemoBoard, max_idx:int=255, delay_interval_ms:int=1):
6262
return None
6363

6464

65-
def factory_test_clocking(tt:DemoBoard, max_idx:int=30, delay_interval_ms:int=50):
65+
def clock_and_compare_output(tt:DemoBoard, max_idx:int, delay_interval_ms:int):
66+
err_count = 0
67+
for i in range(max_idx):
68+
tt.clock_project_once()
69+
time.sleep_ms(delay_interval_ms)
70+
out_byte = tt.output_byte
71+
72+
# give ourselves a little jitter room, in case we're a step
73+
# behind as has happened for reasons unclear
74+
if out_byte != i and out_byte != (i+1) and out_byte != (i-1):
75+
log.warn(f'MISMATCH between expected count {i} and output {out_byte}')
76+
err_count += 1
77+
else:
78+
log.debug(f'Clock count {i}, got {out_byte}')
79+
80+
81+
if err_count:
82+
err_msg = f'{err_count}/{max_idx} mismatches during counting test'
83+
log.error(err_msg)
84+
return err_msg
85+
86+
log.info('RP2040 clocking acting pretty nicely')
87+
return None
88+
89+
def factory_test_clocking_03p5(tt:DemoBoard, max_idx:int=30, delay_interval_ms:int=50):
6690
'''
6791
Tests project comms, clocking and output pins by using tt_um_test to
6892
count clock ticks.
@@ -82,26 +106,22 @@ def factory_test_clocking(tt:DemoBoard, max_idx:int=30, delay_interval_ms:int=50
82106
tt.input_byte = 1
83107
tt.clock_project_stop()
84108
tt.reset_project(False)
109+
return clock_and_compare_output(tt, max_idx, delay_interval_ms)
110+
111+
112+
def factory_test_clocking_04(tt:DemoBoard, max_idx:int=30, delay_interval_ms:int=50):
85113

86-
err_count = 0
87-
for i in range(max_idx):
88-
tt.clock_project_once()
89-
time.sleep_ms(delay_interval_ms)
90-
out_byte = tt.output_byte
91-
92-
# give ourselves a little jitter room, in case we're a step
93-
# behind as has happened for reasons unclear
94-
if out_byte != i and out_byte != (i+1) and out_byte != (i-1):
95-
log.warn(f'MISMATCH between expected count {i} and output {tt.output_byte}')
96-
err_count += 1
114+
log.info(f'Testing manual clocking up to {max_idx} on {tt}')
97115

98116

99-
if err_count:
100-
err_msg = f'{err_count}/{max_idx} mismatches during counting test'
101-
log.error(err_msg)
102-
return err_msg
117+
# select the project from the shuttle
118+
tt.shuttle.tt_um_factory_test.enable()
119+
tt.mode = RPMode.ASIC_RP_CONTROL # make sure we're controlling everything
103120

104-
log.info('RP2040 clocking acting pretty nicely')
105-
return None
106-
107-
121+
122+
tt.reset_project(True)
123+
tt.input_byte = 1
124+
tt.clock_project_stop()
125+
tt.reset_project(False)
126+
127+
return clock_and_compare_output(tt, max_idx, delay_interval_ms)

0 commit comments

Comments
 (0)