9 changed files with 272 additions and 84 deletions
			
			
		| @ -0,0 +1,84 @@ | ||||
| #include "interrupt.h" | ||||
| 
 | ||||
| #define VICBASE	0xFFFFF000 | ||||
| 
 | ||||
| #define IRQStatus	0x00 | ||||
| #define FIQStatus	0x04 | ||||
| #define RawIntr		0x08 | ||||
| #define IntSelect	0x0c | ||||
| #define IntEnable	0x10 | ||||
| #define IntEnClr	0x14 | ||||
| #define SoftInt		0x18 | ||||
| #define SoftIntClear	0x1c | ||||
| #define Protection	0x20 | ||||
| #define VectAddr	0x30 | ||||
| #define DefVectAddr	0x34 | ||||
| #define VectAddr0	0x100 | ||||
| #define VectAddr1	0x104 | ||||
| #define VectAddr2	0x108 | ||||
| #define VectAddr3	0x10c | ||||
| #define VectAddr4	0x110 | ||||
| #define VectAddr5	0x114 | ||||
| #define VectAddr6	0x118 | ||||
| #define VectAddr7	0x11c | ||||
| #define VectAddr8	0x120 | ||||
| #define VectAddr9	0x124 | ||||
| #define VectAddr10	0x128 | ||||
| #define VectAddr11	0x12c | ||||
| #define VectAddr12	0x130 | ||||
| #define VectAddr13	0x134 | ||||
| #define VectAddr14	0x138 | ||||
| #define VectAddr15	0x13c | ||||
| #define VectCntl0	0x200 | ||||
| #define VectCntl1	0x204 | ||||
| #define VectCntl2	0x208 | ||||
| #define VectCntl3	0x20c | ||||
| #define VectCntl4	0x210 | ||||
| #define VectCntl5	0x214 | ||||
| #define VectCntl6	0x218 | ||||
| #define VectCntl7	0x21c | ||||
| #define VectCntl8	0x220 | ||||
| #define VectCntl9	0x224 | ||||
| #define VectCntl10	0x228 | ||||
| #define VectCntl11	0x22c | ||||
| #define VectCntl12	0x230 | ||||
| #define VectCntl13	0x234 | ||||
| #define VectCntl14	0x238 | ||||
| #define VectCntl15	0x23c | ||||
| 
 | ||||
| #define VWREG(x) (((volatile unsigned int *)VICBASE)[(x)/sizeof(unsigned int)]) | ||||
| #define VADDRREG(x) VWREG(VectAddr0 + (x) * 4) | ||||
| #define VCNTLREG(x) VWREG(VectCntl0 + (x) * 4) | ||||
| 
 | ||||
| #define IRQslot_en (1<<5) | ||||
| 
 | ||||
| 
 | ||||
| void __attribute__((interrupt("IRQ"))) interrupt_default_handler(void); | ||||
| 
 | ||||
| 
 | ||||
| void init_interrupt(void) | ||||
| { | ||||
| 	VWREG(IntSelect) = 0; | ||||
| 	VWREG(IntEnable) = 0; | ||||
| 	VWREG(DefVectAddr) = (unsigned int) &interrupt_default_handler; | ||||
| } | ||||
| 
 | ||||
| void __attribute__((interrupt("IRQ"))) interrupt_default_handler(void) | ||||
| { | ||||
| 	/* Do nothing. Assume that if there is a genuine interrupt
 | ||||
| 	 * request that it will be asserted again soon. | ||||
| 	 */ | ||||
| 	interrupt_clear(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Call as interrupt_register(SOURCE, fn) */ | ||||
| 
 | ||||
| void interrupt_register_code(unsigned int source, unsigned int priority, | ||||
| 			     void(*handler)(void)) | ||||
| { | ||||
| 	VADDRREG(priority) = (unsigned int) handler; | ||||
| 	VCNTLREG(priority) = source | IRQslot_en; | ||||
| 	VWREG(IntEnable) |= (1<<source); | ||||
| } | ||||
| 
 | ||||
| @ -0,0 +1,46 @@ | ||||
| #ifndef __INTERRUPT_H | ||||
| #define __INTERRUPT_H | ||||
| 
 | ||||
| #define VICVectAddr (*(volatile unsigned int *)0xFFFFF030) | ||||
| 
 | ||||
| #define I_WDT		0 | ||||
| 
 | ||||
| #define I_ARMCore0	2 | ||||
| #define I_ARMCore1	3 | ||||
| #define I_TIMER0	4 | ||||
| #define I_TIMER1	5 | ||||
| #define I_UART0		6 | ||||
| #define I_UART1		7 | ||||
| 
 | ||||
| #define I_I2C0		9 | ||||
| #define I_SPI0		10 | ||||
| #define I_SPI1		11 | ||||
| #define I_SSP		11 | ||||
| #define I_PLL		12 | ||||
| #define I_RTC		13 | ||||
| #define I_EINT0		14 | ||||
| #define I_EINT1		15 | ||||
| #define I_EINT2		16 | ||||
| 
 | ||||
| #define I_AD0		18 | ||||
| #define I_I2C1		19 | ||||
| 
 | ||||
| #define I_TIMER2	26 | ||||
| #define I_TIMER3	27 | ||||
| 
 | ||||
| /* Assign interrupt priorities here to avoid clashes */ | ||||
| 
 | ||||
| #define I_PRIORITY_I2C0		0 | ||||
| #define I_PRIORITY_UART0	1 | ||||
| #define I_PRIORITY_TIMER0	2 | ||||
| 
 | ||||
| #define interrupt_clear() do { VICVectAddr = 0xff; } while (0) | ||||
| 
 | ||||
| void init_interrupt(void); | ||||
| void interrupt_register_code(unsigned int source, unsigned int priority, | ||||
| 			void(*handler)(void)); | ||||
| 
 | ||||
| #define interrupt_register(x, fn) \ | ||||
| 	interrupt_register_code(I_##x, I_PRIORITY_##x, fn) | ||||
| 
 | ||||
| #endif /* __INTERRUPT_H */ | ||||
| @ -0,0 +1,79 @@ | ||||
| #include "uart.h" | ||||
| 
 | ||||
| #define UARTBASE 0xE000C000 | ||||
| 
 | ||||
| #define RBR 0x00 | ||||
| #define THR 0x00 | ||||
| #define DLL 0x00 | ||||
| #define DLM 0x04 | ||||
| #define IER 0x04 | ||||
| #define IIR 0x08 | ||||
| #define FCR 0x08 | ||||
| 
 | ||||
| #define LCR 0x0c | ||||
| #define LSR 0x14 | ||||
| #define SCR 0x1c | ||||
| #define ACR 0x20 | ||||
| #define FDR 0x28 | ||||
| #define TER 0x30 | ||||
| 
 | ||||
| #define UREG(x) (((volatile unsigned char *)UARTBASE)[x]) | ||||
| 
 | ||||
| #define U0THRE ((UREG(LSR) & (1<<5))) /* UART0 transmitter holding register is empty */ | ||||
| #define U0DR ((UREG(LSR) & (1<<0))) /* UART0 data ready */ | ||||
| 
 | ||||
| void init_uart(void) | ||||
| { | ||||
| 	UREG(FDR) = 0x10; /* DivAddVal = 0, MulVal = 1 */ | ||||
| 
 | ||||
| 	UREG(LCR) = 0x80; | ||||
| 	UREG(DLM) = 0x00; | ||||
| 	UREG(DLL) = 0x08; /* 14745600 / (16*115200) */ | ||||
| 	UREG(LCR) = 0x13; | ||||
| 	UREG(FCR) = 0x07; | ||||
| } | ||||
| 
 | ||||
| void putch(char c) { | ||||
| 	while (!U0THRE); | ||||
| 	UREG(THR) = c; | ||||
| } | ||||
| 
 | ||||
| void putstr(char *s) { | ||||
| 	while (*s) putch(*s++); | ||||
| } | ||||
| 
 | ||||
| void putint(unsigned int n) { | ||||
| 	char s[11]; | ||||
| 	int i; | ||||
| 
 | ||||
| 	i = 10; | ||||
| 	s[i] = '\0'; | ||||
| 
 | ||||
| 	do { | ||||
| 		s[--i] = n % 10 + '0'; | ||||
| 	} while ((n /= 10) > 0); | ||||
| 
 | ||||
| 	putstr(s+i); | ||||
| } | ||||
| 
 | ||||
| void puthex(unsigned int n) { | ||||
| 	char s[9]; | ||||
| 	int i; | ||||
| 
 | ||||
| 	i = 8; | ||||
| 	s[i] = '\0'; | ||||
| 
 | ||||
| 	do { | ||||
| 		int x = n % 16; | ||||
| 		if (x > 9) | ||||
| 			x += 'A' - '0' - 10; | ||||
| 		s[--i] = x + '0'; | ||||
| 	} while ((n /= 16) > 0); | ||||
| 
 | ||||
| 	putstr(s+i); | ||||
| } | ||||
| 
 | ||||
| char getch(void) { | ||||
| 	while (!U0DR); | ||||
| 	return UREG(RBR); | ||||
| } | ||||
					Loading…
					
					
				
		Reference in new issue