new

Dependencies:   Crypto_light mbed-rtos mbed

Fork of ES_CW2_Starter by Edward Stott

Committer:
JINYEENG
Date:
Thu Mar 15 12:38:21 2018 +0000
Revision:
4:ed5a463a64ad
Parent:
3:569b35e2a602
new

Who changed what in which revision?

UserRevisionLine numberNew 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 // Mail
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