voor willem test

Dependencies:   4DGL MODSERIAL mbed mbos

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers USB_receive_3.cpp Source File

USB_receive_3.cpp

00001 // L. van der Kolk, ELVEDEKA, Holland //
00002 // File:  USB_receive_3.cpp     
00003 
00004 #include "mbed.h"
00005 #include "MODSERIAL.h" 
00006 #include "debug_lvdk.h"
00007 
00008 extern MODSERIAL USB;
00009 extern int CDU_FS_interface;  
00010 
00011 #ifdef DEBUG_LVDK
00012 //------- debug only -----------
00013 extern MODSERIAL SERIAL_DEBUG;
00014 //------------------------------
00015 #endif
00016    
00017 void decode_string(int nummer_of_chars);
00018 void read_datafields(int command_number);
00019 
00020 #define max_string_length 80 // : max length of received string starting with $ and ending with CR/LF
00021 #define min_string_length 10 // : min length of received string starting with $ and ending with CR/LF
00022 char string_received[max_string_length + 2]; // : holds received string starting with $ and ending with CR/LF
00023 
00024 #define message_header "$PCDU"  // : common message header in all messages
00025 #define max_commas 10  // : max. nr of possible field separating commas in a valid message string to CDU
00026 int comma[max_commas];      // : array with positions of all found commas in string_receved[]
00027 
00028 #define max_nr_of_commands 10   // : max nr of possible FS-to-CDU commands
00029 // Define array of pointers to possible FS-to-CDU commands with 3 characters:
00030 const char *command[max_nr_of_commands] = {
00031    "123",    // : no valid CDU command nr. 0 , used for debugging only
00032    "MSG",    // : command nr. 1
00033    "EXC",    // : command nr. 2
00034    "BLT",    // : command nr. 3
00035    "SBY",    // : command nr. 4
00036    "CLS",    // : command nr. 5
00037    "SBC",    // : command nr. 6
00038    "WTX",    // : command nr. 7
00039    "ETX",    // : command nr. 8
00040    "KTX",    // : command nr. 9
00041 };
00042 
00043 void collect_FSdata()  {
00044      // Function reads characters from FS written in receive buffer.
00045      // Wiil be called after each RX receive interrupt, so characters will allways be stored.
00046      // When analyze_busy is false, function will start reading characters from defined buffer and 
00047      // collects strings starting with $ and ending with CR/LF. 
00048      // Strings shorter than min_string_length or longer than max_string_length will be ignored,
00049      // others will be analyzed further.
00050      // After analyzing, flag analyze_busy will be set to false again.
00051     static int $_detected = false;      // : no valid begin of string detected (init only on first call)
00052     static int string_pntr = 0;         // : pointer at begin of string (init only on first call)
00053     static int nr_of_received_char = 0; // : counter of received characters (init only on first call)
00054            char rx_char;                // : character which is analyzed 
00055              
00056  if ( CDU_FS_interface == 0 ) {  // : USB Port will be used 
00057    while ( !USB.rxBufferEmpty() )
00058    {    rx_char = USB.getc(); // : get a char from Rx buffer
00059         #ifdef DEBUG_LVDK
00060         // ----------- Debug only ! -------------------------------------------
00061         //SERIAL_DEBUG.putc(rx_char);    // : unprotected immediate echo of char 
00062         // --------------------------------------------------------------------
00063         #endif
00064         // Check for string starting with $ char:
00065         if ( rx_char == '$' && $_detected == false ){
00066             $_detected = true;  // : begin of string is detected 
00067             string_pntr = 0;    // : set pointer to begin of string_received[] buffer
00068         }    
00069         string_received[string_pntr] = rx_char;
00070         string_pntr++;     
00071         if (string_pntr >= max_string_length) {
00072             // command string looks too long, so start all over again:
00073             string_pntr = 0;  // : set pointer back to begin of string_received[] again
00074             nr_of_received_char = 0;   // : reset number of received chars
00075             $_detected = false;
00076         }    
00077         if ( rx_char == '\r' && $_detected == true ) {             
00078             if ( string_pntr > min_string_length ) { // : check minimum string length 
00079                 // Received string can be interesting now because
00080                 // it starts with '$' AND it ends on New-Line  AND
00081                 // it has a minimum length AND it is not too long:
00082                 string_received[string_pntr] = '\0'; // : mark end of string
00083                 #ifdef DEBUG_LVDK
00084                 // ----------- Debug only ! -------------------------------------------------------------------
00085                 // SERIAL_DEBUG.printf("string_received : %s",string_received );  // show string for debugging 
00086                 // --------------------------------------------------------------------------------------------
00087                 #endif
00088                 nr_of_received_char = string_pntr;
00089                 //Call decoder to analyse this string:
00090                 decode_string(nr_of_received_char);
00091                 // Get ready for receiving new commands:
00092                 $_detected = false;
00093                 string_pntr = 0;  // : set pointer back to begin of string_received[] again
00094                 nr_of_received_char = 0;   // : reset number of received chars
00095             }
00096             else {
00097                 $_detected = false;  
00098                 string_pntr = 0; // : set pointer back to begin of string_received[] again
00099                 nr_of_received_char = 0;   // : reset number of received chars
00100             }
00101         }    
00102    } 
00103     
00104  } 
00105 }
00106     
00107 void decode_string(int nummer_of_chars)
00108 {   // -- This function decodes a received $.....CR/LF string written in string_received[] --
00109     // First it checks for a valid checksum and reads the positions of commas in the string.
00110     // If checksum is OK, it will continue to look for valid 3 char FS-to-CDU commands.
00111     // When a valid command is found, data fields will be analyzed further using the found positions
00112     // of commas in the string.
00113     int  i,c, equal;
00114     char byte_read, exor_byte;
00115     char command_string[6], received_checksum[4], calc_checksum[4];
00116    // Get checksum and position of commas in string_received[] :
00117     exor_byte = 0;
00118     i = 1;  // : i points to first char after $
00119     c = 1;  // : position of first comma
00120       do {
00121           byte_read = string_received[i];
00122           if (byte_read == ',' && c < max_commas) {
00123               comma[c] = i;
00124               c++;
00125           }
00126           if (byte_read == '*') break;
00127           exor_byte = exor_byte ^ byte_read;
00128           i++;
00129       } while ( i < nummer_of_chars );
00130       
00131     #ifdef DEBUG_LVDK
00132     // ----------- Debug only ---------------------------------------------------------  
00133     //SERIAL_DEBUG.printf("commas found : %d\n",c-1 );  // : show commas for debugging 
00134     // --------------------------------------------------------------------------------
00135     #endif
00136     i++;   // : i points to first checksum char after char *
00137     strncpy(received_checksum,&string_received[i],2);   // : copy 2 char checksum after * 
00138     // Get calculated checksum by transforming exor_byte in 2 hex chars (with upper case A-F) :
00139     sprintf(calc_checksum,"%02X",exor_byte); // : + extra NULL char added by sprintf 
00140     equal = strncmp(received_checksum,calc_checksum,2);
00141     
00142     // bypass checksum check: ------- !!!!!!!!!
00143     equal = 0;
00144     //-------------------------------
00145     
00146     if (equal != 0) {
00147        #ifdef DEBUG_LVDK
00148        // ----------- Debug only ------------------------------------------------------- 
00149        SERIAL_DEBUG.printf("checksum is NOT OK ! \n" );  // : show message for debugging
00150        // ------------------------------------------------------------------------------
00151        #endif
00152     }
00153     else { // checksum is OK, go on:
00154         // Check for 5 char "$PCDU" header:
00155         equal = strncmp(string_received,message_header,strlen(message_header));
00156           if (equal != 0) {
00157             #ifdef DEBUG_LVDK
00158             // ----------- Debug only --------------------------------------------------------------
00159             SERIAL_DEBUG.printf("no $PCDU header in message !\n" );  // : show message for debugging 
00160             // -------------------------------------------------------------------------------------
00161             #endif
00162           }
00163           else {
00164                // Read 3 char command after message_header:
00165                strncpy(command_string,&string_received[strlen(message_header)],3);
00166                #ifdef DEBUG_LVDK
00167                // ----------- Debug only ---------------------------------------------------------------------
00168                //SERIAL_DEBUG.printf("\ncommand found : %3s\n",command_string ); // : show command for debugging 
00169                //SERIAL_DEBUG.printf("commas found : %d\n",c-1 );               // : show commas for debugging
00170                // --------------------------------------------------------------------------------------------
00171                #endif
00172                // Compare found string with known 3 char command list:
00173                i = 0; 
00174                do {
00175                   equal = strncmp(&command_string[0],command[i],3);
00176                   if( equal == 0) break;
00177                   i++;
00178                } while ( i < max_nr_of_commands);
00179                
00180                 #ifdef DEBUG_LVDK
00181                 // ----------- Debug only ---------------------------------------------------------------
00182                 //SERIAL_DEBUG.printf("command number is : %d\n",i );  // : show command nr for debugging 
00183                 // --------------------------------------------------------------------------------------
00184                 #endif
00185                 
00186                if (equal == 0) {
00187                  // Command is known now, so now read all data fields:
00188                  read_datafields(i);
00189               }
00190          } 
00191     } 
00192     
00193  }
00194  
00195