STM32 gotchas
114. Some TIM register fields are not continuous

Timers are one of the few peripherals in STM32 which is featured in every STM32 family, yet maintains a consistent set of features and registers across the entire STM32 realm (in contrast with GPIO and RTC which in 'F1 are very different from the rest, the two different incarnations of I2C, or the ADC which is different in perhaps every family). Of course, timers have also seen development, and that means, that some of the bitfields in its registers have been expanded and don't fit into the slot they have been assigned originally.

So in newer versions, ST simply added bits to these bitfields elsewhere in the same register, thus creating a non-continuous field of bits.

For examples, let's have a look at STM32G4, which is the newest STM32 family intended for mixed-signal applications e.g. motor control, where timers play a prominent role:

These additional bits are of course OK, but an unaware user might be caught by surprise, if trying to use them as a continuous field. And, unfortunately, not all RMs point out clearly this fact in the description of given bitfield, e.g. as of writing this text, RM0316 rev.8 for the STM32F303, which was probably the first family to feature 4-bit TIMx_SMCR.SMS).

When writing to these bits, the usual AND/OR/SHIFT scheme still can be used - and the CMSIS-mandated device headers indeed define the respective masks to conform to this scheme, e.g.

  #define TIM_SMCR_TS_Pos           (4U)
  #define TIM_SMCR_TS_Msk           (0x30007UL << TIM_SMCR_TS_Pos)               /*!< 0x00300070 */
however, the bitfield values have to be constructed equally carefully
// legacy TS values
  #define  TIM_SMCR_TS__ITR0                   0  // internal interconnections, concrete values defined elsewhere
  #define  TIM_SMCR_TS__ITR1                   1
  #define  TIM_SMCR_TS__ITR2                   2
  #define  TIM_SMCR_TS__ITR3                   3
  #define  TIM_SMCR_TS__TI1F_ED                4  // both edges on CH1 input
  #define  TIM_SMCR_TS__TI1FP1                 5  // TI1FP1 with the same polarity as if CH1 used for capturing in CC1
  #define  TIM_SMCR_TS__TI2FP2                 6  // TI2FP2 with the same polarity as if CH2 used for capturing in CC2
  #define  TIM_SMCR_TS__ETRF                   7  // external trigger input
// extended TS values
  #define  TIM_SMCR_TS__ITR4                   ((1 << 20) + 0)  // internal interconnections, concrete values defined elsewhere
  #define  TIM_SMCR_TS__ITR5                   ((1 << 20) + 1)
  #define  TIM_SMCR_TS__ITR6                   ((1 << 20) + 2)
  [... etc....]

// product/family-specific interconnects for 'G4
  #define  TIM2_SMCR_TS__TIM1_TRGO                  TIM_SMCR_TS__ITR0
  #define  TIM2_SMCR_TS__TIM3_TRGO                  TIM_SMCR_TS__ITR2
  #define  TIM2_SMCR_TS__TIM4_TRGO                  TIM_SMCR_TS__ITR3
  #define  TIM2_SMCR_TS__TIM5_TRGO                  TIM_SMCR_TS__ITR4
  #define  TIM2_SMCR_TS__TIM8_TRGO                  TIM_SMCR_TS__ITR5
  [... etc....]

// and this allows to write
  TIM2->SMCR = (TIM2->SMCR & ~TIM_SMCR_TS_Msk) | (TIM2_SMCR_TS__TIM5_TRGO << TIM_SMCR_TS_Pos);

A maybe less important implication of these extra bits is, that they change the respective registers from 16-bit to 32-bit. This has to be borne in mind for example if the registers are written using DMA.