diff --git a/radio/src/definitions.h b/radio/src/definitions.h new file mode 100644 index 000000000..9f95c2ded --- /dev/null +++ b/radio/src/definitions.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ + +#ifndef _DEFINITIONS_H_ +#define _DEFINITIONS_H_ + +#if defined(SIMU) + #define __ALIGNED +#else + #define __ALIGNED __attribute__((aligned(32))) +#endif + +#if defined(SIMU) + #define __DMA +#elif defined(STM32F4) && !defined(BOOT) + #define __DMA __attribute__((section(".ram"), aligned(32))) +#else + #define __DMA __ALIGNED +#endif + +#if defined(PCBHORUS) && !defined(SIMU) + #define __SDRAM __attribute__((section(".sdram"), aligned(32))) +#else + #define __SDRAM __DMA +#endif + +#if defined(SIMU) || defined(CPUARM) || GCC_VERSION < 472 + typedef int32_t int24_t; +#else + typedef __int24 int24_t; +#endif + +#endif // _DEFINITIONS_H_ diff --git a/radio/src/dmafifo.h b/radio/src/dmafifo.h new file mode 100644 index 000000000..f74aada04 --- /dev/null +++ b/radio/src/dmafifo.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ + +#ifndef _DMA_FIFO_H_ +#define _DMA_FIFO_H_ + +#include "definitions.h" + +template +class DMAFifo +{ + public: + DMAFifo(DMA_Stream_TypeDef * stream): + stream(stream), + ridx(0) + { + } + + void clear() + { + ridx = 0; + } + + uint32_t size() + { + return N; + } + + bool isEmpty() + { + return (ridx == N - stream->NDTR); + } + + bool pop(uint8_t & element) + { + if (isEmpty()) { + return false; + } + else { + element = fifo[ridx]; + ridx = (ridx+1) & (N-1); + return true; + } + } + + uint8_t * buffer() + { + return fifo; + } + + protected: + uint8_t fifo[N]; + DMA_Stream_TypeDef * stream; + volatile uint32_t ridx; +}; + +#endif // _DMA_FIFO_H_ diff --git a/radio/src/fifo.h b/radio/src/fifo.h index 933a332e6..e8dc3e624 100644 --- a/radio/src/fifo.h +++ b/radio/src/fifo.h @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -36,7 +36,8 @@ class Fifo widx = ridx = 0; } - void push(T element) { + void push(T element) + { uint32_t next = (widx+1) & (N-1); if (next != ridx) { fifo[widx] = element; @@ -44,7 +45,8 @@ class Fifo } } - bool pop(T & element) { + bool pop(T & element) + { if (isEmpty()) { return false; } @@ -55,16 +57,19 @@ class Fifo } } - bool isEmpty() { + bool isEmpty() + { return (ridx == widx); } - bool isFull() { + bool isFull() + { uint32_t next = (widx+1) & (N-1); return (next == ridx); } - void flush() { + void flush() + { while (!isEmpty()) {}; } diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 6bb84001c..ef495d269 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -25,6 +25,7 @@ #include #include #include +#include "definitions.h" #if defined(SIMU) #define SWITCH_SIMU(a, b) (a) @@ -203,32 +204,6 @@ #define ROTARY_ENCODER_NAVIGATION #endif -#if defined(SIMU) - #define __ALIGNED -#else - #define __ALIGNED __attribute__((aligned(32))) -#endif - -#if defined(SIMU) - #define __DMA -#elif defined(STM32F4) && !defined(BOOT) - #define __DMA __attribute__((section(".ram"), aligned(32))) -#else - #define __DMA __ALIGNED -#endif - -#if defined(PCBHORUS) && !defined(SIMU) - #define __SDRAM __attribute__((section(".sdram"), aligned(32))) -#else - #define __SDRAM __DMA -#endif - -#if defined(SIMU) || defined(CPUARM) || GCC_VERSION < 472 - typedef int32_t int24_t; -#else - typedef __int24 int24_t; -#endif - #if defined(FAI) #define IS_FAI_ENABLED() true #define IF_FAI_CHOICE(x) diff --git a/radio/src/sbus.cpp b/radio/src/sbus.cpp index 57b7d22e5..ace6d7060 100644 --- a/radio/src/sbus.cpp +++ b/radio/src/sbus.cpp @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -33,7 +33,6 @@ #define SBUS_CH_CENTER 0x3E0 -Fifo sbusFifo; uint8_t SbusFrame[SBUS_MAX_FRAME_SIZE]; uint16_t SbusTimer ; uint8_t SbusIndex = 0 ; @@ -76,7 +75,7 @@ void processSbusInput() { uint8_t rxchar; uint32_t active = 0; - while (sbusFifo.pop(rxchar)) { + while (sbusGetByte(&rxchar)) { active = 1; SbusFrame[SbusIndex++] = rxchar; if (SbusIndex > SBUS_MAX_FRAME_SIZE-1) { diff --git a/radio/src/targets/horus/board_horus.h b/radio/src/targets/horus/board_horus.h index a72a31807..031e272b0 100644 --- a/radio/src/targets/horus/board_horus.h +++ b/radio/src/targets/horus/board_horus.h @@ -308,6 +308,7 @@ int32_t getVolume(void); void telemetryPortInit(uint32_t baudrate); void telemetryPortSetDirectionOutput(void); void sportSendBuffer(uint8_t * buffer, uint32_t count); +int telemetryGetByte(uint8_t * byte); // Haptic driver void hapticInit(void); @@ -318,12 +319,14 @@ void hapticOn(uint32_t pwmPercent); // Second serial port driver #define DEBUG_BAUDRATE 115200 +extern uint8_t serial2Mode; void serial2Init(unsigned int mode, unsigned int protocol); void serial2Putc(char c); #define serial2TelemetryInit(protocol) serial2Init(UART_MODE_TELEMETRY, protocol) void serial2SbusInit(void); void serial2Stop(void); #define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE) +int sbusGetByte(uint8_t * byte); #if defined(USB_JOYSTICK) && !defined(SIMU) void usbJoystickUpdate(void); @@ -332,4 +335,12 @@ void usbJoystickUpdate(void); extern uint8_t currentTrainerMode; void checkTrainerSettings(void); +#if defined(__cplusplus) +#include "fifo.h" +#include "dmafifo.h" +extern DMAFifo<512> telemetryFifo; +extern DMAFifo<32> serial2RxFifo; +extern Fifo sbusFifo; +#endif + #endif // _BOARD_HORUS_H_ diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index c1d67965e..3b1886bfc 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -151,9 +151,11 @@ #define SERIAL_USART USART3 #define SERIAL_USART_IRQHandler USART3_IRQHandler #define SERIAL_USART_IRQn USART3_IRQn +#define SERIAL_DMA_Stream_RX DMA1_Stream1 +#define SERIAL_DMA_Channel_RX DMA_Channel_4 // Telemetry -#define TELEMETRY_RCC_AHB1Periph RCC_AHB1Periph_GPIOD +#define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1) #define TELEMETRY_RCC_APB1Periph RCC_APB1Periph_USART2 #define TELEMETRY_GPIO_DIR GPIOD #define TELEMETRY_DIR_GPIO_PIN GPIO_Pin_4 // PD.04 @@ -164,8 +166,13 @@ #define TELEMETRY_GPIO_PinSource_RX GPIO_PinSource6 #define TELEMETRY_GPIO_AF GPIO_AF_USART2 #define TELEMETRY_USART USART2 -#define TELEMETRY_USART_IRQHandler USART2_IRQHandler -#define TELEMETRY_USART_IRQn USART2_IRQn +#define TELEMETRY_DMA_Stream_RX DMA1_Stream5 +#define TELEMETRY_DMA_Channel_RX DMA_Channel_4 +#define TELEMETRY_DMA_Stream_TX DMA1_Stream6 +#define TELEMETRY_DMA_Channel_TX DMA_Channel_4 +#define TELEMETRY_DMA_TX_Stream_IRQ DMA1_Stream6_IRQn +#define TELEMETRY_DMA_TX_IRQHandler DMA1_Stream6_IRQHandler +#define TELEMETRY_DMA_TX_FLAG_TC DMA_IT_TCIF6 // Heartbeat #define HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOD diff --git a/radio/src/targets/horus/serial2_driver.cpp b/radio/src/targets/horus/serial2_driver.cpp index c1a17db15..73404f853 100644 --- a/radio/src/targets/horus/serial2_driver.cpp +++ b/radio/src/targets/horus/serial2_driver.cpp @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -22,10 +22,9 @@ uint8_t serial2Mode = 0; Fifo serial2TxFifo; -extern Fifo telemetryFifo; -extern Fifo sbusFifo; +DMAFifo<32> serial2RxFifo __DMA (SERIAL_DMA_Stream_RX); -void uart3Setup(unsigned int baudrate) +void uart3Setup(unsigned int baudrate, bool dma) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; @@ -39,42 +38,70 @@ void uart3Setup(unsigned int baudrate) GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(SERIAL_GPIO, &GPIO_InitStructure); - + 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 = USART_Mode_Tx | USART_Mode_Rx; - + USART_Init(SERIAL_USART, &USART_InitStructure); - USART_Cmd(SERIAL_USART, ENABLE); - USART_ITConfig(SERIAL_USART, USART_IT_RXNE, ENABLE); - USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE); - - NVIC_SetPriority(SERIAL_USART_IRQn, 7); - NVIC_EnableIRQ(SERIAL_USART_IRQn); + if (dma) { + DMA_InitTypeDef DMA_InitStructure; + serial2RxFifo.clear(); + USART_ITConfig(SERIAL_USART, USART_IT_RXNE, DISABLE); + USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE); + DMA_InitStructure.DMA_Channel = SERIAL_DMA_Channel_RX; + DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&SERIAL_USART->DR); + DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(serial2RxFifo.buffer()); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = serial2RxFifo.size(); + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + DMA_InitStructure.DMA_Priority = DMA_Priority_Low; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(SERIAL_DMA_Stream_RX, &DMA_InitStructure); + USART_DMACmd(SERIAL_USART, USART_DMAReq_Rx, ENABLE); + USART_Cmd(SERIAL_USART, ENABLE); + DMA_Cmd(SERIAL_DMA_Stream_RX, ENABLE); + } + else { +#if !defined(USB_SERIAL) && defined(CLI) + USART_Cmd(SERIAL_USART, ENABLE); + USART_ITConfig(SERIAL_USART, USART_IT_RXNE, ENABLE); + USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE); + NVIC_SetPriority(SERIAL_USART_IRQn, 7); + NVIC_EnableIRQ(SERIAL_USART_IRQn); +#endif + } } void serial2Init(unsigned int mode, unsigned int protocol) { - USART_DeInit(SERIAL_USART); + serial2Stop(); serial2Mode = mode; switch (mode) { case UART_MODE_TELEMETRY_MIRROR: - uart3Setup(FRSKY_SPORT_BAUDRATE); + uart3Setup(FRSKY_SPORT_BAUDRATE, false); break; #if !defined(USB_SERIAL) && (defined(DEBUG) || defined(CLI)) case UART_MODE_DEBUG: - uart3Setup(DEBUG_BAUDRATE); + uart3Setup(DEBUG_BAUDRATE, false); break; #endif case UART_MODE_TELEMETRY: if (protocol == PROTOCOL_FRSKY_D_SECONDARY) { - uart3Setup(FRSKY_D_BAUDRATE); + uart3Setup(FRSKY_D_BAUDRATE, true); } break; } @@ -89,18 +116,20 @@ void serial2Putc(char c) void serial2SbusInit() { - uart3Setup(100000); + // TODO is it possible on Horus? + uart3Setup(SBUS_BAUDRATE, true); SERIAL_USART->CR1 |= USART_CR1_M | USART_CR1_PCE ; } void serial2Stop() { + DMA_DeInit(SERIAL_DMA_Stream_RX); USART_DeInit(SERIAL_USART); } uint8_t serial2TracesEnabled() { - return 1; // (serial2Mode == 0); + return 1; // TODO (serial2Mode == 0); } #if !defined(SIMU) @@ -118,29 +147,21 @@ extern "C" void SERIAL_USART_IRQHandler(void) } } +#if !defined(USB_SERIAL) && defined(CLI) // Receive uint32_t status = SERIAL_USART->SR; while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) { uint8_t data = SERIAL_USART->DR; - if (!(status & USART_FLAG_ERRORS)) { switch (serial2Mode) { - case UART_MODE_TELEMETRY: - telemetryFifo.push(data); - break; - case UART_MODE_SBUS_TRAINER: - sbusFifo.push(data); - break; -#if defined(CLI) case UART_MODE_DEBUG: cliRxFifo.push(data); break; -#endif } } - status = SERIAL_USART->SR; } -} #endif +} +#endif diff --git a/radio/src/targets/horus/telemetry_driver.cpp b/radio/src/targets/horus/telemetry_driver.cpp index be550df04..5edd40fca 100644 --- a/radio/src/targets/horus/telemetry_driver.cpp +++ b/radio/src/targets/horus/telemetry_driver.cpp @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -18,9 +18,9 @@ * GNU General Public License for more details. */ -#include "../../opentx.h" +#include "opentx.h" -extern Fifo telemetryFifo; +DMAFifo<512> telemetryFifo __DMA (TELEMETRY_DMA_Stream_RX); void telemetryPortInit(uint32_t baudrate) { @@ -29,6 +29,13 @@ void telemetryPortInit(uint32_t baudrate) return; } + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = TELEMETRY_DMA_TX_Stream_IRQ; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pre-emption priority. */; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; @@ -47,32 +54,45 @@ void telemetryPortInit(uint32_t baudrate) GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(TELEMETRY_GPIO_DIR, &GPIO_InitStructure); GPIO_ResetBits(TELEMETRY_GPIO_DIR, TELEMETRY_DIR_GPIO_PIN); - + 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 = USART_Mode_Tx | USART_Mode_Rx; - + USART_Init(TELEMETRY_USART, &USART_InitStructure); + + DMA_InitTypeDef DMA_InitStructure; + telemetryFifo.clear(); + USART_ITConfig(TELEMETRY_USART, USART_IT_RXNE, DISABLE); + USART_ITConfig(TELEMETRY_USART, USART_IT_TXE, DISABLE); + DMA_InitStructure.DMA_Channel = TELEMETRY_DMA_Channel_RX; + DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&TELEMETRY_USART->DR); + DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(telemetryFifo.buffer()); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = telemetryFifo.size(); + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + DMA_InitStructure.DMA_Priority = DMA_Priority_Low; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(TELEMETRY_DMA_Stream_RX, &DMA_InitStructure); + USART_DMACmd(TELEMETRY_USART, USART_DMAReq_Rx, ENABLE); USART_Cmd(TELEMETRY_USART, ENABLE); - USART_ITConfig(TELEMETRY_USART, USART_IT_RXNE, ENABLE); - - NVIC_SetPriority(TELEMETRY_USART_IRQn, 6); - NVIC_EnableIRQ(TELEMETRY_USART_IRQn); + DMA_Cmd(TELEMETRY_DMA_Stream_RX, ENABLE); } -struct SportTxBuffer -{ - uint8_t *ptr; - uint32_t count; -} sportTxBuffer; - void telemetryPortSetDirectionOutput() { TELEMETRY_GPIO_DIR->BSRRL = TELEMETRY_DIR_GPIO_PIN; // output enable - TELEMETRY_USART->CR1 &= ~USART_CR1_RE; // turn off receiver + TELEMETRY_USART->CR1 &= ~USART_CR1_RE; // turn off receiver } void telemetryPortSetDirectionInput() @@ -81,49 +101,64 @@ void telemetryPortSetDirectionInput() TELEMETRY_USART->CR1 |= USART_CR1_RE; // turn on receiver } -void sportSendBuffer(uint8_t *buffer, uint32_t count) +void sportSendBuffer(uint8_t * buffer, uint32_t count) { - sportTxBuffer.ptr = buffer ; - sportTxBuffer.count = count ; + #if 0 telemetryPortSetDirectionOutput(); - TELEMETRY_USART->CR1 |= USART_CR1_TXEIE ; + + DMA_InitTypeDef DMA_InitStructure; + DMA_DeInit(TELEMETRY_DMA_Stream_TX); + DMA_InitStructure.DMA_Channel = TELEMETRY_DMA_Channel_TX; + DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&TELEMETRY_USART->DR); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(buffer); + DMA_InitStructure.DMA_BufferSize = count; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(TELEMETRY_DMA_Stream_TX, &DMA_InitStructure); + DMA_Cmd(TELEMETRY_DMA_Stream_TX, ENABLE); + USART_DMACmd(TELEMETRY_USART, USART_DMAReq_Tx, ENABLE); + DMA_ITConfig(TELEMETRY_DMA_Stream_TX, DMA_IT_TC, ENABLE); + + // enable interrupt and set it's priority + NVIC_EnableIRQ(TELEMETRY_DMA_TX_Stream_IRQ) ; + NVIC_SetPriority(TELEMETRY_DMA_TX_Stream_IRQ, 7); + #endif } -#if !defined(SIMU) -#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE) - -extern "C" void TELEMETRY_USART_IRQHandler() +extern "C" void TELEMETRY_DMA_TX_IRQHandler(void) { - uint32_t status; - uint8_t data; - - status = TELEMETRY_USART->SR; - - if (status & USART_SR_TXE) { - if (sportTxBuffer.count) { - TELEMETRY_USART->DR = *sportTxBuffer.ptr++; - if (--sportTxBuffer.count == 0) { - TELEMETRY_USART->CR1 &= ~USART_CR1_TXEIE; // stop Tx interrupt - TELEMETRY_USART->CR1 |= USART_CR1_TCIE; // enable complete interrupt - } - } - } - - if ((status & USART_SR_TC) && (TELEMETRY_USART->CR1 & USART_CR1_TCIE)) { - TELEMETRY_USART->CR1 &= ~USART_CR1_TCIE ; // stop Complete interrupt + if (DMA_GetITStatus(TELEMETRY_DMA_Stream_TX, TELEMETRY_DMA_TX_FLAG_TC)) { + DMA_ClearITPendingBit(TELEMETRY_DMA_Stream_TX, TELEMETRY_DMA_TX_FLAG_TC); telemetryPortSetDirectionInput(); - while (status & (USART_FLAG_RXNE)) { - status = TELEMETRY_USART->DR; - status = TELEMETRY_USART->SR ; - } - } - - while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) { - data = TELEMETRY_USART->DR; - if (!(status & USART_FLAG_ERRORS)) { - telemetryFifo.push(data); - } - status = TELEMETRY_USART->SR; } } + +// TODO we should have telemetry in an higher layer, functions above should move to a sport_driver.cpp +int telemetryGetByte(uint8_t * byte) +{ + // TODO I am not sure it's possible to have this cable on Horus ... +#if 0 + if (telemetryProtocol == PROTOCOL_FRSKY_D_SECONDARY) { + if (serial2Mode == UART_MODE_TELEMETRY) + return serial2RxFifo.pop(*byte); + else + return 0; + } + else { + return telemetryFifo.pop(*byte); + } +#else + return telemetryFifo.pop(*byte); #endif + + +} diff --git a/radio/src/targets/simu/simpgmspace.cpp b/radio/src/targets/simu/simpgmspace.cpp index 4bb3c425a..2a7e1b521 100644 --- a/radio/src/targets/simu/simpgmspace.cpp +++ b/radio/src/targets/simu/simpgmspace.cpp @@ -1297,6 +1297,7 @@ FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG) { ret void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF) { } void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef* USART_InitStruct) { } void USART_Cmd(USART_TypeDef* USARTx, FunctionalState NewState) { } +void USART_DMACmd(USART_TypeDef* USARTx, uint16_t USART_DMAReq, FunctionalState NewState) { } void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState) { } void RCC_PLLI2SConfig(uint32_t PLLI2SN, uint32_t PLLI2SR) { } void RCC_PLLI2SCmd(FunctionalState NewState) { } diff --git a/radio/src/targets/simu/simpgmspace.h b/radio/src/targets/simu/simpgmspace.h index f691feffc..1ce26a9c2 100644 --- a/radio/src/targets/simu/simpgmspace.h +++ b/radio/src/targets/simu/simpgmspace.h @@ -449,6 +449,8 @@ inline void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, Func inline void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct) { } inline void DMA_Cmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState) { } inline FlagStatus DMA_GetFlagStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG) { return RESET; } +inline ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT) { return RESET; } +inline void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT) { } inline void SPI_I2S_DMACmd(SPI_TypeDef* SPIx, uint16_t SPI_I2S_DMAReq, FunctionalState NewState) { } inline void UART3_Configure(uint32_t baudrate, uint32_t masterClock) { } inline void NVIC_Init(NVIC_InitTypeDef *) { } diff --git a/radio/src/targets/taranis/board_taranis.h b/radio/src/targets/taranis/board_taranis.h index 3d9657fc2..46f06d5a1 100644 --- a/radio/src/targets/taranis/board_taranis.h +++ b/radio/src/targets/taranis/board_taranis.h @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -212,6 +212,7 @@ void stop_cppm_on_heartbeat_capture(void); void init_sbus_on_heartbeat_capture(void); void stop_sbus_on_heartbeat_capture(void); void set_trainer_ppm_parameters(uint32_t idleTime, uint32_t delay, uint32_t positive); +int sbusGetByte(uint8_t * byte); // Keys driver void keysInit(void); @@ -322,7 +323,8 @@ void debugPutc(const char c); // Telemetry driver void telemetryPortInit(uint32_t baudrate); void telemetryPortSetDirectionOutput(void); -void sportSendBuffer(uint8_t *buffer, uint32_t count); +void sportSendBuffer(uint8_t * buffer, uint32_t count); +int telemetryGetByte(uint8_t * byte); // Audio driver void audioInit(void) ; @@ -348,6 +350,7 @@ void hapticOff(void); // Second serial port driver #define DEBUG_BAUDRATE 115200 +extern uint8_t serial2Mode; void serial2Init(unsigned int mode, unsigned int protocol); void serial2Putc(char c); #define serial2TelemetryInit(protocol) serial2Init(UART_MODE_TELEMETRY, protocol) @@ -391,4 +394,12 @@ void usbJoystickUpdate(void); extern uint8_t currentTrainerMode; void checkTrainerSettings(void); +#if defined(__cplusplus) +#include "fifo.h" +#include "dmafifo.h" +extern DMAFifo<512> telemetryFifo; // TODO I don't think we really need 512bytes here! +extern DMAFifo<32> serial2RxFifo; +extern Fifo sbusFifo; +#endif + #endif // _BOARD_TARANIS_H_ diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 5533becdd..1b5fa65b0 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -375,12 +375,14 @@ #define SERIAL_USART USART3 #define SERIAL_USART_IRQHandler USART3_IRQHandler #define SERIAL_USART_IRQn USART3_IRQn +#define SERIAL_DMA_Stream_RX DMA1_Stream1 +#define SERIAL_DMA_Channel_RX DMA_Channel_4 // Telemetry -#define TELEMETRY_RCC_AHB1Periph RCC_AHB1Periph_GPIOD +#define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1) +#define TELEMETRY_RCC_APB1Periph RCC_APB1Periph_USART2 #define TELEMETRY_GPIO_DIR GPIOD #define TELEMETRY_DIR_GPIO_PIN GPIO_Pin_4 // PD.04 -#define TELEMETRY_RCC_APB1Periph RCC_APB1Periph_USART2 #define TELEMETRY_GPIO GPIOD #define TELEMETRY_TX_GPIO_PIN GPIO_Pin_5 // PD.05 #define TELEMETRY_RX_GPIO_PIN GPIO_Pin_6 // PD.06 @@ -388,8 +390,13 @@ #define TELEMETRY_GPIO_PinSource_RX GPIO_PinSource6 #define TELEMETRY_GPIO_AF GPIO_AF_USART2 #define TELEMETRY_USART USART2 -#define TELEMETRY_USART_IRQHandler USART2_IRQHandler -#define TELEMETRY_USART_IRQn USART2_IRQn +#define TELEMETRY_DMA_Stream_RX DMA1_Stream5 +#define TELEMETRY_DMA_Channel_RX DMA_Channel_4 +#define TELEMETRY_DMA_Stream_TX DMA1_Stream6 +#define TELEMETRY_DMA_Channel_TX DMA_Channel_4 +#define TELEMETRY_DMA_TX_Stream_IRQ DMA1_Stream6_IRQn +#define TELEMETRY_DMA_TX_IRQHandler DMA1_Stream6_IRQHandler +#define TELEMETRY_DMA_TX_FLAG_TC DMA_IT_TCIF6 // Heartbeat #define HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOC @@ -481,7 +488,7 @@ #define LCD_GPIO_PIN_NCS GPIO_Pin_14 // PD.14 #define LCD_GPIO_PIN_A0 GPIO_Pin_13 // PD.13 #define LCD_GPIO_PIN_RST GPIO_Pin_12 // PD.12 -#endif +#endif // I2C Bus: EEPROM and CAT5137 digital pot for volume control #define I2C_RCC_AHB1Periph RCC_AHB1Periph_GPIOB diff --git a/radio/src/targets/taranis/serial2_driver.cpp b/radio/src/targets/taranis/serial2_driver.cpp index 614e9b9d0..ab5018a6c 100644 --- a/radio/src/targets/taranis/serial2_driver.cpp +++ b/radio/src/targets/taranis/serial2_driver.cpp @@ -1,31 +1,30 @@ -/* - * Copyright (C) OpenTX - * - * Based on code named - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * 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. - */ - -#include "../../opentx.h" +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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. + */ + +#include "opentx.h" uint8_t serial2Mode = 0; Fifo serial2TxFifo; -extern Fifo telemetryFifo; -extern Fifo sbusFifo; +DMAFifo<32> serial2RxFifo __DMA (SERIAL_DMA_Stream_RX); -void uart3Setup(unsigned int baudrate) +void uart3Setup(unsigned int baudrate, bool dma) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; @@ -39,42 +38,70 @@ void uart3Setup(unsigned int baudrate) GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(SERIAL_GPIO, &GPIO_InitStructure); - + 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 = USART_Mode_Tx | USART_Mode_Rx; - + USART_Init(SERIAL_USART, &USART_InitStructure); - USART_Cmd(SERIAL_USART, ENABLE); - USART_ITConfig(SERIAL_USART, USART_IT_RXNE, ENABLE); - USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE); - - NVIC_SetPriority(SERIAL_USART_IRQn, 7); - NVIC_EnableIRQ(SERIAL_USART_IRQn); + if (dma) { + DMA_InitTypeDef DMA_InitStructure; + serial2RxFifo.clear(); + USART_ITConfig(SERIAL_USART, USART_IT_RXNE, DISABLE); + USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE); + DMA_InitStructure.DMA_Channel = SERIAL_DMA_Channel_RX; + DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&SERIAL_USART->DR); + DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(serial2RxFifo.buffer()); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = serial2RxFifo.size(); + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + DMA_InitStructure.DMA_Priority = DMA_Priority_Low; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(SERIAL_DMA_Stream_RX, &DMA_InitStructure); + USART_DMACmd(SERIAL_USART, USART_DMAReq_Rx, ENABLE); + USART_Cmd(SERIAL_USART, ENABLE); + DMA_Cmd(SERIAL_DMA_Stream_RX, ENABLE); + } + else { +#if !defined(USB_SERIAL) && defined(CLI) + USART_Cmd(SERIAL_USART, ENABLE); + USART_ITConfig(SERIAL_USART, USART_IT_RXNE, ENABLE); + USART_ITConfig(SERIAL_USART, USART_IT_TXE, DISABLE); + NVIC_SetPriority(SERIAL_USART_IRQn, 7); + NVIC_EnableIRQ(SERIAL_USART_IRQn); +#endif + } } void serial2Init(unsigned int mode, unsigned int protocol) { - USART_DeInit(SERIAL_USART); + serial2Stop(); serial2Mode = mode; switch (mode) { case UART_MODE_TELEMETRY_MIRROR: - uart3Setup(FRSKY_SPORT_BAUDRATE); + uart3Setup(FRSKY_SPORT_BAUDRATE, false); break; #if !defined(USB_SERIAL) && (defined(DEBUG) || defined(CLI)) case UART_MODE_DEBUG: - uart3Setup(DEBUG_BAUDRATE); + uart3Setup(DEBUG_BAUDRATE, false); break; #endif case UART_MODE_TELEMETRY: if (protocol == PROTOCOL_FRSKY_D_SECONDARY) { - uart3Setup(FRSKY_D_BAUDRATE); + uart3Setup(FRSKY_D_BAUDRATE, true); } break; } @@ -89,12 +116,13 @@ void serial2Putc(char c) void serial2SbusInit() { - uart3Setup(SBUS_BAUDRATE); + uart3Setup(SBUS_BAUDRATE, true); SERIAL_USART->CR1 |= USART_CR1_M | USART_CR1_PCE ; } void serial2Stop() { + DMA_DeInit(SERIAL_DMA_Stream_RX); USART_DeInit(SERIAL_USART); } @@ -122,29 +150,21 @@ extern "C" void SERIAL_USART_IRQHandler(void) } } +#if !defined(USB_SERIAL) && defined(CLI) // Receive uint32_t status = SERIAL_USART->SR; while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) { uint8_t data = SERIAL_USART->DR; - if (!(status & USART_FLAG_ERRORS)) { switch (serial2Mode) { - case UART_MODE_TELEMETRY: - telemetryFifo.push(data); - break; - case UART_MODE_SBUS_TRAINER: - sbusFifo.push(data); - break; -#if !defined(USB_SERIAL) && defined(CLI) case UART_MODE_DEBUG: cliRxFifo.push(data); break; -#endif } } - status = SERIAL_USART->SR; } -} #endif +} +#endif diff --git a/radio/src/targets/taranis/telemetry_driver.cpp b/radio/src/targets/taranis/telemetry_driver.cpp index 3ebfffc64..cd6b1c184 100644 --- a/radio/src/targets/taranis/telemetry_driver.cpp +++ b/radio/src/targets/taranis/telemetry_driver.cpp @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -18,9 +18,9 @@ * GNU General Public License for more details. */ -#include "../../opentx.h" +#include "opentx.h" -extern Fifo telemetryFifo; +DMAFifo<512> telemetryFifo __DMA (TELEMETRY_DMA_Stream_RX); void telemetryPortInit(uint32_t baudrate) { @@ -29,6 +29,13 @@ void telemetryPortInit(uint32_t baudrate) return; } + NVIC_InitTypeDef NVIC_InitStructure; + NVIC_InitStructure.NVIC_IRQChannel = TELEMETRY_DMA_TX_Stream_IRQ; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* Not used as 4 bits are used for the pre-emption priority. */; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); + USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; @@ -41,7 +48,7 @@ void telemetryPortInit(uint32_t baudrate) GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(TELEMETRY_GPIO, &GPIO_InitStructure); - + GPIO_InitStructure.GPIO_Pin = TELEMETRY_DIR_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; @@ -54,21 +61,34 @@ void telemetryPortInit(uint32_t baudrate) USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; - + USART_Init(TELEMETRY_USART, &USART_InitStructure); + + DMA_InitTypeDef DMA_InitStructure; + telemetryFifo.clear(); + USART_ITConfig(TELEMETRY_USART, USART_IT_RXNE, DISABLE); + USART_ITConfig(TELEMETRY_USART, USART_IT_TXE, DISABLE); + DMA_InitStructure.DMA_Channel = TELEMETRY_DMA_Channel_RX; + DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&TELEMETRY_USART->DR); + DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(telemetryFifo.buffer()); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_BufferSize = telemetryFifo.size(); + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; + DMA_InitStructure.DMA_Priority = DMA_Priority_Low; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(TELEMETRY_DMA_Stream_RX, &DMA_InitStructure); + USART_DMACmd(TELEMETRY_USART, USART_DMAReq_Rx, ENABLE); USART_Cmd(TELEMETRY_USART, ENABLE); - USART_ITConfig(TELEMETRY_USART, USART_IT_RXNE, ENABLE); - - NVIC_SetPriority(TELEMETRY_USART_IRQn, 6); - NVIC_EnableIRQ(TELEMETRY_USART_IRQn); + DMA_Cmd(TELEMETRY_DMA_Stream_RX, ENABLE); } -struct SportTxBuffer -{ - uint8_t *ptr; - uint32_t count; -} sportTxBuffer; - void telemetryPortSetDirectionOutput() { TELEMETRY_GPIO_DIR->BSRRL = TELEMETRY_DIR_GPIO_PIN; // output enable @@ -83,47 +103,53 @@ void telemetryPortSetDirectionInput() void sportSendBuffer(uint8_t * buffer, uint32_t count) { - sportTxBuffer.ptr = buffer; - sportTxBuffer.count = count; telemetryPortSetDirectionOutput(); - TELEMETRY_USART->CR1 |= USART_CR1_TXEIE; + + DMA_InitTypeDef DMA_InitStructure; + DMA_DeInit(TELEMETRY_DMA_Stream_TX); + DMA_InitStructure.DMA_Channel = TELEMETRY_DMA_Channel_TX; + DMA_InitStructure.DMA_PeripheralBaseAddr = CONVERT_PTR_UINT(&TELEMETRY_USART->DR); + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + DMA_InitStructure.DMA_Memory0BaseAddr = CONVERT_PTR_UINT(buffer); + DMA_InitStructure.DMA_BufferSize = count; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; + DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; + DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; + DMA_Init(TELEMETRY_DMA_Stream_TX, &DMA_InitStructure); + DMA_Cmd(TELEMETRY_DMA_Stream_TX, ENABLE); + USART_DMACmd(TELEMETRY_USART, USART_DMAReq_Tx, ENABLE); + DMA_ITConfig(TELEMETRY_DMA_Stream_TX, DMA_IT_TC, ENABLE); + + // enable interrupt and set it's priority + NVIC_EnableIRQ(TELEMETRY_DMA_TX_Stream_IRQ) ; + NVIC_SetPriority(TELEMETRY_DMA_TX_Stream_IRQ, 7); } -#if !defined(SIMU) -#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE) - -extern "C" void TELEMETRY_USART_IRQHandler() +extern "C" void TELEMETRY_DMA_TX_IRQHandler(void) { - uint32_t status; - uint8_t data; - - status = TELEMETRY_USART->SR; - - if (status & USART_SR_TXE) { - if (sportTxBuffer.count) { - TELEMETRY_USART->DR = *sportTxBuffer.ptr++; - if (--sportTxBuffer.count == 0) { - TELEMETRY_USART->CR1 &= ~USART_CR1_TXEIE; // stop Tx interrupt - TELEMETRY_USART->CR1 |= USART_CR1_TCIE; // enable complete interrupt - } - } - } - - if ((status & USART_SR_TC) && (TELEMETRY_USART->CR1 & USART_CR1_TCIE)) { - TELEMETRY_USART->CR1 &= ~USART_CR1_TCIE ; // stop Complete interrupt + if (DMA_GetITStatus(TELEMETRY_DMA_Stream_TX, TELEMETRY_DMA_TX_FLAG_TC)) { + DMA_ClearITPendingBit(TELEMETRY_DMA_Stream_TX, TELEMETRY_DMA_TX_FLAG_TC); telemetryPortSetDirectionInput(); - while (status & (USART_FLAG_RXNE)) { - status = TELEMETRY_USART->DR; - status = TELEMETRY_USART->SR; - } - } - - while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) { - data = TELEMETRY_USART->DR; - if (!(status & USART_FLAG_ERRORS)) { - telemetryFifo.push(data); - } - status = TELEMETRY_USART->SR; } } -#endif + +// TODO we should have telemetry in an higher layer, functions above should move to a sport_driver.cpp +int telemetryGetByte(uint8_t * byte) +{ + if (telemetryProtocol == PROTOCOL_FRSKY_D_SECONDARY) { + if (serial2Mode == UART_MODE_TELEMETRY) + return serial2RxFifo.pop(*byte); + else + return 0; + } + else { + return telemetryFifo.pop(*byte); + } +} diff --git a/radio/src/targets/taranis/trainer_driver.cpp b/radio/src/targets/taranis/trainer_driver.cpp index 7da2b6f4d..88104d0aa 100644 --- a/radio/src/targets/taranis/trainer_driver.cpp +++ b/radio/src/targets/taranis/trainer_driver.cpp @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -18,9 +18,9 @@ * GNU General Public License for more details. */ -#include "../../opentx.h" +#include "opentx.h" -extern Fifo sbusFifo; +Fifo sbusFifo; #define setupTrainerPulses() setupPulsesPPM(TRAINER_MODULE) @@ -243,3 +243,15 @@ extern "C" void HEARTBEAT_USART_IRQHandler() } } #endif + +int sbusGetByte(uint8_t * byte) +{ + switch (currentTrainerMode) { + case TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE: + return sbusFifo.pop(*byte); + case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: + return serial2RxFifo.pop(*byte); + default: + return false; + } +} diff --git a/radio/src/telemetry/frsky.cpp b/radio/src/telemetry/frsky.cpp index 96a1300c1..934dc5437 100644 --- a/radio/src/telemetry/frsky.cpp +++ b/radio/src/telemetry/frsky.cpp @@ -43,10 +43,6 @@ uint8_t frskyTxBufferCount = 0; uint8_t telemetryState = TELEMETRY_INIT; #endif -#if defined(PCBTARANIS) || defined(PCBFLAMENCO) || defined(PCBHORUS) -Fifo telemetryFifo; // TODO should be in the driver -#endif - uint8_t frskyRxBufferCount = 0; FrskyData frskyData; diff --git a/radio/src/telemetry/frsky_sport.cpp b/radio/src/telemetry/frsky_sport.cpp index 6347ea181..ba77828bf 100644 --- a/radio/src/telemetry/frsky_sport.cpp +++ b/radio/src/telemetry/frsky_sport.cpp @@ -337,9 +337,9 @@ bool sportWaitState(SportUpdateState state, int timeout) return true; #else for (int i=timeout/2; i>=0; i--) { - uint8_t data ; - while (telemetryFifo.pop(data)) { - processSerialData(data); + uint8_t byte ; + while (telemetryGetByte(&byte)) { + processSerialData(byte); } if (sportUpdateState == state) { return true; @@ -358,7 +358,7 @@ void blankPacket(uint8_t *packet) memset(packet+2, 0, 6); } -uint8_t sportUpdatePacket[16]; +uint8_t sportUpdatePacket[16] __DMA; void writePacket(uint8_t * packet) { diff --git a/radio/src/telemetry/telemetry.h b/radio/src/telemetry/telemetry.h index 5cb981ccb..36b3f695d 100644 --- a/radio/src/telemetry/telemetry.h +++ b/radio/src/telemetry/telemetry.h @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -21,8 +21,6 @@ #ifndef _TELEMETRY_H_ #define _TELEMETRY_H_ -extern Fifo telemetryFifo; - enum TelemetryProtocol { TELEM_PROTO_FRSKY_D, diff --git a/radio/src/tests/lcd.cpp b/radio/src/tests/lcd.cpp index 926fe07f6..1f27bad18 100644 --- a/radio/src/tests/lcd.cpp +++ b/radio/src/tests/lcd.cpp @@ -194,16 +194,6 @@ TEST(Lcd, vline_x_lt0) #endif #if defined(CPUARM) -TEST(Lcd, SmlsizeDecimalPoint) -{ - lcdClear(); - lcdDrawNumber(0, 1, 105, PREC1|SMLSIZE|LEFT); - lcdDrawNumber(0, LCD_H-7, 105, PREC1|SMLSIZE|LEFT|INVERS); - lcdDrawNumber(LCD_W, 1, 105, PREC2|SMLSIZE); - lcdDrawNumber(LCD_W, LCD_H-7, 105, PREC2|SMLSIZE|INVERS); - EXPECT_TRUE(checkScreenshot("SmlsizeDecimalPoint")); -} - TEST(Lcd, Smlsize) { lcdClear();