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
4Uwe Hermann <uwe@hermann-uwe.de>
5@author @htmlonly &copy; @endhtmlonly 2012
6Ken Sarkies <ksarkies@internode.on.net>
7
8Each I/O port has 16 individually configurable bits. Many I/O pins share GPIO
9functionality with a number of alternate functions and must be configured to
10the alternate function mode if these are to be accessed. A feature is available
11to remap alternative functions to a limited set of alternative pins in the
12event of a clash of requirements.
13
14The data registers associated with each port for input and output are 32 bit
15with the upper 16 bits unused. The output buffer must be written as a 32 bit
16word, but individual bits may be set or reset separately in atomic operations
17to avoid race conditions during interrupts. Bits may also be individually
18locked to prevent accidental configuration changes. Once locked the
19configuration cannot be changed until after the next reset.
20
21Each port bit can be configured as analog or digital input, the latter can be
22floating or pulled up or down. As outputs they can be configured as either
23push-pull or open drain, digital I/O or alternate function, and with maximum
24output speeds of 2MHz, 10MHz, or 50MHz.
25
26On reset all ports are configured as digital floating input.
27
28@section gpio_api_ex Basic GPIO Handling API.
29
30Example 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
43Example 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
74
75/*---------------------------------------------------------------------------*/
76/** @brief Set GPIO Pin Mode
77
78Sets the Pin Direction and Analog/Digital Mode, and Output Pin Pullup,
79for 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
84gpio_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*/
89void 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
121When the pin is set to output mode, this sets the configuration (analog/digital
122and open drain/push pull) and speed, for a set of GPIO pins on a given GPIO
123port.
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*/
132void 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
160Set the alternate function mapping number for each pin. Most pins have
161alternate functions associated with them. When set to AF mode, a pin may be
162used for one of its allocated alternate functions selected by the number given
163here. To determine the number to be used for the desired function refer to the
164individual datasheet for the particular device. A table is given under the Pin
165Selection chapter.
166
167Note that a number of pins may be set but only with a single AF number. In
168practice this would rarely be useful as each pin is likely to require a
169different 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
173gpio_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*/
178void 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_PUPDR(port)
#define GPIO_OTYPER(port)
#define GPIO_MODE(n, mode)
#define GPIO_OSPEED(n, speed)
#define GPIO_AFR(n, af)
#define GPIO_OSPEEDR(port)
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.