1 /** 2 * \file 3 * 4 * \brief Parallel Input/Output (PIO) Controller driver for SAM. 5 * 6 * Copyright (c) 2011-2015 Atmel Corporation. All rights reserved. 7 * 8 * \asf_license_start 9 * 10 * \page License 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions are met: 14 * 15 * 1. Redistributions of source code must retain the above copyright notice, 16 * this list of conditions and the following disclaimer. 17 * 18 * 2. Redistributions in binary form must reproduce the above copyright notice, 19 * this list of conditions and the following disclaimer in the documentation 20 * and/or other materials provided with the distribution. 21 * 22 * 3. The name of Atmel may not be used to endorse or promote products derived 23 * from this software without specific prior written permission. 24 * 25 * 4. This software may only be redistributed and used in connection with an 26 * Atmel microcontroller product. 27 * 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 * 40 * \asf_license_stop 41 * 42 */ 43 /* 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> 45 */ 46 47 #include "pio.h" 48 49 #ifndef PIO_WPMR_WPKEY_PASSWD 50 # define PIO_WPMR_WPKEY_PASSWD PIO_WPMR_WPKEY(0x50494Fu) 51 #endif 52 53 /** 54 * \defgroup sam_drivers_pio_group Peripheral Parallel Input/Output (PIO) Controller 55 * 56 * \par Purpose 57 * 58 * The Parallel Input/Output Controller (PIO) manages up to 32 fully 59 * programmable input/output lines. Each I/O line may be dedicated as a 60 * general-purpose I/O or be assigned to a function of an embedded peripheral. 61 * This assures effective optimization of the pins of a product. 62 * 63 * @{ 64 */ 65 66 #ifndef FREQ_SLOW_CLOCK_EXT 67 /* External slow clock frequency (hz) */ 68 #define FREQ_SLOW_CLOCK_EXT 32768 69 #endif 70 71 /** 72 * \brief Configure PIO internal pull-up. 73 * 74 * \param p_pio Pointer to a PIO instance. 75 * \param ul_mask Bitmask of one or more pin(s) to configure. 76 * \param ul_pull_up_enable Indicates if the pin(s) internal pull-up shall be 77 * configured. 78 */ 79 void pio_pull_up(Pio *p_pio, const uint32_t ul_mask, 80 const uint32_t ul_pull_up_enable) 81 { 82 /* Enable the pull-up(s) if necessary */ 83 if (ul_pull_up_enable) { 84 p_pio->PIO_PUER = ul_mask; 85 } else { 86 p_pio->PIO_PUDR = ul_mask; 87 } 88 } 89 90 /** 91 * \brief Configure Glitch or Debouncing filter for the specified input(s). 92 * 93 * \param p_pio Pointer to a PIO instance. 94 * \param ul_mask Bitmask of one or more pin(s) to configure. 95 * \param ul_cut_off Cuts off frequency for debouncing filter. 96 */ 97 void pio_set_debounce_filter(Pio *p_pio, const uint32_t ul_mask, 98 const uint32_t ul_cut_off) 99 { 100 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70) 101 /* Set Debouncing, 0 bit field no effect */ 102 p_pio->PIO_IFSCER = ul_mask; 103 #elif (SAM3XA || SAM3U) 104 /* Set Debouncing, 0 bit field no effect */ 105 p_pio->PIO_DIFSR = ul_mask; 106 #else 107 #error "Unsupported device" 108 #endif 109 110 /* 111 * The debouncing filter can filter a pulse of less than 1/2 Period of a 112 * programmable Divided Slow Clock: 113 * Tdiv_slclk = ((DIV+1)*2).Tslow_clock 114 */ 115 p_pio->PIO_SCDR = PIO_SCDR_DIV((FREQ_SLOW_CLOCK_EXT / 116 (2 * (ul_cut_off))) - 1); 117 } 118 119 /** 120 * \brief Set a high output level on all the PIOs defined in ul_mask. 121 * This has no immediate effects on PIOs that are not output, but the PIO 122 * controller will save the value if they are changed to outputs. 123 * 124 * \param p_pio Pointer to a PIO instance. 125 * \param ul_mask Bitmask of one or more pin(s) to configure. 126 */ 127 void pio_set(Pio *p_pio, const uint32_t ul_mask) 128 { 129 p_pio->PIO_SODR = ul_mask; 130 } 131 132 /** 133 * \brief Set a low output level on all the PIOs defined in ul_mask. 134 * This has no immediate effects on PIOs that are not output, but the PIO 135 * controller will save the value if they are changed to outputs. 136 * 137 * \param p_pio Pointer to a PIO instance. 138 * \param ul_mask Bitmask of one or more pin(s) to configure. 139 */ 140 void pio_clear(Pio *p_pio, const uint32_t ul_mask) 141 { 142 p_pio->PIO_CODR = ul_mask; 143 } 144 145 /** 146 * \brief Return 1 if one or more PIOs of the given Pin instance currently have 147 * a high level; otherwise returns 0. This method returns the actual value that 148 * is being read on the pin. To return the supposed output value of a pin, use 149 * pio_get_output_data_status() instead. 150 * 151 * \param p_pio Pointer to a PIO instance. 152 * \param ul_type PIO type. 153 * \param ul_mask Bitmask of one or more pin(s) to configure. 154 * 155 * \retval 1 at least one PIO currently has a high level. 156 * \retval 0 all PIOs have a low level. 157 */ 158 uint32_t pio_get(Pio *p_pio, const pio_type_t ul_type, 159 const uint32_t ul_mask) 160 { 161 uint32_t ul_reg; 162 163 if ((ul_type == PIO_OUTPUT_0) || (ul_type == PIO_OUTPUT_1)) { 164 ul_reg = p_pio->PIO_ODSR; 165 } else { 166 ul_reg = p_pio->PIO_PDSR; 167 } 168 169 if ((ul_reg & ul_mask) == 0) { 170 return 0; 171 } else { 172 return 1; 173 } 174 } 175 176 /** 177 * \brief Configure IO of a PIO controller as being controlled by a specific 178 * peripheral. 179 * 180 * \param p_pio Pointer to a PIO instance. 181 * \param ul_type PIO type. 182 * \param ul_mask Bitmask of one or more pin(s) to configure. 183 */ 184 void pio_set_peripheral(Pio *p_pio, const pio_type_t ul_type, 185 const uint32_t ul_mask) 186 { 187 uint32_t ul_sr; 188 189 /* Disable interrupts on the pin(s) */ 190 p_pio->PIO_IDR = ul_mask; 191 192 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70) 193 switch (ul_type) { 194 case PIO_PERIPH_A: 195 ul_sr = p_pio->PIO_ABCDSR[0]; 196 p_pio->PIO_ABCDSR[0] &= (~ul_mask & ul_sr); 197 198 ul_sr = p_pio->PIO_ABCDSR[1]; 199 p_pio->PIO_ABCDSR[1] &= (~ul_mask & ul_sr); 200 break; 201 case PIO_PERIPH_B: 202 ul_sr = p_pio->PIO_ABCDSR[0]; 203 p_pio->PIO_ABCDSR[0] = (ul_mask | ul_sr); 204 205 ul_sr = p_pio->PIO_ABCDSR[1]; 206 p_pio->PIO_ABCDSR[1] &= (~ul_mask & ul_sr); 207 break; 208 #if (!SAMG) 209 case PIO_PERIPH_C: 210 ul_sr = p_pio->PIO_ABCDSR[0]; 211 p_pio->PIO_ABCDSR[0] &= (~ul_mask & ul_sr); 212 213 ul_sr = p_pio->PIO_ABCDSR[1]; 214 p_pio->PIO_ABCDSR[1] = (ul_mask | ul_sr); 215 break; 216 case PIO_PERIPH_D: 217 ul_sr = p_pio->PIO_ABCDSR[0]; 218 p_pio->PIO_ABCDSR[0] = (ul_mask | ul_sr); 219 220 ul_sr = p_pio->PIO_ABCDSR[1]; 221 p_pio->PIO_ABCDSR[1] = (ul_mask | ul_sr); 222 break; 223 #endif 224 /* Other types are invalid in this function */ 225 case PIO_INPUT: 226 case PIO_OUTPUT_0: 227 case PIO_OUTPUT_1: 228 case PIO_NOT_A_PIN: 229 return; 230 } 231 #elif (SAM3XA|| SAM3U) 232 switch (ul_type) { 233 case PIO_PERIPH_A: 234 ul_sr = p_pio->PIO_ABSR; 235 p_pio->PIO_ABSR &= (~ul_mask & ul_sr); 236 break; 237 238 case PIO_PERIPH_B: 239 ul_sr = p_pio->PIO_ABSR; 240 p_pio->PIO_ABSR = (ul_mask | ul_sr); 241 break; 242 243 // other types are invalid in this function 244 case PIO_INPUT: 245 case PIO_OUTPUT_0: 246 case PIO_OUTPUT_1: 247 case PIO_NOT_A_PIN: 248 return; 249 } 250 #else 251 #error "Unsupported device" 252 #endif 253 254 /* Remove the pins from under the control of PIO */ 255 p_pio->PIO_PDR = ul_mask; 256 } 257 258 /** 259 * \brief Configure one or more pin(s) or a PIO controller as inputs. 260 * Optionally, the corresponding internal pull-up(s) and glitch filter(s) can 261 * be enabled. 262 * 263 * \param p_pio Pointer to a PIO instance. 264 * \param ul_mask Bitmask indicating which pin(s) to configure as input(s). 265 * \param ul_attribute PIO attribute(s). 266 */ 267 void pio_set_input(Pio *p_pio, const uint32_t ul_mask, 268 const uint32_t ul_attribute) 269 { 270 pio_disable_interrupt(p_pio, ul_mask); 271 pio_pull_up(p_pio, ul_mask, ul_attribute & PIO_PULLUP); 272 273 /* Enable Input Filter if necessary */ 274 if (ul_attribute & (PIO_DEGLITCH | PIO_DEBOUNCE)) { 275 p_pio->PIO_IFER = ul_mask; 276 } else { 277 p_pio->PIO_IFDR = ul_mask; 278 } 279 280 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70) 281 /* Enable de-glitch or de-bounce if necessary */ 282 if (ul_attribute & PIO_DEGLITCH) { 283 p_pio->PIO_IFSCDR = ul_mask; 284 } else { 285 if (ul_attribute & PIO_DEBOUNCE) { 286 p_pio->PIO_IFSCER = ul_mask; 287 } 288 } 289 #elif (SAM3XA|| SAM3U) 290 /* Enable de-glitch or de-bounce if necessary */ 291 if (ul_attribute & PIO_DEGLITCH) { 292 p_pio->PIO_SCIFSR = ul_mask; 293 } else { 294 if (ul_attribute & PIO_DEBOUNCE) { 295 p_pio->PIO_DIFSR = ul_mask; 296 } 297 } 298 #else 299 #error "Unsupported device" 300 #endif 301 302 /* Configure pin as input */ 303 p_pio->PIO_ODR = ul_mask; 304 p_pio->PIO_PER = ul_mask; 305 } 306 307 /** 308 * \brief Configure one or more pin(s) of a PIO controller as outputs, with 309 * the given default value. Optionally, the multi-drive feature can be enabled 310 * on the pin(s). 311 * 312 * \param p_pio Pointer to a PIO instance. 313 * \param ul_mask Bitmask indicating which pin(s) to configure. 314 * \param ul_default_level Default level on the pin(s). 315 * \param ul_multidrive_enable Indicates if the pin(s) shall be configured as 316 * open-drain. 317 * \param ul_pull_up_enable Indicates if the pin shall have its pull-up 318 * activated. 319 */ 320 void pio_set_output(Pio *p_pio, const uint32_t ul_mask, 321 const uint32_t ul_default_level, 322 const uint32_t ul_multidrive_enable, 323 const uint32_t ul_pull_up_enable) 324 { 325 pio_disable_interrupt(p_pio, ul_mask); 326 pio_pull_up(p_pio, ul_mask, ul_pull_up_enable); 327 328 /* Enable multi-drive if necessary */ 329 if (ul_multidrive_enable) { 330 p_pio->PIO_MDER = ul_mask; 331 } else { 332 p_pio->PIO_MDDR = ul_mask; 333 } 334 335 /* Set default value */ 336 if (ul_default_level) { 337 p_pio->PIO_SODR = ul_mask; 338 } else { 339 p_pio->PIO_CODR = ul_mask; 340 } 341 342 /* Configure pin(s) as output(s) */ 343 p_pio->PIO_OER = ul_mask; 344 p_pio->PIO_PER = ul_mask; 345 } 346 347 /** 348 * \brief Perform complete pin(s) configuration; general attributes and PIO init 349 * if necessary. 350 * 351 * \param p_pio Pointer to a PIO instance. 352 * \param ul_type PIO type. 353 * \param ul_mask Bitmask of one or more pin(s) to configure. 354 * \param ul_attribute Pins attributes. 355 * 356 * \return Whether the pin(s) have been configured properly. 357 */ 358 uint32_t pio_configure(Pio *p_pio, const pio_type_t ul_type, 359 const uint32_t ul_mask, const uint32_t ul_attribute) 360 { 361 /* Configure pins */ 362 switch (ul_type) { 363 case PIO_PERIPH_A: 364 case PIO_PERIPH_B: 365 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70) 366 case PIO_PERIPH_C: 367 case PIO_PERIPH_D: 368 #endif 369 pio_set_peripheral(p_pio, ul_type, ul_mask); 370 pio_pull_up(p_pio, ul_mask, (ul_attribute & PIO_PULLUP)); 371 break; 372 373 case PIO_INPUT: 374 pio_set_input(p_pio, ul_mask, ul_attribute); 375 break; 376 377 case PIO_OUTPUT_0: 378 case PIO_OUTPUT_1: 379 pio_set_output(p_pio, ul_mask, (ul_type == PIO_OUTPUT_1), 380 (ul_attribute & PIO_OPENDRAIN) ? 1 : 0, 381 (ul_attribute & PIO_PULLUP) ? 1 : 0); 382 break; 383 384 default: 385 return 0; 386 } 387 388 return 1; 389 } 390 391 /** 392 * \brief Return 1 if one or more PIOs of the given Pin are configured to 393 * output a high level (even if they are not output). 394 * To get the actual value of the pin, use PIO_Get() instead. 395 * 396 * \param p_pio Pointer to a PIO instance. 397 * \param ul_mask Bitmask of one or more pin(s). 398 * 399 * \retval 1 At least one PIO is configured to output a high level. 400 * \retval 0 All PIOs are configured to output a low level. 401 */ 402 uint32_t pio_get_output_data_status(const Pio *p_pio, 403 const uint32_t ul_mask) 404 { 405 if ((p_pio->PIO_ODSR & ul_mask) == 0) { 406 return 0; 407 } else { 408 return 1; 409 } 410 } 411 412 /** 413 * \brief Configure PIO pin multi-driver. 414 * 415 * \param p_pio Pointer to a PIO instance. 416 * \param ul_mask Bitmask of one or more pin(s) to configure. 417 * \param ul_multi_driver_enable Indicates if the pin(s) multi-driver shall be 418 * configured. 419 */ 420 void pio_set_multi_driver(Pio *p_pio, const uint32_t ul_mask, 421 const uint32_t ul_multi_driver_enable) 422 { 423 /* Enable the multi-driver if necessary */ 424 if (ul_multi_driver_enable) { 425 p_pio->PIO_MDER = ul_mask; 426 } else { 427 p_pio->PIO_MDDR = ul_mask; 428 } 429 } 430 431 /** 432 * \brief Get multi-driver status. 433 * 434 * \param p_pio Pointer to a PIO instance. 435 * 436 * \return The multi-driver mask value. 437 */ 438 uint32_t pio_get_multi_driver_status(const Pio *p_pio) 439 { 440 return p_pio->PIO_MDSR; 441 } 442 443 444 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70) 445 /** 446 * \brief Configure PIO pin internal pull-down. 447 * 448 * \param p_pio Pointer to a PIO instance. 449 * \param ul_mask Bitmask of one or more pin(s) to configure. 450 * \param ul_pull_down_enable Indicates if the pin(s) internal pull-down shall 451 * be configured. 452 */ 453 void pio_pull_down(Pio *p_pio, const uint32_t ul_mask, 454 const uint32_t ul_pull_down_enable) 455 { 456 /* Enable the pull-down if necessary */ 457 if (ul_pull_down_enable) { 458 p_pio->PIO_PPDER = ul_mask; 459 } else { 460 p_pio->PIO_PPDDR = ul_mask; 461 } 462 } 463 #endif 464 465 /** 466 * \brief Enable PIO output write for synchronous data output. 467 * 468 * \param p_pio Pointer to a PIO instance. 469 * \param ul_mask Bitmask of one or more pin(s) to configure. 470 */ 471 void pio_enable_output_write(Pio *p_pio, const uint32_t ul_mask) 472 { 473 p_pio->PIO_OWER = ul_mask; 474 } 475 476 /** 477 * \brief Disable PIO output write. 478 * 479 * \param p_pio Pointer to a PIO instance. 480 * \param ul_mask Bitmask of one or more pin(s) to configure. 481 */ 482 void pio_disable_output_write(Pio *p_pio, const uint32_t ul_mask) 483 { 484 p_pio->PIO_OWDR = ul_mask; 485 } 486 487 /** 488 * \brief Read PIO output write status. 489 * 490 * \param p_pio Pointer to a PIO instance. 491 * 492 * \return The output write mask value. 493 */ 494 uint32_t pio_get_output_write_status(const Pio *p_pio) 495 { 496 return p_pio->PIO_OWSR; 497 } 498 499 /** 500 * \brief Synchronously write on output pins. 501 * \note Only bits unmasked by PIO_OWSR (Output Write Status Register) are 502 * written. 503 * 504 * \param p_pio Pointer to a PIO instance. 505 * \param ul_mask Bitmask of one or more pin(s) to configure. 506 */ 507 void pio_sync_output_write(Pio *p_pio, const uint32_t ul_mask) 508 { 509 p_pio->PIO_ODSR = ul_mask; 510 } 511 512 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70) 513 /** 514 * \brief Configure PIO pin schmitt trigger. By default the Schmitt trigger is 515 * active. 516 * Disabling the Schmitt Trigger is requested when using the QTouch Library. 517 * 518 * \param p_pio Pointer to a PIO instance. 519 * \param ul_mask Bitmask of one or more pin(s) to configure. 520 */ 521 void pio_set_schmitt_trigger(Pio *p_pio, const uint32_t ul_mask) 522 { 523 p_pio->PIO_SCHMITT = ul_mask; 524 } 525 526 /** 527 * \brief Get PIO pin schmitt trigger status. 528 * 529 * \param p_pio Pointer to a PIO instance. 530 * 531 * \return The schmitt trigger mask value. 532 */ 533 uint32_t pio_get_schmitt_trigger(const Pio *p_pio) 534 { 535 return p_pio->PIO_SCHMITT; 536 } 537 #endif 538 539 /** 540 * \brief Configure the given interrupt source. 541 * Interrupt can be configured to trigger on rising edge, falling edge, 542 * high level, low level or simply on level change. 543 * 544 * \param p_pio Pointer to a PIO instance. 545 * \param ul_mask Interrupt source bit map. 546 * \param ul_attr Interrupt source attributes. 547 */ 548 void pio_configure_interrupt(Pio *p_pio, const uint32_t ul_mask, 549 const uint32_t ul_attr) 550 { 551 /* Configure additional interrupt mode registers. */ 552 if (ul_attr & PIO_IT_AIME) { 553 /* Enable additional interrupt mode. */ 554 p_pio->PIO_AIMER = ul_mask; 555 556 /* If bit field of the selected pin is 1, set as 557 Rising Edge/High level detection event. */ 558 if (ul_attr & PIO_IT_RE_OR_HL) { 559 /* Rising Edge or High Level */ 560 p_pio->PIO_REHLSR = ul_mask; 561 } else { 562 /* Falling Edge or Low Level */ 563 p_pio->PIO_FELLSR = ul_mask; 564 } 565 566 /* If bit field of the selected pin is 1, set as 567 edge detection source. */ 568 if (ul_attr & PIO_IT_EDGE) { 569 /* Edge select */ 570 p_pio->PIO_ESR = ul_mask; 571 } else { 572 /* Level select */ 573 p_pio->PIO_LSR = ul_mask; 574 } 575 } else { 576 /* Disable additional interrupt mode. */ 577 p_pio->PIO_AIMDR = ul_mask; 578 } 579 } 580 581 /** 582 * \brief Enable the given interrupt source. 583 * The PIO must be configured as an NVIC interrupt source as well. 584 * The status register of the corresponding PIO controller is cleared 585 * prior to enabling the interrupt. 586 * 587 * \param p_pio Pointer to a PIO instance. 588 * \param ul_mask Interrupt sources bit map. 589 */ 590 void pio_enable_interrupt(Pio *p_pio, const uint32_t ul_mask) 591 { 592 p_pio->PIO_ISR; 593 p_pio->PIO_IER = ul_mask; 594 } 595 596 /** 597 * \brief Disable a given interrupt source, with no added side effects. 598 * 599 * \param p_pio Pointer to a PIO instance. 600 * \param ul_mask Interrupt sources bit map. 601 */ 602 void pio_disable_interrupt(Pio *p_pio, const uint32_t ul_mask) 603 { 604 p_pio->PIO_IDR = ul_mask; 605 } 606 607 /** 608 * \brief Read PIO interrupt status. 609 * 610 * \param p_pio Pointer to a PIO instance. 611 * 612 * \return The interrupt status mask value. 613 */ 614 uint32_t pio_get_interrupt_status(const Pio *p_pio) 615 { 616 return p_pio->PIO_ISR; 617 } 618 619 /** 620 * \brief Read PIO interrupt mask. 621 * 622 * \param p_pio Pointer to a PIO instance. 623 * 624 * \return The interrupt mask value. 625 */ 626 uint32_t pio_get_interrupt_mask(const Pio *p_pio) 627 { 628 return p_pio->PIO_IMR; 629 } 630 631 /** 632 * \brief Set additional interrupt mode. 633 * 634 * \param p_pio Pointer to a PIO instance. 635 * \param ul_mask Interrupt sources bit map. 636 * \param ul_attribute Pin(s) attributes. 637 */ 638 void pio_set_additional_interrupt_mode(Pio *p_pio, 639 const uint32_t ul_mask, const uint32_t ul_attribute) 640 { 641 /* Enables additional interrupt mode if needed */ 642 if (ul_attribute & PIO_IT_AIME) { 643 /* Enables additional interrupt mode */ 644 p_pio->PIO_AIMER = ul_mask; 645 646 /* Configures the Polarity of the event detection */ 647 /* (Rising/Falling Edge or High/Low Level) */ 648 if (ul_attribute & PIO_IT_RE_OR_HL) { 649 /* Rising Edge or High Level */ 650 p_pio->PIO_REHLSR = ul_mask; 651 } else { 652 /* Falling Edge or Low Level */ 653 p_pio->PIO_FELLSR = ul_mask; 654 } 655 656 /* Configures the type of event detection (Edge or Level) */ 657 if (ul_attribute & PIO_IT_EDGE) { 658 /* Edge select */ 659 p_pio->PIO_ESR = ul_mask; 660 } else { 661 /* Level select */ 662 p_pio->PIO_LSR = ul_mask; 663 } 664 } else { 665 /* Disable additional interrupt mode */ 666 p_pio->PIO_AIMDR = ul_mask; 667 } 668 } 669 670 #ifndef PIO_WPMR_WPKEY_PASSWD 671 #define PIO_WPMR_WPKEY_PASSWD PIO_WPMR_WPKEY(0x50494FU) 672 #endif 673 674 /** 675 * \brief Enable or disable write protect of PIO registers. 676 * 677 * \param p_pio Pointer to a PIO instance. 678 * \param ul_enable 1 to enable, 0 to disable. 679 */ 680 void pio_set_writeprotect(Pio *p_pio, const uint32_t ul_enable) 681 { 682 p_pio->PIO_WPMR = PIO_WPMR_WPKEY_PASSWD | (ul_enable & PIO_WPMR_WPEN); 683 } 684 685 /** 686 * \brief Read write protect status. 687 * 688 * \param p_pio Pointer to a PIO instance. 689 * 690 * \return Return write protect status. 691 */ 692 uint32_t pio_get_writeprotect_status(const Pio *p_pio) 693 { 694 return p_pio->PIO_WPSR; 695 } 696 697 /** 698 * \brief Return the value of a pin. 699 * 700 * \param ul_pin The pin number. 701 * 702 * \return The pin value. 703 * 704 * \note If pin is output: a pull-up or pull-down could hide the actual value. 705 * The function \ref pio_get can be called to get the actual pin output 706 * level. 707 * \note If pin is input: PIOx must be clocked to sample the signal. 708 * See PMC driver. 709 */ 710 uint32_t pio_get_pin_value(uint32_t ul_pin) 711 { 712 Pio *p_pio = pio_get_pin_group(ul_pin); 713 714 return (p_pio->PIO_PDSR >> (ul_pin & 0x1F)) & 1; 715 } 716 717 /** 718 * \brief Drive a GPIO pin to 1. 719 * 720 * \param ul_pin The pin index. 721 * 722 * \note The function \ref pio_configure_pin must be called beforehand. 723 */ 724 void pio_set_pin_high(uint32_t ul_pin) 725 { 726 Pio *p_pio = pio_get_pin_group(ul_pin); 727 728 /* Value to be driven on the I/O line: 1. */ 729 p_pio->PIO_SODR = 1 << (ul_pin & 0x1F); 730 } 731 732 /** 733 * \brief Drive a GPIO pin to 0. 734 * 735 * \param ul_pin The pin index. 736 * 737 * \note The function \ref pio_configure_pin must be called before. 738 */ 739 void pio_set_pin_low(uint32_t ul_pin) 740 { 741 Pio *p_pio = pio_get_pin_group(ul_pin); 742 743 /* Value to be driven on the I/O line: 0. */ 744 p_pio->PIO_CODR = 1 << (ul_pin & 0x1F); 745 } 746 747 /** 748 * \brief Toggle a GPIO pin. 749 * 750 * \param ul_pin The pin index. 751 * 752 * \note The function \ref pio_configure_pin must be called before. 753 */ 754 void pio_toggle_pin(uint32_t ul_pin) 755 { 756 Pio *p_pio = pio_get_pin_group(ul_pin); 757 758 if (p_pio->PIO_ODSR & (1 << (ul_pin & 0x1F))) { 759 /* Value to be driven on the I/O line: 0. */ 760 p_pio->PIO_CODR = 1 << (ul_pin & 0x1F); 761 } else { 762 /* Value to be driven on the I/O line: 1. */ 763 p_pio->PIO_SODR = 1 << (ul_pin & 0x1F); 764 } 765 } 766 767 /** 768 * \brief Perform complete pin(s) configuration; general attributes and PIO init 769 * if necessary. 770 * 771 * \param ul_pin Bitmask of one or more pin(s) to configure. 772 * \param ul_flags Pins attributes. 773 * 774 * \return Whether the pin(s) have been configured properly. 775 */ 776 uint32_t pio_configure_pin(uint32_t ul_pin, const uint32_t ul_flags) 777 { 778 Pio *p_pio = pio_get_pin_group(ul_pin); 779 780 /* Configure pins */ 781 switch (ul_flags & PIO_TYPE_Msk) { 782 case PIO_TYPE_PIO_PERIPH_A: 783 pio_set_peripheral(p_pio, PIO_PERIPH_A, (1 << (ul_pin & 0x1F))); 784 pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)), 785 (ul_flags & PIO_PULLUP)); 786 break; 787 case PIO_TYPE_PIO_PERIPH_B: 788 pio_set_peripheral(p_pio, PIO_PERIPH_B, (1 << (ul_pin & 0x1F))); 789 pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)), 790 (ul_flags & PIO_PULLUP)); 791 break; 792 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70) 793 case PIO_TYPE_PIO_PERIPH_C: 794 pio_set_peripheral(p_pio, PIO_PERIPH_C, (1 << (ul_pin & 0x1F))); 795 pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)), 796 (ul_flags & PIO_PULLUP)); 797 break; 798 case PIO_TYPE_PIO_PERIPH_D: 799 pio_set_peripheral(p_pio, PIO_PERIPH_D, (1 << (ul_pin & 0x1F))); 800 pio_pull_up(p_pio, (1 << (ul_pin & 0x1F)), 801 (ul_flags & PIO_PULLUP)); 802 break; 803 #endif 804 805 case PIO_TYPE_PIO_INPUT: 806 pio_set_input(p_pio, (1 << (ul_pin & 0x1F)), ul_flags); 807 break; 808 809 case PIO_TYPE_PIO_OUTPUT_0: 810 case PIO_TYPE_PIO_OUTPUT_1: 811 pio_set_output(p_pio, (1 << (ul_pin & 0x1F)), 812 ((ul_flags & PIO_TYPE_PIO_OUTPUT_1) 813 == PIO_TYPE_PIO_OUTPUT_1) ? 1 : 0, 814 (ul_flags & PIO_OPENDRAIN) ? 1 : 0, 815 (ul_flags & PIO_PULLUP) ? 1 : 0); 816 break; 817 818 default: 819 return 0; 820 } 821 822 return 1; 823 } 824 825 /** 826 * \brief Drive a GPIO port to 1. 827 * 828 * \param p_pio Base address of the PIO port. 829 * \param ul_mask Bitmask of one or more pin(s) to toggle. 830 */ 831 void pio_set_pin_group_high(Pio *p_pio, uint32_t ul_mask) 832 { 833 /* Value to be driven on the I/O line: 1. */ 834 p_pio->PIO_SODR = ul_mask; 835 } 836 837 /** 838 * \brief Drive a GPIO port to 0. 839 * 840 * \param p_pio Base address of the PIO port. 841 * \param ul_mask Bitmask of one or more pin(s) to toggle. 842 */ 843 void pio_set_pin_group_low(Pio *p_pio, uint32_t ul_mask) 844 { 845 /* Value to be driven on the I/O line: 0. */ 846 p_pio->PIO_CODR = ul_mask; 847 } 848 849 /** 850 * \brief Toggle a GPIO group. 851 * 852 * \param p_pio Pointer to a PIO instance. 853 * \param ul_mask Bitmask of one or more pin(s) to configure. 854 */ 855 void pio_toggle_pin_group(Pio *p_pio, uint32_t ul_mask) 856 { 857 if (p_pio->PIO_ODSR & ul_mask) { 858 /* Value to be driven on the I/O line: 0. */ 859 p_pio->PIO_CODR = ul_mask; 860 } else { 861 /* Value to be driven on the I/O line: 1. */ 862 p_pio->PIO_SODR = ul_mask; 863 } 864 } 865 866 /** 867 * \brief Perform complete pin(s) configuration; general attributes and PIO init 868 * if necessary. 869 * 870 * \param p_pio Pointer to a PIO instance. 871 * \param ul_mask Bitmask of one or more pin(s) to configure. 872 * \param ul_flags Pin(s) attributes. 873 * 874 * \return Whether the pin(s) have been configured properly. 875 */ 876 uint32_t pio_configure_pin_group(Pio *p_pio, 877 uint32_t ul_mask, const uint32_t ul_flags) 878 { 879 /* Configure pins */ 880 switch (ul_flags & PIO_TYPE_Msk) { 881 case PIO_TYPE_PIO_PERIPH_A: 882 pio_set_peripheral(p_pio, PIO_PERIPH_A, ul_mask); 883 pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP)); 884 break; 885 case PIO_TYPE_PIO_PERIPH_B: 886 pio_set_peripheral(p_pio, PIO_PERIPH_B, ul_mask); 887 pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP)); 888 break; 889 #if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70) 890 case PIO_TYPE_PIO_PERIPH_C: 891 pio_set_peripheral(p_pio, PIO_PERIPH_C, ul_mask); 892 pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP)); 893 break; 894 case PIO_TYPE_PIO_PERIPH_D: 895 pio_set_peripheral(p_pio, PIO_PERIPH_D, ul_mask); 896 pio_pull_up(p_pio, ul_mask, (ul_flags & PIO_PULLUP)); 897 break; 898 #endif 899 900 case PIO_TYPE_PIO_INPUT: 901 pio_set_input(p_pio, ul_mask, ul_flags); 902 break; 903 904 case PIO_TYPE_PIO_OUTPUT_0: 905 case PIO_TYPE_PIO_OUTPUT_1: 906 pio_set_output(p_pio, ul_mask, 907 ((ul_flags & PIO_TYPE_PIO_OUTPUT_1) 908 == PIO_TYPE_PIO_OUTPUT_1) ? 1 : 0, 909 (ul_flags & PIO_OPENDRAIN) ? 1 : 0, 910 (ul_flags & PIO_PULLUP) ? 1 : 0); 911 break; 912 913 default: 914 return 0; 915 } 916 917 return 1; 918 } 919 920 /** 921 * \brief Enable interrupt for a GPIO pin. 922 * 923 * \param ul_pin The pin index. 924 * 925 * \note The function \ref gpio_configure_pin must be called before. 926 */ 927 void pio_enable_pin_interrupt(uint32_t ul_pin) 928 { 929 Pio *p_pio = pio_get_pin_group(ul_pin); 930 931 p_pio->PIO_IER = 1 << (ul_pin & 0x1F); 932 } 933 934 935 /** 936 * \brief Disable interrupt for a GPIO pin. 937 * 938 * \param ul_pin The pin index. 939 * 940 * \note The function \ref gpio_configure_pin must be called before. 941 */ 942 void pio_disable_pin_interrupt(uint32_t ul_pin) 943 { 944 Pio *p_pio = pio_get_pin_group(ul_pin); 945 946 p_pio->PIO_IDR = 1 << (ul_pin & 0x1F); 947 } 948 949 950 /** 951 * \brief Return GPIO port for a GPIO pin. 952 * 953 * \param ul_pin The pin index. 954 * 955 * \return Pointer to \ref Pio struct for GPIO port. 956 */ 957 Pio *pio_get_pin_group(uint32_t ul_pin) 958 { 959 Pio *p_pio; 960 961 #if (SAM4C || SAM4CP) 962 # ifdef ID_PIOD 963 if (ul_pin > PIO_PC9_IDX) { 964 p_pio = PIOD; 965 } else if (ul_pin > PIO_PB31_IDX) { 966 # else 967 if (ul_pin > PIO_PB31_IDX) { 968 # endif 969 p_pio = PIOC; 970 } else { 971 p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5))); 972 } 973 #elif (SAM4CM) 974 if (ul_pin > PIO_PB21_IDX) { 975 p_pio = PIOC; 976 } else { 977 p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5))); 978 } 979 #else 980 p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5))); 981 #endif 982 return p_pio; 983 } 984 985 /** 986 * \brief Return GPIO port peripheral ID for a GPIO pin. 987 * 988 * \param ul_pin The pin index. 989 * 990 * \return GPIO port peripheral ID. 991 */ 992 uint32_t pio_get_pin_group_id(uint32_t ul_pin) 993 { 994 uint32_t ul_id; 995 996 #if (SAM4C || SAM4CP) 997 # ifdef ID_PIOD 998 if (ul_pin > PIO_PC9_IDX) { 999 ul_id = ID_PIOD; 1000 } else if (ul_pin > PIO_PB31_IDX) { 1001 # else 1002 if (ul_pin > PIO_PB31_IDX) { 1003 # endif 1004 ul_id = ID_PIOC; 1005 } else { 1006 ul_id = ID_PIOA + (ul_pin >> 5); 1007 } 1008 #elif (SAM4CM) 1009 if (ul_pin > PIO_PB21_IDX) { 1010 ul_id = ID_PIOC; 1011 } else { 1012 ul_id = ID_PIOA + (ul_pin >> 5); 1013 } 1014 #else 1015 ul_id = ID_PIOA + (ul_pin >> 5); 1016 #endif 1017 return ul_id; 1018 } 1019 1020 1021 /** 1022 * \brief Return GPIO port pin mask for a GPIO pin. 1023 * 1024 * \param ul_pin The pin index. 1025 * 1026 * \return GPIO port pin mask. 1027 */ 1028 uint32_t pio_get_pin_group_mask(uint32_t ul_pin) 1029 { 1030 uint32_t ul_mask = 1 << (ul_pin & 0x1F); 1031 return ul_mask; 1032 } 1033 1034 #if (SAM3S || SAM4S || SAM4E || SAMV71 || SAMV70 || SAME70 || SAMS70) 1035 /* Capture mode enable flag */ 1036 uint32_t pio_capture_enable_flag; 1037 1038 /** 1039 * \brief Configure PIO capture mode. 1040 * \note PIO capture mode will be disabled automatically. 1041 * 1042 * \param p_pio Pointer to a PIO instance. 1043 * \param ul_mode Bitmask of one or more modes. 1044 */ 1045 void pio_capture_set_mode(Pio *p_pio, uint32_t ul_mode) 1046 { 1047 ul_mode &= (~PIO_PCMR_PCEN); /* Disable PIO capture mode */ 1048 p_pio->PIO_PCMR = ul_mode; 1049 } 1050 1051 /** 1052 * \brief Enable PIO capture mode. 1053 * 1054 * \param p_pio Pointer to a PIO instance. 1055 */ 1056 void pio_capture_enable(Pio *p_pio) 1057 { 1058 p_pio->PIO_PCMR |= PIO_PCMR_PCEN; 1059 pio_capture_enable_flag = true; 1060 } 1061 1062 /** 1063 * \brief Disable PIO capture mode. 1064 * 1065 * \param p_pio Pointer to a PIO instance. 1066 */ 1067 void pio_capture_disable(Pio *p_pio) 1068 { 1069 p_pio->PIO_PCMR &= (~PIO_PCMR_PCEN); 1070 pio_capture_enable_flag = false; 1071 } 1072 1073 /** 1074 * \brief Read from Capture Reception Holding Register. 1075 * \note Data presence should be tested before any read attempt. 1076 * 1077 * \param p_pio Pointer to a PIO instance. 1078 * \param pul_data Pointer to store the data. 1079 * 1080 * \retval 0 Success. 1081 * \retval 1 I/O Failure, Capture data is not ready. 1082 */ 1083 uint32_t pio_capture_read(const Pio *p_pio, uint32_t *pul_data) 1084 { 1085 /* Check if the data is ready */ 1086 if ((p_pio->PIO_PCISR & PIO_PCISR_DRDY) == 0) { 1087 return 1; 1088 } 1089 1090 /* Read data */ 1091 *pul_data = p_pio->PIO_PCRHR; 1092 return 0; 1093 } 1094 1095 /** 1096 * \brief Enable the given interrupt source of PIO capture. The status 1097 * register of the corresponding PIO capture controller is cleared prior 1098 * to enabling the interrupt. 1099 * 1100 * \param p_pio Pointer to a PIO instance. 1101 * \param ul_mask Interrupt sources bit map. 1102 */ 1103 void pio_capture_enable_interrupt(Pio *p_pio, const uint32_t ul_mask) 1104 { 1105 p_pio->PIO_PCISR; 1106 p_pio->PIO_PCIER = ul_mask; 1107 } 1108 1109 /** 1110 * \brief Disable a given interrupt source of PIO capture. 1111 * 1112 * \param p_pio Pointer to a PIO instance. 1113 * \param ul_mask Interrupt sources bit map. 1114 */ 1115 void pio_capture_disable_interrupt(Pio *p_pio, const uint32_t ul_mask) 1116 { 1117 p_pio->PIO_PCIDR = ul_mask; 1118 } 1119 1120 /** 1121 * \brief Read PIO interrupt status of PIO capture. 1122 * 1123 * \param p_pio Pointer to a PIO instance. 1124 * 1125 * \return The interrupt status mask value. 1126 */ 1127 uint32_t pio_capture_get_interrupt_status(const Pio *p_pio) 1128 { 1129 return p_pio->PIO_PCISR; 1130 } 1131 1132 /** 1133 * \brief Read PIO interrupt mask of PIO capture. 1134 * 1135 * \param p_pio Pointer to a PIO instance. 1136 * 1137 * \return The interrupt mask value. 1138 */ 1139 uint32_t pio_capture_get_interrupt_mask(const Pio *p_pio) 1140 { 1141 return p_pio->PIO_PCIMR; 1142 } 1143 #if !(SAMV71 || SAMV70 || SAME70 || SAMS70) 1144 /** 1145 * \brief Get PDC registers base address. 1146 * 1147 * \param p_pio Pointer to an PIO peripheral. 1148 * 1149 * \return PIOA PDC register base address. 1150 */ 1151 Pdc *pio_capture_get_pdc_base(const Pio *p_pio) 1152 { 1153 UNUSED(p_pio); /* Stop warning */ 1154 return PDC_PIOA; 1155 } 1156 #endif 1157 #endif 1158 1159 #if (SAM4C || SAM4CP || SAM4CM || SAMG55) 1160 /** 1161 * \brief Set PIO IO drive. 1162 * 1163 * \param p_pio Pointer to an PIO peripheral. 1164 * \param ul_line Line index (0..31). 1165 * \param mode IO drive mode. 1166 */ 1167 void pio_set_io_drive(Pio *p_pio, uint32_t ul_line, 1168 enum pio_io_drive_mode mode) 1169 { 1170 p_pio->PIO_DRIVER &= ~(1 << ul_line); 1171 p_pio->PIO_DRIVER |= mode << ul_line; 1172 } 1173 #endif 1174 1175 #if (SAMV71 || SAMV70 || SAME70 || SAMS70) 1176 /** 1177 * \brief Enable PIO keypad controller. 1178 * 1179 * \param p_pio Pointer to a PIO instance. 1180 */ 1181 void pio_keypad_enable(Pio *p_pio) 1182 { 1183 p_pio->PIO_KER |= PIO_KER_KCE; 1184 } 1185 1186 /** 1187 * \brief Disable PIO keypad controller. 1188 * 1189 * \param p_pio Pointer to a PIO instance. 1190 */ 1191 void pio_keypad_disable(Pio *p_pio) 1192 { 1193 p_pio->PIO_KER &= (~PIO_KER_KCE); 1194 } 1195 1196 /** 1197 * \brief Set PIO keypad controller row number. 1198 * 1199 * \param p_pio Pointer to a PIO instance. 1200 * \param num Number of row of the keypad matrix. 1201 */ 1202 void pio_keypad_set_row_num(Pio *p_pio, uint8_t num) 1203 { 1204 p_pio->PIO_KRCR &= (~PIO_KRCR_NBR_Msk); 1205 p_pio->PIO_KRCR |= PIO_KRCR_NBR(num); 1206 } 1207 1208 /** 1209 * \brief Get PIO keypad controller row number. 1210 * 1211 * \param p_pio Pointer to a PIO instance. 1212 * 1213 * \return Number of row of the keypad matrix. 1214 */ 1215 uint8_t pio_keypad_get_row_num(const Pio *p_pio) 1216 { 1217 return ((p_pio->PIO_KRCR & PIO_KRCR_NBR_Msk) >> PIO_KRCR_NBR_Pos); 1218 } 1219 1220 /** 1221 * \brief Set PIO keypad controller column number. 1222 * 1223 * \param p_pio Pointer to a PIO instance. 1224 * \param num Number of column of the keypad matrix. 1225 */ 1226 void pio_keypad_set_column_num(Pio *p_pio, uint8_t num) 1227 { 1228 p_pio->PIO_KRCR &= (~PIO_KRCR_NBC_Msk); 1229 p_pio->PIO_KRCR |= PIO_KRCR_NBC(num); 1230 } 1231 1232 /** 1233 * \brief Get PIO keypad controller column number. 1234 * 1235 * \param p_pio Pointer to a PIO instance. 1236 * 1237 * \return Number of column of the keypad matrix. 1238 */ 1239 uint8_t pio_keypad_get_column_num(const Pio *p_pio) 1240 { 1241 return ((p_pio->PIO_KRCR & PIO_KRCR_NBC_Msk) >> PIO_KRCR_NBC_Pos); 1242 } 1243 1244 /** 1245 * \brief Set PIO keypad matrix debouncing value. 1246 * 1247 * \param p_pio Pointer to a PIO instance. 1248 * \param num Number of debouncing value. 1249 */ 1250 void pio_keypad_set_debouncing_value(Pio *p_pio, uint16_t value) 1251 { 1252 p_pio->PIO_KDR = PIO_KDR_DBC(value); 1253 } 1254 1255 /** 1256 * \brief Get PIO keypad matrix debouncing value. 1257 * 1258 * \param p_pio Pointer to a PIO instance. 1259 * 1260 * \return The keypad debouncing value. 1261 */ 1262 uint16_t pio_keypad_get_debouncing_value(const Pio *p_pio) 1263 { 1264 return ((p_pio->PIO_KDR & PIO_KDR_DBC_Msk) >> PIO_KDR_DBC_Pos); 1265 } 1266 1267 /** 1268 * \brief Enable the interrupt source of PIO keypad. 1269 * 1270 * \param p_pio Pointer to a PIO instance. 1271 * \param ul_mask Interrupt sources bit map. 1272 */ 1273 void pio_keypad_enable_interrupt(Pio *p_pio, uint32_t ul_mask) 1274 { 1275 p_pio->PIO_KIER = ul_mask; 1276 } 1277 1278 /** 1279 * \brief Disable the interrupt source of PIO keypad. 1280 * 1281 * \param p_pio Pointer to a PIO instance. 1282 * \param ul_mask Interrupt sources bit map. 1283 */ 1284 void pio_keypad_disable_interrupt(Pio *p_pio, uint32_t ul_mask) 1285 { 1286 p_pio->PIO_KIDR = ul_mask; 1287 } 1288 1289 /** 1290 * \brief Get interrupt mask of PIO keypad. 1291 * 1292 * \param p_pio Pointer to a PIO instance. 1293 * 1294 * \return The interrupt mask value. 1295 */ 1296 uint32_t pio_keypad_get_interrupt_mask(const Pio *p_pio) 1297 { 1298 return p_pio->PIO_KIMR; 1299 } 1300 1301 /** 1302 * \brief Get key press status of PIO keypad. 1303 * 1304 * \param p_pio Pointer to a PIO instance. 1305 * 1306 * \return The status of key press. 1307 * 0: No key press has been detected. 1308 * 1: At least one key press has been detected. 1309 */ 1310 uint32_t pio_keypad_get_press_status(const Pio *p_pio) 1311 { 1312 if (p_pio->PIO_KSR & PIO_KSR_KPR) { 1313 return 1; 1314 } else { 1315 return 0; 1316 } 1317 } 1318 1319 /** 1320 * \brief Get key release status of PIO keypad. 1321 * 1322 * \param p_pio Pointer to a PIO instance. 1323 * 1324 * \return The status of key release. 1325 * 0 No key release has been detected. 1326 * 1 At least one key release has been detected. 1327 */ 1328 uint32_t pio_keypad_get_release_status(const Pio *p_pio) 1329 { 1330 if (p_pio->PIO_KSR & PIO_KSR_KRL) { 1331 return 1; 1332 } else { 1333 return 0; 1334 } 1335 } 1336 1337 /** 1338 * \brief Get simultaneous key press number of PIO keypad. 1339 * 1340 * \param p_pio Pointer to a PIO instance. 1341 * 1342 * \return The number of simultaneous key press. 1343 */ 1344 uint8_t pio_keypad_get_simult_press_num(const Pio *p_pio) 1345 { 1346 return ((p_pio->PIO_KSR & PIO_KSR_NBKPR_Msk) >> PIO_KSR_NBKPR_Pos); 1347 } 1348 1349 /** 1350 * \brief Get simultaneous key release number of PIO keypad. 1351 * 1352 * \param p_pio Pointer to a PIO instance. 1353 * 1354 * \return The number of simultaneous key release. 1355 */ 1356 uint8_t pio_keypad_get_simult_release_num(const Pio *p_pio) 1357 { 1358 return ((p_pio->PIO_KSR & PIO_KSR_NBKRL_Msk) >> PIO_KSR_NBKRL_Pos); 1359 } 1360 1361 /** 1362 * \brief Get detected key press row index of PIO keypad. 1363 * 1364 * \param p_pio Pointer to a PIO instance. 1365 * \param queue The queue of key press row 1366 * 1367 * \return The index of detected key press row. 1368 */ 1369 uint8_t pio_keypad_get_press_row_index(const Pio *p_pio, uint8_t queue) 1370 { 1371 switch (queue) { 1372 case 0: 1373 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY0ROW_Msk) >> PIO_KKPR_KEY0ROW_Pos); 1374 case 1: 1375 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY1ROW_Msk) >> PIO_KKPR_KEY1ROW_Pos); 1376 case 2: 1377 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY2ROW_Msk) >> PIO_KKPR_KEY2ROW_Pos); 1378 case 3: 1379 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY3ROW_Msk) >> PIO_KKPR_KEY3ROW_Pos); 1380 default: 1381 return 0; 1382 } 1383 } 1384 1385 /** 1386 * \brief Get detected key press column index of PIO keypad. 1387 * 1388 * \param p_pio Pointer to a PIO instance. 1389 * \param queue The queue of key press column 1390 * 1391 * \return The index of detected key press column. 1392 */ 1393 uint8_t pio_keypad_get_press_column_index(const Pio *p_pio, uint8_t queue) 1394 { 1395 switch (queue) { 1396 case 0: 1397 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY0COL_Msk) >> PIO_KKPR_KEY0COL_Pos); 1398 case 1: 1399 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY1COL_Msk) >> PIO_KKPR_KEY1COL_Pos); 1400 case 2: 1401 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY2COL_Msk) >> PIO_KKPR_KEY2COL_Pos); 1402 case 3: 1403 return ((p_pio->PIO_KKPR & PIO_KKPR_KEY3COL_Msk) >> PIO_KKPR_KEY3COL_Pos); 1404 default: 1405 return 0; 1406 } 1407 } 1408 1409 /** 1410 * \brief Get detected key release row index of PIO keypad. 1411 * 1412 * \param p_pio Pointer to a PIO instance. 1413 * \param queue The queue of key release row 1414 * 1415 * \return The index of detected key release row. 1416 */ 1417 uint8_t pio_keypad_get_release_row_index(const Pio *p_pio, uint8_t queue) 1418 { 1419 switch (queue) { 1420 case 0: 1421 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY0ROW_Msk) >> PIO_KKRR_KEY0ROW_Pos); 1422 case 1: 1423 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY1ROW_Msk) >> PIO_KKRR_KEY1ROW_Pos); 1424 case 2: 1425 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY2ROW_Msk) >> PIO_KKRR_KEY2ROW_Pos); 1426 case 3: 1427 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY3ROW_Msk) >> PIO_KKRR_KEY3ROW_Pos); 1428 default: 1429 return 0; 1430 } 1431 } 1432 1433 /** 1434 * \brief Get detected key release column index of PIO keypad. 1435 * 1436 * \param p_pio Pointer to a PIO instance. 1437 * \param queue The queue of key release column 1438 * 1439 * \return The index of detected key release column. 1440 */ 1441 uint8_t pio_keypad_get_release_column_index(const Pio *p_pio, uint8_t queue) 1442 { 1443 switch (queue) { 1444 case 0: 1445 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY0COL_Msk) >> PIO_KKRR_KEY0COL_Pos); 1446 case 1: 1447 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY1COL_Msk) >> PIO_KKRR_KEY1COL_Pos); 1448 case 2: 1449 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY2COL_Msk) >> PIO_KKRR_KEY2COL_Pos); 1450 case 3: 1451 return ((p_pio->PIO_KKRR & PIO_KKRR_KEY3COL_Msk) >> PIO_KKRR_KEY3COL_Pos); 1452 default: 1453 return 0; 1454 } 1455 } 1456 1457 #endif 1458 1459 //@} 1460 1461