Desktop Station gateway software for mbed

Dependents:   DSGatewayMBED_Nucleo DSGatewayMBED_Nucleo_Step128

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DSGatewayMBED.cpp Source File

DSGatewayMBED.cpp

00001 /*********************************************************************
00002  * Desktop Station Gateway Library for mbed platform
00003  *
00004  * Copyright (C) 2015 Yaasan
00005  *
00006  */
00007 
00008 #include "DSGatewayMBED.h"
00009 #include "mbed.h"
00010 
00011 SPI spiDS(SPI_MOSI, SPI_MISO, SPI_SCK);
00012 DigitalOut cs(PB_6);
00013 
00014 DSGatewayLib::DSGatewayLib()
00015 {
00016     
00017     poweron = false;
00018     
00019 }
00020 
00021 void DSGatewayLib::begin()
00022 {
00023   /* Open SPI */
00024 
00025   /* SPI mode is default( 8bit, mode 0, 1MHz) */
00026   //spiDS.format(8, 0);
00027   //spiDS.frequency(1000000);
00028     cs = 1;
00029 }
00030 
00031 
00032 DSGatewayLib::~DSGatewayLib()
00033 {
00034   
00035   SetPower(false);
00036 
00037 }
00038 
00039 bool DSGatewayLib::IsPower()
00040 {
00041     
00042     return poweron;
00043     
00044 }
00045 
00046 
00047 void DSGatewayLib::clearMessage(unsigned char *inPackets)
00048 {
00049     for( int i = 0; i < SIZE_PACKET; i++)
00050     {
00051         inPackets[i] = 0;
00052     } 
00053 }
00054 
00055 bool DSGatewayLib::sendMessage(unsigned char *inPackets)
00056 {
00057     byte aReceived[SIZE_PACKET] = {0,0,0,0,0,0,0,0};
00058     int i;
00059 
00060     cs = 0;
00061     
00062     for( i = 0; i < SIZE_PACKET; i++)
00063     {
00064        aReceived[i] = reverseByte(spiDS.write(reverseByte(inPackets[i])));
00065     }
00066     
00067     cs = 1;
00068     
00069     
00070     /* 遅延 */
00071     wait_ms(5);
00072    
00073     /* Check for receiving */
00074     if((aReceived[1] & 0xF0) == CMD_OK)
00075     {
00076         return true;    
00077     }
00078     else if((aReceived[1] & 0xF0) == CMD_WAIT)
00079     {
00080         return true;
00081     }
00082     else
00083     {
00084         return false;
00085     }
00086 }
00087 
00088 bool DSGatewayLib::exchangeMessage(unsigned char *inPackets, word timeout)
00089 {
00090     //unsigned char aTemp[SIZE_PACKET];
00091 
00092     bool aReturnOk = sendMessage(inPackets);
00093     
00094     /*
00095     unsigned long aTime = millis();
00096 
00097     // response;
00098 
00099     while ((millis() < aTime + timeout) || (!aReturnOk)) {
00100         aTemp[0] = CMD_WAIT | 0b0010;
00101         aTemp[1] = aTemp[0];
00102         
00103         delay(20);
00104         
00105         if (sendMessage(aTemp) == true) {
00106             return true;
00107         }
00108     }
00109 
00110     if (DEBUG && !aReturnOk) {
00111         Serial.println(F("!!! Communication Error(Timeout, Command etc)"));
00112     }
00113     */
00114     
00115     return aReturnOk;
00116 }
00117 
00118 
00119 bool DSGatewayLib::SetPower(byte power)
00120 {
00121     unsigned char aPacktes[SIZE_PACKET];
00122 
00123     clearMessage(aPacktes);
00124 
00125     if (power == 1) {
00126         aPacktes[0] = CMD_PWR_ON | 0x02;
00127         aPacktes[1] = aPacktes[0];//CRC
00128         poweron = true;
00129 
00130     }
00131     else
00132     {
00133         aPacktes[0] = CMD_PWR_OFF | 0x02;
00134         aPacktes[1] = aPacktes[0];//CRC
00135         poweron = false;
00136     }
00137 
00138     return exchangeMessage(aPacktes, TIME_REPLY);
00139 }
00140 
00141 bool DSGatewayLib::SetPowerEx(byte power)
00142 {
00143     unsigned char aPacktes[SIZE_PACKET];
00144 
00145     clearMessage(aPacktes);
00146 
00147     if (power == 1) {
00148         aPacktes[0] = CMD_PWR_ON | 0x03;
00149         aPacktes[1] = 3;//Extend command (DCC128 and MM2-28step)
00150         aPacktes[2] = generateCRC(aPacktes, 2);
00151 
00152     }
00153     else
00154     {
00155         aPacktes[0] = CMD_PWR_OFF | 0x02;
00156         aPacktes[1] = aPacktes[0];//CRC
00157     }
00158     
00159 
00160 
00161     return exchangeMessage(aPacktes, TIME_REPLY);
00162 }
00163 
00164 bool DSGatewayLib::SetLocoSpeed(word address, int inSpeed)
00165 {
00166     unsigned char aPacktes[SIZE_PACKET];
00167 
00168     clearMessage(aPacktes);
00169 
00170     aPacktes[0] = CMD_SPEED | 0x06;
00171     aPacktes[1] = lowByte(address);
00172     aPacktes[2] = highByte(address);
00173     aPacktes[3] = lowByte(inSpeed);
00174     aPacktes[4] = highByte(inSpeed);
00175     aPacktes[5] = generateCRC(aPacktes, 5);
00176 
00177     return exchangeMessage(aPacktes, TIME_REPLY);
00178 }
00179 
00180 
00181 bool DSGatewayLib::SetLocoSpeedEx(word address, int inSpeed, int inProtcol)
00182 {
00183     unsigned char aPacktes[SIZE_PACKET];
00184 
00185     clearMessage(aPacktes);
00186 
00187     aPacktes[0] = CMD_SPEED | 0x07;
00188     aPacktes[1] = lowByte(address);
00189     aPacktes[2] = highByte(address);
00190     aPacktes[3] = lowByte(inSpeed);
00191     aPacktes[4] = highByte(inSpeed);
00192     aPacktes[5] = inProtcol;
00193     aPacktes[6] = generateCRC(aPacktes, 6);
00194 
00195     return exchangeMessage(aPacktes, TIME_REPLY);
00196 } 
00197 
00198 bool DSGatewayLib::SetLocoFunction(word address, unsigned char inFunction, unsigned char inPower)
00199 {
00200     unsigned char aPacktes[SIZE_PACKET];
00201 
00202     clearMessage(aPacktes);
00203 
00204     aPacktes[0] = CMD_FUNCTION | 0x06;
00205     aPacktes[1] = lowByte(address);
00206     aPacktes[2] = highByte(address);
00207     aPacktes[3] = inFunction + 1; //1はじまり
00208     aPacktes[4] = inPower;
00209     aPacktes[5] = generateCRC(aPacktes, 5);
00210 
00211     return exchangeMessage(aPacktes, TIME_REPLY);
00212 }
00213 
00214 
00215 bool DSGatewayLib::SetLocoDirection(word address, unsigned char inDirection)
00216 {
00217     unsigned char aPacktes[SIZE_PACKET];
00218 
00219     clearMessage(aPacktes);
00220 
00221     aPacktes[0] = CMD_DIRECTION | 0x05;
00222     aPacktes[1] = lowByte(address);
00223     aPacktes[2] = highByte(address);
00224     aPacktes[3] = inDirection - 1;// FWD 1->0, REV:2->1
00225     aPacktes[4] = generateCRC(aPacktes, 4);
00226 
00227     return exchangeMessage(aPacktes, TIME_REPLY);
00228 }
00229 
00230 /*
00231 bool DSGatewayLib::SetTurnout(word address, bool straight)
00232 {
00233     byte aSwitch = straight == true ? (byte)1 : (byte)0;
00234     
00235     return SetTurnout(address, aSwitch);
00236 }*/
00237 
00238 bool DSGatewayLib::SetTurnout(word address, byte inSwitch)
00239 {
00240     unsigned char aPacktes[SIZE_PACKET];
00241 
00242     clearMessage(aPacktes);
00243 
00244     aPacktes[0] = CMD_ACCESSORY | 0x06;
00245     aPacktes[1] = lowByte(address);
00246     aPacktes[2] = highByte(address);
00247     aPacktes[3] = 0x00; // position
00248     aPacktes[4] = convertAcc_MMDCC(address, inSwitch);// 0: Straight, 1: diverging from DS 1:straight, 0: diverging
00249     aPacktes[5] = generateCRC(aPacktes, 5);
00250 
00251     return exchangeMessage(aPacktes, TIME_REPLY);
00252 }
00253 
00254 byte DSGatewayLib::convertAcc_MMDCC(word address, byte inSwitch)
00255 {
00256     byte aReturn = inSwitch;
00257     
00258     switch( GetLocIDProtocol(address >> 8))
00259     {
00260     case ADDR_ACC_MM2:
00261         /* 0:Straight, 1: diverging */
00262         aReturn = (inSwitch == 0) ? 1 : 0;
00263         break;
00264         
00265     case ADDR_ACC_DCC:
00266         /* 1:Straight, 0: diverging */
00267         aReturn = inSwitch;
00268         break;
00269         
00270     default:
00271         aReturn = inSwitch;
00272         break;
00273     }
00274     
00275     return aReturn;
00276     
00277 }
00278 
00279 word DSGatewayLib::GetLocIDProtocol(byte address)
00280 {
00281     if( address < 0x04)
00282     {
00283             return ADDR_MM2;
00284     }
00285     else if( (address >= 0x30) && (address <= 0x33))
00286     {
00287             return ADDR_ACC_MM2;
00288     }
00289     else if( (address >= 0x38) && (address <= 0x3F))
00290     {
00291             return ADDR_ACC_DCC;
00292     }
00293     else if( (address >= 0x40) && (address <= 0x70))
00294     {
00295             return ADDR_MFX;
00296     }
00297     else if( (address >= 0xC0) && (address <= 0xFF))
00298     {
00299             return ADDR_DCC;
00300     }
00301     else
00302     {
00303         return 0;
00304     }
00305 }
00306 
00307 bool DSGatewayLib::WriteConfig(word address, word number, byte value)
00308 {
00309     unsigned char aPacktes[SIZE_PACKET];
00310     
00311     word aOffsetCVNo;
00312     
00313     if( address >= ADDR_DCC)
00314     {
00315         aOffsetCVNo = number;
00316     }
00317     else
00318     {
00319         aOffsetCVNo = number | 0x8000;
00320     }
00321 
00322     clearMessage(aPacktes);
00323 
00324     aPacktes[0] = CMD_CVWRITE | 0x05;
00325     aPacktes[1] = lowByte(aOffsetCVNo);
00326     aPacktes[2] = highByte(aOffsetCVNo);
00327     aPacktes[3] = value; 
00328     aPacktes[4] = generateCRC(aPacktes, 4);
00329 
00330     return exchangeMessage(aPacktes, TIME_REPLY);
00331 }
00332 
00333 bool DSGatewayLib::ReadConfig(word address, word number, byte *value)
00334 {
00335     unsigned char aPacktes[SIZE_PACKET];
00336 
00337     clearMessage(aPacktes);
00338 
00339     aPacktes[0] = CMD_CVREAD || 0x04;
00340     aPacktes[1] = lowByte(number);
00341     aPacktes[2] = highByte(number);
00342     aPacktes[3] = generateCRC(aPacktes, 3);
00343     
00344     *value = 0;
00345 
00346     return exchangeMessage(aPacktes, TIME_REPLY);
00347 }
00348 
00349 
00350 unsigned char DSGatewayLib::generateCRC(unsigned char *inPackets, unsigned char inLen)
00351 {
00352     unsigned char aCRC = inPackets[0];
00353 
00354     for( int i = 1; i < inLen; i++)
00355     {
00356         aCRC = aCRC ^ inPackets[i];
00357     }
00358     
00359     return aCRC;
00360 
00361 }
00362 
00363 byte lowByte(short int low) {
00364     byte bytelow = 0;
00365     bytelow = (low & 0xFF);
00366     return bytelow;
00367 }
00368 
00369 byte highByte(short int high) {
00370     byte bytehigh = 0;
00371     bytehigh = ((high >> 8) & 0xFF);
00372     return bytehigh;
00373 }
00374 
00375 unsigned char reverseByte(unsigned char inByte)
00376 {
00377     
00378     unsigned char aTemp = 0;
00379     
00380     for( int i = 0; i < 8; i++)
00381     {
00382         aTemp = aTemp | (((inByte >> i) & 0x01) << (7 - i));
00383     }   
00384     
00385     return aTemp;
00386     
00387 }