From 7e6efe12f09270d9441f0d7129c41ec9536c4c2a Mon Sep 17 00:00:00 2001
From: Giovanni Di Sirio <gdisirio@gmail.com>
Date: Thu, 16 Jun 2016 11:56:43 +0000
Subject: Priority bit masking in STM32 serial drivers.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9632 35acf78f-673a-0410-8e92-d51de3d6d3f4
---
 os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c | 11 ++++++++++-
 os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.h |  4 +++-
 os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.c | 20 +++++++++++++++++++-
 os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.h |  4 +++-
 4 files changed, 35 insertions(+), 4 deletions(-)

(limited to 'os')

diff --git a/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c b/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c
index a4f64c7eb..bc4be0edd 100644
--- a/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c
+++ b/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.c
@@ -120,6 +120,15 @@ static void usart_init(SerialDriver *sdp, const SerialConfig *config) {
   u->SR = 0;
   (void)u->SR;  /* SR reset step 1.*/
   (void)u->DR;  /* SR reset step 2.*/
+
+  /* Deciding mask to be applied on the data register on receive, this is
+     required in order to mask out the parity bit.*/
+  if ((config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_PCE) {
+    sdp->rxmask = 0x7F;
+  }
+  else {
+    sdp->rxmask = 0xFF;
+  }
 }
 
 /**
@@ -182,7 +191,7 @@ static void serve_interrupt(SerialDriver *sdp) {
     /* Error condition detection.*/
     if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE  | USART_SR_PE))
       set_error(sdp, sr);
-    b = u->DR;
+    b = (uint8_t)u->DR & sdp->rxmask;
     if (sr & USART_SR_RXNE)
       sdIncomingDataI(sdp, b);
     sr = u->SR;
diff --git a/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.h b/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.h
index d8e368115..a1433ade4 100644
--- a/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.h
+++ b/os/hal/ports/STM32/LLD/USARTv1/hal_serial_lld.h
@@ -300,7 +300,9 @@ typedef struct {
   uint8_t                   ob[SERIAL_BUFFERS_SIZE];                        \
   /* End of the mandatory fields.*/                                         \
   /* Pointer to the USART registers block.*/                                \
-  USART_TypeDef             *usart;
+  USART_TypeDef             *usart;                                         \
+  /* Mask to be applied on received frames.*/                               \
+  uint8_t                   rxmask;
 
 /*===========================================================================*/
 /* Driver macros.                                                            */
diff --git a/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.c b/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.c
index ed2e61607..01515204c 100644
--- a/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.c
+++ b/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.c
@@ -147,6 +147,24 @@ static void usart_init(SerialDriver *sdp, const SerialConfig *config) {
                          USART_CR1_RXNEIE | USART_CR1_TE |
                          USART_CR1_RE;
   u->ICR = 0xFFFFFFFFU;
+
+  /* Deciding mask to be applied on the data register on receive, this is
+     required in order to mask out the parity bit.*/
+  if ((config->cr1 & USART_CR1_PCE) != 0U) {
+    switch (config->cr1 & (USART_CR1_M_1 | USART_CR1_M_0)) {
+    case 0:
+      sdp->rxmask = 0x7F;
+      break;
+    case USART_CR1_M_1:
+      sdp->rxmask = 0x3F;
+      break;
+    default:
+      sdp->rxmask = 0xFF;
+    }
+  }
+  else {
+    sdp->rxmask = 0xFF;
+  }
 }
 
 /**
@@ -212,7 +230,7 @@ static void serve_interrupt(SerialDriver *sdp) {
   /* Data available.*/
   if (isr & USART_ISR_RXNE) {
     osalSysLockFromISR();
-    sdIncomingDataI(sdp, (uint8_t)u->RDR);
+    sdIncomingDataI(sdp, (uint8_t)u->RDR & sdp->rxmask);
     osalSysUnlockFromISR();
   }
 
diff --git a/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.h b/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.h
index b25492ec8..e0f493515 100644
--- a/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.h
+++ b/os/hal/ports/STM32/LLD/USARTv2/hal_serial_lld.h
@@ -336,7 +336,9 @@ typedef struct {
   /* Pointer to the USART registers block.*/                                \
   USART_TypeDef             *usart;                                         \
   /* Clock frequency for the associated USART/UART.*/                       \
-  uint32_t                  clock;
+  uint32_t                  clock;                                          \
+  /* Mask to be applied on received frames.*/                               \
+  uint8_t                   rxmask;
 
 /*===========================================================================*/
 /* Driver macros.                                                            */
-- 
cgit v1.2.3