diff --git a/stmhal/boards/CERB40/mpconfigboard.h b/stmhal/boards/CERB40/mpconfigboard.h
index e6b68ebf39a0465e3d9120f364cacb349a77d349..dfff5c971681c4eeb968e3d7f22d12763ef97dba 100644
--- a/stmhal/boards/CERB40/mpconfigboard.h
+++ b/stmhal/boards/CERB40/mpconfigboard.h
@@ -25,6 +25,22 @@
 #define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2)
 #define MICROPY_HW_CLK_PLLQ (7)
 
+// UART config
+#define MICROPY_HW_UART1_PORT (GPIOA)
+#define MICROPY_HW_UART1_PINS (GPIO_PIN_9 | GPIO_PIN_10)
+#define MICROPY_HW_UART2_PORT (GPIOA)
+#define MICROPY_HW_UART2_PINS (GPIO_PIN_2 | GPIO_PIN_3)
+#define MICROPY_HW_UART2_RTS  (GPIO_PIN_1)
+#define MICROPY_HW_UART2_CTS  (GPIO_PIN_0)
+#define MICROPY_HW_UART3_PORT (GPIOD)
+#define MICROPY_HW_UART3_PINS (GPIO_PIN_8 | GPIO_PIN_9)
+#define MICROPY_HW_UART3_RTS  (GPIO_PIN_12)
+#define MICROPY_HW_UART3_CTS  (GPIO_PIN_11)
+#define MICROPY_HW_UART4_PORT (GPIOA)
+#define MICROPY_HW_UART4_PINS (GPIO_PIN_0 | GPIO_PIN_1)
+#define MICROPY_HW_UART6_PORT (GPIOC)
+#define MICROPY_HW_UART6_PINS (GPIO_PIN_6 | GPIO_PIN_7)
+
 // I2C busses
 #define MICROPY_HW_I2C1_SCL (pin_B6)
 #define MICROPY_HW_I2C1_SDA (pin_B7)
diff --git a/stmhal/boards/ESPRUINO_PICO/mpconfigboard.h b/stmhal/boards/ESPRUINO_PICO/mpconfigboard.h
index 7084d24189ca3b81d86f3ed4276e8aa732e6e4ac..221c0ab1fb451169bb9328ef8114e384291eb2e0 100644
--- a/stmhal/boards/ESPRUINO_PICO/mpconfigboard.h
+++ b/stmhal/boards/ESPRUINO_PICO/mpconfigboard.h
@@ -26,6 +26,16 @@
 // does not have a 32kHz crystal
 #define MICROPY_HW_RTC_USE_LSE      (0)
 
+// UART config
+#define MICROPY_HW_UART1_PORT (GPIOB)
+#define MICROPY_HW_UART1_PINS (GPIO_PIN_6 | GPIO_PIN_7)
+#define MICROPY_HW_UART2_PORT (GPIOA)
+#define MICROPY_HW_UART2_PINS (GPIO_PIN_2 | GPIO_PIN_3)
+#define MICROPY_HW_UART2_RTS  (GPIO_PIN_1)
+#define MICROPY_HW_UART2_CTS  (GPIO_PIN_0)
+#define MICROPY_HW_UART6_PORT (GPIOA)
+#define MICROPY_HW_UART6_PINS (GPIO_PIN_11 | GPIO_PIN_12)
+
 // I2C busses
 #define MICROPY_HW_I2C1_SCL (pin_B6)
 #define MICROPY_HW_I2C1_SDA (pin_B7)
diff --git a/stmhal/boards/HYDRABUS/mpconfigboard.h b/stmhal/boards/HYDRABUS/mpconfigboard.h
index ac89edb30917c32cc192c8ff3842ddec0b391271..79c4203793e985f1cdd73c44e7f3ac5ac9531e8b 100644
--- a/stmhal/boards/HYDRABUS/mpconfigboard.h
+++ b/stmhal/boards/HYDRABUS/mpconfigboard.h
@@ -24,6 +24,22 @@
 #define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2)
 #define MICROPY_HW_CLK_PLLQ (7)
 
+// UART config
+#define MICROPY_HW_UART1_PORT (GPIOA)
+#define MICROPY_HW_UART1_PINS (GPIO_PIN_9 | GPIO_PIN_10)
+#define MICROPY_HW_UART2_PORT (GPIOA)
+#define MICROPY_HW_UART2_PINS (GPIO_PIN_2 | GPIO_PIN_3)
+#define MICROPY_HW_UART2_RTS  (GPIO_PIN_1)
+#define MICROPY_HW_UART2_CTS  (GPIO_PIN_0)
+#define MICROPY_HW_UART3_PORT (GPIOD)
+#define MICROPY_HW_UART3_PINS (GPIO_PIN_8 | GPIO_PIN_9)
+#define MICROPY_HW_UART3_RTS  (GPIO_PIN_12)
+#define MICROPY_HW_UART3_CTS  (GPIO_PIN_11)
+#define MICROPY_HW_UART4_PORT (GPIOA)
+#define MICROPY_HW_UART4_PINS (GPIO_PIN_0 | GPIO_PIN_1)
+#define MICROPY_HW_UART6_PORT (GPIOC)
+#define MICROPY_HW_UART6_PINS (GPIO_PIN_6 | GPIO_PIN_7)
+
 // I2C busses
 #define MICROPY_HW_I2C1_SCL (pin_B6)
 #define MICROPY_HW_I2C1_SDA (pin_B7)
diff --git a/stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h b/stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h
index a985f52fdcde2ce5fb160c1c7cd0ec80e7f2ee90..fba726596b8250a4eda382cfad5435b3c31c57de 100644
--- a/stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h
+++ b/stmhal/boards/NETDUINO_PLUS_2/mpconfigboard.h
@@ -28,6 +28,22 @@
 #define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2)
 #define MICROPY_HW_CLK_PLLQ (7)
 
+// UART config
+#define MICROPY_HW_UART1_PORT (GPIOA)
+#define MICROPY_HW_UART1_PINS (GPIO_PIN_9 | GPIO_PIN_10)
+#define MICROPY_HW_UART2_PORT (GPIOA)
+#define MICROPY_HW_UART2_PINS (GPIO_PIN_2 | GPIO_PIN_3)
+#define MICROPY_HW_UART2_RTS  (GPIO_PIN_1)
+#define MICROPY_HW_UART2_CTS  (GPIO_PIN_0)
+#define MICROPY_HW_UART3_PORT (GPIOD)
+#define MICROPY_HW_UART3_PINS (GPIO_PIN_8 | GPIO_PIN_9)
+#define MICROPY_HW_UART3_RTS  (GPIO_PIN_12)
+#define MICROPY_HW_UART3_CTS  (GPIO_PIN_11)
+#define MICROPY_HW_UART4_PORT (GPIOA)
+#define MICROPY_HW_UART4_PINS (GPIO_PIN_0 | GPIO_PIN_1)
+#define MICROPY_HW_UART6_PORT (GPIOC)
+#define MICROPY_HW_UART6_PINS (GPIO_PIN_6 | GPIO_PIN_7)
+
 // I2C busses
 #define MICROPY_HW_I2C2_SCL (pin_B10)
 #define MICROPY_HW_I2C2_SDA (pin_B11)
diff --git a/stmhal/boards/PYBV10/mpconfigboard.h b/stmhal/boards/PYBV10/mpconfigboard.h
index ef4ad10e5e3ab94e504a612dcaf3d00ff625d9ac..7fe33894d4027dc839ae7b90547bf9a88d78abe2 100644
--- a/stmhal/boards/PYBV10/mpconfigboard.h
+++ b/stmhal/boards/PYBV10/mpconfigboard.h
@@ -28,6 +28,22 @@
 // The pyboard has a 32kHz crystal for the RTC
 #define MICROPY_HW_RTC_USE_LSE      (1)
 
+// UART config
+#define MICROPY_HW_UART1_PORT (GPIOB)
+#define MICROPY_HW_UART1_PINS (GPIO_PIN_6 | GPIO_PIN_7)
+#define MICROPY_HW_UART2_PORT (GPIOA)
+#define MICROPY_HW_UART2_PINS (GPIO_PIN_2 | GPIO_PIN_3)
+#define MICROPY_HW_UART2_RTS  (GPIO_PIN_1)
+#define MICROPY_HW_UART2_CTS  (GPIO_PIN_0)
+#define MICROPY_HW_UART3_PORT (GPIOB)
+#define MICROPY_HW_UART3_PINS (GPIO_PIN_10 | GPIO_PIN_11)
+#define MICROPY_HW_UART3_RTS  (GPIO_PIN_14)
+#define MICROPY_HW_UART3_CTS  (GPIO_PIN_13)
+#define MICROPY_HW_UART4_PORT (GPIOA)
+#define MICROPY_HW_UART4_PINS (GPIO_PIN_0 | GPIO_PIN_1)
+#define MICROPY_HW_UART6_PORT (GPIOC)
+#define MICROPY_HW_UART6_PINS (GPIO_PIN_6 | GPIO_PIN_7)
+
 // X-skin: X9=PB6=SCL, X10=PB7=SDA
 #define MICROPY_HW_I2C1_SCL (pin_B6)
 #define MICROPY_HW_I2C1_SDA (pin_B7)
diff --git a/stmhal/boards/PYBV3/mpconfigboard.h b/stmhal/boards/PYBV3/mpconfigboard.h
index d829b704a110b0762347eceae7187cd758bea14f..86daf0c3938eec2f30bfe68797fdd68dbb849520 100644
--- a/stmhal/boards/PYBV3/mpconfigboard.h
+++ b/stmhal/boards/PYBV3/mpconfigboard.h
@@ -27,6 +27,22 @@
 // The pyboard has a 32kHz crystal for the RTC
 #define MICROPY_HW_RTC_USE_LSE      (1)
 
+// UART config
+#define MICROPY_HW_UART1_PORT (GPIOA)
+#define MICROPY_HW_UART1_PINS (GPIO_PIN_9 | GPIO_PIN_10)
+#define MICROPY_HW_UART2_PORT (GPIOA)
+#define MICROPY_HW_UART2_PINS (GPIO_PIN_2 | GPIO_PIN_3)
+#define MICROPY_HW_UART2_RTS  (GPIO_PIN_1)
+#define MICROPY_HW_UART2_CTS  (GPIO_PIN_0)
+#define MICROPY_HW_UART3_PORT (GPIOB)
+#define MICROPY_HW_UART3_PINS (GPIO_PIN_10 | GPIO_PIN_11)
+#define MICROPY_HW_UART3_RTS  (GPIO_PIN_14)
+#define MICROPY_HW_UART3_CTS  (GPIO_PIN_13)
+#define MICROPY_HW_UART4_PORT (GPIOA)
+#define MICROPY_HW_UART4_PINS (GPIO_PIN_0 | GPIO_PIN_1)
+#define MICROPY_HW_UART6_PORT (GPIOC)
+#define MICROPY_HW_UART6_PINS (GPIO_PIN_6 | GPIO_PIN_7)
+
 // X-skin: X9=PB6=SCL, X10=PB7=SDA
 #define MICROPY_HW_I2C1_SCL (pin_B6)
 #define MICROPY_HW_I2C1_SDA (pin_B7)
diff --git a/stmhal/boards/PYBV4/mpconfigboard.h b/stmhal/boards/PYBV4/mpconfigboard.h
index 35bfca07b9f4ea3593263aa5902f1cf1d265d7bc..4c46052b2258e96423e10775c26df9bb810ca370 100644
--- a/stmhal/boards/PYBV4/mpconfigboard.h
+++ b/stmhal/boards/PYBV4/mpconfigboard.h
@@ -27,6 +27,22 @@
 // The pyboard has a 32kHz crystal for the RTC
 #define MICROPY_HW_RTC_USE_LSE      (1)
 
+// UART config
+#define MICROPY_HW_UART1_PORT (GPIOB)
+#define MICROPY_HW_UART1_PINS (GPIO_PIN_6 | GPIO_PIN_7)
+#define MICROPY_HW_UART2_PORT (GPIOA)
+#define MICROPY_HW_UART2_PINS (GPIO_PIN_2 | GPIO_PIN_3)
+#define MICROPY_HW_UART2_RTS  (GPIO_PIN_1)
+#define MICROPY_HW_UART2_CTS  (GPIO_PIN_0)
+#define MICROPY_HW_UART3_PORT (GPIOB)
+#define MICROPY_HW_UART3_PINS (GPIO_PIN_10 | GPIO_PIN_11)
+#define MICROPY_HW_UART3_RTS  (GPIO_PIN_14)
+#define MICROPY_HW_UART3_CTS  (GPIO_PIN_13)
+#define MICROPY_HW_UART4_PORT (GPIOA)
+#define MICROPY_HW_UART4_PINS (GPIO_PIN_0 | GPIO_PIN_1)
+#define MICROPY_HW_UART6_PORT (GPIOC)
+#define MICROPY_HW_UART6_PINS (GPIO_PIN_6 | GPIO_PIN_7)
+
 // X-skin: X9=PB6=SCL, X10=PB7=SDA
 #define MICROPY_HW_I2C1_SCL (pin_B6)
 #define MICROPY_HW_I2C1_SDA (pin_B7)
diff --git a/stmhal/boards/STM32F4DISC/mpconfigboard.h b/stmhal/boards/STM32F4DISC/mpconfigboard.h
index f22c1a2e8e560fd1d750f3628d31fcc5bff9bd90..30a05ef972b0e37233677a4d165ae2f425bdd975 100644
--- a/stmhal/boards/STM32F4DISC/mpconfigboard.h
+++ b/stmhal/boards/STM32F4DISC/mpconfigboard.h
@@ -24,6 +24,22 @@
 #define MICROPY_HW_CLK_PLLP (RCC_PLLP_DIV2)
 #define MICROPY_HW_CLK_PLLQ (7)
 
+// UART config
+#define MICROPY_HW_UART1_PORT (GPIOA)
+#define MICROPY_HW_UART1_PINS (GPIO_PIN_9 | GPIO_PIN_10)
+#define MICROPY_HW_UART2_PORT (GPIOA)
+#define MICROPY_HW_UART2_PINS (GPIO_PIN_2 | GPIO_PIN_3)
+#define MICROPY_HW_UART2_RTS  (GPIO_PIN_1)
+#define MICROPY_HW_UART2_CTS  (GPIO_PIN_0)
+#define MICROPY_HW_UART3_PORT (GPIOD)
+#define MICROPY_HW_UART3_PINS (GPIO_PIN_8 | GPIO_PIN_9)
+#define MICROPY_HW_UART3_RTS  (GPIO_PIN_12)
+#define MICROPY_HW_UART3_CTS  (GPIO_PIN_11)
+#define MICROPY_HW_UART4_PORT (GPIOA)
+#define MICROPY_HW_UART4_PINS (GPIO_PIN_0 | GPIO_PIN_1)
+#define MICROPY_HW_UART6_PORT (GPIOC)
+#define MICROPY_HW_UART6_PINS (GPIO_PIN_6 | GPIO_PIN_7)
+
 // I2C busses
 #define MICROPY_HW_I2C1_SCL (pin_B6)
 #define MICROPY_HW_I2C1_SDA (pin_B7)
diff --git a/stmhal/uart.c b/stmhal/uart.c
index 65383b6c243f612e70b65c0db0a84cf31c6607b2..676ccee48f5079ab4148370434304be0d002e392 100644
--- a/stmhal/uart.c
+++ b/stmhal/uart.c
@@ -117,94 +117,88 @@ STATIC bool uart_init2(pyb_uart_obj_t *uart_obj) {
     GPIO_TypeDef* GPIO_Port = NULL;
 
     switch (uart_obj->uart_id) {
+        #if defined(MICROPY_HW_UART1_PORT) && defined(MICROPY_HW_UART1_PINS)
         // USART1 is on PA9/PA10 (CK on PA8), PB6/PB7
         case PYB_UART_1:
             UARTx = USART1;
             irqn = USART1_IRQn;
             GPIO_AF_UARTx = GPIO_AF7_USART1;
-
-#if defined (PYBV4) || defined(PYBV10)
-            GPIO_Port = GPIOB;
-            GPIO_Pin = GPIO_PIN_6 | GPIO_PIN_7;
-#else
-            GPIO_Port = GPIOA;
-            GPIO_Pin = GPIO_PIN_9 | GPIO_PIN_10;
-#endif
-
+            GPIO_Port = MICROPY_HW_UART1_PORT;
+            GPIO_Pin = MICROPY_HW_UART1_PINS;
             __USART1_CLK_ENABLE();
             break;
+        #endif
 
+        #if defined(MICROPY_HW_UART2_PORT) && defined(MICROPY_HW_UART2_PINS)
         // USART2 is on PA2/PA3 (CTS,RTS,CK on PA0,PA1,PA4), PD5/PD6 (CK on PD7)
         case PYB_UART_2:
             UARTx = USART2;
             irqn = USART2_IRQn;
             GPIO_AF_UARTx = GPIO_AF7_USART2;
-
-            GPIO_Port = GPIOA;
-            GPIO_Pin = GPIO_PIN_2 | GPIO_PIN_3;
-
+            GPIO_Port = MICROPY_HW_UART2_PORT;
+            GPIO_Pin = MICROPY_HW_UART2_PINS;
+            #if defined(MICROPY_HW_UART2_RTS)
             if (uart_obj->uart.Init.HwFlowCtl & UART_HWCONTROL_RTS) {
-                GPIO_Pin |= GPIO_PIN_1;
+                GPIO_Pin |= MICROPY_HW_UART2_RTS;
             }
+            #endif
+            #if defined(MICROPY_HW_UART2_CTS)
             if (uart_obj->uart.Init.HwFlowCtl & UART_HWCONTROL_CTS) {
-                GPIO_Pin |= GPIO_PIN_0;
+                GPIO_Pin |= MICROPY_HW_UART2_CTS;
             }
-
+            #endif
             __USART2_CLK_ENABLE();
             break;
+        #endif
 
-        #if defined(USART3)
+        #if defined(USART3) && defined(MICROPY_HW_UART3_PORT) && defined(MICROPY_HW_UART3_PINS)
         // USART3 is on PB10/PB11 (CK,CTS,RTS on PB12,PB13,PB14), PC10/PC11 (CK on PC12), PD8/PD9 (CK on PD10)
         case PYB_UART_3:
             UARTx = USART3;
             irqn = USART3_IRQn;
             GPIO_AF_UARTx = GPIO_AF7_USART3;
-
-#if defined(PYBV3) || defined(PYBV4) | defined(PYBV10)
-            GPIO_Port = GPIOB;
-            GPIO_Pin = GPIO_PIN_10 | GPIO_PIN_11;
-
+            GPIO_Port = MICROPY_HW_UART3_PORT;
+            GPIO_Pin = MICROPY_HW_UART3_PINS;
+            #if defined(MICROPY_HW_UART3_RTS)
             if (uart_obj->uart.Init.HwFlowCtl & UART_HWCONTROL_RTS) {
-                GPIO_Pin |= GPIO_PIN_14;
+                GPIO_Pin |= MICROPY_HW_UART3_RTS;
             }
+            #endif
+            #if defined(MICROPY_HW_UART3_CTS)
             if (uart_obj->uart.Init.HwFlowCtl & UART_HWCONTROL_CTS) {
-                GPIO_Pin |= GPIO_PIN_13;
+                GPIO_Pin |= MICROPY_HW_UART3_CTS;
             }
-#else
-            GPIO_Port = GPIOD;
-            GPIO_Pin = GPIO_PIN_8 | GPIO_PIN_9;
-#endif
+            #endif
             __USART3_CLK_ENABLE();
             break;
         #endif
 
-        #if defined(UART4)
+        #if defined(UART4) && defined(MICROPY_HW_UART4_PORT) && defined(MICROPY_HW_UART4_PINS)
         // UART4 is on PA0/PA1, PC10/PC11
         case PYB_UART_4:
             UARTx = UART4;
             irqn = UART4_IRQn;
             GPIO_AF_UARTx = GPIO_AF8_UART4;
-
-            GPIO_Port = GPIOA;
-            GPIO_Pin = GPIO_PIN_0 | GPIO_PIN_1;
-
+            GPIO_Port = MICROPY_HW_UART4_PORT;
+            GPIO_Pin = MICROPY_HW_UART4_PINS;
             __UART4_CLK_ENABLE();
             break;
         #endif
 
+        #if defined(MICROPY_HW_UART6_PORT) && defined(MICROPY_HW_UART6_PINS)
         // USART6 is on PC6/PC7 (CK on PC8)
         case PYB_UART_6:
             UARTx = USART6;
             irqn = USART6_IRQn;
             GPIO_AF_UARTx = GPIO_AF8_USART6;
-
-            GPIO_Port = GPIOC;
-            GPIO_Pin = GPIO_PIN_6 | GPIO_PIN_7;
-
+            GPIO_Port = MICROPY_HW_UART6_PORT;
+            GPIO_Pin = MICROPY_HW_UART6_PINS;
             __USART6_CLK_ENABLE();
             break;
+        #endif
 
         default:
+            // UART does not exist or is not configured for this board
             return false;
     }