mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-06-01 12:57:27 +08:00
committed by
GitHub
parent
17b185d4b2
commit
208c37bc98
@@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE module SYSTEM "module.dtd">
|
||||||
|
|
||||||
|
<module name="light_scheduler" dir="light">
|
||||||
|
<doc>
|
||||||
|
<description>
|
||||||
|
Basic light scheduler using WS2812 driver
|
||||||
|
|
||||||
|
WS2812 are small RGB leds controlled with a 1-wire protocol.
|
||||||
|
This module is an example of controlling several leds with the color changing continuously.
|
||||||
|
Implementation for ChibiOS using DMA.
|
||||||
|
</description>
|
||||||
|
<define name="WS2812_NB_LEDS" value="8" description="Number of leds"/>
|
||||||
|
</doc>
|
||||||
|
<header>
|
||||||
|
<file name="light_scheduler.h"/>
|
||||||
|
</header>
|
||||||
|
<init fun="light_scheduler_init()"/>
|
||||||
|
<periodic fun="light_scheduler_periodic()" freq="8"/>
|
||||||
|
<makefile target="ap">
|
||||||
|
<file name="light_scheduler.c"/>
|
||||||
|
<file_arch name="light_ws2812_arch.c"/>
|
||||||
|
<file_arch name="hal_stm32_dma.c" dir="mcu_periph" cond="ifeq ($(RTOS),chibios)"/>
|
||||||
|
<define name="STM32_PWM_USE_TIM1" value="TRUE" cond="ifeq ($(RTOS),chibios)"/>
|
||||||
|
</makefile>
|
||||||
|
</module>
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Xavier Paris <xavier.paris@enac.fr>
|
||||||
|
*
|
||||||
|
* This file is part of paparazzi
|
||||||
|
*
|
||||||
|
* paparazzi is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* paparazzi 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with paparazzi; see the file COPYING. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file light_ws2812i_arch.c
|
||||||
|
* @brief WS2812 driver based on ChibiOS
|
||||||
|
*
|
||||||
|
* @author Xavier Paris
|
||||||
|
* @maintainer Gautier Hattenberger <gautier.hattenberger@enac.fr>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/****************************************************************************************
|
||||||
|
https://github.com/joewa/WS2812-LED-Driver_ChibiOS/
|
||||||
|
****************************************************************************************/
|
||||||
|
|
||||||
|
#include <hal.h>
|
||||||
|
#include "modules/light/light_ws2812_arch.h"
|
||||||
|
#include "mcu_periph/hal_stm32_dma.h"
|
||||||
|
|
||||||
|
#define WS2812_SERVO_HZ 800000
|
||||||
|
#define WS2812_PWM_FREQUENCY (STM32_SYSCLK/2)
|
||||||
|
|
||||||
|
#define WS2812_DUTYCYCLE_0 (WS2812_PWM_FREQUENCY/(1000000000/350))
|
||||||
|
#define WS2812_DUTYCYCLE_1 (WS2812_PWM_FREQUENCY/(1000000000/800))
|
||||||
|
|
||||||
|
#define WS2812_RESET_BIT_N (50)
|
||||||
|
#define WS2812_COLOR_BIT_N (WS2812_NB_LEDS * 24)
|
||||||
|
#define WS2812_BIT_N (WS2812_COLOR_BIT_N + WS2812_RESET_BIT_N)
|
||||||
|
|
||||||
|
// Use driver 1 by default
|
||||||
|
#ifndef WS2812_CFG_DEF
|
||||||
|
#define WS2812_CFG_DEF WS2812D1_CFG_DEF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define WS2812_DMA_IRQ_PRIORITY 6
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configuration structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t dma_stream;
|
||||||
|
uint8_t dma_channel;
|
||||||
|
uint8_t pwm_channel;
|
||||||
|
uint8_t dma_priority;
|
||||||
|
PWMDriver *pwmp;
|
||||||
|
} WS2812Config;
|
||||||
|
|
||||||
|
// Config from board conf
|
||||||
|
static WS2812Config WS2812CFG = WS2812_CFG_DEF;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Driver structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
const WS2812Config *config;
|
||||||
|
DMAConfig dma_conf;
|
||||||
|
PWMConfig pwm_conf;
|
||||||
|
DMADriver dmap;
|
||||||
|
uint32_t buf[WS2812_BIT_N + 1];
|
||||||
|
} WS2812Driver;
|
||||||
|
|
||||||
|
// Driver
|
||||||
|
static WS2812Driver WS2812D;
|
||||||
|
|
||||||
|
void light_ws2812_arch_init(void)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
for (i = 0; i < WS2812_COLOR_BIT_N; i++) {
|
||||||
|
WS2812D.buf[i] = WS2812_DUTYCYCLE_0;
|
||||||
|
}
|
||||||
|
for (i = 0; i < WS2812_RESET_BIT_N; i++) {
|
||||||
|
WS2812D.buf[i + WS2812_COLOR_BIT_N] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WS2812D.config = &WS2812CFG;
|
||||||
|
|
||||||
|
WS2812D.dma_conf = (DMAConfig) {
|
||||||
|
.stream = WS2812CFG.dma_stream,
|
||||||
|
.channel = WS2812CFG.dma_channel,
|
||||||
|
.dma_priority = WS2812CFG.dma_priority,
|
||||||
|
.irq_priority = WS2812_DMA_IRQ_PRIORITY,
|
||||||
|
.direction = DMA_DIR_M2P,
|
||||||
|
.psize = 4,
|
||||||
|
.msize = 4,
|
||||||
|
.inc_peripheral_addr = false,
|
||||||
|
.inc_memory_addr = true,
|
||||||
|
.circular = true,
|
||||||
|
.error_cb = NULL,
|
||||||
|
.end_cb = NULL,
|
||||||
|
.pburst = 0,
|
||||||
|
.mburst = 0,
|
||||||
|
.fifo = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
WS2812D.pwm_conf = (PWMConfig) {
|
||||||
|
.frequency = WS2812_PWM_FREQUENCY,
|
||||||
|
.period = WS2812_PWM_FREQUENCY / WS2812_SERVO_HZ,
|
||||||
|
.callback = NULL,
|
||||||
|
.channels = {
|
||||||
|
{
|
||||||
|
.mode = PWM_OUTPUT_DISABLED,
|
||||||
|
.callback = NULL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.mode = PWM_OUTPUT_DISABLED,
|
||||||
|
.callback = NULL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.mode = PWM_OUTPUT_DISABLED,
|
||||||
|
.callback = NULL
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.mode = PWM_OUTPUT_DISABLED,
|
||||||
|
.callback = NULL
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.cr2 = 0,
|
||||||
|
.dier = STM32_TIM_DIER_UDE
|
||||||
|
};
|
||||||
|
|
||||||
|
dmaObjectInit(&WS2812D.dmap);
|
||||||
|
dmaStart(&WS2812D.dmap, &WS2812D.dma_conf);
|
||||||
|
dmaStartTransfert(&WS2812D.dmap, &(WS2812D.config->pwmp->tim->CCR[WS2812D.config->pwm_channel]), &WS2812D.buf, WS2812_BIT_N);
|
||||||
|
|
||||||
|
WS2812D.pwm_conf.channels[WS2812D.config->pwm_channel].mode = PWM_OUTPUT_ACTIVE_HIGH;
|
||||||
|
pwmStart(WS2812D.config->pwmp, &WS2812D.pwm_conf);
|
||||||
|
pwmEnableChannel(WS2812D.config->pwmp, WS2812D.config->pwm_channel, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define WS2812_BIT(led, byte, bit) (24*(led) + 8*(byte) + (7 - (bit)))
|
||||||
|
#define WS2812_RED_BIT(led, bit) WS2812_BIT((led), 1, (bit))
|
||||||
|
#define WS2812_GREEN_BIT(led, bit) WS2812_BIT((led), 0, (bit))
|
||||||
|
#define WS2812_BLUE_BIT(led, bit) WS2812_BIT((led), 2, (bit))
|
||||||
|
|
||||||
|
void light_ws2812_arch_set(uint32_t led_number, uint8_t r, uint8_t g, uint8_t b)
|
||||||
|
{
|
||||||
|
uint32_t bit;
|
||||||
|
if (led_number < WS2812_NB_LEDS) {
|
||||||
|
for (bit = 0; bit < 8; bit++) {
|
||||||
|
WS2812D.buf[WS2812_RED_BIT(led_number, bit)] = ((r >> bit) & 0x01) ? WS2812_DUTYCYCLE_1 : WS2812_DUTYCYCLE_0;
|
||||||
|
WS2812D.buf[WS2812_GREEN_BIT(led_number, bit)] = ((g >> bit) & 0x01) ? WS2812_DUTYCYCLE_1 : WS2812_DUTYCYCLE_0;
|
||||||
|
WS2812D.buf[WS2812_BLUE_BIT(led_number, bit)] = ((b >> bit) & 0x01) ? WS2812_DUTYCYCLE_1 : WS2812_DUTYCYCLE_0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Xavier Paris <xavier.paris@enac.fr>
|
||||||
|
*
|
||||||
|
* This file is part of paparazzi
|
||||||
|
*
|
||||||
|
* paparazzi is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* paparazzi 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with paparazzi; see the file COPYING. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file arch/chibios/modules/light/light_ws2812_arch.h
|
||||||
|
* @brief ws2812 driver based on ChibiOS
|
||||||
|
*
|
||||||
|
* @author Xavier Paris
|
||||||
|
* @maintainer Gautier Hattenberger <gautier.hattenberger@enac.fr>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "std.h"
|
||||||
|
|
||||||
|
/** Number of LEDs
|
||||||
|
*/
|
||||||
|
#ifndef WS2812_NB_LEDS
|
||||||
|
#define WS2812_NB_LEDS 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void light_ws2812_arch_init(void);
|
||||||
|
|
||||||
|
/** set color RGB color of one led
|
||||||
|
*/
|
||||||
|
extern void light_ws2812_arch_set(uint32_t led_number, uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
|
||||||
@@ -576,6 +576,16 @@
|
|||||||
#define SDLOG_USB_VBUS_PIN GPIO9
|
#define SDLOG_USB_VBUS_PIN GPIO9
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For WS2812
|
||||||
|
*/
|
||||||
|
#define WS2812D1_CFG_DEF { \
|
||||||
|
.dma_stream = STM32_PWM1_UP_DMA_STREAM, \
|
||||||
|
.dma_channel = STM32_PWM1_UP_DMA_CHANNEL, \
|
||||||
|
.dma_priority = STM32_PWM1_UP_DMA_PRIORITY, \
|
||||||
|
.pwm_channel = 0, \
|
||||||
|
.pwmp = &PWMD1 \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -223,7 +223,9 @@
|
|||||||
* PWM driver system settings.
|
* PWM driver system settings.
|
||||||
*/
|
*/
|
||||||
#define STM32_PWM_USE_ADVANCED FALSE
|
#define STM32_PWM_USE_ADVANCED FALSE
|
||||||
#define STM32_PWM_USE_TIM1 FALSE
|
#ifndef STM32_PWM_USE_TIM1
|
||||||
|
#define STM32_PWM_USE_TIM1 FALSE // enable for WS2812
|
||||||
|
#endif
|
||||||
#ifndef STM32_PWM_USE_TIM2
|
#ifndef STM32_PWM_USE_TIM2
|
||||||
#define STM32_PWM_USE_TIM2 TRUE
|
#define STM32_PWM_USE_TIM2 TRUE
|
||||||
#endif
|
#endif
|
||||||
@@ -242,6 +244,11 @@
|
|||||||
#define STM32_PWM_TIM8_IRQ_PRIORITY 7
|
#define STM32_PWM_TIM8_IRQ_PRIORITY 7
|
||||||
#define STM32_PWM_TIM9_IRQ_PRIORITY 7
|
#define STM32_PWM_TIM9_IRQ_PRIORITY 7
|
||||||
|
|
||||||
|
#define STM32_PWM1_UP_DMA_STREAM STM32_DMA_STREAM_ID(2, 5) // incompatible with SPI1_TX
|
||||||
|
#define STM32_PWM1_UP_DMA_CHANNEL 6
|
||||||
|
#define STM32_PWM1_UP_DMA_IRQ_PRIORITY 6
|
||||||
|
#define STM32_PWM1_UP_DMA_PRIORITY 2
|
||||||
|
|
||||||
#define STM32_PWM2_UP_DMA_STREAM STM32_DMA_STREAM_ID(1, 1)
|
#define STM32_PWM2_UP_DMA_STREAM STM32_DMA_STREAM_ID(1, 1)
|
||||||
#define STM32_PWM2_UP_DMA_CHANNEL 3
|
#define STM32_PWM2_UP_DMA_CHANNEL 3
|
||||||
#define STM32_PWM2_UP_DMA_IRQ_PRIORITY 6
|
#define STM32_PWM2_UP_DMA_IRQ_PRIORITY 6
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Xavier Paris
|
||||||
|
*
|
||||||
|
* This file is part of paparazzi.
|
||||||
|
*
|
||||||
|
* paparazzi is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* paparazzi 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with paparazzi; see the file COPYING. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file modules/light/light_scheduler.c
|
||||||
|
* @brief basic LED scheduler based on WS2812 RGB led driver
|
||||||
|
*
|
||||||
|
* @author Xavier Paris
|
||||||
|
* @maintainer Gautier Hattenberger <gautier.hattenberger@enac.fr>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "modules/light/light_scheduler.h"
|
||||||
|
#include "modules/light/light_ws2812_arch.h"
|
||||||
|
|
||||||
|
static uint32_t s = 0;
|
||||||
|
|
||||||
|
void light_scheduler_init(void)
|
||||||
|
{
|
||||||
|
light_ws2812_arch_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void light_scheduler_periodic(void)
|
||||||
|
{
|
||||||
|
uint32_t n, s0;
|
||||||
|
for (n = 0; n < WS2812_NB_LEDS; n++) {
|
||||||
|
s0 = s + 10 * n;
|
||||||
|
light_ws2812_arch_set(n, s0 % 255, (s0 + 85) % 255, (s0 + 170) % 255);
|
||||||
|
}
|
||||||
|
s += 10;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2019 Xavier Paris
|
||||||
|
*
|
||||||
|
* This file is part of paparazzi.
|
||||||
|
*
|
||||||
|
* paparazzi is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* paparazzi 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with paparazzi; see the file COPYING. If not, see
|
||||||
|
* <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file modules/light/light_scheduler.h
|
||||||
|
* @brief basic LED scheduler based on WS2812 RGB led driver
|
||||||
|
*
|
||||||
|
* @author Xavier Paris
|
||||||
|
* @maintainer Gautier Hattenberger <gautier.hattenberger@enac.fr>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LIGHT_SCHEDULER_H
|
||||||
|
#define LIGHT_SCHEDULER_H
|
||||||
|
|
||||||
|
extern void light_scheduler_init(void);
|
||||||
|
extern void light_scheduler_periodic(void);
|
||||||
|
|
||||||
|
#endif /* LIGHT_SCHEDULER_H */
|
||||||
Reference in New Issue
Block a user