Files
MarklinController/traindispatch.h
2022-03-09 10:24:23 +01:00

204 lines
5.0 KiB
C

#pragma once
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "serial.h"
#include "writepin.h"
void printTrainState(int id, Serial* serial)
{
snprintf(buffer, SNPRINTF_BUFFER_SIZE,
"TRAIN NUMBER: %u ADDRESS: %u CURRENT PACKET: %x SPEED: %i FUNCTIONS: %s FUNCTIONMASK: %s QUIRKS: %s\n",
id, trains[id].getAddress(),
trains[id].getLastPacket(), trains[id].getSpeed(),
bit_rep[trains[id].getFunctions() & 0x0F], bit_rep[trains[id].getFunctionMask() & 0x0F],
bit_rep[trains[id].getQuirks() & 0x0F]);
serial->write(buffer, SNPRINTF_BUFFER_SIZE);
}
int trainDispatch(char* inBuffer, Serial* serial)
{
if( strcmp(inBuffer, "add") == 0 )
{
char* token = strtok(NULL, " ");
uint8_t address = 0;
if(token != NULL)
address = strtol(token, nullptr, 10);
if(address != 0 && trains.remainingCapacity() > 0)
{
uint8_t functionMask = 0;
uint8_t quirks = 0;
token = strtok(NULL, " ");
if(token != NULL)
{
functionMask = strtol(token, nullptr, 2);
token = strtok(NULL, " ");
if(token != NULL)
{
quirks = strtol(token, nullptr, 2);
}
}
trains.push_back(Train(address, functionMask, quirks));
serial->write_p(PSTR("TRAIN saved! "));
printTrainState(trains.count()-1, serial);
save_state();
return 0;
}
serial->write_p(PSTR("Usage: train add [address] [functionmask] [quirks]"));
}
else if( strcmp(inBuffer, "list") == 0 )
{
serial->write_p(PSTR("Trains:\n"));
for(uint8_t i = 0; i < trains.count(); i++)
printTrainState(i, serial);
serial->putChar('\n');
return 0;
}
else if( strcmp(inBuffer, "probe") == 0 )
{
for(uint16_t j = 0; j < 255; j++)
{
snprintf(buffer, SNPRINTF_BUFFER_SIZE, "TRYING ADDR: %x\n", j);
serial->write(buffer, strlen(buffer));
cli();
for(uint8_t k = 0; k < 10; k++)
{
Train::sendRawAddr(j, 60);
_delay_ms(20);
}
for(uint8_t k = 0; k < 3; k++)
{
Train::sendRawAddr(j, 0);
_delay_ms(20);
}
sei();
}
return 0;
}
else
{
uint8_t id = strtol(inBuffer, nullptr, 10);
if(id < trains.count() )
{
setPower(true);
char* token = strtok(NULL, " ");
if( token != NULL && (strcmp(token, "speed") == 0 || strcmp(token, "s") == 0) )
{
token = strtok(NULL, " ");
trains[id].setSpeed(atoi(token));
serial->write_p(PSTR("Set Train speed\n"));
printTrainState(id, serial);
return 0;
}
else if(token != NULL && strcmp(token, "function") == 0 )
{
token = strtok(NULL, " ");
char* boolToken = strtok(NULL, " ");
if(token != NULL && boolToken != NULL)
{
uint8_t functionId = atoi(token);
bool on = (strcmp(boolToken, "on") == 0);
trains[id].sendFunction(functionId, on );
serial->write_p(PSTR("Set Train function "));
serial->write(functionId);
serial->write(on ? " on\n" : " off\n");
printTrainState(id, serial);
return 0;
}
}
else if(token != NULL && strcmp(token, "probe") == 0 )
{
serial->flush();
for(uint16_t j = 0; j < 1024 && !serial->dataIsWaiting(); j++)
{
trains[id].sendRaw(j);
snprintf(buffer, SNPRINTF_BUFFER_SIZE, "TRYING: %x\n", j);
serial->write(buffer, strlen(buffer));
sei();
_delay_ms(250);
cli();
}
sei();
serial->flush();
return 0;
}
else if(token != NULL && strcmp(token, "raw") == 0 )
{
token = strtok(NULL, " ");
if(token != NULL)
{
cli();
uint16_t i = strtol(token, nullptr, 16 );
snprintf(buffer, SNPRINTF_BUFFER_SIZE, "SENDING: %x to %x\n", i, trains[id].getAddress());
serial->write(buffer, strlen(buffer));
for(uint8_t j = 0; j < 100; j++)
{
trains[id].sendRaw(i);
_delay_ms(20);
}
serial->write_p(PSTR("Finished\n"));
sei();
return 0;
}
}
else if( token != NULL && (strcmp(token, "reverse") == 0 || strcmp(token, "r") == 0) )
{
trains[id].reverse();
serial->write_p(PSTR("Reversed Train\n"));
return 0;
}
else if( token != NULL && (strcmp(token, "stop") == 0 || strcmp(token, "p") == 0))
{
trains[id].stop();
printTrainState(id, serial);
return 0;
}
else if( token != NULL && strcmp(token, "edit") == 0)
{
uint8_t functionMask = 0;
uint8_t quirks = 0;
token = strtok(NULL, " ");
if(token != NULL)
{
functionMask = strtol(token, nullptr, 2);
token = strtok(NULL, " ");
if(token != NULL)
{
quirks = strtol(token, nullptr, 2);
}
}
trains[id].stop();
trains[id].setFunctionMask(functionMask);
trains[id].setQuirks(quirks);
save_state();
printTrainState(id, serial);
return 0;
}
else if( token != NULL && strcmp(token, "delete") == 0)
{
trains.erase(id);
serial->write_p(PSTR("Train: "));
serial->write(id);
serial->write_p(PSTR(" deleted\n"));
save_state();
return 0;
}
else
{
serial->write_p(PSTR("Not a valid command\n"));
return -1;
}
}
else
{
serial->write_p(PSTR("Id out of range.\n"));
return -2;
}
}
return -3;
}