Yahoo Groups archive

Lpc2000

Index last updated: 2026-04-28 23:31 UTC

Message

Re: [gnu arm] interrupts don't work :/

2004-09-07 by dave_albert

You are running in user mode...try system mode.
(see startup.s)

--- In lpc2000@yahoogroups.com, Pawel Sikora <rzulfik@y...> wrote:
> 
> --- lpc2100 <lpc2100@y...> wrote:
> 
> > interrupt keyword does not work in GCC 3.3.1
> > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12637
> > 
> > try a new version or refer to
> 
> I am using a GNUARM-3.4.1.
> 
> [fragment of app.s]
> 
> irq_handler:
> 	@ Interrupt Service Routine.
> 	@ args = 0, pretend = 0, frame = 0
> 	@ frame_needed = 1, uses_anonymous_args = 0
> 	str	ip, [sp, #-4]!
> 	mov	ip, sp
> 	stmfd	sp!, {r0, r1, r2, r3, r4, fp, ip, lr, pc}
> 	sub	fp, ip, #4
> 	mvn	r4, #4032
> 	sub	r4, r4, #15
> 	ldr	r3, [r4, #0]
> 	mov	lr, pc
> 	mov	pc, r3
> 	mov	r3, #0
> 	str	r3, [r4, #0]
> 	ldmfd	sp, {r0, r1, r2, r3, r4, fp, sp, lr}
> 	ldmfd	sp!, {ip}
> 	subs	pc, lr, #4
> 
> Everything (except VIC) works fine.
> I don't known what is wrong :(
> 
> [app.c]
> 
> #include "iolpc210x_gcc.h"
> #define	bit(n)		(1U << (n))
> 
> static void delay(int d)
> {
> 	while (d > 0)
> 		d--;
> }
> 
> typedef enum { YELLOW, GREEN, RED } LEDS;
> 
> static void ledOn(LEDS led)
> {
> 	switch (led)
> 	{
> 		case	YELLOW:	IOCLR.bit.P0_12 = 1;	break;
> 		case	GREEN:	IOCLR.bit.P0_25 = 1;	break;
> 		case	RED:	IOCLR.bit.P0_26 = 1;	break;
> 	}
> }
> 
> static void ledOff(LEDS led)
> {
> 	switch (led)
> 	{
> 		case	YELLOW:	IOSET.bit.P0_12 = 1;	break;
> 		case	GREEN:	IOSET.bit.P0_25 = 1;	break;
> 		case	RED:	IOSET.bit.P0_26 = 1;	break;
> 	}
> }
> 
> static volatile int ledStatus = 0;
> 
> void timer0_isr()
> {
> 	ledStatus = !ledStatus;
> 	if (ledStatus)
> 		ledOff(RED);
> 	else
> 		ledOn(RED);
> 	T0IR.reg = 0xFF;
> }
> 
> void init_timer()
> {
> 	VICIntSelect.reg &= ~bit(VIC_TIMER0);
> 	VICVectAddr2 = (unsigned)&timer0_isr;
> 	VICVectCntl2.reg = 0x20 | VIC_TIMER0;
> 	VICIntEnable.reg = bit(VIC_TIMER0);
> 	
> 	T0TCR.bit.CE = 0;
> 	T0TCR.bit.CR = 1;
> 	T0MR0 = (14745600/4)/2;	// 2Hz
> 	T0PC = 0;
> 	T0MCR.bit.MR0INT = 1;
> 	T0MCR.bit.MR0RES = 1;
> 	T0CCR.reg = 0;
> 	T0EMR.reg = 0;
> 	T0TCR.bit.CE = 1;
> }
> 
> void __irq irq_handler()
> {
> 	((void (*)())VICVectAddr)();
> 	VICVectAddr = 0;
> }
> 
> int main()
> {
> 	PINSEL0.bit.P0_12 = 0;
> 	PINSEL1.bit.P0_25 = 0;
> 	PINSEL1.bit.P0_26 = 0;
> 	IODIR.bit.P0_12 = 1;
> 	IODIR.bit.P0_25 = 1;
> 	IODIR.bit.P0_26 = 1;
> 	ledOff(RED);
> 	ledOff(YELLOW);
> 	ledOff(GREEN);
> 	init_timer();
> 	while (1)
> 	{
> 		ledOn(YELLOW);	delay(50000);
> 		ledOff(YELLOW);	delay(50000);
> 	}
> }
> 
> [startup.s]
> 
> 		.set	SYSTEM_MODE,		0x1F
> 		.set	UNDEFINED_MODE,		0x1B
> 		.set	ABORT_MODE,			0x17
> 		.set	SUPERVISOR_MODE,	0x13
> 		.set	IRQ_MODE,			0x12
> 		.set	FIQ_MODE,			0x11
> 		.set	USER_MODE,			0x10
> 
> 		.text
> 		.arm
> 		.align	0
> 
> # exception vectors
> 		ldr		pc, reset_handler_addr
> 		ldr		pc, undefined_instruction_handler_addr
> 		ldr		pc, software_interrupt_handler_addr
> 		ldr		pc, prefetch_abort_handler_addr
> 		ldr		pc, data_abort_handler_addr
> 		ldr		pc, endless_loop
> 		ldr		pc, irq_handler_addr
> 		ldr		pc, fiq_handler_addr
> 
> reset_handler_addr:					.long	reset_handler
> undefined_instruction_handler_addr:	.long
> undefined_instruction_handler
> software_interrupt_handler_addr:	.long
> software_interrupt_handler
> prefetch_abort_handler_addr:		.long
> prefetch_abort_handler
> data_abort_handler_addr:			.long	data_abort_handler
> 									.long	0	/* ARM-reserved vector */
> irq_handler_addr:					.long	irq_handler
> fiq_handler_addr:					.long	fiq_handler
> 
> .global	reset_handler
> reset_handler:
> 		msr		cpsr_c, #UNDEFINED_MODE
> 		ldr		sp, =__UNDEFINED_SP__
> 		msr		cpsr_c, #ABORT_MODE
> 		ldr		sp, =__ABORT_SP__
> 		msr		cpsr_c, #SUPERVISOR_MODE
> 		ldr		sp, =__SUPERVISOR_SP__
> 		msr		cpsr_c, #IRQ_MODE
> 		ldr		sp, =__IRQ_SP__
> 		msr		cpsr_c, #FIQ_MODE
> 		ldr		sp, =__FIQ_SP__
> 		msr		cpsr_c, #USER_MODE
> 		ldr		sp, =__USER_SP__
> # setup a default stack limit (when compiled with
> "-mapcs-stack-check").
> 		sub		sl, sp, #__USER_STACK_SIZE__
> # relocate .data(rw) section (copy from FLASH to RAM).
> 		ldr		r1, =__text_end__
> 		ldr		r2, =__data_start__
> 		ldr		r3, =__data_end__
> reset_handler_L01:
> 		cmp		r2, r3
> 		ldrlo	r0, [r1], #4
> 		strlo	r0, [r2], #4
> 		blo		reset_handler_L01
> # clear .bss(rw) section.
> 		mov		r0, #0
> 		ldr		r1, =__bss_start__
> 		ldr		r2, =__bss_end__
> reset_handler_L02:
> 		cmp		r1, r2
> 		strlo	r0, [r1], #4
> 		blo		reset_handler_L02
> # set up arguments to main and call.
> 		mov		r0, #0
> 		mov		r1, #0
> 		bl		main
> 
> .global endless_loop
> endless_loop:
> 		b		endless_loop
> 
> 		.end
> 
> [lpc2104.ld]
> 
> MEMORY
> {
> 	FLASH(rx)	: ORIGIN = 0x00000000, LENGTH = 128K
> 	RAM(rw)		: ORIGIN = 0x40000000, LENGTH = 16K
> }
> 
> __STACK_START__				= 0x40000000 + 16K;
> 
> __UNDEFINED_STACK_SIZE__	= 0x0004;
> __ABORT_STACK_SIZE__		= 0x0004;
> __SUPERVISOR_STACK_SIZE__	= 0x0004;
> __FIQ_STACK_SIZE__			= 0x0004;
> __IRQ_STACK_SIZE__			= 0x0080;
> __USER_STACK_SIZE__			= 0x0200;
> 
> __UNDEFINED_SP__		= __STACK_START__ - 4;
> __ABORT_SP__			= __UNDEFINED_SP__ -
> __UNDEFINED_STACK_SIZE__;
> __SUPERVISOR_SP__		= __ABORT_SP__ -
> __ABORT_STACK_SIZE__;
> __FIQ_SP__				= __SUPERVISOR_SP__ -
> __SUPERVISOR_STACK_SIZE__;
> __IRQ_SP__				= __FIQ_SP__ - __FIQ_STACK_SIZE__;
> __USER_SP__				= __IRQ_SP__ - __IRQ_STACK_SIZE__;
> 
> SECTIONS
> {
> 	. = 0;
> 	.text :
> 	{
> 		__text_start__ = .;
> 		startup.o(.text)
> 		*(.text)
> 		*(.glue_7)
> 		*(.glue_7t)
> 	}
> 	>FLASH =0
> 	. = ALIGN(4);
> 	.rodata :
> 	{
> 		*(.rodata)
> 		*(.rodata*)
> 	}
> 	>FLASH
> 	. = ALIGN(4);
> 	__text_end__ = .;
> 
> 	.data : AT(__text_end__)
> 	{
> 		__data_start__ = .;
> 		*(.data)
> 	}
> 	>RAM
> 	. = ALIGN(4);
> 	__data_end__ = .;
> 
> 	.bss :
> 	{
> 		__bss_start__ = .;
> 		*(.bss)
> 		*(COMMON)
> 	}
> 	>RAM
> 	. = ALIGN(4);
> 	__bss_end__ = .;
> }
> 
> PROVIDE(undefined_instruction_handler	= endless_loop);
> PROVIDE(software_interrupt_handler		= endless_loop);
> PROVIDE(prefetch_abort_handler			= endless_loop);
> PROVIDE(data_abort_handler				= endless_loop);
> PROVIDE(irq_handler						= endless_loop);
> PROVIDE(fiq_handler						= endless_loop);
> 
> 
> __________________________________________________
> Do You Yahoo!?
> Tired of spam?  Yahoo! Mail has the best spam protection around 
> http://mail.yahoo.com

Attachments

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.