Interrupts.cpp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #include "Interrupts.h"
  2. #include "CXfb.h"
  3. #define INTERRUPTS Nspire::Interrupts
  4. #define INTERRUPT_CONTROLLER 0xDC000000
  5. volatile uint32_t *irq_status = (uint32_t *) (INTERRUPT_CONTROLLER + 0x0);
  6. volatile uint32_t *interrupt_select = (uint32_t *) (INTERRUPT_CONTROLLER + 0xC);
  7. uint32_t interrupt_select_bkp;
  8. volatile uint32_t *interrupt_enable = (uint32_t *) (INTERRUPT_CONTROLLER + 0x10);
  9. volatile uint32_t *interrupt_enable_clear = (uint32_t *) (INTERRUPT_CONTROLLER + 0x14);
  10. uint32_t interrupt_enable_bkp;
  11. volatile uint32_t *interrupt_pointer = (uint32_t *) 0x38;
  12. uint32_t interrupt_pointer_bkp;
  13. // Interrupt source 21 is the LCD
  14. #define INTERRUPT_MASK (1 << 21)
  15. void INTERRUPTS::init()
  16. {
  17. interrupt_select_bkp = *interrupt_select;
  18. *interrupt_select = 0; // All IRQ for now
  19. interrupt_enable_bkp = *interrupt_enable;
  20. *interrupt_enable = INTERRUPT_MASK;
  21. *interrupt_enable_clear = ~(INTERRUPT_MASK);
  22. interrupt_pointer_bkp = *interrupt_pointer;
  23. *interrupt_pointer = (uint32_t) &isr;
  24. // Enable IRQ in the CPU
  25. asm(
  26. "mrs r1, cpsr \n\t"
  27. "bic r1, r1, #0x80 \n\t"
  28. "msr cpsr, r1"
  29. :
  30. :
  31. : "r1");
  32. }
  33. void INTERRUPTS::off()
  34. {
  35. // Disable IRQ in the CPU
  36. asm(
  37. "mrs r1, cpsr \n\t"
  38. "orr r1, r1, #0x80 \n\t"
  39. "msr cpsr, r1"
  40. :
  41. :
  42. : "r1");
  43. *interrupt_select = interrupt_select_bkp;
  44. *interrupt_enable = interrupt_enable_bkp;
  45. *interrupt_enable_clear = ~(interrupt_enable_bkp);
  46. *interrupt_pointer = interrupt_pointer_bkp;
  47. }
  48. void __attribute__((interrupt("IRQ"))) INTERRUPTS::isr()
  49. {
  50. if (*irq_status & (1 << 21))
  51. Nspire::CXfb::vsync_isr();
  52. }