diff --git a/.cproject b/.cproject
index c060ea5..ee9171b 100644
--- a/.cproject
+++ b/.cproject
@@ -22,7 +22,7 @@
-
+
@@ -100,7 +100,7 @@
-
+
diff --git a/Core/Src/main.c b/Core/Src/main.c
index 499b9d6..2ad6793 100644
--- a/Core/Src/main.c
+++ b/Core/Src/main.c
@@ -24,7 +24,8 @@
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
-// #include "ws2812b-dma-driver.h"
+#include
+#include "ws2812.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -94,12 +95,9 @@ int main(void)
HAL_TIM_Base_Start(&htim2);
- int8_t test[] = { 0, 4, 7, 10, 14, 17 };
- HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_1, test, sizeof(test));
- //HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
+ ws2812_Init();
- uint8_t data[] = {0xff, 0x00, 0xff, 0x00, 0xFF, 0x00, 0xfF, 0x00};
/* USER CODE END 2 */
@@ -110,8 +108,25 @@ int main(void)
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
- HAL_GPIO_TogglePin(LED_Green_GPIO_Port, LED_Green_Pin);
- HAL_Delay(500);
+
+ uint8_t r = rand();
+ uint8_t g = rand();
+ uint8_t b = rand();
+
+ for (uint8_t led = 0; led < 24; led++) {
+
+ uint8_t r = rand();
+ uint8_t g = rand();
+ uint8_t b = rand();
+
+ ws2812_reset();
+
+ ws2812_set_colour(led, r, g, b);
+ ws2812_update();
+ HAL_Delay(20);
+ }
+
+ HAL_GPIO_TogglePin(LED_Green_GPIO_Port, LED_Green_Pin);
}
/* USER CODE END 3 */
@@ -135,7 +150,7 @@ void SystemClock_Config(void)
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL5;
+ RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
@@ -150,7 +165,7 @@ void SystemClock_Config(void)
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
- if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
@@ -158,6 +173,7 @@ void SystemClock_Config(void)
/* USER CODE BEGIN 4 */
+
/* USER CODE END 4 */
/**
diff --git a/Core/Src/tim.c b/Core/Src/tim.c
index 5a6b5f8..4371bb4 100644
--- a/Core/Src/tim.c
+++ b/Core/Src/tim.c
@@ -45,7 +45,7 @@ void MX_TIM2_Init(void)
htim2.Instance = TIM2;
htim2.Init.Prescaler = 0;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
- htim2.Init.Period = 19;
+ htim2.Init.Period = 90;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
diff --git a/Drivers/STM32F1xx_HAL_Driver/Inc/ws2812.h b/Drivers/STM32F1xx_HAL_Driver/Inc/ws2812.h
new file mode 100644
index 0000000..61205ad
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Inc/ws2812.h
@@ -0,0 +1,26 @@
+/*
+ * ws2812.h
+ *
+ * Created on: Mar 25, 2026
+ * Author: ewars
+ */
+
+#ifndef STM32F1XX_HAL_DRIVER_INC_WS2812_H_
+#define STM32F1XX_HAL_DRIVER_INC_WS2812_H_
+
+
+#define LED_N 24
+#define RESET_LEN 50
+
+#define PWM_ZERO 29
+#define PWM_ONE 58
+
+
+void ws2812_Init(void);
+void ws2812_update(void);
+void ws2812_set_colour(uint8_t led, uint8_t red, uint8_t green, uint8_t blue);
+void ws2812_wait(void);
+void ws2812_reset(void);
+
+
+#endif /* STM32F1XX_HAL_DRIVER_INC_WS2812_H_ */
diff --git a/Drivers/STM32F1xx_HAL_Driver/Src/ws2812.c b/Drivers/STM32F1xx_HAL_Driver/Src/ws2812.c
new file mode 100644
index 0000000..c3e4fb4
--- /dev/null
+++ b/Drivers/STM32F1xx_HAL_Driver/Src/ws2812.c
@@ -0,0 +1,74 @@
+/*
+ * ws2812.c
+ *
+ * Created on: Mar 25, 2026
+ * Author: ewars
+ */
+
+#include "stdint-gcc.h"
+
+#include "ws2812.h"
+#include "stm32f1xx_hal.h"
+
+extern htim2;
+
+static void set_byte(uint32_t pos, uint8_t value);
+
+uint8_t pwm_reset[RESET_LEN] = {0};
+uint8_t pwm_full = 90;
+
+uint8_t ledStripBuffer[RESET_LEN + LED_N * 24 + 1] = {0};
+
+void ws2812_Init(void){
+
+ for(uint32_t i = 0; i < LED_N * 24; i++){
+ ledStripBuffer[RESET_LEN + i] = PWM_ONE;
+ }
+
+ ledStripBuffer[RESET_LEN + LED_N * 24] = pwm_full;
+
+ ws2812_update();
+
+}
+
+void ws2812_update(void){
+ HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_1, ledStripBuffer, sizeof(ledStripBuffer));
+}
+
+void ws2812_set_colour(uint8_t led, uint8_t red, uint8_t green, uint8_t blue){
+
+ if(led < LED_N){
+ set_byte(RESET_LEN + 24 * led, green);
+ set_byte(RESET_LEN + 24 * led + 8, red);
+ set_byte(RESET_LEN + 24 * led + 16, blue);
+ }
+
+}
+
+void ws2812_reset(void){
+ for(uint8_t i = 0; i < LED_N; i++){
+ ws2812_set_colour(i, 0, 0, 0);
+ }
+}
+
+static void set_byte(uint32_t pos, uint8_t value)
+{
+ int i;
+ for (i = 0; i < 8; i++) {
+ if (value & 0x80) {
+ ledStripBuffer[pos + i] = PWM_ONE;
+ } else {
+ ledStripBuffer[pos + i] = PWM_ZERO;
+ }
+
+ value <<= 1;
+ }
+}
+
+
+
+void ws2812_wait(void){
+ while(HAL_TIM_GetChannelState(&htim2, TIM_CHANNEL_1)){}
+}
+
+
diff --git a/LedRing.ioc b/LedRing.ioc
index f6b4ef3..8ce12f1 100644
--- a/LedRing.ioc
+++ b/LedRing.ioc
@@ -99,32 +99,32 @@ ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_TIM2_Init-TIM2-false-HAL-true
-RCC.ADCFreqValue=20000000
-RCC.AHBFreq_Value=40000000
+RCC.ADCFreqValue=36000000
+RCC.AHBFreq_Value=72000000
RCC.APB1CLKDivider=RCC_HCLK_DIV2
-RCC.APB1Freq_Value=20000000
-RCC.APB1TimFreq_Value=40000000
-RCC.APB2Freq_Value=40000000
-RCC.APB2TimFreq_Value=40000000
-RCC.FCLKCortexFreq_Value=40000000
+RCC.APB1Freq_Value=36000000
+RCC.APB1TimFreq_Value=72000000
+RCC.APB2Freq_Value=72000000
+RCC.APB2TimFreq_Value=72000000
+RCC.FCLKCortexFreq_Value=72000000
RCC.FamilyName=M
-RCC.HCLKFreq_Value=40000000
+RCC.HCLKFreq_Value=72000000
RCC.IPParameters=ADCFreqValue,AHBFreq_Value,APB1CLKDivider,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,MCOFreq_Value,PLLCLKFreq_Value,PLLMCOFreq_Value,PLLMUL,PLLSourceVirtual,SYSCLKFreq_VALUE,SYSCLKSource,TimSysFreq_Value,USBFreq_Value,VCOOutput2Freq_Value
-RCC.MCOFreq_Value=40000000
-RCC.PLLCLKFreq_Value=40000000
-RCC.PLLMCOFreq_Value=20000000
-RCC.PLLMUL=RCC_PLL_MUL5
+RCC.MCOFreq_Value=72000000
+RCC.PLLCLKFreq_Value=72000000
+RCC.PLLMCOFreq_Value=36000000
+RCC.PLLMUL=RCC_PLL_MUL9
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
-RCC.SYSCLKFreq_VALUE=40000000
+RCC.SYSCLKFreq_VALUE=72000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
-RCC.TimSysFreq_Value=40000000
-RCC.USBFreq_Value=40000000
+RCC.TimSysFreq_Value=72000000
+RCC.USBFreq_Value=72000000
RCC.VCOOutput2Freq_Value=8000000
SH.S_TIM2_CH1_ETR.0=TIM2_CH1,PWM Generation1 CH1
SH.S_TIM2_CH1_ETR.ConfNb=1
TIM2.Channel-PWM\ Generation1\ CH1=TIM_CHANNEL_1
TIM2.IPParameters=Channel-PWM Generation1 CH1,Period,Pulse-PWM Generation1 CH1
-TIM2.Period=19
+TIM2.Period=90
TIM2.Pulse-PWM\ Generation1\ CH1=9
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick