Refactor to use new protocol module and sipo.
[bertos.git] / bertos / cpu / cortex-m3 / drv / gpio_lm3s.c
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos 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, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2010 Develer S.r.l. (http://www.develer.com/)
30  *
31  * -->
32  *
33  * \brief LM3S1968 GPIO control interface.
34  *
35  * \author Andrea Righi <arighi@develer.com>
36  */
37
38
39 #include "gpio_lm3s.h"
40
41 #include <cfg/compiler.h>
42 #include <cfg/debug.h>
43
44 #include <io/lm3s.h>
45
46
47 /* Set the pin(s) direction and mode */
48 INLINE int lm3s_gpioPinConfigMode(uint32_t port, uint8_t pins, uint32_t mode)
49 {
50         if (mode == GPIO_DIR_MODE_IN)
51         {
52                 HWREG(port + GPIO_O_DIR)   &= ~pins;
53                 HWREG(port + GPIO_O_AFSEL) &= ~pins;
54         }
55         else if (mode == GPIO_DIR_MODE_OUT)
56         {
57                 HWREG(port + GPIO_O_DIR)   |= pins;
58                 HWREG(port + GPIO_O_AFSEL) &= ~pins;
59         }
60         else if (mode == GPIO_DIR_MODE_HW)
61         {
62                 HWREG(port + GPIO_O_DIR)   &= ~pins;
63                 HWREG(port + GPIO_O_AFSEL) |= pins;
64         }
65         else
66         {
67                 ASSERT(0);
68                 return -1;
69         }
70         return 0;
71 }
72
73 /* Set the pin(s) output strength */
74 INLINE int
75 lm3s_gpioPinConfigStrength(uint32_t port, uint8_t pins, uint32_t strength)
76 {
77         if (strength == GPIO_STRENGTH_2MA)
78         {
79                 HWREG(port + GPIO_O_DR2R) |= pins;
80                 HWREG(port + GPIO_O_DR4R) &= ~pins;
81                 HWREG(port + GPIO_O_DR8R) &= ~pins;
82                 HWREG(port + GPIO_O_SLR)  &= ~pins;
83         }
84         else if (strength == GPIO_STRENGTH_4MA)
85         {
86                 HWREG(port + GPIO_O_DR2R) &= ~pins;
87                 HWREG(port + GPIO_O_DR4R) |= pins;
88                 HWREG(port + GPIO_O_DR8R) &= ~pins;
89                 HWREG(port + GPIO_O_SLR)  &= ~pins;
90         }
91         else if (strength == GPIO_STRENGTH_8MA)
92         {
93                 HWREG(port + GPIO_O_DR2R) &= ~pins;
94                 HWREG(port + GPIO_O_DR4R) &= ~pins;
95                 HWREG(port + GPIO_O_DR8R) |= pins;
96                 HWREG(port + GPIO_O_SLR)  &= ~pins;
97         }
98         else if (strength == GPIO_STRENGTH_8MA_SC)
99         {
100                 HWREG(port + GPIO_O_DR2R) &= ~pins;
101                 HWREG(port + GPIO_O_DR4R) &= ~pins;
102                 HWREG(port + GPIO_O_DR8R) |= pins;
103                 HWREG(port + GPIO_O_SLR)  |= pins;
104         }
105         else
106         {
107                 ASSERT(0);
108                 return -1;
109         }
110         return 0;
111 }
112
113 /* Set the pin(s) type */
114 INLINE int lm3s_gpioPinConfigType(uint32_t port, uint8_t pins, uint32_t type)
115 {
116         if (type == GPIO_PIN_TYPE_STD)
117         {
118                 HWREG(port + GPIO_O_ODR)   &= ~pins;
119                 HWREG(port + GPIO_O_PUR)   &= ~pins;
120                 HWREG(port + GPIO_O_PDR)   &= ~pins;
121                 HWREG(port + GPIO_O_DEN)   |= pins;
122                 HWREG(port + GPIO_O_AMSEL) &= ~pins;
123         }
124         else if (type == GPIO_PIN_TYPE_STD_WPU)
125         {
126                 HWREG(port + GPIO_O_ODR)   &= ~pins;
127                 HWREG(port + GPIO_O_PUR)   |= pins;
128                 HWREG(port + GPIO_O_PDR)   &= ~pins;
129                 HWREG(port + GPIO_O_DEN)   |= pins;
130                 HWREG(port + GPIO_O_AMSEL) &= ~pins;
131         }
132         else if (type == GPIO_PIN_TYPE_STD_WPD)
133         {
134                 HWREG(port + GPIO_O_ODR)   &= ~pins;
135                 HWREG(port + GPIO_O_PUR)   &= ~pins;
136                 HWREG(port + GPIO_O_PDR)   |= pins;
137                 HWREG(port + GPIO_O_DEN)   |= pins;
138                 HWREG(port + GPIO_O_AMSEL) &= ~pins;
139         }
140         else if (type == GPIO_PIN_TYPE_OD)
141         {
142                 HWREG(port + GPIO_O_ODR)   |= pins;
143                 HWREG(port + GPIO_O_PUR)   &= ~pins;
144                 HWREG(port + GPIO_O_PDR)   &= ~pins;
145                 HWREG(port + GPIO_O_DEN)   |= pins;
146                 HWREG(port + GPIO_O_AMSEL) &= ~pins;
147         }
148         else if (type == GPIO_PIN_TYPE_OD_WPU)
149         {
150                 HWREG(port + GPIO_O_ODR)   |= pins;
151                 HWREG(port + GPIO_O_PUR)   |= pins;
152                 HWREG(port + GPIO_O_PDR)   &= ~pins;
153                 HWREG(port + GPIO_O_DEN)   |= pins;
154                 HWREG(port + GPIO_O_AMSEL) &= ~pins;
155         }
156         else if (type == GPIO_PIN_TYPE_OD_WPD)
157         {
158                 HWREG(port + GPIO_O_ODR)   |= pins;
159                 HWREG(port + GPIO_O_PUR)   &= pins;
160                 HWREG(port + GPIO_O_PDR)   |= pins;
161                 HWREG(port + GPIO_O_DEN)   |= pins;
162                 HWREG(port + GPIO_O_AMSEL) &= ~pins;
163         }
164         else if (type == GPIO_PIN_TYPE_ANALOG)
165         {
166                 HWREG(port + GPIO_O_ODR)   &= ~pins;
167                 HWREG(port + GPIO_O_PUR)   &= ~pins;
168                 HWREG(port + GPIO_O_PDR)   &= ~pins;
169                 HWREG(port + GPIO_O_DEN)   &= ~pins;
170                 HWREG(port + GPIO_O_AMSEL) |= pins;
171         }
172         else
173         {
174                 ASSERT(0);
175                 return -1;
176         }
177         return 0;
178 }
179
180 /**
181  * Configure a GPIO pin
182  *
183  * \param port Base address of the GPIO port
184  * \param pins Bit-packed representation of the pin(s)
185  * \param mode Pin(s) configuration mode
186  * \param strength Output drive strength
187  * \param type Pin(s) type
188  *
189  * Return 0 on success, otherwise a negative value.
190  */
191 int lm3s_gpioPinConfig(uint32_t port, uint8_t pins,
192                 uint32_t mode, uint32_t strength, uint32_t type)
193 {
194         int ret;
195
196         ret = lm3s_gpioPinConfigMode(port, pins, mode);
197         if (UNLIKELY(ret < 0))
198                 return ret;
199         ret = lm3s_gpioPinConfigStrength(port, pins, strength);
200         if (UNLIKELY(ret < 0))
201                 return ret;
202         ret = lm3s_gpioPinConfigType(port, pins, type);
203         if (UNLIKELY(ret < 0))
204                 return ret;
205         return 0;
206 }