Skip to content

[STM32Fxx] Add Serial Flow Control #2095

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions hal/targets.json
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@
"inherits": ["Target"],
"progen": {"target": "nucleo-f030r8"},
"detect_code": ["0725"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "LOWPOWERTIMER", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"default_build": "small"
},
"NUCLEO_F031K6": {
Expand Down Expand Up @@ -641,7 +641,7 @@
"inherits": ["Target"],
"progen": {"target": "nucleo-f103rb"},
"detect_code": ["0700"],
"device_has": ["ANALOGIN", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "CAN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"default_build": "small"
},
"NUCLEO_F302R8": {
Expand Down Expand Up @@ -713,7 +713,7 @@
"inherits": ["Target"],
"progen": {"target": "nucleo-f410rb"},
"detect_code": ["0740"],
"device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"default_build": "small"
},
"NUCLEO_F411RE": {
Expand All @@ -725,7 +725,7 @@
"inherits": ["Target"],
"progen": {"target": "nucleo-f411re"},
"detect_code": ["0740"],
"device_has": ["ANALOGIN", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"default_build": "small"
},
"ELMO_F411RE": {
Expand All @@ -748,7 +748,7 @@
"inherits": ["Target"],
"progen": {"target": "nucleo-f446re"},
"detect_code": ["0777"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"default_build": "small"
},
"B96B_F446VE": {
Expand Down Expand Up @@ -950,7 +950,7 @@
"extra_labels": ["STM", "STM32F4", "STM32F429", "STM32F429ZI"],
"supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"],
"progen": {"target": "disco-f429zi"},
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "RTC_LSI", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "RTC_LSI", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"default_build": "small"
},
"DISCO_F469NI": {
Expand All @@ -962,7 +962,7 @@
"inherits": ["Target"],
"progen": {"target": "disco-f469ni"},
"detect_code": ["0788"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "ERROR_RED", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES"],
"default_build": "small"
},
"DISCO_L053C8": {
Expand Down
2 changes: 2 additions & 0 deletions hal/targets/hal/TARGET_STM/TARGET_STM32F0/PeripheralPins.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ extern const PinMap PinMap_PWM[];

extern const PinMap PinMap_UART_TX[];
extern const PinMap PinMap_UART_RX[];
extern const PinMap PinMap_UART_RTS[];
extern const PinMap PinMap_UART_CTS[];

//*** SPI ***

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,20 @@ const PinMap PinMap_UART_RX[] = {
{NC, NC, 0}
};

const PinMap PinMap_UART_RTS[] = {
{PA_1, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_USART1)},
// {PA_1, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_USART2)},
{PA_12, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_USART1)},
{NC, NC, 0}
};

const PinMap PinMap_UART_CTS[] = {
{PA_0, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_USART1)},
// {PA_0, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_USART2)},
{PA_11, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF1_USART1)},
{NC, NC, 0}
};

//*** SPI ***

const PinMap PinMap_SPI_MOSI[] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ struct serial_s {
uint32_t parity;
PinName pin_tx;
PinName pin_rx;
#if DEVICE_SERIAL_FC
uint32_t hw_flow_ctl;
PinName pin_rts;
PinName pin_cts;
#endif
};

struct spi_s {
Expand Down
65 changes: 65 additions & 0 deletions hal/targets/hal/TARGET_STM/TARGET_STM32F0/serial_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,24 @@ UART_HandleTypeDef UartHandle;
int stdio_uart_inited = 0;
serial_t stdio_uart;

#if DEVICE_SERIAL_ASYNCH
#define SERIAL_OBJ(X) (obj->serial.X)
#else
#define SERIAL_OBJ(X) (obj->X)
#endif

static void init_uart(serial_t *obj) {
UartHandle.Instance = (USART_TypeDef *)(obj->uart);

UartHandle.Init.BaudRate = obj->baudrate;
UartHandle.Init.WordLength = obj->databits;
UartHandle.Init.StopBits = obj->stopbits;
UartHandle.Init.Parity = obj->parity;
#if DEVICE_SERIAL_FC
UartHandle.Init.HwFlowCtl = SERIAL_OBJ(hw_flow_ctl);
#else
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
#endif

if (obj->pin_rx == NC) {
UartHandle.Init.Mode = UART_MODE_TX;
Expand Down Expand Up @@ -521,4 +531,59 @@ void serial_break_clear(serial_t *obj) {
// [TODO]
}

#if DEVICE_SERIAL_FC
/** Set HW Control Flow
* @param obj The serial object
* @param type The Control Flow type (FlowControlNone, FlowControlRTS, FlowControlCTS, FlowControlRTSCTS)
* @param rxflow Pin for the rxflow
* @param txflow Pin for the txflow
*/
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
{

// Determine the UART to use (UART_1, UART_2, ...)
UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS);
UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS);

// Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
UARTName instance = (UARTName)pinmap_merge(uart_cts, uart_rts);

MBED_ASSERT(instance != (UARTName)NC);

if(type == FlowControlNone) {
// Disable hardware flow control
SERIAL_OBJ(hw_flow_ctl) = UART_HWCONTROL_NONE;
}
if (type == FlowControlRTS) {
// Enable RTS
MBED_ASSERT(uart_rts != (UARTName)NC);
SERIAL_OBJ(hw_flow_ctl) = UART_HWCONTROL_RTS;
SERIAL_OBJ(pin_rts) = rxflow;
// Enable the pin for RTS function
pinmap_pinout(rxflow, PinMap_UART_RTS);
}
if (type == FlowControlCTS) {
// Enable CTS
MBED_ASSERT(uart_cts != (UARTName)NC);
SERIAL_OBJ(hw_flow_ctl) = UART_HWCONTROL_CTS;
SERIAL_OBJ(pin_cts) = txflow;
// Enable the pin for CTS function
pinmap_pinout(txflow, PinMap_UART_CTS);
}
if (type == FlowControlRTSCTS) {
// Enable CTS & RTS
MBED_ASSERT(uart_rts != (UARTName)NC);
MBED_ASSERT(uart_cts != (UARTName)NC);
SERIAL_OBJ(hw_flow_ctl) = UART_HWCONTROL_RTS_CTS;
SERIAL_OBJ(pin_rts) = rxflow;
SERIAL_OBJ(pin_cts) = txflow;
// Enable the pin for CTS function
pinmap_pinout(txflow, PinMap_UART_CTS);
// Enable the pin for RTS function
pinmap_pinout(rxflow, PinMap_UART_RTS);
}
init_uart(obj);
}
#endif // DEVICE_SERIAL_FC

#endif
2 changes: 2 additions & 0 deletions hal/targets/hal/TARGET_STM/TARGET_STM32F1/PeripheralPins.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ extern const PinMap PinMap_PWM[];

extern const PinMap PinMap_UART_TX[];
extern const PinMap PinMap_UART_RX[];
extern const PinMap PinMap_UART_RTS[];
extern const PinMap PinMap_UART_CTS[];

//*** SPI ***

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,20 @@ const PinMap PinMap_UART_RX[] = {
{NC, NC, 0}
};

const PinMap PinMap_UART_RTS[] = {
{PA_1, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, 0)},
{PA_12, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, 0)},
{PB_14, UART_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, 0)},
{NC, NC, 0}
};

const PinMap PinMap_UART_CTS[] = {
{PA_0, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, 0)},
{PA_11, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, 0)},
{PB_13, UART_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, 0)},
{NC, NC, 0}
};

//*** SPI ***

const PinMap PinMap_SPI_MOSI[] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ struct serial_s {
uint32_t parity;
PinName pin_tx;
PinName pin_rx;
#if DEVICE_SERIAL_FC
uint32_t hw_flow_ctl;
PinName pin_rts;
PinName pin_cts;
#endif
};

struct spi_s {
Expand Down
77 changes: 71 additions & 6 deletions hal/targets/hal/TARGET_STM/TARGET_STM32F1/serial_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@

#define UART_NUM (3)

#if DEVICE_SERIAL_ASYNCH
#define SERIAL_OBJ(X) (obj->serial.X)
#else
#define SERIAL_OBJ(X) (obj->X)
#endif

static uint32_t serial_irq_ids[UART_NUM] = {0, 0, 0};

static uart_irq_handler irq_handler;
Expand All @@ -57,7 +63,11 @@ static void init_uart(serial_t *obj)
UartHandle.Init.WordLength = obj->databits;
UartHandle.Init.StopBits = obj->stopbits;
UartHandle.Init.Parity = obj->parity;
#if DEVICE_SERIAL_FC
UartHandle.Init.HwFlowCtl = SERIAL_OBJ(hw_flow_ctl);
#else
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
#endif

if (obj->pin_rx == NC) {
UartHandle.Init.Mode = UART_MODE_TX;
Expand All @@ -83,20 +93,20 @@ void serial_init(serial_t *obj, PinName tx, PinName rx)

// Enable UART clock
if (obj->uart == UART_1) {
__USART1_FORCE_RESET();
__USART1_RELEASE_RESET();
__USART1_FORCE_RESET();
__USART1_RELEASE_RESET();
__HAL_RCC_USART1_CLK_ENABLE();
obj->index = 0;
}
if (obj->uart == UART_2) {
__USART2_FORCE_RESET();
__USART2_RELEASE_RESET();
__USART2_FORCE_RESET();
__USART2_RELEASE_RESET();
__HAL_RCC_USART2_CLK_ENABLE();
obj->index = 1;
}
if (obj->uart == UART_3) {
__USART3_FORCE_RESET();
__USART3_RELEASE_RESET();
__USART3_FORCE_RESET();
__USART3_RELEASE_RESET();
__HAL_RCC_USART3_CLK_ENABLE();
obj->index = 2;
}
Expand Down Expand Up @@ -350,4 +360,59 @@ void serial_break_clear(serial_t *obj)
{
}

#if DEVICE_SERIAL_FC
/** Set HW Control Flow
* @param obj The serial object
* @param type The Control Flow type (FlowControlNone, FlowControlRTS, FlowControlCTS, FlowControlRTSCTS)
* @param rxflow Pin for the rxflow
* @param txflow Pin for the txflow
*/
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow)
{

// Determine the UART to use (UART_1, UART_2, ...)
UARTName uart_rts = (UARTName)pinmap_peripheral(rxflow, PinMap_UART_RTS);
UARTName uart_cts = (UARTName)pinmap_peripheral(txflow, PinMap_UART_CTS);

// Get the peripheral name (UART_1, UART_2, ...) from the pin and assign it to the object
UARTName instance = (UARTName)pinmap_merge(uart_cts, uart_rts);

MBED_ASSERT(instance != (UARTName)NC);

if(type == FlowControlNone) {
// Disable hardware flow control
SERIAL_OBJ(hw_flow_ctl) = UART_HWCONTROL_NONE;
}
if (type == FlowControlRTS) {
// Enable RTS
MBED_ASSERT(uart_rts != (UARTName)NC);
SERIAL_OBJ(hw_flow_ctl) = UART_HWCONTROL_RTS;
SERIAL_OBJ(pin_rts) = rxflow;
// Enable the pin for RTS function
pinmap_pinout(rxflow, PinMap_UART_RTS);
}
if (type == FlowControlCTS) {
// Enable CTS
MBED_ASSERT(uart_cts != (UARTName)NC);
SERIAL_OBJ(hw_flow_ctl) = UART_HWCONTROL_CTS;
SERIAL_OBJ(pin_cts) = txflow;
// Enable the pin for CTS function
pinmap_pinout(txflow, PinMap_UART_CTS);
}
if (type == FlowControlRTSCTS) {
// Enable CTS & RTS
MBED_ASSERT(uart_rts != (UARTName)NC);
MBED_ASSERT(uart_cts != (UARTName)NC);
SERIAL_OBJ(hw_flow_ctl) = UART_HWCONTROL_RTS_CTS;
SERIAL_OBJ(pin_rts) = rxflow;
SERIAL_OBJ(pin_cts) = txflow;
// Enable the pin for CTS function
pinmap_pinout(txflow, PinMap_UART_CTS);
// Enable the pin for RTS function
pinmap_pinout(rxflow, PinMap_UART_RTS);
}
init_uart(obj);
}
#endif // DEVICE_SERIAL_FC

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,28 @@ const PinMap PinMap_UART_RX[] = {
{NC, NC, 0}
};

const PinMap PinMap_UART_RTS[] = {
// {PA_1, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, // Connected to MEMS
{PA_12, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
// {PB_14, UART_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)}, // Connected to USB
{PD_4, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{PD_12, UART_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
{PG_8, UART_6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
{PG_12, UART_6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
{NC, NC, 0}
};

const PinMap PinMap_UART_CTS[] = {
// {PA_0, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)}, // Connected to BUTTON
{PA_11, UART_1, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART1)},
{PB_13, UART_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
{PD_3, UART_2, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART2)},
{PD_11, UART_3, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF7_USART3)},
// {PG_13, UART_6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)}, // Connected to LED
{PG_15, UART_6, STM_PIN_DATA(STM_MODE_AF_PP, GPIO_PULLUP, GPIO_AF8_USART6)},
{NC, NC, 0}
};

//*** SPI ***

const PinMap PinMap_SPI_MOSI[] = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ struct serial_s {
uint32_t parity;
PinName pin_tx;
PinName pin_rx;
#if DEVICE_SERIAL_FC
uint32_t hw_flow_ctl;
PinName pin_rts;
PinName pin_cts;
#endif
};

struct spi_s {
Expand Down
Loading