Callum and Adel's changes on 12/02/19

Dependencies:   Crypto

Files at this revision

API Documentation at this revision

Comitter:
adehadd
Date:
Thu Mar 14 23:28:20 2019 +0000
Parent:
19:805c87360b55
Child:
21:b296db05483d
Commit message:
threads working, serial output better (has a bug on first run that is unsolved). Up to Part 2 of Labs.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
--- 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] = &currentState;
     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();