11#include <core/common_defines.h>
2+ #include <expansion/expansion.h>
23#include <furi_hal.h>
34#include "../js_modules.h"
45#include <m-array.h>
@@ -88,14 +89,49 @@ static void js_serial_setup(struct mjs* mjs) {
8889 return ;
8990 }
9091
91- serial -> rx_stream = furi_stream_buffer_alloc (RX_BUF_LEN , 1 );
92+ expansion_disable (furi_record_open (RECORD_EXPANSION ));
93+ furi_record_close (RECORD_EXPANSION );
94+
9295 serial -> serial_handle = furi_hal_serial_control_acquire (serial_id );
9396 if (serial -> serial_handle ) {
97+ serial -> rx_stream = furi_stream_buffer_alloc (RX_BUF_LEN , 1 );
9498 furi_hal_serial_init (serial -> serial_handle , baudrate );
9599 furi_hal_serial_async_rx_start (
96100 serial -> serial_handle , js_serial_on_async_rx , serial , false);
97101 serial -> setup_done = true;
102+ } else {
103+ expansion_enable (furi_record_open (RECORD_EXPANSION ));
104+ furi_record_close (RECORD_EXPANSION );
105+ }
106+ }
107+
108+ static void js_serial_deinit (JsSerialInst * js_serial ) {
109+ if (js_serial -> setup_done ) {
110+ furi_hal_serial_async_rx_stop (js_serial -> serial_handle );
111+ furi_hal_serial_deinit (js_serial -> serial_handle );
112+ furi_hal_serial_control_release (js_serial -> serial_handle );
113+ js_serial -> serial_handle = NULL ;
114+ furi_stream_buffer_free (js_serial -> rx_stream );
115+
116+ expansion_enable (furi_record_open (RECORD_EXPANSION ));
117+ furi_record_close (RECORD_EXPANSION );
118+
119+ js_serial -> setup_done = false;
120+ }
121+ }
122+
123+ static void js_serial_end (struct mjs * mjs ) {
124+ mjs_val_t obj_inst = mjs_get (mjs , mjs_get_this (mjs ), INST_PROP_NAME , ~0 );
125+ JsSerialInst * serial = mjs_get_ptr (mjs , obj_inst );
126+ furi_assert (serial );
127+
128+ if (!serial -> setup_done ) {
129+ mjs_prepend_errorf (mjs , MJS_INTERNAL_ERROR , "Serial is not configured" );
130+ mjs_return (mjs , MJS_UNDEFINED );
131+ return ;
98132 }
133+
134+ js_serial_deinit (serial );
99135}
100136
101137static void js_serial_write (struct mjs * mjs ) {
@@ -345,6 +381,55 @@ static void js_serial_read_bytes(struct mjs* mjs) {
345381 free (read_buf );
346382}
347383
384+ static char * js_serial_receive_any (JsSerialInst * serial , size_t * len , uint32_t timeout ) {
385+ uint32_t flags = ThreadEventCustomDataRx ;
386+ if (furi_stream_buffer_is_empty (serial -> rx_stream )) {
387+ flags = js_flags_wait (serial -> mjs , ThreadEventCustomDataRx , timeout );
388+ }
389+ if (flags & ThreadEventCustomDataRx ) { // New data received
390+ * len = furi_stream_buffer_bytes_available (serial -> rx_stream );
391+ if (!* len ) return NULL ;
392+ char * buf = malloc (* len );
393+ furi_stream_buffer_receive (serial -> rx_stream , buf , * len , 0 );
394+ return buf ;
395+ }
396+ return NULL ;
397+ }
398+
399+ static void js_serial_read_any (struct mjs * mjs ) {
400+ mjs_val_t obj_inst = mjs_get (mjs , mjs_get_this (mjs ), INST_PROP_NAME , ~0 );
401+ JsSerialInst * serial = mjs_get_ptr (mjs , obj_inst );
402+ furi_assert (serial );
403+ if (!serial -> setup_done ) {
404+ mjs_prepend_errorf (mjs , MJS_INTERNAL_ERROR , "Serial is not configured" );
405+ mjs_return (mjs , MJS_UNDEFINED );
406+ return ;
407+ }
408+
409+ uint32_t timeout = FuriWaitForever ;
410+
411+ do {
412+ size_t num_args = mjs_nargs (mjs );
413+ if (num_args == 1 ) {
414+ mjs_val_t timeout_arg = mjs_arg (mjs , 0 );
415+ if (!mjs_is_number (timeout_arg )) {
416+ break ;
417+ }
418+ timeout = mjs_get_int32 (mjs , timeout_arg );
419+ }
420+ } while (0 );
421+
422+ size_t bytes_read = 0 ;
423+ char * read_buf = js_serial_receive_any (serial , & bytes_read , timeout );
424+
425+ mjs_val_t return_obj = MJS_UNDEFINED ;
426+ if (bytes_read > 0 && read_buf ) {
427+ return_obj = mjs_mk_string (mjs , read_buf , bytes_read , true);
428+ }
429+ mjs_return (mjs , return_obj );
430+ free (read_buf );
431+ }
432+
348433static bool
349434 js_serial_expect_parse_string (struct mjs * mjs , mjs_val_t arg , PatternArray_t patterns ) {
350435 size_t str_len = 0 ;
@@ -578,10 +663,12 @@ static void* js_serial_create(struct mjs* mjs, mjs_val_t* object) {
578663 mjs_val_t serial_obj = mjs_mk_object (mjs );
579664 mjs_set (mjs , serial_obj , INST_PROP_NAME , ~0 , mjs_mk_foreign (mjs , js_serial ));
580665 mjs_set (mjs , serial_obj , "setup" , ~0 , MJS_MK_FN (js_serial_setup ));
666+ mjs_set (mjs , serial_obj , "end" , ~0 , MJS_MK_FN (js_serial_end ));
581667 mjs_set (mjs , serial_obj , "write" , ~0 , MJS_MK_FN (js_serial_write ));
582668 mjs_set (mjs , serial_obj , "read" , ~0 , MJS_MK_FN (js_serial_read ));
583669 mjs_set (mjs , serial_obj , "readln" , ~0 , MJS_MK_FN (js_serial_readln ));
584670 mjs_set (mjs , serial_obj , "readBytes" , ~0 , MJS_MK_FN (js_serial_read_bytes ));
671+ mjs_set (mjs , serial_obj , "readAny" , ~0 , MJS_MK_FN (js_serial_read_any ));
585672 mjs_set (mjs , serial_obj , "expect" , ~0 , MJS_MK_FN (js_serial_expect ));
586673 * object = serial_obj ;
587674
@@ -590,14 +677,7 @@ static void* js_serial_create(struct mjs* mjs, mjs_val_t* object) {
590677
591678static void js_serial_destroy (void * inst ) {
592679 JsSerialInst * js_serial = inst ;
593- if (js_serial -> setup_done ) {
594- furi_hal_serial_async_rx_stop (js_serial -> serial_handle );
595- furi_hal_serial_deinit (js_serial -> serial_handle );
596- furi_hal_serial_control_release (js_serial -> serial_handle );
597- js_serial -> serial_handle = NULL ;
598- }
599-
600- furi_stream_buffer_free (js_serial -> rx_stream );
680+ js_serial_deinit (js_serial );
601681 free (js_serial );
602682}
603683
0 commit comments