static pin-map - patch for SerialBase class

Related PR:

https://github.com/ARMmbed/mbed-os/pull/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.
pull/12033/head
Przemyslaw Stekiel 2019-12-05 09:48:56 +01:00
parent e2a11c0297
commit 160342b2d0
2 changed files with 41 additions and 19 deletions

View File

@ -330,6 +330,9 @@ protected:
/** Initialize serial port
*/
void _init();
void _init_direct();
/* Pointer to serial init function */
void (SerialBase::*_init_func)();
/** Deinitialize serial port
*/
@ -345,18 +348,20 @@ protected:
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

View File

@ -29,7 +29,8 @@ 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
@ -37,7 +38,7 @@ SerialBase::SerialBase(PinName tx, PinName rx, int baud) :
_irq[i] = NULL;
}
_init();
(this->*_init_func)();
}
SerialBase::SerialBase(const serial_pinmap_t &static_pinmap, int baud) :
@ -50,7 +51,9 @@ 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
@ -58,9 +61,7 @@ SerialBase::SerialBase(const serial_pinmap_t &static_pinmap, int baud) :
_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)
@ -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);
@ -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();
@ -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();
@ -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;
@ -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