Skip to content

Commit

Permalink
PPM input to UART1 with configuration option to Servo 6
Browse files Browse the repository at this point in the history
  • Loading branch information
gtoonstra authored and flixr committed Oct 5, 2012
1 parent e81e04e commit d91dcd2
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 30 deletions.
7 changes: 7 additions & 0 deletions conf/boards/lisa_m_2.0.makefile
Expand Up @@ -101,3 +101,10 @@ endif
ifndef ADC_IR_NB_SAMPLES
ADC_IR_NB_SAMPLES = 16
endif

# default PPM CAPTURE configuration
ifndef RADIO_CONTROL_PPM_PIN
RADIO_CONTROL_PPM_PIN = SERVO6
# RADIO_CONTROL_PPM_PIN = UART1
endif

14 changes: 12 additions & 2 deletions conf/firmwares/subsystems/shared/radio_control_ppm.makefile
@@ -1,5 +1,5 @@
#
# Makefile for shared radio_control ppm susbsytem
# Makefile for shared radio_control ppm subsystem
#

NORADIO = False
Expand All @@ -14,6 +14,7 @@ ifeq ($(NORADIO), False)
$(TARGET).CFLAGS += -DRADIO_CONTROL
ifneq ($(RADIO_CONTROL_LED),none)
ap.CFLAGS += -DRADIO_CONTROL_LED=$(RADIO_CONTROL_LED)
fbw.CFLAGS += -DRADIO_CONTROL_LED=$(RADIO_CONTROL_LED)
endif
$(TARGET).CFLAGS += -DRADIO_CONTROL_TYPE_H=\"subsystems/radio_control/ppm.h\"
$(TARGET).CFLAGS += -DRADIO_CONTROL_TYPE_PPM
Expand All @@ -22,6 +23,15 @@ ifeq ($(NORADIO), False)
$(TARGET).srcs += $(SRC_ARCH)/subsystems/radio_control/ppm_arch.c

ifeq ($(ARCH),stm32)
ap.CFLAGS += -DUSE_TIM2_IRQ
ifeq ($(RADIO_CONTROL_PPM_PIN),UART1)
ap.CFLAGS += -DUSE_TIM1_IRQ
fbw.CFLAGS += -DUSE_TIM1_IRQ
else ifeq ($(RADIO_CONTROL_PPM_PIN),SERVO6)
ap.CFLAGS += -DUSE_TIM2_IRQ
fbw.CFLAGS += -DUSE_TIM2_IRQ
else
$(error unknown configuration for RADIO_CONTROL_PPM_PIN)
endif
endif
endif

14 changes: 12 additions & 2 deletions sw/airborne/arch/stm32/stm32_vector_table.c
Expand Up @@ -159,6 +159,16 @@ extern void adc1_2_irq_handler(void);
#define ADC1_2_IRQ_HANDLER null_handler
#endif

#ifdef USE_TIM1_IRQ
extern void tim1_up_irq_handler(void);
extern void tim1_cc_irq_handler(void);
#define TIM1_UP_IRQ_HANDLER tim1_up_irq_handler
#define TIM1_CC_IRQ_HANDLER tim1_cc_irq_handler
#else
#define TIM1_UP_IRQ_HANDLER null_handler
#define TIM1_CC_IRQ_HANDLER null_handler
#endif

#ifdef USE_TIM2_IRQ
extern void tim2_irq_handler(void);
#define TIM2_IRQ_HANDLER tim2_irq_handler
Expand Down Expand Up @@ -241,9 +251,9 @@ void (* const vector_table[])(void) = {
null_handler, /* can_sce_irq_handler */
EXTI9_5_IRQ_HANDLER, /* exti9_5_irq_handler */
null_handler, /* tim1_brk_irq_handler */
null_handler, /* tim1_up_irq_handler */
TIM1_UP_IRQ_HANDLER, /* tim1_up_irq_handler */
null_handler, /* tim1_trg_com_irq_handler */
null_handler, /* tim1_cc_irq_handler */
TIM1_CC_IRQ_HANDLER, /* tim1_cc_irq_handler */
TIM2_IRQ_HANDLER, /* tim2_irq_handler */
null_handler, /* tim3_irq_handler */
null_handler, /* tim4_irq_handler */
Expand Down
119 changes: 93 additions & 26 deletions sw/airborne/arch/stm32/subsystems/radio_control/ppm_arch.c
Expand Up @@ -32,86 +32,153 @@
#include "mcu_periph/sys_time.h"

/*
*
* This a radio control ppm driver for stm32
* signal on PA1 TIM2/CH2 (uart1 trig on lisa/L)
*
*/
uint8_t ppm_cur_pulse;
*
* This a radio control ppm driver for stm32
* Either on:
* signal on PA1 TIM2/CH2 (uart1 trig on lisa/L) (Servo 6 on Lisa/M2)
* or signal on PA10 TIM1/CH3 (uart1 trig on lisa/L) (uart1 rx on Lisa/M2)
*
*/
uint8_t ppm_cur_pulse;
uint32_t ppm_last_pulse_time;
bool_t ppm_data_valid;
bool_t ppm_data_valid;
static uint32_t timer_rollover_cnt;

#ifdef USE_TIM1_IRQ
#pragma message "UART1 RX pin is used for PPM input"
void tim1_up_irq_handler(void);
void tim1_cc_irq_handler(void);
#endif

#ifdef USE_TIM2_IRQ
#pragma message "Servo pin 6 is used for PPM input"
void tim2_irq_handler(void);
#endif

void ppm_arch_init ( void ) {

/* TIM2 channel 2 pin (PA.01) configuration */
void ppm_arch_init ( void ) {
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
#ifdef USE_TIM1_IRQ
/* TIM1 channel 3 pin (PA.10) configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
#elif defined USE_TIM2_IRQ
/* TIM2 channel 2 pin (PA.01) configuration */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
#endif
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

#ifdef USE_TIM1_IRQ
/* TIM1 clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
#elif defined USE_TIM2_IRQ
/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
#endif

/* GPIOA clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

/* Time Base configuration */
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler = 0x8;
TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
TIM_TimeBaseStructure.TIM_Prescaler = 0x8;
TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
#ifdef USE_TIM1_IRQ
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
#elif defined USE_TIM2_IRQ
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

/* TIM2 configuration: Input Capture mode ---------------------
The external signal is connected to TIM2 CH2 pin (PA.01)
The Rising edge is used as active edge,
------------------------------------------------------------ */
TIM_ICInitTypeDef TIM_ICInitStructure;
#endif

/* TIM2 configuration: Input Capture mode ---------------------
The external signal is connected to TIM2 CH2 pin (PA.01)
TIM1 configuration: Input Capture mode ---------------------
The external signal is connected to TIM1 CH3 pin (PA.10)
The Rising edge is used as active edge,
------------------------------------------------------------ */
TIM_ICInitTypeDef TIM_ICInitStructure;
#ifdef USE_TIM1_IRQ
TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
#elif defined USE_TIM2_IRQ
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
#endif
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICFilter = 0x00;
#ifdef USE_TIM1_IRQ
TIM_ICInit(TIM1, &TIM_ICInitStructure);
#elif defined USE_TIM2_IRQ
TIM_ICInit(TIM2, &TIM_ICInitStructure);

#endif
/* Enable the TIM1 global Interrupt */
/* Enable the TIM2 global Interrupt */
NVIC_InitTypeDef NVIC_InitStructure;
#ifdef USE_TIM1_IRQ
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;
#elif defined USE_TIM2_IRQ
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
#endif
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
#ifdef USE_TIM1_IRQ
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
NVIC_Init(&NVIC_InitStructure);
#endif

#ifdef USE_TIM1_IRQ
/* TIM1 enable counter */
TIM_Cmd(TIM1, ENABLE);
#elif defined USE_TIM2_IRQ
/* TIM2 enable counter */
TIM_Cmd(TIM2, ENABLE);
#endif

#ifdef USE_TIM1_IRQ
/* Enable the CC3 Interrupt Request */
TIM_ITConfig(TIM1, TIM_IT_CC3|TIM_IT_Update, ENABLE);
#elif defined USE_TIM2_IRQ
/* Enable the CC2 Interrupt Request */
TIM_ITConfig(TIM2, TIM_IT_CC2|TIM_IT_Update, ENABLE);
#endif

ppm_last_pulse_time = 0;
ppm_cur_pulse = RADIO_CONTROL_NB_CHANNEL;
timer_rollover_cnt = 0;

}

#ifdef USE_TIM1_IRQ
void tim1_up_irq_handler(void) {
if(TIM_GetITStatus(TIM1, TIM_IT_Update) == SET) {
timer_rollover_cnt+=(1<<16);
TIM_ClearITPendingBit(TIM1, TIM_IT_Update);
}
}

void tim2_irq_handler(void) {

if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET) {
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
void tim1_cc_irq_handler(void) {
if(TIM_GetITStatus(TIM1, TIM_IT_CC3) == SET) {
TIM_ClearITPendingBit(TIM1, TIM_IT_CC3);

uint32_t now = TIM_GetCapture2(TIM2) + timer_rollover_cnt;
uint32_t now = TIM_GetCapture3(TIM1) + timer_rollover_cnt;
DecodePpmFrame(now);
}
}
#elif defined USE_TIM2_IRQ
void tim2_irq_handler(void) {
if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET) {
TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
uint32_t now = TIM_GetCapture2(TIM2) + timer_rollover_cnt;
DecodePpmFrame(now);
}
else if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) {
timer_rollover_cnt+=(1<<16);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}

}
#endif

0 comments on commit d91dcd2

Please sign in to comment.