From 95b6ff8d75a0781c8df128f4dfe6c6dea6897f6f Mon Sep 17 00:00:00 2001 From: Greg Eakin Date: Fri, 7 Jul 2017 22:36:32 -0700 Subject: [PATCH 01/11] Using Indeximal's idea to remove the leading zeros, and use blank space instead. Test the code. --- multiplexed-display/multiplexed-display.ino | 171 +++++++++++++------- 1 file changed, 113 insertions(+), 58 deletions(-) diff --git a/multiplexed-display/multiplexed-display.ino b/multiplexed-display/multiplexed-display.ino index cc018d6..f639d35 100644 --- a/multiplexed-display/multiplexed-display.ino +++ b/multiplexed-display/multiplexed-display.ino @@ -1,6 +1,6 @@ /** - * This sketch is specifically for programming the EEPROM used in the 8-bit - * decimal display decoder described in https://youtu.be/dLh1n2dErzE + * This sketch is specifically for programming the EEPROM used in the 8-bit + * decimal display decoder described in https://youtu.be/dLh1n2dErzE */ #define SHIFT_DATA 2 #define SHIFT_CLK 3 @@ -9,13 +9,21 @@ #define EEPROM_D7 12 #define WRITE_EN 13 + /* Output the address bits and outputEnable signal using shift registers. */ void setAddress(int address, bool outputEnable) { - shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, (address >> 8) | (outputEnable ? 0x00 : 0x80)); - shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, address); + address = address & 0x7FFF; + + // Shift the data out, via the shift register clock + byte msb = (address >> 8) | (outputEnable ? 0x00 : 0x80); + shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, msb); + byte lsb = address & 0xFF; + shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, lsb); + + // Shift-register data is stored in the storage register. digitalWrite(SHIFT_LATCH, LOW); digitalWrite(SHIFT_LATCH, HIGH); digitalWrite(SHIFT_LATCH, LOW); @@ -31,7 +39,7 @@ byte readEEPROM(int address) { } setAddress(address, /*outputEnable*/ true); - byte data = 0; + byte data = 0x00; for (int pin = EEPROM_D7; pin >= EEPROM_D0; pin -= 1) { data = (data << 1) + digitalRead(pin); } @@ -62,19 +70,95 @@ void writeEEPROM(int address, byte data) { /* Read the contents of the EEPROM and print them to the serial monitor. */ -void printContents() { - for (int base = 0; base <= 255; base += 16) { - byte data[16]; - for (int offset = 0; offset <= 15; offset += 1) { - data[offset] = readEEPROM(base + offset); +void printContents(int address) { + for (int base = 0x0000; base < 0x0100; base += 0x10) + { + char buf[20]; + sprintf(buf, "0x%04x: ", address + base); + Serial.print(buf); + for (int offset = 0x00; offset < 0x10; offset += 1) + { + byte data = readEEPROM(address + base + offset); + sprintf(buf, "%02x ", data); + Serial.print(buf); + + if (offset == 7) + Serial.print(" "); } + Serial.println(); + } + Serial.println(); +} + - char buf[80]; - sprintf(buf, "%03x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", - base, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], - data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]); +byte digits[] = {0x7e, 0x30, 0x6d, 0x79, 0x33, 0x5b, 0x5f, 0x70, 0x7f, 0x7b, 0x77, 0x1f, 0x4e, 0x3d, 0x4f, 0x47}; +byte minusSign = 0x01; +byte blank = 0x00; - Serial.println(buf); +/* + Using Indeximal's idea to remove the leading zeros, and use blank space instead. +*/ +void programEEPROM() +{ + // loop over all possible inputs + for (int i = 0x0000; i < 0x0100; i++) + { + if (i % 0x10 == 0x00) + { + Serial.print((i / 256.0) * 100.0); + Serial.println("%"); + } + + // unsigned byte as decimal + { + int d2 = (i / 100) % 10; // 2nd 7segment display (hundreds) + int d3 = (i / 10) % 10; // 3rd 7segment display (tenths) + writeEEPROM(i + 0x0300, blank); // clear first 7segment display + writeEEPROM(i + 0x0200, (d2 == 0) ? blank : digits[d2]); // write the digit or clear if 0 + writeEEPROM(i + 0x0100, (d2 == 0 && d3 == 0) ? blank : digits[d3]); // write the digit or clear if d3 and d2 are 0 + writeEEPROM(i + 0x0000, digits[i % 10]); // write the digit even 0 + } + + // Two's complement + if (i < 0x80) + { + // positive numbers, same as above + int d2 = (i / 100) % 10; // 2nd 7segment display (hundreds) + int d3 = (i / 10) % 10; // 3rd 7segment display (tenths) + writeEEPROM(i + 0x0700, blank); // clear first 7segment display + writeEEPROM(i + 0x0600, (d2 == 0) ? blank : digits[d2]); // write the digit or clear if 0 + writeEEPROM(i + 0x0500, (d2 == 0 && d3 == 0) ? blank : digits[d3]); // write the digit or clear if d3 and d2 are 0 + writeEEPROM(i + 0x0400, digits[i % 10]); // write the digit including 0 + } + else + { + // Example + // d1 d2 d3 d4 + // - 1 2 3 + // - 4 2 + // - 7 + + int value = i - 0x0100; //real value as two's complement + int d2 = (abs(value) / 100) % 10; //hundreds + int d3 = (abs(value) / 10) % 10; //tenths + int d4 = abs(value) % 10; //ones + + //first 7segment display + writeEEPROM(i + 0x0700, d2 == 0 ? blank : minusSign); //write a minus sign to the first 7segment display if the second 7segment display isn't clear + + //second 7segment display + if (d2 == 0 && d3 == 0) { // if the minus sign is further right + writeEEPROM(i + 0x0600, blank); // clear second 7segment display + } else { + writeEEPROM(i + 0x0600, d2 == 0 ? minusSign : digits[d2]); + } + + // third 7segment display + writeEEPROM(i + 0x0500, (d2 == 0 && d3 == 0) ? minusSign : digits[d3]); // write a minus sign if both the second and the third 7segment display are clear + + // last 7segment display + writeEEPROM(i + 0x0400, digits[d4]); // always write the last digit (ones) + } } } @@ -84,59 +168,30 @@ void setup() { pinMode(SHIFT_DATA, OUTPUT); pinMode(SHIFT_CLK, OUTPUT); pinMode(SHIFT_LATCH, OUTPUT); + digitalWrite(WRITE_EN, HIGH); pinMode(WRITE_EN, OUTPUT); - Serial.begin(57600); - - // Bit patterns for the digits 0..9 - byte digits[] = { 0x7e, 0x30, 0x6d, 0x79, 0x33, 0x5b, 0x5f, 0x70, 0x7f, 0x7b }; + Serial.begin(57600); - Serial.println("Programming ones place"); - for (int value = 0; value <= 255; value += 1) { - writeEEPROM(value, digits[value % 10]); - } - Serial.println("Programming tens place"); - for (int value = 0; value <= 255; value += 1) { - writeEEPROM(value + 256, digits[(value / 10) % 10]); - } - Serial.println("Programming hundreds place"); - for (int value = 0; value <= 255; value += 1) { - writeEEPROM(value + 512, digits[(value / 100) % 10]); - } - Serial.println("Programming sign"); - for (int value = 0; value <= 255; value += 1) { - writeEEPROM(value + 768, 0); - } - - Serial.println("Programming ones place (twos complement)"); - for (int value = -128; value <= 127; value += 1) { - writeEEPROM((byte)value + 1024, digits[abs(value) % 10]); - } - Serial.println("Programming tens place (twos complement)"); - for (int value = -128; value <= 127; value += 1) { - writeEEPROM((byte)value + 1280, digits[abs(value / 10) % 10]); - } - Serial.println("Programming hundreds place (twos complement)"); - for (int value = -128; value <= 127; value += 1) { - writeEEPROM((byte)value + 1536, digits[abs(value / 100) % 10]); - } - Serial.println("Programming sign (twos complement)"); - for (int value = -128; value <= 127; value += 1) { - if (value < 0) { - writeEEPROM((byte)value + 1792, 0x01); - } else { - writeEEPROM((byte)value + 1792, 0); - } - } + // Clear and program the EEPROM + // eraseEEPROM(); + programEEPROM(); // Read and print out the contents of the EERPROM Serial.println("Reading EEPROM"); - printContents(); + printContents(0x0000); + printContents(0x0100); + printContents(0x0200); + printContents(0x0300); + printContents(0x0400); + printContents(0x0500); + printContents(0x0600); + printContents(0x0700); } void loop() { // put your main code here, to run repeatedly: - } + From fd3f9828a9c3786d4e0da9aee1e0484fd2cd65ee Mon Sep 17 00:00:00 2001 From: Greg Eakin Date: Fri, 7 Jul 2017 22:55:00 -0700 Subject: [PATCH 02/11] Code cleanup --- .../microcode-eeprom-programmer.ino | 114 ++++++++++++------ 1 file changed, 78 insertions(+), 36 deletions(-) diff --git a/microcode-eeprom-programmer/microcode-eeprom-programmer.ino b/microcode-eeprom-programmer/microcode-eeprom-programmer.ino index 032cb65..a680e94 100644 --- a/microcode-eeprom-programmer/microcode-eeprom-programmer.ino +++ b/microcode-eeprom-programmer/microcode-eeprom-programmer.ino @@ -49,8 +49,13 @@ uint16_t data[] = { * Output the address bits and outputEnable signal using shift registers. */ void setAddress(int address, bool outputEnable) { - shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, (address >> 8) | (outputEnable ? 0x00 : 0x80)); - shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, address); + address = address & 0x7FFF; + + byte msb = (address >> 8) | (outputEnable ? 0x00 : 0x80); + shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, msb); + + byte lsb = address & 0xFF; + shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, lsb); digitalWrite(SHIFT_LATCH, LOW); digitalWrite(SHIFT_LATCH, HIGH); @@ -67,7 +72,7 @@ byte readEEPROM(int address) { } setAddress(address, /*outputEnable*/ true); - byte data = 0; + byte data = 0x00; for (int pin = EEPROM_D7; pin >= EEPROM_D0; pin -= 1) { data = (data << 1) + digitalRead(pin); } @@ -94,24 +99,76 @@ void writeEEPROM(int address, byte data) { delay(10); } +/** + * Clear out the entire EEPROM + */ +void eraseEEPROM() +{ + Serial.println("Erasing EEPROM"); + for (int address = 0x0000; address < 0x0800; address++) { + writeEEPROM(address, 0xff); + + if (address % 0x40 == 0x00) { + Serial.print("."); + } + } + Serial.println("Erasing EEPROM -- Done."); + Serial.println(); +} + + +void programEEPROM(byte data[], int length) +{ + Serial.println("Programming EEPROM"); + for (int address = 0x0000; address < length; address++) { + writeEEPROM(address, data[address]); + + if (address % 0x40 == 0x00) { + Serial.print("."); + } + } + Serial.println(" Done."); + Serial.println(); +} + + +void programEEPROM(uint16_t data[], int offset, int length, bool highByte) +{ + Serial.println("Programming EEPROM"); + for (int address = 0x0000; address < length; address++){ + writeEEPROM(address + offset, data[address] >> (highByte ? 8 : 0)); + + if (address % 0x40 == 0x00) { + Serial.print("."); + } + } + Serial.println(" Done."); + Serial.println(); +} + /* * Read the contents of the EEPROM and print them to the serial monitor. */ -void printContents() { - for (int base = 0; base <= 255; base += 16) { - byte data[16]; - for (int offset = 0; offset <= 15; offset += 1) { - data[offset] = readEEPROM(base + offset); +void printContents(int address) { + for (int base = 0x0000; base < 0x0100; base += 0x10) { + char buf[20]; + sprintf(buf, "0x%04x: e", address + base); + Serial.print(buf); + for (int offset = 0; offset < 0x10; offset += 0x01) { + byte data = readEEPROM(address + base + offset); + sprintf(buf, "%02x ", data); + Serial.print(buf); + + if (offset == 0x07) { + Serial.print(" "); + } } - char buf[80]; - sprintf(buf, "%03x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", - base, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], - data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]); - - Serial.println(buf); + Serial.println(); } + + Serial.println(); } @@ -124,33 +181,18 @@ void setup() { pinMode(WRITE_EN, OUTPUT); Serial.begin(57600); - // Program data bytes - Serial.print("Programming EEPROM"); - - // Program the 8 high-order bits of microcode into the first 128 bytes of EEPROM - for (int address = 0; address < sizeof(data)/sizeof(data[0]); address += 1) { - writeEEPROM(address, data[address] >> 8); - - if (address % 64 == 0) { - Serial.print("."); - } - } + // eraseEEPROM(); - // Program the 8 low-order bits of microcode into the second 128 bytes of EEPROM - for (int address = 0; address < sizeof(data)/sizeof(data[0]); address += 1) { - writeEEPROM(address + 128, data[address]); - - if (address % 64 == 0) { - Serial.print("."); - } - } - - Serial.println(" done"); + // Program data bytes + // Program the 8 high-order bits of microcode into the first 0x80 bytes of EEPROM + programEEPROM(data, 0x00, sizeof data / sizeof data[0], true); + // Program the 8 low-order bits of microcode into the second 0x80 bytes of EEPROM + programEEPROM(data, 0x80, sizeof data / sizeof data[0], false); // Read and print out the contents of the EERPROM Serial.println("Reading EEPROM"); - printContents(); + printContents(0x0000); } From f08bcc1bb2bfefac8564a21be30001561fb3210b Mon Sep 17 00:00:00 2001 From: Greg Eakin Date: Fri, 7 Jul 2017 23:07:13 -0700 Subject: [PATCH 03/11] Initial project import --- multiplexed-display.tests/.gitattributes | 63 +++++ multiplexed-display.tests/.gitignore | 261 ++++++++++++++++++ .../multiplexed-display.tests.sln | 22 ++ .../Properties/AssemblyInfo.cs | 20 ++ .../multiplexed-display.tests/UnitTest1.cs | 14 + .../multiplexed-display.tests.csproj | 67 +++++ .../multiplexed-display.tests/packages.config | 5 + 7 files changed, 452 insertions(+) create mode 100644 multiplexed-display.tests/.gitattributes create mode 100644 multiplexed-display.tests/.gitignore create mode 100644 multiplexed-display.tests/multiplexed-display.tests.sln create mode 100644 multiplexed-display.tests/multiplexed-display.tests/Properties/AssemblyInfo.cs create mode 100644 multiplexed-display.tests/multiplexed-display.tests/UnitTest1.cs create mode 100644 multiplexed-display.tests/multiplexed-display.tests/multiplexed-display.tests.csproj create mode 100644 multiplexed-display.tests/multiplexed-display.tests/packages.config diff --git a/multiplexed-display.tests/.gitattributes b/multiplexed-display.tests/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/multiplexed-display.tests/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/multiplexed-display.tests/.gitignore b/multiplexed-display.tests/.gitignore new file mode 100644 index 0000000..3c4efe2 --- /dev/null +++ b/multiplexed-display.tests/.gitignore @@ -0,0 +1,261 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +project.fragment.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +#*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignoreable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc \ No newline at end of file diff --git a/multiplexed-display.tests/multiplexed-display.tests.sln b/multiplexed-display.tests/multiplexed-display.tests.sln new file mode 100644 index 0000000..4cbe344 --- /dev/null +++ b/multiplexed-display.tests/multiplexed-display.tests.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.15 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "multiplexed-display.tests", "multiplexed-display.tests\multiplexed-display.tests.csproj", "{9D7E2F34-856F-453F-839C-91741F8F0781}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {9D7E2F34-856F-453F-839C-91741F8F0781}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9D7E2F34-856F-453F-839C-91741F8F0781}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9D7E2F34-856F-453F-839C-91741F8F0781}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9D7E2F34-856F-453F-839C-91741F8F0781}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/multiplexed-display.tests/multiplexed-display.tests/Properties/AssemblyInfo.cs b/multiplexed-display.tests/multiplexed-display.tests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..404e5e0 --- /dev/null +++ b/multiplexed-display.tests/multiplexed-display.tests/Properties/AssemblyInfo.cs @@ -0,0 +1,20 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("multiplexed-display.tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("multiplexed-display.tests")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("9d7e2f34-856f-453f-839c-91741f8f0781")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/multiplexed-display.tests/multiplexed-display.tests/UnitTest1.cs b/multiplexed-display.tests/multiplexed-display.tests/UnitTest1.cs new file mode 100644 index 0000000..8f20d7e --- /dev/null +++ b/multiplexed-display.tests/multiplexed-display.tests/UnitTest1.cs @@ -0,0 +1,14 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace multiplexed_display.tests +{ + [TestClass] + public class UnitTest1 + { + [TestMethod] + public void TestMethod1() + { + } + } +} diff --git a/multiplexed-display.tests/multiplexed-display.tests/multiplexed-display.tests.csproj b/multiplexed-display.tests/multiplexed-display.tests/multiplexed-display.tests.csproj new file mode 100644 index 0000000..8735313 --- /dev/null +++ b/multiplexed-display.tests/multiplexed-display.tests/multiplexed-display.tests.csproj @@ -0,0 +1,67 @@ + + + + + Debug + AnyCPU + {9D7E2F34-856F-453F-839C-91741F8F0781} + Library + Properties + multiplexed_display.tests + multiplexed-display.tests + v4.5.2 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\packages\MSTest.TestFramework.1.1.11\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\packages\MSTest.TestFramework.1.1.11\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/multiplexed-display.tests/multiplexed-display.tests/packages.config b/multiplexed-display.tests/multiplexed-display.tests/packages.config new file mode 100644 index 0000000..1ab7218 --- /dev/null +++ b/multiplexed-display.tests/multiplexed-display.tests/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file From b02457980445f6e69b9efb1b5c751e0c2d62590b Mon Sep 17 00:00:00 2001 From: Greg Eakin Date: Fri, 7 Jul 2017 23:08:50 -0700 Subject: [PATCH 04/11] Add test for different display types. --- .../multiplexed-display.tests/UnitTest1.cs | 171 +++++++++++++++++- 1 file changed, 168 insertions(+), 3 deletions(-) diff --git a/multiplexed-display.tests/multiplexed-display.tests/UnitTest1.cs b/multiplexed-display.tests/multiplexed-display.tests/UnitTest1.cs index 8f20d7e..1b79f63 100644 --- a/multiplexed-display.tests/multiplexed-display.tests/UnitTest1.cs +++ b/multiplexed-display.tests/multiplexed-display.tests/UnitTest1.cs @@ -1,14 +1,179 @@ -using System; -using Microsoft.VisualStudio.TestTools.UnitTesting; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; namespace multiplexed_display.tests { [TestClass] public class UnitTest1 { + private readonly char[] _digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + private const char Blank = ' '; + private const char MinusSign = '-'; + private const char HexSigh = 'h'; + + private static string Display(int i, IReadOnlyList data) + { + return $"{data[0x300 + i]}{data[0x200 + i]}{data[0x100 + i]}{data[0x000 + i]}"; + } + + [TestMethod] + public void UnsingedTest() + { + var data = new char[0x400]; + + for (var i = 0; i < 0x100; i++) + { + var d2 = i / 100 % 10; // 2nd 7segment display (hundreds) + var d3 = i / 10 % 10; // 3rd 7segment display (tenths) + data[i + 0x300] = Blank; // clear first 7segment display + data[i + 0x200] = d2 == 0 ? Blank : _digits[d2]; // write the digit or clear if 0 + data[i + 0x100] = d2 == 0 && d3 == 0 ? Blank : _digits[d3]; // write the digit or clear if d3 and d2 are 0 + data[i + 0x000] = _digits[i % 10]; // write the digit even 0 + } + + Assert.AreEqual(" 0", Display(0, data)); + Assert.AreEqual(" 7", Display(7, data)); + Assert.AreEqual(" 16", Display(16, data)); + Assert.AreEqual(" 100", Display(100, data)); + Assert.AreEqual(" 255", Display(255, data)); + } + + [TestMethod] + public void HexTest() + { + var data = new char[0x400]; + + for (var i = 0; i < 0x100; i++) + { + var d2 = i >> 4; + var d3 = i & 0x0F; + data[i + 0x300] = Blank; + data[i + 0x200] = _digits[d2]; + data[i + 0x100] = _digits[d3]; + data[i + 0x000] = HexSigh; + } + + Assert.AreEqual(" 00h", Display(0x00, data)); + Assert.AreEqual(" 07h", Display(0x07, data)); + Assert.AreEqual(" 1ch", Display(0x1C, data)); + Assert.AreEqual(" 64h", Display(0x64, data)); + Assert.AreEqual(" ffh", Display(0xFF, data)); + } + + [TestMethod] + public void TwosCompletentTest() + { + var data = new char[0x400]; + + for (var i = 0; i < 0x100; i++) + { + if (i < 0x80) + { + var d2 = i / 100 % 10; // 2nd 7segment display (hundreds) + var d3 = i / 10 % 10; // 3rd 7segment display (tenths) + data[i + 0x300] = Blank; // clear first 7segment display + data[i + 0x200] = d2 == 0 ? Blank : _digits[d2]; // write the digit or clear if 0 + data[i + 0x100] = d2 == 0 && d3 == 0 ? Blank : _digits[d3]; // write the digit or clear if d3 and d2 are 0 + data[i + 0x000] = _digits[i % 10]; // write the digit even 0 + } + else + { + // Example + // d1 d2 d3 d4 + // - 1 2 3 + // - 4 2 + // - 7 + + var value = i - 0x100; //real value as two's complement + var d2 = Math.Abs(value) / 100 % 10; //hundreds + var d3 = Math.Abs(value) / 10 % 10; //tenths + var d4 = Math.Abs(value) % 10; //ones + + //first 7segment display + data[i + 0x300] = d2 == 0 ? Blank : MinusSign; //write a minus sign to the first 7segment display if the second 7segment display isn't clear + + //second 7segment display + if (d2 == 0 && d3 == 0) + { // if the minus sign is further right + data[i + 0x200] = Blank; // clear second 7segment display + } + else + { + data[i + 0x200] = d2 == 0 ? MinusSign : _digits[d2]; + } + + // third 7segment display + data[i + 0x100] = d2 == 0 && d3 == 0 ? MinusSign : _digits[d3]; // write a minus sign if both the second and the third 7segment display are clear + + // last 7segment display + data[i + 0x000] = _digits[d4]; // always write the last digit (ones) + } + } + + Assert.AreEqual(" 0", Display(0, data)); + Assert.AreEqual(" 16", Display(16, data)); + Assert.AreEqual(" 127", Display(127, data)); + Assert.AreEqual("-128", Display(128, data)); + Assert.AreEqual(" -10", Display(246, data)); + Assert.AreEqual(" -1", Display(255, data)); + } + [TestMethod] - public void TestMethod1() + public void GrayTest() { + var data = new char[0x400]; + + for (var i = 0; i < 0x100; i++) + { + var value = i ^ (i >> 1); + + var d2 = value / 100 % 10; // 2nd 7segment display (hundreds) + var d3 = value / 10 % 10; // 3rd 7segment display (tenths) + data[i + 0x300] = Blank; // clear first 7segment display + data[i + 0x200] = d2 == 0 ? Blank : _digits[d2]; // write the digit or clear if 0 + data[i + 0x100] = d2 == 0 && d3 == 0 ? Blank : _digits[d3]; // write the digit or clear if d3 and d2 are 0 + data[i + 0x000] = _digits[i % 10]; // write the digit even 0 + } + + Assert.AreEqual(" 0", Display(0, data)); + Assert.AreEqual(" 7", Display(7, data)); + Assert.AreEqual(" 26", Display(16, data)); + Assert.AreEqual(" 80", Display(100, data)); + Assert.AreEqual(" 125", Display(255, data)); + } + + [TestMethod] + public void BcdTest() + { + var data = new char[0x400]; + + for (var i = 0; i < 0x100; i++) + { + var d3 = i >> 4; + var d4 = i & 0x0F; + + if (d3 > 9 || d4 > 9) + { + data[i + 0x300] = MinusSign; + data[i + 0x200] = MinusSign; + data[i + 0x100] = MinusSign; + data[i + 0x000] = MinusSign; + continue; + } + + data[i + 0x300] = Blank; + data[i + 0x200] = Blank; + data[i + 0x100] = d3 == 0 ? Blank : _digits[d3]; + data[i + 0x000] = _digits[d4]; + } + + Assert.AreEqual(" 0", Display(0x00, data)); + Assert.AreEqual(" 7", Display(0x07, data)); + Assert.AreEqual(" 26", Display(0x26, data)); + Assert.AreEqual(" 99", Display(0x99, data)); + Assert.AreEqual("----", Display(0x0A, data)); + Assert.AreEqual("----", Display(0xA0, data)); } } } From 081728c51e82d4208ca51b6b7755d9b588afc77c Mon Sep 17 00:00:00 2001 From: Greg Eakin Date: Fri, 7 Jul 2017 23:09:29 -0700 Subject: [PATCH 05/11] Rename the UnitTest1.cs to DisplayTests.cs --- .../multiplexed-display.tests/{UnitTest1.cs => DisplayTests.cs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename multiplexed-display.tests/multiplexed-display.tests/{UnitTest1.cs => DisplayTests.cs} (100%) diff --git a/multiplexed-display.tests/multiplexed-display.tests/UnitTest1.cs b/multiplexed-display.tests/multiplexed-display.tests/DisplayTests.cs similarity index 100% rename from multiplexed-display.tests/multiplexed-display.tests/UnitTest1.cs rename to multiplexed-display.tests/multiplexed-display.tests/DisplayTests.cs From 5a8b1207c95e1cb98e7582b55339705bfe54e305 Mon Sep 17 00:00:00 2001 From: Greg Eakin Date: Fri, 7 Jul 2017 23:58:54 -0700 Subject: [PATCH 06/11] Rename UnitTest1 to DisplayTests Fix the Gray Code test --- .../multiplexed-display.tests/multiplexed-display.tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multiplexed-display.tests/multiplexed-display.tests/multiplexed-display.tests.csproj b/multiplexed-display.tests/multiplexed-display.tests/multiplexed-display.tests.csproj index 8735313..0515b8e 100644 --- a/multiplexed-display.tests/multiplexed-display.tests/multiplexed-display.tests.csproj +++ b/multiplexed-display.tests/multiplexed-display.tests/multiplexed-display.tests.csproj @@ -48,7 +48,7 @@ - + From 4a3431cdb6996b25c3d14f1bbaef753771b6cd42 Mon Sep 17 00:00:00 2001 From: Greg Eakin Date: Fri, 7 Jul 2017 23:59:28 -0700 Subject: [PATCH 07/11] Fix the Gray Code tests Rename UnitTest1 to DisplayTests --- .../multiplexed-display.tests/DisplayTests.cs | 45 ++++++++++++------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/multiplexed-display.tests/multiplexed-display.tests/DisplayTests.cs b/multiplexed-display.tests/multiplexed-display.tests/DisplayTests.cs index 1b79f63..948d719 100644 --- a/multiplexed-display.tests/multiplexed-display.tests/DisplayTests.cs +++ b/multiplexed-display.tests/multiplexed-display.tests/DisplayTests.cs @@ -5,7 +5,7 @@ namespace multiplexed_display.tests { [TestClass] - public class UnitTest1 + public class DisplayTests { private readonly char[] _digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; private const char Blank = ' '; @@ -119,28 +119,43 @@ public void TwosCompletentTest() Assert.AreEqual(" -1", Display(255, data)); } + private static uint BinaryToGray(uint num) + { + return num ^ (num >> 1); + } + + private static uint GrayToBinary32(uint num) + { + num = num ^ (num >> 16); + num = num ^ (num >> 8); + num = num ^ (num >> 4); + num = num ^ (num >> 2); + num = num ^ (num >> 1); + return num; + } + [TestMethod] public void GrayTest() { var data = new char[0x400]; - for (var i = 0; i < 0x100; i++) + for (var gray = 0x000; gray < 0x100; gray++) { - var value = i ^ (i >> 1); - - var d2 = value / 100 % 10; // 2nd 7segment display (hundreds) - var d3 = value / 10 % 10; // 3rd 7segment display (tenths) - data[i + 0x300] = Blank; // clear first 7segment display - data[i + 0x200] = d2 == 0 ? Blank : _digits[d2]; // write the digit or clear if 0 - data[i + 0x100] = d2 == 0 && d3 == 0 ? Blank : _digits[d3]; // write the digit or clear if d3 and d2 are 0 - data[i + 0x000] = _digits[i % 10]; // write the digit even 0 + var binary = GrayToBinary32((uint)gray); + + var d2 = binary / 100 % 10; // 2nd 7segment display (hundreds) + var d3 = binary / 10 % 10; // 3rd 7segment display (tenths) + data[gray + 0x300] = Blank; // clear first 7segment display + data[gray + 0x200] = d2 == 0 ? Blank : _digits[d2]; // write the digit or clear if 0 + data[gray + 0x100] = d2 == 0 && d3 == 0 ? Blank : _digits[d3]; // write the digit or clear if d3 and d2 are 0 + data[gray + 0x000] = _digits[binary % 10]; // write the digit even 0 } - Assert.AreEqual(" 0", Display(0, data)); - Assert.AreEqual(" 7", Display(7, data)); - Assert.AreEqual(" 26", Display(16, data)); - Assert.AreEqual(" 80", Display(100, data)); - Assert.AreEqual(" 125", Display(255, data)); + for (var binary = 0x000; binary < 0x100; binary++) + { + var gray = BinaryToGray((uint)binary); + Assert.AreEqual($"{binary,4:##0}", Display((int)gray, data)); + } } [TestMethod] From 54c901eb5c9586b06f9e097e4007b4bd7abbc1b5 Mon Sep 17 00:00:00 2001 From: Greg Eakin Date: Sat, 8 Jul 2017 00:19:17 -0700 Subject: [PATCH 08/11] Code cleanup --- microcode-eeprom-programmer/microcode-eeprom-programmer.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/microcode-eeprom-programmer/microcode-eeprom-programmer.ino b/microcode-eeprom-programmer/microcode-eeprom-programmer.ino index a680e94..d8cd333 100644 --- a/microcode-eeprom-programmer/microcode-eeprom-programmer.ino +++ b/microcode-eeprom-programmer/microcode-eeprom-programmer.ino @@ -136,7 +136,8 @@ void programEEPROM(uint16_t data[], int offset, int length, bool highByte) { Serial.println("Programming EEPROM"); for (int address = 0x0000; address < length; address++){ - writeEEPROM(address + offset, data[address] >> (highByte ? 8 : 0)); + byte value = data[address] >> (highByte ? 8 : 0); + writeEEPROM(address + offset, value); if (address % 0x40 == 0x00) { Serial.print("."); From af2b176d99ad88f7d28485014911bfe70e4bdfe5 Mon Sep 17 00:00:00 2001 From: Greg Eakin Date: Sat, 8 Jul 2017 23:55:08 -0700 Subject: [PATCH 09/11] Add an erase method --- multiplexed-display/multiplexed-display.ino | 41 +++++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/multiplexed-display/multiplexed-display.ino b/multiplexed-display/multiplexed-display.ino index f639d35..336e58a 100644 --- a/multiplexed-display/multiplexed-display.ino +++ b/multiplexed-display/multiplexed-display.ino @@ -67,6 +67,27 @@ void writeEEPROM(int address, byte data) { } +/** + * Clear out the entire EEPROM + */ +void eraseEEPROM(int address, int length) +{ + char data[80]; + sprintf(data, "Erasing EEPROM, Start 0x%04x, Length 0x%04x", address, length); + Serial.println(data); + for (int offset = 0x0000; offset < length; offset++) { + writeEEPROM(address + offset, 0xff); + + if (offset % 0x40 == 0x00) { + Serial.print("."); + } + } + Serial.println(); + Serial.println("Erasing EEPROM -- Done."); + Serial.println(); +} + + /* Read the contents of the EEPROM and print them to the serial monitor. */ @@ -164,9 +185,11 @@ void programEEPROM() void setup() { - // put your setup code here, to run once: + // put your setup code here, to run once: pinMode(SHIFT_DATA, OUTPUT); pinMode(SHIFT_CLK, OUTPUT); + + digitalWrite(SHIFT_LATCH, LOW); pinMode(SHIFT_LATCH, OUTPUT); digitalWrite(WRITE_EN, HIGH); @@ -175,22 +198,16 @@ void setup() { Serial.begin(57600); // Clear and program the EEPROM - // eraseEEPROM(); + // eraseEEPROM(0x0600, 0x0100); programEEPROM(); - + + // Read and print out the contents of the EERPROM Serial.println("Reading EEPROM"); - printContents(0x0000); - printContents(0x0100); - printContents(0x0200); - printContents(0x0300); - printContents(0x0400); - printContents(0x0500); - printContents(0x0600); - printContents(0x0700); + for (int address = 0x0000; address < 0x0800; address += 0x0100) + printContents(address); } - void loop() { // put your main code here, to run repeatedly: } From 5198b6dd8ba4fc4aa1368d219ae35dc181edd41e Mon Sep 17 00:00:00 2001 From: Greg Eakin Date: Sat, 15 Jul 2017 11:47:45 -0700 Subject: [PATCH 10/11] Fix typo. Where did that stray E character come from? --- microcode-eeprom-programmer/microcode-eeprom-programmer.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microcode-eeprom-programmer/microcode-eeprom-programmer.ino b/microcode-eeprom-programmer/microcode-eeprom-programmer.ino index d8cd333..57aecb0 100644 --- a/microcode-eeprom-programmer/microcode-eeprom-programmer.ino +++ b/microcode-eeprom-programmer/microcode-eeprom-programmer.ino @@ -154,7 +154,7 @@ void programEEPROM(uint16_t data[], int offset, int length, bool highByte) void printContents(int address) { for (int base = 0x0000; base < 0x0100; base += 0x10) { char buf[20]; - sprintf(buf, "0x%04x: e", address + base); + sprintf(buf, "0x%04x: ", address + base); Serial.print(buf); for (int offset = 0; offset < 0x10; offset += 0x01) { byte data = readEEPROM(address + base + offset); From 9392ebf75a0f006885043f242dfdece120b8a11e Mon Sep 17 00:00:00 2001 From: Greg Eakin Date: Sun, 9 Aug 2020 10:44:53 -0700 Subject: [PATCH 11/11] Update the test package. --- .../multiplexed-display.tests/DisplayTests.cs | 21 ++++++++++++++++--- .../multiplexed-display.tests.csproj | 12 +++++------ .../multiplexed-display.tests/packages.config | 4 ++-- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/multiplexed-display.tests/multiplexed-display.tests/DisplayTests.cs b/multiplexed-display.tests/multiplexed-display.tests/DisplayTests.cs index 948d719..7541157 100644 --- a/multiplexed-display.tests/multiplexed-display.tests/DisplayTests.cs +++ b/multiplexed-display.tests/multiplexed-display.tests/DisplayTests.cs @@ -1,4 +1,19 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +// +// Copyright 2017-2020 Greg Eakin +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at: +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using Microsoft.VisualStudio.TestTools.UnitTesting; using System; using System.Collections.Generic; @@ -18,7 +33,7 @@ private static string Display(int i, IReadOnlyList data) } [TestMethod] - public void UnsingedTest() + public void UnsignedTest() { var data = new char[0x400]; @@ -62,7 +77,7 @@ public void HexTest() } [TestMethod] - public void TwosCompletentTest() + public void TwosComplementTest() { var data = new char[0x400]; diff --git a/multiplexed-display.tests/multiplexed-display.tests/multiplexed-display.tests.csproj b/multiplexed-display.tests/multiplexed-display.tests/multiplexed-display.tests.csproj index 0515b8e..feef6f5 100644 --- a/multiplexed-display.tests/multiplexed-display.tests/multiplexed-display.tests.csproj +++ b/multiplexed-display.tests/multiplexed-display.tests/multiplexed-display.tests.csproj @@ -1,6 +1,6 @@  - + Debug AnyCPU @@ -39,10 +39,10 @@ - ..\packages\MSTest.TestFramework.1.1.11\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + ..\packages\MSTest.TestFramework.2.1.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll - ..\packages\MSTest.TestFramework.1.1.11\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + ..\packages\MSTest.TestFramework.2.1.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll @@ -60,8 +60,8 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - + + - + \ No newline at end of file diff --git a/multiplexed-display.tests/multiplexed-display.tests/packages.config b/multiplexed-display.tests/multiplexed-display.tests/packages.config index 1ab7218..506206f 100644 --- a/multiplexed-display.tests/multiplexed-display.tests/packages.config +++ b/multiplexed-display.tests/multiplexed-display.tests/packages.config @@ -1,5 +1,5 @@  - - + + \ No newline at end of file