Skip to content

Commit f704e7f

Browse files
committed
stmhal: Improve REPL CTRL commands.
1 parent 2f8beb8 commit f704e7f

3 files changed

Lines changed: 62 additions & 24 deletions

File tree

stmhal/main.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,19 @@ int main(void) {
446446
#endif
447447
#endif
448448

449-
pyexec_repl();
449+
// enter REPL
450+
// REPL mode can change, or it can request a soft reset
451+
for (;;) {
452+
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
453+
if (pyexec_raw_repl() != 0) {
454+
break;
455+
}
456+
} else {
457+
if (pyexec_friendly_repl() != 0) {
458+
break;
459+
}
460+
}
461+
}
450462

451463
printf("PYB: sync filesystems\n");
452464
storage_flush();

stmhal/pyexec.c

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
#include "usb.h"
2525
#include "usart.h"
2626

27-
static bool repl_display_debugging_info = 0;
27+
pyexec_mode_kind_t pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
28+
STATIC bool repl_display_debugging_info = 0;
2829

2930
void stdout_tx_str(const char *str) {
3031
if (pyb_usart_global_debug != PYB_USART_NONE) {
@@ -279,24 +280,32 @@ bool parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bo
279280
return ret;
280281
}
281282

282-
void pyexec_raw_repl(void) {
283+
int pyexec_raw_repl(void) {
283284
vstr_t line;
284285
vstr_init(&line, 32);
285286

286287
raw_repl_reset:
287-
stdout_tx_str("raw REPL; CTRL-C to exit\r\n");
288+
stdout_tx_str("raw REPL; CTRL-B to exit\r\n");
288289

289290
for (;;) {
290291
vstr_reset(&line);
291292
stdout_tx_str(">");
292293
for (;;) {
293294
char c = stdin_rx_chr();
294295
if (c == VCP_CHAR_CTRL_A) {
296+
// reset raw REPL
295297
goto raw_repl_reset;
298+
} else if (c == VCP_CHAR_CTRL_B) {
299+
// change to friendly REPL
300+
stdout_tx_str("\r\n");
301+
vstr_clear(&line);
302+
pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
303+
return 0;
296304
} else if (c == VCP_CHAR_CTRL_C) {
305+
// clear line
297306
vstr_reset(&line);
298-
break;
299307
} else if (c == VCP_CHAR_CTRL_D) {
308+
// input finished
300309
break;
301310
} else if (c == '\r') {
302311
vstr_add_char(&line, '\n');
@@ -305,30 +314,35 @@ void pyexec_raw_repl(void) {
305314
}
306315
}
307316

317+
// indicate reception of command
308318
stdout_tx_str("OK");
309319

310-
if (vstr_len(&line) == 0) {
311-
// finished
312-
break;
320+
if (line.len == 0) {
321+
// exit for a soft reset
322+
stdout_tx_str("\r\n");
323+
vstr_clear(&line);
324+
return 1;
313325
}
314326

315-
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0);
327+
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line.buf, line.len, 0);
316328
parse_compile_execute(lex, MP_PARSE_FILE_INPUT, false);
317329

330+
// indicate end of output with EOF character
318331
stdout_tx_str("\004");
319332
}
320-
321-
vstr_clear(&line);
322-
stdout_tx_str("\r\n");
323333
}
324334

325-
void pyexec_repl(void) {
335+
int pyexec_friendly_repl(void) {
336+
vstr_t line;
337+
vstr_init(&line, 32);
338+
326339
#if defined(USE_HOST_MODE) && MICROPY_HW_HAS_LCD
327340
// in host mode, we enable the LCD for the repl
328341
mp_obj_t lcd_o = rt_call_function_0(rt_load_name(qstr_from_str("LCD")));
329342
rt_call_function_1(rt_load_attr(lcd_o, qstr_from_str("light")), mp_const_true);
330343
#endif
331344

345+
friendly_repl_reset:
332346
stdout_tx_str("Micro Python build <git hash> on 25/1/2014; " MICROPY_HW_BOARD_NAME " with STM32F405RG\r\n");
333347
stdout_tx_str("Type \"help()\" for more information.\r\n");
334348

@@ -350,22 +364,29 @@ void pyexec_repl(void) {
350364
}
351365
*/
352366

353-
vstr_t line;
354-
vstr_init(&line, 32);
355-
356367
for (;;) {
357368
vstr_reset(&line);
358369
int ret = readline(&line, ">>> ");
359370

360371
if (ret == VCP_CHAR_CTRL_A) {
361-
pyexec_raw_repl();
362-
continue;
372+
// change to raw REPL
373+
stdout_tx_str("\r\n");
374+
vstr_clear(&line);
375+
pyexec_mode_kind = PYEXEC_MODE_RAW_REPL;
376+
return 0;
377+
} else if (ret == VCP_CHAR_CTRL_B) {
378+
// reset friendly REPL
379+
stdout_tx_str("\r\n");
380+
goto friendly_repl_reset;
363381
} else if (ret == VCP_CHAR_CTRL_C) {
382+
// break
364383
stdout_tx_str("\r\n");
365384
continue;
366385
} else if (ret == VCP_CHAR_CTRL_D) {
367-
// EOF
368-
break;
386+
// exit for a soft reset
387+
stdout_tx_str("\r\n");
388+
vstr_clear(&line);
389+
return 1;
369390
} else if (vstr_len(&line) == 0) {
370391
continue;
371392
}
@@ -385,8 +406,6 @@ void pyexec_repl(void) {
385406
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0);
386407
parse_compile_execute(lex, MP_PARSE_SINGLE_INPUT, true);
387408
}
388-
389-
stdout_tx_str("\r\n");
390409
}
391410

392411
bool pyexec_file(const char *filename) {

stmhal/pyexec.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
void pyexec_raw_repl(void);
2-
void pyexec_repl(void);
1+
typedef enum {
2+
PYEXEC_MODE_RAW_REPL,
3+
PYEXEC_MODE_FRIENDLY_REPL,
4+
} pyexec_mode_kind_t;
5+
6+
extern pyexec_mode_kind_t pyexec_mode_kind;
7+
8+
int pyexec_raw_repl(void);
9+
int pyexec_friendly_repl(void);
310
bool pyexec_file(const char *filename);
411

512
MP_DECLARE_CONST_FUN_OBJ(pyb_set_repl_info_obj);

0 commit comments

Comments
 (0)