LPC1768 remap isr to ram

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC1768 remap isr to ram

1,196 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by navman on Mon Jul 04 21:07:03 MST 2011
Hi,
Is there any example code to make the ISR to run out of SRAM. I know that it involves the following steps:
1) Copy ISR from flash to SRAM.
2) Copy vector table to SRAM
3) Remap vector table to SRAM using VTOR

I'm struggling here. Any examples for such code? I'm using the LPC1768 processor with LPCxpresso IDE/compiler & need to have the EXT3 running out of SRAM as I need to do this to avoid the annoying lag(~500ns) when jumping to interrupt (maybe due to flash access resulting from a page fault).
0 Kudos
12 Replies

1,011 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by navman on Fri Jul 08 04:59:40 MST 2011
If I had the liberty of choosing hardware I would have gone for an FPGA or atleast an SPI based A/D. Unfortunately, I have to work with what we have already have :(
0 Kudos

1,011 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Fri Jul 08 04:29:49 MST 2011
Just thinking out loud:

what if you serialize the data and use an SSP interface with DMA ?
You could combine the 2 x 8 bits into 1 16 bits word and transfer a word at a time and let the SPI DMA handle things.

This takes a lot of the stress out of your program.
Hardware should not be too difficult: two 8 bits registers with a parallel load (one clocked on the L-H edge, the other on the H-L edge). Feed the (16 bits) output into a 16 bits shift register with serial out and you're almost done.

Regards,

Rob
0 Kudos

1,011 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by navman on Thu Jul 07 23:57:10 MST 2011
Rob65, Thanks for your detailed analysis. We are doing a highly time-sensitive application so even if we can save 100ns, it would make a big difference. I've contacted NXP for support and waiting for their response.

The application actually is to read a high speed 16bit-ADC which has a 8-bit parallel output & a data ready pin. The data ready pin toggles every 500ns & we need to be able to read a high byte at rising edge and a low byte at the falling edge then store the bytes into a buffer for processing later. Leave alone the buffering, we are struggling to even try and read the data!
0 Kudos

1,011 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Wed Jul 06 23:26:53 MST 2011

Quote: navman
The 12 cycles latency is as per Cortex M3 specifications mentioned here



I call that a "powerpoint specification".
Looks good on a presentation but if you want to know the real ins and outs you might want to read the ARM reference manuals.

From the Cortex M3 Technical Reference manual:


Quote:
3.9.1 Exception handling

There is a maximum of a 12 cycle latency from asserting the interrupt to execution of the
first instruction of the ISR when the memory being accessed [COLOR=Black]has no wait states being
applied[/COLOR]. The first instruction to be executed is fetched in parallel to the stack push.

and later on in that same manual in the description of the vectored interrupt controller:

Quote:
6.2.2 Level versus pulse interrupts

if the interrupt is asserted for at least one cycle, the
NVIC latches the pend bit. When the ISR activates, the pend bit is cleared.

So this firstly tells me that it takes 12 cycles to fetch the instruction, not execute. And that it takes longer if waitstates are applied.
Running from RAM means (AFAIK) no waitstates.

I compiled your code to see what the assembly looks like:

000003f4 <EINT3_IRQHandler>:
     3f4:    b480          push    {r7}
     3f6:    af00          add    r7, sp, #0
     3f8:    f248 0380     movw    r3, #32896    ; 0x8080
     3fc:    f2c4 0302     movt    r3, #16386    ; 0x4002
     400:    f44f 6200     mov.w    r2, #2048    ; 0x800
     404:    62da          str    r2, [r3, #44]    ; 0x2c
     406:    f24c 0340     movw    r3, #49216    ; 0xc040
     40a:    f2c2 0309     movt    r3, #8201    ; 0x2009
     40e:    f04f 0201     mov.w    r2, #1
     412:    775a          strb    r2, [r3, #29]
     414:    f24c 0340     movw    r3, #49216    ; 0xc040
     418:    f2c2 0309     movt    r3, #8201    ; 0x2009
     41c:    f04f 0201     mov.w    r2, #1
     420:    765a          strb    r2, [r3, #25]
     422:    46bd          mov    sp, r7
     424:    bc80          pop    {r7}
     426:    4770          bx    lr
But that is without optimizations (-O0) but I think you are smarter
so this gets (with -O2 or -O3):

00000334 <EINT3_IRQHandler>:
     334:    f248 0180     movw    r1, #32896    ; 0x8080
     338:    f24c 0340     movw    r3, #49216    ; 0xc040
     33c:    f2c2 0309     movt    r3, #8201    ; 0x2009
     340:    2201          movs    r2, #1
     342:    f2c4 0102     movt    r1, #16386    ; 0x4002
     346:    f44f 6000     mov.w    r0, #2048    ; 0x800
     34a:    62c8          str    r0, [r1, #44]    ; 0x2c
     34c:    775a          strb    r2, [r3, #29]
     34e:    765a          strb    r2, [r3, #25]
     350:    4770          bx    lr
So it takes 8 instructions before the FIOCLR gets executed but before that the store to IO2IntClr is performed and the store instructions do have some wait cycles, depending on the programming of your LPC_SC->PCLKSEL1 settings (on reset the GPIOINT runs on cclk/4

With this default I count 12 (interrupt latency) + 1 (GPIOINT latency) + 8 (instructions in the interrupt handler) + 5 (store to GPIOINT) + 1 (GPIO) = 27 cycles before I expect anything on the GPIO output pin.
I assume that there is no latency between the store to FIOCLR and the toggle on the GPIO line and there is no delay in detecting the GPIO interrupt (the lpx17xx  states that interrupt edge detection is asynchronous - please note: level detection is not!)

Still not the 400 ns you are seeing but it is getting closer.

Regards,

Rob
0 Kudos

1,011 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by navman on Wed Jul 06 20:12:38 MST 2011
The 12 cycles latency is as per Cortex M3 specifications mentioned here:

http://www.arm.com/products/processors/cortex-m/cortex-m3.php?tab=Specifications


The toggling of pin is taking 10ns (core running at 100MHz) as measured on an oscilloscope. So I've accounted for this small difference. However when I measure the falling edge of GPIO pin (I use P2.11) to the toggling of P2.8,  I see >400ns lag.

Here is the code for the GPIO interrupt:

__attribute__ ((__section__(".data.ramfunc")))
void EINT3_IRQHandler (void)
// All GPIO interrupts are handled in EINT3
{
LPC_GPIOINT->IO2IntClr = (0x01<<11);//clear interrupt on P2.11

LPC_GPIO2->FIOCLR1 = 0x01;//toggle P2.8
        LPC_GPIO2->FIOSET1 = 0x01;
}

0 Kudos

1,011 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Wed Jul 06 12:02:22 MST 2011
I am not sure what the 12 cycles is.
Is this from the hardware event to the cortex acknowledging the interrupt or is this from hardware event to executing the first instruction in the interrupt handler?
I have not looked at this.

Toggling a pin takes some time, it takes a few AR instructions to address the proper register and there are some wait states on access to the peripheral.

Here is a link to another thread where GPIO speed is discussed.
Apparently it makes a big different how you write your code and compile it.
Even a simple thing as toggling a GPIO pin can take quite some time.

Hope this helps.

Rob
0 Kudos

1,011 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by navman on Wed Jul 06 10:54:04 MST 2011
Thanks to the suggestions above, I've got the ISR working from RAM. However there is still a lot of lag, about 400ns (~40 cycles) from the falling edge to actually toggling a pin inside the interrupt. Any explanation why there is this much lag? The Cortex M3 specifies 12cycles interrupt lag. Is the LPC1768 any different?
0 Kudos

1,011 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Wed Jul 06 00:59:17 MST 2011

Quote: navman

I should probably use the VTOR register for remapping in LPC1768. But there is no CMSIS access to this register nor defined in the header files.



Strange ... on my system SCB->VTOR is defined in core_cm3.h which is automatically there when you do a #include "LPC17xx.h".
I can do a SCB->VTOR = xxx in my code and VTOR turns blue so even Eclipse knows it is there.

You will have to place the vector table in RAM , I looked at the standard linker scripts and thought it should be done as such:
__attribute__ ((__section__(".data.$RAM2.vectors")))
uint32_t *vectors[52];
But ... this does not work :eek:
and after testing around a bit I discovered that any section name that does not exist (e.g. using __section__(".bogus"))) does not even give me a warning :eek::(:mad:

I tend to call this a bug.
For me, section names should never have a "catch all". Typos should not be allowed.

Regards,

Rob
0 Kudos

1,011 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by jharwood on Tue Jul 05 22:41:42 MST 2011

Quote:

But there is no CMSIS access to this register nor defined in the header  files. I tried to use a ptr to this register address & tried  assigning the value in main but it results in a hard fault whenever the  interrupt occurs.

So any suggestions?        

Does this work?
SCB->VTOR = (vtable_addr & 0x1FFFFF80);
0 Kudos

1,011 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by navman on Tue Jul 05 20:33:11 MST 2011
Thanks for your replies. The closet I could already find to what I need was this post:

http://knowledgebase.nxp.com/showthread.php?t=403&page=2

However, I'm having problems with this line:
LPC_SYSCON->SYSMEMREMAP = 1;

I should probably use the VTOR register for remapping in LPC1768. But there is no CMSIS access to this register nor defined in the header files. I tried to use a ptr to this register address & tried assigning the value in main but it results in a hard fault whenever the interrupt occurs.

So any suggestions?
0 Kudos

1,011 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Rob65 on Tue Jul 05 13:45:57 MST 2011

Quote: CodeRedSupport
In the first place, I suggest that you read some of the previous forum posts in this area...



great, if NXP now just would remove the search in this forum and place it with google search I would have found this myself ...
Strange how the search function on this site still does not work.

Dear NXP, would you just remove this and replace it with a google site search instead.

Rob
0 Kudos

1,011 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Tue Jul 05 12:05:22 MST 2011
In the first place, I suggest that you read some of the previous forum posts in this area...

http://www.lmgtfy.com/?q=site%3Aknowledgebase.nxp.com+isr+ram

On the general subject of locating blocks of code into RAM, there is also the following FAQ...

http://support.code-red-tech.com/CodeRedWiki/CodeInRam

Regards,
CodeRedSupport
0 Kudos