diff --git a/CMakeLists.txt b/CMakeLists.txt index da7fa2f..8d49cea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,7 @@ set(CMAKE_LINKER /usr/bin/avr-ld) # Compiler flags add_definitions(-mmcu=${MCU} -DF_CPU=${CPU_SPEED}) -add_definitions(-s -c -g -Os -Wall -std=c++11 ) +add_definitions(-s -c -g -Os -Wall -std=c++17 ) add_definitions(-fno-exceptions -ffunction-sections -fdata-sections) # Linker flags diff --git a/WirelessRelay.cpp b/WirelessRelay.cpp index f8aaaf8..8f83c10 100644 --- a/WirelessRelay.cpp +++ b/WirelessRelay.cpp @@ -1,6 +1,6 @@ #include"WirelessRelay.h" #include -#include "eeprom.h" +#include volatile unsigned char *_port = &PORTB; unsigned char _pin = PB5; @@ -88,15 +88,25 @@ bool WirelessRelay::getExpectedState() return _state; } - -void WirelessRelay::init( const uint16_t id) +char* WirelessRelay::getName() { + return _name; +} + +void WirelessRelay::setName(char name[]) +{ + memcpy(_name, name, strlen(name)+1); +} + +void WirelessRelay::init( const uint16_t id, char nameIn[]) +{ + setName(nameIn); _id=id; } -WirelessRelay::WirelessRelay(const uint16_t id) +WirelessRelay::WirelessRelay(const uint16_t id, char nameIn[]) { - init(id); + init(id, nameIn); } WirelessRelay::WirelessRelay(){} diff --git a/WirelessRelay.h b/WirelessRelay.h index a669959..9b9a611 100644 --- a/WirelessRelay.h +++ b/WirelessRelay.h @@ -11,25 +11,26 @@ class WirelessRelay { public: - static const MAX_NAME_LENGTH = 32; - - char name[MAX_NAME_LENGTH]; + static const uint16_t MAX_NAME_LENGTH = 32; private: bool _state = false; uint16_t _nameAddr; uint16_t _id; + char _name[MAX_NAME_LENGTH]; void sendBit( const bool i); void sync(); void sendId(); public: - WirelessRelay(const uint16_t id, uint16_t nameAddr, char* nameIn = ""); + WirelessRelay(const uint16_t id, char nameIn[]); WirelessRelay(); void setTimeout(uint64_t timeout); - void init(const uint16_t id, uint16_t nameAddr, char* nameIn = ""); + void init(const uint16_t id, char nameIn[]); void on(); void off(); + char* getName(); + void setName(char* name); uint16_t getId(); bool getExpectedState(); }; diff --git a/eeprom.h b/eeprom.h index 114426b..88e476d 100644 --- a/eeprom.h +++ b/eeprom.h @@ -33,9 +33,9 @@ void EEPROM_read_string(uint16_t address, char* buffer, uint16_t length) for(uint16_t i = 0; i < length; i++) buffer[i] = EEPROM_read_char( address+i); } -template void EEPROM_write_class(uint16_t address, const T& in) +template void EEPROM_write_class(uint16_t address, T& in) { - EEPROM_write_string( address, reinterpret_cast &in, sizeof(in)); + EEPROM_write_string( address, reinterpret_cast(&in), sizeof(in)); } template T EEPROM_read_class(uint16_t address) @@ -45,7 +45,7 @@ template T EEPROM_read_class(uint16_t address) return *reinterpret_cast(data); } -template T EEPROM_read_class(uint16_t address, T* in) +template void EEPROM_read_class(uint16_t address, T* in) { - EEPROM_read_string( address, reinterpret_cast &in, sizeof(T) ); + EEPROM_read_string( address, reinterpret_cast(&in), sizeof(T) ); } diff --git a/main.cpp b/main.cpp index 0da1d1a..4969e94 100644 --- a/main.cpp +++ b/main.cpp @@ -9,34 +9,17 @@ #include "rgbled.h" #include "eeprom.h" #include "bitrep.h" +#include "staticvector.h" #define COMMAND_BUFFER_SIZE 32 #define SNPRINTF_BUFFER_SIZE 64 +#define MAX_RELAYS 16 +#define RELAY_VECTOR_EEPROM_ADDR 32 + char buffer[SNPRINTF_BUFFER_SIZE]; -class WirelessRelayStore -{ -public: - static const MAX_RELAYS = 16; - -private: - - WirelessRelay array[MAX_RELAYS]; - uint8_t count; - bool states[MAX_RELAYS]={}; - bool printState = true; - uint16_t baseNameAddr_; - -public: - - WirelessRelayStore(uint16_t baseNameAddr = 0) - bool add( uint16_t id, char* name ); - bool remove(); - WirelessRelay* getRelay(uint8_t id); -}; - -WirelessRelayStore relays; +SVector relays; inline static void printHelp(Serial* serial) { @@ -60,58 +43,72 @@ inline static void printHelp(Serial* serial) aux set [VAL] : Set PWM value, pattern must be 0.\n")); } -void writeState( WirelessRelayStore* relays, Pwm16b* auxPwm, Serial* serial ) +void save() +{ + EEPROM_write_class< SVector > (RELAY_VECTOR_EEPROM_ADDR, relays); +} + +void load() +{ + EEPROM_read_class< SVector > (RELAY_VECTOR_EEPROM_ADDR, &relays); +} + +void writeState( SVector* relays, Pwm16b* auxPwm, Serial* serial ) { serial->write("ST"); serial->write(auxPwm->isOn() ? auxPwm->getValueA() >> 8 : 0); serial->putChar(','); - serial->write(relays->count); - for(uint8_t i = 0; i < relays->count; i++) + serial->write(relays->count()); + for(uint8_t i = 0; i < relays->count(); i++) { serial->putChar(','); - relays->array[i].getExpectedState() ? serial->putChar('1') : serial->putChar('0'); + relays->at(i).getExpectedState() ? serial->putChar('1') : serial->putChar('0'); } serial->putChar('\n'); } -void relayDispatch(WirelessRelayStore* relays, Pwm16b* auxPwm, char* token, Serial* serial) +void relayDispatch(SVector* relays, Pwm16b* auxPwm, char* token, Serial* serial) { if( strcmp(token, "add") == 0 ) { - char* token = strtok(NULL, " \n"); + token = strtok(NULL, " \n"); uint16_t id = strtol(token, nullptr, 2 ); - if(id != 0 && relays->count < MAX_RELAYS) + if(id != 0 && relays->remainingCapacity() > 0) { - relays->array[relays->count].init(id); - - EEPROM_write_char( 0, relays->count+1 ); - EEPROM_write_string( relays->count*2+1, (char*) &id, 2 ); - - uint8_t size = snprintf(buffer, SNPRINTF_BUFFER_SIZE, "Relay saved! NUMBER: %u ID: %X \n", relays->count, id); - serial->write(buffer, size); - - relays->count++; + token = strtok(NULL, " \n"); + if( token == NULL ) + { + char name[] = ""; + WirelessRelay relay(id, name); + relays->push_back(relay); + } + else + { + WirelessRelay relay(id, token); + relays->push_back(relay); + } + save(); } - else serial->write_p(PSTR("Usage: relay add [id] [id] being a 16bit binary nummber\n")); + else if(relays->remainingCapacity() == 0) serial->write_p(PSTR("Relay storage full.\n")); + else serial->write_p(PSTR("Usage: relay add [id] [name]\n [id] being a 16bit binary nummber and [name] an optional string\n")); } else if( strcmp(token, "delete") == 0 ) { - serial->write_p(PSTR("Relay: ")); - serial->write(relays->count); - serial->write_p(PSTR(" deleted\n")); - relays->count--; + relays->erase(relays->count()); + save(); } else if( strcmp(token, "list") == 0 ) { serial->write_p(PSTR("Relays:\n")); - for(uint8_t i = 0; i < relays->count; i++) + for(uint8_t i = 0; i < relays->count(); i++) { - uint16_t id = relays->array[i].getId(); - snprintf(buffer, SNPRINTF_BUFFER_SIZE, "NUMBER: %u ID: %s%s%s%s\n", i, + uint16_t id = relays->at(i).getId(); + snprintf(buffer, SNPRINTF_BUFFER_SIZE, "NUMBER: %u ID: %s%s%s%s NAME: %s\n", i, bit_rep[ id >> 12], bit_rep[(id & 0x0F00) >> 8 ], bit_rep[(id & 0x00F0) >> 4 ], - bit_rep[ id & 0x000F ]); + bit_rep[ id & 0x000F ], + relays->at(i).getName()); serial->write(buffer, SNPRINTF_BUFFER_SIZE); } serial->putChar('\n'); @@ -122,13 +119,13 @@ void relayDispatch(WirelessRelayStore* relays, Pwm16b* auxPwm, char* token, Ser if( token != NULL) { uint8_t selected = atoi(token); - if (selected <= relays->count) + if (selected <= relays->count()) { - relays->array[selected].on(); + relays->at(selected).on(); snprintf(buffer, SNPRINTF_BUFFER_SIZE, "RELAY: %u turned on\n", selected); serial->write(buffer, SNPRINTF_BUFFER_SIZE); - if(relays->printState) writeState(relays, auxPwm, serial); + writeState(relays, auxPwm, serial); } else serial->write("No sutch Relay\n"); } @@ -139,39 +136,21 @@ void relayDispatch(WirelessRelayStore* relays, Pwm16b* auxPwm, char* token, Ser if( token != NULL) { uint8_t selected = atoi(token); - if (selected <= relays->count) + if (selected <= relays->count()) { - relays->array[selected].off(); + relays->at(selected).off(); snprintf(buffer, SNPRINTF_BUFFER_SIZE, "RELAY: %u turned off\n", selected); serial->write(buffer, SNPRINTF_BUFFER_SIZE); - if(relays->printState) writeState(relays, auxPwm, serial); + writeState(relays, auxPwm, serial); } else serial->write("No sutch Relay\n"); } } - else if( strcmp(token, "machine") == 0 ) - { - char* token = strtok(NULL, " \n"); - if( token != NULL) - { - if( strcmp(token, "on") == 0 ) - { - relays->printState = true; - serial->write_p(PSTR("Turned on State printing\n")); - } - else - { - relays->printState = false; - serial->write("Turned off State printing\n"); - } - } - else serial->write_p(PSTR("Usage: relay machine [on/off]\n")); - } else { serial->write(token); - serial->write_p(PSTR(" is not a valid subcommand: relay [add/delete/list/on/off/state/machine]\n")); + serial->write_p(PSTR(" is not a valid subcommand: relay [add/delete/list/on/off]\n")); } } @@ -278,7 +257,7 @@ void auxDispatch(Pwm16b* auxPwm, char* token, Serial* serial) } } -void serialDispatch(Serial* serial , WirelessRelayStore* relays, RgbLed* rgbled, Pwm16b* auxPwm) +void serialDispatch(Serial* serial, SVector* relays, RgbLed* rgbled, Pwm16b* auxPwm) { if(serial->dataIsWaiting()) @@ -299,7 +278,7 @@ void serialDispatch(Serial* serial , WirelessRelayStore* relays, RgbLed* rgbled, else if(strcmp(token, "aux") == 0) { auxDispatch(auxPwm, strtok(NULL, " \n"), serial); - if(relays->printState == true) writeState(relays, auxPwm, serial); + writeState(relays, auxPwm, serial); } else if(strcmp(token, "state") == 0) { @@ -309,7 +288,7 @@ void serialDispatch(Serial* serial , WirelessRelayStore* relays, RgbLed* rgbled, { for(uint16_t i = 0; i < MAX_RELAYS*2+1; i++) EEPROM_write_char(i, 0); serial->write_p(PSTR("EEPROM erased\n")); - relays->count = 0; + load(); } else if(strcmp(token, "help") == 0) { @@ -323,22 +302,6 @@ void serialDispatch(Serial* serial , WirelessRelayStore* relays, RgbLed* rgbled, } } -void restore_relays(WirelessRelayStore* relays) -{ - relays->count = EEPROM_read_char(0); - if(relays->count > MAX_RELAYS ) - { - for(uint16_t i = 0; i < MAX_RELAYS*2+1; i++) EEPROM_write_char(i, 0); - relays->count = 0; - } - for(uint8_t i = 0; i <= relays->count; i++) - { - uint16_t id; - EEPROM_read_string(1+i*2, (char*) &id, 2); - relays->array[i].init(id); - } -} - int main() { @@ -365,9 +328,7 @@ int main() Pwm16b pwmTc1 ( &TCCR1A, &TCCR1B, &OCR1A, &OCR1B, &ICR1, 0b00000001, true, false); - relays.count=0; - - restore_relays(&relays); + load(); serial.write_p(PSTR("RGBController v0.7 starting\n")); while(true) diff --git a/staticvector.h b/staticvector.h index 592497f..2864e1f 100644 --- a/staticvector.h +++ b/staticvector.h @@ -1,6 +1,7 @@ #pragma once +#include -template class SVector; +template class SVector { private: size_t stored = 0; @@ -34,31 +35,32 @@ public: return array[stored]; } - bool empty() + bool empty() const { return stored == 0 ? true : false; } - size_t size(); + size_t count() const { return stored; } - constexpr size_t maxSize() + constexpr size_t maxSize() const { - return std::array::size(); + return size; } - size_t remainingCapacity() + size_t remainingCapacity() const { - return std::array::size() - stored; + return size - stored; } bool push_back(const T in) { if( remainingCapacity() != 0) { - std::array::operator[](stored) = in; + array[stored] = in; + ++stored; return true; } else return false; @@ -67,9 +69,14 @@ public: bool erase(size_t position) { if(position > stored) return false; - if constexpr( std::is_class ) array[position].~T(); + array[position].~T(); --stored; - for( size_t i = position; i < stored ) array[i] = array[i+1]; + for( size_t i = position; i < stored; i++ ) array[i] = array[i+1]; return true; } -} + + void clear() + { + stored = 0; + } +};