diff --git a/stmhal/boards/PYBLITEV10/mpconfigboard.h b/stmhal/boards/PYBLITEV10/mpconfigboard.h
index e6f97c8201f2ea44019bd3b9cd55301def0808ca..27988cad9338f411321680a27560e0e96d86c3bc 100644
--- a/stmhal/boards/PYBLITEV10/mpconfigboard.h
+++ b/stmhal/boards/PYBLITEV10/mpconfigboard.h
@@ -65,7 +65,7 @@
 #define MICROPY_HW_LED2             (pin_A14) // green
 #define MICROPY_HW_LED3             (pin_A15) // yellow
 #define MICROPY_HW_LED4             (pin_B4)  // blue
-#define MICROPY_HW_LED4_PWM         (1)
+#define MICROPY_HW_LED4_PWM         (0) // TIM3 is now a user timer
 #define MICROPY_HW_LED_OTYPE        (GPIO_MODE_OUTPUT_PP)
 #define MICROPY_HW_LED_ON(pin)      (pin->gpio->BSRRL = pin->pin_mask)
 #define MICROPY_HW_LED_OFF(pin)     (pin->gpio->BSRRH = pin->pin_mask)
@@ -77,6 +77,7 @@
 
 // USB config
 #define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9)
+#define MICROPY_HW_USE_ALT_IRQ_FOR_CDC (1)
 
 // MMA accelerometer config
 #define MICROPY_HW_MMA_AVDD_PIN     (pin_A10)
diff --git a/stmhal/main.c b/stmhal/main.c
index 3a15f6158fdd1da68b83593fd4edb9c6fa745612..2eb5a5338563f495d4b81340f14091df85e41fd5 100644
--- a/stmhal/main.c
+++ b/stmhal/main.c
@@ -393,7 +393,12 @@ int main(void) {
 
     // basic sub-system init
     pendsv_init();
+    #if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
+    HAL_NVIC_SetPriority(PVD_IRQn, 6, 0); // same priority as USB
+    HAL_NVIC_EnableIRQ(PVD_IRQn);
+    #else
     timer_tim3_init();
+    #endif
     led_init();
 #if MICROPY_HW_HAS_SWITCH
     switch_init0();
diff --git a/stmhal/stm32_it.c b/stmhal/stm32_it.c
index 5f96c6083b928bc1a4bc82c7f59b29b1e5427634..371d20dd7c13157a93ad57e9f8e3f2398751e373 100644
--- a/stmhal/stm32_it.c
+++ b/stmhal/stm32_it.c
@@ -277,6 +277,12 @@ void SysTick_Handler(void) {
     // be generalised in the future then a dispatch table can be used as
     // follows: ((void(*)(void))(systick_dispatch[uwTick & 0xf]))();
 
+    #if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
+    if (((uwTick) & 7) == 4) { // every 8ms
+        NVIC->STIR = PVD_IRQn;
+    }
+    #endif
+
     if (STORAGE_IDLE_TICK(uwTick)) {
         NVIC->STIR = FLASH_IRQn;
     }
@@ -425,6 +431,10 @@ void EXTI15_10_IRQHandler(void) {
 }
 
 void PVD_IRQHandler(void) {
+    #if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
+    extern void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void);
+    USBD_CDC_HAL_TIM_PeriodElapsedCallback();
+    #endif
     Handle_EXTI_Irq(EXTI_PVD_OUTPUT);
 }
 
@@ -465,7 +475,11 @@ void TIM2_IRQHandler(void) {
 }
 
 void TIM3_IRQHandler(void) {
+    #if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
+    timer_irq_handler(3);
+    #else
     HAL_TIM_IRQHandler(&TIM3_Handle);
+    #endif
 }
 
 void TIM4_IRQHandler(void) {
diff --git a/stmhal/timer.c b/stmhal/timer.c
index cf93a01d7cb485d404b6f9d00f7b508c7c532d5f..bca3f5457ac4a9ecbe01997b99cb04910f32298d 100644
--- a/stmhal/timer.c
+++ b/stmhal/timer.c
@@ -250,9 +250,12 @@ TIM_HandleTypeDef *timer_tim6_init(uint freq) {
 
 // Interrupt dispatch
 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
+    #if !defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
     if (htim == &TIM3_Handle) {
         USBD_CDC_HAL_TIM_PeriodElapsedCallback();
-    } else if (htim == &TIM5_Handle) {
+    } else
+    #endif
+    if (htim == &TIM5_Handle) {
         servo_timer_irq_callback();
     }
 }
@@ -653,7 +656,11 @@ STATIC mp_obj_t pyb_timer_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t
     switch (tim->tim_id) {
         case 1: tim->tim.Instance = TIM1; tim->irqn = TIM1_UP_TIM10_IRQn; break;
         case 2: tim->tim.Instance = TIM2; tim->irqn = TIM2_IRQn; tim->is_32bit = true; break;
+        #if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
+        case 3: tim->tim.Instance = TIM3; tim->irqn = TIM3_IRQn; break;
+        #else
         case 3: nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Timer 3 is for internal use only")); // TIM3 used for low-level stuff; go via regs if necessary
+        #endif
         case 4: tim->tim.Instance = TIM4; tim->irqn = TIM4_IRQn; break;
         case 5: tim->tim.Instance = TIM5; tim->irqn = TIM5_IRQn; tim->is_32bit = true; break;
         #if defined(TIM6)