lpc17xx_gpioirq.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /*
  2. * Copyright (C) 2012 by Ole Reinhardt (ole.reinhardt@embedded-it.de)
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the copyright holders nor the names of
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * For additional information see http://www.ethernut.de/
  33. */
  34. /*
  35. * \verbatim
  36. * $Id: lpc177x_8x_gpio.c $
  37. * \endverbatim
  38. */
  39. #include <arch/cm3.h>
  40. #if defined(MCU_LPC176x)
  41. #include <arch/cm3/nxp/lpc176x.h>
  42. #elif defined(MCU_LPC177x_8x)
  43. #include <arch/cm3/nxp/lpc177x_8x.h>
  44. #elif defined(MCU_LPC407x_8x)
  45. #include <arch/cm3/nxp/lpc407x_8x.h>
  46. #else
  47. #warning "Unknown LPC family"
  48. #endif
  49. #include <dev/gpio.h>
  50. /*!
  51. * \brief PIO interrupt service.
  52. */
  53. static void Lpc17xxGpioIsr(void *arg)
  54. {
  55. GPIO_VECTOR *vct;
  56. uint32_t isr = LPC_GPIOINT->IntStatus;
  57. uint32_t port_status;
  58. if (isr & _BV(NUTGPIO_PORT0)) {
  59. port_status = LPC_GPIOINT->IO0IntStatR | LPC_GPIOINT->IO0IntStatF;
  60. vct = sig_GPIO0.ios_vector;
  61. while (port_status) {
  62. if ((port_status & 1) != 0 && vct->iov_handler) {
  63. (vct->iov_handler) (vct->iov_arg);
  64. }
  65. port_status >>= 1;
  66. vct++;
  67. }
  68. LPC_GPIOINT->IO0IntClr = 0xFFFFFFFF;
  69. }
  70. if (isr & _BV(NUTGPIO_PORT2)) {
  71. port_status = LPC_GPIOINT->IO2IntStatR | LPC_GPIOINT->IO2IntStatF;
  72. vct = sig_GPIO2.ios_vector;
  73. while (port_status) {
  74. if ((port_status & 1) != 0 && vct->iov_handler) {
  75. (vct->iov_handler) (vct->iov_arg);
  76. }
  77. port_status >>= 1;
  78. vct++;
  79. }
  80. LPC_GPIOINT->IO2IntClr = 0xFFFFFFFF;
  81. }
  82. }
  83. /*!
  84. * \brief PIO interrupt control.
  85. */
  86. static int Lpc17xxGpioCtrl(GPIO_SIGNAL * sig, int cmd, void *param, int bit)
  87. {
  88. int rc = 0;
  89. uint32_t *ival = (uint32_t *) param;
  90. switch (cmd) {
  91. case NUT_IRQCTL_STATUS:
  92. if (sig->enabled & _BV(bit)) {
  93. *ival = 1;
  94. } else {
  95. *ival = 0;
  96. }
  97. break;
  98. case NUT_IRQCTL_ENABLE:
  99. sig->enabled |= _BV(bit);
  100. break;
  101. case NUT_IRQCTL_DISABLE:
  102. sig->enabled &= ~_BV(bit);
  103. break;
  104. case NUT_IRQCTL_GETMODE:
  105. if ((sig->mode_rising_enabled & _BV(bit)) && ((sig->mode_falling_enabled & _BV(bit)) == 0)) {
  106. *ival = NUT_IRQMODE_RISINGEDGE;
  107. } else
  108. if (((sig->mode_rising_enabled & _BV(bit)) == 0) && (sig->mode_falling_enabled & _BV(bit))) {
  109. *ival = NUT_IRQMODE_FALLINGEDGE;
  110. } else
  111. if ((sig->mode_rising_enabled & _BV(bit)) && (sig->mode_falling_enabled & _BV(bit))) {
  112. *ival = NUT_IRQMODE_BOTHEDGE;
  113. } else {
  114. *ival = NUT_IRQMODE_NONE;
  115. }
  116. break;
  117. case NUT_IRQCTL_SETMODE:
  118. switch (*ival) {
  119. case NUT_IRQMODE_RISINGEDGE:
  120. sig->mode_rising_enabled |= _BV(bit);
  121. sig->mode_falling_enabled &= ~_BV(bit);
  122. break;
  123. case NUT_IRQMODE_FALLINGEDGE:
  124. sig->mode_rising_enabled &= ~_BV(bit);
  125. sig->mode_falling_enabled |= _BV(bit);
  126. break;
  127. case NUT_IRQMODE_BOTHEDGE:
  128. sig->mode_rising_enabled |= _BV(bit);
  129. sig->mode_falling_enabled |= _BV(bit);
  130. break;
  131. case NUT_IRQMODE_NONE:
  132. sig->mode_rising_enabled &= ~_BV(bit);
  133. sig->mode_falling_enabled &= ~_BV(bit);
  134. break;
  135. default:
  136. rc = -1;
  137. }
  138. break;
  139. default:
  140. rc = -1;
  141. break;
  142. }
  143. /* Enable / disable interrupt and set mode */
  144. switch (sig->ios_port) {
  145. case NUTGPIO_PORT0:
  146. LPC_GPIOINT->IO0IntEnR = sig->mode_rising_enabled & sig->enabled;
  147. LPC_GPIOINT->IO0IntEnF = sig->mode_falling_enabled & sig->enabled;
  148. break;
  149. case NUTGPIO_PORT2:
  150. LPC_GPIOINT->IO2IntEnR = sig->mode_rising_enabled & sig->enabled;
  151. LPC_GPIOINT->IO2IntEnF = sig->mode_falling_enabled & sig->enabled;
  152. break;
  153. default:
  154. rc = -1;
  155. break;
  156. }
  157. return rc;
  158. }
  159. GPIO_SIGNAL sig_GPIO0 = {
  160. NUTGPIO_PORT0, /* ios_port */
  161. Lpc17xxGpioIsr, /* ios_handler */
  162. Lpc17xxGpioCtrl, /* ios_ctl */
  163. NULL, /* ios_vector */
  164. 0, /* mode_rising_enabled */
  165. 0 /* mode_falling_enabled */
  166. };
  167. GPIO_SIGNAL sig_GPIO2 = {
  168. NUTGPIO_PORT2, /* ios_port */
  169. Lpc17xxGpioIsr, /* ios_handler */
  170. Lpc17xxGpioCtrl, /* ios_ctl */
  171. NULL, /* ios_vector */
  172. 0, /* mode_rising_enabled */
  173. 0 /* mode_falling_enabled */
  174. };