gpio.hpp: Add C++ wrapper around Gpio
[contrib/mraa.git] / src / maa.c
1 /*
2  * Author: Brendan Le Foll <brendan.le.foll@intel.com>
3  * Author: Thomas Ingleby <thomas.c.ingleby@intel.com>
4  * Copyright (c) 2014 Intel Corporation.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining
7  * a copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sublicense, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be
15  * included in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25
26 #include <stddef.h>
27
28 #include "maa.h"
29 #include "intel_galileo_rev_d.h"
30 #include "gpio.h"
31 #include "version.h"
32
33 static maa_pininfo_t* pindata;
34 static maa_board_t* plat = NULL;
35
36 const char *
37 maa_get_version()
38 {
39     return gVERSION;
40 }
41
42 #ifdef SWIG
43 maa_result_t
44 maa_init()
45 #else
46 maa_result_t __attribute__((constructor))
47 maa_init()
48 #endif
49 {
50     /** Once more board definitions have been added,
51      *  A method for detecting them will need to be devised.
52      */
53     if (plat != NULL) {
54         return MAA_ERROR_PLATFORM_ALREADY_INITIALISED;
55     }
56 #ifdef SWIGPYTHON
57     // Initialise python threads, this allows use to grab the GIL when we are
58     // required to do so
59     Py_InitializeEx(0);
60     PyEval_InitThreads();
61 #endif
62     plat = maa_intel_galileo_rev_d();
63     return MAA_SUCCESS;
64 }
65
66 static maa_result_t
67 maa_setup_mux_mapped(maa_pin_t meta)
68 {
69     int mi;
70     for (mi = 0; mi < meta.mux_total; mi++) {
71         maa_gpio_context mux_i;
72         mux_i = maa_gpio_init_raw(meta.mux[mi].pin);
73         if (mux_i == NULL)
74             return MAA_ERROR_INVALID_HANDLE;
75         if (maa_gpio_dir(mux_i, MAA_GPIO_OUT) != MAA_SUCCESS)
76             return MAA_ERROR_INVALID_RESOURCE;
77         if (maa_gpio_write(mux_i, meta.mux[mi].value) != MAA_SUCCESS)
78             return MAA_ERROR_INVALID_RESOURCE;
79     }
80     return MAA_SUCCESS;
81 }
82
83 unsigned int
84 maa_check_gpio(int pin)
85 {
86     if (plat == NULL)
87         return -1;
88
89     if (pin < 0 || pin > plat->phy_pin_count)
90         return -1;
91
92     if(plat->pins[pin].capabilites.gpio != 1)
93       return -1;
94
95     if (plat->pins[pin].gpio.mux_total > 0)
96        if (maa_setup_mux_mapped(plat->pins[pin].gpio) != MAA_SUCCESS)
97             return -1;
98     return plat->pins[pin].gpio.pinmap;
99 }
100
101 unsigned int
102 maa_check_aio(int aio)
103 {
104     if (plat == NULL)
105         return -3;
106
107     if (aio < 0 || aio > plat->aio_count)
108         return -1;
109
110     int pin = aio + plat->gpio_count;
111
112     if (plat->pins[pin].capabilites.aio != 1)
113       return -1;
114
115     if (plat->pins[pin].aio.mux_total > 0)
116        if (maa_setup_mux_mapped(plat->pins[pin].aio) != MAA_SUCCESS)
117             return -1;
118     return plat->pins[pin].aio.pinmap;
119 }
120
121 unsigned int
122 maa_check_i2c(int bus_s)
123 {
124     if (plat == NULL)
125         return -3;
126
127     if (plat->i2c_bus_count >! 0) {
128         fprintf(stderr, "No i2c buses defined in platform");
129         return -1;
130     }
131     int bus = 0;
132
133     int pos = plat->i2c_bus[bus].sda;
134     if (plat->pins[pos].i2c.mux_total > 0)
135         if (maa_setup_mux_mapped(plat->pins[pos].i2c) != MAA_SUCCESS)
136              return -2;
137
138     pos = plat->i2c_bus[bus].scl;
139     if (plat->pins[pos].i2c.mux_total > 0)
140         if (maa_setup_mux_mapped(plat->pins[pos].i2c) != MAA_SUCCESS)
141              return -2;
142
143     return plat->i2c_bus[bus].bus_id;
144 }
145
146 maa_pin_t*
147 maa_check_pwm(int pin)
148 {
149     if (plat == NULL)
150         return NULL;
151
152     if (plat->pins[pin].capabilites.pwm != 1)
153         return NULL;
154
155     if (plat->pins[pin].capabilites.gpio == 1) {
156         maa_gpio_context mux_i;
157         mux_i = maa_gpio_init_raw(plat->pins[pin].gpio.pinmap);
158         if (mux_i == NULL)
159             return NULL;
160         if (maa_gpio_dir(mux_i, MAA_GPIO_OUT) != MAA_SUCCESS)
161             return NULL;
162         // Current REV D quirk. //TODO GEN 2
163         if (maa_gpio_write(mux_i, 1) != MAA_SUCCESS)
164             return NULL;
165         if (maa_gpio_close(mux_i) != MAA_SUCCESS)
166             return NULL;
167     }
168
169     if (plat->pins[pin].pwm.mux_total > 0)
170        if (maa_setup_mux_mapped(plat->pins[pin].pwm) != MAA_SUCCESS)
171             return NULL;
172
173     maa_pin_t *ret;
174     ret = (maa_pin_t*) malloc(sizeof(maa_pin_t));
175     ret->pinmap = plat->pins[pin].pwm.pinmap;
176     ret->parent_id = plat->pins[pin].pwm.parent_id;
177     return ret;
178 }
179
180 void
181 maa_result_print(maa_result_t result)
182 {
183     switch (result) {
184         case MAA_SUCCESS: fprintf(stderr, "MAA: SUCCESS\n");
185                           break;
186         case MAA_ERROR_FEATURE_NOT_IMPLEMENTED:
187                           fprintf(stderr, "MAA: Feature not implemented.\n");
188                           break;
189         case MAA_ERROR_FEATURE_NOT_SUPPORTED:
190                           fprintf(stderr, "MAA: Feature not supported by Hardware.\n");
191                           break;
192         case MAA_ERROR_INVALID_VERBOSITY_LEVEL:
193                           fprintf(stderr, "MAA: Invalid verbosity level.\n");
194                           break;
195         case MAA_ERROR_INVALID_PARAMETER:
196                           fprintf(stderr, "MAA: Invalid parameter.\n");
197                           break;
198         case MAA_ERROR_INVALID_HANDLE:
199                           fprintf(stderr, "MAA: Invalid Handle.\n");
200                           break;
201         case MAA_ERROR_NO_RESOURCES:
202                           fprintf(stderr, "MAA: No resources.\n");
203                           break;
204         case MAA_ERROR_INVALID_RESOURCE:
205                           fprintf(stderr, "MAA: Invalid resource.\n");
206                           break;
207         case MAA_ERROR_INVALID_QUEUE_TYPE:
208                           fprintf(stderr, "MAA: Invalid Queue Type.\n");
209                           break;
210         case MAA_ERROR_NO_DATA_AVAILABLE:
211                           fprintf(stderr, "MAA: No Data available.\n");
212                           break;
213         case MAA_ERROR_INVALID_PLATFORM:
214                           fprintf(stderr, "MAA: Platform not recognised.\n");
215                           break;
216         case MAA_ERROR_PLATFORM_NOT_INITIALISED:
217                           fprintf(stderr, "MAA: Platform not initialised.\n");
218                           break;
219         case MAA_ERROR_PLATFORM_ALREADY_INITIALISED:
220                           fprintf(stderr, "MAA: Platform already initialised.\n");
221                           break;
222         case MAA_ERROR_UNSPECIFIED:
223                           fprintf(stderr, "MAA: Unspecified Error.\n");
224                           break;
225         default:     fprintf(stderr, "MAA: Unrecognised error.\n");
226                           break;
227     }
228 }
229
230 maa_boolean_t
231 maa_pin_mode_test(int pin, maa_pinmodes_t mode)
232 {
233     if (plat == NULL) {
234         maa_init();
235         if (plat == NULL)
236             return 0;
237     }
238     if (pin > plat->phy_pin_count || pin < 0)
239         return 0;
240
241     switch(mode) {
242         case MAA_PIN_VALID:
243             if (plat->pins[pin].capabilites.valid == 1)
244                 return 1;
245             break;
246         case MAA_PIN_GPIO:
247             if (plat->pins[pin].capabilites.gpio ==1)
248                 return 1;
249             break;
250         case MAA_PIN_PWM:
251             if (plat->pins[pin].capabilites.pwm ==1)
252                 return 1;
253             break;
254         case MAA_PIN_FAST_GPIO:
255             if (plat->pins[pin].capabilites.fast_gpio ==1)
256                 return 1;
257             break;
258         case MAA_PIN_SPI:
259             if (plat->pins[pin].capabilites.spi ==1)
260                 return 1;
261             break;
262         case MAA_PIN_I2C:
263             if (plat->pins[pin].capabilites.i2c ==1)
264                 return 1;
265             break;
266         case MAA_PIN_AIO:
267             if (pin < plat->aio_count)
268                 pin = pin + plat->gpio_count;
269             if (plat->pins[pin].capabilites.aio ==1)
270                 return 1;
271             break;
272         default: break;
273     }
274     return 0;
275 }