1 /***************************************************************************//**
\r
3 * @brief General Purpose IO (GPIO) peripheral API
\r
6 *******************************************************************************
\r
8 * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
\r
9 *******************************************************************************
\r
11 * Permission is granted to anyone to use this software for any purpose,
\r
12 * including commercial applications, and to alter it and redistribute it
\r
13 * freely, subject to the following restrictions:
\r
15 * 1. The origin of this software must not be misrepresented; you must not
\r
16 * claim that you wrote the original software.
\r
17 * 2. Altered source versions must be plainly marked as such, and must not be
\r
18 * misrepresented as being the original software.
\r
19 * 3. This notice may not be removed or altered from any source distribution.
\r
21 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
\r
22 * obligation to support this Software. Silicon Labs is providing the
\r
23 * Software "AS IS", with no express or implied warranties of any kind,
\r
24 * including, but not limited to, any implied warranties of merchantability
\r
25 * or fitness for any particular purpose or warranties against infringement
\r
26 * of any proprietary rights of a third party.
\r
28 * Silicon Labs will not be liable for any consequential, incidental, or
\r
29 * special damages, or any other relief, or for any claim by any third party,
\r
30 * arising from your use of this Software.
\r
32 ******************************************************************************/
\r
35 #include "em_gpio.h"
\r
37 #if defined(GPIO_COUNT) && (GPIO_COUNT > 0)
\r
38 /***************************************************************************//**
\r
39 * @addtogroup EM_Library
\r
41 ******************************************************************************/
\r
43 /***************************************************************************//**
\r
45 * @brief General Purpose Input/Output (GPIO) API
\r
47 ******************************************************************************/
\r
49 /*******************************************************************************
\r
50 ******************************* DEFINES ***********************************
\r
51 ******************************************************************************/
\r
53 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
\r
55 /** Validation of pin typically usable in assert statements. */
\r
56 #define GPIO_DRIVEMODE_VALID(mode) ((mode) <= 3)
\r
61 /*******************************************************************************
\r
62 ************************** GLOBAL FUNCTIONS *******************************
\r
63 ******************************************************************************/
\r
65 /***************************************************************************//**
\r
67 * Sets the pin location of the debug pins (Serial Wire interface).
\r
70 * Changing the pins used for debugging uncontrolled, may result in a lockout.
\r
72 * @param[in] location
\r
73 * The debug pin location to use (0-3).
\r
74 ******************************************************************************/
\r
75 void GPIO_DbgLocationSet(unsigned int location)
\r
77 #if defined ( _GPIO_ROUTE_SWLOCATION_MASK )
\r
78 EFM_ASSERT(location < AFCHANLOC_MAX);
\r
80 GPIO->ROUTE = (GPIO->ROUTE & ~_GPIO_ROUTE_SWLOCATION_MASK) |
\r
81 (location << _GPIO_ROUTE_SWLOCATION_SHIFT);
\r
88 /***************************************************************************//**
\r
90 * Sets the drive mode for a GPIO port.
\r
93 * The GPIO port to access.
\r
96 * Drive mode to use for port.
\r
97 ******************************************************************************/
\r
98 void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode)
\r
100 EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_DRIVEMODE_VALID(mode));
\r
102 GPIO->P[port].CTRL = (GPIO->P[port].CTRL & ~(_GPIO_P_CTRL_DRIVEMODE_MASK))
\r
103 | (mode << _GPIO_P_CTRL_DRIVEMODE_SHIFT);
\r
107 /***************************************************************************//**
\r
109 * Configure GPIO interrupt.
\r
112 * If reconfiguring a GPIO interrupt that is already enabled, it is generally
\r
113 * recommended to disable it first, see GPIO_Disable().
\r
115 * The actual GPIO interrupt handler must be in place before enabling the
\r
118 * Notice that any pending interrupt for the selected pin is cleared by this
\r
122 * A certain pin number can only be associated with one port. Ie, if GPIO
\r
123 * interrupt 1 is assigned to port A/pin 1, then it is not possibly to use
\r
124 * pin 1 from any other ports for interrupts. Please refer to the reference
\r
128 * The port to associate with @p pin.
\r
131 * The GPIO interrupt number (= port pin).
\r
133 * @param[in] risingEdge
\r
134 * Set to true if interrupts shall be enabled on rising edge, otherwise false.
\r
136 * @param[in] fallingEdge
\r
137 * Set to true if interrupts shall be enabled on falling edge, otherwise false.
\r
139 * @param[in] enable
\r
140 * Set to true if interrupt shall be enabled after configuration completed,
\r
141 * false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable().
\r
142 ******************************************************************************/
\r
143 void GPIO_IntConfig(GPIO_Port_TypeDef port,
\r
151 EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
\r
153 /* There are two registers controlling the interrupt configuration:
\r
154 * The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls
\r
158 GPIO->EXTIPSELL = (GPIO->EXTIPSELL & ~(0xF << (4 * pin))) |
\r
159 (port << (4 * pin));
\r
164 GPIO->EXTIPSELH = (GPIO->EXTIPSELH & ~(0xF << (4 * tmp))) |
\r
165 (port << (4 * tmp));
\r
168 /* Enable/disable rising edge */
\r
169 BITBAND_Peripheral(&(GPIO->EXTIRISE), pin, (unsigned int)risingEdge);
\r
171 /* Enable/disable falling edge */
\r
172 BITBAND_Peripheral(&(GPIO->EXTIFALL), pin, (unsigned int)fallingEdge);
\r
174 /* Clear any pending interrupt */
\r
175 GPIO->IFC = 1 << pin;
\r
177 /* Finally enable/disable interrupt */
\r
178 BITBAND_Peripheral(&(GPIO->IEN), pin, (unsigned int)enable);
\r
182 /***************************************************************************//**
\r
184 * Set the mode for a GPIO pin.
\r
187 * The GPIO port to access.
\r
190 * The pin number in the port.
\r
193 * The desired pin mode.
\r
196 * Value to set for pin in DOUT register. The DOUT setting is important for
\r
197 * even some input mode configurations, determining pull-up/down direction.
\r
198 ******************************************************************************/
\r
199 void GPIO_PinModeSet(GPIO_Port_TypeDef port,
\r
201 GPIO_Mode_TypeDef mode,
\r
204 EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_PIN_VALID(pin));
\r
206 /* If disabling pin, do not modify DOUT in order to reduce chance for */
\r
207 /* glitch/spike (may not be sufficient precaution in all use cases) */
\r
208 if (mode != gpioModeDisabled)
\r
212 GPIO->P[port].DOUTSET = 1 << pin;
\r
216 GPIO->P[port].DOUTCLR = 1 << pin;
\r
220 /* There are two registers controlling the pins for each port. The MODEL
\r
221 * register controls pins 0-7 and MODEH controls pins 8-15. */
\r
224 GPIO->P[port].MODEL = (GPIO->P[port].MODEL & ~(0xF << (pin * 4))) |
\r
225 (mode << (pin * 4));
\r
229 GPIO->P[port].MODEH = (GPIO->P[port].MODEH & ~(0xF << ((pin - 8) * 4))) |
\r
230 (mode << ((pin - 8) * 4));
\r
233 if (mode == gpioModeDisabled)
\r
237 GPIO->P[port].DOUTSET = 1 << pin;
\r
241 GPIO->P[port].DOUTCLR = 1 << pin;
\r
246 /** @} (end addtogroup GPIO) */
\r
247 /** @} (end addtogroup EM_Library) */
\r
249 #endif /* defined(GPIO_COUNT) && (GPIO_COUNT > 0) */
\r