--- /dev/null
+/* ----------------------------------------------------------------------------\r
+ * SAM Software Package License\r
+ * ----------------------------------------------------------------------------\r
+ * Copyright (c) 2015, Atmel Corporation\r
+ *\r
+ * All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions are met:\r
+ *\r
+ * - Redistributions of source code must retain the above copyright notice,\r
+ * this list of conditions and the disclaimer below.\r
+ *\r
+ * Atmel's name may not be used to endorse or promote products derived from\r
+ * this software without specific prior written permission.\r
+ *\r
+ * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
+ * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ * ----------------------------------------------------------------------------\r
+ */\r
+\r
+/** \addtogroup pio_module Working with PIO\r
+ * \section Purpose\r
+ * The PIO driver provides the Interface for configuration the Parallel Input/Output\r
+ * Controller (PIO).\r
+ *\r
+ * \section Usage\r
+ * <ul>\r
+ * <li> Initialize the PIO with the desired period using pio_configure().\r
+ * <li> Set a high or low output level on the given PIO using pio_set() or pio_clear().\r
+ * <li> Get the level of the given PIOs using pio_get() or pio_get_output_date_status().\r
+ * <li> Configures Glitch or Debouncing filter for given input PIO using pio_set_debounce_filter().\r
+ * <li> Enable & disable write protect of the given PIOs using pio_enable_write_protect() or pio_disable_write_protect().\r
+ * <li> Get write protect violation information of given PIO using pio_get_write_protect_violation_info().\r
+ * </li>\r
+ * </ul>\r
+ *\r
+ * For more accurate information, please look at the PIT section of the Datasheet.\r
+ *\r
+ * Related files :\n\r
+ * \ref pio.c\n\r
+ * \ref pio3.h\n\r
+*/\r
+/*@{*/\r
+/*@}*/\r
+\r
+/**\r
+ * \file\r
+ *\r
+ * Implementation of PIO V3 (Parallel Input/Output) controller.\r
+ *\r
+ */\r
+/*----------------------------------------------------------------------------\r
+ * Headers\r
+ *----------------------------------------------------------------------------*/\r
+\r
+#include "chip.h"\r
+#include "peripherals/pio.h"\r
+#include "peripherals/pmc.h"\r
+#include "peripherals/aic.h"\r
+#include "peripherals/matrix.h"\r
+\r
+#include "trace.h"\r
+#include "compiler.h"\r
+\r
+#include <stdint.h>\r
+#include <string.h>\r
+#include <assert.h>\r
+\r
+/*----------------------------------------------------------------------------\r
+ * Local types\r
+ *----------------------------------------------------------------------------*/\r
+\r
+struct _bitfield_pio_cfgr_func {\r
+ uint32_t\r
+ func : 3,\r
+ rfu3_7 : 5,\r
+ dir : 1,\r
+ puen : 1,\r
+ pden : 1,\r
+ rfu11 : 1,\r
+ ifen : 1,\r
+ ifscen : 1,\r
+ opd : 1,\r
+ schmitt : 1,\r
+ drvstr : 2,\r
+ rfu18_23 : 6,\r
+ evtsel : 3,\r
+ rfu27_28 : 2,\r
+ pcfs : 1,\r
+ icfs : 1,\r
+ tampen : 1;\r
+};\r
+\r
+union _pio_cfg {\r
+ struct _bitfield_pio_cfgr_func bitfield;\r
+ uint32_t uint32_value;\r
+};\r
+\r
+/*----------------------------------------------------------------------------\r
+ * Local functions declarations\r
+ *----------------------------------------------------------------------------*/\r
+\r
+#ifdef ID_PIOA\r
+static void _pioa_handler(void);\r
+#endif\r
+#ifdef ID_PIOB\r
+static void _piob_handler(void);\r
+#endif\r
+#ifdef ID_PIOC\r
+static void _pioc_handler(void);\r
+#endif\r
+#ifdef ID_PIOD\r
+static void _piod_handler(void);\r
+#endif\r
+\r
+/*----------------------------------------------------------------------------\r
+ * Local variables\r
+ *----------------------------------------------------------------------------*/\r
+struct _handler {\r
+ uint32_t mask;\r
+ pio_handler_t handler;\r
+ void *user_arg;\r
+};\r
+static struct _handler _handlers[IRQ_PIO_HANDLERS_SIZE];\r
+\r
+static const aic_handler_t _generic_handlers[PIO_GROUP_LENGTH] = {\r
+#ifdef ID_PIOA\r
+ _pioa_handler,\r
+#endif\r
+#ifdef ID_PIOB\r
+ _piob_handler,\r
+#endif\r
+#ifdef ID_PIOC\r
+ _pioc_handler,\r
+#endif\r
+#ifdef ID_PIOD\r
+ _piod_handler,\r
+#endif\r
+};\r
+\r
+/*----------------------------------------------------------------------------\r
+ * Local functions definitions\r
+ *----------------------------------------------------------------------------*/\r
+\r
+static void _handler_push(void (*handler)(uint32_t, uint32_t, void*),\r
+ uint32_t mask, void* user_arg)\r
+{\r
+ static int i = 0;\r
+ _handlers[i].mask = mask;\r
+ _handlers[i].handler = handler;\r
+ _handlers[i].user_arg = user_arg;\r
+ ++i;\r
+ assert(i < ARRAY_SIZE(_handlers));\r
+}\r
+\r
+#ifdef ID_PIOA\r
+static void _pioa_handler(void)\r
+{\r
+ uint32_t status = 0;\r
+ unsigned int i = 0;\r
+ if (matrix_is_peripheral_secured(MATRIX1, ID_PIOA))\r
+ status = PIOA->PIO_PIO_[PIO_GROUP_A].S_PIO_ISR;\r
+ else\r
+ status = PIOA->PIO_IO_GROUP[PIO_GROUP_A].PIO_ISR;\r
+\r
+ for (i = 0; i < ARRAY_SIZE(_handlers); ++i) {\r
+ if (_handlers[i].mask & status) {\r
+ _handlers[i].handler(PIO_GROUP_A, status,\r
+ _handlers[i].user_arg);\r
+ }\r
+ }\r
+}\r
+#endif\r
+#ifdef ID_PIOB\r
+static void _piob_handler(void)\r
+{\r
+ uint32_t status = 0;\r
+ unsigned int i = 0;\r
+ if (matrix_is_peripheral_secured(MATRIX1, ID_PIOB))\r
+ status = PIOA->PIO_PIO_[PIO_GROUP_B].S_PIO_ISR;\r
+ else\r
+ status = PIOA->PIO_IO_GROUP[PIO_GROUP_B].PIO_ISR;\r
+\r
+ for (i = 0; i < ARRAY_SIZE(_handlers); ++i) {\r
+ if (_handlers[i].mask & status) {\r
+ _handlers[i].handler(PIO_GROUP_B, status,\r
+ _handlers[i].user_arg);\r
+ }\r
+ }\r
+\r
+}\r
+#endif\r
+#ifdef ID_PIOC\r
+static void _pioc_handler(void)\r
+{\r
+ uint32_t status = 0;\r
+ unsigned int i = 0;\r
+ if (matrix_is_peripheral_secured(MATRIX1, ID_PIOC))\r
+ status = PIOA->PIO_PIO_[PIO_GROUP_C].S_PIO_ISR;\r
+ else\r
+ status = PIOA->PIO_IO_GROUP[PIO_GROUP_C].PIO_ISR;\r
+\r
+ for (i = 0; i < ARRAY_SIZE(_handlers); ++i) {\r
+ if (_handlers[i].mask & status) {\r
+ _handlers[i].handler(PIO_GROUP_C, status,\r
+ _handlers[i].user_arg);\r
+ }\r
+ }\r
+}\r
+#endif\r
+#ifdef ID_PIOD\r
+static void _piod_handler(void)\r
+{\r
+ uint32_t status = 0;\r
+ unsigned int i = 0;\r
+ if (matrix_is_peripheral_secured(MATRIX1, ID_PIOD))\r
+ status = PIOA->PIO_PIO_[PIO_GROUP_D].S_PIO_ISR;\r
+ else\r
+ status = PIOA->PIO_IO_GROUP[PIO_GROUP_D].PIO_ISR;\r
+\r
+ for (i = 0; i < ARRAY_SIZE(_handlers); ++i) {\r
+ if (_handlers[i].mask & status) {\r
+ _handlers[i].handler(PIO_GROUP_D, status,\r
+ _handlers[i].user_arg);\r
+ }\r
+ }\r
+}\r
+#endif\r
+\r
+static inline uint32_t _pio_group_to_id(int group)\r
+{\r
+ switch(group) {\r
+ case PIO_GROUP_A:\r
+ return ID_PIOA;\r
+ case PIO_GROUP_B:\r
+ return ID_PIOB;\r
+ case PIO_GROUP_C:\r
+ return ID_PIOC;\r
+ case PIO_GROUP_D:\r
+ return ID_PIOD;\r
+ default:\r
+ return (unsigned int)-1;\r
+ };\r
+}\r
+\r
+static void* _pio_configure_pins(const struct _pin *pin, uint32_t periph_id)\r
+{\r
+ PioPio_* piogroup = &PIOA->PIO_PIO_[pin->group];\r
+ if (!matrix_is_peripheral_secured(MATRIX1, periph_id)) {\r
+ piogroup->S_PIO_SIONR = pin->mask;\r
+ return (void*) &PIOA->PIO_IO_GROUP[pin->group];\r
+ } else {\r
+ piogroup->S_PIO_SIOSR = pin->mask;\r
+ return (void*) piogroup;\r
+ }\r
+}\r
+\r
+static void* _pio_retrive_group(const struct _pin *pin, uint32_t periph_id)\r
+{\r
+ if (!matrix_is_peripheral_secured(MATRIX1, periph_id)) {\r
+ return (void*) &PIOA->PIO_IO_GROUP[pin->group];\r
+ } else {\r
+ return (void*) &PIOA->PIO_PIO_[pin->group];\r
+ }\r
+}\r
+/*----------------------------------------------------------------------------\r
+ * Exported functions\r
+ *----------------------------------------------------------------------------*/\r
+\r
+/**\r
+ * \brief Configures a list of Pin instances, each of which can either\r
+ * hold a single pin or a group of pins, depending on the mask value;\r
+ * all pins are configured by this function. The size of the array\r
+ * must also be provided and is easily computed using ARRAY_SIZE\r
+ * whenever its length is not known in advance.\r
+ *\r
+ * \param list Pointer to a list of _pin instances.\r
+ * \param size Size of the _pin list (calculated using PIN_LISTSIZE).\r
+ *\r
+ * \return 1 if the pins have been configured properly; otherwise 0.\r
+ */\r
+uint8_t pio_configure(const struct _pin *pin_list, uint32_t size)\r
+{\r
+ union _pio_cfg cfg;\r
+ PioIo_group* pioiog;\r
+\r
+ /* Configure pins */\r
+ while (size--)\r
+ {\r
+ /* Enable the PIO group if needed */\r
+ uint32_t periph_id = _pio_group_to_id(pin_list->group);\r
+\r
+ assert(pin_list->group < PIO_GROUP_LENGTH);\r
+ cfg.uint32_value = 0;\r
+ pioiog = (PioIo_group*) _pio_configure_pins(pin_list, periph_id);\r
+\r
+ if ( pin_list->attribute != PIO_DEFAULT) {\r
+ cfg.bitfield.puen = (pin_list->attribute & PIO_PULLUP)? 1:0;\r
+ cfg.bitfield.pden = (pin_list->attribute & PIO_PULLDOWN)? 1:0;\r
+ cfg.bitfield.ifen = (pin_list->attribute & PIO_DEGLITCH)? 1:0;\r
+ cfg.bitfield.ifscen = (pin_list->attribute & PIO_DEBOUNCE)? 1:0;\r
+ cfg.bitfield.opd = (pin_list->attribute & PIO_OPENDRAIN)? 1:0;\r
+ cfg.bitfield.schmitt =(pin_list->attribute & PIO_TRIGGER_DIS)? 1:0;\r
+\r
+ switch (pin_list->attribute & PIO_DRVSTR_Msk) {\r
+ case PIO_DRVSTR_HI:\r
+ cfg.bitfield.drvstr = PIO_CFGR_DRVSTR_HI >> PIO_CFGR_DRVSTR_Pos;\r
+ break;\r
+ case PIO_DRVSTR_ME:\r
+ cfg.bitfield.drvstr = PIO_CFGR_DRVSTR_ME >> PIO_CFGR_DRVSTR_Pos;\r
+ break;\r
+ case PIO_DRVSTR_LO:\r
+ default:\r
+ cfg.bitfield.drvstr = PIO_CFGR_DRVSTR_LO >> PIO_CFGR_DRVSTR_Pos;\r
+ break;\r
+ }\r
+\r
+ switch (pin_list->attribute & PIO_EVTSEL_Msk) {\r
+ case PIO_IT_HIGH_LEVEL:\r
+ cfg.bitfield.evtsel = PIO_CFGR_EVTSEL_HIGH >> PIO_CFGR_EVTSEL_Pos;\r
+ break;\r
+ case PIO_IT_LOW_LEVEL:\r
+ cfg.bitfield.evtsel = PIO_CFGR_EVTSEL_LOW >> PIO_CFGR_EVTSEL_Pos;\r
+ break;\r
+ case PIO_IT_BOTH_EDGE:\r
+ cfg.bitfield.evtsel = PIO_CFGR_EVTSEL_BOTH >> PIO_CFGR_EVTSEL_Pos;\r
+ break;\r
+ case PIO_IT_RISE_EDGE:\r
+ cfg.bitfield.evtsel = PIO_CFGR_EVTSEL_RISING >> PIO_CFGR_EVTSEL_Pos;\r
+ break;\r
+ case PIO_IT_FALL_EDGE:\r
+ default:\r
+ cfg.bitfield.evtsel = PIO_CFGR_EVTSEL_FALLING >> PIO_CFGR_EVTSEL_Pos;\r
+ break;\r
+ }\r
+ }\r
+\r
+ switch (pin_list->type){\r
+\r
+ case PIO_PERIPH_A:\r
+ cfg.bitfield.func = PIO_CFGR_FUNC_PERIPH_A >> PIO_CFGR_FUNC_Pos;\r
+ break;\r
+ case PIO_PERIPH_B:\r
+ cfg.bitfield.func = PIO_CFGR_FUNC_PERIPH_B >> PIO_CFGR_FUNC_Pos;\r
+ break;\r
+ case PIO_PERIPH_C:\r
+ cfg.bitfield.func = PIO_CFGR_FUNC_PERIPH_C >> PIO_CFGR_FUNC_Pos;\r
+ break;\r
+ case PIO_PERIPH_D:\r
+ cfg.bitfield.func = PIO_CFGR_FUNC_PERIPH_D >> PIO_CFGR_FUNC_Pos;\r
+ break;\r
+ case PIO_PERIPH_E:\r
+ cfg.bitfield.func = PIO_CFGR_FUNC_PERIPH_E >> PIO_CFGR_FUNC_Pos;\r
+ break;\r
+ case PIO_PERIPH_F:\r
+ cfg.bitfield.func = PIO_CFGR_FUNC_PERIPH_F >> PIO_CFGR_FUNC_Pos;\r
+ break;\r
+ case PIO_GENERIC:\r
+ case PIO_INPUT:\r
+ cfg.bitfield.dir = 0;\r
+ break;\r
+\r
+ case PIO_OUTPUT_0:\r
+ cfg.bitfield.dir = 1;\r
+ pio_clear(pin_list);\r
+ break;\r
+\r
+ case PIO_OUTPUT_1:\r
+ cfg.bitfield.dir = 1;\r
+ pio_set(pin_list);\r
+ break;\r
+\r
+ default:\r
+ case PIO_PERIPH_G:\r
+ return 0;\r
+ }\r
+\r
+ pioiog->PIO_MSKR = pin_list->mask;\r
+ pioiog->PIO_CFGR = cfg.uint32_value;\r
+ pmc_enable_peripheral(periph_id);\r
+\r
+ ++pin_list;\r
+ }\r
+ return 1;\r
+}\r
+\r
+/**\r
+ * \brief Sets a high output level on all the PIOs defined in the\r
+ * given Pin instance. This has no immediate effects on PIOs that are\r
+ * not output, but the PIO controller will memorize the value they are\r
+ * changed to outputs.\r
+ *\r
+ * \param pin Pointer to a Pin instance describing one or more pins.\r
+ */\r
+void pio_set(const struct _pin *pin)\r
+{\r
+ assert(pin->group < PIO_GROUP_LENGTH);\r
+ uint32_t periph_id = _pio_group_to_id(pin->group);\r
+ PioIo_group* pioiog = (PioIo_group*) _pio_retrive_group(pin, periph_id);\r
+ pioiog->PIO_SODR = pin->mask;\r
+}\r
+\r
+/**\r
+ * \brief Sets a low output level on all the PIOs defined in the given\r
+ * Pin instance. This has no immediate effects on PIOs that are not\r
+ * output, but the PIO controller will memorize the value they are\r
+ * changed to outputs.\r
+ *\r
+ * \param pin Pointer to a Pin instance describing one or more pins.\r
+ */\r
+void pio_clear(const struct _pin *pin)\r
+{\r
+ assert(pin->group < PIO_GROUP_LENGTH);\r
+ uint32_t periph_id = _pio_group_to_id(pin->group);\r
+ PioIo_group* pioiog = (PioIo_group*) _pio_retrive_group(pin, periph_id);\r
+ pioiog->PIO_CODR = pin->mask;\r
+}\r
+\r
+/**\r
+ * \brief Returns 1 if one or more PIO of the given Pin instance currently have\r
+ * a high level; otherwise returns 0. This method returns the actual value that\r
+ * is being read on the pin. To return the supposed output value of a pin, use\r
+ * pio_get_output_date_status() instead.\r
+ *\r
+ * \param pin Pointer to a Pin instance describing one or more pins.\r
+ *\r
+ * \return 1 if the Pin instance contains at least one PIO that currently has\r
+ * a high level; otherwise 0.\r
+ */\r
+uint8_t pio_get(const struct _pin *pin)\r
+{\r
+ assert(pin->group < PIO_GROUP_LENGTH);\r
+ uint32_t reg ;\r
+ uint32_t periph_id = _pio_group_to_id(pin->group);\r
+ PioIo_group* pioiog = (PioIo_group*) _pio_retrive_group(pin, periph_id);\r
+\r
+ if ((pin->type == PIO_OUTPUT_0) || (pin->type == PIO_OUTPUT_1)) {\r
+ reg = pioiog->PIO_ODSR ;\r
+ }\r
+ else {\r
+ reg = pioiog->PIO_PDSR ;\r
+ }\r
+ if ( (reg & pin->mask) == 0 ) {\r
+ return 0 ;\r
+ }\r
+ else {\r
+ return 1 ;\r
+ }\r
+}\r
+\r
+/**\r
+ * \brief Returns 1 if one or more PIO of the given Pin are configured\r
+ * to output a high level (even if they are not output). To get the\r
+ * actual value of the pin, use pio_get() instead.\r
+ *\r
+ * \param pin Pointer to a Pin instance describing one or more pins.\r
+ *\r
+ * \return 1 if the Pin instance contains at least one PIO that is configured\r
+ * to output a high level; otherwise 0.\r
+ */\r
+uint8_t pio_get_output_data_status(const struct _pin *pin)\r
+{\r
+ assert(pin->group < PIO_GROUP_LENGTH);\r
+ uint32_t periph_id = _pio_group_to_id(pin->group);\r
+ PioIo_group* pioiog = (PioIo_group*) _pio_retrive_group(pin, periph_id);\r
+\r
+ if ((pioiog->PIO_ODSR & pin->mask) == 0) {\r
+ return 0;\r
+ }\r
+ else {\r
+ return 1;\r
+ }\r
+}\r
+\r
+/**\r
+ * \brief Configures Glitch or Debouncing filter for input.\r
+ *\r
+ * \param pin Pointer to a Pin instance describing one or more pins.\r
+ * \param cuttoff Cutt off frequency for debounce filter.\r
+ */\r
+void pio_set_debounce_filter(const struct _pin *pin, uint32_t cuttoff)\r
+{\r
+ assert(pin->group < PIO_GROUP_LENGTH);\r
+ if (cuttoff == 0) {\r
+ PIOA->S_PIO_SCDR = 0;\r
+ }\r
+ else {\r
+ /* the lowest 14 bits work */\r
+ PIOA->S_PIO_SCDR =\r
+ ((pmc_get_slow_clock()/(2*(cuttoff))) - 1) & 0x3FFF;\r
+ }\r
+}\r
+\r
+/**\r
+ * \brief Enable write protect.\r
+ *\r
+ * \param pin Pointer to a Pin instance describing one or more pins.\r
+ */\r
+void pio_enable_write_protect(const struct _pin *pin)\r
+{\r
+ assert(pin->group < PIO_GROUP_LENGTH);\r
+ PIOA->PIO_WPMR = (PIO_WPMR_WPKEY_VALID | PIO_WPMR_WPEN_EN );\r
+}\r
+\r
+/**\r
+ * \brief Disable write protect.\r
+ *\r
+ * \param pin Pointer to a Pin instance describing one or more pins.\r
+ */\r
+void pio_disable_write_protect(const struct _pin *pin)\r
+{\r
+ assert(pin->group < PIO_GROUP_LENGTH);\r
+ PIOA->PIO_WPMR = (PIO_WPMR_WPKEY_VALID | PIO_WPMR_WPEN_DIS );\r
+}\r
+\r
+/**\r
+ * \brief Get write protect violation information.\r
+ *\r
+ * \param pin Pointer to a Pin instance describing one or more pins.\r
+ */\r
+uint32_t pio_get_write_protect_violation_info(const struct _pin * pin)\r
+{\r
+ assert(pin->group < PIO_GROUP_LENGTH);\r
+ return PIOA->PIO_WPSR;\r
+}\r
+\r
+void pio_add_handler_to_group(uint32_t group, uint32_t mask,\r
+ pio_handler_t handler, void* user_arg)\r
+{\r
+ trace_debug("Enter in pio_add_handler_to_group()\n\r");\r
+ assert(group <\r
+ (sizeof(_generic_handlers)/sizeof(_generic_handlers[0])));\r
+ _handler_push(handler, mask, user_arg);\r
+ uint32_t id = _pio_group_to_id(group);\r
+ aic_set_source_vector(id,\r
+ (aic_handler_t)_generic_handlers[group]);\r
+ aic_enable(id);\r
+}\r
+\r
+void pio_reset_all_it(void)\r
+{\r
+ int i = 0;\r
+ for (i = 0; i < PIO_GROUP_LENGTH; ++i) {\r
+ PIOA->PIO_IO_GROUP[i].PIO_ISR;\r
+ PIOA->PIO_IO_GROUP[i].PIO_IDR = ~0UL;\r
+ }\r
+}\r
+\r
+/**\r
+ * Configures a PIO or a group of PIO to generate an interrupt on status\r
+ * change. The provided interrupt handler will be called with the triggering\r
+ * pin as its parameter (enabling different pin instances to share the same\r
+ * handler).\r
+ * \param pin Pointer to a _pin instance.\r
+ */\r
+void pio_configure_it(const struct _pin *pin)\r
+{\r
+ trace_debug("Enter in pio_configure_it()\n\r");\r
+ assert(pin != NULL);\r
+}\r
+\r
+/**\r
+ * Enables the given interrupt source if it has been configured. The status\r
+ * register of the corresponding PIO controller is cleared prior to enabling\r
+ * the interrupt.\r
+ * \param pin Interrupt source to enable.\r
+ */\r
+void pio_enable_it(const struct _pin *pin)\r
+{\r
+ trace_debug("pio_enable_it() \n\r");\r
+ assert(pin != NULL);\r
+ uint32_t periph_id = _pio_group_to_id(pin->group);\r
+ PioIo_group* pioiog = (PioIo_group*) _pio_retrive_group(pin, periph_id);\r
+\r
+ pioiog->PIO_ISR;\r
+ /* Configure interrupt enable register */\r
+ pioiog->PIO_IER = pin->mask; /* enable interrupt register */\r
+}\r
+\r
+/**\r
+ * Disables a given interrupt source, with no added side effects.\r
+ *\r
+ * \param pin Interrupt source to disable.\r
+ */\r
+void pio_disable_it(const struct _pin *pin)\r
+{\r
+ trace_debug("pio_enable_it()\n\r");\r
+ assert(pin != NULL);\r
+ uint32_t periph_id = _pio_group_to_id(pin->group);\r
+ PioIo_group* pioiog = (PioIo_group*) _pio_retrive_group(pin, periph_id);\r
+ pioiog->PIO_IDR = pin->mask;\r
+}\r