GPIO Speed part 2 - Cortex M0

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

GPIO Speed part 2 - Cortex M0

855 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ArneB on Tue Apr 26 11:22:18 MST 2011
Hi guys,

very interesting discussion about the GPIO toggling speed. I am wondering, if i can use some of your  advices for the M0 (LPC111x familiy), too ? Currently i am struggling to  speed up the GPIO switching on a LPC1114, but the maximum rate i am  able to achieve is really slow, especially for turning an input to a  defined output (yes, RTFM was done, optimizations are enabled [-O3] :D).
Therefore i would like to ask the experts: Are there any special hints for the LPC111x part concerning the GPIOs ?

How about the new LPC12xx family ? I have just dived into the user  manual and it seems, that GPIO switching is much improved. Does anyone  have any experience ?
0 Kudos
10 Replies

690 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ArneB on Thu Apr 28 23:49:18 MST 2011
No, it's a daily work assignment from our boss... :cool:
And as we are clever & smart engineers, we can make the miracle happen... As usual... :)

Back to the topic: We need this speed only for a very short time. We don't have any communication during this period, therefore we can safely disable all interrupts. I know. it's ugly & dirty, but i am mid-age and i need the money... :D

Nevertheless we are trying to tweak the algorithm to relax the speed requirements. My stomach tells me, that this would be the better way...
0 Kudos

690 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by larryvc on Thu Apr 28 15:14:48 MST 2011

Quote: fmackenthun
Hi Guys,

we need to perform the following within about 250ns @ 12MHz

1. change pin direction to output/input
2. change value to high/low

As Arne mentioned we also need defined output and high impedance (input) levels.



ArneB and fmackenthun, This sounds like a homework assignment given by a very sadistic teacher.:)
0 Kudos

690 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by CodeRedSupport on Thu Apr 28 14:12:41 MST 2011

Quote: ArneB
Yep, that's correct. But if you store the target values in registers, you only have a "move register,memory" instruction (sorry, I don't know the exact assembler syntax, but i think you get the point... :)). Even if you have to load a constant into a register it should be done in two cycles: "move #const, register" and "move register,memory".
Or do i miss something ? :rolleyes:



Well, what else is happening on the system? If the ONLY thing you are doing is (in pseudo assembler):
loop:
  mov const, r1
  mov r1, #register
  br loop

Then you might be able to get the speed you want, but, if you are doing ANYTHING else (such as doing this on an interrupt), then there is no way.

i.e. if you are trying to toggle something at 4MHz, then it is impossible the code to be doing anything else, which makes this a very expensive oscillator...
0 Kudos

690 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ArneB on Thu Apr 28 02:23:39 MST 2011
Yep, that's correct. But if you store the target values in registers, you only have a "move register,memory" instruction (sorry, I don't know the exact assembler syntax, but i think you get the point... :)). Even if you have to load a constant into a register it should be done in two cycles: "move #const, register" and "move register,memory".
Or do i miss something ? :rolleyes:
0 Kudos

690 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by TheFallGuy on Thu Apr 28 00:07:24 MST 2011

Quote: fmackenthun
Hi Guys,

we need to perform the following within about 250ns @ 12MHz

1. change pin direction to output/input
2. change value to high/low

As Arne mentioned we also need defined output and high impedance (input) levels.

So far I achieved about 165ns @ 48MHz without using a pull-up/down. This would be about 660ns @12Mhz. Which is way to slow considering that I didn't even use pull-ups.



Are you being a little ambitious? At 12MHz, each cycle is 83nS. 250nS is therefore 3 cycles. That is AT BEST 3 instructions...
0 Kudos

690 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by fmackenthun on Wed Apr 27 23:43:05 MST 2011
Hi Guys,

we need to perform the following within about 250ns @ 12MHz

1. change pin direction to output/input
2. change value to high/low

As Arne mentioned we also need defined output and high impedance (input) levels.

So far I achieved about 165ns @ 48MHz without using a pull-up/down. This would be about 660ns @12Mhz. Which is way to slow considering that I didn't even use pull-ups.
0 Kudos

690 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by NXP_Europe on Wed Apr 27 14:15:19 MST 2011
Hello ArneB,

what would be the optimal frequency you need for the 'switched capacitor algorithm'?
0 Kudos

690 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by ArneB on Wed Apr 27 00:18:05 MST 2011
@NXP_USA: Thanks for the answer, i will try it in the next minutes and post the results.

@all: There is one more issue with the GPIO implementation on the LPC111x: Switching an input to an output at a defined level without an unwanted intermediate state. Due to the "special" bus-hold architecture it will actively drive the level found at the pin and not the level programmed in the output register. The only way for a proper switching i found is using the internal pull-ups/downs, but this will cost some additional cycles... :mad:

1: Enable pull-up/pull-down resistor to define the desired output level
2: Switch GPIO direction to output
3: Disable pull-up/pull-down

Are there any other ideas how to speed up this switching process ?

For the curious ones: I am trying to implement a switched capacitor algorithm.Therefore i need defined output and high impedance (input) levels.
0 Kudos

690 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by NXP_USA on Tue Apr 26 18:32:47 MST 2011
Here is some example code we have used internally. It toggles P3_2. The code executes from RAM for increased performance (but doing so requires the use of custom linker scripts). One benefit of this coding style is that pPinAccess can be used to update multiple pins in a single write cycle if needed (though this code does not demonstrate how to do so). Running off the IRC at 12MHz toggle rates of 3MHz have been obtained, but bear in mind the design of the PCB being used can impact the toggling performance at higher speeds.

If you're afraid of the RAM functions, simply ignore the first line with "__attribute__".

[B]BEGIN C CODE[/B]

__attribute__ ((section(".ramFunc")))
int main (void)
{
register volatile unsigned int* pPinAccess = &LPC_GPIO3->MASKED_ACCESS[(1<<LED_BIT)];
register const unsigned int mask = (1<<LED_BIT);

LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);

/* Loop forever */
while (1)
{
*pPinAccess = 0;
*pPinAccess = mask;

*pPinAccess = 0;
*pPinAccess = mask;

*pPinAccess = 0;
*pPinAccess = mask;
}
}

[B]END C CODE[/B]
0 Kudos

690 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Ex-Zero on Tue Apr 26 11:28:33 MST 2011

Quote:
Currently i am struggling to  speed up the GPIO switching on a LPC1114...

Struggling with what? Perhaps you could post the struggling part of your struggle :)
0 Kudos