mraa: add mraa_get_platform_name
[contrib/mraa.git] / src / mraa.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 #include <sched.h>
29 #include <string.h>
30
31 #define DEBUG
32
33 #include "mraa_internal.h"
34 #include "intel_galileo_rev_d.h"
35 #include "intel_galileo_rev_g.h"
36 #include "intel_edison_fab_c.h"
37 #include "intel_de3815.h"
38 #include "intel_minnow_max.h"
39 #include "gpio.h"
40 #include "version.h"
41
42 mraa_board_t* plat = NULL;
43 static mraa_platform_t platform_type = MRAA_UNKNOWN_PLATFORM;
44 mraa_adv_func_t* advance_func;
45
46 const char *
47 mraa_get_version()
48 {
49     return gVERSION;
50 }
51
52 mraa_result_t
53 mraa_set_log_level(int level)
54 {
55     if (level <= 7 && level >= 0) {
56         setlogmask(LOG_UPTO(level));
57         return MRAA_SUCCESS;
58     }
59     return MRAA_ERROR_INVALID_PARAMETER;
60 }
61
62 mraa_result_t __attribute__((constructor))
63 mraa_init()
64 {
65 #ifdef DEBUG
66     setlogmask(LOG_UPTO(LOG_DEBUG));
67 #else
68     setlogmask(LOG_UPTO(LOG_NOTICE));
69 #endif
70
71     openlog("libmraa", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);
72     syslog(LOG_DEBUG, "libmraa initialised by user %d", getuid());
73
74     if (plat != NULL) {
75         return MRAA_ERROR_PLATFORM_ALREADY_INITIALISED;
76     }
77 #ifdef SWIGPYTHON
78     // Initialise python threads, this allows use to grab the GIL when we are
79     // required to do so
80     Py_InitializeEx(0);
81     PyEval_InitThreads();
82 #endif
83     // detect a galileo gen2 board
84     char *line = NULL;
85     // let getline allocate memory for *line
86     size_t len = 0;
87     FILE *fh = fopen("/sys/devices/virtual/dmi/id/board_name", "r");
88     if (fh != NULL) {
89         if (getline(&line, &len, fh) != -1) {
90             if (strncmp(line, "GalileoGen2", 11) == 0) {
91                 platform_type = MRAA_INTEL_GALILEO_GEN2;
92             } else if (strncmp(line, "BODEGA BAY", 10) == 0) {
93                 platform_type = MRAA_INTEL_EDISON_FAB_C;
94             } else if (strncmp(line, "SALT BAY", 8) == 0) {
95                 platform_type = MRAA_INTEL_EDISON_FAB_C;
96             } else if (strncmp(line, "DE3815", 6) == 0) {
97                 platform_type = MRAA_INTEL_DE3815;
98             } else if (strncmp(line, "NOTEBOOK", 8) == 0) {
99                 platform_type = MRAA_INTEL_MINNOWBOARD_MAX;
100             } else if (strncasecmp(line, "MinnowBoard MAX", 15) == 0) {
101                 platform_type = MRAA_INTEL_MINNOWBOARD_MAX;
102             } else {
103                 platform_type = MRAA_INTEL_GALILEO_GEN1;
104             }
105             free(line);
106         }
107         fclose(fh);
108     }
109
110     advance_func = (mraa_adv_func_t*) malloc(sizeof(mraa_adv_func_t));
111     memset(advance_func, 0, sizeof(mraa_adv_func_t));
112
113     switch(platform_type) {
114         case MRAA_INTEL_GALILEO_GEN2:
115             plat = mraa_intel_galileo_gen2();
116             break;
117         case MRAA_INTEL_GALILEO_GEN1:
118             plat = mraa_intel_galileo_rev_d();
119             break;
120         case MRAA_INTEL_EDISON_FAB_C:
121             plat = mraa_intel_edison_fab_c();
122             break;
123         case MRAA_INTEL_DE3815:
124             plat = mraa_intel_de3815();
125             break;
126         case MRAA_INTEL_MINNOWBOARD_MAX:
127             plat = mraa_intel_minnow_max();
128             break;
129
130         default:
131             plat = mraa_intel_galileo_rev_d();
132             syslog(LOG_ERR, "Platform not supported, initialising as MRAA_INTEL_GALILEO_GEN1");
133     }
134
135     syslog(LOG_NOTICE, "libmraa initialised for platform %d", platform_type);
136     return MRAA_SUCCESS;
137 }
138
139 void
140 mraa_deinit()
141 {
142     free(plat->pins);
143     free(plat);
144     closelog();
145 }
146
147 int
148 mraa_set_priority(const unsigned int priority)
149 {
150     struct sched_param sched_s;
151
152     memset(&sched_s, 0, sizeof(struct sched_param));
153     if (priority > sched_get_priority_max(SCHED_RR)) {
154         sched_s.sched_priority = sched_get_priority_max(SCHED_RR);
155     }
156     else {
157         sched_s.sched_priority = priority;
158     }
159
160     return sched_setscheduler(0, SCHED_RR, &sched_s);
161 }
162
163 mraa_result_t
164 mraa_setup_mux_mapped(mraa_pin_t meta)
165 {
166     int mi;
167     for (mi = 0; mi < meta.mux_total; mi++) {
168         mraa_gpio_context mux_i;
169         mux_i = mraa_gpio_init_raw(meta.mux[mi].pin);
170         if (mux_i == NULL)
171             return MRAA_ERROR_INVALID_HANDLE;
172         mraa_gpio_dir(mux_i, MRAA_GPIO_OUT);
173         if (mraa_gpio_write(mux_i, meta.mux[mi].value) != MRAA_SUCCESS)
174             return MRAA_ERROR_INVALID_RESOURCE;
175     }
176     return MRAA_SUCCESS;
177 }
178
179 void
180 mraa_result_print(mraa_result_t result)
181 {
182     switch (result) {
183         case MRAA_SUCCESS:
184             fprintf(stdout, "MRAA: SUCCESS\n");
185             break;
186         case MRAA_ERROR_FEATURE_NOT_IMPLEMENTED:
187             fprintf(stdout, "MRAA: Feature not implemented.\n");
188             break;
189         case MRAA_ERROR_FEATURE_NOT_SUPPORTED:
190             fprintf(stdout, "MRAA: Feature not supported by Hardware.\n");
191             break;
192         case MRAA_ERROR_INVALID_VERBOSITY_LEVEL:
193             fprintf(stdout, "MRAA: Invalid verbosity level.\n");
194             break;
195         case MRAA_ERROR_INVALID_PARAMETER:
196             fprintf(stdout, "MRAA: Invalid parameter.\n");
197             break;
198         case MRAA_ERROR_INVALID_HANDLE:
199             fprintf(stdout, "MRAA: Invalid Handle.\n");
200             break;
201         case MRAA_ERROR_NO_RESOURCES:
202             fprintf(stdout, "MRAA: No resources.\n");
203             break;
204         case MRAA_ERROR_INVALID_RESOURCE:
205             fprintf(stdout, "MRAA: Invalid resource.\n");
206             break;
207         case MRAA_ERROR_INVALID_QUEUE_TYPE:
208             fprintf(stdout, "MRAA: Invalid Queue Type.\n");
209             break;
210         case MRAA_ERROR_NO_DATA_AVAILABLE:
211             fprintf(stdout, "MRAA: No Data available.\n");
212             break;
213         case MRAA_ERROR_INVALID_PLATFORM:
214             fprintf(stdout, "MRAA: Platform not recognised.\n");
215             break;
216         case MRAA_ERROR_PLATFORM_NOT_INITIALISED:
217             fprintf(stdout, "MRAA: Platform not initialised.\n");
218             break;
219         case MRAA_ERROR_PLATFORM_ALREADY_INITIALISED:
220             fprintf(stdout, "MRAA: Platform already initialised.\n");
221             break;
222         case MRAA_ERROR_UNSPECIFIED:
223             fprintf(stdout, "MRAA: Unspecified Error.\n");
224             break;
225         default:
226             fprintf(stdout, "MRAA: Unrecognised error.\n");
227             break;
228     }
229 }
230
231 mraa_boolean_t
232 mraa_pin_mode_test(int pin, mraa_pinmodes_t mode)
233 {
234     if (plat == NULL) {
235         mraa_init();
236         if (plat == NULL)
237             return 0;
238     }
239     if (pin > plat->phy_pin_count || pin < 0)
240         return 0;
241
242     switch(mode) {
243         case MRAA_PIN_VALID:
244             if (plat->pins[pin].capabilites.valid == 1)
245                 return 1;
246             break;
247         case MRAA_PIN_GPIO:
248             if (plat->pins[pin].capabilites.gpio ==1)
249                 return 1;
250             break;
251         case MRAA_PIN_PWM:
252             if (plat->pins[pin].capabilites.pwm ==1)
253                 return 1;
254             break;
255         case MRAA_PIN_FAST_GPIO:
256             if (plat->pins[pin].capabilites.fast_gpio ==1)
257                 return 1;
258             break;
259         case MRAA_PIN_SPI:
260             if (plat->pins[pin].capabilites.spi ==1)
261                 return 1;
262             break;
263         case MRAA_PIN_I2C:
264             if (plat->pins[pin].capabilites.i2c ==1)
265                 return 1;
266             break;
267         case MRAA_PIN_AIO:
268             if (pin < plat->aio_count)
269                 pin = pin + plat->gpio_count;
270             if (plat->pins[pin].capabilites.aio ==1)
271                 return 1;
272             break;
273         default: break;
274     }
275     return 0;
276 }
277
278 mraa_platform_t mraa_get_platform_type()
279 {
280     return platform_type;
281 }
282
283 unsigned int
284 mraa_adc_raw_bits()
285 {
286     if (plat == NULL)
287         return 0;
288
289     if (plat->aio_count == 0)
290         return 0;
291
292     return plat->adc_raw;
293 }
294
295 unsigned int
296 mraa_adc_supported_bits()
297 {
298     if (plat == NULL)
299         return 0;
300
301     if (plat->aio_count == 0)
302         return 0;
303
304     return plat->adc_supported;
305 }
306
307 mraa_result_t
308 mraa_setup_uart(int index)
309 {
310     if (plat == NULL)
311         return MRAA_ERROR_PLATFORM_NOT_INITIALISED;
312
313     if (plat->uart_dev_count == 0)
314         return MRAA_ERROR_FEATURE_NOT_SUPPORTED;
315
316     if (plat->uart_dev_count <= index)
317         return MRAA_ERROR_NO_RESOURCES;
318
319     int pos = plat->uart_dev[index].rx;
320     if (pos >= 0) {
321         if (plat->pins[pos].uart.mux_total > 0)
322             if (mraa_setup_mux_mapped(plat->pins[pos].uart) != MRAA_SUCCESS)
323                 return MRAA_ERROR_INVALID_RESOURCE;
324     }
325
326     if (pos >= 0) {
327         pos = plat->uart_dev[index].tx;
328         if (plat->pins[pos].uart.mux_total > 0)
329             if (mraa_setup_mux_mapped(plat->pins[pos].uart) != MRAA_SUCCESS)
330                 return MRAA_ERROR_INVALID_RESOURCE;
331     }
332
333     return MRAA_SUCCESS;
334 }
335
336 char*
337 mraa_get_platform_name()
338 {
339     if (plat == NULL)
340         return "Unknown";
341     return plat->platform_name;
342 }