diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index 0c419213a..668e97f83 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -441,6 +441,7 @@ if(CPU_FAMILY STREQUAL STM32) foreach(FILE ${STM32USB_SRC}) set(FIRMWARE_SRC ${FIRMWARE_SRC} ${STM32USB_DIR}/${FILE}) endforeach() + set(SRC ${SRC} sbus.cpp) endif() if(ARCH STREQUAL ARM) @@ -510,7 +511,6 @@ if(ARCH STREQUAL ARM) main_arm.cpp tasks_arm.cpp audio_arm.cpp - sbus.cpp telemetry/telemetry.cpp telemetry/frsky.cpp telemetry/frsky_d_arm.cpp diff --git a/radio/src/targets/taranis/audio_driver.cpp b/radio/src/targets/taranis/audio_driver.cpp index f2123b510..834450941 100644 --- a/radio/src/targets/taranis/audio_driver.cpp +++ b/radio/src/targets/taranis/audio_driver.cpp @@ -27,23 +27,20 @@ void setSampleRate(uint32_t frequency) { register uint32_t timer = (PERI1_FREQUENCY * TIMER_MULT_APB1) / frequency - 1 ; // MCK/8 and 100 000 Hz - TIM6->CR1 &= ~TIM_CR1_CEN ; - TIM6->CNT = 0 ; - TIM6->ARR = limit(2, timer, 65535) ; - TIM6->CR1 |= TIM_CR1_CEN ; + AUDIO_TIMER->CR1 &= ~TIM_CR1_CEN ; + AUDIO_TIMER->CNT = 0 ; + AUDIO_TIMER->ARR = limit(2, timer, 65535) ; + AUDIO_TIMER->CR1 |= TIM_CR1_CEN ; } // Start TIMER6 at 100000Hz, used for DAC trigger void dacTimerInit() { - // Now for timer 6 - RCC->APB1ENR |= RCC_APB1ENR_TIM6EN ; // Enable clock - - TIM6->PSC = 0 ; // Max speed - TIM6->ARR = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 100000 - 1 ; // 10 uS, 100 kHz - TIM6->CR2 = 0 ; - TIM6->CR2 = 0x20 ; - TIM6->CR1 = TIM_CR1_CEN ; + AUDIO_TIMER->PSC = 0 ; // Max speed + AUDIO_TIMER->ARR = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 100000 - 1 ; // 10 uS, 100 kHz + AUDIO_TIMER->CR2 = 0 ; + AUDIO_TIMER->CR2 = 0x20 ; + AUDIO_TIMER->CR1 = TIM_CR1_CEN ; } // Configure DAC0 (or DAC1 for REVA) @@ -53,39 +50,36 @@ void dacInit() { dacTimerInit(); - RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ; // Enable portA clock configure_pins( GPIO_Pin_4, PIN_ANALOG | PIN_PORTA ) ; - RCC->APB1ENR |= RCC_APB1ENR_DACEN ; // Enable clock - RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN ; // Enable DMA1 clock // Chan 7, 16-bit wide, Medium priority, memory increments - DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA - DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits - DMA1_Stream5->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 | + AUDIO_DMA_Stream->CR &= ~DMA_SxCR_EN ; // Disable DMA + AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits + AUDIO_DMA_Stream->CR = DMA_SxCR_CHSEL_0 | DMA_SxCR_CHSEL_1 | DMA_SxCR_CHSEL_2 | DMA_SxCR_PL_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_PSIZE_0 | DMA_SxCR_MINC | DMA_SxCR_DIR_0 | DMA_SxCR_CIRC ; - DMA1_Stream5->PAR = CONVERT_PTR_UINT(&DAC->DHR12R1); - // DMA1_Stream5->M0AR = CONVERT_PTR_UINT(Sine_values); - DMA1_Stream5->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ; - // DMA1_Stream5->NDTR = 100 ; + AUDIO_DMA_Stream->PAR = CONVERT_PTR_UINT(&DAC->DHR12R1); + // AUDIO_DMA_Stream->M0AR = CONVERT_PTR_UINT(Sine_values); + AUDIO_DMA_Stream->FCR = 0x05 ; //DMA_SxFCR_DMDIS | DMA_SxFCR_FTH_0 ; + // AUDIO_DMA_Stream->NDTR = 100 ; DAC->DHR12R1 = 2010 ; DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag DAC->CR = DAC_CR_TEN1 | DAC_CR_EN1 ; // Enable DAC - NVIC_EnableIRQ(TIM6_DAC_IRQn); // TODO needed? - NVIC_SetPriority(TIM6_DAC_IRQn, 7); - NVIC_EnableIRQ(DMA1_Stream5_IRQn); - NVIC_SetPriority(DMA1_Stream5_IRQn, 7); + NVIC_EnableIRQ(AUDIO_TIM_IRQn); // TODO needed? + NVIC_SetPriority(AUDIO_TIM_IRQn, 7); + NVIC_EnableIRQ(AUDIO_DMA_Stream_IRQn); + NVIC_SetPriority(AUDIO_DMA_Stream_IRQn, 7); } bool audioPushBuffer(AudioBuffer * buffer) { if (dacIdle) { dacIdle = false; - DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA channel - DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits - DMA1_Stream5->M0AR = CONVERT_PTR_UINT(buffer->data); - DMA1_Stream5->NDTR = buffer->size; - DMA1_Stream5->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel and interrupt + AUDIO_DMA_Stream->CR &= ~DMA_SxCR_EN ; // Disable DMA channel + AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits + AUDIO_DMA_Stream->M0AR = CONVERT_PTR_UINT(buffer->data); + AUDIO_DMA_Stream->NDTR = buffer->size; + AUDIO_DMA_Stream->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel and interrupt DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1 ; // Enable DAC return true; @@ -97,15 +91,15 @@ bool audioPushBuffer(AudioBuffer * buffer) void dacStart() { - DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits - DMA1_Stream5->CR |= DMA_SxCR_CIRC | DMA_SxCR_EN ; // Enable DMA channel + AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits + AUDIO_DMA_Stream->CR |= DMA_SxCR_CIRC | DMA_SxCR_EN ; // Enable DMA channel DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag DAC->CR |= DAC_CR_EN1 | DAC_CR_DMAEN1 ; // Enable DAC } void dacStop() { - DMA1_Stream5->CR &= ~DMA_SxCR_CIRC ; + AUDIO_DMA_Stream->CR &= ~DMA_SxCR_CIRC ; } @@ -118,13 +112,13 @@ void audioInit() void audioEnd() { DAC->CR = 0 ; - TIM6->CR1 = 0 ; + AUDIO_TIMER->CR1 = 0 ; // Also need to turn off any possible interrupts - NVIC_DisableIRQ(TIM6_DAC_IRQn) ; - NVIC_DisableIRQ(DMA1_Stream5_IRQn) ; + NVIC_DisableIRQ(AUDIO_TIM_IRQn) ; + NVIC_DisableIRQ(AUDIO_DMA_Stream_IRQn) ; } -extern "C" void TIM6_DAC_IRQHandler() +extern "C" void AUDIO_TIM_IRQHandler() { DAC->CR &= ~DAC_CR_DMAEN1 ; // Stop DMA requests #if !defined(REV9E) @@ -133,18 +127,18 @@ extern "C" void TIM6_DAC_IRQHandler() DAC->SR = DAC_SR_DMAUDR1 ; // Write 1 to clear flag } -extern "C" void DMA1_Stream5_IRQHandler() +extern "C" void AUDIO_DMA_Stream_IRQHandler() { - DMA1_Stream5->CR &= ~DMA_SxCR_TCIE ; // Stop interrupt - DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear flags - DMA1_Stream5->CR &= ~DMA_SxCR_EN ; // Disable DMA channel + AUDIO_DMA_Stream->CR &= ~DMA_SxCR_TCIE ; // Stop interrupt + AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear flags + AUDIO_DMA_Stream->CR &= ~DMA_SxCR_EN ; // Disable DMA channel AudioBuffer * nextBuffer = audioQueue.getNextFilledBuffer(); if (nextBuffer) { - DMA1_Stream5->M0AR = CONVERT_PTR_UINT(nextBuffer->data); - DMA1_Stream5->NDTR = nextBuffer->size; - DMA1->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits - DMA1_Stream5->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel + AUDIO_DMA_Stream->M0AR = CONVERT_PTR_UINT(nextBuffer->data); + AUDIO_DMA_Stream->NDTR = nextBuffer->size; + AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits + AUDIO_DMA_Stream->CR |= DMA_SxCR_EN | DMA_SxCR_TCIE ; // Enable DMA channel DAC->SR = DAC_SR_DMAUDR1; // Write 1 to clear flag } else { diff --git a/radio/src/targets/taranis/board_taranis.cpp b/radio/src/targets/taranis/board_taranis.cpp index 2dd4f43bc..39cbf16d2 100644 --- a/radio/src/targets/taranis/board_taranis.cpp +++ b/radio/src/targets/taranis/board_taranis.cpp @@ -121,8 +121,8 @@ extern "C" void INTERRUPT_5MS_IRQHandler() void boardInit() { - RCC_AHB1PeriphClockCmd(PWR_RCC_AHB1Periph | KEYS_RCC_AHB1Periph | LCD_RCC_AHB1Periph | BACKLIGHT_RCC_AHB1Periph | ADC_RCC_AHB1Periph | I2C_RCC_AHB1Periph | SD_RCC_AHB1Periph | HAPTIC_RCC_AHB1Periph | INTMODULE_RCC_AHB1Periph | EXTMODULE_RCC_AHB1Periph | TELEMETRY_RCC_AHB1Periph | SERIAL_RCC_AHB1Periph | TRAINER_RCC_AHB1Periph | HEARTBEAT_RCC_AHB1Periph, ENABLE); - RCC_APB1PeriphClockCmd(LCD_RCC_APB1Periph | BACKLIGHT_RCC_APB1Periph | INTERRUPT_5MS_APB1Periph | TIMER_2MHz_APB1Periph | I2C_RCC_APB1Periph | SD_RCC_APB1Periph | TRAINER_RCC_APB1Periph | TELEMETRY_RCC_APB1Periph | SERIAL_RCC_APB1Periph, ENABLE); + RCC_AHB1PeriphClockCmd(PWR_RCC_AHB1Periph | KEYS_RCC_AHB1Periph | LCD_RCC_AHB1Periph | AUDIO_RCC_AHB1Periph | BACKLIGHT_RCC_AHB1Periph | ADC_RCC_AHB1Periph | I2C_RCC_AHB1Periph | SD_RCC_AHB1Periph | HAPTIC_RCC_AHB1Periph | INTMODULE_RCC_AHB1Periph | EXTMODULE_RCC_AHB1Periph | TELEMETRY_RCC_AHB1Periph | SERIAL_RCC_AHB1Periph | TRAINER_RCC_AHB1Periph | HEARTBEAT_RCC_AHB1Periph, ENABLE); + RCC_APB1PeriphClockCmd(LCD_RCC_APB1Periph | AUDIO_RCC_APB1Periph | BACKLIGHT_RCC_APB1Periph | INTERRUPT_5MS_APB1Periph | TIMER_2MHz_APB1Periph | I2C_RCC_APB1Periph | SD_RCC_APB1Periph | TRAINER_RCC_APB1Periph | TELEMETRY_RCC_APB1Periph | SERIAL_RCC_APB1Periph, ENABLE); RCC_APB2PeriphClockCmd(BACKLIGHT_RCC_APB2Periph | ADC_RCC_APB2Periph | HAPTIC_RCC_APB2Periph | INTMODULE_RCC_APB2Periph | EXTMODULE_RCC_APB2Periph | HEARTBEAT_RCC_APB2Periph, ENABLE); #if !defined(REV9E) diff --git a/radio/src/targets/taranis/board_taranis.h b/radio/src/targets/taranis/board_taranis.h index 46f06d5a1..3c53bd828 100644 --- a/radio/src/targets/taranis/board_taranis.h +++ b/radio/src/targets/taranis/board_taranis.h @@ -397,7 +397,7 @@ 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 Fifo telemetryFifo; extern DMAFifo<32> serial2RxFifo; extern Fifo sbusFifo; #endif diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 1b5fa65b0..ee9e696e3 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -390,13 +390,13 @@ #define TELEMETRY_GPIO_PinSource_RX GPIO_PinSource6 #define TELEMETRY_GPIO_AF GPIO_AF_USART2 #define TELEMETRY_USART USART2 -#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 +#define TELEMETRY_USART_IRQHandler USART2_IRQHandler +#define TELEMETRY_USART_IRQn USART2_IRQn // Heartbeat #define HEARTBEAT_RCC_AHB1Periph RCC_AHB1Periph_GPIOC @@ -537,6 +537,17 @@ #define SD_DMA_Channel_SPI DMA_Channel_0 #endif +// Audio +#define AUDIO_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_DMA1) +#define AUDIO_RCC_APB1Periph (RCC_APB1Periph_TIM6 | RCC_APB1Periph_DAC) +#define AUDIO_DMA_Stream DMA1_Stream5 +#define AUDIO_DMA_Stream_IRQn DMA1_Stream5_IRQn +#define AUDIO_TIM_IRQn TIM6_DAC_IRQn +#define AUDIO_TIM_IRQHandler TIM6_DAC_IRQHandler +#define AUDIO_DMA_Stream_IRQHandler DMA1_Stream5_IRQHandler +#define AUDIO_TIMER TIM6 +#define AUDIO_DMA DMA1 + // Haptic #if defined(REVPLUS) #define HAPTIC_RCC_AHB1Periph RCC_AHB1Periph_GPIOB diff --git a/radio/src/targets/taranis/telemetry_driver.cpp b/radio/src/targets/taranis/telemetry_driver.cpp index cd6b1c184..2098aba3f 100644 --- a/radio/src/targets/taranis/telemetry_driver.cpp +++ b/radio/src/targets/taranis/telemetry_driver.cpp @@ -20,7 +20,7 @@ #include "opentx.h" -DMAFifo<512> telemetryFifo __DMA (TELEMETRY_DMA_Stream_RX); +Fifo telemetryFifo; void telemetryPortInit(uint32_t baudrate) { @@ -61,32 +61,11 @@ 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); - DMA_Cmd(TELEMETRY_DMA_Stream_RX, ENABLE); + USART_ITConfig(TELEMETRY_USART, USART_IT_RXNE, ENABLE); + NVIC_SetPriority(TELEMETRY_USART_IRQn, 6); + NVIC_EnableIRQ(TELEMETRY_USART_IRQn); } void telemetryPortSetDirectionOutput() @@ -140,6 +119,19 @@ extern "C" void TELEMETRY_DMA_TX_IRQHandler(void) } } +#define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE) +extern "C" void TELEMETRY_USART_IRQHandler(void) +{ + uint32_t status = TELEMETRY_USART->SR; + while (status & (USART_FLAG_RXNE | USART_FLAG_ERRORS)) { + uint8_t 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) {