Generic Port Access

From Nutwiki
Revision as of 17:02, 27 October 2016 by Harald (Talk | contribs) (1 revision imported)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Overview

This example demonstrates simple GPIO calls using the Nut/OS GPIO API.

To demonstrate output we'll use a simple LED and resistor from VCC to Port Bit 0, for testing the input we'll use a wire bridge from GND to Port Bit 1.

The example was written for Ethernut 1, 2 and 3. Confirmed working on Ethernut 3, should work on Ethernut 1 and 2 as well but tests still have to be done.

Source

<source lang="c">

  1. include <dev/board.h>
  2. include <dev/gpio.h>
  3. include <sys/timer.h>
  4. include <io.h>
  5. include <stdio.h>
  1. ifdef ETHERNUT1
  2. define OUT_PORT NUTGPIO_PORTB
  3. define OUT_PIN 0
  4. define IN_PORT NUTGPIO_PORTB
  5. define IN_PIN 1
  6. endif
  1. ifdef ETHERNUT2
  2. define OUT_PORT NUTGPIO_PORTB
  3. define OUT_PIN 0
  4. define IN_PORT NUTGPIO_PORTB
  5. define IN_PIN 1
  6. endif
  1. ifdef ETHERNUT3
  2. define OUT_PORT NUTGPIO_PORT
  3. define OUT_PIN 0
  4. define IN_PORT NUTGPIO_PORT
  5. define IN_PIN 1
  6. endif

int main(void) {

   unsigned long baud = 115200;
   int cycles = 0;
   int spd = 10;


   NutRegisterDevice(&DEV_DEBUG, 0, 0);
   freopen(DEV_DEBUG_NAME, "w", stdout);
   _ioctl(_fileno(stdout), UART_SETSPEED, &baud);
   puts("GPIO example\n");
   GpioPinConfigSet(OUT_PORT, OUT_PIN, GPIO_CFG_OUTPUT);
   GpioPinConfigSet(IN_PORT, IN_PIN, GPIO_CFG_PULLUP);
   if (GpioPinGet(IN_PORT, IN_PIN)) {
       puts("Please connect your GPIO Bit 1.");
       while (GpioPinGet(IN_PORT, IN_PIN)) {
           NutSleep(5000);
       }
   }
   for (;;) {
       if (cycles < 5) {
           spd = 1000;
       } else {
           spd = 100;
       }
       puts("Pin: Low");
       GpioPinSetLow(OUT_PORT, OUT_PIN);
       NutSleep(spd);
       puts("Pin: High");
       GpioPinSetHigh(OUT_PORT, OUT_PIN);
       NutSleep(spd);
       cycles++;
       if (cycles >= 55) {
           cycles = 0;
       }
       if (GpioPinGet(IN_PORT, IN_PIN)) {
           puts("The GPIO port bit 1 has been disconnected. Operation was halted. Please reconnect to resume operation.");
           while (GpioPinGet(IN_PORT, IN_PIN)) {
               NutSleep(5000);
           }
       }
   }
   for (;;);

} </source>

Details

<source lang="c">

  1. ifdef ETHERNUT1
  2. define OUT_PORT NUTGPIO_PORTB
  3. define OUT_PIN 0
  4. define IN_PORT NUTGPIO_PORTB
  5. define IN_PIN 1
  6. endif
  1. ifdef ETHERNUT2
  2. define OUT_PORT NUTGPIO_PORTB
  3. define OUT_PIN 0
  4. define IN_PORT NUTGPIO_PORTB
  5. define IN_PIN 1
  6. endif
  1. ifdef ETHERNUT3
  2. define OUT_PORT NUTGPIO_PORT
  3. define OUT_PIN 0
  4. define IN_PORT NUTGPIO_PORT
  5. define IN_PIN 1
  6. endif

</source>

Since all 3 target boards have different pin layouts, we define them depending on the board we're compiling for. Since Nut/OS provides handy platform macros, we won't hesitate to use them.

You should consult the connector sheet for your board to find out which pin each setting corresponds to, especially if you plan on changing them.

Ethernut 1

Ethernut 2

Ethernut 3

<source lang="c"> unsigned long baud = 115200; int cycles = 0; int spd = 10;

NutRegisterDevice(&DEV_DEBUG, 0, 0); freopen(DEV_DEBUG_NAME, "w", stdout); _ioctl(_fileno(stdout), UART_SETSPEED, &baud);

puts("GPIO example\n"); </source>

We set up the debug device for output as usual. The cycles and spd variable will be used for our blinking LED.

<source lang="c"> GpioPinConfigSet(OUT_PORT, OUT_PIN, GPIO_CFG_OUTPUT); GpioPinConfigSet(IN_PORT, IN_PIN, GPIO_CFG_PULLUP); </source>

In order for our pins to work as expected we must first configure them. By default, pins are set to input but are floating. This is not what we want. Our output pin has to be set to output, the input pin must have its pullup resistor enabled.

<source lang="c"> if (GpioPinGet(IN_PORT, IN_PIN)) {

   puts("Please connect your GPIO Bit 1.");
   while (GpioPinGet(IN_PORT, IN_PIN)) {
       NutSleep(5000);
   }

} </source>

Before the demo starts we check if everything is wired correctly. This is not necessary of course but since you'll probably not have the input connected already it'll demonstrate that it works right from the start.

The GpioPinGet simply gets the state of the pin. If it returns 1, it is not connected. So we'll wait until it is connected (0) and then continue.

<source lang="c"> if (cycles < 5) {

   spd = 1000;

} else {

   spd = 100;

} </source>

This part just sets the blinking speed. We want to blink slow first and fast after a few cycles.

<source lang="c"> puts("Pin: Low"); GpioPinSetLow(OUT_PORT, OUT_PIN); NutSleep(spd);

puts("Pin: High"); GpioPinSetHigh(OUT_PORT, OUT_PIN); NutSleep(spd); </source>

Using GpioPinSetLow and GpioPinSetHigh we now change our output port and wait a moment, then change it again. If your LED is connected correctly, it will now blink. Hooray!

<source lang="c"> cycles++; if (cycles >= 55) {

   cycles = 0;

} </source>

This is - again - just cycle logic. It resets the cycle counter so we can alternate between fast and slow blinking. Nothing to see here, move on.

<source lang="c"> if (GpioPinGet(IN_PORT, IN_PIN)) {

   puts("The GPIO port bit 1 has been disconnected. Operation was halted. Please reconnect to resume operation.");
   while (GpioPinGet(IN_PORT, IN_PIN)) {
       NutSleep(5000);
   }

} </source>

Now if during our blinking the input port gets disconnected for some reason, we'll halt the blinking. Again, this is not necessary for the blinking to work, it just demonstrates GPIO input again. You can use it as a switch to control the LED. If you want to try changing this example to change blinking speed when the port is connected/disconnected.

Output

<source lang="text"> GPIO example

Please connect your GPIO Bit 1. Pin: Low Pin: High Pin: Low Pin: High Pin: Low Pin: High Pin: Low Pin: High The GPIO port bit 1 has been disconnected. Operation was halted. Please reconnec t to resume operation. </source>

Advanced Example

GPIO example with webbrowser control and AJAX (Source)

This example lets you control the LED and watch the status of the input pin on the webbrowser in almost realtime without page reloads. The basic program is the same but now you can choose from 4 different programs for the LED and see the state of the input. It uses the jQuery javascript library in addition to Nut/OS for graphical effects in the browser and seamless background updates.

The 4 LED programs are:

  • off
  • on
  • blink slowly
  • blink fast


For more details on how to integrate your own applications with a webinterface, check out the httpd example in your nutapp directory.

See also