private void SelectDevice(Device device) { lock (selectedDeviceLock) { if (!ChildCollection.TryGetValue((int)device, out selectedDevice)) { this.Log(LogLevel.Debug, "Selected non existing device"); selectedDevice = null; } } }
private bool TryResolveSelectedSlave(out II2CPeripheral selectedSlave) { var slaveAddress = (byte)(transmitBuffer.Value >> 1); if (!ChildCollection.TryGetValue(slaveAddress, out selectedSlave)) { this.Log(LogLevel.Warning, "Addressing unregistered slave: 0x{0:X}", slaveAddress); receivedAckFromSlaveNegated.Value = true; return(true); } receivedAckFromSlaveNegated.Value = false; return(false); }
private void HandleWriteToSlaveCommand() { if (generateStartCondition.Value) { generateStartCondition.Value = false; if (transactionInProgress) { // repeated start - finish previous transaction first SendDataToSlave(); } else { transactionInProgress = true; } var slaveAddress = (byte)(transmitBuffer.Value >> 1); var isReadOperation = BitHelper.IsBitSet(transmitBuffer.Value, 0); if (!ChildCollection.TryGetValue(slaveAddress, out selectedSlave)) { this.Log(LogLevel.Warning, "Addressing unregistered slave: 0x{0:X}", slaveAddress); receivedAckFromSlaveNegated.Value = true; } else { if (isReadOperation) { foreach (var b in selectedSlave.Read()) { dataFromSlave.Enqueue(b); } } receivedAckFromSlaveNegated.Value = false; } } else { if (!transactionInProgress) { this.Log(LogLevel.Warning, "Writing to slave without generating START signal"); return; } dataToSlave.Enqueue((byte)transmitBuffer.Value); } interruptFlag.Value = true; }
private uint ReadData(uint oldVal) { if (configEnabled.Value) { if (!ChildCollection.TryGetValue((int)deviceNumber.Value, out selectedDevice)) { this.Log(LogLevel.Warning, "Selected unregistered device number : {0}", deviceNumber.Value); selectedDevice = null; return(0); } //Address is multiplied by 4 cause Read function take offset as argument return(selectedDevice.ConfigurationReadDoubleWord(registerNumber.Value * 4)); } else { this.Log(LogLevel.Warning, "Reading data from device in unhandled state"); } return(0); }
private void HandleReadFromSlaveCommand() { var slaveAddress = (byte)(transmitBuffer.Value >> 1); var isReadOperation = BitHelper.IsBitSet(transmitBuffer.Value, 0); if (ChildCollection.TryGetValue(slaveAddress, out selectedSlave)) { foreach (var b in selectedSlave.Read()) { dataFromSlave.Enqueue(b); } } if (dataFromSlave.Count == 0) { this.Log(LogLevel.Warning, "Trying to read from slave, but no data is available"); receiveBuffer.Value = 0; return; } receiveBuffer.Value = dataFromSlave.Dequeue(); }
protected bool TryGetByAddress(int address, out T peripheral) { return(ChildCollection.TryGetValue(address, out peripheral)); }
private void DefineRegisters() { Registers.Control.Define(this) .WithTag("CR2", 7, 1) .WithFlag(6, out isCoreEnabled, name: "ens1") .WithFlag(5, FieldMode.WriteOneToClear | FieldMode.Read, name: "sta", writeCallback: (_, val) => { if (!val) { return; } switch (CurrentState) { case State.Idle: case State.SlaveAddressReadBitTransmittedAckNotReceived: case State.SlaveAddressWriteBitTransmittedAckNotReceived: pendingMasterTransaction = true; CurrentState = State.StartConditionTransmitted; break; case State.StartConditionTransmitted: case State.RepeatedStartConditionTransmitted: SendDataToSlave(); CurrentState = State.RepeatedStartConditionTransmitted; break; case State.DataTransmittedAckReceived: if (pendingMasterTransaction) { isReadOperation = true; CurrentState = State.RepeatedStartConditionTransmitted; } break; default: this.Log(LogLevel.Warning, "Setting START bit in unhandled state: {0}", CurrentState); break; } }) .WithFlag(4, FieldMode.WriteOneToClear | FieldMode.Read, name: "sto", writeCallback: (_, val) => { if (val) { selectedSlave = null; isReadOperation = false; pendingMasterTransaction = false; CurrentState = State.Idle; } }) .WithFlag(3, out serialInterruptFlag, name: "si", writeCallback: (previousValue, currentValue) => { if (!(previousValue && !currentValue)) { // writing 0 clears the interrupt return; } if (Interlocked.Decrement(ref irqResubmitCounter) > 0) { // if there are any queued irqs set the flag again serialInterruptFlag.Value = true; } else { Interlocked.Increment(ref irqResubmitCounter); } UpdateInterrupt(); }) .WithFlag(2, name: "aa") .WithTag("CR0/CR1", 0, 2); Registers.Status.Define(this) .WithEnumField <ByteRegister, State>(0, 8, FieldMode.Read, valueProviderCallback: _ => { return(CurrentState); } ); Registers.Data.Define(this) .WithValueField(0, 8, name: "sd", valueProviderCallback: _ => { if (receiveBuffer.Count == 0) { this.Log(LogLevel.Warning, "{0} trying to read from empty data buffer, transaction will halt", pendingMasterTransaction ? "Master" : "Slave"); if (pendingMasterTransaction) { pendingMasterTransaction = false; CurrentState = State.DataReceivedAckNotReturned; } else { CurrentState = State.Stop; } return(0); } var result = receiveBuffer.Dequeue(); if (receiveBuffer.Count > 0) { // the state machine requires states in which master and slave are reading from the data register CurrentState = pendingMasterTransaction ? State.DataReceivedAckReturned : State.PreviouslyAddressedWithOwnAddressDataReceivedAckReturned; } return(result); }, writeCallback: (_, val) => { switch (CurrentState) { case State.StartConditionTransmitted: case State.RepeatedStartConditionTransmitted: var slaveAddress = val >> 1; isReadOperation = BitHelper.IsBitSet(val, 0); if (!ChildCollection.TryGetValue((int)slaveAddress, out selectedSlave)) { this.Log(LogLevel.Warning, "Addressing unregistered slave: 0x{0:X}", slaveAddress); CurrentState = (isReadOperation) ? State.SlaveAddressReadBitTransmittedAckNotReceived : State.SlaveAddressWriteBitTransmittedAckNotReceived; } else { if (isReadOperation) { var bytes = selectedSlave.Read(); if (bytes.Length > 0) { foreach (var b in bytes) { receiveBuffer.Enqueue(b); } CurrentState = State.DataReceivedAckReturned; } } else { CurrentState = State.SlaveAddressWriteBitTransmittedAckReceived; } } break; case State.SlaveAddressWriteBitTransmittedAckReceived: case State.DataTransmittedAckReceived: transferBuffer.Enqueue((byte)val); SendDataToSlave(); break; default: this.Log(LogLevel.Warning, "Writing to data register in unhandled state: {0}", CurrentState); break; } }); Registers.Slave0Address.Define(this) .WithValueField(1, 7, name: "adr") .WithFlag(0, name: "gc"); Registers.Slave1Address.Define(this) .WithValueField(1, 7, name: "adr") .WithFlag(0, name: "gc"); }