| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071 |
- #include "Interrupts.h"
- #include "CXfb.h"
- #define INTERRUPTS Nspire::Interrupts
- #define INTERRUPT_CONTROLLER 0xDC000000
- volatile uint32_t *irq_status = (uint32_t *) (INTERRUPT_CONTROLLER + 0x0);
- volatile uint32_t *interrupt_select = (uint32_t *) (INTERRUPT_CONTROLLER + 0xC);
- uint32_t interrupt_select_bkp;
- volatile uint32_t *interrupt_enable = (uint32_t *) (INTERRUPT_CONTROLLER + 0x10);
- volatile uint32_t *interrupt_enable_clear = (uint32_t *) (INTERRUPT_CONTROLLER + 0x14);
- uint32_t interrupt_enable_bkp;
- volatile uint32_t *interrupt_pointer = (uint32_t *) 0x38;
- uint32_t interrupt_pointer_bkp;
- // Interrupt source 21 is the LCD
- #define INTERRUPT_MASK (1 << 21)
- static bool is_on = false;
- void INTERRUPTS::init()
- {
- is_on = true;
- interrupt_select_bkp = *interrupt_select;
- *interrupt_select = 0; // All IRQ for now
- interrupt_enable_bkp = *interrupt_enable;
- *interrupt_enable = INTERRUPT_MASK;
- *interrupt_enable_clear = ~(INTERRUPT_MASK);
- interrupt_pointer_bkp = *interrupt_pointer;
- *interrupt_pointer = (uint32_t) &isr;
- // Enable IRQ in the CPU
- asm(
- "mrs r1, cpsr \n\t"
- "bic r1, r1, #0x80 \n\t"
- "msr cpsr, r1"
- :
- :
- : "r1");
- }
- void INTERRUPTS::off()
- {
- if(!is_on) return;
- is_on = false;
- // Disable IRQ in the CPU
- asm(
- "mrs r1, cpsr \n\t"
- "orr r1, r1, #0x80 \n\t"
- "msr cpsr, r1"
- :
- :
- : "r1");
- *interrupt_select = interrupt_select_bkp;
- *interrupt_enable = interrupt_enable_bkp;
- *interrupt_enable_clear = ~(interrupt_enable_bkp);
- *interrupt_pointer = interrupt_pointer_bkp;
- }
- void __attribute__((interrupt("IRQ"))) INTERRUPTS::isr()
- {
- if (*irq_status & (1 << 21))
- Nspire::CXfb::vsync_isr();
- }
|