We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
Hi All, I am not an expert on ARM yet but an average guy for uC.
I am trying to get hands on with LPC2148 and plan to use it in next project.
One wonderful thing that I came across (I come form a background where we use 8051/mega16 uC) is USB IAP. So without any UART/Serial cable, I can flash program just by using USB cable.
Did some changes like 1. generating bin file (using fromelf --bin ....) and 2. changing IROM1 from 0x0 to 0x2000
to make program work with IAP.
I tasted some program and those worked very well.
But the issue is arising when I try to use Timer0 interrupt. I see controller getting stuck somewhere just after 1st int.
I checked with "Use Memory Layout with Target Dialog" selected and de-selected both. Nothing worked.
This has something to do with vector table but I am not able to make out what?
Any help on this would be appreciated.
Remember, I just made 3 above mentioned changes after creating new project. If there is anything else, please let me know.
Interrupts must be disabled during IAP (see user manual). You need to get your chip into privileged mode (use a SWI) to call "__disable_irq". This site explains how to do that, as well as different user manuals.
Thanks Tamir Michael for quick turn-around.
So in simple words, I cannot use interrupts(any interrupt like Timer, External, etc..) in the program if it is loaded via IAP. Is that correct?
(Sorry for my words. Actually too much of technical confuses me.)
I am using IAP available at Keil's site only. I did read that interrupts are not used but then I thought that I was for IAP's program. i.e. bootloadr itself.
I didn't know that the program that I load via IAP cannot have interrupt.
Any work around?
Thanks, Urvish.
No. Your program cannot handle interrupts _while it is executing IAP_. While it is not - it can handle interrupts.
A program that is loaded at a different place need to remap the interrupt vector table. There are settings in the startup file to do this - copying the interrupt vector table into RAM and remap to that address.
Without remapping, the processor would search for an interrupt handler within your boot loader code.
Thanks Per and Tamir.
Now I unserstood. When program is being copied via IAP it cannot handle int. But once IAP is done copying and control of CPU is handed over the program we have loaded, it can handle interrupt.
But as earlier IVT was at different place (mostly earlier location of ROM), it needed to be relocated. (As IAP is in ROM location 0x0 to Ox2000.) IVT will be after 0x2000.
Thanks again for being good teacher.
Don't forget to actually reset the chip using the watchdog rather than to simply jump to the address of the newly flash binary.
Sorry for being a little dumb here. But, I am actually using a ready hex file provided by the vendor of the board (mostly AN10711 based) for USB IAP programmer.
I have no control over the code of IAP.
IAP works like this... While power up, if I keep P0.15 low, it enters IAP mode, if I keep it high, it jumps directly to user program mode (starting from 0x2000).
Will it still be possible for me to use interrupts or I should have the code of IAP to use interrupt.
The limitations above apply to the bootloader (see AN10711). The bootloader should disable interrupts while flashing your program. You have full control over IAP - you have the bootloader source as well, not?
I think you misunderstood the issue. I have 2 programs now.
1. USB_IAP.hex : loaded at location 0x0:0x1FFF 2. my_prog.bin : loaded from 0x2000:0x2100 via IAP.
Now my_prog.bin has already been loaded via IAP.
Now, when I reset the board, first IAP will run, but as entry to bootloader is not asserted, it will jump to my_prog.bin.
Now, my_prog.bin is using timer interrupt. So, when my_prog.bin is running, (and IAP is not running), will I be able to use interrupt?
I checked the Startup.s file and couldn't figure out much. I do not have code for USB_IAP.hex. I have code of my_prog.bin.
Now, what changes will I have to make to make interrupt of my_prog.bin work.
Per, your inputs will be much appreciated. Tamir, thanks to being with me on this.
Urvish Gohil => Now, what changes will I have to make to make interrupt of my_prog.bin work.
Per => A program that is loaded at a different place need to remap the interrupt vector table. There are settings in the startup file to do this - copying the interrupt vector table into RAM and remap to that address. Without remapping, the processor would search for an interrupt handler within your boot loader code.
On the Startup file of my_prog.bin: Set Options-> Asm-> Conditional Assembly Control Symbols: RAM_INTVEC REMAP RAM_MODE
And check what RAM_INTVEC REMAP RAM_MODE will do for you.
Thanks John for that wonderful and easy explanation. While I did get what Per said, but didn't know how to do it.
Right now I do not have access to the board. Will post here the my observation as soon as I get it(Hope to keep some smileys than).
Hi John, I just tried adding "RAM_INTVEC REMAP RAM_MODE" but it didn't worked.
Here is what I tried. 1. I just wrote a prog in keil which toggles 2 port pins. 1st by a while loop, 2nd by timer. 2. Without adding anything I simulated it in keil. (IROM1 still from 0x0, No remapping) 3. This works well and I see both of the port pins toggling.
Now I made a simple change of Adding "RAM_INTVEC REMAP RAM_MODE". I recompiled the code and simulated. Here, I saw that, as soon as int is occurred, LPC jumps to "LDR PC, [PC, #-0x0FF0]", but does not move from that point.
Moreover, I see words REMAP and RAM_MODE in Startup.s but not the RAM_INTVEC. I am using Startup.s provided by keil only.
KEIL has quite a lot startup.s/LPCooxx.s You need another startup.s like this: rtime.felk.cvut.cz/.../lpc21xx-boot
+# Memory Mapping (when Interrupt Vectors are in RAM) + .equ MEMMAP, 0xE01FC040 /* Memory Mapping Control */ +.ifdef RAM_INTVEC + LDR R0, =MEMMAP + MOV R1, #2 + STR R1, [R0] +.endif
I think what I have is exactly this only.
; Memory Mapping (when Interrupt Vectors are in RAM) MEMMAP EQU 0xE01FC040 ; Memory Mapping Control IF :DEF:REMAP LDR R0, =MEMMAP IF :DEF:EXTMEM_MODE MOV R1, #3 ELIF :DEF:RAM_MODE MOV R1, #2 ELSE MOV R1, #1 ENDIF STR R1, [R0] ENDIF
By defining REMAP and RAM_MODE, this will do exactly what your code snippets does with RAM_INTVEC.
In the Startup.s that I am using, what shown above is the only place where REMAP and RAM_MODE is used. There are no other defines.
I guess your startup.s is very like this one:
forum.sparkfun.com/viewtopic.php
If so, you need to figure out how it accomplishes what Per told you.
And, I don't think you can easily simulate USB_IAP.hex + my_prog.bin, it would be easier to run them on the real hardware.