Skip to content

Commit 66b9682

Browse files
committed
stmhal: Add option to free up TIM3 from USB VCP polling.
This is a hack to free up TIM3 so that it can be used by the user. Instead we use the PVD irq to call the USB VCP polling function, and trigger it from SysTick (so SysTick itself does not do any processing). The feature is enabled for pyboard lite only, since it lacks timers.
1 parent 9aaf888 commit 66b9682

4 files changed

Lines changed: 29 additions & 2 deletions

File tree

stmhal/boards/PYBLITEV10/mpconfigboard.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
#define MICROPY_HW_LED2 (pin_A14) // green
6666
#define MICROPY_HW_LED3 (pin_A15) // yellow
6767
#define MICROPY_HW_LED4 (pin_B4) // blue
68-
#define MICROPY_HW_LED4_PWM (1)
68+
#define MICROPY_HW_LED4_PWM (0) // TIM3 is now a user timer
6969
#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
7070
#define MICROPY_HW_LED_ON(pin) (pin->gpio->BSRRL = pin->pin_mask)
7171
#define MICROPY_HW_LED_OFF(pin) (pin->gpio->BSRRH = pin->pin_mask)
@@ -77,6 +77,7 @@
7777

7878
// USB config
7979
#define MICROPY_HW_USB_VBUS_DETECT_PIN (pin_A9)
80+
#define MICROPY_HW_USE_ALT_IRQ_FOR_CDC (1)
8081

8182
// MMA accelerometer config
8283
#define MICROPY_HW_MMA_AVDD_PIN (pin_A10)

stmhal/main.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,12 @@ int main(void) {
393393

394394
// basic sub-system init
395395
pendsv_init();
396+
#if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
397+
HAL_NVIC_SetPriority(PVD_IRQn, 6, 0); // same priority as USB
398+
HAL_NVIC_EnableIRQ(PVD_IRQn);
399+
#else
396400
timer_tim3_init();
401+
#endif
397402
led_init();
398403
#if MICROPY_HW_HAS_SWITCH
399404
switch_init0();

stmhal/stm32_it.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,12 @@ void SysTick_Handler(void) {
277277
// be generalised in the future then a dispatch table can be used as
278278
// follows: ((void(*)(void))(systick_dispatch[uwTick & 0xf]))();
279279

280+
#if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
281+
if (((uwTick) & 7) == 4) { // every 8ms
282+
NVIC->STIR = PVD_IRQn;
283+
}
284+
#endif
285+
280286
if (STORAGE_IDLE_TICK(uwTick)) {
281287
NVIC->STIR = FLASH_IRQn;
282288
}
@@ -425,6 +431,10 @@ void EXTI15_10_IRQHandler(void) {
425431
}
426432

427433
void PVD_IRQHandler(void) {
434+
#if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
435+
extern void USBD_CDC_HAL_TIM_PeriodElapsedCallback(void);
436+
USBD_CDC_HAL_TIM_PeriodElapsedCallback();
437+
#endif
428438
Handle_EXTI_Irq(EXTI_PVD_OUTPUT);
429439
}
430440

@@ -465,7 +475,11 @@ void TIM2_IRQHandler(void) {
465475
}
466476

467477
void TIM3_IRQHandler(void) {
478+
#if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
479+
timer_irq_handler(3);
480+
#else
468481
HAL_TIM_IRQHandler(&TIM3_Handle);
482+
#endif
469483
}
470484

471485
void TIM4_IRQHandler(void) {

stmhal/timer.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,12 @@ TIM_HandleTypeDef *timer_tim6_init(uint freq) {
250250

251251
// Interrupt dispatch
252252
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
253+
#if !defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
253254
if (htim == &TIM3_Handle) {
254255
USBD_CDC_HAL_TIM_PeriodElapsedCallback();
255-
} else if (htim == &TIM5_Handle) {
256+
} else
257+
#endif
258+
if (htim == &TIM5_Handle) {
256259
servo_timer_irq_callback();
257260
}
258261
}
@@ -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
653656
switch (tim->tim_id) {
654657
case 1: tim->tim.Instance = TIM1; tim->irqn = TIM1_UP_TIM10_IRQn; break;
655658
case 2: tim->tim.Instance = TIM2; tim->irqn = TIM2_IRQn; tim->is_32bit = true; break;
659+
#if defined(MICROPY_HW_USE_ALT_IRQ_FOR_CDC)
660+
case 3: tim->tim.Instance = TIM3; tim->irqn = TIM3_IRQn; break;
661+
#else
656662
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
663+
#endif
657664
case 4: tim->tim.Instance = TIM4; tim->irqn = TIM4_IRQn; break;
658665
case 5: tim->tim.Instance = TIM5; tim->irqn = TIM5_IRQn; tim->is_32bit = true; break;
659666
#if defined(TIM6)

0 commit comments

Comments
 (0)