@@ -32,11 +32,13 @@ UARTSerial::UARTSerial(PinName tx, PinName rx, int baud) :
3232 SerialBase (tx, rx, baud),
3333 _blocking (true ),
3434 _tx_irq_enabled (false ),
35- _rx_irq_enabled (true ),
35+ _rx_irq_enabled (false ),
36+ _tx_enabled (true ),
37+ _rx_enabled (true ),
3638 _dcd_irq (NULL )
3739{
3840 /* Attatch IRQ routines to the serial device. */
39- SerialBase::attach ( callback ( this , &UARTSerial::rx_irq), RxIrq );
41+ enable_rx_irq ( );
4042}
4143
4244UARTSerial::~UARTSerial ()
@@ -188,11 +190,10 @@ ssize_t UARTSerial::write(const void *buffer, size_t length)
188190 }
189191
190192 core_util_critical_section_enter ();
191- if (!_tx_irq_enabled) {
193+ if (_tx_enabled && !_tx_irq_enabled) {
192194 UARTSerial::tx_irq (); // only write to hardware in one place
193195 if (!_txbuf.empty ()) {
194- SerialBase::attach (callback (this , &UARTSerial::tx_irq), TxIrq);
195- _tx_irq_enabled = true ;
196+ enable_tx_irq ();
196197 }
197198 }
198199 core_util_critical_section_exit ();
@@ -231,11 +232,10 @@ ssize_t UARTSerial::read(void *buffer, size_t length)
231232 }
232233
233234 core_util_critical_section_enter ();
234- if (!_rx_irq_enabled) {
235+ if (_rx_enabled && !_rx_irq_enabled) {
235236 UARTSerial::rx_irq (); // only read from hardware in one place
236237 if (!_rxbuf.full ()) {
237- SerialBase::attach (callback (this , &UARTSerial::rx_irq), RxIrq);
238- _rx_irq_enabled = true ;
238+ enable_rx_irq ();
239239 }
240240 }
241241 core_util_critical_section_exit ();
@@ -314,8 +314,7 @@ void UARTSerial::rx_irq(void)
314314 }
315315
316316 if (_rx_irq_enabled && _rxbuf.full ()) {
317- SerialBase::attach (NULL , RxIrq);
318- _rx_irq_enabled = false ;
317+ disable_rx_irq ();
319318 }
320319
321320 /* Report the File handler that data is ready to be read from the buffer. */
@@ -337,8 +336,7 @@ void UARTSerial::tx_irq(void)
337336 }
338337
339338 if (_tx_irq_enabled && _txbuf.empty ()) {
340- SerialBase::attach (NULL , TxIrq);
341- _tx_irq_enabled = false ;
339+ disable_tx_irq ();
342340 }
343341
344342 /* Report the File handler that data can be written to peripheral. */
@@ -347,6 +345,69 @@ void UARTSerial::tx_irq(void)
347345 }
348346}
349347
348+ /* These are all called from critical section */
349+ void UARTSerial::enable_rx_irq ()
350+ {
351+ SerialBase::attach (callback (this , &UARTSerial::rx_irq), RxIrq);
352+ _rx_irq_enabled = true ;
353+ }
354+
355+ void UARTSerial::disable_rx_irq ()
356+ {
357+ SerialBase::attach (NULL , RxIrq);
358+ _rx_irq_enabled = false ;
359+ }
360+
361+ void UARTSerial::enable_tx_irq ()
362+ {
363+ SerialBase::attach (callback (this , &UARTSerial::tx_irq), TxIrq);
364+ _tx_irq_enabled = true ;
365+ }
366+
367+ void UARTSerial::disable_tx_irq ()
368+ {
369+ SerialBase::attach (NULL , TxIrq);
370+ _tx_irq_enabled = false ;
371+ }
372+
373+ int UARTSerial::enable_input (bool yes)
374+ {
375+ core_util_critical_section_enter ();
376+ if (_rx_enabled != yes) {
377+ if (yes) {
378+ UARTSerial::rx_irq ();
379+ if (!_rxbuf.full ()) {
380+ enable_rx_irq ();
381+ }
382+ } else {
383+ disable_rx_irq ();
384+ }
385+ _rx_enabled = yes;
386+ }
387+ core_util_critical_section_exit ();
388+
389+ return 0 ;
390+ }
391+
392+ int UARTSerial::enable_output (bool yes)
393+ {
394+ core_util_critical_section_enter ();
395+ if (_tx_enabled != yes) {
396+ if (yes) {
397+ UARTSerial::tx_irq ();
398+ if (_txbuf.full ()) {
399+ enable_tx_irq ();
400+ }
401+ } else {
402+ disable_tx_irq ();
403+ }
404+ _tx_enabled = yes;
405+ }
406+ core_util_critical_section_exit ();
407+
408+ return 0 ;
409+ }
410+
350411void UARTSerial::wait_ms (uint32_t millisec)
351412{
352413 /* wait_ms implementation for RTOS spins until exact microseconds - we
0 commit comments