mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-19 22:35:23 +03:00
Merge remote-tracking branch 'betaflight/master' into bfdev-osd-cms-separation-poc
This commit is contained in:
commit
e9a2f2b2c1
42 changed files with 640 additions and 344 deletions
4
Makefile
4
Makefile
|
@ -736,11 +736,7 @@ OPTIMIZE = -O0
|
||||||
LTO_FLAGS = $(OPTIMIZE)
|
LTO_FLAGS = $(OPTIMIZE)
|
||||||
else
|
else
|
||||||
OPTIMIZE = -Os
|
OPTIMIZE = -Os
|
||||||
ifeq ($(TARGET),$(filter $(TARGET),$(F1_TARGETS)))
|
|
||||||
LTO_FLAGS = -flto -fuse-linker-plugin $(OPTIMIZE)
|
LTO_FLAGS = -flto -fuse-linker-plugin $(OPTIMIZE)
|
||||||
else
|
|
||||||
LTO_FLAGS = -fuse-linker-plugin $(OPTIMIZE)
|
|
||||||
endif
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
DEBUG_FLAGS = -ggdb3 -DDEBUG
|
DEBUG_FLAGS = -ggdb3 -DDEBUG
|
||||||
|
|
|
@ -1169,7 +1169,7 @@ static bool blackboxWriteSysinfo()
|
||||||
|
|
||||||
switch (xmitState.headerIndex) {
|
switch (xmitState.headerIndex) {
|
||||||
BLACKBOX_PRINT_HEADER_LINE("Firmware type:%s", "Cleanflight");
|
BLACKBOX_PRINT_HEADER_LINE("Firmware type:%s", "Cleanflight");
|
||||||
BLACKBOX_PRINT_HEADER_LINE("Firmware revision:Betaflight %s (%s) %s", FC_VERSION_STRING, shortGitRevision, targetName);
|
BLACKBOX_PRINT_HEADER_LINE("Firmware revision:%s %s (%s) %s", FC_FIRMWARE_NAME, FC_VERSION_STRING, shortGitRevision, targetName);
|
||||||
BLACKBOX_PRINT_HEADER_LINE("Firmware date:%s %s", buildDate, buildTime);
|
BLACKBOX_PRINT_HEADER_LINE("Firmware date:%s %s", buildDate, buildTime);
|
||||||
BLACKBOX_PRINT_HEADER_LINE("Craft name:%s", masterConfig.name);
|
BLACKBOX_PRINT_HEADER_LINE("Craft name:%s", masterConfig.name);
|
||||||
BLACKBOX_PRINT_HEADER_LINE("P interval:%d/%d", masterConfig.blackbox_rate_num, masterConfig.blackbox_rate_denom);
|
BLACKBOX_PRINT_HEADER_LINE("P interval:%d/%d", masterConfig.blackbox_rate_num, masterConfig.blackbox_rate_denom);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define FC_FIRMWARE_NAME "Betaflight"
|
||||||
#define FC_VERSION_MAJOR 3 // increment when a major release is made (big new feature, etc)
|
#define FC_VERSION_MAJOR 3 // increment when a major release is made (big new feature, etc)
|
||||||
#define FC_VERSION_MINOR 1 // increment when a minor release is made (small new feature, change etc)
|
#define FC_VERSION_MINOR 1 // increment when a minor release is made (small new feature, change etc)
|
||||||
#define FC_VERSION_PATCH_LEVEL 0 // increment when a bug is fixed
|
#define FC_VERSION_PATCH_LEVEL 0 // increment when a bug is fixed
|
||||||
|
|
|
@ -162,11 +162,7 @@ typedef struct master_s {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LED_STRIP
|
#ifdef LED_STRIP
|
||||||
ledConfig_t ledConfigs[LED_MAX_STRIP_LENGTH];
|
ledStripConfig_t ledStripConfig;
|
||||||
hsvColor_t colors[LED_CONFIGURABLE_COLOR_COUNT];
|
|
||||||
modeColorIndexes_t modeColors[LED_MODE_COUNT];
|
|
||||||
specialColorIndexes_t specialColors;
|
|
||||||
uint8_t ledstrip_visual_beeper; // suppress LEDLOW mode if beeper is on
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TRANSPONDER
|
#ifdef TRANSPONDER
|
||||||
|
|
|
@ -15,9 +15,12 @@
|
||||||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#define MPU6500_WHO_AM_I_CONST (0x70)
|
#define MPU6500_WHO_AM_I_CONST (0x70)
|
||||||
#define MPU9250_WHO_AM_I_CONST (0x71)
|
#define MPU9250_WHO_AM_I_CONST (0x71)
|
||||||
#define ICM20608G_WHO_AM_I_CONST (0xAF)
|
#define ICM20608G_WHO_AM_I_CONST (0xAF)
|
||||||
|
#define ICM20602_WHO_AM_I_CONST (0x12)
|
||||||
|
|
||||||
#define MPU6500_BIT_RESET (0x80)
|
#define MPU6500_BIT_RESET (0x80)
|
||||||
#define MPU6500_BIT_INT_ANYRD_2CLEAR (1 << 4)
|
#define MPU6500_BIT_INT_ANYRD_2CLEAR (1 << 4)
|
||||||
|
@ -25,8 +28,6 @@
|
||||||
#define MPU6500_BIT_I2C_IF_DIS (1 << 4)
|
#define MPU6500_BIT_I2C_IF_DIS (1 << 4)
|
||||||
#define MPU6500_BIT_RAW_RDY_EN (0x01)
|
#define MPU6500_BIT_RAW_RDY_EN (0x01)
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
bool mpu6500AccDetect(acc_t *acc);
|
bool mpu6500AccDetect(acc_t *acc);
|
||||||
bool mpu6500GyroDetect(gyro_t *gyro);
|
bool mpu6500GyroDetect(gyro_t *gyro);
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,10 @@ bool mpu6500SpiDetect(void)
|
||||||
|
|
||||||
mpu6500ReadRegister(MPU_RA_WHO_AM_I, 1, &tmp);
|
mpu6500ReadRegister(MPU_RA_WHO_AM_I, 1, &tmp);
|
||||||
|
|
||||||
if (tmp == MPU6500_WHO_AM_I_CONST || tmp == MPU9250_WHO_AM_I_CONST || tmp == ICM20608G_WHO_AM_I_CONST) {
|
if (tmp == MPU6500_WHO_AM_I_CONST ||
|
||||||
|
tmp == MPU9250_WHO_AM_I_CONST ||
|
||||||
|
tmp == ICM20608G_WHO_AM_I_CONST ||
|
||||||
|
tmp == ICM20602_WHO_AM_I_CONST) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
* along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
struct dmaChannelDescriptor_s;
|
struct dmaChannelDescriptor_s;
|
||||||
typedef void (*dmaCallbackHandlerFuncPtr)(struct dmaChannelDescriptor_s *channelDescriptor);
|
typedef void (*dmaCallbackHandlerFuncPtr)(struct dmaChannelDescriptor_s *channelDescriptor);
|
||||||
|
|
|
@ -8,7 +8,7 @@ typedef uint8_t ioTag_t; // packet tag to specify IO pin
|
||||||
typedef void* IO_t; // type specifying IO pin. Currently ioRec_t pointer, but this may change
|
typedef void* IO_t; // type specifying IO pin. Currently ioRec_t pointer, but this may change
|
||||||
|
|
||||||
// NONE initializer for ioTag_t variables
|
// NONE initializer for ioTag_t variables
|
||||||
#define IO_TAG_NONE ((ioTag_t)0)
|
#define IO_TAG_NONE IO_TAG(NONE)
|
||||||
|
|
||||||
// NONE initializer for IO_t variable
|
// NONE initializer for IO_t variable
|
||||||
#define IO_NONE ((IO_t)0)
|
#define IO_NONE ((IO_t)0)
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "common/color.h"
|
#include "common/color.h"
|
||||||
#include "common/colorconversion.h"
|
#include "common/colorconversion.h"
|
||||||
#include "dma.h"
|
#include "dma.h"
|
||||||
|
#include "io.h"
|
||||||
#include "light_ws2811strip.h"
|
#include "light_ws2811strip.h"
|
||||||
|
|
||||||
#if defined(STM32F4) || defined(STM32F7)
|
#if defined(STM32F4) || defined(STM32F7)
|
||||||
|
@ -84,10 +85,10 @@ void setStripColors(const hsvColor_t *colors)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ws2811LedStripInit(void)
|
void ws2811LedStripInit(ioTag_t ioTag)
|
||||||
{
|
{
|
||||||
memset(&ledStripDMABuffer, 0, WS2811_DMA_BUFFER_SIZE);
|
memset(&ledStripDMABuffer, 0, WS2811_DMA_BUFFER_SIZE);
|
||||||
ws2811LedStripHardwareInit();
|
ws2811LedStripHardwareInit(ioTag);
|
||||||
ws2811UpdateStrip();
|
ws2811UpdateStrip();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "io_types.h"
|
||||||
|
|
||||||
#define WS2811_LED_STRIP_LENGTH 32
|
#define WS2811_LED_STRIP_LENGTH 32
|
||||||
#define WS2811_BITS_PER_LED 24
|
#define WS2811_BITS_PER_LED 24
|
||||||
#define WS2811_DELAY_BUFFER_LENGTH 42 // for 50us delay
|
#define WS2811_DELAY_BUFFER_LENGTH 42 // for 50us delay
|
||||||
|
@ -36,9 +38,9 @@
|
||||||
#define BIT_COMPARE_0 9 // timer compare value for logical 0
|
#define BIT_COMPARE_0 9 // timer compare value for logical 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ws2811LedStripInit(void);
|
void ws2811LedStripInit(ioTag_t ioTag);
|
||||||
|
|
||||||
void ws2811LedStripHardwareInit(void);
|
void ws2811LedStripHardwareInit(ioTag_t ioTag);
|
||||||
void ws2811LedStripDMAEnable(void);
|
void ws2811LedStripDMAEnable(void);
|
||||||
|
|
||||||
void ws2811UpdateStrip(void);
|
void ws2811UpdateStrip(void);
|
||||||
|
|
|
@ -31,26 +31,15 @@
|
||||||
#include "rcc.h"
|
#include "rcc.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
#if !defined(WS2811_PIN)
|
|
||||||
#define WS2811_PIN PA0
|
|
||||||
#define WS2811_TIMER TIM5
|
|
||||||
#define WS2811_DMA_HANDLER_IDENTIFER DMA1_ST2_HANDLER
|
|
||||||
#define WS2811_DMA_STREAM DMA1_Stream2
|
|
||||||
#define WS2811_DMA_IT DMA_IT_TCIF2
|
|
||||||
#define WS2811_DMA_CHANNEL DMA_Channel_6
|
|
||||||
#define WS2811_TIMER_CHANNEL TIM_Channel_1
|
|
||||||
#define WS2811_TIMER_GPIO_AF GPIO_AF2_TIM5
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static IO_t ws2811IO = IO_NONE;
|
static IO_t ws2811IO = IO_NONE;
|
||||||
static uint16_t timDMASource = 0;
|
|
||||||
bool ws2811Initialised = false;
|
bool ws2811Initialised = false;
|
||||||
|
|
||||||
static TIM_HandleTypeDef TimHandle;
|
static TIM_HandleTypeDef TimHandle;
|
||||||
|
static uint16_t timerChannel = 0;
|
||||||
|
|
||||||
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
|
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
|
||||||
{
|
{
|
||||||
if(htim->Instance==WS2811_TIMER)
|
if(htim->Instance == TimHandle.Instance)
|
||||||
{
|
{
|
||||||
//HAL_TIM_PWM_Stop_DMA(&TimHandle,WS2811_TIMER_CHANNEL);
|
//HAL_TIM_PWM_Stop_DMA(&TimHandle,WS2811_TIMER_CHANNEL);
|
||||||
ws2811LedDataTransferInProgress = 0;
|
ws2811LedDataTransferInProgress = 0;
|
||||||
|
@ -62,9 +51,20 @@ void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t* descriptor)
|
||||||
HAL_DMA_IRQHandler(TimHandle.hdma[descriptor->userParam]);
|
HAL_DMA_IRQHandler(TimHandle.hdma[descriptor->userParam]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ws2811LedStripHardwareInit(void)
|
void ws2811LedStripHardwareInit(ioTag_t ioTag)
|
||||||
{
|
{
|
||||||
TimHandle.Instance = WS2811_TIMER;
|
if (!ioTag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const timerHardware_t *timerHardware = timerGetByTag(ioTag, TIM_USE_ANY);
|
||||||
|
TIM_TypeDef *timer = timerHardware->tim;
|
||||||
|
timerChannel = timerHardware->channel;
|
||||||
|
|
||||||
|
if (timerHardware->dmaStream == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TimHandle.Instance = timer;
|
||||||
|
|
||||||
TimHandle.Init.Prescaler = 1;
|
TimHandle.Init.Prescaler = 1;
|
||||||
TimHandle.Init.Period = 135; // 800kHz
|
TimHandle.Init.Period = 135; // 800kHz
|
||||||
|
@ -78,16 +78,14 @@ void ws2811LedStripHardwareInit(void)
|
||||||
|
|
||||||
static DMA_HandleTypeDef hdma_tim;
|
static DMA_HandleTypeDef hdma_tim;
|
||||||
|
|
||||||
ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN));
|
ws2811IO = IOGetByTag(ioTag);
|
||||||
/* GPIOA Configuration: TIM5 Channel 1 as alternate function push-pull */
|
|
||||||
IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
|
IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
|
||||||
IOConfigGPIOAF(ws2811IO, IO_CONFIG(GPIO_MODE_AF_PP, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_PULLUP), WS2811_TIMER_GPIO_AF);
|
IOConfigGPIOAF(ws2811IO, IO_CONFIG(GPIO_MODE_AF_PP, GPIO_SPEED_FREQ_VERY_HIGH, GPIO_PULLUP), timerHardware->alternateFunction);
|
||||||
|
|
||||||
__DMA1_CLK_ENABLE();
|
__DMA1_CLK_ENABLE();
|
||||||
|
|
||||||
|
|
||||||
/* Set the parameters to be configured */
|
/* Set the parameters to be configured */
|
||||||
hdma_tim.Init.Channel = WS2811_DMA_CHANNEL;
|
hdma_tim.Init.Channel = timerHardware->dmaChannel;
|
||||||
hdma_tim.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
hdma_tim.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||||
hdma_tim.Init.PeriphInc = DMA_PINC_DISABLE;
|
hdma_tim.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||||
hdma_tim.Init.MemInc = DMA_MINC_ENABLE;
|
hdma_tim.Init.MemInc = DMA_MINC_ENABLE;
|
||||||
|
@ -101,30 +99,17 @@ void ws2811LedStripHardwareInit(void)
|
||||||
hdma_tim.Init.PeriphBurst = DMA_PBURST_SINGLE;
|
hdma_tim.Init.PeriphBurst = DMA_PBURST_SINGLE;
|
||||||
|
|
||||||
/* Set hdma_tim instance */
|
/* Set hdma_tim instance */
|
||||||
hdma_tim.Instance = WS2811_DMA_STREAM;
|
hdma_tim.Instance = timerHardware->dmaStream;
|
||||||
|
|
||||||
switch (WS2811_TIMER_CHANNEL) {
|
uint16_t dmaSource = timerDmaSource(timerChannel);
|
||||||
case TIM_CHANNEL_1:
|
|
||||||
timDMASource = TIM_DMA_ID_CC1;
|
|
||||||
break;
|
|
||||||
case TIM_CHANNEL_2:
|
|
||||||
timDMASource = TIM_DMA_ID_CC2;
|
|
||||||
break;
|
|
||||||
case TIM_CHANNEL_3:
|
|
||||||
timDMASource = TIM_DMA_ID_CC3;
|
|
||||||
break;
|
|
||||||
case TIM_CHANNEL_4:
|
|
||||||
timDMASource = TIM_DMA_ID_CC4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Link hdma_tim to hdma[x] (channelx) */
|
/* Link hdma_tim to hdma[x] (channelx) */
|
||||||
__HAL_LINKDMA(&TimHandle, hdma[timDMASource], hdma_tim);
|
__HAL_LINKDMA(&TimHandle, hdma[dmaSource], hdma_tim);
|
||||||
|
|
||||||
dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, timDMASource);
|
dmaSetHandler(timerHardware->dmaIrqHandler, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, dmaSource);
|
||||||
|
|
||||||
/* Initialize TIMx DMA handle */
|
/* Initialize TIMx DMA handle */
|
||||||
if(HAL_DMA_Init(TimHandle.hdma[timDMASource]) != HAL_OK)
|
if(HAL_DMA_Init(TimHandle.hdma[dmaSource]) != HAL_OK)
|
||||||
{
|
{
|
||||||
/* Initialization Error */
|
/* Initialization Error */
|
||||||
return;
|
return;
|
||||||
|
@ -140,7 +125,7 @@ void ws2811LedStripHardwareInit(void)
|
||||||
TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET;
|
TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET;
|
||||||
TIM_OCInitStructure.OCFastMode = TIM_OCFAST_DISABLE;
|
TIM_OCInitStructure.OCFastMode = TIM_OCFAST_DISABLE;
|
||||||
|
|
||||||
if(HAL_TIM_PWM_ConfigChannel(&TimHandle, &TIM_OCInitStructure, WS2811_TIMER_CHANNEL) != HAL_OK)
|
if(HAL_TIM_PWM_ConfigChannel(&TimHandle, &TIM_OCInitStructure, timerChannel) != HAL_OK)
|
||||||
{
|
{
|
||||||
/* Configuration Error */
|
/* Configuration Error */
|
||||||
return;
|
return;
|
||||||
|
@ -160,7 +145,7 @@ void ws2811LedStripDMAEnable(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( HAL_TIM_PWM_Start_DMA(&TimHandle, WS2811_TIMER_CHANNEL, ledStripDMABuffer, WS2811_DMA_BUFFER_SIZE) != HAL_OK)
|
if( HAL_TIM_PWM_Start_DMA(&TimHandle, timerChannel, ledStripDMABuffer, WS2811_DMA_BUFFER_SIZE) != HAL_OK)
|
||||||
{
|
{
|
||||||
/* Starting PWM generation Error */
|
/* Starting PWM generation Error */
|
||||||
ws2811LedDataTransferInProgress = 0;
|
ws2811LedDataTransferInProgress = 0;
|
||||||
|
|
|
@ -30,10 +30,16 @@
|
||||||
#include "rcc.h"
|
#include "rcc.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
|
#define WS2811_TIMER_HZ 24000000
|
||||||
|
#define WS2811_TIMER_PERIOD 29
|
||||||
|
|
||||||
static IO_t ws2811IO = IO_NONE;
|
static IO_t ws2811IO = IO_NONE;
|
||||||
bool ws2811Initialised = false;
|
bool ws2811Initialised = false;
|
||||||
|
static DMA_Channel_TypeDef *dmaChannel = NULL;
|
||||||
|
static TIM_TypeDef *timer = NULL;
|
||||||
|
|
||||||
static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor) {
|
static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor)
|
||||||
|
{
|
||||||
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
|
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
|
||||||
ws2811LedDataTransferInProgress = 0;
|
ws2811LedDataTransferInProgress = 0;
|
||||||
DMA_Cmd(descriptor->channel, DISABLE);
|
DMA_Cmd(descriptor->channel, DISABLE);
|
||||||
|
@ -41,32 +47,38 @@ static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ws2811LedStripHardwareInit(void)
|
void ws2811LedStripHardwareInit(ioTag_t ioTag)
|
||||||
{
|
{
|
||||||
|
if (!ioTag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||||||
DMA_InitTypeDef DMA_InitStructure;
|
DMA_InitTypeDef DMA_InitStructure;
|
||||||
|
|
||||||
uint16_t prescalerValue;
|
const timerHardware_t *timerHardware = timerGetByTag(ioTag, TIM_USE_ANY);
|
||||||
|
timer = timerHardware->tim;
|
||||||
|
|
||||||
dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
|
if (timerHardware->dmaChannel == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN));
|
ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN));
|
||||||
/* GPIOA Configuration: TIM5 Channel 1 as alternate function push-pull */
|
|
||||||
IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
|
IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
|
||||||
IOConfigGPIO(ws2811IO, IO_CONFIG(GPIO_Speed_50MHz, GPIO_Mode_AF_PP));
|
IOConfigGPIO(ws2811IO, IO_CONFIG(GPIO_Speed_50MHz, GPIO_Mode_AF_PP));
|
||||||
|
|
||||||
RCC_ClockCmd(timerRCC(WS2811_TIMER), ENABLE);
|
RCC_ClockCmd(timerRCC(WS2811_TIMER), ENABLE);
|
||||||
|
|
||||||
/* Compute the prescaler value */
|
/* Compute the prescaler value */
|
||||||
prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
|
uint16_t prescalerValue = (uint16_t) (SystemCoreClock / WS2811_TIMER_HZ) - 1;
|
||||||
/* Time base configuration */
|
/* Time base configuration */
|
||||||
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
||||||
TIM_TimeBaseStructure.TIM_Period = 29; // 800kHz
|
TIM_TimeBaseStructure.TIM_Period = WS2811_TIMER_PERIOD; // 800kHz
|
||||||
TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue;
|
TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue;
|
||||||
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
||||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||||
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
|
TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure);
|
||||||
|
|
||||||
/* PWM1 Mode configuration: Channel1 */
|
/* PWM1 Mode configuration: Channel1 */
|
||||||
TIM_OCStructInit(&TIM_OCInitStructure);
|
TIM_OCStructInit(&TIM_OCInitStructure);
|
||||||
|
@ -74,20 +86,17 @@ void ws2811LedStripHardwareInit(void)
|
||||||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
||||||
TIM_OCInitStructure.TIM_Pulse = 0;
|
TIM_OCInitStructure.TIM_Pulse = 0;
|
||||||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
|
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
|
||||||
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
|
TIM_OC1Init(timer, &TIM_OCInitStructure);
|
||||||
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
|
TIM_OC1PreloadConfig(timer, TIM_OCPreload_Enable);
|
||||||
|
|
||||||
TIM_CtrlPWMOutputs(TIM3, ENABLE);
|
TIM_CtrlPWMOutputs(timer, ENABLE);
|
||||||
|
|
||||||
/* configure DMA */
|
/* configure DMA */
|
||||||
/* DMA clock enable */
|
|
||||||
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
|
|
||||||
|
|
||||||
/* DMA1 Channel6 Config */
|
/* DMA1 Channel6 Config */
|
||||||
DMA_DeInit(DMA1_Channel6);
|
DMA_DeInit(dmaChannel);
|
||||||
|
|
||||||
DMA_StructInit(&DMA_InitStructure);
|
DMA_StructInit(&DMA_InitStructure);
|
||||||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM3->CCR1;
|
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)timerCCR(timer, timerHardware->channel);
|
||||||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ledStripDMABuffer;
|
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ledStripDMABuffer;
|
||||||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
|
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
|
||||||
DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE;
|
DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE;
|
||||||
|
@ -99,12 +108,13 @@ void ws2811LedStripHardwareInit(void)
|
||||||
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
||||||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||||||
|
|
||||||
DMA_Init(DMA1_Channel6, &DMA_InitStructure);
|
DMA_Init(dmaChannel, &DMA_InitStructure);
|
||||||
|
|
||||||
/* TIM3 CC1 DMA Request enable */
|
/* TIM3 CC1 DMA Request enable */
|
||||||
TIM_DMACmd(TIM3, TIM_DMA_CC1, ENABLE);
|
TIM_DMACmd(timer, timerDmaSource(timerHardware->channel), ENABLE);
|
||||||
|
|
||||||
DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);
|
DMA_ITConfig(dmaChannel, DMA_IT_TC, ENABLE);
|
||||||
|
dmaSetHandler(timerHardware->dmaIrqHandler, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
|
||||||
|
|
||||||
const hsvColor_t hsv_white = { 0, 255, 255};
|
const hsvColor_t hsv_white = { 0, 255, 255};
|
||||||
ws2811Initialised = true;
|
ws2811Initialised = true;
|
||||||
|
@ -117,10 +127,10 @@ void ws2811LedStripDMAEnable(void)
|
||||||
if (!ws2811Initialised)
|
if (!ws2811Initialised)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DMA_SetCurrDataCounter(DMA1_Channel6, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred
|
DMA_SetCurrDataCounter(dmaChannel, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred
|
||||||
TIM_SetCounter(TIM3, 0);
|
TIM_SetCounter(timer, 0);
|
||||||
TIM_Cmd(TIM3, ENABLE);
|
TIM_Cmd(timer, ENABLE);
|
||||||
DMA_Cmd(DMA1_Channel6, ENABLE);
|
DMA_Cmd(dmaChannel, ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,18 +31,16 @@
|
||||||
#include "rcc.h"
|
#include "rcc.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
|
|
||||||
#ifndef WS2811_PIN
|
#define WS2811_TIMER_HZ 24000000
|
||||||
#define WS2811_PIN PB8 // TIM16_CH1
|
#define WS2811_TIMER_PERIOD 29
|
||||||
#define WS2811_TIMER TIM16
|
|
||||||
#define WS2811_DMA_CHANNEL DMA1_Channel3
|
|
||||||
#define WS2811_DMA_HANDLER_IDENTIFER DMA1_CH3_HANDLER
|
|
||||||
#define WS2811_TIMER_GPIO_AF GPIO_AF_1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static IO_t ws2811IO = IO_NONE;
|
static IO_t ws2811IO = IO_NONE;
|
||||||
bool ws2811Initialised = false;
|
bool ws2811Initialised = false;
|
||||||
|
static DMA_Channel_TypeDef *dmaChannel = NULL;
|
||||||
|
static TIM_TypeDef *timer = NULL;
|
||||||
|
|
||||||
static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor) {
|
static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor)
|
||||||
|
{
|
||||||
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
|
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
|
||||||
ws2811LedDataTransferInProgress = 0;
|
ws2811LedDataTransferInProgress = 0;
|
||||||
DMA_Cmd(descriptor->channel, DISABLE);
|
DMA_Cmd(descriptor->channel, DISABLE);
|
||||||
|
@ -50,51 +48,66 @@ static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ws2811LedStripHardwareInit(void)
|
void ws2811LedStripHardwareInit(ioTag_t ioTag)
|
||||||
{
|
{
|
||||||
|
if (!ioTag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||||||
DMA_InitTypeDef DMA_InitStructure;
|
DMA_InitTypeDef DMA_InitStructure;
|
||||||
|
|
||||||
uint16_t prescalerValue;
|
const timerHardware_t *timerHardware = timerGetByTag(ioTag, TIM_USE_ANY);
|
||||||
|
timer = timerHardware->tim;
|
||||||
|
|
||||||
dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
|
if (timerHardware->dmaChannel == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN));
|
ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN));
|
||||||
/* GPIOA Configuration: TIM5 Channel 1 as alternate function push-pull */
|
|
||||||
IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
|
IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
|
||||||
IOConfigGPIOAF(ws2811IO, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP), WS2811_TIMER_GPIO_AF);
|
IOConfigGPIOAF(ws2811IO, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP), timerHardware->alternateFunction);
|
||||||
|
|
||||||
RCC_ClockCmd(timerRCC(WS2811_TIMER), ENABLE);
|
RCC_ClockCmd(timerRCC(timer), ENABLE);
|
||||||
|
|
||||||
/* Compute the prescaler value */
|
/* Compute the prescaler value */
|
||||||
prescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
|
uint16_t prescalerValue = (uint16_t) (SystemCoreClock / WS2811_TIMER_HZ) - 1;
|
||||||
|
|
||||||
/* Time base configuration */
|
/* Time base configuration */
|
||||||
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
||||||
TIM_TimeBaseStructure.TIM_Period = 29; // 800kHz
|
TIM_TimeBaseStructure.TIM_Period = WS2811_TIMER_PERIOD; // 800kHz
|
||||||
TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue;
|
TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue;
|
||||||
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
||||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||||
TIM_TimeBaseInit(WS2811_TIMER, &TIM_TimeBaseStructure);
|
TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure);
|
||||||
|
|
||||||
/* PWM1 Mode configuration */
|
/* PWM1 Mode configuration */
|
||||||
TIM_OCStructInit(&TIM_OCInitStructure);
|
TIM_OCStructInit(&TIM_OCInitStructure);
|
||||||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
||||||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
if (timerHardware->output & TIMER_OUTPUT_N_CHANNEL) {
|
||||||
|
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
|
||||||
|
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
|
||||||
|
TIM_OCInitStructure.TIM_OCNPolarity = (timerHardware->output & TIMER_OUTPUT_INVERTED) ? TIM_OCNPolarity_High : TIM_OCNPolarity_Low;
|
||||||
|
} else {
|
||||||
|
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
||||||
|
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
|
||||||
|
TIM_OCInitStructure.TIM_OCPolarity = (timerHardware->output & TIMER_OUTPUT_INVERTED) ? TIM_OCPolarity_Low : TIM_OCPolarity_High;
|
||||||
|
}
|
||||||
TIM_OCInitStructure.TIM_Pulse = 0;
|
TIM_OCInitStructure.TIM_Pulse = 0;
|
||||||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
|
TIM_OC1Init(timer, &TIM_OCInitStructure);
|
||||||
TIM_OC1Init(WS2811_TIMER, &TIM_OCInitStructure);
|
TIM_OC1PreloadConfig(timer, TIM_OCPreload_Enable);
|
||||||
TIM_OC1PreloadConfig(WS2811_TIMER, TIM_OCPreload_Enable);
|
|
||||||
|
|
||||||
|
TIM_CtrlPWMOutputs(timer, ENABLE);
|
||||||
|
|
||||||
TIM_CtrlPWMOutputs(WS2811_TIMER, ENABLE);
|
dmaChannel = timerHardware->dmaChannel;
|
||||||
|
|
||||||
/* configure DMA */
|
/* configure DMA */
|
||||||
/* DMA1 Channel Config */
|
/* DMA1 Channel Config */
|
||||||
DMA_DeInit(WS2811_DMA_CHANNEL);
|
DMA_DeInit(dmaChannel);
|
||||||
|
|
||||||
DMA_StructInit(&DMA_InitStructure);
|
DMA_StructInit(&DMA_InitStructure);
|
||||||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&WS2811_TIMER->CCR1;
|
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)timerCCR(timer, timerHardware->channel);
|
||||||
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ledStripDMABuffer;
|
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ledStripDMABuffer;
|
||||||
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
|
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
|
||||||
DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE;
|
DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE;
|
||||||
|
@ -106,11 +119,12 @@ void ws2811LedStripHardwareInit(void)
|
||||||
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
||||||
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
|
||||||
|
|
||||||
DMA_Init(WS2811_DMA_CHANNEL, &DMA_InitStructure);
|
DMA_Init(dmaChannel, &DMA_InitStructure);
|
||||||
|
|
||||||
TIM_DMACmd(WS2811_TIMER, TIM_DMA_CC1, ENABLE);
|
TIM_DMACmd(timer, timerDmaSource(timerHardware->channel), ENABLE);
|
||||||
|
|
||||||
DMA_ITConfig(WS2811_DMA_CHANNEL, DMA_IT_TC, ENABLE);
|
DMA_ITConfig(dmaChannel, DMA_IT_TC, ENABLE);
|
||||||
|
dmaSetHandler(timerHardware->dmaIrqHandler, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
|
||||||
|
|
||||||
const hsvColor_t hsv_white = { 0, 255, 255};
|
const hsvColor_t hsv_white = { 0, 255, 255};
|
||||||
ws2811Initialised = true;
|
ws2811Initialised = true;
|
||||||
|
@ -123,10 +137,10 @@ void ws2811LedStripDMAEnable(void)
|
||||||
if (!ws2811Initialised)
|
if (!ws2811Initialised)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DMA_SetCurrDataCounter(WS2811_DMA_CHANNEL, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred
|
DMA_SetCurrDataCounter(dmaChannel, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred
|
||||||
TIM_SetCounter(WS2811_TIMER, 0);
|
TIM_SetCounter(timer, 0);
|
||||||
TIM_Cmd(WS2811_TIMER, ENABLE);
|
TIM_Cmd(timer, ENABLE);
|
||||||
DMA_Cmd(WS2811_DMA_CHANNEL, ENABLE);
|
DMA_Cmd(dmaChannel, ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,85 +31,93 @@
|
||||||
#include "rcc.h"
|
#include "rcc.h"
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "timer_stm32f4xx.h"
|
#include "timer_stm32f4xx.h"
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
#if !defined(WS2811_PIN)
|
#define WS2811_TIMER_HZ 84000000
|
||||||
#define WS2811_PIN PA0
|
#define WS2811_TIMER_PERIOD 104
|
||||||
#define WS2811_TIMER TIM5
|
|
||||||
#define WS2811_DMA_HANDLER_IDENTIFER DMA1_ST2_HANDLER
|
|
||||||
#define WS2811_DMA_STREAM DMA1_Stream2
|
|
||||||
#define WS2811_DMA_CHANNEL DMA_Channel_6
|
|
||||||
#define WS2811_TIMER_CHANNEL TIM_Channel_1
|
|
||||||
#define WS2811_TIMER_GPIO_AF GPIO_AF_TIM5
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static IO_t ws2811IO = IO_NONE;
|
static IO_t ws2811IO = IO_NONE;
|
||||||
static uint16_t timDMASource = 0;
|
|
||||||
bool ws2811Initialised = false;
|
bool ws2811Initialised = false;
|
||||||
|
static DMA_Stream_TypeDef *stream = NULL;
|
||||||
|
static TIM_TypeDef *timer = NULL;
|
||||||
|
|
||||||
static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor)
|
static void WS2811_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor)
|
||||||
{
|
{
|
||||||
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
|
if (DMA_GET_FLAG_STATUS(descriptor, DMA_IT_TCIF)) {
|
||||||
ws2811LedDataTransferInProgress = 0;
|
ws2811LedDataTransferInProgress = 0;
|
||||||
DMA_Cmd(descriptor->stream, DISABLE);
|
DMA_Cmd(descriptor->stream, DISABLE);
|
||||||
TIM_DMACmd(WS2811_TIMER, timDMASource, DISABLE);
|
|
||||||
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
|
DMA_CLEAR_FLAG(descriptor, DMA_IT_TCIF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ws2811LedStripHardwareInit(void)
|
void ws2811LedStripHardwareInit(ioTag_t ioTag)
|
||||||
{
|
{
|
||||||
|
if (!ioTag) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||||||
DMA_InitTypeDef DMA_InitStructure;
|
DMA_InitTypeDef DMA_InitStructure;
|
||||||
|
|
||||||
uint16_t prescalerValue;
|
const timerHardware_t *timerHardware = timerGetByTag(ioTag, TIM_USE_ANY);
|
||||||
|
timer = timerHardware->tim;
|
||||||
|
|
||||||
RCC_ClockCmd(timerRCC(WS2811_TIMER), ENABLE);
|
if (timerHardware->dmaStream == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ws2811IO = IOGetByTag(IO_TAG(WS2811_PIN));
|
RCC_ClockCmd(timerRCC(timer), ENABLE);
|
||||||
|
|
||||||
|
ws2811IO = IOGetByTag(ioTag);
|
||||||
/* GPIOA Configuration: TIM5 Channel 1 as alternate function push-pull */
|
/* GPIOA Configuration: TIM5 Channel 1 as alternate function push-pull */
|
||||||
IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
|
IOInit(ws2811IO, OWNER_LED_STRIP, RESOURCE_OUTPUT, 0);
|
||||||
IOConfigGPIOAF(ws2811IO, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP), WS2811_TIMER_GPIO_AF);
|
IOConfigGPIOAF(ws2811IO, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_UP), timerHardware->alternateFunction);
|
||||||
|
|
||||||
// Stop timer
|
// Stop timer
|
||||||
TIM_Cmd(WS2811_TIMER, DISABLE);
|
TIM_Cmd(timer, DISABLE);
|
||||||
|
|
||||||
/* Compute the prescaler value */
|
/* Compute the prescaler value */
|
||||||
prescalerValue = (uint16_t)(SystemCoreClock / 2 / 84000000) - 1;
|
uint16_t prescalerValue = (uint16_t)(SystemCoreClock / timerClockDivisor(timer) / WS2811_TIMER_HZ) - 1;
|
||||||
|
|
||||||
/* Time base configuration */
|
/* Time base configuration */
|
||||||
TIM_TimeBaseStructure.TIM_Period = 104; // 800kHz
|
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
||||||
|
TIM_TimeBaseStructure.TIM_Period = WS2811_TIMER_PERIOD; // 800kHz
|
||||||
TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue;
|
TIM_TimeBaseStructure.TIM_Prescaler = prescalerValue;
|
||||||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||||
TIM_TimeBaseInit(WS2811_TIMER, &TIM_TimeBaseStructure);
|
TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure);
|
||||||
|
|
||||||
/* PWM1 Mode configuration: Channel1 */
|
/* PWM1 Mode configuration: Channel1 */
|
||||||
|
TIM_OCStructInit(&TIM_OCInitStructure);
|
||||||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
||||||
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
|
if (timerHardware->output & TIMER_OUTPUT_N_CHANNEL) {
|
||||||
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
|
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
|
||||||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCNPolarity_High;
|
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
|
||||||
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
|
TIM_OCInitStructure.TIM_OCNPolarity = (timerHardware->output & TIMER_OUTPUT_INVERTED) ? TIM_OCNPolarity_High : TIM_OCNPolarity_Low;
|
||||||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
} else {
|
||||||
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
|
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
||||||
|
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
|
||||||
|
TIM_OCInitStructure.TIM_OCPolarity = (timerHardware->output & TIMER_OUTPUT_INVERTED) ? TIM_OCPolarity_Low : TIM_OCPolarity_High;
|
||||||
|
}
|
||||||
TIM_OCInitStructure.TIM_Pulse = 0;
|
TIM_OCInitStructure.TIM_Pulse = 0;
|
||||||
|
|
||||||
timerOCInit(WS2811_TIMER, WS2811_TIMER_CHANNEL, &TIM_OCInitStructure);
|
timerOCInit(timer, timerHardware->channel, &TIM_OCInitStructure);
|
||||||
timerOCPreloadConfig(WS2811_TIMER, WS2811_TIMER_CHANNEL, TIM_OCPreload_Enable);
|
timerOCPreloadConfig(timer, timerHardware->channel, TIM_OCPreload_Enable);
|
||||||
timDMASource = timerDmaSource(WS2811_TIMER_CHANNEL);
|
|
||||||
|
|
||||||
TIM_CtrlPWMOutputs(WS2811_TIMER, ENABLE);
|
TIM_CtrlPWMOutputs(timer, ENABLE);
|
||||||
TIM_ARRPreloadConfig(WS2811_TIMER, ENABLE);
|
TIM_ARRPreloadConfig(timer, ENABLE);
|
||||||
|
|
||||||
TIM_CCxCmd(WS2811_TIMER, WS2811_TIMER_CHANNEL, TIM_CCx_Enable);
|
TIM_CCxCmd(timer, timerHardware->channel, TIM_CCx_Enable);
|
||||||
TIM_Cmd(WS2811_TIMER, ENABLE);
|
TIM_Cmd(timer, ENABLE);
|
||||||
|
|
||||||
|
stream = timerHardware->dmaStream;
|
||||||
/* configure DMA */
|
/* configure DMA */
|
||||||
DMA_Cmd(WS2811_DMA_STREAM, DISABLE);
|
DMA_Cmd(stream, DISABLE);
|
||||||
DMA_DeInit(WS2811_DMA_STREAM);
|
DMA_DeInit(stream);
|
||||||
DMA_StructInit(&DMA_InitStructure);
|
DMA_StructInit(&DMA_InitStructure);
|
||||||
DMA_InitStructure.DMA_Channel = WS2811_DMA_CHANNEL;
|
DMA_InitStructure.DMA_Channel = timerHardware->dmaChannel;
|
||||||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)timerCCR(WS2811_TIMER, WS2811_TIMER_CHANNEL);
|
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)timerCCR(timer, timerHardware->channel);
|
||||||
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ledStripDMABuffer;
|
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ledStripDMABuffer;
|
||||||
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
|
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
|
||||||
DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE;
|
DMA_InitStructure.DMA_BufferSize = WS2811_DMA_BUFFER_SIZE;
|
||||||
|
@ -124,14 +132,15 @@ void ws2811LedStripHardwareInit(void)
|
||||||
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
|
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
|
||||||
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
||||||
|
|
||||||
DMA_Init(WS2811_DMA_STREAM, &DMA_InitStructure);
|
DMA_Init(stream, &DMA_InitStructure);
|
||||||
|
TIM_DMACmd(timer, timerDmaSource(timerHardware->channel), ENABLE);
|
||||||
|
|
||||||
DMA_ITConfig(WS2811_DMA_STREAM, DMA_IT_TC, ENABLE);
|
DMA_ITConfig(stream, DMA_IT_TC, ENABLE);
|
||||||
DMA_ClearITPendingBit(WS2811_DMA_STREAM, dmaFlag_IT_TCIF(WS2811_DMA_STREAM));
|
DMA_ClearITPendingBit(stream, dmaFlag_IT_TCIF(stream));
|
||||||
|
|
||||||
dmaSetHandler(WS2811_DMA_HANDLER_IDENTIFER, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
|
dmaSetHandler(timerHardware->dmaIrqHandler, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
|
||||||
|
|
||||||
const hsvColor_t hsv_white = { 0, 255, 255};
|
const hsvColor_t hsv_white = { 0, 255, 255 };
|
||||||
ws2811Initialised = true;
|
ws2811Initialised = true;
|
||||||
setStripColor(&hsv_white);
|
setStripColor(&hsv_white);
|
||||||
ws2811UpdateStrip();
|
ws2811UpdateStrip();
|
||||||
|
@ -142,10 +151,10 @@ void ws2811LedStripDMAEnable(void)
|
||||||
if (!ws2811Initialised)
|
if (!ws2811Initialised)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DMA_SetCurrDataCounter(WS2811_DMA_STREAM, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred
|
DMA_SetCurrDataCounter(stream, WS2811_DMA_BUFFER_SIZE); // load number of bytes to be transferred
|
||||||
TIM_SetCounter(WS2811_TIMER, 0);
|
TIM_SetCounter(timer, 0);
|
||||||
DMA_Cmd(WS2811_DMA_STREAM, ENABLE);
|
TIM_Cmd(timer, ENABLE);
|
||||||
TIM_DMACmd(WS2811_TIMER, timDMASource, ENABLE);
|
DMA_Cmd(stream, ENABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -208,7 +208,7 @@ void motorInit(const motorConfig_t *motorConfig, uint16_t idlePulse, uint8_t mot
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const timerHardware_t *timerHardware = timerGetByTag(tag, TIM_USE_MOTOR);
|
const timerHardware_t *timerHardware = timerGetByTag(tag, TIM_USE_ANY);
|
||||||
|
|
||||||
if (timerHardware == NULL) {
|
if (timerHardware == NULL) {
|
||||||
/* flag failure and disable ability to arm */
|
/* flag failure and disable ability to arm */
|
||||||
|
@ -271,7 +271,7 @@ void servoInit(const servoConfig_t *servoConfig)
|
||||||
IOInit(servos[servoIndex].io, OWNER_SERVO, RESOURCE_OUTPUT, RESOURCE_INDEX(servoIndex));
|
IOInit(servos[servoIndex].io, OWNER_SERVO, RESOURCE_OUTPUT, RESOURCE_INDEX(servoIndex));
|
||||||
IOConfigGPIO(servos[servoIndex].io, IOCFG_AF_PP);
|
IOConfigGPIO(servos[servoIndex].io, IOCFG_AF_PP);
|
||||||
|
|
||||||
const timerHardware_t *timer = timerGetByTag(tag, TIM_USE_SERVO);
|
const timerHardware_t *timer = timerGetByTag(tag, TIM_USE_ANY);
|
||||||
|
|
||||||
if (timer == NULL) {
|
if (timer == NULL) {
|
||||||
/* flag failure and disable ability to arm */
|
/* flag failure and disable ability to arm */
|
||||||
|
|
|
@ -119,7 +119,8 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t
|
||||||
|
|
||||||
if (configureTimer) {
|
if (configureTimer) {
|
||||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||||
|
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
||||||
|
|
||||||
RCC_ClockCmd(timerRCC(timer), ENABLE);
|
RCC_ClockCmd(timerRCC(timer), ENABLE);
|
||||||
TIM_Cmd(timer, DISABLE);
|
TIM_Cmd(timer, DISABLE);
|
||||||
|
|
||||||
|
@ -139,6 +140,7 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t
|
||||||
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)((SystemCoreClock / timerClockDivisor(timer) / hz) - 1);
|
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t)((SystemCoreClock / timerClockDivisor(timer) / hz) - 1);
|
||||||
TIM_TimeBaseStructure.TIM_Period = MOTOR_BITLENGTH;
|
TIM_TimeBaseStructure.TIM_Period = MOTOR_BITLENGTH;
|
||||||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||||||
|
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
|
||||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||||
TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure);
|
TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +156,6 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t
|
||||||
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
|
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
|
||||||
TIM_OCInitStructure.TIM_OCPolarity = (timerHardware->output & TIMER_OUTPUT_INVERTED) ? TIM_OCPolarity_Low : TIM_OCPolarity_High;
|
TIM_OCInitStructure.TIM_OCPolarity = (timerHardware->output & TIMER_OUTPUT_INVERTED) ? TIM_OCPolarity_Low : TIM_OCPolarity_High;
|
||||||
}
|
}
|
||||||
|
|
||||||
TIM_OCInitStructure.TIM_Pulse = 0;
|
TIM_OCInitStructure.TIM_Pulse = 0;
|
||||||
|
|
||||||
timerOCInit(timer, timerHardware->channel, &TIM_OCInitStructure);
|
timerOCInit(timer, timerHardware->channel, &TIM_OCInitStructure);
|
||||||
|
|
|
@ -120,7 +120,8 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t
|
||||||
|
|
||||||
if (configureTimer) {
|
if (configureTimer) {
|
||||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||||
|
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
|
||||||
|
|
||||||
RCC_ClockCmd(timerRCC(timer), ENABLE);
|
RCC_ClockCmd(timerRCC(timer), ENABLE);
|
||||||
TIM_Cmd(timer, DISABLE);
|
TIM_Cmd(timer, DISABLE);
|
||||||
|
|
||||||
|
@ -140,10 +141,12 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t
|
||||||
TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / timerClockDivisor(timer) / hz) - 1;
|
TIM_TimeBaseStructure.TIM_Prescaler = (SystemCoreClock / timerClockDivisor(timer) / hz) - 1;
|
||||||
TIM_TimeBaseStructure.TIM_Period = MOTOR_BITLENGTH;
|
TIM_TimeBaseStructure.TIM_Period = MOTOR_BITLENGTH;
|
||||||
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
|
||||||
|
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
|
||||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||||
TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure);
|
TIM_TimeBaseInit(timer, &TIM_TimeBaseStructure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TIM_OCStructInit(&TIM_OCInitStructure);
|
||||||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
||||||
if (timerHardware->output & TIMER_OUTPUT_N_CHANNEL) {
|
if (timerHardware->output & TIMER_OUTPUT_N_CHANNEL) {
|
||||||
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
|
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
|
||||||
|
|
|
@ -145,6 +145,7 @@ void pwmDigitalMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t
|
||||||
motor->TimHandle.Instance = timerHardware->tim;
|
motor->TimHandle.Instance = timerHardware->tim;
|
||||||
motor->TimHandle.Init.Prescaler = (SystemCoreClock / timerClockDivisor(timer) / hz) - 1;;
|
motor->TimHandle.Init.Prescaler = (SystemCoreClock / timerClockDivisor(timer) / hz) - 1;;
|
||||||
motor->TimHandle.Init.Period = MOTOR_BITLENGTH;
|
motor->TimHandle.Init.Period = MOTOR_BITLENGTH;
|
||||||
|
motor->TimHandle.Init.RepetitionCounter = 0;
|
||||||
motor->TimHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
motor->TimHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||||
motor->TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
motor->TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||||
if(HAL_TIM_PWM_Init(&motor->TimHandle) != HAL_OK)
|
if(HAL_TIM_PWM_Init(&motor->TimHandle) != HAL_OK)
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
|
||||||
|
@ -25,6 +26,13 @@ typedef enum {
|
||||||
BAUDRATE_KISS = 38400
|
BAUDRATE_KISS = 38400
|
||||||
} escBaudRate_e;
|
} escBaudRate_e;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PROTOCOL_SIMONK = 0,
|
||||||
|
PROTOCOL_BLHELI = 1,
|
||||||
|
PROTOCOL_KISS = 2,
|
||||||
|
PROTOCOL_KISSALL = 3
|
||||||
|
} escProtocol_e;
|
||||||
|
|
||||||
#if defined(USE_ESCSERIAL)
|
#if defined(USE_ESCSERIAL)
|
||||||
|
|
||||||
#include "build/build_config.h"
|
#include "build/build_config.h"
|
||||||
|
@ -80,11 +88,19 @@ typedef struct escSerial_s {
|
||||||
|
|
||||||
uint8_t escSerialPortIndex;
|
uint8_t escSerialPortIndex;
|
||||||
uint8_t mode;
|
uint8_t mode;
|
||||||
|
uint8_t outputCount;
|
||||||
|
|
||||||
timerCCHandlerRec_t timerCb;
|
timerCCHandlerRec_t timerCb;
|
||||||
timerCCHandlerRec_t edgeCb;
|
timerCCHandlerRec_t edgeCb;
|
||||||
} escSerial_t;
|
} escSerial_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
IO_t io;
|
||||||
|
uint8_t inverted;
|
||||||
|
} escOutputs_t;
|
||||||
|
|
||||||
|
escOutputs_t escOutputs[MAX_SUPPORTED_MOTORS];
|
||||||
|
|
||||||
extern timerHardware_t* serialTimerHardware;
|
extern timerHardware_t* serialTimerHardware;
|
||||||
extern escSerial_t escSerialPorts[];
|
extern escSerial_t escSerialPorts[];
|
||||||
|
|
||||||
|
@ -97,14 +113,36 @@ void onSerialTimerEsc(timerCCHandlerRec_t *cbRec, captureCompare_t capture);
|
||||||
void onSerialRxPinChangeEsc(timerCCHandlerRec_t *cbRec, captureCompare_t capture);
|
void onSerialRxPinChangeEsc(timerCCHandlerRec_t *cbRec, captureCompare_t capture);
|
||||||
void onSerialTimerBL(timerCCHandlerRec_t *cbRec, captureCompare_t capture);
|
void onSerialTimerBL(timerCCHandlerRec_t *cbRec, captureCompare_t capture);
|
||||||
void onSerialRxPinChangeBL(timerCCHandlerRec_t *cbRec, captureCompare_t capture);
|
void onSerialRxPinChangeBL(timerCCHandlerRec_t *cbRec, captureCompare_t capture);
|
||||||
static void serialICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity);
|
static void escSerialICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity);
|
||||||
|
|
||||||
void setTxSignalEsc(escSerial_t *escSerial, uint8_t state)
|
void setTxSignalEsc(escSerial_t *escSerial, uint8_t state)
|
||||||
{
|
{
|
||||||
if (state) {
|
if((escSerial->mode = PROTOCOL_KISSALL))
|
||||||
IOHi(escSerial->txIO);
|
{
|
||||||
} else {
|
for (volatile uint8_t i = 0; i < escSerial->outputCount; i++) {
|
||||||
IOLo(escSerial->txIO);
|
uint8_t state_temp = state;
|
||||||
|
if(escOutputs[i].inverted) {
|
||||||
|
state_temp ^= ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state_temp) {
|
||||||
|
IOHi(escOutputs[i].io);
|
||||||
|
} else {
|
||||||
|
IOLo(escOutputs[i].io);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(escSerial->rxTimerHardware->output & TIMER_OUTPUT_INVERTED) {
|
||||||
|
state ^= ENABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state) {
|
||||||
|
IOHi(escSerial->txIO);
|
||||||
|
} else {
|
||||||
|
IOLo(escSerial->txIO);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +156,7 @@ static void escSerialGPIOConfig(ioTag_t tag, ioConfig_t cfg)
|
||||||
IOConfigGPIO(IOGetByTag(tag), cfg);
|
IOConfigGPIO(IOGetByTag(tag), cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serialInputPortConfigEsc(const timerHardware_t *timerHardwarePtr)
|
void escSerialInputPortConfig(const timerHardware_t *timerHardwarePtr)
|
||||||
{
|
{
|
||||||
#ifdef STM32F10X
|
#ifdef STM32F10X
|
||||||
escSerialGPIOConfig(timerHardwarePtr->tag, IOCFG_IPU);
|
escSerialGPIOConfig(timerHardwarePtr->tag, IOCFG_IPU);
|
||||||
|
@ -164,12 +202,12 @@ static void serialTimerRxConfigBL(const timerHardware_t *timerHardwarePtr, uint8
|
||||||
uint8_t mhz = SystemCoreClock / 2000000;
|
uint8_t mhz = SystemCoreClock / 2000000;
|
||||||
TIM_DeInit(timerHardwarePtr->tim);
|
TIM_DeInit(timerHardwarePtr->tim);
|
||||||
timerConfigure(timerHardwarePtr, 0xFFFF, mhz);
|
timerConfigure(timerHardwarePtr, 0xFFFF, mhz);
|
||||||
serialICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, (options & SERIAL_INVERTED) ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling);
|
escSerialICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, (options & SERIAL_INVERTED) ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling);
|
||||||
timerChCCHandlerInit(&escSerialPorts[reference].edgeCb, onSerialRxPinChangeBL);
|
timerChCCHandlerInit(&escSerialPorts[reference].edgeCb, onSerialRxPinChangeBL);
|
||||||
timerChConfigCallbacks(timerHardwarePtr, &escSerialPorts[reference].edgeCb, NULL);
|
timerChConfigCallbacks(timerHardwarePtr, &escSerialPorts[reference].edgeCb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void serialTimerTxConfig(const timerHardware_t *timerHardwarePtr, uint8_t reference)
|
static void escSerialTimerTxConfig(const timerHardware_t *timerHardwarePtr, uint8_t reference)
|
||||||
{
|
{
|
||||||
uint32_t timerPeriod=34;
|
uint32_t timerPeriod=34;
|
||||||
TIM_DeInit(timerHardwarePtr->tim);
|
TIM_DeInit(timerHardwarePtr->tim);
|
||||||
|
@ -178,7 +216,7 @@ static void serialTimerTxConfig(const timerHardware_t *timerHardwarePtr, uint8_t
|
||||||
timerChConfigCallbacks(timerHardwarePtr, &escSerialPorts[reference].timerCb, NULL);
|
timerChConfigCallbacks(timerHardwarePtr, &escSerialPorts[reference].timerCb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void serialICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity)
|
static void escSerialICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity)
|
||||||
{
|
{
|
||||||
TIM_ICInitTypeDef TIM_ICInitStructure;
|
TIM_ICInitTypeDef TIM_ICInitStructure;
|
||||||
|
|
||||||
|
@ -192,17 +230,17 @@ static void serialICConfig(TIM_TypeDef *tim, uint8_t channel, uint16_t polarity)
|
||||||
TIM_ICInit(tim, &TIM_ICInitStructure);
|
TIM_ICInit(tim, &TIM_ICInitStructure);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void serialTimerRxConfig(const timerHardware_t *timerHardwarePtr, uint8_t reference)
|
static void escSerialTimerRxConfig(const timerHardware_t *timerHardwarePtr, uint8_t reference)
|
||||||
{
|
{
|
||||||
// start bit is usually a FALLING signal
|
// start bit is usually a FALLING signal
|
||||||
TIM_DeInit(timerHardwarePtr->tim);
|
TIM_DeInit(timerHardwarePtr->tim);
|
||||||
timerConfigure(timerHardwarePtr, 0xFFFF, 1);
|
timerConfigure(timerHardwarePtr, 0xFFFF, 1);
|
||||||
serialICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Falling);
|
escSerialICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Falling);
|
||||||
timerChCCHandlerInit(&escSerialPorts[reference].edgeCb, onSerialRxPinChangeEsc);
|
timerChCCHandlerInit(&escSerialPorts[reference].edgeCb, onSerialRxPinChangeEsc);
|
||||||
timerChConfigCallbacks(timerHardwarePtr, &escSerialPorts[reference].edgeCb, NULL);
|
timerChConfigCallbacks(timerHardwarePtr, &escSerialPorts[reference].edgeCb, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void serialOutputPortConfig(const timerHardware_t *timerHardwarePtr)
|
static void escSerialOutputPortConfig(const timerHardware_t *timerHardwarePtr)
|
||||||
{
|
{
|
||||||
escSerialGPIOConfig(timerHardwarePtr->tag, IOCFG_OUT_PP);
|
escSerialGPIOConfig(timerHardwarePtr->tag, IOCFG_OUT_PP);
|
||||||
timerChITConfig(timerHardwarePtr,DISABLE);
|
timerChITConfig(timerHardwarePtr,DISABLE);
|
||||||
|
@ -225,7 +263,11 @@ serialPort_t *openEscSerial(escSerialPortIndex_e portIndex, serialReceiveCallbac
|
||||||
{
|
{
|
||||||
escSerial_t *escSerial = &(escSerialPorts[portIndex]);
|
escSerial_t *escSerial = &(escSerialPorts[portIndex]);
|
||||||
|
|
||||||
escSerial->rxTimerHardware = &(timerHardware[output]);
|
if(mode != PROTOCOL_KISSALL){
|
||||||
|
escSerial->rxTimerHardware = &(timerHardware[output]);
|
||||||
|
}
|
||||||
|
|
||||||
|
escSerial->mode = mode;
|
||||||
escSerial->txTimerHardware = &(timerHardware[ESCSERIAL_TIMER_TX_HARDWARE]);
|
escSerial->txTimerHardware = &(timerHardware[ESCSERIAL_TIMER_TX_HARDWARE]);
|
||||||
|
|
||||||
escSerial->port.vTable = escSerialVTable;
|
escSerial->port.vTable = escSerialVTable;
|
||||||
|
@ -247,30 +289,56 @@ serialPort_t *openEscSerial(escSerialPortIndex_e portIndex, serialReceiveCallbac
|
||||||
|
|
||||||
escSerial->escSerialPortIndex = portIndex;
|
escSerial->escSerialPortIndex = portIndex;
|
||||||
|
|
||||||
escSerial->txIO = IOGetByTag(escSerial->rxTimerHardware->tag);
|
if(mode != PROTOCOL_KISSALL)
|
||||||
serialInputPortConfigEsc(escSerial->rxTimerHardware);
|
{
|
||||||
|
escSerial->txIO = IOGetByTag(escSerial->rxTimerHardware->tag);
|
||||||
setTxSignalEsc(escSerial, ENABLE);
|
escSerialInputPortConfig(escSerial->rxTimerHardware);
|
||||||
|
setTxSignalEsc(escSerial, ENABLE);
|
||||||
|
}
|
||||||
delay(50);
|
delay(50);
|
||||||
|
|
||||||
if(mode==0){
|
if(mode==PROTOCOL_SIMONK){
|
||||||
serialTimerTxConfig(escSerial->txTimerHardware, portIndex);
|
escSerialTimerTxConfig(escSerial->txTimerHardware, portIndex);
|
||||||
serialTimerRxConfig(escSerial->rxTimerHardware, portIndex);
|
escSerialTimerRxConfig(escSerial->rxTimerHardware, portIndex);
|
||||||
}
|
}
|
||||||
else if(mode==1){
|
else if(mode==PROTOCOL_BLHELI){
|
||||||
serialTimerTxConfigBL(escSerial->txTimerHardware, portIndex, baud);
|
serialTimerTxConfigBL(escSerial->txTimerHardware, portIndex, baud);
|
||||||
serialTimerRxConfigBL(escSerial->rxTimerHardware, portIndex, options);
|
serialTimerRxConfigBL(escSerial->rxTimerHardware, portIndex, options);
|
||||||
}
|
}
|
||||||
else if(mode==2) {
|
else if(mode==PROTOCOL_KISS) {
|
||||||
serialOutputPortConfig(escSerial->rxTimerHardware); // rx is the pin used
|
escSerialOutputPortConfig(escSerial->rxTimerHardware); // rx is the pin used
|
||||||
|
serialTimerTxConfigBL(escSerial->txTimerHardware, portIndex, baud);
|
||||||
|
}
|
||||||
|
else if(mode==PROTOCOL_KISSALL) {
|
||||||
|
escSerial->outputCount = 0;
|
||||||
|
memset(&escOutputs, 0, sizeof(escOutputs));
|
||||||
|
pwmOutputPort_t *pwmMotors = pwmGetMotors();
|
||||||
|
for (volatile uint8_t i = 0; i < MAX_SUPPORTED_MOTORS; i++) {
|
||||||
|
if (pwmMotors[i].enabled) {
|
||||||
|
if (pwmMotors[i].io != IO_NONE) {
|
||||||
|
for (volatile uint8_t j = 0; j < USABLE_TIMER_CHANNEL_COUNT; j++) {
|
||||||
|
if(pwmMotors[i].io == IOGetByTag(timerHardware[j].tag))
|
||||||
|
{
|
||||||
|
escSerialOutputPortConfig(&timerHardware[j]);
|
||||||
|
if(timerHardware[j].output & TIMER_OUTPUT_INVERTED) {
|
||||||
|
escOutputs[escSerial->outputCount].inverted = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
escOutputs[escSerial->outputCount].io = pwmMotors[i].io;
|
||||||
|
escSerial->outputCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setTxSignalEsc(escSerial, ENABLE);
|
||||||
serialTimerTxConfigBL(escSerial->txTimerHardware, portIndex, baud);
|
serialTimerTxConfigBL(escSerial->txTimerHardware, portIndex, baud);
|
||||||
}
|
}
|
||||||
escSerial->mode = mode;
|
|
||||||
return &escSerial->port;
|
return &escSerial->port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void serialInputPortDeConfig(const timerHardware_t *timerHardwarePtr)
|
void escSerialInputPortDeConfig(const timerHardware_t *timerHardwarePtr)
|
||||||
{
|
{
|
||||||
timerChClearCCFlag(timerHardwarePtr);
|
timerChClearCCFlag(timerHardwarePtr);
|
||||||
timerChITConfig(timerHardwarePtr,DISABLE);
|
timerChITConfig(timerHardwarePtr,DISABLE);
|
||||||
|
@ -284,7 +352,7 @@ void closeEscSerial(escSerialPortIndex_e portIndex, uint16_t output)
|
||||||
|
|
||||||
escSerial->rxTimerHardware = &(timerHardware[output]);
|
escSerial->rxTimerHardware = &(timerHardware[output]);
|
||||||
escSerial->txTimerHardware = &(timerHardware[ESCSERIAL_TIMER_TX_HARDWARE]);
|
escSerial->txTimerHardware = &(timerHardware[ESCSERIAL_TIMER_TX_HARDWARE]);
|
||||||
serialInputPortDeConfig(escSerial->rxTimerHardware);
|
escSerialInputPortDeConfig(escSerial->rxTimerHardware);
|
||||||
timerChConfigCallbacks(escSerial->txTimerHardware,NULL,NULL);
|
timerChConfigCallbacks(escSerial->txTimerHardware,NULL,NULL);
|
||||||
timerChConfigCallbacks(escSerial->rxTimerHardware,NULL,NULL);
|
timerChConfigCallbacks(escSerial->rxTimerHardware,NULL,NULL);
|
||||||
TIM_DeInit(escSerial->txTimerHardware->tim);
|
TIM_DeInit(escSerial->txTimerHardware->tim);
|
||||||
|
@ -339,7 +407,7 @@ reload:
|
||||||
escSerial->isTransmittingData = true;
|
escSerial->isTransmittingData = true;
|
||||||
|
|
||||||
//set output
|
//set output
|
||||||
serialOutputPortConfig(escSerial->rxTimerHardware);
|
escSerialOutputPortConfig(escSerial->rxTimerHardware);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,7 +451,7 @@ reload:
|
||||||
|
|
||||||
if (isEscSerialTransmitBufferEmpty((serialPort_t *)escSerial)) {
|
if (isEscSerialTransmitBufferEmpty((serialPort_t *)escSerial)) {
|
||||||
escSerial->isTransmittingData = false;
|
escSerial->isTransmittingData = false;
|
||||||
serialInputPortConfigEsc(escSerial->rxTimerHardware);
|
escSerialInputPortConfig(escSerial->rxTimerHardware);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -417,7 +485,9 @@ void processTxStateBL(escSerial_t *escSerial)
|
||||||
|
|
||||||
|
|
||||||
//set output
|
//set output
|
||||||
serialOutputPortConfig(escSerial->rxTimerHardware);
|
if(escSerial->mode==PROTOCOL_BLHELI) {
|
||||||
|
escSerialOutputPortConfig(escSerial->rxTimerHardware);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,9 +502,9 @@ void processTxStateBL(escSerial_t *escSerial)
|
||||||
|
|
||||||
escSerial->isTransmittingData = false;
|
escSerial->isTransmittingData = false;
|
||||||
if (isEscSerialTransmitBufferEmpty((serialPort_t *)escSerial)) {
|
if (isEscSerialTransmitBufferEmpty((serialPort_t *)escSerial)) {
|
||||||
if(escSerial->mode==1)
|
if(escSerial->mode==PROTOCOL_BLHELI)
|
||||||
{
|
{
|
||||||
serialInputPortConfigEsc(escSerial->rxTimerHardware);
|
escSerialInputPortConfig(escSerial->rxTimerHardware);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,7 +533,7 @@ void prepareForNextRxByteBL(escSerial_t *escSerial)
|
||||||
escSerial->isSearchingForStartBit = true;
|
escSerial->isSearchingForStartBit = true;
|
||||||
if (escSerial->rxEdge == LEADING) {
|
if (escSerial->rxEdge == LEADING) {
|
||||||
escSerial->rxEdge = TRAILING;
|
escSerial->rxEdge = TRAILING;
|
||||||
serialICConfig(
|
escSerialICConfig(
|
||||||
escSerial->rxTimerHardware->tim,
|
escSerial->rxTimerHardware->tim,
|
||||||
escSerial->rxTimerHardware->channel,
|
escSerial->rxTimerHardware->channel,
|
||||||
(escSerial->port.options & SERIAL_INVERTED) ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling
|
(escSerial->port.options & SERIAL_INVERTED) ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling
|
||||||
|
@ -551,7 +621,7 @@ void onSerialRxPinChangeBL(timerCCHandlerRec_t *cbRec, captureCompare_t capture)
|
||||||
escSerial->transmissionErrors++;
|
escSerial->transmissionErrors++;
|
||||||
}
|
}
|
||||||
|
|
||||||
serialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, inverted ? TIM_ICPolarity_Falling : TIM_ICPolarity_Rising);
|
escSerialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, inverted ? TIM_ICPolarity_Falling : TIM_ICPolarity_Rising);
|
||||||
escSerial->rxEdge = LEADING;
|
escSerial->rxEdge = LEADING;
|
||||||
|
|
||||||
escSerial->rxBitIndex = 0;
|
escSerial->rxBitIndex = 0;
|
||||||
|
@ -569,10 +639,10 @@ void onSerialRxPinChangeBL(timerCCHandlerRec_t *cbRec, captureCompare_t capture)
|
||||||
|
|
||||||
if (escSerial->rxEdge == TRAILING) {
|
if (escSerial->rxEdge == TRAILING) {
|
||||||
escSerial->rxEdge = LEADING;
|
escSerial->rxEdge = LEADING;
|
||||||
serialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, inverted ? TIM_ICPolarity_Falling : TIM_ICPolarity_Rising);
|
escSerialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, inverted ? TIM_ICPolarity_Falling : TIM_ICPolarity_Rising);
|
||||||
} else {
|
} else {
|
||||||
escSerial->rxEdge = TRAILING;
|
escSerial->rxEdge = TRAILING;
|
||||||
serialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, inverted ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling);
|
escSerialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, inverted ? TIM_ICPolarity_Rising : TIM_ICPolarity_Falling);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-------------------------BL*/
|
/*-------------------------BL*/
|
||||||
|
@ -605,7 +675,7 @@ void onSerialTimerEsc(timerCCHandlerRec_t *cbRec, captureCompare_t capture)
|
||||||
{
|
{
|
||||||
escSerial->isReceivingData=0;
|
escSerial->isReceivingData=0;
|
||||||
escSerial->receiveTimeout=0;
|
escSerial->receiveTimeout=0;
|
||||||
serialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, TIM_ICPolarity_Falling);
|
escSerialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, TIM_ICPolarity_Falling);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,7 +725,7 @@ void onSerialRxPinChangeEsc(timerCCHandlerRec_t *cbRec, captureCompare_t capture
|
||||||
bits=1;
|
bits=1;
|
||||||
escSerial->internalRxBuffer = 0x80;
|
escSerial->internalRxBuffer = 0x80;
|
||||||
|
|
||||||
serialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, TIM_ICPolarity_Rising);
|
escSerialICConfig(escSerial->rxTimerHardware->tim, escSerial->rxTimerHardware->channel, TIM_ICPolarity_Rising);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
escSerial->receiveTimeout = 0;
|
escSerial->receiveTimeout = 0;
|
||||||
|
@ -763,7 +833,7 @@ void escSerialInitialize()
|
||||||
|
|
||||||
for (volatile uint8_t i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
|
for (volatile uint8_t i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
|
||||||
// set outputs to pullup
|
// set outputs to pullup
|
||||||
if(timerHardware[i].output==1)
|
if(timerHardware[i].output & TIMER_OUTPUT_ENABLED)
|
||||||
{
|
{
|
||||||
escSerialGPIOConfig(timerHardware[i].tag, IOCFG_IPU); //GPIO_Mode_IPU
|
escSerialGPIOConfig(timerHardware[i].tag, IOCFG_IPU); //GPIO_Mode_IPU
|
||||||
}
|
}
|
||||||
|
@ -844,27 +914,34 @@ static bool ProcessExitCommand(uint8_t c)
|
||||||
void escEnablePassthrough(serialPort_t *escPassthroughPort, uint16_t output, uint8_t mode)
|
void escEnablePassthrough(serialPort_t *escPassthroughPort, uint16_t output, uint8_t mode)
|
||||||
{
|
{
|
||||||
bool exitEsc = false;
|
bool exitEsc = false;
|
||||||
|
uint8_t motor_output = 0;
|
||||||
LED0_OFF;
|
LED0_OFF;
|
||||||
LED1_OFF;
|
LED1_OFF;
|
||||||
//StopPwmAllMotors();
|
//StopPwmAllMotors();
|
||||||
pwmDisableMotors();
|
pwmDisableMotors();
|
||||||
passPort = escPassthroughPort;
|
passPort = escPassthroughPort;
|
||||||
|
|
||||||
uint8_t first_output = 0;
|
uint32_t escBaudrate = (mode == PROTOCOL_KISS) ? BAUDRATE_KISS : BAUDRATE_NORMAL;
|
||||||
for (volatile uint8_t i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
|
|
||||||
if(timerHardware[i].output==1)
|
if((mode == PROTOCOL_KISS) && (output == 255)){
|
||||||
{
|
motor_output = 255;
|
||||||
first_output=i;
|
mode = PROTOCOL_KISSALL;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
uint8_t first_output = 0;
|
||||||
|
for (volatile uint8_t i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
|
||||||
|
if(timerHardware[i].output & TIMER_OUTPUT_ENABLED)
|
||||||
|
{
|
||||||
|
first_output=i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//doesn't work with messy timertable
|
//doesn't work with messy timertable
|
||||||
uint8_t motor_output=first_output+output-1;
|
motor_output=first_output+output-1;
|
||||||
if(motor_output >=USABLE_TIMER_CHANNEL_COUNT)
|
if(motor_output >=USABLE_TIMER_CHANNEL_COUNT)
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
uint32_t escBaudrate = (mode == 2) ? BAUDRATE_KISS : BAUDRATE_NORMAL;
|
|
||||||
|
|
||||||
escPort = openEscSerial(ESCSERIAL1, NULL, motor_output, escBaudrate, 0, mode);
|
escPort = openEscSerial(ESCSERIAL1, NULL, motor_output, escBaudrate, 0, mode);
|
||||||
uint8_t ch;
|
uint8_t ch;
|
||||||
|
@ -898,7 +975,7 @@ void escEnablePassthrough(serialPort_t *escPassthroughPort, uint16_t output, uin
|
||||||
closeEscSerial(ESCSERIAL1, output);
|
closeEscSerial(ESCSERIAL1, output);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(mode==1){
|
if(mode==PROTOCOL_BLHELI){
|
||||||
serialWrite(escPassthroughPort, ch); // blheli loopback
|
serialWrite(escPassthroughPort, ch); // blheli loopback
|
||||||
}
|
}
|
||||||
serialWrite(escPort, ch);
|
serialWrite(escPort, ch);
|
||||||
|
|
|
@ -759,7 +759,7 @@ const timerHardware_t *timerGetByTag(ioTag_t tag, timerUsageFlag_e flag)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
|
for (int i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
|
||||||
if (timerHardware[i].tag == tag) {
|
if (timerHardware[i].tag == tag) {
|
||||||
if (timerHardware[i].usageFlags & flag) {
|
if (timerHardware[i].usageFlags & flag || flag == 0) {
|
||||||
return &timerHardware[i];
|
return &timerHardware[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -810,6 +810,7 @@ volatile timCCR_t* timerCCR(TIM_TypeDef *tim, uint8_t channel)
|
||||||
return (volatile timCCR_t*)((volatile char*)&tim->CCR1 + channel);
|
return (volatile timCCR_t*)((volatile char*)&tim->CCR1 + channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef USE_HAL_DRIVER
|
||||||
uint16_t timerDmaSource(uint8_t channel)
|
uint16_t timerDmaSource(uint8_t channel)
|
||||||
{
|
{
|
||||||
switch (channel) {
|
switch (channel) {
|
||||||
|
@ -823,4 +824,5 @@ uint16_t timerDmaSource(uint8_t channel)
|
||||||
return TIM_DMA_CC4;
|
return TIM_DMA_CC4;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -55,6 +55,7 @@ typedef uint32_t timCNT_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
TIM_USE_ANY = 0x0,
|
||||||
TIM_USE_PPM = 0x1,
|
TIM_USE_PPM = 0x1,
|
||||||
TIM_USE_PWM = 0x2,
|
TIM_USE_PWM = 0x2,
|
||||||
TIM_USE_MOTOR = 0x4,
|
TIM_USE_MOTOR = 0x4,
|
||||||
|
@ -92,11 +93,11 @@ typedef struct timerHardware_s {
|
||||||
#if defined(STM32F3) || defined(STM32F4) || defined(STM32F7)
|
#if defined(STM32F3) || defined(STM32F4) || defined(STM32F7)
|
||||||
uint8_t alternateFunction;
|
uint8_t alternateFunction;
|
||||||
#endif
|
#endif
|
||||||
#if defined(USE_DSHOT)
|
#if defined(USE_DSHOT) || defined(LED_STRIP)
|
||||||
#if defined(STM32F4) || defined(STM32F7)
|
#if defined(STM32F4) || defined(STM32F7)
|
||||||
DMA_Stream_TypeDef *dmaStream;
|
DMA_Stream_TypeDef *dmaStream;
|
||||||
uint32_t dmaChannel;
|
uint32_t dmaChannel;
|
||||||
#elif defined(STM32F3)
|
#elif defined(STM32F3) || defined(STM32F1)
|
||||||
DMA_Channel_TypeDef *dmaChannel;
|
DMA_Channel_TypeDef *dmaChannel;
|
||||||
#endif
|
#endif
|
||||||
uint8_t dmaIrqHandler;
|
uint8_t dmaIrqHandler;
|
||||||
|
|
|
@ -867,3 +867,18 @@ const timerHardware_t *timerGetByTag(ioTag_t tag, timerUsageFlag_e flag)
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t timerDmaSource(uint8_t channel)
|
||||||
|
{
|
||||||
|
switch (channel) {
|
||||||
|
case TIM_CHANNEL_1:
|
||||||
|
return TIM_DMA_ID_CC1;
|
||||||
|
case TIM_CHANNEL_2:
|
||||||
|
return TIM_DMA_ID_CC2;
|
||||||
|
case TIM_CHANNEL_3:
|
||||||
|
return TIM_DMA_ID_CC3;
|
||||||
|
case TIM_CHANNEL_4:
|
||||||
|
return TIM_DMA_ID_CC4;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "drivers/pwm_output.h"
|
#include "drivers/pwm_output.h"
|
||||||
#include "drivers/max7456.h"
|
#include "drivers/max7456.h"
|
||||||
#include "drivers/sound_beeper.h"
|
#include "drivers/sound_beeper.h"
|
||||||
|
#include "drivers/light_ws2811strip.h"
|
||||||
|
|
||||||
#include "fc/config.h"
|
#include "fc/config.h"
|
||||||
#include "fc/rc_controls.h"
|
#include "fc/rc_controls.h"
|
||||||
|
@ -239,6 +240,26 @@ void resetSensorAlignment(sensorAlignmentConfig_t *sensorAlignmentConfig)
|
||||||
sensorAlignmentConfig->mag_align = ALIGN_DEFAULT;
|
sensorAlignmentConfig->mag_align = ALIGN_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef LED_STRIP
|
||||||
|
void resetLedStripConfig(ledStripConfig_t *ledStripConfig)
|
||||||
|
{
|
||||||
|
applyDefaultColors(ledStripConfig->colors);
|
||||||
|
applyDefaultLedStripConfig(ledStripConfig->ledConfigs);
|
||||||
|
applyDefaultModeColors(ledStripConfig->modeColors);
|
||||||
|
applyDefaultSpecialColors(&(ledStripConfig->specialColors));
|
||||||
|
ledStripConfig->ledstrip_visual_beeper = 0;
|
||||||
|
ledStripConfig->ledstrip_aux_channel = THROTTLE;
|
||||||
|
|
||||||
|
for (int i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
|
||||||
|
if (timerHardware[i].usageFlags & TIM_USE_LED) {
|
||||||
|
ledStripConfig->ioTag = timerHardware[i].tag;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ledStripConfig->ioTag = IO_TAG_NONE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_SERVOS
|
#ifdef USE_SERVOS
|
||||||
void resetServoConfig(servoConfig_t *servoConfig)
|
void resetServoConfig(servoConfig_t *servoConfig)
|
||||||
{
|
{
|
||||||
|
@ -598,6 +619,10 @@ void createDefaultConfig(master_t *config)
|
||||||
#endif
|
#endif
|
||||||
resetFlight3DConfig(&config->flight3DConfig);
|
resetFlight3DConfig(&config->flight3DConfig);
|
||||||
|
|
||||||
|
#ifdef LED_STRIP
|
||||||
|
resetLedStripConfig(&config->ledStripConfig);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef GPS
|
#ifdef GPS
|
||||||
// gps/nav stuff
|
// gps/nav stuff
|
||||||
config->gpsConfig.provider = GPS_NMEA;
|
config->gpsConfig.provider = GPS_NMEA;
|
||||||
|
@ -667,14 +692,6 @@ void createDefaultConfig(master_t *config)
|
||||||
config->customMotorMixer[i].throttle = 0.0f;
|
config->customMotorMixer[i].throttle = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LED_STRIP
|
|
||||||
applyDefaultColors(config->colors);
|
|
||||||
applyDefaultLedStripConfig(config->ledConfigs);
|
|
||||||
applyDefaultModeColors(config->modeColors);
|
|
||||||
applyDefaultSpecialColors(&(config->specialColors));
|
|
||||||
config->ledstrip_visual_beeper = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VTX
|
#ifdef VTX
|
||||||
config->vtx_band = 4; //Fatshark/Airwaves
|
config->vtx_band = 4; //Fatshark/Airwaves
|
||||||
config->vtx_channel = 1; //CH1
|
config->vtx_channel = 1; //CH1
|
||||||
|
|
|
@ -930,7 +930,7 @@ static bool mspFcProcessOutCommand(uint8_t cmdMSP, sbuf_t *dst, mspPostProcessFn
|
||||||
#ifdef LED_STRIP
|
#ifdef LED_STRIP
|
||||||
case MSP_LED_COLORS:
|
case MSP_LED_COLORS:
|
||||||
for (i = 0; i < LED_CONFIGURABLE_COLOR_COUNT; i++) {
|
for (i = 0; i < LED_CONFIGURABLE_COLOR_COUNT; i++) {
|
||||||
hsvColor_t *color = &masterConfig.colors[i];
|
hsvColor_t *color = &masterConfig.ledStripConfig.colors[i];
|
||||||
sbufWriteU16(dst, color->h);
|
sbufWriteU16(dst, color->h);
|
||||||
sbufWriteU8(dst, color->s);
|
sbufWriteU8(dst, color->s);
|
||||||
sbufWriteU8(dst, color->v);
|
sbufWriteU8(dst, color->v);
|
||||||
|
@ -939,7 +939,7 @@ static bool mspFcProcessOutCommand(uint8_t cmdMSP, sbuf_t *dst, mspPostProcessFn
|
||||||
|
|
||||||
case MSP_LED_STRIP_CONFIG:
|
case MSP_LED_STRIP_CONFIG:
|
||||||
for (i = 0; i < LED_MAX_STRIP_LENGTH; i++) {
|
for (i = 0; i < LED_MAX_STRIP_LENGTH; i++) {
|
||||||
ledConfig_t *ledConfig = &masterConfig.ledConfigs[i];
|
ledConfig_t *ledConfig = &masterConfig.ledStripConfig.ledConfigs[i];
|
||||||
sbufWriteU32(dst, *ledConfig);
|
sbufWriteU32(dst, *ledConfig);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -949,15 +949,20 @@ static bool mspFcProcessOutCommand(uint8_t cmdMSP, sbuf_t *dst, mspPostProcessFn
|
||||||
for (int j = 0; j < LED_DIRECTION_COUNT; j++) {
|
for (int j = 0; j < LED_DIRECTION_COUNT; j++) {
|
||||||
sbufWriteU8(dst, i);
|
sbufWriteU8(dst, i);
|
||||||
sbufWriteU8(dst, j);
|
sbufWriteU8(dst, j);
|
||||||
sbufWriteU8(dst, masterConfig.modeColors[i].color[j]);
|
sbufWriteU8(dst, masterConfig.ledStripConfig.modeColors[i].color[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < LED_SPECIAL_COLOR_COUNT; j++) {
|
for (int j = 0; j < LED_SPECIAL_COLOR_COUNT; j++) {
|
||||||
sbufWriteU8(dst, LED_MODE_COUNT);
|
sbufWriteU8(dst, LED_MODE_COUNT);
|
||||||
sbufWriteU8(dst, j);
|
sbufWriteU8(dst, j);
|
||||||
sbufWriteU8(dst, masterConfig.specialColors.color[j]);
|
sbufWriteU8(dst, masterConfig.ledStripConfig.specialColors.color[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sbufWriteU8(dst, LED_AUX_CHANNEL);
|
||||||
|
sbufWriteU8(dst, 0);
|
||||||
|
sbufWriteU8(dst, masterConfig.ledStripConfig.ledstrip_aux_channel);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1649,7 +1654,7 @@ static mspResult_e mspFcProcessInCommand(uint8_t cmdMSP, sbuf_t *src)
|
||||||
#ifdef LED_STRIP
|
#ifdef LED_STRIP
|
||||||
case MSP_SET_LED_COLORS:
|
case MSP_SET_LED_COLORS:
|
||||||
for (i = 0; i < LED_CONFIGURABLE_COLOR_COUNT; i++) {
|
for (i = 0; i < LED_CONFIGURABLE_COLOR_COUNT; i++) {
|
||||||
hsvColor_t *color = &masterConfig.colors[i];
|
hsvColor_t *color = &masterConfig.ledStripConfig.colors[i];
|
||||||
color->h = sbufReadU16(src);
|
color->h = sbufReadU16(src);
|
||||||
color->s = sbufReadU8(src);
|
color->s = sbufReadU8(src);
|
||||||
color->v = sbufReadU8(src);
|
color->v = sbufReadU8(src);
|
||||||
|
@ -1663,7 +1668,7 @@ static mspResult_e mspFcProcessInCommand(uint8_t cmdMSP, sbuf_t *src)
|
||||||
return MSP_RESULT_ERROR;
|
return MSP_RESULT_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ledConfig_t *ledConfig = &masterConfig.ledConfigs[i];
|
ledConfig_t *ledConfig = &masterConfig.ledStripConfig.ledConfigs[i];
|
||||||
*ledConfig = sbufReadU32(src);
|
*ledConfig = sbufReadU32(src);
|
||||||
reevaluateLedConfig();
|
reevaluateLedConfig();
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,7 @@ PG_REGISTER_WITH_RESET_FN(specialColorIndexes_t, specialColors, PG_SPECIAL_COLOR
|
||||||
|
|
||||||
static bool ledStripInitialised = false;
|
static bool ledStripInitialised = false;
|
||||||
static bool ledStripEnabled = true;
|
static bool ledStripEnabled = true;
|
||||||
|
static ledStripConfig_t * currentLedStripConfig;
|
||||||
|
|
||||||
static void ledStripDisable(void);
|
static void ledStripDisable(void);
|
||||||
|
|
||||||
|
@ -168,6 +169,7 @@ static const specialColorIndexes_t defaultSpecialColors[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static int scaledThrottle;
|
static int scaledThrottle;
|
||||||
|
static int scaledAux;
|
||||||
|
|
||||||
static void updateLedRingCounts(void);
|
static void updateLedRingCounts(void);
|
||||||
|
|
||||||
|
@ -177,7 +179,7 @@ STATIC_UNIT_TESTED void determineLedStripDimensions(void)
|
||||||
int maxY = 0;
|
int maxY = 0;
|
||||||
|
|
||||||
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
||||||
const ledConfig_t *ledConfig = &masterConfig.ledConfigs[ledIndex];
|
const ledConfig_t *ledConfig = ¤tLedStripConfig->ledConfigs[ledIndex];
|
||||||
|
|
||||||
maxX = MAX(ledGetX(ledConfig), maxX);
|
maxX = MAX(ledGetX(ledConfig), maxX);
|
||||||
maxY = MAX(ledGetY(ledConfig), maxY);
|
maxY = MAX(ledGetY(ledConfig), maxY);
|
||||||
|
@ -199,7 +201,7 @@ STATIC_UNIT_TESTED void updateLedCount(void)
|
||||||
int count = 0, countRing = 0, countScanner= 0;
|
int count = 0, countRing = 0, countScanner= 0;
|
||||||
|
|
||||||
for (int ledIndex = 0; ledIndex < LED_MAX_STRIP_LENGTH; ledIndex++) {
|
for (int ledIndex = 0; ledIndex < LED_MAX_STRIP_LENGTH; ledIndex++) {
|
||||||
const ledConfig_t *ledConfig = &masterConfig.ledConfigs[ledIndex];
|
const ledConfig_t *ledConfig = ¤tLedStripConfig->ledConfigs[ledIndex];
|
||||||
|
|
||||||
if (!(*ledConfig))
|
if (!(*ledConfig))
|
||||||
break;
|
break;
|
||||||
|
@ -229,7 +231,7 @@ void reevaluateLedConfig(void)
|
||||||
// get specialColor by index
|
// get specialColor by index
|
||||||
static hsvColor_t* getSC(ledSpecialColorIds_e index)
|
static hsvColor_t* getSC(ledSpecialColorIds_e index)
|
||||||
{
|
{
|
||||||
return &masterConfig.colors[masterConfig.specialColors.color[index]];
|
return ¤tLedStripConfig->colors[currentLedStripConfig->specialColors.color[index]];
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char directionCodes[LED_DIRECTION_COUNT] = { 'N', 'E', 'S', 'W', 'U', 'D' };
|
static const char directionCodes[LED_DIRECTION_COUNT] = { 'N', 'E', 'S', 'W', 'U', 'D' };
|
||||||
|
@ -251,9 +253,9 @@ bool parseLedStripConfig(int ledIndex, const char *config)
|
||||||
RING_COLORS,
|
RING_COLORS,
|
||||||
PARSE_STATE_COUNT
|
PARSE_STATE_COUNT
|
||||||
};
|
};
|
||||||
static const char chunkSeparators[PARSE_STATE_COUNT] = {',', ':', ':',':', '\0'};
|
static const char chunkSeparators[PARSE_STATE_COUNT] = {',', ':', ':', ':', '\0'};
|
||||||
|
|
||||||
ledConfig_t *ledConfig = &masterConfig.ledConfigs[ledIndex];
|
ledConfig_t *ledConfig = ¤tLedStripConfig->ledConfigs[ledIndex];
|
||||||
memset(ledConfig, 0, sizeof(ledConfig_t));
|
memset(ledConfig, 0, sizeof(ledConfig_t));
|
||||||
|
|
||||||
int x = 0, y = 0, color = 0; // initialize to prevent warnings
|
int x = 0, y = 0, color = 0; // initialize to prevent warnings
|
||||||
|
@ -372,7 +374,7 @@ typedef enum {
|
||||||
|
|
||||||
static quadrant_e getLedQuadrant(const int ledIndex)
|
static quadrant_e getLedQuadrant(const int ledIndex)
|
||||||
{
|
{
|
||||||
const ledConfig_t *ledConfig = &masterConfig.ledConfigs[ledIndex];
|
const ledConfig_t *ledConfig = ¤tLedStripConfig->ledConfigs[ledIndex];
|
||||||
|
|
||||||
int x = ledGetX(ledConfig);
|
int x = ledGetX(ledConfig);
|
||||||
int y = ledGetY(ledConfig);
|
int y = ledGetY(ledConfig);
|
||||||
|
@ -414,7 +416,7 @@ static const struct {
|
||||||
|
|
||||||
static hsvColor_t* getDirectionalModeColor(const int ledIndex, const modeColorIndexes_t *modeColors)
|
static hsvColor_t* getDirectionalModeColor(const int ledIndex, const modeColorIndexes_t *modeColors)
|
||||||
{
|
{
|
||||||
const ledConfig_t *ledConfig = &masterConfig.ledConfigs[ledIndex];
|
const ledConfig_t *ledConfig = ¤tLedStripConfig->ledConfigs[ledIndex];
|
||||||
|
|
||||||
quadrant_e quad = getLedQuadrant(ledIndex);
|
quadrant_e quad = getLedQuadrant(ledIndex);
|
||||||
for (unsigned i = 0; i < ARRAYLEN(directionQuadrantMap); i++) {
|
for (unsigned i = 0; i < ARRAYLEN(directionQuadrantMap); i++) {
|
||||||
|
@ -422,7 +424,7 @@ static hsvColor_t* getDirectionalModeColor(const int ledIndex, const modeColorIn
|
||||||
quadrant_e quadMask = directionQuadrantMap[i].quadrantMask;
|
quadrant_e quadMask = directionQuadrantMap[i].quadrantMask;
|
||||||
|
|
||||||
if (ledGetDirectionBit(ledConfig, dir) && (quad & quadMask))
|
if (ledGetDirectionBit(ledConfig, dir) && (quad & quadMask))
|
||||||
return &masterConfig.colors[modeColors->color[dir]];
|
return ¤tLedStripConfig->colors[modeColors->color[dir]];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -448,7 +450,7 @@ static const struct {
|
||||||
static void applyLedFixedLayers()
|
static void applyLedFixedLayers()
|
||||||
{
|
{
|
||||||
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
||||||
const ledConfig_t *ledConfig = &masterConfig.ledConfigs[ledIndex];
|
const ledConfig_t *ledConfig = ¤tLedStripConfig->ledConfigs[ledIndex];
|
||||||
hsvColor_t color = *getSC(LED_SCOLOR_BACKGROUND);
|
hsvColor_t color = *getSC(LED_SCOLOR_BACKGROUND);
|
||||||
|
|
||||||
int fn = ledGetFunction(ledConfig);
|
int fn = ledGetFunction(ledConfig);
|
||||||
|
@ -456,13 +458,13 @@ static void applyLedFixedLayers()
|
||||||
|
|
||||||
switch (fn) {
|
switch (fn) {
|
||||||
case LED_FUNCTION_COLOR:
|
case LED_FUNCTION_COLOR:
|
||||||
color = masterConfig.colors[ledGetColor(ledConfig)];
|
color = currentLedStripConfig->colors[ledGetColor(ledConfig)];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LED_FUNCTION_FLIGHT_MODE:
|
case LED_FUNCTION_FLIGHT_MODE:
|
||||||
for (unsigned i = 0; i < ARRAYLEN(flightModeToLed); i++)
|
for (unsigned i = 0; i < ARRAYLEN(flightModeToLed); i++)
|
||||||
if (!flightModeToLed[i].flightMode || FLIGHT_MODE(flightModeToLed[i].flightMode)) {
|
if (!flightModeToLed[i].flightMode || FLIGHT_MODE(flightModeToLed[i].flightMode)) {
|
||||||
hsvColor_t *directionalColor = getDirectionalModeColor(ledIndex, &masterConfig.modeColors[flightModeToLed[i].ledMode]);
|
hsvColor_t *directionalColor = getDirectionalModeColor(ledIndex, ¤tLedStripConfig->modeColors[flightModeToLed[i].ledMode]);
|
||||||
if (directionalColor) {
|
if (directionalColor) {
|
||||||
color = *directionalColor;
|
color = *directionalColor;
|
||||||
}
|
}
|
||||||
|
@ -490,7 +492,7 @@ static void applyLedFixedLayers()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ledGetOverlayBit(ledConfig, LED_OVERLAY_THROTTLE)) {
|
if (ledGetOverlayBit(ledConfig, LED_OVERLAY_THROTTLE)) {
|
||||||
hOffset += ((scaledThrottle - 10) * 4) / 3;
|
hOffset += scaledAux;
|
||||||
}
|
}
|
||||||
|
|
||||||
color.h = (color.h + hOffset) % (HSV_HUE_MAX + 1);
|
color.h = (color.h + hOffset) % (HSV_HUE_MAX + 1);
|
||||||
|
@ -503,7 +505,7 @@ static void applyLedFixedLayers()
|
||||||
static void applyLedHsv(uint32_t mask, const hsvColor_t *color)
|
static void applyLedHsv(uint32_t mask, const hsvColor_t *color)
|
||||||
{
|
{
|
||||||
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
||||||
const ledConfig_t *ledConfig = &masterConfig.ledConfigs[ledIndex];
|
const ledConfig_t *ledConfig = ¤tLedStripConfig->ledConfigs[ledIndex];
|
||||||
if ((*ledConfig & mask) == mask)
|
if ((*ledConfig & mask) == mask)
|
||||||
setLedHsv(ledIndex, color);
|
setLedHsv(ledIndex, color);
|
||||||
}
|
}
|
||||||
|
@ -699,7 +701,7 @@ static void applyLedIndicatorLayer(bool updateNow, uint32_t *timer)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
||||||
const ledConfig_t *ledConfig = &masterConfig.ledConfigs[ledIndex];
|
const ledConfig_t *ledConfig = ¤tLedStripConfig->ledConfigs[ledIndex];
|
||||||
if (ledGetOverlayBit(ledConfig, LED_OVERLAY_INDICATOR)) {
|
if (ledGetOverlayBit(ledConfig, LED_OVERLAY_INDICATOR)) {
|
||||||
if (getLedQuadrant(ledIndex) & quadrants)
|
if (getLedQuadrant(ledIndex) & quadrants)
|
||||||
setLedHsv(ledIndex, flashColor);
|
setLedHsv(ledIndex, flashColor);
|
||||||
|
@ -740,7 +742,7 @@ static void applyLedThrustRingLayer(bool updateNow, uint32_t *timer)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
||||||
const ledConfig_t *ledConfig = &masterConfig.ledConfigs[ledIndex];
|
const ledConfig_t *ledConfig = ¤tLedStripConfig->ledConfigs[ledIndex];
|
||||||
if (ledGetFunction(ledConfig) == LED_FUNCTION_THRUST_RING) {
|
if (ledGetFunction(ledConfig) == LED_FUNCTION_THRUST_RING) {
|
||||||
|
|
||||||
bool applyColor;
|
bool applyColor;
|
||||||
|
@ -751,7 +753,7 @@ static void applyLedThrustRingLayer(bool updateNow, uint32_t *timer)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (applyColor) {
|
if (applyColor) {
|
||||||
const hsvColor_t *ringColor = &masterConfig.colors[ledGetColor(ledConfig)];
|
const hsvColor_t *ringColor = ¤tLedStripConfig->colors[ledGetColor(ledConfig)];
|
||||||
setLedHsv(ledIndex, ringColor);
|
setLedHsv(ledIndex, ringColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,7 +869,7 @@ static void applyLedAnimationLayer(bool updateNow, uint32_t *timer)
|
||||||
int nextRow = (frameCounter + 1 < animationFrames) ? frameCounter + 1 : 0;
|
int nextRow = (frameCounter + 1 < animationFrames) ? frameCounter + 1 : 0;
|
||||||
|
|
||||||
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
for (int ledIndex = 0; ledIndex < ledCounts.count; ledIndex++) {
|
||||||
const ledConfig_t *ledConfig = &masterConfig.ledConfigs[ledIndex];
|
const ledConfig_t *ledConfig = ¤tLedStripConfig->ledConfigs[ledIndex];
|
||||||
|
|
||||||
if (ledGetY(ledConfig) == previousRow) {
|
if (ledGetY(ledConfig) == previousRow) {
|
||||||
setLedHsv(ledIndex, getSC(LED_SCOLOR_ANIMATION));
|
setLedHsv(ledIndex, getSC(LED_SCOLOR_ANIMATION));
|
||||||
|
@ -929,7 +931,7 @@ void ledStripUpdate(uint32_t currentTime)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_RC_MODE_ACTIVE(BOXLEDLOW) && !(masterConfig.ledstrip_visual_beeper && isBeeperOn())) {
|
if (IS_RC_MODE_ACTIVE(BOXLEDLOW) && !(currentLedStripConfig->ledstrip_visual_beeper && isBeeperOn())) {
|
||||||
if (ledStripEnabled) {
|
if (ledStripEnabled) {
|
||||||
ledStripDisable();
|
ledStripDisable();
|
||||||
ledStripEnabled = false;
|
ledStripEnabled = false;
|
||||||
|
@ -960,6 +962,7 @@ void ledStripUpdate(uint32_t currentTime)
|
||||||
// apply all layers; triggered timed functions has to update timers
|
// apply all layers; triggered timed functions has to update timers
|
||||||
|
|
||||||
scaledThrottle = ARMING_FLAG(ARMED) ? scaleRange(rcData[THROTTLE], PWM_RANGE_MIN, PWM_RANGE_MAX, 10, 100) : 10;
|
scaledThrottle = ARMING_FLAG(ARMED) ? scaleRange(rcData[THROTTLE], PWM_RANGE_MIN, PWM_RANGE_MAX, 10, 100) : 10;
|
||||||
|
scaledAux = scaleRange(rcData[currentLedStripConfig->ledstrip_aux_channel], PWM_RANGE_MIN, PWM_RANGE_MAX, 0, HSV_HUE_MAX + 1);
|
||||||
|
|
||||||
applyLedFixedLayers();
|
applyLedFixedLayers();
|
||||||
|
|
||||||
|
@ -975,7 +978,7 @@ bool parseColor(int index, const char *colorConfig)
|
||||||
{
|
{
|
||||||
const char *remainingCharacters = colorConfig;
|
const char *remainingCharacters = colorConfig;
|
||||||
|
|
||||||
hsvColor_t *color = &masterConfig.colors[index];
|
hsvColor_t *color = ¤tLedStripConfig->colors[index];
|
||||||
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
static const uint16_t hsv_limit[HSV_COLOR_COMPONENT_COUNT] = {
|
static const uint16_t hsv_limit[HSV_COLOR_COMPONENT_COUNT] = {
|
||||||
|
@ -1028,11 +1031,15 @@ bool setModeColor(ledModeIndex_e modeIndex, int modeColorIndex, int colorIndex)
|
||||||
if (modeIndex < LED_MODE_COUNT) { // modeIndex_e is unsigned, so one-sided test is enough
|
if (modeIndex < LED_MODE_COUNT) { // modeIndex_e is unsigned, so one-sided test is enough
|
||||||
if(modeColorIndex < 0 || modeColorIndex >= LED_DIRECTION_COUNT)
|
if(modeColorIndex < 0 || modeColorIndex >= LED_DIRECTION_COUNT)
|
||||||
return false;
|
return false;
|
||||||
masterConfig.modeColors[modeIndex].color[modeColorIndex] = colorIndex;
|
currentLedStripConfig->modeColors[modeIndex].color[modeColorIndex] = colorIndex;
|
||||||
} else if (modeIndex == LED_SPECIAL) {
|
} else if (modeIndex == LED_SPECIAL) {
|
||||||
if (modeColorIndex < 0 || modeColorIndex >= LED_SPECIAL_COLOR_COUNT)
|
if (modeColorIndex < 0 || modeColorIndex >= LED_SPECIAL_COLOR_COUNT)
|
||||||
return false;
|
return false;
|
||||||
masterConfig.specialColors.color[modeColorIndex] = colorIndex;
|
currentLedStripConfig->specialColors.color[modeColorIndex] = colorIndex;
|
||||||
|
} else if (modeIndex == LED_AUX_CHANNEL) {
|
||||||
|
if (modeColorIndex < 0 || modeColorIndex >= 1)
|
||||||
|
return false;
|
||||||
|
currentLedStripConfig->ledstrip_aux_channel = colorIndex;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1090,21 +1097,26 @@ void applyDefaultSpecialColors(specialColorIndexes_t *specialColors)
|
||||||
memcpy_fn(specialColors, &defaultSpecialColors, sizeof(defaultSpecialColors));
|
memcpy_fn(specialColors, &defaultSpecialColors, sizeof(defaultSpecialColors));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ledStripInit(ledConfig_t *ledConfigsToUse, hsvColor_t *colorsToUse, modeColorIndexes_t *modeColorsToUse, specialColorIndexes_t *specialColorsToUse)
|
void ledStripInit(ledStripConfig_t *ledStripConfig)
|
||||||
{
|
{
|
||||||
ledConfigs = ledConfigsToUse;
|
currentLedStripConfig = ledStripConfig;
|
||||||
colors = colorsToUse;
|
|
||||||
modeColors = modeColorsToUse;
|
ledConfigs = currentLedStripConfig->ledConfigs;
|
||||||
specialColors = *specialColorsToUse;
|
colors = currentLedStripConfig->colors;
|
||||||
|
modeColors = currentLedStripConfig->modeColors;
|
||||||
|
specialColors = currentLedStripConfig->specialColors;
|
||||||
ledStripInitialised = false;
|
ledStripInitialised = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ledStripEnable(void)
|
void ledStripEnable(void)
|
||||||
{
|
{
|
||||||
|
if (currentLedStripConfig == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
reevaluateLedConfig();
|
reevaluateLedConfig();
|
||||||
ledStripInitialised = true;
|
ledStripInitialised = true;
|
||||||
|
|
||||||
ws2811LedStripInit();
|
ws2811LedStripInit(currentLedStripConfig->ioTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ledStripDisable(void)
|
static void ledStripDisable(void)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/color.h"
|
#include "common/color.h"
|
||||||
|
#include "drivers/io_types.h"
|
||||||
|
|
||||||
#define LED_MAX_STRIP_LENGTH 32
|
#define LED_MAX_STRIP_LENGTH 32
|
||||||
#define LED_CONFIGURABLE_COLOR_COUNT 16
|
#define LED_CONFIGURABLE_COLOR_COUNT 16
|
||||||
|
@ -75,7 +76,8 @@ typedef enum {
|
||||||
LED_MODE_ANGLE,
|
LED_MODE_ANGLE,
|
||||||
LED_MODE_MAG,
|
LED_MODE_MAG,
|
||||||
LED_MODE_BARO,
|
LED_MODE_BARO,
|
||||||
LED_SPECIAL
|
LED_SPECIAL,
|
||||||
|
LED_AUX_CHANNEL
|
||||||
} ledModeIndex_e;
|
} ledModeIndex_e;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -134,6 +136,15 @@ typedef struct ledCounts_s {
|
||||||
uint8_t ringSeqLen;
|
uint8_t ringSeqLen;
|
||||||
} ledCounts_t;
|
} ledCounts_t;
|
||||||
|
|
||||||
|
typedef struct ledStripConfig_s {
|
||||||
|
ledConfig_t ledConfigs[LED_MAX_STRIP_LENGTH];
|
||||||
|
hsvColor_t colors[LED_CONFIGURABLE_COLOR_COUNT];
|
||||||
|
modeColorIndexes_t modeColors[LED_MODE_COUNT];
|
||||||
|
specialColorIndexes_t specialColors;
|
||||||
|
uint8_t ledstrip_visual_beeper; // suppress LEDLOW mode if beeper is on
|
||||||
|
rc_alias_e ledstrip_aux_channel;
|
||||||
|
ioTag_t ioTag;
|
||||||
|
} ledStripConfig_t;
|
||||||
|
|
||||||
ledConfig_t *ledConfigs;
|
ledConfig_t *ledConfigs;
|
||||||
hsvColor_t *colors;
|
hsvColor_t *colors;
|
||||||
|
@ -165,7 +176,7 @@ bool parseLedStripConfig(int ledIndex, const char *config);
|
||||||
void generateLedConfig(ledConfig_t *ledConfig, char *ledConfigBuffer, size_t bufferSize);
|
void generateLedConfig(ledConfig_t *ledConfig, char *ledConfigBuffer, size_t bufferSize);
|
||||||
void reevaluateLedConfig(void);
|
void reevaluateLedConfig(void);
|
||||||
|
|
||||||
void ledStripInit(ledConfig_t *ledConfigsToUse, hsvColor_t *colorsToUse, modeColorIndexes_t *modeColorsToUse, specialColorIndexes_t *specialColorsToUse);
|
void ledStripInit(ledStripConfig_t *ledStripConfig);
|
||||||
void ledStripEnable(void);
|
void ledStripEnable(void);
|
||||||
void ledStripUpdate(uint32_t currentTime);
|
void ledStripUpdate(uint32_t currentTime);
|
||||||
|
|
||||||
|
|
|
@ -936,7 +936,7 @@ const clivalue_t valueTable[] = {
|
||||||
{ "magzero_z", VAR_INT16 | MASTER_VALUE, &masterConfig.magZero.raw[Z], .config.minmax = { -32768, 32767 } },
|
{ "magzero_z", VAR_INT16 | MASTER_VALUE, &masterConfig.magZero.raw[Z], .config.minmax = { -32768, 32767 } },
|
||||||
#endif
|
#endif
|
||||||
#ifdef LED_STRIP
|
#ifdef LED_STRIP
|
||||||
{ "ledstrip_visual_beeper", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, &masterConfig.ledstrip_visual_beeper, .config.lookup = { TABLE_OFF_ON } },
|
{ "ledstrip_visual_beeper", VAR_UINT8 | MASTER_VALUE | MODE_LOOKUP, &masterConfig.ledStripConfig.ledstrip_visual_beeper, .config.lookup = { TABLE_OFF_ON } },
|
||||||
#endif
|
#endif
|
||||||
#ifdef USE_RTC6705
|
#ifdef USE_RTC6705
|
||||||
{ "vtx_channel", VAR_UINT8 | MASTER_VALUE, &masterConfig.vtx_channel, .config.minmax = { 0, 39 } },
|
{ "vtx_channel", VAR_UINT8 | MASTER_VALUE, &masterConfig.vtx_channel, .config.minmax = { 0, 39 } },
|
||||||
|
@ -1707,8 +1707,8 @@ static void printLed(uint8_t dumpMask, master_t *defaultConfig)
|
||||||
char ledConfigBuffer[20];
|
char ledConfigBuffer[20];
|
||||||
char ledConfigDefaultBuffer[20];
|
char ledConfigDefaultBuffer[20];
|
||||||
for (uint32_t i = 0; i < LED_MAX_STRIP_LENGTH; i++) {
|
for (uint32_t i = 0; i < LED_MAX_STRIP_LENGTH; i++) {
|
||||||
ledConfig = masterConfig.ledConfigs[i];
|
ledConfig = masterConfig.ledStripConfig.ledConfigs[i];
|
||||||
ledConfigDefault = defaultConfig->ledConfigs[i];
|
ledConfigDefault = defaultConfig->ledStripConfig.ledConfigs[i];
|
||||||
equalsDefault = ledConfig == ledConfigDefault;
|
equalsDefault = ledConfig == ledConfigDefault;
|
||||||
generateLedConfig(&ledConfig, ledConfigBuffer, sizeof(ledConfigBuffer));
|
generateLedConfig(&ledConfig, ledConfigBuffer, sizeof(ledConfigBuffer));
|
||||||
generateLedConfig(&ledConfigDefault, ledConfigDefaultBuffer, sizeof(ledConfigDefaultBuffer));
|
generateLedConfig(&ledConfigDefault, ledConfigDefaultBuffer, sizeof(ledConfigDefaultBuffer));
|
||||||
|
@ -1745,8 +1745,8 @@ static void printColor(uint8_t dumpMask, master_t *defaultConfig)
|
||||||
hsvColor_t *colorDefault;
|
hsvColor_t *colorDefault;
|
||||||
bool equalsDefault;
|
bool equalsDefault;
|
||||||
for (uint32_t i = 0; i < LED_CONFIGURABLE_COLOR_COUNT; i++) {
|
for (uint32_t i = 0; i < LED_CONFIGURABLE_COLOR_COUNT; i++) {
|
||||||
color = &masterConfig.colors[i];
|
color = &masterConfig.ledStripConfig.colors[i];
|
||||||
colorDefault = &defaultConfig->colors[i];
|
colorDefault = &defaultConfig->ledStripConfig.colors[i];
|
||||||
equalsDefault = color->h == colorDefault->h
|
equalsDefault = color->h == colorDefault->h
|
||||||
&& color->s == colorDefault->s
|
&& color->s == colorDefault->s
|
||||||
&& color->v == colorDefault->v;
|
&& color->v == colorDefault->v;
|
||||||
|
@ -1791,21 +1791,26 @@ static void printModeColor(uint8_t dumpMask, master_t *defaultConfig)
|
||||||
{
|
{
|
||||||
for (uint32_t i = 0; i < LED_MODE_COUNT; i++) {
|
for (uint32_t i = 0; i < LED_MODE_COUNT; i++) {
|
||||||
for (uint32_t j = 0; j < LED_DIRECTION_COUNT; j++) {
|
for (uint32_t j = 0; j < LED_DIRECTION_COUNT; j++) {
|
||||||
int colorIndex = masterConfig.modeColors[i].color[j];
|
int colorIndex = masterConfig.ledStripConfig.modeColors[i].color[j];
|
||||||
int colorIndexDefault = defaultConfig->modeColors[i].color[j];
|
int colorIndexDefault = defaultConfig->ledStripConfig.modeColors[i].color[j];
|
||||||
const char *format = "mode_color %u %u %u\r\n";
|
const char *format = "mode_color %u %u %u\r\n";
|
||||||
cliDefaultPrintf(dumpMask, colorIndex == colorIndexDefault, format, i, j, colorIndexDefault);
|
cliDefaultPrintf(dumpMask, colorIndex == colorIndexDefault, format, i, j, colorIndexDefault);
|
||||||
cliDumpPrintf(dumpMask, colorIndex == colorIndexDefault, format, i, j, colorIndex);
|
cliDumpPrintf(dumpMask, colorIndex == colorIndexDefault, format, i, j, colorIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *format = "mode_color %u %u %u\r\n";
|
||||||
for (uint32_t j = 0; j < LED_SPECIAL_COLOR_COUNT; j++) {
|
for (uint32_t j = 0; j < LED_SPECIAL_COLOR_COUNT; j++) {
|
||||||
int colorIndex = masterConfig.specialColors.color[j];
|
int colorIndex = masterConfig.ledStripConfig.specialColors.color[j];
|
||||||
int colorIndexDefault = defaultConfig->specialColors.color[j];
|
int colorIndexDefault = defaultConfig->ledStripConfig.specialColors.color[j];
|
||||||
const char *format = "mode_color %u %u %u\r\n";
|
|
||||||
cliDefaultPrintf(dumpMask, colorIndex == colorIndexDefault, format, LED_SPECIAL, j, colorIndexDefault);
|
cliDefaultPrintf(dumpMask, colorIndex == colorIndexDefault, format, LED_SPECIAL, j, colorIndexDefault);
|
||||||
cliDumpPrintf(dumpMask, colorIndex == colorIndexDefault, format, LED_SPECIAL, j, colorIndex);
|
cliDumpPrintf(dumpMask, colorIndex == colorIndexDefault, format, LED_SPECIAL, j, colorIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ledStripAuxChannel = masterConfig.ledStripConfig.ledstrip_aux_channel;
|
||||||
|
int ledStripAuxChannelDefault = defaultConfig->ledStripConfig.ledstrip_aux_channel;
|
||||||
|
cliDefaultPrintf(dumpMask, ledStripAuxChannel == ledStripAuxChannelDefault, format, LED_AUX_CHANNEL, 0, ledStripAuxChannelDefault);
|
||||||
|
cliDumpPrintf(dumpMask, ledStripAuxChannel == ledStripAuxChannelDefault, format, LED_AUX_CHANNEL, 0, ledStripAuxChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cliModeColor(char *cmdline)
|
static void cliModeColor(char *cmdline)
|
||||||
|
@ -2997,12 +3002,18 @@ static void cliEscPassthrough(char *cmdline)
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
index = atoi(pch);
|
index = atoi(pch);
|
||||||
if ((index >= 0) && (index < USABLE_TIMER_CHANNEL_COUNT)) {
|
if(mode == 2 && index == 255)
|
||||||
printf("passthru at pwm output %d enabled\r\n", index);
|
{
|
||||||
|
printf("passthru on all pwm outputs enabled\r\n");
|
||||||
}
|
}
|
||||||
else {
|
else{
|
||||||
printf("invalid pwm output, valid range: 1 to %d\r\n", USABLE_TIMER_CHANNEL_COUNT);
|
if ((index >= 0) && (index < USABLE_TIMER_CHANNEL_COUNT)) {
|
||||||
return;
|
printf("passthru at pwm output %d enabled\r\n", index);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("invalid pwm output, valid range: 1 to %d\r\n", USABLE_TIMER_CHANNEL_COUNT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -3610,7 +3621,8 @@ static void cliVersion(char *cmdline)
|
||||||
{
|
{
|
||||||
UNUSED(cmdline);
|
UNUSED(cmdline);
|
||||||
|
|
||||||
cliPrintf("# BetaFlight/%s %s %s / %s (%s)\r\n",
|
cliPrintf("# %s/%s %s %s / %s (%s)\r\n",
|
||||||
|
FC_FIRMWARE_NAME,
|
||||||
targetName,
|
targetName,
|
||||||
FC_VERSION_STRING,
|
FC_VERSION_STRING,
|
||||||
buildDate,
|
buildDate,
|
||||||
|
@ -3739,19 +3751,22 @@ typedef struct {
|
||||||
|
|
||||||
const cliResourceValue_t resourceTable[] = {
|
const cliResourceValue_t resourceTable[] = {
|
||||||
#ifdef BEEPER
|
#ifdef BEEPER
|
||||||
{ OWNER_BEEPER, &masterConfig.beeperConfig.ioTag, 0 },
|
{ OWNER_BEEPER, &masterConfig.beeperConfig.ioTag, 0 },
|
||||||
#endif
|
#endif
|
||||||
{ OWNER_MOTOR, &masterConfig.motorConfig.ioTags[0], MAX_SUPPORTED_MOTORS },
|
{ OWNER_MOTOR, &masterConfig.motorConfig.ioTags[0], MAX_SUPPORTED_MOTORS },
|
||||||
#ifdef USE_SERVOS
|
#ifdef USE_SERVOS
|
||||||
{ OWNER_SERVO, &masterConfig.servoConfig.ioTags[0], MAX_SUPPORTED_SERVOS },
|
{ OWNER_SERVO, &masterConfig.servoConfig.ioTags[0], MAX_SUPPORTED_SERVOS },
|
||||||
#endif
|
#endif
|
||||||
#ifndef SKIP_RX_PWM_PPM
|
#ifndef SKIP_RX_PWM_PPM
|
||||||
{ OWNER_PPMINPUT, &masterConfig.ppmConfig.ioTag, 0 },
|
{ OWNER_PPMINPUT, &masterConfig.ppmConfig.ioTag, 0 },
|
||||||
{ OWNER_PWMINPUT, &masterConfig.pwmConfig.ioTags[0], PWM_INPUT_PORT_COUNT },
|
{ OWNER_PWMINPUT, &masterConfig.pwmConfig.ioTags[0], PWM_INPUT_PORT_COUNT },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SONAR
|
#ifdef SONAR
|
||||||
{ OWNER_SONAR_TRIGGER, &masterConfig.sonarConfig.triggerTag, 0 },
|
{ OWNER_SONAR_TRIGGER, &masterConfig.sonarConfig.triggerTag, 0 },
|
||||||
{ OWNER_SONAR_ECHO, &masterConfig.sonarConfig.echoTag, 0 },
|
{ OWNER_SONAR_ECHO, &masterConfig.sonarConfig.echoTag, 0 },
|
||||||
|
#endif
|
||||||
|
#ifdef LED_STRIP
|
||||||
|
{ OWNER_LED_STRIP, &masterConfig.ledStripConfig.ioTag, 0 },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -495,7 +495,7 @@ void init(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LED_STRIP
|
#ifdef LED_STRIP
|
||||||
ledStripInit(masterConfig.ledConfigs, masterConfig.colors, masterConfig.modeColors, &masterConfig.specialColors);
|
ledStripInit(&masterConfig.ledStripConfig);
|
||||||
|
|
||||||
if (feature(FEATURE_LED_STRIP)) {
|
if (feature(FEATURE_LED_STRIP)) {
|
||||||
ledStripEnable();
|
ledStripEnable();
|
||||||
|
|
|
@ -59,7 +59,7 @@
|
||||||
#define MSP_PROTOCOL_VERSION 0
|
#define MSP_PROTOCOL_VERSION 0
|
||||||
|
|
||||||
#define API_VERSION_MAJOR 1 // increment when major changes are made
|
#define API_VERSION_MAJOR 1 // increment when major changes are made
|
||||||
#define API_VERSION_MINOR 21 // increment when any change is made, reset to zero when major changes are released after changing API_VERSION_MAJOR
|
#define API_VERSION_MINOR 22 // increment when any change is made, reset to zero when major changes are released after changing API_VERSION_MAJOR
|
||||||
|
|
||||||
#define API_VERSION_LENGTH 2
|
#define API_VERSION_LENGTH 2
|
||||||
|
|
||||||
|
|
|
@ -24,10 +24,10 @@
|
||||||
#include "drivers/timer.h"
|
#include "drivers/timer.h"
|
||||||
|
|
||||||
const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = {
|
const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = {
|
||||||
{ TIM1, IO_TAG(PA8), TIM_Channel_1, TIM1_CC_IRQn, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_INVERTED, GPIO_AF_6, DMA1_Channel2, DMA1_CH2_HANDLER },
|
|
||||||
{ TIM8, IO_TAG(PB0), TIM_Channel_2, TIM8_CC_IRQn, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_N_CHANNEL | TIMER_OUTPUT_INVERTED, GPIO_AF_4, DMA2_Channel5, DMA2_CH5_HANDLER },
|
|
||||||
{ TIM1, IO_TAG(PB14), TIM_Channel_2, TIM1_CC_IRQn, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_N_CHANNEL | TIMER_OUTPUT_INVERTED, GPIO_AF_6, DMA1_Channel3, DMA1_CH3_HANDLER },
|
{ TIM1, IO_TAG(PB14), TIM_Channel_2, TIM1_CC_IRQn, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_N_CHANNEL | TIMER_OUTPUT_INVERTED, GPIO_AF_6, DMA1_Channel3, DMA1_CH3_HANDLER },
|
||||||
|
{ TIM8, IO_TAG(PB0), TIM_Channel_2, TIM8_CC_IRQn, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_N_CHANNEL | TIMER_OUTPUT_INVERTED, GPIO_AF_4, DMA2_Channel5, DMA2_CH5_HANDLER },
|
||||||
{ TIM15, IO_TAG(PB15), TIM_Channel_1, TIM1_BRK_TIM15_IRQn, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_N_CHANNEL | TIMER_OUTPUT_INVERTED, GPIO_AF_2, DMA1_Channel5, DMA1_CH5_HANDLER },
|
{ TIM15, IO_TAG(PB15), TIM_Channel_1, TIM1_BRK_TIM15_IRQn, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_N_CHANNEL | TIMER_OUTPUT_INVERTED, GPIO_AF_2, DMA1_Channel5, DMA1_CH5_HANDLER },
|
||||||
|
{ TIM1, IO_TAG(PA8), TIM_Channel_1, TIM1_CC_IRQn, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_INVERTED, GPIO_AF_6, DMA1_Channel2, DMA1_CH2_HANDLER },
|
||||||
{ TIM3, IO_TAG(PA6), TIM_Channel_1, TIM3_IRQn, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_INVERTED, GPIO_AF_2, DMA1_Channel6, DMA1_CH6_HANDLER },
|
{ TIM3, IO_TAG(PA6), TIM_Channel_1, TIM3_IRQn, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_INVERTED, GPIO_AF_2, DMA1_Channel6, DMA1_CH6_HANDLER },
|
||||||
{ TIM17, IO_TAG(PA7), TIM_Channel_1, TIM1_TRG_COM_TIM17_IRQn, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_INVERTED, GPIO_AF_1, DMA1_Channel7, DMA1_CH7_HANDLER },
|
{ TIM17, IO_TAG(PA7), TIM_Channel_1, TIM1_TRG_COM_TIM17_IRQn, TIM_USE_MOTOR, TIMER_OUTPUT_ENABLED | TIMER_OUTPUT_INVERTED, GPIO_AF_1, DMA1_Channel7, DMA1_CH7_HANDLER },
|
||||||
|
|
||||||
|
|
1
src/main/target/LUX_RACE/LUXV2_RACE.mk
Executable file
1
src/main/target/LUX_RACE/LUXV2_RACE.mk
Executable file
|
@ -0,0 +1 @@
|
||||||
|
# LUXR_RACE is new version
|
|
@ -21,18 +21,21 @@
|
||||||
#include "drivers/io.h"
|
#include "drivers/io.h"
|
||||||
|
|
||||||
#include "drivers/timer.h"
|
#include "drivers/timer.h"
|
||||||
|
#include "drivers/dma.h"
|
||||||
|
|
||||||
const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = {
|
const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = {
|
||||||
{ TIM1, IO_TAG(PA8), TIM_Channel_1, TIM1_CC_IRQn, TIM_USE_PPM, 0, GPIO_AF_6 }, // PWM1 - PA8
|
{ TIM1, IO_TAG(PA8), TIM_Channel_1, TIM1_CC_IRQn, TIM_USE_PPM, 0, GPIO_AF_6, NULL, 0 }, // PWM1 - PA8
|
||||||
{ TIM3, IO_TAG(PC6), TIM_Channel_1, TIM3_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_2 }, // PWM2 - PC6
|
{ TIM3, IO_TAG(PC6), TIM_Channel_1, TIM3_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_2, DMA1_Channel6, DMA1_CH6_HANDLER }, // PWM2 - PC6
|
||||||
{ TIM3, IO_TAG(PC7), TIM_Channel_2, TIM3_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_2 }, // PWM3 - PC7
|
{ TIM8, IO_TAG(PC7), TIM_Channel_2, TIM8_CC_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_4, DMA2_Channel5, DMA2_CH5_HANDLER }, // PWM3 - PC7
|
||||||
{ TIM3, IO_TAG(PC8), TIM_Channel_3, TIM3_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_2 }, // PMW4 - PC8
|
{ TIM8, IO_TAG(PC8), TIM_Channel_3, TIM8_CC_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_4, DMA2_Channel1, DMA2_CH1_HANDLER }, // PMW4 - PC8
|
||||||
{ TIM3, IO_TAG(PC9), TIM_Channel_4, TIM3_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_2 }, // PWM5 - PC9
|
{ TIM8, IO_TAG(PC9), TIM_Channel_4, TIM8_CC_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_4, DMA2_Channel2, DMA2_CH2_HANDLER }, // PWM5 - PC9
|
||||||
{ TIM2, IO_TAG(PA0), TIM_Channel_1, TIM2_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_1 }, // PWM6 - PA0
|
#ifndef LUXV2_RACE
|
||||||
{ TIM2, IO_TAG(PA1), TIM_Channel_2, TIM2_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_1 }, // PWM7 - PA1
|
{ TIM2, IO_TAG(PA0), TIM_Channel_1, TIM2_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_1, NULL, 0 }, // PWM6 - PA0
|
||||||
{ TIM2, IO_TAG(PA2), TIM_Channel_3, TIM2_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_1 }, // PWM8 - PA2
|
{ TIM2, IO_TAG(PA1), TIM_Channel_2, TIM2_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_1, NULL, 0 }, // PWM7 - PA1
|
||||||
{ TIM2, IO_TAG(PA3), TIM_Channel_4, TIM2_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_1 }, // PWM9 - PA3
|
{ TIM2, IO_TAG(PA2), TIM_Channel_3, TIM2_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_1, NULL, 0 }, // PWM8 - PA2
|
||||||
{ TIM15, IO_TAG(PB14), TIM_Channel_1, TIM1_BRK_TIM15_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_1 }, // PWM10 - PB14
|
{ TIM2, IO_TAG(PA3), TIM_Channel_4, TIM2_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_1, NULL, 0 }, // PWM9 - PA3
|
||||||
{ TIM15, IO_TAG(PB15), TIM_Channel_2, TIM1_BRK_TIM15_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_1 }, // PWM11 - PB15
|
{ TIM15, IO_TAG(PB14), TIM_Channel_1, TIM1_BRK_TIM15_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_1, NULL, 0 }, // PWM10 - PB14
|
||||||
|
{ TIM15, IO_TAG(PB15), TIM_Channel_2, TIM1_BRK_TIM15_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_1, NULL, 0 }, // PWM11 - PB15
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,16 +17,26 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef LUXV2_RACE
|
||||||
|
#define TARGET_BOARD_IDENTIFIER "LUXR"
|
||||||
|
#else
|
||||||
#define TARGET_BOARD_IDENTIFIER "LUX"
|
#define TARGET_BOARD_IDENTIFIER "LUX"
|
||||||
|
#endif
|
||||||
#define BOARD_HAS_VOLTAGE_DIVIDER
|
#define BOARD_HAS_VOLTAGE_DIVIDER
|
||||||
|
|
||||||
#define CONFIG_FASTLOOP_PREFERRED_ACC ACC_DEFAULT
|
#define CONFIG_FASTLOOP_PREFERRED_ACC ACC_DEFAULT
|
||||||
|
|
||||||
#define LED0 PC15
|
#define LED0 PC15
|
||||||
#define LED1 PC14
|
#define LED1 PC14
|
||||||
|
#ifndef LUXV2_RACE
|
||||||
#define LED2 PC13
|
#define LED2 PC13
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LUXV2_RACE
|
||||||
|
#define BEEPER PB9
|
||||||
|
#else
|
||||||
#define BEEPER PB13
|
#define BEEPER PB13
|
||||||
|
#endif
|
||||||
#define BEEPER_INVERTED
|
#define BEEPER_INVERTED
|
||||||
|
|
||||||
// MPU6500 interrupt
|
// MPU6500 interrupt
|
||||||
|
@ -36,26 +46,72 @@
|
||||||
#define USE_MPU_DATA_READY_SIGNAL
|
#define USE_MPU_DATA_READY_SIGNAL
|
||||||
#define ENSURE_MPU_DATA_READY_IS_LOW
|
#define ENSURE_MPU_DATA_READY_IS_LOW
|
||||||
|
|
||||||
|
#define USE_DSHOT
|
||||||
|
|
||||||
#define USE_SPI
|
#define USE_SPI
|
||||||
#define USE_SPI_DEVICE_1
|
#define USE_SPI_DEVICE_1
|
||||||
|
#ifdef LUXV2_RACE
|
||||||
|
#define USE_SPI_DEVICE_2
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SPI1_SCK_PIN PB3
|
#define SPI1_SCK_PIN PB3
|
||||||
#define SPI1_MISO_PIN PB4
|
#define SPI1_MISO_PIN PB4
|
||||||
#define SPI1_MOSI_PIN PB5
|
#define SPI1_MOSI_PIN PB5
|
||||||
|
//#ifndef LUXV2_RACE
|
||||||
#define SPI1_NSS_PIN PA4
|
#define SPI1_NSS_PIN PA4
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
#ifdef LUXV2_RACE
|
||||||
|
#define SPI2_NSS_PIN PB12
|
||||||
|
#define SPI2_SCK_PIN PB13
|
||||||
|
#define SPI2_MISO_PIN PB14
|
||||||
|
#define SPI2_MOSI_PIN PB15
|
||||||
|
|
||||||
|
#define USE_SDCARD
|
||||||
|
#define USE_SDCARD_SPI2
|
||||||
|
|
||||||
|
#define SDCARD_DETECT_INVERTED
|
||||||
|
|
||||||
|
#define SDCARD_DETECT_PIN PC13
|
||||||
|
#define SDCARD_SPI_INSTANCE SPI2
|
||||||
|
#define SDCARD_SPI_CS_PIN SPI2_NSS_PIN
|
||||||
|
|
||||||
|
// SPI2 is on the APB1 bus whose clock runs at 36MHz. Divide to under 400kHz for init:
|
||||||
|
#define SDCARD_SPI_INITIALIZATION_CLOCK_DIVIDER 128
|
||||||
|
// Divide to under 25MHz for normal operation:
|
||||||
|
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 2
|
||||||
|
|
||||||
|
// Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx.
|
||||||
|
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
|
||||||
|
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MPU6000_CS_PIN SPI1_NSS_PIN
|
||||||
|
#define MPU6000_SPI_INSTANCE SPI1
|
||||||
#define MPU6500_CS_PIN SPI1_NSS_PIN
|
#define MPU6500_CS_PIN SPI1_NSS_PIN
|
||||||
#define MPU6500_SPI_INSTANCE SPI1
|
#define MPU6500_SPI_INSTANCE SPI1
|
||||||
|
|
||||||
#define GYRO
|
#define GYRO
|
||||||
|
#ifdef LUXV2_RACE
|
||||||
|
#define USE_GYRO_MPU6000
|
||||||
|
#define USE_GYRO_SPI_MPU6000
|
||||||
|
#define GYRO_MPU6000_ALIGN CW270_DEG
|
||||||
|
#else
|
||||||
#define USE_GYRO_MPU6500
|
#define USE_GYRO_MPU6500
|
||||||
#define USE_GYRO_SPI_MPU6500
|
#define USE_GYRO_SPI_MPU6500
|
||||||
#define GYRO_MPU6500_ALIGN CW270_DEG
|
#define GYRO_MPU6500_ALIGN CW270_DEG
|
||||||
|
#endif
|
||||||
|
|
||||||
#define ACC
|
#define ACC
|
||||||
|
#ifdef LUXV2_RACE
|
||||||
|
#define USE_ACC_MPU6000
|
||||||
|
#define USE_ACC_SPI_MPU6000
|
||||||
|
#define ACC_MPU6000_ALIGN CW270_DEG
|
||||||
|
#else
|
||||||
#define USE_ACC_MPU6500
|
#define USE_ACC_MPU6500
|
||||||
#define USE_ACC_SPI_MPU6500
|
#define USE_ACC_SPI_MPU6500
|
||||||
#define ACC_MPU6500_ALIGN CW270_DEG
|
#define ACC_MPU6500_ALIGN CW270_DEG
|
||||||
|
#endif
|
||||||
|
|
||||||
#define USB_IO
|
#define USB_IO
|
||||||
|
|
||||||
|
@ -63,7 +119,13 @@
|
||||||
#define USE_UART1
|
#define USE_UART1
|
||||||
#define USE_UART2
|
#define USE_UART2
|
||||||
#define USE_UART3
|
#define USE_UART3
|
||||||
|
#ifdef LUXV2_RACE
|
||||||
|
#define USE_UART4
|
||||||
|
#define USE_UART5
|
||||||
|
#define SERIAL_PORT_COUNT 6
|
||||||
|
#else
|
||||||
#define SERIAL_PORT_COUNT 4
|
#define SERIAL_PORT_COUNT 4
|
||||||
|
#endif
|
||||||
|
|
||||||
#define UART1_TX_PIN PC4
|
#define UART1_TX_PIN PC4
|
||||||
#define UART1_RX_PIN PC5
|
#define UART1_RX_PIN PC5
|
||||||
|
@ -74,8 +136,7 @@
|
||||||
#define UART3_TX_PIN PB10
|
#define UART3_TX_PIN PB10
|
||||||
#define UART3_RX_PIN PB11
|
#define UART3_RX_PIN PB11
|
||||||
|
|
||||||
#define USE_I2C
|
#undef USE_I2C
|
||||||
#define I2C_DEVICE (I2CDEV_2)
|
|
||||||
|
|
||||||
#define USE_ADC
|
#define USE_ADC
|
||||||
#define ADC_INSTANCE ADC1
|
#define ADC_INSTANCE ADC1
|
||||||
|
@ -95,6 +156,11 @@
|
||||||
|
|
||||||
#define DEFAULT_RX_FEATURE FEATURE_RX_PPM
|
#define DEFAULT_RX_FEATURE FEATURE_RX_PPM
|
||||||
|
|
||||||
|
#ifdef LUXV2_RACE
|
||||||
|
#define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT
|
||||||
|
#define DEFAULT_FEATURES FEATURE_BLACKBOX
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SPEKTRUM_BIND
|
#define SPEKTRUM_BIND
|
||||||
// USART1, PC5
|
// USART1, PC5
|
||||||
#define BIND_PIN PC5
|
#define BIND_PIN PC5
|
||||||
|
@ -108,6 +174,10 @@
|
||||||
#define TARGET_IO_PORTD (BIT(2))
|
#define TARGET_IO_PORTD (BIT(2))
|
||||||
#define TARGET_IO_PORTF (BIT(0)|BIT(1)|BIT(4))
|
#define TARGET_IO_PORTF (BIT(0)|BIT(1)|BIT(4))
|
||||||
|
|
||||||
|
#ifdef LUXV2_RACE
|
||||||
|
#define USABLE_TIMER_CHANNEL_COUNT 5
|
||||||
|
#else
|
||||||
#define USABLE_TIMER_CHANNEL_COUNT 11
|
#define USABLE_TIMER_CHANNEL_COUNT 11
|
||||||
#define USED_TIMERS (TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(15))
|
#endif
|
||||||
|
#define USED_TIMERS (TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(8) | TIM_N(15))
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
F3_TARGETS += $(TARGET)
|
F3_TARGETS += $(TARGET)
|
||||||
FEATURES = VCP
|
FEATURES = VCP SDCARD
|
||||||
|
|
||||||
TARGET_SRC = \
|
TARGET_SRC = \
|
||||||
drivers/accgyro_mpu.c \
|
drivers/accgyro_mpu.c \
|
||||||
drivers/accgyro_mpu6500.c \
|
drivers/accgyro_mpu6500.c \
|
||||||
drivers/accgyro_spi_mpu6500.c \
|
drivers/accgyro_spi_mpu6500.c \
|
||||||
drivers/accgyro_mpu6500.c
|
drivers/accgyro_mpu6500.c \
|
||||||
|
drivers/accgyro_spi_mpu6000.c
|
0
src/main/target/REVO/AIRBOTF4.mk
Normal file
0
src/main/target/REVO/AIRBOTF4.mk
Normal file
0
src/main/target/REVO/REVOLT.mk
Normal file
0
src/main/target/REVO/REVOLT.mk
Normal file
|
@ -30,10 +30,14 @@ const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = {
|
||||||
{ TIM8, IO_TAG(PC7), TIM_Channel_2, TIM8_CC_IRQn, TIM_USE_PWM, 0, GPIO_AF_TIM8, NULL, 0, 0 }, // S4_IN
|
{ TIM8, IO_TAG(PC7), TIM_Channel_2, TIM8_CC_IRQn, TIM_USE_PWM, 0, GPIO_AF_TIM8, NULL, 0, 0 }, // S4_IN
|
||||||
{ TIM8, IO_TAG(PC8), TIM_Channel_3, TIM8_CC_IRQn, TIM_USE_PWM, 0, GPIO_AF_TIM8, NULL, 0, 0 }, // S5_IN
|
{ TIM8, IO_TAG(PC8), TIM_Channel_3, TIM8_CC_IRQn, TIM_USE_PWM, 0, GPIO_AF_TIM8, NULL, 0, 0 }, // S5_IN
|
||||||
{ TIM8, IO_TAG(PC9), TIM_Channel_4, TIM8_CC_IRQn, TIM_USE_PWM, 0, GPIO_AF_TIM8, NULL, 0, 0 }, // S6_IN
|
{ TIM8, IO_TAG(PC9), TIM_Channel_4, TIM8_CC_IRQn, TIM_USE_PWM, 0, GPIO_AF_TIM8, NULL, 0, 0 }, // S6_IN
|
||||||
{ TIM3, IO_TAG(PB0), TIM_Channel_3, TIM3_IRQn, TIM_USE_PWM, 1, GPIO_AF_TIM3, DMA1_Stream7, DMA_Channel_5, DMA1_ST7_HANDLER }, // S1_OUT
|
{ TIM3, IO_TAG(PB0), TIM_Channel_3, TIM3_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_TIM3, DMA1_Stream7, DMA_Channel_5, DMA1_ST7_HANDLER }, // S1_OUT
|
||||||
{ TIM3, IO_TAG(PB1), TIM_Channel_4, TIM3_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_TIM3, DMA1_Stream2, DMA_Channel_5, DMA1_ST2_HANDLER }, // S2_OUT
|
{ TIM3, IO_TAG(PB1), TIM_Channel_4, TIM3_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_TIM3, DMA1_Stream2, DMA_Channel_5, DMA1_ST2_HANDLER }, // S2_OUT
|
||||||
{ TIM2, IO_TAG(PA3), TIM_Channel_4, TIM2_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_TIM2, DMA1_Stream6, DMA_Channel_3, DMA1_ST6_HANDLER }, // S3_OUT
|
{ TIM2, IO_TAG(PA3), TIM_Channel_4, TIM2_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_TIM2, DMA1_Stream6, DMA_Channel_3, DMA1_ST6_HANDLER }, // S3_OUT
|
||||||
{ TIM2, IO_TAG(PA2), TIM_Channel_3, TIM2_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_TIM2, DMA1_Stream1, DMA_Channel_3, DMA1_ST1_HANDLER }, // S4_OUT
|
{ TIM2, IO_TAG(PA2), TIM_Channel_3, TIM2_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_TIM2, DMA1_Stream1, DMA_Channel_3, DMA1_ST1_HANDLER }, // S4_OUT
|
||||||
{ TIM5, IO_TAG(PA1), TIM_Channel_2, TIM5_IRQn, TIM_USE_MOTOR | TIM_USE_LED, 1, GPIO_AF_TIM5, DMA1_Stream4, DMA_Channel_6, DMA1_ST4_HANDLER }, // S5_OUT
|
#ifdef REVOLT
|
||||||
|
{ TIM4, IO_TAG(PB6), TIM_Channel_1, TIM4_IRQn, TIM_USE_LED, 0, GPIO_AF_TIM4, DMA1_Stream0, DMA_Channel_2, DMA1_ST0_HANDLER }, // LED for REVOLT
|
||||||
|
#else
|
||||||
|
{ TIM5, IO_TAG(PA1), TIM_Channel_2, TIM5_IRQn, TIM_USE_MOTOR | TIM_USE_LED, 1, GPIO_AF_TIM5, DMA1_Stream4, DMA_Channel_6, DMA1_ST4_HANDLER }, // S5_OUT / LED for REVO
|
||||||
{ TIM5, IO_TAG(PA0), TIM_Channel_1, TIM5_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_TIM5, DMA1_Stream2, DMA_Channel_6, DMA1_ST2_HANDLER }, // S6_OUT
|
{ TIM5, IO_TAG(PA0), TIM_Channel_1, TIM5_IRQn, TIM_USE_MOTOR, 1, GPIO_AF_TIM5, DMA1_Stream2, DMA_Channel_6, DMA1_ST2_HANDLER }, // S6_OUT
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,43 +17,71 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#define TARGET_BOARD_IDENTIFIER "REVO"
|
|
||||||
|
|
||||||
#define CONFIG_START_FLASH_ADDRESS (0x08080000) //0x08080000 to 0x080A0000 (FLASH_Sector_8)
|
#define CONFIG_START_FLASH_ADDRESS (0x08080000) //0x08080000 to 0x080A0000 (FLASH_Sector_8)
|
||||||
|
|
||||||
|
#if defined(AIRBOTF4)
|
||||||
|
#define TARGET_BOARD_IDENTIFIER "AIR4"
|
||||||
|
#define USBD_PRODUCT_STRING "AirbotF4"
|
||||||
|
|
||||||
|
#elif defined(REVOLT)
|
||||||
|
#define TARGET_BOARD_IDENTIFIER "RVLT"
|
||||||
|
#define USBD_PRODUCT_STRING "Revolt"
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define TARGET_BOARD_IDENTIFIER "REVO"
|
||||||
#define USBD_PRODUCT_STRING "Revolution"
|
#define USBD_PRODUCT_STRING "Revolution"
|
||||||
|
|
||||||
#ifdef OPBL
|
#ifdef OPBL
|
||||||
#define USBD_SERIALNUMBER_STRING "0x8020000"
|
#define USBD_SERIALNUMBER_STRING "0x8020000"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#define USE_DSHOT
|
#define USE_DSHOT
|
||||||
|
|
||||||
#define LED0 PB5
|
#define LED0 PB5
|
||||||
// Disable LED1, conflicts with AirbotF4/Flip32F4 beeper
|
// Disable LED1, conflicts with AirbotF4/Flip32F4/Revolt beeper
|
||||||
//#define LED1 PB4
|
#if defined(AIRBOTF4) || defined(REVOLT)
|
||||||
|
|
||||||
#define BEEPER PB4
|
#define BEEPER PB4
|
||||||
#define BEEPER_INVERTED
|
#define BEEPER_INVERTED
|
||||||
|
#else
|
||||||
|
#define LED1 PB4
|
||||||
|
// Leave beeper here but with none as io - so disabled unless mapped.
|
||||||
|
#define BEEPER NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
#define INVERTER PC0 // PC0 used as inverter select GPIO
|
// PC0 used as inverter select GPIO
|
||||||
|
#define INVERTER PC0
|
||||||
#define INVERTER_USART USART1
|
#define INVERTER_USART USART1
|
||||||
|
|
||||||
#define MPU6000_CS_PIN PA4
|
#define MPU6000_CS_PIN PA4
|
||||||
#define MPU6000_SPI_INSTANCE SPI1
|
#define MPU6000_SPI_INSTANCE SPI1
|
||||||
|
|
||||||
|
#define MPU6500_CS_PIN PA4
|
||||||
|
#define MPU6500_SPI_INSTANCE SPI1
|
||||||
|
|
||||||
#define ACC
|
#define ACC
|
||||||
#define USE_ACC_SPI_MPU6000
|
#define USE_ACC_SPI_MPU6000
|
||||||
#define GYRO_MPU6000_ALIGN CW270_DEG
|
#define GYRO_MPU6000_ALIGN CW270_DEG
|
||||||
|
|
||||||
|
#define USE_ACC_MPU6500
|
||||||
|
#define USE_ACC_SPI_MPU6500
|
||||||
|
#define ACC_MPU6500_ALIGN CW270_DEG
|
||||||
|
|
||||||
#define GYRO
|
#define GYRO
|
||||||
#define USE_GYRO_SPI_MPU6000
|
#define USE_GYRO_SPI_MPU6000
|
||||||
#define ACC_MPU6000_ALIGN CW270_DEG
|
#define ACC_MPU6000_ALIGN CW270_DEG
|
||||||
|
|
||||||
|
#define USE_GYRO_MPU6500
|
||||||
|
#define USE_GYRO_SPI_MPU6500
|
||||||
|
#define GYRO_MPU9250_ALIGN CW270_DEG
|
||||||
|
|
||||||
// MPU6000 interrupts
|
// MPU6000 interrupts
|
||||||
#define USE_EXTI
|
#define USE_EXTI
|
||||||
#define MPU_INT_EXTI PC4
|
#define MPU_INT_EXTI PC4
|
||||||
#define USE_MPU_DATA_READY_SIGNAL
|
#define USE_MPU_DATA_READY_SIGNAL
|
||||||
|
|
||||||
|
#if !defined(AIRBOTF4) && !defined(REVOLT)
|
||||||
#define MAG
|
#define MAG
|
||||||
#define USE_MAG_HMC5883
|
#define USE_MAG_HMC5883
|
||||||
#define MAG_HMC5883_ALIGN CW90_DEG
|
#define MAG_HMC5883_ALIGN CW90_DEG
|
||||||
|
@ -67,6 +95,7 @@
|
||||||
//#define PITOT
|
//#define PITOT
|
||||||
//#define USE_PITOT_MS4525
|
//#define USE_PITOT_MS4525
|
||||||
//#define MS4525_BUS I2C_DEVICE_EXT
|
//#define MS4525_BUS I2C_DEVICE_EXT
|
||||||
|
#endif
|
||||||
|
|
||||||
#define M25P16_CS_PIN PB3
|
#define M25P16_CS_PIN PB3
|
||||||
#define M25P16_SPI_INSTANCE SPI3
|
#define M25P16_SPI_INSTANCE SPI3
|
||||||
|
@ -78,8 +107,8 @@
|
||||||
#define VBUS_SENSING_PIN PC5
|
#define VBUS_SENSING_PIN PC5
|
||||||
|
|
||||||
#define USE_UART1
|
#define USE_UART1
|
||||||
#define UART1_RX_PIN PA10
|
#define UART1_RX_PIN PA10
|
||||||
#define UART1_TX_PIN PA9
|
#define UART1_TX_PIN PA9
|
||||||
#define UART1_AHB1_PERIPHERALS RCC_AHB1Periph_DMA2
|
#define UART1_AHB1_PERIPHERALS RCC_AHB1Periph_DMA2
|
||||||
|
|
||||||
#define USE_UART3
|
#define USE_UART3
|
||||||
|
@ -106,7 +135,7 @@
|
||||||
#define SPI3_MOSI_PIN PC12
|
#define SPI3_MOSI_PIN PC12
|
||||||
|
|
||||||
#define USE_I2C
|
#define USE_I2C
|
||||||
#define I2C_DEVICE (I2CDEV_1)
|
#define I2C_DEVICE (I2CDEV_1)
|
||||||
|
|
||||||
#define USE_ADC
|
#define USE_ADC
|
||||||
#define CURRENT_METER_ADC_PIN PC1
|
#define CURRENT_METER_ADC_PIN PC1
|
||||||
|
@ -126,7 +155,7 @@
|
||||||
#define WS2811_DMA_FLAG DMA_FLAG_TCIF4
|
#define WS2811_DMA_FLAG DMA_FLAG_TCIF4
|
||||||
#define WS2811_DMA_IT DMA_IT_TCIF4
|
#define WS2811_DMA_IT DMA_IT_TCIF4
|
||||||
|
|
||||||
#define SENSORS_SET (SENSOR_ACC)
|
#define SENSORS_SET (SENSOR_ACC)
|
||||||
|
|
||||||
#define DEFAULT_RX_FEATURE FEATURE_RX_SERIAL
|
#define DEFAULT_RX_FEATURE FEATURE_RX_SERIAL
|
||||||
#define DEFAULT_FEATURES (FEATURE_BLACKBOX)
|
#define DEFAULT_FEATURES (FEATURE_BLACKBOX)
|
||||||
|
@ -140,7 +169,12 @@
|
||||||
#define TARGET_IO_PORTA 0xffff
|
#define TARGET_IO_PORTA 0xffff
|
||||||
#define TARGET_IO_PORTB 0xffff
|
#define TARGET_IO_PORTB 0xffff
|
||||||
#define TARGET_IO_PORTC 0xffff
|
#define TARGET_IO_PORTC 0xffff
|
||||||
#define TARGET_IO_PORTD 0xffff
|
#define TARGET_IO_PORTD (BIT(2))
|
||||||
|
|
||||||
|
#ifdef REVOLT
|
||||||
|
#define USABLE_TIMER_CHANNEL_COUNT 11
|
||||||
|
#else
|
||||||
#define USABLE_TIMER_CHANNEL_COUNT 12
|
#define USABLE_TIMER_CHANNEL_COUNT 12
|
||||||
|
#endif
|
||||||
|
|
||||||
#define USED_TIMERS ( TIM_N(2) | TIM_N(3) | TIM_N(5) | TIM_N(12) | TIM_N(8) | TIM_N(9) )
|
#define USED_TIMERS ( TIM_N(2) | TIM_N(3) | TIM_N(5) | TIM_N(12) | TIM_N(8) | TIM_N(9) )
|
||||||
|
|
|
@ -3,6 +3,8 @@ FEATURES += VCP ONBOARDFLASH
|
||||||
|
|
||||||
TARGET_SRC = \
|
TARGET_SRC = \
|
||||||
drivers/accgyro_spi_mpu6000.c \
|
drivers/accgyro_spi_mpu6000.c \
|
||||||
|
drivers/accgyro_mpu6500.c \
|
||||||
|
drivers/accgyro_spi_mpu6500.c \
|
||||||
drivers/barometer_ms5611.c \
|
drivers/barometer_ms5611.c \
|
||||||
drivers/compass_hmc5883l.c \
|
drivers/compass_hmc5883l.c \
|
||||||
io/cms.c \
|
io/cms.c \
|
||||||
|
|
|
@ -625,8 +625,10 @@ void handleSmartPortTelemetry(void)
|
||||||
#ifdef GPS
|
#ifdef GPS
|
||||||
case FSSP_DATAID_SPEED :
|
case FSSP_DATAID_SPEED :
|
||||||
if (sensors(SENSOR_GPS) && STATE(GPS_FIX)) {
|
if (sensors(SENSOR_GPS) && STATE(GPS_FIX)) {
|
||||||
uint32_t tmpui = (GPS_speed * 36 + 36 / 2) / 100;
|
//convert to knots: 1cm/s = 0.0194384449 knots
|
||||||
smartPortSendPackage(id, tmpui); // given in 0.1 m/s, provide in KM/H
|
//Speed should be sent in knots/1000 (GPS speed is in cm/s)
|
||||||
|
uint32_t tmpui = GPS_speed * 1944 / 100;
|
||||||
|
smartPortSendPackage(id, tmpui);
|
||||||
smartPortHasRequest = 0;
|
smartPortHasRequest = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "usbd_conf.h"
|
#include "usbd_conf.h"
|
||||||
#include "usb_regs.h"
|
#include "usb_regs.h"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
#include "build/version.h"
|
||||||
|
|
||||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||||
* @{
|
* @{
|
||||||
|
@ -57,7 +58,7 @@
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
#define USBD_LANGID_STRING 0x409
|
#define USBD_LANGID_STRING 0x409
|
||||||
#define USBD_MANUFACTURER_STRING "BetaFlight"
|
#define USBD_MANUFACTURER_STRING FC_FIRMWARE_NAME
|
||||||
|
|
||||||
#ifdef USBD_PRODUCT_STRING
|
#ifdef USBD_PRODUCT_STRING
|
||||||
#define USBD_PRODUCT_HS_STRING USBD_PRODUCT_STRING
|
#define USBD_PRODUCT_HS_STRING USBD_PRODUCT_STRING
|
||||||
|
|
|
@ -16,11 +16,13 @@ REPLY_FRAME_ID = 0x32
|
||||||
|
|
||||||
-- Sequence number for next MSP/SPORT packet
|
-- Sequence number for next MSP/SPORT packet
|
||||||
local sportMspSeq = 0
|
local sportMspSeq = 0
|
||||||
|
local sportMspRemoteSeq = 0
|
||||||
|
|
||||||
local mspRxBuf = {}
|
local mspRxBuf = {}
|
||||||
local mspRxIdx = 1
|
local mspRxIdx = 1
|
||||||
local mspRxCRC = 0
|
local mspRxCRC = 0
|
||||||
local mspStarted = false
|
local mspStarted = false
|
||||||
|
local mspLastReq = 0
|
||||||
|
|
||||||
-- Stats
|
-- Stats
|
||||||
mspRequestsSent = 0
|
mspRequestsSent = 0
|
||||||
|
@ -55,7 +57,8 @@ local function mspSendRequest(cmd)
|
||||||
value = bit32.band(cmd,0xFF) -- MSP command
|
value = bit32.band(cmd,0xFF) -- MSP command
|
||||||
value = value + bit32.lshift(cmd,8) -- CRC
|
value = value + bit32.lshift(cmd,8) -- CRC
|
||||||
|
|
||||||
mspRequestsSent = requestsSent + 1
|
mspLastReq = cmd
|
||||||
|
mspRequestsSent = mspRequestsSent + 1
|
||||||
return sportTelemetryPush(LOCAL_SENSOR_ID, REQUEST_FRAME_ID, dataId, value)
|
return sportTelemetryPush(LOCAL_SENSOR_ID, REQUEST_FRAME_ID, dataId, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -90,7 +93,7 @@ local function mspReceivedReply(payload)
|
||||||
mspRxBuf = {}
|
mspRxBuf = {}
|
||||||
|
|
||||||
mspRxSize = payload[idx]
|
mspRxSize = payload[idx]
|
||||||
mspRxCRC = mspRxSize
|
mspRxCRC = bit32.bxor(mspRxSize,mspLastReq)
|
||||||
idx = idx + 1
|
idx = idx + 1
|
||||||
mspStarted = true
|
mspStarted = true
|
||||||
|
|
||||||
|
@ -100,7 +103,7 @@ local function mspReceivedReply(payload)
|
||||||
mspOutOfOrder = mspOutOfOrder + 1
|
mspOutOfOrder = mspOutOfOrder + 1
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
elseif bit32.band(lastSeq+1,0x0F) ~= seq then
|
elseif bit32.band(sportMspRemoteSeq + 1, 0x0F) ~= seq then
|
||||||
mspOutOfOrder = mspOutOfOrder + 1
|
mspOutOfOrder = mspOutOfOrder + 1
|
||||||
mspStarted = false
|
mspStarted = false
|
||||||
return nil
|
return nil
|
||||||
|
@ -114,7 +117,7 @@ local function mspReceivedReply(payload)
|
||||||
end
|
end
|
||||||
|
|
||||||
if idx > 6 then
|
if idx > 6 then
|
||||||
lastRxSeq = seq
|
sportMspRemoteSeq = seq
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -122,6 +125,7 @@ local function mspReceivedReply(payload)
|
||||||
if mspRxCRC ~= payload[idx] then
|
if mspRxCRC ~= payload[idx] then
|
||||||
mspStarted = false
|
mspStarted = false
|
||||||
mspCRCErrors = mspCRCErrors + 1
|
mspCRCErrors = mspCRCErrors + 1
|
||||||
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
mspRepliesReceived = mspRepliesReceived + 1
|
mspRepliesReceived = mspRepliesReceived + 1
|
||||||
|
@ -157,18 +161,14 @@ local function run(event)
|
||||||
local now = getTime()
|
local now = getTime()
|
||||||
|
|
||||||
if event == EVT_MINUS_FIRST or event == EVT_ROT_LEFT or event == EVT_MINUS_REPT then
|
if event == EVT_MINUS_FIRST or event == EVT_ROT_LEFT or event == EVT_MINUS_REPT then
|
||||||
requestsSent = 0
|
mspResetStats()
|
||||||
repliesReceived = 0
|
|
||||||
mspReceivedReply_cnt = 0
|
|
||||||
mspReceivedReply_cnt1 = 0
|
|
||||||
mspReceivedReply_cnt2 = 0
|
|
||||||
mspReceivedReply_cnt3 = 0
|
|
||||||
end
|
end
|
||||||
|
|
||||||
lcd.clear()
|
lcd.clear()
|
||||||
|
lcd.drawText(41,1,"MSP/SPORT test script",INVERS)
|
||||||
|
|
||||||
-- do we have valid telemetry data?
|
-- do we have valid telemetry data?
|
||||||
if getValue("rssi") > 0 then
|
if getValue("RSSI") > 0 then
|
||||||
|
|
||||||
-- draw screen
|
-- draw screen
|
||||||
lcd.drawText(1,11,"Requests:",0)
|
lcd.drawText(1,11,"Requests:",0)
|
||||||
|
@ -178,19 +178,19 @@ local function run(event)
|
||||||
lcd.drawNumber(60,21,mspRepliesReceived)
|
lcd.drawNumber(60,21,mspRepliesReceived)
|
||||||
|
|
||||||
lcd.drawText(1,31,"PkRxed:",0)
|
lcd.drawText(1,31,"PkRxed:",0)
|
||||||
lcd.drawNumber(30,31,mspPkRxed)
|
lcd.drawNumber(60,31,mspPkRxed)
|
||||||
|
|
||||||
lcd.drawText(1,41,"ErrorPk:",0)
|
lcd.drawText(1,41,"ErrorPk:",0)
|
||||||
lcd.drawNumber(30,41,mspErrorPk)
|
lcd.drawNumber(60,41,mspErrorPk)
|
||||||
|
|
||||||
lcd.drawText(71,31,"StartPk:",0)
|
lcd.drawText(91,31,"StartPk:",0)
|
||||||
lcd.drawNumber(100,31,mspStartPk)
|
lcd.drawNumber(160,31,mspStartPk)
|
||||||
|
|
||||||
lcd.drawText(71,41,"OutOfOrder:",0)
|
lcd.drawText(91,41,"OutOfOrder:",0)
|
||||||
lcd.drawNumber(100,41,mspOutOfOrder)
|
lcd.drawNumber(160,41,mspOutOfOrder)
|
||||||
|
|
||||||
lcd.drawText(1,51,"CRCErrors:",0)
|
lcd.drawText(1,51,"CRCErrors:",0)
|
||||||
lcd.drawNumber(30,51,mspCRCErrors)
|
lcd.drawNumber(60,51,mspCRCErrors)
|
||||||
|
|
||||||
-- last request is at least 2s old
|
-- last request is at least 2s old
|
||||||
if lastReqTS + 200 <= now then
|
if lastReqTS + 200 <= now then
|
||||||
|
@ -198,10 +198,10 @@ local function run(event)
|
||||||
lastReqTS = now
|
lastReqTS = now
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
lcd.drawText(20,30,"No telemetry signal", XXLSIZE + BLINK)
|
lcd.drawText(15,20,"No telemetry signal", BLINK + DBLSIZE)
|
||||||
end
|
end
|
||||||
|
|
||||||
pollReply()
|
mspPollReply()
|
||||||
end
|
end
|
||||||
|
|
||||||
return {run=run}
|
return {run=run}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue