ARM7 based quadrocopter
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.

157 lines
5.0KB

  1. /***************************************************************************
  2. * sam7fc - System Interrupt Dispatcher *
  3. * *
  4. * Copyright (C) 01/2008 by Olaf Rempel *
  5. * razzor@kopf-tisch.de *
  6. * *
  7. * This program is free software; you can redistribute it and/or modify *
  8. * it under the terms of the GNU General Public License as published by *
  9. * the Free Software Foundation; version 2 of the License *
  10. * *
  11. * This program is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * You should have received a copy of the GNU General Public License *
  17. * along with this program; if not, write to the *
  18. * Free Software Foundation, Inc., *
  19. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  20. ***************************************************************************/
  21. #include "AT91SAM7S256.h"
  22. #include "at91_sysc.h"
  23. #include "board.h"
  24. static SYSCISR *sysc_isrs[AT91_SYSIRQ_COUNT];
  25. struct _irq_regs {
  26. AT91_REG *mask_register;
  27. uint32_t mask;
  28. AT91_REG *status_register;
  29. uint32_t status;
  30. };
  31. /* same IDs as sysc_isrs enum! */
  32. static const struct _irq_regs irq_regs[] = {
  33. /*
  34. * PIT (Periodic Intervall Timer)
  35. * ISR must read AT91C_PITC_PIVR to clear interrupt
  36. * - PITIEN (Periodic Intervall Timer Interrupt Enable)
  37. */
  38. { AT91C_PITC_PIMR, AT91C_PITC_PITIEN,
  39. AT91C_PITC_PISR, AT91C_PITC_PITS
  40. },
  41. /*
  42. * DBGU (Debug Unit)
  43. * TODO: must use AT91C_DBGU_IDR to fault disable interrupt
  44. * - 12 Interrupt sources
  45. */
  46. { AT91C_DBGU_IMR, (AT91C_US_RXRDY | AT91C_US_TXRDY |
  47. AT91C_US_ENDRX | AT91C_US_ENDTX |
  48. AT91C_US_OVRE | AT91C_US_FRAME |
  49. AT91C_US_PARE | AT91C_US_TXEMPTY |
  50. AT91C_US_TXBUFE | AT91C_US_RXBUFF |
  51. AT91C_US_COMM_TX | AT91C_US_COMM_RX),
  52. AT91C_DBGU_CSR, (AT91C_US_RXRDY | AT91C_US_TXRDY |
  53. AT91C_US_ENDRX | AT91C_US_ENDTX |
  54. AT91C_US_OVRE | AT91C_US_FRAME |
  55. AT91C_US_PARE | AT91C_US_TXEMPTY |
  56. AT91C_US_TXBUFE | AT91C_US_RXBUFF |
  57. AT91C_US_COMM_TX | AT91C_US_COMM_RX)
  58. },
  59. /*
  60. * EFC (Embedded Flash Controller / Memory Controller)
  61. */
  62. { AT91C_MC_FMR, (AT91C_MC_FRDY | AT91C_MC_LOCKE | AT91C_MC_PROGE),
  63. AT91C_MC_FSR, (AT91C_MC_FRDY | AT91C_MC_LOCKE | AT91C_MC_PROGE)
  64. },
  65. /*
  66. * WDT (Watchdog Timer)
  67. * WDMR can be written only once (no fault disable)
  68. * - WDFIEN (Watchdog Fault Interrupt Enable)
  69. */
  70. { AT91C_WDTC_WDMR, AT91C_WDTC_WDFIEN,
  71. AT91C_WDTC_WDSR, (AT91C_WDTC_WDUNF | AT91C_WDTC_WDERR)
  72. },
  73. /*
  74. * RTT (Real-Time Timer)
  75. * Interrupts must be disabled during ISR?!
  76. * - ALMIEN (Alarm Interrupt Enable)
  77. * - RTTCINCIEN (Real-Time Timer Increment Interrupt Enable)
  78. */
  79. { AT91C_RTTC_RTMR, (AT91C_RTTC_ALMIEN | AT91C_RTTC_RTTINCIEN),
  80. AT91C_RTTC_RTSR, (AT91C_RTTC_ALMS | AT91C_RTTC_RTTINC)
  81. },
  82. /*
  83. * RSTC (Reset Controller)
  84. * - AT91C_RSTC_URSTIEN (User Reset Interrupt Enable)
  85. * - AT91C_RSTC_BODIEN (Brownout Detection Interrupt Enable)
  86. */
  87. { AT91C_RSTC_RMR, (AT91C_RSTC_URSTIEN | AT91C_RSTC_BODIEN),
  88. AT91C_RSTC_RSR, (AT91C_RSTC_URSTS | AT91C_RSTC_BODSTS)
  89. },
  90. /*
  91. * PMC (Power Managment Controller)
  92. * TODO: must use AT91C_PMC_IDR to fault disable interrupt
  93. * - 6 Interrupt sources
  94. */
  95. { AT91C_PMC_IMR, (AT91C_PMC_MOSCS | AT91C_PMC_LOCK |
  96. AT91C_PMC_MCKRDY | AT91C_PMC_PCK0RDY |
  97. AT91C_PMC_PCK1RDY | AT91C_PMC_PCK2RDY),
  98. AT91C_PMC_SR, (AT91C_PMC_MOSCS | AT91C_PMC_LOCK |
  99. AT91C_PMC_MCKRDY | AT91C_PMC_PCK0RDY |
  100. AT91C_PMC_PCK1RDY | AT91C_PMC_PCK2RDY)
  101. },
  102. };
  103. /* check Interrupts from internal hardware */
  104. static void at91_sysc_isr(void)
  105. {
  106. uint32_t id;
  107. for (id = 0; id < AT91_SYSIRQ_COUNT; id++) {
  108. /* check if interrups are enabled */
  109. if (*(irq_regs[id].mask_register) & irq_regs[id].mask) {
  110. /* check if interrupts are active */
  111. uint32_t status = *(irq_regs[id].status_register);
  112. if (status & irq_regs[id].status) {
  113. /* execute handler */
  114. if (sysc_isrs[id]) {
  115. sysc_isrs[id](status);
  116. } else {
  117. /* disable interrupts */
  118. *(irq_regs[id].mask_register) &= ~irq_regs[id].mask;
  119. }
  120. }
  121. }
  122. }
  123. }
  124. void at91_sysc_init(void)
  125. {
  126. /* high priority, level triggered, own vector */
  127. AT91S_AIC *aic = AT91C_BASE_AIC;
  128. aic->AIC_SMR[AT91C_ID_SYS] = IRQPRIO_SYSC |
  129. AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL;
  130. aic->AIC_SVR[AT91C_ID_SYS] = (uint32_t)at91_sysc_isr;
  131. aic->AIC_IECR = (1<<AT91C_ID_SYS);
  132. }
  133. void sysc_register_isr(enum syscirqs irq, SYSCISR *isr)
  134. {
  135. if (irq >= AT91_SYSIRQ_COUNT)
  136. return;
  137. sysc_isrs[irq] = isr;
  138. }