[En-Nut-Discussion] Porttrans.h, was: Gpio again.

Uwe Bonnes bon at elektron.ikp.physik.tu-darmstadt.de
Tue Jun 18 15:21:15 CEST 2013


Hello,

looking back at the discussions and the code breakage I caused, I realize
now what a wrong way NutGpio is for portable bitbanging drivers. So I looked
deeper at porttrans.h and finally realized it is the right way for compile
time pin assignments for bit-banging drivers. The idea of defining and
undefineing GPIO_ID is a good way to write the complex macros needed.

However in it's present form there are several drawbacks:
- There are few drivers in the general dev/ directory using porttrans.h
- The code there is still sprankled with device dependent code like in
  dev/sbi_mmc.c
static int SbiMmcIfcInit(NUTDEVICE * dev)
{
    /* Enable all clocks. */
#if defined(PMC_PCER)
#if defined(MMC_CLK_PIO_ID)
    outr(PMC_PCER, _BV(MMC_CLK_PIO_ID));
#endif
- porttrans.h offers GPIO_OPENDRAIN/GPIO_PUSHPULL and device code
(dev/jtag_gpio0.c) uses these functions. However for AVR8 we can't switch
between GPIO_OPENDRAIN/GPIO_PUSHPULL in a stateless manner.
E.g. I see no possiblity to write macros that translate a code sequences like
GPIO_OPENDRAIN, GPIO_SET_LO, GPIO_IS_HI and
GPIO_PUSHPULL, GPIO_SET_LO, GPIO_IS_HI into someting sensible for AVR8. So
again the same objection holds, that I had with NutGpio: I we want to
write portable code, we must restrict ourselfs.
- GPIO_FILTER_xx is also feature only available on few architectures.

As changing porttrans.h _will_ cause breakage in code out there, I would
like to hear your opinion about following roadmap:

- Introduce porttran2.h with a minimum of functionality.
  GPIO_INIT
  * switch on clock related to the port
  * connect GPIO to the Pin
  * start as input with no pull up
  * prepare to go push-pull when switched to output
  * start with port speed allowing 1..2 MHz bitbanging
  GPIO_OUTPUT
  * switch port to output/pushpull
  GPIO_INPUT
  * switch port to input
  GPIO_SET_LO
  * Set the output register low
  GPIO_SET_HI
  * Set the output register high
  GPIO_SET_GET
  * return 1 if pin is high and 0 else

  So a typical I2C pull pin low and then release the pin sequence would be:
  GPIO_INIT, ..., GPIO_SET_LO, GPIO_OUTPUT, ..., GPIO_INPUT, GPIO_SET_HI.

  GPIO_PULLUP_ON|OFF and  GPIO_FILTER_ON|OFF would be optional hints, but
  may have no guarantted effect.

  I would start porttran2.h as a copy of porttran.h and strip
  down. Assembling GPIO_INIT for archs not available here is harder and will
  required code review and|or support from maintainers of the different
  architecture. porttran2.h is not supposed to be includes in arch/dev code!

- Migrate drivers in nut/dev using porttran.h to use porttran2.h, migrate
  more nut/dev gpio drivers to use porttran2.h.

Is this a way to go? Anything I forgot? Better names for porttran2.h?

Thanks
-- 
Uwe Bonnes                bon at elektron.ikp.physik.tu-darmstadt.de

Institut fuer Kernphysik  Schlossgartenstrasse 9  64289 Darmstadt
--------- Tel. 06151 162516 -------- Fax. 06151 164321 ----------


More information about the En-Nut-Discussion mailing list