xref: /btstack/port/samv71-xplained-atwilc3000/ASF/common/services/ioport/ioport.h (revision 1b2596b5303dd8caeea8565532c93cca8dab8cc4)
1 /**
2  * \file
3  *
4  * \brief Common IOPORT service main header file for AVR, UC3 and ARM
5  *        architectures.
6  *
7  * Copyright (c) 2012-2015 Atmel Corporation. All rights reserved.
8  *
9  * \asf_license_start
10  *
11  * \page License
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *
16  * 1. Redistributions of source code must retain the above copyright notice,
17  *    this list of conditions and the following disclaimer.
18  *
19  * 2. Redistributions in binary form must reproduce the above copyright notice,
20  *    this list of conditions and the following disclaimer in the documentation
21  *    and/or other materials provided with the distribution.
22  *
23  * 3. The name of Atmel may not be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * 4. This software may only be redistributed and used in connection with an
27  *    Atmel microcontroller product.
28  *
29  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
30  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
32  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
33  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39  * POSSIBILITY OF SUCH DAMAGE.
40  *
41  * \asf_license_stop
42  *
43  */
44 /*
45  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
46  */
47 #ifndef IOPORT_H
48 #define IOPORT_H
49 
50 #ifdef __cplusplus
51 extern "C" {
52 #endif
53 
54 #include <parts.h>
55 #include <compiler.h>
56 
57 /**
58  * \defgroup ioport_group Common IOPORT API
59  *
60  * See \ref ioport_quickstart.
61  *
62  * This is common IOPORT service for GPIO pin configuration and control in a
63  * standardized manner across the MEGA, MEGA_RF, XMEGA, UC3 and ARM devices.
64  *
65  * Port pin control code is optimized for each platform, and should produce
66  * both compact and fast execution times when used with constant values.
67  *
68  * \section dependencies Dependencies
69  * This driver depends on the following modules:
70  * - \ref sysclk_group for clock speed and functions.
71  * @{
72  */
73 
74 /**
75  * \def IOPORT_CREATE_PIN(port, pin)
76  * \brief Create IOPORT pin number
77  *
78  * Create a IOPORT pin number for use with the IOPORT functions.
79  *
80  * \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen
81  *             architecture)
82  * \param pin IOPORT zero-based index of the I/O pin
83  */
84 
85 /** \brief IOPORT pin directions */
86 enum ioport_direction {
87 	IOPORT_DIR_INPUT,  /*!< IOPORT input direction */
88 	IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */
89 };
90 
91 /** \brief IOPORT levels */
92 enum ioport_value {
93 	IOPORT_PIN_LEVEL_LOW,  /*!< IOPORT pin value low */
94 	IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */
95 };
96 
97 #if MEGA_RF
98 /** \brief IOPORT edge sense modes */
99 enum ioport_sense {
100 	IOPORT_SENSE_LEVEL,     /*!< IOPORT sense low level  */
101 	IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */
102 	IOPORT_SENSE_FALLING,   /*!< IOPORT sense falling edges */
103 	IOPORT_SENSE_RISING,    /*!< IOPORT sense rising edges */
104 };
105 #elif SAM && !SAM4L
106 /** \brief IOPORT edge sense modes */
107 enum ioport_sense {
108 	IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */
109 	IOPORT_SENSE_FALLING,   /*!< IOPORT sense falling edges */
110 	IOPORT_SENSE_RISING,    /*!< IOPORT sense rising edges */
111 	IOPORT_SENSE_LEVEL_LOW, /*!< IOPORT sense low level  */
112 	IOPORT_SENSE_LEVEL_HIGH,/*!< IOPORT sense High level  */
113 };
114 #else
115 enum ioport_sense {
116 	IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */
117 	IOPORT_SENSE_RISING,    /*!< IOPORT sense rising edges */
118 	IOPORT_SENSE_FALLING,   /*!< IOPORT sense falling edges */
119 };
120 #endif
121 
122 
123 #if XMEGA
124 # include "xmega/ioport.h"
125 # if defined(IOPORT_XMEGA_COMPAT)
126 #  include "xmega/ioport_compat.h"
127 # endif
128 #elif MEGA
129 #  include "mega/ioport.h"
130 #elif UC3
131 # include "uc3/ioport.h"
132 #elif SAM
133 # if SAM4L
134 #  include "sam/ioport_gpio.h"
135 # elif (SAMD20 | SAMD21)
136 #  include "sam0/ioport.h"
137 # else
138 #  include "sam/ioport_pio.h"
139 # endif
140 #endif
141 
142 /**
143  * \brief Initializes the IOPORT service, ready for use.
144  *
145  * This function must be called before using any other functions in the IOPORT
146  * service.
147  */
ioport_init(void)148 static inline void ioport_init(void)
149 {
150 	arch_ioport_init();
151 }
152 
153 /**
154  * \brief Enable an IOPORT pin, based on a pin created with \ref
155  * IOPORT_CREATE_PIN().
156  *
157  * \param pin  IOPORT pin to enable
158  */
ioport_enable_pin(ioport_pin_t pin)159 static inline void ioport_enable_pin(ioport_pin_t pin)
160 {
161 	arch_ioport_enable_pin(pin);
162 }
163 
164 /**
165  * \brief Enable multiple pins in a single IOPORT port.
166  *
167  * \param port IOPORT port to enable
168  * \param mask Mask of pins within the port to enable
169  */
ioport_enable_port(ioport_port_t port,ioport_port_mask_t mask)170 static inline void ioport_enable_port(ioport_port_t port,
171 		ioport_port_mask_t mask)
172 {
173 	arch_ioport_enable_port(port, mask);
174 }
175 
176 /**
177  * \brief Disable IOPORT pin, based on a pin created with \ref
178  *        IOPORT_CREATE_PIN().
179  *
180  * \param pin IOPORT pin to disable
181  */
ioport_disable_pin(ioport_pin_t pin)182 static inline void ioport_disable_pin(ioport_pin_t pin)
183 {
184 	arch_ioport_disable_pin(pin);
185 }
186 
187 /**
188  * \brief Disable multiple pins in a single IOPORT port.
189  *
190  * \param port IOPORT port to disable
191  * \param mask Pin mask of pins to disable
192  */
ioport_disable_port(ioport_port_t port,ioport_port_mask_t mask)193 static inline void ioport_disable_port(ioport_port_t port,
194 		ioport_port_mask_t mask)
195 {
196 	arch_ioport_disable_port(port, mask);
197 }
198 
199 /**
200  * \brief Set multiple pin modes in a single IOPORT port, such as pull-up,
201  * pull-down, etc. configuration.
202  *
203  * \param port IOPORT port to configure
204  * \param mask Pin mask of pins to configure
205  * \param mode Mode masks to configure for the specified pins (\ref
206  * ioport_modes)
207  */
ioport_set_port_mode(ioport_port_t port,ioport_port_mask_t mask,ioport_mode_t mode)208 static inline void ioport_set_port_mode(ioport_port_t port,
209 		ioport_port_mask_t mask, ioport_mode_t mode)
210 {
211 	arch_ioport_set_port_mode(port, mask, mode);
212 }
213 
214 /**
215  * \brief Set pin mode for one single IOPORT pin.
216  *
217  * \param pin IOPORT pin to configure
218  * \param mode Mode masks to configure for the specified pin (\ref ioport_modes)
219  */
ioport_set_pin_mode(ioport_pin_t pin,ioport_mode_t mode)220 static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode)
221 {
222 	arch_ioport_set_pin_mode(pin, mode);
223 }
224 
225 /**
226  * \brief Reset multiple pin modes in a specified IOPORT port to defaults.
227  *
228  * \param port IOPORT port to configure
229  * \param mask Mask of pins whose mode configuration is to be reset
230  */
ioport_reset_port_mode(ioport_port_t port,ioport_port_mask_t mask)231 static inline void ioport_reset_port_mode(ioport_port_t port,
232 		ioport_port_mask_t mask)
233 {
234 	arch_ioport_set_port_mode(port, mask, 0);
235 }
236 
237 /**
238  * \brief Reset pin mode configuration for a single IOPORT pin
239  *
240  * \param pin IOPORT pin to configure
241  */
ioport_reset_pin_mode(ioport_pin_t pin)242 static inline void ioport_reset_pin_mode(ioport_pin_t pin)
243 {
244 	arch_ioport_set_pin_mode(pin, 0);
245 }
246 
247 /**
248  * \brief Set I/O direction for a group of pins in a single IOPORT.
249  *
250  * \param port IOPORT port to configure
251  * \param mask Pin mask of pins to configure
252  * \param dir Direction to set for the specified pins (\ref ioport_direction)
253  */
ioport_set_port_dir(ioport_port_t port,ioport_port_mask_t mask,enum ioport_direction dir)254 static inline void ioport_set_port_dir(ioport_port_t port,
255 		ioport_port_mask_t mask, enum ioport_direction dir)
256 {
257 	arch_ioport_set_port_dir(port, mask, dir);
258 }
259 
260 /**
261  * \brief Set direction for a single IOPORT pin.
262  *
263  * \param pin IOPORT pin to configure
264  * \param dir Direction to set for the specified pin (\ref ioport_direction)
265  */
ioport_set_pin_dir(ioport_pin_t pin,enum ioport_direction dir)266 static inline void ioport_set_pin_dir(ioport_pin_t pin,
267 		enum ioport_direction dir)
268 {
269 	arch_ioport_set_pin_dir(pin, dir);
270 }
271 
272 /**
273  * \brief Set an IOPORT pin to a specified logical value.
274  *
275  * \param pin IOPORT pin to configure
276  * \param level Logical value of the pin
277  */
ioport_set_pin_level(ioport_pin_t pin,bool level)278 static inline void ioport_set_pin_level(ioport_pin_t pin, bool level)
279 {
280 	arch_ioport_set_pin_level(pin, level);
281 }
282 
283 /**
284  * \brief Set a group of IOPORT pins in a single port to a specified logical
285  * value.
286  *
287  * \param port IOPORT port to write to
288  * \param mask Pin mask of pins to modify
289  * \param level Level of the pins to be modified
290  */
ioport_set_port_level(ioport_port_t port,ioport_port_mask_t mask,ioport_port_mask_t level)291 static inline void ioport_set_port_level(ioport_port_t port,
292 		ioport_port_mask_t mask, ioport_port_mask_t level)
293 {
294 	arch_ioport_set_port_level(port, mask, level);
295 }
296 
297 /**
298  * \brief Get current value of an IOPORT pin, which has been configured as an
299  * input.
300  *
301  * \param pin IOPORT pin to read
302  * \return Current logical value of the specified pin
303  */
ioport_get_pin_level(ioport_pin_t pin)304 static inline bool ioport_get_pin_level(ioport_pin_t pin)
305 {
306 	return arch_ioport_get_pin_level(pin);
307 }
308 
309 /**
310  * \brief Get current value of several IOPORT pins in a single port, which have
311  * been configured as an inputs.
312  *
313  * \param port IOPORT port to read
314  * \param mask Pin mask of pins to read
315  * \return Logical levels of the specified pins from the read port, returned as
316  * a mask.
317  */
ioport_get_port_level(ioport_pin_t port,ioport_port_mask_t mask)318 static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port,
319 		ioport_port_mask_t mask)
320 {
321 	return arch_ioport_get_port_level(port, mask);
322 }
323 
324 /**
325  * \brief Toggle the value of an IOPORT pin, which has previously configured as
326  * an output.
327  *
328  * \param pin IOPORT pin to toggle
329  */
ioport_toggle_pin_level(ioport_pin_t pin)330 static inline void ioport_toggle_pin_level(ioport_pin_t pin)
331 {
332 	arch_ioport_toggle_pin_level(pin);
333 }
334 
335 /**
336  * \brief Toggle the values of several IOPORT pins located in a single port.
337  *
338  * \param port IOPORT port to modify
339  * \param mask Pin mask of pins to toggle
340  */
ioport_toggle_port_level(ioport_port_t port,ioport_port_mask_t mask)341 static inline void ioport_toggle_port_level(ioport_port_t port,
342 		ioport_port_mask_t mask)
343 {
344 	arch_ioport_toggle_port_level(port, mask);
345 }
346 
347 /**
348  * \brief Set the pin sense mode of a single IOPORT pin.
349  *
350  * \param pin IOPORT pin to configure
351  * \param pin_sense Edge to sense for the pin (\ref ioport_sense)
352  */
ioport_set_pin_sense_mode(ioport_pin_t pin,enum ioport_sense pin_sense)353 static inline void ioport_set_pin_sense_mode(ioport_pin_t pin,
354 		enum ioport_sense pin_sense)
355 {
356 	arch_ioport_set_pin_sense_mode(pin, pin_sense);
357 }
358 
359 /**
360  * \brief Set the pin sense mode of a multiple IOPORT pins on a single port.
361  *
362  * \param port IOPORT port to configure
363  * \param mask Bitmask if pins whose edge sense is to be configured
364  * \param pin_sense Edge to sense for the pins (\ref ioport_sense)
365  */
ioport_set_port_sense_mode(ioport_port_t port,ioport_port_mask_t mask,enum ioport_sense pin_sense)366 static inline void ioport_set_port_sense_mode(ioport_port_t port,
367 		ioport_port_mask_t mask,
368 		enum ioport_sense pin_sense)
369 {
370 	arch_ioport_set_port_sense_mode(port, mask, pin_sense);
371 }
372 
373 /**
374  * \brief Convert a pin ID into a its port ID.
375  *
376  * \param pin IOPORT pin ID to convert
377  * \retval Port ID for the given pin ID
378  */
ioport_pin_to_port_id(ioport_pin_t pin)379 static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin)
380 {
381 	return arch_ioport_pin_to_port_id(pin);
382 }
383 
384 /**
385  * \brief Convert a pin ID into a bitmask mask for the given pin on its port.
386  *
387  * \param pin IOPORT pin ID to convert
388  * \retval Bitmask with a bit set that corresponds to the given pin ID in its port
389  */
ioport_pin_to_mask(ioport_pin_t pin)390 static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin)
391 {
392 	return arch_ioport_pin_to_mask(pin);
393 }
394 
395 /** @} */
396 
397 /**
398  * \page ioport_quickstart Quick start guide for the common IOPORT service
399  *
400  * This is the quick start guide for the \ref ioport_group, with
401  * step-by-step instructions on how to configure and use the service in a
402  * selection of use cases.
403  *
404  * The use cases contain several code fragments. The code fragments in the
405  * steps for setup can be copied into a custom initialization function, while
406  * the steps for usage can be copied into, e.g., the main application function.
407  *
408  * \section ioport_quickstart_basic Basic use case
409  * In this use case we will configure one IO pin for button input and one for
410  * LED control. Then it will read the button state and output it on the LED.
411  *
412  * \section ioport_quickstart_basic_setup Setup steps
413  *
414  * \subsection ioport_quickstart_basic_setup_code Example code
415  * \code
416 	 #define MY_LED    IOPORT_CREATE_PIN(PORTA, 5)
417 	 #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6)
418 
419 	 ioport_init();
420 
421 	 ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT);
422 	 ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT);
423 	 ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP);
424 \endcode
425  *
426  * \subsection ioport_quickstart_basic_setup_flow Workflow
427  * -# It's useful to give the GPIOs symbolic names and this can be done with
428  *    the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a
429  *    button.
430  *   - \code
431 	#define MY_LED    IOPORT_CREATE_PIN(PORTA, 5)
432 	#define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6)
433 \endcode
434  *   - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names
435  *           differ between architectures:
436  *     - MEGA, MEGA_RF and XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions
437  *              PORTA, PORTB ...
438  *     - UC3: Most convenient to pick up the device header file pin definition
439  *            and us it directly. E.g.: AVR32_PIN_PB06
440  *     - SAM: Most convenient to pick up the device header file pin definition
441  *            and us it directly. E.g.: PIO_PA5_IDX<br>
442  *            \ref IOPORT_CREATE_PIN can also be used with port definitions
443  *            PIOA, PIOB ...
444  * -# Initialize the ioport service. This typically enables the IO module if
445  *    needed.
446  *   - \code ioport_init(); \endcode
447  * -# Set the LED GPIO as output:
448  *   - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode
449  * -# Set the button GPIO as input:
450  *   - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode
451  * -# Enable pull-up for the button GPIO:
452  *   - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode
453  *
454  * \section ioport_quickstart_basic_usage Usage steps
455  *
456  * \subsection ioport_quickstart_basic_usage_code Example code
457  * \code
458 	 bool value;
459 
460 	 value = ioport_get_pin_level(MY_BUTTON);
461 	 ioport_set_pin_level(MY_LED, value);
462 \endcode
463  *
464  * \subsection ioport_quickstart_basic_usage_flow Workflow
465  * -# Define a boolean variable for state storage:
466  *   - \code bool value; \endcode
467  * -# Read out the button level into variable value:
468  *   - \code value = ioport_get_pin_level(MY_BUTTON); \endcode
469  * -# Set the LED to read out value from the button:
470  *   - \code ioport_set_pin_level(MY_LED, value); \endcode
471  *
472  * \section ioport_quickstart_advanced Advanced use cases
473  * - \subpage ioport_quickstart_use_case_1 : Port access
474  */
475 
476 /**
477  * \page ioport_quickstart_use_case_1 Advanced use case doing port access
478  *
479  * In this case we will read out the pins from one whole port and write the
480  * read value to another port.
481  *
482  * \section ioport_quickstart_use_case_1_setup Setup steps
483  *
484  * \subsection ioport_quickstart_use_case_1_setup_code Example code
485  * \code
486 	 #define IN_PORT  IOPORT_PORTA
487 	 #define OUT_PORT IOPORT_PORTB
488 	 #define MASK     0x00000060
489 
490 	 ioport_init();
491 
492 	 ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT);
493 	 ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT);
494 \endcode
495  *
496  * \subsection ioport_quickstart_basic_setup_flow Workflow
497  * -# It's useful to give the ports symbolic names:
498  *   - \code
499 	#define IN_PORT  IOPORT_PORTA
500 	#define OUT_PORT IOPORT_PORTB
501 \endcode
502  *   - \note The port names differ between architectures:
503  *     - MEGA_RF, MEGA and XMEGA: There are predefined names for ports: IOPORT_PORTA,
504  *              IOPORT_PORTB ...
505  *     - UC3: Use the index value of the different IO blocks: 0, 1 ...
506  *     - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB
507  *            ...
508  * -# Also useful to define a mask for the bits to work with:
509  *     - \code #define MASK     0x00000060 \endcode
510  * -# Initialize the ioport service. This typically enables the IO module if
511  *    needed.
512  *   - \code ioport_init(); \endcode
513  * -# Set one of the ports as input:
514  *   - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode
515  * -# Set the other port as output:
516  *   - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode
517  *
518  * \section ioport_quickstart_basic_usage Usage steps
519  *
520  * \subsection ioport_quickstart_basic_usage_code Example code
521  * \code
522 	 ioport_port_mask_t value;
523 
524 	 value = ioport_get_port_level(IN_PORT, MASK);
525 	 ioport_set_port_level(OUT_PORT, MASK, value);
526 \endcode
527  *
528  * \subsection ioport_quickstart_basic_usage_flow Workflow
529  * -# Define a variable for port date storage:
530  *   - \code ioport_port_mask_t value; \endcode
531  * -# Read out from one port:
532  *   - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode
533  * -# Put the read data out on the other port:
534  *   - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode
535  */
536 
537 #ifdef __cplusplus
538 }
539 #endif
540 
541 #endif /* IOPORT_H */
542