Skip to content

GPIO

GPIO configuration

Sixteen GPIO pins of the STEP2 are arranged in a DSUB-25P female port. The actual image of the GPIO port and its pin mapping is shown in below.


STEP2's GPIO port configuration

  • GPIO0: pin 5 to pin 12

  • GPIO1: pin 1 to pin 4, and pin 14 to pin 17

  • Pin 18, 19: GPIO1 power, be default it is 5V (user can change to 12V by internal jumper)

  • Pin 20-25: GPIO ground

GPI APIs

NRMKPlatform provides a complete set of user APIs to make use of these GPIO functions. The APIs are packaged in a library named NRMKhw which will be installed with the NRMKPlatform setup. The prototypes of all supported API functions can be found in file NRMKhw_tp.h loacated in the subfolder helper/include/hw of NRMKFoundation installation folder. All these functions are listd in Code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
//GPIO
int tp_gpio_init(void);
void tp_gpio_setdirout(TP_PORT port, uint8_t regcode);
void tp_gpio_setdirin(TP_PORT port, uint8_t regcode);
void tp_gpio_set_dir(TP_PORT port, uint8_t regcode);

uint8_t tp_readport(TP_PORT port);
void tp_writeport(TP_PORT port, TP_PORT portval);

void tp_onpin(TP_PORT port, uint8_t  pincode);
void tp_offpin(TP_PORT port, uint8_t  pincode);
void tp_togglepin(TP_PORT port, uint8_t  pincode);

In addition to the GPIO functions, there are several definitions and datatypes which must be taken into account when using these APIs:

  • Pin: a single pin in one port. A pin number ranging from 0 to 7 has to be used with a port number.

  • Port: a group of pins which can be controlled and accessed at the same time. In STEP2, a port is defined as an enumerated type TP_PORT as in Code below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#define pin00   0x01
#define pin01   0x02
#define pin02   0x04
#define pin03   0x08
#define pin04   0x10
#define pin05   0x20
#define pin06   0x40
#define pin07   0x80
#define pin(i)  ((uint8_t)(1<<i))
#define gpio_allpin 0xFF

typedef enum _TP_UART_CLK_SRC{
    MODE01_8462MHz=0x00,        //01.8462 MHz (24 MHz / 13)     : Max baud=115.2K (default)
    MODE02_0000MHz=0x01,        //02.0000 MHz (24 MHz / 12)     : Max baud=125.0K
    MODE24_0000MHz=0x02,        //24.0000 MHz (24 MHz / 1)      : Max baud=1.5M
    MODE14_1690MHz=0x03         //14.7690 MHz (24 MHz / 1.625)  : Max baud=921.6k
} TP_UART_CLK_SRC;

typedef enum {
    GPIO_GDIR_INPUT  = 0,
    GPIO_GDIR_OUTPUT = 1,
} TP_GPIO_GDIR;

typedef enum {
    GPIO_LOW_LEVEL  = 0,
    GPIO_HIGH_LEVEL = 1,
} TP_GPIO_LEVEL;

typedef enum _TP_PORT{
    port0=0,
    port1=1
} TP_PORT;

GPIO API functions control and access multiple pins or whole port at the same time. One can set port direction, write values to or read values from a port. These are atomic operations which provide higher accessing speed compared to pin control. One of the following functions must be called before using any GPIO function.

  • int tp_gpio_init(void)

    Initialize all GPIO ports. regcode is hexadecimal, with each bit value determining the input pin on the port.

  • void tp_gpio_setdirout(TP_PORT port, uint8_t regcode)

    Set port as output. regcode is hexadecimal, with each bit value determining the output pin on the port.

  • void tp_gpio_setdirin(TP_PORT port, uint8_t regcode)

    Set port as input. regcode is hexadecimal, with each bit value determining the input pin on the port.

Note

Each bit value in regcode determines the input (or output) pin on the port. Bit 1 represents the input (or output) and 0 represents an unused pin. For example, in order to set four pins from 0 to 3 of GPIO1 as output and keep other pins setting unchaged, user can call: tp_gpio_setdirout(port1, 0xF) because hexadecimal 0xF is 1111 as binary.

  • void tp_gpio_set_dir(TP_PORT port, uint8_t regcode)

    Select direction of port. Bitwise value of regcode decides direction of all pins in port. Value of 1 of each bit respects to output direction and value of 0 is for input pin. For example, in order to set 0-3 pins of GPIO1 as input and four pins from 4 to 7 as output, user can call: tp_gpio_set_dir(port1, 0xF0).

  • void tp_onpin(TP_PORT port, uint8_t pincode)

    Set the pins masked by pincode to high level. Bitwise value of pincode decides which pins are affected. For example, in order to set four pins 0, 2, 4, 6 of GPIO1 to high level and keep other pins unchanged, user can call: tp_onpin (port1, 0x55). Here 0x55 = 01010101 in which bit 0,2,4,6 has value of 1.

  • void tp_offpin(TP_PORT port, uint8_t pincode)

    Set the pins masked by pincode to low level. Bitwise value of pincode decides which pins are affected. The usage is same as tp_onpin.


After completing GPIO port initialization, users can read or write port values using following API functions.

  • void tp_writeport(TP_PORT port, uint8_t portval)

    Write value portval directly to port. In order to use this function, the port has to be set as output prior.

  • uint8_t tp_readport(TP_PORT port)

    Read value from input port. The return is an unsigned 8-bit value which indicates pin status of port.


GPIO control example

One simple example which controls GPIO pins is presented below. In this example, 8 pins of GPIO 0 are used to generate 8 PWM signals with xenomai realtime task. The task’s period is 50us, and therefore the PWM’s period is 100us.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/io.h>

#include <native/task.h>
#include <native/timer.h>
#include <native/mutex.h>
#include <rtdk.h>

#include "NRMKhw_tp.h"  //NRMK gpio library

RT_TASK gpio_out_task;
uint8_t allstate=0;
TP_PORT test_port=0;

//output task
void gpio_out_run(void *arg)
{
    int state=0;
    rt_task_set_periodic(NULL, TM_NOW, 5e4);    //cycle: 50us
    while (1)
    {
        if (state==0)
            tp_writeport(test_port, 0xAA);
        else
            tp_writeport(test_port, 0x55);
        state^=1;
        rt_task_wait_period(NULL);
    }
}

void catch_signal(int sig)
{
    rt_task_delete(&gpio_out_task);
    exit(1);
}

int main(int argc, char* argv[])
{
    signal(SIGTERM, catch_signal);
    signal(SIGINT, catch_signal);
    /* Avoids memory swapping for this program */
    mlockall(MCL_CURRENT|MCL_FUTURE);

    /*Perform auto-init of rt_print buffers */
    rt_print_auto_init(1);

    if (tp_gpio_init()!=0) //initialize port
    {
        printf("GPIO Init. Error!\n");
        return 1;
    }

    tp_gpio_setdirout(test_port,  0xFF); //all pin as output

    printf("Running, check the GPIO state....\n");

    //create and start a realtime periodic task for writing gpio
    rt_task_create(&gpio_out_task, "gpio_out", 0, 99, 0);
    rt_task_start(&gpio_out_task, &gpio_out_run, NULL);

    pause();

    rt_task_delete(&gpio_out_task);

    return 0;
}
  • The first step to use GPIO library is to include the header file NRMKhw_tp.h as in line 13. This header file contains prototypes of all supported functions which control GPIO on STEP2.

  • Before using GPIO function, user have to initialize it by calling function tp_gpio_init() as in code (line 51).

  • Since this example use port0 (test_port) as output, the function tp_gpio_setdirout() is used with second parameter 0xFF which indicates that all pin of port0 will have output direction.

  • PWM generation work is taken by a real time task gpio_out_task which is created and started in lines 62-63. The real-time task function gpio_out_run is presented in lines 20-33.

  • In gpio_out_run function, before starting infinity loop, the task period is set 50us at line 23. It is noted that the unit used for realtime task is nano-second(ns), in order to obtain 50us period, the tick value will be 5e4 = 50000ns = 50us.

  • In the body of gpio_out_run function port0(test_port)'s pins are toggled by functions tp_writeport(test_port, 0xAA) and tp_writeport(test_port, 0x55). Function rt_task_wait_period() is used to wait for next period come.

The actual PWM signals on two example pins GPIO0_0 and GPIO0_1 observed from an oscilloscope.


Generated PWM signal on pin GPIO0_0 and GPIO0_1