mirror of https://github.com/rusefi/bldc.git
Removed outdated LED-support
This commit is contained in:
parent
67650d0dac
commit
77af43935a
2
Makefile
2
Makefile
|
@ -146,8 +146,6 @@ CSRC = $(STARTUPSRC) \
|
|||
commands.c \
|
||||
timeout.c \
|
||||
comm_can.c \
|
||||
ws2811.c \
|
||||
led_external.c \
|
||||
encoder.c \
|
||||
flash_helper.c \
|
||||
mc_interface.c \
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "timeout.h"
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "led_external.h"
|
||||
#include "datatypes.h"
|
||||
#include "comm_can.h"
|
||||
#include "terminal.h"
|
||||
|
@ -241,7 +240,6 @@ static THD_FUNCTION(output_thread, arg) {
|
|||
const float max_current_diff = mcconf->l_current_max * mcconf->l_current_max_scale * 0.2;
|
||||
|
||||
if (chuck_d.bt_c && chuck_d.bt_z) {
|
||||
led_external_set_state(LED_EXT_BATT);
|
||||
was_pid = false;
|
||||
continue;
|
||||
}
|
||||
|
@ -265,32 +263,10 @@ static THD_FUNCTION(output_thread, arg) {
|
|||
|
||||
was_z = chuck_d.bt_z;
|
||||
|
||||
led_external_set_reversed(is_reverse);
|
||||
|
||||
float out_val = app_nunchuk_get_decoded_chuk();
|
||||
utils_deadband(&out_val, config.hyst, 1.0);
|
||||
out_val = utils_throttle_curve(out_val, config.throttle_exp, config.throttle_exp_brake, config.throttle_exp_mode);
|
||||
|
||||
// LEDs
|
||||
float x_axis = ((float)chuck_d.js_x - 128.0) / 128.0;
|
||||
if (out_val < -0.001) {
|
||||
if (x_axis < -0.4) {
|
||||
led_external_set_state(LED_EXT_BRAKE_TURN_LEFT);
|
||||
} else if (x_axis > 0.4) {
|
||||
led_external_set_state(LED_EXT_BRAKE_TURN_RIGHT);
|
||||
} else {
|
||||
led_external_set_state(LED_EXT_BRAKE);
|
||||
}
|
||||
} else {
|
||||
if (x_axis < -0.4) {
|
||||
led_external_set_state(LED_EXT_TURN_LEFT);
|
||||
} else if (x_axis > 0.4) {
|
||||
led_external_set_state(LED_EXT_TURN_RIGHT);
|
||||
} else {
|
||||
led_external_set_state(LED_EXT_NORMAL);
|
||||
}
|
||||
}
|
||||
|
||||
if (chuck_d.bt_c) {
|
||||
static float pid_rpm = 0.0;
|
||||
|
||||
|
|
|
@ -261,20 +261,6 @@
|
|||
#define LED_EXT_BATT_LOW 28.0
|
||||
#define LED_EXT_BATT_HIGH 33.0
|
||||
|
||||
/*
|
||||
* Output WS2811 signal on the HALL1 pin. Notice that hall sensors can't be used
|
||||
* at the same time.
|
||||
*/
|
||||
#ifndef WS2811_ENABLE
|
||||
#define WS2811_ENABLE 0
|
||||
#endif
|
||||
#define WS2811_CLK_HZ 800000
|
||||
#define WS2811_LED_NUM 28
|
||||
#define WS2811_USE_CH2 1 // 0: CH1 (PB6) 1: CH2 (PB7)
|
||||
#ifndef WS2811_TEST
|
||||
#define WS2811_TEST 0 // Show a test pattern
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Servo output driver
|
||||
*/
|
||||
|
|
17
datatypes.h
17
datatypes.h
|
@ -974,6 +974,11 @@ typedef enum {
|
|||
COMM_CUSTOM_HW_DATA,
|
||||
COMM_QMLUI_ERASE,
|
||||
COMM_QMLUI_WRITE,
|
||||
|
||||
// IO Board
|
||||
COMM_IO_BOARD_GET_ALL,
|
||||
COMM_IO_BOARD_SET_PWM,
|
||||
COMM_IO_BOARD_SET_DIGITAL,
|
||||
} COMM_PACKET_ID;
|
||||
|
||||
// CAN commands
|
||||
|
@ -1055,18 +1060,6 @@ typedef struct {
|
|||
int drv8301_faults;
|
||||
} fault_data;
|
||||
|
||||
// External LED state
|
||||
typedef enum {
|
||||
LED_EXT_OFF = 0,
|
||||
LED_EXT_NORMAL,
|
||||
LED_EXT_BRAKE,
|
||||
LED_EXT_TURN_LEFT,
|
||||
LED_EXT_TURN_RIGHT,
|
||||
LED_EXT_BRAKE_TURN_LEFT,
|
||||
LED_EXT_BRAKE_TURN_RIGHT,
|
||||
LED_EXT_BATT
|
||||
} LED_EXT_STATE;
|
||||
|
||||
typedef struct {
|
||||
int js_x;
|
||||
int js_y;
|
||||
|
|
219
led_external.c
219
led_external.c
|
@ -1,219 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 Benjamin Vedder benjamin@vedder.se
|
||||
|
||||
This file is part of the VESC firmware.
|
||||
|
||||
The VESC firmware 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
The VESC firmware 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "led_external.h"
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
#include "ws2811.h"
|
||||
#include "mc_interface.h"
|
||||
#include "utils.h"
|
||||
#include "hw.h"
|
||||
|
||||
// Macros
|
||||
#define HAS_FAULT() (mc_interface_get_fault() != FAULT_CODE_NONE)
|
||||
|
||||
// Private variables
|
||||
static THD_WORKING_AREA(led_thread_wa, 1024);
|
||||
static volatile LED_EXT_STATE state;
|
||||
static volatile bool reverse_leds;
|
||||
|
||||
// Private function prototypes
|
||||
static THD_FUNCTION(led_thread, arg);
|
||||
static uint32_t scale_color(uint32_t color, float scale);
|
||||
static void wait_for_state_change(void);
|
||||
static void set_led_wrapper(int led, uint32_t color);
|
||||
|
||||
void led_external_init(void) {
|
||||
reverse_leds = false;
|
||||
state = LED_EXT_OFF;
|
||||
chThdCreateStatic(led_thread_wa, sizeof(led_thread_wa), LOWPRIO, led_thread, NULL);
|
||||
}
|
||||
|
||||
void led_external_set_state(LED_EXT_STATE new_state) {
|
||||
state = new_state;
|
||||
}
|
||||
|
||||
void led_external_set_reversed(bool newstate) {
|
||||
reverse_leds = newstate;
|
||||
}
|
||||
|
||||
static THD_FUNCTION(led_thread, arg) {
|
||||
(void) arg;
|
||||
chRegSetThreadName("LEDs External");
|
||||
|
||||
float batt_level = 0.0;
|
||||
|
||||
for(;;) {
|
||||
mc_fault_code fault = mc_interface_get_fault();
|
||||
if (fault != FAULT_CODE_NONE) {
|
||||
ws2811_set_all(COLOR_BLACK);
|
||||
for (int i = 0;i < (int)fault;i++) {
|
||||
set_led_wrapper(i, COLOR_RED);
|
||||
chThdSleepMilliseconds(200);
|
||||
}
|
||||
|
||||
chThdSleepMilliseconds(1000);
|
||||
|
||||
float scale = 1.0;
|
||||
for (int i = 0;i < 50;i++) {
|
||||
scale -= 0.02;
|
||||
uint32_t color = scale_color(COLOR_RED, scale);
|
||||
for (int j = 0;j < (int)fault;j++) {
|
||||
set_led_wrapper(j, color);
|
||||
}
|
||||
chThdSleepMilliseconds(10);
|
||||
}
|
||||
} else {
|
||||
uint32_t red_weak = scale_color(COLOR_RED, 0.5);
|
||||
LED_EXT_STATE state_last = state;
|
||||
bool rev_last = reverse_leds;
|
||||
|
||||
switch (state) {
|
||||
case LED_EXT_OFF:
|
||||
ws2811_set_all(COLOR_BLACK);
|
||||
wait_for_state_change();
|
||||
break;
|
||||
|
||||
case LED_EXT_NORMAL:
|
||||
for (int i = 0;i < WS2811_LED_NUM / 2;i++) {
|
||||
set_led_wrapper(i, red_weak);
|
||||
set_led_wrapper(i + WS2811_LED_NUM / 2, COLOR_WHITE);
|
||||
}
|
||||
wait_for_state_change();
|
||||
break;
|
||||
|
||||
case LED_EXT_BRAKE:
|
||||
for (int i = 0;i < WS2811_LED_NUM / 2;i++) {
|
||||
set_led_wrapper(i, COLOR_RED);
|
||||
set_led_wrapper(i + WS2811_LED_NUM / 2, COLOR_WHITE);
|
||||
}
|
||||
wait_for_state_change();
|
||||
break;
|
||||
|
||||
case LED_EXT_TURN_LEFT:
|
||||
case LED_EXT_BRAKE_TURN_LEFT:
|
||||
for (int i = 0;i < WS2811_LED_NUM / 2;i++) {
|
||||
if (state == LED_EXT_TURN_LEFT) {
|
||||
set_led_wrapper(i, red_weak);
|
||||
} else {
|
||||
set_led_wrapper(i, COLOR_RED);
|
||||
}
|
||||
set_led_wrapper(i + WS2811_LED_NUM / 2, COLOR_WHITE);
|
||||
}
|
||||
|
||||
while (state == state_last && rev_last == reverse_leds && !HAS_FAULT()) {
|
||||
if ((chVTGetSystemTime() / (CH_CFG_ST_FREQUENCY / 2)) % 2) {
|
||||
set_led_wrapper(WS2811_LED_NUM / 2 - 1, COLOR_ORANGE);
|
||||
set_led_wrapper(WS2811_LED_NUM / 2, COLOR_ORANGE);
|
||||
} else {
|
||||
set_led_wrapper(WS2811_LED_NUM / 2 - 1, COLOR_BLACK);
|
||||
set_led_wrapper(WS2811_LED_NUM / 2, COLOR_BLACK);
|
||||
}
|
||||
chThdSleepMilliseconds(10);
|
||||
}
|
||||
break;
|
||||
|
||||
case LED_EXT_TURN_RIGHT:
|
||||
case LED_EXT_BRAKE_TURN_RIGHT:
|
||||
for (int i = 0;i < WS2811_LED_NUM / 2;i++) {
|
||||
if (state == LED_EXT_TURN_RIGHT) {
|
||||
set_led_wrapper(i, red_weak);
|
||||
} else {
|
||||
set_led_wrapper(i, COLOR_RED);
|
||||
}
|
||||
set_led_wrapper(i + WS2811_LED_NUM / 2, COLOR_WHITE);
|
||||
}
|
||||
|
||||
while (state == state_last && rev_last == reverse_leds && !HAS_FAULT()) {
|
||||
if ((chVTGetSystemTime() / (CH_CFG_ST_FREQUENCY / 2)) % 2) {
|
||||
set_led_wrapper(0, COLOR_ORANGE);
|
||||
set_led_wrapper(WS2811_LED_NUM - 1, COLOR_ORANGE);
|
||||
} else {
|
||||
set_led_wrapper(0, COLOR_BLACK);
|
||||
set_led_wrapper(WS2811_LED_NUM - 1, COLOR_BLACK);
|
||||
}
|
||||
chThdSleepMilliseconds(10);
|
||||
}
|
||||
break;
|
||||
|
||||
case LED_EXT_BATT:
|
||||
while (state == state_last && rev_last == reverse_leds && !HAS_FAULT()) {
|
||||
batt_level = utils_map(GET_INPUT_VOLTAGE(), LED_EXT_BATT_LOW, LED_EXT_BATT_HIGH, 0.0, 1.0);
|
||||
for (int i = 0;i < WS2811_LED_NUM / 2;i++) {
|
||||
if (i < (WS2811_LED_NUM / 2) * batt_level) {
|
||||
if (i < (WS2811_LED_NUM / 2) / 3) {
|
||||
set_led_wrapper(i, COLOR_RED);
|
||||
set_led_wrapper(WS2811_LED_NUM - i - 1, COLOR_RED);
|
||||
} else if (i < (2 * (WS2811_LED_NUM / 2)) / 3) {
|
||||
set_led_wrapper(i, COLOR_YELLOW);
|
||||
set_led_wrapper(WS2811_LED_NUM - i - 1, COLOR_YELLOW);
|
||||
} else {
|
||||
set_led_wrapper(i, COLOR_GREEN);
|
||||
set_led_wrapper(WS2811_LED_NUM - i - 1, COLOR_GREEN);
|
||||
}
|
||||
} else {
|
||||
set_led_wrapper(i, COLOR_BLACK);
|
||||
set_led_wrapper(WS2811_LED_NUM - i - 1, COLOR_BLACK);
|
||||
}
|
||||
}
|
||||
chThdSleepMilliseconds(10);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
chThdSleepMilliseconds(10);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
chThdSleepMilliseconds(1);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t scale_color(uint32_t color, float scale) {
|
||||
uint32_t r = (color >> 16) & 0xFF;
|
||||
uint32_t g = (color >> 8) & 0xFF;
|
||||
uint32_t b = color & 0xFF;
|
||||
|
||||
r *= scale;
|
||||
g *= scale;
|
||||
b *= scale;
|
||||
|
||||
return (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
static void wait_for_state_change(void) {
|
||||
LED_EXT_STATE st = state;
|
||||
bool reversed = reverse_leds;
|
||||
while (state == st && reversed == reverse_leds && !HAS_FAULT()) {
|
||||
chThdSleepMilliseconds(10);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_led_wrapper(int led, uint32_t color) {
|
||||
if (reverse_leds) {
|
||||
if (led < WS2811_LED_NUM / 2) {
|
||||
ws2811_set_led_color(led + WS2811_LED_NUM / 2, color);
|
||||
} else {
|
||||
ws2811_set_led_color(led - WS2811_LED_NUM / 2, color);
|
||||
}
|
||||
} else {
|
||||
ws2811_set_led_color(led, color);
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 Benjamin Vedder benjamin@vedder.se
|
||||
|
||||
This file is part of the VESC firmware.
|
||||
|
||||
The VESC firmware 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
The VESC firmware 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LED_EXTERNAL_H_
|
||||
#define LED_EXTERNAL_H_
|
||||
|
||||
#include "datatypes.h"
|
||||
|
||||
// Functions
|
||||
void led_external_init(void);
|
||||
void led_external_set_state(LED_EXT_STATE new_state);
|
||||
void led_external_set_reversed(bool newstate);
|
||||
|
||||
#endif /* LED_EXTERNAL_H_ */
|
71
main.c
71
main.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2016 - 2019 Benjamin Vedder benjamin@vedder.se
|
||||
Copyright 2016 - 2021 Benjamin Vedder benjamin@vedder.se
|
||||
|
||||
This file is part of the VESC firmware.
|
||||
|
||||
|
@ -39,8 +39,6 @@
|
|||
#include "commands.h"
|
||||
#include "timeout.h"
|
||||
#include "comm_can.h"
|
||||
#include "ws2811.h"
|
||||
#include "led_external.h"
|
||||
#include "encoder.h"
|
||||
#include "servo_simple.h"
|
||||
#include "utils.h"
|
||||
|
@ -261,77 +259,10 @@ int main(void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if WS2811_ENABLE
|
||||
ws2811_init();
|
||||
#if !WS2811_TEST
|
||||
led_external_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Threads
|
||||
chThdCreateStatic(periodic_thread_wa, sizeof(periodic_thread_wa), NORMALPRIO, periodic_thread, NULL);
|
||||
chThdCreateStatic(flash_integrity_check_thread_wa, sizeof(flash_integrity_check_thread_wa), LOWPRIO, flash_integrity_check_thread, NULL);
|
||||
|
||||
#if WS2811_TEST
|
||||
unsigned int color_ind = 0;
|
||||
const int num = 4;
|
||||
const uint32_t colors[] = {COLOR_RED, COLOR_GOLD, COLOR_GRAY, COLOR_MAGENTA, COLOR_BLUE};
|
||||
const int brightness_set = 100;
|
||||
|
||||
for (;;) {
|
||||
chThdSleepMilliseconds(1000);
|
||||
|
||||
for (int i = 0;i < brightness_set;i++) {
|
||||
ws2811_set_brightness(i);
|
||||
chThdSleepMilliseconds(10);
|
||||
}
|
||||
|
||||
chThdSleepMilliseconds(1000);
|
||||
|
||||
for(int i = -num;i <= WS2811_LED_NUM;i++) {
|
||||
ws2811_set_led_color(i - 1, COLOR_BLACK);
|
||||
ws2811_set_led_color(i + num, colors[color_ind]);
|
||||
|
||||
ws2811_set_led_color(0, COLOR_RED);
|
||||
ws2811_set_led_color(WS2811_LED_NUM - 1, COLOR_GREEN);
|
||||
|
||||
chThdSleepMilliseconds(50);
|
||||
}
|
||||
|
||||
for (int i = 0;i < brightness_set;i++) {
|
||||
ws2811_set_brightness(brightness_set - i);
|
||||
chThdSleepMilliseconds(10);
|
||||
}
|
||||
|
||||
color_ind++;
|
||||
if (color_ind >= sizeof(colors) / sizeof(uint32_t)) {
|
||||
color_ind = 0;
|
||||
}
|
||||
|
||||
static int asd = 0;
|
||||
asd++;
|
||||
if (asd >= 3) {
|
||||
asd = 0;
|
||||
|
||||
for (unsigned int i = 0;i < sizeof(colors) / sizeof(uint32_t);i++) {
|
||||
ws2811_set_all(colors[i]);
|
||||
|
||||
for (int i = 0;i < brightness_set;i++) {
|
||||
ws2811_set_brightness(i);
|
||||
chThdSleepMilliseconds(2);
|
||||
}
|
||||
|
||||
chThdSleepMilliseconds(100);
|
||||
|
||||
for (int i = 0;i < brightness_set;i++) {
|
||||
ws2811_set_brightness(brightness_set - i);
|
||||
chThdSleepMilliseconds(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
timeout_init();
|
||||
timeout_configure(appconf->timeout_msec, appconf->timeout_brake_current);
|
||||
|
||||
|
|
|
@ -200,7 +200,6 @@ void mc_interface_init(void) {
|
|||
mc_interface_select_motor_thread(motor_old);
|
||||
|
||||
// Initialize encoder
|
||||
#if !WS2811_ENABLE
|
||||
switch (motor_now()->m_conf.m_sensor_port_mode) {
|
||||
case SENSOR_PORT_MODE_ABI:
|
||||
encoder_init_abi(motor_now()->m_conf.m_encoder_counts);
|
||||
|
@ -242,7 +241,6 @@ void mc_interface_init(void) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize selected implementation
|
||||
switch (motor_now()->m_conf.motor_type) {
|
||||
|
@ -330,7 +328,6 @@ void mc_interface_set_configuration(mc_configuration *configuration) {
|
|||
configuration->motor_type = MOTOR_TYPE_FOC;
|
||||
#endif
|
||||
|
||||
#if !WS2811_ENABLE
|
||||
if (motor->m_conf.m_sensor_port_mode != configuration->m_sensor_port_mode) {
|
||||
encoder_deinit();
|
||||
switch (configuration->m_sensor_port_mode) {
|
||||
|
@ -376,7 +373,6 @@ void mc_interface_set_configuration(mc_configuration *configuration) {
|
|||
if (configuration->m_sensor_port_mode == SENSOR_PORT_MODE_ABI) {
|
||||
encoder_set_counts(configuration->m_encoder_counts);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HW_HAS_DRV8301
|
||||
drv8301_set_oc_mode(configuration->m_drv8301_oc_mode);
|
||||
|
|
5
mcpwm.c
5
mcpwm.c
|
@ -2236,13 +2236,10 @@ void mcpwm_reset_hall_detect_table(void) {
|
|||
* @return
|
||||
* 0: OK
|
||||
* -1: Invalid hall sensor output
|
||||
* -2: WS2811 enabled
|
||||
* -3: Encoder enabled
|
||||
*/
|
||||
int mcpwm_get_hall_detect_result(int8_t *table) {
|
||||
if (WS2811_ENABLE) {
|
||||
return -2;
|
||||
} else if (conf->m_sensor_port_mode != SENSOR_PORT_MODE_HALL) {
|
||||
if (conf->m_sensor_port_mode != SENSOR_PORT_MODE_HALL) {
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
|
253
ws2811.c
253
ws2811.c
|
@ -1,253 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 Benjamin Vedder benjamin@vedder.se
|
||||
|
||||
This file is part of the VESC firmware.
|
||||
|
||||
The VESC firmware 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
The VESC firmware 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "ws2811.h"
|
||||
#include "stm32f4xx_conf.h"
|
||||
#include "ch.h"
|
||||
#include "hal.h"
|
||||
|
||||
// Settings
|
||||
#define TIM_PERIOD (((168000000 / 2 / WS2811_CLK_HZ) - 1))
|
||||
#define LED_BUFFER_LEN (WS2811_LED_NUM + 1)
|
||||
#define BITBUFFER_PAD 50
|
||||
#define BITBUFFER_LEN (24 * LED_BUFFER_LEN + BITBUFFER_PAD)
|
||||
#define WS2811_ZERO (TIM_PERIOD * 0.2)
|
||||
#define WS2811_ONE (TIM_PERIOD * 0.8)
|
||||
|
||||
// Private variables
|
||||
static uint16_t bitbuffer[BITBUFFER_LEN];
|
||||
static uint32_t RGBdata[LED_BUFFER_LEN];
|
||||
static uint8_t gamma_table[256];
|
||||
static uint32_t brightness;
|
||||
|
||||
// Private function prototypes
|
||||
static uint32_t rgb_to_local(uint32_t color);
|
||||
|
||||
void ws2811_init(void) {
|
||||
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
||||
TIM_OCInitTypeDef TIM_OCInitStructure;
|
||||
DMA_InitTypeDef DMA_InitStructure;
|
||||
|
||||
brightness = 100;
|
||||
|
||||
// Default LED values
|
||||
int i, bit;
|
||||
|
||||
for (i = 0;i < LED_BUFFER_LEN;i++) {
|
||||
RGBdata[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0;i < LED_BUFFER_LEN;i++) {
|
||||
uint32_t tmp_color = rgb_to_local(RGBdata[i]);
|
||||
|
||||
for (bit = 0;bit < 24;bit++) {
|
||||
if(tmp_color & (1 << 23)) {
|
||||
bitbuffer[bit + i * 24] = WS2811_ONE;
|
||||
} else {
|
||||
bitbuffer[bit + i * 24] = WS2811_ZERO;
|
||||
}
|
||||
tmp_color <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Fill the rest of the buffer with zeros to give the LEDs a chance to update
|
||||
// after sending all bits
|
||||
for (i = 0;i < BITBUFFER_PAD;i++) {
|
||||
bitbuffer[BITBUFFER_LEN - BITBUFFER_PAD - 1 + i] = 0;
|
||||
}
|
||||
|
||||
// Generate gamma correction table
|
||||
for (i = 0;i < 256;i++) {
|
||||
gamma_table[i] = (int)roundf(powf((float)i / 255.0, 1.0 / 0.45) * 255.0);
|
||||
}
|
||||
|
||||
#if WS2811_USE_CH2
|
||||
palSetPadMode(GPIOB, 7,
|
||||
PAL_MODE_ALTERNATE(GPIO_AF_TIM4) |
|
||||
PAL_STM32_OTYPE_OPENDRAIN |
|
||||
PAL_STM32_OSPEED_MID1);
|
||||
#else
|
||||
palSetPadMode(GPIOB, 6,
|
||||
PAL_MODE_ALTERNATE(GPIO_AF_TIM4) |
|
||||
PAL_STM32_OTYPE_OPENDRAIN |
|
||||
PAL_STM32_OSPEED_MID1);
|
||||
#endif
|
||||
|
||||
// DMA clock enable
|
||||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1 , ENABLE);
|
||||
|
||||
#if WS2811_USE_CH2
|
||||
DMA_DeInit(DMA1_Stream3);
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM4->CCR2;
|
||||
#else
|
||||
DMA_DeInit(DMA1_Stream0);
|
||||
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&TIM4->CCR1;
|
||||
#endif
|
||||
DMA_InitStructure.DMA_Channel = DMA_Channel_2;
|
||||
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)bitbuffer;
|
||||
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
|
||||
DMA_InitStructure.DMA_BufferSize = BITBUFFER_LEN;
|
||||
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
|
||||
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
|
||||
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
|
||||
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
|
||||
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
|
||||
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
|
||||
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
|
||||
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
|
||||
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
|
||||
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
|
||||
|
||||
#if WS2811_USE_CH2
|
||||
DMA_Init(DMA1_Stream3, &DMA_InitStructure);
|
||||
#else
|
||||
DMA_Init(DMA1_Stream0, &DMA_InitStructure);
|
||||
#endif
|
||||
|
||||
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
|
||||
|
||||
// Time Base configuration
|
||||
TIM_TimeBaseStructure.TIM_Prescaler = 0;
|
||||
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
||||
TIM_TimeBaseStructure.TIM_Period = TIM_PERIOD;
|
||||
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
|
||||
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
|
||||
|
||||
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
|
||||
|
||||
// Channel 1 Configuration in PWM mode
|
||||
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
||||
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
||||
TIM_OCInitStructure.TIM_Pulse = bitbuffer[0];
|
||||
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
|
||||
|
||||
#if WS2811_USE_CH2
|
||||
TIM_OC2Init(TIM4, &TIM_OCInitStructure);
|
||||
TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable);
|
||||
#else
|
||||
TIM_OC1Init(TIM4, &TIM_OCInitStructure);
|
||||
TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable);
|
||||
#endif
|
||||
|
||||
// TIM4 counter enable
|
||||
TIM_Cmd(TIM4, ENABLE);
|
||||
|
||||
// DMA enable
|
||||
#if WS2811_USE_CH2
|
||||
DMA_Cmd(DMA1_Stream3, ENABLE);
|
||||
#else
|
||||
DMA_Cmd(DMA1_Stream0, ENABLE);
|
||||
#endif
|
||||
|
||||
// TIM4 Update DMA Request enable
|
||||
#if WS2811_USE_CH2
|
||||
TIM_DMACmd(TIM4, TIM_DMA_CC2, ENABLE);
|
||||
#else
|
||||
TIM_DMACmd(TIM4, TIM_DMA_CC1, ENABLE);
|
||||
#endif
|
||||
|
||||
// Main Output Enable
|
||||
TIM_CtrlPWMOutputs(TIM4, ENABLE);
|
||||
}
|
||||
|
||||
void ws2811_set_led_color(int led, uint32_t color) {
|
||||
if (led >= 0 && led < WS2811_LED_NUM) {
|
||||
RGBdata[led] = color;
|
||||
|
||||
color = rgb_to_local(color);
|
||||
|
||||
int bit;
|
||||
for (bit = 0;bit < 24;bit++) {
|
||||
if(color & (1 << 23)) {
|
||||
bitbuffer[bit + led * 24] = WS2811_ONE;
|
||||
} else {
|
||||
bitbuffer[bit + led * 24] = WS2811_ZERO;
|
||||
}
|
||||
color <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ws2811_get_led_color(int led) {
|
||||
if (led >= 0 && led < WS2811_LED_NUM) {
|
||||
return RGBdata[led];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ws2811_all_off(void) {
|
||||
int i;
|
||||
|
||||
for (i = 0;i < WS2811_LED_NUM;i++) {
|
||||
RGBdata[i] = 0;
|
||||
}
|
||||
|
||||
for (i = 0;i < (WS2811_LED_NUM * 24);i++) {
|
||||
bitbuffer[i] = WS2811_ZERO;
|
||||
}
|
||||
}
|
||||
|
||||
void ws2811_set_all(uint32_t color) {
|
||||
int i, bit;
|
||||
|
||||
for (i = 0;i < WS2811_LED_NUM;i++) {
|
||||
RGBdata[i] = color;
|
||||
|
||||
uint32_t tmp_color = rgb_to_local(color);
|
||||
|
||||
for (bit = 0;bit < 24;bit++) {
|
||||
if(tmp_color & (1 << 23)) {
|
||||
bitbuffer[bit + i * 24] = WS2811_ONE;
|
||||
} else {
|
||||
bitbuffer[bit + i * 24] = WS2811_ZERO;
|
||||
}
|
||||
tmp_color <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ws2811_set_brightness(uint32_t br) {
|
||||
brightness = br;
|
||||
|
||||
for (int i = 0;i < WS2811_LED_NUM;i++) {
|
||||
ws2811_set_led_color(i, ws2811_get_led_color(i));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ws2811_get_brightness(void) {
|
||||
return brightness;
|
||||
}
|
||||
|
||||
static uint32_t rgb_to_local(uint32_t color) {
|
||||
uint32_t r = (color >> 16) & 0xFF;
|
||||
uint32_t g = (color >> 8) & 0xFF;
|
||||
uint32_t b = color & 0xFF;
|
||||
|
||||
r = (r * brightness) / 100;
|
||||
g = (g * brightness) / 100;
|
||||
b = (b * brightness) / 100;
|
||||
|
||||
r = gamma_table[r];
|
||||
g = gamma_table[g];
|
||||
b = gamma_table[b];
|
||||
|
||||
return (g << 16) | (r << 8) | b;
|
||||
}
|
77
ws2811.h
77
ws2811.h
|
@ -1,77 +0,0 @@
|
|||
/*
|
||||
Copyright 2016 Benjamin Vedder benjamin@vedder.se
|
||||
|
||||
This file is part of the VESC firmware.
|
||||
|
||||
The VESC firmware 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
The VESC firmware 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WS2811_H_
|
||||
#define WS2811_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "conf_general.h"
|
||||
|
||||
// Hex color definitions
|
||||
#define COLOR_BLACK 0x000000
|
||||
#define COLOR_WHITE 0xFFFFFF
|
||||
|
||||
#define COLOR_BLUE 0x0000FF
|
||||
#define COLOR_GREEN 0x00FF00
|
||||
#define COLOR_RED 0xFF0000
|
||||
|
||||
#define COLOR_NAVY 0x000080
|
||||
#define COLOR_DARKBLUE 0x00008B
|
||||
#define COLOR_DARKGREEN 0x006400
|
||||
#define COLOR_DARKCYAN 0x008B8B
|
||||
#define COLOR_CYAN 0x00FFFF
|
||||
#define COLOR_TURQUOISE 0x40E0D0
|
||||
#define COLOR_INDIGO 0x4B0082
|
||||
#define COLOR_DARKRED 0x800000
|
||||
#define COLOR_OLIVE 0x808000
|
||||
#define COLOR_GRAY 0x808080
|
||||
#define COLOR_SKYBLUE 0x87CEEB
|
||||
#define COLOR_BLUEVIOLET 0x8A2BE2
|
||||
#define COLOR_LIGHTGREEN 0x90EE90
|
||||
#define COLOR_DARKVIOLET 0x9400D3
|
||||
#define COLOR_YELLOWGREEN 0x9ACD32
|
||||
#define COLOR_BROWN 0xA52A2A
|
||||
#define COLOR_DARKGRAY 0xA9A9A9
|
||||
#define COLOR_SIENNA 0xA0522D
|
||||
#define COLOR_LIGHTBLUE 0xADD8E6
|
||||
#define COLOR_GREENYELLOW 0xADFF2F
|
||||
#define COLOR_SILVER 0xC0C0C0
|
||||
#define COLOR_LIGHTGREY 0xD3D3D3
|
||||
#define COLOR_LIGHTCYAN 0xE0FFFF
|
||||
#define COLOR_VIOLET 0xEE82EE
|
||||
#define COLOR_AZUR 0xF0FFFF
|
||||
#define COLOR_BEIGE 0xF5F5DC
|
||||
#define COLOR_MAGENTA 0xFF00FF
|
||||
#define COLOR_TOMATO 0xFF6347
|
||||
#define COLOR_GOLD 0xFFD700
|
||||
#define COLOR_ORANGE 0xFFA500
|
||||
#define COLOR_SNOW 0xFFFAFA
|
||||
#define COLOR_YELLOW 0xFFFF00
|
||||
|
||||
|
||||
// Functions
|
||||
void ws2811_init(void);
|
||||
void ws2811_set_led_color(int led, uint32_t color);
|
||||
uint32_t ws2811_get_led_color(int led);
|
||||
void ws2811_all_off(void);
|
||||
void ws2811_set_all(uint32_t color);
|
||||
void ws2811_set_brightness(uint32_t br);
|
||||
uint32_t ws2811_get_brightness(void);
|
||||
|
||||
#endif /* WS2811_H_ */
|
Loading…
Reference in New Issue