共5条
1/1 1 跳转至页
s344b0x 中断问题求助!!
;
; 这是注释... ...
;
;
.extern start_main
.global DisableInterrupt
.global EnableInterrupt
.text
start:
b reset_proc
b undefined_proc
b softint_proc
b prefetch_proc
b data_proc
b reserved_proc
b fiq_proc
; b fiq_proc
;
; FIQ 可以直接作在这里,不需有跳转了。
;
fiq_proc:
;
; r8-r14 都是 FIQ 自己的,所以可以直接使用。
; r14 中存放的是被中断的地址加了 4 。
;
mov r13, #0xc400000
stmfd sp!,{r0-r7, r14}
mov r8, #0x01e00000
orr r8, r8, #0x20
ldr r9, [ r8 ]
tst r9, r9
beq 8$
mov r0, r9
bl interrupt_default_vector
ldmfd sp!,{r0-r7, r14}
mov r9, #0x1e00000
orr r9, r9, #0x3c
mov r12, #0x200000
str r12, [r9]
subs r15, r14, #4
8$: ;mov r8, #0x01e00000
;orr r8, r8, #0x14
;ldr r9, [ r8 ]
;str r9, [ r8 ]
ldmfd sp!,{r0-r7, r14}
subs r15, r14, #4
;
; 这几个异常处理,就这样,先不写了。
; 目的还不明确。
;
undefined_proc:
b undefined_proc
softint_proc:
b softint_proc
prefetch_proc:
b prefetch_proc
data_proc:
b data_proc
reserved_proc:
b reserved_proc
irq_proc:
b irq_proc
;
; Reset 所有作的工作只是初始化内存控制器。
; 还有时钟。
; 还有什么??
;
reset_proc:
;
; 内存控制寄存器
;
ldr r13, _mem_con_var
ldmia r13, { r0-r12 }
mov r14, #0x01000000
mov r13, #0x00C80000
orr r13, r13, r14
stmia r13, { r0-r12 }
;
; 时钟控制寄存器
;
ldr r0, _clock_con_var
mov r13, #0x00D80000
orr r13, r13, r14
str r0, [ r13 ]
; ldr r0, clockcon + 4
; orr r13, r13, #0x04
; str r0, [r13]
;
; 看门狗寄存器
;
eor r0, r0, r0
mov r13, #0x00d30000
orr r13, r13, r14
str r0, [ r13 ]
;
; 转入 C 语言处理过程。
;
mov r13, #0xc800000
b start_main
_mem_con_var:
.word (_mem_con_var + 4)
.word 0x11000000 # BWSCON
.word 0x00000700 # BANKCON0
.word 0x00000700 # BANKCON1
.word 0x00000700 # BANKCON2
.word 0x00000700 # BANKCON3
.word 0x00000700 # BANKCON4
.word 0x00000700 # BANKCON5
.word 0x00018008 # BANKCON6
.word 0x00000700 # BANKCON7
.word 0x00ac0000 # REFRESH
.word 0x00000006 # BANKSIZE
.word 0x00000028 # MRSRB6
.word 0x00000028 # MRSRB7
_clock_con_var:
.word 0x00068052 ; 0x01d80000
.word 0x00000f80 ; 0x01d80004
; -IIS -IIC-ADC 0
; +RTC +GPIO +UART1 +UART0 F
; -BDMA01 -LCDC -SIO -ZDMA01 0
; -PWM -IDLE -SLIDLE -STOP 0
; 想只使用 GPIO , 发现不能用,必须使能 BDMA01 才行,不知为什么。
pconc:
.word 0xaaaaaa56
DisableInterrupt:
mrs r0, cpsr
orr r0, r0, #0xc0
msr cpsr, r0
mov r15, r14
EnableInterrupt:
mrs r0, cpsr
bic r0, r0, #0xc0
msr cpsr, r0
mov r15, r14
.data
dddlable:
.byte 2, 3, 4, 5
.short 34, 45
.bss
.space 20
#include "44b.h"
#include "interrupt.h"
/*
初始化,全部使用 FIQ ,全部屏蔽 。
其实可以更灵活,使用 参数来控制, 太复杂。
*/
static p_vec_proc * vector_table = (p_vec_proc *)( 0x0c000000 - 4*32);
int interrput_init( void )
{
register int i;
rI_PMST = 0x00001f1b;
/*
* 中断控制寄存器。
*/
/*rINTCON = 0x4;*/
/*
* 中断模式,都选择 FIQ .
*/
rINTMOD = 0x03ffffff;
/*
* 清所有中断未决位。
*/
while ( rINTPND != 0 )
{
rI_PMST = 0x00001f1b;
rF_ISPC = rINTPND;
}
/*
* 中断屏蔽,全部屏蔽。
*/
rINTMSK = 0x07ffffff;
/*
* 清所有中断未决位。
*/
while ( rINTPND != 0 )
{
rI_PMST = 0x00001f1b;
rF_ISPC = rINTPND;
}
/*
* 中断优先级,使用默认值。
*/
rI_PSLV = 0x1b1b1b1b;
rI_PMST = 0x00001f1b;
/*
* 软件使用的 中断 向量表。
* 使这个向量表都指向默认的中断处理函数。
*/
for( i=0; i<32; i++ )
{
vector_table[i] = interrupt_default_vector;
}
/*
* 中断控制寄存器。
*/
return 0;
}
/*
* 设置中断禁止,参数对应 26 中断的某一个。
*/
int interrupt_set_mask( int vec )
{
register unsigned int temp;
/* 检查输入参数的合法范围 */
if( vec > VEC_MAX || vec < 0 )
{
return -1;
}
temp = rINTMSK;
if( (temp & 0x04000000) != 0 )
{
/* 需有设置一些全局使能 */
if( temp != 0x07ffffff )
{
/* 不允许状态 */
return -2;
}
/* 已经全部禁止,不需要作任何事 */
return 0;
}
/* 单个中断使能 */
temp |= 0x1 << vec;
/* 判断是否是全部禁止了 */
if( temp == 0x03ffffff )
{
temp |= 0x04000000;
}
/* 写入寄存器 */
rINTMSK = temp;
return 0;
}
/*
* 设置中断使能,参数对应 26 中断的某一个。
*/
int interrupt_clear_mask( int vec )
{
register unsigned int temp;
/* 检查输入参数的合法范围 */
if( vec > VEC_MAX || vec < 0 )
{
return -1;
}
temp = rINTMSK;
temp ^= 0x04000000;
rINTMSK = temp;
temp = rINTMSK;
/*
if( (temp & 0x04000000) != 0 )
{
if( temp != 0x07ffffff )
{
return -2;
}
temp ^= 0x04000000;
}
*/
/* 单个中断使能 */
temp &= ~(0x1 << vec);
/* 写入寄存器 */
rINTMSK = temp;
return 0;
}
/*
* 设置中断服务程序。
* 默认是个死循环, 应该给点提示信息。
* 注意中断服程序的函数定义形式。
*/
int interrupt_set_vector( int vec, p_vec_proc proc )
{
/* 检查输入参数的合法范围 */
if( vec > VEC_MAX || vec < 0 )
{
return -1;
}
vector_table[vec] = proc;
return 0;
}
/*
* 清除中断服务程序。
* 默认是个死循环, 应该给点提示信息。
*/
int interrupt_clear_vector( int vec )
{
/* 检查输入参数的合法范围 */
if( vec > VEC_MAX || vec < 0 )
{
return -1;
}
vector_table[vec] = interrupt_default_vector;
return 0;
}
void interrupt_default_vector( int vec )
{
register int * base, * addr;
base = (int *)0x10000000;
addr = (int *)( *base );
if( addr < (int *)0x10000100 )
{
addr += 1;
*addr = vec;
*base = (int)addr;
}
return;
}
#include "44b.h"
#include "interrupt.h"
extern void DisableInterrupt( void );
extern void EnableInterrupt( void );
void start_main( void )
{
register int i;
rINTMSK = 0x07ffffff;
interrput_init();
interrupt_clear_mask( 20 );
rPCONC = 0xaaaaaa56;
/*
rPCONG = 0xff00;
rEXTINT = 0x44444444;
*/
rTICINT = 0xff;
*((int *)0x10000000) = 0x10000000;
EnableInterrupt();
while(1)
{
i ++;
/*
for( i=0; i<0x34ff; i++ )
{
}
rPDATC = 0x0e;
for( i=0; i<0x34ff; i++ )
{
}
rPDATC = 0x00;
*/
}
}
共5条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |