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