not logged in | [Login]


The stm module is very interesting ... it exposes access directly to the MCU's memory (to read and set values) and a whole heap of constants that make it trivial to peer into and influence the behaviour of the MCU's hardware peripherals directly.

directly access MCU memory

Three objects are exposed;

  • stm.mem8 - access 8 bits of memory (right aligned in a 32bit word?)
  • stm.mem16 - access 16 bits of memory (right aligned in a 32bit word?)
  • stm.mem32 - access a 32 bit word of memory

In combination with the constants described hereunder they can be used to read, and write, to the control (and monitoring) registers of the MCU's hardware peripherals, and perhaps all other areas of MCU memory(?).


stm.mem32[stm.TIM3 + stm.TIM_CR1] 
#return the contents of Timer 3's Control Register 1 (yes Timer 3 - one of the ones that uPy won't let you access with pyb.Timer
stm.mem32[stm.TIM3 + stm.TIM_CR1] = value
#yes ... set the value of Timer 3's Control Register 1

Of course, it goes without saying - tinkering around at this level is inevitably going to crash the pyboard more than occasionally, but the likelihood of you permanently damaging it is relatively low.

peripheral+offset constants

The stm module exposes a lot of constants ... generally of two types;

  • start of the sequence of memory addresses associated with a particular instance of a peripheral class, for example;

    • stm.TIM1 - the starting address of the block assigned to Timer 1
    • stm.GPIOA - the starting address of the block assigned to General Purpose IO peripheral A
  • offsets (from a starting address) for each class of peripherals specific settings memory blocks, for example;

    • stm.TIM_CR1 - Timer Control Register 1 offset (stm.TIM1 + stm.TIM_CR1 is Timer 1's Control Register 1 address, and stm.TIM2 + stm.TIM_CR1 is Timer 2's Control Register 1 address)

The value at each peripheral+offset address generally (so far) takes the form of either;

  • a 32 bit (or smaller) number - for example; stm.TIM1 + stm.TIM_ARR (ARR = Auto Reload Register) is the value of Timer 1's Period (uPy; pyb.Timer(1).init(prescaler=x, period=y) )

  • a 32 bit (or smaller) set of flags i.e. each bit (or sub-groupings of bits) indicates whether (simple 1 bit case) some setting or other is on/off (1/0) ... larger sub-groupings of bits can hold more options for the particular setting i.e. 2 bits can hold up to 4 options for the setting etc.

The stm module doesn't break out bitmasks for these sub-word settings, but their details can be found in this stmhal header source starting around line 1078. Some peripheral class flag masks (from this source file) have been translated into uPy module(s);

the constants