예제 #1
0
            internal override Tuple <DataTypeBase, DataTypeBase> transform(DataProcessorConfig config, DataProcessor dpModule)
            {
                switch (config.id)
                {
                case DataProcessorConfig.CombinerConfig.ID: {
                    DataAttributes attributes = new DataAttributes(new byte[] { this.attributes.sizes[0] }, 1, 0, false);
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, attributes), null));
                }
                }

                return(base.transform(config, dpModule));
            }
예제 #2
0
        internal static String createIdentifier(DataTypeBase dataType, DataProcessor dataprocessor, Version firmware, byte revision)
        {
            byte register = Util.clearRead(dataType.eventConfig[1]);

            switch (register)
            {
            case NOTIFY:
            case STATE:
                var processor = dataprocessor.lookupProcessor(dataType.eventConfig[2]);
                DataProcessorConfig config = DataProcessorConfig.from(firmware, revision, processor.Item2.config);

                return(config.CreateIdentifier(register == STATE, dataType.eventConfig[2]));

            default:
                return(null);
            }
        }
예제 #3
0
        internal virtual Tuple <DataTypeBase, DataTypeBase> transform(DataProcessorConfig config)
        {
            switch (config.id)
            {
            case DataProcessorConfig.BufferConfig.ID:
                return(Tuple.Create(
                           new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, new DataAttributes(new byte[] { }, 0, 0, false)) as DataTypeBase,
                           dataProcessorStateCopy(this, this.attributes)
                           ));

            case DataProcessorConfig.AccumulatorConfig.ID: {
                DataProcessorConfig.AccumulatorConfig casted = (DataProcessorConfig.AccumulatorConfig)config;
                DataAttributes attributes = new DataAttributes(new byte[] { casted.output }, 1, 0, !casted.counter && this.attributes.signed);

                return(Tuple.Create(
                           casted.counter ? new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, attributes) : dataProcessorCopy(this, attributes),
                           casted.counter ? new IntegralDataType(null, DATA_PROCESSOR, Util.setRead(DataProcessor.STATE), NO_ID, attributes) :
                           dataProcessorStateCopy(this, attributes)
                           ));
            }

            case DataProcessorConfig.AverageConfig.ID:
            case DataProcessorConfig.DelayConfig.ID:
            case DataProcessorConfig.TimeConfig.ID:
                return(Tuple.Create <DataTypeBase, DataTypeBase>(dataProcessorCopy(this, this.attributes.dataProcessorCopy()), null));

            case DataProcessorConfig.PassthroughConfig.ID:
                return(Tuple.Create(
                           dataProcessorCopy(this, this.attributes.dataProcessorCopy()),
                           new IntegralDataType(DATA_PROCESSOR, Util.setRead(DataProcessor.STATE), NO_ID, new DataAttributes(new byte[] { 2 }, 1, 0, false)) as DataTypeBase
                           ));

            case DataProcessorConfig.MathConfig.ID: {
                DataProcessorConfig.MathConfig casted = (DataProcessorConfig.MathConfig)config;
                DataTypeBase processor = null;
                switch (casted.op)
                {
                case Add:
                    processor = dataProcessorCopy(this, this.attributes.dataProcessorCopySize(4));
                    break;

                case Multiply:
                    processor = dataProcessorCopy(this, this.attributes.dataProcessorCopySize(Math.Abs(casted.rhs) < 1 ? this.attributes.sizes[0] : (byte)4));
                    break;

                case Divide:
                    processor = dataProcessorCopy(this, this.attributes.dataProcessorCopySize(Math.Abs(casted.rhs) < 1 ? (byte)4 : this.attributes.sizes[0]));
                    break;

                case Subtract:
                    processor = dataProcessorCopy(this, this.attributes.dataProcessorCopySigned(true));
                    break;

                case AbsValue:
                    processor = dataProcessorCopy(this, this.attributes.dataProcessorCopySigned(false));
                    break;

                case Modulus:
                    processor = dataProcessorCopy(this, this.attributes.dataProcessorCopy());
                    break;

                case Exponent:
                    processor = new ByteArrayDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, this.attributes.dataProcessorCopySize(4));
                    break;

                case LeftShift:
                    processor = new ByteArrayDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY,
                                                      this.attributes.dataProcessorCopySize((byte)Math.Min(this.attributes.sizes[0] + (casted.rhs / 8), 4)));
                    break;

                case RightShift:
                    processor = new ByteArrayDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY,
                                                      this.attributes.dataProcessorCopySize((byte)Math.Max(this.attributes.sizes[0] - (casted.rhs / 8), 1)));
                    break;

                case Sqrt:
                    processor = new ByteArrayDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, this.attributes.dataProcessorCopySigned(false));
                    break;

                case Constant:
                    DataAttributes attributes = new DataAttributes(new byte[] { 4 }, (byte)1, (byte)0, casted.rhs >= 0);
                    processor = new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, attributes);
                    break;
                }
                if (processor != null)
                {
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(processor, null));
                }
                break;
            }

            case DataProcessorConfig.PulseConfig.ID: {
                DataProcessorConfig.PulseConfig casted = (DataProcessorConfig.PulseConfig)config;
                DataTypeBase processor = null;
                switch (casted.mode)
                {
                case Width:
                    processor = new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, new DataAttributes(new byte[] { 2 }, 1, 0, false));
                    break;

                case Area:
                    processor = dataProcessorCopy(this, attributes.dataProcessorCopySize(4));
                    break;

                case Peak:
                    processor = dataProcessorCopy(this, attributes.dataProcessorCopy());
                    break;

                case OnDetect:
                    processor = new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, new DataAttributes(new byte[] { 1 }, 1, 0, false));
                    break;
                }
                if (processor != null)
                {
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(processor, null));
                }
                break;
            }

            case DataProcessorConfig.ComparisonConfig.ID: {
                DataTypeBase processor = null;
                if (config is DataProcessorConfig.SingleValueComparisonConfig)
                {
                    processor = dataProcessorCopy(this, attributes.dataProcessorCopy());
                }
                else if (config is DataProcessorConfig.MultiValueComparisonConfig)
                {
                    DataProcessorConfig.MultiValueComparisonConfig casted = (DataProcessorConfig.MultiValueComparisonConfig)config;
                    if (casted.mode == ComparisonOutput.PassFail || casted.mode == ComparisonOutput.Zone)
                    {
                        processor = new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, new DataAttributes(new byte[] { 1 }, 1, 0, false));
                    }
                    else
                    {
                        processor = dataProcessorCopy(this, attributes.dataProcessorCopy());
                    }
                }
                if (processor != null)
                {
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(processor, null));
                }
                break;
            }

            case DataProcessorConfig.ThresholdConfig.ID: {
                DataProcessorConfig.ThresholdConfig casted = (DataProcessorConfig.ThresholdConfig)config;
                switch (casted.mode)
                {
                case Threshold.Absolute:
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(dataProcessorCopy(this, attributes.dataProcessorCopy()), null));

                case Threshold.Binary:
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY,
                                                                                          new DataAttributes(new byte[] { 1 }, 1, 0, true)), null));
                }
                break;
            }

            case DataProcessorConfig.DifferentialConfig.ID: {
                DataProcessorConfig.DifferentialConfig casted = (DataProcessorConfig.DifferentialConfig)config;
                switch (casted.mode)
                {
                case Differential.Absolute:
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(dataProcessorCopy(this, attributes.dataProcessorCopy()), null));

                case Differential.Differential:
                    throw new InvalidOperationException("Differential processor in 'difference' mode must be handled by subclasses");

                case Differential.Binary:
                    return(Tuple.Create <DataTypeBase, DataTypeBase>(new IntegralDataType(this, DATA_PROCESSOR, DataProcessor.NOTIFY, new DataAttributes(new byte[] { 1 }, 1, 0, true)), null));
                }
                break;
            }

            case DataProcessorConfig.PackerConfig.ID: {
                DataProcessorConfig.PackerConfig casted = (DataProcessorConfig.PackerConfig)config;
                return(Tuple.Create <DataTypeBase, DataTypeBase>(dataProcessorCopy(this, attributes.dataProcessorCopyCopies(casted.count)), null));
            }

            case DataProcessorConfig.AccounterConfig.ID: {
                DataProcessorConfig.AccounterConfig casted = (DataProcessorConfig.AccounterConfig)config;
                return(Tuple.Create <DataTypeBase, DataTypeBase>(dataProcessorCopy(this, new DataAttributes(new byte[] { casted.length, attributes.length() }, 1, 0, attributes.signed)), null));
            }
            }
            throw new InvalidOperationException("Unable to determine the DataTypeBase object for config: " + Util.arrayToHexString(config.Build()));
        }
예제 #4
0
        internal async Task <ICollection <LoggedDataConsumer> > queryActiveLoggersAsync()
        {
            dataLoggers.Clear();

            var nRemainingLoggers = new Dictionary <DataTypeBase, byte>();
            var placeholder       = new Dictionary <Tuple <byte, byte, byte>, byte>();
            ICollection <DataTypeBase> producers = bridge.aggregateDataSources();

            DataTypeBase guessLogSource(Tuple <byte, byte, byte> key, byte offset, byte length)
            {
                List <DataTypeBase> possible = new List <DataTypeBase>();

                foreach (DataTypeBase it in producers)
                {
                    if (it.eventConfig[0] == key.Item1 && it.eventConfig[1] == key.Item2 && it.eventConfig[2] == key.Item3)
                    {
                        possible.Add(it);
                        if (it.components != null)
                        {
                            possible.AddRange(it.components);
                        }
                    }
                }

                DataTypeBase original        = null;
                bool         multipleEntries = false;

                foreach (DataTypeBase it in possible)
                {
                    if (it.attributes.length() > 4)
                    {
                        original        = it;
                        multipleEntries = true;
                    }
                }

                if (multipleEntries)
                {
                    if (offset == 0 && length > LOG_ENTRY_SIZE)
                    {
                        return(original);
                    }
                    if (!placeholder.ContainsKey(key))
                    {
                        if (length == LOG_ENTRY_SIZE)
                        {
                            placeholder.Add(key, length);
                            return(original);
                        }
                    }
                    else
                    {
                        placeholder[key] += length;
                        if (placeholder[key] == original.attributes.length())
                        {
                            placeholder.Remove(key);
                        }
                        return(original);
                    }
                }

                foreach (DataTypeBase it in possible)
                {
                    if (it.attributes.offset == offset && it.attributes.length() == length)
                    {
                        return(it);
                    }
                }
                return(null);
            }

            for (byte i = 0; i < bridge.lookupModuleInfo(LOGGING).extra[0]; i++)
            {
                var response = await queryLogConfigTask.Execute("Querying log configuration (id = " + i + ") timed out after {0}ms", bridge.TimeForResponse,
                                                                () => bridge.sendCommand(new byte[] { (byte)LOGGING, Util.setRead(TRIGGER), i }));

                if (response.Length > 2)
                {
                    byte offset = (byte)(response[5] & 0x1f), length = (byte)(((response[5] >> 5) & 0x3) + 1);
                    var  source        = guessLogSource(Tuple.Create(response[2], response[3], response[4]), offset, length);
                    var  dataprocessor = bridge.GetModule <IDataProcessor>() as DataProcessor;

                    var state = Util.clearRead(response[3]) == DataProcessor.STATE;
                    if (response[2] == (byte)DATA_PROCESSOR && (response[3] == DataProcessor.NOTIFY || state))
                    {
                        var chain = await dataprocessor.pullChainAsync(response[4]);

                        var first = chain.First();
                        var type  = first.source != null?
                                    guessLogSource(Tuple.Create(first.source[0], first.source[1], first.source[2]), first.offset, first.length) :
                                        dataprocessor.activeProcessors[first.id].Item2.source;

                        while (chain.Count() != 0)
                        {
                            var current          = chain.Pop();
                            var currentConfigObj = DataProcessorConfig.from(bridge.getFirmware(), bridge.lookupModuleInfo(DATA_PROCESSOR).revision, current.config);
                            var next             = type.transform(currentConfigObj);

                            next.Item1.eventConfig[2] = current.id;
                            if (next.Item2 != null)
                            {
                                next.Item2.eventConfig[2] = current.id;
                            }
                            if (!dataprocessor.activeProcessors.ContainsKey(current.id))
                            {
                                dataprocessor.activeProcessors.Add(current.id, Tuple.Create(next.Item2, new NullEditor(currentConfigObj, type, bridge) as EditorImplBase));
                            }

                            type = next.Item1;
                        }

                        source = state ? dataprocessor.lookupProcessor(response[4]).Item1 : type;
                    }

                    if (!nRemainingLoggers.ContainsKey(source) && source.attributes.length() > LOG_ENTRY_SIZE)
                    {
                        nRemainingLoggers.Add(source, (byte)Math.Ceiling((float)(source.attributes.length() / LOG_ENTRY_SIZE)));
                    }

                    LoggedDataConsumer logger = null;
                    foreach (LoggedDataConsumer it in dataLoggers.Values)
                    {
                        if (it.source.eventConfig.SequenceEqual(source.eventConfig) && it.source.attributes.Equals(source.attributes))
                        {
                            logger = it;
                            break;
                        }
                    }

                    if (logger == null || (offset != 0 && !nRemainingLoggers.ContainsKey(source)))
                    {
                        logger = new LoggedDataConsumer(source);
                    }
                    logger.addId(i);
                    dataLoggers.Add(i, logger);

                    if (nRemainingLoggers.TryGetValue(source, out var count))
                    {
                        byte remaining = (byte)(count - 1);
                        nRemainingLoggers[source] = remaining;
                        if (remaining < 0)
                        {
                            nRemainingLoggers.Remove(source);
                        }
                    }
                }
            }

            List <LoggedDataConsumer> orderedLoggers = new List <LoggedDataConsumer>();

            foreach (var k in dataLoggers.Keys.OrderBy(d => d))
            {
                if (!orderedLoggers.Contains(dataLoggers[k]))
                {
                    orderedLoggers.Add(dataLoggers[k]);
                }
            }

            return(orderedLoggers);
        }
예제 #5
0
 internal NullEditor(DataProcessorConfig configObj, DataTypeBase source, IModuleBoardBridge bridge) : base(configObj, source, bridge)
 {
 }
예제 #6
0
 internal EditorImplBase(DataProcessorConfig configObj, DataTypeBase source, IModuleBoardBridge bridge) : base(bridge)
 {
     config         = configObj.Build();
     this.source    = source;
     this.configObj = configObj;
 }
 internal PackerEditorInner(DataProcessorConfig config, DataTypeBase source, IModuleBoardBridge bridge) : base(config, source, bridge)
 {
 }
 internal MultiValueComparatorEditor(DataProcessorConfig config, DataTypeBase source, IModuleBoardBridge bridge) : base(config, source, bridge)
 {
 }