Parses gcode commands sent over serial communication

Dependencies:   4DGL-uLCD-SE MODSERIAL mbed

gparser.cpp

Committer:
ajb88
Date:
2014-04-14
Revision:
0:fa0891ea897b

File content as of revision 0:fa0891ea897b:

/*
 * mbed GCode parsing Library
 *
 */
#include "gparser.h"
#include "mbed.h"
#include "MODSERIAL.h"
#include <ctype.h>

#define TEST

#ifdef TEST
#include "uLCD_4DGL.h"
uLCD_4DGL uLCD(p9,p10,p11);
#endif

#define FEEDME 10
#define END_OF_TRANSMISSION 23
extern MODSERIAL gpc;

/************VARS*******************************/
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

G_cmd gcmd_list[CMD_LIST_SIZE]; // buffer to be filled with commands, main program retrieves commands from here

// buffer used to transfer the serial buffer contents and parse them into cmd structure
char rx_buff[CMD_BUFFER_SIZE];

volatile bool received;     // indicates when a new cmd is available in the serial buffer
bool endTransmission;       // indicates that all the commands have been sent from the pc

int list_position;  // counter to index the array of command structures


/* This initializes the serial port params to match the PC application
 * the interrupt handlers are also initialized here
 */
void parserInit()
{
    list_position = 0;
    received = false;
    endTransmission = false;
    gpc.baud(921600);
    gpc.autoDetectChar('\0');  //<--to catch the null terminator at the end
    gpc.attach(&cmd_Received, MODSERIAL::RxAutoDetect); // declares callback for when cmd is ready
    gpc.rxBufferFlush();    // flush the buffer just in case
}

/* Parses the received messages into a G_cmd structure
 * it waits for the serial buffer to contain an entire command,
 * parses the gcode and sends the FEEDME command
 * to the pc to request another gcode line
 * returns a pointer to the allocated list of commands.
 */
G_cmd* fillInCmdList()
{
    //list_position = 0;      // incremented by parseGcode at the end

    // end_flag_received should be detected in parseGcode()
    while(endTransmission == false) {
        // Light up LED1 to indicate the mbed is ready to receive Serial commands
        led1 = 1;
        if(received == true) {  //if the buffer has received the null terminator

            // Signal that we are now parsing by lighting LED2
            //led1 = 0;
            led2 = 1;
            parseGcode();
            gpc.rxBufferFlush();        // flushing the buffer just in case
            received = false;
            gpc.putc(FEEDME);           // requesting next command from the pc
            led2 = 0;                   // parsing stage is over
        }
    }
    uLCD.printf("Commands copied %d\n", list_position);
    
    for(int i = (list_position - 4); i < list_position; i++) {
        uLCD.printf("%d X:%f Y:%f Z:%f F:%f.\r\n", gcmd_list[i].G, gcmd_list[i].X, gcmd_list[i].Y, gcmd_list[i].Z, gcmd_list[i].F);       
    }
    
    led1 = 1;
    wait(0.5);
    led1 = 0;
    led2 = 1;
    wait(0.5);
    led2 = 0;
    led3 = 1;
    wait(0.5);
    led3 = 0;
    led1 = 1;
    wait(0.5);
    led3 = 1;
    led2 = 1;
    return gcmd_list;
}

//interrupt routine called when the null terminator is received
void cmd_Received(MODSERIAL_IRQ_INFO *q)
{
    MODSERIAL *sys = q->serial;
    sys->move(rx_buff, CMD_BUFFER_SIZE);;
    received = true;
}
//TODO: Detect the connection finish characters and set a flag so fillInCmdBuff can return
// Parses the received message and populates the structure
void parseGcode()
{
    // checking for the termination of connection
    if(rx_buff[0] == END_OF_TRANSMISSION) {
        led4 = 1;       //received end of transmission from pc
        endTransmission = true;
        return;
    }

    // in case there are leading spaces
    char* cmdP = strtok(rx_buff, " G");

    //uLCD.printf("cmdP is pointing now to %s\n", cmdP);

    char coord_label[2];

    //int g = atoi(cmdP);

    //uLCD.printf("list pos is: %d\n", list_position);

    //fill out the command number field
    gcmd_list[list_position].G = atoi(cmdP);

    //uLCD.printf("%d: ", gcmd_list[list_position].G);

    // Looping to get the arguments
    while (cmdP != NULL) {
        // Retrieve the next Label
        cmdP = strtok (NULL, " G");
        // cmdP should be pointing to a letter now
        //uLCD.printf("Coord: %s.\n", cmdP);
        coord_label[0] = cmdP[0];
        coord_label[1] = cmdP[1];

        // retrieve the number after the letter
        cmdP = strtok (NULL, " G");

        // now print the number
        //uLCD.printf("%s ", cmdP);
        switch(coord_label[0]) {
            case 'X':
                gcmd_list[list_position].X = atof(cmdP);
                break;
            case 'Y':
                gcmd_list[list_position].Y = atof(cmdP);
                break;
            case 'Z':
                gcmd_list[list_position].Z = atof(cmdP);
                break;
            case 'F':
                gcmd_list[list_position].F = atof(cmdP);
                break;
            case 'I':
                gcmd_list[list_position].I = atof(cmdP);
                break;
            case 'J':
                gcmd_list[list_position].J = atof(cmdP);
                break;
            default:
        
                break;
        }// switch
    } // while
    list_position++;
}