imx6 - How to make GPIO toggle faster

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

imx6 - How to make GPIO toggle faster

8,977 Views
anson
Contributor II

I'm using iMX6Q without any OS. Toggling GPIO was intended for testing purpose.

From the testing, the output frequency is only 700kHz. It's far less then expectation.

Do I miss anything?

---------

DETAILS

---------

- All settings remain default, one GPIO pin in GPIO_18 group was used.

- 4 Assembly lines was written for this routine.

     - read GPIO register

     - toggle GPIO pin (using XOR logic)

     - write to GPIO register

     - jump to 1st line

- Clock setting is shown as below:

     - PLL1 - System       : 792 MHz

     - PLL2 - System Bus   : 528 MHz

     - IPG clock           :  66 MHz

     - AHB clock           : 132 MHz

     - AXI clock           : 264 MHz

     - DDR clock           : 528 MHz

Labels (1)
13 Replies

4,680 Views
igorpadykov
NXP Employee
NXP Employee

Hi Anson,

seems one can only enable caches (if they are not

yet enabled). Also one can try to write on assembler or

try another attached example (based on SDK).

Actually there are no other ways to make GPIO to toggle faster.

"MX6_PLATFORM_SDK "

http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=i.MX6Q&nodeId=018rH3ZrDRB24A&fpsp=1&t...

-----------------------------------------------------------------------------------------------------------------------

Note: If this post answers your question, please click the Correct Answer button. Thank you!

-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply

4,680 Views
EgleTeam
Contributor V

Hi,

I've tested 5.5Mhz in kernel space (3.0.5) using memory mapped + pointers (writel/readl is 100% slower): would be possible to improve this frequency using inline assembler?. Is there any example of inline assembler handling GPIOs?

Thanks,

Manuel.

0 Kudos
Reply

4,680 Views
anson
Contributor II

Hi EgleTeam,

You got a stable 5.5Mhz? or 5.5Mhz once in a while?

Rgds,

Anson

0 Kudos
Reply

4,680 Views
EgleTeam
Contributor V

Hi Anson,

What do you mean with "stable"? All the time?. If do: that's not possible. With a "regular" linux  100% not possible. Using a RTOS (i.e.: Xenomai) you can get a "relatively" stable throughput but of course not 5.5mbps/gpio. What I meant is we got toggle a GPIO at 5.5Mhz measured with an oscilloscope.

I hope to be helpful.

Manuel.

0 Kudos
Reply

4,680 Views
anson
Contributor II

Hi EgleTeam,

I understand your point. I'm wondering how you could get 5.5Mhz waveform. Mind to share your toggling code and setting?

I'm using RTOS (QNX), it toggle at 1.6Mhz (Full waveform, from rising edge to next rising edge).

I tried assembler without OS, it toggle at 1.0Mhz (very stable, error of 0.003Mhz max).

CODE:

while(1){

     GPIO = 0x1

     GPIO = 0x0

}

Setting:

CPU = 982 MHz

AHB = 132 Mhz

IPG  = 66Mhz

Rgds,

Anson

0 Kudos
Reply

4,680 Views
EgleTeam
Contributor V

Anson,

--------------------

#define GPIO_VAL            0x0

#define GPIO_DIR            0x4

static void *GPIO4_BADDR;

..............................

GPIO4_BADDR = ioremap(0x20A8000, 28);

writel(0x00800000,GPIO4_BADDR+GPIO_DIR);


for(i=0;i<100;i++){

         writel(0x00800000,GPIO4_BADDR+GPIO_VAL);

         writel(0,GPIO4_BADDR+GPIO_VAL); 

}

-----------------------------------

Toggle pin 24 - bank 4.

Hope to be helpful.

Manuel.

4,680 Views
anson
Contributor II

Hi Manuel,

I still get 1.6Mhz with your code.

BTE, I have few question:

1. Which OS are you using?

2. Which Processor are you using?

3. What is your CPU, AHB, IPG Clock?

Rgds,

Anson

0 Kudos
Reply

4,680 Views
EgleTeam
Contributor V

1. Kernel 3.10.17

2. Solo at 1 Ghz (512MB DDR3).

3. No idea what peripheral freq. is used. If you tell me where to, I'll check it.

Regards,

Manuel.

0 Kudos
Reply

4,680 Views
EgleTeam
Contributor V

Anson,

so sorry: I copied/pasted some of our code too fast.

Please use  a pointer instead of "writel":

volatile u32 *gpio4_val = (u32 *)GPIO4_BADDR;

for(i=0;i<100;i++){

       *gpio4_val = 0x00800000;

       *gpio4_val = 0;

}

freescale.png

Merry Christmas to all the community!

Manuel.

0 Kudos
Reply

4,680 Views
ZeeFrench
NXP Employee
NXP Employee

Nice programming and record, I was only able to toggle it at 3.6 MHz ! You can otpmize a few cycles @ 1 GHz but at one point there is a limit due to the fact we have to go through caches, a couple of crossbars and a peripheral bridge @ 66 MHz. The trick to reproduce it with platform SDK (and QNX, they should be aware of this) was to enable caches, MMU and configure mmu entry for those as a standard entry and not as strongly ordered as it is by default, it allows the accesses to be buffered :

+ mmu_enable();

+ // Enable L2 Cache
+ _l2c310_cache_setup();

+ _l2c310_cache_invalidate();

+ _l2c310_cache_enable();

- mmu_map_l1_range(0x00a00000, 0x00a00000, 0x0f600000, kStronglyOrdered,kShareable, kRWAccess); // More peripherals

+ mmu_map_l1_range(0x00a00000, 0x00a00000, 0x0f600000, kDevice, kShareable, kRWAccess); // More peripherals

4,680 Views
EgleTeam
Contributor V

I forgot, there's another way from userspace, perhaps "more comfortably" than implement a kernel driver/module as we did: mapping on "/dev/mem". Here an example for i.MX233:

OLINUXINO/gpio-mmap.h at master · OLIMEX/OLINUXINO · GitHub

Now we are testing this code for i.MX28 but shouldn't be hard to port it for i.MX6.

Regards,

Manuel.

4,680 Views
EgleTeam
Contributor V

Anson,

I will look for the code tomorrow in the office and share. On any case it was not very complicated, just write to the RAM location where the gpio value register (GPIOx_DR)  is mapped.

Regards,

Manuel.

0 Kudos
Reply

4,680 Views
igorpadykov
NXP Employee
NXP Employee

Hi EgleTeam

I think there is no ready assembler example, however you

can easy make assembler program using examples in SDK.

Best regards

chip