Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: 4DGL MODSERIAL mbed mbos
Fork of CDU_Mbed_21 by
USB_receive_5.cpp
- Committer:
- LvdK
- Date:
- 2014-07-20
- Revision:
- 8:422544d24df3
- Child:
- 10:7e350a27f936
File content as of revision 8:422544d24df3:
// L. van der Kolk, ELVEDEKA, Holland //
// File: USB_receive_5.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 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 ( 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;
}
}
}
