swig: fix usage of SWIGPYTHON for python specific code
[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 #include <stdlib.h>
28
29 #include "maa.h"
30 #include "intel_galileo_rev_d.h"
31 #include "gpio.h"
32 #include "version.h"
33
34 static maa_pininfo_t* pindata;
35 static maa_board_t* plat = NULL;
36
37 const char *
38 maa_get_version()
39 {
40     return gVERSION;
41 }
42
43 #ifndef SWIG
44 // this sets a compiler attribute (supported by GCC & clang) to have maa_init()
45 // be called as a constructor make sure your libc supports this!  uclibc needs
46 // to be compiled with UCLIBC_CTOR_DTOR
47 maa_result_t maa_init() __attribute__((constructor));
48 #endif
49 maa_result_t
50 maa_init()
51 {
52     /** Once more board definitions have been added,
53      *  A method for detecting them will need to be devised.
54      */
55     if (plat != NULL) {
56         return MAA_ERROR_PLATFORM_ALREADY_INITIALISED;
57     }
58 #ifdef SWIGPYTHON
59     // Initialise python threads, this allows use to grab the GIL when we are
60     // required to do so
61     Py_InitializeEx(0);
62     PyEval_InitThreads();
63 #endif
64     plat = maa_intel_galileo_rev_d();
65     return MAA_SUCCESS;
66 }
67
68 static maa_result_t
69 maa_setup_mux_mapped(maa_pin_t meta)
70 {
71     int mi;
72     for (mi = 0; mi < meta.mux_total; mi++) {
73         maa_gpio_context* mux_i;
74         mux_i = maa_gpio_init_raw(meta.mux[mi].pin);
75         if (mux_i == NULL)
76             return MAA_ERROR_INVALID_HANDLE;
77         if (maa_gpio_dir(mux_i, MAA_GPIO_OUT) != MAA_SUCCESS)
78             return MAA_ERROR_INVALID_RESOURCE;
79         if (maa_gpio_write(mux_i, meta.mux[mi].value) != MAA_SUCCESS)
80             return MAA_ERROR_INVALID_RESOURCE;
81     }
82     return MAA_SUCCESS;
83 }
84
85 unsigned int
86 maa_check_gpio(int pin)
87 {
88     if (plat == NULL)
89         return -1;
90
91     if (pin < 0 || pin > plat->phy_pin_count)
92         return -1;
93
94     if(plat->pins[pin].capabilites.gpio != 1)
95       return -1;
96
97     if (plat->pins[pin].gpio.mux_total > 0)
98        if (maa_setup_mux_mapped(plat->pins[pin].gpio) != MAA_SUCCESS)
99             return -1;
100     return plat->pins[pin].gpio.pinmap;
101 }
102
103 unsigned int
104 maa_check_aio(int aio)
105 {
106     if (plat == NULL)
107         return -3;
108
109     if (aio < 0 || aio > plat->aio_count)
110         return -1;
111
112     int pin = aio + plat->gpio_count;
113
114     if (plat->pins[pin].capabilites.aio != 1)
115       return -1;
116
117     if (plat->pins[pin].aio.mux_total > 0)
118        if (maa_setup_mux_mapped(plat->pins[pin].aio) != MAA_SUCCESS)
119             return -1;
120     return plat->pins[pin].aio.pinmap;
121 }
122
123 unsigned int
124 maa_check_i2c(int bus_s)
125 {
126     if (plat == NULL)
127         return -3;
128
129     if (plat->i2c_bus_count >! 0) {
130         fprintf(stderr, "No i2c buses defined in platform");
131         return -1;
132     }
133     int bus = 0;
134
135     int pos = plat->i2c_bus[bus].sda;
136     if (plat->pins[pos].i2c.mux_total > 0)
137         if (maa_setup_mux_mapped(plat->pins[pos].i2c) != MAA_SUCCESS)
138              return -2;
139
140     pos = plat->i2c_bus[bus].scl;
141     if (plat->pins[pos].i2c.mux_total > 0)
142         if (maa_setup_mux_mapped(plat->pins[pos].i2c) != MAA_SUCCESS)
143              return -2;
144
145     return plat->i2c_bus[bus].bus_id;
146 }
147
148 maa_pin_t*
149 maa_check_pwm(int pin)
150 {
151     if (plat == NULL)
152         return NULL;
153
154     if (plat->pins[pin].capabilites.pwm != 1)
155       return NULL;
156
157     if (plat->pins[pin].capabilites.gpio == 1) {
158         maa_gpio_context* mux_i;
159         mux_i = maa_gpio_init_raw(plat->pins[pin].gpio.pinmap);
160         if (mux_i == NULL)
161             return NULL;
162         if (maa_gpio_dir(mux_i, MAA_GPIO_OUT) != MAA_SUCCESS)
163             return NULL;
164         // Current REV D quirk. //TODO GEN 2
165         if (maa_gpio_write(mux_i, 1) != MAA_SUCCESS)
166             return NULL;
167         if (maa_gpio_close(mux_i) != MAA_SUCCESS)
168             return NULL;
169     }
170
171     if (plat->pins[pin].pwm.mux_total > 0)
172        if (maa_setup_mux_mapped(plat->pins[pin].pwm) != MAA_SUCCESS)
173             return NULL;
174
175     maa_pin_t *ret;
176     ret = (maa_pin_t*) malloc(sizeof(maa_pin_t));
177     ret->pinmap = plat->pins[pin].pwm.pinmap;
178     ret->parent_id = plat->pins[pin].pwm.parent_id;
179     return ret;
180 }
181
182 void
183 maa_result_print(maa_result_t result)
184 {
185     switch (result) {
186         case MAA_SUCCESS: fprintf(stderr, "MAA: SUCCESS\n");
187                           break;
188         case MAA_ERROR_FEATURE_NOT_IMPLEMENTED:
189                           fprintf(stderr, "MAA: Feature not implemented.\n");
190                           break;
191         case MAA_ERROR_FEATURE_NOT_SUPPORTED:
192                           fprintf(stderr, "MAA: Feature not supported by Hardware.\n");
193                           break;
194         case MAA_ERROR_INVALID_VERBOSITY_LEVEL:
195                           fprintf(stderr, "MAA: Invalid verbosity level.\n");
196                           break;
197         case MAA_ERROR_INVALID_PARAMETER:
198                           fprintf(stderr, "MAA: Invalid parameter.\n");
199                           break;
200         case MAA_ERROR_INVALID_HANDLE:
201                           fprintf(stderr, "MAA: Invalid Handle.\n");
202                           break;
203         case MAA_ERROR_NO_RESOURCES:
204                           fprintf(stderr, "MAA: No resources.\n");
205                           break;
206         case MAA_ERROR_INVALID_RESOURCE:
207                           fprintf(stderr, "MAA: Invalid resource.\n");
208                           break;
209         case MAA_ERROR_INVALID_QUEUE_TYPE:
210                           fprintf(stderr, "MAA: Invalid Queue Type.\n");
211                           break;
212         case MAA_ERROR_NO_DATA_AVAILABLE:
213                           fprintf(stderr, "MAA: No Data available.\n");
214                           break;
215         case MAA_ERROR_INVALID_PLATFORM:
216                           fprintf(stderr, "MAA: Platform not recognised.\n");
217                           break;
218         case MAA_ERROR_PLATFORM_NOT_INITIALISED:
219                           fprintf(stderr, "MAA: Platform not initialised.\n");
220                           break;
221         case MAA_ERROR_PLATFORM_ALREADY_INITIALISED:
222                           fprintf(stderr, "MAA: Platform already initialised.\n");
223                           break;
224         case MAA_ERROR_UNSPECIFIED:
225                           fprintf(stderr, "MAA: Unspecified Error.\n");
226                           break;
227         default:     fprintf(stderr, "MAA: Unrecognised error.\n");
228                           break;
229     }
230 }
231
232 maa_boolean_t
233 maa_pin_mode_test(int pin, maa_pinmodes_t mode)
234 {
235     if (plat == NULL) {
236         maa_init();
237         if (plat == NULL)
238             return 0;
239     }
240     if (pin > plat->phy_pin_count || pin < 0)
241         return 0;
242
243     switch(mode) {
244         case MAA_PIN_VALID:
245             if (plat->pins[pin].capabilites.valid == 1)
246                 return 1;
247             break;
248         case MAA_PIN_GPIO:
249             if (plat->pins[pin].capabilites.gpio ==1)
250                 return 1;
251             break;
252         case MAA_PIN_PWM:
253             if (plat->pins[pin].capabilites.pwm ==1)
254                 return 1;
255             break;
256         case MAA_PIN_FAST_GPIO:
257             if (plat->pins[pin].capabilites.fast_gpio ==1)
258                 return 1;
259             break;
260         case MAA_PIN_SPI:
261             if (plat->pins[pin].capabilites.spi ==1)
262                 return 1;
263             break;
264         case MAA_PIN_I2C:
265             if (plat->pins[pin].capabilites.i2c ==1)
266                 return 1;
267             break;
268         case MAA_PIN_AIO:
269             if (pin < plat->aio_count)
270                 pin = pin + plat->gpio_count;
271             if (plat->pins[pin].capabilites.aio ==1)
272                 return 1;
273             break;
274         default: break;
275     }
276     return 0;
277 }