Yahoo Groups archive

Lpc2000

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

Thread

[gnu arm] interrupts don't work :/

[gnu arm] interrupts don't work :/

2004-08-29 by Pawel Sikora

Hi,

I have the LPC2104 kit.
I've used the IAR-System for developing so far
but I would like to try the GNU ARM.
I've rebuilt several existing applications
that use interrupts but they don't work with GNU ARM.

How can I use interrupts with GNU ARM?
Attached I send an example of a code that works
with IAR and doesn't work with GNU ARM.

Is the crt0.s or led.c a problem?

Help is appreciated.


	
		
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - 100MB free storage!
http://promotions.yahoo.com/new_mail 

[Non-text portions of this message have been removed]

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

2004-08-29 by Pawel Sikora

The attachment:
http://149.156.124.14/~pluto/tmp/led.zip


	
		
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - 100MB free storage!
http://promotions.yahoo.com/new_mail

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

2004-08-30 by lpc2100

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

http://groups.yahoo.com/group/lpc2000/message/223

--- In lpc2000@yahoogroups.com, Pawel Sikora <rzulfik@y...> wrote:
Show quoted textHide quoted text
> Hi,
> 
> I have the LPC2104 kit.
> I've used the IAR-System for developing so far
> but I would like to try the GNU ARM.
> I've rebuilt several existing applications
> that use interrupts but they don't work with GNU ARM.
> 
> How can I use interrupts with GNU ARM?
> Attached I send an example of a code that works
> with IAR and doesn't work with GNU ARM.
> 
> Is the crt0.s or led.c a problem?
> 
> Help is appreciated.

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

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:
Show quoted textHide quoted text
> 
> --- 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

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

2004-09-24 by Konstantin V. Novick

As far as I know, attribute interrupt in GCC works incorrect.
It's better to use an assembler container, for example:
.extern My_C_ISR_Func
.global ISR_Func

.text
.code 32

ISR_Func:
     stmfd   sp!, {r0-r12, lr}
     bl         My_C_ISR_Func
     ldmfd   sp!, {r0-r12, lr}
     subs     pc, lr, #4
.ltorg

-- 
     �������!
         ���������� aka cd_racer


[Non-text portions of this message have been removed]

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

2004-09-24 by Anton Erasmus

On 24 Sep 2004 at 19:49, Konstantin V. Novick wrote:

> 
> As far as I know, attribute interrupt in GCC works incorrect.
[Stuff snipped]

I believe this has been fixed in the newer versions of GCC.

Regards
   Anton Erasmus

> 
> 
> ------------------------ Yahoo! Groups Sponsor
> --------------------~--> $9.95 domain names from Yahoo!. Register
> anything. http://us.click.yahoo.com/J8kdrA/y20IAA/yQLSAA/dN_tlB/TM
> --------------------------------------------------------------------~-
> > 
> 
> 
> Yahoo! Groups Links
> 
> 
> 
> 
> 
> 
> 

-- 
A J Erasmus

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

2004-09-26 by cd_racer2

You can do the following:

MEMMAP = MEMMAP_USERRAMMODE;
*(volatile INT32U *)(0x00000018L) = 0xE51FFFF0L;

(MEMMAP - see page 33 of UM_LPC2106_2105_2104 - user manual,
also you see page 70 of UM_LPC2106_2105_2104).

I haven't use GCC's interrupt attribute because of the old GCC version
(3.2.0). But from this thread I think that GCC use a single
entry-point for IRQ and at this point you are to do a proper jump
(using VICVectAddr register, for example). Thus you can use different
ARM-based microcontrollers in single way (in fact, the addresses of
interrupt registers are different on Atmel's AT91RM9200 and Philips
LPC2106). But in this case you are to write your IRQ entry-point
function in a proper way.

But another way is to place at IRQ vector exception's address
(0x00000018) an instruction, that loads an address from VICVectAddr
register to PC-register. Thus, there's no need to think about
entry-point function. But in this case you are to proper init the
exception vector (according to microcontroller's user manual) and
write a proper container for your's IRQ function.

Small correction

2004-09-27 by Konstantin V. Novick

GCC doesn't use the single entry-point for interrupts,  but the led 
example does.

-- 
    �������!
        ���������� aka cd_racer



[Non-text portions of this message have been removed]

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.