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:
commit
efe50012cb
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 = {
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user