Modifications in 4DGL library. Added CDU_hw_sw.h for version info. Added pins.h for hardware pin remapping
Dependencies: 4DGL-UC MODSERIAL mbed mbos
Fork of CDU_Mbed_30 by
Diff: USB_receive_6.cpp
- Revision:
- 14:5767d651d624
diff -r d60c746c097c -r 5767d651d624 USB_receive_6.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USB_receive_6.cpp Thu Aug 14 20:18:15 2014 +0000 @@ -0,0 +1,198 @@ +// L. van der Kolk, ELVEDEKA, Holland // +// File: USB_receive_6.cpp + +#include "mbed.h" +#include "MODSERIAL.h" + +extern MODSERIAL USB; +extern int FSdata_received_flag; + +//------- debug only --------------------- +//extern MODSERIAL SERIAL_DEBUG; +//---------------------------------------- + +void decode_string(int nummer_of_chars); +void read_datafields(int command_number); + +#define max_string_length 100 // : 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 + 3]; // : 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 13 // : 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 + "FAI", // : command nr.10 + "DPY", // : command nr.11 + "OFS", // : command nr.12 +}; + +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 ( FSdata_received_flag == false ) { // : process received chars only if no decoding busy now + while ( !USB.rxBufferEmpty() ) // : do as long as USB receive buffer is not empty + { rx_char = USB.getc(); // : get a char from Rx buffer + + // ----------- Debug only ! --------------------------------------------- + //SERIAL_DEBUG.putc(rx_char); // : unprotected immediate echo of char + // ---------------------------------------------------------------------- + + // 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; + FSdata_received_flag = 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 + + FSdata_received_flag = true; + + // ----------- Debug only ! ------------------------------------------- + // SERIAL_DEBUG.printf("string_received from USB: %s",string_received ); + // -------------------------------------------------------------------- + + 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 + FSdata_received_flag = false; + } + } + } + + } +} + +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 ); + + + // ----------- Debug only ------------------------------------------- + //SERIAL_DEBUG.printf("commas found : %d\n",c-1 ); // : show commas + // ------------------------------------------------------------------ + + 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); + + // ****************************************************************************************** + // -- Force checksum to allways OK : < -- debug only !! + equal = 0; + // ****************************************************************************************** + + if (equal != 0) { + // ----------- Debug only ------------------------------------------------------- + //SERIAL_DEBUG.printf("checksum is NOT OK ! \n" ); // : show message for debugging + // ------------------------------------------------------------------------------ + FSdata_received_flag = false; + } + else { // checksum is OK, go on: + // Check for 5 char "$PCDU" header: + equal = strncmp(string_received,message_header,strlen(message_header)); + if (equal != 0) { + + // ----------- Debug only --------------------------------------------------- + //SERIAL_DEBUG.printf("no $PCDU header in message !\n" ); // : show message + // -------------------------------------------------------------------------- + + FSdata_received_flag = false; + } + else { + // Read 3 char command after message_header: + strncpy(command_string,&string_received[strlen(message_header)],3); + + // ----------- 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 + // -------------------------------------------------------------------------------------------- + + // 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); + + // ----------- Debug only --------------------------------------------------------------- + //SERIAL_DEBUG.printf("command number is : %d\n",i ); // : show command nr for debugging + // -------------------------------------------------------------------------------------- + + if (equal == 0) { + // Command is known now, so now read all data fields: + read_datafields(i); + } + else FSdata_received_flag = false; + } + } + + } +