/// <summary> /// Set the interface to low (false) or high (true) speed /// </summary> /// <remarks> /// The caller must also tell the PCM to switch speeds /// </remarks> protected override async Task <bool> SetVpwSpeedInternal(VpwSpeed newSpeed) { if (newSpeed == VpwSpeed.Standard) { this.Logger.AddDebugMessage("AVT setting VPW 1X"); await this.Port.Send(AvtDevice.AVT_1X_SPEED.GetBytes()); await Task.Delay(100); byte[] rx = new byte[2]; await ReadAVTPacket(); // C1 00 (switched to 1x) } else { byte[] rx = new byte[4]; await Task.Delay(100); await ReadAVTPacket(); // 23 83 00 20 AVT generated response from generic PCM switch high speed command in Vehicle.cs this.Logger.AddDebugMessage("AVT setting VPW 4X"); await this.Port.Send(AvtDevice.AVT_4X_SPEED.GetBytes()); await Task.Delay(500); // This can take a while.... await ReadAVTPacket(); // C1 01 (switched to 4x) } return(true); }
/// <summary> /// Set the interface to 1x or 4x speed /// </summary> /// <remarks> /// The caller must also tell the PCM to switch speeds /// </remarks> protected override async Task <bool> SetVpwSpeedInternal(VpwSpeed newSpeed) { byte[] Msg = OBDXProDevice.DVI_Set_Speed.GetBytes(); if (newSpeed == VpwSpeed.Standard) { this.Logger.AddDebugMessage("DVI setting VPW 1X"); Msg[3] = 0; this.vpwSpeed = VpwSpeed.Standard; } else { this.Logger.AddDebugMessage("DVI setting VPW 4X"); Msg[3] = 1; this.vpwSpeed = VpwSpeed.FourX; } Msg[Msg.Length - 1] = CalcChecksum(Msg); await this.Port.Send(Msg); byte[] RespBytes = new byte[Msg.Length]; Array.Copy(Msg, RespBytes, Msg.Length); RespBytes[0] += (byte)0x10; RespBytes[RespBytes.Length - 1] = CalcChecksum(RespBytes); Response <Message> m = await FindResponseFromTool(RespBytes); if (m.Status != ResponseStatus.Success) { return(false); } return(true); }
/// <summary> /// Set the interface to low (false) or high (true) speed /// </summary> /// <remarks> /// The caller must also tell the PCM to switch speeds /// </remarks> protected override Task <bool> SetVpwSpeedInternal(VpwSpeed newSpeed) { if (newSpeed == VpwSpeed.Standard) { this.Logger.AddDebugMessage("J2534 setting VPW 1X"); //Disconnect from current protocol DisconnectFromProtocol(); //Connect at new speed ConnectToProtocol(ProtocolID.J1850VPW, BaudRate.J1850VPW_10400, ConnectFlag.NONE); //Set Filter SetFilter(0xFEFFFF, 0x6CF060, 0, TxFlag.NONE, FilterType.PASS_FILTER); //if (m.Status != ResponseStatus.Success) //{ // this.Logger.AddDebugMessage("Failed to set filter, J2534 error code: 0x" + m.Value.ToString("X2")); // return false; //} } else { this.Logger.AddDebugMessage("J2534 setting VPW 4X"); //Disconnect from current protocol DisconnectFromProtocol(); //Connect at new speed ConnectToProtocol(ProtocolID.J1850VPW, BaudRate.J1850VPW_41600, ConnectFlag.NONE); //Set Filter SetFilter(0xFEFFFF, 0x6CF060, 0, TxFlag.NONE, FilterType.PASS_FILTER); } return(Task.FromResult(true)); }
/// <summary> /// Set the interface to low (false) or high (true) speed /// </summary> /// <remarks> /// The caller must also tell the PCM to switch speeds /// </remarks> protected override async Task <bool> SetVpwSpeedInternal(VpwSpeed newSpeed) { if (newSpeed == VpwSpeed.Standard) { this.Logger.AddDebugMessage("DVI setting VPW 1X"); await this.Port.Send(DviDevice.DVI_1X_SPEED.GetBytes()); Response <Message> m = await this.FindResponse(DVI_VPW1X_RESP); if (m.Status != ResponseStatus.Success) { return(false); } } else { this.Logger.AddDebugMessage("DVI setting VPW 4X"); await this.Port.Send(DviDevice.DVI_4X_SPEED.GetBytes()); Response <Message> m = await this.FindResponse(DVI_VPW4X_RESP); if (m.Status != ResponseStatus.Success) { return(false); } } return(true); }
/// <summary> /// Constructor. /// </summary> public Device(ILogger logger) { this.Logger = logger; // These default values can be overwritten in derived classes. this.MaxSendSize = 100; this.MaxReceiveSize = 100; this.Supports4X = false; this.speed = VpwSpeed.Standard; }
/// <summary> /// Set the interface to low (false) or high (true) speed /// </summary> /// <remarks> /// The caller must also tell the PCM to switch speeds /// </remarks> protected override Task <bool> SetVpwSpeedInternal(VpwSpeed newSpeed) { if (newSpeed == VpwSpeed.Standard) { this.Logger.AddDebugMessage("Setting VPW 1X"); } else { this.Logger.AddDebugMessage("Setting VPW 4X"); } return(Task.FromResult(true)); }
/// <summary> /// Set the device's VPW data rate. /// </summary> public async Task <bool> SetVpwSpeed(VpwSpeed newSpeed) { if (this.speed == newSpeed) { return(true); } if (!await this.SetVpwSpeedInternal(newSpeed)) { return(false); } this.speed = newSpeed; return(true); }
/// <summary> /// Set the device's VPW data rate. /// </summary> public async Task <bool> SetVpwSpeed(VpwSpeed newSpeed) { if (this.Speed == newSpeed) { return(true); } if (((newSpeed == VpwSpeed.FourX) && (!Configuration.Enable4xReadWrite)) || (!await this.SetVpwSpeedInternal(newSpeed))) { return(false); } this.Speed = newSpeed; return(true); }
/// <summary> /// Set the interface to low (false) or high (true) speed /// </summary> /// <remarks> /// The caller must also tell the PCM to switch speeds /// </remarks> protected override async Task <bool> SetVpwSpeedInternal(VpwSpeed newSpeed) { if (newSpeed == VpwSpeed.Standard) { this.Logger.AddDebugMessage("AllPro setting VPW 1X"); if (!await this.SendAndVerify("AT VPW1", "OK")) { return(false); } } else { this.Logger.AddDebugMessage("AllPro setting VPW 4X"); if (!await this.SendAndVerify("AT VPW4", "OK")) { return(false); } } return(true); }
/// <summary> /// Set the interface to low (false) or high (true) speed /// </summary> protected abstract Task <bool> SetVpwSpeedInternal(VpwSpeed newSpeed);
/// <summary> /// Does everything required to switch to VPW 4x /// </summary> public async Task <bool> VehicleSetVPW4x(VpwSpeed newSpeed, ToolPresentNotifier notifier) { if (!device.Supports4X) { if (newSpeed == VpwSpeed.FourX) { // where there is no support only report no switch to 4x logger.AddUserMessage("This interface does not support VPW 4x"); } return(true); } // Configure the vehicle bus when switching to 4x if (newSpeed == VpwSpeed.FourX) { logger.AddUserMessage("Attempting switch to VPW 4x"); await device.SetTimeout(TimeoutScenario.ReadProperty); // The list of modules may not be useful after all, but // checking for an empty list indicates an uncooperative // module on the VPW bus. List <byte> modules = await this.RequestHighSpeedPermission(notifier); if (modules == null) { // A device has refused the switch to high speed mode. return(false); } Message broadcast = this.protocol.CreateBeginHighSpeed(DeviceId.Broadcast); await this.device.SendMessage(broadcast); // Check for any devices that refused to switch to 4X speed. // These responses usually get lost, so this code might be pointless. Message response = null; while ((response = await this.device.ReceiveMessage()) != null) { Response <bool> refused = this.protocol.ParseHighSpeedRefusal(response); if (refused.Status != ResponseStatus.Success) { // This should help ELM devices receive responses. await notifier.ForceNotify(); continue; } if (refused.Value == false) { // TODO: Add module number. this.logger.AddUserMessage("Module refused high-speed switch."); return(false); } } } else { logger.AddUserMessage("Reverting to VPW 1x"); } // Request the device to change await device.SetVpwSpeed(newSpeed); TimeoutScenario scenario = newSpeed == VpwSpeed.Standard ? TimeoutScenario.ReadProperty : TimeoutScenario.ReadMemoryBlock; await device.SetTimeout(scenario); return(true); }
/// <summary> /// Get the time required for the given scenario. /// </summary> public virtual int GetTimeoutMilliseconds(TimeoutScenario scenario, VpwSpeed speed) { // This base class is only instantiated for device-independent initialization. return(250); }
/// <summary> /// Get the time required for the given scenario. /// </summary> public override int GetTimeoutMilliseconds(TimeoutScenario scenario, VpwSpeed speed) { int milliseconds; if (speed == VpwSpeed.Standard) { switch (scenario) { case TimeoutScenario.Minimum: milliseconds = 0; break; case TimeoutScenario.ReadProperty: milliseconds = 25; break; case TimeoutScenario.ReadCrc: milliseconds = 100; break; case TimeoutScenario.ReadMemoryBlock: milliseconds = 250; break; case TimeoutScenario.EraseMemoryBlock: milliseconds = 1000; break; case TimeoutScenario.WriteMemoryBlock: milliseconds = 200; break; case TimeoutScenario.SendKernel: milliseconds = 500; break; case TimeoutScenario.DataLogging1: milliseconds = 25; break; case TimeoutScenario.DataLogging2: milliseconds = 40; break; case TimeoutScenario.DataLogging3: milliseconds = 60; break; case TimeoutScenario.Maximum: return(1020); default: throw new NotImplementedException("Unknown timeout scenario " + scenario); } } else { switch (scenario) { case TimeoutScenario.Minimum: milliseconds = 0; break; // The app doesn't currently do this in 4X mode, so this is only a guess. case TimeoutScenario.ReadProperty: milliseconds = 12; break; case TimeoutScenario.ReadCrc: milliseconds = 100; break; case TimeoutScenario.ReadMemoryBlock: milliseconds = 50; break; case TimeoutScenario.EraseMemoryBlock: milliseconds = 1000; break; case TimeoutScenario.WriteMemoryBlock: milliseconds = 170; break; case TimeoutScenario.SendKernel: milliseconds = 10; break; case TimeoutScenario.DataLogging1: milliseconds = 7; break; case TimeoutScenario.DataLogging2: milliseconds = 10; break; case TimeoutScenario.DataLogging3: milliseconds = 15; break; case TimeoutScenario.Maximum: return(1020); default: throw new NotImplementedException("Unknown timeout scenario " + scenario); } } return(milliseconds); }
/// <summary> /// Get the time required for the given scenario. /// </summary> public override int GetTimeoutMilliseconds(TimeoutScenario scenario, VpwSpeed speed) { int milliseconds; if (speed == VpwSpeed.Standard) { switch (scenario) { case TimeoutScenario.Minimum: milliseconds = 0; break; case TimeoutScenario.ReadProperty: milliseconds = 25; break; case TimeoutScenario.ReadCrc: milliseconds = 100; break; case TimeoutScenario.ReadMemoryBlock: milliseconds = 110; break; case TimeoutScenario.EraseMemoryBlock: milliseconds = 1000; break; case TimeoutScenario.WriteMemoryBlock: milliseconds = 800; // 125 works, added some for safety break; case TimeoutScenario.SendKernel: milliseconds = 500; break; case TimeoutScenario.DataLogging1: milliseconds = 25; break; case TimeoutScenario.DataLogging2: milliseconds = 40; break; case TimeoutScenario.DataLogging3: milliseconds = 60; break; case TimeoutScenario.Maximum: return(1020); default: throw new NotImplementedException("Unknown timeout scenario " + scenario); } } else { throw new NotImplementedException("Since when did ScanTool devices support 4x?"); } return(milliseconds); }
/// <summary> /// Does everything required to switch to VPW 4x /// </summary> public async Task <bool> VehicleSetVPW4x(VpwSpeed newSpeed) { if (!device.Supports4X) { if (newSpeed == VpwSpeed.FourX) { // where there is no support only report no switch to 4x logger.AddUserMessage("This interface does not support VPW 4x"); } return(true); } // Configure the vehicle bus when switching to 4x if (newSpeed == VpwSpeed.FourX) { logger.AddUserMessage("Attempting switch to VPW 4x"); await device.SetTimeout(TimeoutScenario.ReadProperty); // The list of modules may not be useful after all, but // checking for an empty list indicates an uncooperative // module on the VPW bus. List <byte> modules = await this.RequestHighSpeedPermission(notifier); if (modules == null) { // A device has refused the switch to high speed mode. return(false); } // Since we had some issue with other modules not staying quiet... await this.ForceSendToolPresentNotification(); Message broadcast = this.protocol.CreateBeginHighSpeed(DeviceId.Broadcast); await this.device.SendMessage(broadcast); // Check for any devices that refused to switch to 4X speed. // These responses usually get lost, so this code might be pointless. Stopwatch sw = new Stopwatch(); sw.Start(); Message response = null; // WARNING: The AllPro stopped receiving permission-to-upload messages when this timeout period // was set to 1500ms. Reducing it to 500 seems to have fixed that problem. // // It would be nice to find a way to wait equally long with all devices, as refusal messages // are still a potetial source of trouble. while (((response = await this.device.ReceiveMessage()) != null) && (sw.ElapsedMilliseconds < 500)) { Response <bool> refused = this.protocol.ParseHighSpeedRefusal(response); if (refused.Status != ResponseStatus.Success) { // This should help ELM devices receive responses. await Task.Delay(100); await notifier.ForceNotify(); continue; } if (refused.Value == false) { // TODO: Add module number. this.logger.AddUserMessage("Module refused high-speed switch."); return(false); } } } else { logger.AddUserMessage("Reverting to VPW 1x"); } // Request the device to change await device.SetVpwSpeed(newSpeed); // Since we had some issue with other modules not staying quiet... await this.ForceSendToolPresentNotification(); return(true); }