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/).

Revision:
0:96eb8cc345dc
Child:
1:39249e22e9f5
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DSGatewayMBED.cpp	Sat Jan 17 01:48:50 2015 +0000
@@ -0,0 +1,366 @@
+#include "DSGatewayMBED.h"
+#include "mbed.h"
+
+SPI spiDS(SPI_MOSI, SPI_MISO, SPI_SCK);
+DigitalOut cs(D10);
+
+DSGatewayLib::DSGatewayLib()
+{
+    
+    poweron = false;
+    
+}
+
+void DSGatewayLib::begin()
+{
+  /* Open SPI */
+
+  spiDS.format(8, 0);
+  spiDS.frequency(1000000);
+
+}
+
+
+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] = spiDS.write(inPackets[i]);
+        wait_us(10);
+    }
+    
+    cs = 1;
+    
+    
+    /* 遅延 */
+    wait_ms(30);
+    
+    /* 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(bool power)
+{
+    unsigned char aPacktes[SIZE_PACKET];
+
+    clearMessage(aPacktes);
+
+    if (power) {
+        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(bool power)
+{
+    unsigned char aPacktes[SIZE_PACKET];
+
+    clearMessage(aPacktes);
+
+    if (power) {
+        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;
+}
\ No newline at end of file