internal override void ToBitfieldWrapper() { _bitfieldWrapper = new GlowImmediateBitfieldWrapper(); _bitfieldWrapper.AddBitfield(_bitfieldWrapper.ColorBitmap); _bitfieldWrapper.AddBitfield(_bitfieldWrapper.ActionOpcode); // Set action opcode: _bitfieldWrapper.ActionOpcode.SetValue((int)ActionOpCode.SetVal); // Set color bitmap (using any led in group as they all have same color): if (LedColor.Red > -1) { _bitfieldWrapper.ColorBitmap.SetFlag((int)ColorSpecifier.Red); var valueBitfield = new Bitfield(width: 8, name: "red value"); valueBitfield.SetValue((uint)LedColor.Red); _bitfieldWrapper.AddBitfield(valueBitfield); } if (LedColor.Green > -1) { _bitfieldWrapper.ColorBitmap.SetFlag((int)ColorSpecifier.Green); var valueBitfield = new Bitfield(width: 8, name: "green value"); valueBitfield.SetValue((uint)LedColor.Green); _bitfieldWrapper.AddBitfield(valueBitfield); } if (LedColor.Blue > -1) { _bitfieldWrapper.ColorBitmap.SetFlag((int)ColorSpecifier.Blue); var valueBitfield = new Bitfield(width: 8, name: "blue value"); valueBitfield.SetValue((uint)LedColor.Blue); _bitfieldWrapper.AddBitfield(valueBitfield); } if (LedColor.Bright > -1) { _bitfieldWrapper.ColorBitmap.SetFlag((int)ColorSpecifier.Bright); var valueBitfield = new Bitfield(width: 5, name: "bright value"); valueBitfield.SetValue((uint)LedColor.Bright); _bitfieldWrapper.AddBitfield(valueBitfield); } // Add led bitmap (led index increases from left to right): _bitfieldWrapper.LedBitmap = new Bitfield(width: DeviceTable.Dev.LedCount, name: "led bitmap"); _bitfieldWrapper.AddBitfield(_bitfieldWrapper.LedBitmap); LedIdxList.ToList().ForEach(idx => _bitfieldWrapper.LedBitmap.SetFlag((uint)(DeviceTable.Dev.LedCount - idx - 1))); }
private Instruction_ContextRegion BuildContextRegionBitfields(List <List <Instruction> > instrSets, out uint contextRegionByteSize, out uint maxInstrPathByteSize) { var contextRegion = new Instruction_ContextRegion(); contextRegion.ToBitfieldWrapper(); // Build common context-region: var contextRegionByteLenBitfield = new Bitfield(width: 16, name: "contx-reg byte len"); var instrRegionByteLenBitfield = new Bitfield(width: 32, name: "instr-reg byte len"); var ledCountBitfield = new Bitfield(width: 16, value: DeviceTable.Dev.LedCount, name: "total led len"); var timerIntervalMs = new Bitfield(width: 16, value: DeviceTable.Dev.TickIntervalMs, name: "tick interval ms"); var simBrightCoeffBitfield = new Bitfield(width: 16, value: DeviceTable.Dev.SimulatorBrightnessCoeff, name: "sim bright coeff"); var totalPathsBitfield = new Bitfield(width: 8, value: (uint)instrSets.Count, name: "total paths"); var pathEndedBitmap = new Bitfield(width: (uint)instrSets.Count, name: "path end bitmap"); contextRegion.BitfieldWrapper.AddBitfield(contextRegionByteLenBitfield); contextRegion.BitfieldWrapper.AddBitfield(instrRegionByteLenBitfield); contextRegion.BitfieldWrapper.AddBitfield(ledCountBitfield); contextRegion.BitfieldWrapper.AddBitfield(timerIntervalMs); contextRegion.BitfieldWrapper.AddBitfield(simBrightCoeffBitfield); contextRegion.BitfieldWrapper.AddBitfield(totalPathsBitfield); contextRegion.BitfieldWrapper.AddBitfield(pathEndedBitmap); uint totalInstrRegionByteLen = 0; maxInstrPathByteSize = 0; // Build a context-region block for each path: for (var i = 0; i < instrSets.Count; i++) { // Mark current path as ended (except path 0): if (i > 0) { pathEndedBitmap.SetFlag((uint)(instrSets.Count - i - 1)); } // Add start of current path byte-address bitfield: if ((instrSets[i].First().BitAddress - instrSets[0].First().BitAddress) % BitsPerByte > 0) { Console.WriteLine("Byte alignment error"); throw new Exception(); } var pathStartByteAddr = (instrSets[i].First().BitAddress - instrSets[0].First().BitAddress) >> BitByteShift; var opcode2Bit = MiscOps.GetOpcode2Bit(pathStartByteAddr, out var valueBitWidth); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: 2, value: opcode2Bit, name: "byte width opcode")); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: valueBitWidth, value: pathStartByteAddr, name: $"path={i} byte addr")); // Add current path byte-length bitfield: var instrPathByteLen = (instrSets[i].Last().BitAddress + instrSets[i].Last().BitfieldWrapper.BitWidth - instrSets[i].First().BitAddress) >> BitByteShift; opcode2Bit = MiscOps.GetOpcode2Bit(instrPathByteLen, out valueBitWidth); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: 2, value: opcode2Bit, name: "byte width opcode")); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: valueBitWidth, value: instrPathByteLen, name: $"path={i} byte len")); // Keep running total of paths length: totalInstrRegionByteLen += instrPathByteLen; maxInstrPathByteSize = Math.Max(maxInstrPathByteSize, instrPathByteLen); // Add current path instruction bit address bitfield: var instrBitAddr = instrPathByteLen << BitByteShift; // max possible value is number of bits in path. opcode2Bit = MiscOps.GetOpcode2Bit(instrBitAddr, out valueBitWidth); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: 2, value: opcode2Bit, name: "byte width opcode")); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: valueBitWidth, value: 0, name: $"path={i} instr bit addr")); // Add current path extra-value bitfield: uint maxValue = 0; var rampInstrs = instrSets[i].Where(x => x.Type == Instruction.InstrType.GlowRamp); if (rampInstrs.Count() > 0) { maxValue = rampInstrs.Max(x => ((GlowRampInstruction)x).RampTicks); } var opcode3Bit = MiscOps.GetOpcode3Bit(maxValue, out valueBitWidth); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: 3, value: opcode3Bit, name: "byte width opcode")); if (valueBitWidth > 0) { contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: valueBitWidth, value: 0, name: $"path={i} extra value")); } // Add current path pause-ticks bitfield: maxValue = 0; var pauseInstrs = instrSets[i].Where(x => x.Type == Instruction.InstrType.Pause); if (pauseInstrs.Count() > 0) { maxValue = pauseInstrs.Max(x => ((PauseInstruction)x).Ticks); } else if (rampInstrs.Count() > 0) { maxValue = 1; } opcode3Bit = MiscOps.GetOpcode3Bit(maxValue, out valueBitWidth); contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: 3, value: opcode3Bit, name: "byte width opcode")); if (valueBitWidth > 0) { contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(width: valueBitWidth, value: 0, name: $"path={i} pause ticks")); } } // Set total instruction region byte length: instrRegionByteLenBitfield.SetValue(totalInstrRegionByteLen); // Add padding to context-region so following instruction path memory is byte-aligned: var paddingWidth = BitsPerByte - (contextRegion.BitfieldWrapper.BitWidth % BitsPerByte); if (paddingWidth < 8) { contextRegion.BitfieldWrapper.AddBitfield(new Bitfield(paddingWidth, "byte-align padding")); } // Set total context-region byte length (convert from bits): contextRegionByteSize = contextRegion.BitfieldWrapper.BitWidth >> BitByteShift; contextRegionByteLenBitfield.SetValue(contextRegionByteSize); return(contextRegion); }