While a huge mux/demux will certainly work, connecting up a bunch of 16:1 muxes is a lot of work, and has some limitations that may or may not be an issue. The more conventional approach would be to use shift registers. Use a serial-in/parallel-out register for the "driving" end, and a parallel-in/serial-out for the receiving end. The nice thing about shift registers is that they can easily be daisy-chained to make a longer shift register. A 256-bit or even 1024 bit shift register isn't a problem at all. With some buffering, the serial stream can even be passed over a cable to another PCB (if that makes your thing easier to make).
There are many 8-bit shift register chips like the 74xx597, but a CPLD is MUCH better for this. But you don't need a giant 256+ pin CPLD. Instead, you can use several smaller CPLD's and chain them together. Although I haven't done the math, I'm fairly sure that using more small to medium size CPLD's would be cheaper than one large CPLD-- and you don't have to worry about BGA's.
This CPLD would be fairly Flip-Flop intensive. What this means is that a normal CPLD architecture (like what Xilinx uses) is not as good as something that is more FPGA-ish. Altera and Lattice both have CPLD's with lots more Flip-Flops per Dollar than what Xilinx has.
While you might not have a lot of experience with CPLD's, this design is very simple and the benefits of using a CPLD is huge. It would be very worth your time to learn how to program CPLD's for this.
Also, the advantages of using a shift register instead of a mux is not easy to see initially. Mostly you get a lot of flexibility in how you drive and sense the wires. You could even be testing several harnesses at one time (if you have enough shift registers). Everything you can test with muxes can be done with shift registers, but shift registers can do more. The one down side to shift registers is that it is slower, although it will still be faster than what you need (I.E., the guy connecting and disconnecting the harness will be much slower than the time to test with shift registers).
I should also say that even if you are using CPLD's, shift registers are still easier than muxes. The main thing is that they are smaller-- although to see the actual advantage/disadvantage you would have to actually do the design in both and see what size of CPLD you need. This is going to be fairly dependent on the type of CPLD architecture used, so any generalizations made with Xilinx won't apply to Altera.
Edit: Below is a little more detail on how to actually perform the test using shift registers...
For doing the test, you can ignore the fact that you are using shift registers and only consider that data is driven on the "driving end" and hopefully read on the "receiving end". How you got the data there and back (via serial) is largely irrelevant. What is important is that you can data that you can drive is completely arbitrary.
The data that you drive with is called the "test vectors". The data that you EXPECT TO READ is also part of the test vectors. If the cable is wired with a 1:1 relationship then you would expect the driving data and the receiving data to be the same as what you drive. If the cable is not 1:1, then it would obviously be different.
If you used a MUX based approach you are still using test vectors, but you have no control over the kind of test vector. With the Muxes, the pattern is called a "Walking Ones", or "Walking Zeros". Let's say that you have a 4-pin cable. With walking ones you would drive the following pattern: 0001, 0010, 0100, 1000. Walking zeros is the same, but inverted.
For a simple continuity test, walking ones/zeros works fairly well. Depending on how you cable is connected, there are other patterns that could be done to speed up the test or to test specific things. For example, if some pins can never be shorted against other pins then you can optimize the test pattern to not look at those cases and thus run faster. Dealing with something other than a walking-ones/zeros can get complicated on the software side of things to handle.
The ultimate method of generating test vectors is done for JTAG testing. JTAG, also called boundary scan, is a similar scheme for testing the connections between chips on a PCB (and between PCB's). Most BGA chips use JTAG. JTAG has shift registers in each chip that can be used to drive/read each pin. A complicated and expensive piece of software looks at the netlist for the PCB and will generate the test vectors. A sophisticated cable tester could do the same thing-- but that would be a lot of work.
Fortunately, for you, there is a MUCH EASIER way to generate the test vectors. Here's what you do... Connect a known good cable to the shift registers. Run a walking-zeros/ones pattern through the driving end. As you do this, record what is seen on the receiving end. On the simple level, you can just use that as your test vectors. When you connect a bad cable and do the same walking-ones/zeros, the data you receive won't match the data you previously recorded-- and therefore you know the cable is bad. This goes by several names, but all the names are some variation of the term "learning", like self-learning, or auto-learning.
So far, this easily handles the case where one pin on the driving end goes to more than one pin on the receiving end, but doesn't handle the other case where multiple pins on the driving end are connected together. For that you need some special stuff to prevent damage from bus contention, and all of your shift register pins should be bi-directional (I.E., function as both the driver and receiver). Here's what you do:
Put a pull-down resistor on each pin. Something around 20K to 50k ohms should be fine.
Put a series resistor between the CPLD and the cable. Something around 100 ohms. This is to help prevent damage from ESD and stuff. A 2700 pF cap to ground (on the CPLD pin side of the 100 ohm resistor) will also help with ESD.
Program the CPLD so that it will only drive the signal high, never driving low. If your output data is a '0' then the CPLD will tri-state that pin and allow the pull-down resistor to bring the line low. In this way, if several CPLD pins are driving the same wire on the cable high then no damage will occur (because the CPLD won't also be driving the same wire low).
Every pin is both a driver and receiver. So if you have a 256 pin cable then your shift registers will be 512 bits for the driver and 512 bits for the receiver. Driving and receiving can be done in the same CPLD, so the PCB complexity doesn't really change because of this. You will have 3 or 4 flip-flops per cable pin in this CPLD, so plan accordingly.
You then do the same walking-ones/zeros pattern while comparing the received data with what was previously recorded. But now it will handle all sorts of arbitrary connections within the wiring harness.
Okay, I can see the changes.
As shown now, the LEDs on the receiving IC will block the data high as they are reversed. The LEDs on the transmitting side aren't a good idea either. If you want LEDs you need to put them from the data line to ground through a resistor, not in series with the connection to cable socket.
Just seen your picture - it looks like you have removed the LEDs, good (I was just about to suggest this.. :-) )
So now it looks as if you have direct connections from IC1 to IC2. If this is the case then if the code (looks reasonable at a glance) and IC wiring are correct then it should work.
If you can confirm with a multimeter that the input pins are seeing a high (or low) voltage and the read value is different, then this would confirm the issue is one or the other of the above. Maybe just apply a known voltage directly and see if you can read that okay)
However, if you are reading different values when the pullups are on/off then that would seem to indicate the read is correct. Try reading a direct voltage and post results, I'm just checking the datasheet for the ICs, will add more shortly.
EDIT - about the pullups:
You can use the internal pullups if you don't mind the line "relaxing" to high when not driven (i.e. default state 1) These are often used for interfacing with open drain buses, or for button to ground, etc to save an external pullup.
If you want to have the lines default state low though, (as is the case for you) you need a pulldown to stop the high impedance floating. Since the IC in question doesn't have internal pulldowns, you need to add them externally.
EDIT - Doh! I've just seen the problem...
In your code you set 1 pin at a time to output and all the rest to inputs. This means that if you have internal pullups on, the undriven pins will default to high! When a pin is set to input, it is high impedance, so effectively it's like disconnecting that end of the line, and the weak pullups will pull the receiving end high.
You need to keep all pins as outputs, and just set one high at a time, this will keep all the pins driven - try this with the pullups on, it should work.
If you know the lines will be driven correctly all the time, you don't need the pullups, but it doesn't hurt to keep them on.
Here is the relevant code (in the intialise registers function):
i2c_start_wait(SLAVE_ADDRESS(0x4E)+I2C_WRITE); // Address Slave 1
i2c_write(0x00); // Set memory pointer to the IODIRA register (IODIRA address is 0x00 - see Page 9)
i2c_write(~(Value)); // Set only one pin at a time as an output and everything else as inputs
i2c_stop();
Change it to:
i2c_start_wait(SLAVE_ADDRESS(0x4E)+I2C_WRITE); // Address Slave 1
i2c_write(0x00); // Set memory pointer to the IODIRA register (IODIRA address is 0x00 - see Page 9)
i2c_write(0x00); // Set all pins as outputs
i2c_stop();
Best Answer
The first thing to check is that !RESET pin of mux properly pulled up by resistor and not held low by master MCU. And I mean really check not just assume that it is OK because it is supposed to be so. The mux might still ACK in reset when you scanning the bus but it will not select output channel on command.
If that is not the case, here is a simple procedure to diagnose the problem. You'd need another I2C device "B", for example VL53L0X that you've mentioned. You've already did some of the steps below, so you can skip those. Also make sure devices with selectable IDs always wired identically in the tests.
You can diagnose further by comparing voltages and pull-ups on main bus and output Mux channels. Also go through the datasheets and re-check supported speeds and re-calculate required pull-up resistor values for Mux channels (they depend on speed and bus capacitance).