not logged in | [Login]

Ref STMHAL: https://github.com/micropython/micropython/blob/master/stmhal/hal/src/stm32f4xx_hal_tim.c

There are 14 Timers (1-14) each attached to one of two peripheral clocks, the speed of which is held in the last two values in pyb.freq().

Return the speed of a timer;

def tim_clockspeed(tim):
  if tim in [1,8,9,10,11]:
    return pyb.freq()[3]
  elif tim in [2,3,4,5,6,7,12,13,14]:
    return pyb.freq()[2]
  else:
    raise ValueError('Invalid timer number specified')

the Timer peripherals

TIM1 On Peripheral APB2 = Clock 2 = 84MHz = 84000000Hz = pyb.freq()[3]

TIM2 On Peripheral APB1 = Clock 1 = 42MHz = 42,000,000Hz = pyb.freq()[2]

TIM3 On Peripheral APB1 = Clock 1 = 42MHz = 42,000,000Hz = pyb.freq()[2]

TIM4 On Peripheral APB1 = Clock 1 = 42MHz = 42,000,000Hz = pyb.freq()[2]

TIM5 On Peripheral APB1 = Clock 1 = 42MHz = 42,000,000Hz = pyb.freq()[2]

TIM6 On Peripheral APB1 = Clock 1 = 42MHz = 42,000,000Hz = pyb.freq()[2]

TIM7 On Peripheral APB1 = Clock 1 = 42MHz = 42,000,000Hz = pyb.freq()[2]

TIM8 On Peripheral APB2 = Clock 2 = 84MHz = 84000000Hz = pyb.freq()[3]

TIM9 On Peripheral APB2 = Clock 2 = 84MHz = 84000000Hz = pyb.freq()[3]

TIM10 On Peripheral APB2 = Clock 2 = 84MHz = 84000000Hz = pyb.freq()[3]

TIM11 On Peripheral APB2 = Clock 2 = 84MHz = 84000000Hz = pyb.freq()[3]

TIM12 On Peripheral APB1 = Clock 1 = 42MHz = 42,000,000Hz = pyb.freq()[2]

TIM13 On Peripheral APB1 = Clock 1 = 42MHz = 42,000,000Hz = pyb.freq()[2]

TIM14 On Peripheral APB1 = Clock 1 = 42MHz = 42,000,000Hz = pyb.freq()[2]

the Timer Offsets

TIM_CR1 Control Register 1 (32bit) - a field-mask value, fields;

CEN     0x0001  0b0000000001        Counter enable       
UDIS    0x0002  0b0000000010        Update disable       
URS     0x0004  0b0000000100        Update request source
OPM     0x0008  0b0000001000        One pulse mode       
DIR     0x0010  0b0000010000        Direction            
CMS     0x0060  0b0001100000        CMS[1:0] bits (Center-aligned mode selection)
ARPE    0x0080  0b0010000000        Auto-reload preload enable    
CKD     0x0300  0b1100000000        CKD[1:0] bits (clock division)

This is set to 1 on initialised timers, including LED4, toggling it on a generic timer with callback stops/starts the callback, setting it to zero on TIM3 with pwm running crashes the board ... but both pwm on LED(4) and callbacks on other times still run)

TIM_CR2 Control Register 2 (32 bit) - a field-mask value, fields;

CCPC    0x0001  0b000000000000001   Capture/Compare Preloaded Control       
CCUS    0x0004  0b000000000000010   Capture/Compare Control Update Selection
CCDS    0x0008  0b000000000001000   Capture/Compare DMA Selection           
MMS     0x0070  0b000000001110000   MMS[2:0] bits (Master Mode Selection)
TI1S    0x0080  0b000000010000000   TI1 Selection
OIS1    0x0100  0b000000100000000   Output Idle state 1 (OC1 output) 
OIS1N   0x0200  0b000001000000000   Output Idle state 1 (OC1N output)
OIS2    0x0400  0b000010000000000   Output Idle state 2 (OC2 output) 
OIS2N   0x0800  0b000100000000000   Output Idle state 2 (OC2N output)
OIS3    0x1000  0b001000000000000   Output Idle state 3 (OC3 output) 
OIS3N   0x2000  0b010000000000000   Output Idle state 3 (OC3N output)
OIS4    0x4000  0b100000000000000   Output Idle state 4 (OC4 output) 

TIM_SMCR Slave Mode Control Register (32 bit) - a field-mask value, fields;

SMS     0x0007  0b0000000000000111  SMS[2:0] bits (Slave mode selection)   
TS      0x0070  0b0000000011100000  TS[2:0] bits (Trigger selection)       
MSM     0x0080  0b0000000010000000  Master/slave mode                      
ETF     0x0F00  0b0000111100000000  ETF[3:0] bits (External trigger filter)
ETPS    0x3000  0b0011000000000000  ETPS[1:0] bits (External trigger prescaler)
ECE     0x4000  0b0100000000000000  External clock enable    
ETP     0x8000  0b1000000000000000  External trigger polarity

Not found to be set on any investigated use case ...

TIM_DIER DMA/Interrupt enable register (32 bit) - a field-mask value, fields;

UIE     0x0001  0b000000000000001   Update interrupt enable
CC1IE   0x0002  0b000000000000010   Capture/Compare 1 interrupt enable  
CC2IE   0x0004  0b000000000000100   Capture/Compare 2 interrupt enable  
CC3IE   0x0008  0b000000000001000   Capture/Compare 3 interrupt enable  
CC4IE   0x0010  0b000000000010000   Capture/Compare 4 interrupt enable  
COMIE   0x0020  0b000000000100000   COM interrupt enable                
TIE     0x0040  0b000000001000000   Trigger interrupt enable            
BIE     0x0080  0b000000010000000   Break interrupt enable              
UDE     0x0100  0b000000100000000   Update DMA request enable           
CC1DE   0x0200  0b000001000000000   Capture/Compare 1 DMA request enable
CC2DE   0x0400  0b000010000000000   Capture/Compare 2 DMA request enable
CC3DE   0x0800  0b000100000000000   Capture/Compare 3 DMA request enable
CC4DE   0x1000  0b001000000000000   Capture/Compare 4 DMA request enable
COMDE   0x2000  0b010000000000000   COM DMA request enable              
TDE     0x4000  0b100000000000000   Trigger DMA request enable          

appears to affect calling of callback, first bit of both TIM_DIER and TIM_DMAR for a Timer must be set(1) for the callback to be called. When a Timer is initialised via uPy pyb module t4=pyb.Timer(4).init(freq=5) this fields value is initially 0, when a callback is initialised l4.callback(lambda t:pyb.LED(1).toggle()) it's set to 1. Can switch the callback on and off by setting this value e.g. Off: stm.mem32[stm.TIM4+stm.TIM_DIER]=0 and On: stm.mem32[stm.TIM4+stm.TIM_DIER]=1

TIM_SR Status Register (32bit - Read Only) - a field-mask value, fields;

UIF     0x0001  0b0000000000001     Update interrupt Flag             
CC1IF   0x0002  0b0000000000010     Capture/Compare 1 interrupt Flag  
CC2IF   0x0004  0b0000000000100     Capture/Compare 2 interrupt Flag  
CC3IF   0x0008  0b0000000001000     Capture/Compare 3 interrupt Flag  
CC4IF   0x0010  0b0000000010000     Capture/Compare 4 interrupt Flag  
COMIF   0x0020  0b0000000100000     COM interrupt Flag                
TIF     0x0040  0b0000001000000     Trigger interrupt Flag            
BIF     0x0080  0b0000010000000     Break interrupt Flag              
CC1OF   0x0200  0b0001000000000     Capture/Compare 1 Overcapture Flag
CC2OF   0x0400  0b0010000000000     Capture/Compare 2 Overcapture Flag
CC3OF   0x0800  0b0100000000000     Capture/Compare 3 Overcapture Flag
CC4OF   0x1000  0b1000000000000     Capture/Compare 4 Overcapture Flag

_appears to have some relation to the clock the timer is attached to (once timer init'd via uPy pyb module), does a value of;

  • 30 indicate APB2 @ 84MHz, and;
  • 31 indicate = APB1 @ 42MHz ???_

TIM_EGR Event Generation Register (32 bit) - a field-mask value, fields;

UG      0x01    0b00000001      Update Generation                        
CC1G    0x02    0b00000010      Capture/Compare 1 Generation             
CC2G    0x04    0b00000100      Capture/Compare 2 Generation             
CC3G    0x08    0b00001000      Capture/Compare 3 Generation             
CC4G    0x10    0b00010000      Capture/Compare 4 Generation             
COMG    0x20    0b00100000      Capture/Compare Control Update Generation
TG      0x40    0b01000000      Trigger Generation                       
BG      0x80    0b10000000      Break Generation                         

TIM_CCMR1 24 0x18 0b11000 TIM Capture/Compare Mode register 1 / int32 This is set to 0x68 on TIM3 (on boot) But not set on a generic timer with/without callback ??? is this related to association with a GPIO channel ??? ??? might be 4 bits per channel configuration ??? ??? 0x68 on CCMR1 = 0b 1101 000 ??? ??? Timer mode for the second of 'something' = 1101 ??? CC1S 0x0003 0b0000000000000011 CC1S[1:0] bits (Capture/Compare 1 Selection) OC1FE 0x0004 0b0000000000000100 Output Compare 1 Fast enable
OC1PE 0x0008 0b0000000000001000 Output Compare 1 Preload enable
OC1M 0x0070 0b0000000001110000 OC1M[2:0] bits (Output Compare 1 Mode)
OC1CE 0x0080 0b0000000010000000 Output Compare 1 Clear Enable
CC2S 0x0300 0b0000001100000000 CC2S[1:0] bits (Capture/Compare 2 Selection) OC2FE 0x0400 0b0000010000000000 Output Compare 2 Fast enable
OC2PE 0x0800 0b0000100000000000 Output Compare 2 Preload enable
OC2M 0x7000 0b0111000000000000 OC2M[2:0] bits (Output Compare 2 Mode)
OC2CE 0x8000 0b1000000000000000 Output Compare 2 Clear Enable different mode?-------------------------------------------------- IC1PSC 0x000C 0b0000000000001100 IC1PSC[1:0] bits (Input Capture 1 Prescaler) IC1F 0x00F0 0b0000000011110000 IC1F[3:0] bits (Input Capture 1 Filter)
IC2PSC 0x0C00 0b0000110000000000 IC2PSC[1:0] bits (Input Capture 2 Prescaler) IC2F 0xF000 0b1111000000000000 IC2F[3:0] bits (Input Capture 2 Filter)
TIM_CCMR2 28 0x1c 0b11100 TIM Capture/Compare Mode Register 2 / int32 Not set ...
??? extension of above, another 4 bits per GPIO channel??? CC3S 0x0003 0b0000000000000011 CC3S[1:0] bits (Capture/Compare 3 Selection) OC3FE 0x0004 0b0000000000000100 Output Compare 3 Fast enable
OC3PE 0x0008 0b0000000000001000 Output Compare 3 Preload enable
OC3M 0x0070 0b0000000001110000 OC3M[2:0] bits (Output Compare 3 Mode) OC3CE 0x0080 0b0000000010000000 Output Compare 3 Clear Enable CC4S 0x0300 0b0000001100000000 CC4S[1:0] bits (Capture/Compare 4 Selection) OC4FE 0x0400 0b0000010000000000 Output Compare 4 Fast enable
OC4PE 0x0800 0b0000100000000000 Output Compare 4 Preload enable OC4M 0x7000 0b0111000000000000 OC4M[2:0] bits (Output Compare 4 Mode) OC4CE 0x8000 0b1000000000000000 Output Compare 4 Clear Enable different mode? -------------------------------------------------- IC3PSC 0x000C 0b0000000000001100 IC3PSC[1:0] bits (Input Capture 3 Prescaler) IC3F 0x00F0 0b0000000011110000 IC3F[3:0] bits (Input Capture 3 Filter) IC4PSC 0x0C00 0b0000110000000000 IC4PSC[1:0] bits (Input Capture 4 Prescaler) IC4F 0xF000 0b1111000000000000 IC4F[3:0] bits (Input Capture 4 Filter) TIM_CCER 32 0x20 0b100000 TIM Capture/Compare Enable Register / int32 This is set to 1 on TIM3 associated with pwm'able LED4 But set to 0 on generic initialised Timer's Set/unsetting it switches LED4 on/off .. No affect on generic callback timers, but it is not read only CC1E 0x0001 0b000000000000001 Capture/Compare 1 output enable
CC1P 0x0002 0b000000000000010 Capture/Compare 1 output Polarity
CC1NE 0x0004 0b000000000000100 Capture/Compare 1 Complementary output enable
CC1NP 0x0008 0b000000000001000 Capture/Compare 1 Complementary output Polarity CC2E 0x0010 0b000000000010000 Capture/Compare 2 output enable
CC2P 0x0020 0b000000000100000 Capture/Compare 2 output Polarity
CC2NE 0x0040 0b000000001000000 Capture/Compare 2 Complementary output enable
CC2NP 0x0080 0b000000010000000 Capture/Compare 2 Complementary output Polarity CC3E 0x0100 0b000000100000000 Capture/Compare 3 output enable
CC3P 0x0200 0b000001000000000 Capture/Compare 3 output Polarity
CC3NE 0x0400 0b000010000000000 Capture/Compare 3 Complementary output enable
CC3NP 0x0800 0b000100000000000 Capture/Compare 3 Complementary output Polarity CC4E 0x1000 0b001000000000000 Capture/Compare 4 output enable
CC4P 0x2000 0b010000000000000 Capture/Compare 4 output Polarity
CC4NP 0x8000 0b100000000000000 0Capture/Compare 4 Complementary output Polarity TIM_CNT 36 0x24 0b100100 TIM Counter Register / int32 The value of the timer counter Can also be reset i.e. to restart the clock interesting possibilities for setting in a callback? TIM_PSC 40 0x28 0b101000 TIM Prescalar Register / int32 period, prescalar and source clock speed define time it takes for timer to 'wrap' to zero (optionally triggering an interrupt) #https://github.com/micropython/micropython/blob/master/stmhal/timer.c def calc(timer, freq): if timer in [1,8,9,10,11]: clk_speed = pyb.freq()[3] elif timer in [2,3,4,5,6,7,12,13,14]: clk_speed = pyb.freq()[2] period = max(1, int(2 * clk_speed / freq)) prescalar = 1 while period > 0xffff: period >>= 1 prescalar <<= 1 prescalar -= 1 period -= 1 return (prescalar, period)

      !!! Need to reverse engineer this to understand settings of TIM3 !!!

TIM_ARR 44 0x2c 0b101100 TIM Auto Reload Register (aka PERIOD) / int32 period, prescalar and source clock speed define time it takes for timer to 'wrap' to zero (optionally triggering an interrupt) This is set to 0x270f on TIM3 (on boot) TIM_RCR 48 0x30 0b110000 TIM Repition Counter Register / int32 Not set on any investigated use case ... TIM_CCR1 52 0x34 0b110100 TIM_CCR2 56 0x38 0b111000 TIM_CCR3 60 0x3c 0b111100 TIM_CCR4 64 0x40 0b1000000 TIM Capture/Compare Registers / int32 For LED4 TIM3.TIM_CCR1 is the duty-cycle of the PWM signal TIM_BDTR 68 0x44 0b1000100 TIM Break and Dead-Time Register / int32 Not set on any investigated use case ... Read Only DTG 0x00FF 0b0000000011111111 DTG[0:7] bits (Dead-Time Generator set-up) LOCK 0x0300 0b0000001100000000 LOCK[1:0] bits (Lock Configuration) OSSI 0x0400 0b0000010000000000 Off-State Selection for Idle mode OSSR 0x0800 0b0000100000000000 Off-State Selection for Run mode BKE 0x1000 0b0001000000000000 Break enable
BKP 0x2000 0b0010000000000000 Break Polarity
AOE 0x4000 0b0100000000000000 Automatic Output enable
MOE 0x8000 0b1000000000000000 Main Output enable
TIM_DCR 72 0x48 0b1001000 TIM DMA Control Register / int32 Not set on any investigated use case ... Toggling it appears to have no effect, but it is read/write DBA 0x001F 0b0000000011111 DBA[4:0] bits (DMA Base Address) DBL 0x1F00 0b1111100000000 DBL[4:0] bits (DMA Burst Length) TIM_DMAR 76 0x4c 0b1001100 TIM DMA Address for Full Transfer (DMA register for burst access) / int32 ??? affects calling of callback TIM_DIER = TIM_DMAR = 1 for callback to run set to 1 when timer init'd (and not changed by uPy when callback attached) 1 - call callback 0 - don't call callback TIM_OR 80 0x50 0b1010000 TIM Option Register / int32 Not set on any investigated use case ... TI4_RMP 0x00C0 0b000011000000 TI4_RMP[1:0] bits (TIM5 Input 4 remap)
ITR1_RMP 0x0C00 0b110000000000 ITR1_RMP[1:0] bits (TIM2 Internal trigger 1 remap)