diff --git a/common.mk b/common.mk
index 537cc3a2..540d8da4 100644
--- a/common.mk
+++ b/common.mk
@@ -58,10 +58,18 @@ ifdef SLEEP_LED_ENABLE
OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
endif
+ifdef SOFTPWM_LED_ENABLE
+ SRC += $(COMMON_DIR)/softpwm_led.c
+ OPT_DEFS += -DSOFTPWM_LED_ENABLE
+ifdef BREATHING_LED_ENABLE
+ OPT_DEFS += -DBREATHING_LED_ENABLE
+endif
+else
ifdef BREATHING_LED_ENABLE
SRC += $(COMMON_DIR)/breathing_led.c
OPT_DEFS += -DBREATHING_LED_ENABLE
endif
+endif
ifdef BACKLIGHT_ENABLE
SRC += $(COMMON_DIR)/backlight.c
diff --git a/common/keyboard.c b/common/keyboard.c
index 08f86be3..c7793eec 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -31,7 +31,11 @@ along with this program. If not, see .
#include "bootmagic.h"
#include "eeconfig.h"
#include "backlight.h"
+#ifdef SOFTPWM_LED_ENABLE
+#include "softpwm_led.h"
+#else
#include "breathing_led.h"
+#endif
#include "keymap_in_eeprom.h"
#ifdef MOUSEKEY_ENABLE
# include "mousekey.h"
@@ -82,6 +86,10 @@ void keyboard_init(void)
backlight_init();
#endif
+#ifdef SOFTPWM_LED_ENABLE
+ softpwm_led_init();
+#endif
+
#ifdef BREATHING_LED_ENABLE
breathing_led_init();
#endif
diff --git a/common/softpwm_led.c b/common/softpwm_led.c
new file mode 100644
index 00000000..e2195c2f
--- /dev/null
+++ b/common/softpwm_led.c
@@ -0,0 +1,155 @@
+#include
+#include
+#include "led.h"
+#include "softpwm_led.h"
+#include "debug.h"
+
+#define SOFTPWM_LED_FREQ 64
+#define SOFTPWM_LED_TIMER_TOP F_CPU / (256 * SOFTPWM_LED_FREQ)
+
+uint8_t softpwm_ocr = 0;
+uint8_t softpwm_ocr_buff = 0;
+
+void softpwm_led_init(void)
+{
+#ifdef SOFTPWM_LED_TIMER3
+ /* Timer3 setup */
+ /* CTC mode */
+ TCCR3B |= (1<> 8) & 0xff;
+ OCR3AL = SOFTPWM_LED_TIMER_TOP & 0xff;
+ SREG = sreg;
+#else
+ /* Timer1 setup */
+ /* CTC mode */
+ TCCR1B |= (1<> 8) & 0xff;
+ OCR1AL = SOFTPWM_LED_TIMER_TOP & 0xff;
+ SREG = sreg;
+#endif
+}
+
+void softpwm_led_enable(void)
+{
+ /* Enable Compare Match Interrupt */
+#ifdef SOFTPWM_LED_TIMER3
+ TIMSK3 |= (1< SOFTPWM_LED_FREQ) {
+ count = 0;
+ step++;
+ if (step > breathing_led_duration) {
+ step = 0;
+ softpwm_ocr_buff = pgm_read_byte(&breathing_table[index]);
+ index++;
+ }
+ }
+ }
+#endif
+}
diff --git a/common/softpwm_led.h b/common/softpwm_led.h
new file mode 100644
index 00000000..5236b1df
--- /dev/null
+++ b/common/softpwm_led.h
@@ -0,0 +1,40 @@
+#ifndef SOFTPWM_LED_H
+#define SOFTPWM_LED_H
+
+#ifdef SOFTPWM_LED_ENABLE
+
+void softpwm_led_init(void);
+void softpwm_led_enable(void);
+void softpwm_led_disable(void);
+void softpwm_led_toggle(void);
+void softpwm_led_set(uint8_t val);
+void softpwm_led_on(void);
+void softpwm_led_off(void);
+
+#ifdef BREATHING_LED_ENABLE
+#define breathing_led_init()
+void breathing_led_enable(void);
+void breathing_led_disable(void);
+void breathing_led_toggle(void);
+void breathing_led_set_duration(uint8_t dur);
+#else
+#define breathing_led_init()
+#define breathing_led_enable()
+#define breathing_led_disable()
+#define breathing_led_toggle()
+#define breathing_led_set_duration()
+#endif
+
+#else
+
+#define softpwm_led_init()
+#define softpwm_led_enable()
+#define softpwm_led_disable()
+#define softpwm_led_toggle()
+#define softpwm_led_set()
+#define softpwm_led_on()
+#define softpwm_led_off()
+
+#endif
+
+#endif