[En-Nut-Discussion] Unified GPIO implementation

Thiago A. Corrêa thiago.correa at gmail.com
Wed Oct 6 20:45:42 CEST 2010


Hi,

2010/10/6 Harald Kipp <harald.kipp at egnite.de>:
> On 06.10.2010 07:29, Thiago A. Corręa wrote:
>> they are 8 bit or 32 bits. It's suggested:
>>
>> AVR:
>> int8_t GpioPinConfigSet( uint8_t port, uint8_t pin, uint8_t cfg)
>>
>> AVR32,ARM,Cortex
>> int GpioPinConfigSet( uint32_t port, uint32_t pin, uint32_t cfg)
>>
>>     Why not define it as simply int8_t GpioPinConfigSet( uint8_t port,
>> uint8_t pin, uint8_t cfg) for all architectures?
>
> The compiler will generate additional code for 32-bitters with uint8_t
> arguments to clear the upper bytes of the register. I'd recommend to use
> uint_fast8_t. See

Ah, ok.

We already define ureg_t in sys/types.h, it fits perfectly for this:

ureg_t GpioPinConfigSet( ureg_t port, ureg_t pin, ureg_t cfg )
where ureg_t is usually sizeof(register)

Then we can have just one include file that defines the function
signature instead of one for each architecture.

> But the return value caught my attention:
>
> int8_t function();
>
> IMHO won't help 8-bitters. AFAIK, functions always must return at least
> 2 bytes on the AVR. Simply because C allows to call unknown functions.
> Such functions are expected to return an integer value.

For AVR32 it makes sense to use a return type that is the same size of
the register, as it's usually stored in R12.
Or it could simply return void.

>
>> We already have those defined in include/dev/gpio.h, except that _PORT
>> is 0 and _PORTA is 1. Should we change it?
>
> My initial intention was, to have distinct definitions for the users of
> single port CPUs like the AT91R40008. Later I recognized, that
>
> #define xxx_PORT xxx_PORTA
>
> would have been sufficient. We really do not need to distinguish PORT
> from PORTA in the API. I have no objections to change this.
>

Ok, can we change this in trunk already then?

>> There is also one area that is not covered in the document. The
>> AVR32 toolchain defines which references the GPIO set their values as
>> pin numbers, not ports/pins. So, some sort of conversion macro is
>> needed, to use that convention with the port/pin convention in Nut/OS.
>
> I think Michael Fischer already implemented such a macro. In general it
> is not a bad idea to use pin numbers only. It would save one parameter
> in the function call.
>

I think we discussed that a while ago and decided to go with the
Port/Pin pair. Really it doesn't make too much of a difference, but
for avr 8 bit it might confuse the users who is acostumed with
ports/pins.
Even though AVR32 toolchain use PIN only in it's defines, the
datasheet does mention ports/pins

I had a macro to do it the other way around: convert pin to port/pin.
I think it was later removed.


About the alternate functions to be configurable by Nut/OS. I'm
already doing it for AVR32. My board uses the alternative2 pins for
the usart.
Here is where I'm at right now:
Nutconf enumerated type requires a macro to define a different macro,
ie, it generates this:
#ifndef UART2_ALT_PINSET
#define UART2_ALT_PINSET ALTERNATE2
#endif

for the following entry in avr32.nut:
{
    macro = "UART2_ALT_PINSET",
    brief = "USART2 Alternative Pinset",
    type = "enumerated",
    choices = function() return GetAlternativePinsets() end,
    flavor = "booldata",
    file = "include/cfg/uart.h"
},

I thought about instead of ALTERNATE2, reuse the GPIO_CFG_PERIPHERAL0
which is already defined. But it might be a bit confusing to see that
in the Nutconf. Should we just define a new set of macros for the
config? Something along the lines of:

#define ALTERNATE_PIN1  1
...
#define ALTERNATE_PINn  n

Or perhaps I'm missing an alternative? What do you think?

Kind Regards,
    Thiago A. Correa



More information about the En-Nut-Discussion mailing list