Driving 3.3V input toggling between input/output pin mode

I have to toggle some inputs of a board that are directly connected to an Altera FPGA. The inputs expect 3.3V and are not 5V tolerant, which troubles me since I can only use an Arduino Duemilanove or Uno.

Anyway the pins in question seem to have an internal pullup, since if I just leave them disconnected they seem to be interpreted as high, so I just thought that I can drive them keeping the Arduino pins to which they are connected low and rather toggling them between output (to make the inputs low) and input (to make them high) modes. Is this going to work without damaging the FPGA?

Thanks.

This has to be verified, however my understanding is that when you configure the port as output it will default to high which is 5V and in this case it will likely damage the FPGA. Why don't you use voltage level shifters instead?

As always I'll recommend using 4504 level shifters. Easy to deal with.

https://www.arduino.cc/en/Tutorial/DigitalPins says:

Arduino (Atmega) pins default to inputs, so they don't need to be explicitly declared as inputs with pinMode() when you're using them as inputs. Pins configured this way are said to be in a high-impedance state

[...]

The pullup resistors are controlled by the same registers that control whether a pin is HIGH or LOW. Consequently, a pin that is configured to have pullup resistors turned on when the pin is an INPUT, will have the pin configured as HIGH if the pin is then switched to an OUTPUT with pinMode(). This works in the other direction as well, and an output pin that is left in a HIGH state will have the pullup resistors set if switched to an input with pinMode().

So internal pullups should be disabled by default, and if they are not enabled the pins should switch to LOW state when switched to outputs, as I read it.

I would just like to avoid level shifters for simplicity's sake, since I plan on ending up with the bare 328P and no external components at all (running on the internal oscillator should be OK).

Just try it out without the FPGA connected.

Configure a pin as output without setting the state and test the logic level with a multimeter. I think you will get 5V by default.

Irrespective of the outcome above, any serious design should incorporate proper voltage level conversion even if the connected device were 5V tolerant. Logic levels are about much more than just mere tolerance of voltage. You need to ensure compatibility on the specific voltage level limits between logic high and low.

Watcher:
…when you configure the port as output it will default to high…

Backwards.

A pin has four states: INPUT, INPUT/PULLUP, OUTPUT/LOW, OUTPUT/HIGH. I will use the labels I, IP, OL, OH. The valid transitions are…

  I  <--> OL
  I  <--> IP
  OL <--> OH
  IP <--> OH

Same table no abbreviations…

  INPUT           <-->  OUTPUT / LOW
  INPUT           <-->  INPUT / PULLUP
  OUTPUT / LOW    <-->  OUTPUT / HIGH
  INPUT / PULLUP  <-->  OUTPUT / HIGH

SukkoPera: Anyway the pins in question seem to have an internal pullup...

I suspect you will be far better served with external 4.7 k pullup resistors. Obviously they have to be connected to the same power supply as the FPGA.

...drive them keeping the Arduino pins to which they are connected low and rather toggling them between output (to make the inputs low) and input (to make them high) modes. Is this going to work without damaging the FPGA?

Yes. Use pinMode to change the pin state from INPUT to OUTPUT / LOW. I believe the key term is "open collector".

Since you are targeting a bare 328 in the end, you could just develop on your Duemilanove or Uno powered with regulated 3.3 v put into the 5 v pin. Upload sketches to it via 3.3 v FTDI adapter or HC-05 bluetooth module so you won't power up to 5v via the USB.

Thanks for all your replies, I'll do some tests as soon as the driving logic is complete.

@djmlambert: Unfortunately I cannot do that, as I have to sample some 5V signals.

So, I've given this a try, first connecting some leds instead of the Altera pins, just to make sure.

The switching works as expected, at least as far as I can see, BUT... when I upload a sketch to the board, when the upload is finished and the board is reset, at least two of the three leds flash dimly for a brief moment. This only seems to occur after uploads, it does not occur whenever the board is reset or powered on for the first time.

At the moment the pins I'm using are A0, A1 and A2 (as digital pins though): do these pins have anything particular? Would I be better off using other pins?

If there is a pullup on the input board side, then use a diode in series to prevent you from sending a positive voltage, just pull the line to ground.

Watcher: This has to be verified, however my understanding is that when you configure the port as output it will default to high which is 5V and in this case it will likely damage the FPGA. Why don't you use voltage level shifters instead?

No, on the ATmega the default state is LOW, and mode INPUT.

You can emulate an open-drain output in this way:

void setup ()
{
  digitalWrite (pin, LOW) ; // unnecessary - defensive programming
}

void loop ()
{
  pinMode (pin, OUTPUT) ;  // drive pin LOW
  pinMode (pin, INPUT) ;  // let pin float (the pull-up does the rest)
}

So pinMode() is used for I/O and digitalWrite () for setup, the opposite way round to push-pull outputing.

At the moment the pins I'm using are A0, A1 and A2 (as digital pins though): do these pins have anything particular?

No.