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.
         }