phaser-ags / firmware /hal /interrupt.c
SNAPKITTYWEST's picture
October 2026 main drop: mirror from GitHub
829b19c verified
Raw History Blame Contribute Delete
2 kB
/*
* HAL — Interrupt Controller driver for OMAP3530 AINTC
*/
#include "interrupt.h"
static irq_handler_t irq_handlers[INTC_NUM_IRQS];
void intc_init(void) {
hw_reg32_t base = (hw_reg32_t)INTC_BASE;
/* Soft reset */
reg_write32(base + INTC_SYSCONFIG, 0x02);
delay_cycles(100);
while (!(reg_read32(base + INTC_SYSSTATUS) & 0x01))
;
/* Mask all interrupts */
for (int i = 0; i < INTC_NUM_MIR_REGS; i++) {
reg_write32(base + INTC_MIR_SET(i), 0xFFFFFFFF);
}
/* Clear all handler pointers */
for (int i = 0; i < INTC_NUM_IRQS; i++) {
irq_handlers[i] = (irq_handler_t)0;
}
/* No priority threshold (all priorities pass) */
reg_write32(base + INTC_THRESHOLD, 0x00);
/* Enable protection (only privileged access) */
reg_write32(base + INTC_PROTECTION, 0x01);
}
void intc_enable_irq(uint8_t irq_num) {
hw_reg32_t base = (hw_reg32_t)INTC_BASE;
int bank = irq_num / 32;
int bit = irq_num % 32;
reg_write32(base + INTC_MIR_CLEAR(bank), (1UL << bit));
}
void intc_disable_irq(uint8_t irq_num) {
hw_reg32_t base = (hw_reg32_t)INTC_BASE;
int bank = irq_num / 32;
int bit = irq_num % 32;
reg_write32(base + INTC_MIR_SET(bank), (1UL << bit));
}
void intc_set_irq_handler(uint8_t irq_num, irq_handler_t handler) {
if (irq_num < INTC_NUM_IRQS)
irq_handlers[irq_num] = handler;
}
uint8_t intc_get_active_irq(void) {
hw_reg32_t base = (hw_reg32_t)INTC_BASE;
return (uint8_t)(reg_read32(base + INTC_SIR_IRQ) & 0x7F);
}
void intc_ack_irq(void) {
hw_reg32_t base = (hw_reg32_t)INTC_BASE;
reg_write32(base + INTC_CONTROL, 0x01);
}
void intc_enable(void) {
__asm__ volatile("cpsie i" ::: "memory");
}
void intc_disable(void) {
__asm__ volatile("cpsid i" ::: "memory");
}
void intc_handle_irq(void) {
uint8_t irq = intc_get_active_irq();
if (irq < INTC_NUM_IRQS && irq_handlers[irq]) {
irq_handlers[irq](irq);
}
intc_ack_irq();
}