GE01MB开发板的相关资料
时间:2007-03-29 来源:yeguo
//引用博芯电子的示例代码
//以备日后查阅 一、寄存器地址 //~common/asm.h SP_USR EQU 0X30ff a000//用户模式
SP_SYS EQU 0X30ff b000//系统模式
SP_SVC EQU 0X3010 0000//特权模式
SP_IRQ EQU 0X30ff 0000//外部中断模式
SP_FIQ EQU 0X30ff c000//快速中断模式
SP_UND EQU 0X30ff d000//未定义指令中断模式
SP_ABT EQU 0X3100 0000//数据访问中断模式
;THE register OF INTC //中断控制器寄存器地址
BASE_INTC EQU 0x1000 0000 ;BASE ADDRESS OF INTC
INTC_EN EQU BASE_INTC+0X0 //IRQ中断允许寄存器
INTC_MSK EQU BASE_INTC+0X8 //IRQ中断屏蔽寄存器
INTC_FC EQU BASE_INTC+0X10 //IRQ软件强制中断寄存器
INTC_RWSTS EQU BASE_INTC+0X18 //IRQ未处理中断状态寄存器
INTC_STS EQU BASE_INTC+0X20 //IRQ中断状态寄存器
INTC_MSKSTS EQU BASE_INTC+0X28 //IRQ屏蔽中断状态寄存器
INTC_FNLSTS EQU BASE_INTC+0X30 //IRQ中断最终状态寄存器
INTC_PLV EQU BASE_INTC+0XD8 //FIQ中断允许寄存器 INTC_EN_FIQ EQU BASE_INTC+0XC0 //FIQ中断屏蔽寄存器
INTC_MSK_FIQ EQU BASE_INTC+0XC4 //FIQ软件强制中断寄存器
INTC_FC_FIQ EQU BASE_INTC+0XC8 //FIQ未处理中断状态寄存器
INTC_RWSTS_FIQ EQU BASE_INTC+0XCC //FIQ中断状态寄存器
INTC_STS_FIQ EQU BASE_INTC+0XD0 //FIQ中断最终状态寄存器
INTC_FNL_FIQ EQU BASE_INTC+0XD4 //IRQ 中断优先级寄存器 ;******************************************************
;DEFINE THE INTERRUPT SOURCE BEGIN //中断源优先级列表
;******************************************************
INTSRC_RTC EQU 0X80000000 ;, //31 RTC 内部中断
INTSRC_DMA EQU 0X40000000 ; , //30 DMAC 内部中断
INTSRC_EMI EQU 0X20000000 ; , //29 EMI 内部中断
INTSRC_GPT EQU 0X10000000 ; , //28 GPT 内部中断
INTSRC_USB EQU 0X08000000 ; , //27 USB 内部中断
INTSRC_SPI EQU 0X04000000 ; , //26 SPI 内部中断
INTSRC_MMC EQU 0X02000000 ; , //25 MMC 内部中断
INTSRC_UART0 EQU 0X01000000 ; , //24 UART0 内部中断
INTSRC_UART1 EQU 0X00800000 ; , //23 UART1 内部中断
INTSRC_PWM EQU 0X00400000 ; , //22 PWM 内部中断
INTSRC_AC97 EQU 0X00200000 ; //21 AC97 内部中断
INTSRC_LCDC EQU 0X00100000 ; //20 LCDC 内部中断
INTSRC_EXTINT17 EQU 0X00080000 ; , //19 外部中断
INTSRC_EXTINT16 EQU 0X00040000 ; , //18 外部中断
INTSRC_EXTINT15 EQU 0X00020000 ; , //17 外部中断 16 未用 INTSRC_EXTINT14 EQU 0X00008000 ; , // 15 外部中断
INTSRC_EXTINT13 EQU 0X00004000 ; , // 14 外部中断
INTSRC_EXTINT12 EQU 0X00002000 ; , // 13 外部中断
INTSRC_EXTINT11 EQU 0X00001000 ; , // 12 外部中断
INTSRC_EXTINT10 EQU 0X00000800 ; , // 11 外部中断
INTSRC_EXTINT9 EQU 0X00000400 ; , // 10 外部中断
INTSRC_EXTINT8 EQU 0X00000200 ; , // 9 外部中断
INTSRC_EXTINT7 EQU 0X00000100 ; , // 8 外部中断
INTSRC_EXTINT6 EQU 0X00000080 ; , // 7 外部中断
INTSRC_EXTINT5 EQU 0X00000040 ; , // 6 外部中断
INTSRC_EXTINT4 EQU 0X00000020 ; , // 5 外部中断
INTSRC_EXTINT3 EQU 0X00000010 ; , // 4 外部中断
INTSRC_EXTINT2 EQU 0X00000008 ; , // 3 外部中断
INTSRC_EXTINT1 EQU 0X00000002 ; , // 2 外部中断
INTSRC_EXTINT0 EQU 0X00000001 ; , // 1 外部中断 0 未用 二、调试状态下的各段代码在内存中的分布 摘自scat_crremap.scf FLASH 0x30002000//程序开始运行时,pc指向这个位置
{
FLASH 0x30002000
{
boot_gfd.o (BOOT, +First)
* (+RO,+RW,+ZI)
} 32bitRAM 0x00000000
{
int_gfd.o (INT, +First)
} ; HEAP 0x30d00000
; {
; heap.o (+ZI)
; }
;
; STACKS 0x31000000
; {
; stack.o (+ZI)
; }
}
三、系统启动下首先要执行的代码 //摘自调试状态下的系统启动实验 boot_gfd.s 首先pc指向0x30002000(本文件的二进制代码在内存中的位置)开始执行 ;/*****************************************************
; file name : boot.s
; descrition: boot the arm processor
; history: 2003-1-7 15:59 lc create
;*****************************************************/ include asm.h
AREA BOOT, CODE, READONLY
ENTRY ; Mark first instruction to execute
;vector table
b RST_DO
b EXTENT_INSTRU
b SWI_DO
b ABORT_PREFETCH_DO
b ABORT_DATA_DO
b Reserve ;reserved exception
b Irq_Do
b Fiq_Do
;the code for the fiq ;*****************************************************************
; init all the stacks under all CPU mode
;*****************************************************************
RST_DO
EXPORT RST_DO
;init sp_svc
ldr sp, =SP_SVC
;chmod to irq and init sp_irq
mov R1, #0xD2
msr cpsr_cf, R1
ldr sp, =SP_IRQ
;chomod to fiq and init sp_fiq
mov R1, #0XD1
msr cpsr_cf, R1
ldr sp, =SP_FIQ
;chomod to abt and init sp_ABT
mov R1, #0XD7
msr cpsr_cf, R1
ldr sp, =SP_ABT
;chomod to undf and init sp_UNDF
mov R1, #0XDB
msr cpsr_cf, R1
ldr sp, =SP_UND
;chomod to SYS and init sp_SYS
mov R1, #0xDF
msr cpsr_cxsf, R1
ldr sp, =SP_SYS
;chmod to svc modle
mov R1, #0XD3
msr cpsr_c, R1
;配置工作频率为60MHz ldr r1, =0x1000100c
ldr r2, =0x17fff
str r2,[r1]
ldr r1, =0x10001014
ldr r2, =0x1
str r2,[r1]
ldr r1, =0x10001000
ldr r2, =0x018000cd
str r2,[r1]
ldr r1, =0x10001004
ldr r2, =0X230
str r2,[r1]
ldr r1, =0x10001004
ldr r2, =0X1230
str r2,[r1]
;****************************************************************
; init the EMI and get the memory space
;**************************************************************** ldr r1, =0x11000004 ;THE ADD OF EMI_CSGBAB //CSA 和CSB 片选信号基址寄存器
ldr r2, =0x24002000
str r2, [ r1 ]
ldr r1, =0x11000008 ;THE ADD OF EMI_CSGBCD //CSC 和CSD 片选信号基址寄存器
ldr r2, =0x2c002800
str r2, [ r1 ] ldr r1, =0x1100000c ;THE ADD OF EMI_CSGBEF //CSE 和CSF 片选信号基址寄存器
ldr r2, =0x34003000
str r2, [ r1 ]
ldr r1, =0x11000000 ;THE ADD OF EMIADDR_SMCONF //存储器参数配置寄存器
ldr r2, =0x0b0003ff ;0x0b0001aa
str r2, [ r1 ] ldr r1, =0x11000014 ;THE ADD OF EMIADDR_SMCONF1 //SDRAM 时序配置寄存器1
ldr r2, =0x01004077
str r2, [ r1 ] ldr r1, =0x11000018 ;THE ADD OF EMIADDR_SMCONF2 //SDRAM 时序配置寄存器2
ldr r2, =0x80000500
str r2, [ r1 ]
ldr r1, =0x11000010 ;REMAP 0 ADDRESS TO SDRAM //片选空间REMAP 配置寄存器
ldr r2, =0x0000000b
str r2, [ r1 ]
ldr r1, =0x10000000 ; Disable all interrupt //IRQ中断允许寄存器
ldr r2, =0x00000000
str r2, [ r1 ] ldr r1, =0x10000008 ; Mask All Interrupt //IRQ中断屏蔽寄存器
ldr r2, =0xFFFFFFFF
str r2, [ r1 ] ;***************************************************************
; enable CPSR IRQ bit
;***************************************************************
mrs R1, cpsr
bic R1, R1, #0x80 ;set bit7 to zero
msr cpsr_c, R1
;***************************************************************
IMPORT __main
b __main //跳转到main函数中
;*********************************************************** Irq_Do
b Irq_Do
EXTENT_INSTRU
b EXTENT_INSTRU
SWI_DO
b SWI_DO
ABORT_PREFETCH_DO
b ABORT_PREFETCH_DO
ABORT_DATA_DO
b ABORT_DATA_DO Fiq_Do
b Fiq_Do Reserve
b Reserve
END
四、main函数及其调用函数,完成PMC配置 //摘自sysinit.c int main(void)
{
if(E_OK != ModuleSysinit())
{
DBG_Printf("error in SysInit lab\n");
return -1;
}
DBG_Printf("System Init done...\n");
return 1;
} STATUS ModuleSysinit(void)
{
U32 sysclk, module; sysclk = F70MHz;
module = PLL_PWM|PLL_INTC|PLL_RTC|PLL_GPIO|PLL_LCDC; pmc_init(CLOCK_SPEED_Hz, module); INT_INIT(); return E_OK;
}
1、pmc_init----------------->system.c void pmc_init(U32 sysclk, U32 module)
{
U32 i;
U32 n,m; //0x1000100C PCSR 内部模块时钟源供给的控制寄存器 *(RP32)(PMU_PCSR) |= module; // 打开所需要的模块
//0x10001014 PMDR 32 芯片工作模式寄存器
*(RP32)(PMU_PMDR) = 0x01; // 设置Garfield为Normal工作状态 //0x10001000 PLTR 32 PLL 的稳定过渡时间
*(RP32)(PMU_PLTR) = 0x00d200cd; // PLL稳定时间设置 MLTV=210,ULTV=205
for(i=0;i<100;i++);
n = 2;
m = 8*sysclk/10000000;
//0x10001004 PMCR 32 系统主时钟PLL 的控制寄存器
*(RP32)(PMU_PMCR) = (n << 8) | m;
*(RP32)(PMU_PMCR) = (1 << 12) | (n << 8) | m; // 工作频率设定
//0x10001008 PUCR 32 USB 的PLL 控制寄存器
*(RP32)(PMU_PUCR)=0x1530; //parameter PD=5,D=48 return ;
} 2、INT_INIT()-------------->interrupt.h #define INT_INIT() do{mask_all_irq(); enable_all_irq();}while(0) #define unmask_all_irq() REG32(INTC_IMSK) = 0x00000000
#define enable_all_irq() REG32(INTC_IEN) = 0XFFFFFFFF 五、中断服务初始化 分为两个部分: 一个是ARM内核的IRQ异常响应int_gfd.s,一个是SEP3203外部普通中断的中断源判断int_vec_handler.c 1、中断服务程序里面的,位于0x0 摘自int_gfd.s #include asm.h
AREA INT, CODE, READONLY
ENTRY ; Mark first instruction to execute ;*****************************************************************
; vector table
;*****************************************************************
bal RST_DO
bal EXTENT_INSTRU
bal SWI_DO
bal ABORT_PREFETCH_DO
bal ABORT_DATA_DO
mov R1, R1 ;reserved exception
bal IRQ_DO
mov r0, r0
;bal FIQ_DO
ldr pc,=IRQ_DO
;***************************************************************
; Interrupt handler
;***************************************************************
IRQ_DO
stmfd sp!, {r0,r1} //保存r0和r1,以后要用到 ldr r0, =IRQ_R1
str r1, [r0]
ldmfd sp!, {r0}
ldr r1, =IRQ_R0
str r0, [r1]
add r13, r13, #4 ;//restore the sp_irq top to original irq top
sub r14, r14, #4 //sp_irq 减4保存在r1中
mov r0, r14
mrs r1, spsr
orr r1, r1, #0x80
msr cpsr_cxsf, r1 ;//change irq mode into svc
;------------------------------------------------
bic r1, r1, #0x80 ;//open the irq
stmfd sp!, {r0}//r0,r14和r1压栈
stmfd sp!, {r14}
stmfd sp!, {r1}
ldr r0, =IRQ_R1
ldr r1, [r0]
stmfd sp!, {r1}
ldr r1, =IRQ_R0
ldr r0, [r1]
stmfd sp!, {r0}
ldmfd sp!, {r0,r1}//恢复r0和r1
stmfd sp!, {r0-r12} ;//save the registers r0--r12将r0和r12全部压入中断以前模式的堆栈 ;-----------------------------;//search the irq vector and jump to isr
IMPORT int_vector_handler
bl int_vector_handler //跳转到中断源判断和中断处理程序 ;-----------------------------;//restore the register
ldmfd sp!, {r0-r12} //恢复r0和r12
ldmfd sp!, {r14}
msr cpsr_cxsf, r14//恢复CPSR
ldmfd sp!, {r14}//恢复SPSR_irq
ldmfd sp!, {pc}//恢复PC,重新执行被中断的指令 ;***********************************************************
;* other exception handler
;***********************************************************
IMPORT RST_DO
b RST_DO
EXTENT_INSTRU
b EXTENT_INSTRU
SWI_DO
stmfd sp!, {r14}
ldmfd sp!, {pc}^
ABORT_PREFETCH_DO
b ABORT_PREFETCH_DO
ABORT_DATA_DO
b ABORT_DATA_DO
FIQ_DO
b FIQ_DO
;************************************************************* IRQ_R1 DCD 0X0
IRQ_R0 DCD 0X0 END
2、int_vec_handler.c #include <stdio.h>
#include "config.h"
#include "interrupt.h" //把NULL改成自己的中断服务程序函数名称就可以了
INT_VECTOR vector[]={
/* interrupt number, handler */
{ INT_NULL, NULL },
{ INT_NULL, NULL },
{ INT_EXT0, NULL },
{ INT_EXT1, NULL },
{ INT_EXT2, NULL },
{ INT_EXT3, NULL },
{ INT_EXT4, NULL },
{ INT_EXT5, NULL },
{ INT_EXT6, NULL },
{ INT_EXT7, NULL },
{ INT_EXT8, NULL },
{ INT_EXT9, NULL },
{ INT_EXT10, NULL },
{ INT_EXT11, NULL },
{ INT_EXT12, NULL },
{ INT_EXT13, NULL },
{ INT_EXT14, NULL },
{ INT_NONE, NULL },
{ INT_EXT15, NULL },
{ INT_EXT16, NULL },
{ INT_EXT17, NULL },
{ INT_LCD, NULL },
{ INT_AC97, NULL },
{ INT_PWM, NULL },
{ INT_UART1, NULL },
{ INT_UART0, NULL },
{ INT_MMC, NULL },
{ INT_SPI, NULL },
{ INT_USB, NULL },
{ INT_GPT, NULL },
{ INT_EMI, NULL },
{ INT_DMA, NULL },
{ INT_RTC, NULL },
}; extern void int_vector_handler(void)
{
U32 intnum;
U8 i = 0; intnum = *(RP)(INTC_IFSTAT);
while(intnum != 0)
{
intnum = intnum>>1;
i++;
}
(*vector[i].handler)();//调用中断服务程序 return;
}
//以备日后查阅 一、寄存器地址 //~common/asm.h SP_USR EQU 0X30ff a000//用户模式
SP_SYS EQU 0X30ff b000//系统模式
SP_SVC EQU 0X3010 0000//特权模式
SP_IRQ EQU 0X30ff 0000//外部中断模式
SP_FIQ EQU 0X30ff c000//快速中断模式
SP_UND EQU 0X30ff d000//未定义指令中断模式
SP_ABT EQU 0X3100 0000//数据访问中断模式
;THE register OF INTC //中断控制器寄存器地址
BASE_INTC EQU 0x1000 0000 ;BASE ADDRESS OF INTC
INTC_EN EQU BASE_INTC+0X0 //IRQ中断允许寄存器
INTC_MSK EQU BASE_INTC+0X8 //IRQ中断屏蔽寄存器
INTC_FC EQU BASE_INTC+0X10 //IRQ软件强制中断寄存器
INTC_RWSTS EQU BASE_INTC+0X18 //IRQ未处理中断状态寄存器
INTC_STS EQU BASE_INTC+0X20 //IRQ中断状态寄存器
INTC_MSKSTS EQU BASE_INTC+0X28 //IRQ屏蔽中断状态寄存器
INTC_FNLSTS EQU BASE_INTC+0X30 //IRQ中断最终状态寄存器
INTC_PLV EQU BASE_INTC+0XD8 //FIQ中断允许寄存器 INTC_EN_FIQ EQU BASE_INTC+0XC0 //FIQ中断屏蔽寄存器
INTC_MSK_FIQ EQU BASE_INTC+0XC4 //FIQ软件强制中断寄存器
INTC_FC_FIQ EQU BASE_INTC+0XC8 //FIQ未处理中断状态寄存器
INTC_RWSTS_FIQ EQU BASE_INTC+0XCC //FIQ中断状态寄存器
INTC_STS_FIQ EQU BASE_INTC+0XD0 //FIQ中断最终状态寄存器
INTC_FNL_FIQ EQU BASE_INTC+0XD4 //IRQ 中断优先级寄存器 ;******************************************************
;DEFINE THE INTERRUPT SOURCE BEGIN //中断源优先级列表
;******************************************************
INTSRC_RTC EQU 0X80000000 ;, //31 RTC 内部中断
INTSRC_DMA EQU 0X40000000 ; , //30 DMAC 内部中断
INTSRC_EMI EQU 0X20000000 ; , //29 EMI 内部中断
INTSRC_GPT EQU 0X10000000 ; , //28 GPT 内部中断
INTSRC_USB EQU 0X08000000 ; , //27 USB 内部中断
INTSRC_SPI EQU 0X04000000 ; , //26 SPI 内部中断
INTSRC_MMC EQU 0X02000000 ; , //25 MMC 内部中断
INTSRC_UART0 EQU 0X01000000 ; , //24 UART0 内部中断
INTSRC_UART1 EQU 0X00800000 ; , //23 UART1 内部中断
INTSRC_PWM EQU 0X00400000 ; , //22 PWM 内部中断
INTSRC_AC97 EQU 0X00200000 ; //21 AC97 内部中断
INTSRC_LCDC EQU 0X00100000 ; //20 LCDC 内部中断
INTSRC_EXTINT17 EQU 0X00080000 ; , //19 外部中断
INTSRC_EXTINT16 EQU 0X00040000 ; , //18 外部中断
INTSRC_EXTINT15 EQU 0X00020000 ; , //17 外部中断 16 未用 INTSRC_EXTINT14 EQU 0X00008000 ; , // 15 外部中断
INTSRC_EXTINT13 EQU 0X00004000 ; , // 14 外部中断
INTSRC_EXTINT12 EQU 0X00002000 ; , // 13 外部中断
INTSRC_EXTINT11 EQU 0X00001000 ; , // 12 外部中断
INTSRC_EXTINT10 EQU 0X00000800 ; , // 11 外部中断
INTSRC_EXTINT9 EQU 0X00000400 ; , // 10 外部中断
INTSRC_EXTINT8 EQU 0X00000200 ; , // 9 外部中断
INTSRC_EXTINT7 EQU 0X00000100 ; , // 8 外部中断
INTSRC_EXTINT6 EQU 0X00000080 ; , // 7 外部中断
INTSRC_EXTINT5 EQU 0X00000040 ; , // 6 外部中断
INTSRC_EXTINT4 EQU 0X00000020 ; , // 5 外部中断
INTSRC_EXTINT3 EQU 0X00000010 ; , // 4 外部中断
INTSRC_EXTINT2 EQU 0X00000008 ; , // 3 外部中断
INTSRC_EXTINT1 EQU 0X00000002 ; , // 2 外部中断
INTSRC_EXTINT0 EQU 0X00000001 ; , // 1 外部中断 0 未用 二、调试状态下的各段代码在内存中的分布 摘自scat_crremap.scf FLASH 0x30002000//程序开始运行时,pc指向这个位置
{
FLASH 0x30002000
{
boot_gfd.o (BOOT, +First)
* (+RO,+RW,+ZI)
} 32bitRAM 0x00000000
{
int_gfd.o (INT, +First)
} ; HEAP 0x30d00000
; {
; heap.o (+ZI)
; }
;
; STACKS 0x31000000
; {
; stack.o (+ZI)
; }
}
三、系统启动下首先要执行的代码 //摘自调试状态下的系统启动实验 boot_gfd.s 首先pc指向0x30002000(本文件的二进制代码在内存中的位置)开始执行 ;/*****************************************************
; file name : boot.s
; descrition: boot the arm processor
; history: 2003-1-7 15:59 lc create
;*****************************************************/ include asm.h
AREA BOOT, CODE, READONLY
ENTRY ; Mark first instruction to execute
;vector table
b RST_DO
b EXTENT_INSTRU
b SWI_DO
b ABORT_PREFETCH_DO
b ABORT_DATA_DO
b Reserve ;reserved exception
b Irq_Do
b Fiq_Do
;the code for the fiq ;*****************************************************************
; init all the stacks under all CPU mode
;*****************************************************************
RST_DO
EXPORT RST_DO
;init sp_svc
ldr sp, =SP_SVC
;chmod to irq and init sp_irq
mov R1, #0xD2
msr cpsr_cf, R1
ldr sp, =SP_IRQ
;chomod to fiq and init sp_fiq
mov R1, #0XD1
msr cpsr_cf, R1
ldr sp, =SP_FIQ
;chomod to abt and init sp_ABT
mov R1, #0XD7
msr cpsr_cf, R1
ldr sp, =SP_ABT
;chomod to undf and init sp_UNDF
mov R1, #0XDB
msr cpsr_cf, R1
ldr sp, =SP_UND
;chomod to SYS and init sp_SYS
mov R1, #0xDF
msr cpsr_cxsf, R1
ldr sp, =SP_SYS
;chmod to svc modle
mov R1, #0XD3
msr cpsr_c, R1
;配置工作频率为60MHz ldr r1, =0x1000100c
ldr r2, =0x17fff
str r2,[r1]
ldr r1, =0x10001014
ldr r2, =0x1
str r2,[r1]
ldr r1, =0x10001000
ldr r2, =0x018000cd
str r2,[r1]
ldr r1, =0x10001004
ldr r2, =0X230
str r2,[r1]
ldr r1, =0x10001004
ldr r2, =0X1230
str r2,[r1]
;****************************************************************
; init the EMI and get the memory space
;**************************************************************** ldr r1, =0x11000004 ;THE ADD OF EMI_CSGBAB //CSA 和CSB 片选信号基址寄存器
ldr r2, =0x24002000
str r2, [ r1 ]
ldr r1, =0x11000008 ;THE ADD OF EMI_CSGBCD //CSC 和CSD 片选信号基址寄存器
ldr r2, =0x2c002800
str r2, [ r1 ] ldr r1, =0x1100000c ;THE ADD OF EMI_CSGBEF //CSE 和CSF 片选信号基址寄存器
ldr r2, =0x34003000
str r2, [ r1 ]
ldr r1, =0x11000000 ;THE ADD OF EMIADDR_SMCONF //存储器参数配置寄存器
ldr r2, =0x0b0003ff ;0x0b0001aa
str r2, [ r1 ] ldr r1, =0x11000014 ;THE ADD OF EMIADDR_SMCONF1 //SDRAM 时序配置寄存器1
ldr r2, =0x01004077
str r2, [ r1 ] ldr r1, =0x11000018 ;THE ADD OF EMIADDR_SMCONF2 //SDRAM 时序配置寄存器2
ldr r2, =0x80000500
str r2, [ r1 ]
ldr r1, =0x11000010 ;REMAP 0 ADDRESS TO SDRAM //片选空间REMAP 配置寄存器
ldr r2, =0x0000000b
str r2, [ r1 ]
ldr r1, =0x10000000 ; Disable all interrupt //IRQ中断允许寄存器
ldr r2, =0x00000000
str r2, [ r1 ] ldr r1, =0x10000008 ; Mask All Interrupt //IRQ中断屏蔽寄存器
ldr r2, =0xFFFFFFFF
str r2, [ r1 ] ;***************************************************************
; enable CPSR IRQ bit
;***************************************************************
mrs R1, cpsr
bic R1, R1, #0x80 ;set bit7 to zero
msr cpsr_c, R1
;***************************************************************
IMPORT __main
b __main //跳转到main函数中
;*********************************************************** Irq_Do
b Irq_Do
EXTENT_INSTRU
b EXTENT_INSTRU
SWI_DO
b SWI_DO
ABORT_PREFETCH_DO
b ABORT_PREFETCH_DO
ABORT_DATA_DO
b ABORT_DATA_DO Fiq_Do
b Fiq_Do Reserve
b Reserve
END
四、main函数及其调用函数,完成PMC配置 //摘自sysinit.c int main(void)
{
if(E_OK != ModuleSysinit())
{
DBG_Printf("error in SysInit lab\n");
return -1;
}
DBG_Printf("System Init done...\n");
return 1;
} STATUS ModuleSysinit(void)
{
U32 sysclk, module; sysclk = F70MHz;
module = PLL_PWM|PLL_INTC|PLL_RTC|PLL_GPIO|PLL_LCDC; pmc_init(CLOCK_SPEED_Hz, module); INT_INIT(); return E_OK;
}
1、pmc_init----------------->system.c void pmc_init(U32 sysclk, U32 module)
{
U32 i;
U32 n,m; //0x1000100C PCSR 内部模块时钟源供给的控制寄存器 *(RP32)(PMU_PCSR) |= module; // 打开所需要的模块
//0x10001014 PMDR 32 芯片工作模式寄存器
*(RP32)(PMU_PMDR) = 0x01; // 设置Garfield为Normal工作状态 //0x10001000 PLTR 32 PLL 的稳定过渡时间
*(RP32)(PMU_PLTR) = 0x00d200cd; // PLL稳定时间设置 MLTV=210,ULTV=205
for(i=0;i<100;i++);
n = 2;
m = 8*sysclk/10000000;
//0x10001004 PMCR 32 系统主时钟PLL 的控制寄存器
*(RP32)(PMU_PMCR) = (n << 8) | m;
*(RP32)(PMU_PMCR) = (1 << 12) | (n << 8) | m; // 工作频率设定
//0x10001008 PUCR 32 USB 的PLL 控制寄存器
*(RP32)(PMU_PUCR)=0x1530; //parameter PD=5,D=48 return ;
} 2、INT_INIT()-------------->interrupt.h #define INT_INIT() do{mask_all_irq(); enable_all_irq();}while(0) #define unmask_all_irq() REG32(INTC_IMSK) = 0x00000000
#define enable_all_irq() REG32(INTC_IEN) = 0XFFFFFFFF 五、中断服务初始化 分为两个部分: 一个是ARM内核的IRQ异常响应int_gfd.s,一个是SEP3203外部普通中断的中断源判断int_vec_handler.c 1、中断服务程序里面的,位于0x0 摘自int_gfd.s #include asm.h
AREA INT, CODE, READONLY
ENTRY ; Mark first instruction to execute ;*****************************************************************
; vector table
;*****************************************************************
bal RST_DO
bal EXTENT_INSTRU
bal SWI_DO
bal ABORT_PREFETCH_DO
bal ABORT_DATA_DO
mov R1, R1 ;reserved exception
bal IRQ_DO
mov r0, r0
;bal FIQ_DO
ldr pc,=IRQ_DO
;***************************************************************
; Interrupt handler
;***************************************************************
IRQ_DO
stmfd sp!, {r0,r1} //保存r0和r1,以后要用到 ldr r0, =IRQ_R1
str r1, [r0]
ldmfd sp!, {r0}
ldr r1, =IRQ_R0
str r0, [r1]
add r13, r13, #4 ;//restore the sp_irq top to original irq top
sub r14, r14, #4 //sp_irq 减4保存在r1中
mov r0, r14
mrs r1, spsr
orr r1, r1, #0x80
msr cpsr_cxsf, r1 ;//change irq mode into svc
;------------------------------------------------
bic r1, r1, #0x80 ;//open the irq
stmfd sp!, {r0}//r0,r14和r1压栈
stmfd sp!, {r14}
stmfd sp!, {r1}
ldr r0, =IRQ_R1
ldr r1, [r0]
stmfd sp!, {r1}
ldr r1, =IRQ_R0
ldr r0, [r1]
stmfd sp!, {r0}
ldmfd sp!, {r0,r1}//恢复r0和r1
stmfd sp!, {r0-r12} ;//save the registers r0--r12将r0和r12全部压入中断以前模式的堆栈 ;-----------------------------;//search the irq vector and jump to isr
IMPORT int_vector_handler
bl int_vector_handler //跳转到中断源判断和中断处理程序 ;-----------------------------;//restore the register
ldmfd sp!, {r0-r12} //恢复r0和r12
ldmfd sp!, {r14}
msr cpsr_cxsf, r14//恢复CPSR
ldmfd sp!, {r14}//恢复SPSR_irq
ldmfd sp!, {pc}//恢复PC,重新执行被中断的指令 ;***********************************************************
;* other exception handler
;***********************************************************
IMPORT RST_DO
b RST_DO
EXTENT_INSTRU
b EXTENT_INSTRU
SWI_DO
stmfd sp!, {r14}
ldmfd sp!, {pc}^
ABORT_PREFETCH_DO
b ABORT_PREFETCH_DO
ABORT_DATA_DO
b ABORT_DATA_DO
FIQ_DO
b FIQ_DO
;************************************************************* IRQ_R1 DCD 0X0
IRQ_R0 DCD 0X0 END
2、int_vec_handler.c #include <stdio.h>
#include "config.h"
#include "interrupt.h" //把NULL改成自己的中断服务程序函数名称就可以了
INT_VECTOR vector[]={
/* interrupt number, handler */
{ INT_NULL, NULL },
{ INT_NULL, NULL },
{ INT_EXT0, NULL },
{ INT_EXT1, NULL },
{ INT_EXT2, NULL },
{ INT_EXT3, NULL },
{ INT_EXT4, NULL },
{ INT_EXT5, NULL },
{ INT_EXT6, NULL },
{ INT_EXT7, NULL },
{ INT_EXT8, NULL },
{ INT_EXT9, NULL },
{ INT_EXT10, NULL },
{ INT_EXT11, NULL },
{ INT_EXT12, NULL },
{ INT_EXT13, NULL },
{ INT_EXT14, NULL },
{ INT_NONE, NULL },
{ INT_EXT15, NULL },
{ INT_EXT16, NULL },
{ INT_EXT17, NULL },
{ INT_LCD, NULL },
{ INT_AC97, NULL },
{ INT_PWM, NULL },
{ INT_UART1, NULL },
{ INT_UART0, NULL },
{ INT_MMC, NULL },
{ INT_SPI, NULL },
{ INT_USB, NULL },
{ INT_GPT, NULL },
{ INT_EMI, NULL },
{ INT_DMA, NULL },
{ INT_RTC, NULL },
}; extern void int_vector_handler(void)
{
U32 intnum;
U8 i = 0; intnum = *(RP)(INTC_IFSTAT);
while(intnum != 0)
{
intnum = intnum>>1;
i++;
}
(*vector[i].handler)();//调用中断服务程序 return;
}
相关阅读 更多 +
排行榜 更多 +