expo: Tidy up the expo.py tool and usage

Tidy up this tool a little:

- define which arguments are needed
- split the enum values out into a header file
- warn if no enum values are found
- display the dtc error if something goes wrong
- avoid a Python traceback on error

Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/doc/develop/expo.rst b/doc/develop/expo.rst
index 2ac4af2..0643283 100644
--- a/doc/develop/expo.rst
+++ b/doc/develop/expo.rst
@@ -367,22 +367,27 @@
 
 ::
 
-    #define ID_PROMPT           1
-    #define ID_SCENE1           2
-    #define ID_SCENE1_TITLE     3
+    /* this comment is parsed by the expo.py tool to insert the values below
 
-    #define ID_CPU_SPEED        4
-    #define ID_CPU_SPEED_TITLE  5
-    #define ID_CPU_SPEED_1      6
-    #define ID_CPU_SPEED_2      7
-    #define ID_CPU_SPEED_3      8
+    enum {
+        ZERO,
+        ID_PROMPT,
+        ID_SCENE1,
+        ID_SCENE1_TITLE,
 
-    #define ID_POWER_LOSS       9
-    #define ID_AC_OFF           10
-    #define ID_AC_ON            11
-    #define ID_AC_MEMORY        12
+        ID_CPU_SPEED,
+        ID_CPU_SPEED_TITLE,
+        ID_CPU_SPEED_1,
+        ID_CPU_SPEED_2,
+        ID_CPU_SPEED_3,
 
-    #define ID_DYNAMIC_START    13
+        ID_POWER_LOSS,
+        ID_AC_OFF,
+        ID_AC_ON,
+        ID_AC_MEMORY,
+
+        ID_DYNAMIC_START,
+    */
 
     &cedit {
         dynamic-start = <ID_DYNAMIC_START>;
diff --git a/test/boot/files/expo_ids.h b/test/boot/files/expo_ids.h
new file mode 100644
index 0000000..027d44b
--- /dev/null
+++ b/test/boot/files/expo_ids.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Sample expo screen layout (ID numbers)
+ */
+
+enum {
+	ZERO,
+	ID_PROMPT,
+
+	ID_SCENE1,
+	ID_SCENE1_TITLE,
+
+	ID_CPU_SPEED,
+	ID_CPU_SPEED_TITLE,
+	ID_CPU_SPEED_1,
+	ID_CPU_SPEED_2,
+	ID_CPU_SPEED_3,
+
+	ID_POWER_LOSS,
+	ID_AC_OFF,
+	ID_AC_ON,
+	ID_AC_MEMORY,
+
+	ID_DYNAMIC_START,
+};
diff --git a/test/boot/files/expo_layout.dts b/test/boot/files/expo_layout.dts
index 55d5c91..913140b 100644
--- a/test/boot/files/expo_layout.dts
+++ b/test/boot/files/expo_layout.dts
@@ -5,28 +5,7 @@
 
 /dts-v1/;
 
-/*
-enum {
-	ZERO,
-	ID_PROMPT,
-
-	ID_SCENE1,
-	ID_SCENE1_TITLE,
-
-	ID_CPU_SPEED,
-	ID_CPU_SPEED_TITLE,
-	ID_CPU_SPEED_1,
-	ID_CPU_SPEED_2,
-	ID_CPU_SPEED_3,
-
-	ID_POWER_LOSS,
-	ID_AC_OFF,
-	ID_AC_ON,
-	ID_AC_MEMORY,
-
-	ID_DYNAMIC_START,
-};
-*/
+/* see expo_ids.h for the IDs */
 
 / {
 	dynamic-start = <ID_DYNAMIC_START>;
diff --git a/test/py/tests/test_ut.py b/test/py/tests/test_ut.py
index aa1d477..6a59c30 100644
--- a/test/py/tests/test_ut.py
+++ b/test/py/tests/test_ut.py
@@ -285,10 +285,12 @@
 def setup_cedit_file(cons):
     infname = os.path.join(cons.config.source_dir,
                            'test/boot/files/expo_layout.dts')
+    inhname = os.path.join(cons.config.source_dir,
+                           'test/boot/files/expo_ids.h')
     expo_tool = os.path.join(cons.config.source_dir, 'tools/expo.py')
     outfname = 'cedit.dtb'
     u_boot_utils.run_and_log(
-        cons, f'{expo_tool} -e {infname} -l {infname} -o {outfname}')
+        cons, f'{expo_tool} -e {inhname} -l {infname} -o {outfname}')
 
 
 @pytest.mark.buildconfigspec('ut_dm')
diff --git a/tools/expo.py b/tools/expo.py
index c6eb87a..ea80c70 100755
--- a/tools/expo.py
+++ b/tools/expo.py
@@ -69,7 +69,10 @@
 
 def run_expo(args):
     """Run the expo program"""
-    ids = calc_ids(args.enum_fname)
+    fname = args.enum_fname or args.layout
+    ids = calc_ids(fname)
+    if not ids:
+        print(f"Warning: No enum ID values found in file '{fname}'")
 
     indata = tools.read_file(args.layout)
 
@@ -88,10 +91,10 @@
 
     with open('/tmp/asc', 'wb') as outf:
         outf.write(data)
-    proc = subprocess.run('dtc', input=data, capture_output=True, check=True)
+    proc = subprocess.run('dtc', input=data, capture_output=True)
     edtb = proc.stdout
     if proc.stderr:
-        print(proc.stderr)
+        print(f"Devicetree compiler error:\n{proc.stderr.decode('utf-8')}")
         return 1
     tools.write_file(args.outfile, edtb)
     return 0
@@ -109,11 +112,13 @@
             args is a list of string arguments
     """
     parser = argparse.ArgumentParser()
+    parser.add_argument('-D', '--debug', action='store_true',
+        help='Enable full debug traceback')
     parser.add_argument('-e', '--enum-fname', type=str,
-        help='C file containing enum declaration for expo items')
-    parser.add_argument('-l', '--layout', type=str,
-        help='Devicetree file source .dts for expo layout')
-    parser.add_argument('-o', '--outfile', type=str,
+        help='.dts or C file containing enum declaration for expo items')
+    parser.add_argument('-l', '--layout', type=str, required=True,
+        help='Devicetree file source .dts for expo layout (and perhaps enums)')
+    parser.add_argument('-o', '--outfile', type=str, required=True,
         help='Filename to write expo layout dtb')
 
     return parser.parse_args(argv)
@@ -122,6 +127,9 @@
     """Start the expo program"""
     args = parse_args(sys.argv[1:])
 
+    if not args.debug:
+        sys.tracebacklimit = 0
+
     ret_code = run_expo(args)
     sys.exit(ret_code)