/// <summary> /// Constructor /// </summary> /// <param name="comm">Object implementing the <see cref="ICommunication"/> interface for talking to the brick</param> /// <param name="alwaysSendEvents">Send events when data changes, or at every poll</param> public Brick(ICommunication comm, bool alwaysSendEvents) { _directCommand = new DirectCommand(this); _systemCommand = new SystemCommand(this); _batchCommand = new Command(this); Buttons = new BrickButtons(); _alwaysSendEvents = alwaysSendEvents; int index = 0; _comm = comm; _comm.ReportReceived += ReportReceived; Ports = new Dictionary<InputPort,Port>(); foreach(InputPort i in Enum.GetValues(typeof(InputPort))) { Ports[i] = new Port { InputPort = i, Index = index++, Name = i.ToString(), }; } }
internal async Task SetLedPatternAsyncInternal(LedPattern ledPattern) { Command c = new Command(CommandType.DirectNoReply); c.SetLedPattern(ledPattern); await _brick.SendCommandAsyncInternal(c); }
internal async Task CreateDirectoryAsyncInternal(string devicePath) { Response r = ResponseManager.CreateResponse(); Command c = new Command(CommandType.SystemReply); c.CreateDirectory(devicePath); await _brick.SendCommandAsyncInternal(c); if(r.SystemReplyStatus != SystemReplyStatus.Success) throw new Exception("Error creating directory: " + r.SystemReplyStatus); }
internal async Task SetMotorPolarityAsyncInternal(OutputPort ports, Polarity polarity) { Command c = new Command(CommandType.DirectNoReply); c.SetMotorPolarity(ports, polarity); await _brick.SendCommandAsyncInternal(c); }
internal async Task SendCommandAsyncInternal(Command c) { await _comm.WriteAsync(c.ToBytes()); if(c.CommandType == CommandType.DirectReply || c.CommandType == CommandType.SystemReply) await ResponseManager.WaitForResponseAsync(c.Response); }
internal async Task OutputReadyAsyncInternal(OutputPort ports) { Command c = new Command(CommandType.DirectNoReply); c.OutputReady(ports); await _brick.SendCommandAsyncInternal(c); }
internal async Task StepMotorAtSpeedAsyncInternal(OutputPort ports, int speed, uint rampUpSteps, uint constantSteps, uint rampDownSteps, bool brake) { Command c = new Command(CommandType.DirectNoReply); c.StepMotorAtSpeed(ports, speed, rampUpSteps, constantSteps, rampDownSteps, brake); await _brick.SendCommandAsyncInternal(c); }
internal async Task DrawTextAsyncInternal(Color color, ushort x, ushort y, string text) { Command c = new Command(CommandType.DirectNoReply); c.DrawText(color, x, y, text); await _brick.SendCommandAsyncInternal(c); }
internal async Task DrawFillWindowAsyncInternal(Color color, ushort y0, ushort y1) { Command c = new Command(CommandType.DirectNoReply); c.DrawFillWindow(color, y0, y1); await _brick.SendCommandAsyncInternal(c); }
internal async Task DrawInverseRectangleAsyncInternal(ushort x, ushort y, ushort width, ushort height) { Command c = new Command(CommandType.DirectNoReply); c.DrawInverseRectangle(x, y, width, height); await _brick.SendCommandAsyncInternal(c); }
internal async Task DrawCircleAsyncInternal(Color color, ushort x, ushort y, ushort radius, bool filled) { Command c = new Command(CommandType.DirectNoReply); c.DrawCircle(color, x, y, radius, filled); await _brick.SendCommandAsyncInternal(c); }
internal async Task DrawRectangleAsyncInternal(Color color, ushort x, ushort y, ushort width, ushort height, bool filled) { Command c = new Command(CommandType.DirectNoReply); c.DrawRectangle(color, x, y, width, height, filled); await _brick.SendCommandAsyncInternal(c); }
internal async Task DrawPixelAsyncInternal(Color color, ushort x, ushort y) { Command c = new Command(CommandType.DirectNoReply); c.DrawPixel(color, x, y); await _brick.SendCommandAsyncInternal(c); }
internal async Task DrawLineAsyncInternal(Color color, ushort x0, ushort y0, ushort x1, ushort y1) { Command c = new Command(CommandType.DirectNoReply); c.DrawLine(color, x0, y0, x1, y1); await _brick.SendCommandAsyncInternal(c); }
internal async Task<int> ReadyPercentAsyncInternal(InputPort port, int mode) { Command c = new Command(CommandType.DirectReply, 1, 0); c.ReadyRaw(port, mode, 0); await _brick.SendCommandAsyncInternal(c); return c.Response.Data[0]; }
internal async Task DrawImageAsyncInternal(Color color, ushort x, ushort y, string devicePath) { Command c = new Command(CommandType.DirectNoReply); c.DrawImage(color, x ,y, devicePath); await _brick.SendCommandAsyncInternal(c); }
internal async Task<string> GetModeNameAsyncInternal(InputPort port, int mode) { Command c = new Command(CommandType.DirectReply, 0x7f, 0); c.GetModeName(port, mode, 0x7f, 0); await _brick.SendCommandAsyncInternal(c); int index = Array.IndexOf(c.Response.Data, (byte)0); return Encoding.UTF8.GetString(c.Response.Data, 0, index); }
internal async Task SelectFontAsyncInternal(FontType fontType) { Command c = new Command(CommandType.DirectNoReply); c.SelectFont(fontType); await _brick.SendCommandAsyncInternal(c); }
internal async Task TurnMotorAtSpeedAsyncInternal(OutputPort ports, int speed) { Command c = new Command(CommandType.DirectNoReply); c.TurnMotorAtSpeed(ports, speed); c.StartMotor(ports); await _brick.SendCommandAsyncInternal(c); }
internal async Task EnableTopLineAsyncInternal(bool enabled) { Command c = new Command(CommandType.DirectNoReply); c.EnableTopLine(enabled); await _brick.SendCommandAsyncInternal(c); }
internal async Task TurnMotorAtSpeedForTimeAsyncInternal(OutputPort ports, int speed, uint msRampUp, uint msConstant, uint msRampDown, bool brake) { Command c = new Command(CommandType.DirectNoReply); c.TurnMotorAtSpeedForTime(ports, speed, msRampUp, msConstant, msRampDown, brake); await _brick.SendCommandAsyncInternal(c); }
internal async Task DrawDottedLineAsyncInternal(Color color, ushort x0, ushort y0, ushort x1, ushort y1, ushort onPixels, ushort offPixels) { Command c = new Command(CommandType.DirectNoReply); c.DrawDottedLine(color, x0, y0, x1, y1, onPixels, offPixels); await _brick.SendCommandAsyncInternal(c); }
internal async Task StartMotorAsyncInternal(OutputPort ports) { Command c = new Command(CommandType.DirectNoReply); c.StartMotor(ports); await _brick.SendCommandAsyncInternal(c); }
internal async Task UpdateUIAsyncInternal() { Command c = new Command(CommandType.DirectNoReply); c.UpdateUI(); await _brick.SendCommandAsyncInternal(c); }
private async Task PollSensorsAsync() { bool changed = false; const int responseSize = 11; int index = 0; Command c = new Command(CommandType.DirectReply, (8 * responseSize) + 6, 0); foreach(InputPort i in Enum.GetValues(typeof(InputPort))) { Port p = Ports[i]; index = p.Index * responseSize; c.GetTypeMode(p.InputPort, (byte)index, (byte)(index+1)); c.ReadySI(p.InputPort, p.Mode, (byte)(index+2)); c.ReadyRaw(p.InputPort, p.Mode, (byte)(index+6)); c.ReadyPercent(p.InputPort, p.Mode, (byte)(index+10)); } index += responseSize; c.IsBrickButtonPressed(BrickButton.Back, (byte)(index+0)); c.IsBrickButtonPressed(BrickButton.Left, (byte)(index+1)); c.IsBrickButtonPressed(BrickButton.Up, (byte)(index+2)); c.IsBrickButtonPressed(BrickButton.Right, (byte)(index+3)); c.IsBrickButtonPressed(BrickButton.Down, (byte)(index+4)); c.IsBrickButtonPressed(BrickButton.Enter, (byte)(index+5)); await SendCommandAsyncInternal(c); if(c.Response.Data == null) return; foreach(InputPort i in Enum.GetValues(typeof(InputPort))) { Port p = Ports[i]; int type = c.Response.Data[(p.Index * responseSize)+0]; byte mode = c.Response.Data[(p.Index * responseSize)+1]; float siValue = BitConverter.ToSingle(c.Response.Data, (p.Index * responseSize)+2); int rawValue = BitConverter.ToInt32(c.Response.Data, (p.Index * responseSize)+6); byte percentValue = c.Response.Data[(p.Index * responseSize)+10]; if((byte)p.Type != type || Math.Abs(p.SIValue - siValue) > 0.01f || p.RawValue != rawValue || p.PercentValue != percentValue) changed = true; if(Enum.IsDefined(typeof(DeviceType), type)) p.Type = (DeviceType)type; else p.Type = DeviceType.Unknown; p.SIValue = siValue; p.RawValue = rawValue; p.PercentValue = percentValue; } if( Buttons.Back != (c.Response.Data[index+0] == 1) || Buttons.Left != (c.Response.Data[index+1] == 1) || Buttons.Up != (c.Response.Data[index+2] == 1) || Buttons.Right != (c.Response.Data[index+3] == 1) || Buttons.Down != (c.Response.Data[index+4] == 1) || Buttons.Enter != (c.Response.Data[index+5] == 1) ) changed = true; Buttons.Back = (c.Response.Data[index+0] == 1); Buttons.Left = (c.Response.Data[index+1] == 1); Buttons.Up = (c.Response.Data[index+2] == 1); Buttons.Right = (c.Response.Data[index+3] == 1); Buttons.Down = (c.Response.Data[index+4] == 1); Buttons.Enter = (c.Response.Data[index+5] == 1); if(changed || _alwaysSendEvents) OnBrickChanged(new BrickChangedEventArgs { Ports = this.Ports, Buttons = this.Buttons }); }
internal async Task<byte[]> GetTypeModeAsyncInternal(InputPort port) { Command c = new Command(CommandType.DirectReply, 2, 0); c.GetTypeMode(port, 0, 1); await _brick.SendCommandAsyncInternal(c); return c.Response.Data; }
internal async Task DeleteFileAsyncInternal(string devicePath) { Response r = ResponseManager.CreateResponse(); Command c = new Command(CommandType.SystemReply); c.DeleteFile(devicePath); await _brick.SendCommandAsyncInternal(c); if(r.SystemReplyStatus != SystemReplyStatus.Success) throw new Exception("Error deleting file: " + r.SystemReplyStatus); }
internal async Task<int> ReadyRawAsyncInternal(InputPort port, int mode) { Command c = new Command(CommandType.DirectReply, 4, 0); c.ReadyRaw(port, mode, 0); await _brick.SendCommandAsyncInternal(c); return BitConverter.ToInt32(c.Response.Data, 0); }
internal async Task WriteFileAsyncInternal(byte[] data, string devicePath) { const int chunkSize = 960; Command commandBegin = new Command(CommandType.SystemReply); commandBegin.AddOpcode(SystemOpcode.BeginDownload); commandBegin.AddRawParameter((uint)data.Length); commandBegin.AddRawParameter(devicePath); await _brick.SendCommandAsyncInternal(commandBegin); if(commandBegin.Response.SystemReplyStatus != SystemReplyStatus.Success) throw new Exception("Could not begin file save: " + commandBegin.Response.SystemReplyStatus); byte handle = commandBegin.Response.Data[0]; int sizeSent = 0; while(sizeSent < data.Length) { Command commandContinue = new Command(CommandType.SystemReply); commandContinue.AddOpcode(SystemOpcode.ContinueDownload); commandContinue.AddRawParameter(handle); int sizeToSend = Math.Min(chunkSize, data.Length - sizeSent); commandContinue.AddRawParameter(data, sizeSent, sizeToSend); sizeSent += sizeToSend; await _brick.SendCommandAsyncInternal(commandContinue); if(commandContinue.Response.SystemReplyStatus != SystemReplyStatus.Success && (commandContinue.Response.SystemReplyStatus != SystemReplyStatus.EndOfFile && sizeSent == data.Length)) throw new Exception("Error saving file: " + commandContinue.Response.SystemReplyStatus); } //Command commandClose = new Command(CommandType.SystemReply); //commandClose.AddOpcode(SystemOpcode.CloseFileHandle); //commandClose.AddRawParameter(handle); //await _brick.SendCommandAsyncInternal(commandClose); //if(commandClose.Response.SystemReplyStatus != SystemReplyStatus.Success) // throw new Exception("Could not close handle: " + commandClose.Response.SystemReplyStatus); }
internal async Task<bool> IsBrickButtonPressedAsyncInternal(BrickButton button) { Command c = new Command(CommandType.DirectReply, 1, 0); c.IsBrickButtonPressed(button, 0); await _brick.SendCommandAsyncInternal(c); return false; }