BusOut, PortOut, DigitalOut speedup

After some chatting in the forums about slow I/O, I thought it'd be worth capturing...

  • The speed you could get from a PortOut concept; something that could allow you to write to multiple bits of a single port
  • The speed you could get from a DigitalOut that was optimised more, keeping the same API

Here is the test code:

#include "mbed.h"
#include "PortOut.h"
#include "DigitalOut2.h"

BusOut bus(P1_24, P1_25, P1_26, P1_27, P1_28, P1_29, P1_30, P1_31);
PortOut port(PORT1, 0xFF000000);
DigitalOut out(LED1);
DigitalOut2 out2(LED2);

Timer t;

int main() {

    t.start();
    for(int i=0; i<1000000; i++) {
        bus = 0;
        bus = 0xFF;
    }
    printf("BusOut  = %8d kHz\n",(int)( 1000.0 / t));

    t.reset();
    for(int i=0; i<1000000; i++) {
        port = 0;
        port = 0xFF000000;
    }
    printf("PortOut = %8d kHz\n", (int)(1000.0 / t));
    
    t.reset();
    for(int i=0; i<1000000; i++) {
        out = 0;
        out = 1;
    }
    printf("DigitalOut = %8d kHz\n", (int)(1000.0 / t));

    t.reset();
    for(int i=0; i<1000000; i++) {
        out2 = 0;
        out2 = 1;
    }
    printf("DigitalOut2 = %8d kHz\n", (int)(1000.0 / t));
}

And here are the results based on an 8-bit BusOut, an initial PortOut and optimised DigitalOut design, maintaining the same API.

BusOut       =  132 kHz   (8-bit)
PortOut      = 5052 kHz   (approx x38 speedup)

DigitalOut   = 1246 kHz
DigitalOutv2 = 7384 kHz   (approx 6x speedup)

These suggest a PortOut gives good results even with a nice clean API, and the DigitalOut can be sped up too. These seem like good potential additions to the API.

As BusOut is constructed from DigitalOut, that would naturally speed up too.


5 comments

23 Mar 2010

Hi

I tried to test the code and have an error:

"Cannot open source input file "PortOut.h": No such file or directory (E5)" in file "/SpeedUpDigitalOut/main.cpp"

It's obvious that portout.h  is missing

Where can i find that file? A search did not work. Also is good to have a link to all different xxx.h   files. i keep searching for them for any project.

Sorry for asking but i m new to this and keep trying to navigate and test different codes.

Thanks

Thanos

23 Mar 2010

Hi Thanos,

These are just my own notes at the moment as i'm working on this; the source isn't published yet as I haven't quite finished them, but I am further with it and is looking good. If all looks good, it may even get in to the next library release.

Thanks for the interest!

Simon

28 Apr 2010

Hi simon,

I am new to mbed and tried sample programs.I want to test ADC with PWM can you suggest me some sample codes.....

 

Thanks in advance...

Regards

Sathishnarayan

10 Jul 2012 . Edited: 10 Jul 2012

Hi

I found port speed difference by mbed library versions and compiler environment (collaboration-beta and non-beta modes).
Do you have plan to revert the output performance as older library version?

Next result shows the diference between mbed-lin rev28 and rev43.
For instance, the PortOut was having 5333kHz by rev28 but it goes down to 2461kHz by rev43 (this happens in non-beta environment).

Built with mbed-lib rev28 on *normal* environment
    BusOut  =      193 kHz
    PortOut =     5333 kHz
    DigitalOut =  7384 kHz

Built with mbed-lib rev43 on *normal* environment
(rev43 is latest in normal env)
    BusOut  =      162 kHz
    PortOut =     2461 kHz
    DigitalOut =  7384 kHz

On addition to this, beta-mode (collaboration beta) gives different result.
The program with mbed-lib-rev26 converted for beta shows the port output slow. (The mbed-lib version became 26 when it is converted.)
And it have slower switching for DigitalOut too.

Built with mbed-lib rev26 on *beta-mode* environment
    BusOut  =      193 kHz
    PortOut =     4173 kHz
    DigitalOut =  5647 kHz

Built with mbed-lib rev40 on *beta-mode* environment
(rev40 is latest in beta env)
    BusOut  =      162 kHz
    PortOut =     2526 kHz
    DigitalOut =  5647 kHz

test code..
For nomal (non-beta) mode:
with rev28 -- http://mbed.org/users/okano/programs/port_speed_test/mcxzzx
with rev43 -- http://mbed.org/users/okano/programs/port_speed_test/mcx405

For beta mode:
http://mbed.org/users/okano/code/port_speed_test_for_beta_env/

12 Jul 2012

Since it was using the mbed library, the speed was varied by versions.
It can be avoidable if no library call is used.

following is a parallel bus emulation sample controls GPIO ports through peripheral registers

#define     ADDR_MASK       0x07878000  //  8 bit address mask on PORT0: Address value will be set into this bit position
#define     DATA_MASK       0x00000FF0  //  8 bit data mask on PORT0: Data value will be appeared on this bit position
#define     CONTROL_MASK    0x00000038  //  Control signals CS=bit5(pin21), WR=bit4(pin22), RD=bit3(pin23)

PortOut     addr_port( Port0, ADDR_MASK );
PortInOut   data_port( Port0, DATA_MASK );
PortOut     ctrl_port( Port2, CONTROL_MASK );

void write_data( char addr, char data ) {
    unsigned long   addr_data;

    __disable_irq();    //  disable interrupt first

    addr_data   = (addr << 19) | (addr << 15) | (data << 4);

    LPC_GPIO0->FIOMASK  = ~(ADDR_MASK | DATA_MASK);
    LPC_GPIO0->FIODIR   = ADDR_MASK;
    LPC_GPIO0->FIOSET   = addr_data;
    LPC_GPIO0->FIOCLR   = ~addr_data;

    LPC_GPIO2->FIOCLR   = 0x20; //  Assert CS signal
    LPC_GPIO0->FIODIR   = ADDR_MASK | DATA_MASK;

    LPC_GPIO2->FIOCLR   = 0x30; //  repeating register write to keep pulse width wide :)
    LPC_GPIO0->FIOSET   = addr_data;
    LPC_GPIO0->FIOCLR   = ~addr_data;
    LPC_GPIO2->FIOSET   = 0x38;
    LPC_GPIO0->FIODIR   = ADDR_MASK;

    __enable_irq();    //  enable interrupt again
}

You need to log in to post a comment