Paparazzi UAS  v5.18.0_stable
Paparazzi is a free software Unmanned Aircraft System.
light_ws2812_arch.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2019 Xavier Paris <xavier.paris@enac.fr>
3  *
4  * This file is part of paparazzi
5  *
6  * paparazzi is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * paparazzi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with paparazzi; see the file COPYING. If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
29 /****************************************************************************************
30 https://github.com/joewa/WS2812-LED-Driver_ChibiOS/
31 ****************************************************************************************/
32 
33 #include <hal.h>
36 #include "mcu_periph/gpio.h"
37 
38 #include BOARD_CONFIG
39 
40 #define WS2812_SERVO_HZ 800000
41 #define WS2812_PWM_FREQUENCY (STM32_SYSCLK/2)
42 
43 #define WS2812_DUTYCYCLE_0 (WS2812_PWM_FREQUENCY/(1000000000/350))
44 #define WS2812_DUTYCYCLE_1 (WS2812_PWM_FREQUENCY/(1000000000/800))
45 
46 #define WS2812_RESET_BIT_N (50)
47 #define WS2812_COLOR_BIT_N (WS2812_NB_LEDS * 24)
48 #define WS2812_BIT_N (WS2812_COLOR_BIT_N + WS2812_RESET_BIT_N)
49 
50 // Use driver 1 by default
51 #ifndef WS2812_CFG_DEF
52 #define WS2812_GPIO WS2812D1_GPIO
53 #define WS2812_PIN WS2812D1_PIN
54 #define WS2812_AF WS2812D1_AF
55 #define WS2812_CFG_DEF WS2812D1_CFG_DEF
56 #endif
57 
58 #define WS2812_DMA_IRQ_PRIORITY 6
59 
63 typedef struct {
68  PWMDriver *pwmp;
69 } WS2812Config;
70 
71 // Config from board conf
73 
77 typedef struct {
80  PWMConfig pwm_conf;
83 } WS2812Driver;
84 
85 // Driver
87 
89 {
90 
92 
93  uint32_t i;
94  for (i = 0; i < WS2812_COLOR_BIT_N; i++) {
96  }
97  for (i = 0; i < WS2812_RESET_BIT_N; i++) {
99  }
100 
102 
105  .channel = WS2812CFG.dma_channel,
106  .dma_priority = WS2812CFG.dma_priority,
107  .irq_priority = WS2812_DMA_IRQ_PRIORITY,
108  .direction = DMA_DIR_M2P,
109  .psize = 4,
110  .msize = 4,
111  .inc_peripheral_addr = false,
112  .inc_memory_addr = true,
113  .circular = true,
114  .error_cb = NULL,
115  .end_cb = NULL,
116  .pburst = 0,
117  .mburst = 0,
118  .fifo = 0
119  };
120 
121  WS2812D.pwm_conf = (PWMConfig) {
122  .frequency = WS2812_PWM_FREQUENCY,
124  .callback = NULL,
125  .channels = {
126  {
127  .mode = PWM_OUTPUT_DISABLED,
128  .callback = NULL
129  },
130  {
131  .mode = PWM_OUTPUT_DISABLED,
132  .callback = NULL
133  },
134  {
135  .mode = PWM_OUTPUT_DISABLED,
136  .callback = NULL
137  },
138  {
139  .mode = PWM_OUTPUT_DISABLED,
140  .callback = NULL
141  },
142  },
143  .cr2 = 0,
144  .dier = STM32_TIM_DIER_UDE
145  };
146 
150 
151  WS2812D.pwm_conf.channels[WS2812D.config->pwm_channel].mode = PWM_OUTPUT_ACTIVE_HIGH;
152  pwmStart(WS2812D.config->pwmp, &WS2812D.pwm_conf);
153  pwmEnableChannel(WS2812D.config->pwmp, WS2812D.config->pwm_channel, 0);
154 }
155 
156 #define WS2812_BIT(led, byte, bit) (24*(led) + 8*(byte) + (7 - (bit)))
157 #define WS2812_RED_BIT(led, bit) WS2812_BIT((led), 1, (bit))
158 #define WS2812_GREEN_BIT(led, bit) WS2812_BIT((led), 0, (bit))
159 #define WS2812_BLUE_BIT(led, bit) WS2812_BIT((led), 2, (bit))
160 
162 {
163  uint32_t bit;
164  if (led_number < WS2812_NB_LEDS) {
165  for (bit = 0; bit < 8; bit++) {
166  WS2812D.buf[WS2812_RED_BIT(led_number, bit)] = ((r >> bit) & 0x01) ? WS2812_DUTYCYCLE_1 : WS2812_DUTYCYCLE_0;
167  WS2812D.buf[WS2812_GREEN_BIT(led_number, bit)] = ((g >> bit) & 0x01) ? WS2812_DUTYCYCLE_1 : WS2812_DUTYCYCLE_0;
168  WS2812D.buf[WS2812_BLUE_BIT(led_number, bit)] = ((b >> bit) & 0x01) ? WS2812_DUTYCYCLE_1 : WS2812_DUTYCYCLE_0;
169  }
170  }
171 }
dmaStartTransfert
bool dmaStartTransfert(DMADriver *dmap, volatile void *periphp, void *mem0p, const size_t size)
Starts a DMA transaction.
Definition: hal_stm32_dma.c:149
DMA_DIR_M2P
@ DMA_DIR_M2P
MEMORY to PERIPHERAL
Definition: hal_stm32_dma.h:89
WS2812D
static WS2812Driver WS2812D
Definition: light_ws2812_arch.c:86
WS2812_SERVO_HZ
#define WS2812_SERVO_HZ
Definition: light_ws2812_arch.c:40
WS2812_DUTYCYCLE_0
#define WS2812_DUTYCYCLE_0
Definition: light_ws2812_arch.c:43
WS2812_BIT_N
#define WS2812_BIT_N
Definition: light_ws2812_arch.c:48
WS2812_COLOR_BIT_N
#define WS2812_COLOR_BIT_N
Definition: light_ws2812_arch.c:47
b
float b
Definition: wedgebug.c:202
WS2812Driver::dma_conf
DMAConfig dma_conf
Definition: light_ws2812_arch.c:79
WS2812_NB_LEDS
#define WS2812_NB_LEDS
Number of LEDs.
Definition: light_ws2812_arch.h:36
uint32_t
unsigned long uint32_t
Definition: types.h:18
WS2812Config
Configuration structure.
Definition: light_ws2812_arch.c:63
WS2812_BLUE_BIT
#define WS2812_BLUE_BIT(led, bit)
Definition: light_ws2812_arch.c:159
WS2812_RESET_BIT_N
#define WS2812_RESET_BIT_N
Definition: light_ws2812_arch.c:46
WS2812Driver
Driver structure.
Definition: light_ws2812_arch.c:77
WS2812_GPIO
#define WS2812_GPIO
Definition: light_ws2812_arch.c:52
WS2812_PIN
#define WS2812_PIN
Definition: light_ws2812_arch.c:53
WS2812Config::pwmp
PWMDriver * pwmp
Definition: light_ws2812_arch.c:68
dmaObjectInit
void dmaObjectInit(DMADriver *dmap)
Definition: hal_stm32_dma.c:56
WS2812Driver::config
const WS2812Config * config
Definition: light_ws2812_arch.c:78
WS2812_CFG_DEF
#define WS2812_CFG_DEF
Definition: light_ws2812_arch.c:55
uint8_t
unsigned char uint8_t
Definition: types.h:14
hal_stm32_dma.h
STM32 DMA subsystem driver header.
WS2812_DMA_IRQ_PRIORITY
#define WS2812_DMA_IRQ_PRIORITY
Definition: light_ws2812_arch.c:58
WS2812Driver::dmap
DMADriver dmap
Definition: light_ws2812_arch.c:81
gpio_setup_pin_af
void gpio_setup_pin_af(ioportid_t port, uint16_t pin, uint8_t af, bool is_output)
Setup a gpio for input or output with alternate function.
Definition: gpio_arch.c:61
light_ws2812_arch_set
void light_ws2812_arch_set(uint32_t led_number, uint8_t r, uint8_t g, uint8_t b)
set color RGB color of one led
Definition: light_ws2812_arch.c:161
WS2812_RED_BIT
#define WS2812_RED_BIT(led, bit)
Definition: light_ws2812_arch.c:157
WS2812Driver::pwm_conf
PWMConfig pwm_conf
Definition: light_ws2812_arch.c:80
gpio.h
light_ws2812_arch_init
void light_ws2812_arch_init(void)
Definition: light_ws2812_arch.c:88
WS2812_GREEN_BIT
#define WS2812_GREEN_BIT(led, bit)
Definition: light_ws2812_arch.c:158
DMADriver
Structure representing a DMA driver.
Definition: hal_stm32_dma.h:365
WS2812Driver::buf
uint32_t buf[WS2812_BIT_N+1]
Definition: light_ws2812_arch.c:82
WS2812_DUTYCYCLE_1
#define WS2812_DUTYCYCLE_1
Definition: light_ws2812_arch.c:44
WS2812Config::pwm_channel
uint8_t pwm_channel
Definition: light_ws2812_arch.c:66
WS2812_PWM_FREQUENCY
#define WS2812_PWM_FREQUENCY
Definition: light_ws2812_arch.c:41
WS2812Config::dma_priority
uint8_t dma_priority
Definition: light_ws2812_arch.c:67
DMAConfig::stream
uint32_t stream
stream associated with transaction
Definition: hal_stm32_dma.h:246
dmaStart
bool dmaStart(DMADriver *dmap, const DMAConfig *cfg)
Configures and activates the DMA peripheral.
Definition: hal_stm32_dma.c:92
DMAConfig
DMA stream configuration structure.
Definition: hal_stm32_dma.h:241
WS2812CFG
static WS2812Config WS2812CFG
Definition: light_ws2812_arch.c:72
light_ws2812_arch.h
ws2812 driver based on ChibiOS
WS2812Config::dma_channel
uint8_t dma_channel
Definition: light_ws2812_arch.c:65
WS2812Config::dma_stream
uint32_t dma_stream
Definition: light_ws2812_arch.c:64
WS2812_AF
#define WS2812_AF
Definition: light_ws2812_arch.c:54