@@ -414,6 +414,59 @@ STATIC mp_obj_t compute_percent_from_pwm_value(uint32_t period, uint32_t cmp) {
414414#endif
415415}
416416
417+ // Computes the 8-bit value for the DTG field in the BDTR register.
418+ //
419+ // 1 tick = 1 count of the timer's clock (source_freq) divided by div.
420+ // 0-128 ticks in inrements of 1
421+ // 128-256 ticks in increments of 2
422+ // 256-512 ticks in increments of 8
423+ // 512-1008 ticks in increments of 16
424+ STATIC uint32_t compute_dtg_from_ticks (mp_int_t ticks ) {
425+ if (ticks <=0 ) {
426+ return 0 ;
427+ }
428+ if (ticks < 128 ) {
429+ return ticks ;
430+ }
431+ if (ticks < 256 ) {
432+ return 0x80 | ((ticks - 128 ) /2 );
433+ }
434+ if (ticks < 512 ) {
435+ return 0xC0 | ((ticks - 256 ) /8 );
436+ }
437+ if (ticks < 1008 ) {
438+ return 0xE0 | ((ticks - 512 ) /16 );
439+ }
440+ return 0xFF ;
441+ }
442+
443+ // Given the 8-bit value stored in the DTG field of the BDTR register, compute
444+ // the number of ticks.
445+ STATIC mp_int_t compute_ticks_from_dtg (uint32_t dtg ) {
446+ if ((dtg & 0x80 )== 0 ) {
447+ return dtg & 0x7F ;
448+ }
449+ if ((dtg & 0xC0 )== 0x80 ) {
450+ return 128 + ((dtg & 0x3F )* 2 );
451+ }
452+ if ((dtg & 0xE0 )== 0xC0 ) {
453+ return 256 + ((dtg & 0x1F )* 8 );
454+ }
455+ return 512 + ((dtg & 0x1F )* 16 );
456+ }
457+
458+ STATIC void config_deadtime (pyb_timer_obj_t * self ,mp_int_t ticks ) {
459+ TIM_BreakDeadTimeConfigTypeDef deadTimeConfig ;
460+ deadTimeConfig .OffStateRunMode = TIM_OSSR_DISABLE ;
461+ deadTimeConfig .OffStateIDLEMode = TIM_OSSI_DISABLE ;
462+ deadTimeConfig .LockLevel = TIM_LOCKLEVEL_OFF ;
463+ deadTimeConfig .DeadTime = compute_dtg_from_ticks (ticks );
464+ deadTimeConfig .BreakState = TIM_BREAK_DISABLE ;
465+ deadTimeConfig .BreakPolarity = TIM_BREAKPOLARITY_LOW ;
466+ deadTimeConfig .AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE ;
467+ HAL_TIMEx_ConfigBreakDeadTime (& self -> tim ,& deadTimeConfig );
468+ }
469+
417470STATIC void pyb_timer_print (void (* print )(void * env ,const char * fmt , ...),void * env ,mp_obj_t self_in ,mp_print_kind_t kind ) {
418471pyb_timer_obj_t * self = self_in ;
419472
@@ -424,7 +477,7 @@ STATIC void pyb_timer_print(void (*print)(void *env, const char *fmt, ...), void
424477uint32_t period = __HAL_TIM_GetAutoreload (& self -> tim )& TIMER_CNT_MASK (self );
425478// for efficiency, we compute and print freq as an int (not a float)
426479uint32_t freq = timer_get_source_freq (self -> tim_id ) / ((prescaler + 1 )* (period + 1 ));
427- print (env ,"Timer(%u, freq=%u, prescaler=%u, period=%u, mode=%s, div=%u) " ,
480+ print (env ,"Timer(%u, freq=%u, prescaler=%u, period=%u, mode=%s, div=%u" ,
428481self -> tim_id ,
429482freq ,
430483prescaler ,
@@ -433,6 +486,10 @@ STATIC void pyb_timer_print(void (*print)(void *env, const char *fmt, ...), void
433486self -> tim .Init .CounterMode == TIM_COUNTERMODE_DOWN ?"DOWN" :"CENTER" ,
434487self -> tim .Init .ClockDivision == TIM_CLOCKDIVISION_DIV4 ?4 :
435488self -> tim .Init .ClockDivision == TIM_CLOCKDIVISION_DIV2 ?2 :1 );
489+ if (IS_TIM_ADVANCED_INSTANCE (self -> tim .Instance )) {
490+ print (env ,", deadtime=%u" ,compute_ticks_from_dtg (self -> tim .Instance -> BDTR & TIM_BDTR_DTG ));
491+ }
492+ print (env ,")" );
436493 }
437494}
438495
@@ -472,6 +529,14 @@ STATIC void pyb_timer_print(void (*print)(void *env, const char *fmt, ...), void
472529///
473530/// - `callback` - as per Timer.callback()
474531///
532+ /// - `deadtime` - specifies the amount of "dead" or inactive time between
533+ /// transitions on complimentary channels (both channels will be inactive)
534+ /// for this time). `deadtime` may be an integer between 0 and 1008, with
535+ /// the following restrictions: 0-128 in steps of 1. 128-256 in steps of
536+ /// 2, 256-512 in steps of 8, and 512-1008 in steps of 16. `deadime`
537+ /// measures ticks of `source_freq` divided by `div` clock ticks.
538+ /// `deadtime` is only available on timers 1 and 8.
539+ ///
475540/// You must either specify freq or both of period and prescaler.
476541STATIC mp_obj_t pyb_timer_init_helper (pyb_timer_obj_t * self ,mp_uint_t n_args ,const mp_obj_t * pos_args ,mp_map_t * kw_args ) {
477542static const mp_arg_t allowed_args []= {
@@ -481,6 +546,7 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, mp_uint_t n_args, c
481546 {MP_QSTR_mode ,MP_ARG_KW_ONLY |MP_ARG_INT , {.u_int = TIM_COUNTERMODE_UP } },
482547 {MP_QSTR_div ,MP_ARG_KW_ONLY |MP_ARG_INT , {.u_int = 1 } },
483548 {MP_QSTR_callback ,MP_ARG_KW_ONLY |MP_ARG_OBJ , {.u_obj = mp_const_none } },
549+ {MP_QSTR_deadtime ,MP_ARG_KW_ONLY |MP_ARG_INT , {.u_int = 0 } },
484550 };
485551
486552// parse args
@@ -537,6 +603,9 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, mp_uint_t n_args, c
537603
538604// init TIM
539605HAL_TIM_Base_Init (& self -> tim );
606+ if (IS_TIM_ADVANCED_INSTANCE (self -> tim .Instance )) {
607+ config_deadtime (self ,args [6 ].u_int );
608+ }
540609if (args [5 ].u_obj == mp_const_none ) {
541610HAL_TIM_Base_Start (& self -> tim );
542611 }else {
@@ -685,6 +754,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_timer_deinit_obj, pyb_timer_deinit);
685754/// - `Timer.FALLING` - captures on falling edge.
686755/// - `Timer.BOTH` - captures on both edges.
687756///
757+ /// Note that capture only works on the primary channel, and not on the
758+ /// complimentary channels.
759+ ///
688760/// PWM Example:
689761///
690762/// timer = pyb.Timer(2, freq=1000)
@@ -808,6 +880,10 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp
808880 }else {
809881HAL_TIM_PWM_Start_IT (& self -> tim ,TIMER_CHANNEL (chan ));
810882 }
883+ // Start the complimentary channel too (if its supported)
884+ if (IS_TIM_CCXN_INSTANCE (self -> tim .Instance ,TIMER_CHANNEL (chan ))) {
885+ HAL_TIMEx_PWMN_Start (& self -> tim ,TIMER_CHANNEL (chan ));
886+ }
811887break ;
812888 }
813889
@@ -824,7 +900,11 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp
824900if (oc_config .OCPolarity == 0xffffffff ) {
825901oc_config .OCPolarity = TIM_OCPOLARITY_HIGH ;
826902 }
827- oc_config .OCNPolarity = TIM_OCNPOLARITY_HIGH ;
903+ if (oc_config .OCPolarity == TIM_OCPOLARITY_HIGH ) {
904+ oc_config .OCNPolarity = TIM_OCNPOLARITY_HIGH ;
905+ }else {
906+ oc_config .OCNPolarity = TIM_OCNPOLARITY_LOW ;
907+ }
828908oc_config .OCFastMode = TIM_OCFAST_DISABLE ;
829909oc_config .OCIdleState = TIM_OCIDLESTATE_SET ;
830910oc_config .OCNIdleState = TIM_OCNIDLESTATE_SET ;
@@ -838,6 +918,10 @@ STATIC mp_obj_t pyb_timer_channel(mp_uint_t n_args, const mp_obj_t *pos_args, mp
838918 }else {
839919HAL_TIM_OC_Start_IT (& self -> tim ,TIMER_CHANNEL (chan ));
840920 }
921+ // Start the complimentary channel too (if its supported)
922+ if (IS_TIM_CCXN_INSTANCE (self -> tim .Instance ,TIMER_CHANNEL (chan ))) {
923+ HAL_TIMEx_OCN_Start (& self -> tim ,TIMER_CHANNEL (chan ));
924+ }
841925break ;
842926 }
843927