diff options
Diffstat (limited to 'lib/python/qmk/cli/generate/config_h.py')
-rwxr-xr-x | lib/python/qmk/cli/generate/config_h.py | 277 |
1 files changed, 277 insertions, 0 deletions
diff --git a/lib/python/qmk/cli/generate/config_h.py b/lib/python/qmk/cli/generate/config_h.py new file mode 100755 index 000000000..4d734017a --- /dev/null +++ b/lib/python/qmk/cli/generate/config_h.py | |||
@@ -0,0 +1,277 @@ | |||
1 | """Used by the make system to generate info_config.h from info.json. | ||
2 | """ | ||
3 | from milc import cli | ||
4 | |||
5 | from qmk.constants import LED_INDICATORS | ||
6 | from qmk.decorators import automagic_keyboard, automagic_keymap | ||
7 | from qmk.info import info_json, rgblight_animations, rgblight_properties, rgblight_toggles | ||
8 | from qmk.path import is_keyboard, normpath | ||
9 | |||
10 | usb_properties = { | ||
11 | 'vid': 'VENDOR_ID', | ||
12 | 'pid': 'PRODUCT_ID', | ||
13 | 'device_ver': 'DEVICE_VER', | ||
14 | } | ||
15 | |||
16 | |||
17 | def debounce(debounce): | ||
18 | """Return the config.h lines that set debounce | ||
19 | """ | ||
20 | return """ | ||
21 | #ifndef DEBOUNCE | ||
22 | # define DEBOUNCE %s | ||
23 | #endif // DEBOUNCE | ||
24 | """ % debounce | ||
25 | |||
26 | |||
27 | def diode_direction(diode_direction): | ||
28 | """Return the config.h lines that set diode direction | ||
29 | """ | ||
30 | return """ | ||
31 | #ifndef DIODE_DIRECTION | ||
32 | # define DIODE_DIRECTION %s | ||
33 | #endif // DIODE_DIRECTION | ||
34 | """ % diode_direction | ||
35 | |||
36 | |||
37 | def keyboard_name(keyboard_name): | ||
38 | """Return the config.h lines that set the keyboard's name. | ||
39 | """ | ||
40 | return """ | ||
41 | #ifndef DESCRIPTION | ||
42 | # define DESCRIPTION %s | ||
43 | #endif // DESCRIPTION | ||
44 | |||
45 | #ifndef PRODUCT | ||
46 | # define PRODUCT %s | ||
47 | #endif // PRODUCT | ||
48 | """ % (keyboard_name, keyboard_name) | ||
49 | |||
50 | |||
51 | def manufacturer(manufacturer): | ||
52 | """Return the config.h lines that set the manufacturer. | ||
53 | """ | ||
54 | return """ | ||
55 | #ifndef MANUFACTURER | ||
56 | # define MANUFACTURER %s | ||
57 | #endif // MANUFACTURER | ||
58 | """ % (manufacturer) | ||
59 | |||
60 | |||
61 | def direct_pins(direct_pins): | ||
62 | """Return the config.h lines that set the direct pins. | ||
63 | """ | ||
64 | rows = [] | ||
65 | |||
66 | for row in direct_pins: | ||
67 | cols = ','.join([col or 'NO_PIN' for col in row]) | ||
68 | rows.append('{' + cols + '}') | ||
69 | |||
70 | col_count = len(direct_pins[0]) | ||
71 | row_count = len(direct_pins) | ||
72 | |||
73 | return """ | ||
74 | #ifndef MATRIX_COLS | ||
75 | # define MATRIX_COLS %s | ||
76 | #endif // MATRIX_COLS | ||
77 | |||
78 | #ifndef MATRIX_ROWS | ||
79 | # define MATRIX_ROWS %s | ||
80 | #endif // MATRIX_ROWS | ||
81 | |||
82 | #ifndef DIRECT_PINS | ||
83 | # define DIRECT_PINS {%s} | ||
84 | #endif // DIRECT_PINS | ||
85 | """ % (col_count, row_count, ','.join(rows)) | ||
86 | |||
87 | |||
88 | def col_pins(col_pins): | ||
89 | """Return the config.h lines that set the column pins. | ||
90 | """ | ||
91 | cols = ','.join(col_pins) | ||
92 | col_num = len(col_pins) | ||
93 | |||
94 | return """ | ||
95 | #ifndef MATRIX_COLS | ||
96 | # define MATRIX_COLS %s | ||
97 | #endif // MATRIX_COLS | ||
98 | |||
99 | #ifndef MATRIX_COL_PINS | ||
100 | # define MATRIX_COL_PINS {%s} | ||
101 | #endif // MATRIX_COL_PINS | ||
102 | """ % (col_num, cols) | ||
103 | |||
104 | |||
105 | def row_pins(row_pins): | ||
106 | """Return the config.h lines that set the row pins. | ||
107 | """ | ||
108 | rows = ','.join(row_pins) | ||
109 | row_num = len(row_pins) | ||
110 | |||
111 | return """ | ||
112 | #ifndef MATRIX_ROWS | ||
113 | # define MATRIX_ROWS %s | ||
114 | #endif // MATRIX_ROWS | ||
115 | |||
116 | #ifndef MATRIX_ROW_PINS | ||
117 | # define MATRIX_ROW_PINS {%s} | ||
118 | #endif // MATRIX_ROW_PINS | ||
119 | """ % (row_num, rows) | ||
120 | |||
121 | |||
122 | def indicators(config): | ||
123 | """Return the config.h lines that setup LED indicators. | ||
124 | """ | ||
125 | defines = [] | ||
126 | |||
127 | for led, define in LED_INDICATORS.items(): | ||
128 | if led in config: | ||
129 | defines.append('') | ||
130 | defines.append('#ifndef %s' % (define,)) | ||
131 | defines.append('# define %s %s' % (define, config[led])) | ||
132 | defines.append('#endif // %s' % (define,)) | ||
133 | |||
134 | return '\n'.join(defines) | ||
135 | |||
136 | |||
137 | def layout_aliases(layout_aliases): | ||
138 | """Return the config.h lines that setup layout aliases. | ||
139 | """ | ||
140 | defines = [] | ||
141 | |||
142 | for alias, layout in layout_aliases.items(): | ||
143 | defines.append('') | ||
144 | defines.append('#ifndef %s' % (alias,)) | ||
145 | defines.append('# define %s %s' % (alias, layout)) | ||
146 | defines.append('#endif // %s' % (alias,)) | ||
147 | |||
148 | return '\n'.join(defines) | ||
149 | |||
150 | |||
151 | def matrix_pins(matrix_pins): | ||
152 | """Add the matrix config to the config.h. | ||
153 | """ | ||
154 | pins = [] | ||
155 | |||
156 | if 'direct' in matrix_pins: | ||
157 | pins.append(direct_pins(matrix_pins['direct'])) | ||
158 | |||
159 | if 'cols' in matrix_pins: | ||
160 | pins.append(col_pins(matrix_pins['cols'])) | ||
161 | |||
162 | if 'rows' in matrix_pins: | ||
163 | pins.append(row_pins(matrix_pins['rows'])) | ||
164 | |||
165 | return '\n'.join(pins) | ||
166 | |||
167 | |||
168 | def rgblight(config): | ||
169 | """Return the config.h lines that setup rgblight. | ||
170 | """ | ||
171 | rgblight_config = [] | ||
172 | |||
173 | for json_key, config_key in rgblight_properties.items(): | ||
174 | if json_key in config: | ||
175 | rgblight_config.append('') | ||
176 | rgblight_config.append('#ifndef %s' % (config_key,)) | ||
177 | rgblight_config.append('# define %s %s' % (config_key, config[json_key])) | ||
178 | rgblight_config.append('#endif // %s' % (config_key,)) | ||
179 | |||
180 | for json_key, config_key in rgblight_toggles.items(): | ||
181 | if config.get(json_key): | ||
182 | rgblight_config.append('') | ||
183 | rgblight_config.append('#ifndef %s' % (config_key,)) | ||
184 | rgblight_config.append('# define %s' % (config_key,)) | ||
185 | rgblight_config.append('#endif // %s' % (config_key,)) | ||
186 | |||
187 | for json_key, config_key in rgblight_animations.items(): | ||
188 | if 'animations' in config and config['animations'].get(json_key): | ||
189 | rgblight_config.append('') | ||
190 | rgblight_config.append('#ifndef %s' % (config_key,)) | ||
191 | rgblight_config.append('# define %s' % (config_key,)) | ||
192 | rgblight_config.append('#endif // %s' % (config_key,)) | ||
193 | |||
194 | return '\n'.join(rgblight_config) | ||
195 | |||
196 | |||
197 | def usb_properties(usb_props): | ||
198 | """Return the config.h lines that setup USB params. | ||
199 | """ | ||
200 | usb_lines = [] | ||
201 | |||
202 | for info_name, config_name in usb_props.items(): | ||
203 | if info_name in usb_props: | ||
204 | usb_lines.append('') | ||
205 | usb_lines.append('#ifndef ' + config_name) | ||
206 | usb_lines.append('# define %s %s' % (config_name, usb_props[info_name])) | ||
207 | usb_lines.append('#endif // ' + config_name) | ||
208 | |||
209 | return '\n'.join(usb_lines) | ||
210 | |||
211 | |||
212 | @cli.argument('-o', '--output', arg_only=True, type=normpath, help='File to write to') | ||
213 | @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") | ||
214 | @cli.argument('-kb', '--keyboard', help='Keyboard to generate config.h for.') | ||
215 | @cli.subcommand('Used by the make system to generate info_config.h from info.json', hidden=True) | ||
216 | @automagic_keyboard | ||
217 | @automagic_keymap | ||
218 | def generate_config_h(cli): | ||
219 | """Generates the info_config.h file. | ||
220 | """ | ||
221 | # Determine our keyboard(s) | ||
222 | if not cli.config.generate_config_h.keyboard: | ||
223 | cli.log.error('Missing paramater: --keyboard') | ||
224 | cli.subcommands['info'].print_help() | ||
225 | return False | ||
226 | |||
227 | if not is_keyboard(cli.config.generate_config_h.keyboard): | ||
228 | cli.log.error('Invalid keyboard: "%s"', cli.config.generate_config_h.keyboard) | ||
229 | return False | ||
230 | |||
231 | # Build the info.json file | ||
232 | kb_info_json = info_json(cli.config.generate_config_h.keyboard) | ||
233 | |||
234 | # Build the info_config.h file. | ||
235 | config_h_lines = ['/* This file was generated by `qmk generate-config-h`. Do not edit or copy.' ' */', '', '#pragma once'] | ||
236 | |||
237 | if 'debounce' in kb_info_json: | ||
238 | config_h_lines.append(debounce(kb_info_json['debounce'])) | ||
239 | |||
240 | if 'diode_direction' in kb_info_json: | ||
241 | config_h_lines.append(diode_direction(kb_info_json['diode_direction'])) | ||
242 | |||
243 | if 'indicators' in kb_info_json: | ||
244 | config_h_lines.append(indicators(kb_info_json['indicators'])) | ||
245 | |||
246 | if 'keyboard_name' in kb_info_json: | ||
247 | config_h_lines.append(keyboard_name(kb_info_json['keyboard_name'])) | ||
248 | |||
249 | if 'layout_aliases' in kb_info_json: | ||
250 | config_h_lines.append(layout_aliases(kb_info_json['layout_aliases'])) | ||
251 | |||
252 | if 'manufacturer' in kb_info_json: | ||
253 | config_h_lines.append(manufacturer(kb_info_json['manufacturer'])) | ||
254 | |||
255 | if 'rgblight' in kb_info_json: | ||
256 | config_h_lines.append(rgblight(kb_info_json['rgblight'])) | ||
257 | |||
258 | if 'matrix_pins' in kb_info_json: | ||
259 | config_h_lines.append(matrix_pins(kb_info_json['matrix_pins'])) | ||
260 | |||
261 | if 'usb' in kb_info_json: | ||
262 | config_h_lines.append(usb_properties(kb_info_json['usb'])) | ||
263 | |||
264 | # Show the results | ||
265 | config_h = '\n'.join(config_h_lines) | ||
266 | |||
267 | if cli.args.output: | ||
268 | cli.args.output.parent.mkdir(parents=True, exist_ok=True) | ||
269 | if cli.args.output.exists(): | ||
270 | cli.args.output.replace(cli.args.output.name + '.bak') | ||
271 | cli.args.output.write_text(config_h) | ||
272 | |||
273 | if not cli.args.quiet: | ||
274 | cli.log.info('Wrote info_config.h to %s.', cli.args.output) | ||
275 | |||
276 | else: | ||
277 | print(config_h) | ||