Skip to content

Commit

Permalink
STM32s Serial does not properly handle parity bits
Browse files Browse the repository at this point in the history
Reworked the serial_format() function for STM32F0x
devices to take the format in the form:
data_bits - parity - stop_bits

E.g. 8 - N - 1

where data_bits exclude the parity bit.
Added a case for 7 bits data as at least the chips
STM32F0x1/STM32F0x2/STM32F0x8 support 7 bits data.

Consolidated serial_format() and uart_init()
functions into a general TARGET_STM serial_api.c
file since the functions are common to all STM targets.

Fixes ARMmbed#4189
  • Loading branch information
fmanno committed May 30, 2017
1 parent 1a37ea6 commit 5e98da1
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 664 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
*/
#include "mbed_assert.h"
#include "serial_api.h"
#include "serial_api_hal.h"

#if DEVICE_SERIAL

Expand All @@ -49,52 +50,13 @@
#endif

static uint32_t serial_irq_ids[UART_NUM] = {0};
static UART_HandleTypeDef uart_handlers[UART_NUM];
UART_HandleTypeDef uart_handlers[UART_NUM];

static uart_irq_handler irq_handler;

int stdio_uart_inited = 0;
serial_t stdio_uart;

#if DEVICE_SERIAL_ASYNCH
#define SERIAL_S(obj) (&((obj)->serial))
#else
#define SERIAL_S(obj) (obj)
#endif

static void init_uart(serial_t *obj)
{
struct serial_s *obj_s = SERIAL_S(obj);
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
huart->Instance = (USART_TypeDef *)(obj_s->uart);

huart->Init.BaudRate = obj_s->baudrate;
huart->Init.WordLength = obj_s->databits;
huart->Init.StopBits = obj_s->stopbits;
huart->Init.Parity = obj_s->parity;
#if DEVICE_SERIAL_FC
huart->Init.HwFlowCtl = obj_s->hw_flow_ctl;
#else
huart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
#endif
huart->TxXferCount = 0;
huart->TxXferSize = 0;
huart->RxXferCount = 0;
huart->RxXferSize = 0;

if (obj_s->pin_rx == NC) {
huart->Init.Mode = UART_MODE_TX;
} else if (obj_s->pin_tx == NC) {
huart->Init.Mode = UART_MODE_RX;
} else {
huart->Init.Mode = UART_MODE_TX_RX;
}

if (HAL_UART_Init(huart) != HAL_OK) {
error("Cannot initialize UART\n");
}
}

void serial_init(serial_t *obj, PinName tx, PinName rx)
{
struct serial_s *obj_s = SERIAL_S(obj);
Expand Down Expand Up @@ -293,39 +255,6 @@ void serial_baud(serial_t *obj, int baudrate)
init_uart(obj);
}

void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
{
struct serial_s *obj_s = SERIAL_S(obj);

if (data_bits == 9) {
obj_s->databits = UART_WORDLENGTH_9B;
} else {
obj_s->databits = UART_WORDLENGTH_8B;
}

switch (parity) {
case ParityOdd:
obj_s->parity = UART_PARITY_ODD;
break;
case ParityEven:
obj_s->parity = UART_PARITY_EVEN;
break;
default: // ParityNone
case ParityForced0: // unsupported!
case ParityForced1: // unsupported!
obj_s->parity = UART_PARITY_NONE;
break;
}

if (stop_bits == 2) {
obj_s->stopbits = UART_STOPBITS_2;
} else {
obj_s->stopbits = UART_STOPBITS_1;
}

init_uart(obj);
}

/******************************************************************************
* INTERRUPTS HANDLING
******************************************************************************/
Expand All @@ -345,6 +274,7 @@ static void uart_irq(int id)
if (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET) {
irq_handler(serial_irq_ids[id], RxIrq);
volatile uint32_t tmpval = huart->Instance->RDR; // Clear RXNE flag
UNUSED(tmpval);
}
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET) {
Expand Down Expand Up @@ -975,6 +905,7 @@ void serial_rx_abort_asynch(serial_t *obj)
// clear flags
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_PEF | UART_CLEAR_FEF | UART_CLEAR_OREF);
volatile uint32_t tmpval = huart->Instance->RDR; // Clear RXNE flag
UNUSED(tmpval);

// reset states
huart->RxXferCount = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
*/
#include "mbed_assert.h"
#include "serial_api.h"
#include "serial_api_hal.h"

#if DEVICE_SERIAL

Expand All @@ -41,52 +42,13 @@
#define UART_NUM (3)

static uint32_t serial_irq_ids[UART_NUM] = {0};
static UART_HandleTypeDef uart_handlers[UART_NUM];
UART_HandleTypeDef uart_handlers[UART_NUM];

static uart_irq_handler irq_handler;

int stdio_uart_inited = 0;
serial_t stdio_uart;

#if DEVICE_SERIAL_ASYNCH
#define SERIAL_S(obj) (&((obj)->serial))
#else
#define SERIAL_S(obj) (obj)
#endif

static void init_uart(serial_t *obj)
{
struct serial_s *obj_s = SERIAL_S(obj);
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
huart->Instance = (USART_TypeDef *)(obj_s->uart);

huart->Init.BaudRate = obj_s->baudrate;
huart->Init.WordLength = obj_s->databits;
huart->Init.StopBits = obj_s->stopbits;
huart->Init.Parity = obj_s->parity;
#if DEVICE_SERIAL_FC
huart->Init.HwFlowCtl = obj_s->hw_flow_ctl;
#else
huart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
#endif
huart->TxXferCount = 0;
huart->TxXferSize = 0;
huart->RxXferCount = 0;
huart->RxXferSize = 0;

if (obj_s->pin_rx == NC) {
huart->Init.Mode = UART_MODE_TX;
} else if (obj_s->pin_tx == NC) {
huart->Init.Mode = UART_MODE_RX;
} else {
huart->Init.Mode = UART_MODE_TX_RX;
}

if (HAL_UART_Init(huart) != HAL_OK) {
error("Cannot initialize UART\n");
}
}

void serial_init(serial_t *obj, PinName tx, PinName rx)
{
struct serial_s *obj_s = SERIAL_S(obj);
Expand Down Expand Up @@ -188,39 +150,6 @@ void serial_baud(serial_t *obj, int baudrate)
init_uart(obj);
}

void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
{
struct serial_s *obj_s = SERIAL_S(obj);

if (data_bits == 9) {
obj_s->databits = UART_WORDLENGTH_9B;
} else {
obj_s->databits = UART_WORDLENGTH_8B;
}

switch (parity) {
case ParityOdd:
obj_s->parity = UART_PARITY_ODD;
break;
case ParityEven:
obj_s->parity = UART_PARITY_EVEN;
break;
default: // ParityNone
case ParityForced0: // unsupported!
case ParityForced1: // unsupported!
obj_s->parity = UART_PARITY_NONE;
break;
}

if (stop_bits == 2) {
obj_s->stopbits = UART_STOPBITS_2;
} else {
obj_s->stopbits = UART_STOPBITS_1;
}

init_uart(obj);
}

/******************************************************************************
* INTERRUPTS HANDLING
******************************************************************************/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
*/
#include "mbed_assert.h"
#include "serial_api.h"
#include "serial_api_hal.h"

#if DEVICE_SERIAL

Expand All @@ -41,52 +42,13 @@
#define UART_NUM (8)

static uint32_t serial_irq_ids[UART_NUM] = {0};
static UART_HandleTypeDef uart_handlers[UART_NUM];
UART_HandleTypeDef uart_handlers[UART_NUM];

static uart_irq_handler irq_handler;

int stdio_uart_inited = 0;
serial_t stdio_uart;

#if DEVICE_SERIAL_ASYNCH
#define SERIAL_S(obj) (&((obj)->serial))
#else
#define SERIAL_S(obj) (obj)
#endif

static void init_uart(serial_t *obj)
{
struct serial_s *obj_s = SERIAL_S(obj);
UART_HandleTypeDef *huart = &uart_handlers[obj_s->index];
huart->Instance = (USART_TypeDef *)(obj_s->uart);

huart->Init.BaudRate = obj_s->baudrate;
huart->Init.WordLength = obj_s->databits;
huart->Init.StopBits = obj_s->stopbits;
huart->Init.Parity = obj_s->parity;
#if DEVICE_SERIAL_FC
huart->Init.HwFlowCtl = obj_s->hw_flow_ctl;
#else
huart->Init.HwFlowCtl = UART_HWCONTROL_NONE;
#endif
huart->TxXferCount = 0;
huart->TxXferSize = 0;
huart->RxXferCount = 0;
huart->RxXferSize = 0;

if (obj_s->pin_rx == NC) {
huart->Init.Mode = UART_MODE_TX;
} else if (obj_s->pin_tx == NC) {
huart->Init.Mode = UART_MODE_RX;
} else {
huart->Init.Mode = UART_MODE_TX_RX;
}

if (HAL_UART_Init(huart) != HAL_OK) {
error("Cannot initialize UART\n");
}
}

void serial_init(serial_t *obj, PinName tx, PinName rx)
{
struct serial_s *obj_s = SERIAL_S(obj);
Expand Down Expand Up @@ -275,39 +237,6 @@ void serial_baud(serial_t *obj, int baudrate)
init_uart(obj);
}

void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_bits)
{
struct serial_s *obj_s = SERIAL_S(obj);

if (data_bits == 9) {
obj_s->databits = UART_WORDLENGTH_9B;
} else {
obj_s->databits = UART_WORDLENGTH_8B;
}

switch (parity) {
case ParityOdd:
obj_s->parity = UART_PARITY_ODD;
break;
case ParityEven:
obj_s->parity = UART_PARITY_EVEN;
break;
default: // ParityNone
case ParityForced0: // unsupported!
case ParityForced1: // unsupported!
obj_s->parity = UART_PARITY_NONE;
break;
}

if (stop_bits == 2) {
obj_s->stopbits = UART_STOPBITS_2;
} else {
obj_s->stopbits = UART_STOPBITS_1;
}

init_uart(obj);
}

/******************************************************************************
* INTERRUPTS HANDLING
******************************************************************************/
Expand Down
Loading

0 comments on commit 5e98da1

Please sign in to comment.