Simon Ford / Mbed 2 deprecated IntToBinaryAssembly

Dependencies:   mbed

Committer:
simon
Date:
Fri Jan 28 10:04:43 2011 +0000
Revision:
0:77155d68f532
Child:
1:eaf79a9d2939

        

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 0:77155d68f532 94 // timing functions
simon 0:77155d68f532 95
simon 0:77155d68f532 96 Timer t;
simon 0:77155d68f532 97
simon 0:77155d68f532 98 void START(char *msg) {
simon 0:77155d68f532 99 printf("Timing %s\n", msg);
simon 0:77155d68f532 100 t.start();
simon 0:77155d68f532 101 t.reset();
simon 0:77155d68f532 102 }
simon 0:77155d68f532 103
simon 0:77155d68f532 104 void STOP() {
simon 0:77155d68f532 105 int v = t.read_us();
simon 0:77155d68f532 106 printf(" - %d us\n", v);
simon 0:77155d68f532 107 }
simon 0:77155d68f532 108
simon 0:77155d68f532 109 #define LOOPS 100000
simon 0:77155d68f532 110
simon 0:77155d68f532 111 int main() {
simon 0:77155d68f532 112 START("Assembly");
simon 0:77155d68f532 113 for(int i=0; i<LOOPS; i++) {
simon 0:77155d68f532 114 binasm(i % 16);
simon 0:77155d68f532 115 }
simon 0:77155d68f532 116 STOP();
simon 0:77155d68f532 117
simon 0:77155d68f532 118 START("C translation");
simon 0:77155d68f532 119 for(int i=0; i<LOOPS; i++) {
simon 0:77155d68f532 120 binc(i % 16);
simon 0:77155d68f532 121 }
simon 0:77155d68f532 122 STOP();
simon 0:77155d68f532 123
simon 0:77155d68f532 124 START("C reg-writes outside the loop");
simon 0:77155d68f532 125 for(int i=0; i<LOOPS; i++) {
simon 0:77155d68f532 126 binc2(i % 16);
simon 0:77155d68f532 127 }
simon 0:77155d68f532 128 STOP();
simon 0:77155d68f532 129
simon 0:77155d68f532 130 START("C with mask lookup table");
simon 0:77155d68f532 131 for(int i=0; i<LOOPS; i++) {
simon 0:77155d68f532 132 binc3(i % 16);
simon 0:77155d68f532 133 }
simon 0:77155d68f532 134 STOP();
simon 0:77155d68f532 135
simon 0:77155d68f532 136 START("C with mask lookup table, but caller loop optimised");
simon 0:77155d68f532 137 for(int i=0; i<LOOPS; i++) {
simon 0:77155d68f532 138 binc3(i & 0xF);
simon 0:77155d68f532 139 }
simon 0:77155d68f532 140 STOP();
simon 0:77155d68f532 141 }