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); | ||||
| } | ||||
| String GwChannel::toString(){ | ||||
|     String rt="CH:"+name; | ||||
|     String rt="CH"+name+"("+sourceId+"):"; | ||||
|     rt+=enabled?"[ena]":"[dis]"; | ||||
|     rt+=NMEAin?"in,":""; | ||||
|     rt+=NMEAout?"out,":""; | ||||
|  |  | |||
|  | @ -35,12 +35,13 @@ class GwSerialLog : public GwLogWriter | |||
|     int wp = 0; | ||||
|     GwSerial *writer; | ||||
|     bool disabled = false; | ||||
| 
 | ||||
|     long flushTimeout=200; | ||||
| public: | ||||
|     GwSerialLog(GwSerial *writer, bool disabled) | ||||
|     GwSerialLog(GwSerial *writer, bool disabled,long flushTimeout=200) | ||||
|     { | ||||
|         this->writer = writer; | ||||
|         this->disabled = disabled; | ||||
|         this->flushTimeout=flushTimeout; | ||||
|         logBuffer = new char[bufferSize]; | ||||
|         wp = 0; | ||||
|     } | ||||
|  | @ -63,16 +64,63 @@ public: | |||
|         { | ||||
|             while (handled < wp) | ||||
|             { | ||||
|                 writer->flush(); | ||||
|                 if ( !writer->flush(flushTimeout)) break; | ||||
|                 size_t rt = writer->sendToClients(logBuffer + handled, -1, true); | ||||
|                 handled += rt; | ||||
|             } | ||||
|             if (handled < wp){ | ||||
|                 if (handled > 0){ | ||||
|                     memmove(logBuffer,logBuffer+handled,wp-handled); | ||||
|                     wp-=handled; | ||||
|                     logBuffer[handled]=0; | ||||
|                 } | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|         wp = 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){ | ||||
|     this->logger=logger; | ||||
|     this->config=config; | ||||
|  | @ -127,16 +175,16 @@ static SerialParam *getSerialParam(int id){ | |||
| } | ||||
| void GwChannelList::addSerial(int id, int rx, int tx, int type){ | ||||
|     if (id == 1){ | ||||
|         addSerial(&Serial1,SERIAL1_CHANNEL_ID,type,rx,tx); | ||||
|         addSerial(new SerialWrapper<decltype(Serial1)>(&Serial1,SERIAL1_CHANNEL_ID),type,rx,tx); | ||||
|         return;    | ||||
|     } | ||||
|     if (id == 2){ | ||||
|         addSerial(&Serial2,SERIAL2_CHANNEL_ID,type,rx,tx); | ||||
|         addSerial(new SerialWrapper<decltype(Serial2)>(&Serial2,SERIAL2_CHANNEL_ID),type,rx,tx); | ||||
|         return;    | ||||
|     } | ||||
|     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; | ||||
|     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); | ||||
|         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){ | ||||
|         if (it->isOwnSource(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; | ||||
|     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); | ||||
|     serialStream->begin(config->getInt(param->baud,115200),SERIAL_8N1,rx,tx); | ||||
|     GwSerial *serial = new GwSerial(logger, serialStream, id, canRead); | ||||
|     serialStream->begin(logger,config->getInt(param->baud,115200),SERIAL_8N1,rx,tx); | ||||
|     GwSerial *serial = new GwSerial(logger, serialStream->getStream(), id, canRead); | ||||
|     LOG_DEBUG(GwLog::LOG, "starting serial %d ", id); | ||||
|     GwChannel *channel = new GwChannel(logger, param->name, id); | ||||
|     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){ | ||||
|     LOG_DEBUG(GwLog::DEBUG,"GwChannelList::begin"); | ||||
|     GwChannel *channel=NULL; | ||||
|  | @ -248,7 +305,7 @@ void GwChannelList::begin(bool fallbackSerial){ | |||
|     if (! fallbackSerial){ | ||||
|         GwSerial *usb=new GwSerial(NULL,&USBSerial,USB_CHANNEL_ID); | ||||
|         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:"; | ||||
|         channel=new GwChannel(logger,"USB",USB_CHANNEL_ID); | ||||
|         channel->setImpl(usb); | ||||
|  | @ -297,10 +354,12 @@ void GwChannelList::begin(bool fallbackSerial){ | |||
|       #define GWSERIAL_RX -1 | ||||
|     #endif | ||||
|     #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 | ||||
|         #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 | ||||
|     //serial 2
 | ||||
|  | @ -311,10 +370,10 @@ void GwChannelList::begin(bool fallbackSerial){ | |||
|       #define GWSERIAL2_RX -1 | ||||
|     #endif | ||||
|     #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 | ||||
|         #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 | ||||
|     //tcp client
 | ||||
|  |  | |||
|  | @ -23,6 +23,12 @@ class GwSocketServer; | |||
| class GwTcpClient; | ||||
| class GwChannelList{ | ||||
|     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; | ||||
|         GwConfigHandler *config; | ||||
|         typedef std::vector<GwChannel *> ChannelList; | ||||
|  | @ -30,8 +36,8 @@ class GwChannelList{ | |||
|         std::map<int,String> modes; | ||||
|         GwSocketServer *sockets; | ||||
|         GwTcpClient *client; | ||||
|         void addSerial(HardwareSerial *stream,int id,const String &mode,int rx,int tx); | ||||
|         void addSerial(HardwareSerial *stream,int id,int type,int rx,int tx); | ||||
|         void addSerial(SerialWrapperBase *stream,const String &mode,int rx,int tx); | ||||
|         void addSerial(SerialWrapperBase *stream,int type,int rx,int tx); | ||||
|     public: | ||||
|         void addSerial(int id, int rx, int tx, int type); | ||||
|         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); | ||||
|     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"); | ||||
|     } | ||||
|     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; | ||||
| } | ||||
| GwSerial::~GwSerial() | ||||
|  | @ -119,11 +115,21 @@ void GwSerial::readMessages(GwMessageFetcher *writer){ | |||
|     writer->handleBuffer(readBuffer); | ||||
| } | ||||
| 
 | ||||
| void GwSerial::flush(){ | ||||
|    if (! isInitialized()) return;  | ||||
|    while (write() == GwBuffer::AGAIN){ | ||||
| bool GwSerial::flush(long max){ | ||||
|    if (! isInitialized()) return false; | ||||
|    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); | ||||
|    } | ||||
|    availableWrite=(serial->availableForWrite() > 0); | ||||
|    return false; | ||||
| } | ||||
| Stream * GwSerial::getStream(bool partialWrite){ | ||||
|     return new GwSerialStream(this,partialWrite); | ||||
|  |  | |||
|  | @ -16,17 +16,19 @@ class GwSerial : public GwChannelInterface{ | |||
|         int id=-1; | ||||
|         int overflows=0; | ||||
|         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: | ||||
|         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(); | ||||
|         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); | ||||
|         void flush(); | ||||
|         bool flush(long millis=200); | ||||
|         virtual Stream *getStream(bool partialWrites); | ||||
|         bool getAvailableWrite(){return availableWrite;} | ||||
|     friend GwSerialStream; | ||||
| }; | ||||
| #endif | ||||
		Loading…
	
		Reference in New Issue
	
	 andreas
						andreas