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)));
        }
Exemplo n.º 2
0
        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);
        }