Skip to content

Commit 2d01fac

Browse files
committed
User config documentation and better REPL inspection capabilities
1 parent db8db69 commit 2d01fac

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

src/ttboard/config/config_file.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ def load(self, filepath:str):
4343
except: # no FileNotFoundError on uPython
4444
log.warn(f'Could not load config file {filepath}')
4545

46+
@property
47+
def filepath(self):
48+
return self._inifile_path
49+
50+
@filepath.setter
51+
def filepath(self, set_to:str):
52+
self.load(set_to)
4653
@property
4754
def is_loaded(self):
4855
return self._ini_file_loaded

src/ttboard/config/user_config.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,31 @@
1212
log = logging.getLogger(__name__)
1313

1414
class UserProjectConfig:
15+
'''
16+
Configuration specific to a project, held in a section with the
17+
project's shuttle name, e.g.
18+
19+
[tt_um_psychogenic_neptuneproportional]
20+
# set clock to 4kHz
21+
clock_frequency = 4000
22+
# clock config 4k, disp single bits
23+
input_byte = 0b11001000
24+
mode = ASIC_ON_BOARD
25+
26+
You can use this to set:
27+
- mode (str)
28+
- start_in_reset (bool)
29+
- input_byte (int)
30+
- bidir_direction (int)
31+
- bidir_byte (int)
32+
- clock_frequency (int)
33+
34+
all keys are optional.
35+
36+
A repr function lets you see the basics, do a print(tt.user_config.tt_um_someproject) to
37+
see more info.
38+
39+
'''
1540
def __init__(self, section:str, conf:ConfigParser):
1641
self.section = section
1742
self._config = conf
@@ -20,6 +45,8 @@ def __init__(self, section:str, conf:ConfigParser):
2045
def config(self):
2146
return self._config
2247

48+
49+
2350
def has(self, name:str):
2451
return self.config.has_option(self.section, name)
2552

@@ -31,10 +58,58 @@ def get(self, name:str):
3158

3259
def __getattr__(self, name):
3360
return self.get(name)
61+
62+
def _properties_dict(self, include_unset:bool=False):
63+
ret = dict()
64+
known_attribs = ['mode', 'start_in_reset', 'input_byte',
65+
'bidir_direction',
66+
'bidir_byte',
67+
'clock_frequency',
68+
]
69+
for atr in known_attribs:
70+
v = self.get(atr)
71+
if v is not None or include_unset:
72+
ret[atr] = v
73+
74+
return ret
3475

76+
def __repr__(self):
77+
props = self._properties_dict(True)
78+
return f'<UserProjectConfig {self.section}, {props["clock_frequency"]}Hz, mode: {props["mode"]}>'
3579

80+
def __str__(self):
81+
return f'UserProjectConfig {self.section}\n{self._properties_dict()}'
3682

3783
class UserConfig(ConfigFile):
84+
'''
85+
Encapsulates the configuration for defaults and all the projects, in sections.
86+
The DEFAULT section holds system wide defaults and the default project to load
87+
on startup.
88+
89+
DEFAULT section may have
90+
91+
# project: project to load by default
92+
project = tt_um_test
93+
94+
# start in reset (bool)
95+
start_in_reset = no
96+
97+
# mode can be any of
98+
# - SAFE: all RP2040 pins inputs
99+
# - ASIC_ON_BOARD: TT inputs,nrst and clock driven, outputs monitored
100+
# - ASIC_MANUAL_INPUTS: basically same as safe, but intent is clear
101+
mode = ASIC_ON_BOARD
102+
103+
# log_level can be one of
104+
# - DEBUG
105+
# - INFO
106+
# - WARN
107+
# - ERROR
108+
log_level = INFO
109+
Each project section is named [SHUTTLE_PROJECT_NAME]
110+
and will be an instance of, and described by, UserProjectConfig
111+
'''
112+
38113
def __init__(self, ini_filepath:str='config.ini'):
39114
super().__init__(ini_filepath)
40115

@@ -70,5 +145,19 @@ def project(self, name:str):
70145

71146
return UserProjectConfig(name, self.ini_file)
72147

148+
def __getattr__(self, name):
149+
if name in self.sections:
150+
return self.project(name)
151+
152+
def __dir__(self):
153+
return self.sections
154+
def __repr__(self):
155+
return f'<UserConfig {self.filepath}, default project: {self.default_project}>'
156+
157+
def __str__(self):
158+
def_mode = self.default_mode
159+
if def_mode is not None:
160+
def_mode = RPMode.to_string(def_mode)
161+
return f'UserConfig {self.filepath}, Defaults:\nproject: {self.default_project}\nmode: {def_mode}'
73162

74163

0 commit comments

Comments
 (0)