Skip to content

Commit a0b02aa

Browse files
authored
Merge pull request #14498 from ghseb/uartserial-shadowing
UARTSerial writes even if tx is disabled
2 parents 2bec3ee + c51822c commit a0b02aa

File tree

2 files changed

+30
-33
lines changed

2 files changed

+30
-33
lines changed

drivers/UARTSerial.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,9 @@ class UARTSerial : private SerialBase, public FileHandle, private NonCopyable<UA
278278
/** Unbuffered write - invoked when write called from critical section */
279279
ssize_t write_unbuffered(const char *buf_ptr, size_t length);
280280

281-
void enable_rx_irq();
281+
void update_rx_irq();
282282
void disable_rx_irq();
283-
void enable_tx_irq();
283+
void update_tx_irq();
284284
void disable_tx_irq();
285285

286286
/** Software serial buffers
@@ -296,8 +296,6 @@ class UARTSerial : private SerialBase, public FileHandle, private NonCopyable<UA
296296
bool _blocking;
297297
bool _tx_irq_enabled;
298298
bool _rx_irq_enabled;
299-
bool _tx_enabled;
300-
bool _rx_enabled;
301299
InterruptIn *_dcd_irq;
302300

303301
/** Device Hanged up

drivers/source/UARTSerial.cpp

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,25 +28,21 @@ UARTSerial::UARTSerial(PinName tx, PinName rx, int baud) :
2828
_blocking(true),
2929
_tx_irq_enabled(false),
3030
_rx_irq_enabled(false),
31-
_tx_enabled(true),
32-
_rx_enabled(true),
3331
_dcd_irq(NULL)
3432
{
3533
/* Attatch IRQ routines to the serial device. */
36-
enable_rx_irq();
34+
update_rx_irq();
3735
}
3836

3937
UARTSerial::UARTSerial(const serial_pinmap_t &static_pinmap, int baud) :
4038
SerialBase(static_pinmap, baud),
4139
_blocking(true),
4240
_tx_irq_enabled(false),
4341
_rx_irq_enabled(false),
44-
_tx_enabled(true),
45-
_rx_enabled(true),
4642
_dcd_irq(NULL)
4743
{
4844
/* Attatch IRQ routines to the serial device. */
49-
enable_rx_irq();
45+
update_rx_irq();
5046
}
5147

5248
UARTSerial::~UARTSerial()
@@ -196,14 +192,7 @@ ssize_t UARTSerial::write(const void *buffer, size_t length)
196192
data_written++;
197193
}
198194

199-
core_util_critical_section_enter();
200-
if (_tx_enabled && !_tx_irq_enabled) {
201-
UARTSerial::tx_irq(); // only write to hardware in one place
202-
if (!_txbuf.empty()) {
203-
enable_tx_irq();
204-
}
205-
}
206-
core_util_critical_section_exit();
195+
update_tx_irq();
207196
}
208197

209198
api_unlock();
@@ -238,14 +227,7 @@ ssize_t UARTSerial::read(void *buffer, size_t length)
238227
data_read++;
239228
}
240229

241-
core_util_critical_section_enter();
242-
if (_rx_enabled && !_rx_irq_enabled) {
243-
UARTSerial::rx_irq(); // only read from hardware in one place
244-
if (!_rxbuf.full()) {
245-
enable_rx_irq();
246-
}
247-
}
248-
core_util_critical_section_exit();
230+
update_rx_irq();
249231

250232
api_unlock();
251233

@@ -352,25 +334,40 @@ void UARTSerial::tx_irq(void)
352334
}
353335
}
354336

355-
/* These are all called from critical section */
356-
void UARTSerial::enable_rx_irq()
337+
void UARTSerial::update_rx_irq()
357338
{
358-
SerialBase::attach(callback(this, &UARTSerial::rx_irq), RxIrq);
359-
_rx_irq_enabled = true;
339+
core_util_critical_section_enter();
340+
if (_rx_enabled && !_rx_irq_enabled) {
341+
UARTSerial::rx_irq();
342+
if (!_rxbuf.full()) {
343+
SerialBase::attach(callback(this, &UARTSerial::rx_irq), RxIrq);
344+
_rx_irq_enabled = true;
345+
}
346+
}
347+
core_util_critical_section_exit();
360348
}
361349

350+
/* This is called called from critical section or interrupt context */
362351
void UARTSerial::disable_rx_irq()
363352
{
364353
SerialBase::attach(NULL, RxIrq);
365354
_rx_irq_enabled = false;
366355
}
367356

368-
void UARTSerial::enable_tx_irq()
357+
void UARTSerial::update_tx_irq()
369358
{
370-
SerialBase::attach(callback(this, &UARTSerial::tx_irq), TxIrq);
371-
_tx_irq_enabled = true;
359+
core_util_critical_section_enter();
360+
if (_tx_enabled && !_tx_irq_enabled) {
361+
UARTSerial::tx_irq();
362+
if (!_txbuf.empty()) {
363+
SerialBase::attach(callback(this, &UARTSerial::tx_irq), TxIrq);
364+
_tx_irq_enabled = true;
365+
}
366+
}
367+
core_util_critical_section_exit();
372368
}
373369

370+
/* This is called called from critical section or interrupt context */
374371
void UARTSerial::disable_tx_irq()
375372
{
376373
SerialBase::attach(NULL, TxIrq);
@@ -381,6 +378,7 @@ int UARTSerial::enable_input(bool enabled)
381378
{
382379
api_lock();
383380
SerialBase::enable_input(enabled);
381+
update_rx_irq(); // Eventually enable rx-interrupt to handle incoming data
384382
api_unlock();
385383

386384
return 0;
@@ -390,6 +388,7 @@ int UARTSerial::enable_output(bool enabled)
390388
{
391389
api_lock();
392390
SerialBase::enable_output(enabled);
391+
update_tx_irq(); // Eventually enable tx-interrupt to flush buffered data
393392
api_unlock();
394393

395394
return 0;

0 commit comments

Comments
 (0)