added prescaler for 16 bit pwm in LPC1347 target
Fork of mbed-dev by
Diff: targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/emlib/src/em_gpio.c
- Revision:
- 144:ef7eb2e8f9f7
- Parent:
- 50:a417edff4437
diff -r 423e1876dc07 -r ef7eb2e8f9f7 targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/emlib/src/em_gpio.c --- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/emlib/src/em_gpio.c Tue Aug 02 14:07:36 2016 +0000 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/emlib/src/em_gpio.c Fri Sep 02 15:07:44 2016 +0100 @@ -1,320 +1,320 @@ -/***************************************************************************//** - * @file em_gpio.c - * @brief General Purpose IO (GPIO) peripheral API - * devices. - * @version 4.2.1 - ******************************************************************************* - * @section License - * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b> - ******************************************************************************* - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - * - * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no - * obligation to support this Software. Silicon Labs is providing the - * Software "AS IS", with no express or implied warranties of any kind, - * including, but not limited to, any implied warranties of merchantability - * or fitness for any particular purpose or warranties against infringement - * of any proprietary rights of a third party. - * - * Silicon Labs will not be liable for any consequential, incidental, or - * special damages, or any other relief, or for any claim by any third party, - * arising from your use of this Software. - * - ******************************************************************************/ - - -#include "em_gpio.h" - -#if defined(GPIO_COUNT) && (GPIO_COUNT > 0) - -/***************************************************************************//** - * @addtogroup EM_Library - * @{ - ******************************************************************************/ - -/***************************************************************************//** - * @addtogroup GPIO - * @brief General Purpose Input/Output (GPIO) API - * @{ - ******************************************************************************/ - -/******************************************************************************* - ******************************* DEFINES *********************************** - ******************************************************************************/ - -/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */ - -/** Validation of pin typically usable in assert statements. */ -#define GPIO_DRIVEMODE_VALID(mode) ((mode) <= 3) -#define GPIO_STRENGHT_VALID(strenght) (!((strenght) & \ - ~(_GPIO_P_CTRL_DRIVESTRENGTH_MASK \ - | _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK))) -/** @endcond */ - - -/******************************************************************************* - ************************** GLOBAL FUNCTIONS ******************************* - ******************************************************************************/ - -/***************************************************************************//** - * @brief - * Sets the pin location of the debug pins (Serial Wire interface). - * - * @note - * Changing the pins used for debugging uncontrolled, may result in a lockout. - * - * @param[in] location - * The debug pin location to use (0-3). - ******************************************************************************/ -void GPIO_DbgLocationSet(unsigned int location) -{ -#if defined ( _GPIO_ROUTE_SWLOCATION_MASK ) - EFM_ASSERT(location < AFCHANLOC_MAX); - - GPIO->ROUTE = (GPIO->ROUTE & ~_GPIO_ROUTE_SWLOCATION_MASK) | - (location << _GPIO_ROUTE_SWLOCATION_SHIFT); -#else - (void)location; -#endif -} - -#if defined (_GPIO_P_CTRL_DRIVEMODE_MASK) -/***************************************************************************//** - * @brief - * Sets the drive mode for a GPIO port. - * - * @param[in] port - * The GPIO port to access. - * - * @param[in] mode - * Drive mode to use for port. - ******************************************************************************/ -void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode) -{ - EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_DRIVEMODE_VALID(mode)); - - GPIO->P[port].CTRL = (GPIO->P[port].CTRL & ~(_GPIO_P_CTRL_DRIVEMODE_MASK)) - | (mode << _GPIO_P_CTRL_DRIVEMODE_SHIFT); -} -#endif - - -#if defined (_GPIO_P_CTRL_DRIVESTRENGTH_MASK) -/***************************************************************************//** - * @brief - * Sets the drive strength for a GPIO port. - * - * @param[in] port - * The GPIO port to access. - * - * @param[in] strength - * Drive strength to use for port. - ******************************************************************************/ -void GPIO_DriveStrengthSet(GPIO_Port_TypeDef port, - GPIO_DriveStrength_TypeDef strength) -{ - EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_STRENGHT_VALID(strength)); - BUS_RegMaskedWrite(&GPIO->P[port].CTRL, - _GPIO_P_CTRL_DRIVESTRENGTH_MASK | _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK, - strength); -} -#endif - -/***************************************************************************//** - * @brief - * Configure GPIO interrupt. - * - * @details - * If reconfiguring a GPIO interrupt that is already enabled, it is generally - * recommended to disable it first, see GPIO_Disable(). - * - * The actual GPIO interrupt handler must be in place before enabling the - * interrupt. - * - * Notice that any pending interrupt for the selected pin is cleared by this - * function. - * - * @note - * A certain pin number can only be associated with one port. Ie, if GPIO - * interrupt 1 is assigned to port A/pin 1, then it is not possibly to use - * pin 1 from any other ports for interrupts. Please refer to the reference - * manual. - * - * @param[in] port - * The port to associate with @p pin. - * - * @param[in] pin - * The GPIO interrupt number (= port pin). - * - * @param[in] risingEdge - * Set to true if interrupts shall be enabled on rising edge, otherwise false. - * - * @param[in] fallingEdge - * Set to true if interrupts shall be enabled on falling edge, otherwise false. - * - * @param[in] enable - * Set to true if interrupt shall be enabled after configuration completed, - * false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable(). - ******************************************************************************/ -void GPIO_IntConfig(GPIO_Port_TypeDef port, - unsigned int pin, - bool risingEdge, - bool fallingEdge, - bool enable) -{ - uint32_t tmp; - - EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin)); - - /* There are two registers controlling the interrupt configuration: - * The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls - * pins 8-15. */ - if (pin < 8) - { - BUS_RegMaskedWrite(&GPIO->EXTIPSELL, - 0xF << (4 * pin), - port << (4 * pin)); - } - else - { - tmp = pin - 8; - BUS_RegMaskedWrite(&GPIO->EXTIPSELH, - 0xF << (4 * tmp), - port << (4 * tmp)); - } - - /* Enable/disable rising edge */ - BUS_RegBitWrite(&(GPIO->EXTIRISE), pin, risingEdge); - - /* Enable/disable falling edge */ - BUS_RegBitWrite(&(GPIO->EXTIFALL), pin, fallingEdge); - - /* Clear any pending interrupt */ - GPIO->IFC = 1 << pin; - - /* Finally enable/disable interrupt */ - BUS_RegBitWrite(&(GPIO->IEN), pin, enable); -} - - -/***************************************************************************//** - * @brief - * Set the mode for a GPIO pin. - * - * @param[in] port - * The GPIO port to access. - * - * @param[in] pin - * The pin number in the port. - * - * @param[in] mode - * The desired pin mode. - * - * @param[in] out - * Value to set for pin in DOUT register. The DOUT setting is important for - * even some input mode configurations, determining pull-up/down direction. - ******************************************************************************/ -void GPIO_PinModeSet(GPIO_Port_TypeDef port, - unsigned int pin, - GPIO_Mode_TypeDef mode, - unsigned int out) -{ - EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin)); - - /* If disabling pin, do not modify DOUT in order to reduce chance for */ - /* glitch/spike (may not be sufficient precaution in all use cases) */ - if (mode != gpioModeDisabled) - { - if (out) - { - GPIO_PinOutSet(port, pin); - } - else - { - GPIO_PinOutClear(port, pin); - } - } - - /* There are two registers controlling the pins for each port. The MODEL - * register controls pins 0-7 and MODEH controls pins 8-15. */ - if (pin < 8) - { - BUS_RegMaskedWrite(&GPIO->P[port].MODEL, - 0xF << (pin * 4), - mode << (pin * 4)); - } - else - { - BUS_RegMaskedWrite(&GPIO->P[port].MODEH, - 0xF << ((pin - 8) * 4), - mode << ((pin - 8) * 4)); - } - - if (mode == gpioModeDisabled) - { - if (out) - { - GPIO_PinOutSet(port, pin); - } - else - { - GPIO_PinOutClear(port, pin); - } - } -} - -#if defined( _GPIO_EM4WUEN_MASK ) -/**************************************************************************//** - * @brief - * Enable GPIO pin wake-up from EM4. When the function exits, - * EM4 mode can be safely entered. - * - * @note - * It is assumed that the GPIO pin modes are set correctly. - * Valid modes are @ref gpioModeInput and @ref gpioModeInputPull. - * - * @param[in] pinmask - * Bitmask containing the bitwise logic OR of which GPIO pin(s) to enable. - * Refer to Reference Manuals for pinmask to GPIO port/pin mapping. - * @param[in] polaritymask - * Bitmask containing the bitwise logic OR of GPIO pin(s) wake-up polarity. - * Refer to Reference Manuals for pinmask to GPIO port/pin mapping. - *****************************************************************************/ -void GPIO_EM4EnablePinWakeup(uint32_t pinmask, uint32_t polaritymask) -{ - EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0); - -#if defined( _GPIO_EM4WUPOL_MASK ) - EFM_ASSERT((polaritymask & ~_GPIO_EM4WUPOL_MASK) == 0); - GPIO->EM4WUPOL &= ~pinmask; /* Set wakeup polarity */ - GPIO->EM4WUPOL |= pinmask & polaritymask; -#elif defined( _GPIO_EXTILEVEL_MASK ) - EFM_ASSERT((polaritymask & ~_GPIO_EXTILEVEL_MASK) == 0); - GPIO->EXTILEVEL &= ~pinmask; - GPIO->EXTILEVEL |= pinmask & polaritymask; -#endif - GPIO->EM4WUEN |= pinmask; /* Enable wakeup */ - - GPIO_EM4SetPinRetention(true); /* Enable pin retention */ - -#if defined( _GPIO_CMD_EM4WUCLR_MASK ) - GPIO->CMD = GPIO_CMD_EM4WUCLR; /* Clear wake-up logic */ -#elif defined( _GPIO_IFC_EM4WU_MASK ) - GPIO_IntClear(pinmask); -#endif -} -#endif - -/** @} (end addtogroup GPIO) */ -/** @} (end addtogroup EM_Library) */ - -#endif /* defined(GPIO_COUNT) && (GPIO_COUNT > 0) */ +/***************************************************************************//** + * @file em_gpio.c + * @brief General Purpose IO (GPIO) peripheral API + * devices. + * @version 4.2.1 + ******************************************************************************* + * @section License + * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b> + ******************************************************************************* + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + * + * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no + * obligation to support this Software. Silicon Labs is providing the + * Software "AS IS", with no express or implied warranties of any kind, + * including, but not limited to, any implied warranties of merchantability + * or fitness for any particular purpose or warranties against infringement + * of any proprietary rights of a third party. + * + * Silicon Labs will not be liable for any consequential, incidental, or + * special damages, or any other relief, or for any claim by any third party, + * arising from your use of this Software. + * + ******************************************************************************/ + + +#include "em_gpio.h" + +#if defined(GPIO_COUNT) && (GPIO_COUNT > 0) + +/***************************************************************************//** + * @addtogroup EM_Library + * @{ + ******************************************************************************/ + +/***************************************************************************//** + * @addtogroup GPIO + * @brief General Purpose Input/Output (GPIO) API + * @{ + ******************************************************************************/ + +/******************************************************************************* + ******************************* DEFINES *********************************** + ******************************************************************************/ + +/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */ + +/** Validation of pin typically usable in assert statements. */ +#define GPIO_DRIVEMODE_VALID(mode) ((mode) <= 3) +#define GPIO_STRENGHT_VALID(strenght) (!((strenght) & \ + ~(_GPIO_P_CTRL_DRIVESTRENGTH_MASK \ + | _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK))) +/** @endcond */ + + +/******************************************************************************* + ************************** GLOBAL FUNCTIONS ******************************* + ******************************************************************************/ + +/***************************************************************************//** + * @brief + * Sets the pin location of the debug pins (Serial Wire interface). + * + * @note + * Changing the pins used for debugging uncontrolled, may result in a lockout. + * + * @param[in] location + * The debug pin location to use (0-3). + ******************************************************************************/ +void GPIO_DbgLocationSet(unsigned int location) +{ +#if defined ( _GPIO_ROUTE_SWLOCATION_MASK ) + EFM_ASSERT(location < AFCHANLOC_MAX); + + GPIO->ROUTE = (GPIO->ROUTE & ~_GPIO_ROUTE_SWLOCATION_MASK) | + (location << _GPIO_ROUTE_SWLOCATION_SHIFT); +#else + (void)location; +#endif +} + +#if defined (_GPIO_P_CTRL_DRIVEMODE_MASK) +/***************************************************************************//** + * @brief + * Sets the drive mode for a GPIO port. + * + * @param[in] port + * The GPIO port to access. + * + * @param[in] mode + * Drive mode to use for port. + ******************************************************************************/ +void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode) +{ + EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_DRIVEMODE_VALID(mode)); + + GPIO->P[port].CTRL = (GPIO->P[port].CTRL & ~(_GPIO_P_CTRL_DRIVEMODE_MASK)) + | (mode << _GPIO_P_CTRL_DRIVEMODE_SHIFT); +} +#endif + + +#if defined (_GPIO_P_CTRL_DRIVESTRENGTH_MASK) +/***************************************************************************//** + * @brief + * Sets the drive strength for a GPIO port. + * + * @param[in] port + * The GPIO port to access. + * + * @param[in] strength + * Drive strength to use for port. + ******************************************************************************/ +void GPIO_DriveStrengthSet(GPIO_Port_TypeDef port, + GPIO_DriveStrength_TypeDef strength) +{ + EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_STRENGHT_VALID(strength)); + BUS_RegMaskedWrite(&GPIO->P[port].CTRL, + _GPIO_P_CTRL_DRIVESTRENGTH_MASK | _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK, + strength); +} +#endif + +/***************************************************************************//** + * @brief + * Configure GPIO interrupt. + * + * @details + * If reconfiguring a GPIO interrupt that is already enabled, it is generally + * recommended to disable it first, see GPIO_Disable(). + * + * The actual GPIO interrupt handler must be in place before enabling the + * interrupt. + * + * Notice that any pending interrupt for the selected pin is cleared by this + * function. + * + * @note + * A certain pin number can only be associated with one port. Ie, if GPIO + * interrupt 1 is assigned to port A/pin 1, then it is not possibly to use + * pin 1 from any other ports for interrupts. Please refer to the reference + * manual. + * + * @param[in] port + * The port to associate with @p pin. + * + * @param[in] pin + * The GPIO interrupt number (= port pin). + * + * @param[in] risingEdge + * Set to true if interrupts shall be enabled on rising edge, otherwise false. + * + * @param[in] fallingEdge + * Set to true if interrupts shall be enabled on falling edge, otherwise false. + * + * @param[in] enable + * Set to true if interrupt shall be enabled after configuration completed, + * false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable(). + ******************************************************************************/ +void GPIO_IntConfig(GPIO_Port_TypeDef port, + unsigned int pin, + bool risingEdge, + bool fallingEdge, + bool enable) +{ + uint32_t tmp; + + EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin)); + + /* There are two registers controlling the interrupt configuration: + * The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls + * pins 8-15. */ + if (pin < 8) + { + BUS_RegMaskedWrite(&GPIO->EXTIPSELL, + 0xF << (4 * pin), + port << (4 * pin)); + } + else + { + tmp = pin - 8; + BUS_RegMaskedWrite(&GPIO->EXTIPSELH, + 0xF << (4 * tmp), + port << (4 * tmp)); + } + + /* Enable/disable rising edge */ + BUS_RegBitWrite(&(GPIO->EXTIRISE), pin, risingEdge); + + /* Enable/disable falling edge */ + BUS_RegBitWrite(&(GPIO->EXTIFALL), pin, fallingEdge); + + /* Clear any pending interrupt */ + GPIO->IFC = 1 << pin; + + /* Finally enable/disable interrupt */ + BUS_RegBitWrite(&(GPIO->IEN), pin, enable); +} + + +/***************************************************************************//** + * @brief + * Set the mode for a GPIO pin. + * + * @param[in] port + * The GPIO port to access. + * + * @param[in] pin + * The pin number in the port. + * + * @param[in] mode + * The desired pin mode. + * + * @param[in] out + * Value to set for pin in DOUT register. The DOUT setting is important for + * even some input mode configurations, determining pull-up/down direction. + ******************************************************************************/ +void GPIO_PinModeSet(GPIO_Port_TypeDef port, + unsigned int pin, + GPIO_Mode_TypeDef mode, + unsigned int out) +{ + EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin)); + + /* If disabling pin, do not modify DOUT in order to reduce chance for */ + /* glitch/spike (may not be sufficient precaution in all use cases) */ + if (mode != gpioModeDisabled) + { + if (out) + { + GPIO_PinOutSet(port, pin); + } + else + { + GPIO_PinOutClear(port, pin); + } + } + + /* There are two registers controlling the pins for each port. The MODEL + * register controls pins 0-7 and MODEH controls pins 8-15. */ + if (pin < 8) + { + BUS_RegMaskedWrite(&GPIO->P[port].MODEL, + 0xF << (pin * 4), + mode << (pin * 4)); + } + else + { + BUS_RegMaskedWrite(&GPIO->P[port].MODEH, + 0xF << ((pin - 8) * 4), + mode << ((pin - 8) * 4)); + } + + if (mode == gpioModeDisabled) + { + if (out) + { + GPIO_PinOutSet(port, pin); + } + else + { + GPIO_PinOutClear(port, pin); + } + } +} + +#if defined( _GPIO_EM4WUEN_MASK ) +/**************************************************************************//** + * @brief + * Enable GPIO pin wake-up from EM4. When the function exits, + * EM4 mode can be safely entered. + * + * @note + * It is assumed that the GPIO pin modes are set correctly. + * Valid modes are @ref gpioModeInput and @ref gpioModeInputPull. + * + * @param[in] pinmask + * Bitmask containing the bitwise logic OR of which GPIO pin(s) to enable. + * Refer to Reference Manuals for pinmask to GPIO port/pin mapping. + * @param[in] polaritymask + * Bitmask containing the bitwise logic OR of GPIO pin(s) wake-up polarity. + * Refer to Reference Manuals for pinmask to GPIO port/pin mapping. + *****************************************************************************/ +void GPIO_EM4EnablePinWakeup(uint32_t pinmask, uint32_t polaritymask) +{ + EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0); + +#if defined( _GPIO_EM4WUPOL_MASK ) + EFM_ASSERT((polaritymask & ~_GPIO_EM4WUPOL_MASK) == 0); + GPIO->EM4WUPOL &= ~pinmask; /* Set wakeup polarity */ + GPIO->EM4WUPOL |= pinmask & polaritymask; +#elif defined( _GPIO_EXTILEVEL_MASK ) + EFM_ASSERT((polaritymask & ~_GPIO_EXTILEVEL_MASK) == 0); + GPIO->EXTILEVEL &= ~pinmask; + GPIO->EXTILEVEL |= pinmask & polaritymask; +#endif + GPIO->EM4WUEN |= pinmask; /* Enable wakeup */ + + GPIO_EM4SetPinRetention(true); /* Enable pin retention */ + +#if defined( _GPIO_CMD_EM4WUCLR_MASK ) + GPIO->CMD = GPIO_CMD_EM4WUCLR; /* Clear wake-up logic */ +#elif defined( _GPIO_IFC_EM4WU_MASK ) + GPIO_IntClear(pinmask); +#endif +} +#endif + +/** @} (end addtogroup GPIO) */ +/** @} (end addtogroup EM_Library) */ + +#endif /* defined(GPIO_COUNT) && (GPIO_COUNT > 0) */