Subversion Repositories freemyipod

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 theseven 1
//
2
//
3
//    Copyright 2010 TheSeven
4
//
5
//
427 farthen 6
//    This file is part of emCORE.
14 theseven 7
//
427 farthen 8
//    emCORE is free software: you can redistribute it and/or
14 theseven 9
//    modify it under the terms of the GNU General Public License as
10
//    published by the Free Software Foundation, either version 2 of the
11
//    License, or (at your option) any later version.
12
//
427 farthen 13
//    emCORE is distributed in the hope that it will be useful,
14 theseven 14
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16
//    See the GNU General Public License for more details.
17
//
18
//    You should have received a copy of the GNU General Public License along
427 farthen 19
//    with emCORE.  If not, see <http://www.gnu.org/licenses/>.
14 theseven 20
//
21
//
22
 
23
 
24
#include "global.h"
25
#include "panic.h"
232 theseven 26
#include "interrupt.h"
14 theseven 27
#include "s5l8701.h"
28
 
29
 
30
#define default_interrupt(name) extern __attribute__((weak,alias("unhandled_irq"))) void name(void)
31
 
32
default_interrupt(EXT0);
33
default_interrupt(EXT1);
34
default_interrupt(EXT2);
35
default_interrupt(EINT_VBUS);
36
default_interrupt(EINTG);
15 theseven 37
default_interrupt(INT_WDT);
14 theseven 38
default_interrupt(INT_TIMERA);
39
default_interrupt(INT_TIMERB);
40
default_interrupt(INT_TIMERC);
41
default_interrupt(INT_TIMERD);
15 theseven 42
default_interrupt(INT_DMA0);
43
default_interrupt(INT_DMA1);
44
default_interrupt(INT_DMA2);
45
default_interrupt(INT_DMA3);
46
default_interrupt(INT_DMA4);
47
default_interrupt(INT_DMA5);
48
default_interrupt(INT_DMA6);
49
default_interrupt(INT_DMA7);
50
default_interrupt(INT_DMA8);
14 theseven 51
default_interrupt(INT_ALARM_RTC);
52
default_interrupt(INT_PRI_RTC);
53
default_interrupt(RESERVED1);
54
default_interrupt(INT_UART);
55
default_interrupt(INT_USB_HOST);
56
default_interrupt(INT_USB_FUNC);
57
default_interrupt(INT_LCDC_0);
58
default_interrupt(INT_LCDC_1);
59
default_interrupt(INT_ECC);
60
default_interrupt(INT_CALM);
61
default_interrupt(INT_ATA);
62
default_interrupt(INT_UART0);
63
default_interrupt(INT_SPDIF_OUT);
64
default_interrupt(INT_SDCI);
65
default_interrupt(INT_LCD);
132 theseven 66
default_interrupt(INT_WHEEL);
14 theseven 67
default_interrupt(INT_IIC);
68
default_interrupt(RESERVED2);
69
default_interrupt(INT_MSTICK);
70
default_interrupt(INT_ADC_WAKEUP);
71
default_interrupt(INT_ADC);
72
default_interrupt(INT_UNK1);
73
default_interrupt(INT_UNK2);
74
default_interrupt(INT_UNK3);
75
 
76
 
77
void unhandled_irq(void)
78
{
79
    panicf(PANIC_FATAL, "Unhandled IRQ %d!", INTOFFSET);
80
}
81
 
85 theseven 82
static void (* timervector[])(void) IDATA_ATTR =
15 theseven 83
{
84
    INT_TIMERA,INT_TIMERB,INT_TIMERC,INT_TIMERD
85
};
86
 
87
void INT_TIMER(void) ICODE_ATTR;
14 theseven 88
void INT_TIMER()
89
{
282 theseven 90
    if (TACON & (TACON >> 4) & 0x7000) timervector[0]();
91
    if (TBCON & (TBCON >> 4) & 0x7000) timervector[1]();
92
    if (TCCON & (TCCON >> 4) & 0x7000) timervector[2]();
93
    if (TDCON & (TDCON >> 4) & 0x7000) timervector[3]();
14 theseven 94
}
95
 
258 theseven 96
static void (* dmavector[])(void) IDATA_ATTR =
14 theseven 97
{
15 theseven 98
    INT_DMA0,INT_DMA1,INT_DMA2,INT_DMA3,INT_DMA4,INT_DMA5,INT_DMA6,INT_DMA7,INT_DMA8
99
};
100
 
101
void INT_DMA(void) ICODE_ATTR;
102
void INT_DMA()
103
{
104
    uint32_t dmaallst = DMAALLST;
105
    uint32_t dmaallst2 = DMAALLST2;
106
    if (dmaallst & (DMACON0 >> 16) & 3) dmavector[0]();
107
    if (dmaallst & (DMACON1 >> 12) & 0x30) dmavector[1]();
108
    if (dmaallst & (DMACON2 >> 8) & 0x300) dmavector[2]();
109
    if (dmaallst & (DMACON3 >> 4) & 0x3000) dmavector[3]();
110
    if (dmaallst2 & (DMACON4 >> 16) & 3) dmavector[4]();
111
    if (dmaallst2 & (DMACON5 >> 12) & 0x30) dmavector[5]();
112
    if (dmaallst2 & (DMACON6 >> 8) & 0x300) dmavector[6]();
113
    if (dmaallst2 & (DMACON7 >> 4) & 0x3000) dmavector[7]();
114
    if (dmaallst2 & DMACON8 & 0x30000) dmavector[8]();
115
}
116
 
85 theseven 117
static void (* irqvector[])(void) IDATA_ATTR =
15 theseven 118
{
14 theseven 119
    EXT0,EXT1,EXT2,EINT_VBUS,EINTG,INT_TIMER,INT_WDT,INT_UNK1,
120
    INT_UNK2,INT_UNK3,INT_DMA,INT_ALARM_RTC,INT_PRI_RTC,RESERVED1,INT_UART,INT_USB_HOST,
121
    INT_USB_FUNC,INT_LCDC_0,INT_LCDC_1,INT_CALM,INT_ATA,INT_UART0,INT_SPDIF_OUT,INT_ECC,
132 theseven 122
    INT_SDCI,INT_LCD,INT_WHEEL,INT_IIC,RESERVED2,INT_MSTICK,INT_ADC_WAKEUP,INT_ADC
14 theseven 123
};
124
 
125
void irqhandler(void)
126
{
127
    int irq_no = INTOFFSET;
128
    irqvector[irq_no]();
129
    SRCPND = (1 << irq_no);
130
    INTPND = INTPND;
15 theseven 131
}
132
 
85 theseven 133
void interrupt_enable(int irq, bool state)
134
{
387 theseven 135
    uint32_t mode = enter_critical_section();
252 theseven 136
    if (state) INTMSK |= 1 << irq;
137
    else INTMSK &= ~(1 << irq);
387 theseven 138
    leave_critical_section(mode);
85 theseven 139
}
140
 
141
void interrupt_set_handler(int irq, void* handler)
142
{
252 theseven 143
    if (handler) irqvector[irq] = handler;
144
    else irqvector[irq] = unhandled_irq;
85 theseven 145
}
146
 
147
void int_timer_set_handler(int timer, void* handler)
148
{
252 theseven 149
    if (handler) timervector[timer] = handler;
150
    else timervector[timer] = unhandled_irq;
85 theseven 151
}
152
 
258 theseven 153
void int_dma_set_handler(int channel, void* handler)
154
{
155
    if (handler) dmavector[channel] = handler;
156
    else dmavector[channel] = unhandled_irq;
157
}
158
 
15 theseven 159
void interrupt_init(void)
160
{
85 theseven 161
    INTMSK = (1 << IRQ_TIMER) | (1 << IRQ_DMA);
15 theseven 162
}
219 theseven 163
 
164
void interrupt_shutdown(void)
165
{
166
    INTMSK = 0;
167
}