stingr lib for v8_1

Revision:
0:0159aa4d2062
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Stingr.cpp	Mon Oct 29 12:45:27 2018 +0000
@@ -0,0 +1,761 @@
+/* 
+ * mbed STINGR Library
+ * Copyright (c) 2018 
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+ 
+#include "Stingr.h"
+#include "mbed.h"
+#include "rtos.h"
+
+#define QUERY_ESN           'a'
+#define QUERY_BURSTS        'b'
+#define QUERY_FIRMWARE      'c'
+#define QUERY_SETUP         'd'
+#define QUERY_HARDWARE      'e'
+#define NAK_COMMAND         'f'
+#define SETUP               'g'
+#define SEND_DATA           'h'
+#define ABORT_TRANSMISSION  'i'
+
+// These two lines redundant?
+Serial _stingrUART(p13, p14, 9600);  // tx, rx Comunicación Serial con el STINGR
+Serial _pc(USBTX, USBRX, 9600);      // tx, rx Comunicación Serial con la PC
+
+// Pin Digital de entrada "CTS" en modo Pull-Up 
+// para encontrarse normalmente a VCC cuando no haya un pulso. 
+DigitalIn _CTS(p11, PullUp);         
+
+// Pin Digital de Salida "RTS" 
+// Predefinido para valer 1 en su estado inactivo dentro del código.
+DigitalOut _RTS(p12, 1);
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+// Constructor
+Stingr::Stingr()
+{
+    incomingByte = 0;
+    flag = 1;
+    num = 0;
+    incomingByteR = 0;
+    incomingByteX = 0;
+    
+    // For Luis Fernando:
+    // This thread is for the Mbed to read and serial print responses from STINGR
+    t1.start(callback(this,&Stingr::respuesta));
+    
+    // For Luis Fernando:
+    // This thread is for reading commands from serial PC. (May be commented)
+    t2.start(callback(this,&Stingr::PC_communication));
+}
+
+// Accessor
+const char* Stingr::get_resp() const
+{
+    return _resp;
+}
+
+// Mutator
+void Stingr::setPacketByte(int incomingByte)
+{
+    _packet[num] = incomingByte;
+    num++;
+}
+
+/******************************************************************************/
+/********************[SERIAL PACKET PROCESSING FUNCTIONS]**********************/
+/******************************************************************************/
+
+void Stingr::clearPacket()
+{
+    num = 0;
+    for(int i = 0; i < 15 ; i++)
+        _packet[i] = 0;
+}
+
+void Stingr::printPacket()
+{
+    _pc.printf("\nResponse(Stingr)dec: \t");
+    for(int i = 0; i < 15 ; i++)
+    {
+        _pc.printf("%u",_packet[i]);  // Format specifier
+        _pc.printf(" ");
+    }
+}
+
+void Stingr::waitCTS()
+{
+    Thread::wait(200);                                                    // Se da un tiempo para que el analizador se estabilice
+    incomingByte=0;
+    //pc.printf("El valor de CTS es %d\n\r",CTS.read());        // Se lee el valor de la variable CTS, la cual debe ser 1
+    //pc.printf("El valor de RTS es %d\n\r",RTS.read());        // Se lee el valor de la variable RTS, la cual debe ser 1
+    _RTS=0;                                                      // Se manda un pulso en bajo en RTS, para inicial el proceso de transmisión
+    
+    while(flag==1)
+    {// Flag inicialmente vale 1, así que el ciclo while cambiará hasta que esa condición no se cumpla           
+        flag=_CTS.read();        // Cuando entra el ciclo, se iguala flag a CTS, el cual cuando cambie a 0 provocará que termine el while (máx 125 ms)
+        //pc.printf("El valor de flag es %d\n\r", flag);    // Se imprime el valor de flag, para identificar cuando termina el ciclo while
+    }
+}
+
+void Stingr::postCommand()
+{
+    Thread::wait(10);                // Se esperan .1 segundos una vez que se terminaron de hacer las transmisiones
+    //El tiempo total de transmisión es; el wait previo a las transmisiones, el tiempo que tarda el Mu en enviar los datos y el wait posterior a la transmisión
+    _RTS=1;
+    Thread::wait(150);
+    //pc.printf("\n\rCTS: %d\n\r",CTS.read());
+    flag=1;
+} 
+
+void Stingr::command(char* com)  
+{ 
+    char c = com[0];    
+        
+    switch(c) 
+    {
+        case QUERY_ESN:
+            query_ESN();
+            break;
+            
+        case QUERY_BURSTS:
+            query_Bursts();
+            break;
+            
+        case QUERY_FIRMWARE:
+            query_Firmware();
+            break;
+            
+        case QUERY_SETUP:
+            query_Setup();
+            break;
+            
+        case QUERY_HARDWARE:
+            query_Hardware();
+            break;
+            
+        case NAK_COMMAND:
+            NAK_command();
+            break;
+            
+        case SETUP:
+            _setup(com);           //* later make this function to pass buf parameter
+            break;
+            
+        case SEND_DATA:
+            send_Data(com);
+            break;
+            
+        case ABORT_TRANSMISSION:
+            abort_Transmission();
+            break;
+            
+        default:
+        {
+            //do nothing
+        }
+    }     
+}
+
+void Stingr::execute(char* com)  
+{ 
+    char c = com[0];    
+
+    switch(c) 
+    {
+        case 'a':
+        case 'b':
+        case 'c':
+        case 'd':
+        case 'e':
+        case 'f':
+        case 'g':
+        case 'h':
+        case 'i':
+            // if 'a'-'i', set _resp to garbage for 1st call
+            strncpy(_resp,"garbage",sizeof(_resp)); 
+            break;
+        default:
+        {
+            // do nothing for 2nd call.
+        } 
+    }     
+}
+
+/******************************************************************************/
+/************************[STINGR COMMAND FUNCTIONS]****************************/
+/******************************************************************************/
+
+//0x01 Query ESN
+void Stingr::query_ESN()
+{
+    led1=!led1;             
+        
+    _pc.printf("\r0x01\t\t\tQuery ESN\n");
+    _pc.printf("Command(HEX):\t\tAA 5 1 50 D5\n\r");
+    _pc.printf("Response(Stingr)HEX:\t");
+    
+    waitCTS();
+    Thread::wait(10);
+     
+    _stingrUART.putc(0XAA);      
+    _stingrUART.putc(0X05);
+    _stingrUART.putc(0X01);
+    _stingrUART.putc(0X50);
+    _stingrUART.putc(0XD5);  
+    
+    postCommand();
+    printPacket();
+    
+// Correct ESN
+    if (_packet[3] ==   0 && // 0x00
+        _packet[4] ==  41 && // 0x29
+        _packet[5] ==  72 && // 0x48      //0x43 STINGR TLE
+        _packet[6] == 254)   // 0xFE      //0xB3 STINGR TLE 
+    {
+        clearPacket();
+        _pc.printf("\nQuery ESN is correct. VALID\n");
+        strncpy(_resp,"Query ESN is correct",sizeof(_resp)); 
+    }
+// Wrong ESN
+    else
+    {
+        clearPacket();
+        _pc.printf("\nNAK response. INVALID\n");    
+        strncpy(_resp,"NAK response (Query ESN)",sizeof(_resp));  
+    }
+}
+
+//0x04 Query Bursts
+void Stingr::query_Bursts()
+{
+    int bursts = 0; //default value
+    
+    led2=!led2;
+    _pc.printf("\r0x04\t\t\tQuery Burst Remaining\n");
+    _pc.printf("Command(HEX):\t\tAA 5 4 FD 82\n\r");
+    _pc.printf("Response(Stingr)HEX:\t");
+    waitCTS();
+    Thread::wait(10);
+                    
+    _stingrUART.putc(0XAA);      
+    _stingrUART.putc(0X05);
+    _stingrUART.putc(0X04);
+    _stingrUART.putc(0XFD);
+    _stingrUART.putc(0X82);
+    
+    postCommand();
+    printPacket();
+    
+// NAK response
+    if (_packet[0] == 170 && // 0xAA
+        _packet[1] ==   5 && // 0x05
+        _packet[2] == 255 && // 0xFF
+        _packet[3] == 161 && // 0xA1
+        _packet[4] == 203)   // 0xCB
+    {
+        clearPacket();
+        
+        _pc.printf("\nNAK response. INVALID"); 
+        strncpy(_resp,"NAK response (Query Bursts)",sizeof(_resp));
+    }
+// ACK response
+    else
+    {
+        bursts = _packet[3];
+        clearPacket();
+        
+        char qry[2];
+        sprintf(qry,"%d",bursts); 
+        char strt[] = "Bursts Remaining is ";   
+        strcat(strt,qry);
+                                
+        _pc.printf("\nBursts Remaining: \t");
+        _pc.printf("%u",bursts); 
+        _pc.printf("\n");
+                                
+        strncpy(_resp,strt,sizeof(_resp)); 
+    }
+}
+    
+//0x05 Query Firmware
+void Stingr::query_Firmware()
+{
+    led3=!led3;
+    _pc.printf("\r0x05\t\t\tQuery Firmware Version\n");
+    _pc.printf("Command(HEX):\t\tAA 5 5 74 93\n\r");
+    _pc.printf("Response(Stingr)HEX:\t");
+    waitCTS();
+    Thread::wait(10);               
+    _stingrUART.putc(0XAA);      
+    _stingrUART.putc(0X05);
+    _stingrUART.putc(0X05);
+    _stingrUART.putc(0X74);
+    _stingrUART.putc(0X93);        
+    
+    postCommand();
+    printPacket();
+    if (_packet[3] == 1 && // 0x01
+        _packet[4] == 3)   // 0x03
+    {
+        clearPacket();
+        _pc.printf("\nResponse Processing:\tQuery Firmware is correct. VALID\n");
+        _pc.printf(" Firmware Version: 1.3\n");
+        strncpy(_resp,"Query Firmware is correct",sizeof(_resp));    
+    }
+    else
+    {
+        clearPacket();
+        _pc.printf("NAK. INVALID");
+        strncpy(_resp,"NAK response (Query Firmware)",sizeof(_resp));
+    }
+}
+
+//0x07 Query Setup
+void Stingr::query_Setup()
+{
+    int numSetup = 0;
+    led4=!led4;
+    _pc.printf("\r0x07\t\t\tQuery Setup\n");
+    _pc.printf("Command(HEX):\t\tAA 5 7 66 B0\n\r");
+    _pc.printf("Response(Stingr)HEX:\t");
+    waitCTS();
+    Thread::wait(10);
+                    
+    _stingrUART.putc(0XAA);      
+    _stingrUART.putc(0X05);
+    _stingrUART.putc(0X07);
+    _stingrUART.putc(0X66);
+    _stingrUART.putc(0XB0);
+    
+    postCommand();
+    
+// NAK response
+    if (_packet[0] == 170 && // 0xAA
+        _packet[1] ==   5 && // 0x05
+        _packet[2] == 255 && // 0xFF
+        _packet[3] == 161 && // 0xA1
+        _packet[4] == 203)   // 0xCB
+    {
+        clearPacket();
+        _pc.printf("NAK");    
+    }
+// ACK response 
+    else
+    {
+        numSetup = _packet[7]*10000000 + _packet[8]*100000 + _packet[9]*1000 + _packet[10];
+        clearPacket();
+        
+        char qryRF[1];
+        char qryBursts[2];
+        char qryMin[3];
+        char qryMax[3];
+    
+        char strt[] = "";   
+                                
+        //Print Channel 
+        _pc.printf("\n RF Channel: ");
+        _pc.printf("%u",numSetup/(10000000)); 
+        int rfprint = numSetup/(10000000);                  // RF channel
+        sprintf(qryRF,"%d",rfprint);
+        strcat(strt,qryRF);
+        numSetup = numSetup - (numSetup/10000000)*10000000; // Truncate RF Digits
+                            
+        //Print Bursts
+        _pc.printf("\n # of Bursts: ");
+        _pc.printf("%u",numSetup/(100000));                  // Bursts Per Message
+        int burprint = numSetup/(100000);
+        sprintf(qryBursts,"%d",burprint);
+        strcat(strt,qryBursts);
+        numSetup = numSetup - (numSetup/100000)*100000;     // Truncate Burst Digits
+                            
+        //Print Min Interval
+        _pc.printf("\n Min Burst Interval: ");
+        _pc.printf("%u",numSetup/1000*5);                    // Min Interval
+        int minprint = numSetup/1000*5;
+        sprintf(qryMin,"%d",minprint);
+        strcat(strt,qryMin);
+        numSetup = numSetup - (numSetup/1000)*1000;         // Truncate Min Interval
+        _pc.printf(" seconds");
+                            
+        //Print Max Interval
+        _pc.printf("\n Max Burst Interval: ");
+        _pc.printf("%u",numSetup*5);
+        int maxprint = numSetup*5;                          // Max Interval
+        sprintf(qryMax,"%d",maxprint);
+        strcat(strt,qryMax);
+        _pc.printf(" seconds\n");
+                            
+        strncpy(_resp,strt,sizeof(_resp));
+    }
+}
+
+//0x09 Query Hardware
+void Stingr::query_Hardware()
+{
+    led1=!led1;
+    _pc.printf("\r0x09\t\t\tQuery Hardware Version\n");
+    _pc.printf("Command(HEX):\t\tAA 5 9 18 59\n\r");
+    _pc.printf("Response(Stingr)HEX:\t");
+    waitCTS();
+    Thread::wait(10);                
+    
+    _stingrUART.putc(0XAA);      
+    _stingrUART.putc(0X05);
+    _stingrUART.putc(0X09);
+    _stingrUART.putc(0X18);
+    _stingrUART.putc(0X59);
+    
+    postCommand();
+    printPacket();
+    
+// ACK response
+    if (_packet[5] == 143 && // 0x8F
+        _packet[6] == 98  && // 0x62
+        _packet[7] == 98)    // 0x62
+    {
+        clearPacket();
+        _pc.printf("\nResponse Processing:\tQuery Hardware is correct. VALID\n");
+        _pc.printf(" Device Code: 01\n");
+        _pc.printf(" CPU Revision: 62\n");
+        _pc.printf(" Radio Revision: 62\n");
+        strncpy(_resp,"Query Hardware is correct",sizeof(_resp));    
+    }
+// NAK response
+    else
+    {
+        clearPacket();
+        _pc.printf("\n");
+        _pc.printf("NAK. INVALID");
+        strncpy(_resp,"NAK response (Query Hardware)",sizeof(_resp));
+    }
+}
+
+//NAK Command
+void Stingr::NAK_command()
+{
+    led2=!led2;
+    _pc.printf("\rXxXX\t\t\tNAK\n");
+    _pc.printf("Command(HEX):\t\tAA 5 7 66 B1\n\r");
+    _pc.printf("Response(Stingr)HEX:\t");
+    waitCTS();
+    Thread::wait(10);  
+                  
+    _stingrUART.putc(0XAA);      
+    _stingrUART.putc(0X05);
+    _stingrUART.putc(0X07);
+    _stingrUART.putc(0X66);
+    _stingrUART.putc(0XB1);
+    
+    postCommand();
+    printPacket();
+    clearPacket();
+    _pc.printf("\n");
+    strncpy(_resp,"NAK response",sizeof(_resp)); 
+}
+
+//0x06 Setup
+void Stingr::_setup(char* b)
+{
+    led3=!led3;
+    _pc.printf("\r0x06\t\t\tSetup\n");
+    //_pc.printf("Command(HEX):\t\tAA 0E 06 00 00 00 00 00 03 18 30 00 CE 9C\n\r");
+    
+// RF Channel 
+    int rf = b[1] - '0';
+    _pc.printf("rf channel: %u \n",rf);
+    
+// Bursts
+    int brst = b[2] - '0';
+    _pc.printf("bursts: %u \n", brst);    
+    
+// Min Interval
+    int min_hund = b[3] - '0';
+    int min_tens = b[4] - '0';
+    int min_ones = b[5] - '0';   
+    //_pc.printf("Min interval: %u%u%u seconds\n", min_hund, min_tens, min_ones);
+    int min_int = (min_hund*100 + min_tens*10 + min_ones)/5;
+    _pc.printf("Min interval: %u seconds\n", min_int*5);
+
+// Max Interval
+    int max_hund = b[6] - '0';
+    int max_tens = b[7] - '0';
+    int max_ones = b[8] - '0';
+    //_pc.printf("Max interval: %u%u%u seconds\n", max_hund, max_tens, max_ones);
+    int max_int = (max_hund*100 + max_tens*10 + max_ones)/5;
+    _pc.printf("Max interval: %u seconds\n", max_int*5);
+
+    char header[12] = {0xAA,0x0E,0x06,0x00,0x00,0x00,0x00,rf,brst,min_int,max_int,0x00};
+    
+    _pc.printf("Command(HEX):\t\t");
+    //Print b characters in HEX
+    for(int k = 0; k < 12; k++)   
+        _pc.printf("%X ",header[k]); 
+    
+    // CRC calculation
+    char *t = (char *)header;    //a
+    char crc1 = ModRTU_CRC(t,t[1]-2)&0xFF;
+    char crc2 = ModRTU_CRC(t,t[1]-2)>>8;
+    
+    _pc.printf("%X ",crc1); //%X print char in HEX format
+    _pc.printf("%X ",crc2); //%X print char in HEX format
+    
+    _pc.printf("\nResponse(Stingr)HEX:\t");
+    
+    waitCTS();
+    Thread::wait(10);
+    
+    
+    //Send Command to STINGR
+    for(int k = 0; k < 12; k++)
+        _stingrUART.putc(header[k]);
+    _stingrUART.putc(crc1);
+    _stingrUART.putc(crc2);    
+    
+    /*              
+    _stingrUART.putc(0XAA);      
+    _stingrUART.putc(0X0E);
+    _stingrUART.putc(0X06);
+    _stingrUART.putc(0X00);
+    _stingrUART.putc(0X00);
+    _stingrUART.putc(0X00);
+    _stingrUART.putc(0X00);
+    _stingrUART.putc(0X00);
+    _stingrUART.putc(0X03);
+    _stingrUART.putc(0X18);
+    _stingrUART.putc(0X30);
+    _stingrUART.putc(0X00);
+    _stingrUART.putc(0XCE);
+    _stingrUART.putc(0X9C);
+    */
+    
+    postCommand();
+    printPacket();
+    
+    _pc.printf("\n");
+    clearPacket();
+}
+                           
+//0x00 Send Data
+void Stingr::send_Data(char* b) //char* s //Replace "buf" with "b"
+{
+    led4=!led4;
+    
+// Count all characters before the "Return" key in the buffer
+    int cnt = 0;         
+    for (int k = 0; k < 200; k++)
+    {
+        if(b[k] == '\n') 
+            break;
+        cnt++; 
+    }  
+    
+// Print command info and input                    
+    _pc.printf("0x00\t\t\tSend Data\n\r");
+    cnt--; //Decrement total by 1. Don't count 8/h.
+    _pc.printf("Data Packet length: \t%u\n",cnt);    
+    
+// Port b array to str, but without first character '8/h'                    
+    char str[cnt];  //Declare str array. str will copy buf but without '8'
+    for (int k = 0; k < cnt; k++)
+        str[k] = b[k+1]; //Starts 1 index after '8'.
+                        
+// str1 copies str but with correct datalength by truncating the extra characters
+// found in str        
+    char str1[cnt]; 
+    strncpy(str1,str,cnt); //truncation of extra characters
+    str1[cnt] = '\0'; //Null character                    
+    _pc.printf("Data Packet: \t\t%s \n",str1);
+    
+//--------------------replace b with str1
+    
+    waitCTS();
+    Thread::wait(10);                
+
+// Put str "data" into Serial packet array (to send to STINGR)
+    size_t n = strlen(str1);   //Measure size of b. This includes the zeros //!replaced
+    int number = n+3;
+    int len = n+5;
+    char header[3] = {0xAA,len,0x00};  //Define header information
+    char vec[number];
+    //pc.printf("number = %u\n",number);
+    
+    //store all in vec
+    for(int k = 0; k < 3; k++)
+       vec[k] = header[k];
+    for(int k = 3; k < number; k++)
+       vec[k] = str1[k-3];//!replaced
+       
+    _pc.printf("Command(HEX):\t\t");
+    //Print b characters in HEX
+    for(int k = 0; k < number; k++)   
+        _pc.printf("%X ",vec[k]); 
+
+// CRC calculation
+    char *t = (char *)vec;    //a
+    char crc1 = ModRTU_CRC(t,t[1]-2)&0xFF;
+    char crc2 = ModRTU_CRC(t,t[1]-2)>>8;
+    
+    _pc.printf("%X ",crc1); //%X print char in HEX format
+    _pc.printf("%X ",crc2); //%X print char in HEX format
+    _pc.printf("\nResponse(Stingr)HEX:\t");
+    
+//Send Command to STINGR
+    for(int k = 0; k < number; k++)
+        _stingrUART.putc(vec[k]);
+    _stingrUART.putc(crc1);
+    _stingrUART.putc(crc2);
+          
+    postCommand();
+    printPacket();
+    
+// NAK response
+    if (_packet[0] == 170 && // 0xAA
+        _packet[1] ==   5 && // 0x05
+        _packet[2] == 255 && // 0xFF
+        _packet[3] == 161 && // 0xA1
+        _packet[4] == 203)   // 0xCB
+    {  
+        clearPacket();
+        _pc.printf("\n");
+        _pc.printf("\nNAK response. INVALID");  
+        strncpy(_resp,"NAK response (Send Data)",sizeof(_resp)); 
+    }
+// ACK response
+    else
+    {
+        clearPacket();
+        _pc.printf("\n");        
+        _pc.printf("\nSend Data is successful. VALID\n");
+        strncpy(_resp,"Send Data is successful",sizeof(_resp));
+    }
+}
+
+//0x03 Abort Transmission
+void Stingr::abort_Transmission()
+{
+    led1=!led1;
+    _pc.printf("\r0x03\t\t\tAbort Transmission\n");
+    _pc.printf("Command(HEX):\t\tAA 5 3 42 F6\n\r");
+    _pc.printf("Response(Stingr)HEX:\t");
+    waitCTS();
+    Thread::wait(10);               
+    _stingrUART.putc(0XAA);      
+    _stingrUART.putc(0X05);
+    _stingrUART.putc(0X03);
+    _stingrUART.putc(0X42);
+    _stingrUART.putc(0XF6);
+    
+    postCommand();
+    printPacket();
+
+// ACK response
+    if (_packet[0] == 170 && // 0xAA
+        _packet[1] ==   5 && // 0x05
+        _packet[2] ==   3 && // 0x03
+        _packet[3] ==  66 && // 0x42
+        _packet[4] == 246)   // 0xF6
+    {
+        clearPacket();
+        _pc.printf("\nResponse Processing:\tTransmission successfully aborted.\n");
+        strncpy(_resp,"Transmission successfully aborted.",sizeof(_resp));
+    }
+// NAK response
+    else
+    {
+        clearPacket();
+        _pc.printf("\nResponse Processing:\tNAK response. INVALID");   
+        strncpy(_resp,"NAK response (Abort Transmission)",sizeof(_resp)); 
+    }
+}
+
+uint16_t Stingr::ModRTU_CRC(char * buf, int len)
+{
+    unsigned char i;
+    unsigned short data;
+    uint16_t crc = 0xFFFF;
+ 
+    do{
+        data = (unsigned int)0x00FF & *buf++;
+        crc = crc ^ data;
+
+        for(i = 8; i > 0; i--)
+        {
+            if(crc & 0x0001)
+                crc = (crc >> 1) ^ 0x8408;
+            else
+                crc >>=1;  
+        }
+    
+    }while (--len);
+  
+    crc = ~crc;
+  
+    // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
+    return (crc);  
+}
+
+void Stingr::respuesta()
+{
+    while(1)
+    {
+        if(_stingrUART.readable()) 
+        {   // Se esperan datos provenientes del TX del módulo STX3
+            incomingByteR = _stingrUART.getc();
+            //stingr.setPacketByte(incomingByteR);
+            setPacketByte(incomingByteR);
+            _pc.printf("%X",incomingByteR);  // Format specifier
+            _pc.printf(" ");
+        }
+    }
+}
+
+// Thread 2: Reading commands from PC
+void Stingr::PC_communication()
+{
+    int a = 0;
+    
+    while(1)
+    {
+        char str1[200];
+        if (_pc.readable())
+        { 
+            incomingByteX = _pc.getc();
+            strx[a] = incomingByteX;
+            a++;
+            
+            if(incomingByteX == '\n')
+            {
+                _pc.printf("\n\nPC input: \t\t");  
+                strncpy(str1,strx,sizeof(strx));
+                _pc.printf("%s",str1);
+                _pc.printf("\n");
+                //stingr.command(str1);
+                command(str1);
+                memset(strx, 0, 200);
+                a = 0;
+            }
+        }           
+    }
+}
\ No newline at end of file