@@ -59,7 +59,23 @@ STATIC bool repl_display_debugging_info = 0;
59
59
#define EXEC_FLAG_SOURCE_IS_FILENAME (1 << 5)
60
60
#define EXEC_FLAG_SOURCE_IS_READER (1 << 6)
61
61
62
- #define NUM_ESCAPED 8 // This value has to match the value in tools/pyboard.py
62
+ #define RAWCODE_PASTE_NUM_ESCAPED 8 // This value has to match the same constant in tools/pyboard.py
63
+
64
+ // Raw REPL serial protocol control sequences
65
+ #define RAW_REPL_CTRL_INIT CHAR_CTRL_A
66
+ #define RAW_REPL_CTRL_EXIT_TO_FRIENDLY CHAR_CTRL_B
67
+ #define RAW_REPL_CTRL_CLEAR_LINE CHAR_CTRL_C
68
+ #define RAW_REPL_CTRL_EOF CHAR_CTRL_D
69
+ #define RAW_REPL_CTRL_INIT_CMD CHAR_CTRL_E
70
+ // CHAR_CTRL_F is recognised in raw paste mode (as an escape sequence), but not in raw REPL mode
71
+
72
+ // Sequence ^A ^E (RAW_REPL_CTRL_INIT, RAW_REPL_CTRL_INIT_CMD) can initiate one or more "init commands" based on the next
73
+ // character in the sequence:
74
+ #define RAW_REPL_INIT_CMD_PASTE_SOURCE 'A'
75
+ #define RAW_REPL_INIT_CMD_PASTE_RAWCODE 'B'
76
+
77
+ #define RAW_REPL_INIT_CMD_RESP_UNSUPPORTED "R\x00"
78
+ #define RAW_REPL_INIT_CMD_RESP_OK "R\x01"
63
79
64
80
// parses, compiles and executes the code in the lexer
65
81
// frees the lexer before returning
@@ -234,9 +250,9 @@ STATIC mp_uint_t mp_reader_stdin_readbyte(void *data) {
234
250
return MP_READER_EOF ;
235
251
}
236
252
}else if (c == CHAR_CTRL_F ) {
237
- // escape sequence, next character is escaped by addingNUM_ESCAPED to it
253
+ // escape sequence, next character is escaped by addingRAWCODE_PASTE_NUM_ESCAPED to it
238
254
int e = mp_hal_stdin_rx_chr ();
239
- c = e - NUM_ESCAPED ;
255
+ c = e - RAWCODE_PASTE_NUM_ESCAPED ;
240
256
}
241
257
242
258
if (-- reader -> window_remain == 0 ) {
@@ -277,30 +293,33 @@ STATIC void mp_reader_new_stdin(mp_reader_t *reader, mp_reader_stdin_t *reader_s
277
293
reader -> close = mp_reader_stdin_close ;
278
294
}
279
295
280
- STATIC int do_reader_stdin (int c ) {
281
- bool supported_command = c == 'A' ;
296
+ STATIC int handle_raw_repl_init_cmd (int c ) {
297
+ int exec_flags = EXEC_FLAG_PRINT_EOF |EXEC_FLAG_SOURCE_IS_READER ;
298
+ bool supported_command = false;
299
+
300
+ if (c == RAW_REPL_INIT_CMD_PASTE_SOURCE ) {
301
+ supported_command = true;
302
+ }
282
303
#if MICROPY_PERSISTENT_CODE_LOAD
283
- supported_command = (c == 'B' )|| supported_command ;
304
+ if (c == RAW_REPL_INIT_CMD_PASTE_RAWCODE ) {
305
+ exec_flags |=EXEC_FLAG_SOURCE_IS_RAW_CODE ;
306
+ supported_command = true;
307
+ }
284
308
#endif
285
309
286
310
if (!supported_command ) {
287
311
// Unsupported command.
288
- mp_hal_stdout_tx_strn ("R\x00" ,2 );
312
+ mp_hal_stdout_tx_strn (RAW_REPL_INIT_CMD_RESP_UNSUPPORTED ,2 );
289
313
return 0 ;
290
314
}
291
315
292
316
// Indicate reception of command.
293
- mp_hal_stdout_tx_strn ("R\x01" ,2 );
317
+ mp_hal_stdout_tx_strn (RAW_REPL_INIT_CMD_RESP_OK ,2 );
294
318
295
319
// Entering raw paste mode
296
- // c == 'A' input is source, c == 'B' input is bytecode
297
320
mp_reader_t reader ;
298
321
mp_reader_stdin_t reader_stdin ;
299
322
mp_reader_new_stdin (& reader ,& reader_stdin ,MICROPY_REPL_STDIN_BUFFER_MAX );
300
- int exec_flags = EXEC_FLAG_PRINT_EOF |EXEC_FLAG_SOURCE_IS_READER ;
301
- if (c == 'B' ) {
302
- exec_flags |=EXEC_FLAG_SOURCE_IS_RAW_CODE ;
303
- }
304
323
return parse_compile_execute (& reader ,MP_PARSE_FILE_INPUT ,exec_flags );
305
324
}
306
325
@@ -335,30 +354,30 @@ void pyexec_event_repl_init(void) {
335
354
}
336
355
337
356
STATIC int pyexec_raw_repl_process_char (int c ) {
338
- if (c == CHAR_CTRL_A ) {
357
+ if (c == RAW_REPL_CTRL_INIT ) {
339
358
// reset raw REPL
340
- if (vstr_len (MP_STATE_VM (repl_line ))== 2 && vstr_str (MP_STATE_VM (repl_line ))[0 ]== CHAR_CTRL_E ) {
341
- int ret = do_reader_stdin (vstr_str (MP_STATE_VM (repl_line ))[1 ]);
359
+ if (vstr_len (MP_STATE_VM (repl_line ))== 2 && vstr_str (MP_STATE_VM (repl_line ))[0 ]== RAW_REPL_CTRL_INIT_CMD ) {
360
+ int ret = handle_raw_repl_init_cmd (vstr_str (MP_STATE_VM (repl_line ))[1 ]);
342
361
if (ret & PYEXEC_FORCED_EXIT ) {
343
362
return ret ;
344
363
}
345
364
gotoreset ;
346
365
}
347
366
mp_hal_stdout_tx_str ("raw REPL; CTRL-B to exit\r\n" );
348
367
gotoreset ;
349
- }else if (c == CHAR_CTRL_B ) {
368
+ }else if (c == RAW_REPL_CTRL_EXIT_TO_FRIENDLY ) {
350
369
// change to friendly REPL
351
370
pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL ;
352
371
vstr_reset (MP_STATE_VM (repl_line ));
353
372
repl .cont_line = false;
354
373
repl .paste_mode = false;
355
374
pyexec_friendly_repl_process_char (CHAR_CTRL_B );
356
375
return 0 ;
357
- }else if (c == CHAR_CTRL_C ) {
376
+ }else if (c == RAW_REPL_CTRL_CLEAR_LINE ) {
358
377
// clear line
359
378
vstr_reset (MP_STATE_VM (repl_line ));
360
379
return 0 ;
361
- }else if (c == CHAR_CTRL_D ) {
380
+ }else if (c == RAW_REPL_CTRL_EOF ) {
362
381
// input finished
363
382
}else {
364
383
// let through any other raw 8-bit value
@@ -419,7 +438,7 @@ STATIC int pyexec_friendly_repl_process_char(int c) {
419
438
420
439
if (!repl .cont_line ) {
421
440
422
- if (ret == CHAR_CTRL_A ) {
441
+ if (ret == RAW_REPL_CTRL_INIT ) {
423
442
// change to raw REPL
424
443
pyexec_mode_kind = PYEXEC_MODE_RAW_REPL ;
425
444
mp_hal_stdout_tx_str ("\r\n" );
@@ -529,10 +548,10 @@ int pyexec_raw_repl(void) {
529
548
mp_hal_stdout_tx_str (">" );
530
549
for (;;) {
531
550
int c = mp_hal_stdin_rx_chr ();
532
- if (c == CHAR_CTRL_A ) {
551
+ if (c == RAW_REPL_CTRL_INIT ) {
533
552
// reset raw REPL
534
- if (vstr_len (& line )== 2 && vstr_str (& line )[0 ]== CHAR_CTRL_E ) {
535
- int ret = do_reader_stdin (vstr_str (& line )[1 ]);
553
+ if (vstr_len (& line )== 2 && vstr_str (& line )[0 ]== RAW_REPL_CTRL_INIT_CMD ) {
554
+ int ret = handle_raw_repl_init_cmd (vstr_str (& line )[1 ]);
536
555
if (ret & PYEXEC_FORCED_EXIT ) {
537
556
return ret ;
538
557
}
@@ -541,16 +560,16 @@ int pyexec_raw_repl(void) {
541
560
continue ;
542
561
}
543
562
gotoraw_repl_reset ;
544
- }else if (c == CHAR_CTRL_B ) {
563
+ }else if (c == RAW_REPL_CTRL_EXIT_TO_FRIENDLY ) {
545
564
// change to friendly REPL
546
565
mp_hal_stdout_tx_str ("\r\n" );
547
566
vstr_clear (& line );
548
567
pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL ;
549
568
return 0 ;
550
- }else if (c == CHAR_CTRL_C ) {
569
+ }else if (c == RAW_REPL_CTRL_CLEAR_LINE ) {
551
570
// clear line
552
571
vstr_reset (& line );
553
- }else if (c == CHAR_CTRL_D ) {
572
+ }else if (c == RAW_REPL_CTRL_EOF ) {
554
573
// input finished
555
574
break ;
556
575
}else {
@@ -632,7 +651,7 @@ int pyexec_friendly_repl(void) {
632
651
int ret = readline (& line ,mp_repl_get_ps1 ());
633
652
mp_parse_input_kind_t parse_input_kind = MP_PARSE_SINGLE_INPUT ;
634
653
635
- if (ret == CHAR_CTRL_A ) {
654
+ if (ret == RAW_REPL_CTRL_INIT ) {
636
655
// change to raw REPL
637
656
mp_hal_stdout_tx_str ("\r\n" );
638
657
vstr_clear (& line );