From fcf84e7f5d6f4f0c72ca7307b8d53b565e0f406d Mon Sep 17 00:00:00 2001 From: Aaron Cuevas Lopez Date: Sun, 13 Oct 2024 21:36:35 +0200 Subject: [PATCH] Update I2C accesses on Neuropixel devices - Use the specific serializer enum for serializer addresses - Use the DS90UB9x static method to set i2c speed - Use the DS90UB9x static methos for serdes link initialization --- OpenEphys.Onix1/ConfigureNeuropixelsV1e.cs | 17 ++++++------- OpenEphys.Onix1/ConfigureNeuropixelsV2e.cs | 19 +++++++------- .../ConfigureNeuropixelsV2eBeta.cs | 25 +++++++++---------- 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/OpenEphys.Onix1/ConfigureNeuropixelsV1e.cs b/OpenEphys.Onix1/ConfigureNeuropixelsV1e.cs index 353e618..39541a9 100644 --- a/OpenEphys.Onix1/ConfigureNeuropixelsV1e.cs +++ b/OpenEphys.Onix1/ConfigureNeuropixelsV1e.cs @@ -141,8 +141,7 @@ public override IObservable Process(IObservable source var serializer = new I2CRegisterContext(device, DS90UB9x.SER_ADDR); // set I2C clock rate to ~400 kHz - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.SCLHIGH, 20); - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.SCLLOW, 20); + DS90UB9x.Set933I2CRate(device, 400e3); // read probe metadata var probeMetadata = new NeuropixelsV1eMetadata(serializer); @@ -167,8 +166,8 @@ public override IObservable Process(IObservable source var deviceInfo = new NeuropixelsV1eDeviceInfo(context, DeviceType, deviceAddress, probeControl); var shutdown = Disposable.Create(() => { - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO10, NeuropixelsV1e.DefaultGPO10Config); - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO32, NeuropixelsV1e.DefaultGPO32Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO10, NeuropixelsV1e.DefaultGPO10Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO32, NeuropixelsV1e.DefaultGPO32Config); }); return new CompositeDisposable( DeviceManager.RegisterDevice(deviceName, deviceInfo), @@ -194,10 +193,10 @@ static void ConfigureDeserializer(DeviceContext device) device.WriteRegister(DS90UB9x.DATALINES0, 0x3245106B); // Sync, psb[0], psb[1], psb[2], psb[3], psb[4], psb[5], psb[6], device.WriteRegister(DS90UB9x.DATALINES1, 0xFFFFFFFF); + DS90UB9x.Initialize933SerDesLink(device, DS90UB9xMode.Raw12BitHighFrequency); + // configure deserializer I2C aliases var deserializer = new I2CRegisterContext(device, DS90UB9x.DES_ADDR); - uint coaxMode = 0x4 + (uint)DS90UB9xMode.Raw12BitHighFrequency; // 0x4 maintains coax mode - deserializer.WriteByte((uint)DS90UB9xDeserializerI2CRegister.PortMode, coaxMode); uint alias = NeuropixelsV1e.ProbeAddress << 1; deserializer.WriteByte((uint)DS90UB9xDeserializerI2CRegister.SlaveID1, alias); @@ -211,16 +210,16 @@ static void ConfigureDeserializer(DeviceContext device) static void ResetProbe(I2CRegisterContext serializer, uint gpo10Config) { gpo10Config &= ~NeuropixelsV1e.Gpo10ResetMask; - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO10, gpo10Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO10, gpo10Config); Thread.Sleep(1); gpo10Config |= NeuropixelsV1e.Gpo10ResetMask; - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO10, gpo10Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO10, gpo10Config); } static uint TurnOnLed(I2CRegisterContext serializer, uint gpo23Config) { gpo23Config &= ~NeuropixelsV1e.Gpo32LedMask; - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO32, gpo23Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO32, gpo23Config); return gpo23Config; } diff --git a/OpenEphys.Onix1/ConfigureNeuropixelsV2e.cs b/OpenEphys.Onix1/ConfigureNeuropixelsV2e.cs index f9e710a..9518ecc 100644 --- a/OpenEphys.Onix1/ConfigureNeuropixelsV2e.cs +++ b/OpenEphys.Onix1/ConfigureNeuropixelsV2e.cs @@ -137,9 +137,8 @@ public override IObservable Process(IObservable source var gpo10Config = EnableProbeSupply(serializer); // set I2C clock rate to ~400 kHz - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.SCLHIGH, 20); - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.SCLLOW, 20); - + DS90UB9x.Set933I2CRate(device, 400e3); + // read probe metadata var probeAMetadata = ReadProbeMetadata(serializer, NeuropixelsV2e.ProbeASelected); var probeBMetadata = ReadProbeMetadata(serializer, NeuropixelsV2e.ProbeBSelected); @@ -210,7 +209,7 @@ public override IObservable Process(IObservable source var deviceInfo = new NeuropixelsV2eDeviceInfo(context, DeviceType, deviceAddress, gainCorrectionA, gainCorrectionB); var shutdown = Disposable.Create(() => { - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO10, NeuropixelsV2e.DefaultGPO10Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO10, NeuropixelsV2e.DefaultGPO10Config); SelectProbe(serializer, NeuropixelsV2e.NoProbeSelected); }); return new CompositeDisposable( @@ -237,10 +236,10 @@ static void ConfigureDeserializer(DeviceContext device) device.WriteRegister(DS90UB9x.DATALINES0, 0xFFFFF8A6); // NP A device.WriteRegister(DS90UB9x.DATALINES1, 0xFFFFF97B); // NP B + DS90UB9x.Initialize933SerDesLink(device, DS90UB9xMode.Raw12BitHighFrequency); + // configure deserializer I2C aliases var deserializer = new I2CRegisterContext(device, DS90UB9x.DES_ADDR); - uint coaxMode = 0x4 + (uint)DS90UB9xMode.Raw12BitHighFrequency; // 0x4 maintains coax mode - deserializer.WriteByte((uint)DS90UB9xDeserializerI2CRegister.PortMode, coaxMode); uint alias = NeuropixelsV2e.ProbeAddress << 1; deserializer.WriteByte((uint)DS90UB9xDeserializerI2CRegister.SlaveID1, alias); @@ -257,7 +256,7 @@ static uint EnableProbeSupply(I2CRegisterContext serializer) SelectProbe(serializer, NeuropixelsV2e.NoProbeSelected); // turn on analog supply and wait for boot - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO10, gpo10Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO10, gpo10Config); System.Threading.Thread.Sleep(20); return gpo10Config; } @@ -269,16 +268,16 @@ static NeuropixelsV2eMetadata ReadProbeMetadata(I2CRegisterContext serializer, b } static void SelectProbe(I2CRegisterContext serializer, byte probeSelect) { - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO32, probeSelect); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO32, probeSelect); System.Threading.Thread.Sleep(20); } static void ResetProbes(I2CRegisterContext serializer, uint gpo10Config) { gpo10Config &= ~NeuropixelsV2e.GPO10ResetMask; - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO10, gpo10Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO10, gpo10Config); gpo10Config |= NeuropixelsV2e.GPO10ResetMask; - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO10, gpo10Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO10, gpo10Config); } static void ConfigureProbeStreaming(I2CRegisterContext i2cNP) diff --git a/OpenEphys.Onix1/ConfigureNeuropixelsV2eBeta.cs b/OpenEphys.Onix1/ConfigureNeuropixelsV2eBeta.cs index 40cfb0c..23e16a5 100644 --- a/OpenEphys.Onix1/ConfigureNeuropixelsV2eBeta.cs +++ b/OpenEphys.Onix1/ConfigureNeuropixelsV2eBeta.cs @@ -150,12 +150,11 @@ public override IObservable Process(IObservable source var serializer = new I2CRegisterContext(device, DS90UB9x.SER_ADDR); var gpo10Config = NeuropixelsV2eBeta.DefaultGPO10Config; var gpo32Config = NeuropixelsV2eBeta.DefaultGPO32Config; - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO10, gpo10Config); - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO32, gpo32Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO10, gpo10Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO32, gpo32Config); // set I2C clock rate to ~400 kHz - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.SCLHIGH, 20); - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.SCLLOW, 20); + DS90UB9x.Set933I2CRate(device, 400e3); // read probe metadata var probeAMetadata = ReadProbeMetadata(serializer, ref gpo32Config, NeuropixelsV2eBeta.SelectProbeA); @@ -170,7 +169,7 @@ public override IObservable Process(IObservable source // REC_NRESET and NRESET go high on both probes to take the ASIC out of reset // TODO: not sure if REC_NRESET and NRESET are tied together on flex gpo10Config |= NeuropixelsV2eBeta.GPO10ResetMask | NeuropixelsV2eBeta.GPO10NResetMask; - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO10, gpo10Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO10, gpo10Config); System.Threading.Thread.Sleep(20); // configure probe streaming @@ -227,7 +226,7 @@ public override IObservable Process(IObservable source // toggle probe LED gpo32Config = (gpo32Config & ~NeuropixelsV2eBeta.GPO32LedMask) | (EnableLed ? 0 : NeuropixelsV2eBeta.GPO32LedMask); - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO32, gpo32Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO32, gpo32Config); // Both probes are now streaming, hit them with a mux reset to (roughly) sync. // NB: We have found that this gives PCLK-level synchronization MOST of the time. @@ -238,8 +237,8 @@ public override IObservable Process(IObservable source var deviceInfo = new NeuropixelsV2eDeviceInfo(context, DeviceType, deviceAddress, gainCorrectionA, gainCorrectionB); var shutdown = Disposable.Create(() => { - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO10, NeuropixelsV2eBeta.DefaultGPO10Config); - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO32, NeuropixelsV2eBeta.DefaultGPO32Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO10, NeuropixelsV2eBeta.DefaultGPO10Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO32, NeuropixelsV2eBeta.DefaultGPO32Config); }); return new CompositeDisposable( DeviceManager.RegisterDevice(deviceName, deviceInfo), @@ -265,10 +264,10 @@ static void ConfigureDeserializer(DeviceContext device) device.WriteRegister(DS90UB9x.DATALINES0, 0x00007654); // NP A device.WriteRegister(DS90UB9x.DATALINES1, 0x00000123); // NP B + DS90UB9x.Initialize933SerDesLink(device, DS90UB9xMode.Raw12BitHighFrequency); + // configure deserializer I2C aliases var deserializer = new I2CRegisterContext(device, DS90UB9x.DES_ADDR); - uint coaxMode = 0x4 + (uint)DS90UB9xMode.Raw12BitHighFrequency; // 0x4 maintains coax mode - deserializer.WriteByte((uint)DS90UB9xDeserializerI2CRegister.PortMode, coaxMode); uint alias = NeuropixelsV2eBeta.ProbeAddress << 1; deserializer.WriteByte((uint)DS90UB9xDeserializerI2CRegister.SlaveID1, alias); @@ -293,17 +292,17 @@ static void SelectProbe(I2CRegisterContext serializer, ref uint gpo32Config, byt NeuropixelsV2eBeta.SelectProbeB => gpo32Config & ~NeuropixelsV2eBeta.ProbeSelectMask, _ => gpo32Config }; - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO32, gpo32Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO32, gpo32Config); System.Threading.Thread.Sleep(20); } static void SyncProbes(I2CRegisterContext serializer, uint gpo10Config) { gpo10Config &= ~NeuropixelsV2eBeta.GPO10NResetMask; - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO10, gpo10Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO10, gpo10Config); gpo10Config |= NeuropixelsV2eBeta.GPO10NResetMask; - serializer.WriteByte((uint)DS90UB9xSerializerI2CRegister.GPIO10, gpo10Config); + serializer.WriteByte((uint)DS90UB933SerializerI2CRegister.GPIO10, gpo10Config); } static void ConfigureProbeStreaming(I2CRegisterContext i2cNP)