Skip to content

Commit 3d2bebd

Browse files
committed
STM32 serial driver: Add explicit pinmap support
1 parent e82e190 commit 3d2bebd

File tree

2 files changed

+96
-48
lines changed

2 files changed

+96
-48
lines changed

targets/TARGET_STM/TARGET_STM32F4/serial_device.c

Lines changed: 53 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -725,57 +725,87 @@ void serial_rx_abort_asynch(serial_t *obj)
725725
* Set HW Control Flow
726726
* @param obj The serial object
727727
* @param type The Control Flow type (FlowControlNone, FlowControlRTS, FlowControlCTS, FlowControlRTSCTS)
728-
* @param rxflow Pin for the rxflow
729-
* @param txflow Pin for the txflow
728+
* @param pinmap Pointer to strucure which holds static pinmap
730729
*/
731-
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
730+
#if EXPLICIT_PINMAP_READY
731+
#define SERIAL_SET_FC_DIRECT serial_set_flow_control_direct
732+
void serial_set_flow_control_direct(serial_t *obj, FlowControl type, const serial_fc_pinmap_t *pinmap)
733+
#else
734+
#define SERIAL_SET_FC_DIRECT _serial_set_flow_control_direct
735+
static void _serial_set_flow_control_direct(serial_t *obj, FlowControl type, const serial_fc_pinmap_t *pinmap)
736+
#endif
732737
{
733738
struct serial_s *obj_s = SERIAL_S(obj);
734739

735-
// Checked used UART name (UART_1, UART_2, ...)
736-
UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS);
737-
UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS);
738-
if (((UARTName)pinmap_merge(uart_rts, obj_s->uart) == (UARTName)NC) || ((UARTName)pinmap_merge(uart_cts, obj_s->uart) == (UARTName)NC)) {
739-
MBED_ASSERT(0);
740-
return;
741-
}
742-
743740
if (type == FlowControlNone) {
744741
// Disable hardware flow control
745742
obj_s->hw_flow_ctl = UART_HWCONTROL_NONE;
746743
}
747744
if (type == FlowControlRTS) {
748745
// Enable RTS
749-
MBED_ASSERT(uart_rts != (UARTName)NC);
746+
MBED_ASSERT(pinmap->rx_flow_pin != (UARTName)NC);
750747
obj_s->hw_flow_ctl = UART_HWCONTROL_RTS;
751-
obj_s->pin_rts = rxflow;
748+
obj_s->pin_rts = pinmap->rx_flow_pin;
752749
// Enable the pin for RTS function
753-
pinmap_pinout(rxflow, PinMap_UART_RTS);
750+
pin_function(pinmap->rx_flow_pin, pinmap->rx_flow_function);
751+
pin_mode(pinmap->rx_flow_pin, PullNone);
754752
}
755753
if (type == FlowControlCTS) {
756754
// Enable CTS
757-
MBED_ASSERT(uart_cts != (UARTName)NC);
755+
MBED_ASSERT(pinmap->tx_flow_pin != (UARTName)NC);
758756
obj_s->hw_flow_ctl = UART_HWCONTROL_CTS;
759-
obj_s->pin_cts = txflow;
757+
obj_s->pin_cts = pinmap->tx_flow_pin;
760758
// Enable the pin for CTS function
761-
pinmap_pinout(txflow, PinMap_UART_CTS);
759+
pin_function(pinmap->tx_flow_pin, pinmap->tx_flow_function);
760+
pin_mode(pinmap->tx_flow_pin, PullNone);
762761
}
763762
if (type == FlowControlRTSCTS) {
764763
// Enable CTS & RTS
765-
MBED_ASSERT(uart_rts != (UARTName)NC);
766-
MBED_ASSERT(uart_cts != (UARTName)NC);
764+
MBED_ASSERT(pinmap->rx_flow_pin != (UARTName)NC);
765+
MBED_ASSERT(pinmap->tx_flow_pin != (UARTName)NC);
767766
obj_s->hw_flow_ctl = UART_HWCONTROL_RTS_CTS;
768-
obj_s->pin_rts = rxflow;
769-
obj_s->pin_cts = txflow;
767+
obj_s->pin_rts = pinmap->rx_flow_pin;;
768+
obj_s->pin_cts = pinmap->tx_flow_pin;;
770769
// Enable the pin for CTS function
771-
pinmap_pinout(txflow, PinMap_UART_CTS);
770+
pin_function(pinmap->tx_flow_pin, pinmap->tx_flow_function);
771+
pin_mode(pinmap->tx_flow_pin, PullNone);
772772
// Enable the pin for RTS function
773-
pinmap_pinout(rxflow, PinMap_UART_RTS);
773+
pin_function(pinmap->rx_flow_pin, pinmap->rx_flow_function);
774+
pin_mode(pinmap->rx_flow_pin, PullNone);
774775
}
775776

776777
init_uart(obj);
777778
}
778779

780+
/**
781+
* Set HW Control Flow
782+
* @param obj The serial object
783+
* @param type The Control Flow type (FlowControlNone, FlowControlRTS, FlowControlCTS, FlowControlRTSCTS)
784+
* @param rxflow Pin for the rxflow
785+
* @param txflow Pin for the txflow
786+
*/
787+
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
788+
{
789+
struct serial_s *obj_s = SERIAL_S(obj);
790+
791+
UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS);
792+
UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS);
793+
794+
if (((UARTName)pinmap_merge(uart_rts, obj_s->uart) == (UARTName)NC) || ((UARTName)pinmap_merge(uart_cts, obj_s->uart) == (UARTName)NC)) {
795+
MBED_ASSERT(0);
796+
return;
797+
}
798+
799+
int peripheral = (int)pinmap_merge(uart_rts, uart_cts);
800+
801+
int tx_flow_function = (int)pinmap_find_function(txflow, PinMap_UART_CTS);
802+
int rx_flow_function = (int)pinmap_find_function(rxflow, PinMap_UART_RTS);
803+
804+
const serial_fc_pinmap_t explicit_uart_fc_pinmap = {peripheral, txflow, tx_flow_function, rxflow, rx_flow_function};
805+
806+
SERIAL_SET_FC_DIRECT(obj, type, &explicit_uart_fc_pinmap);
807+
}
808+
779809
#endif /* DEVICE_SERIAL_FC */
780810

781811
#endif /* DEVICE_SERIAL */

targets/TARGET_STM/serial_api.c

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -47,27 +47,20 @@ extern uint32_t serial_irq_ids[];
4747
HAL_StatusTypeDef init_uart(serial_t *obj);
4848
int8_t get_uart_index(UARTName uart_name);
4949

50-
void serial_init(serial_t *obj, PinName tx, PinName rx)
50+
#if EXPLICIT_PINMAP_READY
51+
#define SERIAL_INIT_DIRECT serial_init_direct
52+
void serial_init_direct(serial_t *obj, const serial_pinmap_t *pinmap)
53+
#else
54+
#define SERIAL_INIT_DIRECT _serial_init_direct
55+
static void _serial_init_direct(serial_t *obj, const serial_pinmap_t *pinmap)
56+
#endif
5157
{
5258
struct serial_s *obj_s = SERIAL_S(obj);
53-
uint8_t stdio_config = 0;
54-
55-
// Determine the UART to use (UART_1, UART_2, ...)
56-
UARTName uart_tx = (UARTName)pinmap_peripheral(tx, PinMap_UART_TX);
57-
UARTName uart_rx = (UARTName)pinmap_peripheral(rx, PinMap_UART_RX);
5859

5960
// Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
60-
obj_s->uart = (UARTName)pinmap_merge(uart_tx, uart_rx);
61+
obj_s->uart = (UARTName)pinmap->peripheral;
6162
MBED_ASSERT(obj_s->uart != (UARTName)NC);
6263

63-
if ((tx == STDIO_UART_TX) || (rx == STDIO_UART_RX)) {
64-
stdio_config = 1;
65-
} else {
66-
if (uart_tx == pinmap_peripheral(STDIO_UART_TX, PinMap_UART_TX)) {
67-
error("Error: new serial object is using same UART as STDIO");
68-
}
69-
}
70-
7164
// Reset and enable clock
7265
#if defined(USART1_BASE)
7366
if (obj_s->uart == UART_1) {
@@ -164,19 +157,19 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
164157
MBED_ASSERT(obj_s->index >= 0);
165158

166159
// Configure UART pins
167-
pinmap_pinout(tx, PinMap_UART_TX);
168-
pinmap_pinout(rx, PinMap_UART_RX);
160+
pin_function(pinmap->tx_pin, pinmap->tx_function);
161+
pin_function(pinmap->rx_pin, pinmap->rx_function);
169162

170-
if (tx != NC) {
171-
pin_mode(tx, PullUp);
163+
if (pinmap->tx_pin != NC) {
164+
pin_mode(pinmap->tx_pin, PullUp);
172165
}
173-
if (rx != NC) {
174-
pin_mode(rx, PullUp);
166+
if (pinmap->rx_pin != NC) {
167+
pin_mode(pinmap->rx_pin, PullUp);
175168
}
176169

177170
// Configure UART
178171
obj_s->baudrate = 9600; // baudrate default value
179-
if (stdio_config) {
172+
if (pinmap->stdio_config) {
180173
#if MBED_CONF_PLATFORM_STDIO_BAUD_RATE
181174
obj_s->baudrate = MBED_CONF_PLATFORM_STDIO_BAUD_RATE; // baudrate takes value from platform/mbed_lib.json
182175
#endif /* MBED_CONF_PLATFORM_STDIO_BAUD_RATE */
@@ -193,18 +186,43 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)
193186
obj_s->hw_flow_ctl = UART_HWCONTROL_NONE;
194187
#endif
195188

196-
obj_s->pin_tx = tx;
197-
obj_s->pin_rx = rx;
189+
obj_s->pin_tx = pinmap->tx_pin;
190+
obj_s->pin_rx = pinmap->rx_pin;
198191

199192
init_uart(obj); /* init_uart will be called again in serial_baud function, so don't worry if init_uart returns HAL_ERROR */
200193

201194
// For stdio management in platform/mbed_board.c and platform/mbed_retarget.cpp
202-
if (stdio_config) {
195+
if (pinmap->stdio_config) {
203196
stdio_uart_inited = 1;
204197
memcpy(&stdio_uart, obj, sizeof(serial_t));
205198
}
206199
}
207200

201+
void serial_init(serial_t *obj, PinName tx, PinName rx)
202+
{
203+
uint32_t uart_tx = pinmap_peripheral(tx, PinMap_UART_TX);
204+
uint32_t uart_rx = pinmap_peripheral(rx, PinMap_UART_RX);
205+
206+
int peripheral = (int)pinmap_merge(uart_tx, uart_rx);
207+
208+
int tx_function = (int)pinmap_find_function(tx, PinMap_UART_TX);
209+
int rx_function = (int)pinmap_find_function(rx, PinMap_UART_RX);
210+
211+
uint8_t stdio_config = false;
212+
213+
if ((tx == STDIO_UART_TX) || (rx == STDIO_UART_RX)) {
214+
stdio_config = true;
215+
} else {
216+
if (uart_tx == pinmap_peripheral(STDIO_UART_TX, PinMap_UART_TX)) {
217+
error("Error: new serial object is using same UART as STDIO");
218+
}
219+
}
220+
221+
const serial_pinmap_t explicit_uart_pinmap = {peripheral, tx, tx_function, rx, rx_function, stdio_config};
222+
223+
SERIAL_INIT_DIRECT(obj, &explicit_uart_pinmap);
224+
}
225+
208226
void serial_free(serial_t *obj)
209227
{
210228
struct serial_s *obj_s = SERIAL_S(obj);

0 commit comments

Comments
 (0)