Reply by Timo August 19, 20092009-08-19
andyzammy wrote:
> I'm currently trying to use the INT0 to trigger FIQ. It's the same
> problem as last time: I'm confused because i don't know what offset to
> give the FIQ_Handler line in the startup file. I would have said #-0x134
> but that didn't work when i tried it.

FIQ is not vectored by VIC. Typically the FIQ handler is coded in
assembler starting right from the FIQ vector address. Otherwise the idea
of the FIQs may vanish.

Of course you can alternatively put a direct branch to your C function
into the FIQ vector address.

--

Timo

An Engineer's Guide to the LPC2100 Series

Reply by andyzammy August 19, 20092009-08-19
bump this up please, still not too sure about how this works

Reply by andyzammy August 12, 20092009-08-12
I'm currently trying to use the INT0 to trigger FIQ. It's the same problem as last time: I'm confused because i don't know what offset to give the FIQ_Handler line in the startup file. I would have said #-0x134 but that didn't work when i tried it.

Could someone please explain how this works?

Thanks for your time,
Zammy

Reply by Andy Zammy April 21, 20092009-04-21
--- In l..., "rolf_meeser" wrote:
>
> With this code you will end up in an infinite loop when an IRQ interrupt occurs!
>
> Change the line containing
> LDR PC, IRQ_Addr
> to
> LDR PC, [PC, #-0x120]
>
> This will fetch the handler address from the VIC (VICAddress), and jump to the handler all in one instruction.
>
> Rolf

wow, i've read those comments loads of times and not once did it ever hit me. i can see now how the handlers branch to themselves. dow! i don't really know any assembly so nothing is obvious to me at this point.

the interrupt now works, thanks very much for the fix Rolf, and thanks everyone for their time and posts!
zammy



Reply by rolf_meeser April 21, 20092009-04-21
--- In l..., Andy Zammy wrote:
>
> Vectors: LDR PC, Reset_Addr
> LDR PC, Undef_Addr
> LDR PC, SWI_Addr
> LDR PC, PAbt_Addr
> LDR PC, DAbt_Addr
> NOP /* Reserved Vector */
> LDR PC, IRQ_Addr
> LDR PC, FIQ_Addr
>
> Reset_Addr: .word Reset_Handler
> Undef_Addr: .word Undef_Handler
> SWI_Addr: .word SWI_Handler
> PAbt_Addr: .word PAbt_Handler
> DAbt_Addr: .word DAbt_Handler
> .word 0 /* Reserved Address */
> IRQ_Addr: .word IRQ_Handler
> FIQ_Addr: .word FIQ_Handler
>
> Undef_Handler: B Undef_Handler
> SWI_Handler: B SWI_Handler
> PAbt_Handler: B PAbt_Handler
> DAbt_Handler: B DAbt_Handler
> IRQ_Handler: B IRQ_Handler
> FIQ_Handler: B FIQ_Handler
>

With this code you will end up in an infinite loop when an IRQ interrupt occurs!

Change the line containing
LDR PC, IRQ_Addr
to
LDR PC, [PC, #-0x120]

This will fetch the handler address from the VIC (VICAddress), and jump to the handler all in one instruction.

Rolf

Reply by Andy Zammy April 21, 20092009-04-21
> In a previous post you said that your code is based on an LPC2148 example.
>
> Did you take the whole project, and then modified it for the LPC2368?
> If yes, did you modify the LDR instruction in the startup code at address 0x18?
> The LPC2148 should have something like "LDR PC,[PC,#-0xFF0]", while for the LPC2368 this should be "LDR PC,[PC,#-0x120]".
>
> Just an idea. This is a pretty common mistake...
>
> Rolf

I didn't use a startup file for the 2148, there was only the c code on that site anyway (afaik), i used my own startup file. I have very little understanding about startup and linker files, so there could be a problem in there. I know that interrupts aren't enabled in my startup code, which is why i needed the EnableIRQ functions with the assembly in it. Here is my startup code, just in case anyone needs to look at it:

# *** Startup Code (executed after Reset) ***
# Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs

.equ Mode_USR, 0x10
.equ Mode_FIQ, 0x11
.equ Mode_IRQ, 0x12
.equ Mode_SVC, 0x13
.equ Mode_ABT, 0x17
.equ Mode_UND, 0x1B
.equ Mode_SYS, 0x1F

.equ I_Bit, 0x80 /* when I bit is set, IRQ is disabled */
.equ F_Bit, 0x40 /* when F bit is set, FIQ is disabled */
# Stack Configuration

.equ Top_Stack, 0x40004000
.equ UND_Stack_Size, 0x00000004
.equ SVC_Stack_Size, 0x00000004
.equ ABT_Stack_Size, 0x00000004
.equ FIQ_Stack_Size, 0x00000004
.equ IRQ_Stack_Size, 0x00000080
.equ USR_Stack_Size, 0x00000400
# Starupt Code must be linked first at Address at which it expects to run.

.text
.arm

.global _startup
.func _startup
_startup:
# Exception Vectors
# Mapped to Address 0.
# Absolute addressing mode must be used.
# Dummy Handlers are implemented as infinite loops which can be modified.

Vectors: LDR PC, Reset_Addr
LDR PC, Undef_Addr
LDR PC, SWI_Addr
LDR PC, PAbt_Addr
LDR PC, DAbt_Addr
NOP /* Reserved Vector */
LDR PC, IRQ_Addr
LDR PC, FIQ_Addr

Reset_Addr: .word Reset_Handler
Undef_Addr: .word Undef_Handler
SWI_Addr: .word SWI_Handler
PAbt_Addr: .word PAbt_Handler
DAbt_Addr: .word DAbt_Handler
.word 0 /* Reserved Address */
IRQ_Addr: .word IRQ_Handler
FIQ_Addr: .word FIQ_Handler

Undef_Handler: B Undef_Handler
SWI_Handler: B SWI_Handler
PAbt_Handler: B PAbt_Handler
DAbt_Handler: B DAbt_Handler
IRQ_Handler: B IRQ_Handler
FIQ_Handler: B FIQ_Handler
# Reset Handler

Reset_Handler:

# Initialise Interrupt System
# ...
# Setup Stack for each mode

LDR R0, =Top_Stack

# Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size

# Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size

# Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size

# Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size

# Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size

# Enter User Mode and set its Stack Pointer
MSR CPSR_c, #Mode_USR
MOV SP, R0

# Setup a default Stack Limit (when compiled with "-mapcs-stack-check")
SUB SL, SP, #USR_Stack_Size
# Relocate .data section (Copy from ROM to RAM)
LDR R1, =_etext
LDR R2, =_data
LDR R3, =_edata
LoopRel: CMP R2, R3
LDRLO R0, [R1], #4
STRLO R0, [R2], #4
BLO LoopRel
# Clear .bss section (Zero init)
MOV R0, #0
LDR R1, =__bss_start__
LDR R2, =__bss_end__
LoopZI: CMP R1, R2
STRLO R0, [R1], #4
BLO LoopZI
# Enter the C code
ADR LR, __main_exit
LDR R0, =main
BX R0

__main_exit: B __main_exit
.size _startup, . - _startup
.endfunc
.end



Reply by rolf_meeser April 21, 20092009-04-21
--- In l..., Andy Zammy wrote:

> > What's the size of your IRQ stack? I bet it's too small, so
> > overflows into your System/User stack, trashing it.
>
> the IRQ stack is currently 0x80. i tried making it bigger but it didn't seem to make any difference.

In a previous post you said that your code is based on an LPC2148 example.

Did you take the whole project, and then modified it for the LPC2368?
If yes, did you modify the LDR instruction in the startup code at address 0x18?
The LPC2148 should have something like "LDR PC,[PC,#-0xFF0]", while for the LPC2368 this should be "LDR PC,[PC,#-0x120]".

Just an idea. This is a pretty common mistake...

Rolf

Reply by Andy Zammy April 21, 20092009-04-21
--- In l..., "mjames_doveridge" wrote:

> Well, what happens when you put a debugger breakpoint at the start of the interrupt handler?
>
> There are those in this group that maintain that they can get these complex, embedded systems working without a debugger, but I really do not see how, especially with interrupts and possibly an OS .
>
> Rgds,
> Martin

Unfortunately i do not have access to a jtag debugger and i doubt i will be able to get a hold of one. I will look into it though.

--- In l..., Jan Brittenson wrote:

> What's the size of your IRQ stack? I bet it's too small, so
> overflows into your System/User stack, trashing it.

the IRQ stack is currently 0x80. i tried making it bigger but it didn't seem to make any difference.



Reply by Jan Brittenson April 20, 20092009-04-20
Andy Zammy wrote:
> bump. i still haven't been able to get anywhere with this. any suggestions would be really appreciated.
What's the size of your IRQ stack? I bet it's too small, so
overflows into your System/User stack, trashing it.

Reply by mjames_doveridge April 20, 20092009-04-20
--- In l..., Andy Zammy wrote:
>
> bump. i still haven't been able to get anywhere with this. any suggestions would be really appreciated.
>

Well, what happens when you put a debugger breakpoint at the start of the interrupt handler?

There are those in this group that maintain that they can get these complex, embedded systems working without a debugger, but I really do not see how, especially with interrupts and possibly an OS .

Rgds,
Martin