OpenMPTL - STM32F10X
C++ Microprocessor Template Library
gpio.hpp
Go to the documentation of this file.
1 /*
2  * OpenMPTL - C++ Microprocessor Template Library
3  *
4  * Copyright (C) 2012-2017 Axel Burri <axel@tty0.ch>
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 3 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  */
20 
21 #ifndef ARCH_GPIO_HPP_INCLUDED
22 #define ARCH_GPIO_HPP_INCLUDED
23 
24 // === GPIO Ports ===
25 //
26 // GPIO ports are configured as //input floating// upon reset and
27 // alternate functions are not enabled.
28 //
29 // Each GPIO port has two 32 bit configuration registers - GPIOx_CRL and
30 // GPIOx_CRH, two 32 bit data registers, GPIOx_IDR and GPIOx_ODR, a 32
31 // bit set-reset register, GPIO_xBSRR, a 16 bit reset register, GPIOx_BRR
32 // and a 32 bit locking register, GPIOx_LCKR.
33 //
34 // Each GPIO pin can be configured as one of:
35 //
36 // *Input floating
37 // *Input pull-up
38 // *Input pull-down
39 // *Analog input
40 // *Output open-drain
41 // *Output push-pull
42 // *Alternate function push-pull
43 // *Alternate function open-drain
44 
45 // === Configuring the GPIO ports ===
46 //
47 // Each I/O pin of a GPIO port has four configuration bits - GPIOx_CRL
48 // holds configuration bits for 8 pins and GPIOx_CRH holds the
49 // configuration bits for the remaining 8 pins.
50 //
51 // The four configuration bits are divided into two MODE bits and two CNF
52 // bits - with MODE bits occupying lower bit positions. For example, in
53 // the case GPIO port B, bits 0 and 1 of GPIOB_CRL are the MODE bits and
54 // bits 2 and 3 are the CNF bits for pin 0. The MODE bits can have the
55 // following values:
56 //
57 // *00 - Input mode (reset state)
58 // *01 - Output mode (max 10MHz speed)
59 // *10 - Output mode (max 2MHz speed)
60 // *11 - Output mode (max 50MHz speed)
61 //
62 // The CNF bit values are interpreted differently according to the
63 // MODE. If MODE is input, the CNF bit values are interpreted as:
64 
65 // *00 - Analog input
66 // *01 - Floating input
67 // *10 - Input with pull-up/pull-down
68 // *11 - reserved
69 //
70 // If MODE is output, the CNF bit values are interpreted as:
71 //
72 // *00 - General purpose output push-pull
73 // *01 - General purpose output open-drain
74 // *10 - Alternate function output push-pull
75 // *11 - Alternate function output open-drain
76 //
77 // Normally, to drive LED's, we will configure the output pins as
78 // push-pull.
79 
80 // === push/pull and open-drain ===
81 //
82 // The push-pull output actually uses two transistors. Each will be on to
83 // drive the output to the appropriate level: the top transistor will be
84 // on when the output has to be driven high and the bottom transistor
85 // will turn on when the output has to go low.
86 //
87 // The open-drain output lacks the top transistor. When the output has to
88 // go high you simply turn off the bottom transistor, but the line is now
89 // pulled high only by the pullup resistor.
90 //
91 // Your micro allows you to select between the two types, which means
92 // that by setting some bits in some register you actually enable/
93 // disable the top transistor and enable/disable the pullup (if internal,
94 // otherwise you just disable the top transistor and have to use an
95 // external pullup)
96 //
97 // The advantage of the push-pull output is the higher speed, because the
98 // line is driven both ways. With the pullup the line can only rise as
99 // fast as the RC time constant allows. The R is the pullup, the C is the
100 // parasitic capacitance, including the pin capacitance and the board
101 // capacitance.
102 // The push-pull can typically source more current. With the open-drain
103 // the current is limited by the R and R cannot be made very small,
104 // because the lower transistor has to sink that current when the output
105 // is low; that means higher power consumption.
106 //
107 // However, the open-drain allows you to cshort several outputs together,
108 // with a common pullup. This is called an wired-OR connection. Now you
109 // can drive the output low with any of the IO pins. To drive it high all
110 // ouputs have to be high. This is advantageous in some situations,
111 // because it eliminates the external gates that would otherwise be
112 // required.
113 
114 #include <type_traits>
115 #include <typelist.hpp>
116 #include <arch/rcc.hpp>
117 #include <freq.hpp>
118 #include <arch/reg/gpio.hpp>
119 #include <gpio_base.hpp>
120 
121 namespace mptl {
122 
123 
124 //////////////////// gpio ////////////////////
125 
126 
127 template< char port, int pin_no >
128 class gpio
129 {
130  static_assert(port >= 'A', "invalid GPIO port");
131 #if defined (STM32F10X_HD) || defined (STM32F10X_XL)
132  static_assert(port <= 'G', "invalid GPIO port");
133 #else
134  static_assert(port <= 'E', "invalid GPIO port");
135 #endif
136  static_assert((pin_no >= 0) && (pin_no < 16), "invalid GPIO pin-no");
137 
138 public:
139 
140  using GPIOx = GPIO<port>;
141 
143 
144 protected:
145 
146  static constexpr uint32_t pin_mask = (uint32_t)1 << pin_no;
147 
148 public: /* ------ configuration resources ------ */
149 
150  struct mode
151  {
152  /** Input mode */
154 
155  /** Output mode */
156  template<freq_t speed>
157  using output = typename std::enable_if<
158  speed == mhz(2) || speed == mhz(10) || speed == mhz(50),
160  speed == mhz(10) ? 1 :
161  speed == mhz(2) ? 2 :
162  speed == mhz(50) ? 3 : 0xff
163  >
164  >::type;
165  };
166 
167  struct input_type
168  {
169  /** Analog input */
171 
172  /** Floating input */
174 
175  /** Input with pull-up / pull-down */
177  };
178 
179  struct output_type
180  {
181  /** General purpose output push-pull (e.g. LED's) */
183 
184  /** General purpose output open-drain */
186 
187  /** Alternate function output push-pull */
189 
190  /** Alternate function output open-drain */
192  };
193 
194 public: /* ------ static member functions ------ */
195 
196  static void set() {
197  GPIOx::BSRR::store(pin_mask);
198  }
199  static void reset() {
200  GPIOx::BRR::store(pin_mask);
201  }
202 
203  static uint32_t read_input_bit() {
204  return GPIOx::IDR::test(pin_mask);
205  }
206 
207  static uint32_t read_output_bit() {
208  return GPIOx::ODR::test(pin_mask);
209  }
210 };
211 
212 
213 //////////////////// gpio_input ////////////////////
214 
215 
216 template<char port, unsigned pin_no, gpio_active_state active_state = gpio_active_state::high >
218 : public gpio_input_base< gpio< port, pin_no >, active_state >
219 {
221 public:
222  using resources = typelist<
223  typename gpio_type::resources,
224  typename gpio_type::mode::input
225  >;
226 };
227 
228 
229 //////////////////// gpio_output ////////////////////
230 
231 
232 template<
233  char port,
234  unsigned pin_no,
236  freq_t speed = mhz(50)
237  >
239 : public gpio_output_base< gpio< port, pin_no >, active_state >
240 {
242 public:
243  using resources = typelist<
244  typename gpio_type::resources,
245  typename gpio_type::mode::template output<speed>
246  >;
247 };
248 
249 
250 //////////////////// gpio_led ////////////////////
251 
252 
253 template<
254  char port,
255  unsigned pin_no,
257  freq_t speed = mhz(2)
258  >
259 class gpio_led
260 : public gpio_led_base< gpio_output< port, pin_no, active_state, speed > >
261 {
263 public:
264  using resources = typelist<
265  typename gpio_type::resources,
266  typename gpio_type::output_type::push_pull
267  >;
268 };
269 
270 } // namespace mptl
271 
272 #endif // ARCH_GPIO_HPP_INCLUDED
Definition: gpio.hpp:150
unsigned int freq_t
static uint32_t read_output_bit()
Definition: gpio.hpp:207
Definition: gpio.hpp:179
Definition: rcc.hpp:220
typelist< typename gpio_type::resources, typename gpio_type::output_type::push_pull > resources
Definition: gpio.hpp:267
Definition: gpio.hpp:128
static constexpr uint32_t pin_mask
Definition: gpio.hpp:146
typename std::enable_if< speed==mhz(2)||speed==mhz(10)||speed==mhz(50), regval< typename GPIOx::template CRx< pin_no >::MODE, speed==mhz(10) ? 1 :speed==mhz(2) ? 2 :speed==mhz(50) ? 3 :0xff > >::type output
Output mode.
Definition: gpio.hpp:164
Definition: gpio.hpp:167
gpio_active_state
Definition: gpio.hpp:217
typename mpl::make_typelist< sane_typelist<>, Tp... >::type typelist
static constexpr freq_t mhz(unsigned long long x)
Definition: gpio.hpp:259
typelist< typename gpio_type::resources, typename gpio_type::mode::input > resources
Definition: gpio.hpp:225
static uint32_t read_input_bit()
Definition: gpio.hpp:203
static void reset()
Definition: gpio.hpp:199
typelist< typename gpio_type::resources, typename gpio_type::mode::template output< speed > > resources
Definition: gpio.hpp:246
static __always_inline void store(Tp const value)
General-purpose and alternate-function I/Os (GPIOs and AFIOs)
Definition: gpio.hpp:39
Definition: gpio.hpp:238
static __always_inline value_type test(value_type const value)