123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842 |
- /*****************************************************************************
- *
- * \file
- *
- * \brief GPIO software driver interface for AVR UC3.
- *
- * Copyright (c) 2010-2018 Microchip Technology Inc. and its subsidiaries.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Subject to your compliance with these terms, you may use Microchip
- * software and any derivatives exclusively with Microchip products.
- * It is your responsibility to comply with third party license terms applicable
- * to your use of third party software (including open source software) that
- * may accompany Microchip software.
- *
- * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES,
- * WHETHER EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE,
- * INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY,
- * AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE
- * LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL
- * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE
- * SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE
- * POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT
- * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY
- * RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
- * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
- *
- * \asf_license_stop
- *
- *****************************************************************************/
- /*
- * Support and FAQ: visit <a href="https://www.microchip.com/support/">Microchip Support</a>
- */
- #include "gpio.h"
- /** \name Peripheral Bus Interface
- *
- * @{
- */
- /** \brief Enables specific module modes for a set of pins.
- *
- * \param gpiomap The pin map.
- * \param size The number of pins in \a gpiomap.
- *
- * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
- */
- uint32_t gpio_enable_module(const gpio_map_t gpiomap, uint32_t size)
- {
- uint32_t status = GPIO_SUCCESS;
- uint32_t i;
- for (i = 0; i < size; i++) {
- status |= gpio_enable_module_pin(gpiomap->pin, gpiomap->function);
- gpiomap++;
- }
- return status;
- }
- /** \brief Enables a specific module mode for a pin.
- *
- * \note A pin and pin function index can be found in the device part header
- * file. The \c AVR32_*_PIN constants map a GPIO number from the device
- * datasheet to the appropriate pin function, while the corresponding
- * \c AVR32_*_FUNCTION macro contains the appropriate function index.
- * \n\n
- * For example, the constants \c AVR32_PWM_3_PIN and
- * \c AVR32_PWM_3_FUNCTION contain the pin and function index of the PWM
- * module, channel 3, for the current device (if available).
- *
- * \param pin The pin number.
- * \param function The pin function.
- *
- * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
- */
- uint32_t gpio_enable_module_pin(uint32_t pin, uint32_t function)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
- /* Enable the correct function. */
- switch (function) {
- case 0: /* A function. */
- gpio_port->pmr0c = 1 << (pin & 0x1F);
- gpio_port->pmr1c = 1 << (pin & 0x1F);
- #if (AVR32_GPIO_H_VERSION >= 210)
- gpio_port->pmr2c = 1 << (pin & 0x1F);
- #endif
- break;
- case 1: /* B function. */
- gpio_port->pmr0s = 1 << (pin & 0x1F);
- gpio_port->pmr1c = 1 << (pin & 0x1F);
- #if (AVR32_GPIO_H_VERSION >= 210)
- gpio_port->pmr2c = 1 << (pin & 0x1F);
- #endif
- break;
- case 2: /* C function. */
- gpio_port->pmr0c = 1 << (pin & 0x1F);
- gpio_port->pmr1s = 1 << (pin & 0x1F);
- #if (AVR32_GPIO_H_VERSION >= 210)
- gpio_port->pmr2c = 1 << (pin & 0x1F);
- #endif
- break;
- case 3: /* D function. */
- gpio_port->pmr0s = 1 << (pin & 0x1F);
- gpio_port->pmr1s = 1 << (pin & 0x1F);
- #if (AVR32_GPIO_H_VERSION >= 210)
- gpio_port->pmr2c = 1 << (pin & 0x1F);
- #endif
- break;
- #if (AVR32_GPIO_H_VERSION >= 210)
- case 4: /* E function. */
- gpio_port->pmr0c = 1 << (pin & 0x1F);
- gpio_port->pmr1c = 1 << (pin & 0x1F);
- gpio_port->pmr2s = 1 << (pin & 0x1F);
- break;
- case 5: /* F function. */
- gpio_port->pmr0s = 1 << (pin & 0x1F);
- gpio_port->pmr1c = 1 << (pin & 0x1F);
- gpio_port->pmr2s = 1 << (pin & 0x1F);
- break;
- case 6: /* G function. */
- gpio_port->pmr0c = 1 << (pin & 0x1F);
- gpio_port->pmr1s = 1 << (pin & 0x1F);
- gpio_port->pmr2s = 1 << (pin & 0x1F);
- break;
- case 7: /* H function. */
- gpio_port->pmr0s = 1 << (pin & 0x1F);
- gpio_port->pmr1s = 1 << (pin & 0x1F);
- gpio_port->pmr2s = 1 << (pin & 0x1F);
- break;
- #endif
- default:
- return GPIO_INVALID_ARGUMENT;
- }
- /* Disable GPIO control. */
- gpio_port->gperc = 1 << (pin & 0x1F);
- return GPIO_SUCCESS;
- }
- /** \brief Enables the GPIO mode of a set of pins.
- *
- * \param gpiomap The pin map.
- * \param size The number of pins in \a gpiomap.
- */
- void gpio_enable_gpio(const gpio_map_t gpiomap, uint32_t size)
- {
- uint32_t i;
- for (i = 0; i < size; i++) {
- gpio_enable_gpio_pin(gpiomap->pin);
- gpiomap++;
- }
- }
- /** \brief Enables the GPIO mode of a pin.
- *
- * \param pin The pin number.\n
- * Refer to the product header file `uc3x.h' (where x is the part
- * number; e.g. x = a0512) for pin definitions. E.g., to enable the
- * GPIO mode of PX21, AVR32_PIN_PX21 can be used. Module pins such as
- * AVR32_PWM_3_PIN for PWM channel 3 can also be used to release
- * module pins for GPIO.
- */
- void gpio_enable_gpio_pin(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- gpio_port->oderc = 1 << (pin & 0x1F);
- gpio_port->gpers = 1 << (pin & 0x1F);
- }
- /** \brief Enables the pull-up resistor of a pin.
- *
- * \param pin The pin number.
- */
- void gpio_enable_pin_pull_up(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- gpio_port->puers = 1 << (pin & 0x1F);
- #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
- defined(AVR32_GPIO_212_H_INCLUDED)
- gpio_port->pderc = 1 << (pin & 0x1F);
- #endif
- }
- /** \brief Disables the pull-up resistor of a pin.
- *
- * \param pin The pin number.
- */
- void gpio_disable_pin_pull_up(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- gpio_port->puerc = 1 << (pin & 0x1F);
- }
- #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
- defined(AVR32_GPIO_212_H_INCLUDED)
- /* Added support of Pull-up Resistor, Pull-down Resistor and Buskeeper Control. */
- /** \brief Enables the pull-down resistor of a pin.
- *
- * \param pin The pin number.
- */
- void gpio_enable_pin_pull_down(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- gpio_port->puerc = 1 << (pin & 0x1F);
- gpio_port->pders = 1 << (pin & 0x1F);
- }
- /** \brief Disables the pull-down resistor of a pin.
- *
- * \param pin The pin number.
- */
- void gpio_disable_pin_pull_down(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- gpio_port->pderc = 1 << (pin & 0x1F);
- }
- /** \brief Enables the buskeeper functionality on a pin.
- *
- * \param pin The pin number.
- */
- void gpio_enable_pin_buskeeper(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- gpio_port->puers = 1 << (pin & 0x1F);
- gpio_port->pders = 1 << (pin & 0x1F);
- }
- /** \brief Disables the buskeeper functionality on a pin.
- *
- * \param pin The pin number.
- */
- void gpio_disable_pin_buskeeper(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- gpio_port->puerc = 1 << (pin & 0x1F);
- gpio_port->pderc = 1 << (pin & 0x1F);
- }
- #endif
- /** \brief Configuration functionality on a pin.
- *
- * \param pin The pin number.
- * \param flags The configuration.
- */
- void gpio_configure_pin(uint32_t pin, uint32_t flags)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
- /* Both pull-up and pull-down set means buskeeper */
- #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
- defined(AVR32_GPIO_212_H_INCLUDED)
- if (flags & GPIO_PULL_DOWN) {
- gpio_port->pders = 1 << (pin & 0x1F);
- } else {
- gpio_port->pderc = 1 << (pin & 0x1F);
- }
- #endif
- if (flags & GPIO_PULL_UP) {
- gpio_port->puers = 1 << (pin & 0x1F);
- } else {
- gpio_port->puerc = 1 << (pin & 0x1F);
- }
- /* Enable open-drain mode if requested */
- #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
- defined(AVR32_GPIO_212_H_INCLUDED)
- if (flags & GPIO_OPEN_DRAIN) {
- gpio_port->odmers = 1 << (pin & 0x1F);
- } else {
- gpio_port->odmerc = 1 << (pin & 0x1F);
- }
- #endif
- #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
- defined(AVR32_GPIO_212_H_INCLUDED)
- /* Select drive strength */
- if (flags & GPIO_DRIVE_LOW) {
- gpio_port->odcr0s = 1 << (pin & 0x1F);
- } else {
- gpio_port->odcr0c = 1 << (pin & 0x1F);
- }
- if (flags & GPIO_DRIVE_HIGH) {
- gpio_port->odcr1s = 1 << (pin & 0x1F);
- } else {
- gpio_port->odcr1c = 1 << (pin & 0x1F);
- }
- #endif
- /* Select interrupt level for group */
- if (flags & GPIO_INTERRUPT) {
- if (flags & GPIO_BOTHEDGES) {
- gpio_port->imr0c = 1 << (pin & 0x1F);
- gpio_port->imr1c = 1 << (pin & 0x1F);
- } else if (flags & GPIO_RISING) {
- gpio_port->imr0s = 1 << (pin & 0x1F);
- gpio_port->imr1c = 1 << (pin & 0x1F);
- } else if (flags & GPIO_FALLING) {
- gpio_port->imr0c = 1 << (pin & 0x1F);
- gpio_port->imr1s = 1 << (pin & 0x1F);
- }
- }
- /* Select direction and initial pin state */
- if (flags & GPIO_DIR_OUTPUT) {
- if (flags & GPIO_INIT_HIGH) {
- gpio_port->ovrs = 1 << (pin & 0x1F);
- } else {
- gpio_port->ovrc = 1 << (pin & 0x1F);
- }
- gpio_port->oders = 1 << (pin & 0x1F);
- } else {
- gpio_port->oderc = 1 << (pin & 0x1F);
- }
- /* Enable GPIO */
- gpio_port->gpers = 1 << (pin & 0x1F);
- }
- /** \brief Configuration functionality on a port.
- *
- * \param port The port number.
- * \param mask The mask.
- * \param flags The configuration.
- */
- void gpio_configure_group(uint32_t port, uint32_t mask, uint32_t flags)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[port];
- /* Both pull-up and pull-down set means buskeeper */
- #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
- defined(AVR32_GPIO_212_H_INCLUDED)
- if (flags & GPIO_PULL_DOWN) {
- gpio_port->pders = mask;
- } else {
- gpio_port->pderc = mask;
- }
- #endif
- if (flags & GPIO_PULL_UP) {
- gpio_port->puers = mask;
- } else {
- gpio_port->puerc = mask;
- }
- /* Enable open-drain mode if requested */
- #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
- defined(AVR32_GPIO_212_H_INCLUDED)
- if (flags & GPIO_OPEN_DRAIN) {
- gpio_port->odmers = mask;
- } else {
- gpio_port->odmerc = mask;
- }
- if (flags & GPIO_OPEN_DRAIN) {
- gpio_port->pders = mask;
- } else {
- gpio_port->pderc = mask;
- }
- #endif
- #if defined(AVR32_GPIO_200_H_INCLUDED) || defined(AVR32_GPIO_210_H_INCLUDED) || \
- defined(AVR32_GPIO_212_H_INCLUDED)
- /* Select drive strength */
- if (flags & GPIO_DRIVE_LOW) {
- gpio_port->odcr0s = mask;
- } else {
- gpio_port->odcr0c = mask;
- }
- if (flags & GPIO_DRIVE_HIGH) {
- gpio_port->odcr1s = mask;
- } else {
- gpio_port->odcr1c = mask;
- }
- #endif
- /* Select interrupt level for group */
- if (flags & GPIO_INTERRUPT) {
- if (flags & GPIO_BOTHEDGES) {
- gpio_port->imr0c = mask;
- gpio_port->imr1c = mask;
- } else if (flags & GPIO_RISING) {
- gpio_port->imr0s = mask;
- gpio_port->imr1c = mask;
- } else if (flags & GPIO_FALLING) {
- gpio_port->imr0c = mask;
- gpio_port->imr1s = mask;
- }
- }
- /* Select direction and initial pin state */
- if (flags & GPIO_DIR_OUTPUT) {
- if (flags & GPIO_INIT_HIGH) {
- gpio_port->ovrs = mask;
- } else {
- gpio_port->ovrc = mask;
- }
- gpio_port->oders = mask;
- } else {
- gpio_port->oderc = mask;
- }
- /* Enable GPIO */
- gpio_port->gpers = mask;
- }
- /** \brief Returns the value of a pin.
- *
- * \param pin The pin number.
- *
- * \return The pin value.
- */
- bool gpio_get_pin_value(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- return (gpio_port->pvr >> (pin & 0x1F)) & 1;
- }
- /** \brief Returns the output value set for a GPIO pin.
- *
- * \param pin The pin number.
- *
- * \return The pin output value.
- *
- * \note This function must be used in conjunction with \ref gpio_set_gpio_pin,
- * \ref gpio_clr_gpio_pin and \ref gpio_tgl_gpio_pin.
- */
- bool gpio_get_gpio_pin_output_value(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- return (gpio_port->ovr >> (pin & 0x1F)) & 1;
- }
- /** \brief Returns the output value set for a GPIO pin using open drain.
- *
- * \param pin The pin number.
- *
- * \return The pin output value.
- *
- * \note This function must be used in conjunction with
- * \ref gpio_set_gpio_open_drain_pin, \ref gpio_clr_gpio_open_drain_pin
- * and \ref gpio_tgl_gpio_open_drain_pin.
- */
- bool gpio_get_gpio_open_drain_pin_output_value(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- return ((gpio_port->oder >> (pin & 0x1F)) & 1) ^ 1;
- }
- /** \brief Drives a GPIO pin to 1.
- *
- * \param pin The pin number.
- */
- void gpio_set_gpio_pin(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- /* Value to be driven on the I/O line: 1. */
- gpio_port->ovrs = 1 << (pin & 0x1F);
- /* The GPIO output driver is enabled for that pin. */
- gpio_port->oders = 1 << (pin & 0x1F);
- /* The GPIO module controls that pin. */
- gpio_port->gpers = 1 << (pin & 0x1F);
- }
- /** \brief Drives a GPIO pin to 1.
- *
- * \param pin The pin number.
- *
- * \note The function \ref gpio_configure_pin must be called before.
- */
- void gpio_set_pin_high(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- /* Value to be driven on the I/O line: 1. */
- gpio_port->ovrs = 1 << (pin & 0x1F);
- }
- /** \brief Drives a GPIO port to 1.
- *
- * \param port The port number.
- * \param mask The mask.
- */
- void gpio_set_group_high(uint32_t port, uint32_t mask)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[port];
-
- /* Value to be driven on the I/O group: 1. */
- gpio_port->ovrs = mask;
- }
- /** \brief Drives a GPIO pin to 0.
- *
- * \param pin The pin number.
- *
- * \note The function \ref gpio_configure_pin must be called before.
- */
- void gpio_set_pin_low(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- /* Value to be driven on the I/O line: 0. */
- gpio_port->ovrc = 1 << (pin & 0x1F);
- }
- /** \brief Drives a GPIO pin to 0.
- *
- * \param pin The pin number.
- */
- void gpio_clr_gpio_pin(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- /* Value to be driven on the I/O line: 0. */
- gpio_port->ovrc = 1 << (pin & 0x1F);
- /* The GPIO output driver is enabled for that pin. */
- gpio_port->oders = 1 << (pin & 0x1F);
- /* The GPIO module controls that pin. */
- gpio_port->gpers = 1 << (pin & 0x1F);
- }
- /** \brief Drives a GPIO port to 0.
- *
- * \param port The port number.
- * \param mask The mask.
- */
- void gpio_set_group_low(uint32_t port, uint32_t mask)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[port];
-
- /* Value to be driven on the I/O group: 0. */
- gpio_port->ovrc = mask;
- }
- /** \brief Toggles a GPIO pin.
- *
- * \param pin The pin number.
- */
- void gpio_tgl_gpio_pin(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- /* Toggle the I/O line. */
- gpio_port->ovrt = 1 << (pin & 0x1F);
- /* The GPIO output driver is enabled for that pin. */
- gpio_port->oders = 1 << (pin & 0x1F);
- /* The GPIO module controls that pin. */
- gpio_port->gpers = 1 << (pin & 0x1F);
- }
- /** \brief Toggles a GPIO pin.
- *
- * \param pin The pin number.
- *
- * \note The function \ref gpio_configure_pin must be called before.
- */
- void gpio_toggle_pin(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- /* Toggle the I/O line. */
- gpio_port->ovrt = 1 << (pin & 0x1F);
- }
- /** \brief Toggles a GPIO group.
- *
- * \param port The port number.
- * \param mask The mask.
- */
- void gpio_toggle_group(uint32_t port, uint32_t mask)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[port];
-
- /* Toggle the I/O port. */
- gpio_port->ovrt = mask;
- }
- /** \brief Drives a GPIO pin to 1 using open drain.
- *
- * \param pin The pin number.
- */
- void gpio_set_gpio_open_drain_pin(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
- /* The GPIO output driver is disabled for that pin. */
- gpio_port->oderc = 1 << (pin & 0x1F);
- /* The GPIO module controls that pin. */
- gpio_port->gpers = 1 << (pin & 0x1F);
- }
- /** \brief Drives a GPIO pin to 0 using open drain.
- *
- * \param pin The pin number.
- */
- void gpio_clr_gpio_open_drain_pin(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
- /* Value to be driven on the I/O line: 0. */
- gpio_port->ovrc = 1 << (pin & 0x1F);
- /* The GPIO output driver is enabled for that pin. */
- gpio_port->oders = 1 << (pin & 0x1F);
- /* The GPIO module controls that pin. */
- gpio_port->gpers = 1 << (pin & 0x1F);
- }
- /** \brief Toggles a GPIO pin using open drain.
- *
- * \param pin The pin number.
- */
- void gpio_tgl_gpio_open_drain_pin(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
- /* Value to be driven on the I/O line if the GPIO output driver is
- * enabled: 0. */
- gpio_port->ovrc = 1 << (pin & 0x1F);
- /* The GPIO output driver is toggled for that pin. */
- gpio_port->odert = 1 << (pin & 0x1F);
- /* The GPIO module controls that pin. */
- gpio_port->gpers = 1 << (pin & 0x1F);
- }
- /** \brief Enables the glitch filter of a pin.
- *
- * When the glitch filter is enabled, a glitch with duration of less than 1
- * clock cycle is automatically rejected, while a pulse with duration of 2 clock
- * cycles or more is accepted. For pulse durations between 1 clock cycle and 2
- * clock cycles, the pulse may or may not be taken into account, depending on
- * the precise timing of its occurrence. Thus for a pulse to be guaranteed
- * visible it must exceed 2 clock cycles, whereas for a glitch to be reliably
- * filtered out, its duration must not exceed 1 clock cycle. The filter
- * introduces 2 clock cycles latency.
- *
- * \param pin The pin number.
- */
- void gpio_enable_pin_glitch_filter(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- gpio_port->gfers = 1 << (pin & 0x1F);
- }
- /** \brief Disables the glitch filter of a pin.
- *
- * \param pin The pin number.
- */
- void gpio_disable_pin_glitch_filter(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- gpio_port->gferc = 1 << (pin & 0x1F);
- }
- /** \brief Configure the edge detector of an input pin
- *
- * \param pin The pin number.
- * \param mode The edge detection mode (\ref GPIO_PIN_CHANGE,
- * \ref GPIO_RISING_EDGE or \ref GPIO_FALLING_EDGE).
- *
- * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
- */
- static uint32_t gpio_configure_edge_detector(uint32_t pin, uint32_t mode)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
- /* Configure the edge detector. */
- switch (mode) {
- case GPIO_PIN_CHANGE:
- gpio_port->imr0c = 1 << (pin & 0x1F);
- gpio_port->imr1c = 1 << (pin & 0x1F);
- break;
- case GPIO_RISING_EDGE:
- gpio_port->imr0s = 1 << (pin & 0x1F);
- gpio_port->imr1c = 1 << (pin & 0x1F);
- break;
- case GPIO_FALLING_EDGE:
- gpio_port->imr0c = 1 << (pin & 0x1F);
- gpio_port->imr1s = 1 << (pin & 0x1F);
- break;
- default:
- return GPIO_INVALID_ARGUMENT;
- }
- return GPIO_SUCCESS;
- }
- /** \brief Enables the interrupt of a pin with the specified settings.
- *
- * \param pin The pin number.
- * \param mode The trigger mode (\ref GPIO_PIN_CHANGE, \ref GPIO_RISING_EDGE or
- * \ref GPIO_FALLING_EDGE).
- *
- * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
- */
- uint32_t gpio_enable_pin_interrupt(uint32_t pin, uint32_t mode)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
- /* Enable the glitch filter. */
- gpio_port->gfers = 1 << (pin & 0x1F);
- /* Configure the edge detector. */
- if (GPIO_INVALID_ARGUMENT == gpio_configure_edge_detector(pin, mode)) {
- return(GPIO_INVALID_ARGUMENT);
- }
- /* Enable interrupt. */
- gpio_port->iers = 1 << (pin & 0x1F);
- return GPIO_SUCCESS;
- }
- /** \brief Disables the interrupt of a pin.
- *
- * \param pin The pin number.
- */
- void gpio_disable_pin_interrupt(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- gpio_port->ierc = 1 << (pin & 0x1F);
- }
- /** \brief Gets the interrupt flag of a pin.
- *
- * \param pin The pin number.
- *
- * \return The pin interrupt flag.
- */
- bool gpio_get_pin_interrupt_flag(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
-
- return (gpio_port->ifr >> (pin & 0x1F)) & 1;
- }
- /** \brief Clears the interrupt flag of a pin.
- *
- * \param pin The pin number.
- */
- void gpio_clear_pin_interrupt_flag(uint32_t pin)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
- #if (AVR32_GPIO_H_VERSION == 211)
- /* GPIO erratum - Writing a one to the GPIO.IFRC register */
- /* to clear an interrupt will be ignored if interrupt is enabled for the */
- /* corresponding port. */
- /* Work around for the erratum - Disable the interrupt, clear it by
- * writing */
- /* a one to GPIO.IFRC, then enable the interrupt. */
- /* Save interrupt enable register. */
- uint32_t const gpio_ier = gpio_port->ier;
- /* Disable interrupt. */
- gpio_port->ierc = gpio_ier;
- /* Clear pin interrupt. */
- gpio_port->ifrc = 1 << (pin & 0x1F);
- /* Restore interrupt enable register. */
- gpio_port->ier = gpio_ier;
- #else
- gpio_port->ifrc = 1 << (pin & 0x1F);
- #endif
- }
- #if UC3L
- /** \brief Configure the peripheral event trigger mode of a pin
- *
- * \param pin The pin number.
- * \param mode The trigger mode (\ref GPIO_PIN_CHANGE, \ref GPIO_RISING_EDGE or
- * \ref GPIO_FALLING_EDGE).
- * \param use_igf use the Input Glitch Filter (true) or not (false).
- *
- * \return \ref GPIO_SUCCESS or \ref GPIO_INVALID_ARGUMENT.
- */
- uint32_t gpio_configure_pin_periph_event_mode(uint32_t pin, uint32_t mode,
- uint32_t use_igf)
- {
- volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
- if (true == use_igf) {
- /* Enable the glitch filter. */
- gpio_port->gfers = 1 << (pin & 0x1F);
- } else {
- /* Disable the glitch filter. */
- gpio_port->gferc = 1 << (pin & 0x1F);
- }
- /* Configure the edge detector. */
- return gpio_configure_edge_detector(pin, mode);
- }
- #endif
- /** @} */
|