You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

81 lines
3.9 KiB

  1. /* Copyright 2021 QMK
  2. *
  3. * This program is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 3 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #pragma once
  17. #include "stdint.h"
  18. #include "samd51j18a.h"
  19. #include "pin_defs.h"
  20. typedef uint8_t pin_t;
  21. #define SAMD_PORT(pin) (((pin)&0x20) >> 5)
  22. #define SAMD_PIN(pin) ((pin)&0x1f)
  23. #define SAMD_PIN_MASK(pin) (1 << ((pin)&0x1f))
  24. #define setPinInput(pin) \
  25. do { \
  26. PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.INEN = 1; \
  27. PORT->Group[SAMD_PORT(pin)].DIRCLR.reg = SAMD_PIN_MASK(pin); \
  28. } while (0)
  29. #define setPinInputHigh(pin) \
  30. do { \
  31. PORT->Group[SAMD_PORT(pin)].DIRCLR.reg = SAMD_PIN_MASK(pin); \
  32. PORT->Group[SAMD_PORT(pin)].OUTSET.reg = SAMD_PIN_MASK(pin); \
  33. PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.INEN = 1; \
  34. PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.PULLEN = 1; \
  35. } while (0)
  36. #define setPinInputLow(pin) \
  37. do { \
  38. PORT->Group[SAMD_PORT(pin)].DIRCLR.reg = SAMD_PIN_MASK(pin); \
  39. PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \
  40. PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.INEN = 1; \
  41. PORT->Group[SAMD_PORT(pin)].PINCFG[SAMD_PIN(pin)].bit.PULLEN = 1; \
  42. } while (0)
  43. #define setPinOutputPushPull(pin) \
  44. do { \
  45. PORT->Group[SAMD_PORT(pin)].DIRSET.reg = SAMD_PIN_MASK(pin); \
  46. PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \
  47. } while (0)
  48. #define setPinOutputOpenDrain(pin) _Static_assert(0, "arm_atsam platform does not implement an open-drain output")
  49. #define setPinOutput(pin) setPinOutputPushPull(pin)
  50. #define writePinHigh(pin) \
  51. do { \
  52. PORT->Group[SAMD_PORT(pin)].OUTSET.reg = SAMD_PIN_MASK(pin); \
  53. } while (0)
  54. #define writePinLow(pin) \
  55. do { \
  56. PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \
  57. } while (0)
  58. #define writePin(pin, level) \
  59. do { \
  60. if (level) \
  61. PORT->Group[SAMD_PORT(pin)].OUTSET.reg = SAMD_PIN_MASK(pin); \
  62. else \
  63. PORT->Group[SAMD_PORT(pin)].OUTCLR.reg = SAMD_PIN_MASK(pin); \
  64. } while (0)
  65. #define readPin(pin) ((PORT->Group[SAMD_PORT(pin)].IN.reg & SAMD_PIN_MASK(pin)) != 0)
  66. #define togglePin(pin) (PORT->Group[SAMD_PORT(pin)].OUTTGL.reg = SAMD_PIN_MASK(pin))