1 /***************************************************************************//**
2 * @file
3 * @brief General Purpose IO (GPIO) peripheral API
4 * @author Energy Micro AS
5 * @version 3.0.0
6 *******************************************************************************
7 * @section License
8 * <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
9 *******************************************************************************
10 *
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute it
13 * freely, subject to the following restrictions:
14 *
15 * 1. The origin of this software must not be misrepresented; you must not
16 * claim that you wrote the original software.
17 * 2. Altered source versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software.
19 * 3. This notice may not be removed or altered from any source distribution.
20 *
21 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
22 * obligation to support this Software. Energy Micro AS is providing the
23 * Software "AS IS", with no express or implied warranties of any kind,
24 * including, but not limited to, any implied warranties of merchantability
25 * or fitness for any particular purpose or warranties against infringement
26 * of any proprietary rights of a third party.
27 *
28 * Energy Micro AS will not be liable for any consequential, incidental, or
29 * special damages, or any other relief, or for any claim by any third party,
30 * arising from your use of this Software.
31 *
32 ******************************************************************************/
33 #ifndef __EM_GPIO_H
34 #define __EM_GPIO_H
35
36 #include <stdbool.h>
37 #include "em_part.h"
38 #include "em_bitband.h"
39 #include "em_assert.h"
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 /***************************************************************************//**
46 * @addtogroup EM_Library
47 * @{
48 ******************************************************************************/
49
50 /***************************************************************************//**
51 * @addtogroup GPIO
52 * @{
53 ******************************************************************************/
54
55 /*******************************************************************************
56 ******************************** ENUMS ************************************
57 ******************************************************************************/
58
59 /** GPIO ports identificator. */
60 typedef enum
61 {
62 gpioPortA = 0, /**< Port A */
63 gpioPortB = 1, /**< Port B */
64 gpioPortC = 2, /**< Port C */
65 gpioPortD = 3, /**< Port D */
66 gpioPortE = 4, /**< Port E */
67 gpioPortF = 5 /**< Port F */
68 } GPIO_Port_TypeDef;
69
70 /** GPIO drive mode. */
71 typedef enum
72 {
73 /** Default 6mA */
74 gpioDriveModeStandard = GPIO_P_CTRL_DRIVEMODE_STANDARD,
75 /** 0.5 mA */
76 gpioDriveModeLowest = GPIO_P_CTRL_DRIVEMODE_LOWEST,
77 /** 20 mA */
78 gpioDriveModeHigh = GPIO_P_CTRL_DRIVEMODE_HIGH,
79 /** 2 mA */
80 gpioDriveModeLow = GPIO_P_CTRL_DRIVEMODE_LOW
81 } GPIO_DriveMode_TypeDef;
82
83 /** Pin mode. For more details on each mode, please refer to the EFM32
84 * reference manual. */
85 typedef enum
86 {
87 /** Input disabled. Pullup if DOUT is set. */
88 gpioModeDisabled = _GPIO_P_MODEL_MODE0_DISABLED,
89 /** Input enabled. Filter if DOUT is set */
90 gpioModeInput = _GPIO_P_MODEL_MODE0_INPUT,
91 /** Input enabled. DOUT determines pull direction */
92 gpioModeInputPull = _GPIO_P_MODEL_MODE0_INPUTPULL,
93 /** Input enabled with filter. DOUT determines pull direction */
94 gpioModeInputPullFilter = _GPIO_P_MODEL_MODE0_INPUTPULLFILTER,
95 /** Push-pull output */
96 gpioModePushPull = _GPIO_P_MODEL_MODE0_PUSHPULL,
97 /** Push-pull output with drive-strength set by DRIVEMODE */
98 gpioModePushPullDrive = _GPIO_P_MODEL_MODE0_PUSHPULLDRIVE,
99 /** Wired-or output */
100 gpioModeWiredOr = _GPIO_P_MODEL_MODE0_WIREDOR,
101 /** Wired-or output with pull-down */
102 gpioModeWiredOrPullDown = _GPIO_P_MODEL_MODE0_WIREDORPULLDOWN,
103 /** Open-drain output */
104 gpioModeWiredAnd = _GPIO_P_MODEL_MODE0_WIREDAND,
105 /** Open-drain output with filter */
106 gpioModeWiredAndFilter = _GPIO_P_MODEL_MODE0_WIREDANDFILTER,
107 /** Open-drain output with pullup */
108 gpioModeWiredAndPullUp = _GPIO_P_MODEL_MODE0_WIREDANDPULLUP,
109 /** Open-drain output with filter and pullup */
110 gpioModeWiredAndPullUpFilter = _GPIO_P_MODEL_MODE0_WIREDANDPULLUPFILTER,
111 /** Open-drain output with drive-strength set by DRIVEMODE */
112 gpioModeWiredAndDrive = _GPIO_P_MODEL_MODE0_WIREDANDDRIVE,
113 /** Open-drain output with filter and drive-strength set by DRIVEMODE */
114 gpioModeWiredAndDriveFilter = _GPIO_P_MODEL_MODE0_WIREDANDDRIVEFILTER,
115 /** Open-drain output with pullup and drive-strength set by DRIVEMODE */
116 gpioModeWiredAndDrivePullUp = _GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUP,
117 /** Open-drain output with filter, pullup and drive-strength set by DRIVEMODE */
118 gpioModeWiredAndDrivePullUpFilter = _GPIO_P_MODEL_MODE0_WIREDANDDRIVEPULLUPFILTER
119 } GPIO_Mode_TypeDef;
120
121 /*******************************************************************************
122 ***************************** PROTOTYPES **********************************
123 ******************************************************************************/
124
125 void GPIO_DbgLocationSet(unsigned int location);
126 #if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
127 __STATIC_INLINE void GPIO_EM4SetPinRetention(bool enable);
128 #endif
129
130 /***************************************************************************//**
131 * @brief
132 * Enable/disable serial wire clock pin.
133 *
134 * @note
135 * Disabling SWDClk will disable the debug interface, which may result in
136 * a lockout if done early in startup (before debugger is able to halt core).
137 *
138 * @param[in] enable
139 * @li false - disable serial wire clock.
140 * @li true - enable serial wire clock (default after reset).
141 ******************************************************************************/
GPIO_DbgSWDClkEnable(bool enable)142 __STATIC_INLINE void GPIO_DbgSWDClkEnable(bool enable)
143 {
144 BITBAND_Peripheral(&(GPIO->ROUTE), _GPIO_ROUTE_SWCLKPEN_SHIFT, (unsigned int)enable);
145 }
146
147
148 /***************************************************************************//**
149 * @brief
150 * Enable/disable serial wire data pin.
151 *
152 * @note
153 * Disabling SWDClk will disable the debug interface, which may result in
154 * a lockout if done early in startup (before debugger is able to halt core).
155 *
156 * @param[in] enable
157 * @li false - disable serial wire data pin.
158 * @li true - enable serial wire data pin (default after reset).
159 ******************************************************************************/
GPIO_DbgSWDIOEnable(bool enable)160 __STATIC_INLINE void GPIO_DbgSWDIOEnable(bool enable)
161 {
162 BITBAND_Peripheral(&(GPIO->ROUTE), _GPIO_ROUTE_SWDIOPEN_SHIFT, (unsigned int)enable);
163 }
164
165
166 /***************************************************************************//**
167 * @brief
168 * Enable/Disable serial wire output pin.
169 *
170 * @note
171 * Enabling this pin is not sufficient to fully enable serial wire output
172 * which is also dependent on issues outside the GPIO module. Please refer to
173 * DBG_SWOEnable().
174 *
175 * @param[in] enable
176 * @li false - disable serial wire viewer pin (default after reset).
177 * @li true - enable serial wire viewer pin.
178 ******************************************************************************/
GPIO_DbgSWOEnable(bool enable)179 __STATIC_INLINE void GPIO_DbgSWOEnable(bool enable)
180 {
181 BITBAND_Peripheral(&(GPIO->ROUTE), _GPIO_ROUTE_SWOPEN_SHIFT, (unsigned int)enable);
182 }
183
184
185 void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode);
186
187
188 #if defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_TINY_FAMILY)
189 /**************************************************************************//**
190 * @brief
191 * Disable GPIO pin wake-up from EM4.
192 *
193 * @param[in] pinmask
194 * Bitmask containing the bitwise logic OR of which GPIO pin(s) to disable.
195 * Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
196 *****************************************************************************/
GPIO_EM4DisablePinWakeup(uint32_t pinmask)197 __STATIC_INLINE void GPIO_EM4DisablePinWakeup(uint32_t pinmask)
198 {
199 EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);
200
201 GPIO->EM4WUEN &= ~pinmask;
202 }
203
204
205 /**************************************************************************//**
206 * @brief
207 * Enable GPIO pin wake-up from EM4. When the function exits,
208 * EM4 mode can be safely entered.
209 *
210 * @note
211 * It is assumed that the GPIO pin modes are set correctly.
212 * Valid modes are @ref gpioModeInput and @ref gpioModeInputPull.
213 *
214 * @param[in] pinmask
215 * Bitmask containing the bitwise logic OR of which GPIO pin(s) to enable.
216 * Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
217 * @param[in] polaritymask
218 * Bitmask containing the bitwise logic OR of GPIO pin(s) wake-up polarity.
219 * Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
220 *****************************************************************************/
GPIO_EM4EnablePinWakeup(uint32_t pinmask,uint32_t polaritymask)221 __STATIC_INLINE void GPIO_EM4EnablePinWakeup(uint32_t pinmask,
222 uint32_t polaritymask)
223 {
224 EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);
225 EFM_ASSERT((polaritymask & ~_GPIO_EM4WUPOL_MASK) == 0);
226
227 GPIO->EM4WUPOL &= ~pinmask; /* Set wakeup polarity */
228 GPIO->EM4WUPOL |= pinmask & polaritymask;
229 GPIO->EM4WUEN |= pinmask; /* Enable wakeup */
230
231 GPIO_EM4SetPinRetention(true); /* Enable pin retention */
232
233 GPIO->CMD = GPIO_CMD_EM4WUCLR; /* Clear wake-up logic */
234 }
235
236 /**************************************************************************//**
237 * @brief
238 * Check which GPIO pin(s) that caused a wake-up from EM4.
239 *
240 * @return
241 * Bitmask containing the bitwise logic OR of which GPIO pin(s) caused the
242 * wake-up. Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
243 *****************************************************************************/
GPIO_EM4GetPinWakeupCause(void)244 __STATIC_INLINE uint32_t GPIO_EM4GetPinWakeupCause(void)
245 {
246 return GPIO->EM4WUCAUSE & _GPIO_EM4WUCAUSE_MASK;
247 }
248
249
250 /**************************************************************************//**
251 * @brief
252 * Enable GPIO pin retention of output enable, output value, pull enable and
253 * pull direction in EM4.
254 *
255 * @param[in] enable
256 * @li true - enable EM4 pin retention.
257 * @li false - disable EM4 pin retention.
258 *****************************************************************************/
GPIO_EM4SetPinRetention(bool enable)259 __STATIC_INLINE void GPIO_EM4SetPinRetention(bool enable)
260 {
261 if (enable)
262 {
263 GPIO->CTRL |= GPIO_CTRL_EM4RET;
264 }
265 else
266 {
267 GPIO->CTRL &= ~GPIO_CTRL_EM4RET;
268 }
269 }
270 #endif
271
272
273 /***************************************************************************//**
274 * @brief
275 * Enable/disable input sensing.
276 *
277 * @details
278 * Disabling input sensing if not used, can save some energy consumption.
279 *
280 * @param[in] val
281 * Bitwise logic OR of one or more of:
282 * @li GPIO_INSENSE_INTSENSE - interrupt input sensing.
283 * @li GPIO_INSENSE_PRSSENSE - peripheral reflex system input sensing.
284 *
285 * @param[in] mask
286 * Mask containing bitwise logic OR of bits similar as for @p val used to indicate
287 * which input sense options to disable/enable.
288 ******************************************************************************/
GPIO_InputSenseSet(uint32_t val,uint32_t mask)289 __STATIC_INLINE void GPIO_InputSenseSet(uint32_t val, uint32_t mask)
290 {
291 GPIO->INSENSE = (GPIO->INSENSE & ~mask) | (val & mask);
292 }
293
294
295 /***************************************************************************//**
296 * @brief
297 * Clear one or more pending GPIO interrupts.
298 *
299 * @param[in] flags
300 * Bitwise logic OR of GPIO interrupt sources to clear.
301 ******************************************************************************/
GPIO_IntClear(uint32_t flags)302 __STATIC_INLINE void GPIO_IntClear(uint32_t flags)
303 {
304 GPIO->IFC = flags;
305 }
306
307
308 void GPIO_IntConfig(GPIO_Port_TypeDef port,
309 unsigned int pin,
310 bool risingEdge,
311 bool fallingEdge,
312 bool enable);
313
314
315 /***************************************************************************//**
316 * @brief
317 * Disable one or more GPIO interrupts.
318 *
319 * @param[in] flags
320 * GPIO interrupt sources to disable.
321 ******************************************************************************/
GPIO_IntDisable(uint32_t flags)322 __STATIC_INLINE void GPIO_IntDisable(uint32_t flags)
323 {
324 GPIO->IEN &= ~flags;
325 }
326
327
328 /***************************************************************************//**
329 * @brief
330 * Enable one or more GPIO interrupts.
331 *
332 * @note
333 * Depending on the use, a pending interrupt may already be set prior to
334 * enabling the interrupt. Consider using GPIO_IntClear() prior to enabling
335 * if such a pending interrupt should be ignored.
336 *
337 * @param[in] flags
338 * GPIO interrupt sources to enable.
339 ******************************************************************************/
GPIO_IntEnable(uint32_t flags)340 __STATIC_INLINE void GPIO_IntEnable(uint32_t flags)
341 {
342 GPIO->IEN |= flags;
343 }
344
345
346 /***************************************************************************//**
347 * @brief
348 * Get pending GPIO interrupts.
349 *
350 * @return
351 * GPIO interrupt sources pending.
352 ******************************************************************************/
GPIO_IntGet(void)353 __STATIC_INLINE uint32_t GPIO_IntGet(void)
354 {
355 return(GPIO->IF);
356 }
357
358
359 /***************************************************************************//**
360 * @brief
361 * Get enabled and pending GPIO interrupt flags.
362 * Useful for handling more interrupt sources in the same interrupt handler.
363 *
364 * @note
365 * Interrupt flags are not cleared by the use of this function.
366 *
367 * @return
368 * Pending and enabled GPIO interrupt sources.
369 * The return value is the bitwise AND combination of
370 * - the OR combination of enabled interrupt sources in GPIO_IEN register
371 * and
372 * - the OR combination of valid interrupt flags in GPIO_IF register.
373 ******************************************************************************/
GPIO_IntGetEnabled(void)374 __STATIC_INLINE uint32_t GPIO_IntGetEnabled(void)
375 {
376 uint32_t tmp;
377
378 /* Store GPIO->IEN in temporary variable in order to define explicit order
379 * of volatile accesses. */
380 tmp = GPIO->IEN;
381
382 /* Bitwise AND of pending and enabled interrupts */
383 return GPIO->IF & tmp;
384 }
385
386
387 /**************************************************************************//**
388 * @brief
389 * Set one or more pending GPIO interrupts from SW.
390 *
391 * @param[in] flags
392 * GPIO interrupt sources to set to pending.
393 *****************************************************************************/
GPIO_IntSet(uint32_t flags)394 __STATIC_INLINE void GPIO_IntSet(uint32_t flags)
395 {
396 GPIO->IFS = flags;
397 }
398
399
400 /***************************************************************************//**
401 * @brief
402 * Locks the GPIO configuration.
403 ******************************************************************************/
GPIO_Lock(void)404 __STATIC_INLINE void GPIO_Lock(void)
405 {
406 GPIO->LOCK = GPIO_LOCK_LOCKKEY_LOCK;
407 }
408
409
410 unsigned int GPIO_PinInGet(GPIO_Port_TypeDef port, unsigned int pin);
411 void GPIO_PinModeSet(GPIO_Port_TypeDef port,
412 unsigned int pin,
413 GPIO_Mode_TypeDef mode,
414 unsigned int out);
415 void GPIO_PinOutClear(GPIO_Port_TypeDef port, unsigned int pin);
416 unsigned int GPIO_PinOutGet(GPIO_Port_TypeDef port, unsigned int pin);
417 void GPIO_PinOutSet(GPIO_Port_TypeDef port, unsigned int pin);
418 void GPIO_PinOutToggle(GPIO_Port_TypeDef port, unsigned int pin);
419
420 uint32_t GPIO_PortInGet(GPIO_Port_TypeDef port);
421 void GPIO_PortOutClear(GPIO_Port_TypeDef port, uint32_t pins);
422 uint32_t GPIO_PortOutGet(GPIO_Port_TypeDef port);
423 void GPIO_PortOutSet(GPIO_Port_TypeDef port, uint32_t pins);
424 void GPIO_PortOutSetVal(GPIO_Port_TypeDef port, uint32_t val, uint32_t mask);
425 void GPIO_PortOutToggle(GPIO_Port_TypeDef port, uint32_t pins);
426
427 /***************************************************************************//**
428 * @brief
429 * Unlocks the GPIO configuration.
430 ******************************************************************************/
GPIO_Unlock(void)431 __STATIC_INLINE void GPIO_Unlock(void)
432 {
433 GPIO->LOCK = GPIO_LOCK_LOCKKEY_UNLOCK;
434 }
435
436
437 /** @} (end addtogroup GPIO) */
438 /** @} (end addtogroup EM_Library) */
439
440 #ifdef __cplusplus
441 }
442 #endif
443
444 #endif /* __EM_GPIO_H */
445