]> rtime.felk.cvut.cz Git - pes-rpp/rpp-lib.git/blob - rpp/src/rpp/gio.c
e4612c594bf599754c705d66f407fc912de49d7c
[pes-rpp/rpp-lib.git] / rpp / src / rpp / gio.c
1 /* Copyright (C) 2013-2015 Czech Technical University in Prague
2  * Authors:
3  *     - Michal Horn <hornmich@fel.cvut.cz>
4  *     - Michal Sojka <sojkam1@fel.cvut.cz>
5  *
6  * This document contains proprietary information belonging to Czech
7  * Technical University in Prague. Passing on and copying of this
8  * document, and communication of its contents is not permitted
9  * without prior written authorization.
10  *
11  */
12
13 #include "base.h"
14 #include "rpp/gio.h"
15 #include "drv/gio_tab.h"
16 #include "rpp/mutex.h"
17
18 RPP_MUTEX_DEFINE(mutex_gio);
19
20 static uint32_t ports_initialized = 0;
21
22 /* Configuration consistency check */
23 STATIC_ASSERT(RPP_GIO_PORT_GIOA == (1 << GIO_PORT_GIOA) &&
24                           RPP_GIO_PORT_GIOB == (1 << GIO_PORT_GIOB) &&
25                           RPP_GIO_PORT_NHET1 == (1 << GIO_PORT_HET1) &&
26                           RPP_GIO_PORT_SPI5 == (1 << GIO_PORT_SPI5) &&
27                           1,
28                           Port_configuration_is_not_consistent);
29
30 int8_t rpp_gio_init(uint32_t init_ports)
31 {
32         enum pin_name pin;
33         if (!RPP_MUTEX_INIT(mutex_gio))
34                 return FAILURE;
35
36         gioREG->GCR0 = 1;   // Bring GIO out of reset
37
38         for (pin = (enum pin_name)0; pin < _PIN_COUNT; pin++) {
39                 int port_num = gio_port(gio_table[pin].pin_dsc);
40                 if ((init_ports & (1 << port_num)) &&
41                         !(ports_initialized & (1 << port_num)))
42                         gio_setup(gio_table[pin].pin_dsc);
43         }
44
45         ports_initialized |= init_ports;
46
47         return SUCCESS;
48 }
49
50 int8_t rpp_gio_set(enum pin_name pin, boolean_t value)
51 {
52         if (ports_initialized == 0 || pin >= _PIN_COUNT || pin < 0)
53                 return FAILURE;
54
55         gio_tab_set(pin, value);        /* Thread safe */
56         return SUCCESS;
57 }
58
59 int8_t rpp_gio_get(enum pin_name pin)
60 {
61         if (ports_initialized == 0 || pin >= _PIN_COUNT || pin < 0)
62                 return FAILURE;
63
64         boolean_t ret_val = gio_tab_get(pin) ? 1 : 0; /* Thread safe */
65
66         return ret_val;
67 }
68
69 int8_t rpp_gio_setup(enum pin_name pin, enum rpp_gio_io io, enum rpp_gio_in_mode in_mode,
70                                          boolean_t open_drain)
71 {
72         if (ports_initialized == 0 || pin >= _PIN_COUNT || pin < 0)
73                 return FAILURE;
74
75         uint32_t mode_flags[] = {
76                 [RPP_GIO_MODE_PULLDIS]  = GIO_PIN_CONF_MODE_PDIS,
77                 [RPP_GIO_MODE_PULLUP]   = GIO_PIN_CONF_MODE_PU | GIO_PIN_CONF_MODE_PEN,
78                 [RPP_GIO_MODE_PULLDOWN] = GIO_PIN_CONF_MODE_PD | GIO_PIN_CONF_MODE_PEN,
79         };
80         uint32_t dsc = gio_table[pin].pin_dsc & ~GIO_PIN_CONF_MASK;
81         dsc |= (io == RPP_GIO_OUT) ? GIO_PIN_CONF_DIR_OUT : GIO_PIN_CONF_DIR_IN;
82         dsc |= mode_flags[in_mode];
83         dsc |= open_drain ? GIO_PIN_CONF_OD_ON : GIO_PIN_CONF_OD_OFF;
84
85         RPP_MUTEX_LOCK(mutex_gio);
86         gio_setup(dsc);
87         RPP_MUTEX_UNLOCK(mutex_gio);
88
89         return SUCCESS;
90 }