diff --git a/Makefile b/Makefile index 84ca300fda..3ca0e248cc 100644 --- a/Makefile +++ b/Makefile @@ -143,6 +143,7 @@ NAZE_SRC = startup_stm32f10x_md_gcc.S \ drivers/sonar_hcsr04.c \ drivers/pwm_common.c \ drivers/serial_softserial.c \ + drivers/serial_uart_common.c \ drivers/serial_uart_stm32f10x.c \ drivers/timer_common.c \ $(COMMON_SRC) @@ -155,6 +156,7 @@ FY90Q_SRC = startup_stm32f10x_md_gcc.S \ drivers/pwm_fy90q.c \ drivers/bus_i2c_stm32f10x.c \ drivers/bus_spi.c \ + drivers/serial_uart_common.c \ drivers/serial_uart_stm32f10x.c \ $(COMMON_SRC) @@ -170,6 +172,7 @@ OLIMEXINO_SRC = startup_stm32f10x_md_gcc.S \ drivers/gpio_stm32f10x.c \ drivers/pwm_common.c \ drivers/serial_softserial.c \ + drivers/serial_uart_common.c \ drivers/serial_uart_stm32f10x.c \ drivers/timer_common.c \ $(COMMON_SRC) @@ -187,6 +190,7 @@ STM32F3DISCOVERY_SRC = startup_stm32f30x_md_gcc.S \ drivers/bus_spi.c \ drivers/gpio_stm32f30x.c \ drivers/pwm_common.c \ + drivers/serial_uart_common.c \ drivers/serial_uart_stm32f30x.c \ drivers/serial_softserial.c \ drivers/timer_common.c \ diff --git a/src/drivers/serial_uart_common.c b/src/drivers/serial_uart_common.c new file mode 100644 index 0000000000..eaa95205de --- /dev/null +++ b/src/drivers/serial_uart_common.c @@ -0,0 +1,210 @@ +#include +#include +#include + +#include "platform.h" + +#include "serial_common.h" +#include "serial_uart_common.h" + +uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode); +uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode); + +serialPort_t *uartOpen(USART_TypeDef *USARTx, serialReceiveCallbackPtr callback, uint32_t baudRate, portMode_t mode) +{ + DMA_InitTypeDef DMA_InitStructure; + USART_InitTypeDef USART_InitStructure; + + uartPort_t *s = NULL; + + if (USARTx == USART1) { + s = serialUSART1(baudRate, mode); + } else if (USARTx == USART2) { + s = serialUSART2(baudRate, mode); + } else { + return (serialPort_t *)s; + } + // common serial initialisation code should move to serialPort::init() + s->port.rxBufferHead = s->port.rxBufferTail = 0; + s->port.txBufferHead = s->port.txBufferTail = 0; + // callback for IRQ-based RX ONLY + s->port.callback = callback; + s->port.mode = mode; + s->port.baudRate = baudRate; + + USART_InitStructure.USART_BaudRate = baudRate; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + if (mode & MODE_SBUS) { + USART_InitStructure.USART_StopBits = USART_StopBits_2; + USART_InitStructure.USART_Parity = USART_Parity_Even; + } else { + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_No; + } + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = 0; + if (mode & MODE_RX) + USART_InitStructure.USART_Mode |= USART_Mode_Rx; + if (mode & MODE_TX) + USART_InitStructure.USART_Mode |= USART_Mode_Tx; + USART_Init(s->USARTx, &USART_InitStructure); + + DMA_StructInit(&DMA_InitStructure); + DMA_InitStructure.DMA_PeripheralBaseAddr = s->rxDMAPeripheralBaseAddr; + DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + + // Receive DMA or IRQ + if (mode & MODE_RX) { + if (s->rxDMAChannel) { + DMA_InitStructure.DMA_BufferSize = s->port.rxBufferSize; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; + DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)s->port.rxBuffer; + DMA_DeInit(s->rxDMAChannel); + DMA_Init(s->rxDMAChannel, &DMA_InitStructure); + DMA_Cmd(s->rxDMAChannel, ENABLE); + USART_DMACmd(s->USARTx, USART_DMAReq_Rx, ENABLE); + s->rxDMAPos = DMA_GetCurrDataCounter(s->rxDMAChannel); + } else { + USART_ClearITPendingBit(s->USARTx, USART_IT_RXNE); + USART_ITConfig(s->USARTx, USART_IT_RXNE, ENABLE); + } + } + + DMA_StructInit(&DMA_InitStructure); + DMA_InitStructure.DMA_PeripheralBaseAddr = s->txDMAPeripheralBaseAddr; + DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + + // Transmit DMA or IRQ + if (mode & MODE_TX) { + if (s->txDMAChannel) { + DMA_InitStructure.DMA_BufferSize = s->port.txBufferSize; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_DeInit(s->txDMAChannel); + DMA_Init(s->txDMAChannel, &DMA_InitStructure); + DMA_ITConfig(s->txDMAChannel, DMA_IT_TC, ENABLE); + DMA_SetCurrDataCounter(s->txDMAChannel, 0); + s->txDMAChannel->CNDTR = 0; + USART_DMACmd(s->USARTx, USART_DMAReq_Tx, ENABLE); + } else { + USART_ITConfig(s->USARTx, USART_IT_TXE, ENABLE); + } + } + + USART_Cmd(s->USARTx, ENABLE); + + return (serialPort_t *)s; +} + +void uartSetBaudRate(serialPort_t *instance, uint32_t baudRate) +{ + USART_InitTypeDef USART_InitStructure; + uartPort_t *s = (uartPort_t *)instance; + + USART_InitStructure.USART_BaudRate = baudRate; + USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_StopBits = USART_StopBits_1; + USART_InitStructure.USART_Parity = USART_Parity_No; + USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; + USART_InitStructure.USART_Mode = 0; + if (s->port.mode & MODE_RX) + USART_InitStructure.USART_Mode |= USART_Mode_Rx; + if (s->port.mode & MODE_TX) + USART_InitStructure.USART_Mode |= USART_Mode_Tx; + USART_Init(s->USARTx, &USART_InitStructure); + + s->port.baudRate = baudRate; +} + +void uartSetMode(serialPort_t *s, portMode_t mode) +{ + // not implemented. +} + + +void uartStartTxDMA(uartPort_t *s) +{ + s->txDMAChannel->CMAR = (uint32_t)&s->port.txBuffer[s->port.txBufferTail]; + if (s->port.txBufferHead > s->port.txBufferTail) { + s->txDMAChannel->CNDTR = s->port.txBufferHead - s->port.txBufferTail; + s->port.txBufferTail = s->port.txBufferHead; + } else { + s->txDMAChannel->CNDTR = s->port.txBufferSize - s->port.txBufferTail; + s->port.txBufferTail = 0; + } + s->txDMAEmpty = false; + DMA_Cmd(s->txDMAChannel, ENABLE); +} + +uint8_t uartTotalBytesWaiting(serialPort_t *instance) +{ + uartPort_t *s = (uartPort_t*)instance; + // FIXME always returns 1 or 0, not the amount of bytes waiting + if (s->rxDMAChannel) + return s->rxDMAChannel->CNDTR != s->rxDMAPos; + else + return s->port.rxBufferTail != s->port.rxBufferHead; +} + +// BUGBUG TODO TODO FIXME - What is the bug? +bool isUartTransmitBufferEmpty(serialPort_t *instance) +{ + uartPort_t *s = (uartPort_t *)instance; + if (s->txDMAChannel) + return s->txDMAEmpty; + else + return s->port.txBufferTail == s->port.txBufferHead; +} + +uint8_t uartRead(serialPort_t *instance) +{ + uint8_t ch; + uartPort_t *s = (uartPort_t *)instance; + + if (s->rxDMAChannel) { + ch = s->port.rxBuffer[s->port.rxBufferSize - s->rxDMAPos]; + if (--s->rxDMAPos == 0) + s->rxDMAPos = s->port.rxBufferSize; + } else { + ch = s->port.rxBuffer[s->port.rxBufferTail]; + s->port.rxBufferTail = (s->port.rxBufferTail + 1) % s->port.rxBufferSize; + } + + return ch; +} + +void uartWrite(serialPort_t *instance, uint8_t ch) +{ + uartPort_t *s = (uartPort_t *)instance; + s->port.txBuffer[s->port.txBufferHead] = ch; + s->port.txBufferHead = (s->port.txBufferHead + 1) % s->port.txBufferSize; + + if (s->txDMAChannel) { + if (!(s->txDMAChannel->CCR & 1)) + uartStartTxDMA(s); + } else { + USART_ITConfig(s->USARTx, USART_IT_TXE, ENABLE); + } +} + +const struct serialPortVTable uartVTable[] = { + { + uartWrite, + uartTotalBytesWaiting, + uartRead, + uartSetBaudRate, + isUartTransmitBufferEmpty, + uartSetMode, + } +}; diff --git a/src/drivers/serial_uart.h b/src/drivers/serial_uart_common.h similarity index 90% rename from src/drivers/serial_uart.h rename to src/drivers/serial_uart_common.h index d57eb80bda..1b6981cce7 100755 --- a/src/drivers/serial_uart.h +++ b/src/drivers/serial_uart_common.h @@ -19,6 +19,9 @@ typedef struct { uint32_t rxDMAPos; bool txDMAEmpty; + uint32_t txDMAPeripheralBaseAddr; + uint32_t rxDMAPeripheralBaseAddr; + USART_TypeDef *USARTx; } uartPort_t; diff --git a/src/drivers/serial_uart_stm32f10x.c b/src/drivers/serial_uart_stm32f10x.c index cac0119381..2dee756a83 100755 --- a/src/drivers/serial_uart_stm32f10x.c +++ b/src/drivers/serial_uart_stm32f10x.c @@ -9,7 +9,7 @@ #include "gpio_common.h" #include "serial_common.h" -#include "serial_uart.h" +#include "serial_uart_common.h" /* DMA UART routines idea lifted from AutoQuad @@ -19,6 +19,8 @@ static uartPort_t uartPort1; static uartPort_t uartPort2; +void uartStartTxDMA(uartPort_t *s); + // USART1 - Telemetry (RX/TX by DMA) uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode) { @@ -38,6 +40,11 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode) s->port.rxBufferSize = UART1_RX_BUFFER_SIZE; s->port.txBufferSize = UART1_TX_BUFFER_SIZE; + s->USARTx = USART1; + + s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR; + s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR; + s->rxDMAChannel = DMA1_Channel5; s->txDMAChannel = DMA1_Channel4; @@ -85,6 +92,9 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode) s->USARTx = USART2; + s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR; + s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->DR; + RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); // USART2_TX PA2 // USART2_RX PA3 @@ -108,194 +118,6 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode) return s; } -serialPort_t *uartOpen(USART_TypeDef *USARTx, serialReceiveCallbackPtr callback, uint32_t baudRate, portMode_t mode) -{ - DMA_InitTypeDef DMA_InitStructure; - USART_InitTypeDef USART_InitStructure; - - uartPort_t *s = NULL; - - if (USARTx == USART1) - s = serialUSART1(baudRate, mode); - if (USARTx == USART2) - s = serialUSART2(baudRate, mode); - - s->USARTx = USARTx; - - // common serial initialisation code should move to serialPort::init() - s->port.rxBufferHead = s->port.rxBufferTail = 0; - s->port.txBufferHead = s->port.txBufferTail = 0; - // callback for IRQ-based RX ONLY - s->port.callback = callback; - s->port.mode = mode; - s->port.baudRate = baudRate; - - USART_InitStructure.USART_BaudRate = baudRate; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - if (mode & MODE_SBUS) { - USART_InitStructure.USART_StopBits = USART_StopBits_2; - USART_InitStructure.USART_Parity = USART_Parity_Even; - } else { - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_Parity = USART_Parity_No; - } - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = 0; - if (mode & MODE_RX) - USART_InitStructure.USART_Mode |= USART_Mode_Rx; - if (mode & MODE_TX) - USART_InitStructure.USART_Mode |= USART_Mode_Tx; - USART_Init(USARTx, &USART_InitStructure); - USART_Cmd(USARTx, ENABLE); - - DMA_StructInit(&DMA_InitStructure); - DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USARTx->DR; - DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - - // Receive DMA or IRQ - if (mode & MODE_RX) { - if (s->rxDMAChannel) { - DMA_InitStructure.DMA_BufferSize = s->port.rxBufferSize; - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; - DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; - DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)s->port.rxBuffer; - DMA_DeInit(s->rxDMAChannel); - DMA_Init(s->rxDMAChannel, &DMA_InitStructure); - DMA_Cmd(s->rxDMAChannel, ENABLE); - USART_DMACmd(USARTx, USART_DMAReq_Rx, ENABLE); - s->rxDMAPos = DMA_GetCurrDataCounter(s->rxDMAChannel); - } else { - USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); - } - } - - // Transmit DMA or IRQ - if (mode & MODE_TX) { - if (s->txDMAChannel) { - DMA_InitStructure.DMA_BufferSize = s->port.txBufferSize; - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; - DMA_DeInit(s->txDMAChannel); - DMA_Init(s->txDMAChannel, &DMA_InitStructure); - DMA_ITConfig(s->txDMAChannel, DMA_IT_TC, ENABLE); - DMA_SetCurrDataCounter(s->txDMAChannel, 0); - s->txDMAChannel->CNDTR = 0; - USART_DMACmd(USARTx, USART_DMAReq_Tx, ENABLE); - } else { - USART_ITConfig(USARTx, USART_IT_TXE, ENABLE); - } - } - - return (serialPort_t *)s; -} - -void uartSetBaudRate(serialPort_t *instance, uint32_t baudRate) -{ - USART_InitTypeDef USART_InitStructure; - uartPort_t *s = (uartPort_t *)instance; - - USART_InitStructure.USART_BaudRate = baudRate; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_Parity = USART_Parity_No; - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = 0; - if (s->port.mode & MODE_RX) - USART_InitStructure.USART_Mode |= USART_Mode_Rx; - if (s->port.mode & MODE_TX) - USART_InitStructure.USART_Mode |= USART_Mode_Tx; - USART_Init(s->USARTx, &USART_InitStructure); - - s->port.baudRate = baudRate; -} - -void uartSetMode(serialPort_t *s, portMode_t mode) -{ - // not implemented. -} - - -static void uartStartTxDMA(uartPort_t *s) -{ - s->txDMAChannel->CMAR = (uint32_t)&s->port.txBuffer[s->port.txBufferTail]; - if (s->port.txBufferHead > s->port.txBufferTail) { - s->txDMAChannel->CNDTR = s->port.txBufferHead - s->port.txBufferTail; - s->port.txBufferTail = s->port.txBufferHead; - } else { - s->txDMAChannel->CNDTR = s->port.txBufferSize - s->port.txBufferTail; - s->port.txBufferTail = 0; - } - s->txDMAEmpty = false; - DMA_Cmd(s->txDMAChannel, ENABLE); -} - -uint8_t uartTotalBytesWaiting(serialPort_t *instance) -{ - uartPort_t *s = (uartPort_t*)instance; - // FIXME always returns 1 or 0, not the amount of bytes waiting - if (s->rxDMAChannel) - return s->rxDMAChannel->CNDTR != s->rxDMAPos; - else - return s->port.rxBufferTail != s->port.rxBufferHead; -} - -// BUGBUG TODO TODO FIXME - What is the bug? -bool isUartTransmitBufferEmpty(serialPort_t *instance) -{ - uartPort_t *s = (uartPort_t *)instance; - if (s->txDMAChannel) - return s->txDMAEmpty; - else - return s->port.txBufferTail == s->port.txBufferHead; -} - -uint8_t uartRead(serialPort_t *instance) -{ - uint8_t ch; - uartPort_t *s = (uartPort_t *)instance; - - if (s->rxDMAChannel) { - ch = s->port.rxBuffer[s->port.rxBufferSize - s->rxDMAPos]; - if (--s->rxDMAPos == 0) - s->rxDMAPos = s->port.rxBufferSize; - } else { - ch = s->port.rxBuffer[s->port.rxBufferTail]; - s->port.rxBufferTail = (s->port.rxBufferTail + 1) % s->port.rxBufferSize; - } - - return ch; -} - -void uartWrite(serialPort_t *instance, uint8_t ch) -{ - uartPort_t *s = (uartPort_t *)instance; - s->port.txBuffer[s->port.txBufferHead] = ch; - s->port.txBufferHead = (s->port.txBufferHead + 1) % s->port.txBufferSize; - - if (s->txDMAChannel) { - if (!(s->txDMAChannel->CCR & 1)) - uartStartTxDMA(s); - } else { - USART_ITConfig(s->USARTx, USART_IT_TXE, ENABLE); - } -} - -const struct serialPortVTable uartVTable[] = { - { - uartWrite, - uartTotalBytesWaiting, - uartRead, - uartSetBaudRate, - isUartTransmitBufferEmpty, - uartSetMode, - } -}; - // Handlers // USART1 Tx DMA Handler diff --git a/src/drivers/serial_uart_stm32f30x.c b/src/drivers/serial_uart_stm32f30x.c index 55f4a02974..8bf8a05bec 100644 --- a/src/drivers/serial_uart_stm32f30x.c +++ b/src/drivers/serial_uart_stm32f30x.c @@ -14,7 +14,7 @@ #include "gpio_common.h" #include "serial_common.h" -#include "serial_uart.h" +#include "serial_uart_common.h" // Using RX DMA disables the use of receive callbacks #define USE_USART1_RX_DMA @@ -40,6 +40,8 @@ static uartPort_t uartPort1; static uartPort_t uartPort2; +void uartStartTxDMA(uartPort_t *s); + uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode) { uartPort_t *s; @@ -63,6 +65,11 @@ uartPort_t *serialUSART1(uint32_t baudRate, portMode_t mode) #endif s->txDMAChannel = DMA1_Channel4; + s->USARTx = USART1; + + s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR; + s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; @@ -123,6 +130,10 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode) s->USARTx = USART2; + s->rxDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->RDR; + s->txDMAPeripheralBaseAddr = (uint32_t)&s->USARTx->TDR; + + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; @@ -158,205 +169,6 @@ uartPort_t *serialUSART2(uint32_t baudRate, portMode_t mode) return s; } -serialPort_t *uartOpen(USART_TypeDef *USARTx, serialReceiveCallbackPtr callback, uint32_t baudRate, portMode_t mode) -{ - DMA_InitTypeDef DMA_InitStructure; - USART_InitTypeDef USART_InitStructure; - - uartPort_t *s = NULL; - - if (USARTx == USART1) - s = serialUSART1(baudRate, mode); - if (USARTx == USART2) - s = serialUSART2(baudRate, mode); - - s->USARTx = USARTx; - - // common serial initialisation code should move to serialPort::init() - s->port.rxBufferHead = s->port.rxBufferTail = 0; - s->port.txBufferHead = s->port.txBufferTail = 0; - // callback for IRQ-based RX ONLY - s->port.callback = callback; - s->port.mode = mode; - s->port.baudRate = baudRate; - - USART_InitStructure.USART_BaudRate = baudRate; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - if (mode & MODE_SBUS) { - USART_InitStructure.USART_StopBits = USART_StopBits_2; - USART_InitStructure.USART_Parity = USART_Parity_Even; - } else { - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_Parity = USART_Parity_No; - } - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = 0; - if (mode & MODE_RX) - USART_InitStructure.USART_Mode |= USART_Mode_Rx; - if (mode & MODE_TX) - USART_InitStructure.USART_Mode |= USART_Mode_Tx; - USART_Init(USARTx, &USART_InitStructure); - - DMA_StructInit(&DMA_InitStructure); - DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USARTx->RDR; - DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - - // Receive DMA or IRQ - if (mode & MODE_RX) { - if (s->rxDMAChannel) { - DMA_InitStructure.DMA_BufferSize = s->port.rxBufferSize; - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; - DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; - DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)s->port.rxBuffer; - DMA_DeInit(s->rxDMAChannel); - DMA_Init(s->rxDMAChannel, &DMA_InitStructure); - DMA_Cmd(s->rxDMAChannel, ENABLE); - USART_DMACmd(USARTx, USART_DMAReq_Rx, ENABLE); - s->rxDMAPos = DMA_GetCurrDataCounter(s->rxDMAChannel); - } else { - USART_ClearITPendingBit(USARTx, USART_IT_RXNE); - USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); - } - } - - DMA_StructInit(&DMA_InitStructure); - DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USARTx->TDR; - DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - - // Transmit DMA or IRQ - if (mode & MODE_TX) { - if (s->txDMAChannel) { - DMA_InitStructure.DMA_BufferSize = s->port.txBufferSize; - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; - DMA_DeInit(s->txDMAChannel); - DMA_Init(s->txDMAChannel, &DMA_InitStructure); - DMA_ITConfig(s->txDMAChannel, DMA_IT_TC, ENABLE); - DMA_SetCurrDataCounter(s->txDMAChannel, 0); - s->txDMAChannel->CNDTR = 0; - USART_DMACmd(USARTx, USART_DMAReq_Tx, ENABLE); - } else { - USART_ITConfig(USARTx, USART_IT_TXE, ENABLE); - } - } - - USART_Cmd(USARTx, ENABLE); - - return (serialPort_t *)s; -} - -void uartSetBaudRate(serialPort_t *instance, uint32_t baudRate) -{ - USART_InitTypeDef USART_InitStructure; - uartPort_t *s = (uartPort_t *)instance; - - USART_InitStructure.USART_BaudRate = baudRate; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_Parity = USART_Parity_No; - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = 0; - if (s->port.mode & MODE_RX) - USART_InitStructure.USART_Mode |= USART_Mode_Rx; - if (s->port.mode & MODE_TX) - USART_InitStructure.USART_Mode |= USART_Mode_Tx; - USART_Init(s->USARTx, &USART_InitStructure); - - s->port.baudRate = baudRate; -} - -void uartSetMode(serialPort_t *s, portMode_t mode) -{ - // not implemented. -} - - -static void uartStartTxDMA(uartPort_t *s) -{ - s->txDMAChannel->CMAR = (uint32_t)&s->port.txBuffer[s->port.txBufferTail]; - if (s->port.txBufferHead > s->port.txBufferTail) { - s->txDMAChannel->CNDTR = s->port.txBufferHead - s->port.txBufferTail; - s->port.txBufferTail = s->port.txBufferHead; - } else { - s->txDMAChannel->CNDTR = s->port.txBufferSize - s->port.txBufferTail; - s->port.txBufferTail = 0; - } - s->txDMAEmpty = false; - DMA_Cmd(s->txDMAChannel, ENABLE); -} - -uint8_t uartTotalBytesWaiting(serialPort_t *instance) -{ - uartPort_t *s = (uartPort_t*)instance; - // FIXME always returns 1 or 0, not the amount of bytes waiting - if (s->rxDMAChannel) - return s->rxDMAChannel->CNDTR != s->rxDMAPos; - else - return s->port.rxBufferTail != s->port.rxBufferHead; -} - -// BUGBUG TODO TODO FIXME - What is the bug? -bool isUartTransmitBufferEmpty(serialPort_t *instance) -{ - uartPort_t *s = (uartPort_t *)instance; - if (s->txDMAChannel) - return s->txDMAEmpty; - else - return s->port.txBufferTail == s->port.txBufferHead; -} - -uint8_t uartRead(serialPort_t *instance) -{ - uint8_t ch; - uartPort_t *s = (uartPort_t *)instance; - - if (s->rxDMAChannel) { - ch = s->port.rxBuffer[s->port.rxBufferSize - s->rxDMAPos]; - if (--s->rxDMAPos == 0) - s->rxDMAPos = s->port.rxBufferSize; - } else { - ch = s->port.rxBuffer[s->port.rxBufferTail]; - s->port.rxBufferTail = (s->port.rxBufferTail + 1) % s->port.rxBufferSize; - } - - return ch; -} - -void uartWrite(serialPort_t *instance, uint8_t ch) -{ - uartPort_t *s = (uartPort_t *)instance; - s->port.txBuffer[s->port.txBufferHead] = ch; - s->port.txBufferHead = (s->port.txBufferHead + 1) % s->port.txBufferSize; - - if (s->txDMAChannel) { - if (!(s->txDMAChannel->CCR & 1)) - uartStartTxDMA(s); - } else { - USART_ITConfig(s->USARTx, USART_IT_TXE, ENABLE); - } -} - -const struct serialPortVTable uartVTable[] = { - { - uartWrite, - uartTotalBytesWaiting, - uartRead, - uartSetBaudRate, - isUartTransmitBufferEmpty, - uartSetMode, - } -}; - static void handleUsartTxDma(uartPort_t *s) { DMA_Cmd(s->txDMAChannel, DISABLE); diff --git a/src/gps_common.c b/src/gps_common.c index 53c5ffda49..c52ea9942f 100644 --- a/src/gps_common.c +++ b/src/gps_common.c @@ -11,7 +11,7 @@ #include "drivers/system_common.h" #include "drivers/serial_common.h" -#include "drivers/serial_uart.h" +#include "drivers/serial_uart_common.h" #include "serial_common.h" #include "drivers/gpio_common.h" diff --git a/src/rx_sbus.c b/src/rx_sbus.c index 63f49a67d8..4bec9934a8 100644 --- a/src/rx_sbus.c +++ b/src/rx_sbus.c @@ -6,7 +6,7 @@ #include "drivers/system_common.h" #include "drivers/serial_common.h" -#include "drivers/serial_uart.h" +#include "drivers/serial_uart_common.h" #include "serial_common.h" #include "failsafe.h" diff --git a/src/rx_spektrum.c b/src/rx_spektrum.c index 53d92bff95..05790b3f0c 100644 --- a/src/rx_spektrum.c +++ b/src/rx_spektrum.c @@ -6,7 +6,7 @@ #include "drivers/system_common.h" #include "drivers/serial_common.h" -#include "drivers/serial_uart.h" +#include "drivers/serial_uart_common.h" #include "serial_common.h" #include "failsafe.h" diff --git a/src/rx_sumd.c b/src/rx_sumd.c index 2be2e42e7a..6b276c5577 100644 --- a/src/rx_sumd.c +++ b/src/rx_sumd.c @@ -6,7 +6,7 @@ #include "drivers/system_common.h" #include "drivers/serial_common.h" -#include "drivers/serial_uart.h" +#include "drivers/serial_uart_common.h" #include "serial_common.h" #include "failsafe.h" diff --git a/src/serial_common.c b/src/serial_common.c index f83b074dd6..62a5ce124e 100644 --- a/src/serial_common.c +++ b/src/serial_common.c @@ -6,7 +6,7 @@ #include "drivers/system_common.h" #include "drivers/serial_common.h" -#include "drivers/serial_uart.h" +#include "drivers/serial_uart_common.h" #include "serial_cli.h" #include "serial_msp.h"