Port vs Pin

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
nsoatw
Posts: 15
Joined: Mon May 12, 2014 6:13 pm

Port vs Pin

Post by nsoatw » Thu May 29, 2014 4:33 pm

I have searched but found nothing on how to access ports as a byte rather than as pins only.
What I'd like to do is connect an LCD, which has an 8-bit data port and 4 bits worth of control pins.
I was hoping I could access it something like this:
data_port = Port (PA0-PA7, output)
data_port.set(255)

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

Re: Port vs Pin

Post by dhylands » Thu May 29, 2014 5:12 pm

On the STM32F4xx, the GPIO ports are 16-bits wide.

The description of the various registers can be found in the STM32F4xx Reference Manual (Note: This is a 1713 page document - about 21 Mb)

The GPIO section starts on page 265 and the register descriptions start on page 278.

You'll most likely bee interested in the GPIOx_ODR, and/or GPIOx_BSRRx registers.

Using GPIOx_ODR will allow multiple bits to be set and/or cleared simultaneously, but you need to do it as a read-modify-write sequence which can have consequences if you also have ISRs on the system which are trying to modify bits which your code isn't using.

If you use the GPIOx_BSRRx register, then you can set or clear specified bits and not affect any other code (since using the GPIOx_BSRRx registers is purely a write operation, and only the bits set to 1 in the register are affected). From my perspective, this would be the preferred register to use.

There is an stm module (I don't see any docs for it yet) which allows arbitrary registers to be read/written from MicroPython. Here's an example for manipulating some of the LEDs simultaneously. The 4 LEDs are mapped as follows:
PB4 - BLUE
PA13 - RED
PA14 - GREEN
PA15 - YELLOW

So Red, Green, and Yellow are all on Port A, so we'll use those. To turn on all 3 LEDs at the same time:

Code: Select all

>>> import stm
>>> stm.mem16[stm.GPIOA + stm.GPIO_BSRRL] = 0xE000
and to turn all 3 off at the same time:

Code: Select all

>>> import stm
>>> stm.mem16[stm.GPIOA + stm.GPIO_BSRRH] = 0xE000
To do on and off at the same time, you could do:

Code: Select all

>>> stm.mem32[stm.GPIOA + stm.GPIO_BSRRL] = 0x40002000 # Red on Green off
>>> stm.mem32[stm.GPIOA + stm.GPIO_BSRRL] = 0x20004000 # Red off, Green on
Due to limitations in the way ints work on MicroPython, you can only specify 31 of the 32 bits, so if you try to manipulate bit 31, you'll get an error:

Code: Select all

>>> stm.mem32[stm.GPIOA + stm.GPIO_BSRRL] = 0x80000000
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: overflow converting long int to machine word
You can use

Code: Select all

>>> import stm
>>> dir(stm)
to see which register offsets have been defined.

nsoatw
Posts: 15
Joined: Mon May 12, 2014 6:13 pm

Re: Port vs Pin

Post by nsoatw » Fri May 30, 2014 1:48 pm

Many thanks Dave, precisely what I nedded!
I have read parts of the ref manual, and just wanted to know if there were any specific stm-commands available, rather than writing assembler.

Post Reply