Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Inc/targets.h
Original file line number Diff line number Diff line change
Expand Up @@ -4136,6 +4136,9 @@
#define IC_TIMER_CHANNEL TIMER_CH_0
#define IC_TIMER_REGISTER TIMER2
#define INPUT_DMA_CHANNEL DMA_CH3
#define LED_TIMER_REGISTER TIMER14
#define LED_DMA_CHANNEL DMA_CH4
#define LED_USES_PA2
#define IC_DMA_IRQ_NAME DMA_Channel3_4_IRQn

#define PHASE_A_GPIO_LOW GPIO_PIN_1
Expand Down Expand Up @@ -4168,6 +4171,9 @@
#define IC_TIMER_CHANNEL TIMER_CH_0
#define IC_TIMER_REGISTER TIMER2
#define INPUT_DMA_CHANNEL DMA_CH3
#define LED_TIMER_REGISTER TIMER14
#define LED_DMA_CHANNEL DMA_CH4
#define LED_USES_PA2
#define IC_DMA_IRQ_NAME DMA_Channel3_4_IRQn

#define PHASE_A_GPIO_LOW GPIO_PIN_1
Expand Down Expand Up @@ -4200,6 +4206,9 @@
#define IC_TIMER_CHANNEL TIMER_CH_0
#define IC_TIMER_REGISTER TIMER14
#define INPUT_DMA_CHANNEL DMA_CH4
#define LED_TIMER_REGISTER TIMER2
#define LED_DMA_CHANNEL DMA_CH3
#define LED_USES_PB4
#define IC_DMA_IRQ_NAME DMA_Channel3_4_IRQn

#define PHASE_A_GPIO_LOW GPIO_PIN_1
Expand Down
20 changes: 20 additions & 0 deletions Mcu/e230/Inc/WS2812.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* WS2812.h
*
* Created on: Sep 9, 2020
* Author: Alka
*/

#ifndef INC_WS2812_H_
#define INC_WS2812_H_

#include "main.h"
#define RGB_BUFFER_SIZE 28

void send_LED_DMA();
void WS2812_Init(void);
void send_LED_RGB(uint8_t red, uint8_t green, uint8_t blue);

extern char dma_busy;

#endif /* INC_WS2812_H_ */
10 changes: 10 additions & 0 deletions Mcu/e230/Src/IO.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@ uint16_t change_time = 0;

void receiveDshotDma()
{
#ifdef USE_TIMER_2_CHANNEL_0
RCU_REG_VAL(RCU_TIMER2RST) |= BIT(RCU_BIT_POS(RCU_TIMER2RST));
RCU_REG_VAL(RCU_TIMER2RST) &= ~BIT(RCU_BIT_POS(RCU_TIMER2RST));
#endif
#ifdef USE_TIMER_14_CHANNEL_0
RCU_REG_VAL(RCU_TIMER14RST) |= BIT(RCU_BIT_POS(RCU_TIMER14RST));
RCU_REG_VAL(RCU_TIMER14RST) &= ~BIT(RCU_BIT_POS(RCU_TIMER14RST));
#endif

TIMER_CHCTL0(IC_TIMER_REGISTER) = 0x41;
TIMER_CHCTL2(IC_TIMER_REGISTER) = 0xa;
TIMER_PSC(IC_TIMER_REGISTER) = ic_timer_prescaler;
Expand All @@ -43,10 +48,15 @@ void receiveDshotDma()

void sendDshotDma()
{
#ifdef USE_TIMER_2_CHANNEL_0
RCU_REG_VAL(RCU_TIMER2RST) |= BIT(RCU_BIT_POS(RCU_TIMER2RST));
RCU_REG_VAL(RCU_TIMER2RST) &= ~BIT(RCU_BIT_POS(RCU_TIMER2RST));
#endif
#ifdef USE_TIMER_14_CHANNEL_0
RCU_REG_VAL(RCU_TIMER14RST) |= BIT(RCU_BIT_POS(RCU_TIMER14RST));
RCU_REG_VAL(RCU_TIMER14RST) &= ~BIT(RCU_BIT_POS(RCU_TIMER14RST));
#endif

TIMER_CHCTL0(IC_TIMER_REGISTER) = 0x60;
TIMER_CHCTL2(IC_TIMER_REGISTER) = 0x3;
TIMER_PSC(IC_TIMER_REGISTER) = output_timer_prescaler;
Expand Down
154 changes: 154 additions & 0 deletions Mcu/e230/Src/WS2812.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* WS2812.c
*
* Created on: Sep 9, 2020
* Author: Alka
*
* Modified for GD32E230 on: Oct 23, 2025
* Author: Scarittagle
*/

#include "WS2812.h"

#include "targets.h"

char dma_busy;

uint16_t led_Buffer[RGB_BUFFER_SIZE] = {
0,
0,
20,
20,
20,
20,
20,
20,
20,
20,
60,
60,
60,
60,
60,
60,
60,
60,
20,
20,
20,
20,
20,
20,
20,
20,
0,
0,
};

void send_LED_DMA()
{
dma_busy = 1;
dma_channel_disable(LED_DMA_CHANNEL);
dma_memory_address_config(LED_DMA_CHANNEL, (uint32_t)led_Buffer);
dma_transfer_number_config(LED_DMA_CHANNEL, RGB_BUFFER_SIZE);
dma_channel_enable(LED_DMA_CHANNEL);
}

void send_LED_RGB(uint8_t red, uint8_t green, uint8_t blue)
{
if (!dma_busy) {
uint32_t twenty_four_bit_color_number = green << 16 | red << 8 | blue;

for (int i = 0; i < 24; i++) {
led_Buffer[i + 2] = (((twenty_four_bit_color_number >> (23 - i)) & 1) * 31) + 28;
// Bit 0: 0*31+28 = 28 (~311ns HIGH, ~939ns LOW) - blog CODE_0
// Bit 1: 1*31+28 = 59 (~656ns HIGH, ~594ns LOW) - blog CODE_1
Comment on lines +64 to +65
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected spelling of 'blog' to 'below' in timing comments.

Suggested change
// Bit 0: 0*31+28 = 28 (~311ns HIGH, ~939ns LOW) - blog CODE_0
// Bit 1: 1*31+28 = 59 (~656ns HIGH, ~594ns LOW) - blog CODE_1
// Bit 0: 0*31+28 = 28 (~311ns HIGH, ~939ns LOW) - below CODE_0
// Bit 1: 1*31+28 = 59 (~656ns HIGH, ~594ns LOW) - below CODE_1

Copilot uses AI. Check for mistakes.
}
send_LED_DMA();
}
}

void WS2812_Init(void)
{
// Init Timer&DMA config structures
timer_oc_parameter_struct timer_ocinitpara;
timer_parameter_struct timer_initpara;
dma_parameter_struct dma_initpara;

// NVIC Settings
NVIC_SetPriority(DMA_Channel3_4_IRQn, 1);
NVIC_EnableIRQ(DMA_Channel3_4_IRQn);

// Periph Clocks settings
rcu_periph_clock_enable(RCU_DMA);

#ifdef LED_USES_PB4
rcu_periph_clock_enable(RCU_TIMER2);
rcu_periph_clock_enable(RCU_GPIOB);
#endif
#ifdef LED_USES_PA2
rcu_periph_clock_enable(RCU_TIMER14);
Comment on lines +86 to +90
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Timer/pin mapping is incorrect. According to comments on lines 95-96, PA2 maps to TIM14 and PB4 maps to TIM2. However, line 86 enables TIMER2 for LED_USES_PB4, and line 90 enables TIMER14 for LED_USES_PA2, which is backwards. The timer clock enable calls should be swapped to match the correct pin-to-timer mapping.

Suggested change
rcu_periph_clock_enable(RCU_TIMER2);
rcu_periph_clock_enable(RCU_GPIOB);
#endif
#ifdef LED_USES_PA2
rcu_periph_clock_enable(RCU_TIMER14);
rcu_periph_clock_enable(RCU_TIMER14);
rcu_periph_clock_enable(RCU_GPIOB);
#endif
#ifdef LED_USES_PA2
rcu_periph_clock_enable(RCU_TIMER2);

Copilot uses AI. Check for mistakes.
rcu_periph_clock_enable(RCU_GPIOA);
#endif

// Configure GPIO
//PA2 --> TIM14
//PB4 --> TIM2
Comment on lines +95 to +96
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments incorrectly map pin-to-timer relationships. According to the code at lines 86 and 90, PA2 uses TIMER14 and PB4 uses TIMER2, but the comments state the opposite. The comments should read: 'PA2 --> TIMER14' and 'PB4 --> TIMER2'.

Suggested change
//PA2 --> TIM14
//PB4 --> TIM2
//PA2 --> TIMER14
//PB4 --> TIMER2

Copilot uses AI. Check for mistakes.
#ifdef LED_USES_PB4// that means the esc is using PA2 as signal pin, so we configure PB4 as ws2812 data pin
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after #ifdef LED_USES_PB4 before the comment delimiter. Should be #ifdef LED_USES_PB4 //.

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after the conditional directive. Should be '#ifdef LED_USES_PB4 //' for better readability.

Suggested change
#ifdef LED_USES_PB4// that means the esc is using PA2 as signal pin, so we configure PB4 as ws2812 data pin
#ifdef LED_USES_PB4 // that means the esc is using PA2 as signal pin, so we configure PB4 as ws2812 data pin

Copilot uses AI. Check for mistakes.
gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4);
gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4);
gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_4);
#endif
#ifdef LED_USES_PA2 // same as above
gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_2);
gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
gpio_af_set(GPIOA, GPIO_AF_0, GPIO_PIN_2);
#endif

// Configure Timer
timer_deinit(LED_TIMER_REGISTER);
timer_initpara.prescaler = 0;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 89; // 800KHz
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(LED_TIMER_REGISTER, &timer_initpara);

// Configure Timer Channel
timer_ocinitpara.outputstate = TIMER_CCX_ENABLE;
timer_ocinitpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocinitpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocinitpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocinitpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH;
timer_ocinitpara.ocnidlestate = TIMER_OC_IDLE_STATE_LOW;

timer_channel_output_config(LED_TIMER_REGISTER, TIMER_CH_0, &timer_ocinitpara);
timer_channel_output_pulse_value_config(LED_TIMER_REGISTER, TIMER_CH_0, 0);
timer_channel_output_mode_config(LED_TIMER_REGISTER, TIMER_CH_0, TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(LED_TIMER_REGISTER, TIMER_CH_0, TIMER_OC_SHADOW_DISABLE);
timer_primary_output_config(LED_TIMER_REGISTER, ENABLE);
timer_dma_transfer_config(LED_TIMER_REGISTER, TIMER_DMACFG_DMATA_CH0CV, TIMER_DMACFG_DMATC_1TRANSFER);
timer_dma_enable(LED_TIMER_REGISTER, TIMER_DMA_UPD);
timer_auto_reload_shadow_enable(LED_TIMER_REGISTER);
timer_enable(LED_TIMER_REGISTER);

dma_deinit(LED_DMA_CHANNEL);
dma_initpara.periph_addr = (uint32_t)&TIMER_CH0CV(LED_TIMER_REGISTER);
dma_initpara.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_initpara.memory_addr = (uint32_t)&led_Buffer;
dma_initpara.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_initpara.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
dma_initpara.memory_width = DMA_MEMORY_WIDTH_16BIT;
dma_initpara.direction = DMA_MEMORY_TO_PERIPHERAL;
dma_initpara.number = RGB_BUFFER_SIZE;
dma_initpara.priority = DMA_PRIORITY_HIGH;
dma_init(LED_DMA_CHANNEL, &dma_initpara);
dma_circulation_disable(LED_DMA_CHANNEL); // Normal mode, not circular
dma_memory_to_memory_disable(LED_DMA_CHANNEL);
dma_interrupt_enable(LED_DMA_CHANNEL, DMA_INT_FTF); // Enable interrupts in init
dma_interrupt_enable(LED_DMA_CHANNEL, DMA_INT_ERR);
dma_channel_enable(LED_DMA_CHANNEL);

}

17 changes: 17 additions & 0 deletions Mcu/e230/Src/gd32e23x_it.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ uint16_t interrupt_time = 0;
#include "main.h"
#include "systick.h"
#include "targets.h"
#include "WS2812.h"
Comment on lines 26 to +27
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The WS2812.h header is included unconditionally but is only used within the #ifdef USE_LED_STRIP block in this file. The include should be wrapped with the same conditional to avoid unnecessary header inclusion when LED strip support is not enabled.

Suggested change
#include "targets.h"
#include "WS2812.h"
#include "targets.h"
#ifdef USE_LED_STRIP
#include "WS2812.h"
#endif

Copilot uses AI. Check for mistakes.

/*!
\brief this function handles NMI exception
Expand Down Expand Up @@ -72,6 +73,22 @@ void SysTick_Handler(void) { delay_decrement(); }

void DMA_Channel3_4_IRQHandler(void)
{
#ifdef USE_LED_STRIP
// Check transfer complete for WS2812
if (dma_interrupt_flag_get(LED_DMA_CHANNEL, DMA_INT_FLAG_FTF)) {
dma_interrupt_flag_clear(LED_DMA_CHANNEL, DMA_INT_FLAG_G);
dma_channel_disable(LED_DMA_CHANNEL);
dma_busy = 0; // Ready for next LED update
return;
}
if (dma_interrupt_flag_get(LED_DMA_CHANNEL, DMA_INT_FLAG_ERR)) {
dma_interrupt_flag_clear(LED_DMA_CHANNEL, DMA_INT_FLAG_G);
dma_channel_disable(LED_DMA_CHANNEL);
dma_busy = 0; // Ready for next LED update
return;
}
#endif

if (dshot_telemetry && armed) {
DMA_INTC |= DMA_FLAG_ADD(DMA_INT_FLAG_G, INPUT_DMA_CHANNEL);
DMA_CHCTL(INPUT_DMA_CHANNEL) &= ~DMA_CHXCTL_CHEN;
Expand Down
17 changes: 14 additions & 3 deletions Mcu/e230/Src/peripherals.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
#include "functions.h"
#include "serial_telemetry.h"
#include "targets.h"
#ifdef USE_LED_STRIP
#include "WS2812.h"
#endif


void initCorePeripherals(void)
{
Expand All @@ -34,6 +38,9 @@ void initCorePeripherals(void)
#ifdef USE_RGB_LED
LED_GPIO_init();
#endif
#ifdef USE_LED_STRIP
WS2812_Init();
#endif
#ifdef USE_SERIAL_TELEMETRY
telem_UART_Init();
#endif
Expand Down Expand Up @@ -238,8 +245,6 @@ void MX_DMA_Init(void)
NVIC_SetPriority(DMA_Channel1_2_IRQn, 3);
NVIC_EnableIRQ(DMA_Channel1_2_IRQn);

// NVIC_SetPriority(DMA_Channel3_4_IRQn, 1);
// NVIC_EnableIRQ(DMA_Channel3_4_IRQn);
}

void MX_GPIO_Init(void) { }
Expand Down Expand Up @@ -270,10 +275,16 @@ void UN_TIM_Init(void)

NVIC_SetPriority(IC_DMA_IRQ_NAME, 1);
NVIC_EnableIRQ(IC_DMA_IRQ_NAME);
#ifdef LED_USES_PA2
rcu_periph_clock_enable(RCU_TIMER2);
rcu_periph_clock_enable(RCU_TIMER14);
TIMER_CAR(TIMER2) = 0xFFFF;
TIMER_PSC(TIMER2) = 10;
#endif
#ifdef LED_USES_PB4
rcu_periph_clock_enable(RCU_TIMER14);
TIMER_CAR(TIMER14) = 0xFFFF;
TIMER_PSC(TIMER14) = 10;
#endif
Comment on lines +278 to +287
Copy link

Copilot AI Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate timer initialization logic in peripherals.c (lines 278-287) and WS2812.c (lines 85-92). The timer clock enable calls are redundant since WS2812_Init() already performs comprehensive timer initialization. Consider removing the timer clock enable from peripherals.c or add a comment explaining why both are needed.

Copilot uses AI. Check for mistakes.
/* enable a TIMER */

// LL_TIM_DisableARRPreload(IC_TIMER_REGISTER);
Expand Down