Desktop Station gateway software for mbed
Dependents: DSGatewayMBED_Nucleo DSGatewayMBED_Nucleo_Step128
This library provides to control DCC and Marklin Motorola 2 locomtoives and turnouts via DCC/MM2 Shield. Please check our wiki site(http://desktopstation.net/wiki/).
DSGatewayMBED.cpp
- Committer:
- yaasan
- Date:
- 2015-01-23
- Revision:
- 1:39249e22e9f5
- Parent:
- 0:96eb8cc345dc
File content as of revision 1:39249e22e9f5:
/********************************************************************* * Desktop Station Gateway Library for mbed platform * * Copyright (C) 2015 Yaasan * */ #include "DSGatewayMBED.h" #include "mbed.h" SPI spiDS(SPI_MOSI, SPI_MISO, SPI_SCK); DigitalOut cs(PB_6); DSGatewayLib::DSGatewayLib() { poweron = false; } void DSGatewayLib::begin() { /* Open SPI */ /* SPI mode is default( 8bit, mode 0, 1MHz) */ //spiDS.format(8, 0); //spiDS.frequency(1000000); cs = 1; } DSGatewayLib::~DSGatewayLib() { SetPower(false); } bool DSGatewayLib::IsPower() { return poweron; } void DSGatewayLib::clearMessage(unsigned char *inPackets) { for( int i = 0; i < SIZE_PACKET; i++) { inPackets[i] = 0; } } bool DSGatewayLib::sendMessage(unsigned char *inPackets) { byte aReceived[SIZE_PACKET] = {0,0,0,0,0,0,0,0}; int i; cs = 0; for( i = 0; i < SIZE_PACKET; i++) { aReceived[i] = reverseByte(spiDS.write(reverseByte(inPackets[i]))); } cs = 1; /* 遅延 */ wait_ms(5); /* Check for receiving */ if((aReceived[1] & 0xF0) == CMD_OK) { return true; } else if((aReceived[1] & 0xF0) == CMD_WAIT) { return true; } else { return false; } } bool DSGatewayLib::exchangeMessage(unsigned char *inPackets, word timeout) { //unsigned char aTemp[SIZE_PACKET]; bool aReturnOk = sendMessage(inPackets); /* unsigned long aTime = millis(); // response; while ((millis() < aTime + timeout) || (!aReturnOk)) { aTemp[0] = CMD_WAIT | 0b0010; aTemp[1] = aTemp[0]; delay(20); if (sendMessage(aTemp) == true) { return true; } } if (DEBUG && !aReturnOk) { Serial.println(F("!!! Communication Error(Timeout, Command etc)")); } */ return aReturnOk; } bool DSGatewayLib::SetPower(byte power) { unsigned char aPacktes[SIZE_PACKET]; clearMessage(aPacktes); if (power == 1) { aPacktes[0] = CMD_PWR_ON | 0x02; aPacktes[1] = aPacktes[0];//CRC poweron = true; } else { aPacktes[0] = CMD_PWR_OFF | 0x02; aPacktes[1] = aPacktes[0];//CRC poweron = false; } return exchangeMessage(aPacktes, TIME_REPLY); } bool DSGatewayLib::SetPowerEx(byte power) { unsigned char aPacktes[SIZE_PACKET]; clearMessage(aPacktes); if (power == 1) { aPacktes[0] = CMD_PWR_ON | 0x03; aPacktes[1] = 3;//Extend command (DCC128 and MM2-28step) aPacktes[2] = generateCRC(aPacktes, 2); } else { aPacktes[0] = CMD_PWR_OFF | 0x02; aPacktes[1] = aPacktes[0];//CRC } return exchangeMessage(aPacktes, TIME_REPLY); } bool DSGatewayLib::SetLocoSpeed(word address, int inSpeed) { unsigned char aPacktes[SIZE_PACKET]; clearMessage(aPacktes); aPacktes[0] = CMD_SPEED | 0x06; aPacktes[1] = lowByte(address); aPacktes[2] = highByte(address); aPacktes[3] = lowByte(inSpeed); aPacktes[4] = highByte(inSpeed); aPacktes[5] = generateCRC(aPacktes, 5); return exchangeMessage(aPacktes, TIME_REPLY); } bool DSGatewayLib::SetLocoSpeedEx(word address, int inSpeed, int inProtcol) { unsigned char aPacktes[SIZE_PACKET]; clearMessage(aPacktes); aPacktes[0] = CMD_SPEED | 0x07; aPacktes[1] = lowByte(address); aPacktes[2] = highByte(address); aPacktes[3] = lowByte(inSpeed); aPacktes[4] = highByte(inSpeed); aPacktes[5] = inProtcol; aPacktes[6] = generateCRC(aPacktes, 6); return exchangeMessage(aPacktes, TIME_REPLY); } bool DSGatewayLib::SetLocoFunction(word address, unsigned char inFunction, unsigned char inPower) { unsigned char aPacktes[SIZE_PACKET]; clearMessage(aPacktes); aPacktes[0] = CMD_FUNCTION | 0x06; aPacktes[1] = lowByte(address); aPacktes[2] = highByte(address); aPacktes[3] = inFunction + 1; //1はじまり aPacktes[4] = inPower; aPacktes[5] = generateCRC(aPacktes, 5); return exchangeMessage(aPacktes, TIME_REPLY); } bool DSGatewayLib::SetLocoDirection(word address, unsigned char inDirection) { unsigned char aPacktes[SIZE_PACKET]; clearMessage(aPacktes); aPacktes[0] = CMD_DIRECTION | 0x05; aPacktes[1] = lowByte(address); aPacktes[2] = highByte(address); aPacktes[3] = inDirection - 1;// FWD 1->0, REV:2->1 aPacktes[4] = generateCRC(aPacktes, 4); return exchangeMessage(aPacktes, TIME_REPLY); } /* bool DSGatewayLib::SetTurnout(word address, bool straight) { byte aSwitch = straight == true ? (byte)1 : (byte)0; return SetTurnout(address, aSwitch); }*/ bool DSGatewayLib::SetTurnout(word address, byte inSwitch) { unsigned char aPacktes[SIZE_PACKET]; clearMessage(aPacktes); aPacktes[0] = CMD_ACCESSORY | 0x06; aPacktes[1] = lowByte(address); aPacktes[2] = highByte(address); aPacktes[3] = 0x00; // position aPacktes[4] = convertAcc_MMDCC(address, inSwitch);// 0: Straight, 1: diverging from DS 1:straight, 0: diverging aPacktes[5] = generateCRC(aPacktes, 5); return exchangeMessage(aPacktes, TIME_REPLY); } byte DSGatewayLib::convertAcc_MMDCC(word address, byte inSwitch) { byte aReturn = inSwitch; switch( GetLocIDProtocol(address >> 8)) { case ADDR_ACC_MM2: /* 0:Straight, 1: diverging */ aReturn = (inSwitch == 0) ? 1 : 0; break; case ADDR_ACC_DCC: /* 1:Straight, 0: diverging */ aReturn = inSwitch; break; default: aReturn = inSwitch; break; } return aReturn; } word DSGatewayLib::GetLocIDProtocol(byte address) { if( address < 0x04) { return ADDR_MM2; } else if( (address >= 0x30) && (address <= 0x33)) { return ADDR_ACC_MM2; } else if( (address >= 0x38) && (address <= 0x3F)) { return ADDR_ACC_DCC; } else if( (address >= 0x40) && (address <= 0x70)) { return ADDR_MFX; } else if( (address >= 0xC0) && (address <= 0xFF)) { return ADDR_DCC; } else { return 0; } } bool DSGatewayLib::WriteConfig(word address, word number, byte value) { unsigned char aPacktes[SIZE_PACKET]; word aOffsetCVNo; if( address >= ADDR_DCC) { aOffsetCVNo = number; } else { aOffsetCVNo = number | 0x8000; } clearMessage(aPacktes); aPacktes[0] = CMD_CVWRITE | 0x05; aPacktes[1] = lowByte(aOffsetCVNo); aPacktes[2] = highByte(aOffsetCVNo); aPacktes[3] = value; aPacktes[4] = generateCRC(aPacktes, 4); return exchangeMessage(aPacktes, TIME_REPLY); } bool DSGatewayLib::ReadConfig(word address, word number, byte *value) { unsigned char aPacktes[SIZE_PACKET]; clearMessage(aPacktes); aPacktes[0] = CMD_CVREAD || 0x04; aPacktes[1] = lowByte(number); aPacktes[2] = highByte(number); aPacktes[3] = generateCRC(aPacktes, 3); *value = 0; return exchangeMessage(aPacktes, TIME_REPLY); } unsigned char DSGatewayLib::generateCRC(unsigned char *inPackets, unsigned char inLen) { unsigned char aCRC = inPackets[0]; for( int i = 1; i < inLen; i++) { aCRC = aCRC ^ inPackets[i]; } return aCRC; } byte lowByte(short int low) { byte bytelow = 0; bytelow = (low & 0xFF); return bytelow; } byte highByte(short int high) { byte bytehigh = 0; bytehigh = ((high >> 8) & 0xFF); return bytehigh; } unsigned char reverseByte(unsigned char inByte) { unsigned char aTemp = 0; for( int i = 0; i < 8; i++) { aTemp = aTemp | (((inByte >> i) & 0x01) << (7 - i)); } return aTemp; }