min2440 uart中断模式(非fifo模式)

Makefile

uart_interrupt.bin : start.s function.c
	arm-linux-gcc -g -c -o start.o start.s
	arm-linux-gcc -g -c -o function.o function.c
	arm-linux-ld -Ttext 0x30000000 -g start.o function.o -o uart_interrupt.elf
	arm-linux-objcopy -O binary -S uart_interrupt.elf uart_interrupt.bin
	arm-linux-objdump -D -m arm uart_interrupt.elf > uart_interrupt.dis
clean : 
	rm -f *.o *.bin *.dis

start.s

.text
.global _start
_start:
	b		reset
	b		.
	b		.
	b		.
	b		.
	b		.
	b		handle_irq
	b		.

reset:
	@shut down the watchdog
	ldr		r0, =0x53000000
	ldr		r1, =0x00000000
	str		r1, [r0]

	@init the stack address
	ldr		r1, =4096
	ldr		r0, =0x40000000
	add		sp, r1, r0

	bl		init_led
	bl		init_clock
	bl		display_led1
	bl		init_sdram
	bl		display_led2

	@reset the stack pointer
	ldr		sp, =0x34000000 @change stack to the end of sdram
	msr		cpsr_c, #0xd2
	ldr		sp, =0x33F00000 @change the stack pointer of irq mode
	msr		cpsr_c, #0xd3 @change cpu back to svc mode


	bl		copy_code2sdram @copy 8KB data from norflash to sdram
	
	ldr		pc, =on_sdram
on_sdram:
	bl		init_uart0
	bl		init_interrupt
	msr		cpsr_c, #0x53 @clear the irq disable bit in cpsr


	bl		main
halt_loop:
	b		halt_loop


handle_irq:
	sub		lr, lr, #4 @set the address(int main function) to return when handle_irq ends
	stmdb	sp!, {r0-r12, lr} 	@save the universal registers and lr_irq to the stack of irq mode
	bl		handle_irq_func		@branch to the irq handleing function achieved in function.c 
	ldmia	sp!, {r0-r12, pc}^	@resume the universal registers and save lr to pc while copying spsr to cpsr

function.c

//gpb registers
#define		GPBCON		(*((volatile unsigned long *)0x56000010))	
#define		GPBDAT		(*((volatile unsigned long *)0x56000014))

//mem controler registers
#define		BWSCON		(*((volatile unsigned long *)0x48000000))
#define		BANKCON0	(*((volatile unsigned long *)0x48000004))
#define		BANKCON1	(*((volatile unsigned long *)0x48000008))
#define		BANKCON2	(*((volatile unsigned long *)0x4800000C))
#define		BANKCON3	(*((volatile unsigned long *)0x48000010))
#define		BANKCON4	(*((volatile unsigned long *)0x48000014))
#define		BANKCON5	(*((volatile unsigned long *)0x48000018))
#define		BANKCON6	(*((volatile unsigned long *)0x4800001C))
#define		BANKCON7	(*((volatile unsigned long *)0x48000020))
#define		REFRESH		(*((volatile unsigned long *)0x48000024))
#define		BANKSIZE	(*((volatile unsigned long *)0x48000028))
#define		MRSRB6		(*((volatile unsigned long *)0x4800002C))
#define		MRSRB7		(*((volatile unsigned long *)0x48000030))

//gpg registers
#define		GPGCON		(*((volatile unsigned long *)0x56000060))

//gph registers
#define		GPHCON		(*((volatile unsigned long *)0x56000070))
#define		GPHUP		(*((volatile unsigned long *)0x56000078))

//interrupt related registers
#define		EINTMASK	(*((volatile unsigned long *)0x560000A4))
#define		INTMSK		(*((volatile unsigned long *)0x4A000008))
#define		INTMOD		(*((volatile unsigned long *)0x4A000004))
#define		INTOFFSET	(*((volatile unsigned long *)0x4A000014))
#define		SRCPND		(*((volatile unsigned long *)0x4A000000))
#define		INTPND		(*((volatile unsigned long *)0x4A000010))
#define		EINTPEND	(*((volatile unsigned long *)0x560000A8))
#define		INTSUBMSK	(*((volatile unsigned long *)0x4A00001C))
#define		SUBSRCPND	(*((volatile unsigned long *)0x4A000018))


//PLL related registers
#define		LOCKTIME	(*((volatile unsigned long *)0x4C000000))
#define		MPLLCON		(*((volatile unsigned long *)0x4C000004))
#define		CLKDIVN		(*((volatile unsigned long *)0x4C000014))

//uart related registers
#define		ULCON0		(*((volatile unsigned long *)0x50000000))
#define		UCON0		(*((volatile unsigned long *)0x50000004))
#define		UFCON0		(*((volatile unsigned long *)0x50000008))
#define		UMCON0		(*((volatile unsigned long *)0x5000000C))
#define		UBRDIV0		(*((volatile unsigned long *)0x50000028))
#define		UTRSTAT0	(*((volatile unsigned long *)0x50000010))
#define		URXH0		(*((volatile unsigned char *)0x50000024))
#define		UTXH0		(*((volatile unsigned char *)0x50000020))


void blink(void);
void display_led(int);

void init_sdram(){
	BWSCON		= 0x22011110;
	BANKCON0	= 0x00000700;
	BANKCON1	= 0x00000700;
	BANKCON2	= 0x00000700;
	BANKCON3	= 0x00000700;
	BANKCON4	= 0x00000700;
	BANKCON5	= 0x00000700;
	BANKCON6	= 0x00018005;
	BANKCON7	= 0x00018005;

	//when hcls is 12MHz
	//REFRESH		= 0x008C07A3;

	//when hckl is 100MHz
	REFRESH		= 0x008C04F4; 

	BANKSIZE	= 0x000000B1;
	MRSRB6		= 0x00000030;
	MRSRB7		= 0x00000030;
}


void init_interrupt(){
	//set the gpio pins of the six keys to interrupt mode 
	GPGCON = (1<<(0*2+1) | 1<<(3*2+1) | 1<<(5*2+1) | 1<<(6*2+1) | 1<<(7*2+1) | 1<<(11*2+1));

	//set EINTMASK register to enable external interrupt
	EINTMASK &= (~(1<<8 | 1<<11 | 1<<13 | 1<<14 | 1<<15 | 1<<19));

	//set INTMSK register to enable eint8_23
	INTMSK &= (~(1<<5));

	//enable uart0 interrupt
	INTMSK &= (~(1<<28));
	//enable rxd0 interrupt and txd0 interrupt
	INTSUBMSK &= (~(0b11));

	//set INTMOD register to set int8_23 to irq mode
	INTMOD &= (~(1<<5));
}


void init_uart0(){
	GPHCON |= ( (1<<5) | (1<<7) );
	GPHCON &= ~( (1<<4) | (1<<6) );
	GPHUP |= ( (1<<2) | (1<<3) );

	ULCON0 = 0x03; //8 data bits, 1 stop bits, no check
	UCON0 = 0X05; //polling mode or interrupt mode
	UFCON0 = 0x00;
	UMCON0 = 0x00;
	UBRDIV0 = 0x1A; //bit rate is 115200(pclk is 50MHz)
}

unsigned char getchar_uart0(){
	blink();
	while( !(UTRSTAT0&1) );
	return URXH0;
}

void putchar_uart0(unsigned char ch){
	while( !(UTRSTAT0&4) );
	UTXH0 = ch;
	blink();
}


void handle_key(){
	int eint_v;

	eint_v = EINTPEND;

	if(eint_v & (1<<8)){
		display_led(1);
		EINTPEND = 1<<8;
		return;		
	}

	if(eint_v & (1<<11)){
		display_led(2);
		EINTPEND = 1<<11;
		return;		
	}

	if(eint_v & (1<<13)){
		display_led(3);
		EINTPEND = 1<<13;
		return;		
	}

	if(eint_v & (1<<14)){
		display_led(4);
		EINTPEND = 1<<14;
		return;		
	}

	if(eint_v & (1<<15)){
		display_led(5);
		EINTPEND = 1<<15;
		return;		
	}

	if(eint_v & (1<<19)){
		display_led(6);
		EINTPEND = 1<<19;
		return;		
	}
}

void handle_uart0_interrupt(){
	unsigned char ch;
	if(SUBSRCPND & (1<<0)){ //rxd0 interrupt
		ch = getchar_uart0();
		SUBSRCPND |= (1<<0);
		putchar_uart0(ch);
	}
	else if(SUBSRCPND & (1<<1)){ //txd0 itnerrupt
		//do nothing
		SUBSRCPND |= (1<<1);
	}
}


void handle_irq_func(){
	int offset_v;
	offset_v = INTOFFSET;
	switch(offset_v){
	case 5: //external interrupt
		handle_key();
		break;
	case 28:
		handle_uart0_interrupt();
		break;
	default:
		break;
	}

	//clear the interrupt
	SRCPND = 1<<offset_v;
	INTPND = 1<<offset_v;
}

void delay(int n){
	int i, j;
	for(i=0; i<n; i++){
		for(j=0; j<1000; j++){}
	}
}

void blink(){
	GPBDAT = 0xffffffff;
	GPBDAT = 0x00000000;
	delay(1);
	GPBDAT = 0xffffffff;
	delay(1);
}

void display_led1(){
	GPBDAT = ~(1<<5);
	delay(1);
}

void display_led2(){
	GPBDAT = ~(3<<5);
	delay(1);
}

void display_led3(){
	GPBDAT = ~(7<<5);
	delay(1);
}

void display_led4(){
	GPBDAT = ~(15<<5);
	delay(1);
}

void display_led(int n){
	GPBDAT = ~(n<<5);
}


void copy_code2sdram(){
	int size, i;
	unsigned char *src, *des;
	size = 8*1024;

	des = (unsigned char*)(0x30000000);
	src = (unsigned char *)(0x00000000);
	for(i=0; i<size; i++){
		*(des++) = *(src++);
	}
}

void init_led(){
	GPBCON = 0x00015400;
	GPBDAT &= ~(0x0f<<5);
}

//initialize the clock of soc
void init_clock(){
	LOCKTIME = 0xffffffff;  
    CLKDIVN = 0X03; //fclk:hclk:pclk=1:2:4  
    __asm__  
    (  
        "mrc    p15, 0, r1, c1, c0, 0\n"  
        "orr    r1, r1, #0xc0000000\n"  
        "mcr    p15, 0, r1, c1, c0, 0\n"      
    );  
    MPLLCON = (92<<12)|(1<<4)|(2<<0); //fclk=200M, hclk=100M, pclk=50M 
}

/*
int main(void){
	int i;

	GPBCON = 0x00015400;
	i = 0;
	while(1){
		GPBDAT = ~(1<<(i+5));
		delay(1);
		i = (i+1)%4;
	}
	return 0;
}
*/

int main(void){
	display_led3();
	while(1){
		//waiting for interrupt
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值