Yahoo Groups archive

Lpc2000

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

Message

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

2004-09-03 by Pawel Sikora

--- lpc2100 <lpc2100@...> 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.