mirror of
https://github.com/thooge/esp32-nmea2000-obp60.git
synced 2025-12-14 06:23:07 +01:00
intermediate,untested: reorganize channel handling
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#include "GwSerial.h"
|
||||
#include "GwHardware.h"
|
||||
|
||||
class GwSerialStream: public Stream{
|
||||
private:
|
||||
@@ -40,11 +41,13 @@ class GwSerialStream: public Stream{
|
||||
|
||||
|
||||
|
||||
GwSerial::GwSerial(GwLog *logger, GwSerial::SerialWrapperBase *s, bool allowRead):serial(s)
|
||||
GwSerial::GwSerial(GwLog *logger, Stream * stream,int id,int type,bool allowRead)
|
||||
{
|
||||
LOG_DEBUG(GwLog::DEBUG,"creating GwSerial %p id %d",this,id);
|
||||
this->id=s->getId();
|
||||
this->logger = logger;
|
||||
this->id=id;
|
||||
this->stream=stream;
|
||||
this->type=type;
|
||||
String bufName="Ser(";
|
||||
bufName+=String(id);
|
||||
bufName+=")";
|
||||
@@ -62,6 +65,20 @@ GwSerial::~GwSerial()
|
||||
if (readBuffer) delete readBuffer;
|
||||
}
|
||||
|
||||
String GwSerial::getMode(){
|
||||
switch (type){
|
||||
case GWSERIAL_TYPE_UNI:
|
||||
return "UNI";
|
||||
case GWSERIAL_TYPE_BI:
|
||||
return "BI";
|
||||
case GWSERIAL_TYPE_RX:
|
||||
return "RX";
|
||||
case GWSERIAL_TYPE_TX:
|
||||
return "TX";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
bool GwSerial::isInitialized() { return initialized; }
|
||||
size_t GwSerial::enqueue(const uint8_t *data, size_t len, bool partial)
|
||||
{
|
||||
@@ -70,9 +87,9 @@ size_t GwSerial::enqueue(const uint8_t *data, size_t len, bool partial)
|
||||
}
|
||||
GwBuffer::WriteStatus GwSerial::write(){
|
||||
if (! isInitialized()) return GwBuffer::ERROR;
|
||||
size_t numWrite=serial->availableForWrite();
|
||||
size_t numWrite=availableForWrite();
|
||||
size_t rt=buffer->fetchData(numWrite,[](uint8_t *buffer,size_t len, void *p){
|
||||
return ((GwSerial *)p)->serial->write(buffer,len);
|
||||
return ((GwSerial *)p)->stream->write(buffer,len);
|
||||
},this);
|
||||
if (rt != 0){
|
||||
LOG_DEBUG(GwLog::DEBUG+1,"Serial %d write %d",id,rt);
|
||||
@@ -93,11 +110,11 @@ void GwSerial::loop(bool handleRead,bool handleWrite){
|
||||
write();
|
||||
if (! isInitialized()) return;
|
||||
if (! handleRead) return;
|
||||
size_t available=serial->available();
|
||||
size_t available=stream->available();
|
||||
if (! available) return;
|
||||
if (allowRead){
|
||||
size_t rd=readBuffer->fillData(available,[](uint8_t *buffer, size_t len, void *p)->size_t{
|
||||
return ((GwSerial *)p)->serial->readBytes(buffer,len);
|
||||
return ((GwSerial *)p)->stream->readBytes(buffer,len);
|
||||
},this);
|
||||
if (rd != 0){
|
||||
LOG_DEBUG(GwLog::DEBUG+2,"GwSerial %d read %d bytes",id,rd);
|
||||
@@ -106,7 +123,7 @@ void GwSerial::loop(bool handleRead,bool handleWrite){
|
||||
else{
|
||||
uint8_t buffer[10];
|
||||
if (available > 10) available=10;
|
||||
serial->readBytes(buffer,available);
|
||||
stream->readBytes(buffer,available);
|
||||
}
|
||||
}
|
||||
void GwSerial::readMessages(GwMessageFetcher *writer){
|
||||
@@ -115,10 +132,11 @@ void GwSerial::readMessages(GwMessageFetcher *writer){
|
||||
writer->handleBuffer(readBuffer);
|
||||
}
|
||||
|
||||
bool GwSerial::flush(long max){
|
||||
bool GwSerial::flush(){
|
||||
if (! isInitialized()) return false;
|
||||
long max=getFlushTimeout();
|
||||
if (! availableWrite) {
|
||||
if ( serial->availableForWrite() < 1){
|
||||
if ( availableForWrite() < 1){
|
||||
return false;
|
||||
}
|
||||
availableWrite=true;
|
||||
@@ -128,7 +146,7 @@ bool GwSerial::flush(long max){
|
||||
if (write() != GwBuffer::AGAIN) return true;
|
||||
vTaskDelay(1);
|
||||
}
|
||||
availableWrite=(serial->availableForWrite() > 0);
|
||||
availableWrite=(availableForWrite() > 0);
|
||||
return false;
|
||||
}
|
||||
Stream * GwSerial::getStream(bool partialWrite){
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
#include "GwChannelInterface.h"
|
||||
class GwSerialStream;
|
||||
class GwSerial : public GwChannelInterface{
|
||||
private:
|
||||
protected:
|
||||
GwBuffer *buffer;
|
||||
GwBuffer *readBuffer=NULL;
|
||||
GwLog *logger;
|
||||
Stream *stream;
|
||||
bool initialized=false;
|
||||
bool allowRead=true;
|
||||
GwBuffer::WriteStatus write();
|
||||
@@ -17,36 +18,66 @@ class GwSerial : public GwChannelInterface{
|
||||
int overflows=0;
|
||||
size_t enqueue(const uint8_t *data, size_t len,bool partial=false);
|
||||
bool availableWrite=false; //if this is false we will wait for availabkleWrite until we flush again
|
||||
virtual long getFlushTimeout(){return 2000;}
|
||||
virtual int availableForWrite()=0;
|
||||
int type=0;
|
||||
public:
|
||||
class SerialWrapperBase{
|
||||
public:
|
||||
virtual void begin(GwLog* logger,unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1)=0;
|
||||
virtual int getId()=0;
|
||||
virtual int available(){return getStream()->available();}
|
||||
size_t readBytes(uint8_t *buffer, size_t length){
|
||||
return getStream()->readBytes(buffer,length);
|
||||
}
|
||||
virtual int availableForWrite(void){
|
||||
return getStream()->availableForWrite();
|
||||
}
|
||||
size_t write(const uint8_t *buffer, size_t size){
|
||||
return getStream()->write(buffer,size);
|
||||
}
|
||||
private:
|
||||
virtual Stream *getStream()=0;
|
||||
};
|
||||
static const int bufferSize=200;
|
||||
GwSerial(GwLog *logger,SerialWrapperBase *stream,bool allowRead=true);
|
||||
~GwSerial();
|
||||
GwSerial(GwLog *logger,Stream *stream,int id,int type,bool allowRead=true);
|
||||
virtual ~GwSerial();
|
||||
bool isInitialized();
|
||||
virtual size_t sendToClients(const char *buf,int sourceId,bool partial=false);
|
||||
virtual void loop(bool handleRead=true,bool handleWrite=true);
|
||||
virtual void readMessages(GwMessageFetcher *writer);
|
||||
bool flush(long millis=200);
|
||||
bool flush();
|
||||
virtual Stream *getStream(bool partialWrites);
|
||||
bool getAvailableWrite(){return availableWrite;}
|
||||
virtual void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1)=0;
|
||||
virtual String getMode() override;
|
||||
friend GwSerialStream;
|
||||
private:
|
||||
SerialWrapperBase *serial;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class GwSerialImpl : public GwSerial{
|
||||
private:
|
||||
template<class C>
|
||||
void beginImpl(C *s,unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1){}
|
||||
void beginImpl(HardwareSerial *s,unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1){
|
||||
s->begin(baud,config,rxPin,txPin);
|
||||
}
|
||||
template<class C>
|
||||
void setError(C* s, GwLog *logger){}
|
||||
void setError(HardwareSerial *s,GwLog *logger){
|
||||
LOG_DEBUG(GwLog::LOG,"enable serial errors for channel %d",id);
|
||||
s->onReceiveError([logger,this](hardwareSerial_error_t err){
|
||||
LOG_DEBUG(GwLog::ERROR,"serial error on id %d: %d",this->id,(int)err);
|
||||
});
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
|
||||
void beginImpl(HWCDC *s,unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1){
|
||||
s->begin(baud);
|
||||
}
|
||||
#endif
|
||||
template<class C>
|
||||
long getFlushTimeoutImpl(const C*){return 2000;}
|
||||
long getFlushTimeoutImpl(HWCDC *){return 200;}
|
||||
|
||||
T *serial;
|
||||
protected:
|
||||
virtual long getFlushTimeout() override{
|
||||
return getFlushTimeoutImpl(serial);
|
||||
}
|
||||
virtual int availableForWrite(){
|
||||
return serial->availableForWrite();
|
||||
}
|
||||
public:
|
||||
GwSerialImpl(GwLog* logger,T* s,int i,int type,bool allowRead=true): GwSerial(logger,s,i,type,allowRead),serial(s){}
|
||||
virtual ~GwSerialImpl(){}
|
||||
virtual void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1) override{
|
||||
beginImpl(serial,baud,config,rxPin,txPin);
|
||||
setError(serial,logger);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user