Testbench for FastIO

Dependencies:   FastIO mbed

Fork of FastIO by Igor Skochinsky

Revision:
5:8a7a7df0a9c7
Parent:
3:8d217a0bb245
Child:
7:b45620275f74
--- a/main.cpp	Tue May 25 08:35:39 2010 +0000
+++ b/main.cpp	Tue Jul 01 17:21:29 2014 +0000
@@ -1,73 +1,344 @@
 #include "mbed.h"
-
 #include "FastIO.h"
+ 
+DigitalInOut led1(LED1);
+FastInOut<LED2> led2;
+ 
+Timer t;
+#define LOOPS 10000
 
-#define LED_MASK 0x07800000
+void basic_test();
+void fixed_write();
+void variable_write();
+void read();
+void operator_toggle();
+void input_output();
+
+void print_results(int digicount, int fastcount);
+
+int main() {
+    printf("\r\nAll numbers are the number of core clock cycles per IO operation\r\n");
+    
+    basic_test();
+    fixed_write();
+    variable_write();
+    read();
+    operator_toggle();
+    input_output();
+    
+    while(1);
+}
 
-DigitalOut led1(LED1);
-FastOut<LED2> led2;
-PortOut ledport(Port0, LED_MASK);
-FastPortOut<Port0, LED_MASK> ledport2;
-MaskedPortOut<Port0, LED_MASK> ledport3;
+void print_results(int digicount, int fastcount) {
+    float digicycles = (float)digicount / LOOPS * (float)SystemCoreClock / 1000000.0f;
+    float fastcycles = (float)fastcount / LOOPS * (float)SystemCoreClock / 1000000.0f;
+    printf("Standard took %.1f cycles, FastIO took %.1f cycles, which is %d%%\r\n", digicycles, fastcycles,(int)(100.0f*fastcycles/digicycles + 0.5));
+}
+ 
+void basic_test() {
+printf("Verifying basic behavior\r\n");
+    int error = 0;
+    led1.output();
+    led2.output();
+    led1 = 1;
+    led2 = 1;
+    error += (led1.read() != 1);
+    error += (led2.read() != 1);
+    led1 = 0;
+    led2 = 0;
+    error += (led1.read() != 0);
+    error += (led2.read() != 0);
+    
+    if (error == 0) 
+        printf("Basic behavior verified\r\n");
+    else {
+        printf("Error in basic behavior\r\n");
+        while(1);
+    }
+}
 
-Timer t;
-#define LOOPS 100000000
-int main() {
-    int value = 0;
-    int count = LOOPS;
+
+void fixed_write() {
+    int overhead;
+    int digitalinout;
+    int fastinout;
+    int count;
+    
+    printf("\nMeasuring fixed write pattern speed\r\n");
+    led1.output();
+    led2.output();
+    
+    //Calculate loop overhead
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
+    while ( count -- ) {
+        led1.write(1);
+        led1.write(0);
+    }
+    t.stop();
+    overhead = t.read_us();
+    
+    count = LOOPS / 2;
+    t.reset();
     t.start();
     while ( count -- )
     {
-        led1.write(value);
-        value = 1-value;
+        led1.write(1);
+        led1.write(0);
+        led1.write(1);
+        led1.write(0);
+    }
+    t.stop();
+    digitalinout = t.read_us() - overhead;
+    
+    //Calculate loop overhead
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
+    while ( count -- ) {
+        led2.write(1);
+        led2.write(0);
+    }
+    t.stop();
+    overhead = t.read_us();
+    
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
+    while ( count -- )
+    {
+        led2.write(1);
+        led2.write(0);
+        led2.write(1);
+        led2.write(0);
     }
     t.stop();
-    printf("DigitalOut: %f seconds (%d ns per iteration).\n", t.read(), t.read_us()/(LOOPS/1000));
+    fastinout = t.read_us() - overhead;
+    
+    print_results(digitalinout, fastinout);
+}
+
+void variable_write() {
+    int overhead;
+    int digitalinout;
+    int fastinout;
+    int count;
+    
+    printf("\nMeasuring variable write pattern speed\r\n");
+    led1.output();
+    led2.output();
+    
+    //Calculate loop overhead
+    int value = 1;
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
+    while ( count -- ) {
+        value = value - 1; led1.write(value);
+        value = value - 1; 
+        value = value - 1;
+        value = value - 1; led1.write(value);
+    }
+    
+    t.stop();
+    overhead = t.read_us();
+
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
+    while ( count -- )
+    {
+        value = value - 1; led1.write(value);
+        value = value - 1; led1.write(value);
+        value = value - 1; led1.write(value);
+        value = value - 1; led1.write(value);
+    }
+    t.stop();
+    digitalinout = t.read_us() - overhead;
     
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
+    while ( count -- ) {
+        value = value - 1; led2.write(value);
+        value = value - 1; 
+        value = value - 1;
+        value = value - 1; led2.write(value);
+    }
+    
+    t.stop();
+    overhead = t.read_us();
+
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
+    while ( count -- )
+    {
+        value = value - 1; led2.write(value);
+        value = value - 1; led2.write(value);
+        value = value - 1; led2.write(value);
+        value = value - 1; led2.write(value);
+    }
+    t.stop();
+    fastinout = t.read_us() - overhead;
+    print_results(digitalinout, fastinout);
+}
+
+void read() {
+    int overhead;
+    int digitalinout;
+    int fastinout;
+    int count;
+    
+    printf("\nMeasuring read speed\r\n");
+    led1.input(); led1.mode(PullUp);
+    led2.input(); led2.mode(PullUp);
+    
+    //Calculate loop overhead
+    count = LOOPS;
+    t.reset();
+    t.start();
+    while ( count -- ) {
+    }
+    t.stop();
+    overhead = t.read_us();
+
     count = LOOPS;
     t.reset();
     t.start();
     while ( count -- )
     {
-        led2 = value;
-        value = 1-value;
+        if (led1.read() == 2)       //This shouldn't happen due to pull-up, if you get weird results, it is happening
+            break;   
     }
     t.stop();
-    printf("FastOut: %f seconds (%d ns per iteration).\n", t.read(), t.read_us()/(LOOPS/1000));
-
-    count = LOOPS;
-    t.reset();
-    t.start();
-    value = LED_MASK;
-    while ( count -- )
-    {
-        ledport.write(value);
-        value ^= LED_MASK;
-    }
-    t.stop();
-    printf("PortOut: %f seconds (%d ns per iteration).\n", t.read(), t.read_us()/(LOOPS/1000));
+    digitalinout = t.read_us() - overhead;
 
     count = LOOPS;
     t.reset();
     t.start();
-    value = LED_MASK;
     while ( count -- )
     {
-        ledport2 = value;
-        value ^= LED_MASK;
+        if (led2.read() == 2)       //This shouldn't happen due to pull-up, if you get weird results, it is happening
+            break;       
+    }
+    t.stop();
+    fastinout = t.read_us() - overhead;
+ 
+    print_results(digitalinout, fastinout);
+}
+
+void operator_toggle() {
+    int overhead;
+    int digitalinout;
+    int fastinout;
+    int count;
+    
+    printf("\nMeasuring toggling using operators speed\r\n");
+    led1.output();
+    led2.output();
+    
+    //Calculate loop overhead
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
+    while ( count -- ) {
+        led1 = !led1;      
+        led1 = !led1;
+    }
+    t.stop();
+    overhead = t.read_us();
+
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
+    while ( count -- ) {
+        led1 = !led1;      
+        led1 = !led1;
+        led1 = !led1;      
+        led1 = !led1;
+    }
+    t.stop();
+    digitalinout = t.read_us() - overhead;
+    
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
+    while ( count -- ) {
+        led2 = !led2;
+        led2 = !led2;
     }
     t.stop();
-    printf("FastPortOut: %f seconds (%d ns per iteration).\n", t.read(), t.read_us()/(LOOPS/1000));
+    overhead = t.read_us();
+    
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
+    while ( count -- )
+    {
+         led2 = !led2;
+         led2 = !led2;
+         led2 = !led2;
+         led2 = !led2;
+    }
+    t.stop();
+    fastinout = t.read_us() - overhead;
+    print_results(digitalinout, fastinout);
+}
 
-    count = LOOPS;
+void input_output() {
+    int overhead;
+    int digitalinout;
+    int fastinout;
+    int count;
+    
+    printf("\nMeasuring switching between input and output\r\n");
+    
+    //Calculate loop overhead
+    count = LOOPS / 2;
     t.reset();
     t.start();
-    value = LED_MASK;
+    while ( count -- ) {
+        led1.input();
+        led1.output();
+    }
+    t.stop();
+    overhead = t.read_us();
+
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
+    while ( count -- ) {
+        led1.input();
+        led1.output();
+        led1.input();
+        led1.output();
+    }
+    t.stop();
+    digitalinout = t.read_us() - overhead;
+    
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
+    while ( count -- ) {
+        led2.input();
+        led2.output();
+    }
+    t.stop();
+    overhead = t.read_us();
+    
+    count = LOOPS / 2;
+    t.reset();
+    t.start();
     while ( count -- )
     {
-        ledport3 = value;
-        value ^= LED_MASK;
+        led2.input();
+        led2.output();
+        led2.input();
+        led2.output();
     }
     t.stop();
-    printf("MaskedPortOut: %f seconds (%d ns per iteration).\n", t.read(), t.read_us()/(LOOPS/1000));
-}
+    fastinout = t.read_us() - overhead;
+    print_results(digitalinout, fastinout);
+}
\ No newline at end of file