From d13c931f778391bbee73f5a35499d583e4fc146a Mon Sep 17 00:00:00 2001 From: Martin Vladic Date: Sun, 8 Dec 2019 12:51:37 +0100 Subject: [PATCH] mp debug trace log --- modular-psu-firmware.eez-project | 886 +++++++++++------- scripts/diode-tester-fast.py | 62 ++ scripts/diode-tester.py | 81 +- scripts/test.py | 4 + src/eez/debug.cpp | 139 ++- src/eez/debug.h | 11 + src/eez/gui/action_impl.cpp | 5 + src/eez/gui/app_context.cpp | 26 +- src/eez/gui/app_context.h | 6 +- src/eez/gui/data.cpp | 27 +- src/eez/gui/data.h | 8 +- src/eez/gui/dialogs.cpp | 5 + src/eez/gui/dialogs.h | 1 + src/eez/gui/gui.cpp | 3 +- src/eez/gui/gui.h | 3 +- src/eez/gui/page.cpp | 21 + src/eez/gui/page.h | 2 + src/eez/memory.h | 5 +- src/eez/modules/psu/channel.cpp | 4 +- src/eez/modules/psu/channel.h | 2 +- src/eez/modules/psu/channel_dispatcher.cpp | 2 +- src/eez/modules/psu/dlog_record.cpp | 22 +- src/eez/modules/psu/dlog_record.h | 3 +- src/eez/modules/psu/dlog_view.cpp | 6 +- src/eez/modules/psu/gui/data.cpp | 162 +++- src/eez/modules/psu/gui/file_manager.cpp | 5 +- src/eez/modules/psu/gui/psu.cpp | 24 +- src/eez/modules/psu/gui/psu.h | 4 + src/eez/modules/psu/scpi/dlog.cpp | 2 +- src/eez/modules/psu/scpi/meas.cpp | 6 +- src/eez/modules/psu/scpi/outp.cpp | 2 +- src/eez/mp.cpp | 53 +- src/eez/mp.h | 11 + .../micropython/ports/bb3/genhdr/mpversion.h | 6 +- .../ports/bb3/genhdr/qstrdefs.generated.h | 6 + .../micropython/ports/bb3/mod/eez/modeez.cpp | 124 ++- .../micropython/ports/bb3/mod/eez/modeez.h | 6 + .../ports/bb3/mod/eez/modeez_table.c | 12 + 38 files changed, 1250 insertions(+), 507 deletions(-) create mode 100644 scripts/diode-tester-fast.py diff --git a/modular-psu-firmware.eez-project b/modular-psu-firmware.eez-project index 630c8b3bb..b6779e8d9 100644 --- a/modular-psu-firmware.eez-project +++ b/modular-psu-firmware.eez-project @@ -1815,29 +1815,34 @@ "type": "string", "defaultValue": "U1" }, - { - "name": "dlog_time_offset", - "description": "", - "type": "string", - "defaultValue": "0s" - }, { "name": "dlog_current_time", "type": "string", "defaultValue": "8.34s" }, { - "name": "dlog_time_duration", + "name": "dlog_file_length", + "defaultValue": "17Kb" + }, + { + "name": "dlog_x_axis_offset", + "description": "", "type": "string", - "defaultValue": "8.34s" + "defaultValue": "0s" }, { - "name": "dlog_time_div", + "name": "dlog_x_axis_div", "defaultValue": "200ms" }, { - "name": "dlog_file_length", - "defaultValue": "17Kb" + "name": "dlog_x_axis_range_max", + "type": "string", + "defaultValue": "8.34s" + }, + { + "name": "dlog_x_axis_range_max_label", + "type": "string", + "defaultValue": "Total duration" }, { "name": "is_single_page_on_stack", @@ -1986,6 +1991,20 @@ "name": "script_info", "type": "string", "defaultValue": "script info" + }, + { + "name": "script_is_started", + "type": "boolean", + "defaultValue": "1" + }, + { + "name": "debug_trace_log", + "type": "list", + "defaultValue": "[{}, {}, {}, {}, {}, {}]" + }, + { + "name": "debug_trace_log_line", + "defaultValue": "Text" } ], "actions": [ @@ -2620,6 +2639,9 @@ }, { "name": "dlog_auto_scale" + }, + { + "name": "show_debug_trace_log" } ], "extensionDefinitions": [ @@ -4780,7 +4802,7 @@ "top": 240, "width": 41, "height": 32, - "text": "\\u0022", + "text": "\\u0020", "focusStyle": {} }, { @@ -7780,124 +7802,150 @@ "gridFlow": "row" }, { - "type": "Text", + "type": "Container", "style": { "inheritFrom": "overlay" }, "left": 8, "top": 36, - "width": 28, - "height": 28, - "text": "\\u00a3", - "focusStyle": {} - }, - { - "type": "Select", - "style": { - "inheritFrom": "overlay" - }, - "data": "dlog_state", - "left": 40, - "top": 36, - "width": 200, + "width": 232, "height": 28, + "name": "dlog info", "widgets": [ - { - "type": "Rectangle", - "style": { - "inheritFrom": "overlay" - }, - "left": 0, - "top": 0, - "width": 200, - "height": 28, - "invertColors": true - }, { "type": "Text", "style": { - "inheritFrom": "overlay", - "alignHorizontal": "left" + "inheritFrom": "overlay" }, "left": 0, "top": 0, - "width": 200, + "width": 28, "height": 28, - "text": "Dlog trigger waiting", + "text": "\\u00a3", "focusStyle": {} }, { - "type": "Container", + "type": "Select", "style": { - "inheritFrom": "default" + "inheritFrom": "overlay" }, - "left": 0, + "data": "dlog_state", + "left": 32, "top": 0, "width": 200, "height": 28, "widgets": [ { - "type": "DisplayData", + "type": "Rectangle", "style": { - "inheritFrom": "overlay", - "alignHorizontal": "left" + "inheritFrom": "overlay" }, - "data": "dlog_current_time", "left": 0, "top": 0, - "width": 100, + "width": 200, "height": 28, - "focusStyle": { - "inheritFrom": "default" - }, - "displayOption": 0 + "invertColors": true }, { - "type": "DisplayData", + "type": "Text", "style": { "inheritFrom": "overlay", "alignHorizontal": "left" }, - "data": "dlog_file_length", - "left": 100, + "left": 0, "top": 0, - "width": 100, + "width": 200, "height": 28, - "focusStyle": { + "text": "Dlog trigger waiting", + "focusStyle": {} + }, + { + "type": "Container", + "style": { "inheritFrom": "default" }, - "displayOption": 0 + "left": 0, + "top": 0, + "width": 200, + "height": 28, + "widgets": [ + { + "type": "DisplayData", + "style": { + "inheritFrom": "overlay", + "alignHorizontal": "left" + }, + "data": "dlog_current_time", + "left": 0, + "top": 0, + "width": 100, + "height": 28, + "focusStyle": { + "inheritFrom": "default" + }, + "displayOption": 0 + }, + { + "type": "DisplayData", + "style": { + "inheritFrom": "overlay", + "alignHorizontal": "left" + }, + "data": "dlog_file_length", + "left": 100, + "top": 0, + "width": 100, + "height": 28, + "focusStyle": { + "inheritFrom": "default" + }, + "displayOption": 0 + } + ] } ] } ] }, { - "type": "Text", + "type": "Container", "style": { - "inheritFrom": "overlay", - "font": "Heydings14" + "inheritFrom": "overlay" }, "left": 8, "top": 64, - "width": 28, - "height": 28, - "text": "\\u007d", - "focusStyle": {} - }, - { - "type": "Text", - "style": { - "inheritFrom": "overlay", - "alignHorizontal": "left" - }, - "data": "script_info", - "left": 40, - "top": 64, - "width": 200, + "width": 232, "height": 28, - "text": "", - "focusStyle": {} + "name": "script info", + "widgets": [ + { + "type": "Text", + "style": { + "inheritFrom": "overlay", + "font": "Heydings14" + }, + "left": 0, + "top": 0, + "width": 28, + "height": 28, + "text": "\\u007d", + "focusStyle": {} + }, + { + "type": "Text", + "style": { + "inheritFrom": "overlay", + "alignHorizontal": "left" + }, + "data": "script_info", + "left": 32, + "top": 0, + "width": 200, + "height": 28, + "text": "", + "focusStyle": {} + } + ] } ], "overlay": "overlay", @@ -9797,7 +9845,7 @@ "data": "event_queue_multiple_pages", "left": 93, "top": 240, - "width": 387, + "width": 346, "height": 32, "widgets": [ { @@ -9807,7 +9855,7 @@ }, "left": 0, "top": 0, - "width": 387, + "width": 346, "height": 32 }, { @@ -9817,7 +9865,7 @@ }, "left": 0, "top": 0, - "width": 387, + "width": 346, "height": 32, "widgets": [ { @@ -9828,7 +9876,7 @@ "data": "event_queue_page_info", "left": 0, "top": 0, - "width": 291, + "width": 250, "height": 32, "focusStyle": { "inheritFrom": "default", @@ -9843,7 +9891,7 @@ "font": "Heydings14" }, "action": "event_queue_previous_page", - "left": 291, + "left": 250, "top": 0, "width": 48, "height": 32, @@ -9862,7 +9910,7 @@ "font": "Heydings14" }, "action": "event_queue_next_page", - "left": 339, + "left": 298, "top": 0, "width": 48, "height": 32, @@ -9879,6 +9927,20 @@ ] } ] + }, + { + "type": "Text", + "style": { + "inheritFrom": "status_bgnd", + "font": "Heydings14" + }, + "action": "show_debug_trace_log", + "left": 439, + "top": 240, + "width": 41, + "height": 32, + "text": "\\u0022", + "focusStyle": {} } ], "left": 0, @@ -43383,7 +43445,7 @@ "style": { "inheritFrom": "default" }, - "data": "dlog_time_offset", + "data": "dlog_x_axis_offset", "action": "edit", "left": 0, "top": 0, @@ -43400,12 +43462,12 @@ "activeColor": "status_line_background", "activeBackgroundColor": "status_line_text" }, - "data": "dlog_time_offset", + "data": "dlog_x_axis_offset", "left": 0, "top": 0, "width": 80, "height": 14, - "text": "Time offset", + "text": "Offset", "focusStyle": { "inheritFrom": "edit_value_focus_S_center", "font": "RobotoCondensed-Regular" @@ -43420,7 +43482,7 @@ "activeColor": "status_line_background", "activeBackgroundColor": "status_line_text" }, - "data": "dlog_time_offset", + "data": "dlog_x_axis_offset", "action": "", "left": 0, "top": 14, @@ -43438,7 +43500,7 @@ "style": { "inheritFrom": "default" }, - "data": "dlog_time_div", + "data": "dlog_x_axis_div", "action": "edit", "left": 80, "top": 0, @@ -43455,12 +43517,12 @@ "activeColor": "status_line_background", "activeBackgroundColor": "status_line_text" }, - "data": "dlog_time_div", + "data": "dlog_x_axis_div", "left": 0, "top": 0, "width": 80, "height": 14, - "text": "Time div", + "text": "Div", "focusStyle": { "inheritFrom": "edit_value_focus_S_center", "font": "RobotoCondensed-Regular" @@ -43475,7 +43537,7 @@ "activeColor": "status_line_background", "activeBackgroundColor": "status_line_text" }, - "data": "dlog_time_div", + "data": "dlog_x_axis_div", "action": "", "left": 0, "top": 14, @@ -43498,12 +43560,12 @@ "activeColor": "status_line_background", "activeBackgroundColor": "status_line_text" }, - "data": "", + "data": "dlog_x_axis_range_max_label", "left": 160, "top": 0, "width": 80, "height": 14, - "text": "Total duration", + "text": "", "focusStyle": { "inheritFrom": "edit_value_focus_S_center", "font": "RobotoCondensed-Regular" @@ -43518,7 +43580,7 @@ "activeColor": "status_line_background", "activeBackgroundColor": "status_line_text" }, - "data": "dlog_time_duration", + "data": "dlog_x_axis_range_max", "left": 160, "top": 14, "width": 80, @@ -43570,7 +43632,7 @@ "action": "dlog_toggle", "left": 0, "top": 0, - "width": 80, + "width": 40, "height": 32, "text": "\\u0023", "focusStyle": {} @@ -43585,9 +43647,9 @@ "activeBackgroundColor": "status_line_text" }, "data": "dlog_state", - "left": 80, + "left": 40, "top": 0, - "width": 360, + "width": 200, "height": 32, "widgets": [ { @@ -43601,7 +43663,7 @@ }, "left": 0, "top": 0, - "width": 360, + "width": 200, "height": 32, "invertColors": true }, @@ -43617,7 +43679,7 @@ }, "left": 0, "top": 0, - "width": 360, + "width": 200, "height": 32, "text": "Dlog trigger waiting", "focusStyle": {} @@ -43633,7 +43695,7 @@ }, "left": 0, "top": 0, - "width": 360, + "width": 200, "height": 32, "widgets": [ { @@ -43669,7 +43731,7 @@ "data": "dlog_file_length", "left": 100, "top": 0, - "width": 260, + "width": 100, "height": 32, "focusStyle": { "inheritFrom": "default" @@ -43679,6 +43741,81 @@ ] } ] + }, + { + "type": "Select", + "style": { + "inheritFrom": "default" + }, + "data": "script_is_started", + "left": 240, + "top": 0, + "width": 200, + "height": 32, + "widgets": [ + { + "type": "Rectangle", + "style": { + "inheritFrom": "default", + "color": "status_line_text", + "backgroundColor": "status_line_background", + "activeColor": "status_line_background", + "activeBackgroundColor": "status_line_text" + }, + "left": 0, + "top": 0, + "width": 200, + "height": 32, + "invertColors": true + }, + { + "type": "Container", + "style": { + "inheritFrom": "default" + }, + "left": 0, + "top": 0, + "width": 200, + "height": 32, + "widgets": [ + { + "type": "Text", + "style": { + "inheritFrom": "overlay", + "font": "Heydings14", + "color": "status_line_text", + "backgroundColor": "status_line_background", + "activeColor": "status_line_background", + "activeBackgroundColor": "status_line_text" + }, + "left": 0, + "top": 0, + "width": 32, + "height": 32, + "text": "\\u007d", + "focusStyle": {} + }, + { + "type": "Text", + "style": { + "inheritFrom": "overlay", + "alignHorizontal": "left", + "color": "status_line_text", + "backgroundColor": "status_line_background", + "activeColor": "status_line_background", + "activeBackgroundColor": "status_line_text" + }, + "data": "script_info", + "left": 32, + "top": 0, + "width": 168, + "height": 32, + "text": "", + "focusStyle": {} + } + ] + } + ] } ] } @@ -45096,6 +45233,107 @@ "width": 480, "height": 272 }, + { + "name": "debug_trace_log", + "style": "default", + "widgets": [ + { + "type": "List", + "style": { + "inheritFrom": "default" + }, + "data": "debug_trace_log", + "left": 0, + "top": 0, + "width": 448, + "height": 240, + "itemWidget": { + "type": "Text", + "style": { + "inheritFrom": "default", + "font": "RobotoCondensed-Regular", + "alignHorizontal": "left" + }, + "data": "debug_trace_log_line", + "left": 0, + "top": 0, + "width": 448, + "height": 24, + "text": "", + "focusStyle": {} + }, + "listType": "vertical", + "gap": 0 + }, + { + "type": "ScrollBar", + "style": { + "inheritFrom": "default_inverse" + }, + "data": "debug_trace_log", + "left": 448, + "top": 0, + "width": 32, + "height": 238, + "thumbStyle": { + "inheritFrom": "scrollbar_thumb" + }, + "buttonsStyle": { + "inheritFrom": "scrollbar_button" + }, + "leftButtonText": "\\u0083", + "rightButtonText": "\\u0084" + }, + { + "type": "Container", + "style": { + "inheritFrom": "default" + }, + "left": 0, + "top": 240, + "width": 480, + "height": 32, + "name": "Status line", + "widgets": [ + { + "type": "Text", + "style": { + "inheritFrom": "status_bgnd", + "font": "Heydings14", + "alignVertical": "center", + "color": "status_line_text", + "backgroundColor": "status_line_background", + "activeColor": "status_line_background", + "activeBackgroundColor": "status_line_text" + }, + "action": "show_previous_page", + "left": 0, + "top": 0, + "width": 41, + "height": 32, + "text": "E", + "focusStyle": {} + }, + { + "type": "Text", + "style": { + "inheritFrom": "bottom_button_textual_S_left" + }, + "left": 41, + "top": 0, + "width": 439, + "height": 32, + "text": "Debug trace log", + "focusStyle": {} + } + ] + } + ], + "left": 0, + "top": 0, + "width": 480, + "height": 272 + }, { "name": "file_menu", "description": "Standby menu", @@ -362725,17 +362963,15 @@ }, { "encoding": 34, - "x": 0, + "x": 1, "y": 0, - "width": 19, + "width": 17, "height": 19, "dx": 19, "glyphBitmap": { "height": 19, "pixelArray": [ - 42, - 198, - 251, + 173, 252, 252, 252, @@ -362749,181 +362985,12 @@ 252, 252, 252, - 251, - 198, - 40, - 201, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 200, - 250, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 249, - 175, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 173, - 17, - 143, - 195, - 196, - 196, - 196, - 196, - 196, - 196, - 196, - 196, - 196, - 196, - 196, - 196, - 196, - 195, - 142, - 16, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14, - 134, - 187, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 187, - 134, - 13, - 170, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 167, - 249, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, - 255, + 252, + 252, + 152, 255, 255, 255, - 249, - 205, 255, 255, 255, @@ -362937,13 +363004,43 @@ 255, 255, 255, + 236, 255, + 155, + 104, + 104, + 104, + 104, + 104, + 104, + 104, + 104, + 104, + 104, + 104, + 104, + 104, + 172, + 236, 255, + 98, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 122, + 236, 255, 255, - 204, - 48, - 207, 255, 255, 255, @@ -362958,12 +363055,9 @@ 255, 255, 255, + 236, 255, - 206, - 46, - 0, - 0, - 3, + 79, 4, 4, 4, @@ -362977,58 +363071,93 @@ 4, 4, 4, - 3, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 14, - 134, - 187, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 188, - 187, - 134, - 13, - 170, - 255, + 107, + 236, 255, 255, + 252, + 252, + 252, + 252, + 252, + 252, + 252, + 252, + 252, + 252, + 252, + 252, + 252, 255, + 236, 255, + 79, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 4, + 107, + 236, 255, 255, + 252, + 252, + 252, + 252, + 252, + 252, + 252, + 252, + 252, + 252, + 252, + 252, + 252, 255, + 236, 255, + 111, + 44, + 44, + 44, + 44, + 44, + 44, + 44, + 44, + 44, + 44, + 44, + 44, + 44, + 133, + 236, 255, + 101, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 36, + 125, + 236, 255, 255, 255, @@ -363036,8 +363165,6 @@ 255, 255, 255, - 167, - 249, 255, 255, 255, @@ -363047,19 +363174,75 @@ 255, 255, 255, + 236, 255, + 75, + 3, + 3, + 3, + 3, + 2, + 2, + 2, + 2, + 1, + 1, + 1, + 1, + 0, + 0, + 0, 255, + 248, + 236, + 236, + 236, + 236, + 236, + 236, + 236, + 111, + 0, + 240, + 240, + 240, + 240, + 240, + 186, 255, + 120, + 68, + 68, + 68, + 68, + 68, + 68, + 68, + 32, + 0, 255, 255, 255, 255, + 221, + 29, 255, - 249, - 205, + 179, + 140, + 140, + 140, + 140, + 140, + 140, + 140, + 66, + 0, 255, 255, 255, + 221, + 29, + 0, 255, 255, 255, @@ -363069,21 +363252,32 @@ 255, 255, 255, + 120, + 0, 255, 255, + 222, + 30, + 0, + 0, 255, 255, 255, - 204, - 48, - 204, 255, 255, 255, 255, 255, 255, + 120, + 0, 255, + 223, + 31, + 0, + 0, + 0, + 177, 255, 255, 255, @@ -363092,15 +363286,21 @@ 255, 255, 255, - 203, - 46 + 120, + 0, + 215, + 32, + 0, + 0, + 0, + 0 ], - "width": 19 + "width": 17 }, "source": { "filePath": "fonts\\webhostinghub-glyphs.ttf", "size": 14, - "encoding": 61735 + "encoding": 61633 } }, { diff --git a/scripts/diode-tester-fast.py b/scripts/diode-tester-fast.py new file mode 100644 index 000000000..1add6cfc7 --- /dev/null +++ b/scripts/diode-tester-fast.py @@ -0,0 +1,62 @@ +from utime import ticks_ms, ticks_add, ticks_diff, sleep_ms +from eez import scpi, setU, getOutputMode, getI, dlogTraceData + +U_STEP = 0.1 +U_MAX = 40.0 +TIME_STEP_MS = 4 +MEASURE_DELAY_MS = 2 +I_SET = 4.0 +TRACE_FILE = "/diode-tester.dlog" + +try: + scpi("OUTP 0") + scpi("INST ch1") + I_MAX = float(scpi("CURR? MAX")) + scpi("VOLT 0") + scpi("CURR " + str(I_SET)) + + scpi("SENS:DLOG:TRAC:X:UNIT VOLT") + scpi("SENS:DLOG:TRAC:X:STEP " + str(U_STEP)) + scpi("SENS:DLOG:TRAC:X:RANG:MAX " + str(U_MAX)) + scpi("SENS:DLOG:TRAC:Y1:UNIT AMPER") + scpi("SENS:DLOG:TRAC:Y1:RANG:MAX " + str(I_MAX)) + + # FILE_NAME_MAX_CHARS = 20 + # fileName = scpi('query text, "Diode model", ' % FILE_NAME_MAX_CHARS) + + scpi("INIT:DLOG:TRACE \"" + TRACE_FILE + "\""); + + scpi("OUTP 1") + + scpi("DISP:WINDOW:DLOG") + + ch = 1 + + t = ticks_ms() + i = 0 + while True: + u_set = i * U_STEP + if u_set > U_MAX: + break + + setU(ch, u_set) + + t = ticks_add(t, MEASURE_DELAY_MS) + sleep_ms(ticks_diff(t, ticks_ms())) + + mode = getOutputMode(ch) + #if mode.startswith("CC"): + # break + + curr = getI(ch) + dlogTraceData(curr) + + i = i + 1 + + t = ticks_add(t, TIME_STEP_MS - MEASURE_DELAY_MS) + sleep_ms(ticks_diff(t, ticks_ms())) + + print(i, u_set, curr, mode) +finally: + scpi("ABOR:DLOG") + scpi("OUTP 0") diff --git a/scripts/diode-tester.py b/scripts/diode-tester.py index be71360db..1362e2d76 100644 --- a/scripts/diode-tester.py +++ b/scripts/diode-tester.py @@ -1,60 +1,57 @@ -#import ustruct -#from utime import ticks_ms, sleep_ms -from eez import scpi #, dlog +from utime import ticks_ms, ticks_add, ticks_diff, sleep_ms +from eez import scpi U_STEP = 0.1 U_MAX = 40.0 -#TIME_STEP_MS = 10 -#MEASURE_DELAY_MS = 5 +TIME_STEP_MS = 4 +MEASURE_DELAY_MS = 2 I_SET = 4.0 TRACE_FILE = "/diode-tester.dlog" -scpi("INST ch1") -I_MAX = float(scpi("CURR? MAX")) -scpi("VOLT 0") -scpi("CURR " + str(I_SET)) +try: + scpi("OUTP 0") + scpi("INST ch1") + I_MAX = float(scpi("CURR? MAX")) + scpi("VOLT 0") + scpi("CURR " + str(I_SET)) -scpi("SENS:DLOG:TRAC:X:UNIT VOLT") -scpi("SENS:DLOG:TRAC:X:STEP " + str(U_STEP)) -scpi("RANG:MAX " + str(U_MAX)) -scpi("SENS:DLOG:TRAC:Y1:UNIT AMPER") -scpi("SENS:DLOG:TRAC:Y1:RANG:MAX " + str(I_MAX)) + scpi("SENS:DLOG:TRAC:X:UNIT VOLT") + scpi("SENS:DLOG:TRAC:X:STEP " + str(U_STEP)) + scpi("SENS:DLOG:TRAC:X:RANG:MAX " + str(U_MAX)) + scpi("SENS:DLOG:TRAC:Y1:UNIT AMPER") + scpi("SENS:DLOG:TRAC:Y1:RANG:MAX " + str(I_MAX)) -# FILE_NAME_MAX_CHARS = 20 -# fileName = scpi('query text, "Diode model", ' % FILE_NAME_MAX_CHARS) + # FILE_NAME_MAX_CHARS = 20 + # fileName = scpi('query text, "Diode model", ' % FILE_NAME_MAX_CHARS) -scpi("INIT:DLOG:TRACE \"" + TRACE_FILE + "\""); + scpi("INIT:DLOG:TRACE \"" + TRACE_FILE + "\""); -scpi("OUTP 1") + scpi("OUTP 1") -scpi("DISP:WINDOW:DLOG") + scpi("DISP:WINDOW:DLOG") -#t = ticks_ms() -i = 0 -while True: - u_set = i * U_STEP - if u_set > U_MAX: - break + t = ticks_ms() + i = 0 + while True: + u_set = i * U_STEP + if u_set > U_MAX: + break - scpi("VOLT " + str(u_set)) + scpi("VOLT " + str(u_set)) - #t = ticks_add(t, MEASURE_DELAY_MS) - #sleep_ms(ticks_diff(t, ticks_ms())) + t = ticks_add(t, MEASURE_DELAY_MS) + sleep_ms(ticks_diff(t, ticks_ms())) - mode = scpi("OUTP:MODE?") - #if mode.startswith("CC"): - # break + mode = scpi("OUTP:MODE?") + #if mode.startswith("CC"): + # break - scpi("DLOG:TRACE:DATA " + scpi("MEAS:CURR?")) + scpi("DLOG:TRACE:DATA " + scpi("MEAS:CURR?")) - #print(u_set) - #print(curr) - #print(mode) + i = i + 1 - i = i + 1 - - #t = ticks_add(t, (TIME_STEP_MS - MEASURE_DELAY_MS) * 1000) - #sleep_ms(ticks_diff(t, ticks_ms())) - -scpi("ABOR:DLOG") -scpi("OUTP 0") + t = ticks_add(t, TIME_STEP_MS - MEASURE_DELAY_MS) + sleep_ms(ticks_diff(t, ticks_ms())) +finally: + scpi("ABOR:DLOG") + scpi("OUTP 0") diff --git a/scripts/test.py b/scripts/test.py index 11f998aee..6fe83bac1 100644 --- a/scripts/test.py +++ b/scripts/test.py @@ -3,3 +3,7 @@ print(ustruct.pack('hhl', 1, 2, 3)) print(utime.ticks_ms()) +print("sleep begin") +utime.sleep_ms(10000) +print("sleep end") +print(utime.ticks_ms()) diff --git a/src/eez/debug.cpp b/src/eez/debug.cpp index f4b114833..617c3516a 100644 --- a/src/eez/debug.cpp +++ b/src/eez/debug.cpp @@ -18,12 +18,13 @@ #ifdef DEBUG -#include - #include #include #include +#include +#include + // TODO these includes should not be inside apps/psu #include @@ -37,17 +38,145 @@ using namespace eez::psu; namespace eez { namespace debug { +static char *g_log = (char *)DEBUG_TRACE_LOG; +static uint32_t g_head; +static uint32_t g_tail; +static bool g_full; + +static uint32_t g_numLines; +static uint32_t g_changed; + +static uint32_t g_lastLineIndex; +static uint32_t g_lastLineCharPosition; + +static uint32_t g_startPosition = 0; +static const uint32_t TRACE_LOG_PAGE_SIZE = 10; + +void addCharToLog(char ch) { + *(g_log + g_head) = ch; + + // advance pointer + if (g_full) { + g_tail = (g_tail + 1) % DEBUG_TRACE_LOG_SIZE; + } + g_head = (g_head + 1) % DEBUG_TRACE_LOG_SIZE; + g_full = g_head == g_tail; +} + void Trace(const char *format, ...) { va_list args; va_start(args, format); - //vprintf(format, args); - char buffer[896]; vsnprintf(buffer, 896, format, args); - Serial.write(buffer, strlen(buffer)); va_end(args); + + for (char *p = buffer; *p; p++) { + if (*p == '\r') { + continue; + } + if (*p == '\n') { + addCharToLog(0); + } else if (*p == '\t') { + static const int TAB_SIZE = 4; + for (int i = 0; i < TAB_SIZE; i++) { + addCharToLog(' '); + } + } else { + addCharToLog(*p); + } + } + + g_changed = true; + + g_lastLineIndex = 0; + g_lastLineCharPosition = g_tail; +} + +uint32_t getNumTraceLogLines() { + if (g_changed) { + g_changed = false; + g_numLines = 1; + uint32_t from = g_tail; + uint32_t to = g_head > 0 ? g_head - 1 : DEBUG_TRACE_LOG_SIZE - 1; + for (uint32_t i = from; i != to; i = (i + 1) % DEBUG_TRACE_LOG_SIZE) { + if (!g_log[i]) { + g_numLines++; + } + } + } + return g_numLines; +} + +const char *getTraceLogLine(uint32_t lineIndex) { + if (lineIndex > g_lastLineIndex) { + do { + if (g_log[g_lastLineCharPosition] == 0) { + g_lastLineIndex++; + } + + g_lastLineCharPosition = (g_lastLineCharPosition + 1) % DEBUG_TRACE_LOG_SIZE; + } while (g_lastLineIndex != lineIndex); + } else if (lineIndex < g_lastLineIndex) { + if (lineIndex == 0) { + g_lastLineIndex = 0; + g_lastLineCharPosition = g_tail; + } else { + g_lastLineCharPosition = (g_lastLineCharPosition + DEBUG_TRACE_LOG_SIZE - 2) % DEBUG_TRACE_LOG_SIZE; + + do { + if (g_log[g_lastLineCharPosition] == 0) { + g_lastLineIndex--; + } + + g_lastLineCharPosition = (g_lastLineCharPosition + DEBUG_TRACE_LOG_SIZE - 1) % DEBUG_TRACE_LOG_SIZE; + } while (g_lastLineIndex != lineIndex); + + g_lastLineCharPosition = (g_lastLineCharPosition + 2) % DEBUG_TRACE_LOG_SIZE; + } + } + + return g_log + g_lastLineCharPosition; +} + +uint32_t getTraceLogStartPosition() { + uint32_t position = g_startPosition; + uint32_t count = eez::debug::getNumTraceLogLines(); + if (count <= TRACE_LOG_PAGE_SIZE) { + position = 0; + } else if (position > count - TRACE_LOG_PAGE_SIZE) { + position = count - TRACE_LOG_PAGE_SIZE; + } + return position; +} + +void setTraceLogStartPosition(uint32_t position) { + g_startPosition = position; +} + +void resetTraceLogStartPosition() { + uint32_t count = eez::debug::getNumTraceLogLines(); + if (count <= TRACE_LOG_PAGE_SIZE) { + g_startPosition = 0; + } else { + g_startPosition = count - TRACE_LOG_PAGE_SIZE; + } +} + +uint32_t getTraceLogPageSize() { + return TRACE_LOG_PAGE_SIZE; +} + +void onEncoder(int counter) { +#if defined(EEZ_PLATFORM_SIMULATOR) + counter = -counter; +#endif + int32_t newPosition = getTraceLogStartPosition() + counter; + if (newPosition < 0) { + newPosition = 0; + } + setTraceLogStartPosition(newPosition); } //////////////////////////////////////////////////////////////////////////////// diff --git a/src/eez/debug.h b/src/eez/debug.h index 33c906707..25ea666d5 100644 --- a/src/eez/debug.h +++ b/src/eez/debug.h @@ -27,6 +27,17 @@ namespace debug { void Trace(const char *format, ...); +uint32_t getNumTraceLogLines(); +const char *getTraceLogLine(uint32_t lineIndex); + +uint32_t getTraceLogStartPosition(); +void setTraceLogStartPosition(uint32_t position); +void resetTraceLogStartPosition(); + +uint32_t getTraceLogPageSize(); + +void onEncoder(int couter); + } // namespace debug } // namespace eez diff --git a/src/eez/gui/action_impl.cpp b/src/eez/gui/action_impl.cpp index 36045f081..c177fff5f 100644 --- a/src/eez/gui/action_impl.cpp +++ b/src/eez/gui/action_impl.cpp @@ -1244,6 +1244,11 @@ void action_file_manager_sort_by() { #endif } +void action_show_debug_trace_log() { + eez::debug::resetTraceLogStartPosition(); + pushPage(PAGE_ID_DEBUG_TRACE_LOG); +} + } // namespace gui } // namespace eez diff --git a/src/eez/gui/app_context.cpp b/src/eez/gui/app_context.cpp index 519cdccd6..90fb03ec4 100644 --- a/src/eez/gui/app_context.cpp +++ b/src/eez/gui/app_context.cpp @@ -67,7 +67,7 @@ void AppContext::stateManagment() { } m_nextIterOperation = NEXT_ITER_OPERATION_NONE; } else if (m_nextIterOperation == NEXT_ITER_OPERATION_PUSH) { - pushPage(m_pageIdToSetOnNextIter); + pushPage(m_pageIdToSetOnNextIter, m_pageToSetOnNextIter); m_nextIterOperation = NEXT_ITER_OPERATION_NONE; } @@ -209,15 +209,19 @@ void AppContext::replacePage(int pageId, Page *page) { } void AppContext::pushPage(int pageId, Page *page) { - int previousPageId = getActivePageId(); + if (osThreadGetId() != g_guiTaskHandle) { + pushPageOnNextIter(pageId, page); + } else { + int previousPageId = getActivePageId(); - // advance stack pointre - if (getActivePageId() != INTERNAL_PAGE_ID_NONE) { - m_pageNavigationStackPointer++; - assert (m_pageNavigationStackPointer < CONF_GUI_PAGE_NAVIGATION_STACK_SIZE); - } + // advance stack pointre + if (getActivePageId() != INTERNAL_PAGE_ID_NONE) { + m_pageNavigationStackPointer++; + assert (m_pageNavigationStackPointer < CONF_GUI_PAGE_NAVIGATION_STACK_SIZE); + } - doShowPage(pageId, page, previousPageId); + doShowPage(pageId, page, previousPageId); + } } void AppContext::popPage() { @@ -258,14 +262,16 @@ void AppContext::showPage(int pageId) { } } -void AppContext::showPageOnNextIter(int pageId) { +void AppContext::showPageOnNextIter(int pageId, Page *page) { m_nextIterOperation = NEXT_ITER_OPERATION_SET; m_pageIdToSetOnNextIter = pageId; + m_pageToSetOnNextIter = page; } -void AppContext::pushPageOnNextIter(int pageId) { +void AppContext::pushPageOnNextIter(int pageId, Page *page) { m_nextIterOperation = NEXT_ITER_OPERATION_PUSH; m_pageIdToSetOnNextIter = pageId; + m_pageToSetOnNextIter = page; } void AppContext::pushSelectFromEnumPage(const data::EnumItem *enumDefinition, uint16_t currentValue, diff --git a/src/eez/gui/app_context.h b/src/eez/gui/app_context.h index af48b9c54..e0dc058eb 100644 --- a/src/eez/gui/app_context.h +++ b/src/eez/gui/app_context.h @@ -61,13 +61,14 @@ class AppContext { void (*m_dialogLaterCallback)(); void(*m_toastAction)(int param); int m_toastActionParam; + void(*m_toastActionWithoutParam)(); void (*m_checkAsyncOperationStatus)(); virtual void stateManagment(); void showPage(int pageId); - void showPageOnNextIter(int pageId); - void pushPageOnNextIter(int pageId); + void showPageOnNextIter(int pageId, Page *page = nullptr); + void pushPageOnNextIter(int pageId, Page *page = nullptr); void pushPage(int pageId, Page *page = 0); void popPage(); @@ -127,6 +128,7 @@ class AppContext { NextIterOperation m_nextIterOperation; int m_pageIdToSetOnNextIter; + Page *m_pageToSetOnNextIter; SelectFromEnumPage m_selectFromEnumPage; diff --git a/src/eez/gui/data.cpp b/src/eez/gui/data.cpp index ea925de2b..23aa2ab14 100644 --- a/src/eez/gui/data.cpp +++ b/src/eez/gui/data.cpp @@ -34,6 +34,7 @@ #include #include #include +#include // TODO #include @@ -295,6 +296,26 @@ void YT_DATA_GET_VALUE_FUNCTION_POINTER_value_to_text(const Value &value, char * text[0] = 0; } +bool compare_DEBUG_TRACE_LOG_STR_value(const Value &a, const Value &b) { + return strcmp(a.getString(), b.getString()) == 0; +} + +void DEBUG_TRACE_LOG_STR_value_to_text(const Value &value, char *text, int count) { + const char *p = value.getString(); + + while (--count) { + *text++ = *p; + if (*p == 0) { + break; + } + if (++p == (const char *)DEBUG_TRACE_LOG + DEBUG_TRACE_LOG_SIZE) { + p = (const char *)DEBUG_TRACE_LOG; + } + } + + *text = 0; +} + //////////////////////////////////////////////////////////////////////////////// static CompareValueFunction g_compareBuiltInValueFunctions[] = { @@ -315,7 +336,8 @@ static CompareValueFunction g_compareBuiltInValueFunctions[] = { compare_SLOT_INFO2_value, compare_TEST_RESULT_value, compare_TIME_SECONDS_value, - compare_YT_DATA_GET_VALUE_FUNCTION_POINTER_value + compare_YT_DATA_GET_VALUE_FUNCTION_POINTER_value, + compare_DEBUG_TRACE_LOG_STR_value }; static ValueToTextFunction g_builtInValueToTextFunctions[] = { @@ -337,7 +359,8 @@ static ValueToTextFunction g_builtInValueToTextFunctions[] = { SLOT_INFO2_value_to_text, TEST_RESULT_value_to_text, TIME_SECONDS_value_to_text, - YT_DATA_GET_VALUE_FUNCTION_POINTER_value_to_text + YT_DATA_GET_VALUE_FUNCTION_POINTER_value_to_text, + DEBUG_TRACE_LOG_STR_value_to_text }; //////////////////////////////////////////////////////////////////////////////// diff --git a/src/eez/gui/data.h b/src/eez/gui/data.h index 4c9c21ca9..9d89acc9c 100644 --- a/src/eez/gui/data.h +++ b/src/eez/gui/data.h @@ -45,6 +45,7 @@ enum BuiltInValueType { VALUE_TYPE_TEST_RESULT, VALUE_TYPE_TIME_SECONDS, VALUE_TYPE_YT_DATA_GET_VALUE_FUNCTION_POINTER, + VALUE_TYPE_DEBUG_TRACE_LOG_STR, VALUE_TYPE_USER, }; @@ -101,7 +102,12 @@ struct Value { { } - Value(int value, ValueType type) + Value(const char *str, ValueType type) + : type_(type), options_(0), unit_(UNIT_UNKNOWN), str_(str) + { + } + + Value(int value, ValueType type) : type_(type), options_(0), unit_(UNIT_UNKNOWN), int_(value) { } diff --git a/src/eez/gui/dialogs.cpp b/src/eez/gui/dialogs.cpp index 3f930e334..189478964 100644 --- a/src/eez/gui/dialogs.cpp +++ b/src/eez/gui/dialogs.cpp @@ -100,6 +100,11 @@ void errorMessageWithAction(data::Value value, void (*action)(int param), const sound::playBeep(); } +void errorMessageWithAction(const char *message, void (*action)(), const char *actionLabel) { + pushToastMessage(ToastMessagePage::create(ERROR_TOAST, message, action, actionLabel)); + sound::playBeep(); +} + //////////////////////////////////////////////////////////////////////////////// void yesNoDialog(int yesNoPageId, const char *message, void (*yes_callback)(), diff --git a/src/eez/gui/dialogs.h b/src/eez/gui/dialogs.h index f677e8e2e..07cd45dde 100644 --- a/src/eez/gui/dialogs.h +++ b/src/eez/gui/dialogs.h @@ -41,6 +41,7 @@ void errorMessage(const char *message1, const char *message2); void errorMessage(const char *message1, const char *message2, const char *message3); void errorMessage(data::Value value); void errorMessageWithAction(data::Value value, void (*action)(int param), const char *actionLabel, int actionParam); +void errorMessageWithAction(const char *message, void (*action)(), const char *actionLabel); void yesNoDialog(int yesNoPageId, const char *message, void (*yes_callback)(), void (*no_callback)(), void (*cancel_callback)()); diff --git a/src/eez/gui/gui.cpp b/src/eez/gui/gui.cpp index 9624b2a36..5b5edc841 100644 --- a/src/eez/gui/gui.cpp +++ b/src/eez/gui/gui.cpp @@ -207,7 +207,8 @@ static ActionExecFunc g_internalActionExecFunctions[] = { 0, action_internal_select_enum_item, popPage, - ToastMessagePage::executeAction + ToastMessagePage::executeAction, + ToastMessagePage::executeActionWithoutParam }; bool isInternalAction(int actionId) { diff --git a/src/eez/gui/gui.h b/src/eez/gui/gui.h index d519a7cbf..dea1d2a6f 100644 --- a/src/eez/gui/gui.h +++ b/src/eez/gui/gui.h @@ -32,7 +32,8 @@ enum InternalActionsEnum { ACTION_ID_INTERNAL_SELECT_ENUM_ITEM = -1, ACTION_ID_INTERNAL_DIALOG_CLOSE = -2, - ACTION_ID_INTERNAL_TOAST_ACTION = -3 + ACTION_ID_INTERNAL_TOAST_ACTION = -3, + ACTION_ID_INTERNAL_TOAST_ACTION_WITHOUT_PARAM = -4 }; namespace eez { diff --git a/src/eez/gui/page.cpp b/src/eez/gui/page.cpp index 2b2637e38..ea65bedbb 100644 --- a/src/eez/gui/page.cpp +++ b/src/eez/gui/page.cpp @@ -172,6 +172,22 @@ ToastMessagePage *ToastMessagePage::create(ToastType type, data::Value message1V return page; } +ToastMessagePage *ToastMessagePage::create(ToastType type, const char *message, void (*action)(), const char *actionLabel) { + ToastMessagePage *page = ToastMessagePage::findFreePage(); + + page->type = type; + page->message1 = message; + page->message2 = actionLabel; + page->message3 = nullptr; + page->actionWidgetIsActive = false; + + page->actionWidget.action = ACTION_ID_INTERNAL_TOAST_ACTION_WITHOUT_PARAM; + page->appContext = g_appContext; + page->appContext->m_toastActionWithoutParam = action; + + return page; +} + bool ToastMessagePage::onEncoder(int counter) { popPage(); return false; @@ -314,6 +330,11 @@ void ToastMessagePage::executeAction() { g_appContext->m_toastAction(g_appContext->m_toastActionParam); } +void ToastMessagePage::executeActionWithoutParam() { + popPage(); + g_appContext->m_toastActionWithoutParam(); +} + //////////////////////////////////////////////////////////////////////////////// void SelectFromEnumPage::init(const data::EnumItem *enumDefinition_, uint16_t currentValue_, diff --git a/src/eez/gui/page.h b/src/eez/gui/page.h index ca4f9710a..68309ddb0 100644 --- a/src/eez/gui/page.h +++ b/src/eez/gui/page.h @@ -82,6 +82,7 @@ class ToastMessagePage : public InternalPage { static ToastMessagePage *create(ToastType type, const char *message1, const char *message2); static ToastMessagePage *create(ToastType type, const char *message1, const char *message2, const char *message3); static ToastMessagePage *create(ToastType type, data::Value message1Value, void (*action)(int param), const char *actionLabel, int actionParam); + static ToastMessagePage *create(ToastType type, const char *message, void (*action)(), const char *actionLabel); void pageFree(); @@ -93,6 +94,7 @@ class ToastMessagePage : public InternalPage { WidgetCursor findWidget(int x, int y); static void executeAction(); + static void executeActionWithoutParam(); private: ToastType type; diff --git a/src/eez/memory.h b/src/eez/memory.h index 8a54f6581..20d297424 100644 --- a/src/eez/memory.h +++ b/src/eez/memory.h @@ -57,7 +57,10 @@ static const uint32_t FILE_MANAGER_MEMORY_SIZE = 256 * 1024; static uint8_t * const VRAM_SCREENSHOOT_JPEG_OUT_BUFFER = FILE_MANAGER_MEMORY + FILE_MANAGER_MEMORY_SIZE; static const uint32_t VRAM_SCREENSHOOT_JPEG_OUT_BUFFER_SIZE = 256 * 1024; -static uint8_t * const SCREENSHOOT_BUFFER_START_ADDRESS = VRAM_SCREENSHOOT_JPEG_OUT_BUFFER + VRAM_SCREENSHOOT_JPEG_OUT_BUFFER_SIZE; +static uint8_t * const DEBUG_TRACE_LOG = FILE_MANAGER_MEMORY + FILE_MANAGER_MEMORY_SIZE; +static const uint32_t DEBUG_TRACE_LOG_SIZE = 32 * 1024; + +static uint8_t * const SCREENSHOOT_BUFFER_START_ADDRESS = DEBUG_TRACE_LOG + DEBUG_TRACE_LOG_SIZE; static const uint32_t SCREENSHOOT_BUFFER_SIZE = 480 * 272 * 3; #if defined(EEZ_PLATFORM_STM32) diff --git a/src/eez/modules/psu/channel.cpp b/src/eez/modules/psu/channel.cpp index b5a5eed98..b108af632 100644 --- a/src/eez/modules/psu/channel.cpp +++ b/src/eez/modules/psu/channel.cpp @@ -464,7 +464,7 @@ void Channel::protectionCheck(ProtectionValue &cpv) { delay -= PROT_DELAY_CORRECTION; } else if (IS_OCP_VALUE(this, cpv)) { state = prot_conf.flags.i_state; - condition = channel_dispatcher::getIMon(*this) >= channel_dispatcher::getISet(*this); + condition = channel_dispatcher::getIMonLast(*this) >= channel_dispatcher::getISet(*this); delay = prot_conf.i_delay; delay -= PROT_DELAY_CORRECTION; } else { @@ -1275,7 +1275,7 @@ void Channel::setOperBits(int bit_mask, bool on) { reg_set_oper_isum_bit(channelIndex, bit_mask, on); } -const char *Channel::getCvModeStr() const { +const char *Channel::getModeStr() const { if (isCvMode()) return "CV"; else if (isCcMode()) diff --git a/src/eez/modules/psu/channel.h b/src/eez/modules/psu/channel.h index 7ae2db18e..ca4270c84 100644 --- a/src/eez/modules/psu/channel.h +++ b/src/eez/modules/psu/channel.h @@ -441,7 +441,7 @@ class Channel { } /// Returns "CC", "CV" or "UR" - const char *getCvModeStr() const; + const char *getModeStr() const; /// Returns currently set voltage limit float getVoltageLimit() const; diff --git a/src/eez/modules/psu/channel_dispatcher.cpp b/src/eez/modules/psu/channel_dispatcher.cpp index 728626cdc..26b98b474 100644 --- a/src/eez/modules/psu/channel_dispatcher.cpp +++ b/src/eez/modules/psu/channel_dispatcher.cpp @@ -365,7 +365,7 @@ ChannelSnapshot &getChannelSnapshot(int channelIndex) { for (int i = 0; i < CH_NUM; i++) { Channel &channel = Channel::get(i); ChannelSnapshot &channelSnapshot = g_channelSnapshots[i]; - const char *mode_str = channel.getCvModeStr(); + const char *mode_str = channel.getModeStr(); channelSnapshot.uMon = channel_dispatcher::getUMon(channel); channelSnapshot.iMon = channel_dispatcher::getIMon(channel); if (strcmp(mode_str, "CC") == 0) { diff --git a/src/eez/modules/psu/dlog_record.cpp b/src/eez/modules/psu/dlog_record.cpp index a1ee758a1..08cb2f7b6 100644 --- a/src/eez/modules/psu/dlog_record.cpp +++ b/src/eez/modules/psu/dlog_record.cpp @@ -254,8 +254,8 @@ State getState() { return g_state; } -int checkDlogParameters(dlog_view::Parameters ¶meters, bool doNotCheckFilePath) { - if (g_traceInitiated) { +int checkDlogParameters(dlog_view::Parameters ¶meters, bool doNotCheckFilePath, bool forTraceUsage) { + if (forTraceUsage) { if (parameters.xAxis.step <= 0) { // TODO replace with more specific error return SCPI_ERROR_EXECUTION_ERROR; @@ -278,12 +278,12 @@ int checkDlogParameters(dlog_view::Parameters ¶meters, bool doNotCheckFilePa // TODO replace with more specific error return SCPI_ERROR_EXECUTION_ERROR; } + } - if (!doNotCheckFilePath) { - if (!parameters.filePath[0]) { - // TODO replace with more specific error - return SCPI_ERROR_EXECUTION_ERROR; - } + if (!doNotCheckFilePath) { + if (!parameters.filePath[0]) { + // TODO replace with more specific error + return SCPI_ERROR_EXECUTION_ERROR; } } @@ -302,13 +302,17 @@ bool isExecuting() { return g_state == STATE_EXECUTING; } +bool isTraceExecuting() { + return g_state == STATE_EXECUTING && g_traceInitiated; +} + static int doInitiate() { int error = SCPI_RES_OK; if (g_parameters.triggerSource == trigger::SOURCE_IMMEDIATE) { error = startImmediately(); } else { - error = checkDlogParameters(g_parameters); + error = checkDlogParameters(g_parameters, false, g_traceInitiated); if (error == SCPI_RES_OK) { setState(STATE_INITIATED); } @@ -342,7 +346,7 @@ void log(uint32_t tickCount); int startImmediately() { int err; - err = checkDlogParameters(g_parameters); + err = checkDlogParameters(g_parameters, false, g_traceInitiated); if (err != SCPI_RES_OK) { return err; } diff --git a/src/eez/modules/psu/dlog_record.h b/src/eez/modules/psu/dlog_record.h index d3529d38f..13ed0a9e0 100644 --- a/src/eez/modules/psu/dlog_record.h +++ b/src/eez/modules/psu/dlog_record.h @@ -51,10 +51,11 @@ extern dlog_view::Parameters g_guiParameters; extern dlog_view::Recording g_recording; State getState(); -int checkDlogParameters(dlog_view::Parameters ¶meters, bool doNotCheckFilePath = false); +int checkDlogParameters(dlog_view::Parameters ¶meters, bool doNotCheckFilePath, bool forTraceUsage); bool isIdle(); bool isInitiated(); bool isExecuting(); +bool isTraceExecuting(); int initiate(); int initiateTrace(); int startImmediately(); diff --git a/src/eez/modules/psu/dlog_view.cpp b/src/eez/modules/psu/dlog_view.cpp index 7da766c1b..3d74cb07e 100644 --- a/src/eez/modules/psu/dlog_view.cpp +++ b/src/eez/modules/psu/dlog_view.cpp @@ -398,7 +398,11 @@ void initDlogValues(Recording &recording) { dlogValueIndex++; } - } + } + + for (; dlogValueIndex < MAX_NUM_OF_Y_VALUES; dlogValueIndex++) { + recording.dlogValues[dlogValueIndex].isVisible = false; + } } int getNumVisibleDlogValues(const Recording &recording) { diff --git a/src/eez/modules/psu/gui/data.cpp b/src/eez/modules/psu/gui/data.cpp index 03ae0d5d9..ee1728071 100644 --- a/src/eez/modules/psu/gui/data.cpp +++ b/src/eez/modules/psu/gui/data.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #if OPTION_ENCODER #include #endif @@ -4211,8 +4212,8 @@ void data_overlay(data::DataOperationEnum operation, data::Cursor &cursor, data: static const int LIST_ICON_WIDGET = 0; static const int LIST_GRID_WIDGET = 1; - static const int DLOG_ICON_WIDGET = 2; - static const int DLOG_STATUS_WIDGET = 3; + static const int DLOG_INFO_WIDGET = 2; + static const int SCRIPT_INFO_WIDGET = 3; static Overlay overlay; static WidgetOverride widgetOverrides[NUM_WIDGETS]; @@ -4224,9 +4225,10 @@ void data_overlay(data::DataOperationEnum operation, data::Cursor &cursor, data: bool areListCountersVisible = list::g_numChannelsWithVisibleCounters > 0; bool isDlogVisible = !dlog_record::isIdle(); + bool isScriptVisible = !mp::isIdle(); int state = 0; - if (areListCountersVisible || isDlogVisible) { + if (areListCountersVisible || isDlogVisible || isScriptVisible) { if (list::g_numChannelsWithVisibleCounters > 0) { if (list::g_numChannelsWithVisibleCounters > 4) { state = 1; @@ -4238,8 +4240,13 @@ void data_overlay(data::DataOperationEnum operation, data::Cursor &cursor, data: state = 4; } } + if (isDlogVisible) { - state += 5; + state |= 0x8000; + } + + if (isScriptVisible) { + state |= 0x4000; } } @@ -4252,8 +4259,8 @@ void data_overlay(data::DataOperationEnum operation, data::Cursor &cursor, data: const Widget *listIconWidget = GET_WIDGET_LIST_ELEMENT(containerWidget->widgets, LIST_ICON_WIDGET); const Widget *listGridWidget = GET_WIDGET_LIST_ELEMENT(containerWidget->widgets, LIST_GRID_WIDGET); - const Widget *dlogIconWidget = GET_WIDGET_LIST_ELEMENT(containerWidget->widgets, DLOG_ICON_WIDGET); - const Widget *dlogStatusWidget = GET_WIDGET_LIST_ELEMENT(containerWidget->widgets, DLOG_STATUS_WIDGET); + const Widget *dlogInfoWidget = GET_WIDGET_LIST_ELEMENT(containerWidget->widgets, DLOG_INFO_WIDGET); + const Widget *scriptInfoWidget = GET_WIDGET_LIST_ELEMENT(containerWidget->widgets, SCRIPT_INFO_WIDGET); overlay.width = widgetCursor.widget->w; overlay.height = widgetCursor.widget->h; @@ -4278,7 +4285,7 @@ void data_overlay(data::DataOperationEnum operation, data::Cursor &cursor, data: overlay.height += listGridWidget->h; } else { widgetOverrides[LIST_GRID_WIDGET].h = listGridWidget->h; - if (list::g_numChannelsWithVisibleCounters == 1 && !isDlogVisible) { + if (list::g_numChannelsWithVisibleCounters == 1 && !isDlogVisible && !isScriptVisible) { widgetOverrides[LIST_GRID_WIDGET].w = listGridWidget->w / 2; overlay.width -= listGridWidget->w / 2; } @@ -4290,26 +4297,29 @@ void data_overlay(data::DataOperationEnum operation, data::Cursor &cursor, data: } if (isDlogVisible) { - widgetOverrides[DLOG_ICON_WIDGET].isVisible = true; - widgetOverrides[DLOG_ICON_WIDGET].x = dlogIconWidget->x; - widgetOverrides[DLOG_ICON_WIDGET].y = overlay.height - (widgetCursor.widget->h - dlogIconWidget->y); - widgetOverrides[DLOG_ICON_WIDGET].w = listIconWidget->w; - widgetOverrides[DLOG_ICON_WIDGET].h = listIconWidget->h; - - widgetOverrides[DLOG_STATUS_WIDGET].isVisible = true; - widgetOverrides[DLOG_STATUS_WIDGET].x = dlogStatusWidget->x; - widgetOverrides[DLOG_STATUS_WIDGET].y = overlay.height - (widgetCursor.widget->h - dlogStatusWidget->y); - widgetOverrides[DLOG_STATUS_WIDGET].w = dlogStatusWidget->w; - widgetOverrides[DLOG_STATUS_WIDGET].h = dlogStatusWidget->h; + widgetOverrides[DLOG_INFO_WIDGET].isVisible = true; + widgetOverrides[DLOG_INFO_WIDGET].x = dlogInfoWidget->x; + widgetOverrides[DLOG_INFO_WIDGET].y = overlay.height - (widgetCursor.widget->h - dlogInfoWidget->y); + widgetOverrides[DLOG_INFO_WIDGET].w = dlogInfoWidget->w; + widgetOverrides[DLOG_INFO_WIDGET].h = dlogInfoWidget->h; } else { - widgetOverrides[DLOG_ICON_WIDGET].isVisible = false; - widgetOverrides[DLOG_STATUS_WIDGET].isVisible = false; - overlay.height -= dlogStatusWidget->h; + widgetOverrides[DLOG_INFO_WIDGET].isVisible = false; + overlay.height -= dlogInfoWidget->h; + } + + if (isScriptVisible) { + widgetOverrides[SCRIPT_INFO_WIDGET].isVisible = true; + widgetOverrides[SCRIPT_INFO_WIDGET].x = scriptInfoWidget->x; + widgetOverrides[SCRIPT_INFO_WIDGET].y = overlay.height - (widgetCursor.widget->h - scriptInfoWidget->y); + widgetOverrides[SCRIPT_INFO_WIDGET].w = scriptInfoWidget->w; + widgetOverrides[SCRIPT_INFO_WIDGET].h = scriptInfoWidget->h; + } else { + widgetOverrides[SCRIPT_INFO_WIDGET].isVisible = false; + overlay.height -= scriptInfoWidget->h; } } } - value = data::Value(&overlay, VALUE_TYPE_POINTER); } } @@ -4460,7 +4470,7 @@ void data_dlog_file_name(data::DataOperationEnum operation, data::Cursor &cursor void data_dlog_start_enabled(data::DataOperationEnum operation, data::Cursor &cursor, data::Value &value) { #if OPTION_SD_CARD if (operation == data::DATA_OPERATION_GET) { - value = dlog_record::checkDlogParameters(dlog_record::g_guiParameters, true) == SCPI_RES_OK ? 1 : 0; + value = dlog_record::checkDlogParameters(dlog_record::g_guiParameters, true, false) == SCPI_RES_OK ? 1 : 0; } #endif } @@ -4589,7 +4599,7 @@ void data_recording(data::DataOperationEnum operation, data::Cursor &cursor, dat dlogValueParams->div = Value(newDiv, dlogValueParams->div.getUnit()); } - } else if (g_focusDataId == DATA_ID_DLOG_TIME_DIV) { + } else if (g_focusDataId == DATA_ID_DLOG_X_AXIS_DIV) { if (touchDrag->type == EVENT_TYPE_TOUCH_DOWN) { valueAtTouchDown = recording.timeDiv; xAtTouchDown = touchDrag->x; @@ -4598,8 +4608,8 @@ void data_recording(data::DataOperationEnum operation, data::Cursor &cursor, dat float newDiv = valueAtTouchDown * scale; - float min = getMin(g_focusCursor, DATA_ID_DLOG_TIME_DIV).getFloat(); - float max = getMax(g_focusCursor, DATA_ID_DLOG_TIME_DIV).getFloat(); + float min = getMin(g_focusCursor, DATA_ID_DLOG_X_AXIS_DIV).getFloat(); + float max = getMax(g_focusCursor, DATA_ID_DLOG_X_AXIS_DIV).getFloat(); newDiv = roundPrec(clamp(newDiv, min, max), dlog_view::TIME_PREC); @@ -4633,16 +4643,14 @@ void data_dlog_overlay(data::DataOperationEnum operation, data::Cursor &cursor, int state = 0; int numVisibleDlogValues = 0; - if (&recording != &dlog_record::g_recording) { - state = numVisibleDlogValues = dlog_view::getNumVisibleDlogValues(recording); + state = numVisibleDlogValues = dlog_view::getNumVisibleDlogValues(recording); - if (dlog_view::g_overlayMinimized) { - state |= 0x80; - } - - state |= 0x100; + if (dlog_view::g_overlayMinimized) { + state |= 0x80; } + state |= 0x100; + if (overlay.state != state) { overlay.state = state; @@ -4765,52 +4773,74 @@ void data_dlog_visible_value_offset(data::DataOperationEnum operation, data::Cur #endif } -void data_dlog_time_offset(data::DataOperationEnum operation, data::Cursor &cursor, data::Value &value) { +void data_dlog_x_axis_offset(data::DataOperationEnum operation, data::Cursor &cursor, data::Value &value) { #if OPTION_SD_CARD dlog_view::Recording &recording = dlog_view::getRecording(); if (operation == data::DATA_OPERATION_GET) { - bool focused = g_focusCursor == cursor && g_focusDataId == DATA_ID_DLOG_TIME_OFFSET; + bool focused = g_focusCursor == cursor && g_focusDataId == DATA_ID_DLOG_X_AXIS_OFFSET; if (focused && g_focusEditValue.getType() != VALUE_TYPE_NONE) { value = g_focusEditValue; } else { - value = Value(recording.timeOffset, UNIT_SECOND); + value = Value(recording.timeOffset, recording.parameters.xAxis.unit); } } else if (operation == data::DATA_OPERATION_GET_MIN) { - value = Value(0.0f, UNIT_SECOND); + value = Value(0.0f, recording.parameters.xAxis.unit); } else if (operation == data::DATA_OPERATION_GET_MAX) { - value = Value(dlog_view::getMaxTimeOffset(recording), UNIT_SECOND); + value = Value(dlog_view::getMaxTimeOffset(recording), recording.parameters.xAxis.unit); } else if (operation == data::DATA_OPERATION_SET) { dlog_view::changeTimeOffset(recording, value.getFloat()); } else if (operation == data::DATA_OPERATION_GET_NAME) { - value = "Time Offset"; + value = "Offset"; } else if (operation == data::DATA_OPERATION_GET_UNIT) { - value = UNIT_SECOND; + value = recording.parameters.xAxis.unit; } #endif } -void data_dlog_time_div(data::DataOperationEnum operation, data::Cursor &cursor, data::Value &value) { +void data_dlog_x_axis_div(data::DataOperationEnum operation, data::Cursor &cursor, data::Value &value) { #if OPTION_SD_CARD dlog_view::Recording &recording = dlog_view::getRecording(); if (operation == data::DATA_OPERATION_GET) { - bool focused = g_focusCursor == cursor && g_focusDataId == DATA_ID_DLOG_TIME_DIV; + bool focused = g_focusCursor == cursor && g_focusDataId == DATA_ID_DLOG_X_AXIS_DIV; if (focused && g_focusEditValue.getType() != VALUE_TYPE_NONE) { value = g_focusEditValue; } else { - value = Value(recording.timeDiv, UNIT_SECOND); + value = Value(recording.timeDiv, recording.parameters.xAxis.unit); } } else if (operation == data::DATA_OPERATION_GET_MIN || operation == data::DATA_OPERATION_GET_DEF) { - value = Value(recording.timeDivMin, UNIT_SECOND); + value = Value(recording.timeDivMin, recording.parameters.xAxis.unit); } else if (operation == data::DATA_OPERATION_GET_MAX) { - value = Value(recording.timeDivMax, UNIT_SECOND); + value = Value(recording.timeDivMax, recording.parameters.xAxis.unit); } else if (operation == data::DATA_OPERATION_SET) { dlog_view::changeTimeDiv(recording, value.getFloat()); } else if (operation == data::DATA_OPERATION_GET_NAME) { - value = "Time Div"; + value = "Div"; } else if (operation == data::DATA_OPERATION_GET_UNIT) { - value = UNIT_SECOND; + value = recording.parameters.xAxis.unit; + } +#endif +} + +void data_dlog_x_axis_range_max(data::DataOperationEnum operation, data::Cursor &cursor, data::Value &value) { +#if OPTION_SD_CARD + if (operation == data::DATA_OPERATION_GET) { + dlog_view::Recording &recording = dlog_view::getRecording(); + value = Value(dlog_view::getDuration(recording), recording.parameters.xAxis.unit); + } +#endif +} + +void data_dlog_x_axis_range_max_label(data::DataOperationEnum operation, data::Cursor &cursor, data::Value &value) { +#if OPTION_SD_CARD + if (operation == data::DATA_OPERATION_GET) { + dlog_view::Recording &recording = dlog_view::getRecording(); + if (recording.parameters.xAxis.unit == UNIT_SECOND) { + value = "Total duration"; + } else { + value = "Max."; + } } #endif } @@ -4847,6 +4877,7 @@ void data_dlog_time_duration(data::DataOperationEnum operation, data::Cursor &cu } #endif } + void data_dlog_file_length(data::DataOperationEnum operation, data::Cursor &cursor, data::Value &value) { #if OPTION_SD_CARD if (operation == data::DATA_OPERATION_GET) { @@ -5013,6 +5044,43 @@ void data_file_manager_opened_image(data::DataOperationEnum operation, data::Cur #endif } +void data_script_is_started(data::DataOperationEnum operation, data::Cursor &cursor, data::Value &value) { + if (operation == data::DATA_OPERATION_GET) { + value = mp::isIdle() ? 0 : 1; + } +} + +void data_script_info(data::DataOperationEnum operation, data::Cursor &cursor, data::Value &value) { + if (operation == data::DATA_OPERATION_GET) { + // get script file name + const char *p = mp::g_scriptPath + strlen(mp::g_scriptPath) - 1; + while (p >= mp::g_scriptPath && *p != '/' && *p != '\\') { + p--; + } + value = p + 1; + } +} + +void data_debug_trace_log(data::DataOperationEnum operation, data::Cursor &cursor, data::Value &value) { + if (operation == data::DATA_OPERATION_COUNT) { + value = (int)eez::debug::getNumTraceLogLines(); + } else if (operation == DATA_OPERATION_YT_DATA_GET_SIZE) { + value = Value(eez::debug::getNumTraceLogLines(), VALUE_TYPE_UINT32); + } else if (operation == DATA_OPERATION_YT_DATA_GET_POSITION) { + value = Value(eez::debug::getTraceLogStartPosition(), VALUE_TYPE_UINT32); + } else if (operation == DATA_OPERATION_YT_DATA_SET_POSITION) { + eez::debug::setTraceLogStartPosition(value.getUInt32()); + } else if (operation == DATA_OPERATION_YT_DATA_GET_PAGE_SIZE) { + value = Value(eez::debug::getTraceLogPageSize(), VALUE_TYPE_UINT32); + } +} + +void data_debug_trace_log_line(data::DataOperationEnum operation, data::Cursor &cursor, data::Value &value) { + if (operation == data::DATA_OPERATION_GET) { + value = Value(eez::debug::getTraceLogLine(cursor.i), VALUE_TYPE_DEBUG_TRACE_LOG_STR); + } +} + } // namespace gui } // namespace eez diff --git a/src/eez/modules/psu/gui/file_manager.cpp b/src/eez/modules/psu/gui/file_manager.cpp index 2ece250fd..a6be7e0d9 100644 --- a/src/eez/modules/psu/gui/file_manager.cpp +++ b/src/eez/modules/psu/gui/file_manager.cpp @@ -296,7 +296,7 @@ bool isOpenFileEnabled() { } if (fileItem->type == FILE_TYPE_MICROPYTHON) { - return true; + return mp::isIdle(); } return false; @@ -426,6 +426,9 @@ void deleteFile() { } void onEncoder(int counter) { +#if defined(EEZ_PLATFORM_SIMULATOR) + counter = -counter; +#endif int32_t newPosition = getFilesStartPosition() + counter; if (newPosition < 0) { newPosition = 0; diff --git a/src/eez/modules/psu/gui/psu.cpp b/src/eez/modules/psu/gui/psu.cpp index 79f1967be..c55a07ecd 100644 --- a/src/eez/modules/psu/gui/psu.cpp +++ b/src/eez/modules/psu/gui/psu.cpp @@ -79,6 +79,14 @@ namespace eez { +namespace mp { + +void onUncaughtScriptExceptionHook() { + eez::psu::gui::g_psuAppContext.showUncaughtScriptExceptionMessage(); +} + +} + namespace gui { #if EEZ_PLATFORM_STM32 @@ -104,6 +112,7 @@ void stateManagmentHook() { } namespace psu { + namespace gui { PsuAppContext g_psuAppContext; @@ -291,8 +300,12 @@ void PsuAppContext::stateManagment() { } } - dlog_view::stateManagment(); + + if (m_showUncaughtScriptExceptionMessage) { + m_showUncaughtScriptExceptionMessage = false; + errorMessageWithAction("Uncaught script exception!", action_show_debug_trace_log, "Show debug trace log"); + } } bool PsuAppContext::isActiveWidget(const WidgetCursor &widgetCursor) { @@ -615,6 +628,10 @@ uint8_t PsuAppContext::getTextMessageVersion() { return g_psuAppContext.m_textMessageVersion; } +void PsuAppContext::showUncaughtScriptExceptionMessage() { + m_showUncaughtScriptExceptionMessage = true; +} + //////////////////////////////////////////////////////////////////////////////// bool isChannelCalibrationsDone() { @@ -1086,6 +1103,11 @@ void onEncoder(int counter, bool clicked) { return; } + if (activePageId == PAGE_ID_DEBUG_TRACE_LOG) { + eez::debug::onEncoder(counter); + return; + } + if (activePage) { if (activePage->onEncoder(counter)) { return; diff --git a/src/eez/modules/psu/gui/psu.h b/src/eez/modules/psu/gui/psu.h index ada1d256a..a04f6dca3 100644 --- a/src/eez/modules/psu/gui/psu.h +++ b/src/eez/modules/psu/gui/psu.h @@ -81,6 +81,8 @@ class PsuAppContext : public AppContext { static const char *getTextMessage(); static uint8_t getTextMessageVersion(); + void showUncaughtScriptExceptionMessage(); + protected: bool m_pushProgressPage; const char *m_progressMessage; @@ -92,6 +94,8 @@ class PsuAppContext : public AppContext { bool m_showTextMessage; bool m_clearTextMessage; + bool m_showUncaughtScriptExceptionMessage; + int getMainPageId() override; void onPageChanged(int previousPageId, int activePageId) override; bool isAutoRepeatAction(int action) override; diff --git a/src/eez/modules/psu/scpi/dlog.cpp b/src/eez/modules/psu/scpi/dlog.cpp index ca4cff63e..d631d8b44 100644 --- a/src/eez/modules/psu/scpi/dlog.cpp +++ b/src/eez/modules/psu/scpi/dlog.cpp @@ -827,7 +827,7 @@ scpi_result_t scpi_cmd_initiateDlogTrace(scpi_t *context) { scpi_result_t scpi_cmd_dlogTraceData(scpi_t *context) { #if OPTION_SD_CARD - if (!dlog_record::isExecuting()) { + if (!dlog_record::isTraceExecuting()) { SCPI_ErrorPush(context, SCPI_ERROR_EXECUTION_ERROR); return SCPI_RES_ERR; } diff --git a/src/eez/modules/psu/scpi/meas.cpp b/src/eez/modules/psu/scpi/meas.cpp index 9e0002878..3a6287de1 100644 --- a/src/eez/modules/psu/scpi/meas.cpp +++ b/src/eez/modules/psu/scpi/meas.cpp @@ -36,7 +36,7 @@ scpi_result_t scpi_cmd_measureScalarCurrentDcQ(scpi_t *context) { } char buffer[256] = { 0 }; - strcatCurrent(buffer, channel_dispatcher::getIMon(*channel)); + strcatCurrent(buffer, channel_dispatcher::getIMonLast(*channel)); SCPI_ResultCharacters(context, buffer, strlen(buffer)); return SCPI_RES_OK; @@ -50,7 +50,7 @@ scpi_result_t scpi_cmd_measureScalarPowerDcQ(scpi_t *context) { } char buffer[256] = { 0 }; - strcatFloat(buffer, channel_dispatcher::getUMon(*channel) * channel_dispatcher::getIMon(*channel)); + strcatFloat(buffer, channel_dispatcher::getUMonLast(*channel) * channel_dispatcher::getIMonLast(*channel)); SCPI_ResultCharacters(context, buffer, strlen(buffer)); return SCPI_RES_OK; @@ -64,7 +64,7 @@ scpi_result_t scpi_cmd_measureScalarVoltageDcQ(scpi_t *context) { } char buffer[256] = { 0 }; - strcatFloat(buffer, channel_dispatcher::getUMon(*channel)); + strcatFloat(buffer, channel_dispatcher::getUMonLast(*channel)); SCPI_ResultCharacters(context, buffer, strlen(buffer)); return SCPI_RES_OK; diff --git a/src/eez/modules/psu/scpi/outp.cpp b/src/eez/modules/psu/scpi/outp.cpp index 230ba257a..4207dd30b 100644 --- a/src/eez/modules/psu/scpi/outp.cpp +++ b/src/eez/modules/psu/scpi/outp.cpp @@ -37,7 +37,7 @@ scpi_result_t scpi_cmd_outputModeQ(scpi_t *context) { return SCPI_RES_ERR; } - SCPI_ResultText(context, channel->getCvModeStr()); + SCPI_ResultText(context, channel->getModeStr()); return SCPI_RES_OK; } diff --git a/src/eez/mp.cpp b/src/eez/mp.cpp index cc4037a88..92f6894bd 100644 --- a/src/eez/mp.cpp +++ b/src/eez/mp.cpp @@ -25,8 +25,12 @@ #include #include +#include #include +#include +#include + #include #ifdef _MSC_VER @@ -122,7 +126,9 @@ osThreadDef(g_mpTask, mainLoop, osPriorityNormal, 0, 4096); osMessageQDef(g_mpMessageQueue, MP_QUEUE_SIZE, uint32_t); osMessageQId g_mpMessageQueueId; -static char *g_scriptPath = (char *)MP_BUFFER; +State g_state; + +char *g_scriptPath = (char *)MP_BUFFER; static char *g_scriptSource = g_scriptPath + MAX_PATH_LENGTH + 1; static const size_t MAX_SCRIPT_SOURCE_AND_HEAP_SIZE = MP_BUFFER_SIZE - MAX_PATH_LENGTH + 1; static size_t g_scriptSourceLength; @@ -134,6 +140,7 @@ using namespace eez::psu::scpi; static char g_scpiData[SCPI_PARSER_INPUT_BUFFER_LENGTH]; static size_t g_scpiDataLen; +static int_fast16_t g_lastError; size_t SCPI_Write(scpi_t *context, const char *data, size_t len) { len = MIN(len, SCPI_PARSER_INPUT_BUFFER_LENGTH - g_scpiDataLen); @@ -149,38 +156,24 @@ scpi_result_t SCPI_Flush(scpi_t *context) { } int SCPI_Error(scpi_t *context, int_fast16_t err) { - //if (err != 0) { - // scpi::printError(err); + g_lastError = err; - // if (err == SCPI_ERROR_INPUT_BUFFER_OVERRUN) { - // scpi::onBufferOverrun(*context); - // } - //} + if (err != 0) { + psu::scpi::printError(err); + + if (err == SCPI_ERROR_INPUT_BUFFER_OVERRUN) { + psu::scpi::onBufferOverrun(*context); + } + } return 0; } scpi_result_t SCPI_Control(scpi_t *context, scpi_ctrl_name_t ctrl, scpi_reg_val_t val) { - //if (serial::g_testResult == TEST_OK) { - // char errorOutputBuffer[256]; - // if (SCPI_CTRL_SRQ == ctrl) { - // sprintf(errorOutputBuffer, "**SRQ: 0x%X (%d)\r\n", val, val); - // } else { - // sprintf(errorOutputBuffer, "**CTRL %02x: 0x%X (%d)\r\n", ctrl, val, val); - // } - // Serial.println(errorOutputBuffer); - //} - return SCPI_RES_OK; } scpi_result_t SCPI_Reset(scpi_t *context) { - //if (serial::g_testResult == TEST_OK) { - // char errorOutputBuffer[256]; - // strcpy(errorOutputBuffer, "**Reset\r\n"); - // Serial.println(errorOutputBuffer); - //} - return eez::psu::reset() ? SCPI_RES_OK : SCPI_RES_ERR; } @@ -251,6 +244,7 @@ void oneIter() { } else { // uncaught exception mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); + onUncaughtScriptExceptionHook(); } gc_sweep_all(); @@ -279,11 +273,12 @@ void oneIter() { } else { // uncaught exception mp_obj_print_exception(&mp_plat_print, (mp_obj_t)nlr.ret_val); + onUncaughtScriptExceptionHook(); } - - mp_deinit(); #endif + g_state = STATE_IDLE; + break; } } @@ -295,8 +290,8 @@ enum { }; void startScript(const char *filePath) { + g_state = STATE_EXECUTING; strcpy(g_scriptPath, filePath); - osMessagePut(scpi::g_scpiMessageQueueId, SCPI_QUEUE_MP_MESSAGE(LOAD_SCRIPT, 0), osWaitForever); } @@ -367,9 +362,15 @@ bool scpi(const char *commandOrQueryText, const char **resultText, size_t *resul // } // } + g_lastError = 0; + input(g_scpiContext, (const char *)commandOrQueryText, strlen(commandOrQueryText)); input(g_scpiContext, "\r\n", 2); + if (g_lastError != 0) { + mp_raise_ValueError("SCPI error"); + } + if (g_scpiDataLen >= 2 && g_scpiData[g_scpiDataLen - 2] == '\r' && g_scpiData[g_scpiDataLen - 1] == '\n') { g_scpiDataLen -= 2; } diff --git a/src/eez/mp.h b/src/eez/mp.h index 42a902870..019966fec 100644 --- a/src/eez/mp.h +++ b/src/eez/mp.h @@ -24,12 +24,23 @@ namespace eez { namespace mp { +enum State { + STATE_IDLE, + STATE_EXECUTING +}; + +extern State g_state; +extern char *g_scriptPath; + bool onSystemStateChanged(); void onQueueMessage(uint32_t type, uint32_t param); void startScript(const char *filePath); +inline bool isIdle() { return g_state == STATE_IDLE; } bool scpi(const char *commandOrQueryText, const char **resultText, size_t *resultTextLen); +void onUncaughtScriptExceptionHook(); + } // mp } // eez diff --git a/src/third_party/micropython/ports/bb3/genhdr/mpversion.h b/src/third_party/micropython/ports/bb3/genhdr/mpversion.h index 27a449241..e6edc8743 100644 --- a/src/third_party/micropython/ports/bb3/genhdr/mpversion.h +++ b/src/third_party/micropython/ports/bb3/genhdr/mpversion.h @@ -1,4 +1,4 @@ // This file was generated by py/makeversionhdr.py -#define MICROPY_GIT_TAG "d202a13-dirty" -#define MICROPY_GIT_HASH "d202a13-dirty" -#define MICROPY_BUILD_DATE "2019-12-06" +#define MICROPY_GIT_TAG "1930c98-dirty" +#define MICROPY_GIT_HASH "1930c98-dirty" +#define MICROPY_BUILD_DATE "2019-12-07" diff --git a/src/third_party/micropython/ports/bb3/genhdr/qstrdefs.generated.h b/src/third_party/micropython/ports/bb3/genhdr/qstrdefs.generated.h index 624f8e2d0..89af09d28 100644 --- a/src/third_party/micropython/ports/bb3/genhdr/qstrdefs.generated.h +++ b/src/third_party/micropython/ports/bb3/genhdr/qstrdefs.generated.h @@ -200,11 +200,15 @@ QDEF(MP_QSTR_closure, (const byte*)"\x74\x07" "closure") QDEF(MP_QSTR_complex, (const byte*)"\xc5\x07" "complex") QDEF(MP_QSTR_default, (const byte*)"\xce\x07" "default") QDEF(MP_QSTR_dict_view, (const byte*)"\x2d\x09" "dict_view") +QDEF(MP_QSTR_dlogTraceData, (const byte*)"\x94\x0d" "dlogTraceData") QDEF(MP_QSTR_eez, (const byte*)"\x3f\x03" "eez") QDEF(MP_QSTR_filter, (const byte*)"\x25\x06" "filter") QDEF(MP_QSTR_float, (const byte*)"\x35\x05" "float") QDEF(MP_QSTR_function, (const byte*)"\x27\x08" "function") QDEF(MP_QSTR_generator, (const byte*)"\x96\x09" "generator") +QDEF(MP_QSTR_getI, (const byte*)"\xda\x04" "getI") +QDEF(MP_QSTR_getOutputMode, (const byte*)"\x4f\x0d" "getOutputMode") +QDEF(MP_QSTR_getU, (const byte*)"\xc6\x04" "getU") QDEF(MP_QSTR_heap_lock, (const byte*)"\xad\x09" "heap_lock") QDEF(MP_QSTR_heap_unlock, (const byte*)"\x56\x0b" "heap_unlock") QDEF(MP_QSTR_hex, (const byte*)"\x70\x03" "hex") @@ -220,6 +224,8 @@ QDEF(MP_QSTR_pack_into, (const byte*)"\x1f\x09" "pack_into") QDEF(MP_QSTR_pend_throw, (const byte*)"\xf3\x0a" "pend_throw") QDEF(MP_QSTR_real, (const byte*)"\xbf\x04" "real") QDEF(MP_QSTR_scpi, (const byte*)"\xec\x04" "scpi") +QDEF(MP_QSTR_setI, (const byte*)"\x4e\x04" "setI") +QDEF(MP_QSTR_setU, (const byte*)"\x52\x04" "setU") QDEF(MP_QSTR_sleep, (const byte*)"\xea\x05" "sleep") QDEF(MP_QSTR_sleep_ms, (const byte*)"\x0b\x08" "sleep_ms") QDEF(MP_QSTR_sleep_us, (const byte*)"\x13\x08" "sleep_us") diff --git a/src/third_party/micropython/ports/bb3/mod/eez/modeez.cpp b/src/third_party/micropython/ports/bb3/mod/eez/modeez.cpp index a4bbf5847..611d38653 100644 --- a/src/third_party/micropython/ports/bb3/mod/eez/modeez.cpp +++ b/src/third_party/micropython/ports/bb3/mod/eez/modeez.cpp @@ -16,8 +16,15 @@ * along with this program. If not, see . */ +#include + #include +#include +#include +#include +#include + #ifdef _MSC_VER #pragma warning( push ) #pragma warning( disable : 4200) @@ -33,10 +40,13 @@ extern "C" { #pragma warning( pop ) #endif +using namespace eez::mp; +using namespace eez::psu; + mp_obj_t modeez_scpi(mp_obj_t commandOrQueryText) { const char *resultText; size_t resultTextLen; - if (!eez::mp::scpi(mp_obj_str_get_str(commandOrQueryText), &resultText, &resultTextLen)) { + if (!scpi(mp_obj_str_get_str(commandOrQueryText), &resultText, &resultTextLen)) { return mp_const_false; } @@ -46,3 +56,115 @@ mp_obj_t modeez_scpi(mp_obj_t commandOrQueryText) { return mp_obj_new_str(resultText, resultTextLen); } + +mp_obj_t modeez_getU(mp_obj_t channelIndexObj) { + int channelIndex = mp_obj_get_int(channelIndexObj) - 1; + if (channelIndex < 0 || channelIndex >= CH_NUM) { + mp_raise_ValueError("Invalid channel index"); + } + Channel &channel = Channel::get(channelIndex); + + return mp_obj_new_float(eez::psu::channel_dispatcher::getUMonLast(channel)); +} + +mp_obj_t modeez_setU(mp_obj_t channelIndexObj, mp_obj_t value) { + int channelIndex = mp_obj_get_int(channelIndexObj) - 1; + if (channelIndex < 0 || channelIndex >= CH_NUM) { + mp_raise_ValueError("Invalid channel index"); + } + Channel &channel = Channel::get(channelIndex); + + if (channel_dispatcher::getVoltageTriggerMode(channel) != TRIGGER_MODE_FIXED && !trigger::isIdle()) { + mp_raise_ValueError("Can not change transient trigger"); + } + + if (channel.isRemoteProgrammingEnabled()) { + mp_raise_ValueError("Remote programming enabled"); + } + + float voltage = mp_obj_get_float(value); + + if (voltage > channel_dispatcher::getULimit(channel)) { + mp_raise_ValueError("Voltage limit exceeded"); + } + + if (voltage * channel_dispatcher::getISetUnbalanced(channel) > channel_dispatcher::getPowerLimit(channel)) { + mp_raise_ValueError("Power limit exceeded"); + } + + channel_dispatcher::setVoltage(channel, voltage); + + return mp_const_none; +} + +mp_obj_t modeez_getI(mp_obj_t channelIndexObj) { + int channelIndex = mp_obj_get_int(channelIndexObj) - 1; + if (channelIndex < 0 || channelIndex >= CH_NUM) { + mp_raise_ValueError("Invalid channel index"); + } + Channel &channel = Channel::get(channelIndex); + + return mp_obj_new_float(eez::psu::channel_dispatcher::getIMonLast(channel)); +} + +mp_obj_t modeez_setI(mp_obj_t channelIndexObj, mp_obj_t value) { + int channelIndex = mp_obj_get_int(channelIndexObj) - 1; + if (channelIndex < 0 || channelIndex >= CH_NUM) { + mp_raise_ValueError("Invalid channel index"); + } + Channel &channel = Channel::get(channelIndex); + + if (channel_dispatcher::getVoltageTriggerMode(channel) != TRIGGER_MODE_FIXED && !trigger::isIdle()) { + mp_raise_ValueError("Can not change transient trigger"); + } + + float current = mp_obj_get_float(value); + + if (current > channel_dispatcher::getILimit(channel)) { + mp_raise_ValueError("Current limit exceeded"); + } + + if (current * channel_dispatcher::getUSetUnbalanced(channel) > channel_dispatcher::getPowerLimit(channel)) { + mp_raise_ValueError("Power limit exceeded"); + } + + channel_dispatcher::setCurrent(channel, current); + + return mp_const_none; +} + +mp_obj_t modeez_getOutputMode(mp_obj_t channelIndexObj) { + int channelIndex = mp_obj_get_int(channelIndexObj) - 1; + if (channelIndex < 0 || channelIndex >= CH_NUM) { + mp_raise_ValueError("Invalid channel index"); + } + Channel &channel = Channel::get(channelIndex); + + const char *modeStr = channel.getModeStr(); + + return mp_obj_new_str(modeStr, strlen(modeStr)); +} + +mp_obj_t modeez_dlogTraceData(size_t n_args, const mp_obj_t *args) { + if (!dlog_record::isTraceExecuting()) { + mp_raise_ValueError("DLOG trace data not started"); + } + + if (n_args < dlog_record::g_recording.parameters.numYAxes) { + mp_raise_ValueError("Too few values"); + } + + if (n_args > dlog_record::g_recording.parameters.numYAxes) { + mp_raise_ValueError("Too many values"); + } + + float values[4]; + + for (size_t i = 0; i < n_args; i++) { + values[i] = mp_obj_get_float(args[i]); + } + + dlog_record::log(values); + + return mp_const_none; +} diff --git a/src/third_party/micropython/ports/bb3/mod/eez/modeez.h b/src/third_party/micropython/ports/bb3/mod/eez/modeez.h index 0273950a1..34cdd1dfa 100644 --- a/src/third_party/micropython/ports/bb3/mod/eez/modeez.h +++ b/src/third_party/micropython/ports/bb3/mod/eez/modeez.h @@ -21,3 +21,9 @@ #include mp_obj_t modeez_scpi(mp_obj_t commandOrQueryText); +mp_obj_t modeez_getU(mp_obj_t channelIndexObj); +mp_obj_t modeez_setU(mp_obj_t channelIndexObj, mp_obj_t value); +mp_obj_t modeez_getI(mp_obj_t channelIndexObj); +mp_obj_t modeez_setI(mp_obj_t channelIndexObj, mp_obj_t value); +mp_obj_t modeez_getOutputMode(mp_obj_t channelIndexObj); +mp_obj_t modeez_dlogTraceData(size_t n_args, const mp_obj_t *args); diff --git a/src/third_party/micropython/ports/bb3/mod/eez/modeez_table.c b/src/third_party/micropython/ports/bb3/mod/eez/modeez_table.c index f9ca6ea4d..ae6fef2b4 100644 --- a/src/third_party/micropython/ports/bb3/mod/eez/modeez_table.c +++ b/src/third_party/micropython/ports/bb3/mod/eez/modeez_table.c @@ -19,10 +19,22 @@ #include "modeez.h" STATIC MP_DEFINE_CONST_FUN_OBJ_1(modeez_scpi_obj, modeez_scpi); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(modeez_getU_obj, modeez_getU); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(modeez_setU_obj, modeez_setU); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(modeez_getI_obj, modeez_getI); +STATIC MP_DEFINE_CONST_FUN_OBJ_2(modeez_setI_obj, modeez_setI); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(modeez_getOutputMode_obj, modeez_getOutputMode); +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(modeez_dlogTraceData_obj, 1, 4, modeez_dlogTraceData); STATIC const mp_rom_map_elem_t modeez_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_eez) }, { MP_ROM_QSTR(MP_QSTR_scpi), (mp_obj_t)&modeez_scpi_obj }, + { MP_ROM_QSTR(MP_QSTR_getU), (mp_obj_t)&modeez_getU_obj }, + { MP_ROM_QSTR(MP_QSTR_setU), (mp_obj_t)&modeez_setU_obj }, + { MP_ROM_QSTR(MP_QSTR_getI), (mp_obj_t)&modeez_getI_obj }, + { MP_ROM_QSTR(MP_QSTR_setI), (mp_obj_t)&modeez_setI_obj }, + { MP_ROM_QSTR(MP_QSTR_getOutputMode), (mp_obj_t)&modeez_getOutputMode_obj }, + { MP_ROM_QSTR(MP_QSTR_dlogTraceData), (mp_obj_t)&modeez_dlogTraceData_obj }, }; STATIC MP_DEFINE_CONST_DICT(modeez_module_globals, modeez_module_globals_table);