Skip to content

Commit

Permalink
feat: RGB leds supports
Browse files Browse the repository at this point in the history
# Conflicts:
#	radio/src/gui/gui_common.cpp
  • Loading branch information
raphaelcoeffic committed Aug 6, 2023
1 parent ac4aeef commit 6f21389
Show file tree
Hide file tree
Showing 48 changed files with 803 additions and 81 deletions.
5 changes: 3 additions & 2 deletions radio/src/boards/generic_stm32/module_ports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "hal/module_port.h"
#include "stm32_serial_driver.h"
#include "stm32_softserial_driver.h"
#include "stm32_dma.h"

#include "module_ports.h"
#include "board.h"
Expand Down Expand Up @@ -86,7 +87,7 @@ static_assert(__STM32_PULSE_IS_TIMER_CHANNEL_SUPPORTED(INTMODULE_TIMER_Channel),
"Unsupported timer channel");

// Make sure the DMA channel is supported
static_assert(__STM32_PULSE_IS_DMA_STREAM_SUPPORTED(INTMODULE_TIMER_DMA_STREAM),
static_assert(__STM32_IS_DMA_STREAM_SUPPORTED(INTMODULE_TIMER_DMA_STREAM),
"Unsupported DMA stream");

#if !defined(INTMODULE_TIMER_DMA_IRQHandler)
Expand Down Expand Up @@ -198,7 +199,7 @@ static_assert(__STM32_PULSE_IS_TIMER_CHANNEL_SUPPORTED(EXTMODULE_TIMER_Channel),
"Unsupported timer channel");

// Make sure the DMA channel is supported
static_assert(__STM32_PULSE_IS_DMA_STREAM_SUPPORTED(EXTMODULE_TIMER_DMA_STREAM_LL),
static_assert(__STM32_DMA_IS_STREAM_SUPPORTED(EXTMODULE_TIMER_DMA_STREAM_LL),
"Unsupported DMA stream");

#if !defined(EXTMODULE_TIMER_DMA_IRQHandler)
Expand Down
120 changes: 120 additions & 0 deletions radio/src/boards/generic_stm32/rgb_leds.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright (C) EdgeTx
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include "stm32_pulse_driver.h"
#include "rgb_leds.h"
#include "hal.h"
#include "opentx.h"

#if defined(LED_STRIP_GPIO)

#include "stm32_ws2812.h"
#include "stm32_dma.h"

#if !defined(SIMU)
#include <FreeRTOS/include/FreeRTOS.h>
#include <FreeRTOS/include/timers.h>
#endif

extern const stm32_pulse_timer_t _led_timer;

static TimerHandle_t rgbLedTimer = nullptr;
static StaticTimer_t rgbLedTimerBuffer;

void rgbSetLedColor(uint8_t led, uint8_t r, uint8_t g, uint8_t b)
{
ws2812_set_color(led, r, g, b);
}

void rgbLedColorApply()
{
ws2812_update(&_led_timer);;
}

static void rgbLedTimerCb(TimerHandle_t xTimer)
{
(void)xTimer;

if (!isFunctionActive(FUNCTION_RGBLED)) {
for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
rgbSetLedColor(i, 0, 0, 0);
}
}
ws2812_update(&_led_timer);
}

void rgbLedStart()
{
if (!rgbLedTimer) {
rgbLedTimer =
xTimerCreateStatic("rgbLed", LED_STRIP_REFRESH_PERIOD / RTOS_MS_PER_TICK, pdTRUE, (void*)0,
rgbLedTimerCb, &rgbLedTimerBuffer);
}

if (rgbLedTimer) {
if( xTimerStart( rgbLedTimer, 0 ) != pdPASS ) {
/* The timer could not be set into the Active state. */
}
}
}

void rgbLedStop()
{
if (rgbLedTimer) {
if( xTimerStop( rgbLedTimer, 5 / RTOS_MS_PER_TICK ) != pdPASS ) {
/* The timer could not be stopped. */
}
}
}

const stm32_pulse_timer_t _led_timer = {
.GPIOx = LED_STRIP_GPIO,
.GPIO_Pin = LED_STRIP_GPIO_PIN_DATA,
.GPIO_Alternate = LED_STRIP_GPIO_PIN_AF,
.TIMx = LED_STRIP_TIMER,
.TIM_Freq = LED_STRIP_TIMER_FREQ,
.TIM_Channel = LED_STRIP_TIMER_CHANNEL,
.TIM_IRQn = (IRQn_Type)-1,
.DMAx = LED_STRIP_TIMER_DMA,
.DMA_Stream = LED_STRIP_TIMER_DMA_STREAM,
.DMA_Channel = LED_STRIP_TIMER_DMA_CHANNEL,
.DMA_IRQn = LED_STRIP_TIMER_DMA_IRQn,
.DMA_TC_CallbackPtr = nullptr,
};

// Make sure the timer channel is supported
static_assert(__STM32_PULSE_IS_TIMER_CHANNEL_SUPPORTED(LED_STRIP_TIMER_CHANNEL),
"Unsupported timer channel");

// Make sure the DMA channel is supported
static_assert(__STM32_DMA_IS_STREAM_SUPPORTED(LED_STRIP_TIMER_DMA_STREAM),
"Unsupported DMA stream");

#if !defined(LED_STRIP_TIMER_DMA_IRQHandler)
#error "Missing LED_STRIP_TIMER_DMA_IRQHandler definition"
#endif

extern "C" void LED_STRIP_TIMER_DMA_IRQHandler()
{
ws2812_dma_isr(&_led_timer);
}

#endif
29 changes: 29 additions & 0 deletions radio/src/boards/generic_stm32/rgb_leds.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (C) EdgeTx
*
* Based on code named
* opentx - https://github.com/opentx/opentx
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#pragma once

void rgbLedStart();
void rgbLedStop();
void rgbSetLedColor(unsigned char, unsigned char, unsigned char, unsigned char);
void rgbLedColorApply();

// void boardInitRGBLed();
11 changes: 11 additions & 0 deletions radio/src/dataconstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,7 @@ enum Functions {
FUNC_DISABLE_TOUCH,
FUNC_SET_SCREEN,
#endif
FUNC_RGB_LED,
#if defined(DEBUG)
FUNC_TEST, // should remain the last before MAX as not added in Companion
#endif
Expand Down Expand Up @@ -675,6 +676,16 @@ enum ModelOverridableEnable {
OVERRIDE_ON
};

// List of modes available for RGB leds
enum FunctionRgbLedsParams {
FUNC_RGBLEDS_LUA,
FUNC_RGBLEDS_WHITE,
FUNC_RGBLEDS_BLUE,
FUNC_RGBLEDS_RED,
FUNC_RGBLEDS_YELLOW,
FUNC_RGBLEDS_GREEN,
FUNC_RGBLEDS_MAX SKIP = FUNC_RGBLEDS_GREEN
};
#define SELECTED_THEME_NAME_LEN 26

#endif // _DATACONSTANTS_H_
44 changes: 44 additions & 0 deletions radio/src/functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "opentx.h"
#include "switches.h"
#include "boards/generic_stm32/rgb_leds.h"

#if defined(COLORLCD)
void setRequestedMainView(uint8_t view);
Expand Down Expand Up @@ -411,6 +412,47 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext
}
break;

#if defined(LED_STRIP_GPIO)
case FUNC_RGB_LED:
newActiveFunctions |= (1u << FUNCTION_RGBLED);

switch (CFN_PARAM(cfn)) {
case FUNC_RGBLEDS_LUA:
// color values are set using LUA
break;

case FUNC_RGBLEDS_WHITE:
for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
rgbSetLedColor(i, 50, 50, 50);
}
break;

case FUNC_RGBLEDS_BLUE:
for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
rgbSetLedColor(i, 0, 0, 50);
}
break;

case FUNC_RGBLEDS_RED:
for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
rgbSetLedColor(i, 50, 0, 0);
}
break;

case FUNC_RGBLEDS_YELLOW:
for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
rgbSetLedColor(i, 50, 50, 0);
}
break;

case FUNC_RGBLEDS_GREEN:
for (uint8_t i = 0; i < LED_STRIP_LENGTH; i++) {
rgbSetLedColor(i, 0, 50, 0);
}
break;
}
break;
#endif
#if defined(PXX2)
case FUNC_RACING_MODE:
if (isRacingModeEnabled()) {
Expand Down Expand Up @@ -531,6 +573,8 @@ const char* funcGetLabel(uint8_t func)
case FUNC_SET_SCREEN:
return STR_SF_SET_SCREEN;
#endif
case FUNC_RGB_LED:
return STR_SF_RGBLEDS;
#if defined(DEBUG)
case FUNC_TEST:
return STR_SF_TEST;
Expand Down
7 changes: 7 additions & 0 deletions radio/src/gui/128x64/model_special_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,13 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
INCDEC_ENABLE_CHECK(isSourceAvailable);
}
}
else if (func == FUNC_RGB_LED) {
val_max = FUNC_RGBLEDS_MAX;
lcdDrawTextAtIndex(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, STR_FUNCRGBLEDS, val_displayed, attr);
if (active) {
CFN_PARAM(cfn) = CHECK_INCDEC_PARAM(event, val_displayed, val_min, val_max);
}
}
#if defined(SDCARD)
else if (func == FUNC_LOGS) {
val_min = SD_LOGS_PERIOD_MIN;
Expand Down
5 changes: 5 additions & 0 deletions radio/src/gui/gui_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,7 @@ bool isAssignableFunctionAvailable(int function, CustomFunctionData * functions)
#endif
#if !defined(HAPTIC)
case FUNC_HAPTIC:
return false;
#endif
#if !defined(DANGEROUS_MODULE_FUNCTIONS)
case FUNC_RANGECHECK:
Expand All @@ -595,6 +596,10 @@ bool isAssignableFunctionAvailable(int function, CustomFunctionData * functions)
case FUNC_PLAY_SCRIPT:
return false;
#endif
#if !defined(LED_STRIP_GPIO)
case FUNC_RGB_LED:
return false;
#endif

default:
return true;
Expand Down
38 changes: 37 additions & 1 deletion radio/src/lua/api_general.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
#include "hal/rotary_encoder.h"
#include "switches.h"
#include "input_mapping.h"
#if defined(LED_STRIP_GPIO)
#include "boards/generic_stm32/rgb_leds.h"
#endif


#if defined(LIBOPENUI)
#include "libopenui.h"
Expand Down Expand Up @@ -2771,6 +2775,33 @@ static int luaGetTrainerStatus(lua_State * L)
return 1;
}

#if defined(LED_STRIP_GPIO) \
/*luadoc
@function setRgbLedColor(id, rvalue, bvalue, cvalue)
@param id: integer identifying a led in the led chain
@param rvalue: interger, value of red channel
@param gvalue: interger, value of green channel
@param bvalue: interger, value of blue channel
@status current Introduced in 2.9
*/

static int luaSetRgbLedColor(lua_State * L)
{
uint8_t id = luaL_checkunsigned(L, 1);
uint8_t r = luaL_checkunsigned(L, 2);
uint8_t g = luaL_checkunsigned(L, 3);
uint8_t b = luaL_checkunsigned(L, 4);

rgbSetLedColor(id, r, g, b);

return 1;
}
#endif

#define KEY_EVENTS(xxx, yyy) \
{ "EVT_"#xxx"_FIRST", LRO_NUMVAL(EVT_KEY_FIRST(yyy)) }, \
Expand Down Expand Up @@ -2858,6 +2889,9 @@ LROT_BEGIN(etxlib, NULL, 0)
LROT_FUNCENTRY( getSourceIndex, luaGetSourceIndex )
LROT_FUNCENTRY( getSourceName, luaGetSourceName )
LROT_FUNCENTRY( sources, luaSources )
#if defined(LED_STRIP_GPIO)
LROT_FUNCENTRY(setRgbLedColor, luaSetRgbLedColor )
#endif
LROT_END(etxlib, NULL, 0)

LROT_BEGIN(etxcst, NULL, 0)
Expand Down Expand Up @@ -3194,7 +3228,9 @@ LROT_BEGIN(etxcst, NULL, 0)
LROT_NUMENTRY( PLAY_NOW, PLAY_NOW )
LROT_NUMENTRY( PLAY_BACKGROUND, PLAY_BACKGROUND )
LROT_NUMENTRY( TIMEHOUR, TIMEHOUR )

#if defined(LED_STRIP_GPIO)
LROT_NUMENTRY( LED_STRIP_LENGTH, LED_STRIP_LENGTH )
#endif
LROT_NUMENTRY( UNIT_RAW, UNIT_RAW )
LROT_NUMENTRY( UNIT_VOLTS, UNIT_VOLTS )
LROT_NUMENTRY( UNIT_AMPS, UNIT_AMPS )
Expand Down
9 changes: 9 additions & 0 deletions radio/src/opentx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@
* GNU General Public License for more details.
*/

#if !defined(SIMU)
#include "stm32_ws2812.h"
#include "boards/generic_stm32/rgb_leds.h"
#endif

#include "opentx.h"
#include "io/frsky_firmware_update.h"
#include "hal/adc_driver.h"
Expand Down Expand Up @@ -1610,6 +1615,10 @@ void opentxInit()

resetBacklightTimeout();

#if defined(LED_STRIP_GPIO) && !defined(SIMU)
rgbLedStart();
#endif

pulsesStart();
WDG_ENABLE(WDG_DURATION);
}
Expand Down
3 changes: 3 additions & 0 deletions radio/src/opentx.h
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,9 @@ enum FunctionsActive {
#if defined(HARDWARE_TOUCH)
FUNCTION_DISABLE_TOUCH,
#endif
#if defined(LED_STRIP_GPIO)
FUNCTION_RGBLED,
#endif
};

#define VARIO_FREQUENCY_ZERO 700/*Hz*/
Expand Down
Loading

0 comments on commit 6f21389

Please sign in to comment.