Embedded System CW2
Dependencies: Crypto_light mbed-rtos mbed
Fork of ES_CW2_Starter by
Revision 4:bcd27085832d, committed 2018-03-23
- Comitter:
- ylx15
- Date:
- Fri Mar 23 20:39:06 2018 +0000
- Parent:
- 3:569b35e2a602
- Commit message:
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Crypto_light.lib Fri Mar 23 20:39:06 2018 +0000 @@ -0,0 +1,1 @@ +http://os.mbed.com/users/estott/code/Crypto_light/#634f9c4cbab1
--- a/main.cpp Thu Mar 01 09:41:46 2018 +0000 +++ b/main.cpp Fri Mar 23 20:39:06 2018 +0000 @@ -1,4 +1,7 @@ #include "mbed.h" +#include "SHA256.h" +#include "rtos.h" +#include <algorithm> //Photointerrupter input pins #define I1pin D2 @@ -37,44 +40,167 @@ //const int8_t stateMap[] = {0x07,0x01,0x03,0x02,0x05,0x00,0x04,0x07}; //Alternative if phase order of input or drive is reversed //Phase lead to make motor spin -const int8_t lead = 2; //2 for forwards, -2 for backwards +int8_t lead = 2; //2 for forwards, -2 for backwards. (used to be const) //Status LED DigitalOut led1(LED1); //Photointerrupter inputs -DigitalIn I1(I1pin); -DigitalIn I2(I2pin); -DigitalIn I3(I3pin); +InterruptIn I1(I1pin); +InterruptIn I2(I2pin); +InterruptIn I3(I3pin); //Motor Drive outputs -DigitalOut L1L(L1Lpin); +PwmOut L1L(L1Lpin); DigitalOut L1H(L1Hpin); -DigitalOut L2L(L2Lpin); +PwmOut L2L(L2Lpin); DigitalOut L2H(L2Hpin); -DigitalOut L3L(L3Lpin); +PwmOut L3L(L3Lpin); DigitalOut L3H(L3Hpin); + +////////////////////////////////////////////////////////// Print to serial port + +//Class Mail +typedef struct{ + char label1; + char label2; + uint8_t code; + uint32_t data; +} message_t; +Mail<message_t, 16> outMessages; + +//Add message to the queue +void putMessage(char label1, char label2, uint8_t code, uint32_t data) { + message_t *pMessage = outMessages.alloc(); + pMessage->label1 = label1; + pMessage->label2 = label2; + pMessage->code = code; + pMessage->data = data; + outMessages.put(pMessage); +} + +//Initialise the serial port +RawSerial pc(SERIAL_TX, SERIAL_RX); + +Thread commOutT(osPriorityHigh,1024); + +void commOutFn(){ + while (1){ + // wait for a message to be available in the queue from outmessage + osEvent newEvent = outMessages.get(); + message_t *pMessage= (message_t*)newEvent.value.p; + if ((pMessage -> code == 2) || (pMessage -> code == 9)){ + // output hex values only for bitcoin key and nonce + pc.printf("Message %d with data 0x%016x\n\r", pMessage -> code, pMessage -> data); + }else{ + pc.printf("Message %d : %c - %c with data %i\n\r", pMessage -> code, pMessage ->label1, pMessage->label2, pMessage -> data); + } + outMessages.free(pMessage); // empty previously allocated memory + } +} + +////////////////////////////////////////////////////////////////////// Decoding +//Initialize variables +Mutex newKey_mutex; +volatile uint64_t newKey = 0; +// where possible make integers of size less than 32 to assure atomic access +volatile uint32_t motorPower = 1000; +volatile int32_t newVelocity = 0; +volatile int32_t desiredPosition = 0; +volatile int32_t desiredRotations = 0; + +Queue<void, 8> inCharQ; + +int32_t motorPosition; + +// serialISR receive each incoming byte and place it in the queue +void serialISR(){ + // receive incoming byte. called to prevent the interrupt from retriggering + uint8_t newChar = pc.getc(); + inCharQ.put((void*)newChar); // place it in a queue +} + +// Code for the decoding thread +const uint8_t arr_size = 25; +char newCmd [arr_size]; // create array large enough -> depends on commands +uint8_t buffPosition = 0; + +Thread ReceiveBytesT(osPriorityNormal,1024); + +void ReceiveBytesFn(){ + pc.attach(&serialISR); + while(1) { + osEvent newEvent = inCharQ.get(); + uint8_t newChar = (uint8_t)newEvent.value.p; + + if (buffPosition < arr_size) { + // determine when the command is finished + if (newChar == '\r'){ // equivalent of the enter key + newCmd[buffPosition] = '\0'; // signs the end for sscanf + + //Bitcoin Key + if (newCmd[0]=='K'){ + newKey_mutex.lock(); + //decode the command and set the new key value + sscanf(newCmd, "K%x", &newKey); + newKey_mutex.unlock(); + } + + //Set motor Torque/ motorPwer + if (newCmd[0]=='T'){ + // no need for mutex because uint32_t access is atomic + sscanf(newCmd, "T%i", &motorPower); + } + + //Set rotational speed + if (newCmd[0]=='V'){ + sscanf(newCmd, "V%i", &newVelocity); + } + + //Set Position Control + if (newCmd[0]=='P'){ + sscanf(newCmd, "P%i", &desiredPosition); + } + + //Set Rotation Control + if (newCmd[0]=='R'){ + sscanf(newCmd, "R%i", &desiredRotations); + desiredPosition = motorPosition + desiredRotations*6; + } + + buffPosition = 0; // reset the buff position + } + else{ + newCmd[buffPosition] = newChar; + buffPosition++; + } + } + } +} + +///////////////////////////////////////////////////////////////// Motor Control + //Set a given drive state -void motorOut(int8_t driveState){ +void motorOut(int8_t driveState, uint32_t motor_torque){ //Lookup the output byte from the drive state. int8_t driveOut = driveTable[driveState & 0x07]; //Turn off first - if (~driveOut & 0x01) L1L = 0; + if (~driveOut & 0x01) L1L.pulsewidth_us(0); if (~driveOut & 0x02) L1H = 1; - if (~driveOut & 0x04) L2L = 0; + if (~driveOut & 0x04) L2L.pulsewidth_us(0); if (~driveOut & 0x08) L2H = 1; - if (~driveOut & 0x10) L3L = 0; + if (~driveOut & 0x10) L3L.pulsewidth_us(0); if (~driveOut & 0x20) L3H = 1; //Then turn on - if (driveOut & 0x01) L1L = 1; + if (driveOut & 0x01) L1L.pulsewidth_us(motor_torque); if (driveOut & 0x02) L1H = 0; - if (driveOut & 0x04) L2L = 1; + if (driveOut & 0x04) L2L.pulsewidth_us(motor_torque); if (driveOut & 0x08) L2H = 0; - if (driveOut & 0x10) L3L = 1; + if (driveOut & 0x10) L3L.pulsewidth_us(motor_torque); if (driveOut & 0x20) L3H = 0; } @@ -86,21 +212,139 @@ //Basic synchronisation routine int8_t motorHome() { //Put the motor in drive state 0 and wait for it to stabilise - motorOut(0); + motorOut(0, 1000); wait(2.0); //Get the rotor state return readRotorState(); } +int8_t orState = 0; //Rotot offset at motor state 0 + +volatile float ys = 0; +volatile float yr = 0; +volatile float y_tmp = 0; +volatile int32_t v = 0; + +void motorISR(){ + // choose between ys and yr according to the positions + if (v>=0){ + if(min(ys,yr)==yr){ + y_tmp = yr; + }else{ + y_tmp = ys; + } + }else{ + if(max(ys,yr)==yr){ + y_tmp = yr; + }else{ + y_tmp = ys; + } + } + + + // V0 overrides everything + if ((abs(y_tmp) > 1000)||(newVelocity == 0)){ + motorPower = 1000; + }else{ + motorPower = abs(y_tmp); + } + if ((y_tmp>=0)||(newVelocity ==0)){ + lead = 2; + } + else { + lead = -2; + } + + + // a count of 6 will equal one revolution + static int8_t oldRotorState; + int8_t rotorState = readRotorState(); + motorOut((rotorState-orState+lead+6)%6, motorPower); + if (rotorState - oldRotorState == 5) motorPosition--; + else if (rotorState - oldRotorState == -5) motorPosition++; + else motorPosition += (rotorState - oldRotorState); + oldRotorState = rotorState; + +} + + + +Thread motorCtrlT (osPriorityNormal,512); // 1024 too big + +void motorCtrlTick(){ + motorCtrlT.signal_set(0x1); +} + +void motorCtrlFn(){ + int32_t motorposition_old = 0; + int32_t v_calc_counter = 0; + int32_t kp = 23; + int32_t kd = 18; + int32_t localMotorPosition = 0; + int32_t localDesiredPosition = 0; + int32_t local_s = 0; + int32_t Er = 0; + int32_t Er_old = 0; + int32_t dErdt = 0; + + Ticker motorCtrlTicker; + motorCtrlTicker.attach_us(&motorCtrlTick,100000); // 100ms = 100000us + while(1){ + Timer t; + t.start(); + motorCtrlT.signal_wait(0x1); // from here onward it executes once 0.1s + + // make local copies to compute computation + // becasue these variables can be updated at anytime + localDesiredPosition = desiredPosition; + localMotorPosition = motorPosition; + local_s = newVelocity; + Er = localDesiredPosition-localMotorPosition; + + // below is the velocity per second since this runs every 0.1s + v = (localMotorPosition-motorposition_old)/(6*t.read()); + dErdt = (Er-Er_old)/t.read(); + t.reset(); + + motorposition_old = localMotorPosition; + Er_old = Er; + + v_calc_counter ++; + + if (v_calc_counter >= 10){ + //putMessage('c','v',3, v); //current velocity + v_calc_counter = 0; + } + + yr = kp*Er + kd*dErdt; + + // there were problems with the function abs(). use if-else instead + if (v>=0){ + if (Er >= 0){ + ys = kp*(local_s - v); + }else{ + ys = -1*kp*(local_s - v); + } + }else{ + if (Er >= 0){ + ys = kp*(local_s + v); + }else{ + ys = -1*kp*(local_s + v); + } + } + + } +} + + //Main int main() { - int8_t orState = 0; //Rotot offset at motor state 0 - int8_t intState = 0; - int8_t intStateOld = 0; - //Initialise the serial port - Serial pc(SERIAL_TX, SERIAL_RX); + L1L.period_us(2000); + L2L.period_us(2000); + L3L.period_us(2000); + pc.printf("Hello\n\r"); //Run the motor synchronisation @@ -108,13 +352,56 @@ pc.printf("Rotor origin: %x\n\r",orState); //orState is subtracted from future rotor state inputs to align rotor and motor states + I1.rise(&motorISR); + I1.fall(&motorISR); + I2.rise(&motorISR); + I2.fall(&motorISR); + I3.rise(&motorISR); + I3.fall(&motorISR); + + commOutT.start(commOutFn); + ReceiveBytesT.start(ReceiveBytesFn); + motorCtrlT.start(motorCtrlFn); + + SHA256 tmp; + + uint8_t sequence[] = {0x45,0x6D,0x62,0x65,0x64,0x64,0x65,0x64,0x20,0x53,0x79,0x73,0x74,0x65,0x6D,0x73,0x20,0x61,0x72,0x65,0x20,0x66,0x75,0x6E,0x20,0x61,0x6E,0x64,0x20,0x64,0x6F,0x20,0x61,0x77,0x65,0x73,0x6F,0x6D,0x65,0x20,0x74,0x68,0x69,0x6E,0x67,0x73,0x21,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + uint64_t* key = (uint64_t*)((int)sequence + 48); + uint64_t* nonce = (uint64_t*)((int)sequence + 56); + uint8_t hash[32]; + + Timer t; + t.start(); + uint32_t hashcount = 0; + //Poll the rotor state and set the motor outputs accordingly to spin the motor while (1) { - intState = readRotorState(); - if (intState != intStateOld) { - intStateOld = intState; - motorOut((intState-orState+lead+6)%6); //+6 to make sure the remainder is positive + newKey_mutex.lock(); + *key = newKey; + newKey_mutex.unlock(); + + tmp.computeHash(hash, sequence, 64); + *nonce = *nonce + 1; + // increase the hashcount after every computeHash + hashcount ++; + + + if (t.read()>=1){ + putMessage('H','R',1, hashcount); // hash rate per second + hashcount = 0; + t.reset(); + putMessage('c','v',3, v); //current velocity in rotation per second + putMessage('T','V',4, newVelocity); // Target Velocity in rotation per second + putMessage('c','p',5, motorPosition); // current position + putMessage('T','P',6, desiredPosition); // Target Position + //putMessage('K','K',9, *key); } + + if ((hash[0]==0)&&(hash[1]==0)){ + putMessage('B','N',2,*nonce); // Bitcoin Nonce + } + + } -} - + +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Fri Mar 23 20:39:06 2018 +0000 @@ -0,0 +1,1 @@ +http://os.mbed.com/users/mbed_official/code/mbed-rtos/#5713cbbdb706
--- a/mbed.bld Thu Mar 01 09:41:46 2018 +0000 +++ b/mbed.bld Fri Mar 23 20:39:06 2018 +0000 @@ -1,1 +1,1 @@ -https://os.mbed.com/users/mbed_official/code/mbed/builds/7130f322cb7e \ No newline at end of file +https://os.mbed.com/users/mbed_official/code/mbed/builds/5571c4ff569f \ No newline at end of file