diff --git a/lib/usart_enhanced.c b/lib/usart_enhanced.c
new file mode 100644
index 0000000..efbcf36
--- /dev/null
+++ b/lib/usart_enhanced.c
@@ -0,0 +1,185 @@
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+/** library for enhanced USART communication (code)
+ * @file usart_enhanced.c
+ * @author King Kévin
+ * @date 2018
+ * @details the USART peripherals only support 8 or 9-bit word and even or odd parity (included in the data bits). The library adds support for 5 to 8-bit words, none/even/odd/mark/space parity (on top of the data bits)
+ * @note since parity is handled in software, the parity error (PE) flag is unused and should be replaced by the value return by usart_enhanced_parity_error
+ * @remark 9-bit raw communication is not supported since this is not common and can be done without this library
+ */
+/* standard libraries */
+#include // standard integer types
+
+/* STM32 (including CM3) libraries */
+#include // USART utilities
+
+/* own libraries */
+#include "usart_enhanced.h" // utilities for USART enhancements
+
+/** number of available USART peripherals */
+#define USART_PERIPHERALS_NB 3
+/** configured enhanced USART word size */
+static uint8_t usart_enhanced_databits[USART_PERIPHERALS_NB];
+/** configured enhanced USART parity */
+static enum usart_enhanced_parity_t usart_enhanced_parity[USART_PERIPHERALS_NB];
+/** last enhanced USART parity error status */
+static bool usart_enhanced_parity_errors[USART_PERIPHERALS_NB];
+
+/** know if there is an even number of 1's in a integer
+ * @remark a look-up is a lot faster than making the calculation and doesn't does a lot of (flash) space
+ */
+static const bool even_parity_lut[256] = { true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, true, false, false, true, false, true, true, false, true, false, false, true, false, true, true, false, false, true, true, false, true, false, false, true, };
+
+
+/** get index of corresponding enhanced USART configurations
+ * @param[in] usart USART peripheral base address
+ * @return index used for the individual USART configurations
+ * @note the returned value is valid only is less than USART_PERIPHERALS_NB
+ */
+static uint8_t usart_enhanced_id(uint32_t usart)
+{
+ uint8_t to_return = USART_PERIPHERALS_NB;
+ switch (usart) {
+ case USART1:
+ to_return = 0;
+ break;
+ case USART2:
+ to_return = 1;
+ break;
+ case USART3:
+ to_return = 2;
+ break;
+ default:
+ to_return = USART_PERIPHERALS_NB;
+ break;
+ }
+ return to_return;
+}
+
+bool usart_enhanced_config(uint32_t usart, uint8_t databits, enum usart_enhanced_parity_t parity)
+{
+ /* sanity check */
+ uint8_t id = usart_enhanced_id(usart);
+ if (id>=USART_PERIPHERALS_NB) {
+ return false;
+ }
+ if (databits<5 || databits>8) {
+ return false;
+ }
+ if (parity>USART_ENHANCED_PARITY_SPACE) {
+ return false;
+ }
+
+ // save configuration for later use
+ usart_enhanced_databits[id] = databits;
+ usart_enhanced_parity[id] = parity;
+ // configure USART peripheral
+ if (8==databits && USART_ENHANCED_PARITY_NONE!=parity) { // the parity bit is additional to the data bits
+ usart_set_databits(usart, 9);
+ } else {
+ usart_set_databits(usart, 8);
+ }
+ usart_set_parity(usart, USART_PARITY_NONE); // set no parity since we will take care of it ourselves
+ // we could also lower the number of stop bits when less than 8 bits are used, for higher throughput, but this is not a good idea since most UART transceiver parse 8 bits even is less is used
+ return true;
+}
+
+void usart_enhanced_send(uint32_t usart, uint8_t data)
+{
+ /* sanity check */
+ uint8_t id = usart_enhanced_id(usart);
+ if (id>=USART_PERIPHERALS_NB) {
+ return;
+ }
+
+ data &= ~(0xff<=USART_PERIPHERALS_NB) {
+ return 0xff;
+ }
+
+ uint16_t input = usart_recv(usart); // read received character (also clears the error flags)
+ input &= ~(0xffff<<(usart_enhanced_databits[id]+1)); // only keep the data bits + parity bit
+ // check the parity
+ uint16_t parity = input&(1<=USART_PERIPHERALS_NB) {
+ return false;
+ }
+ return usart_enhanced_parity_errors[id];
+}
diff --git a/lib/usart_enhanced.h b/lib/usart_enhanced.h
new file mode 100644
index 0000000..33f32c7
--- /dev/null
+++ b/lib/usart_enhanced.h
@@ -0,0 +1,71 @@
+/* This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+/** library for enhanced USART communication (API)
+ * @file usart_enhanced.h
+ * @author King Kévin
+ * @date 2018
+ * @details the USART peripherals only support 8 or 9-bit word and even or odd parity (included in the data bits). The library adds support for 5 to 8-bit words, none/even/odd/mark/space parity (on top of the data bits)
+ * @note since parity is handled in software, the parity error (PE) flag is unused and should be replaced by the value return by usart_enhanced_parity_error
+ * @remark 9-bit raw communication is not supported since this is not common and can be done without this library
+ */
+#pragma once
+
+/** enhanced USART setting for the additional parity bit*/
+enum usart_enhanced_parity_t {
+ /** no parity */
+ USART_ENHANCED_PARITY_NONE,
+ /** even parity
+ * @note the number of 1's is even
+ */
+ USART_ENHANCED_PARITY_EVEN,
+ /** odd parity
+ * @note the number of 1's is odd
+ */
+ USART_ENHANCED_PARITY_ODD,
+ /** mark parity
+ * @note the parity bit is 1
+ */
+ USART_ENHANCED_PARITY_MARK,
+ /** space parity
+ * @note the parity bit is 0
+ */
+ USART_ENHANCED_PARITY_SPACE,
+};
+
+/** configure enhanced USART
+ * @param[in] usart USART peripheral base address
+ * @param[in] databits word size in bits (5 to 8)
+ * @param[in] parity additional parity bit
+ * @return if the input settings are valid and the configuration is successful
+ */
+bool usart_enhanced_config(uint32_t usart, uint8_t databits, enum usart_enhanced_parity_t parity);
+/** send data over the enhanced USART using the configuration
+ * @param[in] usart USART peripheral base address
+ * @param[in] data data to be sent
+ * @note uses usart_send
+ */
+void usart_enhanced_send(uint32_t usart, uint8_t data);
+/** receive data over the enhanced USART using the configuration
+ * @param[in] usart USART peripheral base address
+ * @return data received
+ * @note uses usart_recv
+ */
+uint8_t usart_enhanced_recv(uint32_t usart);
+/** get the parity status of the received data
+ * @param[in] usart USART peripheral base address
+ * @return if there is a parity error
+ * @note the check only applies to the last data retrieved using usart_enhanced_recv
+ */
+bool usart_enhanced_parity_error(uint32_t usart);