public void BitBangSpiTest() { Console.WriteLine("Starting bit bang SPI functionality test..."); byte[] MISO; List <byte> MOSI = new List <byte>(); for (int i = 0; i < 1024; i++) { MOSI.Add((byte)(i & 0x7F)); } Console.WriteLine("Testing bit bang SPI word length..."); for (uint wordLen = 8; wordLen <= 512; wordLen += 8) { Console.WriteLine("Testing bit length of " + wordLen.ToString()); /* Override SPI pins */ FX3.BitBangSpiConfig = new BitBangSpiConfig(true); MISO = FX3.BitBangSpi(wordLen, 1, MOSI.ToArray(), 1000); Assert.AreEqual(Math.Ceiling(wordLen / 8.0), MISO.Count(), "ERROR: Invalid data count"); for (int i = 0; i < MISO.Count(); i++) { Assert.AreEqual(MOSI[i], MISO[i], "ERROR: Invalid echo data"); } /* Override DIO3/4 pins */ FX3.BitBangSpiConfig.MOSI = (FX3PinObject)FX3.DIO3; FX3.BitBangSpiConfig.MISO = (FX3PinObject)FX3.DIO4; MISO = FX3.BitBangSpi(wordLen, 1, MOSI.ToArray(), 1000); Assert.AreEqual(Math.Ceiling(wordLen / 8.0), MISO.Count(), "ERROR: Invalid data count"); for (int i = 0; i < MISO.Count(); i++) { Assert.AreEqual(MOSI[i], MISO[i], "ERROR: Invalid echo data"); } } Console.WriteLine("Testing restore hardware SPI functionality..."); FX3.RestoreHardwareSpi(); TestSpiFunctionality(); }
public void SetReadPinTest() { Console.WriteLine("Starting pin read/write test..."); const int NUM_TRIALS = 100; Console.WriteLine("Testing " + NUM_TRIALS.ToString() + " pin set/read trials"); for (int trial = 0; trial < NUM_TRIALS; trial++) { Console.WriteLine("Starting trial " + trial.ToString()); FX3.SetPin(FX3.DIO3, 1); Assert.AreEqual(1, FX3.ReadPin(FX3.DIO4), "ERROR: Invalid pin value read on DIO4"); FX3.SetPin(FX3.DIO3, 0); Assert.AreEqual(0, FX3.ReadPin(FX3.DIO4), "ERROR: Invalid pin value read on DIO4"); FX3.SetPin(FX3.DIO4, 1); Assert.AreEqual(1, FX3.ReadPin(FX3.DIO3), "ERROR: Invalid pin value read on DIO3"); FX3.SetPin(FX3.DIO4, 0); Assert.AreEqual(0, FX3.ReadPin(FX3.DIO3), "ERROR: Invalid pin value read on DIO3"); } }
private void TestSpiFunctionality() { switch (FX3.WordLength) { case 8: Assert.AreEqual(0x55, FX3.Transfer(0x55) & 0xFF, "ERROR: SPI data failed to echo back. SCLK Freq " + FX3.SclkFrequency.ToString() + "Hz"); Assert.AreEqual(0xAA, FX3.Transfer(0xAA) & 0xFF, "ERROR: SPI data failed to echo back. SCLK Freq " + FX3.SclkFrequency.ToString() + "Hz"); break; case 16: Assert.AreEqual(0x5555, FX3.Transfer(0x5555) & 0xFFFF, "ERROR: SPI data failed to echo back. SCLK Freq " + FX3.SclkFrequency.ToString() + "Hz"); Assert.AreEqual(0xAAAA, FX3.Transfer(0xAAAA) & 0xFFFF, "ERROR: SPI data failed to echo back. SCLK Freq " + FX3.SclkFrequency.ToString() + "Hz"); break; case 32: default: Assert.AreEqual(0x55555555, FX3.Transfer(0x55555555), "ERROR: SPI data failed to echo back. SCLK Freq " + FX3.SclkFrequency.ToString() + "Hz"); Assert.AreEqual(0xAAAAAAAA, FX3.Transfer(0xAAAAAAAA), "ERROR: SPI data failed to echo back. SCLK Freq " + FX3.SclkFrequency.ToString() + "Hz"); break; } }
public void GenericStreamCancelTest() { Console.WriteLine("Starting generic stream cancel test..."); long firstCount; FX3.SensorType = DeviceType.IMU; FX3.PartType = DUTType.IMU; for (int trial = 0; trial < 10; trial++) { Console.WriteLine("Starting trial " + trial.ToString()); /* Start stream */ FX3.StartBufferedStream(new[] { 0U, 1U, 2U }, 1, 1000000, 10, null); firstCount = FX3.GetNumBuffersRead; System.Threading.Thread.Sleep(100); Assert.Greater(FX3.GetNumBuffersRead, firstCount, "ERROR: Expected to have read buffers"); /* Cancel stream (stop stream) */ FX3.StopStream(); System.Threading.Thread.Sleep(20); /* Check SPI functionality */ TestSpiFunctionality(); /* Start stream */ FX3.StartBufferedStream(new[] { 0U, 1U, 2U }, 1, 1000000, 10, null); firstCount = FX3.GetNumBuffersRead; System.Threading.Thread.Sleep(100); Assert.Greater(FX3.GetNumBuffersRead, firstCount, "ERROR: Expected to have read buffers"); /* Cancel stream (cancel stream) */ FX3.CancelStreamAsync(); System.Threading.Thread.Sleep(20); /* Check SPI functionality */ TestSpiFunctionality(); } }
public void BoardDetectionTest() { Console.WriteLine("Starting FX3 board detection test..."); string sn = FX3.ActiveFX3SerialNumber; Assert.AreEqual(0, FX3.AvailableFX3s.Count(), "ERROR: Expected no available FX3s"); Assert.AreEqual(1, FX3.BusyFX3s.Count(), "ERROR: Expected 1 busy FX3"); Assert.AreEqual(sn, FX3.BusyFX3s[0], "Invalid busy FX3 SN"); Console.WriteLine("Rebooting FX3..."); FX3.Disconnect(); FX3.WaitForBoard(10); Assert.AreEqual(1, FX3.AvailableFX3s.Count(), "ERROR: Expected 1 available FX3"); Assert.AreEqual(sn, FX3.AvailableFX3s[0], "Invalid available FX3 SN"); Assert.AreEqual(0, FX3.BusyFX3s.Count(), "ERROR: Expected 0 busy FX3s"); FX3.Connect(sn); Assert.AreEqual(0, FX3.AvailableFX3s.Count(), "ERROR: Expected no available FX3s"); Assert.AreEqual(1, FX3.BusyFX3s.Count(), "ERROR: Expected 1 busy FX3"); Assert.AreEqual(sn, FX3.BusyFX3s[0], "Invalid busy FX3 SN"); }
public void PWMGenerationTest() { Console.WriteLine("Starting PWM generation test..."); double posWidth, negWidth; double measuredFreq, measuredDutyCycle; for (double freq = 20; freq < 40000; freq *= 1.2) { for (double dutyCycle = 0.02; dutyCycle <= 0.98; dutyCycle += 0.02) { Console.WriteLine("Starting PWM with freq " + freq.ToString("f2") + "Hz, " + dutyCycle.ToString("f2") + " duty cycle..."); FX3.StartPWM(freq, dutyCycle, FX3.DIO3); posWidth = FX3.MeasureBusyPulse(FX3.DIO2, 1, 0, FX3.DIO4, 1, 1000); negWidth = FX3.MeasureBusyPulse(FX3.DIO2, 1, 0, FX3.DIO4, 0, 1000); measuredFreq = 1000 / (posWidth + negWidth); measuredDutyCycle = posWidth / (posWidth + negWidth); Console.WriteLine("Measured freq: " + measuredFreq.ToString("f2") + "Hz, measured duty cycle: " + measuredDutyCycle.ToString("f2")); Assert.AreEqual(freq, measuredFreq, 0.01 * freq, "ERROR: Invalid freq measured"); Assert.AreEqual(dutyCycle, measuredDutyCycle, 0.01, "ERROR: Invalid duty cycle measured"); } } }
public void ResistorConfigurationTest() { Console.WriteLine("Starting GPIO resistor configuration test..."); for (int trial = 0; trial < 10; trial++) { Console.WriteLine("Enabling internal pull up on all user accessible GPIO..."); SetPinResistorSetting(FX3PinResistorSetting.PullUp); System.Threading.Thread.Sleep(50); Console.WriteLine("Checking input stage values..."); Assert.AreEqual(1, FX3.ReadPin(FX3.DIO1), "ERROR: Expected pin to be high"); Assert.AreEqual(1, FX3.ReadPin(FX3.DIO2), "ERROR: Expected pin to be high"); Assert.AreEqual(1, FX3.ReadPin(FX3.DIO3), "ERROR: Expected pin to be high"); Assert.AreEqual(1, FX3.ReadPin(FX3.DIO4), "ERROR: Expected pin to be high"); Assert.AreEqual(1, FX3.ReadPin(FX3.FX3_GPIO1), "ERROR: Expected pin to be high"); Assert.AreEqual(1, FX3.ReadPin(FX3.FX3_GPIO2), "ERROR: Expected pin to be high"); Assert.AreEqual(1, FX3.ReadPin(FX3.FX3_GPIO3), "ERROR: Expected pin to be high"); Assert.AreEqual(1, FX3.ReadPin(FX3.FX3_GPIO4), "ERROR: Expected pin to be high"); Console.WriteLine("Enabling internal pull down on all user accessible GPIO..."); SetPinResistorSetting(FX3PinResistorSetting.PullDown); System.Threading.Thread.Sleep(50); Console.WriteLine("Checking input stage values..."); Assert.AreEqual(0, FX3.ReadPin(FX3.DIO1), "ERROR: Expected pin to be low"); Assert.AreEqual(0, FX3.ReadPin(FX3.DIO2), "ERROR: Expected pin to be low"); Assert.AreEqual(0, FX3.ReadPin(FX3.DIO3), "ERROR: Expected pin to be low"); Assert.AreEqual(0, FX3.ReadPin(FX3.DIO4), "ERROR: Expected pin to be low"); Assert.AreEqual(0, FX3.ReadPin(FX3.FX3_GPIO1), "ERROR: Expected pin to be low"); Assert.AreEqual(0, FX3.ReadPin(FX3.FX3_GPIO2), "ERROR: Expected pin to be low"); Assert.AreEqual(0, FX3.ReadPin(FX3.FX3_GPIO3), "ERROR: Expected pin to be low"); Assert.AreEqual(0, FX3.ReadPin(FX3.FX3_GPIO4), "ERROR: Expected pin to be low"); Console.WriteLine("Disabling resistors..."); SetPinResistorSetting(FX3PinResistorSetting.None); System.Threading.Thread.Sleep(50); } }
public void ErrorLogCountTest() { Console.WriteLine("Starting error log count test..."); uint count, firstCount; List <FX3ErrorLog> log; firstCount = FX3.GetErrorLogCount(); for (int trial = 0; trial < 5; trial++) { count = FX3.GetErrorLogCount(); Console.WriteLine("Error log count: " + count.ToString()); Assert.AreEqual(firstCount, count, "ERROR: Invalid error log count"); } if (firstCount > 1500) { Console.WriteLine("ERROR: Error log full. Clearing..."); FX3.ClearErrorLog(); Assert.AreEqual(0, FX3.GetErrorLogCount(), "ERROR: Error log count clear failed"); firstCount = 0; } log = FX3.GetErrorLog(); Assert.AreEqual(firstCount, log.Count(), "ERROR: Invalid error log size"); Console.WriteLine("Rebooting FX3..."); FX3.Disconnect(); System.Threading.Thread.Sleep(1000); Connect(); count = FX3.GetErrorLogCount(); Console.WriteLine("Error log count: " + count.ToString()); Assert.AreEqual(firstCount, count, "ERROR: Invalid error log count"); log = FX3.GetErrorLog(); Assert.AreEqual(firstCount, log.Count(), "ERROR: Invalid error log size"); }
private void ActivateLED(int index) { switch (index) { case 0: FX3.SetPin(new FX3Api.FX3PinObject(13), 0); break; case 1: FX3.SetPin(new FX3Api.BitBangSpiConfig(true).CS, 0); break; case 2: FX3.SetPin(FX3.DIO4, 0); break; case 3: FX3.SetPin(FX3.DIO3, 0); break; case 4: FX3.SetPin(FX3.DIO2, 0); break; case 5: FX3.SetPin(FX3.DIO1, 0); break; case 6: FX3.DutSupplyMode = DutVoltage.On5_0Volts; break; case 7: FX3.DutSupplyMode = DutVoltage.On3_3Volts; break; } }
public void ErrorLogRobustnessTest() { Console.WriteLine("Starting error log robustness test..."); List <FX3ErrorLog> initialLog, log; I2CPreamble preRead = new I2CPreamble(); preRead.DeviceAddress = 0xA0; preRead.PreambleData.Add(0); preRead.PreambleData.Add(0); preRead.PreambleData.Add(0xA1); preRead.StartMask = 4; I2CPreamble preWrite = new I2CPreamble(); preWrite.DeviceAddress = 0; preWrite.PreambleData.Add(0); preWrite.StartMask = 0; Console.WriteLine("Rebooting FX3..."); FX3.Disconnect(); System.Threading.Thread.Sleep(500); Connect(); Console.WriteLine("Getting initial error log..."); initialLog = FX3.GetErrorLog(); foreach (FX3ErrorLog entry in initialLog) { Console.WriteLine(entry.ToString()); } Console.WriteLine("Starting I2C Read..."); try { FX3.I2CReadBytes(preRead, 32, 1000); } catch (Exception e) { Console.WriteLine(e.Message); } Console.WriteLine("Getting error log..."); log = FX3.GetErrorLog(); CheckLogEquality(initialLog, log, false); Console.WriteLine("Starting invalid I2C write..."); try { FX3.I2CWriteBytes(preWrite, new byte[] { 1, 2, 3, 4 }, 1000); } catch (Exception e) { Console.WriteLine(e.Message); } Console.WriteLine("Getting error log..."); log = FX3.GetErrorLog(); CheckLogEquality(initialLog, log, true); initialLog.Clear(); foreach (FX3ErrorLog entry in log) { initialLog.Add(entry); } Console.WriteLine("Starting I2C stream..."); FX3.StartI2CStream(preRead, 64, 10); System.Threading.Thread.Sleep(2000); Console.WriteLine("Getting error log..."); log = FX3.GetErrorLog(); CheckLogEquality(initialLog, log, false); Console.WriteLine("Rebooting FX3..."); FX3.Disconnect(); System.Threading.Thread.Sleep(500); Connect(); Console.WriteLine("Getting error log..."); log = FX3.GetErrorLog(); CheckLogEquality(initialLog, log, false); Console.WriteLine("Starting I2C Read..."); try { FX3.I2CReadBytes(preRead, 32, 1000); } catch (Exception e) { Console.WriteLine(e.Message); } Console.WriteLine("Generating new error log..."); GenerateErrorLog(); Console.WriteLine("Getting error log..."); log = FX3.GetErrorLog(); Assert.AreEqual(initialLog.Count + 1, log.Count, "ERROR: Invalid log count"); CheckLogEquality(initialLog, log, true); }
public void PWMPinInfoTest() { Console.WriteLine("Starting pin PWM info test..."); int exCount; PinPWMInfo info; Console.WriteLine("Testing default PWM pin info for each pin..."); foreach (PropertyInfo prop in FX3.GetType().GetProperties()) { if (prop.PropertyType == typeof(AdisApi.IPinObject)) { Assert.AreEqual(0, FX3.GetPinPWMInfo((AdisApi.IPinObject)prop.GetValue(FX3)).IdealFrequency, "ERROR: Expected PWM pins to be disabled for all pins initially"); } } Console.WriteLine("Testing PWM pin info for each pin..."); foreach (PropertyInfo prop in FX3.GetType().GetProperties()) { if (prop.PropertyType == typeof(AdisApi.IPinObject)) { if (((AdisApi.IPinObject)prop.GetValue(FX3)).pinConfig % 8 != 0) { FX3.StartPWM(2000, 0.5, (AdisApi.IPinObject)prop.GetValue(FX3)); info = FX3.GetPinPWMInfo((AdisApi.IPinObject)prop.GetValue(FX3)); Assert.AreEqual(((AdisApi.IPinObject)prop.GetValue(FX3)).pinConfig, info.FX3GPIONumber, "ERROR: Invalid GPIO Number"); Assert.AreEqual(info.FX3GPIONumber % 8, info.FX3TimerBlock, "ERROR: Invalid FX3 timer block"); Assert.AreEqual(2000, info.IdealFrequency, "ERROR: Invalid frequency"); Assert.AreEqual(0.5, info.IdealDutyCycle, "ERROR: Invalid duty cycle"); FX3.StopPWM((AdisApi.IPinObject)prop.GetValue(FX3)); } else { exCount = 0; try { FX3.StartPWM(2000, 0.5, (AdisApi.IPinObject)prop.GetValue(FX3)); } catch (Exception e) { Console.WriteLine(e.Message); exCount = 1; } Assert.AreEqual(1, exCount, "ERROR: Expected exception to be thrown for pins which cannot run PWM"); } } } Console.WriteLine("Sweeping PWM freq..."); { for (double freq = 0.5; freq < 100000; freq = freq * 1.1) { FX3.StartPWM(freq, 0.5, FX3.DIO1); Assert.AreEqual(freq, FX3.GetPinPWMInfo(FX3.DIO1).IdealFrequency, "ERROR: Invalid IdealFrequency"); Assert.AreEqual(freq, FX3.GetPinPWMInfo(FX3.DIO1).RealFrequency, 0.001 * freq, "ERROR: Invalid RealFrequency"); } } Console.WriteLine("Sweeping PWM duty cycle at 1KHz..."); for (double dutyCycle = 0.01; dutyCycle < 1.0; dutyCycle += 0.01) { FX3.StartPWM(1000, dutyCycle, FX3.DIO1); Assert.AreEqual(dutyCycle, FX3.GetPinPWMInfo(FX3.DIO1).IdealDutyCycle, "ERROR: Invalid ideal duty cycle"); Assert.AreEqual(dutyCycle, FX3.GetPinPWMInfo(FX3.DIO1).RealDutyCycle, 0.001 * dutyCycle, "ERROR: Invalid real duty cycle"); } }
public void MeasureBusyPulseTest() { double period; double pwmPeriod = 1000; double measuredPeriodPin, measuredPeriodSpi; List <byte> SpiData = new List <byte>(); SpiData.Add(0); SpiData.Add(0); /* Test small period measurements (0.5us - 500us) */ for (period = 0.5; period < 500; period += 0.5) { FX3.StartPWM(1000, (pwmPeriod - period) / pwmPeriod, FX3.DIO4); measuredPeriodPin = 1000 * FX3.MeasureBusyPulse(FX3.DIO2, 1, 0, FX3.DIO3, 0, 100); measuredPeriodSpi = 1000 * FX3.MeasureBusyPulse(SpiData.ToArray(), FX3.DIO3, 0, 100); Console.WriteLine("Negative PWM Period: " + period.ToString() + "us.\t Error: " + (period - measuredPeriodPin).ToString() + "us"); Console.WriteLine("Measured period: " + measuredPeriodPin.ToString() + "us"); /* Assert with 0.2us margin of error */ Assert.AreEqual(period, measuredPeriodSpi, 0.2, "ERROR: Invalid period measured"); Assert.AreEqual(period, measuredPeriodSpi, 0.2, "ERROR: Invalid period measured"); /* Measure positive period */ FX3.StartPWM(1000, period / pwmPeriod, FX3.DIO4); measuredPeriodPin = 1000 * FX3.MeasureBusyPulse(FX3.DIO2, 1, 0, FX3.DIO3, 1, 100); measuredPeriodSpi = 1000 * FX3.MeasureBusyPulse(SpiData.ToArray(), FX3.DIO3, 1, 100); Console.WriteLine("Positive PWM Period: " + period.ToString() + "us.\t Error: " + (period - measuredPeriodPin).ToString() + "us"); Console.WriteLine("Measured period: " + measuredPeriodPin.ToString() + "us"); /* Assert with 0.2us margin of error */ Assert.AreEqual(period, measuredPeriodSpi, 0.2, "ERROR: Invalid period measured"); Assert.AreEqual(period, measuredPeriodSpi, 0.2, "ERROR: Invalid period measured"); } /* Test large period measurements (2ms - 50ms) */ pwmPeriod = 100; for (period = 2; period < 50; period += 2) { FX3.StartPWM(10, (pwmPeriod - period) / pwmPeriod, FX3.DIO4); measuredPeriodPin = FX3.MeasureBusyPulse(FX3.DIO2, 1, 0, FX3.DIO3, 0, 200); measuredPeriodSpi = FX3.MeasureBusyPulse(SpiData.ToArray(), FX3.DIO3, 0, 200); Console.WriteLine("Negative PWM Period: " + period.ToString() + "ms.\t Error: " + (period - measuredPeriodPin).ToString() + "ms"); /* Assert with 1% margin of error */ Assert.AreEqual(period, measuredPeriodSpi, period * 0.1, "ERROR: Invalid period measured"); Assert.AreEqual(period, measuredPeriodSpi, period * 0.1, "ERROR: Invalid period measured"); /* Measure positive period */ FX3.StartPWM(10, period / pwmPeriod, FX3.DIO4); measuredPeriodPin = FX3.MeasureBusyPulse(FX3.DIO2, 1, 0, FX3.DIO3, 1, 200); measuredPeriodSpi = FX3.MeasureBusyPulse(SpiData.ToArray(), FX3.DIO3, 1, 200); Console.WriteLine("Positive PWM Period: " + period.ToString() + "ms.\t Error: " + (period - measuredPeriodPin).ToString() + "ms"); /* Assert with 1% margin of error */ Assert.AreEqual(period, measuredPeriodSpi, period * 0.1, "ERROR: Invalid period measured"); Assert.AreEqual(period, measuredPeriodSpi, period * 0.1, "ERROR: Invalid period measured"); } /* Test very large period measurements (1 sec) */ Console.WriteLine("Testing 1 second period signal measurements..."); period = 1000; FX3.StartPWM(0.5, 0.5, FX3.DIO4); measuredPeriodPin = FX3.MeasureBusyPulse(FX3.DIO2, 1, 0, FX3.DIO3, 0, 5000); measuredPeriodSpi = FX3.MeasureBusyPulse(SpiData.ToArray(), FX3.DIO3, 0, 5000); Assert.AreEqual(period, measuredPeriodSpi, period * 0.1, "ERROR: Invalid period measured"); Assert.AreEqual(period, measuredPeriodSpi, period * 0.1, "ERROR: Invalid period measured"); measuredPeriodPin = FX3.MeasureBusyPulse(FX3.DIO2, 1, 0, FX3.DIO3, 1, 5000); measuredPeriodSpi = FX3.MeasureBusyPulse(SpiData.ToArray(), FX3.DIO3, 1, 5000); Assert.AreEqual(period, measuredPeriodSpi, period * 0.1, "ERROR: Invalid period measured"); Assert.AreEqual(period, measuredPeriodSpi, period * 0.1, "ERROR: Invalid period measured"); }
public void SpiStallTimeTest() { Console.WriteLine("Starting SPI stall time test..."); double expectedTime; Stopwatch timer = new Stopwatch(); double baseTime = 0; int numReads = 5; uint[] MOSI = new uint[200]; /* Stall time for transfer reads (32 bits) */ Console.WriteLine("Testing stall time for 32-bit reads (transfer stream)..."); FX3.WordLength = 32; FX3.SclkFrequency = 15000000; FX3.ChipSelectLeadTime = SpiLagLeadTime.SPI_SSN_LAG_LEAD_ONE_HALF_CLK; FX3.ChipSelectLagTime = SpiLagLeadTime.SPI_SSN_LAG_LEAD_ONE_HALF_CLK; /* Get base stall time (5us stall) */ for (int i = 0; i < 8; i++) { timer.Restart(); for (int trial = 0; trial < numReads; trial++) { FX3.TransferArray(MOSI, 5); } timer.Stop(); baseTime += timer.ElapsedMilliseconds; } /* Average base time */ baseTime /= 8.0; Console.WriteLine("Base SPI transfer time with 5us stall: " + baseTime.ToString() + "ms"); for (ushort stallTime = 50; stallTime >= 7; stallTime--) { Console.WriteLine("Testing stall time of " + stallTime.ToString() + "us"); FX3.StallTime = stallTime; /* Perform sets of 5 sets of 200 32-bit transfers (999 stalls). Expected time is in ms */ expectedTime = (stallTime - 5) * numReads; /* Add base time overhead */ expectedTime += baseTime; timer.Restart(); for (int trial = 0; trial < numReads; trial++) { FX3.TransferArray(MOSI, 5); } timer.Stop(); Console.WriteLine("Expected time: " + expectedTime.ToString() + "ms, real time: " + timer.ElapsedMilliseconds.ToString() + "ms"); Assert.AreEqual(expectedTime, timer.ElapsedMilliseconds, 0.5 * baseTime, "ERROR: Invalid transfer time"); System.Threading.Thread.Sleep(100); } /* Stall time for generic reads */ Console.WriteLine("Testing stall time for 16-bit reads (generic stream)..."); FX3.WordLength = 16; /* Get base stall time (5us stall) */ baseTime = 0; for (int i = 0; i < 8; i++) { timer.Restart(); for (int trial = 0; trial < numReads; trial++) { FX3.ReadRegArray(MOSI, 5); } timer.Stop(); baseTime += timer.ElapsedMilliseconds; } /* Average base time */ baseTime /= 8.0; Console.WriteLine("Base SPI transfer time with 5us stall: " + baseTime.ToString() + "ms"); for (ushort stallTime = 50; stallTime >= 7; stallTime--) { Console.WriteLine("Testing stall time of " + stallTime.ToString() + "us"); FX3.StallTime = stallTime; /* Perform sets of 5 sets of 200 16-bit transfers (999 stalls). Expected time is in ms */ expectedTime = (stallTime - 5) * numReads; /* Add base time overhead */ expectedTime += baseTime; timer.Restart(); for (int trial = 0; trial < numReads; trial++) { FX3.ReadRegArray(MOSI, 5); } timer.Stop(); Console.WriteLine("Expected time: " + expectedTime.ToString() + "ms, real time: " + timer.ElapsedMilliseconds.ToString() + "ms"); Assert.AreEqual(expectedTime, timer.ElapsedMilliseconds, 0.5 * baseTime, "ERROR: Invalid transfer time"); System.Threading.Thread.Sleep(100); } FX3.StallTime = 5; }
public void I2CBitRateTest() { Console.WriteLine("Starting I2C bit rate test..."); Console.WriteLine("Testing input validation..."); uint startingBitRate; int numExpections = 0; startingBitRate = FX3.I2CBitRate; Assert.AreEqual(100000, startingBitRate, "ERROR: Invalid default I2C bit rate"); try { FX3.I2CBitRate = 99999; } catch (Exception e) { numExpections++; Console.WriteLine(e.Message); } Assert.AreEqual(1, numExpections, "ERROR: Expected exception to be thrown"); Assert.AreEqual(startingBitRate, FX3.I2CBitRate, "ERROR: Expected I2C bit rate setting to be rejected"); try { FX3.I2CBitRate = 1000001; } catch (Exception e) { numExpections++; Console.WriteLine(e.Message); } Assert.AreEqual(2, numExpections, "ERROR: Expected exception to be thrown"); Assert.AreEqual(startingBitRate, FX3.I2CBitRate, "ERROR: Expected I2C bit rate setting to be rejected"); Console.WriteLine("Testing reads across valid bit rate range..."); I2CPreamble pre = new I2CPreamble(); pre.DeviceAddress = 0xA0; pre.PreambleData.Add(0); pre.PreambleData.Add(0); pre.PreambleData.Add(0xA1); pre.StartMask = 4; byte[] InitialRead, SecondRead; Console.WriteLine("Performing initial flash read..."); const uint READ_LEN = 1024; InitialRead = FX3.I2CReadBytes(pre, READ_LEN, 2000); for (uint bitrate = 100000; bitrate <= 1000000; bitrate += 100000) { Console.WriteLine("Testing " + bitrate.ToString() + "bits/s..."); FX3.I2CBitRate = bitrate; Assert.AreEqual(bitrate, FX3.I2CBitRate, "ERROR: Setting bit rate failed"); SecondRead = FX3.I2CReadBytes(pre, READ_LEN, 2000); for (int i = 0; i < InitialRead.Count(); i++) { Assert.AreEqual(InitialRead[i], SecondRead[i], "ERROR: Expected flash read data to match"); } } }
public void SpiTransferTest() { Console.WriteLine("Starting SPI transfer test..."); uint writeVal; uint[] readArray; List <uint> writeData = new List <uint>(); /* Set word length of 8 */ Console.WriteLine("Testing word length of 8 bits..."); FX3.WordLength = 8; TestSpiFunctionality(); for (int bit = 0; bit < 8; bit++) { Console.WriteLine("Testing bit " + bit.ToString()); Assert.AreEqual(1U << bit, FX3.Transfer(1U << bit), "ERROR: SPI loop back failed"); } /* Bits outside of word length should not be echo'd */ for (int bit = 8; bit < 32; bit++) { Console.WriteLine("Testing bit " + bit.ToString()); Assert.AreEqual(0, FX3.Transfer(1U << bit), "ERROR: SPI loop back failed"); } /* Set word length of 16 */ Console.WriteLine("Testing word length of 16 bits..."); FX3.WordLength = 16; for (int bit = 0; bit < 16; bit++) { Console.WriteLine("Testing bit " + bit.ToString()); Assert.AreEqual(1U << bit, FX3.Transfer(1U << bit), "ERROR: SPI loop back failed"); } /* Bits outside of word length should not be echo'd */ for (int bit = 16; bit < 32; bit++) { Console.WriteLine("Testing bit " + bit.ToString()); Assert.AreEqual(0, FX3.Transfer(1U << bit), "ERROR: SPI loop back failed"); } /* Set word length of 24 */ Console.WriteLine("Testing word length of 24 bits..."); FX3.WordLength = 24; for (int bit = 0; bit < 24; bit++) { Console.WriteLine("Testing bit " + bit.ToString()); Assert.AreEqual(1U << bit, FX3.Transfer(1U << bit), "ERROR: SPI loop back failed"); } /* Bits outside of word length should not be echo'd */ for (int bit = 24; bit < 32; bit++) { Console.WriteLine("Testing bit " + bit.ToString()); Assert.AreEqual(0, FX3.Transfer(1U << bit), "ERROR: SPI loop back failed"); } /* Set word length of 32 */ Console.WriteLine("Testing word length of 32 bits..."); FX3.WordLength = 32; for (int bit = 0; bit < 32; bit++) { Console.WriteLine("Testing bit " + bit.ToString()); Assert.AreEqual(1U << bit, FX3.Transfer(1U << bit), "ERROR: SPI loop back failed"); } Console.WriteLine("Testing random 32-bit values..."); var rnd = new Random(); for (int trial = 0; trial < 256; trial++) { writeVal = (uint)(rnd.NextDouble() * uint.MaxValue); Console.WriteLine("Writing 0x" + writeVal.ToString("X8")); Assert.AreEqual(writeVal, FX3.Transfer(writeVal), "ERROR: SPI loop back failed"); } Console.WriteLine("Testing array based SPI transfers..."); for (int writeSize = 1; writeSize < 10; writeSize++) { writeData.Clear(); for (uint i = 0; i < writeSize; i++) { writeData.Add(i); } for (uint numBuffers = 1; numBuffers < 10; numBuffers++) { for (uint numCaptures = 1; numCaptures < 10; numCaptures++) { Console.WriteLine("Testing write data array " + writeSize.ToString() + " words long, with " + numCaptures.ToString() + " numcaptures and " + numBuffers.ToString() + " numbuffers"); readArray = FX3.TransferArray(writeData, numCaptures, numBuffers); /* Size should be write data count * numbuffers * numCaptures */ Assert.AreEqual(writeSize * numBuffers * numCaptures, readArray.Count(), "ERROR: Invalid data size received"); int i = 0; /* Check echo data */ for (int index = 0; index < readArray.Count(); index++) { i = index % writeSize; Assert.AreEqual(writeData[i], readArray[i], "ERROR: Invalid SPI data at index " + index.ToString()); } } } } }
public void BurstSpiTest() { Console.WriteLine("Starting SPI burst read test..."); List <byte> BurstTxData = new List <byte>(); ushort[] BurstData; int index; RegMapClasses.RegClass triggerReg = new RegMapClasses.RegClass(); triggerReg.NumBytes = 2; triggerReg.Address = 0x12; FX3.DrActive = false; for (int byteCount = 4; byteCount < 400; byteCount += 2) { Console.WriteLine("Testing burst read of " + byteCount.ToString() + " bytes..."); FX3.BurstByteCount = byteCount; Assert.AreEqual(byteCount, FX3.BurstByteCount, "ERROR; Byte count not applied correctly"); Assert.AreEqual((byteCount - 2) / 2, FX3.WordCount, "ERROR: FX3 burst word count not set correctly"); /* Burst trigger reg */ FX3.TriggerReg = triggerReg; /* strip header */ Console.WriteLine("Testing burst read with trigger reg and header stripped..."); FX3.StripBurstTriggerWord = true; FX3.SetupBurstMode(); FX3.StartBurstStream(1, FX3.BurstMOSIData); FX3.WaitForStreamCompletion(50); BurstData = FX3.GetBuffer(); Assert.AreEqual((byteCount / 2) - 1, BurstData.Count(), "ERROR: Invalid burst data count"); for (int i = 0; i < BurstData.Count(); i++) { Assert.AreEqual(0, BurstData[i], "ERROR: Expected all burst data to be 0"); } /* No strip header */ Console.WriteLine("Testing burst read with trigger reg and header not stripped..."); FX3.StripBurstTriggerWord = false; FX3.SetupBurstMode(); FX3.StartBurstStream(1, FX3.BurstMOSIData); FX3.WaitForStreamCompletion(50); BurstData = FX3.GetBuffer(); Assert.AreEqual((byteCount / 2), BurstData.Count(), "ERROR: Invalid burst data count"); Assert.AreEqual(0x1200, BurstData[0], "ERROR: Invalid burst data echoed"); for (int i = 1; i < BurstData.Count(); i++) { Assert.AreEqual(0, BurstData[i], "ERROR: Expected remainder of burst data to be 0"); } /* Burst transmit data */ BurstTxData.Clear(); for (int i = 0; i < byteCount; i++) { BurstTxData.Add((byte)(i & 0xFFU)); } FX3.BurstMOSIData = BurstTxData.ToArray(); for (int i = 0; i < BurstTxData.Count; i++) { Assert.AreEqual(BurstTxData[i], FX3.BurstMOSIData[i], "ERROR: Burst MOSI data not applied correctly"); } /* strip header */ Console.WriteLine("Testing burst read with MOSI byte array and header stripped..."); FX3.StripBurstTriggerWord = true; FX3.SetupBurstMode(); FX3.StartBurstStream(1, FX3.BurstMOSIData); FX3.WaitForStreamCompletion(50); BurstData = FX3.GetBuffer(); Assert.AreEqual((byteCount / 2) - 1, BurstData.Count(), "ERROR: Invalid burst data count"); index = 2; for (int i = 0; i < BurstData.Count(); i++) { Assert.AreEqual(BurstTxData[index], BurstData[i] >> 8, "ERROR: Invalid burst data echoed"); Assert.AreEqual(BurstTxData[index + 1], BurstData[i] & 0xFF, "ERROR: Invalid burst data echoed"); index += 2; } /* No strip header */ Console.WriteLine("Testing burst read with MOSI byte array and header not stripped..."); FX3.StripBurstTriggerWord = false; FX3.SetupBurstMode(); FX3.StartBurstStream(1, FX3.BurstMOSIData); FX3.WaitForStreamCompletion(50); BurstData = FX3.GetBuffer(); Assert.AreEqual((byteCount / 2), BurstData.Count(), "ERROR: Invalid burst data count"); index = 0; for (int i = 0; i < BurstData.Count(); i++) { Assert.AreEqual(BurstTxData[index], BurstData[i] >> 8, "ERROR: Invalid burst data echoed"); Assert.AreEqual(BurstTxData[index + 1], BurstData[i] & 0xFF, "ERROR: Invalid burst data echoed"); index += 2; } } Console.WriteLine("Testing Dr Active triggering for burst..."); FX3.DrPin = FX3.DIO3; FX3.StartPWM(100, 0.5, FX3.DIO4); FX3.BurstByteCount = 64; BurstTxData.Clear(); for (int i = 0; i < 64; i++) { BurstTxData.Add((byte)(i & 0xFFU)); } FX3.BurstMOSIData = BurstTxData.ToArray(); FX3.StripBurstTriggerWord = false; FX3.SetupBurstMode(); FX3.DrActive = true; double expectedTime; long drActiveTime, baseTime; Stopwatch timer = new Stopwatch(); for (uint numBuffers = 100; numBuffers <= 300; numBuffers += 100) { Console.WriteLine("Capturing " + numBuffers.ToString() + " buffers with DrActive set to false..."); FX3.DrActive = false; FX3.StartBurstStream(numBuffers, FX3.BurstMOSIData); timer.Restart(); while (FX3.GetNumBuffersRead < numBuffers) { System.Threading.Thread.Sleep(1); } baseTime = timer.ElapsedMilliseconds; Console.WriteLine("Stream time: " + baseTime.ToString() + "ms"); CheckBurstBuffers(BurstTxData.ToArray(), numBuffers); Console.WriteLine("Capturing " + numBuffers.ToString() + " buffers with DrActive set to true..."); expectedTime = 10 * numBuffers; //100Hz DR FX3.DrActive = true; FX3.StartBurstStream(numBuffers, FX3.BurstMOSIData); timer.Restart(); while (FX3.GetNumBuffersRead < numBuffers) { System.Threading.Thread.Sleep(1); } drActiveTime = timer.ElapsedMilliseconds; Console.WriteLine("Stream time: " + drActiveTime.ToString() + "ms"); Assert.AreEqual(expectedTime, drActiveTime, 0.25 * expectedTime, "ERROR: Invalid stream time"); CheckBurstBuffers(BurstTxData.ToArray(), numBuffers); Assert.Less(baseTime, drActiveTime, "ERROR: Base stream time greater than DrActive stream time"); } }
public void TransferArrayWithWriteTest() { uint[] res; uint[] initialMOSI = new uint[6]; uint[] repeatedMOSI = new uint[4]; Stopwatch timer = new Stopwatch(); double time; Console.WriteLine("Starting SPI write then read stream test..."); FX3.WordLength = 32; FX3.StallTime = 3; FX3.SclkFrequency = 4000000; FX3.DrActive = false; FX3.DrPin = FX3.DIO3; for (uint i = 0; i < 4; i++) { repeatedMOSI[i] = i; } initialMOSI[0] = 0xAAAAAAAA; initialMOSI[5] = 0x55555555; /* Both false */ Console.WriteLine("Testing both DR inactive..."); FX3.DrActive = false; System.Threading.Thread.Sleep(10); FX3.StartPWM(10, 0.5, FX3.DIO4); timer.Restart(); res = FX3.WriteReadTransferArray(initialMOSI, false, repeatedMOSI, 10); time = timer.ElapsedMilliseconds; Assert.LessOrEqual(time, 10, "Expected time of less than 10ms"); Assert.AreEqual(repeatedMOSI.Count() * 10, res.Count(), "Invalid data size"); CheckRxData(res); /* dr active */ Console.WriteLine("Testing DR active read..."); FX3.DrActive = true; System.Threading.Thread.Sleep(10); FX3.StartPWM(10, 0.5, FX3.DIO4); timer.Restart(); res = FX3.WriteReadTransferArray(initialMOSI, false, repeatedMOSI, 10); time = timer.ElapsedMilliseconds; //10 reads at 10Hz -> approx 1 sec. Give range 1000 - 1200 Assert.AreEqual(time, 1100, 100, "Expected time of between 1000ms and 1200ms"); Assert.AreEqual(repeatedMOSI.Count() * 10, res.Count(), "Invalid data size"); CheckRxData(res); /* initial dr active */ Console.WriteLine("Testing DR active write..."); FX3.DrActive = false; System.Threading.Thread.Sleep(10); FX3.StartPWM(10, 0.5, FX3.DIO4); timer.Restart(); res = FX3.WriteReadTransferArray(initialMOSI, true, repeatedMOSI, 10); time = timer.ElapsedMilliseconds; //Should be between 50ms and 150ms Assert.AreEqual(time, 100, 50, "Expected time of between 50ms and 150ms"); Assert.AreEqual(repeatedMOSI.Count() * 10, res.Count(), "Invalid data size"); CheckRxData(res); /* Both true */ Console.WriteLine("Testing both DR active..."); FX3.DrActive = true; System.Threading.Thread.Sleep(10); FX3.StartPWM(10, 0.5, FX3.DIO4); timer.Restart(); res = FX3.WriteReadTransferArray(initialMOSI, true, repeatedMOSI, 10); time = timer.ElapsedMilliseconds; //10 reads at 10Hz -> approx 1 sec. Give range 1000 - 1200 Assert.AreEqual(time, 1100, 100, "Expected time of between 1000ms and 1200ms"); Assert.AreEqual(repeatedMOSI.Count() * 10, res.Count(), "Invalid data size"); CheckRxData(res); }
public void ErrorLogContentsTest() { Console.WriteLine("Starting error contents test..."); List <FX3ErrorLog> initialLog, log; uint count; count = FX3.GetErrorLogCount(); if (count > 1500) { Console.WriteLine("Error log count of " + count.ToString() + " exceeds log capacity. Clearing log..."); FX3.ClearErrorLog(); Assert.AreEqual(0, FX3.GetErrorLogCount(), "ERROR: Error log count clear failed"); } initialLog = FX3.GetErrorLog(); Console.WriteLine("Initial error log count: " + initialLog.Count.ToString()); foreach (FX3ErrorLog logEntry in initialLog) { Console.WriteLine(logEntry.ToString()); } for (int trial = 0; trial < 5; trial++) { Console.WriteLine("Reading error log..."); log = FX3.GetErrorLog(); Assert.AreEqual(initialLog.Count, log.Count, "ERROR: Invalid error log count"); for (int i = 0; i < log.Count; i++) { Assert.AreEqual(initialLog[i], log[i], "ERROR: Invalid log entry"); } } Console.WriteLine("Adding a new item to the error log..."); string version = FX3.GetFirmwareVersion; long uptime = FX3.ActiveFX3.Uptime; GenerateErrorLog(); log = FX3.GetErrorLog(); Console.WriteLine(log[log.Count - 1].ToString()); Assert.AreEqual(initialLog.Count + 1, log.Count, "ERROR: Error log count not incremented correctly"); count = (uint)log.Count; for (int i = 0; i < initialLog.Count; i++) { Assert.AreEqual(initialLog[i], log[i], "ERROR: Invalid older log entries"); } /* Check new log entry */ Assert.AreEqual(uptime, log[log.Count - 1].OSUptime, 1000, "ERROR: Invalid error log uptime"); /*Check boot time stamp */ uint expectedTimestamp = (uint)((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds - (uptime / 1000)); Assert.AreEqual(log[log.Count - 1].BootTimeStamp, expectedTimestamp, 120, "ERROR: Invalid boot time stamp"); /* Check file (should have originated in HelperFunctions (10)) */ Assert.AreEqual(10, log[log.Count - 1].FileIdentifier, "ERROR: Invalid file identifier. Expected error to have originated in HelperFunctions.c"); initialLog = FX3.GetErrorLog(); Assert.AreEqual(count, log.Count, "ERROR: Invalid log count"); /* Reboot FX3 and check contents */ Console.WriteLine("Rebooting FX3..."); FX3.Disconnect(); Connect(); for (int trial = 0; trial < 5; trial++) { Console.WriteLine("Reading error log..."); log = FX3.GetErrorLog(); Assert.AreEqual(initialLog.Count, log.Count, "ERROR: Invalid error log count"); for (int i = 0; i < log.Count; i++) { Assert.AreEqual(initialLog[i], log[i], "ERROR: Invalid log entry"); } } }
public void ADcmXLRealTimeStreamTest() { Console.WriteLine("Starting ADcmXL data stream test..."); double expectedTime; double realTime; double baseTime; uint numBuffers = 13600; Stopwatch timer = new Stopwatch(); FX3.DrActive = true; FX3.SensorType = DeviceType.ADcmXL; FX3.PartType = DUTType.ADcmXL3021; FX3.DrPin = FX3.DIO3; /* Start 6.8KHz, 80% duty cycle DR signal on DIO4 */ FX3.StartPWM(6800, 0.8, FX3.DIO4); Console.WriteLine("Measuring base stream time..."); baseTime = 0; for (int trial = 0; trial < 5; trial++) { timer.Restart(); FX3.StartRealTimeStreaming(1000); System.Threading.Thread.Sleep(5); FX3.WaitForStreamCompletion(1000); baseTime += (timer.ElapsedMilliseconds - (1000.0 / 6.8)); } baseTime /= 5; Console.WriteLine("Base stream overhead time: " + baseTime.ToString() + "ms"); for (int trial = 0; trial < 4; trial++) { Console.WriteLine("Starting trial " + trial.ToString()); /* Start stream */ timer.Restart(); FX3.StartRealTimeStreaming(numBuffers); System.Threading.Thread.Sleep(100); FX3.WaitForStreamCompletion((int)(numBuffers / 6.0) + 1000); timer.Stop(); Assert.AreEqual(FX3.GetNumBuffersRead, numBuffers, "ERROR: Invalid number of buffers read"); realTime = timer.ElapsedMilliseconds; /* Take off a base time */ realTime -= baseTime; expectedTime = numBuffers / 6.8; Console.WriteLine("Expected time: " + expectedTime.ToString() + "ms, Real time: " + realTime.ToString() + "ms"); Assert.AreEqual(expectedTime, realTime, 0.01 * expectedTime, "ERROR: Invalid stream time"); /* Check SPI functionality */ FX3.WordLength = 16; TestSpiFunctionality(); } Console.WriteLine("Verifying that when the DR edge is missed the stream waits until the following edge to start..."); FX3.SclkFrequency = 8000000; timer.Restart(); FX3.StartRealTimeStreaming(numBuffers); System.Threading.Thread.Sleep(100); FX3.WaitForStreamCompletion((int)(2 * numBuffers / 6.0) + 1000); timer.Stop(); Assert.AreEqual(FX3.GetNumBuffersRead, numBuffers, "ERROR: Invalid number of buffers read"); realTime = timer.ElapsedMilliseconds; /* Take off a base time */ realTime -= baseTime; /* Twice the time because we read every other data ready */ expectedTime = 2 * numBuffers / 6.8; Console.WriteLine("Expected time: " + expectedTime.ToString() + "ms, Real time: " + realTime.ToString() + "ms"); Assert.AreEqual(expectedTime, realTime, 0.01 * expectedTime, "ERROR: Invalid stream time"); }