4 * \brief Common IOPORT service main header file for AVR, UC3 and ARM
\r
7 * Copyright (c) 2012 Atmel Corporation. All rights reserved.
\r
13 * Redistribution and use in source and binary forms, with or without
\r
14 * modification, are permitted provided that the following conditions are met:
\r
16 * 1. Redistributions of source code must retain the above copyright notice,
\r
17 * this list of conditions and the following disclaimer.
\r
19 * 2. Redistributions in binary form must reproduce the above copyright notice,
\r
20 * this list of conditions and the following disclaimer in the documentation
\r
21 * and/or other materials provided with the distribution.
\r
23 * 3. The name of Atmel may not be used to endorse or promote products derived
\r
24 * from this software without specific prior written permission.
\r
26 * 4. This software may only be redistributed and used in connection with an
\r
27 * Atmel microcontroller product.
\r
29 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
\r
30 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\r
31 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
\r
32 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
\r
33 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
\r
35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
\r
36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
\r
37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
\r
38 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
\r
39 * POSSIBILITY OF SUCH DAMAGE.
\r
52 #include <compiler.h>
\r
55 * \defgroup ioport_group Common IOPORT API
\r
57 * See \ref ioport_quickstart.
\r
59 * This is common IOPORT service for GPIO pin configuration and control in a
\r
60 * standardized manner across the MEGA, MEGA_RF, XMEGA, UC3 and ARM devices.
\r
62 * Port pin control code is optimized for each platform, and should produce
\r
63 * both compact and fast execution times when used with constant values.
\r
65 * \section dependencies Dependencies
\r
66 * This driver depends on the following modules:
\r
67 * - \ref sysclk_group for clock speed and functions.
\r
72 * \def IOPORT_CREATE_PIN(port, pin)
\r
73 * \brief Create IOPORT pin number
\r
75 * Create a IOPORT pin number for use with the IOPORT functions.
\r
77 * \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen
\r
79 * \param pin IOPORT zero-based index of the I/O pin
\r
82 /** \brief IOPORT pin directions */
\r
83 enum ioport_direction {
\r
84 IOPORT_DIR_INPUT, /*!< IOPORT input direction */
\r
85 IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */
\r
88 /** \brief IOPORT levels */
\r
90 IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */
\r
91 IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */
\r
95 /** \brief IOPORT edge sense modes */
\r
97 IOPORT_SENSE_LEVEL, /*!< IOPORT sense low level */
\r
98 IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */
\r
99 IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */
\r
100 IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */
\r
102 #elif SAM && !SAM4L
\r
103 /** \brief IOPORT edge sense modes */
\r
104 enum ioport_sense {
\r
105 IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */
\r
106 IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */
\r
107 IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */
\r
108 IOPORT_SENSE_LEVEL_LOW, /*!< IOPORT sense low level */
\r
109 IOPORT_SENSE_LEVEL_HIGH,/*!< IOPORT sense High level */
\r
112 enum ioport_sense {
\r
113 IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */
\r
114 IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */
\r
115 IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */
\r
121 # include "xmega/ioport.h"
\r
122 # if defined(IOPORT_XMEGA_COMPAT)
\r
123 # include "xmega/ioport_compat.h"
\r
126 # include "mega/ioport.h"
\r
128 # include "uc3/ioport.h"
\r
131 # include "sam/ioport_gpio.h"
\r
133 # include "sam/ioport_pio.h"
\r
138 * \brief Initializes the IOPORT service, ready for use.
\r
140 * This function must be called before using any other functions in the IOPORT
\r
143 static inline void ioport_init(void)
\r
145 arch_ioport_init();
\r
149 * \brief Enable an IOPORT pin, based on a pin created with \ref
\r
150 * IOPORT_CREATE_PIN().
\r
152 * \param pin IOPORT pin to enable
\r
154 static inline void ioport_enable_pin(ioport_pin_t pin)
\r
156 arch_ioport_enable_pin(pin);
\r
160 * \brief Enable multiple pins in a single IOPORT port.
\r
162 * \param port IOPORT port to enable
\r
163 * \param mask Mask of pins within the port to enable
\r
165 static inline void ioport_enable_port(ioport_port_t port,
\r
166 ioport_port_mask_t mask)
\r
168 arch_ioport_enable_port(port, mask);
\r
172 * \brief Disable IOPORT pin, based on a pin created with \ref
\r
173 * IOPORT_CREATE_PIN().
\r
175 * \param pin IOPORT pin to disable
\r
177 static inline void ioport_disable_pin(ioport_pin_t pin)
\r
179 arch_ioport_disable_pin(pin);
\r
183 * \brief Disable multiple pins in a single IOPORT port.
\r
185 * \param port IOPORT port to disable
\r
186 * \param mask Pin mask of pins to disable
\r
188 static inline void ioport_disable_port(ioport_port_t port,
\r
189 ioport_port_mask_t mask)
\r
191 arch_ioport_disable_port(port, mask);
\r
195 * \brief Set multiple pin modes in a single IOPORT port, such as pull-up,
\r
196 * pull-down, etc. configuration.
\r
198 * \param port IOPORT port to configure
\r
199 * \param mask Pin mask of pins to configure
\r
200 * \param mode Mode masks to configure for the specified pins (\ref
\r
203 static inline void ioport_set_port_mode(ioport_port_t port,
\r
204 ioport_port_mask_t mask, ioport_mode_t mode)
\r
206 arch_ioport_set_port_mode(port, mask, mode);
\r
210 * \brief Set pin mode for one single IOPORT pin.
\r
212 * \param pin IOPORT pin to configure
\r
213 * \param mode Mode masks to configure for the specified pin (\ref ioport_modes)
\r
215 static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode)
\r
217 arch_ioport_set_pin_mode(pin, mode);
\r
221 * \brief Reset multiple pin modes in a specified IOPORT port to defaults.
\r
223 * \param port IOPORT port to configure
\r
224 * \param mask Mask of pins whose mode configuration is to be reset
\r
226 static inline void ioport_reset_port_mode(ioport_port_t port,
\r
227 ioport_port_mask_t mask)
\r
229 arch_ioport_set_port_mode(port, mask, 0);
\r
233 * \brief Reset pin mode configuration for a single IOPORT pin
\r
235 * \param pin IOPORT pin to configure
\r
237 static inline void ioport_reset_pin_mode(ioport_pin_t pin)
\r
239 arch_ioport_set_pin_mode(pin, 0);
\r
243 * \brief Set I/O direction for a group of pins in a single IOPORT.
\r
245 * \param port IOPORT port to configure
\r
246 * \param mask Pin mask of pins to configure
\r
247 * \param dir Direction to set for the specified pins (\ref ioport_direction)
\r
249 static inline void ioport_set_port_dir(ioport_port_t port,
\r
250 ioport_port_mask_t mask, enum ioport_direction dir)
\r
252 arch_ioport_set_port_dir(port, mask, dir);
\r
256 * \brief Set direction for a single IOPORT pin.
\r
258 * \param pin IOPORT pin to configure
\r
259 * \param dir Direction to set for the specified pin (\ref ioport_direction)
\r
261 static inline void ioport_set_pin_dir(ioport_pin_t pin,
\r
262 enum ioport_direction dir)
\r
264 arch_ioport_set_pin_dir(pin, dir);
\r
268 * \brief Set an IOPORT pin to a specified logical value.
\r
270 * \param pin IOPORT pin to configure
\r
271 * \param level Logical value of the pin
\r
273 static inline void ioport_set_pin_level(ioport_pin_t pin, bool level)
\r
275 arch_ioport_set_pin_level(pin, level);
\r
279 * \brief Set a group of IOPORT pins in a single port to a specified logical
\r
282 * \param port IOPORT port to write to
\r
283 * \param mask Pin mask of pins to modify
\r
284 * \param level Level of the pins to be modified
\r
286 static inline void ioport_set_port_level(ioport_port_t port,
\r
287 ioport_port_mask_t mask, ioport_port_mask_t level)
\r
289 arch_ioport_set_port_level(port, mask, level);
\r
293 * \brief Get current value of an IOPORT pin, which has been configured as an
\r
296 * \param pin IOPORT pin to read
\r
297 * \return Current logical value of the specified pin
\r
299 static inline bool ioport_get_pin_level(ioport_pin_t pin)
\r
301 return arch_ioport_get_pin_level(pin);
\r
305 * \brief Get current value of several IOPORT pins in a single port, which have
\r
306 * been configured as an inputs.
\r
308 * \param port IOPORT port to read
\r
309 * \param mask Pin mask of pins to read
\r
310 * \return Logical levels of the specified pins from the read port, returned as
\r
313 static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port,
\r
314 ioport_port_mask_t mask)
\r
316 return arch_ioport_get_port_level(port, mask);
\r
320 * \brief Toggle the value of an IOPORT pin, which has previously configured as
\r
323 * \param pin IOPORT pin to toggle
\r
325 static inline void ioport_toggle_pin_level(ioport_pin_t pin)
\r
327 arch_ioport_toggle_pin_level(pin);
\r
331 * \brief Toggle the values of several IOPORT pins located in a single port.
\r
333 * \param port IOPORT port to modify
\r
334 * \param mask Pin mask of pins to toggle
\r
336 static inline void ioport_toggle_port_level(ioport_port_t port,
\r
337 ioport_port_mask_t mask)
\r
339 arch_ioport_toggle_port_level(port, mask);
\r
343 * \brief Set the pin sense mode of a single IOPORT pin.
\r
345 * \param pin IOPORT pin to configure
\r
346 * \param pin_sense Edge to sense for the pin (\ref ioport_sense)
\r
348 static inline void ioport_set_pin_sense_mode(ioport_pin_t pin,
\r
349 enum ioport_sense pin_sense)
\r
351 arch_ioport_set_pin_sense_mode(pin, pin_sense);
\r
355 * \brief Set the pin sense mode of a multiple IOPORT pins on a single port.
\r
357 * \param port IOPORT port to configure
\r
358 * \param mask Bitmask if pins whose edge sense is to be configured
\r
359 * \param pin_sense Edge to sense for the pins (\ref ioport_sense)
\r
361 static inline void ioport_set_port_sense_mode(ioport_port_t port,
\r
362 ioport_port_mask_t mask,
\r
363 enum ioport_sense pin_sense)
\r
365 arch_ioport_set_port_sense_mode(port, mask, pin_sense);
\r
369 * \brief Convert a pin ID into a its port ID.
\r
371 * \param pin IOPORT pin ID to convert
\r
372 * \retval Port ID for the given pin ID
\r
374 static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin)
\r
376 return arch_ioport_pin_to_port_id(pin);
\r
380 * \brief Convert a pin ID into a bitmask mask for the given pin on its port.
\r
382 * \param pin IOPORT pin ID to convert
\r
383 * \retval Bitmask with a bit set that corresponds to the given pin ID in its port
\r
385 static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin)
\r
387 return arch_ioport_pin_to_mask(pin);
\r
393 * \page ioport_quickstart Quick start guide for the common IOPORT service
\r
395 * This is the quick start guide for the \ref ioport_group, with
\r
396 * step-by-step instructions on how to configure and use the service in a
\r
397 * selection of use cases.
\r
399 * The use cases contain several code fragments. The code fragments in the
\r
400 * steps for setup can be copied into a custom initialization function, while
\r
401 * the steps for usage can be copied into, e.g., the main application function.
\r
403 * \section ioport_quickstart_basic Basic use case
\r
404 * In this use case we will configure one IO pin for button input and one for
\r
405 * LED control. Then it will read the button state and output it on the LED.
\r
407 * \section ioport_quickstart_basic_setup Setup steps
\r
409 * \subsection ioport_quickstart_basic_setup_code Example code
\r
411 * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5)
\r
412 * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6)
\r
416 * ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT);
\r
417 * ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT);
\r
418 * ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP);
\r
421 * \subsection ioport_quickstart_basic_setup_flow Workflow
\r
422 * -# It's useful to give the GPIOs symbolic names and this can be done with
\r
423 * the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a
\r
426 * #define MY_LED IOPORT_CREATE_PIN(PORTA, 5)
\r
427 * #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6)
\r
429 * - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names
\r
430 * differ between architectures:
\r
431 * - MEGA, MEGA_RF and XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions
\r
433 * - UC3: Most convenient to pick up the device header file pin definition
\r
434 * and us it directly. E.g.: AVR32_PIN_PB06
\r
435 * - SAM: Most convenient to pick up the device header file pin definition
\r
436 * and us it directly. E.g.: PIO_PA5_IDX<br>
\r
437 * \ref IOPORT_CREATE_PIN can also be used with port definitions
\r
439 * -# Initialize the ioport service. This typically enables the IO module if
\r
441 * - \code ioport_init(); \endcode
\r
442 * -# Set the LED GPIO as output:
\r
443 * - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode
\r
444 * -# Set the button GPIO as input:
\r
445 * - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode
\r
446 * -# Enable pull-up for the button GPIO:
\r
447 * - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode
\r
449 * \section ioport_quickstart_basic_usage Usage steps
\r
451 * \subsection ioport_quickstart_basic_usage_code Example code
\r
455 * value = ioport_get_pin_level(MY_BUTTON);
\r
456 * ioport_set_pin_level(MY_LED, value);
\r
459 * \subsection ioport_quickstart_basic_usage_flow Workflow
\r
460 * -# Define a boolean variable for state storage:
\r
461 * - \code bool value; \endcode
\r
462 * -# Read out the button level into variable value:
\r
463 * - \code value = ioport_get_pin_level(MY_BUTTON); \endcode
\r
464 * -# Set the LED to read out value from the button:
\r
465 * - \code ioport_set_pin_level(MY_LED, value); \endcode
\r
467 * \section ioport_quickstart_advanced Advanced use cases
\r
468 * - \subpage ioport_quickstart_use_case_1 : Port access
\r
472 * \page ioport_quickstart_use_case_1 Advanced use case doing port access
\r
474 * In this case we will read out the pins from one whole port and write the
\r
475 * read value to another port.
\r
477 * \section ioport_quickstart_use_case_1_setup Setup steps
\r
479 * \subsection ioport_quickstart_use_case_1_setup_code Example code
\r
481 * #define IN_PORT IOPORT_PORTA
\r
482 * #define OUT_PORT IOPORT_PORTB
\r
483 * #define MASK 0x00000060
\r
487 * ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT);
\r
488 * ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT);
\r
491 * \subsection ioport_quickstart_basic_setup_flow Workflow
\r
492 * -# It's useful to give the ports symbolic names:
\r
494 * #define IN_PORT IOPORT_PORTA
\r
495 * #define OUT_PORT IOPORT_PORTB
\r
497 * - \note The port names differ between architectures:
\r
498 * - MEGA_RF, MEGA and XMEGA: There are predefined names for ports: IOPORT_PORTA,
\r
500 * - UC3: Use the index value of the different IO blocks: 0, 1 ...
\r
501 * - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB
\r
503 * -# Also useful to define a mask for the bits to work with:
\r
504 * - \code #define MASK 0x00000060 \endcode
\r
505 * -# Initialize the ioport service. This typically enables the IO module if
\r
507 * - \code ioport_init(); \endcode
\r
508 * -# Set one of the ports as input:
\r
509 * - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode
\r
510 * -# Set the other port as output:
\r
511 * - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode
\r
513 * \section ioport_quickstart_basic_usage Usage steps
\r
515 * \subsection ioport_quickstart_basic_usage_code Example code
\r
517 * ioport_port_mask_t value;
\r
519 * value = ioport_get_port_level(IN_PORT, MASK);
\r
520 * ioport_set_port_level(OUT_PORT, MASK, value);
\r
523 * \subsection ioport_quickstart_basic_usage_flow Workflow
\r
524 * -# Define a variable for port date storage:
\r
525 * - \code ioport_port_mask_t value; \endcode
\r
526 * -# Read out from one port:
\r
527 * - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode
\r
528 * -# Put the read data out on the other port:
\r
529 * - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode
\r
536 #endif /* IOPORT_H */
\r