SV_STATUS doSVDeferredProcessing( void ) { if( DeferredProcessingRequired ) { lnMsg msg ; SV_Addr_t unData ; msg.sv.command = (byte) OPC_PEER_XFER ; msg.sv.mesg_size = (byte) 0x10 ; msg.sv.src = DeferredSrcAddr ; msg.sv.sv_cmd = SV_DISCOVER | (byte) 0x40 ; msg.sv.sv_type = (byte) 0x02 ; msg.sv.svx1 = (byte) 0x10 ; msg.sv.svx2 = (byte) 0x10 ; unData.stDecoded.unDestinationId.w = readSVDestinationId(); unData.stDecoded.unVendorIdOrSvAddress.w = SV_VENDOR_ID; unData.stDecoded.unDeviceId.w = SV_DEVICE_ID; unData.stDecoded.unSerialNumber.b.lo = readSVStorage(SV_ADDR_SERIAL_NUMBER_L); unData.stDecoded.unSerialNumber.b.hi = readSVStorage(SV_ADDR_SERIAL_NUMBER_H); encodePeerData( &msg.px, unData.abPlain ); if( sendLocoNetPacketTry( &msg, LN_BACKOFF_INITIAL + ( unData.stDecoded.unSerialNumber.b.lo % (byte) 10 ) ) != LN_DONE ) return SV_DEFERRED_PROCESSING_NEEDED ; DeferredProcessingRequired = 0 ; } return SV_OK ; }
LN_STATUS LocoNetClass::send(lnMsg *pPacket) { unsigned char ucTry; unsigned char ucPrioDelay = LN_BACKOFF_INITIAL; LN_STATUS enReturn; unsigned char ucWaitForEnterBackoff; for (ucTry = 0; ucTry < LN_TX_RETRIES_MAX; ucTry++) { // wait previous traffic and than prio delay and than try tx ucWaitForEnterBackoff = 1; // don't want to abort do/while loop before do // we did not see the backoff state once { enReturn = sendLocoNetPacketTry(pPacket, ucPrioDelay); if (enReturn == LN_DONE) // success? return LN_DONE; if (enReturn == LN_PRIO_BACKOFF) ucWaitForEnterBackoff = 0; // now entered backoff -> next state != LN_BACKOFF is worth incrementing the try counter } while ((enReturn == LN_CD_BACKOFF) || // waiting CD backoff (enReturn == LN_PRIO_BACKOFF) || // waiting master+prio backoff ((enReturn == LN_NETWORK_BUSY) && ucWaitForEnterBackoff)); // or within any traffic unfinished // failed -> next try going to higher prio = smaller prio delay if (ucPrioDelay > LN_BACKOFF_MIN) ucPrioDelay--; } LnBuffer.Stats.TxErrors++ ; return LN_RETRY_ERROR; }
LN_STATUS LocoNetClass::send( uint8_t OpCode, uint8_t Data1, uint8_t Data2, uint8_t PrioDelay ) { lnMsg SendPacket ; SendPacket.data[ 0 ] = OpCode ; SendPacket.data[ 1 ] = Data1 ; SendPacket.data[ 2 ] = Data2 ; return sendLocoNetPacketTry( &SendPacket, PrioDelay ) ; }
LN_STATUS LocoNetClass::send(lnMsg *pPacket, uint8_t ucPrioDelay) { return sendLocoNetPacketTry(pPacket, ucPrioDelay); }