voor willem test

Dependencies:   4DGL MODSERIAL mbed mbos

USB_receive_3.cpp

Committer:
LvdK
Date:
2014-07-17
Revision:
7:6576a287e563

File content as of revision 7:6576a287e563:

// L. van der Kolk, ELVEDEKA, Holland //
// File:  USB_receive_3.cpp     

#include "mbed.h"
#include "MODSERIAL.h" 
#include "debug_lvdk.h"

extern MODSERIAL USB;
extern int CDU_FS_interface;  

#ifdef DEBUG_LVDK
//------- debug only -----------
extern MODSERIAL SERIAL_DEBUG;
//------------------------------
#endif
   
void decode_string(int nummer_of_chars);
void read_datafields(int command_number);

#define max_string_length 80 // : max length of received string starting with $ and ending with CR/LF
#define min_string_length 10 // : min length of received string starting with $ and ending with CR/LF
char string_received[max_string_length + 2]; // : holds received string starting with $ and ending with CR/LF

#define message_header "$PCDU"  // : common message header in all messages
#define max_commas 10  // : max. nr of possible field separating commas in a valid message string to CDU
int comma[max_commas];      // : array with positions of all found commas in string_receved[]

#define max_nr_of_commands 10   // : max nr of possible FS-to-CDU commands
// Define array of pointers to possible FS-to-CDU commands with 3 characters:
const char *command[max_nr_of_commands] = {
   "123",    // : no valid CDU command nr. 0 , used for debugging only
   "MSG",    // : command nr. 1
   "EXC",    // : command nr. 2
   "BLT",    // : command nr. 3
   "SBY",    // : command nr. 4
   "CLS",    // : command nr. 5
   "SBC",    // : command nr. 6
   "WTX",    // : command nr. 7
   "ETX",    // : command nr. 8
   "KTX",    // : command nr. 9
};

void collect_FSdata()  {
     // Function reads characters from FS written in receive buffer.
     // Wiil be called after each RX receive interrupt, so characters will allways be stored.
     // When analyze_busy is false, function will start reading characters from defined buffer and 
     // collects strings starting with $ and ending with CR/LF. 
     // Strings shorter than min_string_length or longer than max_string_length will be ignored,
     // others will be analyzed further.
     // After analyzing, flag analyze_busy will be set to false again.
    static int $_detected = false;      // : no valid begin of string detected (init only on first call)
    static int string_pntr = 0;         // : pointer at begin of string (init only on first call)
    static int nr_of_received_char = 0; // : counter of received characters (init only on first call)
           char rx_char;                // : character which is analyzed 
             
 if ( CDU_FS_interface == 0 ) {  // : USB Port will be used 
   while ( !USB.rxBufferEmpty() )
   {    rx_char = USB.getc(); // : get a char from Rx buffer
        #ifdef DEBUG_LVDK
        // ----------- Debug only ! -------------------------------------------
        //SERIAL_DEBUG.putc(rx_char);    // : unprotected immediate echo of char 
        // --------------------------------------------------------------------
        #endif
        // Check for string starting with $ char:
        if ( rx_char == '$' && $_detected == false ){
            $_detected = true;  // : begin of string is detected 
            string_pntr = 0;    // : set pointer to begin of string_received[] buffer
        }    
        string_received[string_pntr] = rx_char;
        string_pntr++;     
        if (string_pntr >= max_string_length) {
            // command string looks too long, so start all over again:
            string_pntr = 0;  // : set pointer back to begin of string_received[] again
            nr_of_received_char = 0;   // : reset number of received chars
            $_detected = false;
        }    
        if ( rx_char == '\r' && $_detected == true ) {             
            if ( string_pntr > min_string_length ) { // : check minimum string length 
                // Received string can be interesting now because
                // it starts with '$' AND it ends on New-Line  AND
                // it has a minimum length AND it is not too long:
                string_received[string_pntr] = '\0'; // : mark end of string
                #ifdef DEBUG_LVDK
                // ----------- Debug only ! -------------------------------------------------------------------
                // SERIAL_DEBUG.printf("string_received : %s",string_received );  // show string for debugging 
                // --------------------------------------------------------------------------------------------
                #endif
                nr_of_received_char = string_pntr;
                //Call decoder to analyse this string:
                decode_string(nr_of_received_char);
                // Get ready for receiving new commands:
                $_detected = false;
                string_pntr = 0;  // : set pointer back to begin of string_received[] again
                nr_of_received_char = 0;   // : reset number of received chars
            }
            else {
                $_detected = false;  
                string_pntr = 0; // : set pointer back to begin of string_received[] again
                nr_of_received_char = 0;   // : reset number of received chars
            }
        }    
   } 
    
 } 
}
    
void decode_string(int nummer_of_chars)
{   // -- This function decodes a received $.....CR/LF string written in string_received[] --
    // First it checks for a valid checksum and reads the positions of commas in the string.
    // If checksum is OK, it will continue to look for valid 3 char FS-to-CDU commands.
    // When a valid command is found, data fields will be analyzed further using the found positions
    // of commas in the string.
    int  i,c, equal;
    char byte_read, exor_byte;
    char command_string[6], received_checksum[4], calc_checksum[4];
   // Get checksum and position of commas in string_received[] :
    exor_byte = 0;
    i = 1;  // : i points to first char after $
    c = 1;  // : position of first comma
      do {
          byte_read = string_received[i];
          if (byte_read == ',' && c < max_commas) {
              comma[c] = i;
              c++;
          }
          if (byte_read == '*') break;
          exor_byte = exor_byte ^ byte_read;
          i++;
      } while ( i < nummer_of_chars );
      
    #ifdef DEBUG_LVDK
    // ----------- Debug only ---------------------------------------------------------  
    //SERIAL_DEBUG.printf("commas found : %d\n",c-1 );  // : show commas for debugging 
    // --------------------------------------------------------------------------------
    #endif
    i++;   // : i points to first checksum char after char *
    strncpy(received_checksum,&string_received[i],2);   // : copy 2 char checksum after * 
    // Get calculated checksum by transforming exor_byte in 2 hex chars (with upper case A-F) :
    sprintf(calc_checksum,"%02X",exor_byte); // : + extra NULL char added by sprintf 
    equal = strncmp(received_checksum,calc_checksum,2);
    
    // bypass checksum check: ------- !!!!!!!!!
    equal = 0;
    //-------------------------------
    
    if (equal != 0) {
       #ifdef DEBUG_LVDK
       // ----------- Debug only ------------------------------------------------------- 
       SERIAL_DEBUG.printf("checksum is NOT OK ! \n" );  // : show message for debugging
       // ------------------------------------------------------------------------------
       #endif
    }
    else { // checksum is OK, go on:
        // Check for 5 char "$PCDU" header:
        equal = strncmp(string_received,message_header,strlen(message_header));
          if (equal != 0) {
            #ifdef DEBUG_LVDK
            // ----------- Debug only --------------------------------------------------------------
            SERIAL_DEBUG.printf("no $PCDU header in message !\n" );  // : show message for debugging 
            // -------------------------------------------------------------------------------------
            #endif
          }
          else {
               // Read 3 char command after message_header:
               strncpy(command_string,&string_received[strlen(message_header)],3);
               #ifdef DEBUG_LVDK
               // ----------- Debug only ---------------------------------------------------------------------
               //SERIAL_DEBUG.printf("\ncommand found : %3s\n",command_string ); // : show command for debugging 
               //SERIAL_DEBUG.printf("commas found : %d\n",c-1 );               // : show commas for debugging
               // --------------------------------------------------------------------------------------------
               #endif
               // Compare found string with known 3 char command list:
               i = 0; 
               do {
                  equal = strncmp(&command_string[0],command[i],3);
                  if( equal == 0) break;
                  i++;
               } while ( i < max_nr_of_commands);
               
                #ifdef DEBUG_LVDK
                // ----------- Debug only ---------------------------------------------------------------
                //SERIAL_DEBUG.printf("command number is : %d\n",i );  // : show command nr for debugging 
                // --------------------------------------------------------------------------------------
                #endif
                
               if (equal == 0) {
                 // Command is known now, so now read all data fields:
                 read_datafields(i);
              }
         } 
    } 
    
 }