AnsweredAssumed Answered

"gpiolite" simple GPIO driver for MQX on MCF52259

Question asked by gilles buloz on Mar 3, 2011
Latest reply on Nov 11, 2011 by gilles buloz

Hi forum !

 

I have written a simple gpio driver for MCF52259 because the original gpio driver seemed a little bit complex to me.

I post it here in the even it could be useful to somebody.

 

It is much more simplier than the standard gpio driver, because it makes use of the specific features of the MCF52259 such as the atomic level setting of I/Os through SET or CLR registers (only a write required, no read+modify+write), and does not have to support several processors each having a different way to manage the GPIO.

 

Interupts are also supported on the port NQ pins (IRQ1,3,5,7)

 

It has been tested with MQX 3.4 (built with CodeWarrior 7.1.2 GUI) but is probably OK with newer versions.

 

It is supplied "AS IS" at your own risks. Do as you want with it.

 

WARNING : To use it, disable the standard GPIO driver in the BSP configuration to avoid side effects :
            #define BSPCFG_ENABLE_GPIODEV 0

WARNING : take care not to confuse the GPIOLITE_xxx macros from this driver with the GPIO_xxx ones from the standard driver (they are not compatible).

Here is a brief overview of its very simple API :

 

--- Install the driver ---
  _io_gpiolite_install("gpiolite:");

--- Open the driver device file ---
  FILE_PTR fd_gpiolite;
  fd_gpiolite = fopen("gpiolite:", NULL);

--- Set PORTUB pin 2 as input and read current level ---
  ioctl(fd_gpiolite, GPIOLITE_IOCTL_SET_INPUT, (pointer)(GPIOLITE_PORTUB | GPIOLITE_PIN2));
  level = ioctl(fd_gpiolite, GPIOLITE_IOCTL_READ, (pointer)(GPIOLITE_PORTUB | GPIOLITE_PIN2));

--- Set PORTUA pin 3 as output, then to level 1, then to level 0 ---
  ioctl(fd_gpiolite, GPIOLITE_IOCTL_SET_OUTPUT, (pointer)(GPIOLITE_PORTTA | GPIOLITE_PIN3));
  ioctl(fd_gpiolite, GPIOLITE_IOCTL_WRITE1, (pointer)(GPIOLITE_PORTTA | GPIOLITE_PIN3));
  ioctl(fd_gpiolite, GPIOLITE_IOCTL_WRITE0, (pointer)(GPIOLITE_PORTTA | GPIOLITE_PIN3));

Note : a GPIO can be changed at any time from input to output and back.

--- Enable interrupt on both edges for PORTNQ pin 1 (IRQ1) and install a handler ---

Note : once a pin has been configured for interrupt, it is exclusively used as input with the handler defined. GPIOLITE_IOCTL_READ and GPIOLITE_IOCTL_WRITE1/0 IOCTLs should not be used on this pin.

  static void gpio_it_handler(uint_8 pin, uint_8 level)
  {
    // the code here must be short and fast as it is run from interrupt context
    // pin is the pin number on which IRQ occured (in case several pins have the same handler)
    // level is the current level read on pin when this function was called
  }

  {
    GPIOLITE_DEV_SET_PNQ_IT_DATA pnq_it_data;
    pnq_it_data.pin = (GPIOLITE_PORTNQ | GPIOLITE_PIN1);
    pnq_it_data.itmode = PORTNQ_ITMODE_BOTH_EDGES;
    pnq_it_data.handler = gpio_it_handler;
    if (ioctl(fd_gpiolite, GPIOLITE_IOCTL_SET_PNQ_IT, &pnq_it_data)) {
        printf("ERROR: GPIOLITE_IOCTL_SET_PNQ_IT failed.\n");
    }
  }

 

Outcomes