1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-17 02:52:12 +01:00

Merge branch 'spektrum_rtc_supervisor'

This commit is contained in:
James Cotton 2011-05-29 17:19:48 -05:00
commit efe50012cb
11 changed files with 104 additions and 124 deletions

View File

@ -187,6 +187,7 @@ SRC += $(PIOSSTM32F10X)/pios_spektrum.c
SRC += $(PIOSSTM32F10X)/pios_debug.c
SRC += $(PIOSSTM32F10X)/pios_gpio.c
SRC += $(PIOSSTM32F10X)/pios_exti.c
SRC += $(PIOSSTM32F10X)/pios_rtc.c
SRC += $(PIOSSTM32F10X)/pios_wdg.c

View File

@ -64,6 +64,7 @@
#define PIOS_INCLUDE_FREERTOS
#define PIOS_INCLUDE_GPIO
#define PIOS_INCLUDE_EXTI
#define PIOS_INCLUDE_RTC
#define PIOS_INCLUDE_WDG
#define PIOS_INCLUDE_BL_HELPER

View File

@ -348,39 +348,38 @@ void PIOS_USART_spektrum_irq_handler(void)
}
#include <pios_spektrum_priv.h>
void TIM2_IRQHandler();
void TIM2_IRQHandler() __attribute__ ((alias ("PIOS_TIM2_irq_handler")));
void RTC_IRQHandler();
void RTC_IRQHandler() __attribute__ ((alias ("PIOS_SUPV_irq_handler")));
const struct pios_spektrum_cfg pios_spektrum_cfg = {
.pios_usart_spektrum_cfg = &pios_usart_spektrum_cfg,
.tim_base_init = {
.TIM_Prescaler = (PIOS_MASTER_CLOCK / 1000000) - 1, /* For 1 uS accuracy */
.TIM_ClockDivision = TIM_CKD_DIV1,
.TIM_CounterMode = TIM_CounterMode_Up,
.TIM_Period = ((1000000 / 120) - 1), //11ms-10*16b/115200bps atleast one interrupt between frames
.TIM_RepetitionCounter = 0x0000,
},
.gpio_init = { //used for bind feature
.GPIO_Mode = GPIO_Mode_Out_PP,
.GPIO_Speed = GPIO_Speed_2MHz,
},
.remap = 0,
.irq = {
.handler = TIM2_IRQHandler,
.handler = RTC_IRQHandler,
.init = {
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
.NVIC_IRQChannelSubPriority = 0,
.NVIC_IRQChannelCmd = ENABLE,
},
},
.timer = TIM2,
.port = GPIOB,
.ccr = TIM_IT_Update,
.pin = GPIO_Pin_11,
};
void PIOS_TIM2_irq_handler()
{
PIOS_SPEKTRUM_irq_handler(pios_usart_spektrum_id);
void PIOS_SUPV_irq_handler() {
if (RTC_GetITStatus(RTC_IT_SEC))
{
/* Call the right handler */
PIOS_SPEKTRUM_irq_handler(pios_usart_spektrum_id);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Clear the RTC Second interrupt */
RTC_ClearITPendingBit(RTC_IT_SEC);
}
}
#endif /* PIOS_INCLUDE_SPEKTRUM */
@ -441,14 +440,12 @@ const struct pios_servo_channel pios_servo_channels[] = {
.channel = TIM_Channel_1,
.pin = GPIO_Pin_4,
},
#ifndef PIOS_INCLUDE_SPEKTRUM
{
.timer = TIM2,
.port = GPIOA,
.channel = TIM_Channel_3,
.pin = GPIO_Pin_2,
},
#endif
};
const struct pios_servo_cfg pios_servo_cfg = {

View File

@ -75,7 +75,7 @@ NVIC value of 255. */
#if defined(DEBUG)
#define configGENERATE_RUN_TIME_STATS 1
#define INCLUDE_uxTaskGetRunTime 1
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() PIOS_RTC_Start()
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() PIOS_RTC_Init()
// Note: Using the tick count defeats the purpose here, need some timer on the scale of 10khz
#define portGET_RUN_TIME_COUNTER_VALUE() PIOS_RTC_Counter()
#endif

View File

@ -504,39 +504,38 @@ void PIOS_USART_spektrum_irq_handler(void)
}
#include <pios_spektrum_priv.h>
void TIM6_IRQHandler();
void TIM6_IRQHandler() __attribute__ ((alias ("PIOS_TIM6_irq_handler")));
void RTC_IRQHandler();
void RTC_IRQHandler() __attribute__ ((alias ("PIOS_SUPV_irq_handler")));
const struct pios_spektrum_cfg pios_spektrum_cfg = {
.pios_usart_spektrum_cfg = &pios_usart_spektrum_cfg,
.tim_base_init = {
.TIM_Prescaler = (PIOS_MASTER_CLOCK / 1000000) - 1, /* For 1 uS accuracy */
.TIM_ClockDivision = TIM_CKD_DIV1,
.TIM_CounterMode = TIM_CounterMode_Up,
.TIM_Period = ((1000000 / 120) - 1), //11ms-10*16b/115200bps, atleast one interrupt between frames
.TIM_RepetitionCounter = 0x0000,
},
.gpio_init = { //used for bind feature
.GPIO_Mode = GPIO_Mode_Out_PP,
.GPIO_Speed = GPIO_Speed_2MHz,
},
.remap = 0,
.irq = {
.handler = TIM6_IRQHandler,
.handler = RTC_IRQHandler,
.init = {
.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID,
.NVIC_IRQChannelSubPriority = 0,
.NVIC_IRQChannelCmd = ENABLE,
},
},
.timer = TIM6,
.port = GPIOA,
.ccr = TIM_IT_Update,
.pin = GPIO_Pin_10,
};
void PIOS_TIM6_irq_handler()
{
PIOS_SPEKTRUM_irq_handler();
void PIOS_SUPV_irq_handler() {
if (RTC_GetITStatus(RTC_IT_SEC))
{
/* Call the right handler */
PIOS_SPEKTRUM_irq_handler(pios_usart_spektrum_id);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Clear the RTC Second interrupt */
RTC_ClearITPendingBit(RTC_IT_SEC);
}
}
#endif /* PIOS_COM_SPEKTRUM */
@ -1049,6 +1048,7 @@ void PIOS_Board_Init(void) {
#if defined(PIOS_INCLUDE_SPEKTRUM)
/* SPEKTRUM init must come before comms */
PIOS_RTC_Init(); // Spektrum uses RTC to check for frame failures
PIOS_SPEKTRUM_Init();
if (PIOS_USART_Init(&pios_usart_spektrum_id, &pios_usart_spektrum_cfg)) {

View File

@ -138,7 +138,7 @@ extern void vPortYieldFromISR( void );
extern void vPortEnterCritical( void );
extern void vPortExitCritical( void );
void PIOS_RTC_Start();
void PIOS_RTC_Init();
uint32_t PIOS_RTC_Counter();
#define portDISABLE_INTERRUPTS() portSET_INTERRUPT_MASK()

View File

@ -33,7 +33,11 @@
#if defined(PIOS_INCLUDE_RTC)
void PIOS_RTC_Start()
#ifndef PIOS_RTC_PRESCALAR
#define PIOS_RTC_PRESCALAR 100
#endif
void PIOS_RTC_Init()
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP | RCC_APB1Periph_PWR,
ENABLE);
@ -44,7 +48,14 @@ void PIOS_RTC_Start()
RTC_WaitForLastTask();
RTC_WaitForSynchro();
RTC_WaitForLastTask();
RTC_SetPrescaler(0); // counting at 8e6 / 128
#if defined(PIOS_INCLUDE_SPEKTRUM)
/* Enable the RTC Second interrupt */
RTC_ITConfig( RTC_IT_SEC, ENABLE );
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
#endif
RTC_SetPrescaler(PIOS_RTC_PRESCALAR); // counting at 8e6 / 128
RTC_WaitForLastTask();
RTC_SetCounter(0);
RTC_WaitForLastTask();
@ -55,6 +66,15 @@ uint32_t PIOS_RTC_Counter()
return RTC_GetCounter();
}
float PIOS_RTC_Rate()
{
return (float) (8e6 / 128) / (1 + PIOS_RTC_PRESCALAR);
}
float PIOS_RTC_MsPerTick()
{
return 1000.0f / PIOS_RTC_Rate();
}
#endif

View File

@ -41,16 +41,24 @@
#error "AUX com cannot be used with SPEKTRUM"
#endif
/**
* @Note Framesyncing:
* The code resets the watchdog timer whenever a single byte is received, so what watchdog code
* is never called if regularly getting bytes.
* RTC timer is running @625Hz, supervisor timer has divider 5 so frame sync comes every 1/125Hz=8ms.
* Good for both 11ms and 22ms framecycles
*/
/* Global Variables */
/* Local Variables, use pios_usart */
/* Local Variables */
static uint16_t CaptureValue[12],CaptureValueTemp[12];
static uint8_t prev_byte = 0xFF, sync = 0, bytecount = 0, datalength=0, frame_error=0, byte_array[20] = { 0 };
uint8_t sync_of = 0;
uint16_t supv_timer=0;
/**
* Initialise the onboard USARTs
* Bind and Initialise Spektrum satellite receiver
*/
void PIOS_SPEKTRUM_Init(void)
{
@ -59,62 +67,15 @@ void PIOS_SPEKTRUM_Init(void)
PIOS_SPEKTRUM_Bind();
}
NVIC_InitTypeDef NVIC_InitStructure = pios_spektrum_cfg.irq.init;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure = pios_spektrum_cfg.tim_base_init;
/* Enable appropriate clock to timer module */
switch((int32_t) pios_spektrum_cfg.timer) {
case (int32_t)TIM1:
NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQn;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
break;
case (int32_t)TIM2:
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
break;
case (int32_t)TIM3:
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
break;
case (int32_t)TIM4:
NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
break;
#ifdef STM32F10X_HD
case (int32_t)TIM5:
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
break;
case (int32_t)TIM6:
NVIC_InitStructure.NVIC_IRQChannel = TIM6_IRQn;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
break;
case (int32_t)TIM7:
NVIC_InitStructure.NVIC_IRQChannel = TIM7_IRQn;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7, ENABLE);
break;
case (int32_t)TIM8:
NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
break;
#endif
}
/* Init RTC supervisor timer interrupt */
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = PIOS_IRQ_PRIO_MID;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Configure timer clocks */
TIM_InternalClockConfig(pios_spektrum_cfg.timer);
TIM_TimeBaseInit(pios_spektrum_cfg.timer, &TIM_TimeBaseStructure);
/* Enable the Capture Compare Interrupt Request */
TIM_ITConfig(pios_spektrum_cfg.timer, pios_spektrum_cfg.ccr, ENABLE);
/* Clear update pending flag */
TIM_ClearFlag(pios_spektrum_cfg.timer, TIM_FLAG_Update);
/* Enable timers */
TIM_Cmd(pios_spektrum_cfg.timer, ENABLE);
/* Init RTC clock */
PIOS_RTC_Init();
}
/**
@ -263,8 +224,7 @@ int32_t PIOS_SPEKTRUM_Decode(uint8_t b)
}
/* Interrupt handler for USART */
void SPEKTRUM_IRQHandler(uint32_t usart_id)
{
void SPEKTRUM_IRQHandler(uint32_t usart_id) {
/* by always reading DR after SR make sure to clear any error interrupts */
volatile uint16_t sr = pios_spektrum_cfg.pios_usart_spektrum_cfg->regs->SR;
volatile uint8_t b = pios_spektrum_cfg.pios_usart_spektrum_cfg->regs->DR;
@ -280,33 +240,34 @@ void SPEKTRUM_IRQHandler(uint32_t usart_id)
/* Disable TXE interrupt (TXEIE=0) */
USART_ITConfig(pios_spektrum_cfg.pios_usart_spektrum_cfg->regs, USART_IT_TXE, DISABLE);
}
/* clear "watchdog" timer */
TIM_SetCounter(pios_spektrum_cfg.timer, 0);
/* byte arrived so clear "watchdog" timer */
supv_timer=0;
}
/**
* This function handles TIM6 global interrupt request.
*/
*@brief This function is called between frames and when a spektrum word hasnt been decoded for too long
*@brief clears the channel values
*/
void PIOS_SPEKTRUM_irq_handler() {
//PIOS_SPEKTRUM_SUPV_IRQ_FUNC {
/* Clear timer interrupt pending bit */
TIM_ClearITPendingBit(pios_spektrum_cfg.timer, TIM_IT_Update);
/* sync between frames */
sync = 0;
bytecount = 0;
prev_byte = 0xFF;
frame_error=0;
sync_of++;
/* watchdog activated */
if (sync_of > 12) {
/* signal lost */
sync_of = 0;
for (int i = 0; i < 12; i++)
{
CaptureValue[i] = 0;
CaptureValueTemp[i] = 0;
/* 125hz */
supv_timer++;
if(supv_timer > 5) {
/* sync between frames */
sync = 0;
bytecount = 0;
prev_byte = 0xFF;
frame_error = 0;
sync_of++;
/* watchdog activated after 100ms silence */
if (sync_of > 12) {
/* signal lost */
sync_of = 0;
for (int i = 0; i < 12; i++) {
CaptureValue[i] = 0;
CaptureValueTemp[i] = 0;
}
}
supv_timer = 0;
}
}

View File

@ -27,12 +27,14 @@
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef PIOS_SERVO_H
#define PIOS_SERVO_H
#ifndef PIOS_RTC_H
#define PIOS_RTC_H
/* Public Functions */
extern void PIOS_RTC_Start();
extern void PIOS_RTC_Init();
extern uint32_t PIOS_RTC_Counter();
extern float PIOS_RTC_Rate();
extern float PIOS_RTC_MsPerTick();
#endif /* PIOS_SERVO_H */

View File

@ -37,13 +37,10 @@
struct pios_spektrum_cfg {
const struct pios_usart_cfg * pios_usart_spektrum_cfg;
TIM_TimeBaseInitTypeDef tim_base_init;
GPIO_InitTypeDef gpio_init;
uint32_t remap; /* GPIO_Remap_* */
struct stm32_irq irq;
TIM_TypeDef * timer;
GPIO_TypeDef * port;
uint16_t ccr;
uint16_t pin;
};

View File

@ -73,6 +73,7 @@
#include <pios_irq.h>
#include <pios_adc.h>
#include <pios_servo.h>
#include <pios_rtc.h>
#include <pios_i2c.h>
#include <pios_spi.h>
#include <pios_ppm.h>