4444#endif
4545
4646#include < assert.h>
47+ #include < deque>
4748
4849int g_snapshot_idx = 0 ;
4950
@@ -68,6 +69,10 @@ extern const etx_hal_adc_driver_t simu_adc_driver;
6869void lcdCopy (void * dest, void * src);
6970void lcdFlushed ();
7071
72+ #if defined(AUX_SERIAL) || defined(AUX2_SERIAL)
73+ static void hostSerialInit ();
74+ #endif
75+
7176void simuInit ()
7277{
7378#if defined(ROTARY_ENCODER_NAVIGATION)
@@ -81,6 +86,10 @@ void simuInit()
8186 adcInit (&simu_adc_driver);
8287 // Switches
8388 switchInit ();
89+
90+ #if defined(AUX_SERIAL) || defined(AUX2_SERIAL)
91+ hostSerialInit ();
92+ #endif
8493}
8594
8695bool keysStates[MAX_KEYS] = { false };
@@ -394,36 +403,115 @@ const etx_serial_port_t UsbSerialPort = { "USB-VCP", nullptr, nullptr };
394403#endif
395404
396405#if defined(AUX_SERIAL) || defined(AUX2_SERIAL)
397- static void * null_drv_init (void * hw_def, const etx_serial_init* dev) { return nullptr ; }
398- static void null_drv_deinit (void * ctx) { }
399- static void null_drv_send_byte (void * ctx, uint8_t b) { }
400- static void null_drv_send_buffer (void * ctx, const uint8_t * b, uint32_t l) { }
401- static bool null_drv_tx_completed (void * ctx) { return true ; }
402- static int null_drv_get_byte (void * ctx, uint8_t * b) { return 0 ; }
403- static void null_drv_set_baudrate (void * ctx, uint32_t baudrate) { }
404-
405- const etx_serial_driver_t null_drv = {
406- .init = null_drv_init,
407- .deinit = null_drv_deinit,
408- .sendByte = null_drv_send_byte,
409- .sendBuffer = null_drv_send_buffer,
410- .txCompleted = null_drv_tx_completed,
406+ // Per-port bridge state. TX is forwarded to the host via WASM imports;
407+ // RX bytes pushed in via simuAuxSerialReceive() are buffered in rxQueue
408+ // and consumed by the firmware through host_drv_get_byte().
409+ struct host_serial_port_t {
410+ uint8_t index;
411+ mutex_handle_t rxMutex;
412+ std::deque<uint8_t > rxQueue;
413+ };
414+
415+ static host_serial_port_t hostSerialPorts[MAX_AUX_SERIAL] = {
416+ { SP_AUX1, {}, {} },
417+ { SP_AUX2, {}, {} },
418+ };
419+
420+ static void hostSerialInit ()
421+ {
422+ for (uint8_t i = 0 ; i < MAX_AUX_SERIAL; ++i)
423+ mutex_create (&hostSerialPorts[i].rxMutex );
424+ }
425+
426+ static void * host_drv_init (void * hw_def, const etx_serial_init* dev)
427+ {
428+ if (hw_def == nullptr || dev == nullptr ) return nullptr ;
429+
430+ auto * port = static_cast <host_serial_port_t *>(hw_def);
431+ mutex_lock (&port->rxMutex );
432+ port->rxQueue .clear ();
433+ mutex_unlock (&port->rxMutex );
434+ simuAuxSerialStart (port->index , dev->baudrate , dev->encoding );
435+ return port;
436+ }
437+
438+ static void host_drv_deinit (void * ctx)
439+ {
440+ if (ctx == nullptr ) return ;
441+ auto * port = static_cast <host_serial_port_t *>(ctx);
442+ simuAuxSerialStop (port->index );
443+ }
444+
445+ static void host_drv_send_byte (void * ctx, uint8_t b)
446+ {
447+ if (ctx == nullptr ) return ;
448+ auto * port = static_cast <host_serial_port_t *>(ctx);
449+ simuAuxSerialSendBuffer (port->index , &b, 1 );
450+ }
451+
452+ static void host_drv_send_buffer (void * ctx, const uint8_t * b, uint32_t l)
453+ {
454+ if (ctx == nullptr || b == nullptr || l == 0 ) return ;
455+ auto * port = static_cast <host_serial_port_t *>(ctx);
456+ simuAuxSerialSendBuffer (port->index , b, l);
457+ }
458+
459+ static bool host_drv_tx_completed (void *) { return true ; }
460+
461+ static int host_drv_get_byte (void * ctx, uint8_t * b)
462+ {
463+ if (ctx == nullptr || b == nullptr ) return 0 ;
464+ auto * port = static_cast <host_serial_port_t *>(ctx);
465+ mutex_lock (&port->rxMutex );
466+ if (port->rxQueue .empty ()) {
467+ mutex_unlock (&port->rxMutex );
468+ return 0 ;
469+ }
470+ *b = port->rxQueue .front ();
471+ port->rxQueue .pop_front ();
472+ mutex_unlock (&port->rxMutex );
473+ return 1 ;
474+ }
475+
476+ static void host_drv_set_baudrate (void * ctx, uint32_t baudrate)
477+ {
478+ if (ctx == nullptr ) return ;
479+ auto * port = static_cast <host_serial_port_t *>(ctx);
480+ simuAuxSerialSetBaudrate (port->index , baudrate);
481+ }
482+
483+ const etx_serial_driver_t host_drv = {
484+ .init = host_drv_init,
485+ .deinit = host_drv_deinit,
486+ .sendByte = host_drv_send_byte,
487+ .sendBuffer = host_drv_send_buffer,
488+ .txCompleted = host_drv_tx_completed,
411489 .waitForTxCompleted = nullptr ,
412490 .enableRx = nullptr ,
413- .getByte = null_drv_get_byte ,
491+ .getByte = host_drv_get_byte ,
414492 .getLastByte = nullptr ,
415493 .getBufferedBytes = nullptr ,
416494 .copyRxBuffer = nullptr ,
417495 .clearRxBuffer = nullptr ,
418496 .getBaudrate = nullptr ,
419- .setBaudrate = null_drv_set_baudrate ,
497+ .setBaudrate = host_drv_set_baudrate ,
420498 .setPolarity = nullptr ,
421499 .setHWOption = nullptr ,
422500 .setReceiveCb = nullptr ,
423501 .setIdleCb = nullptr ,
424502 .setBaudrateCb = nullptr ,
425503};
426504
505+ void simuAuxSerialReceive (uint8_t port_nr, const uint8_t * data, uint32_t len)
506+ {
507+ if (port_nr >= MAX_AUX_SERIAL || data == nullptr || len == 0 ) return ;
508+ auto & port = hostSerialPorts[port_nr];
509+ mutex_lock (&port.rxMutex );
510+ for (uint32_t i = 0 ; i < len; ++i)
511+ port.rxQueue .push_back (data[i]);
512+ mutex_unlock (&port.rxMutex );
513+ }
514+
427515#if defined(AUX_SERIAL_PWR_GPIO)
428516static void null_pwr_aux (uint8_t ) {}
429517#endif
@@ -437,8 +525,8 @@ static void null_pwr_aux(uint8_t) {}
437525#endif
438526static etx_serial_port_t auxSerialPort = {
439527 " AUX1" ,
440- &null_drv ,
441- nullptr ,
528+ &host_drv ,
529+ &hostSerialPorts[SP_AUX1] ,
442530 AUX_SERIAL_PWR
443531};
444532#define AUX_SERIAL_PORT &auxSerialPort
@@ -454,8 +542,8 @@ static etx_serial_port_t auxSerialPort = {
454542#endif
455543static etx_serial_port_t aux2SerialPort = {
456544 " AUX2" ,
457- &null_drv ,
458- nullptr ,
545+ &host_drv ,
546+ &hostSerialPorts[SP_AUX2] ,
459547 AUX2_SERIAL_PWR
460548};
461549#define AUX2_SERIAL_PORT &aux2SerialPort
0 commit comments