libopencm3
A free/libre/open-source firmware library for various ARM Cortex-M3 microcontrollers.
gpio_common_f0234.c
Go to the documentation of this file.
1 /** @addtogroup gpio_file
2 
3 @author @htmlonly © @endhtmlonly 2009
4 Uwe Hermann <uwe@hermann-uwe.de>
5 @author @htmlonly &copy; @endhtmlonly 2012
6 Ken Sarkies <ksarkies@internode.on.net>
7 
8 Each I/O port has 16 individually configurable bits. Many I/O pins share GPIO
9 functionality with a number of alternate functions and must be configured to
10 the alternate function mode if these are to be accessed. A feature is available
11 to remap alternative functions to a limited set of alternative pins in the
12 event of a clash of requirements.
13 
14 The data registers associated with each port for input and output are 32 bit
15 with the upper 16 bits unused. The output buffer must be written as a 32 bit
16 word, but individual bits may be set or reset separately in atomic operations
17 to avoid race conditions during interrupts. Bits may also be individually
18 locked to prevent accidental configuration changes. Once locked the
19 configuration cannot be changed until after the next reset.
20 
21 Each port bit can be configured as analog or digital input, the latter can be
22 floating or pulled up or down. As outputs they can be configured as either
23 push-pull or open drain, digital I/O or alternate function, and with maximum
24 output speeds of 2MHz, 10MHz, or 50MHz.
25 
26 On reset all ports are configured as digital floating input.
27 
28 @section gpio_api_ex Basic GPIO Handling API.
29 
30 Example 1: Push-pull digital output actions with pullup on ports C2 and C9
31 
32 @code
33  gpio_mode_setup(GPIOC, GPIO_MODE_OUTPUT,
34  GPIO_PUPD_PULLUP, GPIO2 | GPIO9);
35  gpio_set_output_options(GPIOC, GPIO_OTYPE_PP,
36  GPIO_OSPEED_25MHZ, GPIO2 | GPIO9);
37  gpio_set(GPIOC, GPIO2 | GPIO9);
38  gpio_clear(GPIOC, GPIO2);
39  gpio_toggle(GPIOC, GPIO2 | GPIO9);
40  gpio_port_write(GPIOC, 0x204);
41 @endcode
42 
43 Example 2: Digital input on port C12 with pullup
44 
45 @code
46  gpio_mode_setup(GPIOC, GPIO_MODE_INPUT,
47  GPIO_PUPD_PULLUP, GPIO12);
48  reg16 = gpio_port_read(GPIOC);
49 @endcode
50 
51 */
52 /*
53  * This file is part of the libopencm3 project.
54  *
55  * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
56  *
57  * This library is free software: you can redistribute it and/or modify
58  * it under the terms of the GNU Lesser General Public License as published by
59  * the Free Software Foundation, either version 3 of the License, or
60  * (at your option) any later version.
61  *
62  * This library is distributed in the hope that it will be useful,
63  * but WITHOUT ANY WARRANTY; without even the implied warranty of
64  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
65  * GNU Lesser General Public License for more details.
66  *
67  * You should have received a copy of the GNU Lesser General Public License
68  * along with this library. If not, see <http://www.gnu.org/licenses/>.
69  */
70 
71 /**@{*/
72 
73 #include <libopencm3/stm32/gpio.h>
74 
75 /*---------------------------------------------------------------------------*/
76 /** @brief Set GPIO Pin Mode
77 
78 Sets the Pin Direction and Analog/Digital Mode, and Output Pin Pullup,
79 for a set of GPIO pins on a given GPIO port.
80 
81 @param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id
82 @param[in] mode Unsigned int8. Pin mode @ref gpio_mode
83 @param[in] pull_up_down Unsigned int8. Pin pullup/pulldown configuration @ref
84 gpio_pup
85 @param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id
86  If multiple pins are to be set, use bitwise OR '|' to separate
87  them.
88 */
89 void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t pull_up_down,
90  uint16_t gpios)
91 {
92  uint16_t i;
93  uint32_t moder, pupd;
94 
95  /*
96  * We want to set the config only for the pins mentioned in gpios,
97  * but keeping the others, so read out the actual config first.
98  */
99  moder = GPIO_MODER(gpioport);
100  pupd = GPIO_PUPDR(gpioport);
101 
102  for (i = 0; i < 16; i++) {
103  if (!((1 << i) & gpios)) {
104  continue;
105  }
106 
107  moder &= ~GPIO_MODE_MASK(i);
108  moder |= GPIO_MODE(i, mode);
109  pupd &= ~GPIO_PUPD_MASK(i);
110  pupd |= GPIO_PUPD(i, pull_up_down);
111  }
112 
113  /* Set mode and pull up/down control registers. */
114  GPIO_MODER(gpioport) = moder;
115  GPIO_PUPDR(gpioport) = pupd;
116 }
117 
118 /*---------------------------------------------------------------------------*/
119 /** @brief Set GPIO Output Options
120 
121 When the pin is set to output mode, this sets the configuration (analog/digital
122 and open drain/push pull) and speed, for a set of GPIO pins on a given GPIO
123 port.
124 
125 @param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id
126 @param[in] otype Unsigned int8. Pin output type @ref gpio_output_type
127 @param[in] speed Unsigned int8. Pin speed @ref gpio_speed
128 @param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id
129  If multiple pins are to be set, use bitwise OR '|' to separate
130  them.
131 */
132 void gpio_set_output_options(uint32_t gpioport, uint8_t otype, uint8_t speed,
133  uint16_t gpios)
134 {
135  uint16_t i;
136  uint32_t ospeedr;
137 
138  if (otype == 0x1) {
139  GPIO_OTYPER(gpioport) |= gpios;
140  } else {
141  GPIO_OTYPER(gpioport) &= ~gpios;
142  }
143 
144  ospeedr = GPIO_OSPEEDR(gpioport);
145 
146  for (i = 0; i < 16; i++) {
147  if (!((1 << i) & gpios)) {
148  continue;
149  }
150  ospeedr &= ~GPIO_OSPEED_MASK(i);
151  ospeedr |= GPIO_OSPEED(i, speed);
152  }
153 
154  GPIO_OSPEEDR(gpioport) = ospeedr;
155 }
156 
157 /*---------------------------------------------------------------------------*/
158 /** @brief Set GPIO Alternate Function Selection
159 
160 Set the alternate function mapping number for each pin. Most pins have
161 alternate functions associated with them. When set to AF mode, a pin may be
162 used for one of its allocated alternate functions selected by the number given
163 here. To determine the number to be used for the desired function refer to the
164 individual datasheet for the particular device. A table is given under the Pin
165 Selection chapter.
166 
167 Note that a number of pins may be set but only with a single AF number. In
168 practice this would rarely be useful as each pin is likely to require a
169 different number.
170 
171 @param[in] gpioport Unsigned int32. Port identifier @ref gpio_port_id
172 @param[in] alt_func_num Unsigned int8. Pin alternate function number @ref
173 gpio_af_num
174 @param[in] gpios Unsigned int16. Pin identifiers @ref gpio_pin_id
175  If multiple pins are to be set, use bitwise OR '|' to separate
176  them.
177 */
178 void gpio_set_af(uint32_t gpioport, uint8_t alt_func_num, uint16_t gpios)
179 {
180  uint16_t i;
181  uint32_t afrl, afrh;
182 
183  afrl = GPIO_AFRL(gpioport);
184  afrh = GPIO_AFRH(gpioport);
185 
186  for (i = 0; i < 8; i++) {
187  if (!((1 << i) & gpios)) {
188  continue;
189  }
190  afrl &= ~GPIO_AFR_MASK(i);
191  afrl |= GPIO_AFR(i, alt_func_num);
192  }
193 
194  for (i = 8; i < 16; i++) {
195  if (!((1 << i) & gpios)) {
196  continue;
197  }
198  afrh &= ~GPIO_AFR_MASK(i - 8);
199  afrh |= GPIO_AFR(i - 8, alt_func_num);
200  }
201 
202  GPIO_AFRL(gpioport) = afrl;
203  GPIO_AFRH(gpioport) = afrh;
204 }
205 /**@}*/
206 
#define GPIO_AFRH(port)
#define GPIO_MODER(port)
#define GPIO_AFRL(port)
#define GPIO_PUPD(n, pupd)
#define GPIO_AFR_MASK(n)
#define GPIO_MODE_MASK(n)
#define GPIO_PUPDR(port)
#define GPIO_OTYPER(port)
#define GPIO_MODE(n, mode)
#define GPIO_OSPEED(n, speed)
#define GPIO_OSPEED_MASK(n)
#define GPIO_AFR(n, af)
#define GPIO_OSPEEDR(port)
#define GPIO_PUPD_MASK(n)
void gpio_set_af(uint32_t gpioport, uint8_t alt_func_num, uint16_t gpios)
Set GPIO Alternate Function Selection.
void gpio_mode_setup(uint32_t gpioport, uint8_t mode, uint8_t pull_up_down, uint16_t gpios)
Set GPIO Pin Mode.
void gpio_set_output_options(uint32_t gpioport, uint8_t otype, uint8_t speed, uint16_t gpios)
Set GPIO Output Options.