Simon Ford / Mbed 2 deprecated IntToBinaryAssembly

Dependencies:   mbed

Committer:
simon
Date:
Fri Jan 28 10:56:45 2011 +0000
Revision:
1:eaf79a9d2939
Parent:
0:77155d68f532
Child:
2:56fbeac9ddc8
added PortOut

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 0:77155d68f532 1 // sford, Examples of C-based optimisations of...
simon 0:77155d68f532 2 //
simon 0:77155d68f532 3 // INTEGER TO BINARY by J.P. Armstrong
simon 0:77155d68f532 4 // http://www.armtronics.com/
simon 0:77155d68f532 5 //
simon 0:77155d68f532 6 // Improved by Igor Skochinsky
simon 0:77155d68f532 7 //
simon 0:77155d68f532 8 // PART OF CODE FROM:
simon 0:77155d68f532 9 // http://mbed.org/cookbook/Assembly-Language
simon 0:77155d68f532 10
simon 0:77155d68f532 11 #include "mbed.h"
simon 0:77155d68f532 12
simon 0:77155d68f532 13 // This program will blink LED1 and LED4
simon 0:77155d68f532 14 // using assembly language for LED1 and
simon 0:77155d68f532 15 // API functions for LED4
simon 0:77155d68f532 16 // declare external assembly language function (in a *.s file)
simon 0:77155d68f532 17 extern "C" int binasm(int value);
simon 0:77155d68f532 18
simon 0:77155d68f532 19 #define L1 0x040000
simon 0:77155d68f532 20 #define L2 0x100000
simon 0:77155d68f532 21 #define L3 0x200000
simon 0:77155d68f532 22 #define L4 0x800000
simon 0:77155d68f532 23
simon 0:77155d68f532 24 #define ALLLEDS (L1 | L2 | L3 | L4)
simon 0:77155d68f532 25
simon 0:77155d68f532 26 #define GPIO1BASE 0x2009C020
simon 0:77155d68f532 27 #define GPIOSETOFF 0x18
simon 0:77155d68f532 28 #define GPIOCLROFF 0x1C
simon 0:77155d68f532 29
simon 0:77155d68f532 30 const uint32_t masks[] = {L1, L2, L3, L4};
simon 0:77155d68f532 31
simon 0:77155d68f532 32 // the asm code, translated in to a more natural expressive C function
simon 0:77155d68f532 33 void binc(int value) {
simon 0:77155d68f532 34 LPC_GPIO1->FIOCLR = ALLLEDS;
simon 0:77155d68f532 35 value += 1;
simon 0:77155d68f532 36 for(int i=0; i<4; i++) {
simon 0:77155d68f532 37 if((value >> i) & 1) {
simon 0:77155d68f532 38 LPC_GPIO1->FIOSET = masks[i];
simon 0:77155d68f532 39 } else {
simon 0:77155d68f532 40 LPC_GPIO1->FIOCLR = masks[i];
simon 0:77155d68f532 41 }
simon 0:77155d68f532 42 }
simon 0:77155d68f532 43 }
simon 0:77155d68f532 44
simon 0:77155d68f532 45 // creating the mask values before writing them to registers
simon 0:77155d68f532 46 void binc2(int value) {
simon 0:77155d68f532 47 value += 1;
simon 0:77155d68f532 48 uint32_t set = 0;
simon 0:77155d68f532 49 uint32_t clr = 0;
simon 0:77155d68f532 50
simon 0:77155d68f532 51 for(int i=0; i<4; i++) {
simon 0:77155d68f532 52 if((value >> i) & 1) {
simon 0:77155d68f532 53 set = masks[i];
simon 0:77155d68f532 54 } else {
simon 0:77155d68f532 55 clr = masks[i];
simon 0:77155d68f532 56 }
simon 0:77155d68f532 57 }
simon 0:77155d68f532 58 LPC_GPIO1->FIOSET = set;
simon 0:77155d68f532 59 LPC_GPIO1->FIOCLR = clr;
simon 0:77155d68f532 60 }
simon 0:77155d68f532 61
simon 0:77155d68f532 62 const uint32_t masks2[] = {
simon 0:77155d68f532 63 L1,
simon 0:77155d68f532 64 L2,
simon 0:77155d68f532 65 L2 | L1,
simon 0:77155d68f532 66 L3,
simon 0:77155d68f532 67 L3 | L1,
simon 0:77155d68f532 68 L3 | L2,
simon 0:77155d68f532 69 L3 | L2 | L1,
simon 0:77155d68f532 70 L4,
simon 0:77155d68f532 71 L4 | L1,
simon 0:77155d68f532 72 L4 | L2,
simon 0:77155d68f532 73 L4 | L2 | L1,
simon 0:77155d68f532 74 L4 | L3,
simon 0:77155d68f532 75 L4 | L3 | L1,
simon 0:77155d68f532 76 L4 | L3 | L2,
simon 0:77155d68f532 77 L4 | L3 | L2 | L1
simon 0:77155d68f532 78 };
simon 0:77155d68f532 79
simon 0:77155d68f532 80 // using a full lookup for the masks (space vs time tradeoff)
simon 0:77155d68f532 81 void binc3(int value) {
simon 0:77155d68f532 82 value += 1;
simon 0:77155d68f532 83 uint32_t set = masks2[value];
simon 0:77155d68f532 84 uint32_t clr = ~masks2[value] & ALLLEDS;
simon 0:77155d68f532 85 LPC_GPIO1->FIOSET = set;
simon 0:77155d68f532 86 LPC_GPIO1->FIOCLR = clr;
simon 0:77155d68f532 87 }
simon 0:77155d68f532 88
simon 0:77155d68f532 89 DigitalOut myled1(LED1);
simon 0:77155d68f532 90 DigitalOut myled2(LED2);
simon 0:77155d68f532 91 DigitalOut myled3(LED3);
simon 0:77155d68f532 92 DigitalOut myled4(LED4);
simon 0:77155d68f532 93
simon 1:eaf79a9d2939 94 PortOut ledport(Port1, ALLLEDS);
simon 1:eaf79a9d2939 95
simon 1:eaf79a9d2939 96 // creating the mask values before writing them to registers
simon 1:eaf79a9d2939 97 void binc6(int value) {
simon 1:eaf79a9d2939 98 uint32_t set = 0;
simon 1:eaf79a9d2939 99 for(int i=0; i<4; i++) {
simon 1:eaf79a9d2939 100 if((value >> i) & 1) {
simon 1:eaf79a9d2939 101 set |= masks[i];
simon 1:eaf79a9d2939 102 }
simon 1:eaf79a9d2939 103 }
simon 1:eaf79a9d2939 104 ledport = set;
simon 1:eaf79a9d2939 105 }
simon 1:eaf79a9d2939 106
simon 1:eaf79a9d2939 107 void binc7(int value) {
simon 1:eaf79a9d2939 108 ledport = masks2[value];
simon 1:eaf79a9d2939 109 }
simon 1:eaf79a9d2939 110
simon 0:77155d68f532 111 // timing functions
simon 0:77155d68f532 112
simon 0:77155d68f532 113 Timer t;
simon 0:77155d68f532 114
simon 0:77155d68f532 115 void START(char *msg) {
simon 0:77155d68f532 116 printf("Timing %s\n", msg);
simon 0:77155d68f532 117 t.start();
simon 0:77155d68f532 118 t.reset();
simon 0:77155d68f532 119 }
simon 0:77155d68f532 120
simon 0:77155d68f532 121 void STOP() {
simon 0:77155d68f532 122 int v = t.read_us();
simon 0:77155d68f532 123 printf(" - %d us\n", v);
simon 0:77155d68f532 124 }
simon 0:77155d68f532 125
simon 0:77155d68f532 126 #define LOOPS 100000
simon 0:77155d68f532 127
simon 0:77155d68f532 128 int main() {
simon 0:77155d68f532 129 START("Assembly");
simon 0:77155d68f532 130 for(int i=0; i<LOOPS; i++) {
simon 0:77155d68f532 131 binasm(i % 16);
simon 0:77155d68f532 132 }
simon 0:77155d68f532 133 STOP();
simon 0:77155d68f532 134
simon 0:77155d68f532 135 START("C translation");
simon 0:77155d68f532 136 for(int i=0; i<LOOPS; i++) {
simon 0:77155d68f532 137 binc(i % 16);
simon 0:77155d68f532 138 }
simon 0:77155d68f532 139 STOP();
simon 0:77155d68f532 140
simon 0:77155d68f532 141 START("C reg-writes outside the loop");
simon 0:77155d68f532 142 for(int i=0; i<LOOPS; i++) {
simon 0:77155d68f532 143 binc2(i % 16);
simon 0:77155d68f532 144 }
simon 0:77155d68f532 145 STOP();
simon 0:77155d68f532 146
simon 0:77155d68f532 147 START("C with mask lookup table");
simon 0:77155d68f532 148 for(int i=0; i<LOOPS; i++) {
simon 0:77155d68f532 149 binc3(i % 16);
simon 0:77155d68f532 150 }
simon 0:77155d68f532 151 STOP();
simon 0:77155d68f532 152
simon 0:77155d68f532 153 START("C with mask lookup table, but caller loop optimised");
simon 0:77155d68f532 154 for(int i=0; i<LOOPS; i++) {
simon 0:77155d68f532 155 binc3(i & 0xF);
simon 0:77155d68f532 156 }
simon 0:77155d68f532 157 STOP();
simon 1:eaf79a9d2939 158
simon 1:eaf79a9d2939 159 START("PortOut");
simon 1:eaf79a9d2939 160 for(int i=0; i<LOOPS; i++) {
simon 1:eaf79a9d2939 161 binc6(i & 0xF);
simon 1:eaf79a9d2939 162 }
simon 1:eaf79a9d2939 163 STOP();
simon 1:eaf79a9d2939 164
simon 1:eaf79a9d2939 165 START("PortOut lookup");
simon 1:eaf79a9d2939 166 for(int i=0; i<LOOPS; i++) {
simon 1:eaf79a9d2939 167 binc7(i & 0xF);
simon 1:eaf79a9d2939 168 }
simon 1:eaf79a9d2939 169 STOP();
simon 0:77155d68f532 170 }