mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-15 20:35:33 +03:00
CC3D - Support PPM input on IN_S1.
This required timer overflow events to be used in the calculation of PPM channel data. CC3D tested, other targets may be unstable as a result. Needs further testing.
This commit is contained in:
parent
440e942af4
commit
a5ec1355d4
6 changed files with 69 additions and 34 deletions
|
@ -70,7 +70,7 @@ enum {
|
|||
TYPE_S,
|
||||
};
|
||||
|
||||
#if USABLE_TIMER_CHANNEL_COUNT >= 14
|
||||
#if defined(NAZE) || defined(OLIMEXINO) || defined(NAZE32PRO) || defined(STM32F3DISCOVERY)
|
||||
static const uint16_t multiPPM[] = {
|
||||
PWM1 | (TYPE_IP << 8), // PPM input
|
||||
PWM9 | (TYPE_M << 8), // Swap to servo if needed
|
||||
|
@ -138,17 +138,7 @@ static const uint16_t airPWM[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#if USABLE_TIMER_CHANNEL_COUNT == 12
|
||||
#ifdef CC3D // XXX HACK while PPM and MOTOR code conflicts.
|
||||
static const uint16_t multiPPM[] = {
|
||||
PWM6 | (TYPE_IP << 8), // PPM input
|
||||
PWM7 | (TYPE_M << 8), // Swap to servo if needed
|
||||
PWM8 | (TYPE_M << 8), // Swap to servo if needed
|
||||
PWM9 | (TYPE_M << 8),
|
||||
PWM10 | (TYPE_M << 8),
|
||||
0xFFFF
|
||||
};
|
||||
#else
|
||||
#ifdef CC3D
|
||||
static const uint16_t multiPPM[] = {
|
||||
PWM1 | (TYPE_IP << 8), // PPM input
|
||||
PWM7 | (TYPE_M << 8), // Swap to servo if needed
|
||||
|
@ -164,7 +154,6 @@ static const uint16_t multiPPM[] = {
|
|||
PWM6 | (TYPE_M << 8), // Swap to servo if needed
|
||||
0xFFFF
|
||||
};
|
||||
#endif
|
||||
static const uint16_t multiPWM[] = {
|
||||
PWM1 | (TYPE_IW << 8), // input #1
|
||||
PWM2 | (TYPE_IW << 8),
|
||||
|
|
|
@ -102,7 +102,7 @@ void pwmRSSIInConfig(uint8_t timerIndex)
|
|||
pwmRSSIICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Rising);
|
||||
|
||||
timerConfigure(timerHardwarePtr, 0xFFFF, 1);
|
||||
configureTimerCaptureCompareInterrupt(timerHardwarePtr, UNUSED_CALLBACK_REFERENCE, pwmRssiCallback);
|
||||
configureTimerCaptureCompareInterrupt(timerHardwarePtr, UNUSED_CALLBACK_REFERENCE, pwmRssiCallback, NULL);
|
||||
}
|
||||
|
||||
uint16_t pwmRSSIRead(void)
|
||||
|
|
|
@ -79,18 +79,36 @@ void resetPPMDataReceivedState(void)
|
|||
|
||||
#define MIN_CHANNELS_BEFORE_PPM_FRAME_CONSIDERED_VALID 4
|
||||
|
||||
static void ppmCallback(uint8_t port, captureCompare_t capture)
|
||||
uint32_t largeCounter = 0;
|
||||
|
||||
static void ppmOverflowCallback(uint8_t port, captureCompare_t capture)
|
||||
{
|
||||
uint16_t diff; // See PPM_TIMER_PERIOD
|
||||
static captureCompare_t now;
|
||||
static captureCompare_t last = 0;
|
||||
largeCounter += capture;
|
||||
}
|
||||
|
||||
static void ppmEdgeCallback(uint8_t port, captureCompare_t capture)
|
||||
{
|
||||
uint32_t diff; // See PPM_TIMER_PERIOD
|
||||
static uint32_t now = 0;
|
||||
static uint32_t last = 0;
|
||||
|
||||
static uint8_t chan = 0;
|
||||
|
||||
last = now;
|
||||
now = capture;
|
||||
|
||||
now += largeCounter;
|
||||
|
||||
diff = now - last;
|
||||
|
||||
#if 0
|
||||
static uint32_t diffs[20];
|
||||
static uint8_t diffIndex = 0;
|
||||
|
||||
diffIndex = (diffIndex + 1) % 20;
|
||||
diffs[diffIndex] = diff;
|
||||
#endif
|
||||
|
||||
if (diff > 2700) { // Per http://www.rcgroups.com/forums/showpost.php?p=21996147&postcount=3960 "So, if you use 2.5ms or higher as being the reset for the PPM stream start, you will be fine. I use 2.7ms just to be safe."
|
||||
if (chan >= MIN_CHANNELS_BEFORE_PPM_FRAME_CONSIDERED_VALID) {
|
||||
ppmFrameCount++;
|
||||
|
@ -105,7 +123,7 @@ static void ppmCallback(uint8_t port, captureCompare_t capture)
|
|||
|
||||
}
|
||||
|
||||
static void pwmCallback(uint8_t port, captureCompare_t capture)
|
||||
static void pwmEdgeCallback(uint8_t port, captureCompare_t capture)
|
||||
{
|
||||
pwmInputPort_t *pwmInputPort = &pwmInputPorts[port];
|
||||
const timerHardware_t *timerHardware = pwmInputPort->timerHardware;
|
||||
|
@ -167,7 +185,7 @@ void pwmInConfig(uint8_t timerIndex, uint8_t channel)
|
|||
pwmICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Rising);
|
||||
|
||||
timerConfigure(timerHardwarePtr, PWM_TIMER_PERIOD, PWM_TIMER_MHZ);
|
||||
configureTimerCaptureCompareInterrupt(timerHardwarePtr, channel, pwmCallback);
|
||||
configureTimerCaptureCompareInterrupt(timerHardwarePtr, channel, pwmEdgeCallback, NULL);
|
||||
}
|
||||
|
||||
#define UNUSED_PPM_TIMER_REFERENCE 0
|
||||
|
@ -186,7 +204,7 @@ void ppmInConfig(uint8_t timerIndex)
|
|||
pwmICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Rising);
|
||||
|
||||
timerConfigure(timerHardwarePtr, PPM_TIMER_PERIOD, PWM_TIMER_MHZ);
|
||||
configureTimerCaptureCompareInterrupt(timerHardwarePtr, UNUSED_PPM_TIMER_REFERENCE, ppmCallback);
|
||||
configureTimerCaptureCompareInterrupt(timerHardwarePtr, UNUSED_PPM_TIMER_REFERENCE, ppmEdgeCallback, ppmOverflowCallback);
|
||||
}
|
||||
|
||||
uint16_t pwmRead(uint8_t channel)
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
|
@ -102,7 +103,7 @@ static void serialTimerTxConfig(const timerHardware_t *timerHardwarePtr, uint8_t
|
|||
|
||||
uint8_t mhz = SystemCoreClock / 1000000;
|
||||
timerConfigure(timerHardwarePtr, timerPeriod, mhz);
|
||||
configureTimerCaptureCompareInterrupt(timerHardwarePtr, reference, onSerialTimer);
|
||||
configureTimerCaptureCompareInterrupt(timerHardwarePtr, reference, onSerialTimer, NULL);
|
||||
}
|
||||
|
||||
static void serialICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity)
|
||||
|
@ -123,7 +124,7 @@ static void serialTimerRxConfig(const timerHardware_t *timerHardwarePtr, uint8_t
|
|||
{
|
||||
// start bit is usually a FALLING signal
|
||||
serialICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, inversion == SERIAL_INVERTED ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling);
|
||||
configureTimerCaptureCompareInterrupt(timerHardwarePtr, reference, onSerialRxPinChange);
|
||||
configureTimerCaptureCompareInterrupt(timerHardwarePtr, reference, onSerialRxPinChange, NULL);
|
||||
}
|
||||
|
||||
static void serialOutputPortConfig(const timerHardware_t *timerHardwarePtr)
|
||||
|
|
|
@ -229,7 +229,8 @@ static const uint16_t channels[CC_CHANNELS_PER_TIMER] = {
|
|||
typedef struct timerConfig_s {
|
||||
TIM_TypeDef *tim;
|
||||
uint8_t channel;
|
||||
timerCCCallbackPtr *callback;
|
||||
timerCCCallbackPtr *edgeCallback;
|
||||
timerCCCallbackPtr *overflowCallback;
|
||||
uint8_t reference;
|
||||
} timerConfig_t;
|
||||
|
||||
|
@ -258,7 +259,12 @@ static uint8_t lookupTimerConfigIndex(TIM_TypeDef *tim, const uint16_t channel)
|
|||
return lookupTimerIndex(tim) + (MAX_TIMERS * lookupChannelIndex(channel));
|
||||
}
|
||||
|
||||
void configureTimerChannelCallback(TIM_TypeDef *tim, uint8_t channel, uint8_t reference, timerCCCallbackPtr *callback)
|
||||
void configureTimerChannelCallback(TIM_TypeDef *tim, uint8_t channel, uint8_t reference, timerCCCallbackPtr *edgeCallback)
|
||||
{
|
||||
configureTimerChannelCallbacks(tim, channel, reference, edgeCallback, NULL);
|
||||
}
|
||||
|
||||
void configureTimerChannelCallbacks(TIM_TypeDef *tim, uint8_t channel, uint8_t reference, timerCCCallbackPtr *edgeCallback, timerCCCallbackPtr *overflowCallback)
|
||||
{
|
||||
assert_param(IS_TIM_CHANNEL(channel));
|
||||
|
||||
|
@ -268,7 +274,8 @@ void configureTimerChannelCallback(TIM_TypeDef *tim, uint8_t channel, uint8_t re
|
|||
return;
|
||||
}
|
||||
|
||||
timerConfig[timerConfigIndex].callback = callback;
|
||||
timerConfig[timerConfigIndex].edgeCallback = edgeCallback;
|
||||
timerConfig[timerConfigIndex].overflowCallback = overflowCallback;
|
||||
timerConfig[timerConfigIndex].channel = channel;
|
||||
timerConfig[timerConfigIndex].reference = reference;
|
||||
}
|
||||
|
@ -291,10 +298,13 @@ void configureTimerInputCaptureCompareChannel(TIM_TypeDef *tim, const uint8_t ch
|
|||
}
|
||||
}
|
||||
|
||||
void configureTimerCaptureCompareInterrupt(const timerHardware_t *timerHardwarePtr, uint8_t reference, timerCCCallbackPtr *callback)
|
||||
void configureTimerCaptureCompareInterrupt(const timerHardware_t *timerHardwarePtr, uint8_t reference, timerCCCallbackPtr *edgeCallback, timerCCCallbackPtr *overflowCallback)
|
||||
{
|
||||
configureTimerChannelCallback(timerHardwarePtr->tim, timerHardwarePtr->channel, reference, callback);
|
||||
configureTimerChannelCallbacks(timerHardwarePtr->tim, timerHardwarePtr->channel, reference, edgeCallback, overflowCallback);
|
||||
configureTimerInputCaptureCompareChannel(timerHardwarePtr->tim, timerHardwarePtr->channel);
|
||||
if (overflowCallback) {
|
||||
TIM_ITConfig(timerHardwarePtr->tim, TIM_IT_Update, ENABLE);
|
||||
}
|
||||
}
|
||||
|
||||
void timerNVICConfigure(uint8_t irq)
|
||||
|
@ -342,10 +352,26 @@ static void timCCxHandler(TIM_TypeDef *tim)
|
|||
{
|
||||
captureCompare_t capture;
|
||||
timerConfig_t *timerConfig;
|
||||
uint8_t channel;
|
||||
uint8_t channelIndex;
|
||||
|
||||
if (TIM_GetITStatus(tim, TIM_IT_Update) == SET) {
|
||||
TIM_ClearITPendingBit(tim, TIM_IT_Update);
|
||||
capture = tim->ARR;
|
||||
|
||||
for (channelIndex = 0; channelIndex < CC_CHANNELS_PER_TIMER; channelIndex++) {
|
||||
channel = channels[channelIndex];
|
||||
timerConfig = findTimerConfig(tim, channel);
|
||||
|
||||
if (!timerConfig->overflowCallback) {
|
||||
continue;
|
||||
}
|
||||
timerConfig->overflowCallback(timerConfig->reference, capture);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t channelIndex = 0;
|
||||
for (channelIndex = 0; channelIndex < CC_CHANNELS_PER_TIMER; channelIndex++) {
|
||||
uint8_t channel = channels[channelIndex];
|
||||
channel = channels[channelIndex];
|
||||
|
||||
if (channel == TIM_Channel_1 && TIM_GetITStatus(tim, TIM_IT_CC1) == SET) {
|
||||
TIM_ClearITPendingBit(tim, TIM_IT_CC1);
|
||||
|
@ -371,10 +397,10 @@ static void timCCxHandler(TIM_TypeDef *tim)
|
|||
continue; // avoid uninitialised variable dereference
|
||||
}
|
||||
|
||||
if (!timerConfig->callback) {
|
||||
if (!timerConfig->edgeCallback) {
|
||||
continue;
|
||||
}
|
||||
timerConfig->callback(timerConfig->reference, capture);
|
||||
timerConfig->edgeCallback(timerConfig->reference, capture);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -55,5 +55,6 @@ void timerConfigure(const timerHardware_t *timerHardwarePtr, uint16_t period, ui
|
|||
void timerNVICConfigure(uint8_t irq);
|
||||
|
||||
void configureTimerInputCaptureCompareChannel(TIM_TypeDef *tim, const uint8_t channel);
|
||||
void configureTimerCaptureCompareInterrupt(const timerHardware_t *timerHardwarePtr, uint8_t reference, timerCCCallbackPtr *callback);
|
||||
void configureTimerChannelCallback(TIM_TypeDef *tim, uint8_t channel, uint8_t reference, timerCCCallbackPtr *callback);
|
||||
void configureTimerCaptureCompareInterrupt(const timerHardware_t *timerHardwarePtr, uint8_t reference, timerCCCallbackPtr *edgeCallback, timerCCCallbackPtr *overflowCallback);
|
||||
void configureTimerChannelCallback(TIM_TypeDef *tim, uint8_t channel, uint8_t reference, timerCCCallbackPtr *edgeCallback);
|
||||
void configureTimerChannelCallbacks(TIM_TypeDef *tim, uint8_t channel, uint8_t reference, timerCCCallbackPtr *edgeCallback, timerCCCallbackPtr *overflowCallback);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue