Controlling Slew Rate of GPIO

The official pyboard running MicroPython.
This is the reference design and main target board for MicroPython.
You can buy one at the store.
Target audience: Users with a pyboard.
jarraneil
Posts: 2
Joined: Wed Mar 28, 2018 10:16 pm

Controlling Slew Rate of GPIO

Post by jarraneil » Wed Mar 28, 2018 10:29 pm

Is there any way (other than assembler) to slow down the slew rate on GPIO (specifically the clock on the SPI bus). The GPIO_InitStructure.GPIO_Speed register allows for the following options

GPIO_Speed_2MHz /*!< Low speed */
GPIO_Speed_25MHz /*!< Medium speed */
GPIO_Speed_50MHz /*!< Fast speed */
GPIO_Speed_100MHz

I would like low speed mode to reduce reflections and ringing on the SPI bus

User avatar
dhylands
Posts: 3821
Joined: Mon Jan 06, 2014 6:08 pm
Location: Peachland, BC, Canada
Contact:

Re: Controlling Slew Rate of GPIO

Post by dhylands » Thu Mar 29, 2018 12:01 am

You can manipulate registers directly from python using the stm module.

Let's say that you wanted to control SPI1's MOSI pin, which is pin A7. The stm module provides stm.GPIOA which is the port A base register, and stm.GPIO_OSPEEDR is an offset from the base to get to the OSPEEDR register.

The OSPEEDR register is arranged as 16 2-bit fields, one field for each pin.

To set the speed medium speed (bit pattern 0b01) you could do something like this:

Code: Select all

ospeedr = stm.mem32[stm.GPIOA + stm.GPIO_OSPEEDR]
ospeedr &= ~(0b11 << 14)	# Clear the 2 bit field for bit 7
ospeedr |= 0b01 << 14		# Set the 2 bit field for bit 7 to 0b01 (medium)
stm.mem32[stm.GPIOA + stm.GPIO_OSPEEDR] = ospeedr
You can also generalize this a bit. The Pin module provides a pin() method which returns the pin number, and the gpio() method returns the base address of the gpio port associated with the pin. I just noticed that the gpio() function needs to be masked with 0x7fffffff in order to get the correct value (carryover from how small ints are represented). So you could also do:

Code: Select all

pin = pyb.Pin('A7')
ospeedr_addr = (pin.gpio() & 0x7fffffff) + stm.GPIO_OSPEEDR
ospeed_shift = pin.pin() * 2
ospeedr = stm.mem32[ospeedr_addr]
ospeedr &= (~0b11 << ospeedr_shift
ospeedr |= 0b01 << ospeedr_shift
stm.mem32[ospeedr_addr] = ospeedr

jarraneil
Posts: 2
Joined: Wed Mar 28, 2018 10:16 pm

Re: Controlling Slew Rate of GPIO

Post by jarraneil » Thu Mar 29, 2018 1:22 am

Thanks for the excellent reply Dave. I look forward to trying this when I am back in front of the hardware tomorrow.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Controlling Slew Rate of GPIO

Post by pythoncoder » Fri Mar 30, 2018 4:38 am

I'd be interested to know if speed selection actually affects the slew rate. The datasheets I have are non-committal on this, with slew rate values being 'TBD'. The output port block diagram rather suggests that it might have no effect.

Another option if it fails would be a CR network, maybe try something like 220Ω and 100pF?
Peter Hinch
Index to my micropython libraries.

chuckbook
Posts: 135
Joined: Fri Oct 30, 2015 11:55 pm

Re: Controlling Slew Rate of GPIO

Post by chuckbook » Fri Mar 30, 2018 5:56 pm

Usually variable output speeds are implemented with several FETs of different size which results in different Rdson and gate capacity.
This allows different driver strengths and in consequence different output speeds. A typical application is to reduce EMI by avoiding excessive slope rates.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Controlling Slew Rate of GPIO

Post by pythoncoder » Sat Mar 31, 2018 8:11 am

Clever. However this would presumably cause the maximum drive current to be a function of speed and the STM data sheet I have makes no suggestion of this
The GPIOs (general purpose input/outputs) can sink or source up to ±8 mA, and sink or
source up to ±20 mA (with a relaxed V OL /V OH ) except PC13, PC14 and PC15 which can
sink or source up to ±3mA. When using the PC13 to PC15 GPIOs in output mode, the
speed should not exceed 2 MHz with a maximum load of 30 pF.
It goes on to talk about the number of pins that can source or sink on multiple pins but I can see no reference to frequency. So I remain rather puzzled about this :?

[EDIT]
Thinking about this some more, if a pin can sink or source 20mA that implies a slew rate into a 20pF load of 1V/ns. Which is pretty quick.
Peter Hinch
Index to my micropython libraries.

chuckbook
Posts: 135
Joined: Fri Oct 30, 2015 11:55 pm

Re: Controlling Slew Rate of GPIO

Post by chuckbook » Tue Apr 03, 2018 9:59 am

The key phrase is "(with a relaxed V OL/V OH)". In fact at least on STM32 devices we tested the speed of a GPIO output affects Rds. Which means you can source 20 mA but the voltage drops more or less depending on the output speed.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Controlling Slew Rate of GPIO

Post by pythoncoder » Wed Apr 04, 2018 6:59 am

I'd be interested to hear the outcome of actual measurements. My DSO is far too slow to time such fast edges.
Peter Hinch
Index to my micropython libraries.

chuckbook
Posts: 135
Joined: Fri Oct 30, 2015 11:55 pm

Re: Controlling Slew Rate of GPIO

Post by chuckbook » Wed Apr 04, 2018 11:04 am

Just a quick test run. Scope probe connected with two wet shoelaces to Y5 and GND of a PYBLITE to simulate lousy wiring.
The 150Ohm load was just measured with a step whereas other tests used a pulse.
GPIO_SLOW_150OHM
GPIO_SLOW_OPEN
GPIO_FAST_OPEN
Attachments
gpio_slow_150Ohm.jpg
gpio_slow_150Ohm.jpg (152.46 KiB) Viewed 6493 times
gpio_slow.jpg
gpio_slow.jpg (153.38 KiB) Viewed 6493 times
gpio_fast.jpg
gpio_fast.jpg (155.24 KiB) Viewed 6493 times

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Controlling Slew Rate of GPIO

Post by pythoncoder » Thu Apr 05, 2018 7:15 am

Thank you, interesting results - my doubts were clearly unfounded. It's odd that STM don't characterise this useful feature in the datasheet.
Peter Hinch
Index to my micropython libraries.

Post Reply