[En-Nut-Discussion] Nut/OS GPIO API Initial Design and Current Status
Ole Reinhardt
ole.reinhardt at embedded-it.de
Mon Oct 15 18:33:31 CEST 2012
Hi all,
> Why do you think that GpioPinSetLow takes an additional read cycle? With
> Bit0 '0' writen to the Bitbanding address the bit is reset, with '1' ist is
> set.
>
> But here we are at the internal implementation of GPIO for the STM32
> platform. Isn't that independant of the Ethernut GPIO Api? Do yu care if
> setting a pin in the bitbanging drivers is a tick slower on one platform
> then it could be hand-coded in a non-portable way?
With all the discussion about the bitbanding: Have you ever checked if
the bitband access for your CPU does exactly what you expect?
I ask as I had big problems on the LCP with the bitband access to the
GPIO pins:
I implemented GpioPinSetxxx set exactly the same way as it is done for
STM32 using bitbanding.
Now calling:
GpioPinSetHigh(NUTGPIO_PORT0, 1);
GpioPinSetHigh(NUTGPIO_PORT0, 2);
Result:
Only Pin 2 is set, pin1 did not change.
I discussed this with some NXP engeneers and they explained this as a
problem with the bitband statemachine. Internally you still have a
read-modify-write operation to the same register where each opration
takes a few CPU cycles. These two accesses are now translated in two
such read-modify-write operations, but they run more or less in parallel
and therefore it is translated to something like this:
state = read_state(port0)
state |= pin1
state = read_state(port0)
write_state(port0, state)
state |= pin2
write_state(port0, state)
So this is a race condition internally.
In fact, if you write:
GpioPinSetHigh(NUTGPIO_PORT0, 1);
_NOP(); _NOP();
GpioPinSetHigh(NUTGPIO_PORT0, 2);
_NOP(); _NOP();
everything works as expected.
So at last, I decided not to use bitband access for the GPIO pins.
I know, this issue will most probably be an issue of the LPC CPUs, but
perhaps you should check this for STM32 as well.
> We can argue about the Macros I introduced, the names are sub-otipmal. But
> still I don't see the advantage of writing "BB_PERIPH(&GPIOB->ODR,
> I2CBUS1_SDA_PIN) = 1;" or something similar against GpioPinSetLow(port, pin).
I think it is fully ok to use the API in places where you don't need
high performance pin I/O. Using the API reads much easier than the
register access, but as mentioned before, I would try to use as less
dependencies to the GPIO API as possible and try to configure the I/O
port settings in the board file.
> Harald> Sorry, that was a serious question, not a didactic question. I'm
> Harald> just curious, if you intend to implement GPIO_PinAFConfig
> Harald> features into GpioPinConfigSet to make it more portable.
>
> Ulrich's proposal intended to do so. The STM32 gpio usage doesn't do that at
> the moment, neither does LPC. avr32/dev/pwm.c puts the argument for the pin
> configuration in the flags, that's the only file i see such a use.
> I can do so for STM32 too, I am totally unbiased in that regard.
On the LPC I'm using it like this:
GpioPinConfigSet(SD_SDIO_PORT_0, SD_CMD_PIN, GPIO_CFG_PERIPHERAL2 |
GPIO_CFG_PULLUP); // SD_CMD
> But if we ever see the alternate function setting in platform independant
> code, there is something wrong.
Yes, this code should only be used by the board files or platform
depending application code.
Bye,
Ole
--
Thermotemp GmbH, Embedded-IT
Embedded Hard-/ Software and Open Source Development,
Integration and Consulting
http://www.embedded-it.de
Geschäftsstelle Siegen - Steinstraße 67 - D-57072 Siegen -
tel +49 (0)271 5513597, +49 (0)271-73681 - fax +49 (0)271 736 97
Hauptsitz - Hademarscher Weg 7 - 13503 Berlin
Tel +49 (0)30 4315205 - Fax +49 (0)30 43665002
Geschäftsführer: Jörg Friedrichs, Ole Reinhardt
Handelsregister Berlin Charlottenburg HRB 45978 UstID DE 156329280
More information about the En-Nut-Discussion
mailing list