From 6a02c2f8cdc596a218952d79fea13625863bda9d Mon Sep 17 00:00:00 2001 From: uvos Date: Thu, 13 Jan 2022 13:59:08 +0100 Subject: [PATCH] improve it --- main.cpp | 15 ++-- ringbuffer.h | 223 +++++++++++++++++++++++++++------------------------ train.cpp | 53 +++++++++++- train.h | 8 +- 4 files changed, 181 insertions(+), 118 deletions(-) diff --git a/main.cpp b/main.cpp index 319041b..7ed6f78 100644 --- a/main.cpp +++ b/main.cpp @@ -8,6 +8,7 @@ #include "train.h" #include "eeprom.h" #include "bitrep.h" +#include "ringbuffer.h" #define MAX_TRAINS 16 #define COMMAND_BUFFER_SIZE 64 @@ -126,7 +127,7 @@ void trainDispatch(char* inBuffer, Serial* serial) serial->write_p(PSTR("Trains:\n")); for(uint8_t i = 0; i < storedTrains; i++) { - snprintf(buffer, SNPRINTF_BUFFER_SIZE, "NUMBER: %u ID: %s%s CURRENT PACKET: %x", i, bit_rep[trains[i].getAddress() >> 4], bit_rep[trains[i].getAddress() & 0x0F], trains[i].getLastPacket()); + snprintf(buffer, SNPRINTF_BUFFER_SIZE, "NUMBER: %u ID: %s%s CURRENT PACKET: %x SPEED: %u", i, bit_rep[trains[i].getAddress() >> 4], bit_rep[trains[i].getAddress() & 0x0F], trains[i].getLastPacket(), trains[i].getSpeed()); serial->write(buffer, SNPRINTF_BUFFER_SIZE); serial->write_p(PSTR(" PROTOCOL: ")); if(trains[i].getProtocol() == Train::M_DELTA)serial->write_p(PSTR("delta\n")); @@ -258,7 +259,7 @@ void serialDispatch(Serial* serial) { char buffer[COMMAND_BUFFER_SIZE]; unsigned int length = serial->getString(buffer, COMMAND_BUFFER_SIZE); - if(length > 2) + if(length > 0) { serial->write_p(PSTR("Got: ")); serial->putChar('\"'); @@ -271,13 +272,13 @@ void serialDispatch(Serial* serial) if(token != NULL) trainDispatch(token, serial); } - else if(length > 4 && strncmp(token, "erase", 4) == 0) + else if(strncmp(token, "erase", 4) == 0) { for(uint16_t i = 0; i < EPPROM_SIZE; i++) EEPROM_write_char(i, 0); serial->write_p(PSTR("EEPROM erased\n")); storedTrains = 0; } - else if(length > 3 && strcmp(token, "dump") == 0) + else if(strcmp(token, "dump") == 0) { for(uint16_t i = 0; i < EPPROM_SIZE; i++) { @@ -286,7 +287,7 @@ void serialDispatch(Serial* serial) } serial->putChar('\n'); } - else if(length > 3 && (strcmp(token, "stop") == 0 || strcmp(token, "s") == 0 )) + else if((strcmp(token, "stop") == 0 || strcmp(token, "s") == 0 )) { for(uint16_t i = 0; i < storedTrains; i++) { @@ -295,12 +296,12 @@ void serialDispatch(Serial* serial) sei(); } } - else if(length > 3 && strcmp(token, "power") == 0) + else if(strcmp(token, "power") == 0) { token = strtok(NULL, " "); if(token != NULL)powerDispatch(token, serial); } - else if(length > 3 && strcmp(token, "help") == 0) + else if(strcmp(token, "help") == 0) { printHelp(serial); } diff --git a/ringbuffer.h b/ringbuffer.h index 2796310..02dde2b 100755 --- a/ringbuffer.h +++ b/ringbuffer.h @@ -1,18 +1,18 @@ /*UVOS*/ -/* This file is part of TelemetrySystem. - * - * TelemetrySystem is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License (LGPL) version 3 as published by - * the Free Software Foundation. - * - * TelemetrySystem 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with TelemetrySystem. If not, see . +/* This file is part of UsbLedController. +* +* UsbLedController is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License (LGPL) version 3 as published by +* the Free Software Foundation. +* +* UsbLedController 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 General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with UsbLedController. If not, see . */ #pragma once @@ -22,104 +22,115 @@ template < int BUFFER_SIZE, typename T = uint8_t > class RingBuffer { private: - - volatile uint_fast16_t _headIndex = 0; - volatile uint_fast16_t _tailIndex = 0; + + volatile uint_fast16_t _headIndex = 0; + volatile uint_fast16_t _tailIndex = 0; volatile bool _overrun = false; - volatile T _buffer[BUFFER_SIZE]; - + volatile T _buffer[BUFFER_SIZE]; + public: - - RingBuffer() - { - flush(); - } - - uint_fast16_t remaining() const volatile - { - return (_headIndex-_tailIndex); - } - - uint_fast16_t remainingCapacity() const volatile - { - return BUFFER_SIZE - (_headIndex-_tailIndex); - } - - bool isOverun() volatile - { - bool returnVal = _overrun; - _overrun = false; - return returnVal; - } - - bool isEmpty() const volatile - { - return _tailIndex >= _headIndex; - } - - T read() volatile - { - if(!isEmpty()) - { - _tailIndex++; - return _buffer[(_tailIndex - 1) % BUFFER_SIZE]; - } - else return '\0'; - } - - unsigned int read( T* buffer, unsigned int length ) volatile - { - unsigned int i = 0; - for(; i < length && !isEmpty(); i++) - { - buffer[i] = read(); - } - return i; - } - - void write( T in ) volatile - { - if (_headIndex - BUFFER_SIZE > 0 && _tailIndex - BUFFER_SIZE > 0) - { - _headIndex -= BUFFER_SIZE; - _tailIndex -= BUFFER_SIZE; - } - _buffer[_headIndex % BUFFER_SIZE] = in; - _headIndex++; + + RingBuffer() + { + flush(); + } + + uint_fast16_t remaining() const volatile + { + return (_headIndex-_tailIndex); + } + + uint_fast16_t remainingCapacity() const volatile + { + return BUFFER_SIZE - (_headIndex-_tailIndex); + } + + unsigned capacity() const volatile + { + return BUFFER_SIZE; + } + + bool isOverun() volatile + { + bool returnVal = _overrun; + return returnVal; + } + + bool isEmpty() const volatile + { + return _tailIndex >= _headIndex; + } + + const T operator[](uint_fast16_t idx) const volatile + { + return _buffer[idx]; + } + + T read() volatile + { + _overrun = false; + if(!isEmpty()) + { + _tailIndex++; + return _buffer[(_tailIndex - 1) % BUFFER_SIZE]; + } + else return '\0'; + } + + unsigned int read( T* buffer, unsigned int length ) volatile + { + unsigned int i = 0; + for(; i < length && !isEmpty(); i++) + { + buffer[i] = read(); + } + return i; + } + + void write( T in ) volatile + { + if ((int)_headIndex - BUFFER_SIZE > 0 && (int)_tailIndex - BUFFER_SIZE > 0) + { + _headIndex -= BUFFER_SIZE; + _tailIndex -= BUFFER_SIZE; + } + _buffer[_headIndex % BUFFER_SIZE] = in; + _headIndex++; if(remaining() > BUFFER_SIZE) { _overrun = true; _tailIndex = _headIndex - BUFFER_SIZE; } - } - - void write( T* buffer, const unsigned int length ) volatile - { - for(unsigned int i = 0; i < length; i++) write(buffer[i]); - } - - void flush(T flushCharacter = ' ') volatile - { - _headIndex = 0; - _tailIndex = 0; - for(int i = 0; i < BUFFER_SIZE; i++) _buffer[i] = flushCharacter; - } - - unsigned int getString(T terminator, T* buffer, const unsigned int bufferLength) volatile - { - unsigned int i = 0; - for(; i <= remaining() && i <= BUFFER_SIZE && _buffer[(_tailIndex+i) % BUFFER_SIZE] != terminator; i++); - - if( i < remaining() && i > 0) - { - if(i > bufferLength-1) i = bufferLength-1; - read(buffer, i); - buffer[i]='\0'; - _tailIndex++; - } - else if(i == 0) _tailIndex++; - else i = 0; - - return i; - } + } + + void write( T* buffer, const unsigned int length ) volatile + { + for(unsigned int i = 0; i < length; i++) write(buffer[i]); + } + + void flush(T flushCharacter = ' ') volatile + { + _headIndex = 0; + _tailIndex = 0; + for(int i = 0; i < BUFFER_SIZE; i++) _buffer[i] = flushCharacter; + _overrun = false; + } + + unsigned int getString(T terminator, T* buffer, const unsigned int bufferLength) volatile + { + unsigned int i = 0; + for(; i <= remaining() && i <= BUFFER_SIZE && _buffer[(_tailIndex+i) % BUFFER_SIZE] != terminator; i++); + + if( i < remaining() && i > 0) + { + if(i > bufferLength-1) i = bufferLength-1; + read(buffer, i); + buffer[i]='\0'; + _tailIndex++; + } + else if(i == 0) _tailIndex++; + else i = 0; + + return i; + } }; diff --git a/train.cpp b/train.cpp index e5c61a7..0bec4e1 100644 --- a/train.cpp +++ b/train.cpp @@ -114,9 +114,26 @@ void Train::setSpeed(uint8_t speed) resendData(); } +uint8_t Train::getSpeed() +{ + uint8_t speed = 0; + for(uint8_t i = 0; i < 4; i++) + speed |= ((bool)(lastDataPacket & (1 << (i+1)*2))) << i; + return speed; +} + void Train::resendData() { sendRaw(lastDataPacket); + if(functionTimer > 0) + { + --functionTimer; + } + else if(functionTimer == 0) + { + functionClear(); + --functionTimer; + } } uint16_t Train::getLastPacket() @@ -126,20 +143,48 @@ uint16_t Train::getLastPacket() void Train::reverse() { + functionClear(); + resendData(); + resendData(); + if(getSpeed() > 0) + { + setSpeed(0); + resendData(); + resendData(); + _delay_ms(2000); + } sendRaw(0b000001100); sendRaw(0b000001100); } +void Train::functionClear() +{ + lastDataPacket = lastDataPacket & ~(0b10101010); +} + void Train::sendFunction(const uint8_t function, bool enable) { - if(function == 0) lastDataPacket = (lastDataPacket & ~0b00000011) | (enable ? 0b00000011 : 0b00000000); + if(function == 0) + { + lastDataPacket = (lastDataPacket & ~0b00000001) | (enable ? 0b00000001 : 0b00000000); + //lastDataPacket = (lastDataPacket & ~0b1100000000) | (enable ? 0b1100000000 : 0); + } else if(_protocol == M_DIGITAL && function <= 3) { - lastDataPacket = lastDataPacket | 0b1000000000; - if(enable) lastDataPacket = lastDataPacket | (1 << (9-function*2)); - else lastDataPacket = lastDataPacket & ~(1 << (9-function*2)); + if(enable) + lastDataPacket |= 0b1000000000; + else + lastDataPacket &= ~0b1000000000; + for(uint8_t i = 0; i < 4; ++i ) + { + if(function > i) + lastDataPacket = lastDataPacket | (1 << (7-i*2)); + else + lastDataPacket = lastDataPacket & ~(1 << (7-i*2)); + } } resendData(); + functionTimer = 10; } void Train::setProtocol(const uint8_t protocol) diff --git a/train.h b/train.h index 6e7b6f3..50b463c 100644 --- a/train.h +++ b/train.h @@ -17,6 +17,8 @@ public: private: uint8_t _address; + uint8_t _function = 0; + uint8_t _speed = 0; static const unsigned char _pinHighA = PD5; static const unsigned char _pinLowA = PD4; @@ -28,10 +30,12 @@ private: uint8_t _protocol = M_DIGITAL; uint16_t lastDataPacket = 0; - + int8_t functionTimer = -1; + inline static void off(); void sendBit(const bool bit); void sendAddress(); + void functionClear(); public: @@ -56,6 +60,8 @@ public: void setSpeed(uint8_t speed); + uint8_t getSpeed(); + void setProtocol(const uint8_t protocol); void setAddress(const uint8_t address);