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.
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.
Are you using this: ics.nxp.com/.../ ==> Boot Loader V2.12 for LPC213x and LPC214x (Apr 12, 2007) And it does not provide source code for bootloader (USB_IAP.hex)?
Take a look at this: it is for LPC23xx. http://www.keil.com/forum/13707/
See if you can debug your my_prog.bin like the below. After all of that, I start my Debug Session. The Disassembly Window shows the Machine Code/ASM Code of the Bootloader (without the Source Code). Then, the Bootloader jumps to my application. So that, I get the state while the Bootloader just finishes its work, and pass the control to my application. I can observe the CPSR and the R13/SP of Supervisor Mode etc, to see if the solutions works properly.
John, I did try the changes on hardware also. Yes, you are correct that simulation cannot be always correct.
BTW, I didn't find this connected to this issue. "Are you using this:
USB_IAP.hex is going to be the secondary bootloader which resides in 128k flash. And, as far as I understand, the link you gave is for primary bootloader which is by default by NXP.
Here is what I am using "">www.nxp.com/search
BTW, Right now I am looking at "http://www.keil.com/forum/13707/" which you gave. Though this tread is for different uC and App Not is also different (AN10759), I think the idea should be same.
Thanks for the pointer. Will have a look at it and post the conclusion here.
Meanwhile, if there is something new, I would be glad to take it.
www.nxp.com/.../LPC2000_Series_Secondary_Bootloader.zip
The above link is not for USB_IAP either. I am sorry.
www.sparkfun.com/.../94
LPC2148 USB Bootloader Tutorial by zagGrad | August 04, 2008 | 17 comments
This link should provide everything you need, except it may not be designed for your hardware, and it is not for KEIL toolchain.
.if (RAM_MODE==0) /* Relocate .data section (Copy from ROM to RAM) */ LDR R1, =_etext LDR R2, =_data LDR R3, =_edata CMP R2, R3 BEQ DataIsEmpty LoopRel: CMP R2, R3 LDRLO R0, [R1], #4 STRLO R0, [R2], #4 BLO LoopRel DataIsEmpty: .endif
www.embeddedrelated.com/.../39585.php
Copying Interrupt vector table to RAM
It is for IAR toolchain.
(9) LDMIA r8!,{r0-r7} ; Load Vectors (10) STMIA r9!,{r0-r7} ; Store Vectors (11) LDMIA r8!,{r0-r7} ; Load secondary vector table (12) STMIA r9!,{r0-r7} ; Store secondary vector table ; Setup Memory Mapping Control to remap the RAM vector area (13) LDR r0,=LPC231X_MEMMAP (14) MOV r1,#2 ; MEMMAP to User RAM mode (15) STRNE r1,[r0,#0] ; Remap Memory, if not remapped already
John, From the other link you gave me (http://www.keil.com/forum/13707/) I found this.
; Copy Exception Vectors to Internal RAM --------------------------------------- RAM_BASE EQU 0x40000000 IF :DEF:RAM_INTVEC ADR R8, Vectors ; Source LDR R9, =RAM_BASE ; Destination LDMIA R8!, {R0-R7} ; Load Vectors STMIA R9!, {R0-R7} ; Store Vectors LDMIA R8!, {R0-R7} ; Load Handler Addresses STMIA R9!, {R0-R7} ; Store Handler Addresses ENDIF
I think this was missing from my Startup.s This also supports your defines "RAM_INTVEC REMAP RAM_MODE".
Giving it a try now.
Hi John, Something good, something bad... I told you about the link from where I got USB_IAP.hex. (originally Memory.hex) which is USB based secondary bootloader.
Link : www.nxp.com/search
Here, with the code of USB bootloader, there is a sample code as well for user program. I used it and copied it over the board (with some modification for my board) (project name : blinky)
And VOILA, It worked.
Now, I am trying to figure out the changes between two.
John, A really strange thing is going on. After the Blinky worked well. I moved back to my earlier project and flash it. It just worked. I'm not sure how.
Even after spending some good, I couldn't figure out the issue.
So I decided to start a new project in keil and just copied the C file from the earlier version (Remember, this file was never touched in the whole process).
I made sure that Startup.s is original only (original of Keil, without RAM_INTVEC).
The only changes I made was to change IROM1 from 0x0 to 0x2000 and added Run Cmd to generate .bin.
NO ADDITION OF REMAP, RAM_MODE or RAM_INTVEC.
And, it worked.
Now, I am totally confused about what is going on.
Just to be careful about data in RAM, I re-plugged the power supply as well. Still it worked.
Did that Blinky made some changes?
I am planning to order one more of the same board. So will check this issue on that also. Till then, do you have some experiments which I should be trying on this board?
It is possible.
=== Flash === Bootloader Vector -> Both Bootloader and Application use this Vector Bootloader PROGRAM Bootloader PROGRAM Bootloader PROGRAM Bootloader PROGRAM Bootloader PROGRAM Bootloader ISR PROGRAM -> Both Bootloader and Application use this ISR ============= Application PROGRAM Application PROGRAM Application PROGRAM Application PROGRAM Application PROGRAM Application PROGRAM
One of the bootloaders you have tried, provided a usable ISR PROGRAM. If you did not erase this usable ISR PROGRAM, every Applications work fine.
LPC2148 seems quite old. LPC23xx/LPC24xx seem a little old. It is now LPC17xx. (LPC13xx?)
I think you are right.
So, in short, If 1. I get a new board (or completely erase the flash) 2. Program the USB Bootloader 3. Copy the newly working binary (not the Blinky)
it will not work immediately. I will need to run blinky once to make it running :)
LPC2148 may be old. But til now I was using AVR (8-bit) controllers. So I planned to move a level up so that next projects can be better.
And, to get familier with the uC, I got this Development board at very good rate. "">www.nex-robotics.com/.../arm7-lpc2148-development-board.html"
This will ramp up the development time.
I surely have a look at LPC17xx/13xx. But now as I have started with this, I plan to understand it properly. So the jump to 17/13xx would be easier.
BTW, thanks for suggestion.
Exception Vectors -> ARM design Vectored Interrupt Controller -> NXP design One of the Exception Vectors is linked to Vectored Interrupt Controller.
LPC21xx / LPC23xx -> ARM7 -> VIC LPC17xx (LPC13xx?) -> ARM Cortex-M -> NVIC
ARM7 is very different from Cortex-M; and due to the foundry process etc, Cortex-M might be cheaper than ARM7. But of course, different projects have different considerations, LPC2148 might still be the best choice for your projects. (When will NXP terminate LPC21xx?)
View all questions in Keil forum