Skip to content

Commit e218b5d

Browse files
author
Sebastian Stockhammer
committed
Free serial resources if not needed anymore
1 parent acf576a commit e218b5d

File tree

3 files changed

+104
-30
lines changed

3 files changed

+104
-30
lines changed

drivers/SerialBase.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,30 @@ class SerialBase : private NonCopyable<SerialBase> {
295295

296296
int _base_putc(int c);
297297

298+
/** Initialize serial port
299+
*/
300+
void _init();
301+
302+
/** Deinitialize serial port
303+
*/
304+
void _deinit();
305+
306+
/** Enable serial input
307+
*
308+
* If both serial input and serial output are disabled, the
309+
* peripheral is freed. If either serial input or serial
310+
* output is re-enabled, the peripheral is reinitialized.
311+
*/
312+
void _enable_input(bool enable = true);
313+
314+
/** Enable serial output
315+
*
316+
* If both serial input and serial output are disabled, the
317+
* peripheral is freed. If either serial input or serial
318+
* output is re-enabled, the peripheral is reinitialized.
319+
*/
320+
void _enable_output(bool enable = true);
321+
298322
#if DEVICE_SERIAL_ASYNCH
299323
CThunk<SerialBase> _thunk_irq;
300324
DMAUsage _tx_usage;
@@ -308,6 +332,10 @@ class SerialBase : private NonCopyable<SerialBase> {
308332
serial_t _serial;
309333
Callback<void()> _irq[IrqCnt];
310334
int _baud;
335+
bool _rx_enabled;
336+
bool _tx_enabled;
337+
const PinName _tx_pin;
338+
const PinName _rx_pin;
311339
#endif
312340
};
313341

drivers/source/SerialBase.cpp

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,15 @@ SerialBase::SerialBase(PinName tx, PinName rx, int baud) :
3030
_rx_callback(NULL), _tx_asynch_set(false),
3131
_rx_asynch_set(false),
3232
#endif
33-
_serial(), _baud(baud)
33+
_serial(), _baud(baud), _rx_enabled(true), _tx_enabled(true), _tx_pin(tx), _rx_pin(rx)
3434
{
3535
// No lock needed in the constructor
3636

3737
for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
3838
_irq[i] = NULL;
3939
}
4040

41-
serial_init(&_serial, tx, rx);
42-
serial_baud(&_serial, _baud);
43-
serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
41+
_init();
4442
}
4543

4644
void SerialBase::baud(int baudrate)
@@ -120,6 +118,74 @@ int SerialBase::_base_putc(int c)
120118
return c;
121119
}
122120

121+
void SerialBase::_init()
122+
{
123+
serial_init(&_serial, _tx_pin, _rx_pin);
124+
serial_baud(&_serial, _baud);
125+
serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
126+
}
127+
128+
void SerialBase::_deinit()
129+
{
130+
serial_free(&_serial);
131+
}
132+
133+
void SerialBase::_enable_input(bool enable)
134+
{
135+
if (_rx_enabled != enable) {
136+
if(enable && !_tx_enabled) {
137+
_init();
138+
}
139+
140+
core_util_critical_section_enter();
141+
if (enable) {
142+
// Enable rx IRQ if attached (indicated by rx IRQ callback not NULL)
143+
if(_irq[RxIrq]) {
144+
_irq[RxIrq].call();
145+
serial_irq_set(&_serial, (SerialIrq)RxIrq, 1);
146+
}
147+
} else {
148+
// Disable rx IRQ
149+
serial_irq_set(&_serial, (SerialIrq)RxIrq, 0);
150+
}
151+
core_util_critical_section_exit();
152+
153+
_rx_enabled = enable;
154+
155+
if (!enable && !_tx_enabled) {
156+
_deinit();
157+
}
158+
}
159+
}
160+
161+
void SerialBase::_enable_output(bool enable)
162+
{
163+
if (_tx_enabled != enable) {
164+
if(enable && !_rx_enabled) {
165+
_init();
166+
}
167+
168+
core_util_critical_section_enter();
169+
if (enable) {
170+
// Enable tx IRQ if attached (indicated by tx IRQ callback not NULL)
171+
if(_irq[TxIrq]) {
172+
_irq[TxIrq].call();
173+
serial_irq_set(&_serial, (SerialIrq)TxIrq, 1);
174+
}
175+
} else {
176+
// Disable tx IRQ
177+
serial_irq_set(&_serial, (SerialIrq)TxIrq, 0);
178+
}
179+
core_util_critical_section_exit();
180+
181+
_tx_enabled = enable;
182+
183+
if (!enable && !_rx_enabled) {
184+
_deinit();
185+
}
186+
}
187+
}
188+
123189
void SerialBase::set_break()
124190
{
125191
lock();

drivers/source/UARTSerial.cpp

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -366,38 +366,18 @@ void UARTSerial::disable_tx_irq()
366366

367367
int UARTSerial::enable_input(bool enabled)
368368
{
369-
core_util_critical_section_enter();
370-
if (_rx_enabled != enabled) {
371-
if (enabled) {
372-
UARTSerial::rx_irq();
373-
if (!_rxbuf.full()) {
374-
enable_rx_irq();
375-
}
376-
} else {
377-
disable_rx_irq();
378-
}
379-
_rx_enabled = enabled;
380-
}
381-
core_util_critical_section_exit();
369+
api_lock();
370+
_enable_input(enabled);
371+
api_unlock();
382372

383373
return 0;
384374
}
385375

386376
int UARTSerial::enable_output(bool enabled)
387377
{
388-
core_util_critical_section_enter();
389-
if (_tx_enabled != enabled) {
390-
if (enabled) {
391-
UARTSerial::tx_irq();
392-
if (!_txbuf.empty()) {
393-
enable_tx_irq();
394-
}
395-
} else {
396-
disable_tx_irq();
397-
}
398-
_tx_enabled = enabled;
399-
}
400-
core_util_critical_section_exit();
378+
api_lock();
379+
_enable_input(enabled);
380+
api_unlock();
401381

402382
return 0;
403383
}

0 commit comments

Comments
 (0)