1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-12-24 05:11:24 +01:00

WifiInterface compiles

Basic logic compiles... untested
This commit is contained in:
Asbelos 2020-06-13 09:36:10 +01:00
parent 0a60a36d30
commit 2a36ad365c
7 changed files with 241 additions and 21 deletions

View File

@ -19,10 +19,9 @@ void myCallback(int result) {
}
DCCEXParser serialParser;
DCCEXParser wifiParser;
void setup() {
Serial.begin(115200);
Serial.begin(SERIAL_BAUD_RATE);
DCC::begin();
if (WIFI_PORT>0) WifiInterface::setup();
DIAG(F("\n===== CVReader demonstrating DCC::getLocoId() call ==========\n"));
@ -36,5 +35,5 @@ void loop() {
// This line passes input on Serial to the DCCEXParser
serialParser.loop(Serial);
if (WIFI_PORT>0) WifiInterface::loop(wifiParser);
if (WIFI_PORT>0) WifiInterface::loop();
}

View File

@ -5,8 +5,8 @@ const int WIFI_PORT = 99; // OR set to zero for no wifi
const char WIFI_SSID[] = "BTHub5-M6PT"; // your network SSID (name)
const char WIFI_PASS[] = "49de8d4862"; // your network password
const long WIFI_BAUD_RATE=115200;
const long WIFI_CONNECT_RETRIES=10;
const long SERIAL_BAUD_RATE=115200;
// This hardware configuration would normally be setup using a bunch of #ifdefs.
@ -26,7 +26,7 @@ const byte PROG_BRAKE_PIN = 10;
const float PROG_SENSE_FACTOR=1; // analgRead(PROG_SENSE_PIN) * PROG_SENSE_FACTOR = milliamps
// Allocations with memory implications.. however tiny!
// Base system takes approx 500 bytes + 4 per loco and 3 per turnout.
// Base system takes approx 500 bytes + 3 per loco and 4 per turnout.
const byte MAX_LOCOS=50;
const byte MAX_TURNOUTS=50;

View File

@ -5,6 +5,7 @@ struct DCCEXParser
{
DCCEXParser();
void loop(Stream & pstream);
void parse(Print & stream, const char * command);
void flush();
private:
@ -14,7 +15,6 @@ struct DCCEXParser
bool inCommandPayload=false;
char buffer[MAX_BUFFER+2];
int splitValues( int result[MAX_PARAMS]);
void parse(Print & stream, const char * command);
bool parseT(Print & stream, int params, int p[]);
bool parseZ(Print & stream, int params, int p[]);

99
MemStream.cpp Normal file
View File

@ -0,0 +1,99 @@
/*
(c) 2015 Ingo Fischer
buffer serial device
based on Arduino SoftwareSerial
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "MemStream.h"
MemStream::MemStream(uint8_t *buffer, const uint16_t len, uint16_t content_len, bool allowWrite)
:_buffer(buffer),_len(len), _buffer_overflow(false), _pos_write(content_len), _pos_read(0), _allowWrite(allowWrite)
{
if (content_len==0) memset(_buffer, 0, _len);
if (content_len>len) {
content_len=len;
_pos_write=len;
}
}
size_t MemStream::write(uint8_t byte) {
if (! _allowWrite) return -1;
if (_pos_write >= _len) {
_buffer_overflow = true;
return 0;
}
_buffer[_pos_write] = byte;
++_pos_write;
return 1;
}
void MemStream::flush() {
memset(_buffer, 0, _len);
_pos_write = 0;
_pos_read = 0;
}
int MemStream::read() {
if (_pos_read >= _len) {
_buffer_overflow = true;
return -1;
}
if (_pos_read >= _pos_write) {
return -1;
}
return _buffer[_pos_read++];
}
int MemStream::peek() {
if (_pos_read >= _len) {
_buffer_overflow = true;
return -1;
}
if (_pos_read >= _pos_write) {
return -1;
}
return _buffer[_pos_read+1];
}
int MemStream::available() {
int ret=_pos_write-_pos_read;
if (ret<0) ret=0;
return ret;
}
void MemStream::setBufferContent(uint8_t *buffer, uint16_t content_len) {
memset(_buffer, 0, _len);
memcpy(_buffer, buffer, content_len);
_buffer_overflow=false;
_pos_write=content_len;
_pos_read=0;
}
void MemStream::setBufferContentFromProgmem(uint8_t *buffer, uint16_t content_len) {
memset(_buffer, 0, _len);
memcpy_P(_buffer, buffer, content_len);
_buffer_overflow=false;
_pos_write=content_len;
_pos_read=0;
}
void MemStream::setBufferContentPosition(uint16_t read_pos, uint16_t write_pos) {
_pos_write=write_pos;
_pos_read=read_pos;
}

69
MemStream.h Normal file
View File

@ -0,0 +1,69 @@
/*
(c) 2015 Ingo FIscher
buffer serial device
based on Arduino SoftwareSerial
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MemStream_h
#define MemStream_h
#include <inttypes.h>
#include <Stream.h>
#include <avr/pgmspace.h>
class MemStream : public Stream
{
private:
uint8_t * _buffer;
const uint16_t _len;
bool _buffer_overflow;
uint16_t _pos_read;
uint16_t _pos_write;
bool _allowWrite;
public:
// public methods
MemStream(uint8_t *buffer, const uint16_t len, uint16_t content_len = 0, bool allowWrite=true);
~MemStream() {}
operator const uint8_t *() const { return _buffer; }
operator const char *() const { return (const char*)_buffer; }
const uint16_t current_length() const { return _pos_write; }
bool listen() { return true; }
void end() {}
bool isListening() { return true; }
bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; }
int peek();
virtual size_t write(uint8_t byte);
virtual int read();
virtual int available();
virtual void flush();
void setBufferContent(uint8_t *buffer, uint16_t content_len);
void setBufferContentFromProgmem(uint8_t *buffer, uint16_t content_len);
void setBufferContentPosition(uint16_t read_pos, uint16_t write_pos);
using Print::write;
};
#endif

View File

@ -3,14 +3,22 @@
#include "DIAG.h"
#include "StringFormatter.h"
const char READY_SEARCH[]="\r\nready\r\n";
const char OK_SEARCH[]="\r\nOK\r\n";
bool WifiInterface::connected=false;
DCCEXParser WifiInterface::parser;
byte WifiInterface::loopstate=0;
int WifiInterface::datalength=0;
int WifiInterface::connectionId;
byte WifiInterface::buffer[MAX_WIFI_BUFFER];
MemStream WifiInterface::streamer(buffer,sizeof(buffer));
void WifiInterface::setup() {
DIAG(F("\n++++++ Wifi Setup In Progress ++++++++\n"));
connected=setup2();
// TODO calloc the buffer and streamer and parser etc
DIAG(F("\n++++++ Wifi Setup %s ++++++++\n"), connected?"OK":"FAILED");
}
@ -64,15 +72,54 @@ bool WifiInterface::checkForOK( const int timeout,char * search) {
}
void WifiInterface::loop(DCCEXParser & parser) {
void WifiInterface::loop() {
if (!connected) return;
while(Serial1.available()) Serial.write(Serial1.read());
// TODO Read incoming...
// if starts +IPD
// get session id
// fill buffer
// set session id into PrintAT
// call parser
// implement parser flush
}
// read anything into a buffer, collecting info on the way
while (loopstate!=99 && Serial1.available()) {
int ch=Serial1.read();
switch (loopstate) {
case 0: // looking for +
connectionId=0;
streamer.flush();
if (ch=='+') loopstate=1;
break;
case 1: // Looking for I
loopstate= (ch=='I')?2:0;
break;
case 2: // Looking for P
loopstate= (ch=='P')?3:0;
break;
case 3: // Looking for D
loopstate= (ch=='D')?4:0;
break;
case 4: // Looking for ,
loopstate= (ch==',')?5:0;
break;
case 5: // reading connection id
if (ch==',') loopstate=6;
else connectionId=10*connectionId+(ch-'0');
break;
case 6: // reading for length
if (ch==':') loopstate=(datalength==0)?99:7; // 99 is getout without reading next char
else datalength=datalength*10 + (ch-'0');
break;
case 7: // reading data
datalength--;
if (datalength==0) loopstate=99;
break;
} // switch
} // while
if (loopstate!=99) return;
// TODO remove > in data
streamer.write('\0');
streamer.flush(); // reset write position to start of buffer
// SIDE EFFECT WARNING:::
// We know that parser will read the entire buffer before starting to write to it.
// Otherwise we would have to copy the buffer elsewhere and RAM is in short supply.
// TODO ... tell parser that callbacks are diallowed because we dont want to handle the async
parser.parse(streamer,buffer+1);
StringFormatter::send(Serial1,F("AT+CIPSEND=%d,%d\r\n>%s"),connectionId,streamer.available(),buffer);
loopstate=0;
}

View File

@ -2,19 +2,25 @@
#ifndef WifiInterface_h
#define WifiInterface_h
#include "DCCEXParser.h"
#include "MemStream.h"
class WifiInterface {
public:
static void setup();
static void loop(DCCEXParser & parser);
static void loop();
private:
static DCCEXParser parser;
static bool setup2();
static bool checkForOK(const int timeout, char * search);
static bool connected;
static const byte MAX_BUFFER=64;
static byte inboundBuffer[MAX_BUFFER];
static byte loopstate;
static int datalength;
static int connectionId;
static const byte MAX_WIFI_BUFFER=64;
static byte buffer[MAX_WIFI_BUFFER];
static MemStream streamer;
};
#endif