Callum and Adel's changes on 12/02/19
Dependencies: Crypto
Diff: main.cpp
- Revision:
- 20:c60f4785b556
- Parent:
- 19:805c87360b55
- Child:
- 21:b296db05483d
diff -r 805c87360b55 -r c60f4785b556 main.cpp --- a/main.cpp Thu Mar 14 16:08:50 2019 +0000 +++ b/main.cpp Thu Mar 14 23:28:20 2019 +0000 @@ -1,7 +1,7 @@ #include "SHA256.h" #include "mbed.h" -#include <iostream> -#include "rtos.h" +// #include <iostream> +// #include "rtos.h" /*TODO: Change @@ -64,28 +64,25 @@ InterruptIn I3(I3pin); //Motor Drive outputs -PwmOut L1L(L1Lpin); +DigitalOut L1L(L1Lpin); DigitalOut L1H(L1Hpin); -PwmOut L2L(L2Lpin); +DigitalOut L2L(L2Lpin); DigitalOut L2H(L2Hpin); -PwmOut L3L(L3Lpin); +DigitalOut L3L(L3Lpin); DigitalOut L3H(L3Hpin); -//Declare and start threads +/*//Declare and start threads class T_{ - protected: - - uint32_t motorPower; // motor toque - float targetVel; - float targetRot; + // protected: + public: Thread *p_comm_in; Thread *p_comm_out; Thread *p_motor_ctrl; - public: + T_(){ //(priority, stack size, @@ -96,10 +93,6 @@ p_comm_in = &comm_in; p_comm_out = &comm_out; p_motor_ctrl = &motor_ctrl; - - motorPower = 300; - targetVel = 45.0; - targetRot = 459.0; } @@ -111,105 +104,32 @@ if (p_motor_ctrl->get_state() == 2) p_motor_ctrl->terminate(); } -}; - - -class Motor : public T_{ +};*/ - private: - int32_t MAXPWM; - int8_t orState; // Rotor offset at motor state 0 - int8_t intStateOld; // Motor old state, may change in ISR - - int32_t motorPos; - - +class Comm /*: public T_*/{ + public: - Motor(){ - MAXPWM = 1000; - orState = 0; - intStateOld = 0; - } - - - //~~~~~~~~~~~~Set a given drive state~~~~~~~~~~~~ - void motorOut(int8_t driveState, uint32_t pw){ - - //Lookup the output byte from the drive state. - int8_t driveOut = driveTable[driveState & 0x07]; - - //Turn off first - if (~driveOut & 0x01) L1L.pulsewidth_us(0); - if (~driveOut & 0x02) L1H = 1; - if (~driveOut & 0x04) L2L.pulsewidth_us(0); - if (~driveOut & 0x08) L2H = 1; - if (~driveOut & 0x10) L3L.pulsewidth_us(0); - if (~driveOut & 0x20) L3H = 1; - - //Then turn on - if (driveOut & 0x01) L1L.pulsewidth_us(pw); - if (driveOut & 0x02) L1H = 0; - if (driveOut & 0x04) L2L.pulsewidth_us(pw); - if (driveOut & 0x08) L2H = 0; - if (driveOut & 0x10) L3L.pulsewidth_us(pw); - if (driveOut & 0x20) L3H = 0; - } - - inline int8_t readRotorState(){ - return stateMap[I1 + 2*I2 + 4*I3]; - } - - int8_t motorHome() { - //Put the motor in drive state 0 and wait for it to stabilise - motorOut(0, MAXPWM); // set to max PWM - wait(2.0); - - //Get the rotor state - return readRotorState(); - } - - void motorISR() { - static int8_t oldRotorState; - int8_t rotorState = readRotorState(); - - motorOut((rotorState-orState+lead+6)%6,motorPower); - - // update motorPosition and oldRotorState - if (rotorState - oldRotorState == 5) motorPos--; - else if (rotorState - oldRotorState == -5) motorPos++; - else motorPos += (rotorState - oldRotorState); - oldRotorState = rotorState; - } - - void stateUpdate(int8_t *params[]) { // () { // **params - *params[0] = readRotorState(); - int8_t currentState = *params[0]; - int8_t offset = *params[1]; - - motorOut((currentState - offset + lead + 6) % 6, MAXPWM); - } -}; - - -class Comm : public T_{ - - private: + Thread t_comm_in; + Thread t_comm_out; + // Thread *p_motor_ctrl; + bool _RUN; RawSerial pc; - Queue<void, 8> inCharQ; // Input Character Queue - - volatile uint64_t newKey; // hash key - Mutex newKey_mutex; // Restrict access to prevent deadlock. + // Queue<void, 8> inCharQ; // Input Character Queue + static const char MsgChar[11]; uint8_t MAXCMDLENGTH; - char newCmd[]; - uint8_t cmdIndx; + + volatile uint8_t cmdIndx; + volatile uint8_t inCharQIdx; - + volatile uint32_t motorPower; // motor toque + volatile float targetVel; + volatile float targetRot; enum msgType {motorState, posIn, velIn, posOut, velOut, @@ -219,7 +139,6 @@ error}; - typedef struct { msgType type; uint32_t message; @@ -228,16 +147,49 @@ Mail<msg, 32> mailStack; void serialISR(){ - uint8_t newChar = pc.getc(); - inCharQ.put((void*)newChar); + if (pc.readable()) { + char newChar = pc.getc(); + // inCharQ.put((void*)newChar); // void* = pointer to an unknown type that cannot be dereferenced + + if (inCharQIdx == (MAXCMDLENGTH)) { + inCharQ[MAXCMDLENGTH] = '\0'; // force the string to have an end character + putMessage(error, 1); + inCharQIdx = 0; // reset buffer index + // pc.putc('\r'); // carriage return moves to the start of the line + // for (int i = 0; i < MAXCMDLENGTH; ++i) + // { + // inCharQ[i] = ' '; + // pc.putc(' '); + // } + + // pc.putc('\r'); // carriage return moves to the start of the line + } + else{ + if(newChar != '\r'){ //While the command is not over, + inCharQ[inCharQIdx] = newChar; //save input character and + inCharQIdx++; //advance index + pc.putc(newChar); + } + else{ + inCharQ[inCharQIdx] = '\0'; //When the command is finally over, + strncpy(newCmd, inCharQ, MAXCMDLENGTH); // Will copy 18 characters from inCharQ to newCmd + cmdParser(); //parse the command for decoding. + for (int i = 0; i < MAXCMDLENGTH; ++i) // reset buffer + inCharQ[i] = ' '; + inCharQIdx = 0; // reset index + } + } + } + + } - void commInFn() { - if (_RUN) - pc.attach(callback(this, &Comm::serialISR)); + /*void commInFn() { + // if (_RUN) + while (_RUN) { osEvent newEvent = inCharQ.get(); - uint8_t newChar = ((uint8_t)(&newEvent.value.p)); + uint8_t newChar = (uint8_t)(newEvent.value.p); // size_t to type cast the 64bit pointer properly pc.putc(newChar); if(cmdIndx >= MAXCMDLENGTH){ //Make sure there is no overflow in comand. cmdIndx = 0; @@ -255,25 +207,34 @@ } } } + }*/ + + void returnCursor() { + pc.putc('>'); + for (int i = 0; i < inCharQIdx; ++i) // reset cursor position + pc.putc(inCharQ[i]); + // for (int i = inCharQIdx; i < MAXCMDLENGTH; ++i) // fill remaining with blanks + // pc.putc(' '); + // pc.putc('<'); } void cmdParser(){ switch(newCmd[0]) { - case 'K': + case 'K': //(MsgChar[keyAdded]):// newKey_mutex.lock(); //Ensure there is no deadlock sscanf(newCmd, "K%x", &newKey); //Find desired the Key code putMessage(keyAdded, newKey); //Print it out newKey_mutex.unlock(); break; - case 'V': + case 'V': //(MsgChar[velIn]):// sscanf(newCmd, "V%f", &targetVel); //Find desired the target velocity putMessage(velIn, targetVel); //Print it out break; - case 'R': + case 'R': //(MsgChar[posIn]):// sscanf(newCmd, "R%f", &targetRot); //Find desired target rotation putMessage(posIn, targetRot); //Print it out break; - case 'T': + case 'T': //(MsgChar[torque]):// sscanf(newCmd, "T%d", &motorPower); //Find desired target torque putMessage(torque, motorPower); //Print it out break; @@ -285,7 +246,7 @@ void commOutFn() { while (_RUN) { osEvent newEvent = mailStack.get(); - msg *pMessage = (msg*)newEvent.value.p; // ADEL ?? + msg *pMessage = (msg*)newEvent.value.p; //Case switch to choose serial output based on incoming message switch(pMessage->type) { @@ -293,34 +254,38 @@ pc.printf("The motor is currently in state %x\n\r", pMessage->message); break; case hashRate: - pc.printf("Mining at a rate of %.2f Hash/s\n\r", (int32_t)pMessage->message); + pc.printf("\r>%s< Mining: %.4u Hash/s\r", inCharQ, (uint32_t)pMessage->message); + returnCursor(); break; case nonceMatch: - pc.printf("Nonce found: %x\n\r", pMessage->message); + pc.printf("\r>%s< Nonce found: %x\r", inCharQ, pMessage->message); + returnCursor(); break; case keyAdded: - pc.printf("New key added:\t0x%016x\n\r", pMessage->message); + pc.printf("New Key Added:\t0x%016x\n\r", pMessage->message); break; case torque: - pc.printf("Motor torque set to:\t%d\n\r", pMessage->message); + pc.printf("Motor Torque set to:\t%d\n\r", pMessage->message); break; case velIn: - pc.printf("Target velocity set to:\t%.2f\n\r", targetVel); + pc.printf("Target Velocity set to:\t%.2f\n\r", targetVel); break; case velOut: pc.printf("Current Velocity:\t%.2f\n\r", \ (float)((int32_t)pMessage->message / 6)); break; case posIn: - pc.printf("Target rotation set to:\t%.2f\n\r", \ + pc.printf("Target Rotation set to:\t%.2f\n\r", \ (float)((int32_t)pMessage->message / 6)); break; case posOut: - pc.printf("Current position:\t%.2f\n\r", \ + pc.printf("Current Position:\t%.2f\n\r", \ (float)((int32_t)pMessage->message / 6)); break; case error: - pc.printf("Debugging position:%x\n\r", pMessage->message); + pc.printf("\r>%s< Debugging position:%x\n\r", inCharQ, pMessage->message); + for (int i = 0; i < MAXCMDLENGTH; ++i) // reset buffer + inCharQ[i] = ' '; break; default: pc.printf("Unknown Error. Message: %x\n\r", pMessage->message); @@ -334,17 +299,56 @@ //TODO: stop function, maybe use parent deconstructor //void stop_comm{} - public: + // public: + + volatile uint64_t newKey; // hash key + Mutex newKey_mutex; // Restrict access to prevent deadlock. - Comm(): pc(SERIAL_TX, SERIAL_RX), T_(){ // inherit from the RawSerial constructor - + Comm() : pc(SERIAL_TX, SERIAL_RX) { // inherit from the RawSerial constructor + + pc.printf("%s\n\r", "Welcome" ); MAXCMDLENGTH = 18; - newCmd[MAXCMDLENGTH] = '0'; + + // reset buffer + // MbedOS prints 'Embedded Systems are fun and do awesome things!' + // if you print a null terminator + pc.putc('>'); + for (int i = 0; i < MAXCMDLENGTH; ++i) { + inCharQ[i] = '.'; + pc.putc('.'); + } + pc.putc('<'); + pc.putc('\r'); + + inCharQ[MAXCMDLENGTH] = '\0'; + strncpy(newCmd, inCharQ, MAXCMDLENGTH); + cmdIndx = 0; + inCharQIdx = 0; + // inCharQIdx = MAXCMDLENGTH-1; + + + + pc.attach(callback(this, &Comm::serialISR)); + + // Thread t_comm_in(osPriorityAboveNormal, 1024); + Thread t_comm_out(osPriorityAboveNormal, 1024); + // Thread t_motor_ctrl(osPriorityAboveNormal, 1024); + motorPower = 300; targetVel = 45.0; targetRot = 459.0; + + + + /*MsgChar = {'m', 'R', 'V', 'r', 'v', + + 'h', 'K', 'n', + + 'T', 'r', + + 'e'};*/ } @@ -356,19 +360,94 @@ } void start_comm(){ - p_comm_in->start(callback(this, &Comm::commInFn)); - p_comm_out->start(callback(this, &Comm::commOutFn)); + _RUN = true; + - _RUN = true; + // reset buffer + // MbedOS prints 'Embedded Systems are fun and do awesome things!' + // if you print a null terminator + pc.putc('>'); + for (int i = 0; i < MAXCMDLENGTH; ++i) { + inCharQ[i] = '.'; + pc.putc('.'); + } + pc.putc('<'); + pc.putc('\r'); + + inCharQ[MAXCMDLENGTH] = '\0'; + strncpy(newCmd, inCharQ, MAXCMDLENGTH); + + // returnCursor(); + + // t_comm_in.start(callback(this, &Comm::commInFn)); + // this::thread::wait() + // wait(1.0); + t_comm_out.start(callback(this, &Comm::commOutFn)); + + } + + char newCmd[]; // because unallocated must be defined at the bottom of the class + char inCharQ[]; }; + +//Set a given drive state +void motorOut(int8_t driveState){ + + //Lookup the output byte from the drive state. + int8_t driveOut = driveTable[driveState & 0x07]; + + //Turn off first + if (~driveOut & 0x01) L1L = 0; + if (~driveOut & 0x02) L1H = 1; + if (~driveOut & 0x04) L2L = 0; + if (~driveOut & 0x08) L2H = 1; + if (~driveOut & 0x10) L3L = 0; + if (~driveOut & 0x20) L3H = 1; + + //Then turn on + if (driveOut & 0x01) L1L = 1; + if (driveOut & 0x02) L1H = 0; + if (driveOut & 0x04) L2L = 1; + if (driveOut & 0x08) L2H = 0; + if (driveOut & 0x10) L3L = 1; + if (driveOut & 0x20) L3H = 0; + } + + //Convert photointerrupter inputs to a rotor state +inline int8_t readRotorState(){ + return stateMap[I1 + 2*I2 + 4*I3]; + } + +//Basic synchronisation routine +int8_t motorHome() { + //Put the motor in drive state 0 and wait for it to stabilise + motorOut(0); + wait(2.0); + + //Get the rotor state + return readRotorState(); +} + + +void stateUpdate(int8_t *params[]) { // () { // **params + *params[0] = readRotorState(); + int8_t currentState = *params[0]; + int8_t offset = *params[1]; + + motorOut((currentState - offset + lead + 6) % 6); +} + //Main int main() { // std::ios::sync_with_stdio(false); - SHA256::SHA256 Miner; + Comm comm_plz; + + // comm_plz.pc.printf("%s\n", "do i work bruh" ); // using printf of class is calm + SHA256 Miner; uint8_t sequence[] = {0x45,0x6D,0x62,0x65,0x64,0x64,0x65,0x64, 0x20,0x53,0x79,0x73,0x74,0x65,0x6D,0x73, @@ -385,16 +464,14 @@ uint32_t hashCounter = 0; Timer timer; + comm_plz.start_comm(); + // Motor States int8_t orState = 0; //Rotot offset at motor state 0 int8_t currentState = 0; //Rotot offset at motor state 0 int8_t stateList[6]; //Rotot offset at motor state 0 //Run the motor synchronisation - - - Motor motor; - Motor* p_motor = &motor; - orState = p_motor->motorHome(); + orState = motorHome(); // Add callbacks // I1.fall(&stateUpdate); @@ -404,7 +481,7 @@ params[0] = ¤tState; params[1] = &orState; - I1.fall(callback(*(p_motor->stateUpdate),params)); + I1.fall(callback(&stateUpdate,params)); I2.fall(callback(&stateUpdate,params)); I3.fall(callback(&stateUpdate,params)); @@ -416,31 +493,31 @@ currentState = readRotorState(); motorOut((currentState-orState+lead+6)%6); // We push it digitally - pc.printf("Rotor origin: %x\n\r",orState); - orState is subtracted from future rotor state inputs to align rotor and motor states - intState = readRotorState(); - if (intState != intStateOld) { - pc.printf("old:%d \t new:%d \t next:%d \n\r",intStateOld, intState, (intState-orState+lead+6)%6); - intStateOld = intState; - motorOut((intState-orState+lead+6)%6); //+6 to make sure the remainder is positive - } + // pc.printf("Rotor origin: %x\n\r",orState); + // orState is subtracted from future rotor state inputs to align rotor and motor states + // intState = readRotorState(); + //if (intState != intStateOld) { + // pc.printf("old:%d \t new:%d \t next:%d \n\r",intStateOld, intState, (intState-orState+lead+6)%6); + // intStateOld = intState; + // motorOut((intState-orState+lead+6)%6); //+6 to make sure the remainder is positive + // } // Keep the program running indefinitely timer.start(); // start timer int stateCount = 0; while (1) { - pc.printf("Current:%d \t Next:%d \n\r", currentState, (currentState-orState+lead+6)%6); + // pc.printf("Current:%d \t Next:%d \n\r", currentState, (currentState-orState+lead+6)%6); + comm_plz.newKey_mutex.lock(); + *key = comm_plz.newKey; + comm_plz.newKey_mutex.unlock(); Miner.computeHash(hash, sequence, length64); hashCounter++; if ((hash[0]==0) && (hash[1]==0)){ - //pc.printf("hash: "); - //for(int i = 0; i < 32; ++i) - //pc.printf("%02x", hash[i]); - //pc.printf("\n\r"); + comm_plz.putMessage((Comm::msgType)7, *nonce); } - // // Try a new nonce + // Try a new nonce (*nonce)++; if (stateCount<6){ @@ -455,8 +532,9 @@ stateCount = 0; } - // // Per Second i.e. when greater or equal to 1 + // Per Second i.e. when greater or equal to 1 if (timer.read() >= 1){ + comm_plz.putMessage((Comm::msgType)5, hashCounter); //pc.printf("HashRate = %02u \n\r",hashCounter); hashCounter=0; timer.reset();