diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index d7f6e687d..0254939ca 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -415,7 +415,7 @@ if(ARCH STREQUAL ARM) pulses_driver.cpp keys_driver.cpp adc_driver.cpp - # trainer_driver.cpp + trainer_driver.cpp audio_driver.cpp serial2_driver.cpp telemetry_driver.cpp diff --git a/radio/src/targets/sky9x/board_sky9x.cpp b/radio/src/targets/sky9x/board_sky9x.cpp index 1097b69f3..4f8249077 100644 --- a/radio/src/targets/sky9x/board_sky9x.cpp +++ b/radio/src/targets/sky9x/board_sky9x.cpp @@ -90,11 +90,7 @@ inline void setup_switches() #endif } -#if defined(SIMU) -#define stop_trainer_capture() -#define sam_boot() -#else - +#if !defined(SIMU) inline void UART3_Configure(uint32_t baudrate, uint32_t masterClock) { register Uart *pUart = BT_USART; @@ -179,77 +175,6 @@ inline void start_timer2() TC0->TC_CHANNEL[2].TC_IER = TC_IER0_CPCS ; } -// Start TIMER3 for input capture -inline void start_timer3() -{ - register Tc *ptc ; - - // Enable peripheral clock TC0 = bit 23 thru TC5 = bit 28 - PMC->PMC_PCER0 |= 0x04000000L ; // Enable peripheral clock to TC3 - - ptc = TC1 ; // Tc block 1 (TC3-5) - ptc->TC_BCR = 0 ; // No sync - ptc->TC_BMR = 2 ; - ptc->TC_CHANNEL[0].TC_CMR = 0x00000000 ; // Capture mode - ptc->TC_CHANNEL[0].TC_CMR = 0x00090005 ; // 0000 0000 0000 1001 0000 0000 0000 0101, XC0, A rise, b fall - ptc->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) - - configure_pins( PIO_PC23, PIN_PERIPHERAL | PIN_INPUT | PIN_PER_B | PIN_PORTC | PIN_PULLUP ) ; - - NVIC_SetPriority( TC3_IRQn, 14 ) ; // Low priority interrupt - NVIC_EnableIRQ(TC3_IRQn) ; - ptc->TC_CHANNEL[0].TC_IER = TC_IER0_LDRAS ; -} - -// Start Timer4 to provide 0.5uS clock for input capture -void start_timer4() -{ - register Tc *ptc ; - register uint32_t timer ; - - timer = Master_frequency / (2*2000000) ; // MCK/2 and 2MHz - - // Enable peripheral clock TC0 = bit 23 thru TC5 = bit 28 - PMC->PMC_PCER0 |= 0x08000000L ; // Enable peripheral clock to TC4 - - ptc = TC1 ; // Tc block 1 (TC3-5) - ptc->TC_BCR = 0 ; // No sync - ptc->TC_BMR = 0 ; - ptc->TC_CHANNEL[1].TC_CMR = 0x00008000 ; // Waveform mode - ptc->TC_CHANNEL[1].TC_RC = timer ; - ptc->TC_CHANNEL[1].TC_RA = timer >> 1 ; - ptc->TC_CHANNEL[1].TC_CMR = 0x0009C000 ; // 0000 0000 0000 1001 1100 0000 0100 0000 - // MCK/2, set @ RA, Clear @ RC waveform - ptc->TC_CHANNEL[1].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) -} - -// Timer3 used for PPM_IN pulse width capture. Counter running at 16MHz / 8 = 2MHz -// equating to one count every half millisecond. (2 counts = 1ms). Control channel -// count delta values thus can range from about 1600 to 4400 counts (800us to 2200us), -// corresponding to a PPM signal in the range 0.8ms to 2.2ms (1.5ms at center). -// (The timer is free-running and is thus not reset to zero at each capture interval.) -// Timer 4 generates the 2MHz clock to clock Timer 3 - -extern "C" void TC3_IRQHandler() //capture ppm in at 2MHz -{ - uint16_t capture = TC1->TC_CHANNEL[0].TC_RA ; - (void) TC1->TC_CHANNEL[0].TC_SR ; // Acknowledge the interrupt - - captureTrainerPulses(capture); -} - -void init_trainer_capture() -{ - start_timer4() ; - start_timer3() ; -} - -void stop_trainer_capture() -{ - TC1->TC_CHANNEL[0].TC_IDR = TC_IDR0_LDRAS ; - NVIC_DisableIRQ(TC3_IRQn) ; -} - void interrupt5ms() { static uint32_t pre_scale ; // Used to get 10 Hz counter diff --git a/radio/src/targets/sky9x/trainer_driver.cpp b/radio/src/targets/sky9x/trainer_driver.cpp new file mode 100644 index 000000000..bfac53aa6 --- /dev/null +++ b/radio/src/targets/sky9x/trainer_driver.cpp @@ -0,0 +1,92 @@ +/* + * 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" + +// Start TIMER3 for input capture +inline void start_timer3() +{ + register Tc *ptc ; + + // Enable peripheral clock TC0 = bit 23 thru TC5 = bit 28 + PMC->PMC_PCER0 |= 0x04000000L ; // Enable peripheral clock to TC3 + + ptc = TC1 ; // Tc block 1 (TC3-5) + ptc->TC_BCR = 0 ; // No sync + ptc->TC_BMR = 2 ; + ptc->TC_CHANNEL[0].TC_CMR = 0x00000000 ; // Capture mode + ptc->TC_CHANNEL[0].TC_CMR = 0x00090005 ; // 0000 0000 0000 1001 0000 0000 0000 0101, XC0, A rise, b fall + ptc->TC_CHANNEL[0].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) + + configure_pins( PIO_PC23, PIN_PERIPHERAL | PIN_INPUT | PIN_PER_B | PIN_PORTC | PIN_PULLUP ) ; + + NVIC_SetPriority( TC3_IRQn, 14 ) ; // Low priority interrupt + NVIC_EnableIRQ(TC3_IRQn) ; + ptc->TC_CHANNEL[0].TC_IER = TC_IER0_LDRAS ; +} + +// Start Timer4 to provide 0.5uS clock for input capture +void start_timer4() +{ + register Tc *ptc ; + register uint32_t timer ; + + timer = Master_frequency / (2*2000000) ; // MCK/2 and 2MHz + + // Enable peripheral clock TC0 = bit 23 thru TC5 = bit 28 + PMC->PMC_PCER0 |= 0x08000000L ; // Enable peripheral clock to TC4 + + ptc = TC1 ; // Tc block 1 (TC3-5) + ptc->TC_BCR = 0 ; // No sync + ptc->TC_BMR = 0 ; + ptc->TC_CHANNEL[1].TC_CMR = 0x00008000 ; // Waveform mode + ptc->TC_CHANNEL[1].TC_RC = timer ; + ptc->TC_CHANNEL[1].TC_RA = timer >> 1 ; + ptc->TC_CHANNEL[1].TC_CMR = 0x0009C000 ; // 0000 0000 0000 1001 1100 0000 0100 0000 + // MCK/2, set @ RA, Clear @ RC waveform + ptc->TC_CHANNEL[1].TC_CCR = 5 ; // Enable clock and trigger it (may only need trigger) +} + +// Timer3 used for PPM_IN pulse width capture. Counter running at 16MHz / 8 = 2MHz +// equating to one count every half millisecond. (2 counts = 1ms). Control channel +// count delta values thus can range from about 1600 to 4400 counts (800us to 2200us), +// corresponding to a PPM signal in the range 0.8ms to 2.2ms (1.5ms at center). +// (The timer is free-running and is thus not reset to zero at each capture interval.) +// Timer 4 generates the 2MHz clock to clock Timer 3 + +extern "C" void TC3_IRQHandler() //capture ppm in at 2MHz +{ + uint16_t capture = TC1->TC_CHANNEL[0].TC_RA ; + (void) TC1->TC_CHANNEL[0].TC_SR ; // Acknowledge the interrupt + + captureTrainerPulses(capture); +} + +void init_trainer_capture() +{ + start_timer4() ; + start_timer3() ; +} + +void stop_trainer_capture() +{ + TC1->TC_CHANNEL[0].TC_IDR = TC_IDR0_LDRAS ; + NVIC_DisableIRQ(TC3_IRQn) ; +}