Changes ported from modules, to support multiple tmp101 sensors.
[dtplug] / core / pio.c
1 /****************************************************************************
2  *  core/pio.c
3  *
4  * Copyright 2012 Nathael Pajani <nathael.pajani@ed3l.fr>
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  *************************************************************************** */
21 /***************************************************************************** */
22 /*                GPIOs                                                        */
23 /***************************************************************************** */
25 /*   Public access to Pins setup
26  * Refer to LPC176x documentation (UM10360.pdf) for more information.
27  */
30 #include <stdint.h>
31 #include "core/lpc_regs_17xx.h"
32 #include "core/lpc_core_cm3.h"
33 #include "core/system.h"
34 #include "core/pio.h"
38 /* Simple copy function. */
39 void pio_copy(struct pio* dst, const struct pio* src)
40 {
41         if ((dst == NULL) || (src == NULL)) {
42                 return;
43         }
44         dst->port = src->port;
45         dst->pin = src->pin;
46         dst->alt_setting = src->alt_setting;
47 }
49 /* Configure the pin in the requested function and mode. */
50 void config_pio(const struct pio* pp, uint32_t mode)
51 {
52         struct lpc_pin_func_control* io_ctl = LPC_PIN_FUNCTION_CONTROL;
53         if ((pp == NULL) || (pp->port > 4) || (pp->pin > 31)) {
54                 return;
55         }
56         /* Set function */
57         io_ctl->func_sel[ LPC_IO_PIN_REG(pp->port, pp->pin) ] &= ~(0x03 << LPC_IO_PIN_OFFSET(pp->pin));
58         io_ctl->func_sel[ LPC_IO_PIN_REG(pp->port, pp->pin) ] |= (pp->alt_setting << LPC_IO_PIN_OFFSET(pp->pin));
59         /* Set mode */
60         io_ctl->mode_sel[ LPC_IO_PIN_REG(pp->port, pp->pin) ] &= ~(0x03 << LPC_IO_PIN_OFFSET(pp->pin));
61         io_ctl->mode_sel[ LPC_IO_PIN_REG(pp->port, pp->pin) ] |= ((mode & 0x03) << LPC_IO_PIN_OFFSET(pp->pin));
62         /* Set open drain (or not) */
63         if (mode & LPC_IO_MODE_OPEN_DRAIN) {
64                 io_ctl->opendrain_ctrl[ pp->port ] |= (0x01 << pp->pin);
65         } else {
66                 io_ctl->opendrain_ctrl[ pp->port ] &= ~(0x01 << pp->pin);
67         }
68 }
71 void set_pins(const struct pio_config* pins)
72 {
73         int i = 0;
74         for (i = 0; pins[i].pio.port != 0xFF; i++) {
75                 config_pio(&(pins[i].pio), pins[i].mode);
76         }
77 }