示例#1
0
        protected uint ReadInner()
        {
            foreach (var registerField in registerFields)
            {
                UnderlyingValue = registerField.CallValueProviderHandler(UnderlyingValue);
            }
            var baseValue     = UnderlyingValue;
            var valueToRead   = UnderlyingValue;
            var changedFields = new List <RegisterField>();

            foreach (var registerField in registerFields)
            {
                if (!registerField.fieldMode.IsReadable())
                {
                    BitHelper.ClearBits(ref valueToRead, registerField.position, registerField.width);
                }
                if (registerField.fieldMode.IsFlagSet(FieldMode.ReadToClear) &&
                    BitHelper.AreAnyBitsSet(UnderlyingValue, registerField.position, registerField.width))
                {
                    BitHelper.ClearBits(ref UnderlyingValue, registerField.position, registerField.width);
                    changedFields.Add(registerField);
                }
            }
            foreach (var registerField in registerFields)
            {
                registerField.CallReadHandler(baseValue, UnderlyingValue);
            }
            foreach (var changedRegister in changedFields.Distinct())
            {
                changedRegister.CallChangeHandler(baseValue, UnderlyingValue);
            }
            return(valueToRead);
        }
示例#2
0
        private void OutputFrames()
        {
            var currentPointer = txdPointer.Value;

            // The TXD.PTR register has been copied to internal double-buffers
            eventTxPointerUpdated.Value = true;
            UpdateInterrupts();

            // RxTxMaxCnt denotes number of DoubleWords, we need to calculate samples number
            for (var samples = 0u; samples < maxSamplesCount.Value * samplesPerDoubleWord; samples++)
            {
                var thisSample = machine.SystemBus.ReadDoubleWord(currentPointer + samples * sampleWidth / 8);
                BitHelper.ClearBits(ref thisSample, (int)sampleWidth, (int)(32 - sampleWidth));
                encoder.AcceptSample(thisSample);
            }
        }
        public byte Transmit(byte data)
        {
            if (!spiMode)
            {
                this.Log(LogLevel.Error, "Received data over SPI, but the SPI mode is disabled.");
                return(0);
            }

            this.Log(LogLevel.Noisy, "SPI: Received byte 0x{0:X} in state {1}", data, spiContext.State);

            switch (spiContext.State)
            {
            case SpiState.WaitingForCommand:
            {
                if (data == DummyByte)
                {
                    this.Log(LogLevel.Noisy, "Received a DUMMY byte, ignoring it");
                    return(GenerateR1Response().AsByte());
                }

                // two MSB of the SPI command byte should be '01'
                if (BitHelper.IsBitSet(data, 7) || !BitHelper.IsBitSet(data, 6))
                {
                    this.Log(LogLevel.Warning, "Unexpected command number value 0x{0:X}, ignoring this - expect problems", data);
                    return(GenerateR1Response(illegalCommand: true).AsByte());
                }

                // clear COMMAND bit, we don't need it anymore
                BitHelper.ClearBits(ref data, 6);

                spiContext.CommandNumber = (uint)data;

                spiContext.ArgumentBytes = 0;
                spiContext.State         = SpiState.WaitingForArgBytes;
                break;
            }

            case SpiState.WaitingForArgBytes:
            {
                this.Log(LogLevel.Noisy, "Storing as arg byte #{0}", spiContext.ArgumentBytes);

                spiContext.Argument <<= 8;
                spiContext.Argument  |= data;
                spiContext.ArgumentBytes++;

                if (spiContext.ArgumentBytes == 4)
                {
                    spiContext.State = SpiState.WaitingForCRC;
                }
                break;
            }

            case SpiState.WaitingForCRC:
            {
                // we don't check CRC

                this.Log(LogLevel.Noisy, "Sending a command to the SD card");
                var result = HandleCommand(spiContext.CommandNumber, spiContext.Argument).AsByteArray();
                spiContext.ResponseBuffer.EnqueueRange(result);

                if (spiContext.ResponseBuffer.Count == 0)
                {
                    this.Log(LogLevel.Warning, "Received an empty response, this is strange and might cause problems!");
                    spiContext.State = SpiState.WaitingForCommand;
                    break;
                }
                else
                {
                    spiContext.State = SpiState.SendingResponse;
                    return(spiContext.ResponseBuffer.Dequeue());
                }
            }

            case SpiState.SendingResponse:
            {
                if (spiContext.ResponseBuffer.TryDequeue(out var value))
                {
                    return(value);
                }

                this.Log(LogLevel.Noisy, "This is the end of response buffer");
                spiContext.State = SpiState.WaitingForCommand;
                break;
            }

            default:
            {
                throw new ArgumentException($"Received data 0x{data:X} in an unexpected state {spiContext.State}");
            }
            }

            return(0);
        }