Skip to content

Commit 7d60ee4

Browse files
committed
Dynamic shuttle indexes based on chip ROM
1 parent 21c5008 commit 7d60ee4

File tree

7 files changed

+144
-18
lines changed

7 files changed

+144
-18
lines changed

.github/workflows/release.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ jobs:
99
# ubuntu
1010
env:
1111
RPOS_UF2FILE: RPI_PICO-20240222-v1.22.2.uf2
12+
TT_RUNS_SUPPORTED: "tt03p5 tt04"
1213
runs-on: ubuntu-latest
1314
steps:
1415
# need the repo checked out
@@ -27,6 +28,12 @@ jobs:
2728
python-version: '3.10'
2829
cache: 'pip'
2930
# build it
31+
- name: get the os
32+
run: |
33+
mkdir $GITHUB_WORKSPACE/sdk/src/shuttles
34+
for chip in $TT_RUNS_SUPPORTED; do wget -O $GITHUB_WORKSPACE/sdk/src/shuttles/$chip.json "https://index.tinytapeout.com/$chip.json?fields=repo,address,commit,clock_hz"; done
35+
run: |
36+
# build it
3037
- run: |
3138
pip install uf2utils
3239
touch $GITHUB_WORKSPACE/sdk/src/release_${{ github.ref_name }}

src/shuttle_index.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

src/ttboard/boot/first.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,8 @@ def run_complete(self, success:bool):
211211
os.unlink(self.FirstBootIniFile)
212212
self.log_message('Unlinked first_boot ini file')
213213
except:
214-
self.log_error(f'Issue unlinking {self.FirstBootIniFile}?')
214+
# can happen (unlinked above)
215+
pass
215216

216217
self.log_message(f'First boot run success: {success}')
217218
if self._first_log is not None:

src/ttboard/boot/rom.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
'''
2+
Created on Apr 26, 2024
3+
4+
@author: Pat Deegan
5+
@copyright: Copyright (C) 2024 Pat Deegan, https://psychogenic.com
6+
'''
7+
8+
class ChipROM:
9+
def __init__(self, project_mux):
10+
self.project_mux = project_mux
11+
self._contents = None
12+
self._pins = project_mux.pins
13+
14+
15+
def _send_and_rcv(self, send:int):
16+
self._pins.input_byte = send
17+
return self._pins.output_byte
18+
19+
@property
20+
def shuttle(self):
21+
return self.contents['shuttle']
22+
23+
@property
24+
def repo(self):
25+
return self.contents['repo']
26+
27+
@property
28+
def commit(self):
29+
return self.contents['commit']
30+
31+
@property
32+
def contents(self):
33+
if self._contents is not None:
34+
return self._contents
35+
36+
# select project 0
37+
self.project_mux.reset_and_clock_mux(0)
38+
39+
self._contents = {
40+
'shuttle': 'tt03p5',
41+
'repo': '',
42+
'commit': ''
43+
}
44+
45+
magic = self._send_and_rcv(0)
46+
if magic != 0x78:
47+
48+
return self._contents
49+
50+
rom_data = ''
51+
for i in range(32, 128):
52+
byte = self._send_and_rcv(i)
53+
if byte == 0:
54+
break
55+
rom_data += chr(byte)
56+
57+
self._contents = {}
58+
for l in rom_data.splitlines():
59+
try:
60+
k,v = l.split('=')
61+
self._contents[k] = v
62+
except:
63+
pass
64+
65+
return self._contents
66+
67+

src/ttboard/demoboard.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
@copyright: Copyright (C) 2024 Pat Deegan, https://psychogenic.com
1616
'''
1717
import ttboard.util.time as time
18+
from ttboard.globals import Globals
1819
from ttboard.mode import RPMode
1920
from ttboard.pins import Pins
2021
from ttboard.project_mux import ProjectMux, Design
@@ -102,14 +103,14 @@ def __init__(self,
102103

103104
log.info(f'Demoboard starting up in mode {RPMode.to_string(mode)}')
104105

105-
self.pins = Pins(mode=mode)
106-
self.shuttle = ProjectMux(self.pins)
106+
self.pins = Globals.pins(mode=mode)
107+
self.shuttle = Globals.project_mux()
107108

108109
# config
109110
self.apply_configs = apply_user_config
110111

111112
# internal
112-
self.shuttle.designEnabledCallback = self.apply_user_config
113+
self.shuttle.design_enabled_callback = self.apply_user_config
113114
self._clock_pwm = None
114115

115116
self.load_default_project()

src/ttboard/globals.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'''
2+
Created on Apr 26, 2024
3+
4+
@author: Pat Deegan
5+
@copyright: Copyright (C) 2024 Pat Deegan, https://psychogenic.com
6+
'''
7+
from ttboard.mode import RPMode
8+
from ttboard.pins.pins import Pins
9+
from ttboard.project_mux import ProjectMux
10+
11+
class Globals:
12+
Pins_Singleton = None
13+
ProjectMux_Singleton = None
14+
15+
@classmethod
16+
def pins(cls, mode=None) -> Pins:
17+
if cls.Pins_Singleton is None:
18+
if mode is None:
19+
mode = RPMode.SAFE
20+
cls.Pins_Singleton = Pins(mode=mode)
21+
22+
if mode is not None and mode != cls.Pins_Singleton.mode:
23+
cls.Pins_Singleton.mode = mode
24+
25+
return cls.Pins_Singleton
26+
27+
@classmethod
28+
def project_mux(cls) -> ProjectMux:
29+
if cls.ProjectMux_Singleton is None:
30+
cls.ProjectMux_Singleton = ProjectMux(cls.pins())
31+
32+
return cls.ProjectMux_Singleton
33+

src/ttboard/project_mux.py

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import json
99
import ttboard.util.time as time
1010
from ttboard.pins import Pins
11+
from ttboard.boot.rom import ChipROM
1112

1213
import ttboard.logging as logging
1314
log = logging.getLogger(__name__)
@@ -42,16 +43,19 @@ def __repr__(self):
4243
return f'<Design {self.project_index}: {self.name}>'
4344

4445
class DesignIndex:
45-
def __init__(self, projectMux, srcJSONFile:str='shuttle_index.json'):
46+
def __init__(self, projectMux, src_JSON_file:str='shuttle_index.json'):
4647
self._shuttle_index = dict()
4748
self._project_count = 0
48-
with open(srcJSONFile) as fh:
49-
index = json.load(fh)
50-
for project in index["projects"]:
51-
des = Design(projectMux, project["address"], project)
52-
self._shuttle_index[des.name] = des
53-
setattr(self, des.name, des)
54-
self._project_count += 1
49+
try:
50+
with open(src_JSON_file) as fh:
51+
index = json.load(fh)
52+
for project in index["projects"]:
53+
des = Design(projectMux, project["address"], project)
54+
self._shuttle_index[des.name] = des
55+
setattr(self, des.name, des)
56+
self._project_count += 1
57+
except OSError:
58+
log.error(f'Could not open shuttle index {src_JSON_file}')
5559

5660

5761
@property
@@ -71,11 +75,12 @@ def get(self, project_name:str) -> Design:
7175

7276

7377
class ProjectMux:
74-
def __init__(self, pins:Pins):
78+
def __init__(self, pins:Pins, shuttle_index_file:str=None):
7579
self.p = pins
7680
self._design_index = None
7781
self.enabled = None
78-
self.designEnabledCallback = None
82+
self.design_enabled_callback = None
83+
self.shuttle_index_file = shuttle_index_file
7984

8085
def reset(self):
8186
log.debug('Resetting project mux')
@@ -97,8 +102,8 @@ def enable(self, design:Design):
97102
log.info(f'Enable design {design.name}')
98103
self.reset_and_clock_mux(design.count)
99104
self.enabled = design
100-
if self.designEnabledCallback is not None:
101-
self.designEnabledCallback(design)
105+
if self.design_enabled_callback is not None:
106+
self.design_enabled_callback(design)
102107

103108

104109
def reset_and_clock_mux(self, count:int):
@@ -118,10 +123,23 @@ def reset_and_clock_mux(self, count:int):
118123
self.p.cena(1)
119124
self.p.muxCtrl.mode_project_IO()
120125

126+
@property
127+
def pins(self) -> Pins:
128+
return self.p
121129
@property
122130
def projects(self):
123131
if self._design_index is None:
124-
self._design_index = DesignIndex(self)
132+
if self.shuttle_index_file is None:
133+
log.debug('No shuttle index file specified, loading rom')
134+
rom = ChipROM(self)
135+
log.info(f'Chip reported by ROM is {rom.shuttle} commit {rom.commit}')
136+
shuttle_file = f'/shuttles/{rom.shuttle}.json'
137+
self.shuttle_index_file = shuttle_file
138+
139+
140+
log.info(f'Loading shuttle file {self.shuttle_index_file}')
141+
142+
self._design_index = DesignIndex(self, src_JSON_file=self.shuttle_index_file)
125143

126144
return self._design_index
127145

0 commit comments

Comments
 (0)