First Commit

Dependencies:   mbed Crypto_light mbed-rtos

Spin it 2 win it

Committer:
TrebleStick
Date:
Mon Mar 12 14:41:46 2018 +0000
Revision:
4:e1141c1d8b19
Parent:
3:2e32d7974962
Child:
5:fe9b21ba2e33
Worked up to CW2 3)C)ii) apart form knowing the max buffer length

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TrebleStick 0:88c3d6c8a4eb 1 #include "mbed.h"
andrebharath 3:2e32d7974962 2 #include "Crypto_light/hash/SHA256.h"
andrebharath 3:2e32d7974962 3 #include "mbed-rtos/rtos/rtos.h"
TrebleStick 0:88c3d6c8a4eb 4
TrebleStick 0:88c3d6c8a4eb 5 //Photointerrupter input pins
TrebleStick 0:88c3d6c8a4eb 6 #define I1pin D2
TrebleStick 0:88c3d6c8a4eb 7 #define I2pin D11
TrebleStick 0:88c3d6c8a4eb 8 #define I3pin D12
andrebharath 3:2e32d7974962 9
TrebleStick 0:88c3d6c8a4eb 10 //Incremental encoder input pins
TrebleStick 0:88c3d6c8a4eb 11 #define CHA D7
TrebleStick 0:88c3d6c8a4eb 12 #define CHB D8
andrebharath 3:2e32d7974962 13
TrebleStick 0:88c3d6c8a4eb 14 //Motor Drive output pins //Mask in output byte
TrebleStick 0:88c3d6c8a4eb 15 #define L1Lpin D4 //0x01
TrebleStick 0:88c3d6c8a4eb 16 #define L1Hpin D5 //0x02
TrebleStick 0:88c3d6c8a4eb 17 #define L2Lpin D3 //0x04
TrebleStick 0:88c3d6c8a4eb 18 #define L2Hpin D6 //0x08
TrebleStick 0:88c3d6c8a4eb 19 #define L3Lpin D9 //0x10
TrebleStick 0:88c3d6c8a4eb 20 #define L3Hpin D10 //0x20
TrebleStick 0:88c3d6c8a4eb 21
andrebharath 3:2e32d7974962 22 //Enum for putMessage message types
andrebharath 3:2e32d7974962 23 #define MSG_HASHCOUNT 0
andrebharath 3:2e32d7974962 24 #define MSG_NONCE_OK 1
TrebleStick 4:e1141c1d8b19 25 #define MSG_OVERFLOW 2
TrebleStick 4:e1141c1d8b19 26 //FIFO constant definitions
TrebleStick 4:e1141c1d8b19 27 #define MAX_ARRAY_SIZE 256 //check the variable fifo position if this is changed
TrebleStick 4:e1141c1d8b19 28
andrebharath 3:2e32d7974962 29
TrebleStick 0:88c3d6c8a4eb 30 //Mapping from sequential drive states to motor phase outputs
TrebleStick 0:88c3d6c8a4eb 31 /*
TrebleStick 0:88c3d6c8a4eb 32 State L1 L2 L3
TrebleStick 0:88c3d6c8a4eb 33 0 H - L
TrebleStick 0:88c3d6c8a4eb 34 1 - H L
TrebleStick 0:88c3d6c8a4eb 35 2 L H -
TrebleStick 0:88c3d6c8a4eb 36 3 L - H
TrebleStick 0:88c3d6c8a4eb 37 4 - L H
TrebleStick 0:88c3d6c8a4eb 38 5 H L -
TrebleStick 0:88c3d6c8a4eb 39 6 - - -
TrebleStick 0:88c3d6c8a4eb 40 7 - - -
TrebleStick 0:88c3d6c8a4eb 41 */
TrebleStick 0:88c3d6c8a4eb 42 //Drive state to output table
TrebleStick 0:88c3d6c8a4eb 43 const int8_t driveTable[] = {0x12,0x18,0x09,0x21,0x24,0x06,0x00,0x00};
andrebharath 3:2e32d7974962 44
TrebleStick 0:88c3d6c8a4eb 45 //Mapping from interrupter inputs to sequential rotor states. 0x00 and 0x07 are not valid
TrebleStick 0:88c3d6c8a4eb 46 const int8_t stateMap[] = {0x07,0x05,0x03,0x04,0x01,0x00,0x02,0x07};
TrebleStick 0:88c3d6c8a4eb 47 //const int8_t stateMap[] = {0x07,0x01,0x03,0x02,0x05,0x00,0x04,0x07}; //Alternative if phase order of input or drive is reversed
andrebharath 3:2e32d7974962 48
TrebleStick 0:88c3d6c8a4eb 49 //Phase lead to make motor spin
TrebleStick 0:88c3d6c8a4eb 50 const int8_t lead = 2; //2 for forwards, -2 for backwards
andrebharath 3:2e32d7974962 51
TrebleStick 4:e1141c1d8b19 52 //Instantiate the serial port, using RawSerial to deal with
TrebleStick 4:e1141c1d8b19 53 //serial's undocumented buffering behaviour
TrebleStick 4:e1141c1d8b19 54 RawSerial pc(SERIAL_TX, SERIAL_RX);
TrebleStick 4:e1141c1d8b19 55
TrebleStick 4:e1141c1d8b19 56 //serial port ISR to take individual chars
TrebleStick 4:e1141c1d8b19 57 void serialISR(){
TrebleStick 4:e1141c1d8b19 58 uint8_t newChar = pc.getc();
TrebleStick 4:e1141c1d8b19 59 inCharQ.put((void*)newChar);
TrebleStick 4:e1141c1d8b19 60 }
TrebleStick 4:e1141c1d8b19 61 //decode commands
TrebleStick 4:e1141c1d8b19 62 Thread decodeT;
TrebleStick 0:88c3d6c8a4eb 63
TrebleStick 4:e1141c1d8b19 64 void decodeFn(){
TrebleStick 4:e1141c1d8b19 65 pc.attach(&serialISR);
TrebleStick 4:e1141c1d8b19 66 char charArray[MAX_ARRAY_SIZE] = "";
TrebleStick 4:e1141c1d8b19 67 uint32_t bufferPosition = 0; //change this variable type if the max buffer/fifio size is found to be different
TrebleStick 4:e1141c1d8b19 68 bool exit = false;
TrebleStick 4:e1141c1d8b19 69 while(!exit) {
TrebleStick 4:e1141c1d8b19 70
TrebleStick 4:e1141c1d8b19 71 //get new char
TrebleStick 4:e1141c1d8b19 72 osEvent newEvent = inCharQ.get();
TrebleStick 4:e1141c1d8b19 73 uint8_t newChar = (uint8_t)newEvent.value.p;
TrebleStick 4:e1141c1d8b19 74
TrebleStick 4:e1141c1d8b19 75 //------error for overflow-------------------------//
TrebleStick 4:e1141c1d8b19 76 if(bufferPosition >= MAX_ARRAY_SIZE - 1){
TrebleStick 4:e1141c1d8b19 77 exit = true;
TrebleStick 4:e1141c1d8b19 78 putMessage(MSG_OVERFLOW, bufferPositon); //
TrebleStick 4:e1141c1d8b19 79 }
TrebleStick 4:e1141c1d8b19 80 //-------------------------------------------------//
TrebleStick 4:e1141c1d8b19 81
TrebleStick 4:e1141c1d8b19 82
TrebleStick 4:e1141c1d8b19 83
TrebleStick 4:e1141c1d8b19 84 //check for carriage return "\r"
TrebleStick 4:e1141c1d8b19 85 if(newChar == 'r'){
TrebleStick 4:e1141c1d8b19 86 if(bufferpostion != 0){
TrebleStick 4:e1141c1d8b19 87 if(charArray[bufferposition - 1] == '\\'){
TrebleStick 4:e1141c1d8b19 88 //carriage found
TrebleStick 4:e1141c1d8b19 89 newChar = '0'; //replace character
TrebleStick 4:e1141c1d8b19 90
TrebleStick 4:e1141c1d8b19 91 //add to array
TrebleStick 4:e1141c1d8b19 92 charArray[bufferPosition] = newChar;
TrebleStick 4:e1141c1d8b19 93
TrebleStick 4:e1141c1d8b19 94 //reset buffer
TrebleStick 4:e1141c1d8b19 95 bufferPosition = 0;
TrebleStick 4:e1141c1d8b19 96 //send char array to decoder ***
TrebleStick 4:e1141c1d8b19 97 }
TrebleStick 4:e1141c1d8b19 98 }
TrebleStick 4:e1141c1d8b19 99 }
TrebleStick 4:e1141c1d8b19 100 //Add new char to array
TrebleStick 4:e1141c1d8b19 101 else{
TrebleStick 4:e1141c1d8b19 102 //add character at current position
TrebleStick 4:e1141c1d8b19 103 charArray[bufferPosition] = newChar;
TrebleStick 4:e1141c1d8b19 104 bufferPosition ++;
TrebleStick 4:e1141c1d8b19 105 }
TrebleStick 4:e1141c1d8b19 106
TrebleStick 4:e1141c1d8b19 107 }//end of : while(!exit){}
TrebleStick 4:e1141c1d8b19 108
TrebleStick 4:e1141c1d8b19 109
TrebleStick 4:e1141c1d8b19 110
TrebleStick 4:e1141c1d8b19 111 //Place it on the end of a char[] array. Make the array large enough to contain the
TrebleStick 4:e1141c1d8b19 112 //longest possible command. You will need to keep an index of the current buffer
TrebleStick 4:e1141c1d8b19 113 //position. This would be easier with the C++ std::string class but there is not
TrebleStick 4:e1141c1d8b19 114 //enough memory available for this. Using a C-style array is also faster and does not
TrebleStick 4:e1141c1d8b19 115 //involve the uncertainty of dynamic memory allocation.
TrebleStick 4:e1141c1d8b19 116
TrebleStick 4:e1141c1d8b19 117 //Include a test to make sure you do not write past the end of the buffer if the
TrebleStick 4:e1141c1d8b19 118 //incoming string is too long. Buffer overflows have historically been the source of
TrebleStick 4:e1141c1d8b19 119 //many software crashes and vulnerabilities since you may be able to alter the return
TrebleStick 4:e1141c1d8b19 120 //address of a function if you write past the end of a buffer.
TrebleStick 4:e1141c1d8b19 121
TrebleStick 4:e1141c1d8b19 122
TrebleStick 4:e1141c1d8b19 123
TrebleStick 4:e1141c1d8b19 124
TrebleStick 4:e1141c1d8b19 125 //If the incoming character is a carriage return ‘\r’ it indicates the end of a
TrebleStick 4:e1141c1d8b19 126 //command. At this point:
TrebleStick 4:e1141c1d8b19 127 //i. Place a string termination character ‘\0’ at the end of the command. This
TrebleStick 4:e1141c1d8b19 128 //is used by functions like printf() and sscanf() to detect the end of the
TrebleStick 4:e1141c1d8b19 129 //string.
TrebleStick 4:e1141c1d8b19 130 //ii. Reset the buffer position index back to 0 ready to record the next command.
TrebleStick 4:e1141c1d8b19 131 //iii. Test the first character to determine which command was sent.
TrebleStick 4:e1141c1d8b19 132 //iv. Decode the rest of the command
andrebharath 3:2e32d7974962 133
TrebleStick 4:e1141c1d8b19 134
TrebleStick 4:e1141c1d8b19 135
TrebleStick 4:e1141c1d8b19 136
TrebleStick 4:e1141c1d8b19 137
TrebleStick 4:e1141c1d8b19 138
TrebleStick 4:e1141c1d8b19 139 }
TrebleStick 4:e1141c1d8b19 140 //structure for Mail Class
andrebharath 3:2e32d7974962 141 typedef struct {
andrebharath 3:2e32d7974962 142 uint8_t code;
andrebharath 3:2e32d7974962 143 uint32_t data;
andrebharath 3:2e32d7974962 144 } message_t ;
andrebharath 3:2e32d7974962 145
TrebleStick 4:e1141c1d8b19 146 //Mail class allowing 16 messages to be stored up in the FIFO
andrebharath 3:2e32d7974962 147 Mail<message_t,16> outMessages;
andrebharath 3:2e32d7974962 148
TrebleStick 4:e1141c1d8b19 149 //Replacement for printf so that notification shortcodes can be sent
andrebharath 3:2e32d7974962 150 void putMessage(uint8_t code, uint32_t data)
andrebharath 3:2e32d7974962 151 {
andrebharath 3:2e32d7974962 152 message_t *pMessage = outMessages.alloc();
andrebharath 3:2e32d7974962 153 pMessage->code = code;
andrebharath 3:2e32d7974962 154 pMessage->data = data;
andrebharath 3:2e32d7974962 155 outMessages.put(pMessage);
andrebharath 3:2e32d7974962 156 }
andrebharath 3:2e32d7974962 157
andrebharath 3:2e32d7974962 158 Thread commOutT;
andrebharath 3:2e32d7974962 159
andrebharath 3:2e32d7974962 160 void commOutFn()
andrebharath 3:2e32d7974962 161 {
andrebharath 3:2e32d7974962 162 while(1) {
andrebharath 3:2e32d7974962 163 osEvent newEvent = outMessages.get();
andrebharath 3:2e32d7974962 164 message_t *pMessage = (message_t*)newEvent.value.p;
andrebharath 3:2e32d7974962 165 pc.printf("Message %d with data 0x%016x\r\n",
andrebharath 3:2e32d7974962 166 pMessage->code,pMessage->data);
andrebharath 3:2e32d7974962 167 outMessages.free(pMessage);
andrebharath 3:2e32d7974962 168 }
andrebharath 3:2e32d7974962 169 }
andrebharath 3:2e32d7974962 170
andrebharath 3:2e32d7974962 171
TrebleStick 0:88c3d6c8a4eb 172 //Status LED
TrebleStick 0:88c3d6c8a4eb 173 DigitalOut led1(LED1);
andrebharath 3:2e32d7974962 174
TrebleStick 0:88c3d6c8a4eb 175 //Photointerrupter inputs
andrebharath 3:2e32d7974962 176 InterruptIn I1(I1pin);
andrebharath 3:2e32d7974962 177 InterruptIn I2(I2pin);
andrebharath 3:2e32d7974962 178 InterruptIn I3(I3pin);
andrebharath 3:2e32d7974962 179
TrebleStick 0:88c3d6c8a4eb 180 //Motor Drive outputs
TrebleStick 0:88c3d6c8a4eb 181 DigitalOut L1L(L1Lpin);
TrebleStick 0:88c3d6c8a4eb 182 DigitalOut L1H(L1Hpin);
TrebleStick 0:88c3d6c8a4eb 183 DigitalOut L2L(L2Lpin);
TrebleStick 0:88c3d6c8a4eb 184 DigitalOut L2H(L2Hpin);
TrebleStick 0:88c3d6c8a4eb 185 DigitalOut L3L(L3Lpin);
TrebleStick 0:88c3d6c8a4eb 186 DigitalOut L3H(L3Hpin);
andrebharath 3:2e32d7974962 187
andrebharath 3:2e32d7974962 188 volatile uint16_t hashcount = 0;
TrebleStick 0:88c3d6c8a4eb 189
andrebharath 3:2e32d7974962 190 void do_hashcount()
andrebharath 3:2e32d7974962 191 {
andrebharath 3:2e32d7974962 192 putMessage(MSG_HASHCOUNT, hashcount);
andrebharath 3:2e32d7974962 193 hashcount = 0;
andrebharath 3:2e32d7974962 194 }
andrebharath 3:2e32d7974962 195
TrebleStick 0:88c3d6c8a4eb 196 //Set a given drive state
andrebharath 3:2e32d7974962 197 void motorOut(int8_t driveState)
andrebharath 3:2e32d7974962 198 {
TrebleStick 0:88c3d6c8a4eb 199
TrebleStick 0:88c3d6c8a4eb 200 //Lookup the output byte from the drive state.
TrebleStick 0:88c3d6c8a4eb 201 int8_t driveOut = driveTable[driveState & 0x07];
TrebleStick 0:88c3d6c8a4eb 202
TrebleStick 0:88c3d6c8a4eb 203 //Turn off first
TrebleStick 0:88c3d6c8a4eb 204 if (~driveOut & 0x01) L1L = 0;
TrebleStick 0:88c3d6c8a4eb 205 if (~driveOut & 0x02) L1H = 1;
TrebleStick 0:88c3d6c8a4eb 206 if (~driveOut & 0x04) L2L = 0;
TrebleStick 0:88c3d6c8a4eb 207 if (~driveOut & 0x08) L2H = 1;
TrebleStick 0:88c3d6c8a4eb 208 if (~driveOut & 0x10) L3L = 0;
TrebleStick 0:88c3d6c8a4eb 209 if (~driveOut & 0x20) L3H = 1;
TrebleStick 0:88c3d6c8a4eb 210
TrebleStick 0:88c3d6c8a4eb 211 //Then turn on
TrebleStick 0:88c3d6c8a4eb 212 if (driveOut & 0x01) L1L = 1;
TrebleStick 0:88c3d6c8a4eb 213 if (driveOut & 0x02) L1H = 0;
TrebleStick 0:88c3d6c8a4eb 214 if (driveOut & 0x04) L2L = 1;
TrebleStick 0:88c3d6c8a4eb 215 if (driveOut & 0x08) L2H = 0;
TrebleStick 0:88c3d6c8a4eb 216 if (driveOut & 0x10) L3L = 1;
TrebleStick 0:88c3d6c8a4eb 217 if (driveOut & 0x20) L3H = 0;
andrebharath 3:2e32d7974962 218 }
TrebleStick 0:88c3d6c8a4eb 219
andrebharath 3:2e32d7974962 220 //Convert photointerrupter inputs to a rotor state
andrebharath 3:2e32d7974962 221 inline int8_t readRotorState()
andrebharath 3:2e32d7974962 222 {
TrebleStick 0:88c3d6c8a4eb 223 return stateMap[I1 + 2*I2 + 4*I3];
andrebharath 3:2e32d7974962 224 }
andrebharath 3:2e32d7974962 225
TrebleStick 0:88c3d6c8a4eb 226 //Basic synchronisation routine
andrebharath 3:2e32d7974962 227 int8_t motorHome()
andrebharath 3:2e32d7974962 228 {
TrebleStick 0:88c3d6c8a4eb 229 //Put the motor in drive state 0 and wait for it to stabilise
TrebleStick 0:88c3d6c8a4eb 230 motorOut(0);
andrebharath 3:2e32d7974962 231 wait(2.0);
TrebleStick 0:88c3d6c8a4eb 232
TrebleStick 0:88c3d6c8a4eb 233 //Get the rotor state
TrebleStick 0:88c3d6c8a4eb 234 return readRotorState();
TrebleStick 0:88c3d6c8a4eb 235 }
andrebharath 3:2e32d7974962 236
andrebharath 3:2e32d7974962 237 void photointerrupter_isr()
andrebharath 3:2e32d7974962 238 {
andrebharath 3:2e32d7974962 239 int8_t orState = motorHome();
andrebharath 3:2e32d7974962 240 int8_t intState = readRotorState();
andrebharath 3:2e32d7974962 241 motorOut((intState-orState+lead+6)%6); //+6 to make sure the remainder is positive
andrebharath 3:2e32d7974962 242 }
TrebleStick 0:88c3d6c8a4eb 243
TrebleStick 0:88c3d6c8a4eb 244 //Main
andrebharath 3:2e32d7974962 245 int main()
andrebharath 3:2e32d7974962 246 {
andrebharath 3:2e32d7974962 247 I1.rise(&photointerrupter_isr);
andrebharath 3:2e32d7974962 248 I2.rise(&photointerrupter_isr);
andrebharath 3:2e32d7974962 249 I3.rise(&photointerrupter_isr);
andrebharath 3:2e32d7974962 250
andrebharath 3:2e32d7974962 251 I1.fall(&photointerrupter_isr);
andrebharath 3:2e32d7974962 252 I2.fall(&photointerrupter_isr);
andrebharath 3:2e32d7974962 253 I3.fall(&photointerrupter_isr);
andrebharath 3:2e32d7974962 254
andrebharath 3:2e32d7974962 255 Ticker hashcounter;
andrebharath 3:2e32d7974962 256 hashcounter.attach(&do_hashcount, 1.0);
TrebleStick 0:88c3d6c8a4eb 257
andrebharath 3:2e32d7974962 258 commOutT.start(&commOutFn);
TrebleStick 0:88c3d6c8a4eb 259
TrebleStick 4:e1141c1d8b19 260 decodeT.start(&decodeFN);
TrebleStick 4:e1141c1d8b19 261
andrebharath 3:2e32d7974962 262 uint8_t sequence[] = {0x45,0x6D,0x62,0x65,0x64,0x64,0x65,0x64,
andrebharath 3:2e32d7974962 263 0x20,0x53,0x79,0x73,0x74,0x65,0x6D,0x73,
andrebharath 3:2e32d7974962 264 0x20,0x61,0x72,0x65,0x20,0x66,0x75,0x6E,
andrebharath 3:2e32d7974962 265 0x20,0x61,0x6E,0x64,0x20,0x64,0x6F,0x20,
andrebharath 3:2e32d7974962 266 0x61,0x77,0x65,0x73,0x6F,0x6D,0x65,0x20,
andrebharath 3:2e32d7974962 267 0x74,0x68,0x69,0x6E,0x67,0x73,0x21,0x20,
andrebharath 3:2e32d7974962 268 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
andrebharath 3:2e32d7974962 269 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
andrebharath 3:2e32d7974962 270 uint64_t* key = (uint64_t*)((int)sequence + 48);
andrebharath 3:2e32d7974962 271 uint64_t* nonce = (uint64_t*)((int)sequence + 56);
andrebharath 3:2e32d7974962 272 uint8_t hash[32];
TrebleStick 0:88c3d6c8a4eb 273
TrebleStick 0:88c3d6c8a4eb 274 //Poll the rotor state and set the motor outputs accordingly to spin the motor
TrebleStick 0:88c3d6c8a4eb 275 while (1) {
andrebharath 3:2e32d7974962 276 SHA256::computeHash(hash, sequence, 64);
TrebleStick 0:88c3d6c8a4eb 277
andrebharath 3:2e32d7974962 278 if (hash[0] == 0 && hash[1] == 0) {
andrebharath 3:2e32d7974962 279 putMessage(MSG_NONCE_OK, *nonce);
andrebharath 3:2e32d7974962 280 }
andrebharath 3:2e32d7974962 281
andrebharath 3:2e32d7974962 282 (*nonce)++;
andrebharath 3:2e32d7974962 283 hashcount++;
TrebleStick 1:a530f6235850 284
TrebleStick 0:88c3d6c8a4eb 285 }
TrebleStick 0:88c3d6c8a4eb 286 }
andrebharath 3:2e32d7974962 287
andrebharath 3:2e32d7974962 288