Skip to content

Commit

Permalink
static pin-map - patch for SerialBase class
Browse files Browse the repository at this point in the history
Related PR:

ARMmbed#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.
  • Loading branch information
mprse committed Dec 9, 2019
1 parent b14f495 commit 465329c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 19 deletions.
25 changes: 15 additions & 10 deletions drivers/SerialBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,9 @@ class SerialBase : private NonCopyable<SerialBase> {
/** Initialize serial port
*/
void _init();
void _init_direct();
/* Pointer to serial init function */
void (SerialBase::*_init_func)();

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

serial_t _serial {};
Callback<void()> _irq[IrqCnt];
int _baud;
bool _rx_enabled = true;
bool _tx_enabled = true;
const PinName _tx_pin;
const PinName _rx_pin;
serial_t _serial {};
Callback<void()> _irq[IrqCnt];
int _baud;
bool _rx_enabled = true;
bool _tx_enabled = true;
const PinName _tx_pin;
const PinName _rx_pin;
const serial_pinmap_t *_static_pinmap = NULL;

#if DEVICE_SERIAL_FC
Flow _flow_type = Disabled;
PinName _flow1 = NC;
PinName _flow2 = NC;
Flow _flow_type = Disabled;
PinName _flow1 = NC;
PinName _flow2 = NC;
const serial_fc_pinmap_t *_static_pinmap_fc = NULL;
#endif

#endif
Expand Down
35 changes: 26 additions & 9 deletions drivers/source/SerialBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,16 @@ SerialBase::SerialBase(PinName tx, PinName rx, int baud) :
#endif
_baud(baud),
_tx_pin(tx),
_rx_pin(rx)
_rx_pin(rx),
_init_func(&SerialBase::_init)
{
// No lock needed in the constructor

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

_init();
(this->*_init_func)();
}

SerialBase::SerialBase(const serial_pinmap_t &static_pinmap, int baud) :
Expand All @@ -50,17 +51,17 @@ SerialBase::SerialBase(const serial_pinmap_t &static_pinmap, int baud) :
_serial(),
_baud(baud),
_tx_pin(static_pinmap.tx_pin),
_rx_pin(static_pinmap.rx_pin)
_rx_pin(static_pinmap.rx_pin),
_static_pinmap(&static_pinmap),
_init_func(&SerialBase::_init_direct)
{
// No lock needed in the constructor

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

serial_init_direct(&_serial, &static_pinmap);
serial_baud(&_serial, _baud);
serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
(this->*_init_func)();
}

void SerialBase::baud(int baudrate)
Expand Down Expand Up @@ -156,6 +157,18 @@ void SerialBase::_init()
serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
}

void SerialBase::_init_direct()
{
serial_init_direct(&_serial, _static_pinmap);
#if DEVICE_SERIAL_FC
if (_static_pinmap_fc) {
set_flow_control(_flow_type, *_static_pinmap_fc);
}
#endif
serial_baud(&_serial, _baud);
serial_irq_handler(&_serial, SerialBase::_irq_handler, (uint32_t)this);
}

void SerialBase::_deinit()
{
serial_free(&_serial);
Expand All @@ -166,7 +179,7 @@ void SerialBase::enable_input(bool enable)
lock();
if (_rx_enabled != enable) {
if (enable && !_tx_enabled) {
_init();
(this->*_init_func)();
}

core_util_critical_section_enter();
Expand Down Expand Up @@ -203,7 +216,7 @@ void SerialBase::enable_output(bool enable)
lock();
if (_tx_enabled != enable) {
if (enable && !_rx_enabled) {
_init();
(this->*_init_func)();
}

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

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

void SerialBase::set_flow_control(Flow type, const serial_fc_pinmap_t &static_pinmap)
{
MBED_ASSERT(_static_pinmap != NULL); // this function must be used when serial object has been created using static pin-map constructor
lock();
_static_pinmap_fc = &static_pinmap;
_flow_type = type;
FlowControl flow_type = (FlowControl)type;
serial_set_flow_control_direct(&_serial, flow_type, &static_pinmap);
serial_set_flow_control_direct(&_serial, flow_type, _static_pinmap_fc);
unlock();
}
#endif
Expand Down

0 comments on commit 465329c

Please sign in to comment.