Skip to content

Commit 160342b

Browse files
committed
static pin-map - patch for SerialBase class
Related PR: #10924 The above PR adds functions to disable/enable serial input/output. If both serial input and serial output are disabled, the peripheral is freed. If either serial input or serial output is re-enabled, the peripheral is reinitialized. I missed this change while working on the static pinmap and unfortunately it has an impact on it. The reinitialization is a problem for static pinmap. Now the HAL init()/init_direct() function is called not only in the constructor (but also when re-enabling the peripheral). In the current version, even if static pinmap constructor was used to create an object (and init_direct() HAL API), when reinitialization is done it uses init() HAL API. This must be split. If static pinmap constructor is used, then the peripheral must be always initialized using HAL init_direct() function. If regular the constructor is used, then the peripheral must be initialized using HAL init() function. The same split also must be done while setting flow control during reinitialization.
1 parent e2a11c0 commit 160342b

File tree

2 files changed

+41
-19
lines changed

2 files changed

+41
-19
lines changed

drivers/SerialBase.h

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,9 @@ class SerialBase : private NonCopyable<SerialBase> {
330330
/** Initialize serial port
331331
*/
332332
void _init();
333+
void _init_direct();
334+
/* Pointer to serial init function */
335+
void (SerialBase::*_init_func)();
333336

334337
/** Deinitialize serial port
335338
*/
@@ -345,18 +348,20 @@ class SerialBase : private NonCopyable<SerialBase> {
345348
bool _rx_asynch_set = false;
346349
#endif
347350

348-
serial_t _serial {};
349-
Callback<void()> _irq[IrqCnt];
350-
int _baud;
351-
bool _rx_enabled = true;
352-
bool _tx_enabled = true;
353-
const PinName _tx_pin;
354-
const PinName _rx_pin;
351+
serial_t _serial {};
352+
Callback<void()> _irq[IrqCnt];
353+
int _baud;
354+
bool _rx_enabled = true;
355+
bool _tx_enabled = true;
356+
const PinName _tx_pin;
357+
const PinName _rx_pin;
358+
const serial_pinmap_t *_static_pinmap = NULL;
355359

356360
#if DEVICE_SERIAL_FC
357-
Flow _flow_type = Disabled;
358-
PinName _flow1 = NC;
359-
PinName _flow2 = NC;
361+
Flow _flow_type = Disabled;
362+
PinName _flow1 = NC;
363+
PinName _flow2 = NC;
364+
const serial_fc_pinmap_t *_static_pinmap_fc = NULL;
360365
#endif
361366

362367
#endif

drivers/source/SerialBase.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,16 @@ SerialBase::SerialBase(PinName tx, PinName rx, int baud) :
2929
#endif
3030
_baud(baud),
3131
_tx_pin(tx),
32-
_rx_pin(rx)
32+
_rx_pin(rx),
33+
_init_func(&SerialBase::_init)
3334
{
3435
// No lock needed in the constructor
3536

3637
for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
3738
_irq[i] = NULL;
3839
}
3940

40-
_init();
41+
(this->*_init_func)();
4142
}
4243

4344
SerialBase::SerialBase(const serial_pinmap_t &static_pinmap, int baud) :
@@ -50,17 +51,17 @@ SerialBase::SerialBase(const serial_pinmap_t &static_pinmap, int baud) :
5051
_serial(),
5152
_baud(baud),
5253
_tx_pin(static_pinmap.tx_pin),
53-
_rx_pin(static_pinmap.rx_pin)
54+
_rx_pin(static_pinmap.rx_pin),
55+
_static_pinmap(&static_pinmap),
56+
_init_func(&SerialBase::_init_direct)
5457
{
5558
// No lock needed in the constructor
5659

5760
for (size_t i = 0; i < sizeof _irq / sizeof _irq[0]; i++) {
5861
_irq[i] = NULL;
5962
}
6063

61-
serial_init_direct(&_serial, &static_pinmap);
62-
serial_baud(&_serial, _baud);
63-
serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
64+
(this->*_init_func)();
6465
}
6566

6667
void SerialBase::baud(int baudrate)
@@ -156,6 +157,18 @@ void SerialBase::_init()
156157
serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
157158
}
158159

160+
void SerialBase::_init_direct()
161+
{
162+
serial_init_direct(&_serial, _static_pinmap);
163+
#if DEVICE_SERIAL_FC
164+
if (_static_pinmap_fc) {
165+
set_flow_control(_flow_type, *_static_pinmap_fc);
166+
}
167+
#endif
168+
serial_baud(&_serial, _baud);
169+
serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
170+
}
171+
159172
void SerialBase::_deinit()
160173
{
161174
serial_free(&_serial);
@@ -166,7 +179,7 @@ void SerialBase::enable_input(bool enable)
166179
lock();
167180
if (_rx_enabled != enable) {
168181
if (enable && !_tx_enabled) {
169-
_init();
182+
(this->*_init_func)();
170183
}
171184

172185
core_util_critical_section_enter();
@@ -203,7 +216,7 @@ void SerialBase::enable_output(bool enable)
203216
lock();
204217
if (_tx_enabled != enable) {
205218
if (enable && !_rx_enabled) {
206-
_init();
219+
(this->*_init_func)();
207220
}
208221

209222
core_util_critical_section_enter();
@@ -289,6 +302,7 @@ SerialBase::~SerialBase()
289302
#if DEVICE_SERIAL_FC
290303
void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2)
291304
{
305+
MBED_ASSERT(_static_pinmap == NULL); // this function must be used when serial object has been created using dynamic pin-map constructor
292306
lock();
293307

294308
_flow_type = type;
@@ -318,9 +332,12 @@ void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2)
318332

319333
void SerialBase::set_flow_control(Flow type, const serial_fc_pinmap_t &static_pinmap)
320334
{
335+
MBED_ASSERT(_static_pinmap != NULL); // this function must be used when serial object has been created using static pin-map constructor
321336
lock();
337+
_static_pinmap_fc = &static_pinmap;
338+
_flow_type = type;
322339
FlowControl flow_type = (FlowControl)type;
323-
serial_set_flow_control_direct(&_serial, flow_type, &static_pinmap);
340+
serial_set_flow_control_direct(&_serial, flow_type, _static_pinmap_fc);
324341
unlock();
325342
}
326343
#endif

0 commit comments

Comments
 (0)