Desktop Station gateway software for mbed
Dependents: DSGatewayMBED_Nucleo DSGatewayMBED_Nucleo_Step128
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 }
Generated on Wed Jul 13 2022 10:53:18 by 1.7.2