Merge "i2s: Add in missing IRQ registers"
diff --git a/shodan_infrastructure/MatchaI2S.cs b/shodan_infrastructure/MatchaI2S.cs
index 292f659..037ab35 100644
--- a/shodan_infrastructure/MatchaI2S.cs
+++ b/shodan_infrastructure/MatchaI2S.cs
@@ -204,7 +204,7 @@
if (!rxBuffer.Full()) {
rxBuffer.Write(sample);
- if (rxBuffer.count == mappedRxTriggerLevel)
+ if ((rxBuffer.count == mappedRxTriggerLevel) && (rxWatermarkIrqEnabled.Value))
{
this.Log(LogLevel.Debug, "I2S RX FIFO Watermark.");
Connections[(int)Events.RxWatermarkIRQ].Blink();
@@ -212,11 +212,35 @@
}
}
- Connections[(int)Events.RxOverflowIRQ].Blink();
+ if (rxOverflowIrqEnabled.Value) {
+ Connections[(int)Events.RxOverflowIRQ].Blink();
+ }
}
private void CreateRegisters()
{
+ Registers.IrqState.Define(this)
+ .WithFlag(0, name: "TX_WATERMARK", valueProviderCallback: _ => { return txBuffer.count >= mappedTxTriggerLevel; })
+ .WithFlag(1, name: "RX_WATERMARK", valueProviderCallback: _ => { return rxBuffer.count >= mappedRxTriggerLevel; })
+ .WithFlag(2, name: "TX_EMPTY", valueProviderCallback: _ => { return txBuffer.Empty(); })
+ .WithFlag(3, name: "RX_OVERFLOW", valueProviderCallback: _ => { return rxBuffer.Full(); });
+
+ Registers.IrqEnable.Define(this)
+ .WithFlag(0, out txWatermarkIrqEnabled, name: "ENABLE_TX_WATERMARK")
+ .WithFlag(1, out rxWatermarkIrqEnabled, name: "ENABLE_RX_WATERMARK")
+ .WithFlag(2, out txEmptyIrqEnabled, name: "ENABLE_TX_EMPTY")
+ .WithFlag(3, out rxOverflowIrqEnabled, name: "ENABLE_RX_OVERFLOW");
+
+ Registers.IrqTest.Define(this)
+ .WithFlag(0, name: "TEST_TX_WATERMARK",
+ writeCallback: (_, __) => { Connections[(int)Events.TxWatermarkIRQ].Blink(); })
+ .WithFlag(1, name: "TEST_RX_WATERMARK",
+ writeCallback: (_, __) => { Connections[(int)Events.RxWatermarkIRQ].Blink(); })
+ .WithFlag(2, name: "TEST_TX_EMPTY",
+ writeCallback: (_, __) => { Connections[(int)Events.TxEmptyIRQ].Blink(); })
+ .WithFlag(3, name: "TEST_RX_OVERFLOW",
+ writeCallback: (_, __) => { Connections[(int)Events.RxOverflowIRQ].Blink(); });
+
Registers.Control.Define(this)
.WithFlag(0, out txEnable, name: "TX",
writeCallback: (_, val) => {
@@ -238,18 +262,22 @@
.WithReservedBits(3, 15)
.WithValueField(18, 6, out rxClkDivide, name: "NCO_RX")
.WithValueField(25, 6, out txClkDivide, name: "NCO_TX");
+
Registers.Status.Define32(this)
.WithFlag(0, name: "TXFULL", valueProviderCallback: _ => { return txBuffer.Full(); })
.WithFlag(1, name: "RXFULL", valueProviderCallback: _ => { return rxBuffer.Full(); })
.WithFlag(2, name: "TXEMPTY", valueProviderCallback: _ => { return txBuffer.Empty(); })
.WithFlag(3, name: "RXEMPTY", valueProviderCallback: _ => { return rxBuffer.Empty(); })
.WithReservedBits(4, 27);
+
Registers.ReadData.Define32(this)
.WithValueField(0, 31, FieldMode.Read, name: "RDATA",
valueProviderCallback: _ => { return rxBuffer.Read(); });
+
Registers.WriteData.Define32(this)
.WithValueField(0, 31, name: "WDATA",
writeCallback: (_, val) => { txBuffer.Write(val); });
+
Registers.FifoControl.Define32(this)
.WithFlag(0, name: "RXRST", writeCallback: (_, val) => { if (val) ResetRx(); })
.WithFlag(1, name: "TXRST", writeCallback: (_, val) => { if (val) ResetTx(); })
@@ -271,10 +299,21 @@
name: "RXILVL")
.WithValueField(5, 2, out txTriggerLevel,
writeCallback: (_, val) => {
- val = 0b01;
+ switch (val) {
+ case 0b00: mappedTxTriggerLevel = 1; break;
+ case 0b01: mappedTxTriggerLevel = 4; break;
+ case 0b10: mappedTxTriggerLevel = 8; break;
+ case 0b11: mappedTxTriggerLevel = 16; break;
+ default:
+ this.Log(LogLevel.Error, "Trying to set invalid TX trigger level. Setting to default");
+ val = 0b00;
+ mappedTxTriggerLevel = 8;
+ break;
+ }
},
name: "TXILVL")
.WithReservedBits(7, 24);
+
Registers.FifoStatus.Define32(this)
.WithValueField(0, 6, name: "TXLVL",
valueProviderCallback: _ => { return txBuffer.count; })
@@ -288,6 +327,11 @@
private IFlagRegisterField rxEnable;
private IFlagRegisterField loopbackEnable;
+ private IFlagRegisterField txWatermarkIrqEnabled;
+ private IFlagRegisterField rxWatermarkIrqEnabled;
+ private IFlagRegisterField txEmptyIrqEnabled;
+ private IFlagRegisterField rxOverflowIrqEnabled;
+
private IValueRegisterField rxClkDivide;
private IValueRegisterField txClkDivide;
private IValueRegisterField rxTriggerLevel;
@@ -316,20 +360,35 @@
private enum Registers
{
- Control = 0x0, // Control register
- Status = 0x1, // I2S Live Status register
+ IrqState = 0x00, // Current interrupt states
+ // bit 0: TX watermark
+ // bit 1: RX watermark
+ // bit 2: TX empty
+ // bit 3: RX overflow
+ IrqEnable = 0x04, // Whether or not interrupts are enabled
+ // bit 0: TX watermark
+ // bit 1: RX watermark
+ // bit 2: TX empty
+ // bit 3: RX overflow
+ IrqTest = 0x08, // IRQ testing
+ // bit 0: TX watermark
+ // bit 1: RX watermark
+ // bit 2: TX empty
+ // bit 3: RX overflow
+ Control = 0x0c, // Control register
+ Status = 0x10, // I2S Live Status register
// bit 0: TX buffer full
// bit 1: RX buffer full
// bit 2: TX FIFO empty
// bit 3: RX FIFO empty
- ReadData = 0x2, // I2S read data
- WriteData = 0x3, // I2S write data
- FifoControl = 0x4, // I2S FIFO control register
+ ReadData = 0x14, // I2S read data
+ WriteData = 0x18, // I2S write data
+ FifoControl = 0x1c, // I2S FIFO control register
// bit 0: RX FIFO reset (write 1 to reset)
// bit 1: TX FIFO reset (write 1 to reset)
// bit 4-2: Trigger level for RX interrupts
// bit 6-5: Trigger level for TX interrupts
- FifoStatus = 0x5, // I2S FIFO status register
+ FifoStatus = 0x20, // I2S FIFO status register
// bit 5:0: Current fill level of TX fifo
// bit 21:16: Current fill level of RX fifo.
}