For coursework of group 3 in SOFT564Z

Dependencies:   Motordriver ros_lib_kinetic

Debug.cpp

Committer:
Jonathan738
Date:
2020-01-05
Revision:
12:82b8fe254222
Parent:
8:e406c6f728bd

File content as of revision 12:82b8fe254222:

/*------------------------------------------------------------------------------
Creator : Jonathan Wheadon
Date : 29/11/2019
------------------------------------------------------------------------------*/
#include "mbed.h"
#include "rtos.h"
#include "Debug.hpp"
//#include "dateTime.hpp"
#include "General.hpp"
#include "Pins.h"

// queue for Terminal events
EventQueue TerminalQueue(32 * EVENTS_EVENT_SIZE);
/* The EventQueue object is part of mbed's rtos.h */


// Create Object PC of class Terminal with Set SERIAL_TX and SERIAL_RX pins
Terminal PC(SERIAL_TX, SERIAL_RX);
/* Terminal object defined in Debug.hpp */

DigitalOut debugLED(LED2);
DigitalOut debugLED_temp(LED3);

/*------------------------------------------------------------------------------
 Thread for handiling the terminal
------------------------------------------------------------------------------*/
void TerminalThread(void)
{
    // Initialise the terminal printing the table.
    PC.init();
    
    // Enter Forever loop
    while(1) {
        // loop forever dispatching any function called to the queue
        TerminalQueue.dispatch_forever();
    }
}


/*------------------------------------------------------------------------------
 initialize terminal, print table, initialize variables and attach interupts
------------------------------------------------------------------------------*/
void Terminal::init(void)
{
    CurrentIDX = 0;
    col = false;

    debugLED_temp = 0;

    // Set baud rate for serial object pc
    pc.baud (115200);

    // Hide cursor, move to x 0 y 0 and change print colour to green
    pc.printf("\x1b[?25l");
    Cursor(0,0);
    Colour(ColourGREEN);

    // Print DATA table to present data
    pc.printf("|      PROJ515          :      DEBUG MENU       |                                               |\n\r"
              "|***********************************************************************************************|\n\r"
              "|      Error Type       |      Time Stamp       |                 Error MSG                     |\n\r"
              "|-----------------------|-----------------------|-----------------------------------------------|\n\r");
    for(char idx = 0; idx < Rows; idx++) {
        pc.printf("|                       |                       |                                               |\n\r");
    }
    pc.printf("|***********************************************************************************************|\n\r"
              "| Input Command Line :                                                                          |\n\r"
              "|-----------------------------------------------------------------------------------------------|\n\r"
              "|                                                                                               |\n\r"
              "|***********************************************************************************************|\n\r"
              "                                                                                                 ");

    // initialise variables
    buffer_pointer = 0;

    // Attach interupts
    pc.attach(this, &Terminal::Input_Handler,pc.RxIrq);             // This interupt fires whenever data is added to the terminal buffer and calls function input handler
}

/*------------------------------------------------------------------------------
 Move cursor of pc terminal to co-ordinates 'X' and 'Y' (between 0 and 255)
------------------------------------------------------------------------------*/
void Terminal::Cursor(char X, char Y)
{
    pc.printf("\x1b[%d;%dH",Y,X);
}

/*------------------------------------------------------------------------------
 Change pc terminal print colour (8 bit colour) to colour defined by "COLOUR"
------------------------------------------------------------------------------*/
void Terminal::Colour(char COLOUR)
{
    pc.printf("\x1b[38;5;%dm",COLOUR);
}

/*------------------------------------------------------------------------------
 Prints data(STRING) to cell in table defined by IDX
------------------------------------------------------------------------------*/
void Terminal::PrintDATA(char* STRING, char IDX)
{
    char Y = (IDX/3)+5;
    char X = ((IDX%3)*24)+3;
    Cursor(X,Y);
    pc.printf("%s",STRING);
}

/*------------------------------------------------------------------------------
 Function checks terminal buffer to see which key has been entered and saves to
 internal buffer, if carridge return (0x0D) has been pressed it calls function
 to decode the command and add the relavant function to the event QUEUE
------------------------------------------------------------------------------*/
void Terminal::checkKEY(void)
{
    // read char in buffer and save as gotkey
    char gotkey;
    gotkey=pc.getc();

    // if not byte is found do nothing and exit
    if(gotkey == NULL) {
        // do nothing

        // if key is enter (carridge return) call handleCOMMAND function
    } else if (gotkey == 0x0D) {
        Terminal_buffer[buffer_pointer] = 0x00;
        TerminalQueue.call(&PC, &Terminal::HandleCOMMAND);
        buffer_pointer = 0;
        Cursor((24),(Rows+6));
        pc.printf("                                ");

        // if key entered is backspace print " " over last printed char and shift bufferpointer back
    }  else if (gotkey == 0x7f) {
        if (buffer_pointer > 0) {
            buffer_pointer -= 1;
            Cursor((24 + buffer_pointer),(Rows+6));
            pc.printf(" ");
        } else {
            //do nothing
        }

        // if input not specific command save the char to the internal buffer
    } else {
        Colour(ColourWHITE);
        if(buffer_pointer == 30) {
            // do error thing
        } else {
            pc.printf("\x1b[4m");
            Cursor((24 + buffer_pointer),(Rows+6));
            Colour(ColourWHITE);
            pc.printf("%c",gotkey);
            pc.printf("\x1b[24m");
            Terminal_buffer[buffer_pointer] = gotkey;
            buffer_pointer++;
        }
    }
    // re attach the interupt on the serial input flag
    pc.attach(this, &Terminal::Input_Handler,pc.RxIrq);
    wait_ms(100);
}

/*------------------------------------------------------------------------------
 Function decodes command that has been input on input command line and performs
 any necasary action
------------------------------------------------------------------------------*/
void Terminal::HandleCOMMAND(void)
{
    int commandSize = 0;
    int dataSIZE = 0;
    bool searchingCOMMAND = true;
    bool searchingDATA = true;
    while(searchingCOMMAND) {
        if((Terminal_buffer[commandSize] == ' ') || (Terminal_buffer[commandSize] == 0x00)) {
            searchingCOMMAND = false;
        } else {
            commandSize++;
        }

        // debug break loop if too big
        if(commandSize > 4) {
            break;
        }
    }
    while(searchingDATA) {
        if((Terminal_buffer[commandSize+dataSIZE+1] == ' ') || (Terminal_buffer[commandSize+dataSIZE+1] == 0x00)) {
            searchingDATA = false;
        } else {
            dataSIZE++;
        }

        // debug break loop if too big
        if(dataSIZE > 3) {
            break;
        }
    }

    if(commandSize == 4) {
        // Action for input of MOVE command
        if((Terminal_buffer[0] == 'M') && (Terminal_buffer[1] == 'O') && (Terminal_buffer[2] == 'V') && (Terminal_buffer[3] == 'E')) {
            if(dataSIZE != 3) {
                Error msgs;
                msgs.ErrorCode = warning;
                msgs.TimeStamp = "TimeStamp";
                msgs.ErrorMSGS = "input Value is not valid for command \"MOVE\"";
                ERROR_MSGS(msgs);
            } else if((Terminal_buffer[4] != ' ') || (Terminal_buffer[6] != '.')) {
                Error msgs;
                msgs.ErrorCode = warning;
                msgs.TimeStamp = "TimeStamp";
                msgs.ErrorMSGS = "Value input is incorrect format for command \"READ\"";
                ERROR_MSGS(msgs);
            } else {
                float inputVAL;
                BYTE tempARRAY[4] = {'0', Terminal_buffer[5], Terminal_buffer[6], Terminal_buffer[7]};
                inputVAL = strTOflt(tempARRAY);
                
                char buffer_Temp[20];
                sprintf(buffer_Temp, "%1.1f", inputVAL);
                printDEBUG(buffer_Temp);
                
            }
        }
    }
}

/*------------------------------------------------------------------------------
 ISR for whenever data is in terminal buffer, add function to terminal queue
 to check which charecteter has been entered and add it to a buffer.
------------------------------------------------------------------------------*/
void Terminal::Input_Handler(void)
{    
    char gotkey; 
    pc.attach(0);
    gotkey=pc.getc();
    // remove the interupt from the serial input flag
    //pc.attach(NULL,pc.RxIrq);
    debugLED_temp = 1;
    // if data is in the buffer call function to check which key has been entered
    if(pc.readable()!= 0)
    {
        TerminalQueue.call(&PC, &Terminal::checkKEY);
        
    // if no data present in the buffer re attach the interupt
    } else {
        pc.attach(this, &Terminal::Input_Handler,pc.RxIrq);
    }
}

/*------------------------------------------------------------------------------
 Function prints debug messages to screen
------------------------------------------------------------------------------*/
void Terminal::printDEBUG(char* msgs)
{
    // first delete any messages shown in the debug line
    Cursor(3,(Rows+8));
    Colour(ColourWHITE);
    pc.printf("                                                                                              ");
    // now print the new data to the line
    Cursor(3,(Rows+8));
    pc.printf(msgs);
}

/*------------------------------------------------------------------------------
 Function prints ERROR messages to screen
------------------------------------------------------------------------------*/
void Terminal::ERROR_MSGS(Error msgs)
{
    // first delete any messages shown in the debug line
    Cursor(3,(Rows+8));
    pc.printf("                                                                                              ");
    Cursor(3,(Rows+8));

    // Print diferent messages dependent on the Error code attached in the struct Error
    switch(msgs.ErrorCode) {
        case warning :
            Colour(ColourYELLOW);
            PrintDATA("Warning", CurrentIDX);
            PrintDATA(msgs.TimeStamp, CurrentIDX+1);
            PrintDATA(msgs.ErrorMSGS, CurrentIDX+2);
            break;

        case fault :
            Colour(ColourAMBER);
            PrintDATA("Fault", CurrentIDX);
            PrintDATA(msgs.TimeStamp, CurrentIDX+1);
            PrintDATA(msgs.ErrorMSGS, CurrentIDX+2);
            break;

        case criticalERROR :
            Colour(ColourRED);
            PrintDATA("Critical ERROR", CurrentIDX);
            PrintDATA(msgs.TimeStamp, CurrentIDX+1);
            PrintDATA(msgs.ErrorMSGS, CurrentIDX+2);
            break;

        case criticalFAILURE :
            Colour(ColourRED);
            PrintDATA("Critical FAILURE", CurrentIDX);
            PrintDATA(msgs.TimeStamp, CurrentIDX+1);
            PrintDATA(msgs.ErrorMSGS, CurrentIDX+2);
            break;

        default :
            // This point should never be reached as it would indicate a full
            // failure which would cause the watchdog to reset the system
            break;
    }
    
    if(CurrentIDX > MaxDATA-6)
    {
        CurrentIDX = 0;
    } else {
        CurrentIDX += 3;
    }
}

/*------------------------------------------------------------------------------
 Function converts string to float, one decimal place expected must be 4 bytes
 long, PAd with '0', example 1.2f would be "01.2" and 12.3f would be "12.3"
------------------------------------------------------------------------------*/
float strTOflt(char ary[4])
{
    //check that values entered are in format "00.0"
    for(int tester = 0; tester < 4; tester++) {
        if(tester != 2) {
            int testing = (int)(ary[tester]-'0');
            if((testing > 9) || (testing < 0)) {
                return NULL;
            }
        } else if(ary[tester] != '.') {
            return NULL;
        }
    }

    float retFlt;

    retFlt = ((float)(ary[0]-'0'))*10.0f;
    retFlt += ((float)(ary[1]-'0'));
    retFlt += ((float)(ary[3]-'0'))/10.0f;

    if(retFlt > 60.0f) {
        return NULL;
    } else {
        return retFlt;
    }
}

/*------------------------------------------------------------------------------
 Function converts string to int.
 expected format allows upto 3 digits, 1 to 999
------------------------------------------------------------------------------*/
int strTOint(char ary[3])
{
    //check that values entered are in format "000"
    for(int tester = 0; tester < 3; tester++) {
        int testing = (int)(ary[tester]-'0');
        if((testing > 9) || (testing < 0)) {
            return NULL;
        }
    }

    int temp_int = (int)(ary[0]-'0')*100;
    temp_int += (int)(ary[1]-'0')*10;
    temp_int += (int)(ary[2]-'0');

    return temp_int;
}
/*------------------------------------------------------------------------------
    Function to create and send an error message
------------------------------------------------------------------------------*/
void Flag_Error(int ErrorCode, char* ErrorMSG)
{
    //BYTE SampleTimeTag [20];
    //strcpy(SampleTimeTag, getSystemDateTime());

    Error msgs;
    msgs.ErrorCode = ErrorCode;
    msgs.TimeStamp = "Temp";
    msgs.ErrorMSGS = ErrorMSG;
    TerminalQueue.call(&PC, &Terminal::ERROR_MSGS, msgs);
}