i2s: fix interrupt state register handling

The INTR_STATE register uses W1C (Write-once Clear) semantics.

Change-Id: If6ac172fffa34ef7233f7917c222b4f49ab613bb
diff --git a/shodan_infrastructure/MatchaI2S.cs b/shodan_infrastructure/MatchaI2S.cs
index 3031755..5845f70 100644
--- a/shodan_infrastructure/MatchaI2S.cs
+++ b/shodan_infrastructure/MatchaI2S.cs
@@ -300,10 +300,18 @@
         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(); });
+                .WithFlag(0, name: "TX_WATERMARK",
+                      valueProviderCallback: _ => { return txBuffer.Count >= mappedTxTriggerLevel; },
+                      writeCallback: (_, val) => { if (val) TxWatermarkIRQ.Set(false); })
+                .WithFlag(1, name: "RX_WATERMARK",
+                      valueProviderCallback: _ => { return rxBuffer.Count >= mappedRxTriggerLevel; },
+                      writeCallback: (_, val) => { if (val) RxWatermarkIRQ.Set(false); })
+                .WithFlag(2, name: "TX_EMPTY",
+                      valueProviderCallback: _ => { return txBuffer.Empty(); },
+                      writeCallback: (_, val) => { if (val) TxEmptyIRQ.Set(false); })
+                .WithFlag(3, name: "RX_OVERFLOW",
+                      valueProviderCallback: _ => { return rxBuffer.Full(); },
+                      writeCallback: (_, val) => { if (val) RxOverflowIRQ.Set(false); });
 
             Registers.IrqEnable.Define(this)
                 .WithFlag(0, out txWatermarkIrqEnabled, name: "ENABLE_TX_WATERMARK")