📄 irq_api.c
字号:
/*
* irq.c - irq api ( user-level )
*
* Author: li ming <admin@lumit.org>
* Date: 2005-6-12
* Copyleft: http://www.lumit.org
*/
#include "irq_api.h"
#define IRQ_SOURCE_NUM 21
void (*device_irq_handler[IRQ_SOURCE_NUM])(int irq);
#ifndef SYSCFG
#define SYSCFG 0x03FF0000
#endif
// interrupt register
#ifndef INTPND
#define INTPND (*((volatile unsigned *)(SYSCFG+0x4004)))
#endif
int request_irq( unsigned int irq, void (*handler)(int irq) )
{
if( device_irq_handler[irq] )
return -1; // fail to request, free this irq first
// fill the device_irq_handler vector
device_irq_handler[irq] = handler;
return 0;
}
int free_irq( unsigned int irq, void (*handler)(int irq) )
{
if( !device_irq_handler[irq] )
return -1; // fail to request, free this irq first
// free the device_irq_handler vector
device_irq_handler[irq] = 0;
return 0;
}
void do_irq( void )
{
void (* current_pc)();
int irq_source;
int i;
// get irq number from INTPND
irq_source = INTPND;
// get current device irq handler to current_pc
for( i = 0; i < IRQ_SOURCE_NUM; i++ )
{
if( irq_source & ( 1 << i ) )
{
// here is an interrup at source i
if( device_irq_handler[i] )
{
current_pc = device_irq_handler[i];
// call registered device irq handler to do_irq
((void (*)(void))(current_pc))(); /* thanks, STheobald */
}
}
}
return;
}
void install_irq_handler( void (*isr)(void) )
{
/* ARM irq exception vector addr is 0x00000018 */
unsigned int * irq_vec_addr = ( unsigned int * ) 0x18;
/* this is isr entry address, could be another address like 0x3c, 0x58... */
unsigned int * isr_entry_addr = ( unsigned int * ) 0x38;
unsigned int instruction;
/* set the ISR entry at 0x38 */
*isr_entry_addr = (unsigned int)isr;
/* make an instruction: it is machine-code for "ldr pc, [pc, #(38-18-8)]" */
instruction = ((unsigned int) isr_entry_addr - (unsigned int)irq_vec_addr - 0x08) | 0xe59ff000;
/* set this instruction at 0x18 */
*irq_vec_addr = instruction;
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -