Split train class into item and train
Use SVector to store trains
This commit is contained in:
@ -17,9 +17,7 @@ set(PORT_SPEED "57600" CACHE STRING "Serial Port Speed")
|
|||||||
set(PROGRAMMER "stk500v1" CACHE STRING "Programmer Type")
|
set(PROGRAMMER "stk500v1" CACHE STRING "Programmer Type")
|
||||||
set(COMPILE_FLAGS "" CACHE STRING "Additional Compiler Flags")
|
set(COMPILE_FLAGS "" CACHE STRING "Additional Compiler Flags")
|
||||||
|
|
||||||
# Set own source files
|
set(SRC_FILES main.cpp serial.cpp train.cpp item.cpp)
|
||||||
# Simply list all your C / C++ source (not header!) files here
|
|
||||||
set(SRC_FILES main.cpp serial.cpp train.cpp)
|
|
||||||
|
|
||||||
# Compiler suite specification
|
# Compiler suite specification
|
||||||
set(CMAKE_C_COMPILER /usr/bin/avr-gcc)
|
set(CMAKE_C_COMPILER /usr/bin/avr-gcc)
|
||||||
|
93
item.cpp
Normal file
93
item.cpp
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#include "item.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static volatile unsigned char *_port = &PORTD;
|
||||||
|
|
||||||
|
Item::Item(const uint8_t address): _address(address)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item::setAddress(const uint8_t address)
|
||||||
|
{
|
||||||
|
_address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Item::getAddress()
|
||||||
|
{
|
||||||
|
return _address;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item::off()
|
||||||
|
{
|
||||||
|
writePin(_port, _pinHighA, false);
|
||||||
|
writePin(_port, _pinHighB, false);
|
||||||
|
writePin(_port, _pinLowA, true);
|
||||||
|
writePin(_port, _pinLowB, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item::setOutput(const uint8_t state)
|
||||||
|
{
|
||||||
|
if(state == HIGH)
|
||||||
|
{
|
||||||
|
off();
|
||||||
|
_delay_us(3);
|
||||||
|
writePin(_port, _pinHighA, true);
|
||||||
|
writePin(_port, _pinLowB, false);
|
||||||
|
}
|
||||||
|
else if (state == LOW)
|
||||||
|
{
|
||||||
|
off();
|
||||||
|
_delay_us(3);
|
||||||
|
writePin(_port, _pinHighB, true);
|
||||||
|
writePin(_port, _pinLowA, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item::sendBit(const bool bit)
|
||||||
|
{
|
||||||
|
if(bit)
|
||||||
|
{
|
||||||
|
setOutput(HIGH);
|
||||||
|
_delay_us(170);
|
||||||
|
setOutput(LOW);
|
||||||
|
_delay_us(25);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setOutput(HIGH);
|
||||||
|
_delay_us(20);
|
||||||
|
setOutput(LOW);
|
||||||
|
_delay_us(175);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item::sendAddress(uint8_t address)
|
||||||
|
{
|
||||||
|
for(uint8_t i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
|
sendBit(address & (1 << i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Item::sendRawAddr(const uint16_t address, const uint16_t data)
|
||||||
|
{
|
||||||
|
for(uint8_t j = 0; j < SEND_COUNT; j++)
|
||||||
|
{
|
||||||
|
sendAddress(address);
|
||||||
|
for(uint8_t i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
sendBit(data & (1 << i));
|
||||||
|
}
|
||||||
|
_delay_ms(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Item::sendRaw(const uint16_t data)
|
||||||
|
{
|
||||||
|
sendRawAddr(_address, data);
|
||||||
|
}
|
46
item.h
Normal file
46
item.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include "writepin.h"
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
|
class Item
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
static constexpr uint8_t HIGH = 2;
|
||||||
|
static constexpr uint8_t LOW = 1;
|
||||||
|
static constexpr uint8_t OFF = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
static constexpr unsigned char _pinHighA = PD5;
|
||||||
|
static constexpr unsigned char _pinLowA = PD4;
|
||||||
|
static constexpr unsigned char _pinHighB = PD2;
|
||||||
|
static constexpr unsigned char _pinLowB = PD3;
|
||||||
|
static constexpr uint8_t SEND_COUNT = 2;
|
||||||
|
|
||||||
|
uint8_t _address;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
inline static void off();
|
||||||
|
static void sendBit(const bool bit);
|
||||||
|
static void sendAddress(uint8_t address);
|
||||||
|
uint16_t packetAddSpeed();
|
||||||
|
uint16_t packetAddDirection();
|
||||||
|
uint16_t packetAddFunction(const uint8_t function);
|
||||||
|
uint16_t assemblePacket();
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static void setOutput(const uint8_t state);
|
||||||
|
|
||||||
|
Item(const uint8_t address);
|
||||||
|
|
||||||
|
void sendRaw(const uint16_t data);
|
||||||
|
static void sendRawAddr(const uint16_t address, const uint16_t data);
|
||||||
|
|
||||||
|
void setAddress(const uint8_t address);
|
||||||
|
uint8_t getAddress();
|
||||||
|
|
||||||
|
};
|
83
main.cpp
83
main.cpp
@ -9,16 +9,15 @@
|
|||||||
#include "eeprom.h"
|
#include "eeprom.h"
|
||||||
#include "bitrep.h"
|
#include "bitrep.h"
|
||||||
#include "ringbuffer.h"
|
#include "ringbuffer.h"
|
||||||
|
#include "staticvector.h"
|
||||||
|
|
||||||
#define MAX_TRAINS 16
|
|
||||||
#define COMMAND_BUFFER_SIZE 64
|
#define COMMAND_BUFFER_SIZE 64
|
||||||
#define SNPRINTF_BUFFER_SIZE 128
|
#define SNPRINTF_BUFFER_SIZE 128
|
||||||
#define EPPROM_SIZE 1024
|
#define EPPROM_SIZE 1024
|
||||||
|
|
||||||
char buffer[SNPRINTF_BUFFER_SIZE];
|
char buffer[SNPRINTF_BUFFER_SIZE];
|
||||||
|
|
||||||
uint16_t storedTrains = 0;
|
SVector<Train, 16> trains;
|
||||||
Train trains[MAX_TRAINS];
|
|
||||||
|
|
||||||
bool autoff = true;
|
bool autoff = true;
|
||||||
bool powerIsOn = true;
|
bool powerIsOn = true;
|
||||||
@ -54,9 +53,9 @@ void timer0InterruptEnable(const bool enable)
|
|||||||
void save_state()
|
void save_state()
|
||||||
{
|
{
|
||||||
cli();
|
cli();
|
||||||
EEPROM_write_char( 0, storedTrains );
|
EEPROM_write_char( 0, trains.count() );
|
||||||
EEPROM_write_char( 1, autoff );
|
EEPROM_write_char( 1, autoff );
|
||||||
for(uint16_t i = 0; i < storedTrains; i++)
|
for(uint16_t i = 0; i < trains.count(); i++)
|
||||||
{
|
{
|
||||||
EEPROM_write_char( i*2+32, trains[i].getAddress());
|
EEPROM_write_char( i*2+32, trains[i].getAddress());
|
||||||
EEPROM_write_char( i*2+32+1, trains[i].getFunctionMask());
|
EEPROM_write_char( i*2+32+1, trains[i].getFunctionMask());
|
||||||
@ -66,17 +65,19 @@ void save_state()
|
|||||||
|
|
||||||
void restore_state()
|
void restore_state()
|
||||||
{
|
{
|
||||||
storedTrains = EEPROM_read_char(0);
|
uint8_t trainCount = EEPROM_read_char(0);
|
||||||
autoff = EEPROM_read_char(1);
|
autoff = EEPROM_read_char(1);
|
||||||
if(storedTrains > MAX_TRAINS )
|
|
||||||
|
trains.clear();
|
||||||
|
if(trainCount > trains.maxSize() )
|
||||||
{
|
{
|
||||||
for(uint16_t i = 0; i < EPPROM_SIZE; i++) EEPROM_write_char(i, 0);
|
for(uint16_t i = 0; i < EPPROM_SIZE; i++)
|
||||||
storedTrains = 0;
|
EEPROM_write_char(i, 0);
|
||||||
}
|
}
|
||||||
else for(uint8_t i = 0; i < storedTrains; i++)
|
else
|
||||||
{
|
{
|
||||||
trains[i].setAddress(EEPROM_read_char(32+i*2));
|
for(uint8_t i = 0; i < trainCount; i++)
|
||||||
trains[i].setFunctionMask(EEPROM_read_char(32+1+i*2));
|
trains.push_back(Train(EEPROM_read_char(32+i*2), EEPROM_read_char(32+1+i*2)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,42 +109,32 @@ int trainDispatch(char* inBuffer, Serial* serial)
|
|||||||
uint8_t address = 0;
|
uint8_t address = 0;
|
||||||
if(token != NULL)
|
if(token != NULL)
|
||||||
address = strtol(token, nullptr, 10);
|
address = strtol(token, nullptr, 10);
|
||||||
if(address != 0 && storedTrains < MAX_TRAINS)
|
if(address != 0 && trains.remainingCapacity() > 0)
|
||||||
{
|
{
|
||||||
trains[storedTrains].setAddress(address);
|
uint8_t functionMask = 0;
|
||||||
|
|
||||||
token = strtok(NULL, " ");
|
token = strtok(NULL, " ");
|
||||||
if(token != NULL)
|
if(token != NULL)
|
||||||
trains[storedTrains].setFunctionMask(strtol(token, nullptr, 2 ));
|
functionMask = strtol(token, nullptr, 2);
|
||||||
|
|
||||||
|
trains.push_back(Train(address, functionMask));
|
||||||
|
|
||||||
uint8_t size = snprintf(buffer, SNPRINTF_BUFFER_SIZE, "TRAIN saved! NUMBER: %u ADDRESS: %u FUNCTIONS: %s FUNCTIONMASK: %s\n",
|
uint8_t size = snprintf(buffer, SNPRINTF_BUFFER_SIZE, "TRAIN saved! NUMBER: %u ADDRESS: %u FUNCTIONS: %s FUNCTIONMASK: %s\n",
|
||||||
storedTrains,
|
trains.count(),
|
||||||
address,
|
address,
|
||||||
bit_rep[trains[storedTrains].getFunctions() & 0x0F],
|
bit_rep[trains.back().getFunctions() & 0x0F],
|
||||||
bit_rep[trains[storedTrains].getFunctionMask() & 0x0F]);
|
bit_rep[trains.back().getFunctionMask() & 0x0F]);
|
||||||
serial->write(buffer, size);
|
serial->write(buffer, size);
|
||||||
|
|
||||||
storedTrains++;
|
|
||||||
save_state();
|
save_state();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
serial->write_p(PSTR("Usage: train add [address] [functionmask]"));
|
serial->write_p(PSTR("Usage: train add [address] [functionmask]"));
|
||||||
}
|
}
|
||||||
else if( strcmp(inBuffer, "delete") == 0)
|
|
||||||
{
|
|
||||||
serial->write_p(PSTR("Train: "));
|
|
||||||
serial->write(storedTrains-1);
|
|
||||||
serial->write_p(PSTR(" deleted\n"));
|
|
||||||
storedTrains--;
|
|
||||||
if(storedTrains < 0)
|
|
||||||
storedTrains = 0;
|
|
||||||
save_state();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else if( strcmp(inBuffer, "list") == 0 )
|
else if( strcmp(inBuffer, "list") == 0 )
|
||||||
{
|
{
|
||||||
serial->write_p(PSTR("Trains:\n"));
|
serial->write_p(PSTR("Trains:\n"));
|
||||||
for(uint8_t i = 0; i < storedTrains; i++)
|
for(uint8_t i = 0; i < trains.count(); i++)
|
||||||
{
|
{
|
||||||
snprintf(buffer, SNPRINTF_BUFFER_SIZE, "NUMBER: %u ID: %u CURRENT PACKET: %x SPEED: %i FUNCTIONS: %s FUNCTIONMASK: %s\n",
|
snprintf(buffer, SNPRINTF_BUFFER_SIZE, "NUMBER: %u ID: %u CURRENT PACKET: %x SPEED: %i FUNCTIONS: %s FUNCTIONMASK: %s\n",
|
||||||
i, trains[i].getAddress(),
|
i, trains[i].getAddress(),
|
||||||
@ -178,7 +169,7 @@ int trainDispatch(char* inBuffer, Serial* serial)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint8_t id = strtol(inBuffer, nullptr, 10);
|
uint8_t id = strtol(inBuffer, nullptr, 10);
|
||||||
if(id < storedTrains )
|
if(id < trains.count() )
|
||||||
{
|
{
|
||||||
if(powerIsOn == false)
|
if(powerIsOn == false)
|
||||||
{
|
{
|
||||||
@ -233,7 +224,7 @@ int trainDispatch(char* inBuffer, Serial* serial)
|
|||||||
uint16_t i = strtol(token, nullptr, 16 );
|
uint16_t i = strtol(token, nullptr, 16 );
|
||||||
snprintf(buffer, SNPRINTF_BUFFER_SIZE, "SENDING: %x to %x\n", i, trains[id].getAddress());
|
snprintf(buffer, SNPRINTF_BUFFER_SIZE, "SENDING: %x to %x\n", i, trains[id].getAddress());
|
||||||
serial->write(buffer, strlen(buffer));
|
serial->write(buffer, strlen(buffer));
|
||||||
//for(uint8_t j = 0; j < 100; j++)
|
for(uint8_t j = 0; j < 100; j++)
|
||||||
{
|
{
|
||||||
trains[id].sendRaw(i);
|
trains[id].sendRaw(i);
|
||||||
_delay_ms(20);
|
_delay_ms(20);
|
||||||
@ -254,6 +245,13 @@ int trainDispatch(char* inBuffer, Serial* serial)
|
|||||||
trains[id].stop();
|
trains[id].stop();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else if( strcmp(inBuffer, "delete") == 0)
|
||||||
|
{
|
||||||
|
trains.erase(id);
|
||||||
|
serial->write_p(PSTR("Train: "));
|
||||||
|
serial->write(id);
|
||||||
|
serial->write_p(PSTR(" deleted\n"));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
serial->write_p(PSTR("Not a valid command\n"));
|
serial->write_p(PSTR("Not a valid command\n"));
|
||||||
@ -280,7 +278,7 @@ int powerDispatch(char* token, Serial* serial)
|
|||||||
}
|
}
|
||||||
else if( strcmp(token, "on") == 0)
|
else if( strcmp(token, "on") == 0)
|
||||||
{
|
{
|
||||||
for(uint16_t i = 0; i < storedTrains; i++)
|
for(uint16_t i = 0; i < trains.count(); i++)
|
||||||
{
|
{
|
||||||
trains[i].setSpeed(0);
|
trains[i].setSpeed(0);
|
||||||
}
|
}
|
||||||
@ -334,7 +332,7 @@ void serialDispatch(Serial* serial)
|
|||||||
{
|
{
|
||||||
for(uint16_t i = 0; i < EPPROM_SIZE; i++) EEPROM_write_char(i, 0);
|
for(uint16_t i = 0; i < EPPROM_SIZE; i++) EEPROM_write_char(i, 0);
|
||||||
serial->write_p(PSTR("EEPROM erased\n"));
|
serial->write_p(PSTR("EEPROM erased\n"));
|
||||||
storedTrains = 0;
|
trains.clear();
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
else if(strcmp(token, "dump") == 0)
|
else if(strcmp(token, "dump") == 0)
|
||||||
@ -349,7 +347,7 @@ void serialDispatch(Serial* serial)
|
|||||||
}
|
}
|
||||||
else if((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++)
|
for(uint16_t i = 0; i < trains.count(); i++)
|
||||||
{
|
{
|
||||||
cli();
|
cli();
|
||||||
trains[i].stop();
|
trains[i].stop();
|
||||||
@ -426,13 +424,12 @@ int main()
|
|||||||
|
|
||||||
while(true)
|
while(true)
|
||||||
{
|
{
|
||||||
if(resendEvent && storedTrains > 0)
|
if(resendEvent && trains.count() > 0)
|
||||||
{
|
{
|
||||||
//_delay_ms(100);
|
|
||||||
timer0InterruptEnable(false);
|
timer0InterruptEnable(false);
|
||||||
trains[trainToResend].sendData();
|
trains[trainToResend].sendData();
|
||||||
trainToResend++;
|
trainToResend++;
|
||||||
if(storedTrains <= trainToResend)
|
if(trains.count() <= trainToResend)
|
||||||
trainToResend = 0;
|
trainToResend = 0;
|
||||||
resendEvent = false;
|
resendEvent = false;
|
||||||
timer0InterruptEnable(true);
|
timer0InterruptEnable(true);
|
||||||
@ -441,7 +438,7 @@ int main()
|
|||||||
if(autoff)
|
if(autoff)
|
||||||
{
|
{
|
||||||
bool trainsRunning = false;
|
bool trainsRunning = false;
|
||||||
for(uint16_t i = 0; i < storedTrains; i++)
|
for(uint16_t i = 0; i < trains.count(); i++)
|
||||||
trainsRunning = trainsRunning || trains[i].isActive();
|
trainsRunning = trainsRunning || trains[i].isActive();
|
||||||
if(!trainsRunning)
|
if(!trainsRunning)
|
||||||
{
|
{
|
||||||
|
88
staticvector.h
Normal file
88
staticvector.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
template<typename T, size_t size> class SVector
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
size_t stored = 0;
|
||||||
|
|
||||||
|
|
||||||
|
char buff[sizeof(T)*size];
|
||||||
|
T *array = (T*)buff;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
T* data()
|
||||||
|
{
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator[](size_t i)
|
||||||
|
{
|
||||||
|
return array[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
T& at(size_t i)
|
||||||
|
{
|
||||||
|
return array[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
T& front()
|
||||||
|
{
|
||||||
|
return array[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
T& back()
|
||||||
|
{
|
||||||
|
return array[stored-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return stored == 0 ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t count() const
|
||||||
|
{
|
||||||
|
return stored;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr size_t maxSize() const
|
||||||
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t remainingCapacity() const
|
||||||
|
{
|
||||||
|
return size - stored;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool push_back(const T in)
|
||||||
|
{
|
||||||
|
if( remainingCapacity() != 0)
|
||||||
|
{
|
||||||
|
array[stored] = in;
|
||||||
|
++stored;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool erase(size_t position)
|
||||||
|
{
|
||||||
|
if(position > stored)
|
||||||
|
return false;
|
||||||
|
array[position].~T();
|
||||||
|
--stored;
|
||||||
|
for( size_t i = position; i < stored; i++ )
|
||||||
|
memcpy(&array[i], &array[i+1], sizeof(T));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear()
|
||||||
|
{
|
||||||
|
for( size_t i = 0; i < stored; i++ )
|
||||||
|
array[i].~T();
|
||||||
|
stored = 0;
|
||||||
|
}
|
||||||
|
};
|
115
train.cpp
115
train.cpp
@ -1,109 +1,10 @@
|
|||||||
#include "train.h"
|
#include "train.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
static volatile unsigned char *_port = &PORTD;
|
Train::Train(const uint8_t address, uint8_t functionmask): Item(address), _functionmask(functionmask)
|
||||||
|
|
||||||
Train::Train(const uint8_t address, uint8_t functionmask): _address(address), _functionmask(functionmask)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
Train::Train()
|
|
||||||
{
|
|
||||||
_address = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Train::setAddress(const uint8_t address)
|
|
||||||
{
|
|
||||||
_address = address;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t Train::getAddress()
|
|
||||||
{
|
|
||||||
return _address;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Train::stop()
|
|
||||||
{
|
|
||||||
_speed = 0;
|
|
||||||
_function = 0;
|
|
||||||
sendData();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Train::off()
|
|
||||||
{
|
|
||||||
writePin(_port, _pinHighA, false);
|
|
||||||
writePin(_port, _pinHighB, false);
|
|
||||||
writePin(_port, _pinLowA, true);
|
|
||||||
writePin(_port, _pinLowB, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Train::setOutput(const uint8_t state)
|
|
||||||
{
|
|
||||||
if(state == HIGH)
|
|
||||||
{
|
|
||||||
off();
|
|
||||||
_delay_us(3);
|
|
||||||
writePin(_port, _pinHighA, true);
|
|
||||||
writePin(_port, _pinLowB, false);
|
|
||||||
}
|
|
||||||
else if (state == LOW)
|
|
||||||
{
|
|
||||||
off();
|
|
||||||
_delay_us(3);
|
|
||||||
writePin(_port, _pinHighB, true);
|
|
||||||
writePin(_port, _pinLowA, false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
off();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Train::sendBit(const bool bit)
|
|
||||||
{
|
|
||||||
if(bit)
|
|
||||||
{
|
|
||||||
setOutput(HIGH);
|
|
||||||
_delay_us(170);
|
|
||||||
setOutput(LOW);
|
|
||||||
_delay_us(25);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setOutput(HIGH);
|
|
||||||
_delay_us(20);
|
|
||||||
setOutput(LOW);
|
|
||||||
_delay_us(175);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Train::sendAddress(uint8_t address)
|
|
||||||
{
|
|
||||||
for(uint8_t i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
sendBit(address & (1 << i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Train::sendRawAddr(const uint16_t address, const uint16_t data)
|
|
||||||
{
|
|
||||||
for(uint8_t j = 0; j < SEND_COUNT; j++)
|
|
||||||
{
|
|
||||||
sendAddress(address);
|
|
||||||
for(uint8_t i = 0; i < 10; i++)
|
|
||||||
{
|
|
||||||
sendBit(data & (1 << i));
|
|
||||||
}
|
|
||||||
_delay_ms(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Train::sendRaw(const uint16_t data)
|
|
||||||
{
|
|
||||||
sendRawAddr(_address, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t Train::packetAddSpeed()
|
uint16_t Train::packetAddSpeed()
|
||||||
{
|
{
|
||||||
uint16_t packet = 0;
|
uint16_t packet = 0;
|
||||||
@ -181,7 +82,15 @@ uint8_t Train::getSpeed()
|
|||||||
return _speed;
|
return _speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t Train::assemblePacket()
|
void Train::stop()
|
||||||
|
{
|
||||||
|
_speed = 0;
|
||||||
|
_function = 0;
|
||||||
|
sendData();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t Train::assembleSpeedPacket()
|
||||||
{
|
{
|
||||||
uint16_t packet = packetAddSpeed() | packetAddFunction(0) | packetAddDirection();
|
uint16_t packet = packetAddSpeed() | packetAddFunction(0) | packetAddDirection();
|
||||||
return packet;
|
return packet;
|
||||||
@ -189,7 +98,7 @@ uint16_t Train::assemblePacket()
|
|||||||
|
|
||||||
void Train::sendData()
|
void Train::sendData()
|
||||||
{
|
{
|
||||||
sendRaw(assemblePacket());
|
sendRaw(assembleSpeedPacket());
|
||||||
if(_functionmask)
|
if(_functionmask)
|
||||||
{
|
{
|
||||||
uint8_t functionToResend = (_function & 0xF0) >> 4;
|
uint8_t functionToResend = (_function & 0xF0) >> 4;
|
||||||
@ -208,7 +117,7 @@ void Train::sendData()
|
|||||||
|
|
||||||
uint16_t Train::getLastPacket()
|
uint16_t Train::getLastPacket()
|
||||||
{
|
{
|
||||||
return assemblePacket();
|
return assembleSpeedPacket();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Train::reverse()
|
void Train::reverse()
|
||||||
|
43
train.h
43
train.h
@ -1,47 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "writepin.h"
|
#include "item.h"
|
||||||
#include <util/delay.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
|
|
||||||
class Train
|
class Train: public Item
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
|
|
||||||
static constexpr uint8_t HIGH = 2;
|
|
||||||
static constexpr uint8_t LOW = 1;
|
|
||||||
static constexpr uint8_t OFF = 0;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
uint8_t _function = 0;
|
||||||
static constexpr unsigned char _pinHighA = PD5;
|
|
||||||
static constexpr unsigned char _pinLowA = PD4;
|
|
||||||
static constexpr unsigned char _pinHighB = PD2;
|
|
||||||
static constexpr unsigned char _pinLowB = PD3;
|
|
||||||
|
|
||||||
uint8_t _address;
|
|
||||||
uint8_t _function = 0;
|
|
||||||
uint8_t _functionmask;
|
uint8_t _functionmask;
|
||||||
uint8_t _speed = 0;
|
uint8_t _speed = 0;
|
||||||
bool _direction = false;
|
bool _direction = false;
|
||||||
|
|
||||||
static const uint8_t SEND_COUNT = 2;
|
|
||||||
|
|
||||||
inline static void off();
|
|
||||||
static void sendBit(const bool bit);
|
|
||||||
static void sendAddress(uint8_t address);
|
|
||||||
uint16_t packetAddSpeed();
|
uint16_t packetAddSpeed();
|
||||||
uint16_t packetAddDirection();
|
uint16_t packetAddDirection();
|
||||||
uint16_t packetAddFunction(const uint8_t function);
|
uint16_t packetAddFunction(const uint8_t function);
|
||||||
uint16_t assemblePacket();
|
uint16_t assembleSpeedPacket();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static void setOutput(const uint8_t state);
|
Train(const uint8_t address, uint8_t functionmask = 0b0000);
|
||||||
|
|
||||||
Train(const uint8_t address, uint8_t functionmask = 0b1111);
|
|
||||||
Train();
|
|
||||||
|
|
||||||
void sendData();
|
void sendData();
|
||||||
|
|
||||||
@ -51,8 +27,6 @@ public:
|
|||||||
|
|
||||||
bool isActive() {return getSpeed() || getFunctions();}
|
bool isActive() {return getSpeed() || getFunctions();}
|
||||||
|
|
||||||
uint8_t getAddress();
|
|
||||||
|
|
||||||
uint16_t getLastPacket();
|
uint16_t getLastPacket();
|
||||||
|
|
||||||
void setSpeed(uint8_t speed);
|
void setSpeed(uint8_t speed);
|
||||||
@ -65,12 +39,5 @@ public:
|
|||||||
|
|
||||||
uint8_t getFunctionMask();
|
uint8_t getFunctionMask();
|
||||||
|
|
||||||
void setAddress(const uint8_t address);
|
|
||||||
|
|
||||||
void sendFunction(const uint8_t function, bool enable = true);
|
void sendFunction(const uint8_t function, bool enable = true);
|
||||||
|
|
||||||
void sendRaw(const uint16_t data);
|
|
||||||
|
|
||||||
static void sendRawAddr(const uint16_t address, const uint16_t data);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user