The DONE
pin in not used during JTAG programming and can be tied high:
If JTAG is the only configuration mode, then PROGRAM_B, INIT_B, and DONE can be
tied High to a 330Ω resistor. (p57)
However, if Serial programming is used, then all the DONE
pins should be tied together and the DriveDone
should be disabled for all devices except the first:
It is important to connect the DONE pins for all devices in a serial daisy chain. Failing to connect the DONE pins can cause configuration to fail. (p135)
All devices except the first should disable the driver on the DONE pin. (p135)
If both are to be used, there are two options:
Alternatively, the driver can be disabled for all DONE pins and an external pull-up resistor can be added to pull the signal High after all devices have released it. (p135)
For debugging purposes, it is often helpful to have a way of disconnecting individual DONE pins from the common DONE signal, so that devices can be individually configured through the serial or JTAG interface. (p135)
In your case, I think connecting them and tying them all high while disabling the DONE
pin is the best way to go.
All page numbers reference the User Guide
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 answer is in most cases, yes. The GPIO pins on most FPGAs will be bidirectional, just like those on an ATMega (Arduino board MCU).
For an FPGA, you simply need to describe the logic for a tri-state buffer to be able to control the direction. This is quite simple in most cases.
To give an example, let's assume Verilog:
From the above code, the synthesis tools would infer a tristate buffer with a control pin. I've labelled the ports with the names of the corresponding ATMega registers. The
ioPin
signal connects to the outside world, and is declared asinout
meaning bidirectional.When the
direction
pin is high, thenioPin
will be an output, driven with the value oftoPin
. Whendirection
is low, thenioPin
will be an input (driven by high-z). ThefromPin
signal will always reflect the value ofioPin
regardless of whether it is an input or output.You can make similar constructs in VHDL and schematic/netlist entry methods.
Additionally many FPGA manufactures will provide primitive elements for bidirectional buffers if you prefer to not rely on synthesis guesswork.