new
Dependencies: Crypto_light mbed-rtos mbed
Fork of ES_CW2_Starter by
main.cpp@4:ed5a463a64ad, 2018-03-15 (annotated)
- Committer:
- JINYEENG
- Date:
- Thu Mar 15 12:38:21 2018 +0000
- Revision:
- 4:ed5a463a64ad
- Parent:
- 3:569b35e2a602
new
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
estott | 0:de4320f74764 | 1 | #include "mbed.h" |
JINYEENG | 4:ed5a463a64ad | 2 | #include "SHA256.h" |
JINYEENG | 4:ed5a463a64ad | 3 | #include "rtos.h" |
JINYEENG | 4:ed5a463a64ad | 4 | #include <string> |
estott | 0:de4320f74764 | 5 | |
JINYEENG | 4:ed5a463a64ad | 6 | |
JINYEENG | 4:ed5a463a64ad | 7 | //------------------------ Define Inputs -------------------------------------// |
JINYEENG | 4:ed5a463a64ad | 8 | |
JINYEENG | 4:ed5a463a64ad | 9 | // Photointerrupter input pins |
estott | 0:de4320f74764 | 10 | #define I1pin D2 |
estott | 2:4e88faab6988 | 11 | #define I2pin D11 |
estott | 2:4e88faab6988 | 12 | #define I3pin D12 |
estott | 2:4e88faab6988 | 13 | |
JINYEENG | 4:ed5a463a64ad | 14 | // Incremental encoder input pins |
estott | 2:4e88faab6988 | 15 | #define CHA D7 |
JINYEENG | 4:ed5a463a64ad | 16 | #define CHB D8 |
estott | 0:de4320f74764 | 17 | |
JINYEENG | 4:ed5a463a64ad | 18 | // Motor Drive output pins //Mask in output byte |
estott | 2:4e88faab6988 | 19 | #define L1Lpin D4 //0x01 |
estott | 2:4e88faab6988 | 20 | #define L1Hpin D5 //0x02 |
estott | 2:4e88faab6988 | 21 | #define L2Lpin D3 //0x04 |
estott | 2:4e88faab6988 | 22 | #define L2Hpin D6 //0x08 |
estott | 2:4e88faab6988 | 23 | #define L3Lpin D9 //0x10 |
estott | 0:de4320f74764 | 24 | #define L3Hpin D10 //0x20 |
estott | 0:de4320f74764 | 25 | |
JINYEENG | 4:ed5a463a64ad | 26 | // Mapping from sequential drive states to motor phase outputs |
estott | 0:de4320f74764 | 27 | /* |
estott | 0:de4320f74764 | 28 | State L1 L2 L3 |
estott | 0:de4320f74764 | 29 | 0 H - L |
estott | 0:de4320f74764 | 30 | 1 - H L |
estott | 0:de4320f74764 | 31 | 2 L H - |
estott | 0:de4320f74764 | 32 | 3 L - H |
estott | 0:de4320f74764 | 33 | 4 - L H |
estott | 0:de4320f74764 | 34 | 5 H L - |
estott | 0:de4320f74764 | 35 | 6 - - - |
estott | 0:de4320f74764 | 36 | 7 - - - |
estott | 0:de4320f74764 | 37 | */ |
JINYEENG | 4:ed5a463a64ad | 38 | |
JINYEENG | 4:ed5a463a64ad | 39 | |
JINYEENG | 4:ed5a463a64ad | 40 | //---------------------------- Global Variables ------------------------------// |
JINYEENG | 4:ed5a463a64ad | 41 | |
JINYEENG | 4:ed5a463a64ad | 42 | // For Motor |
JINYEENG | 4:ed5a463a64ad | 43 | // Drive state to output table |
JINYEENG | 4:ed5a463a64ad | 44 | const int8_t driveTable[] = { 0x12, 0x18, 0x09, 0x21, 0x24, 0x06, 0x00, 0x00 }; |
estott | 2:4e88faab6988 | 45 | |
JINYEENG | 4:ed5a463a64ad | 46 | // Mapping from interrupter inputs to sequential rotor states. |
JINYEENG | 4:ed5a463a64ad | 47 | // 0x00 and 0x07 are not valid |
JINYEENG | 4:ed5a463a64ad | 48 | const int8_t stateMap[] = {0x07,0x05,0x03,0x04,0x01,0x00,0x02,0x07}; |
estott | 2:4e88faab6988 | 49 | |
JINYEENG | 4:ed5a463a64ad | 50 | // Alternative if phase order of input or drive is reversed |
JINYEENG | 4:ed5a463a64ad | 51 | //const int8_t stateMap[] = {0x07,0x01,0x03,0x02,0x05,0x00,0x04,0x07}; |
JINYEENG | 4:ed5a463a64ad | 52 | |
JINYEENG | 4:ed5a463a64ad | 53 | // Phase lead to make motor spin |
JINYEENG | 4:ed5a463a64ad | 54 | const int8_t lead = -2; //2 for forwards, -2 for backwards |
JINYEENG | 4:ed5a463a64ad | 55 | //enum messageName ={"Hash_Rate","Nonce","Key"}; |
estott | 0:de4320f74764 | 56 | |
estott | 0:de4320f74764 | 57 | //Status LED |
estott | 0:de4320f74764 | 58 | DigitalOut led1(LED1); |
estott | 0:de4320f74764 | 59 | |
estott | 0:de4320f74764 | 60 | //Photointerrupter inputs |
JINYEENG | 4:ed5a463a64ad | 61 | InterruptIn I1(I1pin); |
JINYEENG | 4:ed5a463a64ad | 62 | InterruptIn I2(I2pin); |
JINYEENG | 4:ed5a463a64ad | 63 | InterruptIn I3(I3pin); |
estott | 0:de4320f74764 | 64 | |
estott | 0:de4320f74764 | 65 | //Motor Drive outputs |
estott | 0:de4320f74764 | 66 | DigitalOut L1L(L1Lpin); |
estott | 0:de4320f74764 | 67 | DigitalOut L1H(L1Hpin); |
estott | 0:de4320f74764 | 68 | DigitalOut L2L(L2Lpin); |
estott | 0:de4320f74764 | 69 | DigitalOut L2H(L2Hpin); |
estott | 0:de4320f74764 | 70 | DigitalOut L3L(L3Lpin); |
estott | 0:de4320f74764 | 71 | DigitalOut L3H(L3Hpin); |
estott | 0:de4320f74764 | 72 | |
JINYEENG | 4:ed5a463a64ad | 73 | int8_t orState = 0; //Rotot offset at motor state 0 |
JINYEENG | 4:ed5a463a64ad | 74 | |
JINYEENG | 4:ed5a463a64ad | 75 | //Initialise the serial port |
JINYEENG | 4:ed5a463a64ad | 76 | RawSerial pc(SERIAL_TX, SERIAL_RX); |
JINYEENG | 4:ed5a463a64ad | 77 | int8_t intState = 0; |
JINYEENG | 4:ed5a463a64ad | 78 | int8_t intStateOld = 0; |
JINYEENG | 4:ed5a463a64ad | 79 | |
JINYEENG | 4:ed5a463a64ad | 80 | // Variables for Hash |
JINYEENG | 4:ed5a463a64ad | 81 | uint8_t sequence[] = {0x45, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, |
JINYEENG | 4:ed5a463a64ad | 82 | 0x20, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6D, 0x73, |
JINYEENG | 4:ed5a463a64ad | 83 | 0x20, 0x61, 0x72, 0x65, 0x20, 0x66, 0x75, 0x6E, |
JINYEENG | 4:ed5a463a64ad | 84 | 0x20, 0x61, 0x6E, 0x64, 0x20, 0x64, 0x6F, 0x20, |
JINYEENG | 4:ed5a463a64ad | 85 | 0x61, 0x77, 0x65, 0x73, 0x6F, 0x6D, 0x65, 0x20, |
JINYEENG | 4:ed5a463a64ad | 86 | 0x74, 0x68, 0x69, 0x6E, 0x67, 0x73, 0x21, 0x20, |
JINYEENG | 4:ed5a463a64ad | 87 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
JINYEENG | 4:ed5a463a64ad | 88 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
JINYEENG | 4:ed5a463a64ad | 89 | |
JINYEENG | 4:ed5a463a64ad | 90 | uint64_t* key = (uint64_t*)((int)sequence + 48); |
JINYEENG | 4:ed5a463a64ad | 91 | uint64_t* nonce = (uint64_t*)((int)sequence + 56); |
JINYEENG | 4:ed5a463a64ad | 92 | uint8_t hash[32]; |
JINYEENG | 4:ed5a463a64ad | 93 | |
JINYEENG | 4:ed5a463a64ad | 94 | // For Thread |
JINYEENG | 4:ed5a463a64ad | 95 | |
JINYEENG | 4:ed5a463a64ad | 96 | // Timer |
JINYEENG | 4:ed5a463a64ad | 97 | Timer t; |
JINYEENG | 4:ed5a463a64ad | 98 | |
JINYEENG | 4:ed5a463a64ad | 99 | // Threading |
JINYEENG | 4:ed5a463a64ad | 100 | Thread commOutT; |
JINYEENG | 4:ed5a463a64ad | 101 | Thread commOutT2; |
JINYEENG | 4:ed5a463a64ad | 102 | |
JINYEENG | 4:ed5a463a64ad | 103 | typedef struct{ |
JINYEENG | 4:ed5a463a64ad | 104 | uint8_t code; |
JINYEENG | 4:ed5a463a64ad | 105 | uint32_t data; |
JINYEENG | 4:ed5a463a64ad | 106 | } message_t; |
JINYEENG | 4:ed5a463a64ad | 107 | |
JINYEENG | 4:ed5a463a64ad | 108 | |
JINYEENG | 4:ed5a463a64ad | 109 | Mail<message_t, 16> outMessages; |
JINYEENG | 4:ed5a463a64ad | 110 | |
JINYEENG | 4:ed5a463a64ad | 111 | // Queue |
JINYEENG | 4:ed5a463a64ad | 112 | char command[19]; |
JINYEENG | 4:ed5a463a64ad | 113 | |
JINYEENG | 4:ed5a463a64ad | 114 | Queue <void,8> inCharQ; |
JINYEENG | 4:ed5a463a64ad | 115 | |
JINYEENG | 4:ed5a463a64ad | 116 | uint32_t newKey;//to pass new key |
JINYEENG | 4:ed5a463a64ad | 117 | uint32_t keyLala; |
JINYEENG | 4:ed5a463a64ad | 118 | uint64_t combinedKey; |
JINYEENG | 4:ed5a463a64ad | 119 | |
JINYEENG | 4:ed5a463a64ad | 120 | Mutex key_mutex; |
JINYEENG | 4:ed5a463a64ad | 121 | |
JINYEENG | 4:ed5a463a64ad | 122 | //------------------------- Motor Functions ----------------------------------// |
JINYEENG | 4:ed5a463a64ad | 123 | |
JINYEENG | 4:ed5a463a64ad | 124 | // Set a given sdrive state |
JINYEENG | 4:ed5a463a64ad | 125 | void motorOut(int8_t driveState) { |
estott | 2:4e88faab6988 | 126 | //Lookup the output byte from the drive state. |
estott | 2:4e88faab6988 | 127 | int8_t driveOut = driveTable[driveState & 0x07]; |
JINYEENG | 4:ed5a463a64ad | 128 | |
estott | 2:4e88faab6988 | 129 | //Turn off first |
estott | 2:4e88faab6988 | 130 | if (~driveOut & 0x01) L1L = 0; |
estott | 2:4e88faab6988 | 131 | if (~driveOut & 0x02) L1H = 1; |
estott | 2:4e88faab6988 | 132 | if (~driveOut & 0x04) L2L = 0; |
estott | 2:4e88faab6988 | 133 | if (~driveOut & 0x08) L2H = 1; |
estott | 2:4e88faab6988 | 134 | if (~driveOut & 0x10) L3L = 0; |
estott | 2:4e88faab6988 | 135 | if (~driveOut & 0x20) L3H = 1; |
JINYEENG | 4:ed5a463a64ad | 136 | |
estott | 2:4e88faab6988 | 137 | //Then turn on |
estott | 2:4e88faab6988 | 138 | if (driveOut & 0x01) L1L = 1; |
estott | 2:4e88faab6988 | 139 | if (driveOut & 0x02) L1H = 0; |
estott | 2:4e88faab6988 | 140 | if (driveOut & 0x04) L2L = 1; |
estott | 2:4e88faab6988 | 141 | if (driveOut & 0x08) L2H = 0; |
estott | 2:4e88faab6988 | 142 | if (driveOut & 0x10) L3L = 1; |
estott | 2:4e88faab6988 | 143 | if (driveOut & 0x20) L3H = 0; |
JINYEENG | 4:ed5a463a64ad | 144 | } |
estott | 0:de4320f74764 | 145 | |
JINYEENG | 4:ed5a463a64ad | 146 | // Convert photointerrupter inputs to a rotor state |
JINYEENG | 4:ed5a463a64ad | 147 | inline int8_t readRotorState() { |
JINYEENG | 4:ed5a463a64ad | 148 | return stateMap[I1 + 2 * I2 + 4 * I3]; |
JINYEENG | 4:ed5a463a64ad | 149 | } |
JINYEENG | 4:ed5a463a64ad | 150 | |
JINYEENG | 4:ed5a463a64ad | 151 | // Basic synchronisation routine |
estott | 2:4e88faab6988 | 152 | int8_t motorHome() { |
estott | 0:de4320f74764 | 153 | //Put the motor in drive state 0 and wait for it to stabilise |
estott | 0:de4320f74764 | 154 | motorOut(0); |
JINYEENG | 4:ed5a463a64ad | 155 | wait(1.0); |
JINYEENG | 4:ed5a463a64ad | 156 | |
estott | 0:de4320f74764 | 157 | //Get the rotor state |
estott | 2:4e88faab6988 | 158 | return readRotorState(); |
estott | 0:de4320f74764 | 159 | } |
JINYEENG | 4:ed5a463a64ad | 160 | |
JINYEENG | 4:ed5a463a64ad | 161 | void read() { |
JINYEENG | 4:ed5a463a64ad | 162 | intState = readRotorState(); |
JINYEENG | 4:ed5a463a64ad | 163 | if (intState != intStateOld) { |
JINYEENG | 4:ed5a463a64ad | 164 | intStateOld = intState; |
JINYEENG | 4:ed5a463a64ad | 165 | motorOut((intState - orState + lead + 6) % 6); |
JINYEENG | 4:ed5a463a64ad | 166 | //+6 to make sure the remainder is positive |
JINYEENG | 4:ed5a463a64ad | 167 | } |
JINYEENG | 4:ed5a463a64ad | 168 | } |
JINYEENG | 4:ed5a463a64ad | 169 | |
JINYEENG | 4:ed5a463a64ad | 170 | |
JINYEENG | 4:ed5a463a64ad | 171 | // -------------------------- Thread Functions -------------------------------// |
JINYEENG | 4:ed5a463a64ad | 172 | |
JINYEENG | 4:ed5a463a64ad | 173 | void putMessage(uint8_t code, uint64_t data) { |
JINYEENG | 4:ed5a463a64ad | 174 | message_t *pMessage = outMessages.alloc(); |
JINYEENG | 4:ed5a463a64ad | 175 | pMessage->code = code; |
JINYEENG | 4:ed5a463a64ad | 176 | pMessage->data = data; |
JINYEENG | 4:ed5a463a64ad | 177 | outMessages.put(pMessage); |
JINYEENG | 4:ed5a463a64ad | 178 | } |
JINYEENG | 4:ed5a463a64ad | 179 | |
JINYEENG | 4:ed5a463a64ad | 180 | void commOutFn() { |
JINYEENG | 4:ed5a463a64ad | 181 | while(1){ |
JINYEENG | 4:ed5a463a64ad | 182 | osEvent newEvent = outMessages.get(); |
JINYEENG | 4:ed5a463a64ad | 183 | message_t *pMessage = (message_t*)newEvent.value.p; |
JINYEENG | 4:ed5a463a64ad | 184 | //pc.printf("%s = 0x%016x \r \n",messageName[pMessage->code], pMessage->data); |
JINYEENG | 4:ed5a463a64ad | 185 | if(pMessage->code == 1) { |
JINYEENG | 4:ed5a463a64ad | 186 | pc.printf("Nonce = 0x%016x \r \n", pMessage->data); |
JINYEENG | 4:ed5a463a64ad | 187 | } else if(pMessage->code == 0){ |
JINYEENG | 4:ed5a463a64ad | 188 | pc.printf("Hash Rate = %d \r \n", pMessage->data); |
JINYEENG | 4:ed5a463a64ad | 189 | } else if(pMessage->code == 2){ |
JINYEENG | 4:ed5a463a64ad | 190 | pc.printf("Key = 0x%016x \r \n", pMessage->data); |
JINYEENG | 4:ed5a463a64ad | 191 | } |
JINYEENG | 4:ed5a463a64ad | 192 | |
JINYEENG | 4:ed5a463a64ad | 193 | |
JINYEENG | 4:ed5a463a64ad | 194 | outMessages.free(pMessage); |
estott | 2:4e88faab6988 | 195 | } |
estott | 0:de4320f74764 | 196 | } |
estott | 0:de4320f74764 | 197 | |
JINYEENG | 4:ed5a463a64ad | 198 | void serialISR() { |
JINYEENG | 4:ed5a463a64ad | 199 | uint8_t newChar = pc.getc(); |
JINYEENG | 4:ed5a463a64ad | 200 | inCharQ.put((void*)newChar); |
JINYEENG | 4:ed5a463a64ad | 201 | } |
JINYEENG | 4:ed5a463a64ad | 202 | |
JINYEENG | 4:ed5a463a64ad | 203 | void keyBuffer() { |
JINYEENG | 4:ed5a463a64ad | 204 | pc.attach(&serialISR); |
JINYEENG | 4:ed5a463a64ad | 205 | int i = 0; |
JINYEENG | 4:ed5a463a64ad | 206 | while(1){ |
JINYEENG | 4:ed5a463a64ad | 207 | osEvent newEvent =inCharQ.get(); |
JINYEENG | 4:ed5a463a64ad | 208 | uint8_t newchar = (uint8_t)newEvent.value.p; |
JINYEENG | 4:ed5a463a64ad | 209 | command[i] = newchar; |
JINYEENG | 4:ed5a463a64ad | 210 | if (newchar =='r' && command[i-1] == '\\' ) { // detect end of line |
JINYEENG | 4:ed5a463a64ad | 211 | command[i]='0'; |
JINYEENG | 4:ed5a463a64ad | 212 | if (command[0] == 'K') { |
JINYEENG | 4:ed5a463a64ad | 213 | key_mutex.lock(); |
JINYEENG | 4:ed5a463a64ad | 214 | sscanf(command, "%*c %8x %8x", key, (uint64_t*)((int)key+4) ); |
JINYEENG | 4:ed5a463a64ad | 215 | pc.printf("Key: %8x%8x \r\n", *key, *((uint64_t*)(int)key+4)); |
JINYEENG | 4:ed5a463a64ad | 216 | key_mutex.unlock(); |
JINYEENG | 4:ed5a463a64ad | 217 | } |
JINYEENG | 4:ed5a463a64ad | 218 | i = -1; |
JINYEENG | 4:ed5a463a64ad | 219 | } |
JINYEENG | 4:ed5a463a64ad | 220 | i++; |
JINYEENG | 4:ed5a463a64ad | 221 | if(i>=sizeof(command)-1){ |
JINYEENG | 4:ed5a463a64ad | 222 | i=0; |
JINYEENG | 4:ed5a463a64ad | 223 | putMessage(2,0); |
JINYEENG | 4:ed5a463a64ad | 224 | } |
JINYEENG | 4:ed5a463a64ad | 225 | } |
JINYEENG | 4:ed5a463a64ad | 226 | } |
JINYEENG | 4:ed5a463a64ad | 227 | |
JINYEENG | 4:ed5a463a64ad | 228 | |
JINYEENG | 4:ed5a463a64ad | 229 | //-------------------------------- Main --------------------------------------// |
JINYEENG | 4:ed5a463a64ad | 230 | |
JINYEENG | 4:ed5a463a64ad | 231 | int main() { |
JINYEENG | 4:ed5a463a64ad | 232 | newKey=*key; |
JINYEENG | 4:ed5a463a64ad | 233 | |
JINYEENG | 4:ed5a463a64ad | 234 | commOutT.start(commOutFn); |
JINYEENG | 4:ed5a463a64ad | 235 | commOutT2.start(keyBuffer); |
JINYEENG | 4:ed5a463a64ad | 236 | |
JINYEENG | 4:ed5a463a64ad | 237 | // Run the motor synchronisation |
JINYEENG | 4:ed5a463a64ad | 238 | orState = motorHome(); |
JINYEENG | 4:ed5a463a64ad | 239 | // orState is subtracted from future rotor state inputs to align rotor and motor states |
JINYEENG | 4:ed5a463a64ad | 240 | |
JINYEENG | 4:ed5a463a64ad | 241 | // Interrupt, if the motor is moved it will enter the interrupt and keep rotating |
JINYEENG | 4:ed5a463a64ad | 242 | I1.rise(&read); |
JINYEENG | 4:ed5a463a64ad | 243 | I2.rise(&read); |
JINYEENG | 4:ed5a463a64ad | 244 | I3.rise(&read); |
JINYEENG | 4:ed5a463a64ad | 245 | I1.fall(&read); |
JINYEENG | 4:ed5a463a64ad | 246 | I2.fall(&read); |
JINYEENG | 4:ed5a463a64ad | 247 | I3.fall(&read); |
JINYEENG | 4:ed5a463a64ad | 248 | |
JINYEENG | 4:ed5a463a64ad | 249 | // Poll the rotor state and set the motor outputs accordingly to spin the motor |
JINYEENG | 4:ed5a463a64ad | 250 | |
JINYEENG | 4:ed5a463a64ad | 251 | // Create an old ref to nonce |
JINYEENG | 4:ed5a463a64ad | 252 | uint64_t oldNonce = *nonce; |
JINYEENG | 4:ed5a463a64ad | 253 | uint32_t hashRate; |
JINYEENG | 4:ed5a463a64ad | 254 | |
JINYEENG | 4:ed5a463a64ad | 255 | while (1) { |
JINYEENG | 4:ed5a463a64ad | 256 | |
JINYEENG | 4:ed5a463a64ad | 257 | // Start the timer |
JINYEENG | 4:ed5a463a64ad | 258 | t.start(); |
JINYEENG | 4:ed5a463a64ad | 259 | |
JINYEENG | 4:ed5a463a64ad | 260 | // Compute hash key after nonce is added by 1 every time |
JINYEENG | 4:ed5a463a64ad | 261 | SHA256::computeHash(hash, (uint8_t*)((int)sequence), sizeof(sequence)); |
JINYEENG | 4:ed5a463a64ad | 262 | |
JINYEENG | 4:ed5a463a64ad | 263 | if(t.read() > 1) { |
JINYEENG | 4:ed5a463a64ad | 264 | t.stop(); |
JINYEENG | 4:ed5a463a64ad | 265 | hashRate = ((int)*nonce - (int)oldNonce) / t.read(); |
JINYEENG | 4:ed5a463a64ad | 266 | oldNonce = *nonce; |
JINYEENG | 4:ed5a463a64ad | 267 | putMessage(0, hashRate); |
JINYEENG | 4:ed5a463a64ad | 268 | t.reset(); |
JINYEENG | 4:ed5a463a64ad | 269 | } |
JINYEENG | 4:ed5a463a64ad | 270 | |
JINYEENG | 4:ed5a463a64ad | 271 | if(hash[0] == 0 && hash[1] == 0) { |
JINYEENG | 4:ed5a463a64ad | 272 | putMessage(1, (int)*nonce); |
JINYEENG | 4:ed5a463a64ad | 273 | } |
JINYEENG | 4:ed5a463a64ad | 274 | *nonce= (int)*nonce+1; |
JINYEENG | 4:ed5a463a64ad | 275 | } |
JINYEENG | 4:ed5a463a64ad | 276 | } |
JINYEENG | 4:ed5a463a64ad | 277 |