allow to start m5 atom s3 without USB device connected
This commit is contained in:
parent
5b0b8ba799
commit
d27e811317
|
@ -173,7 +173,7 @@ void GwChannel::toJson(GwJsonDocument &doc){
|
||||||
if (countIn) countIn->toJson(doc);
|
if (countIn) countIn->toJson(doc);
|
||||||
}
|
}
|
||||||
String GwChannel::toString(){
|
String GwChannel::toString(){
|
||||||
String rt="CH:"+name;
|
String rt="CH"+name+"("+sourceId+"):";
|
||||||
rt+=enabled?"[ena]":"[dis]";
|
rt+=enabled?"[ena]":"[dis]";
|
||||||
rt+=NMEAin?"in,":"";
|
rt+=NMEAin?"in,":"";
|
||||||
rt+=NMEAout?"out,":"";
|
rt+=NMEAout?"out,":"";
|
||||||
|
|
|
@ -35,12 +35,13 @@ class GwSerialLog : public GwLogWriter
|
||||||
int wp = 0;
|
int wp = 0;
|
||||||
GwSerial *writer;
|
GwSerial *writer;
|
||||||
bool disabled = false;
|
bool disabled = false;
|
||||||
|
long flushTimeout=200;
|
||||||
public:
|
public:
|
||||||
GwSerialLog(GwSerial *writer, bool disabled)
|
GwSerialLog(GwSerial *writer, bool disabled,long flushTimeout=200)
|
||||||
{
|
{
|
||||||
this->writer = writer;
|
this->writer = writer;
|
||||||
this->disabled = disabled;
|
this->disabled = disabled;
|
||||||
|
this->flushTimeout=flushTimeout;
|
||||||
logBuffer = new char[bufferSize];
|
logBuffer = new char[bufferSize];
|
||||||
wp = 0;
|
wp = 0;
|
||||||
}
|
}
|
||||||
|
@ -63,16 +64,63 @@ public:
|
||||||
{
|
{
|
||||||
while (handled < wp)
|
while (handled < wp)
|
||||||
{
|
{
|
||||||
writer->flush();
|
if ( !writer->flush(flushTimeout)) break;
|
||||||
size_t rt = writer->sendToClients(logBuffer + handled, -1, true);
|
size_t rt = writer->sendToClients(logBuffer + handled, -1, true);
|
||||||
handled += rt;
|
handled += rt;
|
||||||
}
|
}
|
||||||
|
if (handled < wp){
|
||||||
|
if (handled > 0){
|
||||||
|
memmove(logBuffer,logBuffer+handled,wp-handled);
|
||||||
|
wp-=handled;
|
||||||
|
logBuffer[handled]=0;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
wp = 0;
|
wp = 0;
|
||||||
logBuffer[0] = 0;
|
logBuffer[0] = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class SerialWrapper : public GwChannelList::SerialWrapperBase{
|
||||||
|
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
|
||||||
|
T *serial;
|
||||||
|
int id;
|
||||||
|
public:
|
||||||
|
SerialWrapper(T* s,int i):serial(s),id(i){}
|
||||||
|
virtual void begin(GwLog* logger,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);
|
||||||
|
};
|
||||||
|
virtual Stream *getStream() override{
|
||||||
|
return serial;
|
||||||
|
}
|
||||||
|
virtual int getId() override{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
GwChannelList::GwChannelList(GwLog *logger, GwConfigHandler *config){
|
GwChannelList::GwChannelList(GwLog *logger, GwConfigHandler *config){
|
||||||
this->logger=logger;
|
this->logger=logger;
|
||||||
this->config=config;
|
this->config=config;
|
||||||
|
@ -127,16 +175,16 @@ static SerialParam *getSerialParam(int id){
|
||||||
}
|
}
|
||||||
void GwChannelList::addSerial(int id, int rx, int tx, int type){
|
void GwChannelList::addSerial(int id, int rx, int tx, int type){
|
||||||
if (id == 1){
|
if (id == 1){
|
||||||
addSerial(&Serial1,SERIAL1_CHANNEL_ID,type,rx,tx);
|
addSerial(new SerialWrapper<decltype(Serial1)>(&Serial1,SERIAL1_CHANNEL_ID),type,rx,tx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (id == 2){
|
if (id == 2){
|
||||||
addSerial(&Serial2,SERIAL2_CHANNEL_ID,type,rx,tx);
|
addSerial(new SerialWrapper<decltype(Serial2)>(&Serial2,SERIAL2_CHANNEL_ID),type,rx,tx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_DEBUG(GwLog::ERROR,"invalid serial config with id %d",id);
|
LOG_DEBUG(GwLog::ERROR,"invalid serial config with id %d",id);
|
||||||
}
|
}
|
||||||
void GwChannelList::addSerial(HardwareSerial *stream,int id,int type,int rx,int tx){
|
void GwChannelList::addSerial(GwChannelList::SerialWrapperBase *stream,int type,int rx,int tx){
|
||||||
const char *mode=nullptr;
|
const char *mode=nullptr;
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -157,9 +205,10 @@ void GwChannelList::addSerial(HardwareSerial *stream,int id,int type,int rx,int
|
||||||
LOG_DEBUG(GwLog::ERROR,"unknown serial type %d",type);
|
LOG_DEBUG(GwLog::ERROR,"unknown serial type %d",type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addSerial(stream,id,mode,rx,tx);
|
addSerial(stream,mode,rx,tx);
|
||||||
}
|
}
|
||||||
void GwChannelList::addSerial(HardwareSerial *serialStream,int id,const String &mode,int rx,int tx){
|
void GwChannelList::addSerial(GwChannelList::SerialWrapperBase *serialStream,const String &mode,int rx,int tx){
|
||||||
|
int id=serialStream->getId();
|
||||||
for (auto &&it:theChannels){
|
for (auto &&it:theChannels){
|
||||||
if (it->isOwnSource(id)){
|
if (it->isOwnSource(id)){
|
||||||
LOG_DEBUG(GwLog::ERROR,"trying to re-add serial id=%d, ignoring",id);
|
LOG_DEBUG(GwLog::ERROR,"trying to re-add serial id=%d, ignoring",id);
|
||||||
|
@ -201,8 +250,8 @@ void GwChannelList::addSerial(HardwareSerial *serialStream,int id,const String &
|
||||||
if (tx < 0) canWrite=false;
|
if (tx < 0) canWrite=false;
|
||||||
LOG_DEBUG(GwLog::DEBUG,"serial set up: mode=%s,rx=%d,canRead=%d,tx=%d,canWrite=%d",
|
LOG_DEBUG(GwLog::DEBUG,"serial set up: mode=%s,rx=%d,canRead=%d,tx=%d,canWrite=%d",
|
||||||
mode.c_str(),rx,(int)canRead,tx,(int)canWrite);
|
mode.c_str(),rx,(int)canRead,tx,(int)canWrite);
|
||||||
serialStream->begin(config->getInt(param->baud,115200),SERIAL_8N1,rx,tx);
|
serialStream->begin(logger,config->getInt(param->baud,115200),SERIAL_8N1,rx,tx);
|
||||||
GwSerial *serial = new GwSerial(logger, serialStream, id, canRead);
|
GwSerial *serial = new GwSerial(logger, serialStream->getStream(), id, canRead);
|
||||||
LOG_DEBUG(GwLog::LOG, "starting serial %d ", id);
|
LOG_DEBUG(GwLog::LOG, "starting serial %d ", id);
|
||||||
GwChannel *channel = new GwChannel(logger, param->name, id);
|
GwChannel *channel = new GwChannel(logger, param->name, id);
|
||||||
channel->setImpl(serial);
|
channel->setImpl(serial);
|
||||||
|
@ -241,6 +290,14 @@ void GwChannelList::preinit(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
template<typename S>
|
||||||
|
long getFlushTimeout(S &s){
|
||||||
|
return 200;
|
||||||
|
}
|
||||||
|
template<>
|
||||||
|
long getFlushTimeout(HardwareSerial &s){
|
||||||
|
return 2000;
|
||||||
|
}
|
||||||
void GwChannelList::begin(bool fallbackSerial){
|
void GwChannelList::begin(bool fallbackSerial){
|
||||||
LOG_DEBUG(GwLog::DEBUG,"GwChannelList::begin");
|
LOG_DEBUG(GwLog::DEBUG,"GwChannelList::begin");
|
||||||
GwChannel *channel=NULL;
|
GwChannel *channel=NULL;
|
||||||
|
@ -248,7 +305,7 @@ void GwChannelList::begin(bool fallbackSerial){
|
||||||
if (! fallbackSerial){
|
if (! fallbackSerial){
|
||||||
GwSerial *usb=new GwSerial(NULL,&USBSerial,USB_CHANNEL_ID);
|
GwSerial *usb=new GwSerial(NULL,&USBSerial,USB_CHANNEL_ID);
|
||||||
USBSerial.begin(config->getInt(config->usbBaud));
|
USBSerial.begin(config->getInt(config->usbBaud));
|
||||||
logger->setWriter(new GwSerialLog(usb,config->getBool(config->usbActisense)));
|
logger->setWriter(new GwSerialLog(usb,config->getBool(config->usbActisense),getFlushTimeout(USBSerial)));
|
||||||
logger->prefix="GWSERIAL:";
|
logger->prefix="GWSERIAL:";
|
||||||
channel=new GwChannel(logger,"USB",USB_CHANNEL_ID);
|
channel=new GwChannel(logger,"USB",USB_CHANNEL_ID);
|
||||||
channel->setImpl(usb);
|
channel->setImpl(usb);
|
||||||
|
@ -297,10 +354,12 @@ void GwChannelList::begin(bool fallbackSerial){
|
||||||
#define GWSERIAL_RX -1
|
#define GWSERIAL_RX -1
|
||||||
#endif
|
#endif
|
||||||
#ifdef GWSERIAL_TYPE
|
#ifdef GWSERIAL_TYPE
|
||||||
addSerial(&Serial1,SERIAL1_CHANNEL_ID,GWSERIAL_TYPE,GWSERIAL_RX,GWSERIAL_TX);
|
setSerialError(&Serial1,SERIAL1_CHANNEL_ID,this->logger);
|
||||||
|
addSerial(new SerialWrapper<decltype(Serial1)>(&Serial1,SERIAL1_CHANNEL_ID),GWSERIAL_TYPE,GWSERIAL_RX,GWSERIAL_TX);
|
||||||
#else
|
#else
|
||||||
#ifdef GWSERIAL_MODE
|
#ifdef GWSERIAL_MODE
|
||||||
addSerial(&Serial1,SERIAL1_CHANNEL_ID,GWSERIAL_MODE,GWSERIAL_RX,GWSERIAL_TX);
|
setSerialError(&Serial1,SERIAL1_CHANNEL_ID,this->logger);
|
||||||
|
addSerial(new SerialWrapper<decltype(Serial1)>(&Serial1,SERIAL1_CHANNEL_ID),GWSERIAL_MODE,GWSERIAL_RX,GWSERIAL_TX);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
//serial 2
|
//serial 2
|
||||||
|
@ -311,10 +370,10 @@ void GwChannelList::begin(bool fallbackSerial){
|
||||||
#define GWSERIAL2_RX -1
|
#define GWSERIAL2_RX -1
|
||||||
#endif
|
#endif
|
||||||
#ifdef GWSERIAL2_TYPE
|
#ifdef GWSERIAL2_TYPE
|
||||||
addSerial(&Serial2,SERIAL2_CHANNEL_ID,GWSERIAL2_TYPE,GWSERIAL2_RX,GWSERIAL2_TX);
|
addSerial(new SerialWrapper<decltype(Serial2)>(&Serial2,SERIAL2_CHANNEL_ID),GWSERIAL2_TYPE,GWSERIAL2_RX,GWSERIAL2_TX);
|
||||||
#else
|
#else
|
||||||
#ifdef GWSERIAL2_MODE
|
#ifdef GWSERIAL2_MODE
|
||||||
addSerial(&Serial2,SERIAL2_CHANNEL_ID,GWSERIAL2_MODE,GWSERIAL2_RX,GWSERIAL2_TX);
|
addSerial(new SerialWrapper<decltype(Serial2)>(&Serial2,SERIAL2_CHANNEL_ID),GWSERIAL2_MODE,GWSERIAL2_RX,GWSERIAL2_TX);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
//tcp client
|
//tcp client
|
||||||
|
|
|
@ -23,6 +23,12 @@ class GwSocketServer;
|
||||||
class GwTcpClient;
|
class GwTcpClient;
|
||||||
class GwChannelList{
|
class GwChannelList{
|
||||||
private:
|
private:
|
||||||
|
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 Stream *getStream()=0;
|
||||||
|
virtual int getId()=0;
|
||||||
|
};
|
||||||
GwLog *logger;
|
GwLog *logger;
|
||||||
GwConfigHandler *config;
|
GwConfigHandler *config;
|
||||||
typedef std::vector<GwChannel *> ChannelList;
|
typedef std::vector<GwChannel *> ChannelList;
|
||||||
|
@ -30,8 +36,8 @@ class GwChannelList{
|
||||||
std::map<int,String> modes;
|
std::map<int,String> modes;
|
||||||
GwSocketServer *sockets;
|
GwSocketServer *sockets;
|
||||||
GwTcpClient *client;
|
GwTcpClient *client;
|
||||||
void addSerial(HardwareSerial *stream,int id,const String &mode,int rx,int tx);
|
void addSerial(SerialWrapperBase *stream,const String &mode,int rx,int tx);
|
||||||
void addSerial(HardwareSerial *stream,int id,int type,int rx,int tx);
|
void addSerial(SerialWrapperBase *stream,int type,int rx,int tx);
|
||||||
public:
|
public:
|
||||||
void addSerial(int id, int rx, int tx, int type);
|
void addSerial(int id, int rx, int tx, int type);
|
||||||
GwChannelList(GwLog *logger, GwConfigHandler *config);
|
GwChannelList(GwLog *logger, GwConfigHandler *config);
|
||||||
|
|
|
@ -40,7 +40,7 @@ class GwSerialStream: public Stream{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
GwSerial::GwSerial(GwLog *logger, HardwareSerial *s, int id,bool allowRead):serial(s)
|
GwSerial::GwSerial(GwLog *logger, Stream *s, int id,bool allowRead):serial(s)
|
||||||
{
|
{
|
||||||
LOG_DEBUG(GwLog::DEBUG,"creating GwSerial %p id %d",this,id);
|
LOG_DEBUG(GwLog::DEBUG,"creating GwSerial %p id %d",this,id);
|
||||||
this->id=id;
|
this->id=id;
|
||||||
|
@ -54,10 +54,6 @@ GwSerial::GwSerial(GwLog *logger, HardwareSerial *s, int id,bool allowRead):seri
|
||||||
this->readBuffer=new GwBuffer(logger, GwBuffer::RX_BUFFER_SIZE,bufName+"rd");
|
this->readBuffer=new GwBuffer(logger, GwBuffer::RX_BUFFER_SIZE,bufName+"rd");
|
||||||
}
|
}
|
||||||
buffer->reset("init");
|
buffer->reset("init");
|
||||||
serial->onReceiveError([this](hardwareSerial_error_t err){
|
|
||||||
GwLog *logger=this->logger;
|
|
||||||
LOG_DEBUG(GwLog::ERROR,"serial error on id %d: %d",this->id,(int)err);
|
|
||||||
});
|
|
||||||
initialized=true;
|
initialized=true;
|
||||||
}
|
}
|
||||||
GwSerial::~GwSerial()
|
GwSerial::~GwSerial()
|
||||||
|
@ -119,11 +115,21 @@ void GwSerial::readMessages(GwMessageFetcher *writer){
|
||||||
writer->handleBuffer(readBuffer);
|
writer->handleBuffer(readBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GwSerial::flush(){
|
bool GwSerial::flush(long max){
|
||||||
if (! isInitialized()) return;
|
if (! isInitialized()) return false;
|
||||||
while (write() == GwBuffer::AGAIN){
|
if (! availableWrite) {
|
||||||
|
if ( serial->availableForWrite() < 1){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
availableWrite=true;
|
||||||
|
}
|
||||||
|
auto start=millis();
|
||||||
|
while (millis() < (start+max)){
|
||||||
|
if (write() != GwBuffer::AGAIN) return true;
|
||||||
vTaskDelay(1);
|
vTaskDelay(1);
|
||||||
}
|
}
|
||||||
|
availableWrite=(serial->availableForWrite() > 0);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
Stream * GwSerial::getStream(bool partialWrite){
|
Stream * GwSerial::getStream(bool partialWrite){
|
||||||
return new GwSerialStream(this,partialWrite);
|
return new GwSerialStream(this,partialWrite);
|
||||||
|
|
|
@ -16,17 +16,19 @@ class GwSerial : public GwChannelInterface{
|
||||||
int id=-1;
|
int id=-1;
|
||||||
int overflows=0;
|
int overflows=0;
|
||||||
size_t enqueue(const uint8_t *data, size_t len,bool partial=false);
|
size_t enqueue(const uint8_t *data, size_t len,bool partial=false);
|
||||||
HardwareSerial *serial;
|
Stream *serial;
|
||||||
|
bool availableWrite=false; //if this is false we will wait for availabkleWrite until we flush again
|
||||||
public:
|
public:
|
||||||
static const int bufferSize=200;
|
static const int bufferSize=200;
|
||||||
GwSerial(GwLog *logger,HardwareSerial *stream,int id,bool allowRead=true);
|
GwSerial(GwLog *logger,Stream *stream,int id,bool allowRead=true);
|
||||||
~GwSerial();
|
~GwSerial();
|
||||||
bool isInitialized();
|
bool isInitialized();
|
||||||
virtual size_t sendToClients(const char *buf,int sourceId,bool partial=false);
|
virtual size_t sendToClients(const char *buf,int sourceId,bool partial=false);
|
||||||
virtual void loop(bool handleRead=true,bool handleWrite=true);
|
virtual void loop(bool handleRead=true,bool handleWrite=true);
|
||||||
virtual void readMessages(GwMessageFetcher *writer);
|
virtual void readMessages(GwMessageFetcher *writer);
|
||||||
void flush();
|
bool flush(long millis=200);
|
||||||
virtual Stream *getStream(bool partialWrites);
|
virtual Stream *getStream(bool partialWrites);
|
||||||
|
bool getAvailableWrite(){return availableWrite;}
|
||||||
friend GwSerialStream;
|
friend GwSerialStream;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue