Code:
#include <Arduino.h>
// C++ includes
#include <cstdint>
#include <cstring>
#include <EEPROM.h>
#include <SdFat.h> //We do not use the built-in SD.h file because it calls Serial.print
#define Debug 0
#define SBUS_Baudrate 57600
#define SBUS_Serial Serial1
#define HWSERIAL2 Serial2
#define UART0_C2_RX_ENABLE UART_C2_RE | UART_C2_RIE | UART_C2_ILIE
constexpr int max_SBUS_Datasize = 513;
// Keeps track of when the last frame was received.
elapsedMillis lastFrameTime;
// Interval between printing received values.
constexpr unsigned long kPrintInterval = 5;
unsigned long p;
// The last value sent to kChannel.
uint8_t lastValue;
boolean first;
uint8_t buf1[max_SBUS_Datasize];
uint8_t buf2[max_SBUS_Datasize];
uint8_t *activeBuf;
uint8_t *inactiveBuf;
int activeBufIndex;
uint16_t packetCount;
volatile uint32_t packetTimestamp;
volatile int16_t bufcounter;
uint16_t packetSize;
void uart0_rx_status_isr();
void uart0_rx_error_isr();
void SBUS_begin(void);
int SBUS_readFrameData(uint8_t *buf,uint16_t len);
#define writebuffer_size 1000
uint8_t buffer1[writebuffer_size];
uint8_t buffer2[writebuffer_size];
uint8_t *activeWritebuffer;
uint8_t *inactiveWritebuffer;
uint8_t activeWritebufferIndex;
volatile uint16_t buffer1counter,buffer2counter,DataReadCounter, DataToWriteCounter;
bool set_datawrite_flag,compareResult;;
const uint8_t ErrorFrame[5] ={0x1,0xF,0x21,0x87,0x2A};
const bool ErrorFrameVerification[5] ={1,1,1,0,1};
const uint8_t Header[2]={'S',':'};
uint8_t *ptrDataSave;
/************************************************/
//SdFatSdio SD;
//SdFatSdioEX SD;
SdFat SD;
File myFile;
// SD chip select pin
const uint8_t SD_CS_PIN = 4;
uint32_t lastSyncTime;
const uint16_t MAX_TIME_BEFORE_SYNC_MSEC = 2000;
//#define MAX_TIME_BEFORE_SYNC_MSEC 5000
#define FILE_BASE_NAME "Data"
char fileName[13] = FILE_BASE_NAME "00.lho";
// The folder track depth is used by "cd .." and "pwd"
// This looks like an ugly hack but the sdfatlib is not supporting going back to previous folder yet.
// The current handling of "cd .." should be removed when it's available in the sdfat library.
#define FOLDER_TRACK_DEPTH 2
char folderTree[FOLDER_TRACK_DEPTH][12];
#define CFG_FILENAME "config2.txt" //This is the name of the file that contains the unit settings
#define MAX_CFG "115200,115200,103,214,0,1,1,0,4000,120,0,0\0" //= 115200 bps, escape char of ASCII(103), 214 times, new log mode, verbose on, echo on, ignore RX false.
#define CFG_LENGTH (strlen(MAX_CFG) + 1) //Length of text found in config file. strlen ignores \0 so we have to add it back
#define SEQ_FILENAME "SEQLOG00.TXT" //This is the name for the file when you're in sequential mode
//Internal EEPROM locations for the user settings
#define LOCATION_SYSTEM_SETTING 0x02
#define LOCATION_ESCAPE_CHAR 0x05
#define LOCATION_MAX_ESCAPE_CHAR 0x06
#define LOCATION_VERBOSE 0x07
#define LOCATION_ECHO 0x08
#define LOCATION_IGNORE_RX 0x09
#define LOCATION_ERR_FLG 0x0A
#define LOCATION_RESET_EE 0x0B
#define LOCATION_ERR_FILE_RENAME 0x0C
#define LOCATION_FILE_NUMBER_LSB 0x10
#define LOCATION_FILE_NUMBER_MID 0x11
#define LOCATION_FILE_NUMBER_MSB 0x12
#define LOCATION_RX_BAUD_SETTING_HIGH 0x20
#define LOCATION_RX_BAUD_SETTING_MID 0x21
#define LOCATION_RX_BAUD_SETTING_LOW 0x22
#define LOCATION_LIN_BAUD_SETTING_HIGH 0x30
#define LOCATION_LIN_BAUD_SETTING_MID 0x31
#define LOCATION_LIN_BAUD_SETTING_LOW 0x32
#define LOCATION_RX_NUMBER_LSB 0x40
#define LOCATION_RX_NUMBER_MSB 0x41
#define LOCATION_RX_FRAME_COUNT_LSB 0x42
#define LOCATION_RX_FRAME_COUNT_MSB 0x43
#define BAUD_MIN 1200
#define BAUD_MAX 1000000
#define MODE_NEWLOG 0
#define MODE_SEQLOG 1
#define MODE_COMMAND 2
/***************** Error codes ****************************************/
//Blinking LED error codes
#define ERROR_SD_INIT 3
#define ERROR_NEW_BAUD 5
#define ERROR_CARD_INIT 6
#define ERROR_VOLUME_INIT 7
#define ERROR_ROOT_INIT 8
#define ERROR_FILE_OPEN 9
//These are bit locations used when testing for simple embedded commands.
#define ECHO 0x01
#define EXTENDED_INFO 0x02
#define OFF 0x00
#define ON 0x01
#define LIN_SYNCH_BYTE_POS 0x00
#define LIN_ID_BYTE_POS 0x01
//Used for wild card delete and search
struct command_arg
{
char* arg; //Points to first character in command line argument
byte arg_length; //Length of command line argument
};
//The number of command line arguments
//Increase to support more arguments but be aware of the memory restrictions
//command <arg1> <arg2> <arg3> <arg4> <arg5>
#define MAX_COUNT_COMMAND_LINE_ARGS 5
static struct command_arg cmd_arg[MAX_COUNT_COMMAND_LINE_ARGS];
byte feedback_mode = (ECHO | EXTENDED_INFO);
const uint8_t SdChipSelect = 4;
#define error(msg) SD.errorHalt(F(msg))
/*******************/
uint8_t Monitormode = 1;
const int ledPin = 13;
char new_file_name[13];
//uint32_t lastSyncTime = 0;
//byte Monitormode = 0;
long setting_uart_speed_LIN,setting_uart_speed_RX; //This is the baud rate that the system runs at, default is 9600. Can be 1,200 to 1,000,000
byte setting_system_mode; //This is the mode the system runs in, default is MODE_NEWLOG
byte setting_escape_character; //This is the ASCII character we look for to break logging, default is ctrl+z
byte setting_max_escape_character; //Number of escape chars before break logging, default is 3
byte setting_verbose; //This controls the whether we get extended or simple responses.
byte setting_echo; //This turns on/off echoing at the command prompt
byte setting_ignore_RX; //This flag, when set to 1 will make OpenLog ignore the state of the RX pin when powering up
int setting_RX_NUMBER,setting_RX_FRAME_COUNT;
byte setting_RESET_EE;
byte setting_ERR_FILE_RENAME;
byte setting_ERR_FLG;
int RX_LINE_ANZAHL = 200; // Size limit trigger of RX buffer - if bigger then readout Rxbuffer;
int RX_FRAME_COUNT = 140; // gibt an wieviel zeichen eine Zeile mindestens hatn
const int ANZAHL = 2048; // größe der Pakete die vom Rx Buffer in den lokalen Puffer kopiert werden sollen;
const int LOCAL_RX_TEST_BUFF_SIZE = 4096; //This is the 1. Test Buffer.
const int LOCAL_BUFF_SIZE = 8192; //This is the 2nd buffer. It pulls from the larger NewSerial buffer as quickly as possible.
byte localBuffer[LOCAL_BUFF_SIZE];
byte localRXBuffer[LOCAL_BUFF_SIZE];
int localRXBuffer_index, localBuffer_index = 0;
byte RX_Trigger;
byte checkedSpot;
byte escape_chars_received = 0;
const uint16_t MAX_IDLE_TIME_MSEC = 500; //The number of milliseconds before unit goes to sleep
//const uint16_t MAX_TIME_BEFORE_SYNC_MSEC = 2000;
//LIN_global
int n_LIN_C,LIN_BYTE_COUNTER;
char ch_LIN;
#define LIN_DATA_SIZE 640
char LIN_DATA[LIN_DATA_SIZE]; // normally Array should have only a size of 10 - but because i want so see possible data packet corruption
unsigned long ul_LIN_PACKET_TIME =0,ul_RX_PACKET_TIME = 0;
long l_LIN_TIME = 0,l_RX_TIME = 0;;
char ch_LIN_TIME[4], ch_RX_TIME[4];
//SBUS_global
unsigned int n_SBUS_C,n_SBUS_C_last,SBUS_BYTE_COUNTER;
char ch_SBUS;
#define SBUS_DATA_SIZE 640
char SBUS_DATA[SBUS_DATA_SIZE]; // normally Array should have only a size of 10 - but because i want so see possible data packet corruption
uint8_t invalidFrame = 0;
unsigned long ul_SBUS_PACKET_TIME =0;
long l_SBUS_TIME = 0;
char ch_SBUS_TIME[4];
char SBUS_initialised = 0;
char SBUS_Broadcast_Data = 0;
char SBUS_synchronised = 0;
extern uint16_t num_framing_errors_last;
extern uint16_t num_framing_errors;
extern uint16_t num_frame_posistion[3000+ (3000/3)];
extern uint16_t num_frame_posistion_write_counter,num_frame_posistion_read_counter,num_frame_posistion_counter_max,num_frame_packets_to_read;
extern uint32_t num_frame_posistion_time[3000 + (3000/3)];
extern uint32_t last_reception_time_micros;
extern uint32_t sum_elapsed_milliseconds;
uint16_t loc_num_frame_packets_to_read;
extern uint32_t time_since_last_reception;
extern uint8_t FrameLED_value;
uint8_t End_of_Data_LED_state = 0;
extern uint32_t head_pos_external;
extern uint32_t tail_pos_external ;
unsigned int pos_Endmarker,pos_SBUS_Endmarker = 0;
byte msb, lsb, mib;
uint32_t new_file_number;
//The number of command line arguments
//Increase to support more arguments but be aware of the memory restrictions
//command <arg1> <arg2> <arg3> <arg4> <arg5>
#define MAX_COUNT_COMMAND_LINE_ARGS 5
//The following are system functions needed for basic operation
//=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
//Blinks the status LEDs to indicate a type of error
void blink_error(byte ERROR_TYPE) {
while(1) {
for(int x = 0 ; x < ERROR_TYPE ; x++) {
digitalWrite(ledPin, HIGH);
delay(200);
digitalWrite(ledPin, LOW);
delay(200);
}
delay(2000);
}
}
//Handle errors by printing the error type and blinking LEDs in certain way
//The function will never exit - it loops forever inside blink_error
void systemError(byte error_type)
{
if (Monitormode) Serial.print(F("Error "));
switch(error_type)
{
case ERROR_CARD_INIT:
if (Monitormode) Serial.print(F("card.init"));
blink_error(ERROR_SD_INIT);
break;
case ERROR_VOLUME_INIT:
if (Monitormode) Serial.print(F("volume.init"));
blink_error(ERROR_SD_INIT);
break;
case ERROR_ROOT_INIT:
if (Monitormode) Serial.print(F("root.init"));
blink_error(ERROR_SD_INIT);
break;
case ERROR_FILE_OPEN:
if (Monitormode) Serial.print(F("file.open"));
blink_error(ERROR_SD_INIT);
break;
}
}
void setup_SD_card()
{
}
unsigned long read_last_SD_file_number_from_EEPROM()
{
byte msb, lsb, mib;
uint32_t new_file_number;
//Combine two 8-bit EEPROM spots into one 16-bit number
lsb = EEPROM.read(LOCATION_FILE_NUMBER_LSB);
mib = EEPROM.read(LOCATION_FILE_NUMBER_MID);
msb = EEPROM.read(LOCATION_FILE_NUMBER_MSB);
new_file_number = msb;
new_file_number = new_file_number << 8;
new_file_number |= mib;
new_file_number = new_file_number << 8;
new_file_number |= lsb;
return (new_file_number);
//If both EEPROM spots are 255 (0xFF), that means they are un-initialized (first time OpenLog has been turned on)
//Let's init them both to 0
if((lsb == 255) && (mib == 255) && (msb == 255))
{
new_file_number = 0; //By default, unit will start at file number zero
EEPROM.write(LOCATION_FILE_NUMBER_LSB, 0x00);
EEPROM.write(LOCATION_FILE_NUMBER_MID, 0x00);
EEPROM.write(LOCATION_FILE_NUMBER_MSB, 0x00);
}
if (Monitormode)
{
Serial.print("Newlog_routine FileNumber: ");
Serial.println(new_file_number,DEC);
}
//The above code looks like it will forever loop if we ever create 65535 logs
//Let's quit if we ever get to 65534
//9876543 logs is quite possible if you have a system with lots of power on/off cycles
if(new_file_number == 9876543)
{
//Gracefully drop out to command prompt with some error
if (Monitormode) Serial.print(F("!Too many logs:1!"));
return(0); //Bail!
}
}
void initialise_buffer()
{
activeBufIndex = 0;
activeBuf = buf1;
activeWritebuffer = buffer2;
inactiveWritebuffer = buffer1;
ptrDataSave = buffer1;
DataToWriteCounter = 0;
DataReadCounter = 0;
}
void setup()
{
// const uint8_t BASE_NAME_SIZE = sizeof(FILE_BASE_NAME) - 1;
// char fileName[13] = FILE_BASE_NAME "00.loh";
// put your setup code here, to run once:
pinMode(3, OUTPUT);
pinMode(19, OUTPUT);
pinMode(20, OUTPUT);
delay(2000); // Instead of while (!Serial), doesn't seem to work on Teensy
pinMode(21, OUTPUT);
pinMode(22, OUTPUT);
pinMode(23, OUTPUT);
initialise_buffer();
set_datawrite_flag = 0;
Serial.begin(115200);
delay(2000); // Instead of while (!Serial), doesn't seem to work on Teensy
Serial.println("Starting.");
read_system_settings(); //Load all system settings from EEPROM
// HWSERIAL1.begin(setting_uart_speed_LIN);
if (Monitormode) {
Serial.print("LIN_baud : ");
Serial.println(setting_uart_speed_LIN, DEC);
}
// //Setup RXin UART
//
// HWSERIAL2.begin(setting_uart_speed_RX);
// if (Monitormode)
// {
// Serial.print("UART_Baud : ");
// Serial.println(setting_uart_speed_RX, DEC);
// }
//Setup SD & FAT
if (!SD.begin(SdChipSelect, SD_SCK_MHZ(50))) systemError(ERROR_CARD_INIT);
// if (!volume.init(&card)) systemError(ERROR_VOLUME_INIT);
// currentDirectory.close(); //We close the cD before opening root. This comes from QuickStart example. Saves 4 bytes.
// if (!currentDirectory.openRoot(&volume)) systemError(ERROR_ROOT_INIT);
if (Monitormode) Serial.print(F("2"));
// printRam(); //Print the available RAM
//Search for a config file and load any settings found. This will over-ride previous EEPROM settings if found.
read_config_file();
SdFile newFile; //This will contain the file for SD writing
//Combine two 8-bit EEPROM spots into one 16-bit number
lsb = EEPROM.read(LOCATION_FILE_NUMBER_LSB);
mib = EEPROM.read(LOCATION_FILE_NUMBER_MID);
msb = EEPROM.read(LOCATION_FILE_NUMBER_MSB);
new_file_number = msb;
new_file_number = new_file_number << 8;
new_file_number |= mib;
new_file_number = new_file_number << 8;
new_file_number |= lsb;
//If both EEPROM spots are 255 (0xFF), that means they are un-initialized (first time OpenLog has been turned on)
//Let's init them both to 0
if((lsb == 255) && (mib == 255) && (msb == 255))
{
new_file_number = 0; //By default, unit will start at file number zero
EEPROM.write(LOCATION_FILE_NUMBER_LSB, 0x00);
EEPROM.write(LOCATION_FILE_NUMBER_MID, 0x00);
EEPROM.write(LOCATION_FILE_NUMBER_MSB, 0x00);
}
if (Monitormode) {
Serial.print("Newlog_routine FileNumber: ");
Serial.println(new_file_number,DEC);
}
//The above code looks like it will forever loop if we ever create 65535 logs
//Let's quit if we ever get to 65534
//65534 logs is quite possible if you have a system with lots of power on/off cycles
if(new_file_number == 9876543)
{
//Gracefully drop out to command prompt with some error
if (Monitormode) Serial.print(F("!Too many logs:1!"));
}
//If we made it this far, everything looks good - let's start testing to see if our file number is the next available
//Search for next available log spot
//char new_file_name[] = "LOG00000.TXT";
setting_ERR_FLG = EEPROM.read(LOCATION_ERR_FLG);
if (Monitormode)
{
Serial.println("test if (setting_ERR_FLG & setting_ERR_FILE_RENAME)");
Serial.print("setting_ERR_FLG: ");
Serial.println(setting_ERR_FLG,DEC);
Serial.print("setting_ERR_FILE_RENAME: ");
Serial.println(setting_ERR_FILE_RENAME,DEC);
}
if (setting_ERR_FLG & setting_ERR_FILE_RENAME) // logging LIN_ID error occur & Renaming option active?
{
sprintf_P(new_file_name, PSTR("L%07d.TXT"), (new_file_number - 1)); //Splice the old file number into this file name
if (Monitormode)
{
Serial.print("old_file_name with Error: ");
Serial.println(new_file_name);
}
uint8_t test = 5;
while(test)
{
if (!newFile.open(new_file_name, O_CREAT | O_WRITE ))
{
Serial.print("not possible to open file : ");
Serial.println(new_file_name);
error(" 2 file.open");
test--;
delay(200);
}
else
{
test = 0;
}
Serial.print("writeFile: ");
// Serial.printf("%s\n",filename[13]);
}
if (Monitormode)
{
Serial.print("S02: ");
//Serial.println(new_file_name);
}
// if (!newFile.open(¤tDirectory, new_file_name, O_CREAT | O_RDWR))break;
sprintf_P(new_file_name, PSTR("E%07d.TXT"), (new_file_number -1)); //Splice the old file number into this file name
if (Monitormode)
{
Serial.print("Error file_name : ");
Serial.println(new_file_name);
}
// if (!newFile.rename(¤tDirectory, new_file_name))
if (!newFile.rename(SD.vwd(), new_file_name))
{
if (Monitormode) Serial.println("error renaming last File with ERROR");
}
newFile.close();
setting_ERR_FLG = 0;
EEPROM.write(LOCATION_ERR_FLG,setting_ERR_FLG);
if (Monitormode)
{
Serial.print("S04 : ");
}
}
sprintf_P(new_file_name, PSTR("L%07d.TXT"), new_file_number); //Splice the new file number into this file name
if (Monitormode)
{
Serial.print("new_file_name 0: ");
Serial.println(new_file_name);
}
//While(1)
//{
// sprintf_P(new_file_name, PSTR("L%07d.TXT"), new_file_number); //Splice the new file number into this file name
//
// if (Monitormode)
// {
// Serial.print("new_file_name 0: ");
// Serial.println(new_file_name);
// }
//
//
// //Try to open file, if fail (file doesn't exist), then break
// if (newFile.open(new_file_name, O_CREAT | O_EXCL | O_WRITE))
// {
// if (Monitormode) Serial.print("//Try to open file, if fail (file doesn't exist), then break");
//
// }
// //Try to open file and see if it is empty. If so, use it.
// if (newFile.open(new_file_name, O_READ))
// {
// if (Monitormode) Serial.println("//Try to open file and see if it is empty. If so, use it.");
// if (newFile.fileSize() == 0)
// {
// newFile.close(); // Close this existing file we just opened.
//
// if (Monitormode)
// {
// Serial.print("new_file_name_file size == 0: ");
// Serial.println(new_file_name);
// }
// //return(new_file_name); // Use existing empty file.
//
// }
// newFile.close(); // Close this existing file we just opened.
// }
//
// //Try the next number
// new_file_number++;
// if(new_file_number > 9876542) //There is a max of 9876542 logs
// {
// if (Monitormode) Serial.print(F("!Too many logs:2!"));
//
// }
//
// newFile.close(); //Close this new file we just opened
// }
//if (!newFile.open(new_file_name, O_CREAT | O_WRITE | O_EXCL)) {
// if (Monitormode)
// {
//
// Serial.print("S05");
// Serial.print(" failed open File: ");
// // Serial.printf("%s\n",filename[13]);
// }
// error("file.open");
// }
//else
// {
// Serial.print("writeFile: ");
// // Serial.printf("%s\n",filename[13]);
// }
//
new_file_number++; //Increment so the next power up uses the next file #
//Record new_file number to EEPROM
lsb = (byte)(new_file_number & 0x0000FF);
mib = (byte)((new_file_number & 0x00FF00) >> 8);
msb = (byte)((new_file_number & 0xFF0000) >> 16);
EEPROM.write(LOCATION_FILE_NUMBER_LSB, lsb); // LSB
if (EEPROM.read(LOCATION_FILE_NUMBER_MSB) != mib)
EEPROM.write(LOCATION_FILE_NUMBER_MID, mib); // MIB
if (EEPROM.read(LOCATION_FILE_NUMBER_MSB) != msb)
EEPROM.write(LOCATION_FILE_NUMBER_MSB, msb); // MSB
#if DEBUG
if (Monitormode)
{
Serial.print(F("\nNewLog Mode : Created new file: "));
Serial.println(new_file_name);
}
#endif
//
// // read_system_settings(); //Load all system settings from EEPROM
//
// Serial.print("Initializing SD card...");
// // Initialize at the highest speed supported by the board that is
// // not over 50 MHz. Try a lower speed if SPI errors occur.
// if (!SD.begin(SdChipSelect, SD_SCK_MHZ(50))) {
// SD.initErrorHalt();
// }
// Find an unused file name.
// if (BASE_NAME_SIZE > 6) {
// error("FILE_BASE_NAME too long");
// }
// while (SD.exists(fileName)) {
// if (fileName[BASE_NAME_SIZE + 1] != '9') {
// fileName[BASE_NAME_SIZE + 1]++;
// } else if (fileName[BASE_NAME_SIZE] != '9') {
// fileName[BASE_NAME_SIZE + 1] = '0';
// fileName[BASE_NAME_SIZE]++;
// } else {
// error("Can't create file name");
// }
// }
//if (!myFile.open(fileName, O_CREAT | O_WRITE | O_EXCL)) {
// error("file.open");
// }
//else
// {
// Serial.print("writeFile: ");
// // Serial.printf("%s\n",filename[13]);
// }
// DataReadCounter
// init Buffer
}
void loop() {
int z;
uint8_t Synch_activate = 0;
uint8_t write_LED_state = 0;
uint8_t read_buffer;
if (!myFile.open(new_file_name, O_CREAT | O_WRITE | O_EXCL)) {
if (Monitormode)
{
Serial.print("S05");
Serial.print(" failed open File: ");
// Serial.printf("%s\n",filename[13]);
}
error("file.open");
}
else
{
Serial.print("writeFile: ");
// Serial.printf("%s\n",filename[13]);
}
//
// if (!SD.begin(SD_CS_PIN, SD_SCK_MHZ(50))) {
// Serial.println("initialization failed!");
// return;
// }
//
// if (!SD.begin(SD_CS_PIN))
// {
// Serial.println("initialization failed!");
// return;
// }
Serial.print("initialization done, filestat: ");
lastSyncTime = millis();
digitalWrite(3, 0);
delay(100);
digitalWrite(3, 1);
delay(10);
digitalWrite(3, 0);
delay(100);
digitalWrite(3, 1);
SBUS_begin();
while(1)
{
//delay(1);
// if the file opened okay, write to it:
if ((myFile) && (set_datawrite_flag == 1))
{
//Serial.printn("Writing Data...");
// Serial.println(" ");
// Serial.print("Writing Data.., from Adress");
// z= (unsigned int)activeWritebuffer;
// Serial.println(z,HEX);
// Serial.print(" Data to Write : ");
// Serial.println(DataToWriteCounter);
//
// for ( uint16_t i = 0; i<DataToWriteCounter;i++ )
// {
// Serial.print(" 0x");
// read_buffer = *(activeWritebuffer+i);
// Serial.print(read_buffer,HEX);
// //Serial.print((*(inactiveWritebuffer+i),HEX);
//
// }
// Serial.println("");
// myFile.println("testing 1, 2, 3.");
digitalWriteFast(20, 1);
myFile.write(activeWritebuffer, DataToWriteCounter-1) ;
// digitalWrite(ledPin, 1);
digitalWriteFast(20, 0);
set_datawrite_flag = 0;
if (!Synch_activate) Synch_activate= 1;
}
if(((millis() - lastSyncTime) > MAX_TIME_BEFORE_SYNC_MSEC)&&(Synch_activate ==1))//This will force a sync approximately every 5 seconds
{
digitalWrite(3, 0);
delayMicroseconds(10);
digitalWrite(3, 1);
delayMicroseconds(10);
digitalWrite(3, 0);
myFile.sync(); //Sync the card
Serial.println("Synch");
lastSyncTime = millis();
}
}
}
void SBUS_begin(void)
{
SBUS_Serial.begin(SBUS_Baudrate,SERIAL_8N1);
// Enable receive-only
UART0_C2 = UART0_C2_RX_ENABLE;
attachInterruptVector(IRQ_UART0_STATUS, uart0_rx_status_isr);
attachInterruptVector(IRQ_UART0_ERROR, uart0_rx_error_isr);
// We fill bytes from the buffer in the framing error ISR, so we
// can set to the same priority.
NVIC_SET_PRIORITY(IRQ_UART0_ERROR, NVIC_GET_PRIORITY(IRQ_UART0_STATUS));
// Enable UART0 interrupt on frame error
UART0_C3 |= UART_C3_FEIE;
NVIC_ENABLE_IRQ(IRQ_UART0_ERROR);
// break;
}
void SBUS_end(void)
{
//ed
// Disable UART0 interrupt on frame error
UART0_C3 &= ~UART_C3_FEIE;
NVIC_DISABLE_IRQ(IRQ_UART0_ERROR);
}
int SBUS_readFrameData(uint8_t *buf,uint16_t len)
{
int z;
bool Errorflag = 0;
uint8_t read_buffer;
int retval = -1;
if (len <= 0 )
{
return 0;
}
// Pointer für sicherung der Daten ausgeben
z= (unsigned int)ptrDataSave;
Serial.print("Adress ptrDataSave readFrame= 0x");
Serial.println(z,HEX);
Serial.println("");
Serial.print(" Datareadcounter S: ");
Serial.print(DataReadCounter);
// for ( uint16_t i = 0; i<len;i++ )
// {
// Serial.print(" B:0x");
// Serial.print(inactiveBuf[i],HEX);
// }
Serial.println("");
if (((sizeof(ErrorFrame))<len) && (len < (sizeof(ErrorFrame)+10)))
{
Errorflag = 1;
for ( uint16_t i = 0; i<(sizeof(ErrorFrame));i++ )
{
if ((ErrorFrameVerification[i])&& (ErrorFrame[i]!=inactiveBuf[i]))
{
Errorflag = 0;
break;
}
}
if (Errorflag)
{
if (!setting_ERR_FLG)
{
#if DEBUG
Serial.print("setting_ERR_FLG = 1");
Serial.println (" *** ");
Serial.println (" !!! Errorframe detect");
//delay(10000);
Serial.println (" *** ");
#endif
setting_ERR_FLG = 1;
EEPROM.write(LOCATION_ERR_FLG,1);
}
//# if Debug
// Serial.println (" ************************************************************* ");
// Serial.println (" !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Errorframe detect");
// delay(10000);
// Serial.println (" ************************************************************* ");
//
//# endif
}
}
__disable_irq();
if ( (DataReadCounter+256) < writebuffer_size )
{
writeDataToInactiveBuffer(ptrDataSave,len);
// buf = buf+len;
__enable_irq();
}
else
{
__disable_irq();
Serial.printf("Swap Buffer write %d Bytes \n",DataReadCounter);
if (activeWritebuffer == buffer1)
{
activeWritebuffer = buffer2;
inactiveWritebuffer = buffer1;
ptrDataSave = buffer1;
z= (unsigned int)ptrDataSave;
Serial.print("Adress ptrDataSave Buffer 1= 0x");
Serial.println(z,HEX);
DataToWriteCounter =DataReadCounter;
DataReadCounter = 0;
}
else
{
activeWritebuffer = buffer1;
inactiveWritebuffer = buffer2;
ptrDataSave = buffer2;
z= (unsigned int)ptrDataSave;
Serial.print("Adress ptrDataSave Buffer 2= 0x");
Serial.println(z,HEX);
DataToWriteCounter = DataReadCounter;
DataReadCounter = 0;
}
# if Debug
//DataReadCounter = 0;
Serial.printf("print date in write buffer, data to write: %u\n",DataToWriteCounter);
for ( uint16_t i = 0; i<DataToWriteCounter;i++ )
{
Serial.print(" 0x");
read_buffer = *(activeWritebuffer+i);
Serial.print(read_buffer,HEX);
//Serial.print((*(inactiveWritebuffer+i),HEX);
}
# endif
// for ( uint16_t i = 0; i<DataToWriteCounter;i++ )
// {
// Serial.print(" D[");
// Serial.print(i,DEC);
// Serial.print("]:0x");
// Serial.println(activeWritebuffer[i],HEX);
// }
Serial.println("");
// for test only
writeDataToInactiveBuffer(ptrDataSave,len);
// buf = buf+len;
__enable_irq();
set_datawrite_flag = 1;
Serial.println(" status writeflag");
Serial.println((myFile) && (set_datawrite_flag == 1));
}
return DataReadCounter;
}
void writeDataToInactiveBuffer(uint8_t *buf,uint16_t len)
{
int z;
uint8_t read_buffer;
# if Debug
z= (unsigned int)ptrDataSave;
Serial.print("Adress ptrDataSave= 0x");
Serial.println(z,HEX);
Serial.println("");
Serial.print(" Datareadcounter S: ");
Serial.print(DataReadCounter);
Serial.printf("Data Read Counter before:%d \n",DataReadCounter);
# endif
// Data structure:
// (Header 2Byte = M:) (Time in Millis as 4 byte = 0xXX 0xXX 0xXX 0xXX) (Tab Char = 0x09) (SBUS Data Frame)
//write Header ( M: )
memcpy(buf,Header,sizeof(Header));
DataReadCounter += sizeof(Header);
buf += sizeof(Header); // new Added
//convert ulong to byte write Time in millis
*buf ++= (uint8_t)(packetTimestamp & 0x000000ff);
*buf ++= (uint8_t)((packetTimestamp>>8) & 0x000000ff);
*buf ++= (uint8_t)((packetTimestamp>>16) & 0x000000ff);
*buf ++= (uint8_t)((packetTimestamp>>24) & 0x000000ff);
DataReadCounter += sizeof(packetTimestamp);
// write Tab
*buf ++= 0x09;
// write M-Dataframe
memcpy(buf,inactiveBuf,len);
DataReadCounter = DataReadCounter+len+1;
ptrDataSave = ptrDataSave+len+7;
# if Debug
Serial.printf("\nData Read Counter@SBUS_readFrameData:%d \n",DataReadCounter);
Serial.print(" Data im BufferB:");
for ( uint16_t i = 0; i<DataReadCounter;i++ )
{
Serial.print(" 0x");
read_buffer = *(inactiveWritebuffer+i);
Serial.print(read_buffer,HEX);
//Serial.print((*(inactiveWritebuffer+i),HEX);
}
Serial.println("");
# endif
}
void completePacket() {
// An empty packet isn't valid
int z;
if (first) {
first = false;
} else {
// Swap the buffers
if (activeBuf == buf1) {
activeBuf = buf2;
inactiveBuf = buf1;
}
else {
activeBuf = buf1;
inactiveBuf = buf2;
}
packetCount++;
packetSize = activeBufIndex;
packetTimestamp = millis();
}
activeBufIndex = 0;
Serial.print(" Datareadcounter CompletePacket: ");
Serial.println(DataReadCounter);
// z= (unsigned int)ptrDataSave;
// Serial.print("Adress ptrDataSave= 0x");
// Serial.println(z,HEX);
//Serial.println((uint16_t)&ptrDataSave);
SBUS_readFrameData((ptrDataSave), packetSize);
}
void resetPacket() {
activeBufIndex = 0;
}
void receiveByte(uint8_t b) {
if (activeBufIndex < max_SBUS_Datasize) {
activeBuf[activeBufIndex++] = b;
}
// Serial.print(b,HEX);
// Serial.print(" ");
}
// ---------------------------------------------------------------------------
// UART0 RX ISRs
// ---------------------------------------------------------------------------
void uart0_rx_status_isr() {
uint8_t b;
// Receiver *instance = rxInstances[0];
uint8_t status = UART0_S1;
#ifdef HAS_KINETISK_UART0_FIFO
// If the receive buffer is full or there's an idle condition
if ((status & (UART_S1_RDRF | UART_S1_IDLE)) != 0) {
__disable_irq();
uint8_t avail = UART0_RCFIFO;
if (avail == 0) {
// Read the register to clear the interrupt, but since it's empty,
// this causes the FIFO to become misaligned, so send RXFLUSH to
// reinitialize its pointers.
// Do this inside no interrupts to avoid a potential race condition
// between reading RCFIFO and flushing the FIFO.
b = UART0_D;
UART0_CFIFO = UART_CFIFO_RXFLUSH;
__enable_irq();
return;
} else {
__enable_irq();
// Read all but the last available, then read S1 and the final value
// So says the chip docs,
// Section 47.3.5 UART Status Register 1 (UART_S1)
// In the NOTE part.
digitalWriteFast(23, 0);
while (--avail > 0) {
b = UART0_D;
receiveByte(b);
}
digitalWriteFast(23, 1);
status = UART0_S1;
b = UART0_D;
receiveByte(b);
}
}
#else
// If the receive buffer is full
if ((status & UART_S1_RDRF) != 0) {
b = UART0_D;
receiveByte(b);
}
#endif // HAS_KINETISK_UART0_FIFO
}
//************************************* isr
void uart0_rx_error_isr() {
uint8_t b;
// Receiver *instance = rxInstances[0];
// A framing error indicates a break
if ((UART0_S1 & UART_S1_FE) != 0) {
digitalWriteFast(19, 0);
// Only allow a packet whose framing error actually indicates a break.
// A value of zero indicates a true break and not some other
// framing error.
// Note: Reading a byte clears interrupt flags
#ifdef HAS_KINETISK_UART0_FIFO
// Flush anything in the buffer
uint8_t avail = UART0_RCFIFO;
if (avail > 1) {
while (--avail > 0) {
b = UART0_D;
receiveByte(b);
}
}
#endif // HAS_KINETISK_UART0_FIFO
b = UART0_D;
if (b == 0) {
completePacket();
}
else {
// Not a break
//instance->resetPacket();
}
digitalWriteFast(19, 1);
}
}
/*******************************************************************************************************************************************/
//Reads the current system settings from EEPROM
//If anything looks weird, reset setting to default value
void read_system_settings(void)
{
//Read what the current UART speed is from EEPROM memory
//Default is 19200
setting_uart_speed_RX = readBaud_RX(); //Combine the three bytes
if(setting_uart_speed_RX < BAUD_MIN || setting_uart_speed_RX > BAUD_MAX)
{
setting_uart_speed_RX = 57600; //Reset UART to 9600 if there is no speed stored
writeBaud_RX(setting_uart_speed_RX); //Record to EEPROM
}
//Read what the current UART speed is from EEPROM memory
//Default is 19200
setting_uart_speed_LIN = readBaud_LIN(); //Combine the three bytes
if(setting_uart_speed_LIN < BAUD_MIN || setting_uart_speed_LIN > BAUD_MAX)
{
setting_uart_speed_LIN = 57600; //Reset UART to 9600 if there is no speed stored
writeBaud_LIN(setting_uart_speed_LIN); //Record to EEPROM
}
//Determine the system mode we should be in
//Default is NEWLOG mode
setting_system_mode = EEPROM.read(LOCATION_SYSTEM_SETTING);
if(setting_system_mode > 5)
{
setting_system_mode = MODE_NEWLOG; //By default, unit will turn on and go to new file logging
EEPROM.write(LOCATION_SYSTEM_SETTING, setting_system_mode);
}
//Read the escape_character
//ASCII(26) is ctrl+z
setting_escape_character = EEPROM.read(LOCATION_ESCAPE_CHAR);
if(setting_escape_character == 0 || setting_escape_character == 255)
{
setting_escape_character = 36; //Reset escape character to ctrl+z
EEPROM.write(LOCATION_ESCAPE_CHAR, setting_escape_character);
}
//Read the number of escape_characters to look for
//Default is 3
setting_max_escape_character = EEPROM.read(LOCATION_MAX_ESCAPE_CHAR);
if(setting_max_escape_character > 5)
{
setting_max_escape_character = 0; //Reset number of escape characters to 3
EEPROM.write(LOCATION_MAX_ESCAPE_CHAR, setting_max_escape_character);
}
//Read whether we should use verbose responses or not
//Default is true
setting_verbose = EEPROM.read(LOCATION_VERBOSE);
if(setting_verbose != ON || setting_verbose != OFF)
{
setting_verbose = ON; //Reset verbose to true
EEPROM.write(LOCATION_VERBOSE, setting_verbose);
}
//Read whether we should echo characters or not
//Default is true
setting_echo = EEPROM.read(LOCATION_ECHO);
if(setting_echo != ON || setting_echo != OFF)
{
setting_echo = ON; //Reset to echo on
EEPROM.write(LOCATION_ECHO, setting_echo);
}
//Set flags for extended mode options
if (setting_verbose == ON)
feedback_mode |= EXTENDED_INFO;
else
feedback_mode &= ((byte)~EXTENDED_INFO);
if (setting_echo == ON)
feedback_mode |= ECHO;
else
feedback_mode &= ((byte)~ECHO);
//Read whether we should ignore RX at power up
//Some users need OpenLog to ignore the RX pin during power up
//Default is false or ignore
setting_ignore_RX = EEPROM.read(LOCATION_IGNORE_RX);
if(setting_ignore_RX > 1)
{
setting_ignore_RX = OFF; //By default we DO NOT ignore RX
EEPROM.write(LOCATION_IGNORE_RX, setting_ignore_RX);
}
////Read what the current UART speed is from EEPROM memory
// //Default is 19200
setting_RX_NUMBER = readRX_NUMBER(); //Combine the three bytes
RX_LINE_ANZAHL = setting_RX_NUMBER;
if(setting_RX_NUMBER == 0 || setting_RX_NUMBER > 1024)
{
setting_RX_NUMBER = 220; //Reset UART to 9600 if there is no speed stored
writeRX_NUMBER(setting_RX_NUMBER); //Record to EEPROM
}
////Read what the current UART speed is from EEPROM memory
// //Default is 19200
setting_RX_FRAME_COUNT = readRX_FRAME_COUNT(); //Combine the three bytes
RX_FRAME_COUNT = setting_RX_FRAME_COUNT;
if(setting_RX_FRAME_COUNT == 0 || setting_RX_FRAME_COUNT > (setting_RX_NUMBER-1))
{
setting_RX_FRAME_COUNT = (setting_RX_NUMBER/2); //Reset UART to 9600 if there is no speed stored
writeRX_FRAME_COUNT(setting_RX_FRAME_COUNT); //Record to EEPROM
}
// //Read whether we should ignore RX at power up
// //Some users need OpenLog to ignore the RX pin during power up
// //Default is false or ignore
setting_RESET_EE = EEPROM.read(LOCATION_RESET_EE);
if(setting_RESET_EE > 1)
{
setting_RESET_EE = OFF; //By default we DO NOT ignore RX
EEPROM.write(LOCATION_RESET_EE, setting_RESET_EE);
}
// //Read whether we should ignore RX at power up
// //Some users need OpenLog to ignore the RX pin during power up
// //Default is false or ignore
setting_ERR_FILE_RENAME = EEPROM.read(LOCATION_ERR_FILE_RENAME);
if(setting_ERR_FILE_RENAME > 1)
{
setting_ERR_FILE_RENAME = ON; //By default we DO NOT ignore RX
EEPROM.write(LOCATION_ERR_FILE_RENAME, setting_ERR_FILE_RENAME);
}
setting_ERR_FLG = EEPROM.read(LOCATION_ERR_FLG);
if(setting_ERR_FLG > 1)
{
setting_ERR_FLG = OFF; //By default we DO NOT ignore RX
EEPROM.write(LOCATION_ERR_FLG, setting_ERR_FLG);
}
}
//A rudimentary way to convert a string to a long 32 bit integer
//Used by the read command, in command shell and baud from the system menu
uint32_t strtolong(const char* str)
{
uint32_t l = 0;
while(*str >= '0' && *str <= '9')
l = l * 10 + (*str++ - '0');
return l;
}
void read_config_file(void)
{
// SdFile rootDirectory;
SdFile configFile;
// if (!rootDirectory.openRoot(&volume)) systemError(ERROR_ROOT_INIT); // open the root directory
char configFileName[strlen(CFG_FILENAME)]; //Limited to 8.3
strcpy_P(configFileName, PSTR(CFG_FILENAME)); //This is the name of the config file. 'config.sys' is probably a bad idea.
//Check to see if we have a config file
if (!configFile.open(configFileName, O_READ)) {
// if (!configFile.open(&rootDirectory, configFileName, O_READ)) {
//If we don't have a config file already, then create config file and record the current system settings to the file
#if DEBUG
Serial.println(F("No config found - creating default:"));
#endif
configFile.close();
// rootDirectory.close(); //Close out the file system before we open a new one
//Record the current eeprom settings to the config file
record_config_file();
//return;
}
//If we found the config file then load settings from file and push them into EEPROM
#if DEBUG
Serial.println(F("Found config file!"));
#endif
//Read up to 22 characters from the file. There may be a better way of doing this...
char c;
int len;
byte settings_string[CFG_LENGTH]; //"115200,103,14,0,1,1,0\0" = 115200 bps, escape char of ASCII(103), 14 times, new log mode, verbose on, echo on, ignore RX false.
for(len = 0 ; len < CFG_LENGTH ; len++) {
if( ((c = configFile.read()) < 0)) break; //We've reached the end of the file
if(c == '\0') break; //Bail if we hit the end of this string
settings_string[len] = c;
}
configFile.close();
// rootDirectory.close();
#if DEBUG
//Print line for debugging
Serial.print("Configfile_StringLength : ");
Serial.print(len, DEC);
Serial.print(F(" Text Settings: "));
for(int i = 0; i < len; i++)
Serial.write(settings_string[i]);
Serial.println();
Serial.print(F("Len: "));
Serial.println(len);
#endif
//Default the system settings in case things go horribly wrong
//115200,115200,103,214,0,1,1,0,4000,120,0,0\0
long new_system_baud_LIN = 57600;
long new_system_baud_RX = 57600;
byte new_system_escape = 26;
byte new_system_max_escape = 0;
byte new_system_mode = MODE_NEWLOG;
byte new_system_verbose = ON;
byte new_system_echo = ON;
byte new_system_ignore_RX = OFF;
long new_system_RX_NUMBER = 200;
long new_system_RX_FRAME_COUNT = 140;
byte new_system_RESET_EE = OFF;
byte new_system_ERR_FILE_RENAME = ON;
//Parse the settings out
byte i = 0, j = 0, setting_number = 0;
char new_setting[7]; //Max length of a setting is 7, the bps setting = '1000000' plus '\0'
byte new_setting_int = 0;
for(i = 0 ; i < len; i++)
{
//Pick out one setting from the line of text
for(j = 0 ; settings_string[i] != ',' && i < len && j < 6 ; )
{
new_setting[j] = settings_string[i];
i++;
j++;
}
new_setting[j] = '\0'; //Terminate the string for array compare
new_setting_int = atoi(new_setting); //Convert string to int
Serial.print("setting_number: ");
Serial.print(setting_number ,DEC);
Serial.print(" - ");
switch (setting_number)
{
case 0: //baud_LIN
new_system_baud_LIN = strtolong(new_setting);
Serial.println(new_system_baud_LIN,DEC);
//Basic error checking
if(new_system_baud_LIN < BAUD_MIN || new_system_baud_LIN > BAUD_MAX) new_system_baud_LIN = 57600; //Default to 19200
break;
case 1: //baud_RX
new_system_baud_RX = strtolong(new_setting);
Serial.println(new_system_baud_RX,DEC);
//Basic error checking
if(new_system_baud_RX < BAUD_MIN || new_system_baud_RX > BAUD_MAX) new_system_baud_RX = 57600; //Default to 19200
break;
case 2: //system_escape //Escape character
new_system_escape = new_setting_int;
Serial.println(new_system_escape,DEC);
if(new_system_escape == 0 || new_system_escape > 127) new_system_escape = 36; //Default is ctrl+z
break;
case 3: //system_max_escape
new_system_max_escape = new_setting_int;
Serial.println( new_system_max_escape,DEC);
if(new_system_max_escape > 254) new_system_max_escape = 0; //Default is 3
break;
case 4: //system_mode
new_system_mode = new_setting_int;
Serial.println(new_system_mode,DEC);
if(new_system_mode == 0 || new_system_mode > MODE_COMMAND) new_system_mode = MODE_NEWLOG; //Default is NEWLOG
break;
case 5: //system_verbose
new_system_verbose = new_setting_int;
Serial.println(new_system_verbose,DEC);
if(new_system_verbose != ON && new_system_verbose != OFF) new_system_verbose = ON; //Default is on
break;
case 6: //system_echo
new_system_echo = new_setting_int;
Serial.println(new_system_echo,DEC);
if(new_system_echo != ON && new_system_echo != OFF) new_system_echo = ON; //Default is on
break;
case 7: //system_ignore_RX
new_system_ignore_RX = new_setting_int;
Serial.println(new_system_ignore_RX,DEC);
if(new_system_ignore_RX != ON && new_system_ignore_RX != OFF) new_system_ignore_RX = OFF; //Default is to listen to RX
break;
case 8: //system_RX_ANZAHL
new_system_RX_NUMBER = strtolong(new_setting);
Serial.print(new_system_RX_NUMBER,DEC);
Serial.print(" - ");
if(new_system_RX_NUMBER == 0 || new_system_RX_NUMBER > 1024) new_system_RX_NUMBER = 220; //Default is to listen to RX
Serial.println(new_system_RX_NUMBER,DEC);
break;
case 9: // RX_FRAME_COUNT
new_system_RX_FRAME_COUNT = strtolong(new_setting);
Serial.print(new_system_RX_FRAME_COUNT,DEC);
Serial.print(" - ");
if(new_system_RX_FRAME_COUNT == 0 || new_system_RX_FRAME_COUNT > (new_system_RX_NUMBER)) new_system_RX_FRAME_COUNT = (new_system_RX_NUMBER / 2 ); //Default is to listen to RX
Serial.println(new_system_RX_FRAME_COUNT,DEC);
break;
case 10: //system_RESET_EE
new_system_RESET_EE = new_setting_int;
Serial.println(new_system_RESET_EE,DEC);
if(new_system_RESET_EE != ON && new_system_RESET_EE != OFF) new_system_RESET_EE = OFF; //Default is to listen to RX
break;
case 11: // system_ERR_FILE_RENAME
new_system_ERR_FILE_RENAME = new_setting_int;
Serial.println(new_system_ERR_FILE_RENAME,DEC);
if(new_system_ERR_FILE_RENAME != ON && new_system_ERR_FILE_RENAME != OFF) new_system_ERR_FILE_RENAME = ON; //Default is to listen to RX
break;
default:
break;
}
setting_number++;
}
//We now have the settings loaded into the global variables. Now check if they're different from EEPROM settings
boolean recordNewSettings = false;
if(new_system_baud_LIN != setting_uart_speed_LIN) {
//If the baud rate from the file is different from the current setting,
//Then update the setting to the file setting
//And re-init the UART
writeBaud_LIN(new_system_baud_LIN); //Write this baudrate to EEPROM
setting_uart_speed_LIN = new_system_baud_LIN;
SBUS_Serial.begin(setting_uart_speed_LIN);
Serial.print("Set LIN Baudrate: ");
Serial.println(setting_uart_speed_LIN,DEC);
recordNewSettings = true;
}
if(new_system_baud_RX != setting_uart_speed_RX) {
//If the baud rate from the file is different from the current setting,
//Then update the setting to the file setting
//And re-init the UART
writeBaud_RX(new_system_baud_RX); //Write this baudrate to EEPROM
setting_uart_speed_RX = new_system_baud_RX;
// HWSERIAL2.begin(setting_uart_speed_RX);
Serial.print("Set Uart Baudrate: ");
Serial.println(setting_uart_speed_RX,DEC);
recordNewSettings = true;
}
if(new_system_mode != setting_system_mode) {
//Goto new system mode
setting_system_mode = new_system_mode;
EEPROM.write(LOCATION_SYSTEM_SETTING, setting_system_mode);
recordNewSettings = true;
}
if(new_system_escape != setting_escape_character) {
//Goto new system escape char
setting_escape_character = new_system_escape;
EEPROM.write(LOCATION_ESCAPE_CHAR, setting_escape_character);
recordNewSettings = true;
}
if(new_system_max_escape != setting_max_escape_character) {
//Goto new max escape
setting_max_escape_character = new_system_max_escape;
EEPROM.write(LOCATION_MAX_ESCAPE_CHAR, setting_max_escape_character);
recordNewSettings = true;
}
if(new_system_verbose != setting_verbose) {
//Goto new verbose setting
setting_verbose = new_system_verbose;
EEPROM.write(LOCATION_VERBOSE, setting_verbose);
recordNewSettings = true;
}
if(new_system_echo != setting_echo) {
//Goto new echo setting
setting_echo = new_system_echo;
EEPROM.write(LOCATION_ECHO, setting_echo);
recordNewSettings = true;
}
if(new_system_ignore_RX != setting_ignore_RX) {
//Goto new ignore setting
setting_ignore_RX = new_system_ignore_RX;
EEPROM.write(LOCATION_IGNORE_RX, setting_ignore_RX);
recordNewSettings = true;
}
if(new_system_RX_NUMBER != setting_RX_NUMBER) {
//If the baud rate from the file is different from the current setting,
//Then update the setting to the file setting
//And re-init the UART
Serial.print("DiFFer detected new_system_RX_NUMBER fehlt: ");
Serial.print(new_system_RX_NUMBER,DEC);
Serial.print(" / setting_RX_NUMBER: ");
Serial.println(setting_RX_NUMBER,DEC);
writeRX_NUMBER(new_system_RX_NUMBER); //Write this baudrate to EEPROM
setting_RX_NUMBER = new_system_RX_NUMBER;
RX_LINE_ANZAHL = new_system_RX_NUMBER; // definiere neuen Wert zum festlegen der max Zeichen...
// Serial.print("Code für set new_system_RX_NUMBER fehlt: ");
// Serial.println(new_system_RX_NUMBER,DEC);
recordNewSettings = true;
}
if(new_system_RX_FRAME_COUNT != setting_RX_FRAME_COUNT) {
//If the baud rate from the file is different from the current setting,
//Then update the setting to the file setting
//And re-init the UART
Serial.print("Differ detect - new_system_RX_FRAME_COUNT : ");
Serial.print(new_system_RX_FRAME_COUNT,DEC);
Serial.print(" / setting_RX_FRAME_COUNT: ");
Serial.println(setting_RX_FRAME_COUNT,DEC);
writeRX_FRAME_COUNT(new_system_RX_FRAME_COUNT); //Write this baudrate to EEPROM
setting_RX_FRAME_COUNT = new_system_RX_FRAME_COUNT;
RX_FRAME_COUNT = new_system_RX_FRAME_COUNT; // definiere neuen Wert zum festlegen der max Zeichen...
Serial.print("Differ detect - new_system_RX_FRAME_COUNT : ");
Serial.print(new_system_RX_FRAME_COUNT,DEC);
Serial.print(" / setting_RX_FRAME_COUNT: ");
Serial.println(setting_RX_FRAME_COUNT,DEC);
recordNewSettings = true;
}
// Code für RESET_EE FEHLt !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if(new_system_RESET_EE != setting_RESET_EE) {
//If the baud rate from the file is different from the current setting,
//Then update the setting to the file setting
//And re-init the UART
if (new_system_RESET_EE ==1 )
{
// RESET_EEPROM
EEPROM.write(LOCATION_SYSTEM_SETTING, 0xFF);
EEPROM.write(LOCATION_ESCAPE_CHAR, 0xFF);
EEPROM.write(LOCATION_MAX_ESCAPE_CHAR, 0xFF);
EEPROM.write(LOCATION_VERBOSE, 0xFF);
EEPROM.write(LOCATION_ECHO, 0xFF);
EEPROM.write(LOCATION_IGNORE_RX, 0xFF);
EEPROM.write(LOCATION_ERR_FLG, 0x0);
EEPROM.write(LOCATION_RESET_EE, 0x0);
EEPROM.write(LOCATION_ERR_FILE_RENAME, 0x1);
EEPROM.write(LOCATION_FILE_NUMBER_LSB, 0xFF);
EEPROM.write(LOCATION_FILE_NUMBER_MID, 0xFF);
EEPROM.write(LOCATION_FILE_NUMBER_MSB, 0xFF);
EEPROM.write(LOCATION_RX_BAUD_SETTING_HIGH,0xFF);
EEPROM.write(LOCATION_RX_BAUD_SETTING_MID, 0xFF);
EEPROM.write(LOCATION_RX_BAUD_SETTING_LOW, 0xFF);
EEPROM.write(LOCATION_LIN_BAUD_SETTING_HIGH,0xFF);
EEPROM.write(LOCATION_LIN_BAUD_SETTING_MID, 0xFF);
EEPROM.write(LOCATION_LIN_BAUD_SETTING_LOW, 0xFF);
//Remove the config file if it is there
SdFile rootDirectory;
// if (!rootDirectory.openRoot(&volume)) systemError(ERROR_ROOT_INIT); // open the root directory
char configFileName[strlen(CFG_FILENAME)];
strcpy_P(configFileName, PSTR(CFG_FILENAME)); //This is the name of the config file. 'config.sys' is probably a bad idea.
//If there is currently a config file, trash it _reset EE
// if (myFile.open(&rootDirectory, configFileName, O_WRITE)) {
// Serial.println(F("Deleting config"));
// if (!myFile.remove()){
// Serial.println(F("Remove config failed"));
// return;
// }
// }
Serial.println(F("Unit has been reset. Please power cycle"));
while(1)
{
for(int time_d = 0;time_d < 20;time_d++)
{
pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
delay(100 + (2*time_d*time_d));
digitalWrite(13, LOW);
delay(time_d*time_d + 200);
Serial.println(F("Unit has been reset. Please power cycle"));
}
};
}
// write back to File so that it could be done only once....
writeBaud_RX(new_system_baud_RX); //Write this baudrate to EEPROM
setting_uart_speed_RX = new_system_baud_RX;
// HWSERIAL2.begin(setting_uart_speed_RX);
Serial.print("Set Uart Baudrate: ");
Serial.println(setting_uart_speed_RX,DEC);
recordNewSettings = true;
}
//
// Code für ERR_FILE_RENAME FEHLt !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// if(new_system_baud_RX != setting_uart_speed_RX) {
// //If the baud rate from the file is different from the current setting,
// //Then update the setting to the file setting
// //And re-init the UART
//
// writeBaud_RX(new_system_baud_RX); //Write this baudrate to EEPROM
// setting_uart_speed_RX = new_system_baud_RX;
// HWSERIAL2.begin(setting_uart_speed_RX);
// Serial.print("Set Uart Baudrate: ");
// Serial.println(setting_uart_speed_RX,DEC);
// recordNewSettings = true;
// }
//
//We don't want to constantly record a new config file on each power on. Only record when there is a change.
if(recordNewSettings == true) record_config_file(); //If we corrected some values because the config file was corrupt, then overwrite any corruption
else
#if DEBUG
Serial.println(F("Config file matches system settings"));
#endif
//All done! New settings are loaded. System will now operate off new config settings found in file.
//Set flags for extended mode options
if (setting_verbose == ON)
feedback_mode |= EXTENDED_INFO;
else
feedback_mode &= ((byte)~EXTENDED_INFO);
if (setting_echo == ON)
feedback_mode |= ECHO;
else
feedback_mode &= ((byte)~ECHO);
}
//Records the current EEPROM settings to the config file
//If a config file exists, it is trashed and a new one is created
void record_config_file(void)
{
//I'm worried that the user may not be in the root directory when modifying config settings. If that is the case,
//config file will not be found and it will be created in some erroneus directory. The changes to user settings may be lost on the
//next power cycles. To prevent this, we will open another instance of the file system, then close it down when we are done.
SdFile rootDirectory;
SdFile myFile;
Serial.println("Record new ConfigFile");
// if (!rootDirectory.openRoot(&volume)) systemError(ERROR_ROOT_INIT); // open the root directory
char configFileName[strlen(CFG_FILENAME)];
strcpy_P(configFileName, PSTR(CFG_FILENAME)); //This is the name of the config file. 'config.sys' is probably a bad idea.
//If there is currently a config file, trash it
if (myFile.open(configFileName, O_WRITE)) {
if (!myFile.remove()){
Serial.println(F("Remove config failed"));
myFile.close(); //Close this file
// rootDirectory.close(); //Close this file structure instance
//return;
}
}
// myFile.close(); //Not sure if we need to close the file before we try to reopen it
//Create config file
if (myFile.open(configFileName, O_CREAT | O_APPEND | O_WRITE) == 0) {
Serial.println(F("Create config failed"));
myFile.close(); //Close this file
//
//rootDirectory.close(); //Close this file structure instance
//return;
}
Serial.println(F("Config was successfully created, now record current system settings to the config file"));
//Config was successfully created, now record current system settings to the config file
char settings_string[CFG_LENGTH]; //"115200,103,14,0,1,1,0\0" = 115200 bps, escape char of ASCII(103), 14 times, new log mode, verbose on, echo on, ignore RX false.
//Before we read the EEPROM values, they've already been tested and defaulted in the read_system_settings function
long current_system_baud_RX = readBaud_RX();
long current_system_baud_LIN = readBaud_LIN();
byte current_system_escape = EEPROM.read(LOCATION_ESCAPE_CHAR);
byte current_system_max_escape = EEPROM.read(LOCATION_MAX_ESCAPE_CHAR);
byte current_system_mode = EEPROM.read(LOCATION_SYSTEM_SETTING);
byte current_system_verbose = EEPROM.read(LOCATION_VERBOSE);
byte current_system_echo = EEPROM.read(LOCATION_ECHO);
byte current_system_ignore_RX = EEPROM.read(LOCATION_IGNORE_RX);
int current_system_RX_Anzahl = readRX_NUMBER();
int current_system_RX_FRAME_COUNT = readRX_FRAME_COUNT();
byte current_system_RESET_EE = EEPROM.read(LOCATION_RESET_EE);
byte current_system_ERR_FILE_RENAME = EEPROM.read(LOCATION_ERR_FILE_RENAME);
//Convert system settings to visible ASCII characters
sprintf_P(settings_string, PSTR("%ld,%ld,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\0"), current_system_baud_LIN,current_system_baud_RX, current_system_escape, current_system_max_escape, current_system_mode, current_system_verbose, current_system_echo, current_system_ignore_RX,current_system_RX_Anzahl,current_system_RX_FRAME_COUNT,current_system_RESET_EE,current_system_ERR_FILE_RENAME);
//Record current system settings to the config file
if(myFile.write(settings_string, strlen(settings_string)) != strlen(settings_string))
Serial.println(F("error writing to file"));
myFile.print('\0'); //Add a End of String
myFile.println(); //Add a break between lines
//Add a decoder line to the file
#define HELP_STR "baud_LIN,baud_RX,escape,esc#,mode,verb,echo,ignoreRX,RX_Anzahl,RX_FRAME_COUNT,RESET_EE,ERR_FILE_RENAME\0"
char helperString[strlen(HELP_STR) + 1]; //strlen is preprocessed but returns one less because it ignores the \0
strcpy_P(helperString, PSTR(HELP_STR));
myFile.write(helperString); //Add this string to the file
myFile.sync(); //Sync all newly written data to card
myFile.close(); //Close this file
// rootDirectory.close(); //Close this file structure instance
//Now that the new config file has the current system settings, nothing else to do!
Serial.println(F("current system settings recorded to the config file"));
}
//Given a baud rate (long number = four bytes but we only use three), record to EEPROM
void writeBaud_LIN(long uartRate)
{
EEPROM.write(LOCATION_LIN_BAUD_SETTING_HIGH, (byte)((uartRate & 0x00FF0000) >> 16));
EEPROM.write(LOCATION_LIN_BAUD_SETTING_MID, (byte)(uartRate >> 8));
EEPROM.write(LOCATION_LIN_BAUD_SETTING_LOW, (byte)uartRate);
}
void writeBaud_RX(long uartRate)
{
EEPROM.write(LOCATION_RX_BAUD_SETTING_HIGH, (byte)((uartRate & 0x00FF0000) >> 16));
EEPROM.write(LOCATION_RX_BAUD_SETTING_MID, (byte)(uartRate >> 8));
EEPROM.write(LOCATION_RX_BAUD_SETTING_LOW, (byte)uartRate);
}
void writeRX_FRAME_COUNT(long FRAME_COUNT)
{
EEPROM.write(LOCATION_RX_FRAME_COUNT_MSB, highByte(FRAME_COUNT));
EEPROM.write(LOCATION_RX_FRAME_COUNT_LSB, lowByte(FRAME_COUNT));
}
void writeRX_NUMBER(int RX_NUMBER)
{
EEPROM.write(LOCATION_RX_NUMBER_MSB, highByte(RX_NUMBER));
EEPROM.write(LOCATION_RX_NUMBER_LSB, lowByte(RX_NUMBER));
}
//Look up the baud rate. This requires three bytes be combined into one long
long readBaud_RX(void)
{
byte uartSpeedHigh = EEPROM.read(LOCATION_RX_BAUD_SETTING_HIGH);
byte uartSpeedMid = EEPROM.read(LOCATION_RX_BAUD_SETTING_MID);
byte uartSpeedLow = EEPROM.read(LOCATION_RX_BAUD_SETTING_LOW);
long uartSpeed_RX = 0x00FF0000 & ((long)uartSpeedHigh << 16) | ((long)uartSpeedMid << 8) | uartSpeedLow; //Combine the three bytes
return(uartSpeed_RX);
}
long readBaud_LIN(void)
{
byte uartSpeedHigh = EEPROM.read(LOCATION_LIN_BAUD_SETTING_HIGH);
byte uartSpeedMid = EEPROM.read(LOCATION_LIN_BAUD_SETTING_MID);
byte uartSpeedLow = EEPROM.read(LOCATION_LIN_BAUD_SETTING_LOW);
long uartSpeed_LIN = 0x00FF0000 & ((long)uartSpeedHigh << 16) | ((long)uartSpeedMid << 8) | uartSpeedLow; //Combine the three bytes
return(uartSpeed_LIN);
}
int readRX_FRAME_COUNT(void)
{
byte RXFrameCountHigh = EEPROM.read(LOCATION_RX_FRAME_COUNT_MSB);
byte RXFrameCountLow = EEPROM.read(LOCATION_RX_FRAME_COUNT_LSB);
int RXFrameCount = (RXFrameCountHigh << 8) | RXFrameCountLow; //Combine the three bytes
return(RXFrameCount);
}
int readRX_NUMBER(void)
{
byte RXNumberHigh = EEPROM.read(LOCATION_RX_NUMBER_MSB);
byte RXNumberLow = EEPROM.read(LOCATION_RX_NUMBER_LSB);
int RXNumber = (RXNumberHigh << 8) | RXNumberLow; //Combine the three bytes
return(RXNumber);
}