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); } } } }