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); }
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); }