From 4c60f6c795f8046f95c3bc94c570e281c9d510b2 Mon Sep 17 00:00:00 2001 From: Petr Ledvina Date: Tue, 31 Mar 2015 14:48:17 +0200 Subject: [PATCH] Fix 303 serial inversion and bidir mode - USART_HalfDuplexCmd must be called only when USART is disabled - input should be PullDown for inverted serial - INVERTED BIDIR mode changed to GPIO_OType_PP (not opendrain) - opendrain won't work well for inverted serial; USART releases pin when transmission is done, so PP is OK --- src/main/drivers/serial_uart.c | 27 ++++++++++----------------- src/main/drivers/serial_uart_stm32f30x.c | 18 ++++++++++++------ 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/src/main/drivers/serial_uart.c b/src/main/drivers/serial_uart.c index 19b5c0bb5..474ce65a4 100644 --- a/src/main/drivers/serial_uart.c +++ b/src/main/drivers/serial_uart.c @@ -52,18 +52,11 @@ static void usartConfigurePinInversion(uartPort_t *uartPort) { #ifdef STM32F303xC uint32_t inversionPins = 0; - // Inversion when using OPTION_BIDIR not supported yet. - if (uartPort->port.options & SERIAL_BIDIR) { - // Clear inversion on both Tx and Rx - inversionPins |= USART_InvPin_Tx | USART_InvPin_Rx; - inverted = false; - } else { - if (uartPort->port.mode & MODE_TX) { - inversionPins |= USART_InvPin_Tx; - } - if (uartPort->port.mode & MODE_RX) { - inversionPins |= USART_InvPin_Rx; - } + if (uartPort->port.mode & MODE_TX) { + inversionPins |= USART_InvPin_Tx; + } + if (uartPort->port.mode & MODE_RX) { + inversionPins |= USART_InvPin_Rx; } USART_InvPinCmd(uartPort->USARTx, inversionPins, inverted ? ENABLE : DISABLE); @@ -93,6 +86,11 @@ static void uartReconfigure(uartPort_t *uartPort) usartConfigurePinInversion(uartPort); + if(uartPort->port.options & SERIAL_BIDIR) + USART_HalfDuplexCmd(uartPort->USARTx, ENABLE); + else + USART_HalfDuplexCmd(uartPort->USARTx, DISABLE); + USART_Cmd(uartPort->USARTx, ENABLE); } @@ -182,11 +180,6 @@ serialPort_t *uartOpen(USART_TypeDef *USARTx, serialReceiveCallbackPtr callback, USART_Cmd(s->USARTx, ENABLE); - if (options & SERIAL_BIDIR) - USART_HalfDuplexCmd(s->USARTx, ENABLE); - else - USART_HalfDuplexCmd(s->USARTx, DISABLE); - return (serialPort_t *)s; } diff --git a/src/main/drivers/serial_uart_stm32f30x.c b/src/main/drivers/serial_uart_stm32f30x.c index fa1622561..c7d62d5f0 100644 --- a/src/main/drivers/serial_uart_stm32f30x.c +++ b/src/main/drivers/serial_uart_stm32f30x.c @@ -116,13 +116,15 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode, portOptions_t optio GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_PuPd = (options & SERIAL_INVERTED) ? GPIO_PuPd_DOWN : GPIO_PuPd_UP; if (options & SERIAL_BIDIR) { GPIO_InitStructure.GPIO_Pin = UART1_TX_PIN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_OType = (options & SERIAL_INVERTED) ? GPIO_OType_PP : GPIO_OType_OD; GPIO_PinAFConfig(UART1_GPIO, UART1_TX_PINSOURCE, UART1_GPIO_AF); GPIO_Init(UART1_GPIO, &GPIO_InitStructure); + if(!(options & SERIAL_INVERTED)) + GPIO_SetBits(UART1_GPIO, UART1_TX_PIN); // OpenDrain output should be inactive } else { if (mode & MODE_TX) { GPIO_InitStructure.GPIO_Pin = UART1_TX_PIN; @@ -195,13 +197,15 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode, portOptions_t optio GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_PuPd = (options & SERIAL_INVERTED) ? GPIO_PuPd_DOWN : GPIO_PuPd_UP; if (options & SERIAL_BIDIR) { GPIO_InitStructure.GPIO_Pin = UART2_TX_PIN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_OType = (options & SERIAL_INVERTED) ? GPIO_OType_PP : GPIO_OType_OD; GPIO_PinAFConfig(UART2_GPIO, UART2_TX_PINSOURCE, UART2_GPIO_AF); GPIO_Init(UART2_GPIO, &GPIO_InitStructure); + if(!(options & SERIAL_INVERTED)) + GPIO_SetBits(UART2_GPIO, UART2_TX_PIN); // OpenDrain output should be inactive } else { if (mode & MODE_TX) { GPIO_InitStructure.GPIO_Pin = UART2_TX_PIN; @@ -276,13 +280,15 @@ uartPort_t *serialUSART3(uint32_t baudRate, portMode_t mode, portOptions_t optio GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_PuPd = (options & SERIAL_INVERTED) ? GPIO_PuPd_DOWN : GPIO_PuPd_UP; if (options & SERIAL_BIDIR) { GPIO_InitStructure.GPIO_Pin = UART3_TX_PIN; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_OType = (options & SERIAL_INVERTED) ? GPIO_OType_PP : GPIO_OType_OD; GPIO_PinAFConfig(UART3_GPIO, UART3_TX_PINSOURCE, UART3_GPIO_AF); GPIO_Init(UART3_GPIO, &GPIO_InitStructure); + if(!(options & SERIAL_INVERTED)) + GPIO_SetBits(UART3_GPIO, UART3_TX_PIN); // OpenDrain output should be inactive } else { if (mode & MODE_TX) { GPIO_InitStructure.GPIO_Pin = UART3_TX_PIN; -- 2.11.4.GIT